FProtOutput { my($line, $infections, $types, $BaseDir, $Name) = @_; #my($line) = @_; my($report, $infected, $dot, $id, $part, $virus, @rest); my($logout); #print STDERR "$fprot_InCruft $line"; chomp $line; # Look for the "Program version: 4...." line which shows we are running # version 4 and therefore have different headers at the start of the # scan output. if ($fprot_InCruft==-2) { my $version = $1 if $line =~ /program\s+version:\s*([\d.]+)/i; if ($version > 3.12) { $fprot_InCruft -= 1; return 0; } } return 0 if $fprot_InCruft > 0; # Return if we are still in headers # One header paragraph has finished, count it if ($line eq "") { $fprot_InCruft += 1; return 0; } $fprot_InCruft == 0 or return 0; # Prefer s/// to m// as less likely to do unpredictable things. # We hope. # JKF 5+11/1/2002 Make "security risk" and "joke program" lines look like # virus infections for easier parsing. # JKF 25/02/2002 Add all sorts of patterns gleaned from a coredump of F-Prot # JKF 24/07/2002 Reparse the lines to turn them into infection reports $report = $line; $logout = $line; $logout =~ s/%/%%/g; MailScanner::Log::InfoLog($logout); if ($line =~ /(is|could be) a (security risk|virus construction)/) { $line =~ s/(is|could be) a (security risk|virus construction).*$/Infection: /; } if ($line =~ /(is|could be) a mass-mailing worm/) { $line =~ s/(is|could be) a mass-mailing worm.*$/Infection: /; } elsif ($line =~ /(is|could be) a( boot sector)? virus dropper/) { $line =~ s/(is|could be) a( boot sector)? virus dropper.*$/Infection: /; } elsif ($line =~ /(is|could be) a corrupted or intended/) { $line =~ s/(is|could be) a corrupted or intended.*$/Infection: /; } elsif ($line =~ /(is|could be) a (joke|destructive) program/) { $line =~ s/(is|could be) a (joke|destructive) program.*$/Infection: /; } elsif ($line =~ /(is|could be) infected with an unknown virus/) { $line =~ s/(is|could be) infected with an unknown virus.*$/Infection: /; } elsif ($line =~ /contains.*\(non-working\)/) { $line =~ s/contains /Infection: /; } if ($line =~ /\s\sInfection:\s/) { # Get to relevant filename in a reasonably but not # totally robust manner (*impossible* to be totally robust # if we have slashes, spaces and "->" in filenames) $line =~ s/^(.*?)->.+(\s\sInfection:.*)/$1$2/; # strip archive bits if present $line =~ s/^.*(\/.*\/.*)\s\sInfection:([^:]*).*$/$1/ # get to the meat or die trying or MailScanner::Log::DieLog("Dodgy things going on in F-Prot output:\n$report\n"); #print STDERR "**$line\n"; $virus = $2; $virus =~ s/^\s*(\S+).*$/$1/; # 1st word after Infection: is the virus MailScanner::Log::InfoLog("Virus Scanning: F-Prot found virus %s", $virus); ($dot,$id,$part,@rest) = split(/\//, $line); $report = $Name . ': ' . $report if $Name; $infections->{"$id"}{"$part"} .= $report . "\n"; $types->{"$id"}{"$part"} .= "v"; # so we know what to tell sender return 1; } # Have now seen F-Prot produce infection lines without Infection: in them! # Look for W32 in the last word of the line if ($line =~ /W32\/\S+$/) { # Get to relevant filename in a reasonably but not # totally robust manner (*impossible* to be totally robust # if we have slashes, spaces and "->" in filenames) $line =~ s/^(.*?)->.+(\sW32\/\S+)/$1$2/; # strip archive bits if present $line =~ s/^.*(\/.*\/.*)\s(W32\/\S+)$/$1/ # get to the meat or die trying or MailScanner::Log::DieLog("Dodgy things going on in F-Prot output2:\n$report\n"); #print STDERR "**$line\n"; $virus = $2; MailScanner::Log::InfoLog("Virus Scanning: F-Prot found problem %s", $virus); ($dot,$id,$part,@rest) = split(/\//, $line); $report = $Name . ': ' . $report if $Name; $infections->{"$id"}{"$part"} .= $report . "\n"; $types->{"$id"}{"$part"} .= "v"; # so we know what to tell sender return 1; } # Ignore files we couldn't scan as they were encrypted if ($line =~ /\s\sNot scanned \(encrypted\)/ || $line =~ /\s\sNot scanned \(unsupported compression method\)/ || $line =~ /Virus-infected files in archives cannot be deleted\./) { return 0; } MailScanner::Log::WarnLog("Either you've found a bug in MailScanner's F-Prot output parser, or F-Prot's output format has changed! F-Prot said this \"$line\". Please mail the author of MailScanner"); return 0; }