Automatically disconnect DENY'd server if it doesn't go willingly.
Implement queue_pre and queue_post hooks. git-svn-id: https://svn.perl.org/qpsmtpd/branches/0.3x@626 958fd67b-6ff1-0310-b445-bb7760255be9
This commit is contained in:
parent
4a824a2e7d
commit
82a32ed558
@ -433,6 +433,14 @@ sub auth_mechanism {
|
||||
my $self = shift;
|
||||
return (defined $self->{_auth_mechanism} ? $self->{_auth_mechanism} : "" );
|
||||
}
|
||||
|
||||
sub denied {
|
||||
my ($self, $value) = @_;
|
||||
$self->transaction->{_denied} = $value if defined $value;
|
||||
return (defined $self->transaction->{_denied}
|
||||
? $self->transaction->{_denied}
|
||||
: "" );
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
|
@ -2,11 +2,13 @@ package Qpsmtpd::Plugin;
|
||||
use Qpsmtpd::Constants;
|
||||
use strict;
|
||||
|
||||
# more or less in the order they will fire
|
||||
our @hooks = qw(
|
||||
logging config queue data data_post quit rcpt mail ehlo helo
|
||||
logging config pre-connection connect ehlo helo
|
||||
auth auth-plain auth-login auth-cram-md5
|
||||
connect reset_transaction unrecognized_command disconnect
|
||||
deny ok pre-connection post-connection
|
||||
rcpt mail data data_post queue_pre queue queue_post
|
||||
quit reset_transaction disconnect post-connection
|
||||
unrecognized_command deny ok
|
||||
);
|
||||
our %hooks = map { $_ => 1 } @hooks;
|
||||
|
||||
|
@ -50,6 +50,12 @@ sub dispatch {
|
||||
|
||||
$self->{_counter}++;
|
||||
|
||||
if ( $cmd !~ /^(rset|quit)$/ and $self->denied ) { # RFC non-compliant
|
||||
$self->log(LOGWARN, "non-RFC compliant MTA disconnected");
|
||||
$self->respond(521, "non-RFC compliant MTA disconnected (#5.7.0)");
|
||||
$self->disconnect;
|
||||
}
|
||||
|
||||
if ($cmd !~ /^(\w{1,12})$/ or !exists $self->{_commands}->{$1}) {
|
||||
my ($rc, $msg) = $self->run_hooks("unrecognized_command", $cmd, @_);
|
||||
if ($rc == DENY_DISCONNECT) {
|
||||
@ -150,8 +156,10 @@ sub helo {
|
||||
if ($rc == DONE) {
|
||||
# do nothing
|
||||
} elsif ($rc == DENY) {
|
||||
$self->denied(1);
|
||||
$self->respond(550, $msg);
|
||||
} elsif ($rc == DENYSOFT) {
|
||||
$self->denied(1);
|
||||
$self->respond(450, $msg);
|
||||
} elsif ($rc == DENY_DISCONNECT) {
|
||||
$self->respond(550, $msg);
|
||||
@ -178,8 +186,10 @@ sub ehlo {
|
||||
if ($rc == DONE) {
|
||||
# do nothing
|
||||
} elsif ($rc == DENY) {
|
||||
$self->denied(1);
|
||||
$self->respond(550, $msg);
|
||||
} elsif ($rc == DENYSOFT) {
|
||||
$self->denied(1);
|
||||
$self->respond(450, $msg);
|
||||
} elsif ($rc == DENY_DISCONNECT) {
|
||||
$self->respond(550, $msg);
|
||||
@ -290,11 +300,13 @@ sub mail {
|
||||
return 1;
|
||||
}
|
||||
elsif ($rc == DENY) {
|
||||
$self->denied(1);
|
||||
$msg ||= $from->format . ', denied';
|
||||
$self->log(LOGINFO, "deny mail from " . $from->format . " ($msg)");
|
||||
$self->respond(550, $msg);
|
||||
}
|
||||
elsif ($rc == DENYSOFT) {
|
||||
$self->denied(1);
|
||||
$msg ||= $from->format . ', temporarily denied';
|
||||
$self->log(LOGINFO, "denysoft mail from " . $from->format . " ($msg)");
|
||||
$self->respond(450, $msg);
|
||||
@ -336,10 +348,12 @@ sub rcpt {
|
||||
return 1;
|
||||
}
|
||||
elsif ($rc == DENY) {
|
||||
$self->denied(1);
|
||||
$msg ||= 'relaying denied';
|
||||
$self->respond(550, $msg);
|
||||
}
|
||||
elsif ($rc == DENYSOFT) {
|
||||
$self->denied(1);
|
||||
$msg ||= 'relaying denied';
|
||||
return $self->respond(450, $msg);
|
||||
}
|
||||
@ -558,7 +572,7 @@ sub data {
|
||||
$self->respond(452, $msg || "Message denied temporarily");
|
||||
}
|
||||
else {
|
||||
$self->queue($self->transaction);
|
||||
$self->queue($self->transaction);
|
||||
}
|
||||
|
||||
# DATA is always the end of a "transaction"
|
||||
@ -578,7 +592,18 @@ sub getline {
|
||||
sub queue {
|
||||
my ($self, $transaction) = @_;
|
||||
|
||||
my ($rc, $msg) = $self->run_hooks("queue");
|
||||
# First fire any queue_pre hooks
|
||||
my ($rc, $msg) = $self->run_hooks("queue_pre");
|
||||
if ($rc == DONE) {
|
||||
return 1;
|
||||
}
|
||||
elsif ($rc != OK and $rc != DECLINED) {
|
||||
return $self->log(LOGERROR, "pre plugin returned illegal value");
|
||||
return 0;
|
||||
}
|
||||
|
||||
# If we got this far, run the queue hooks
|
||||
($rc, $msg) = $self->run_hooks("queue");
|
||||
if ($rc == DONE) {
|
||||
return 1;
|
||||
}
|
||||
@ -586,16 +611,20 @@ sub queue {
|
||||
$self->respond(250, ($msg || 'Queued'));
|
||||
}
|
||||
elsif ($rc == DENY) {
|
||||
$self->denied(1);
|
||||
$self->respond(552, $msg || "Message denied");
|
||||
}
|
||||
elsif ($rc == DENYSOFT) {
|
||||
$self->denied(1);
|
||||
$self->respond(452, $msg || "Message denied temporarily");
|
||||
}
|
||||
else {
|
||||
$self->respond(451, $msg || "Queuing declined or disabled; try again later" );
|
||||
}
|
||||
|
||||
|
||||
|
||||
# And finally run any queue_post hooks
|
||||
($rc, $msg) = $self->run_hooks("queue_post");
|
||||
$self->log(LOGERROR, $msg) unless $rc == OK;
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user