]>
git.proxmox.com Git - pmg-api.git/blob - PMG/Quarantine.pm
1 package PMG
::Quarantine
;
14 sub add_to_blackwhite
{
15 my ($dbh, $username, $listname, $addrs, $delete) = @_;
17 my $name = $listname eq 'BL' ?
'BL' : 'WL';
18 my $oname = $listname eq 'BL' ?
'WL' : 'BL';
19 my $qu = $dbh->quote ($username);
21 my $sth = $dbh->prepare(
22 "SELECT * FROM UserPrefs WHERE pmail = $qu AND (Name = 'BL' OR Name = 'WL')");
25 my $list = { 'WL' => {}, 'BL' => {} };
27 while (my $ref = $sth->fetchrow_hashref()) {
28 my $data = $ref->{data
};
30 my @alist = split('\s+', $data);
33 foreach my $a (@alist) {
34 if ($a =~ m/^[[:ascii:]]+$/) {
39 $list->{$ref->{name
}} = $tmp;
46 foreach my $v (@$addrs) {
47 die "email address '$v' is too long (> 512 characters)\n"
51 delete($list->{$name}->{$v});
53 if ($v =~ m/[[:^ascii:]]/) {
54 die "email address '$v' contains invalid characters\n";
56 $list->{$name}->{$v} = 1;
57 delete ($list->{$oname}->{$v});
61 my $wlist = $dbh->quote(join (',', keys %{$list->{WL
}}) || '');
62 my $blist = $dbh->quote(join (',', keys %{$list->{BL
}}) || '');
66 die "whitelist size exceeds limit (> $maxlen bytes)\n"
67 if length($wlist) > $maxlen;
68 die "blacklist size exceeds limit (> $maxlen bytes)\n"
69 if length($blist) > $maxlen;
73 "DELETE FROM UserPrefs WHERE pmail = $qu AND (Name = 'WL' OR Name = 'BL');" .
74 "INSERT INTO UserPrefs (PMail, Name, Data, MTime) " .
75 "VALUES ($qu, 'BL', $blist, EXTRACT (EPOCH FROM now()));" .
76 "INSERT INTO UserPrefs (PMail, Name, Data, MTime) " .
77 "VALUES ($qu, 'WL', $wlist, EXTRACT (EPOCH FROM now()));");
80 my $values = [ keys %{$list->{$name}} ];
85 sub deliver_quarantined_mail
{
86 my ($dbh, $ref, $targets) = @_;
88 my $filename = $ref->{file
};
89 my $spooldir = $PMG::MailQueue
::spooldir
;
90 my $path = "$spooldir/$filename";
92 my $id = 'C' . $ref->{cid
} . 'R' . $ref->{rid
};
94 my $sender = 'postmaster'; # notify postmaster if something fails
99 my $smtp = Net
::SMTP-
>new ('127.0.0.1', Port
=> 10025, Hello
=> 'quarantine') ||
100 die "unable to connect to localhost at port 10025\n";
104 if (!$smtp->mail($sender)) {
105 die sprintf("smtp from error - got: %s %s\n", $smtp->code, $smtp->message);
108 if (!$smtp->to (@$targets)) {
109 die sprintf("smtp to error - got: %s %s\n", $smtp->code, $smtp->message);
116 open(my $fh, '<', $path) || die "unable to open file '$path' - $!\n";
118 while (defined(my $line = <$fh>)) {
120 if ($header && ($line =~ m/^\s*$/)) {
124 # skip Delivered-To and Return-Path (avoid problem with postfix
125 # forwarding loop detection (man local))
126 next if ($header && (($line =~ m/^Delivered-To:/i) || ($line =~ m/^Return-Path:/i)));
128 # rfc821 requires this
129 $line =~ s/^\./\.\./mg;
130 $smtp->datasend("$line\n");
134 if ($smtp->dataend()) {
135 my (@msgs) = $smtp->message;
136 my ($last_msg) = $msgs[$#msgs];
137 ($resid) = $last_msg =~ m/Ok: queued as ([0-9A-Z]+)/;
139 die sprintf("smtp error - got: %s %s\n", $smtp->code, $smtp->message);
142 die sprintf("sending data failed - got: %s %s\n", $smtp->code, $smtp->message);
145 my $sth = $dbh->prepare(
146 "UPDATE CMSReceivers SET Status='D', MTime = ? " .
147 "WHERE CMailStore_CID = ? AND CMailStore_RID = ? AND PMail = ?");
148 $sth->execute(time(), $ref->{cid
}, $ref->{rid
}, $ref->{pmail
});
153 $smtp->quit if $smtp;
156 my $msg = "deliver quarantined mail '$id' ($path) failed: $err";
161 syslog
('info', "delivered quarantined mail '$id' ($path)");
166 sub delete_quarantined_mail
{
167 my ($dbh, $ref) = @_;
169 my $filename = $ref->{file
};
170 my $spooldir = $PMG::MailQueue
::spooldir
;
171 my $path = "$spooldir/$filename";
173 my $id = 'C' . $ref->{cid
} . 'R' . $ref->{rid
};
176 my $sth = $dbh->prepare(
177 "UPDATE CMSReceivers SET Status='D', MTime = ? WHERE " .
178 "CMailStore_CID = ? AND CMailStore_RID = ? AND PMail = ?");
179 $sth->execute (time(), $ref->{cid
}, $ref->{rid
}, $ref->{pmail
});
183 my $msg = "delete quarantined mail '$id' ($path) failed: $err";
184 syslog
('err', $msg);
188 syslog
('info', "marked quarantined mail '$id' as deleted ($path)");