#!perl -w =head1 NAME check_bogus_bounce - Check that a bounce message isn't bogus =head1 DESCRIPTION This plugin is designed to reject bogus bounce messages. In our case a bogus bounce message is defined as a bounce message which has more than a single recipient. =head1 CONFIGURATION Only a single argument is recognized and is assumed to be the default action. Valid settings are: =over 8 =item log Merely log the receipt of the bogus bounce (the default behaviour). =item deny Deny with a hard error code. =item denysoft Deny with a soft error code. =back =cut =head1 AUTHOR Steve Kemp -- http://steve.org.uk/Software/qpsmtpd/ =cut =begin doc Look for our single expected argument and configure "action" appropriately. =end doc =cut sub register { my ($self, $qp, $arg, @nop) = (@_); # # Default behaviour is to merely log. # $self->{_action} = "log"; # # Unless one was specified # if ($arg) { if ($arg =~ /^(log|deny|denysoft)$/i) { $self->{_action} = $arg; } else { die "Invalid argument '$arg' - use one of : log, deny, denysoft"; } } } =begin doc Handle the detection of bounces here. If we find a match then we'll react with our expected action. =end doc =cut sub hook_data_post { my ($self, $transaction) = (@_); # # Find the sender, and return unless it wasn't a bounce. # my $sender = $transaction->sender->address || undef; return DECLINED unless ($sender eq "<>"); # # Get the recipients. # my @to = $transaction->recipients || (); return DECLINED unless (scalar @to > 1); # # OK at this point we know: # # 1. It is a bounce, via the null-envelope. # 2. It is a bogus bounce, because there are more than one recipients. # if (lc $self->{_action} eq "log") { $self->log(LOGWARN, $self->plugin_name() . " bogus bounce for :" . join(",", @to)); } elsif (lc $self->{_action} eq "deny") { return (DENY, $self->plugin_name() . " determined this to be a bogus bounce"); } elsif (lc $self->{_action} eq "denysoft") { return (DENYSOFT, $self->plugin_name() . " determined this to be a bogus bounce"); } else { $self->log(LOGWARN, $self->plugin_name() . " failed to determine action. bug?"); } # # All done; allow this to proceed # return DECLINED; }