Hello and good luck in 2007

I wanted to prepare a test box for you, that would not be a problem, but I 
could not leave it inside our network, and I don't have a separate network 
segment where I could allow you to play with root. Anyway I could prepare a 
vmware-player image if it helps debugging.

In the meantime I have prepared a patch for the bug. Currently it is for  
version 2.20-9 (debian stable). It count positive responses for each RCPT 
command, and then after DATA it reads the same amount of responses. Moreover 
I had to fix part of the server code which parses HELO/EHLO/LHLO command. It 
was broken and based the decision on the argument instead of command.

I will try to port the bugfix to version 2.30-16. I'm not sure if it will not 
break other patches added for debian package. Now I'm testing the patch on a 
server where a breakage should not be disaster.

-- 
Regards
        Vladislav Kurz

--- /usr/sbin/spampd.orig	2005-03-21 23:20:05.000000000 +0100
+++ /usr/sbin/spampd.new	2007-01-25 17:49:31.922377552 +0100
@@ -164,14 +164,18 @@
 		return 0 unless defined($_ = $self->_getline);
 		s/[\r\n]*$//;
 		$self->{state} = $_;
-		if (s/^.?he?lo\s+//i) {  # mp: find helo|ehlo|lhlo
-			# mp: determine protocol (for future use)
-			if ( /^L/i ) { 
-				$self->{proto} = "lmtp";
-			} elsif ( /^E/i ) { 
-    			$self->{proto} = "esmtp"; 
-			} else { 
-    			$self->{proto} = "smtp"; }
+		if (s/^helo\s+//i) {
+		    $self->{proto} = "smtp";
+		    s/\s*$//;
+		    s/\s+/ /g;
+		    $self->{helo} = $_;
+		} elsif (s/^ehlo\s+//i) {
+		    $self->{proto} = "esmtp";
+		    s/\s*$//;
+		    s/\s+/ /g;
+		    $self->{helo} = $_;
+		} elsif (s/^lhlo\s+//i) {
+		    $self->{proto} = "lmtp";
 		    s/\s*$//;
 		    s/\s+/ /g;
 		    $self->{helo} = $_;
@@ -591,6 +595,7 @@
 sub process_request {
   my $self = shift;
   my $msg;
+  my $rcpt_ok;
   	
   eval {
 	
@@ -687,6 +692,24 @@
 		  $self->log(2, "Destination response indicates error after DATA command"); }
 	  }
 
+	  # patch for LMTP - multiple responses after . after DATA, done by Vladislav Kurz
+	  # we have to count sucessful RCPT commands and then read the same amount of responses
+	  if ( $smtp_server->{proto} eq 'lmtp' ) {
+		if ( $smtp_server->{state} =~ /^rset/i ) { $rcpt_ok=0; }
+		if ( $smtp_server->{state} =~ /^mail/i ) { $rcpt_ok=0; }
+		if ( $smtp_server->{state} =~ /^rcpt/i and $destresp =~ /^25/ ) { $rcpt_ok++; }
+		if ( $smtp_server->{state} eq '.' ) {
+			while ( --$rcpt_ok ) {
+				$destresp = $client->hear;
+				$smtp_server->ok($destresp)
+				    or die "Error in server->ok(client->hear): $!";
+				if ( $self->{spampd}->{debug} ) {
+				    $self->log(2, "Destination response: '" . $destresp . "'");
+				}
+			}
+		}
+	  }
+
 	  # restart the timeout alarm  
 	  alarm($timeout);
 		

Reply via email to