badmailfrom: remove rcpt hook (uses naughty instead)

This commit is contained in:
Matt Simerson 2012-06-22 20:03:47 -04:00
parent 046bc43e8e
commit e4133127d5
2 changed files with 30 additions and 39 deletions

View File

@ -48,12 +48,6 @@ anywhere in the string.
^admin.*\.ppoonn400\.com$ ^admin.*\.ppoonn400\.com$
=head1 NOTES
According to the SMTP protocol, we can't reject until after the RCPT
stage, so store it until later.
=head1 AUTHORS =head1 AUTHORS
2002 - Jim Winstead - initial author of badmailfrom 2002 - Jim Winstead - initial author of badmailfrom
@ -65,16 +59,10 @@ stage, so store it until later.
=cut =cut
sub register { sub register {
my ($self,$qp) = shift, shift; my ($self,$qp) = (shift, shift);
$self->{_args} = { @_ }; $self->{_args} = { @_ };
# preserve legacy "reject during rcpt" behavior
$self->{_args}{reject} = 1 if ! defined $self->{_args}{reject}; $self->{_args}{reject} = 1 if ! defined $self->{_args}{reject};
return if ! $self->{_args}{reject}; # reject 0, log only
return if $self->{_args}{reject} eq 'naughty'; # naughty will reject
$self->register_hook('rcpt', 'rcpt_handler');
}; };
sub hook_mail { sub hook_mail {
@ -86,7 +74,6 @@ sub hook_mail {
if ( defined $self->{_badmailfrom_config} ) { # testing if ( defined $self->{_badmailfrom_config} ) { # testing
@badmailfrom = @{$self->{_badmailfrom_config}}; @badmailfrom = @{$self->{_badmailfrom_config}};
}; };
return DECLINED if $self->is_immune_sender( $sender, \@badmailfrom ); return DECLINED if $self->is_immune_sender( $sender, \@badmailfrom );
my $host = lc $sender->host; my $host = lc $sender->host;
@ -98,20 +85,22 @@ sub hook_mail {
next unless $bad; next unless $bad;
next unless $self->is_match( $from, $bad, $host ); next unless $self->is_match( $from, $bad, $host );
$reason ||= "Your envelope sender is in my badmailfrom list"; $reason ||= "Your envelope sender is in my badmailfrom list";
$self->connection->notes('naughty', $reason); $self->connection->notes('karma', ($self->connection->notes('karma') || 0) - 1);
return $self->get_reject( $reason );
} }
if ( ! $self->connection->notes('naughty') ) {
$self->log(LOGINFO, "pass"); $self->log(LOGINFO, "pass");
};
return DECLINED; return DECLINED;
} }
sub is_match { sub is_match {
my ( $self, $from, $bad, $host ) = @_; my ( $self, $from, $bad, $host ) = @_;
if ( $bad =~ /[\/\^\$\*\+]/ ) { # it's a regexp if ( $bad =~ /[\/\^\$\*\+\!\%\?\\]/ ) { # it's a regexp
if ( $from =~ /$bad/ ) {
$self->log(LOGDEBUG, "badmailfrom pattern ($bad) match for $from"); $self->log(LOGDEBUG, "badmailfrom pattern ($bad) match for $from");
return 1 if $from =~ /$bad/; return 1;
};
return; return;
}; };
@ -128,30 +117,21 @@ sub is_match {
return 1; return 1;
}; };
sub rcpt_handler {
my ($self, $transaction, $rcpt, %param) = @_;
my $note = $self->connection->notes('naughty') or return (DECLINED);
$self->log(LOGINFO, "fail, $note");
return (DENY, $note);
}
sub is_immune_sender { sub is_immune_sender {
my ($self, $sender, $badmf ) = @_; my ($self, $sender, $badmf ) = @_;
if ( ! scalar @$badmf ) { if ( ! scalar @$badmf ) {
$self->log(LOGDEBUG, 'skip: empty list'); $self->log(LOGDEBUG, 'skip, empty list');
return 1; return 1;
}; };
if ( ! $sender || $sender->format eq '<>' ) { if ( ! $sender || $sender->format eq '<>' ) {
$self->log(LOGDEBUG, 'skip: null sender'); $self->log(LOGDEBUG, 'skip, null sender');
return 1; return 1;
}; };
if ( ! $sender->host || ! $sender->user ) { if ( ! $sender->host || ! $sender->user ) {
$self->log(LOGDEBUG, 'skip: missing user or host'); $self->log(LOGDEBUG, 'skip, missing user or host');
return 1; return 1;
}; };

View File

@ -4,6 +4,7 @@ use strict;
use Data::Dumper; use Data::Dumper;
use Qpsmtpd::Address; use Qpsmtpd::Address;
use Qpsmtpd::Constants;
sub register_tests { sub register_tests {
my $self = shift; my $self = shift;
@ -42,6 +43,8 @@ sub test_badmailfrom_is_immune_sender {
sub test_badmailfrom_hook_mail { sub test_badmailfrom_hook_mail {
my $self = shift; my $self = shift;
$self->_reset_connection_flags();
my $transaction = $self->qp->transaction; my $transaction = $self->qp->transaction;
my $test_email = 'matt@test.com'; my $test_email = 'matt@test.com';
@ -49,16 +52,16 @@ sub test_badmailfrom_hook_mail {
$transaction->sender($address); $transaction->sender($address);
$self->{_badmailfrom_config} = ['matt@test.net','matt@test.com']; $self->{_badmailfrom_config} = ['matt@test.net','matt@test.com'];
$transaction->notes('badmailfrom', ''); $transaction->notes('naughty', '');
my ($r, $err) = $self->hook_mail( $transaction, $address ); my ($r, $err) = $self->hook_mail( $transaction, $address );
cmp_ok( $r, '==', 901, "hook_mail rc"); cmp_ok( $r, '==', DENY, "hook_mail rc");
cmp_ok( $err, 'eq', 'Your envelope sender is in my badmailfrom list', "hook_mail: default reason"); cmp_ok( $err, 'eq', 'Your envelope sender is in my badmailfrom list', "default reason");
$self->{_badmailfrom_config} = ['matt@test.net','matt@test.com Yer a spammin bastert']; $self->{_badmailfrom_config} = ['matt@test.net','matt@test.com Yer a spammin bastert'];
$transaction->notes('badmailfrom', ''); $transaction->notes('naughty', '');
($r, $err) = $self->hook_mail( $transaction, $address ); ($r, $err) = $self->hook_mail( $transaction, $address );
cmp_ok( $r, '==', 901, "hook_mail rc"); cmp_ok( $r, '==', DENY, "hook_mail rc");
cmp_ok( $err, 'eq', 'Yer a spammin bastert', "hook_mail: custom reason"); cmp_ok( $err, 'eq', 'Yer a spammin bastert', "custom reason");
}; };
sub test_badmailfrom_match { sub test_badmailfrom_match {
@ -88,3 +91,11 @@ sub test_badmailfrom_match {
"check_badmailfrom pattern non-match"); "check_badmailfrom pattern non-match");
}; };
sub _reset_connection_flags {
my $self = shift;
$self->qp->connection->relay_client(0);
$self->qp->connection->notes('whitelisthost', 0);
$self->connection->notes('naughty',0);
$self->connection->notes('rejected', 0);
};