mirror of
https://github.com/MailScanner/v5.git
synced 2024-09-20 07:16:10 +08:00
FET: Add support for the Sophos SAVID Daemon Anti-virus Engine (#481)
This commit is contained in:
parent
707d7d9001
commit
74ed6cde64
|
@ -709,6 +709,7 @@ Virus Scanning = yes
|
||||||
# avastd the daemon version from www.avast.com
|
# avastd the daemon version from www.avast.com
|
||||||
# sophos from www.sophos.com
|
# sophos from www.sophos.com
|
||||||
# sophossavi (also from www.sophos.com, using the SAVI perl module)
|
# sophossavi (also from www.sophos.com, using the SAVI perl module)
|
||||||
|
# savid (also from www.sophos.com, using the SAVID daemon)
|
||||||
# bitdefender from www.bitdefender.com
|
# bitdefender from www.bitdefender.com
|
||||||
# esets from www.eset.com
|
# esets from www.eset.com
|
||||||
# f-secure from www.f-secure.com
|
# f-secure from www.f-secure.com
|
||||||
|
@ -929,6 +930,9 @@ Sophos Lib Dir = /opt/sophos-av/lib
|
||||||
# scanner setting.
|
# scanner setting.
|
||||||
Monitors For Sophos Updates = /opt/sophos-av/lib/sav/*.ide
|
Monitors For Sophos Updates = /opt/sophos-av/lib/sav/*.ide
|
||||||
|
|
||||||
|
# SophosSAVID only: location of the socket
|
||||||
|
SAVID Socket = /var/lib/savdid/savdid.sock
|
||||||
|
|
||||||
#
|
#
|
||||||
# Options specific to ClamAV Anti-Virus
|
# Options specific to ClamAV Anti-Virus
|
||||||
# -------------------------------------
|
# -------------------------------------
|
||||||
|
|
|
@ -447,6 +447,7 @@ MSMailSocketType inet
|
||||||
MSMailSocketDir /var/spool/postfix/public/qmqp
|
MSMailSocketDir /var/spool/postfix/public/qmqp
|
||||||
KseSocket /var/run/kse/kse.sock
|
KseSocket /var/run/kse/kse.sock
|
||||||
FsecureSocket /tmp/.fsav-0
|
FsecureSocket /tmp/.fsav-0
|
||||||
|
SAVIDSocket /var/lib/savdid/savdid.sock
|
||||||
|
|
||||||
#
|
#
|
||||||
# These variables match on any rule matching From:, else anything for To:
|
# These variables match on any rule matching From:, else anything for To:
|
||||||
|
|
|
@ -82,6 +82,17 @@ my %Scanners = (
|
||||||
SupportScanning => $S_SUPPORTED,
|
SupportScanning => $S_SUPPORTED,
|
||||||
SupportDisinfect => $S_NONE,
|
SupportDisinfect => $S_NONE,
|
||||||
},
|
},
|
||||||
|
savid => {
|
||||||
|
Name => 'Sophos',
|
||||||
|
Lock => 'sophosBusy.lock',
|
||||||
|
CommonOptions => '',
|
||||||
|
DisinfectOptions => '',
|
||||||
|
ScanOptions => '',
|
||||||
|
InitParser => \&InitSAVIDParser,
|
||||||
|
ProcessOutput => \&ProcessOutput,
|
||||||
|
SupportScanning => $S_SUPPORTED,
|
||||||
|
SupportDisinfect => $S_NONE,
|
||||||
|
},
|
||||||
sophossavi => {
|
sophossavi => {
|
||||||
Name => 'SophosSAVI',
|
Name => 'SophosSAVI',
|
||||||
Lock => 'sophosBusy.lock',
|
Lock => 'sophosBusy.lock',
|
||||||
|
@ -930,6 +941,9 @@ sub TryOneCommercial {
|
||||||
} elsif ( $scanner eq 'f-secured' ) {
|
} elsif ( $scanner eq 'f-secured' ) {
|
||||||
FsecureScan( $subdir, $disinfect, $batch );
|
FsecureScan( $subdir, $disinfect, $batch );
|
||||||
exit;
|
exit;
|
||||||
|
} elsif ( $scanner eq 'savid' ) {
|
||||||
|
SAVIDScan( $subdir, $disinfect, $batch );
|
||||||
|
exit;
|
||||||
} else {
|
} else {
|
||||||
exec "$sweepcommand $instdir $voptions $subdir";
|
exec "$sweepcommand $instdir $voptions $subdir";
|
||||||
MailScanner::Log::WarnLog("Cannot run commercial AV $scanner " .
|
MailScanner::Log::WarnLog("Cannot run commercial AV $scanner " .
|
||||||
|
@ -1165,6 +1179,13 @@ sub InitGenericParser {
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Initialise any state variables the Sophos SAVID output parser uses
|
||||||
|
my (%SAVIDFiles);
|
||||||
|
|
||||||
|
sub InitSAVIDParser {
|
||||||
|
%SAVIDFiles = ();
|
||||||
|
}
|
||||||
|
|
||||||
# Initialise any state variables the Sophos SAVI output parser uses
|
# Initialise any state variables the Sophos SAVI output parser uses
|
||||||
sub InitSophosSAVIParser {
|
sub InitSophosSAVIParser {
|
||||||
;
|
;
|
||||||
|
@ -2132,6 +2153,18 @@ sub InstalledScanners {
|
||||||
s/^sophos$/sophossavi/i;
|
s/^sophos$/sophossavi/i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if ( SAVIDScan('ISITINSTALLED') eq 'SAVIDOK' ) {
|
||||||
|
# if sophos in list replace with savid
|
||||||
|
my $foundit = 0;
|
||||||
|
foreach (@installed) {
|
||||||
|
if ( $_ eq 'sophos' ) {
|
||||||
|
s/^sophos$/savid/;
|
||||||
|
$foundit = 1;
|
||||||
|
last;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
push @installed, 'savid' unless $foundit;
|
||||||
|
}
|
||||||
if (ClamdScan('ISITINSTALLED') eq 'CLAMDOK') {
|
if (ClamdScan('ISITINSTALLED') eq 'CLAMDOK') {
|
||||||
# If clamav is in the list, replace it with clamd, else add clamd
|
# If clamav is in the list, replace it with clamd, else add clamd
|
||||||
my $foundit = 0;
|
my $foundit = 0;
|
||||||
|
@ -3312,4 +3345,153 @@ sub Fsecured {
|
||||||
$dh->close;
|
$dh->close;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Savid functions
|
||||||
|
|
||||||
|
sub SAVIDScan {
|
||||||
|
my ( $dirname, $disinfect, $messagebatch ) = @_;
|
||||||
|
|
||||||
|
my $lintonly = 0;
|
||||||
|
$lintonly = 1 if $dirname eq 'ISITINSTALLED';
|
||||||
|
|
||||||
|
my $ScanDir = "$global::MS->{work}->{dir}/$dirname";
|
||||||
|
$ScanDir =~ s/\/\.$//;
|
||||||
|
|
||||||
|
my $TimeOut = MailScanner::Config::Value('virusscannertimeout');
|
||||||
|
my $Socket = MailScanner::Config::Value('SAVIDSocket');
|
||||||
|
$Socket = '/var/lib/savdid/savdid.sock' unless ($Socket);
|
||||||
|
my $line = '';
|
||||||
|
my $sock;
|
||||||
|
|
||||||
|
$sock = ConnectToAV( $Socket, undef, $TimeOut );
|
||||||
|
print "ERROR:: COULD NOT CONNECT TO SAVID, RECOMMEND RESTARTING DAEMON "
|
||||||
|
. ":: $dirname\n"
|
||||||
|
unless $sock || $lintonly;
|
||||||
|
print "ScAnNeRfAiLeD\n" unless $sock || $lintonly;
|
||||||
|
MailScanner::Log::WarnLog( "ERROR:: COULD NOT CONNECT TO SAVID, "
|
||||||
|
. "RECOMMEND RESTARTING DAEMON " )
|
||||||
|
unless $sock || $lintonly;
|
||||||
|
return 1 unless $sock;
|
||||||
|
|
||||||
|
# $sock->close if $lintonly;
|
||||||
|
return 'SAVIDOK' if $lintonly;
|
||||||
|
|
||||||
|
%SAVIDFiles = ();
|
||||||
|
|
||||||
|
if ( SAVID( $ScanDir, $sock ) == -1 ) {
|
||||||
|
print "ERROR:: COULD NOT SCAN USING SAVID,"
|
||||||
|
. " RECOMMEND CHECKING DIRECTORY ACCESS "
|
||||||
|
. ":: $dirname\n";
|
||||||
|
print "ScAnNeRfAiLeD\n";
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Read back all the reports
|
||||||
|
foreach my $key ( keys %SAVIDFiles ) {
|
||||||
|
my ($path);
|
||||||
|
|
||||||
|
$path = $key;
|
||||||
|
$path =~ s/^$ScanDir/./;
|
||||||
|
|
||||||
|
if ( $SAVIDFiles{$key}->{error} ) {
|
||||||
|
print "ERROR:: $SAVIDFiles{$key}->{errormsg} :: $path\n";
|
||||||
|
}
|
||||||
|
elsif ( !$SAVIDFiles{$key}->{error} && $SAVIDFiles{$key}->{infected} ) {
|
||||||
|
print "INFECTED:: $SAVIDFiles{$key}->{virusname} :: $path\n";
|
||||||
|
}
|
||||||
|
elsif ($SAVIDFiles{$key}->{clean}
|
||||||
|
&& !$SAVIDFiles{$key}->{error}
|
||||||
|
&& !$SAVIDFiles{$key}->{infected} )
|
||||||
|
{
|
||||||
|
print "CLEAN:: message did not match any signature :: $path\n";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
print "ERROR:: $SAVIDFiles{$key}->{error} :: $path\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$sock->close;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub SAVID {
|
||||||
|
my ( $dir, $sock ) = @_;
|
||||||
|
|
||||||
|
my $dh = new DirHandle $dir;
|
||||||
|
|
||||||
|
unless ($dh) {
|
||||||
|
MailScanner::Log::WarnLog( "SAVID: failed to process directory %s",
|
||||||
|
$dir );
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
my $file;
|
||||||
|
while ( defined( $file = $dh->read ) ) {
|
||||||
|
my $f = "$dir/$file";
|
||||||
|
$f =~ /^(.*)$/;
|
||||||
|
$f = $1;
|
||||||
|
next if $file =~ /^\./ && -d $f;
|
||||||
|
if ( -d $f ) {
|
||||||
|
SAVID( $f, $sock );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
my %response;
|
||||||
|
$response{error} = 0;
|
||||||
|
$response{clean} = 0;
|
||||||
|
$response{infected} = 0;
|
||||||
|
$response{virusname} = '';
|
||||||
|
$response{errormsg} = '';
|
||||||
|
|
||||||
|
# check if we can write to socket
|
||||||
|
unless ( $sock->print("$f\n") ) {
|
||||||
|
$response{errormsg} = "SAVID: failed to scan $f";
|
||||||
|
$response{error} = 1;
|
||||||
|
$SAVIDFiles{$f} = \%response;
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
|
||||||
|
# check if we can flush socket
|
||||||
|
unless ( $sock->flush ) {
|
||||||
|
$response{errormsg} = "SAVID: failed to scan $f";
|
||||||
|
$response{error} = 1;
|
||||||
|
$SAVIDFiles{$f} = \%response;
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
|
||||||
|
# check if we can read the response
|
||||||
|
my ( $scan_response, $rc );
|
||||||
|
my $rc = $sock->sysread( $scan_response, 256 );
|
||||||
|
|
||||||
|
unless ($rc) {
|
||||||
|
$response{error} = 1;
|
||||||
|
$response{errormsg} = "SAVID: no response to scan $f";
|
||||||
|
$SAVIDFiles{$f} = \%response;
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
|
||||||
|
# process the results
|
||||||
|
if ( $scan_response =~ m/^0/ ) {
|
||||||
|
$response{clean} = 1;
|
||||||
|
$response{infected} = 0;
|
||||||
|
}
|
||||||
|
elsif ( $scan_response =~ m/^1/ ) {
|
||||||
|
$response{clean} = 0;
|
||||||
|
$response{infected} = 1;
|
||||||
|
my ($virus_name) = $scan_response =~ /^1:(.*)$/;
|
||||||
|
$response{virusname} = $virus_name;
|
||||||
|
}
|
||||||
|
elsif ( $scan_response =~ m/^-1:(.*)$/ ) {
|
||||||
|
my $error_message = $1;
|
||||||
|
$error_message ||= 'SAVID: unknown error';
|
||||||
|
$response{error} = 1;
|
||||||
|
$response{errormsg} = $error_message;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$response{error} = 1;
|
||||||
|
$response{errormsg} = 'SAVID: unknown response error';
|
||||||
|
}
|
||||||
|
|
||||||
|
$SAVIDFiles{$f} = \%response;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$dh->close;
|
||||||
|
}
|
||||||
|
|
||||||
1;
|
1;
|
||||||
|
|
|
@ -1876,6 +1876,16 @@ Ignored Web Bug Filenames = spacer pixel.gif pixel.png',
|
||||||
scanner setting.',
|
scanner setting.',
|
||||||
'value' => ' /opt/sophos-av/lib/sav/*.ide',
|
'value' => ' /opt/sophos-av/lib/sav/*.ide',
|
||||||
),
|
),
|
||||||
|
'savidsocket' =>
|
||||||
|
array (
|
||||||
|
'external' => 'SAVIDSocket',
|
||||||
|
'type' => 'other',
|
||||||
|
'ruleset' => 'no',
|
||||||
|
'default' => '/var/lib/savdid/savdid.sock',
|
||||||
|
'name' => 'SAVID Socket',
|
||||||
|
'desc' => ' SophosSAVID only: location of the socket',
|
||||||
|
'value' => ' /var/lib/savdid/savdid.sock',
|
||||||
|
),
|
||||||
'mta' =>
|
'mta' =>
|
||||||
array (
|
array (
|
||||||
'external' => 'mta',
|
'external' => 'mta',
|
||||||
|
|
Loading…
Reference in a new issue