Been having some issues where a connection would be killed by DENY or
DENYSOFT in the rcpto stage and yet qpsmtpd would allow the sender to
continue issuing commands and still accept the email.  I've thrown together
a quick little patch that implements a {_killed} variable based on the code
to $self->respond.  If the code is 4xx or 5xx then _killed gets set and no
other commands are taken by read_input except for quit.  It's working here
just fine it seems but if anybody has any problems or comments with it let
me know.  The diff is against svn 790.


-- 
Ed McLain
Sr. Data Center Engineer
TekLinks, Inc.
205.314.6634
[EMAIL PROTECTED]

diff -ur /tmp/qpsmtpd/lib/Qpsmtpd/ConfigServer.pm ./Qpsmtpd/ConfigServer.pm
--- /tmp/qpsmtpd/lib/Qpsmtpd/ConfigServer.pm    1969-12-31 18:00:00.000000000 
-0600
+++ ./Qpsmtpd/ConfigServer.pm   2007-09-07 12:22:10.279931000 -0500
@@ -15,6 +15,7 @@
     _transaction
     _test_mode
     _extras
+    _killed
     other_fds
 );
 
diff -ur /tmp/qpsmtpd/lib/Qpsmtpd/PollServer.pm ./Qpsmtpd/PollServer.pm
--- /tmp/qpsmtpd/lib/Qpsmtpd/PollServer.pm      1969-12-31 18:00:00.000000000 
-0600
+++ ./Qpsmtpd/PollServer.pm     2007-09-07 12:23:03.059229500 -0500
@@ -28,6 +28,7 @@
     _test_mode
     _extras
     _continuation
+    _killed
 );
 use Qpsmtpd::Constants;
 use Qpsmtpd::Address;
diff -ur /tmp/qpsmtpd/lib/Qpsmtpd/TcpServer/Prefork.pm 
./Qpsmtpd/TcpServer/Prefork.pm
--- /tmp/qpsmtpd/lib/Qpsmtpd/TcpServer/Prefork.pm       1969-12-31 
18:00:00.000000000 -0600
+++ ./Qpsmtpd/TcpServer/Prefork.pm      2007-09-07 13:15:34.930217500 -0500
@@ -30,9 +30,13 @@
       alarm 0;
       $_ =~ s/\r?\n$//s; # advanced chomp
       $self->log(LOGINFO, "dispatching $_");
-      $self->connection->notes('original_string', $_);
-      defined $self->dispatch(split / +/, $_, 2)
-        or $self->respond(502, "command unrecognized: '$_'");
+      if ( $self->{_killed} and $self->{_killed} eq 1 and $_ !~ m/quit/i ) {
+        $self->respond(502, "Connection killed.  Reconnect to send new 
email.");
+      } else {
+        $self->connection->notes('original_string', $_);
+        defined $self->dispatch(split / +/, $_, 2)
+          or $self->respond(502, "command unrecognized: '$_'");
+      }
       alarm $timeout;
     }
   };
@@ -46,6 +50,7 @@

 sub respond {
   my ($self, $code, @messages) = @_;
+  $self->{_killed} = 1 if $code =~ /[4|5]\d\d/;
   while (my $msg = shift @messages) {
     my $line = $code . (@messages?"-":" ").$msg;
     $self->log(LOGINFO, $line);
diff -ur /tmp/qpsmtpd/lib/Qpsmtpd/TcpServer.pm ./Qpsmtpd/TcpServer.pm
--- /tmp/qpsmtpd/lib/Qpsmtpd/TcpServer.pm       1969-12-31 18:00:00.000000000 
-0600
+++ ./Qpsmtpd/TcpServer.pm      2007-09-07 13:15:10.472689000 -0500
@@ -93,9 +93,13 @@
     alarm 0;
     $_ =~ s/\r?\n$//s; # advanced chomp
     $self->log(LOGINFO, "dispatching $_");
-    $self->connection->notes('original_string', $_);
-    defined $self->dispatch(split / +/, $_, 2)
-      or $self->respond(502, "command unrecognized: '$_'");
+    if ( $self->{_killed} and $self->{_killed} eq 1 and $_ !~ m/quit/i ) {
+      $self->respond(502, "Connection killed.  Reconnect to send new email.");
+    } else {
+      $self->connection->notes('original_string', $_);
+      defined $self->dispatch(split / +/, $_, 2)
+        or $self->respond(502, "command unrecognized: '$_'");
+    }
     alarm $timeout;
   }
   alarm(0);
@@ -104,6 +108,7 @@
 sub respond {
   my ($self, $code, @messages) = @_;
   my $buf = '';
+  $self->{_killed} = 1 if $code =~ /[4|5]\d\d/;
   while (my $msg = shift @messages) {
     my $line = $code . (@messages?"-":" ").$msg;
     $self->log(LOGINFO, $line);

Reply via email to