cvs commit: qpsmtpd/plugins/virus uvscan

[email protected] (John Peacock)
Newsgroups perl.cvs.qpsmtpd
Message-ID <[email protected]>
cvsuser     04/07/16 13:23:17

  Modified:    .        Changes
  Added:       plugins/virus uvscan
  Log:
  Add "plugin/virus/uvscan" - McAfee commandline virus scanner
  
  Revision  Changes    Path
  1.70      +2 -0      qpsmtpd/Changes
  
  Index: Changes
  ===================================================================
  RCS file: /cvs/public/qpsmtpd/Changes,v
  retrieving revision 1.69
  retrieving revision 1.70
  diff -u -w -r1.69 -r1.70
  --- Changes	14 Jul 2004 23:58:47 -0000	1.69
  +++ Changes	16 Jul 2004 20:23:17 -0000	1.70
  @@ -5,6 +5,8 @@
     Mail::Address does RFC822 addresses, we need SMTP addresses.
     Replace Mail::Address with Peter J. Holzer's Qpsmtpd::Address module.
   
  +  Add "plugin/virus/uvscan" - McAfee commandline virus scanner
  +
   
   0.28 - 2004/06/05
   
  
  
  
  1.1                  qpsmtpd/plugins/virus/uvscan
  
  Index: uvscan
  ===================================================================
  #!/usr/bin/perl -w
  =head1 NAME
  
  uvscan
  
  =head1 DESCRIPTION
  
  A qpsmtpd plugin for the McAfee commandline virus scanner, uvscan.
  
  =head1 INSTALL AND CONFIG
  
  Place this plugin in the plugin/virus directory beneath the standard
  qpsmtpd installation.  If you installed uvscan with the default path, you
  can use this plugin with default options (nothing specified):
  
  =over 4
  
  =item B<uvscan_location>
  
  Full path to the uvscan binary and all signature files; defaults to
  /usr/local/bin/uvscan.
  
  =item B<deny_viruses>
  
  Whether the scanner will automatically delete messages which have viruses.
  Takes either 'yes' or 'no' (defaults to 'yes').
  
  =back
  
  =head1 AUTHOR
  
  John Peacock <[email protected]>
  
  =head1 COPYRIGHT AND LICENSE
  
  Copyright (c) 2004 John Peacock
  
  Based heavily on the clamav plugin
  
  This plugin is licensed under the same terms as the qpsmtpd package itself.
  Please see the LICENSE file included with qpsmtpd for details.
  
  =cut
  
  sub register {
    my ($self, $qp, @args) = @_;
    $self->register_hook("data_post", "uvscan");
  
    while (@args) {
    	$self->{"_uvscan"}->{pop @args}=pop @args;
    }
    $self->{"_uvscan"}->{"uvscan_location"}||="/usr/local/bin/uvscan";
  }
   
  sub uvscan {
    my ($self, $transaction) = @_;
   
    return (DECLINED)
      if $transaction->body_size > 250_000;
  
    my $filename = $transaction->body_filename;
    return (DECLINED) unless $filename;
   
    # Now do the actual scanning!
    my @cmd =($self->{"_uvscan"}->{"uvscan_location"},
  	'--mime', '--unzip', '--secure', '--noboot',
  	$filename, '2>&1 |');
    $self->log(LOGINFO, "Running: ",join(' ', @cmd));
    open(FILE, join(' ', @cmd)); #perl 5.6 doesn't properly support the pipe
    # mode list form of open, but this is basically the same thing. This form
    # of exec is safe(ish).
    my $output;
    while (<FILE>) { $output.=$_; }
    close FILE;
  
    my $result = ($? >> 8);
    my $signal = ($? & 127);
   
    unlink($filename);
  
    my $virus;
    if ($output && $output =~ m/.*\W+Found (.*)\n/m) {
      $virus=$1;
    }
    if ($output && $output =~ m/password-protected/m) {
      return (DENY, 'We do not accept password-protected zip files!');
    }
  
    if ($signal) {
      $self->log(LOGWARN, "uvscan exited with signal: $signal");
      return (DECLINED);
    }
    if ($result == 2) {
        $self->log(LOGERROR, "Integrity check for a DAT file failed.");
        return (DECLINED);
    } elsif ($result == 6) {
        $self->log(LOGERROR, "A general problem has occurred.");
        return (DECLINED);
    } elsif ($result == 8) {
        $self->log(LOGERROR, "The program could not find a DAT file.");
        return (DECLINED);
    } elsif ($result == 15) {
        $self->log(LOGERROR, "The program self-check failed");
        return (DECLINED);
    } elsif ( $result ) { # all of the possible virus returns
      if ($result == 12) {
        $self->log(LOGERROR, "The program tried to clean a file but failed.");
      } elsif ($result == 13) {
        $self->log(LOGERROR, "One or more virus(es) found");
      } elsif ($result == 19) {
        $self->log(LOGERROR, "Successfully cleaned the file");
      }
  
      if (lc($self->{"_uvscan"}->{"deny_viruses"}) eq "yes") {
         return (DENY, "Virus Found: $virus");
      }
      $transaction->header->add('X-Virus-Found', 'Yes');
      $transaction->header->add('X-Virus-Details', $virus);
      return (DECLINED);
    }
    
    $transaction->header->add('X-Virus-Checked', 'Checked');
    return (DECLINED);
  }
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.