On 2006-03-03 14:27:10 -0500, John Peacock wrote: > Johan Almqvist wrote: > >(and maybe we should modify qpsmtpd's behaviour to be more > >consistent in terms of what it returns, so as to issue 5xx's for the > >rest of the transaction if a DENY has been returned). > > Beat you to it. There is code in branches/0.3x now that disconnects any > connection where we've already issued a 5xx once (except for QUIT and RSET).
Be careful there. Something like:
rcpt to:<[EMAIL PROTECTED]>
550 no such user <[EMAIL PROTECTED]>
rcpt to:<[EMAIL PROTECTED]>
250 <[EMAIL PROTECTED]>, recipient ok
is entirely permissible, and in fact happens quite a lot if someone has
an old address in their address book. So you don't want to disconnect
after the first denied RCPT or your users will complain about the
unintended greylisting.
I wrote a plugin a some time ago[0] which counts the number of denies and
disconnects after a configurable number of denies. I think I posted it
to the list at the time, but here it is again.
hp
[0] May 2004 to be precise. I wrote it as an example for a talk about
qpsmtpd.
--
_ | Peter J. Holzer | Ich sehe nun ein, dass Computer wenig
|_|_) | Sysadmin WSR | geeignet sind, um sich was zu merken.
| | | [EMAIL PROTECTED] |
__/ | http://www.hjp.at/ | -- Holger Lembke in dan-am
=head1 NAME
count_denies - Count denies and disconnect when we have too many
=head1 DESCRIPTION
Disconnect the client if it receives too many denies.
Good for thwarting dictionary attacks.
=head1 CONFIGURATION
Takes one parameter, the number of allowed denies
before we disconnect the client. Defaults to 4.
=cut
sub register {
my ($self, $qp, @args) = @_;
$self->register_hook("deny", "check_deny");
$self->register_hook("rcpt", "check_rcpt");
if (@args > 0) {
$self->{_deny_max} = $args[0];
$self->log(LOGWARN, "WARNING: Ignoring additional arguments.") if (@args >
1);
} else {
$self->{_deny_max} = 4;
}
$qp->connection->notes('deny_count', 0);
}
sub check_deny {
my ($self, $transaction, $plugin, $result, $message) = @_;
# Qpsmtpd::Plugin::count_denies=HASH(0x8264290)
Qpsmtpd::Transaction=HASH(0x8892a1c) aliases 901 no such user <[EMAIL
PROTECTED]>
$self->log(LOGINFO, "check_deny: @_");
$self->log(LOGINFO, "check_deny: result=$result");
if ($result == DENY) {
my $deny_count = $self->qp->connection->notes('deny_count');
$self->log(LOGDEBUG, "check_deny: Deny count $deny_count");
$self->qp->connection->notes('deny_count', $deny_count+1);
}
return DECLINED;
}
sub check_rcpt {
my ($self, $transaction, $rcpt) = @_;
my $deny_count =
$self->qp->connection->notes('deny_count');
$self->log(LOGDEBUG, "check_rcpt: Deny count $deny_count");
if ($deny_count >= $self->{_deny_max}) {
$self->log(LOGNOTICE, "Closing connection. $deny_count denied commands.");
return (DENYSOFT_DISCONNECT, "Closing connection. $deny_count denied
commands.");
}
return DECLINED;
}
pgpjZ3yIkmJqZ.pgp
Description: PGP signature
