cvs commit: qpsmtpd/plugins check_earlytalker
[email protected] (Devin Carraway)
| Newsgroups | perl.cvs.qpsmtpd |
|---|---|
| Message-ID | <[email protected]> |
cvsuser 04/08/01 00:08:07
Modified: plugins check_earlytalker
Log:
Incorporate suggestions and part of a patch from Mark Powell:
- Make the awkward silence at connection configurable (default still 1sec)
- Add an option to defer reaction to the HELO to the MAIL-FROM command
instead, anticipating broken SMTP agents that don't gracefully handle
disconnection after greeting.
Also made the specific response configurable (soft, hard, nothing).
Revision Changes Path
1.3 +76 -15 qpsmtpd/plugins/check_earlytalker
Index: check_earlytalker
===================================================================
RCS file: /cvs/public/qpsmtpd/plugins/check_earlytalker,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -w -r1.2 -r1.3
--- check_earlytalker 5 Mar 2004 12:46:24 -0000 1.2
+++ check_earlytalker 1 Aug 2004 07:08:07 -0000 1.3
@@ -4,28 +4,68 @@
=head1 DESCRIPTION
-Hooks connect, checks to see if the remote host starts talking before
-we've issued a 2xx greeting. If so, we're likely looking at a
-direct-to-MX spam agent which pipelines its entire SMTP conversation,
-and will happily dump an entire spam into our mail log even if later
-tests deny acceptance.
+Checks to see if the remote host starts talking before we've issued a 2xx
+greeting. If so, we're likely looking at a direct-to-MX spam agent which
+pipelines its entire SMTP conversation, and will happily dump an entire spam
+into our mail log even if later tests deny acceptance.
-Such clients gets a 450 error code.
+Depending on configuration, clients which behave in this way are either
+immediately disconnected with a deny or denysoft code, or else are issued this
+on all mail/rcpt commands in the transaction.
-=head1 TODO
+=head1 CONFIGURATION
-Make how long we wait before reading from the socket configurable
-(currently 1 second)
+=over 4
-Make the soft/hard response code configurable (currently DENYSOFT)
+=item wait [integer]
+
+The number of seconds to delay the initial greeting to see if the connecting
+host speaks first. The default is 1.
+
+=item action [string: deny, denysoft, log]
+
+What to do when matching an early-talker -- the options are I<deny>,
+I<denysoft> or I<log>.
+
+If I<log> is specified, the connection will be allowed to proceed as normal,
+and only a warning will be logged.
+
+The default is I<denysoft>.
+
+=item defer-reject [boolean]
+
+When an early-talker is detected, if this option is set to a true value, the
+SMTP greeting will be issued as usual, but all RCPT/MAIL commands will be
+issued a deny or denysoft (depending on the value of I<action>). The default
+is to react at the SMTP greeting stage by issuing the apropriate response code
+and terminating the SMTP connection.
+
+=back
=cut
use IO::Select;
+use warnings;
+use strict;
+
sub register {
- my ($self, $qp) = @_;
+ my ($self, $qp, @args) = @_;
+
+ if (@args % 2) {
+ $self->log(LOGERROR, "Unrecognized/mismatched arguments");
+ return undef;
+ }
+ $self->{_args} = {
+ 'wait' => 1,
+ 'action' => 'denysoft',
+ 'defer-reject' => 0,
+ @args,
+ };
$self->register_hook('connect', 'connect_handler');
+ $self->register_hook('mail', 'mail_handler')
+ if $self->{_args}->{'defer-reject'};
+ 1;
}
sub connect_handler {
@@ -33,10 +73,31 @@
my $in = new IO::Select;
$in->add(\*STDIN) || return DECLINED;
- if ($in->can_read(1)) {
- $self->log(LOGDEBUG, "remote host started talking before we said hello");
- return (DENYSOFT, "Don't be rude and talk before I say hello!");
+ if ($in->can_read($self->{_args}->{'wait'})) {
+ $self->log(LOGNOTICE, 'remote host started talking before we said hello');
+ if ($self->{_args}->{'defer-reject'}) {
+ $self->qp->connection->notes('earlytalker', 1);
+ } else {
+ my $msg = 'Connecting host started transmitting before SMTP greeting';
+ return (DENY,$msg) if $self->{_args}->{'action'} eq 'deny';
+ return (DENYSOFT,$msg) if $self->{_args}->{'action'} eq 'denysoft';
+ }
+ } else {
+ $self->log(LOGINFO, 'remote host said nothing spontaneous, proceeding');
}
- $self->log(LOGINFO,"remote host said nothing spontaneous, proceeding");
return DECLINED;
}
+
+sub mail_handler {
+ my ($self, $txn) = @_;
+ my $msg = 'Connecting host started transmitting before SMTP greeting';
+
+ return DECLINED unless $self->qp->connection->notes('earlytalker');
+ return (DENY,$msg) if $self->{_args}->{'action'} eq 'deny';
+ return (DENYSOFT,$msg) if $self->{_args}->{'action'} eq 'denysoft';
+ return DECLINED;
+}
+
+
+1;
+