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:
parent
bb75098a84
commit
2f3a326e11
@ -1003,7 +1003,7 @@ Arguments are
|
||||
my ($self, $transaction, $trace, $hook, $plugin, @log) = @_;
|
||||
# $trace: level of message, for example
|
||||
# LOGWARN, LOGDEBUG, ...
|
||||
# $hook: the hook in\/for which this logging
|
||||
# $hook: the hook in/for which this logging
|
||||
# was called
|
||||
# $plugin: the plugin calling this hook
|
||||
# @log: the log message
|
||||
@ -1174,6 +1174,37 @@ as arguments to the hook
|
||||
|
||||
=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
|
||||
|
||||
B<NOTE:> This hook is only available in qpsmtpd-async.
|
||||
|
@ -7,7 +7,7 @@ our @hooks = qw(
|
||||
logging config pre-connection connect ehlo_parse ehlo
|
||||
helo_parse helo auth_parse auth auth-plain auth-login auth-cram-md5
|
||||
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
|
||||
unrecognized_command deny ok received_line help
|
||||
);
|
||||
|
@ -502,7 +502,22 @@ sub help_respond {
|
||||
|
||||
sub noop {
|
||||
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");
|
||||
return 1;
|
||||
}
|
||||
|
||||
sub vrfy {
|
||||
|
65
plugins/noop_counter
Normal file
65
plugins/noop_counter
Normal 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
|
Loading…
Reference in New Issue
Block a user