Hi *, some annoying clients tried to abuse one of my systems as open relay. Each of them did more than 350 attempts before giving up... Now they're forced to stop after 10 attempts ;-) Any objections against the attached diff? If not, I'll submit to SVN.
Hanno
--- plugins/rcpt_ok 2007-09-03 17:48:08.000000000 +0200 +++ plugins/rcpt_ok.max_relay_attempts 2007-08-22 11:59:03.000000000 +0200 @@ -2,8 +2,43 @@ # # It should be configured to be run _LAST_! # + +=head1 NAME + +rcpt_ok - check the standard rcpthosts config + +=head1 SYNOPIS + +rcpt_ok [MAX_RELAY_ATTEMPTS] + +=head1 DESCRIPTION + +The B<rcpt_ok> plugin checks the F<rcpthosts> and F<morercpthosts> config +files for domains, which we accept mail for. If not found it tells the +client that relaying is not allowed. Clients which are marked as +C<relay clients> are excluded from this rule. + +The optional parameter I<MAX_RELAY_ATTEMPTS> configures this plugin to drop +the connection if the number of attempted (unsuccessfull) relayings is +higher than I<MAX_RELAY_ATTEMPTS>. Set to C<0> to disable (which is also the +default). + +=cut + use Qpsmtpd::DSN; +sub register { + my ($self, $qp, @args) = @_; + die "Too many arguments" if (@args > 1); + if (@args) { + die "argument not a number" unless $args[0] =~ /^\d+$/; + $self->{_relay_deny_max} = $args[0]; + } + else { + $self->{_relay_deny_max} = 0; + } +} + sub hook_rcpt { my ($self, $transaction, $recipient, %param) = @_; my $host = lc $recipient->host; @@ -31,6 +66,13 @@ return (OK); } else { + if ($self->{_relay_deny_max}) { + my $deny_count = $self->qp->connection->notes('_relay_deny_count') || 0; + ++$deny_count; + return Qpsmtpd::DSN->relaying_denied(DENY_DISCONNECT, "Too many relaying attempts") + if ($deny_count > $self->{_relay_deny_max}); + $self->qp->connection->notes('_relay_deny_count', $deny_count) + } # default of relaying_denied is obviously DENY, # we use the default "Relaying denied" message... return Qpsmtpd::DSN->relaying_denied();