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