From 8b50b6dd46600d8d8f6116bda590815bc8d6837b Mon Sep 17 00:00:00 2001 From: John Peacock Date: Thu, 9 Jun 2005 16:36:43 +0000 Subject: [PATCH] Two new plugins from Gordon Rowell * plugins/check_badrcptto_patterns Match bad RCPTO address with regex * plugins/check_norelay Carve out holes from larger relay blocks git-svn-id: https://svn.perl.org/qpsmtpd/trunk@431 958fd67b-6ff1-0310-b445-bb7760255be9 --- plugins/check_badrcptto_patterns | 53 +++++++++++++++++++++++++++ plugins/check_norelay | 62 ++++++++++++++++++++++++++++++++ 2 files changed, 115 insertions(+) create mode 100644 plugins/check_badrcptto_patterns create mode 100644 plugins/check_norelay diff --git a/plugins/check_badrcptto_patterns b/plugins/check_badrcptto_patterns new file mode 100644 index 0000000..95a480b --- /dev/null +++ b/plugins/check_badrcptto_patterns @@ -0,0 +1,53 @@ +=pod + +=head1 SYNOPSIS + +This plugin checks the badrcptto_patterns config. This allows +special patterns to be denied (e.g. percent hack, bangs, +double ats). + +=head1 CONFIG + +config/badrcptto_patterns + +Patterns are stored in the format pattern\sresponse, where pattern +is a Perl pattern expression. Don't forget to anchor the pattern if +you want to restrict it from matching anywhere in the string. + +qpsmtpd already ensures that the address contains an @, with something +to the left and right of the @. + +=head1 AUTHOR + +Copyright 2005 Gordon Rowell + +This software is free software and may be distributed under the same +terms as Perl itself. + +=cut + +sub register +{ + my ($self, $qp) = @_; + $self->register_hook("rcpt", "check_for_badrcptto_patterns"); +} + +sub check_for_badrcptto_patterns +{ + my ($self, $transaction, $recipient) = @_; + + return (DECLINED) if $self->qp->connection->relay_client(); + + my @badrcptto = $self->qp->config("badrcptto_patterns") or return (DECLINED); + my $host = lc $recipient->host; + my $to = lc($recipient->user) . '@' . $host; + + for (@badrcptto) + { + my ($pattern, $response) = split /\s+/, $_, 2; + + return (DENY, $response) if ($to =~ /$pattern/); + } + + return (DECLINED); +} diff --git a/plugins/check_norelay b/plugins/check_norelay new file mode 100644 index 0000000..f5b40b0 --- /dev/null +++ b/plugins/check_norelay @@ -0,0 +1,62 @@ +=pod + +=head1 SYNOPSIS + +This plugin checks the norelayclients config file to see if +relaying is denied. + +This allows specific clients, such as the gateway, to be denied +relaying, even though they would be allowed relaying by the +relayclients file. + +=head1 CONFIG + +config/norelayclients + +Each line is: +- a full IP address +- partial IP address terminated by a dot for matching whole networks + e.g. 192.168.42. + +=head1 BUGS AND LIMITATIONS + +This plugin does not have a more_norelayclients map equivalent +of the more_relayclients map of the check_relay plugin. + +=head1 AUTHOR + +Based on check_relay plugin from the qpsmtpd distribution. + +Copyright 2005 Gordon Rowell + +This software is free software and may be distributed under the same +terms as Perl itself. + +=cut + +sub register { + my ($self, $qp) = @_; + $self->register_hook("connect", "check_norelay"); +} + +sub check_norelay { + my ($self, $transaction) = @_; + my $connection = $self->qp->connection; + + # Check if this IP is not allowed to relay + my @no_relay_clients = $self->qp->config("norelayclients"); + my %no_relay_clients = map { $_ => 1 } @no_relay_clients; + my $client_ip = $self->qp->connection->remote_ip; + while ($client_ip) { + if ( exists($no_relay_clients{$client_ip}) ) + { + $connection->relay_client(0); + delete $ENV{RELAYCLIENT}; + $self->log(LOGNOTICE, "check_norelay: $client_ip denied relaying"); + last; + } + $client_ip =~ s/\d+\.?$//; # strip off another 8 bits + } + + return (DECLINED); +}