[PATCH] badmailfromto: added strictures, tests, and

[email protected] (Matt Simerson)
Newsgroups perl.qpsmtpd
Message-ID <[email protected]>
badmailfromto: added strictures, tests, and

rearranged portions of logic for ease of reading

---
plugins/check_badmailfromto        |   68 ++++++++++++++++++++++++------------
t/plugin_tests/check_badmailfromto |   36 +++++++++++++++++++
2 files changed, 82 insertions(+), 22 deletions(-)
create mode 100644 t/plugin_tests/check_badmailfromto

diff --git a/plugins/check_badmailfromto b/plugins/check_badmailfromto
index a57f6f6..3a39874 100644
--- a/plugins/check_badmailfromto
+++ b/plugins/check_badmailfromto
@@ -17,14 +17,14 @@ Based heavily on check_badmailfrom.

=cut

+use strict;
+use Qpsmtpd::Constants;
+
sub hook_mail {
  my ($self, $transaction, $sender, %param) = @_;

-  my @badmailfromto = $self->qp->config("badmailfromto")
-    or return (DECLINED);
-
-  return (DECLINED) unless ($sender->format ne "<>"
-			    and $sender->host && $sender->user);
+    my @badmailfromto = $self->qp->config("badmailfromto");
+    return DECLINED if $self->is_sender_immune( $sender, \@badmailfromto );

  my $host = lc $sender->host;
  my $from = lc($sender->user) . '@' . $host;
@@ -33,27 +33,51 @@ sub hook_mail {
    $bad =~ s/^\s*(\S+).*/$1/;
    next unless $bad;
    $bad = lc $bad;
-    $self->log(LOGWARN, "Bad badmailfromto config: No \@ sign in $bad") and next unless $bad =~ m/\@/;
-    $transaction->notes('badmailfromto', "$bad")
-      if ($bad eq $from)
-      || (substr($bad,0,1) eq '@' && $bad eq "\@$host");
+    if ( $bad !~ m/\@/ ) {
+        $self->log(LOGWARN, 'badmailfromto: bad config, no @ sign in '. $bad);
+        next;
+    };
+    if ( $bad eq $from || (substr($bad,0,1) eq '@' && $bad eq "\@$host") ) {
+        $transaction->notes('badmailfromto', $bad);
+    };
  }
  return (DECLINED);
}

sub hook_rcpt {
-  my ($self, $transaction, $rcpt, %param) = @_;
-  my $recipient = lc($rcpt->user) . '@' . lc($rcpt->host);
-  my $sender = $transaction->notes('badmailfromto');
-  if ($sender) {
-    my @badmailfromto = $self->qp->config("badmailfromto")
-      or return (DECLINED);
-
-    foreach (@badmailfromto) {
-      my ($from, $to) = m/^\s*(\S+)\t(\S+).*/;
-      return (DENY, "mail to $recipient not accepted here")
-        if lc($from) eq $sender and lc($to) eq $recipient;
+    my ($self, $transaction, $rcpt, %param) = @_;
+    my $recipient = lc($rcpt->user) . '@' . lc($rcpt->host);
+    my $sender = $transaction->notes('badmailfromto') or do {
+        $self->log(LOGDEBUG, "pass: sender not listed");
+        return (DECLINED);
+    };
+
+    foreach ( $self->qp->config("badmailfromto") ) {
+        my ($from, $to) = m/^\s*(\S+)\t(\S+).*/;
+        return (DENY, "mail to $recipient not accepted here")
+            if lc($from) eq $sender && lc($to) eq $recipient;
    }
-  }
-  return (DECLINED);
+    $self->log(LOGDEBUG, "pass: recipient not listed");
+    return (DECLINED);
}
+
+sub is_sender_immune {
+    my ($self, $sender, $badmf ) = @_;
+
+    if ( ! scalar @$badmf ) {
+        $self->log(LOGDEBUG, 'skip: empty list');
+        return 1;
+    };
+
+    if ( ! $sender || $sender->format eq '<>' ) {
+        $self->log(LOGDEBUG, 'skip: null sender');
+        return 1;
+    };
+
+    if ( ! $sender->host || ! $sender->user ) {
+        $self->log(LOGDEBUG, 'skip: missing user or host');
+        return 1;
+    };
+
+    return;
+};
diff --git a/t/plugin_tests/check_badmailfromto b/t/plugin_tests/check_badmailfromto
new file mode 100644
index 0000000..73d9bb9
--- /dev/null
+++ b/t/plugin_tests/check_badmailfromto
@@ -0,0 +1,36 @@
+#!perl -w
+
+use strict;
+use Data::Dumper;
+
+use Qpsmtpd::Address;
+
+sub register_tests {
+    my $self = shift;
+
+    $self->register_test("test_badmailfromto_is_sender_immune", 5);
+}
+
+sub test_badmailfromto_is_sender_immune {
+    my $self = shift;
+
+    my $transaction = $self->qp->transaction;
+    my $test_email = '[email protected]';
+    $transaction->sender( Qpsmtpd::Address->new( "<$test_email>" ) );
+    ok( $self->is_sender_immune( $transaction->sender, [] ), "is_immune, empty list");
+
+    $transaction->sender( Qpsmtpd::Address->new( '<>' ) );
+    ok( $self->is_sender_immune( $transaction->sender, ['[email protected]'] ), "is_immune, null sender");
+
+    my $address = Qpsmtpd::Address->new( '<matt@>' );
+    $transaction->sender($address);
+    ok( $self->is_sender_immune( $transaction->sender, ['[email protected]'] ), "is_immune, missing host");
+
+    $address = Qpsmtpd::Address->new( '<@example.com>' );
+    $transaction->sender($address);
+    ok( $self->is_sender_immune( $transaction->sender, ['[email protected]'] ), "is_immune, missing user");
+
+    $transaction->sender( Qpsmtpd::Address->new( '<[email protected]>' ) );
+    ok( ! $self->is_sender_immune( $transaction->sender, ['[email protected]'] ), "is_immune, false");
+};
+
-- 
1.7.9.6
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.