#!perl -w =head1 NAME count_unrecognized_commands - Count unrecognized commands and disconnect when we have too many =head1 DESCRIPTION Disconnect the client if it sends too many unrecognized commands. Good for rejecting spam sent through open HTTP proxies. =head1 CONFIGURATION Takes one parameter, the number of allowed unrecognized commands before we disconnect the client. Defaults to 4. =cut use strict; use warnings; use Qpsmtpd::Constants; sub register { my ($self, $qp ) = shift, shift; $self->{_unrec_cmd_max} = shift || 4; if ( scalar @_ ) { $self->log(LOGWARN, "Ignoring additional arguments."); } } sub hook_connect { my $self = shift; $self->qp->connection->notes('unrec_cmd_count', 0); return DECLINED; } sub hook_unrecognized_command { my ($self, $cmd) = @_[0,2]; $self->log(LOGINFO, "Unrecognized command '$cmd'"); my $badcmdcount = $self->qp->connection->notes( 'unrec_cmd_count', ($self->qp->connection->notes('unrec_cmd_count') || 0) + 1 ); if ($badcmdcount >= $self->{_unrec_cmd_max}) { my $msg = "Closing connection, $badcmdcount unrecognized commands."; $self->log(LOGINFO, "fail: $msg"); return (DENY_DISCONNECT, "$msg Perhaps you should read RFC 2821?"); } return DECLINED; }