clamav support for mailscanner (patch)

Adrian Bridgett adrian at SMOP.CO.UK
Thu Sep 19 19:50:20 IST 2002


Here's a basic parser for clamav (clamav.elektrapro.com).  I've unit tested
it with zip archives only (no rar archives etc).  Maybe "TryOneCommercial"
should be renamed ;-)

I havn't actually started using mailscanner yet (I'm about to swap from
amavisd-new having seen the source code <g>), so this is definitely not
tested in production.

Hope this is useful for someone - patch attached is against 3.22.13-1
(debian package), but should apply pretty cleanly (the diff against 3.13
just failed on one offset).

I must say, I'm not a great fan of the InitParser/ProcessOutput stuff - any
particular reason why it was done this way (calling it a line at a time -
you could pass it a file desciptor)?

Adrian

Email: adrian at smop.co.uk
Windows NT - Unix in beta-testing. GPG/PGP keys available on public key servers
Debian GNU/Linux  -*-  By professionals for professionals  -*-  www.debian.org
-------------- next part --------------
diff -ru 3.22.orig/etc/mailscanner/mailscanner.conf 3.22/etc/mailscanner/mailscanner.conf
--- 3.22.orig/etc/mailscanner/mailscanner.conf  2002-09-11 23:51:48.000000000 +0100
+++ 3.22/etc/mailscanner/mailscanner.conf       2002-09-18 22:22:37.000000000 +0100
@@ -119,6 +119,7 @@
 # panda     from www.pandasoftware.com, or
 # rav       from www.ravantivirus.com, or
 # antivir   from www.antivir.de, or
+# clamav    from clamav.elektrapro.com or
 # none
 #
 # Note: If you want to use multiple virus scanners, then this should be a
Only in 3.22/etc/mailscanner: mailscanner.conf~
Only in 3.22/etc/mailscanner/wrapper: clamavwrapper
diff -ru 3.22.orig/usr/share/mailscanner/sweep.pl 3.22/usr/share/mailscanner/sweep.pl
--- 3.22.orig/usr/share/mailscanner/sweep.pl    2002-09-10 09:01:02.000000000 +0100
+++ 3.22/usr/share/mailscanner/sweep.pl 2002-09-18 22:21:41.000000000 +0100
@@ -173,6 +173,16 @@
     SupportScanning    => $S_UNSUPPORTED,
     SupportDisinfect   => $S_UNSUPPORTED,
   },
+  clamav              => {
+    Lock              => 'ClamAV.lock',
+    CommonOptions     => '-r --disable-summary --stdout',
+    DisinfectOptions  => '',
+    ScanOptions               => '',
+    InitParser                => \&InitClamAVParser,
+    ProcessOutput     => \&ProcessClamAVOutput,
+    SupportScanning   => $S_BETA,
+    SupportDisinfect  => $S_NONE,
+  },
   "none"               => {
     Lock               => 'NoneBusy.lock',
     CommonOptions      => '',
@@ -507,6 +517,13 @@
   ;
 }

+# Initialise any state variables the ClamAV output parser uses
+my ($clamav_archive);
+sub InitClamAVParser {
+  $clamav_archive = "";
+}
+
+
 # These functions must be called with, in order:
 # * The line of output from the scanner
 # * A reference to the hash containing problem details
@@ -1022,6 +1039,63 @@
   return 0;
 }

+# Process ClamAV (v0.22) output
+sub ProcessClamAVOutput {
+  my($line, $infections, $types, $BaseDir) = @_;
+
+  if ($line =~ /^ERROR:/ or $line =~ /^execv\(p\):/)
+  {
+    chomp $line;
+    Log::WarnLog($line);
+    return 0;
+  }
+
+  # clamscan currently stops as soon as one virus is found
+  # therefore there is little point saying which part
+  # it's still a start mind!
+
+  # Only tested with --unzip since only windows boxes get viruses ;-)
+
+  if (/^Archive:  (.*)$/)
+  {
+    $clamav_archive = $1;
+    return 0;
+  }
+  return 0 if /^  /;  # "  inflating", "  deflating.." from --unzip
+  if ($clamav_archive && /^$clamav_archive:/)
+  {
+    $clamav_archive = "";
+    return 0;
+  }
+
+  return 0 if /OK$/;
+
+  if (/^(.*?): (.*) FOUND$/)
+  {
+     my ($id, $part, $virus);
+     $virus = $2;
+     if ($clamav_archive)
+     {
+        $id = $clamav_archive;
+       ($part = $1) =~ s/^.*\///;  # get basename of file
+     }
+     else
+     {
+        $id = $1;
+        $part = "";
+     }
+     $id =~ s/$BaseDir\///;
+
+    $infections->{"$id"}{"$part"} .= "contains $virus\n";
+    $types->{"$id"}{"$part"} .= "v";
+    return 1;
+  }
+
+  chomp $line;
+  Log::WarnLog("ProcessClamAVOutput: unrecognised line \"$line\"");
+  return 0;
+}
+

 sub CallOwnChecking {
   my($BaseDir, $mime, $infections, $inftypes) = @_;


More information about the MailScanner mailing list