Author: vetinari
Date: Wed Sep  5 05:03:07 2007
New Revision: 790

Added:
   contrib/vetinari/rcpt_ok_maxrelay

Log:
new plugin: rcpt_ok_maxrelay - wrapper for rcpt_ok, which drops the connection 
after configured number of unsuccessful relaying attempts

Added: contrib/vetinari/rcpt_ok_maxrelay
==============================================================================
--- (empty file)
+++ contrib/vetinari/rcpt_ok_maxrelay   Wed Sep  5 05:03:07 2007
@@ -0,0 +1,59 @@
+#
+
+=head1 NAME
+
+rcpt_ok_maxrelay - wrapper for rcpt_ok, drop connection after too many 
relaying attempts
+
+=head1 SYNOPIS
+
+rcpt_ok_maxrelay [MAX_RELAY_ATTEMPTS]
+
+=head1 DESCRIPTION
+
+The B<rcpt_ok_maxrelay> plugin wraps the B<rcpt_ok> plugin. 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. This plugin counts the
+number of unsuccessfull relaying attempts and drops the connection if
+too many were made. 
+
+The optional parameter I<MAX_RELAY_ATTEMPTS> configures this plugin to drop 
+the connection after I<MAX_RELAY_ATTEMPTS> unsuccessful relaying attempts. 
+Set to C<0> to disable, default is C<5>.
+
+=head1 NOTES
+
+Do not load both (B<rcpt_ok> and B<rcpt_ok_maxrelay>). This plugin should 
+be configured to run I<last>, like B<rcpt_ok>.
+
+=cut
+
+use Qpsmtpd::DSN;
+
+sub init {
+    my ($self, $qp, @args) = @_;
+    die "too many arguments" 
+      if @args > 1;
+    $self->{_count_relay_max} = defined $args[0] ? $args[0] : 5;
+    $self->isa_plugin("rcpt_ok");
+}
+
+sub hook_rcpt {
+    my ($self, $transaction, $recipient) = @_;
+
+    my ($rc, @msg) = $self->SUPER::hook_rcpt($transaction, $recipient);
+
+    return ($rc, @msg) 
+      unless (($rc == DENY) and $self->{_count_relay_max});
+
+    my $count = ($self->qp->connection->notes('count_relay_attempts') || 0) + 
1;
+    $self->qp->connection->notes('count_relay_attempts', $count);
+
+    return ($rc, @msg)
+      unless ($count > $self->{_count_relay_max});
+
+    return Qpsmtpd::DSN->relaying_denied(DENY_DISCONNECT, "Too many relaying 
attempts");
+}
+
+# vim: ts=4 sw=4 expandtab syn=perl

Reply via email to