karma: limit rcpts to 1 for senders with neg karma

This commit is contained in:
Matt Simerson 2013-04-24 16:30:28 -04:00
parent bbc6e895cc
commit eccaf17d18

View File

@ -244,9 +244,10 @@ sub register {
#$self->prune_db(); # keep the DB compact
$self->register_hook('connect', 'connect_handler');
$self->register_hook('rcpt_pre', 'rcpt_handler');
$self->register_hook('data', 'data_handler');
$self->register_hook('data_post', 'data_handler');
$self->register_hook('disconnect', 'disconnect_handler');
$self->register_hook('received_line', 'rcpt_handler');
}
sub hook_pre_connection {
@ -256,8 +257,6 @@ sub hook_pre_connection {
my $remote_ip = $args{remote_ip};
#my $max_conn = $args{max_conn_ip};
my $db = $self->get_db_location();
my $lock = $self->get_db_lock($db) or return DECLINED;
my $tied = $self->get_db_tie($db, $lock) or return DECLINED;
@ -323,28 +322,38 @@ sub connect_handler {
}
sub rcpt_handler {
my ($self, $transaction, $recipient, %args) = @_;
my ($self, $transaction, $addr) = @_;
my $recipients = scalar $self->transaction->recipients;
return DECLINED if $recipients < 2; # only one recipient
return DECLINED if $self->is_immune();
my $recipients = scalar $self->transaction->recipients or do {
$self->log(LOGDEBUG, "info, no recipient count");
return DECLINED;
};
my $history = $self->connection->notes('karma_history');
return DECLINED if $history > 0; # good history, no limit
if ( $history > 0 ) {
$self->log(LOGDEBUG, "info, good history");
return DECLINED;
};
my $karma = $self->connection->notes('karma');
return DECLINED if $karma > 0; # good connection, no limit
if ( $karma > 0 ) {
$self->log(LOGDEBUG, "info, good connection");
return DECLINED;
};
# limit # of recipients if host has negative or unknown karma
return $self->get_reject("too many recipients");
return (DENY, "too many recipients for karma $karma (h: $history)");
}
sub data_handler {
my ($self, $transaction) = @_;
if ( $self->qp->connection->relay_client ) {
$self->adjust_karma(5); # big karma boost for authenticated user/IP
};
return DECLINED if $self->is_immune();
return DECLINED if $self->is_naughty(); # let naughty do it
# cutting off a naughty sender at DATA prevents having to receive the message
my $karma = $self->connection->notes('karma');
if ( $karma < -3 ) { # bad karma
return $self->get_reject("very bad karma: $karma");