]> git.proxmox.com Git - pmg-api.git/blob - src/PMG/RuleDB/BCC.pm
ruledb: encode e-mail addresses for syslog
[pmg-api.git] / src / PMG / RuleDB / BCC.pm
1 package PMG::RuleDB::BCC;
2
3 use strict;
4 use warnings;
5 use DBI;
6 use Encode qw(encode);
7
8 use PVE::SafeSyslog;
9
10 use PMG::Utils;
11 use PMG::ModGroup;
12 use PMG::DKIMSign;
13 use PMG::RuleDB::Object;
14
15 use base qw(PMG::RuleDB::Object);
16
17 sub otype {
18 return 4005;
19 }
20
21 sub oclass {
22 return 'action';
23 }
24
25 sub otype_text {
26 return 'BCC';
27 }
28
29 sub oisedit {
30 return 1;
31 }
32
33 sub final {
34 return 0;
35 }
36
37 sub priority {
38 return 80;
39 }
40
41 sub new {
42 my ($type, $target, $original, $ogroup) = @_;
43
44 my $class = ref($type) || $type;
45
46 my $self = $class->SUPER::new($class->otype(), $ogroup);
47
48 $self->{target} = $target || 'receiver@domain.tld';
49
50 defined ($original) || ($original = 1);
51
52 $self->{original} = $original;
53
54 return $self;
55 }
56
57 sub load_attr {
58 my ($type, $ruledb, $id, $ogroup, $value) = @_;
59
60 my $class = ref($type) || $type;
61
62 defined($value) || return undef;
63
64 $value =~ m/^([01]):(.*)/ || return undef;
65
66 my ($target, $original) = ($2, $1);
67
68 my $obj = $class->new($target, $original, $ogroup);
69 $obj->{id} = $id;
70
71 $obj->{digest} = Digest::SHA::sha1_hex($id, $target, $original, $ogroup);
72
73 return $obj;
74 }
75
76 sub save {
77 my ($self, $ruledb) = @_;
78
79 defined($self->{ogroup}) || die "undefined object attribute: ERROR";
80 defined($self->{target}) || die "undefined object attribute: ERROR";
81 defined($self->{original}) || die "undefined object attribute: ERROR";
82
83 if ($self->{original}) {
84 $self->{original} = 1;
85 } else {
86 $self->{original} = 0;
87 }
88
89 my $value = "$self->{original}:$self->{target}";
90
91 if (defined($self->{id})) {
92 # update
93
94 $ruledb->{dbh}->do(
95 "UPDATE Object SET Value = ? WHERE ID = ?",
96 undef, $value, $self->{id});
97
98 } else {
99 # insert
100
101 my $sth = $ruledb->{dbh}->prepare(
102 "INSERT INTO Object (Objectgroup_ID, ObjectType, Value) " .
103 "VALUES (?, ?, ?);");
104
105 $sth->execute($self->{ogroup}, $self->otype, $value);
106
107 $self->{id} = PMG::Utils::lastid($ruledb->{dbh}, 'object_id_seq');
108 }
109
110 return $self->{id};
111 }
112
113 sub execute {
114 my ($self, $queue, $ruledb, $mod_group, $targets,
115 $msginfo, $vars, $marks) = @_;
116
117 my $subgroups = $mod_group->subgroups($targets, 1);
118
119 my $rulename = encode('UTF-8', $vars->{RULE} // 'unknown');
120
121 my $bcc_to = PMG::Utils::subst_values_for_header($self->{target}, $vars);
122
123 if ($bcc_to =~ m/^\s*$/) {
124 # this happens if a notification is triggered by bounce mails
125 # which notifies the sender <> - we just log and then ignore it
126 syslog('info', "%s: bcc to <> (rule: %s, ignored)", $queue->{logid}, $rulename);
127 return;
128 }
129
130 my @bcc_targets = split (/\s*,\s*/, $bcc_to);
131
132 if ($self->{original}) {
133 $subgroups = [[\@bcc_targets, $mod_group->{entity}]];
134 }
135
136 foreach my $ta (@$subgroups) {
137 my ($tg, $entity) = (@$ta[0], @$ta[1]);
138
139 $entity = $entity->dup();
140 PMG::Utils::remove_marks($entity);
141
142 my $dkim = $msginfo->{dkim} // {};
143 if ($dkim->{sign}) {
144 eval {
145 $entity = PMG::DKIMSign::sign_entity($entity,
146 $dkim->{selector}, $msginfo->{sender}, $dkim->{sign_all});
147 };
148 syslog('warning',
149 "Could not create DKIM-Signature - disabling Signing: $@") if $@;
150 }
151
152 if ($msginfo->{testmode}) {
153 my $fh = $msginfo->{test_fh};
154 print $fh "bcc from: $msginfo->{sender}\n";
155 printf $fh "bcc to: %s\n", join (',', @$tg);
156 print $fh "bcc content:\n";
157 $entity->print ($fh);
158 print $fh "bcc end\n";
159 } else {
160 my $param = {};
161 for my $bcc (@bcc_targets) {
162 $param->{rcpt}->{$bcc}->{notify} = "never";
163 }
164 my $qid = PMG::Utils::reinject_mail(
165 $entity, $msginfo->{sender}, \@bcc_targets,
166 $msginfo->{xforward}, $msginfo->{fqdn}, $param);
167 foreach (@bcc_targets) {
168 my $target = encode('UTF-8', $_);
169 if ($qid) {
170 syslog(
171 'info',
172 "%s: bcc to <%s> (rule: %s, %s)",
173 $queue->{logid},
174 $target,
175 $rulename,
176 $qid,
177 );
178 } else {
179 syslog(
180 'err',
181 "%s: bcc to <%s> (rule: %s) failed",
182 $queue->{logid},
183 $target,
184 $rulename,
185 );
186 }
187 }
188 }
189 }
190
191 # warn if no subgroups
192 }
193
194 sub short_desc {
195 my $self = shift;
196
197 my $descr = "send bcc to: $self->{target}";
198
199 $descr .= " (original)" if $self->{original};
200
201 return $descr;
202 }
203
204 sub properties {
205 my ($class) = @_;
206
207 return {
208 target => {
209 description => "Send a Blind Carbon Copy to this email address.",
210 type => 'string', format => 'email',
211 },
212 original =>{
213 description => "Send the original, unmodified mail.",
214 type => 'boolean',
215 optional => 1,
216 default => 1,
217 },
218 };
219 }
220
221 sub get {
222 my ($self) = @_;
223
224 return {
225 target => $self->{target},
226 original => $self->{original},
227 };
228 }
229
230 sub update {
231 my ($self, $param) = @_;
232
233 $self->{target} = $param->{target};
234 $self->{original} = $param->{original} ? 1 : 0;
235 }
236
237 1;
238
239 __END__
240
241 =head1 PMG::RuleDB::BCC
242
243 Send BCC.