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:
parent
b54c8ec46c
commit
9664eb9469
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user