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) = @_;
|
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.
|
||||||
|
@ -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
|
||||||
);
|
);
|
||||||
|
@ -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
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