badmailfromto: added strictures, tests, and
rearranged portionsn of logic for ease of reading
This commit is contained in:
parent
c44db8c9e2
commit
1910fabf0e
@ -17,14 +17,14 @@ Based heavily on check_badmailfrom.
|
|||||||
|
|
||||||
=cut
|
=cut
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
use Qpsmtpd::Constants;
|
||||||
|
|
||||||
sub hook_mail {
|
sub hook_mail {
|
||||||
my ($self, $transaction, $sender, %param) = @_;
|
my ($self, $transaction, $sender, %param) = @_;
|
||||||
|
|
||||||
my @badmailfromto = $self->qp->config("badmailfromto")
|
my @badmailfromto = $self->qp->config("badmailfromto");
|
||||||
or return (DECLINED);
|
return DECLINED if $self->is_sender_immune( $sender, \@badmailfromto );
|
||||||
|
|
||||||
return (DECLINED) unless ($sender->format ne "<>"
|
|
||||||
and $sender->host && $sender->user);
|
|
||||||
|
|
||||||
my $host = lc $sender->host;
|
my $host = lc $sender->host;
|
||||||
my $from = lc($sender->user) . '@' . $host;
|
my $from = lc($sender->user) . '@' . $host;
|
||||||
@ -33,27 +33,51 @@ sub hook_mail {
|
|||||||
$bad =~ s/^\s*(\S+).*/$1/;
|
$bad =~ s/^\s*(\S+).*/$1/;
|
||||||
next unless $bad;
|
next unless $bad;
|
||||||
$bad = lc $bad;
|
$bad = lc $bad;
|
||||||
$self->log(LOGWARN, "Bad badmailfromto config: No \@ sign in $bad") and next unless $bad =~ m/\@/;
|
if ( $bad !~ m/\@/ ) {
|
||||||
$transaction->notes('badmailfromto', "$bad")
|
$self->log(LOGWARN, 'badmailfromto: bad config, no @ sign in '. $bad);
|
||||||
if ($bad eq $from)
|
next;
|
||||||
|| (substr($bad,0,1) eq '@' && $bad eq "\@$host");
|
};
|
||||||
|
if ( $bad eq $from || (substr($bad,0,1) eq '@' && $bad eq "\@$host") ) {
|
||||||
|
$transaction->notes('badmailfromto', $bad);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
return (DECLINED);
|
return (DECLINED);
|
||||||
}
|
}
|
||||||
|
|
||||||
sub hook_rcpt {
|
sub hook_rcpt {
|
||||||
my ($self, $transaction, $rcpt, %param) = @_;
|
my ($self, $transaction, $rcpt, %param) = @_;
|
||||||
my $recipient = lc($rcpt->user) . '@' . lc($rcpt->host);
|
my $recipient = lc($rcpt->user) . '@' . lc($rcpt->host);
|
||||||
my $sender = $transaction->notes('badmailfromto');
|
my $sender = $transaction->notes('badmailfromto') or do {
|
||||||
if ($sender) {
|
$self->log(LOGDEBUG, "pass: sender not listed");
|
||||||
my @badmailfromto = $self->qp->config("badmailfromto")
|
return (DECLINED);
|
||||||
or return (DECLINED);
|
};
|
||||||
|
|
||||||
foreach (@badmailfromto) {
|
foreach ( $self->qp->config("badmailfromto") ) {
|
||||||
my ($from, $to) = m/^\s*(\S+)\t(\S+).*/;
|
my ($from, $to) = m/^\s*(\S+)\t(\S+).*/;
|
||||||
return (DENY, "mail to $recipient not accepted here")
|
return (DENY, "mail to $recipient not accepted here")
|
||||||
if lc($from) eq $sender and lc($to) eq $recipient;
|
if lc($from) eq $sender && lc($to) eq $recipient;
|
||||||
}
|
}
|
||||||
}
|
$self->log(LOGDEBUG, "pass: recipient not listed");
|
||||||
return (DECLINED);
|
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;
|
||||||
|
};
|
||||||
|
36
t/plugin_tests/check_badmailfromto
Normal file
36
t/plugin_tests/check_badmailfromto
Normal file
@ -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 = 'matt@test.com';
|
||||||
|
$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, ['bad@example.com'] ), "is_immune, null sender");
|
||||||
|
|
||||||
|
my $address = Qpsmtpd::Address->new( '<matt@>' );
|
||||||
|
$transaction->sender($address);
|
||||||
|
ok( $self->is_sender_immune( $transaction->sender, ['bad@example.com'] ), "is_immune, missing host");
|
||||||
|
|
||||||
|
$address = Qpsmtpd::Address->new( '<@example.com>' );
|
||||||
|
$transaction->sender($address);
|
||||||
|
ok( $self->is_sender_immune( $transaction->sender, ['bad@example.com'] ), "is_immune, missing user");
|
||||||
|
|
||||||
|
$transaction->sender( Qpsmtpd::Address->new( '<matt@example.com>' ) );
|
||||||
|
ok( ! $self->is_sender_immune( $transaction->sender, ['bad@example.com'] ), "is_immune, false");
|
||||||
|
};
|
||||||
|
|
Loading…
Reference in New Issue
Block a user