unrecognized_command hook and a count_unrecognized_commands

plugin. (Rasjid Wilcox)


git-svn-id: https://svn.perl.org/qpsmtpd/trunk@134 958fd67b-6ff1-0310-b445-bb7760255be9
This commit is contained in:
Ask Bjørn Hansen 2003-04-15 17:39:03 +00:00
parent 22ca786bac
commit f27b77ae61
5 changed files with 74 additions and 2 deletions

View File

@ -1,5 +1,8 @@
0.26-dev
unrecognized_command hook and a count_unrecognized_commands
plugin. (Rasjid Wilcox)
check_earlytalker plugin. Deny the connection if the client talks
before we show our SMTP banner. (From Devin Carraway)

View File

@ -125,6 +125,14 @@ Called on "helo" from the client.
DECLINED - Qpsmtpd will send the standard HELO message
=head2 unrecognized_command
Called when we get a command that isn't recognized.
DENY - Return 521 and disconnect the client
DONE - Qpsmtpd won't do anything; the plugin responded
Anything else - Return '500 Unrecognized command'
=head2 disconnect
Called just before we shutdown a connection.

View File

@ -9,6 +9,8 @@
quit_fortune
#check_earlytalker
count_unrecognized_commands 4
require_resolvable_fromhost
rhsbl

View File

@ -46,8 +46,20 @@ sub dispatch {
#$self->respond(553, $state{dnsbl_blocked}), return 1
# if $state{dnsbl_blocked} and ($cmd eq "rcpt");
$self->respond(500, "Unrecognized command"), return 1
if ($cmd !~ /^(\w{1,12})$/ or !exists $self->{_commands}->{$1});
if ($cmd !~ /^(\w{1,12})$/ or !exists $self->{_commands}->{$1}) {
my ($rc, $msg) = $self->run_hooks("unrecognized_command", $cmd);
if ($rc == DENY) {
$self->respond(521, $msg);
$self->disconnect;
}
elsif ($rc == DONE) {
1;
}
else {
$self->respond(500, "Unrecognized command");
}
return 1
}
$cmd = $1;
if (1 or $self->{_commands}->{$cmd} and $self->can($cmd)) {

View File

@ -0,0 +1,47 @@
=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
sub register {
my ($self, $qp, @args) = @_;
$self->register_hook("unrecognized_command", "check_unrec_cmd");
if (@args > 0) {
$self->{_unrec_cmd_max} = $args[0];
$self->log(1, "WARNING: Ignoring additional arguments.") if (@args > 1);
} else {
$self->{_unrec_cmd_max} = 4;
}
$self->{_unrec_cmd_count} = 0;
}
sub check_unrec_cmd {
my ($self, $transaction, $cmd) = @_;
$self->log(5, "Unrecognized command '$cmd'");
$self->{_unrec_cmd_count}++;
my $badcmdcount = $self->{_unrec_cmd_count};
if ($badcmdcount >= $self->{_unrec_cmd_max}) {
$self->log(5, "Closing connection. Too many unrecognized commands.");
return (DENY, "Closing connection. $badcmdcount unrecognized commands. Perhaps you should read RFC 2821?");
}
return DECLINED;
}