From past discussion on this list, it was discussed "how easy" it would 
be to throw together a script to check validity before putting a message 
into production.  But I don't recall anyone ever actually offering up 
their script.   Earlier today, someone had posted something to the 
SpamAssassin list that showed they weren't properly handling downloaded 
signature databases, and it just so happens that I just got around to 
writing such a script the other day.

So I thought I'd post it here for review/criticism/distribution.

One note: the reason I use the %destdirs hash, even though they're all 
the same destination, is that I plan in the future to use multiple 
instances of Mail::ClamAV running from different directories, each with 
a different source of signatures.  Right now it's 1 clamd running with 
all of the sigs, though, so it's all 1 destination.


Also, be careful of line wraps caused by email... I'll try to put this 
up on a web page in the nearish future.


    -------


Here's the script I use for importing from MSRBL and Sanesecurity.  I
run it out of cron with -all, on the hour.  You'll probably need to
modify some bits of the first few lines (down to the rsync binary location):

#!/usr/local/bin/perl

my $chmod = "/bin/chmod";
my $mv = "/bin/mv";
my $gunzip = "/usr/bin/gunzip";
my $clamscan = "/usr/local/bin/clamscan";
my $testfile = "/bin/sh";
my $diff = "/usr/bin/diff";

my %methods =
    ("http"  => "/usr/local/bin/wget -q",
     "rsync" => "/usr/bin/rsync -q");

my %urls =
    ("msrbl-spam" => "rsync://rsync.mirror.msrbl.com/msrbl/MSRBL-SPAM.ndb",
     "msrbl-imgs" =>
"rsync://rsync.mirror.msrbl.com/msrbl/MSRBL-Images.hdb",
     "sane-phish" =>
"http://www.sanesecurity.com/clamav/phishsigs/phish.ndb.gz";,
     "sane-scam"  =>
"http://www.sanesecurity.com/clamav/scamsigs/scam.ndb.gz";);

my %tmpdirs =
    ("msrbl-spam" => "/tmp/msrbl",
     "msrbl-imgs" => "/tmp/msrbl",
     "sane-phish" => "/tmp/sanecomputing",
     "sane-scam"  => "/tmp/sanecomputing");


my %destdirs =
    ("msrbl-spam" => "/var/lib/clamav",
     "msrbl-imgs" => "/var/lib/clamav",
     "sane-phish" => "/var/lib/clamav",
     "sane-scam"  => "/var/lib/clamav");


my $getall = 0;
my (@distros, $dist, $tmpdir, $proto, $method, $file, $retcode);
my ($ufile, $diffout, $destdir);

if ($ARGV[0] =~ "--?al?l?") {
    $getall = 1;
    @distros = keys(%urls);
    }
else {
    @distros = @ARGV;
    }

foreach $dist (sort (@distros)) {
    $tmpdir = $tmpdirs{$dist};
    $destdir = $destdirs{$dist};
    $url = $urls{$dist};
    $proto = $url; $proto =~ s/:.*$//;
    $method = $methods{$proto};
    $file = $url; $file =~ s"^.*/([^/]*)$"$1";
    $ufile = $file; $ufile =~ s/\.gz$//;

    if ((-e $tmpdir) && (!(-d $tmpdir))) {
       rename ($tmpdir, ($tmpdir . ".bad"))
          || die "tmpdir $tmpdir isn't a directory, can't rename it";
       mkdir ($tmpdir) || die "can't make tmpdir $tmpdir";
       }
    elsif (! (-e $tmpdir)) {
       mkdir ($tmpdir) || die "can't make tmpdir $tmpdir";
       }
    system ("$chmod 700 $tmpdir");

    if ((-e $destdir) && (!(-d $destdir))) {
       rename ($destdir, ($destdir . ".bad"))
          || die "destdir $destdir isn't a directory, can't rename it";
       mkdir ($destdir) || die "can't make destdir $destdir";
       }
    elsif (! (-e $destdir)) {
       mkdir ($destdir) || die "can't make destdir $tmpdir";
       }
    system ("$chmod 775 $destdir");

    chdir ($tmpdir);

    if (-e $file) {
       unlink ($file);
       }

    if (-e $ufile) {
       unlink ($ufile);
       }

    # download the file
    if ($proto eq "rsync") {
       system("$method $url $file");
       }
    elsif ($proto eq "http") {
       system("$method $url");
       }

    unless (-e $file) {
       print "   didn't get download file $file\n";
       last;
       }

    if ($file =~ /\.gz$/) {
       system("$gunzip $file");
       $file = $ufile;
       }

    # test against clamav
    $retcode =
       system("$clamscan --database=$tmpdir $testfile > /dev/null 2>&1")
/ 256;

    if ($retcode == 0) {
       # clamscan of testfile worked and didn't find a virus
       # lets see if it's the same file we already have/had
       $diffout = (system("$diff --brief --speed-large-files
$tmpdir/$file $destdir/$file > /dev/null 2>/dev/null")) / 256;
       if ($diffout == 0) {
          # file hasn't changed
          unlink ($file);
          }
       else {
          print "   $file appears to have changed, moving to destination\n";
          system("$mv $tmpdir/$file $destdir/$file");
          system("$chmod 644 $destdir/$file");
          }
       }
    elsif ($retcode == 1) {
       print "   found a virus in $testfile while testing $dist\n";
       }
    else {
       print "   new $dist download appears to be corrupt\n";
       }
    }
_______________________________________________
Help us build a comprehensive ClamAV guide: visit http://wiki.clamav.net
http://lurker.clamav.net/list/clamav-users.html

Reply via email to