]> git.proxmox.com Git - pmg-api.git/blob - PMG/RuleDB/ContentTypeFilter.pm
Accept.pm: fix short_descr
[pmg-api.git] / PMG / RuleDB / ContentTypeFilter.pm
1 package PMG::RuleDB::ContentTypeFilter;
2
3 use strict;
4 use warnings;
5 use Carp;
6 use DBI;
7
8 use PVE::SafeSyslog;
9 use MIME::Words;
10
11 use PMG::RuleDB::MatchField;
12
13 use base qw(PMG::RuleDB::MatchField);
14
15 my $mtypes = {
16 'message/delivery-status' => undef,
17 'message/disposition-notification' => undef,
18 'message/external-body' => undef,
19 'message/news' => undef,
20 'message/partial' => undef,
21 'message/rfc822' => undef,
22 'multipart/alternative' => undef,
23 'multipart/digest' => undef,
24 'multipart/encrypted' => undef,
25 'multipart/mixed' => undef,
26 'multipart/related' => undef,
27 'multipart/report' => undef,
28 'multipart/signed' => undef,
29 };
30
31 my $oldtypemap = {
32 'application/x-msdos-program' => 'application/x-ms-dos-executable',
33 'application/java-vm' => 'application/x-java',
34 'application/x-javascript' => 'application/javascript',
35 };
36
37 sub load_mime_types {
38 open(DAT, "/usr/share/mime/globs") ||
39 croak ("Could not open file $!: ERROR");
40
41 while (my $row = <DAT>) {
42 next if $row =~ m/^\#/;
43
44 if ($row =~ m/([A-Za-z0-9-_\.]*)\/([A-Za-z0-9-_\+\.]*):\*\.(\S{1,10})\s*$/) {
45
46 my $m = "$1/$2";
47 my $end = $3;
48
49 $m =~ s/\./\\\./g; # quote '.'
50 $m =~ s/\+/\\\+/g; # quote '+'
51
52 if (defined ($end)) {
53 $mtypes->{"$m"} = $mtypes->{"$m"} ? $mtypes->{"$m"} . ",$end" : $end;
54 }
55 }
56 }
57 close(DAT);
58 }
59
60 load_mime_types ();
61
62 sub otype {
63 return 3003;
64 }
65
66 sub otype_text {
67 return 'ContentType Filter';
68 }
69
70 sub oicon {
71 #fixme:
72 return 'contentfilter.gif';
73 }
74
75 sub new {
76 my ($type, $fvalue, $ogroup) = @_;
77
78 my $class = ref($type) || $type;
79
80 # translate old values
81 if ($fvalue && (my $nt = $oldtypemap->{$fvalue})) {
82 $fvalue = $nt;
83 }
84
85 my $self = $class->SUPER::new('content-type', $fvalue, $ogroup);
86
87 $self->{mtypes} = $mtypes;
88
89 return $self;
90 }
91
92 sub load_attr {
93 my ($type, $ruledb, $id, $ogroup, $value) = @_;
94
95 my $class = ref($type) || $type;
96
97 my $obj = $class->SUPER::load_attr($ruledb, $id, $ogroup, $value);
98
99 # translate old values
100 if ($obj->{field_value} && (my $nt = $oldtypemap->{$obj->{field_value}})) {
101 $obj->{field_value} = $nt;
102 }
103
104 $obj->{mtypes} = $mtypes;
105
106 return $obj;
107 }
108
109 sub parse_entity {
110 my ($self, $entity) = @_;
111
112 my $res;
113
114 # match subtypes? We currently do exact matches only.
115
116 if (my $id = $entity->head->mime_attr ('x-proxmox-tmp-aid')) {
117 chomp $id;
118
119 my $header_ct = $entity->head->mime_attr ('content-type');
120
121 my $magic_ct = $entity->{PMX_magic_ct};
122
123 my $glob_ct = $entity->{PMX_glob_ct};
124
125 if ($header_ct && $header_ct =~ m|$self->{field_value}|) {
126 push @$res, $id;
127 } elsif ($magic_ct && $magic_ct =~ m|$self->{field_value}|) {
128 push @$res, $id;
129 } elsif ($glob_ct && $glob_ct =~ m|$self->{field_value}|) {
130 push @$res, $id;
131 }
132 }
133
134 foreach my $part ($entity->parts) {
135 if (my $match = $self->parse_entity ($part)) {
136 push @$res, @$match;
137 }
138 }
139
140 return $res;
141 }
142
143 sub what_match {
144 my ($self, $queue, $entity, $msginfo) = @_;
145
146 return $self->parse_entity ($entity);
147 }
148
149
150 1;
151
152 __END__
153
154 =head1 PMG::RuleDB::ContentTypeFilter
155
156 Content type filter.