Change remaining plugins to use LOGXXXX constants instead of bare numbers.

Change plugins/dnsbl to permit AUTH'd or other relay clients even if IP
is on a blacklist.


git-svn-id: https://svn.perl.org/qpsmtpd/trunk@442 958fd67b-6ff1-0310-b445-bb7760255be9
This commit is contained in:
John Peacock 2005-06-22 14:08:57 +00:00
parent b54c8ec46c
commit 9664eb9469
7 changed files with 38 additions and 34 deletions

View File

@ -37,7 +37,7 @@ sub register {
if (@args > 0) { if (@args > 0) {
$self->{_days} = $args[0]; $self->{_days} = $args[0];
$self->log(1, "WARNING: Ignoring additional arguments.") if (@args > 1); $self->log(LOGWARN, "WARNING: Ignoring additional arguments.") if (@args > 1);
} }
} }

View File

@ -153,24 +153,28 @@ sub process_sockets {
sub rcpt_handler { sub rcpt_handler {
my ($self, $transaction, $rcpt) = @_; my ($self, $transaction, $rcpt) = @_;
my $connection = $self->qp->connection;
# RBLSMTPD being non-empty means it contains the failure message to return # RBLSMTPD being non-empty means it contains the failure message to return
if (defined ($ENV{'RBLSMTPD'}) && $ENV{'RBLSMTPD'} ne '') { if (defined ($ENV{'RBLSMTPD'}) && $ENV{'RBLSMTPD'} ne '') {
my $result = $ENV{'RBLSMTPD'}; my $result = $ENV{'RBLSMTPD'};
my $remote_ip = $self->qp->connection->remote_ip; my $remote_ip = $connection->remote_ip;
$result =~ s/%IP%/$remote_ip/g; $result =~ s/%IP%/$remote_ip/g;
return ($self->{_dnsbl}->{DENY}, return ($self->{_dnsbl}->{DENY},
join(" ", $self->qp->config('dnsbl_rejectmsg'), $result)); join(" ", $self->qp->config('dnsbl_rejectmsg'), $result));
} }
my $note = $self->process_sockets; my $note = $self->process_sockets;
my $whitelist = $self->qp->connection->notes('whitelisthost'); my $whitelist = $connection->notes('whitelisthost');
if ( $note ) { if ( $note ) {
if ( $rcpt->user =~ /^(?:postmaster|abuse|mailer-daemon|root)$/i ) { if ( $rcpt->user =~ /^(?:postmaster|abuse|mailer-daemon|root)$/i ) {
$self->log(2, "Don't blacklist special account: ".$rcpt->user); $self->log(LOGWARN, "Don't blacklist special account: ".$rcpt->user);
} }
elsif ( $whitelist ) { elsif ( $whitelist ) {
$self->log(2, "Whitelist overrode blacklist: $whitelist"); $self->log(LOGWARN, "Whitelist overrode blacklist: $whitelist");
}
elsif ( $connection->relay_client() ) {
$self->log(LOGWARN, "Don't blacklist relay/auth clients");
} }
else { else {
return ($self->{_dnsbl}->{DENY}, $note); return ($self->{_dnsbl}->{DENY}, $note);

View File

@ -129,7 +129,7 @@ sub register {
map { split /\s+/, $_, 2 } $self->qp->config('denysoft_greylist'), map { split /\s+/, $_, 2 } $self->qp->config('denysoft_greylist'),
%arg }; %arg };
if (my @bad = grep { ! exists $ARGS{$_} } sort keys %$config) { if (my @bad = grep { ! exists $ARGS{$_} } sort keys %$config) {
$self->log(1, "invalid parameter(s): " . join(',',@bad)); $self->log(LOGALERT, "invalid parameter(s): " . join(',',@bad));
} }
$self->{_greylist_config} = $config; $self->{_greylist_config} = $config;
unless ($config->{recipient} || $config->{per_recipient}) { unless ($config->{recipient} || $config->{per_recipient}) {
@ -173,7 +173,7 @@ sub data_handler {
return DECLINED unless $note; return DECLINED unless $note;
# Decline if ALL recipients are whitelisted # Decline if ALL recipients are whitelisted
if (($transaction->notes('whitelistrcpt')||0) == scalar($transaction->recipients)) { if (($transaction->notes('whitelistrcpt')||0) == scalar($transaction->recipients)) {
$self->log(4,"all recipients whitelisted - skipping"); $self->log(LOGWARN,"all recipients whitelisted - skipping");
return DECLINED; return DECLINED;
} }
return DENYSOFT, $note; return DENYSOFT, $note;
@ -182,7 +182,7 @@ sub data_handler {
sub denysoft_greylist { sub denysoft_greylist {
my ($self, $transaction, $sender, $rcpt, $config) = @_; my ($self, $transaction, $sender, $rcpt, $config) = @_;
$config ||= $self->{_greylist_config}; $config ||= $self->{_greylist_config};
$self->log(7, "config: " . join(',',map { $_ . '=' . $config->{$_} } sort keys %$config)); $self->log(LOGDEBUG, "config: " . join(',',map { $_ . '=' . $config->{$_} } sort keys %$config));
# Always allow relayclients and whitelisted hosts/senders # Always allow relayclients and whitelisted hosts/senders
return DECLINED if exists $ENV{RELAYCLIENT}; return DECLINED if exists $ENV{RELAYCLIENT};
@ -194,24 +194,24 @@ sub denysoft_greylist {
if $config->{per_recipient_db}; if $config->{per_recipient_db};
$dbdir ||= -d "$QPHOME/var/db" ? "$QPHOME/var/db" : "$QPHOME/config"; $dbdir ||= -d "$QPHOME/var/db" ? "$QPHOME/var/db" : "$QPHOME/config";
my $db = "$dbdir/$DB"; my $db = "$dbdir/$DB";
$self->log(6,"using $db as greylisting database"); $self->log(LOGINFO,"using $db as greylisting database");
my $remote_ip = $self->qp->connection->remote_ip; my $remote_ip = $self->qp->connection->remote_ip;
my $fmt = "%s:%d:%d:%d"; my $fmt = "%s:%d:%d:%d";
# Check denysoft db # Check denysoft db
unless (open LOCK, ">$db.lock") { unless (open LOCK, ">$db.lock") {
$self->log(2, "opening lockfile failed: $!"); $self->log(LOGCRIT, "opening lockfile failed: $!");
return DECLINED; return DECLINED;
} }
unless (flock LOCK, LOCK_EX) { unless (flock LOCK, LOCK_EX) {
$self->log(2, "flock of lockfile failed: $!"); $self->log(LOGCRIT, "flock of lockfile failed: $!");
close LOCK; close LOCK;
return DECLINED; return DECLINED;
} }
my %db = (); my %db = ();
unless (tie %db, 'AnyDBM_File', $db, O_CREAT|O_RDWR, 0600) { unless (tie %db, 'AnyDBM_File', $db, O_CREAT|O_RDWR, 0600) {
$self->log(2, "tie to database $db failed: $!"); $self->log(LOGCRIT, "tie to database $db failed: $!");
close LOCK; close LOCK;
return DECLINED; return DECLINED;
} }
@ -223,12 +223,12 @@ sub denysoft_greylist {
my ($ts, $new, $black, $white) = (0,0,0,0); my ($ts, $new, $black, $white) = (0,0,0,0);
if ($db{$key}) { if ($db{$key}) {
($ts, $new, $black, $white) = split /:/, $db{$key}; ($ts, $new, $black, $white) = split /:/, $db{$key};
$self->log(3, "ts: " . localtime($ts) . ", now: " . localtime); $self->log(LOGERROR, "ts: " . localtime($ts) . ", now: " . localtime);
if (! $white) { if (! $white) {
# Black IP - deny, but don't update timestamp # Black IP - deny, but don't update timestamp
if (time - $ts < $config->{black_timeout}) { if (time - $ts < $config->{black_timeout}) {
$db{$key} = sprintf $fmt, $ts, $new, ++$black, 0; $db{$key} = sprintf $fmt, $ts, $new, ++$black, 0;
$self->log(2, "key $key black DENYSOFT - $black failed connections"); $self->log(LOGCRIT, "key $key black DENYSOFT - $black failed connections");
untie %db; untie %db;
close LOCK; close LOCK;
return $config->{mode} eq 'testonly' ? DECLINED : DENYSOFT, $DENYMSG; return $config->{mode} eq 'testonly' ? DECLINED : DENYSOFT, $DENYMSG;
@ -236,33 +236,33 @@ sub denysoft_greylist {
# Grey IP - accept unless timed out # Grey IP - accept unless timed out
elsif (time - $ts < $config->{grey_timeout}) { elsif (time - $ts < $config->{grey_timeout}) {
$db{$key} = sprintf $fmt, time, $new, $black, 1; $db{$key} = sprintf $fmt, time, $new, $black, 1;
$self->log(2, "key $key updated grey->white"); $self->log(LOGCRIT, "key $key updated grey->white");
untie %db; untie %db;
close LOCK; close LOCK;
return DECLINED; return DECLINED;
} }
else { else {
$self->log(3, "key $key has timed out (grey)"); $self->log(LOGERROR, "key $key has timed out (grey)");
} }
} }
# White IP - accept unless timed out # White IP - accept unless timed out
else { else {
if (time - $ts < $config->{white_timeout}) { if (time - $ts < $config->{white_timeout}) {
$db{$key} = sprintf $fmt, time, $new, $black, ++$white; $db{$key} = sprintf $fmt, time, $new, $black, ++$white;
$self->log(2, "key $key is white, $white deliveries"); $self->log(LOGCRIT, "key $key is white, $white deliveries");
untie %db; untie %db;
close LOCK; close LOCK;
return DECLINED; return DECLINED;
} }
else { else {
$self->log(3, "key $key has timed out (white)"); $self->log(LOGERROR, "key $key has timed out (white)");
} }
} }
} }
# New ip or entry timed out - record new and return DENYSOFT # New ip or entry timed out - record new and return DENYSOFT
$db{$key} = sprintf $fmt, time, ++$new, $black, 0; $db{$key} = sprintf $fmt, time, ++$new, $black, 0;
$self->log(2, "key $key initial DENYSOFT, unknown"); $self->log(LOGCRIT, "key $key initial DENYSOFT, unknown");
untie %db; untie %db;
close LOCK; close LOCK;
return $config->{mode} eq 'testonly' ? DECLINED : DENYSOFT, $DENYMSG; return $config->{mode} eq 'testonly' ? DECLINED : DENYSOFT, $DENYMSG;

View File

@ -26,7 +26,7 @@ sub register {
} }
unless ($self->{_maildir}) { unless ($self->{_maildir}) {
$self->log(1, "WARNING: maildir directory not specified"); $self->log(LOGWARN, "WARNING: maildir directory not specified");
return 0; return 0;
} }

View File

@ -213,7 +213,7 @@ sub check_spam {
$transaction->header->add('X-Spam-Status', $transaction->header->add('X-Spam-Status',
"$flag, hits=$hits required=$required\n" . "$flag, hits=$hits required=$required\n" .
"\ttests=$tests", 0); "\ttests=$tests", 0);
$self->log(5, "check_spam: $flag, hits=$hits, required=$required, " . $self->log(LOGNOTICE, "check_spam: $flag, hits=$hits, required=$required, " .
"tests=$tests"); "tests=$tests");
return (DECLINED); return (DECLINED);

View File

@ -117,7 +117,7 @@ sub register {
if (exists $self->{_avclient_bin} && $self->{_avclient_bin} =~ /^(\/[\/\-\_\.a-z0-9A-Z]*)$/) { if (exists $self->{_avclient_bin} && $self->{_avclient_bin} =~ /^(\/[\/\-\_\.a-z0-9A-Z]*)$/) {
$self->{_avclient_bin} = $1; $self->{_avclient_bin} = $1;
} else { } else {
$self->log(1, "FATAL ERROR: No binary aveclient found: '".$self->{_avclient_bin}."'"); $self->log(LOGALERT, "FATAL ERROR: No binary aveclient found: '".$self->{_avclient_bin}."'");
exit 3; exit 3;
} }
} }
@ -153,7 +153,7 @@ sub avscan {
# check if something went wrong # check if something went wrong
if ($signal) { if ($signal) {
$self->log(1, "kavscanner exited with signal: $signal"); $self->log(LOGERROR, "kavscanner exited with signal: $signal");
return (DECLINED); return (DECLINED);
} }
@ -164,20 +164,20 @@ sub avscan {
# ok a somewhat virus was found # ok a somewhat virus was found
shift @output; shift @output;
$description = "REPORT: ".join(", ",@output); $description = "REPORT: ".join(", ",@output);
$self->log(1, "Virus found! ($description)"); $self->log(LOGWARN, "Virus found! ($description)");
# we don't want to be disturbed be these, so block mail and DENY connection # we don't want to be disturbed be these, so block mail and DENY connection
return(DENY, "Virus found: $description"); return(DENY, "Virus found: $description");
} else { } else {
$self->log(0, "aveserver: no viruses have been detected.") if($result =~ /^0$/); $self->log(LOGCRIT, "aveserver: no viruses have been detected.") if($result =~ /^0$/);
$self->log(0, "aveserver: system error launching the application (file not found, unable to read the file).") if($result =~ /^0$/); $self->log(LOGCRIT, "aveserver: system error launching the application (file not found, unable to read the file).") if($result =~ /^0$/);
$self->log(0, "aveserver: some of the required parameters are missing from the command line.") if($result =~ /^9$/); $self->log(LOGCRIT, "aveserver: some of the required parameters are missing from the command line.") if($result =~ /^9$/);
return(DENY, "Unable to scan for virus, please contact admin of ".$self->qp->config("me").", if you feel this is an error!") if $self->{_blockonerror}; return(DENY, "Unable to scan for virus, please contact admin of ".$self->qp->config("me").", if you feel this is an error!") if $self->{_blockonerror};
} }
} }
$self->log(1, "kavscanner results: $description"); $self->log(LOGINFO, "kavscanner results: $description");
$transaction->header->add('X-Virus-Checked', 'Checked by Kaspersky on '.$self->qp->config("me")); $transaction->header->add('X-Virus-Checked', 'Checked by Kaspersky on '.$self->qp->config("me"));
return (DECLINED); return (DECLINED);
} }

View File

@ -74,7 +74,7 @@ sub register {
$self->{_kavscanner_bin} =~ /^(\/[\/\-\_\.a-z0-9A-Z]*)$/) { $self->{_kavscanner_bin} =~ /^(\/[\/\-\_\.a-z0-9A-Z]*)$/) {
$self->{_kavscanner_bin} = $1; $self->{_kavscanner_bin} = $1;
} else { } else {
$self->log(1, "FATAL ERROR: Unexpected characters in kavscanner argument"); $self->log(LOGALERT, "FATAL ERROR: Unexpected characters in kavscanner argument");
exit 3; exit 3;
} }
} }
@ -94,7 +94,7 @@ sub kav_scan {
# Now do the actual scanning! # Now do the actual scanning!
my $cmd = $self->{_kavscanner_bin}." -Y -P -B -MP -MD -* $filename 2>&1"; my $cmd = $self->{_kavscanner_bin}." -Y -P -B -MP -MD -* $filename 2>&1";
$self->log(1, "Running: $cmd"); $self->log(LOGNOTICE, "Running: $cmd");
my @output = `$cmd`; my @output = `$cmd`;
chomp(@output); chomp(@output);
@ -105,7 +105,7 @@ sub kav_scan {
close $temp_fh; close $temp_fh;
if ($signal) { if ($signal) {
$self->log(1, "kavscanner exited with signal: $signal"); $self->log(LOGWARN, "kavscanner exited with signal: $signal");
return (DECLINED); return (DECLINED);
} }
@ -127,7 +127,7 @@ sub kav_scan {
."suspicions: ".join(", ", @suspicious); ."suspicions: ".join(", ", @suspicious);
# else we may get a veeeery long X-Virus-Details: line or log entry # else we may get a veeeery long X-Virus-Details: line or log entry
$description = substr($description,0,60); $description = substr($description,0,60);
$self->log(1, "There be a virus! ($description)"); $self->log(LOGWARN, "There be a virus! ($description)");
### Untested by now, need volunteers ;-) ### Untested by now, need volunteers ;-)
#if ($self->qp->config("kav_deny")) { #if ($self->qp->config("kav_deny")) {
# foreach my $d (keys %{$self->qp->config("kav_deny", "map")}) { # foreach my $d (keys %{$self->qp->config("kav_deny", "map")}) {
@ -165,11 +165,11 @@ sub kav_scan {
} }
} }
} else { } else {
$self->log(0, "corrupt or unknown Kaspersky scanner/resource problems - exit status $result"); $self->log(LOGEMERG, "corrupt or unknown Kaspersky scanner/resource problems - exit status $result");
} }
} }
$self->log(1, "kavscanner results: $description"); $self->log(LOGINFO, "kavscanner results: $description");
$transaction->header->add('X-Virus-Checked', 'Checked by '.$self->qp->config("me")); $transaction->header->add('X-Virus-Checked', 'Checked by '.$self->qp->config("me"));
return (DECLINED); return (DECLINED);