qpsmtpd/plugins/virus/bitdefender

133 lines
3.0 KiB
Plaintext
Raw Normal View History

#!perl -Tw
=head1 NAME
bitdefender -- BitDefender Linux Edition antivirus plugin for qpsmtpd
=head1 DESCRIPTION
This plugin scans incoming mail with the BitDefender Linux Edition scanner,
and can at your option reject or flag infected messages.
=head1 CONFIGURATION
=over 4
=item B<bitdefender_location>
Full path to the BitDefender binary and all signature files; defaults to
/opt/bdc/bdc.
=item B<deny_viruses>
Whether the scanner will automatically delete messages which have viruses.
Takes either 'yes' or 'no' (defaults to 'yes').
=item B<max_size>
Maximum size in kilobytes for messages which will be scanned; defaults to 128k;
=back
=head1 DEPENDENCIES
=over 4
=item B<BitDefender>
The BitDefender Linux Edition is available to use, free of charge, from
this link:
<http://www.bitdefender.com/bd/site/products.php?p_id=16>
Please read the documentation for configuring automatic updates of the
virus profiles.
=back
=head1 AUTHOR
John Peacock <jpeacock@cpan.org>
=head1 COPYRIGHT AND LICENSE
Copyright (c) 2004 John Peacock
Based lightly 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
use strict;
use warnings;
POD corrections, additional tests, plugin consistency on files in plugins dir: fixed a number of POD errors formatted some # comments into POD removed bare 1; (these are plugins, not perl modules) most instances of this were copy/pasted from a previous plugin that had it removed instances of # vim ts=N ... they weren't consistent, many didn't match .perltidyrc on modules that failed perl -c tests, added 'use Qpsmtpd::Constants;' Conflicts: plugins/async/check_earlytalker plugins/async/dns_whitelist_soft plugins/async/dnsbl plugins/async/queue/smtp-forward plugins/async/require_resolvable_fromhost plugins/async/rhsbl plugins/async/uribl plugins/auth/auth_checkpassword plugins/auth/auth_cvm_unix_local plugins/auth/auth_flat_file plugins/auth/auth_ldap_bind plugins/auth/auth_vpopmail plugins/auth/auth_vpopmail_sql plugins/auth/authdeny plugins/check_badmailfromto plugins/check_badrcptto_patterns plugins/check_bogus_bounce plugins/check_earlytalker plugins/check_norelay plugins/check_spamhelo plugins/connection_time plugins/dns_whitelist_soft plugins/dnsbl plugins/domainkeys plugins/greylisting plugins/hosts_allow plugins/http_config plugins/logging/adaptive plugins/logging/apache plugins/logging/connection_id plugins/logging/transaction_id plugins/logging/warn plugins/milter plugins/queue/exim-bsmtp plugins/queue/maildir plugins/queue/postfix-queue plugins/queue/smtp-forward plugins/quit_fortune plugins/random_error plugins/rcpt_map plugins/rcpt_regexp plugins/relay_only plugins/require_resolvable_fromhost plugins/rhsbl plugins/sender_permitted_from plugins/spamassassin plugins/tls plugins/tls_cert plugins/uribl plugins/virus/aveclient plugins/virus/bitdefender plugins/virus/clamav plugins/virus/clamdscan plugins/virus/hbedv plugins/virus/kavscanner plugins/virus/klez_filter plugins/virus/sophie plugins/virus/uvscan
2012-04-08 02:11:16 +02:00
use File::Path;
use Qpsmtpd::Constants;
sub register {
my ( $self, $qp, @args ) = @_;
while (@args) {
$self->{"_bitd"}->{ pop @args } = pop @args;
}
$self->{"_bitd"}->{"bitdefender_location"} ||= "/opt/bdc/bdc";
$self->{"_bitd"}->{"deny_viruses"} ||= "yes";
$self->{"_bitd"}->{"max_size"} ||= 128;
$self->{"_bitd"}->{"max_size"} *= 1024;
}
sub hook_data_post {
my ( $self, $transaction ) = @_;
if ( $transaction->data_size > $self->{"_bitd"}->{"max_size"} ) {
$self->log( LOGWARN,
'Mail too large to scan ('
. $transaction->data_size . " vs "
. $self->{"_bitd"}->{"max_size"}
. ")" );
return (DECLINED);
}
# Ignore non-multipart emails
my $content_type = $transaction->header->get('Content-Type');
$content_type =~ s/\s/ /g if defined $content_type;
unless ( $content_type
&& $content_type =~ m!\bmultipart/.*\bboundary="?([^"]+)!i )
{
$self->log( LOGERROR, "non-multipart mail - skipping" );
return DECLINED;
}
my $filename = $transaction->body_filename;
unless (defined $filename) {
$self->log(LOGERROR, "didn't get a filename");
return DECLINED;
}
# Now do the actual scanning!
open my $bdc, "-|",
$self->{"_bitd"}->{"bitdefender_location"}
. " --mail --all --arc $filename";
my $output;
while (<$bdc>) {
if (/infected: (.+)$/) {
$output = $1;
last;
}
}
close $bdc;
if ($output) {
$self->log( LOGINFO, "Virus(es) found: $output" );
if ( $self->{"_bitd"}->{"deny_viruses"} eq "yes" ) {
return ( DENY, "Virus Found: $output" );
}
}
return (DECLINED);
}