From aa199bee3bb8aa98c6a5beab89b30f872e8fdef1 Mon Sep 17 00:00:00 2001 From: Hanno Hecker Date: Fri, 13 Feb 2009 21:33:28 +0100 Subject: [PATCH] "new" plugin rcpt_regexp from SVNs contrib/ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * updated docs * use magic hooking with hook_rcpt * add note about regexes being eval()ed => trusted users only Signed-off-by: Ask Bjørn Hansen --- Changes | 2 + plugins/rcpt_regexp | 99 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 101 insertions(+) create mode 100644 plugins/rcpt_regexp diff --git a/Changes b/Changes index 3bbf0b7..f592e37 100644 --- a/Changes +++ b/Changes @@ -1,3 +1,5 @@ + Add rcpt_regexp plugin (Hanno Hecker) + Add notes method to Qpsmtpd::Address objects (Jared Johnson) Add remove_recipient method to the transaction object (Jared Johnson) diff --git a/plugins/rcpt_regexp b/plugins/rcpt_regexp new file mode 100644 index 0000000..9406faa --- /dev/null +++ b/plugins/rcpt_regexp @@ -0,0 +1,99 @@ +=head1 NAME + +rcpt_regexp - check recipients against a list of regular expressions + +=head1 DESCRIPTION + +B reads a list of regular expressions, return codes and comments +from the I config file. If the regular expression does NOT match +I, it is used as a string which is compared with I. +The recipient addresses are checked against this list, and if the first +matches, the return code from that line and the comment are returned to +qpsmtpd. Return code can be any valid plugin return code from +L. Matching is always done case insenstive. + +=head1 CONFIG FILE + +The config file I contains lines with a perl RE, including the +"/"s, a return code and a comment, which will be returned to the sender, if +the code is not OK or DECLINED. Example: + + # rcpt_regexp - config for rcpt_regexp plugin + me@myhost.org OK Accepting mail + /^user\d+\@doma\.in$/ OK Accepting mail + info@myhost.com DENY User not found. + /^unused\@.*/ DENY User not found. + /^.*$/ DECLINED Fall through to next rcpt plugin + +=head1 NOTE + +The C config file should be writeable by trusted users only: the +regexes are compiled with I. + +=head1 COPYRIGHT AND LICENSE + +Copyright (c) 2005 Hanno Hecker + +This plugin is licensed under the same terms as the qpsmtpd package itself. +Please see the LICENSE file included with qpsmtpd for details. + +=cut + +use Qpsmtpd::Constants; + +sub hook_rcpt { + my ($self, $transaction, $recipient) = @_; + return (DECLINED) + unless $recipient->host && $recipient->user; + + my $rcpt = lc $recipient->user . '@' . $recipient->host; + my ($re, $const, $comment, $str, $ok, $err); + + foreach ($self->qp->config("rcpt_regexp")) { + s/^\s*//; + ($re, $const, $comment) = split /\s+/, $_, 3; + $str = undef; + if ($re =~ m#^/(.*)/$#) { + $re = $1; + $ok = eval { $re = qr/$re/i; }; + if ($@) { + ($err = $@) =~ s/\s*at \S+ line \d+\.\s*$//; + $self->log(LOGWARN, "REGEXP '$re' not valid: $err"); + next; + } + $re = $ok; + } + else { + $str = lc $re; + } + + unless (defined $const) { + $self->(LOGWARN, "rcpt_regexp - no return code"); + next; + } + + $ok = $const; + $const = Qpsmtpd::Constants::return_code($const); + unless (defined $const) { + $self->log(LOGWARN, + "rcpt_regexp - '$ok' is not a valid " + . "constant, ignoring this line" + ); + next; + } + + if (defined $str) { + next unless $str eq $rcpt; + $self->log(LOGDEBUG, "String $str matched $rcpt, returning $ok"); + } + else { + next unless $rcpt =~ $re; + $self->log(LOGDEBUG, "RE $re matched $rcpt, returning $ok"); + } + + return ($const, $comment); + } + return (DECLINED); +} + +# vim: ts=4 sw=4 expandtab syn=perl