Hi,
The following patch rejects mail that contains either a bare line-feed
or bare carriage-return.  However, this test is only performed in the
header section of the message.  I'm sure it could be extended to the
whole mail message, but I thought I would start safe to begin with.

This patch also replaces the 451 response code when disconnection,
with the proper 421 response code.  Finally, I renamed the @header
variable to @headers so that it isn't confused with the $header
object.

As always, the patch can be downloaded from:

http://www.flarenet.com/consulting/software/qpsmtpd/lib.qpsmtpd.smtp.reject-bare-crlf.patch

        -- Robert

Index: lib/Qpsmtpd/SMTP.pm
===================================================================
RCS file: /cvs/public/qpsmtpd/lib/Qpsmtpd/SMTP.pm,v
retrieving revision 1.21
diff -u -r1.21 SMTP.pm
--- lib/Qpsmtpd/SMTP.pm 3 Dec 2003 20:58:30 -0000       1.21
+++ lib/Qpsmtpd/SMTP.pm 30 Dec 2003 19:27:00 -0000
@@ -348,15 +348,35 @@
   while (<STDIN>) {
     $complete++, last if $_ eq ".\r\n";
     $i++;
-    $self->respond(451, "See http://develooper.com/code/qpsmtpd/barelf.html";), exit
-      if $_ eq ".\n";
+
+    if ($_ eq "\n") {
+      $self->respond(421, "See http://develooper.com/code/qpsmtpd/barelf.html";);
+      return $self->disconnect;
+    }
+
+    #
+    # Reject messages that have either bare LF or CR when we're in the
+    # header portion.  This could be extended to the entire body, but
+    # this is a good first step.  I've noticed a lot of spam that is
+    # malformed in the header.
+    #
+    # NOTE: I'm using zero-width negative look-ahead and look-behind
+    # assertions to match the patterns.  See "perlre" for more
+    # information. - rjkaes
+    #
+    if ($in_header and m/(?:\r(?!\n))|(?:(?<!\r)\n)/) {
+         $self->respond(421, "Bare LF and CR are not allowed.  See Section 2.3.7 of 
http://www.faqs.org/rfcs/rfc2821.html";);
+         return $self->disconnect;
+
+    }
+
     # add a transaction->blocked check back here when we have line by line plugin 
access...
     unless (($max_size and $size > $max_size)) {
       s/\r\n$/\n/;
       s/^\.\./\./;
       if ($in_header and m/^\s*$/) {
        $in_header = 0;
-       my @header = split /^/m, $buffer;
+       my @headers = split /^/m, $buffer;
 
        # ... need to check that we don't reformat any of the received lines.
        #
@@ -365,7 +385,7 @@
        #   gateway MUST prepend a Received: line, but it MUST NOT alter in any
        #   way a Received: line that is already in the header.
 
-       $header->extract([EMAIL PROTECTED]);
+       $header->extract([EMAIL PROTECTED]);
        #$header->add("X-SMTPD", "qpsmtpd/".$self->version.", 
http://develooper.com/code/qpsmtpd/";);
 
        $buffer = "";


-- 
    Robert James Kaes    ---  Flarenet Inc.  ---    (519) 426-3782
                 http://www.flarenet.com/consulting/
      * Putting the Service Back in Internet Service Provider *

Reply via email to