Gentoo Forums
Gentoo Forums
Gentoo Forums
Quick Search: in
Scan/quarantine viruses in maildirs w/f-prot script
View unanswered posts
View posts from last 24 hours

Reply to topic    Gentoo Forums Forum Index Documentation, Tips & Tricks
View previous topic :: View next topic  
Author Message

Joined: 19 Apr 2002
Posts: 712

PostPosted: Tue Dec 31, 2002 12:51 am    Post subject: Scan/quarantine viruses in maildirs w/f-prot script Reply with quote


the following script is intended for use with maildirs and the f-prot virus scanner. It uses qmail-inject to mail reports although this can easily be changed. I wrote it because I wanted something that would purge infected items from my user's maildirs, quarantine them and mail a nice report.

Be warned: I knocked this together really quickly. There're quite a few dirty hacks in it, not nearly enough sanity checks, not enough comments, use of global variables when I could have made them local with more effort and lots of other things could be done better than they are. I may update it, but then I might not and leave it to you! Having said that, it's worked well enough for me so far and I figured Tips'n'Tricks would be somewhat enriched by it.

On the plus side, a lot of it is configurable. You need to set the vars near the top which control respectively:
  • From address on emailed report
  • Your local domain
  • Administrator's email address (who always gets the report as well as the scanned user)
  • A unix group which is used to determine which users should have their maildirs scanned. You must specify one.
  • Location of your home directories.
  • Maildir naming convention
  • Where you want f-prot to put the scan logs, which the script subsequently parses.
  • Options to pass to f-prot
At the moment it's hardcoded to move any infected mail items into /quarantine/username, and it's not yet smart enough to make the appropriate username directory so you'll have to make them yourself first. Need to change that soon. Anyway, you're all set after that. So here it is:
use strict;

my $infections;
my $files;
my $objects;
my $suspicious;
my $time;
my @infected;
my @report;
my $user;
my @users;
my $lastfilepath;

# Customise here ...
my $returnpath = 'vscan@myserver.local';
my $domain = '';
my $admin = "thedaddy\@$domain";
my $group = 'staffgrp';
my $home = '/home';
my $maildir = '.maildir';
my $logdir = '/root/scripts';
my $foptions = '-archive -packed';

# Get user list from specified group whose mailboxes will be scanned
$_ = `cat /etc/group | grep $group`;
@users = split(/,/, $1);

foreach $user (@users) {
   next if $user eq 'root';
   # For safety's sake
   $infections = 0;
   $files = 0;
   $objects = 0;
   $suspicious = 0;
   $time = '';
   @infected = ( );
   @report = ( );
   $lastfilepath = '';

   # Let's begin
   print "Now scanning mailbox belonging to: $user ...";
   system("f-prot $foptions -report=$logdir/$user.fprot $home/$user/$maildir");
   quarantine($user) if ($infections);

# Open log
sub readlog {
   my $user=$_[0];
        open (LOG, "<$logdir/$user.fprot");
                @report = <LOG>;
        close (LOG);

# Parse report
sub parse {

foreach (@report) {

   # Infection reported?
   if ( m/(\/.+)\->(.+)  Infection: (.+)/ ) {
      my $filepath = $1;
      my $attachment = $2;
      my $infected = $3;

      my $from;
      my $to;
      my $subject;
      my $date;
      my @msg;

      open(EMAIL, "<$filepath") || die "Fatal error while analysing infected message at \"$filepath\"";
         @msg = <EMAIL>;
      close (EMAIL);

         my $n = 0;
         my $nlines = @msg;
         # Determine From, To, Subject
         while (!$from || !$to || !$subject || !$date)  {
            last if $n > $nlines;
            $_ = $msg[$n];
            $from = $1 if ( m/From: (.+)/ );
            $to = $1 if ( m/To: (.+)/ );
            $subject = $1 if ( m/Subject: (.+)/ );
            $date = $1 if ( m/Date: (.+)/ );

      # Blanks?
      (!$from) and $from = "<blank>";
      (!$to) and $to = "<blank>";
      (!$subject) and $subject = "<blank>";
      (!$date) and $date = "<blank>";

      push (@infected, [ $filepath, $attachment, $infected, $date, $from, $to, $subject ]);

   # Number of files scanned
   $files = $1 if ( m/Files: (\d+)/ );
   # Number of infections
   $infections = $1 if ( m/Infected: (\d+)/ );
   # Suspicious files
   $suspicious = $1 if ( m/Suspicious: (\d+)/ );
   # Objects scanned
   $objects = $1 if ( m/Objects scanned: (\d+)/ );
   # Time taken
   $time = $1 if (m/Time: (\d+:\d+)/ );


sub quarantine {
   my $user=$_[0];
   foreach my $record (@infected) {
      my $filepath = $record->[0];
      # Some mail items may have mutiple infected attachments
      # so we next line checks for that
      next if $filepath eq $lastfilepath;
      $lastfilepath = $filepath;
      my $attachment = $record->[1];
      my $infection = $record->[2];
      $filepath=~ m/\/([^\/]+)$/;
      my $file = $1;
      print "Moving $file to quarantine for user: $user\n";
      # Move it
      rename("$filepath", "/quarantine/$user/$file") || die "Fatal error while attempting to quarantine mailitem: \"$filepath\" for user \"$user\"";

sub mailreport {
my $user=$_[0];
my $msg = qq|From: $returnpath
To: $admin
Cc: $user\@$domain
Subject: Maildir scan report for '$user'

This is an automated report generated by the F-Prot anti-virus mailbox scanning script.
Any questions should be directed to your system administrator: $admin.

if ($infections) {
   $msg = $msg . "Mailbox: '$user' was scanned and contained infected items. The infected items have been moved into quarantine.\n";
   $msg = $msg . "A full breakdown follows: \n\n";
} else {
   $msg = $msg . "Mailbox: '$user' was scanned and contained no infected items.\n";
   $msg = $msg . "A full breakdown follows: \n\n";

if ($infections) {
   foreach my $record (@infected) {
   $msg = $msg . "Date: " . $record->[3] . "\n";
   $msg = $msg . "From: " . $record->[4] . "\n";
   $msg = $msg . "To: " . $record->[5] . "\n";
   $msg = $msg . "Subject: " . $record->[6] . "\n";
   $msg = $msg . "Infected Attachment: " . $record->[1] . "\n";
   $msg = $msg . "Infected by: " . $record->[2] . "\n\n";

$msg = $msg . qq|Files scanned: $files
Objects scanned: $objects

$infections and $msg = $msg . "Infected: $infections\n";
$msg = $msg . qq|Suspicious objects: $suspicious
Scan time: $time|;

system ("echo \"$msg\" | /var/qmail/bin/qmail-inject");
Back to top
View user's profile Send private message
Display posts from previous:   
Reply to topic    Gentoo Forums Forum Index Documentation, Tips & Tricks All times are GMT
Page 1 of 1

Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum