X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=scripts%2Fspamscan-sa;h=3f6c26f490a650d8c7f6747febb9ef850194f2ce;hb=867420593c939cf9585bd42f558778ad598076b9;hp=3ee76826793958d5d50f693797d48b152806cbe1;hpb=0bfbbcbc2bdbc9b888a8d8e90f11f724834df5a1;p=debbugs.git diff --git a/scripts/spamscan-sa b/scripts/spamscan-sa index 3ee7682..3f6c26f 100755 --- a/scripts/spamscan-sa +++ b/scripts/spamscan-sa @@ -4,18 +4,16 @@ # unfortunatly we can't use strict; -use lib qw(/usr/lib/debbugs); +use warnings; +use strict; use Mail::CrossAssassin; - use Mail::SpamAssassin; -use Mail::SpamAssassin::NoMailAudit; -my $config_path = '/etc/debbugs'; -require "$config_path/config"; +use Debbugs::Config qw(:config); # New versions of debbugs will not allow use in /etc/debbugs/config use POSIX qw(strftime); -$gSpamMailbox = strftime($gSpamMailbox,gmtime); -$gCrossMailbox = strftime($gCrossMailbox,gmtime); +my $spam_mailbox = strftime($config{spam_mailbox},gmtime); +my $cross_mailbox = strftime($config{spam_crossassassin_mailbox},gmtime); umask 002; $| = 1; @@ -26,130 +24,123 @@ sub header_or_empty ($$) { my $value = $mail->get_header($hdr); if (defined $value) { chomp $value; - $value =~ tr/\n/\\n/; + # replace newlines with '\n' + $value =~ s/\n/\\n/g; return $value; } return ''; } -my $user_prefs = "$ENV{HOME}/.spamassassin/user_prefs"; - my $spam = Mail::SpamAssassin->new({ dont_copy_prefs => 1, - site_rules_filename => $gSpamRulesDir, - userprefs_filename => $user_prefs, - local_tests_only => ($gSpamLocalTestsOnly || 0), + site_rules_filename => $config{spam_rules_dir}, + userprefs_filename => $config{spam_user_prefs}, + local_tests_only => ($config{spam_local_tests_only} || 0), debug => ($ENV{DEBBUGS_SPAM_DEBUG} || 0), }); $spam->compile_now(1); # use all user preferences - while (my $id = ) { - chomp $id; - my $nf = or die "Could not read nf: $!"; - chomp $nf; - unless (rename "incoming/S$id", "incoming/R$id") { - die "Could not rename incoming/S$id: $!"; - } - my $out = "[$nf] $id scanning ...\n"; - open MESSAGE, "< incoming/R$id" or die "open incoming/R$id: $!"; - my @textarray; - # Kludge to work around Received: then From_ weirdness in receive; - # remove when receive is fixed? We may continue to need it for - # reprocessing old messages. - $textarray[0] = ; - if ($textarray[0] =~ /^Received:/) { - my $maybefrom = ; - if ($maybefrom =~ /^From /) { - $textarray[1] = $textarray[0]; - $textarray[0] = $maybefrom; - } else { - $textarray[1] = $maybefrom; - } - } - push @textarray, ; - close MESSAGE; - my $mail = Mail::SpamAssassin::NoMailAudit->new(data => \@textarray); - $mail->{noexit} = 1; - - my $messageid = header_or_empty($mail, 'Message-Id'); - $out .= " From: " . header_or_empty($mail, 'From') . "\n"; - $out .= " Subject: ". header_or_empty($mail, 'Subject') . "\n"; - $out .= " Date: " . header_or_empty($mail, 'Date') . "\n"; - $out .= " Message-Id: $messageid\n"; - my $keys = ca_keys($mail->get_body); - print "$keys\n$messageid\n" - or die "Could not send keys: $!"; - my $ca_score = or die "Could not read ca_score: $!"; - chomp $ca_score; - my $todo = 0; - my $seen = or die "Child could not read seen: $!"; - chomp $seen; - my $status; - my $nseen = $seen; - if ($seen) { - $todo = 1; - $out .= " spam $seen duplicate\n"; - } else { - $status = $spam->check($mail); - $status->rewrite_mail(); - - if ($status->is_spam()) { -# $mail->accept($gSpamMailbox); -# unlink "incoming/R$id" or warn "unlink incoming/R$id: $!"; - $todo = 1; - my $score = sprintf "%.1f/%.1f %d", - $status->get_hits(), $status->get_required_hits(), - $ca_score; - $out .= " spam $score\n"; - $nseen = $score; - } elsif ($status->get_hits() > 0 && $ca_score >= $gMaxCross) { -# $mail->accept($gCrossMailbox); -# unlink "incoming/R$id" or warn "unlink incoming/R$id: $!"; - $todo = 2; - my $score = sprintf "%.1f/%.1f %d", - $status->get_hits(), $status->get_required_hits(), $ca_score; - $out .= " spam $score\n"; - $nseen = $score; - } else { - open OUT, "> incoming/I$id" or die "open incoming/I$id: $!"; - my @headers = $mail->get_all_headers(); - if ($headers[0] =~ /^From /) { - my $from = $headers[0]; - $headers[0] = $headers[1]; - $headers[1] = $from; - } - print OUT join '', @headers or die "print incoming/I$id: $!"; - if ($ca_score > 1) { - print OUT "X-CrossAssassin-Score: $ca_score\n" - or die "print incoming/I$id: $!"; - } - print OUT "\n" or die "print incoming/I$id: $!"; - print OUT @{$mail->get_body()} or die "print incoming/I$id: $!"; - close OUT or die "close incoming/I$id: $!"; - unlink "incoming/R$id" or warn "unlink incoming/R$id: $!"; - $out .= sprintf " ok %.1f/%.1f %d\n", - $status->get_hits(), $status->get_required_hits(), - $ca_score; - } - } - print "$todo\n"; - my $x = ; - if ($todo) { - open OUT, '>>', ($todo == 1) ? $gSpamMailbox : $gCrossMailbox - or die "Could not open assassinated: $!"; - my @headers = $mail->get_all_headers(); - print OUT @headers - or die "print assassinated: $!"; - print OUT "\n" - or die "print assassinated: $!"; - foreach (@{$mail->get_body()}) { - s/^From />From /; - print OUT $_ - or die "print assassinated: $!"; - } - close OUT or die "Close assassinated: $!"; +while (my $id = ) { + chomp $id; + my $nf = ; + if (not defined $nf) { + die "Could not read nf: $!"; + } + chomp $nf; + unless (rename "incoming/S$id", "incoming/R$id") { + die "Could not rename incoming/S$id: $!"; + } + my $out = "[$nf] $id scanning ...\n"; + open MESSAGE, "< incoming/R$id" or die "open incoming/R$id: $!"; + # Kludge to work around Received: then From_ weirdness in receive; + # remove when receive is fixed? We may continue to need it for + # reprocessing old messages. + my @textarray = ; + if ($textarray[0] !~ /^From /) { + ($textarray[0], $textarray[1]) = ($textarray[1], $textarray[0]); + } + close MESSAGE; + my $mail = $spam->parse(\@textarray); + + my $messageid = header_or_empty($mail, 'Message-Id'); + $out .= " From: " . header_or_empty($mail, 'From') . "\n"; + $out .= " Subject: ". header_or_empty($mail, 'Subject') . "\n"; + $out .= " Date: " . header_or_empty($mail, 'Date') . "\n"; + $out .= " Message-Id: $messageid\n"; + my $keys = ca_keys($mail->get_body); + print "$keys\n$messageid\n" + or die "Could not send keys: $!"; + my $ca_score = ; + die "Could not read ca_score: $!" if not defined $ca_score; + chomp $ca_score; + my $todo = 0; + my ($headers, $body); + my $seen = ; + die "Child could not read seen: $!" if not defined $seen; + chomp $seen; + my $status; + my $nseen = $seen; + if ($seen) { + $todo = 1; + $headers = join('',$mail->get_all_headers()); + $body = join('', @{$mail->get_body()}); + $out .= " spam $seen duplicate\n"; + } else { + $status = $spam->check($mail); + ($headers, $body) = split /\n\n/, $status->rewrite_mail(), 2; + $headers .= "\n"; + $body .= "\n"; + + if ($status->is_spam()) { + $todo = 1; + my $score = sprintf "%.1f/%.1f %d", + $status->get_score(), $status->get_required_score(), + $ca_score; + $out .= " spam $score\n"; + $nseen = $score; + } elsif ($status->get_score() > 0 && $ca_score >= $config{spam_max_cross}) { + $todo = 2; + my $score = sprintf "%.1f/%.1f %d", + $status->get_score(), $status->get_required_score(), $ca_score; + $out .= " spam $score\n"; + $nseen = $score; + } else { + my ($before, $received, $after) = $headers =~ + /(^.*?)(^Received\: \(at .*?\n)(.*$)/ms; + open OUT, "> incoming/I$id" or die "open incoming/I$id: $!"; + print OUT $received . $before . $after + or die "print incoming/I$id: $!"; + if ($ca_score > 1) { + print OUT "X-CrossAssassin-Score: $ca_score\n" + or die "print incoming/I$id: $!"; } - $out =~ tr/\n/\r/; - print "$nseen\n$out\n"; - $status->finish() unless($seen); + print OUT "\n" or die "print incoming/I$id: $!"; + print OUT $body or die "print incoming/I$id: $!"; + close OUT or die "close incoming/I$id: $!"; + unlink "incoming/R$id" or warn "unlink incoming/R$id: $!"; + $out .= sprintf " ok %.1f/%.1f %d\n", + $status->get_score(), $status->get_required_score(), + $ca_score; } + } + print "$todo\n"; + ; + if ($todo) { + open OUT, '>>', ($todo == 1) ? $spam_mailbox : $cross_mailbox + or die "Could not open assassinated: $!"; + print OUT $headers or die "print assassinated: $!"; + if ($ca_score > 1) { + print OUT "X-CrossAssassin-Score: $ca_score\n" + or die "print assassinated: $!"; + } + print OUT "\n" or die "print assassinated: $!"; + $body =~ s/^From />From /gm; + print OUT $body or die "print assassinated: $!"; + close OUT or die "Close assassinated: $!"; + unlink "incoming/R$id" or warn "unlink incoming/R$id: $!"; + } + $out =~ tr/\n/\r/; + print "$nseen\n$out\n"; + $status->finish() unless($seen); + $mail->finish(); +}