Pluggable hook "noop" with example plugin (noop_counter) and doc update.

... now check_earlytalker can be expanded to VRFY and NOOP (see RFC 1854, #2.1)


git-svn-id: https://svn.perl.org/qpsmtpd/trunk@836 958fd67b-6ff1-0310-b445-bb7760255be9
This commit is contained in:
Hanno Hecker 2008-01-24 18:43:34 +00:00
parent bb75098a84
commit 2f3a326e11
4 changed files with 113 additions and 2 deletions

View File

@ -1003,7 +1003,7 @@ Arguments are
my ($self, $transaction, $trace, $hook, $plugin, @log) = @_; my ($self, $transaction, $trace, $hook, $plugin, @log) = @_;
# $trace: level of message, for example # $trace: level of message, for example
# LOGWARN, LOGDEBUG, ... # LOGWARN, LOGDEBUG, ...
# $hook: the hook in\/for which this logging # $hook: the hook in/for which this logging
# was called # was called
# $plugin: the plugin calling this hook # $plugin: the plugin calling this hook
# @log: the log message # @log: the log message
@ -1174,6 +1174,37 @@ as arguments to the hook
=pod =pod
=head2 hook_noop
If the client sents the B<NOOP> command, this hook is called. Default is to
return C<250 OK>.
Allowed return codes are:
=over 4
=item DONE
Plugin gave the answer
=item DENY_DISCONNECT
Return error code and disconnect client
=item DENY
Return error code.
=item Anything Else...
Give the default answer of B<250 OK>.
=back
Arguments are
my ($self,$transaction,@args) = @_;
=head2 hook_post_fork =head2 hook_post_fork
B<NOTE:> This hook is only available in qpsmtpd-async. B<NOTE:> This hook is only available in qpsmtpd-async.

View File

@ -7,7 +7,7 @@ our @hooks = qw(
logging config pre-connection connect ehlo_parse ehlo logging config pre-connection connect ehlo_parse ehlo
helo_parse helo auth_parse auth auth-plain auth-login auth-cram-md5 helo_parse helo auth_parse auth auth-plain auth-login auth-cram-md5
rcpt_parse rcpt_pre rcpt mail_parse mail mail_pre rcpt_parse rcpt_pre rcpt mail_parse mail mail_pre
data data_post queue_pre queue queue_post vrfy data data_post queue_pre queue queue_post vrfy noop
quit reset_transaction disconnect post-connection quit reset_transaction disconnect post-connection
unrecognized_command deny ok received_line help unrecognized_command deny ok received_line help
); );

View File

@ -502,7 +502,22 @@ sub help_respond {
sub noop { sub noop {
my $self = shift; my $self = shift;
$self->run_hooks("noop");
}
sub noop_respond {
my ($self, $rc, $msg, $args) = @_;
return 1 if $rc == DONE;
if ($rc == DENY || $rc == DENY_DISCONNECT) {
$msg->[0] ||= "Stop wasting my time."; # FIXME: better default message?
$self->respond(500, @$msg);
$self->disconnect if $rc == DENY_DISCONNECT;
return 1;
}
$self->respond(250, "OK"); $self->respond(250, "OK");
return 1;
} }
sub vrfy { sub vrfy {

65
plugins/noop_counter Normal file
View File

@ -0,0 +1,65 @@
#
#
#
=head1 NAME
noop_counter - disconnect after too many consecutive NOOPs, example plugin for the hook_noop()
=head1 DESCRIPTION
The B<noop_counter> counts the number of consecutive C<NOOP> commands given
by a client and disconnects after a given number.
Any other command than a C<NOOP> resets the counter.
One argument may be given: the number of C<NOOP>s after which the client will
be disconnected.
=head1 NOTE
This plugin should be loaded early to be able to reset the counter on any other
command.
=cut
sub register {
my ($self, $qp, @args) = @_;
$self->{_noop_count} = 0;
$self->{_max_noop} = 3;
if ($args[0] && $args[0] =~ /^\d+$/) {
$self->{_max_noop} = shift @args;
}
}
sub hook_noop {
my ($self, $transaction, @args) = @_;
++$self->{_noop_count};
### the following block is not used, RFC 2821 says we SHOULD ignore
### any arguments... so we MAY return an error if we want to :-)
# return (DENY, "Syntax error, NOOP does not take any arguments")
# if $args[0];
if ($self->{_noop_count} >= $self->{_max_noop}) {
return (DENY_DISCONNECT,
"Stop wasting my time, too many consecutive NOOPs");
}
return (DECLINED);
}
sub reset_noop_counter {
$_[0]->{_noop_count} = 0;
return (DECLINED);
}
# and bind the counter reset to the hooks, QUIT not useful here:
*hook_helo = *hook_ehlo = # HELO / EHLO
*hook_mail = # MAIL FROM:
*hook_rcpt = # RCPT TO:
*hook_data = # DATA
*hook_reset_transaction = # RSET
*hook_vrfy = # VRFY
*hook_help = # HELP
\&reset_noop_counter;
# vim: ts=4 sw=4 expandtab syn=perl