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