[Mimedefang] Filter configuration help required
Jan-Pieter Cornet
johnpc at xs4all.nl
Thu Mar 15 05:10:00 EDT 2007
On Thu, Mar 15, 2007 at 07:40:11AM +0000, Rob MacGregor wrote:
> I'm looking for advice/examples on how to change MD's configuration so
> that if only one of my AV scanners fails (as in, doesn't work), but
> the other works, the message isn't tempfailed.
>
> The reason? We'll I've just moved from clamav 0.90 to 0.90.1 and I'm
> finding it silently crashing at random intervals. I don't want mail
> delayed while I try and find the cause.
I've been doing that for over a year now. Here's the code:
This is a bit of configuration we have in a separate file
(but just make sure the variables get set, somewhere)
@scanners = (
{"Virus:SOPHIE" => 'sophie'},
{"Virus:FPROTD" => 'fprotd'},
{"Virus:CLAMD" => 'clamd'},
);
$viruses_that_dont_fake_sender_re =
qr{ ^( Joke # jokes and hoaxes
| OF97 # Sophos' office/wordmacro virus naming
| WM97
| [WXO](97|2000)M # ClamAV word/excel/office 97/2000 macro
)\b
| (\b|_)eicar(\b|_) # "eicar" test virus, anywhere, even in _ chars
}xi;
... and here's the part from filter_begin:
my @VirusNames;
my $Suspicious = 0;
SCANNER:
foreach my $scan (@scanners) {
my ($key,$val) = %{$scan};
if ($Features{$key}) {
my $scanner = "message_contains_virus_$val";
no strict 'refs';
my $t0 = [gettimeofday]
if ($virus_timer);
undef $VirusName;
my($code, $category, $action) = &$scanner();
md_syslog('debug', "$MsgID: $key took " .
tv_interval ($t0) . " seconds");
if ($action eq "tempfail") {
md_syslog('warning', "$MsgID: Problem running virus scanner " .
"$key: code=$code, category=$category, action=$action");
$tempfail++;
}
elsif ($category eq "virus") {
if ( ! $VirusName ) {
### no virus name? Likely an f-prot bug... just flag as
### suspicious
md_graphdefang_log($val, "suspicious - no virus name",
$RelayAddr);
$Suspicious++;
next SCANNER;
}
push @VirusNames, $VirusName;
md_graphdefang_log($val, $VirusName, $RelayAddr);
$FoundVirus++;
}
else {
$ScanOK++;
}
}
}
if ( !$ScanOK && !$FoundVirus) {
action_tempfail("No virus scanners found");
}
if ($FoundVirus) {
### @VirusNames might be empty if no scanner set $VirusName itself.
@VirusNames = ("unknown") if !@VirusNames;
my $longvirusname = join('|', @VirusNames);
md_graphdefang_log('virus', $longvirusname, $RelayAddr);
if ( grep { /$viruses_that_dont_fake_sender_re/ } @VirusNames ) {
### it's a virus that does not fake its sender
return action_bounce ("Virus $longvirusname found",
"554", "5.7.1");
}
elsif ( ($FoundVirus+$Suspicious) == 1 and ($ScanOK+$tempfail) > 0 )
{
### only one virusscanner picked it up - tempfail it
return action_tempfail(
"Possibly infected with virus $longvirusname",
"451", "4.7.1");
}
else {
### multiple virus scanners saw it as a virus - discard
return action_discard ();
}
}
else {
md_graphdefang_log('clean', $RelayAddr);
}
__END__
There's a few quirks in that code, but you can of course remove those.
First, F-prot needs a workaround because it has false-positive problems.
The code at the bottom (after the if ($FoundVirus)...) is such that a virus
is only discarded if two or more scanners detect the virus. Otherwise,
we tempfail. Unless it is a virus which is known NOT to fake headers,
in which case we reject it.
--
Jan-Pieter Cornet <johnpc at xs4all.nl>
!! Disclamer: The addressee of this email is not the intended recipient. !!
!! This is only a test of the echelon and data retention systems. Please !!
!! archive this message indefinitely to allow verification of the logs. !!
More information about the MIMEDefang
mailing list