Philip Paeps:
> On 2019-10-13 13:29:27 (-0700), Wietse Venema wrote:
> > Philip Paeps:
> >> I've started noticing messages like these in my logs and the logs on 
> >> mx1.FreeBSD.org in recent months:
> >>
> >> Oct 13 00:58:21 rincewind postfix/postscreen[76460]: COMMAND 
> >> PIPELINING from [46.101.147.153]:59818 after BDAT: DKIM-Signature: 
> >> v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=masozm.com;\r\n\t 
> >> s=mail; h=Content-
> >> ...
> >
> > There are two problems: one is big and one is small.
> >
> > The big problem: it is a PROTOCOL ERROR when the remote SMTP client 
> > sends a BDAT (or DATA) command, because postscreen rejects all RCPT TO 
> > commands, and does not announce PIPELINING support.
> >
> > So no matter what, this client should not pass strict postscreen 
> > protocol enforcement.
> 
> I'll see if I can find an appropriate Exim mailing list to post this on. 
>   Or is there an Exim lurker on postfix-users who can pick this up? ;-)

I have filed a bug, and forgot to write down the number.

> > The small problem: the 20180903 patch incorrectly fixes a misleading 
> > warning message; it tests the right flag, but in the wrong variable.  
> > If I fix this, then postscreen in strict protocol mode should still 
> > flag Exim's behavior as a protocol error.
> 
> Better error/warning messages are always appreciated. :)  Even if they 
> don't make the real problem go away, they might make it slightly easier 
> to identify.

I have a fix (attached) that no longer flags this as a PIPELINING
error (because it isn't). It just logs "BDAT without valid RCPT"
without blocking mail.

> >> I've turned postscreen_pipelining_enable off on mx1.FreeBSD.org for 
> >> the time being because it was getting a lot of legitimate email 
> >> deferred (and timed out).
> >
> > Another reason to turn off all 'after-220' tests is that turning on 
> > one will turn on the others, too. That may be OK when a client has 
> > already failed the 'before-220' tests, but should probably not happen 
> > otherwise.
> 
> Thanks for the suggestion and the additional context.  I've grepped 
> through my mailserver logs and the mx1.FreeBSD.org logs for the past 
> week or so and it doesn't look like the 'after-220' checks are catching 
> much spam.  Most spammers get killed by the RBL checks.

I also fixed the code that gratuitously turned on too many checks,

> I've now turned all the 'after-220' checks off again.
> 
> ```
> postscreen_bare_newline_enable = no
> postscreen_pipelining_enable = no
> postscreen_non_smtp_command_enable = no
> ```
> 
> Perhaps the wording of the "Important note" in POSTSCREEN_README should 
> be a little more strongly worded?

Not sure. It's already a lot of text, and adding more text 
increases the likelihood that it will be ignored.

        Wietse
diff -ur /var/tmp/postfix-3.5-20191013/HISTORY ./HISTORY
--- /var/tmp/postfix-3.5-20191013/HISTORY       2019-10-13 12:04:37.000000000 
-0400
+++ ./HISTORY   2019-10-13 18:07:20.000000000 -0400
@@ -24437,3 +24437,15 @@
        smtp/smtp_rcpt.c, tls/tls_certkey.c, util/nbbio.c,
        util/vstream_tweak.c.
 
+20191014
+
+       Bugfix (introduced: Postfix 2.8): don't gratuitously enable
+       all after-220 tests when only one such test is enabled.
+       This made selective tests impossible with 'good' clients.
+       File: postscreen/postscreen_smtpd.c.
+
+       Bugfix: the 20180903 fix for a misleading "PIPELINING after
+       BDAT" warning looked at the wrong variable. The warning
+       now says "BDAT without valid RCPT", and the error is no
+       longer treated as a command PIPELINING error. File:
+       postscreen/postscreen_smtpd.c.
diff -ur /var/tmp/postfix-3.5-20191013/src/postscreen/postscreen_smtpd.c 
./src/postscreen/postscreen_smtpd.c
--- /var/tmp/postfix-3.5-20191013/src/postscreen/postscreen_smtpd.c     
2019-10-13 11:32:18.000000000 -0400
+++ ./src/postscreen/postscreen_smtpd.c 2019-10-13 18:11:52.000000000 -0400
@@ -591,6 +591,8 @@
      * never see DATA from a legitimate client, because 1) the server rejects
      * every recipient, and 2) the server does not announce PIPELINING.
      */
+    msg_info("DATA without valid RCPT from [%s]:%s",
+            PSC_CLIENT_ADDR_PORT(state), cmd);
     if (PSC_SMTPD_NEXT_TOKEN(args) != 0)
        PSC_CLEAR_EVENT_DROP_SESSION_STATE(state,
                                           psc_smtpd_time_event,
@@ -620,6 +622,8 @@
      * client, because 1) the server rejects every recipient, and 2) the
      * server does not announce PIPELINING.
      */
+    msg_info("BDAT without valid RCPT from [%s]:%s",
+            PSC_CLIENT_ADDR_PORT(state), cmd);
     if (state->ehlo_discard_mask & EHLO_MASK_CHUNKING)
        PSC_CLEAR_EVENT_DROP_SESSION_STATE(state,
                                           psc_smtpd_time_event,
@@ -1033,7 +1037,7 @@
            }
        }
        /* Command PIPELINING test. */
-       if ((state->flags & PSC_SMTPD_CMD_FLAG_HAS_PAYLOAD) == 0
+       if ((cmdp->flags & PSC_SMTPD_CMD_FLAG_HAS_PAYLOAD) == 0
            && (state->flags & PSC_STATE_MASK_PIPEL_TODO_SKIP)
            == PSC_STATE_FLAG_PIPEL_TODO && !PSC_SMTPD_BUFFER_EMPTY(state)) {
            printable(command, '?');
@@ -1172,16 +1176,17 @@
     state->read_state = PSC_SMTPD_CMD_ST_ANY;
 
     /*
-     * Opportunistically make postscreen more useful by turning on the
-     * pipelining and non-SMTP command tests when a pre-handshake test
-     * failed, or when some deep test is configured as enabled.
+     * Disable all after-220 tests when we need to hang up immediately after
+     * reading the first SMTP client command.
      * 
-     * XXX Make "opportunistically" configurable for each test.
+     * Opportunistically make postscreen more useful, by turning on all
+     * after-220 tests when a pre-handshake test failed. Do not turn on
+     * additional tests when some deep test is configured as enabled.
      */
-    if ((state->flags & PSC_STATE_FLAG_SMTPD_X21) == 0) {
-       state->flags |= PSC_STATE_MASK_SMTPD_TODO;
-    } else {
+    if (state->flags & PSC_STATE_FLAG_SMTPD_X21) {
        state->flags &= ~PSC_STATE_MASK_SMTPD_TODO;
+    } else if (state->flags & PSC_STATE_MASK_ANY_FAIL) {
+       state->flags |= PSC_STATE_MASK_SMTPD_TODO;
     }
 
     /*

Reply via email to