[svn:qpsmtpd] rev 431 - in trunk: . plugins

[email protected] 9 Jun 2005 16:36:44 -0000
Newsgroups perl.cvs.qpsmtpd
Message-ID <[email protected]>
Author: jpeacock
Date: Thu Jun  9 09:36:43 2005
New Revision: 431

Added:
   trunk/plugins/check_badrcptto_patterns
   trunk/plugins/check_norelay
Modified:
   trunk/   (props changed)
Log:
 Two new plugins from Gordon Rowell <[email protected]>
 
 *   plugins/check_badrcptto_patterns
     Match bad RCPTO address with regex
 
 *   plugins/check_norelay
     Carve out holes from larger relay blocks


Added: trunk/plugins/check_badrcptto_patterns
==============================================================================
--- (empty file)
+++ trunk/plugins/check_badrcptto_patterns	Thu Jun  9 09:36:43 2005
@@ -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 <[email protected]>
+
+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);
+}

Added: trunk/plugins/check_norelay
==============================================================================
--- (empty file)
+++ trunk/plugins/check_norelay	Thu Jun  9 09:36:43 2005
@@ -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 <[email protected]>
+
+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);
+}