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);