2002-11-06 11:54:41 +01:00
|
|
|
#!/usr/bin/perl -w
|
|
|
|
# Clam-AV plugin.
|
|
|
|
|
|
|
|
use File::Temp qw(tempfile);
|
|
|
|
|
|
|
|
sub register {
|
2003-10-08 09:15:51 +02:00
|
|
|
my ($self, $qp, @args) = @_;
|
2002-11-06 11:54:41 +01:00
|
|
|
$self->register_hook("data_post", "clam_scan");
|
2003-10-08 09:15:51 +02:00
|
|
|
|
|
|
|
if (@args > 0) {
|
|
|
|
# Untaint scanner location
|
|
|
|
if ($args[0] =~ /^(\/[\/\-\_\.a-z0-9A-Z]*)$/) {
|
|
|
|
$self->{_clamscan_loc} = $1;
|
|
|
|
} else {
|
2004-03-05 13:46:24 +01:00
|
|
|
$self->log(LOGERROR, "FATAL ERROR: Unexpected characters in clamav argument 1");
|
2003-10-08 09:15:51 +02:00
|
|
|
exit 3;
|
|
|
|
}
|
2004-03-05 13:46:24 +01:00
|
|
|
$self->log(LOGWARN, "WARNING: Ignoring additional arguments.") if (@args > 1);
|
2003-10-08 09:15:51 +02:00
|
|
|
} else {
|
|
|
|
$self->{_clamscan_loc} = "/usr/local/bin/clamscan";
|
|
|
|
}
|
2002-11-06 11:54:41 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
sub clam_scan {
|
|
|
|
my ($self, $transaction) = @_;
|
|
|
|
|
|
|
|
my ($temp_fh, $filename) = tempfile();
|
|
|
|
print $temp_fh $transaction->header->as_string;
|
|
|
|
print $temp_fh "\n";
|
2003-10-08 09:15:51 +02:00
|
|
|
$transaction->body_resetpos;
|
2002-11-06 11:54:41 +01:00
|
|
|
while (my $line = $transaction->body_getline) {
|
|
|
|
print $temp_fh $line;
|
|
|
|
}
|
|
|
|
seek($temp_fh, 0, 0);
|
|
|
|
|
|
|
|
# Now do the actual scanning!
|
2003-10-08 09:15:51 +02:00
|
|
|
my $cmd = $self->{_clamscan_loc}." --stdout -i --max-recursion=50 --disable-summary $filename 2>&1";
|
2004-03-05 13:46:24 +01:00
|
|
|
$self->log(LOGDEBUG, "Running: $cmd");
|
2002-11-06 11:54:41 +01:00
|
|
|
my $output = `$cmd`;
|
|
|
|
|
|
|
|
my $result = ($? >> 8);
|
|
|
|
my $signal = ($? & 127);
|
|
|
|
|
|
|
|
unlink($filename);
|
|
|
|
chomp($output);
|
|
|
|
|
|
|
|
$output =~ s/^.* (.*) FOUND$/$1 /mg;
|
|
|
|
|
2004-03-05 13:46:24 +01:00
|
|
|
$self->log(LOGDEBUG, "clamscan results: $output");
|
2002-11-06 11:54:41 +01:00
|
|
|
|
|
|
|
if ($signal) {
|
2004-03-05 13:46:24 +01:00
|
|
|
$self->log(LOGINFO, "clamscan exited with signal: $signal");
|
2002-11-06 11:54:41 +01:00
|
|
|
return (DECLINED);
|
|
|
|
}
|
|
|
|
if ($result == 1) {
|
2004-03-05 13:46:24 +01:00
|
|
|
$self->log(LOGINFO, "Virus(es) found");
|
2002-11-06 11:54:41 +01:00
|
|
|
# return (DENY, "Virus Found: $output");
|
|
|
|
$transaction->header->add('X-Virus-Found', 'Yes');
|
|
|
|
$transaction->header->add('X-Virus-Details', $output);
|
|
|
|
}
|
|
|
|
elsif ($result) {
|
2004-03-05 13:46:24 +01:00
|
|
|
$self->log(LOGWARN, "ClamAV error: $result\n");
|
2002-11-06 11:54:41 +01:00
|
|
|
}
|
|
|
|
$transaction->header->add('X-Virus-Checked', 'Checked');
|
|
|
|
return (DECLINED);
|
|
|
|
}
|