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;
|
my $self = shift;
|
||||||
return (defined $self->{_auth_mechanism} ? $self->{_auth_mechanism} : "" );
|
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;
|
1;
|
||||||
|
|
||||||
|
@ -2,11 +2,13 @@ package Qpsmtpd::Plugin;
|
|||||||
use Qpsmtpd::Constants;
|
use Qpsmtpd::Constants;
|
||||||
use strict;
|
use strict;
|
||||||
|
|
||||||
|
# more or less in the order they will fire
|
||||||
our @hooks = qw(
|
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
|
auth auth-plain auth-login auth-cram-md5
|
||||||
connect reset_transaction unrecognized_command disconnect
|
rcpt mail data data_post queue_pre queue queue_post
|
||||||
deny ok pre-connection post-connection
|
quit reset_transaction disconnect post-connection
|
||||||
|
unrecognized_command deny ok
|
||||||
);
|
);
|
||||||
our %hooks = map { $_ => 1 } @hooks;
|
our %hooks = map { $_ => 1 } @hooks;
|
||||||
|
|
||||||
|
@ -50,6 +50,12 @@ sub dispatch {
|
|||||||
|
|
||||||
$self->{_counter}++;
|
$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}) {
|
if ($cmd !~ /^(\w{1,12})$/ or !exists $self->{_commands}->{$1}) {
|
||||||
my ($rc, $msg) = $self->run_hooks("unrecognized_command", $cmd, @_);
|
my ($rc, $msg) = $self->run_hooks("unrecognized_command", $cmd, @_);
|
||||||
if ($rc == DENY_DISCONNECT) {
|
if ($rc == DENY_DISCONNECT) {
|
||||||
@ -150,8 +156,10 @@ sub helo {
|
|||||||
if ($rc == DONE) {
|
if ($rc == DONE) {
|
||||||
# do nothing
|
# do nothing
|
||||||
} elsif ($rc == DENY) {
|
} elsif ($rc == DENY) {
|
||||||
|
$self->denied(1);
|
||||||
$self->respond(550, $msg);
|
$self->respond(550, $msg);
|
||||||
} elsif ($rc == DENYSOFT) {
|
} elsif ($rc == DENYSOFT) {
|
||||||
|
$self->denied(1);
|
||||||
$self->respond(450, $msg);
|
$self->respond(450, $msg);
|
||||||
} elsif ($rc == DENY_DISCONNECT) {
|
} elsif ($rc == DENY_DISCONNECT) {
|
||||||
$self->respond(550, $msg);
|
$self->respond(550, $msg);
|
||||||
@ -178,8 +186,10 @@ sub ehlo {
|
|||||||
if ($rc == DONE) {
|
if ($rc == DONE) {
|
||||||
# do nothing
|
# do nothing
|
||||||
} elsif ($rc == DENY) {
|
} elsif ($rc == DENY) {
|
||||||
|
$self->denied(1);
|
||||||
$self->respond(550, $msg);
|
$self->respond(550, $msg);
|
||||||
} elsif ($rc == DENYSOFT) {
|
} elsif ($rc == DENYSOFT) {
|
||||||
|
$self->denied(1);
|
||||||
$self->respond(450, $msg);
|
$self->respond(450, $msg);
|
||||||
} elsif ($rc == DENY_DISCONNECT) {
|
} elsif ($rc == DENY_DISCONNECT) {
|
||||||
$self->respond(550, $msg);
|
$self->respond(550, $msg);
|
||||||
@ -290,11 +300,13 @@ sub mail {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
elsif ($rc == DENY) {
|
elsif ($rc == DENY) {
|
||||||
|
$self->denied(1);
|
||||||
$msg ||= $from->format . ', denied';
|
$msg ||= $from->format . ', denied';
|
||||||
$self->log(LOGINFO, "deny mail from " . $from->format . " ($msg)");
|
$self->log(LOGINFO, "deny mail from " . $from->format . " ($msg)");
|
||||||
$self->respond(550, $msg);
|
$self->respond(550, $msg);
|
||||||
}
|
}
|
||||||
elsif ($rc == DENYSOFT) {
|
elsif ($rc == DENYSOFT) {
|
||||||
|
$self->denied(1);
|
||||||
$msg ||= $from->format . ', temporarily denied';
|
$msg ||= $from->format . ', temporarily denied';
|
||||||
$self->log(LOGINFO, "denysoft mail from " . $from->format . " ($msg)");
|
$self->log(LOGINFO, "denysoft mail from " . $from->format . " ($msg)");
|
||||||
$self->respond(450, $msg);
|
$self->respond(450, $msg);
|
||||||
@ -336,10 +348,12 @@ sub rcpt {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
elsif ($rc == DENY) {
|
elsif ($rc == DENY) {
|
||||||
|
$self->denied(1);
|
||||||
$msg ||= 'relaying denied';
|
$msg ||= 'relaying denied';
|
||||||
$self->respond(550, $msg);
|
$self->respond(550, $msg);
|
||||||
}
|
}
|
||||||
elsif ($rc == DENYSOFT) {
|
elsif ($rc == DENYSOFT) {
|
||||||
|
$self->denied(1);
|
||||||
$msg ||= 'relaying denied';
|
$msg ||= 'relaying denied';
|
||||||
return $self->respond(450, $msg);
|
return $self->respond(450, $msg);
|
||||||
}
|
}
|
||||||
@ -558,7 +572,7 @@ sub data {
|
|||||||
$self->respond(452, $msg || "Message denied temporarily");
|
$self->respond(452, $msg || "Message denied temporarily");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$self->queue($self->transaction);
|
$self->queue($self->transaction);
|
||||||
}
|
}
|
||||||
|
|
||||||
# DATA is always the end of a "transaction"
|
# DATA is always the end of a "transaction"
|
||||||
@ -578,7 +592,18 @@ sub getline {
|
|||||||
sub queue {
|
sub queue {
|
||||||
my ($self, $transaction) = @_;
|
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) {
|
if ($rc == DONE) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -586,16 +611,20 @@ sub queue {
|
|||||||
$self->respond(250, ($msg || 'Queued'));
|
$self->respond(250, ($msg || 'Queued'));
|
||||||
}
|
}
|
||||||
elsif ($rc == DENY) {
|
elsif ($rc == DENY) {
|
||||||
|
$self->denied(1);
|
||||||
$self->respond(552, $msg || "Message denied");
|
$self->respond(552, $msg || "Message denied");
|
||||||
}
|
}
|
||||||
elsif ($rc == DENYSOFT) {
|
elsif ($rc == DENYSOFT) {
|
||||||
|
$self->denied(1);
|
||||||
$self->respond(452, $msg || "Message denied temporarily");
|
$self->respond(452, $msg || "Message denied temporarily");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$self->respond(451, $msg || "Queuing declined or disabled; try again later" );
|
$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