]> git.proxmox.com Git - pmg-api.git/commitdiff
truncate large mails before passing them to spamassassin
authorDietmar Maurer <dietmar@proxmox.com>
Fri, 29 Dec 2017 11:14:43 +0000 (12:14 +0100)
committerDietmar Maurer <dietmar@proxmox.com>
Fri, 29 Dec 2017 11:14:43 +0000 (12:14 +0100)
So we always analyze the first part of large mails.

PMG/RuleDB/Spam.pm

index 53f2e636c78b0a8f74d598efca22a14f8baf0db4..8545b62cfdb4e54d1f9bd9003f6315bb87172800 100644 (file)
@@ -362,9 +362,7 @@ sub analyze_spam {
     my $spamtest = $queue->{sa};
 
     # only run SA in testmode or when clamav_heuristic did not confirm spam (score < 5)
-    # do not run SA if mail is too large
-    if (($queue->{bytes} <= $maxspamsize) && 
-       ($msginfo->{testmode} || ($sa_score < 5))) {
+    if ($msginfo->{testmode} || ($sa_score < 5)) {
 
        # save and disable alarm (SA forgets to clear alarm in some cases) 
        my $previous_alarm = alarm (0);
@@ -372,15 +370,33 @@ sub analyze_spam {
        my $pid = $$;
 
        eval {
-           $queue->{fh}->seek (0, 0);
+           $queue->{fh}->seek(0, 0);
+
+           # Truncate message to $maxspamsize
+           # Note: similar code to read content is used inside
+           # Mail::SpamAssassin::Message->new()
+           my $nread;
+           my $raw_str = '';
+           while ($nread = sysread($queue->{fh}, $raw_str, 16384, length($raw_str))) {
+               last if length($raw_str) >= $maxspamsize;
+           }
+           defined($nread) || die "error reading message: $!\n";
+
+           my $suppl_attrib = {};
+           if (length($raw_str) >= $maxspamsize &&
+               length($raw_str) < $queue->{bytes}) {
+               $suppl_attrib->{body_size} = $queue->{bytes};
+           }
+
+           my @message = split(/^/m, $raw_str, -1);
+           undef $raw_str; # free memory early
 
-           *SATMP = \*{$queue->{fh}};
-           my $mail = $spamtest->parse(\*SATMP);
+           my $mail = $spamtest->parse(\@message, 0, $suppl_attrib);
 
            # hack: pass envelope sender to spamassassin
            $mail->header('X-Proxmox-Envelope-From', $queue->{from});
 
-           my $status = $spamtest->check ($mail);
+           my $status = $spamtest->check($mail);
 
            #my $fromhash = { $queue->{from} => 1 }; 
            #foreach my $f ($status->all_from_addrs()) {