[exim-cvs] Reject "dot, LF" as ending data phase. Bug 3063

Página Inicial
Delete this message
Reply to this message
Autor: Exim Git Commits Mailing List
Data:  
Para: exim-cvs
Assunto: [exim-cvs] Reject "dot, LF" as ending data phase. Bug 3063
Gitweb: https://git.exim.org/exim.git/commitdiff/cf1376206284f2a4f11e32d931d4aade34c206c5
Commit:     cf1376206284f2a4f11e32d931d4aade34c206c5
Parent:     322ae953e144d9e1fdc06d993d2e4551f5fb1322
Author:     Jeremy Harris <jgh146exb@???>
AuthorDate: Fri Dec 22 23:57:05 2023 +0000
Committer:  Jeremy Harris <jgh146exb@???>
CommitDate: Fri Dec 22 23:57:05 2023 +0000


    Reject "dot, LF" as ending data phase.  Bug 3063
---
 doc/doc-txt/ChangeLog |  8 ++++++++
 src/src/receive.c     | 16 ++++++++++++----
 src/src/smtp_in.c     | 11 +++++++----
 3 files changed, 27 insertions(+), 8 deletions(-)


diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog
index c46f3b8c0..56b0aca9b 100644
--- a/doc/doc-txt/ChangeLog
+++ b/doc/doc-txt/ChangeLog
@@ -58,6 +58,14 @@ JH/11 Bug 3046: Fix queue-runs.  Previously, the arrivel of a notification or
       the latter being missed, and no further queue scheduled runs being
       initiated.  This ouwld be more likely on high-load systems.


+JH/12 Enforce a data synch check before emitting the 354 "go ahead".  Previously
+      this was only done if a pre-data ACL was configured.
+
+JH/13 Refuse to accept a line "dot, LF" as end-of-DATA unless operating in
+      LF-only mode (as detected from the first header line).  Previously we did
+      accept that in (normal) CRLF mode; this has been raised as a possible
+      attack scenario (under the name "smtp smuggling").
+



Exim version 4.97
diff --git a/src/src/receive.c b/src/src/receive.c
index e35400aec..c6f612832 100644
--- a/src/src/receive.c
+++ b/src/src/receive.c
@@ -1960,8 +1960,10 @@ for (;;)

   if (ch == '\n')
     {
-    if (first_line_ended_crlf == TRUE_UNSET) first_line_ended_crlf = FALSE;
-      else if (first_line_ended_crlf) receive_ungetc(' ');
+    if (first_line_ended_crlf == TRUE_UNSET)
+      first_line_ended_crlf = FALSE;
+    else if (first_line_ended_crlf)
+      receive_ungetc(' ');
     goto EOL;
     }


@@ -1970,6 +1972,7 @@ for (;;)
   This implements the dot-doubling rule, though header lines starting with
   dots aren't exactly common. They are legal in RFC 822, though. If the
   following is CRLF or LF, this is the line that that terminates the
+
   entire message. We set message_ended to indicate this has happened (to
   prevent further reading), and break out of the loop, having freed the
   empty header, and set next = NULL to indicate no data line. */
@@ -1977,7 +1980,11 @@ for (;;)
   if (f.dot_ends && ptr == 0 && ch == '.')
     {
     ch = (receive_getc)(GETC_BUFFER_UNLIMITED);
-    if (ch == '\r')
+    if (ch == '\n' && first_line_ended_crlf == TRUE /* and not TRUE_UNSET */ )
+            /* dot, LF  but we are in CRLF mode.  Attack? */
+      ch = ' ';    /* replace the LF with a space */
+
+    else if (ch == '\r')
       {
       ch = (receive_getc)(GETC_BUFFER_UNLIMITED);
       if (ch != '\n')
@@ -2013,7 +2020,8 @@ for (;;)
     ch = (receive_getc)(GETC_BUFFER_UNLIMITED);
     if (ch == '\n')
       {
-      if (first_line_ended_crlf == TRUE_UNSET) first_line_ended_crlf = TRUE;
+      if (first_line_ended_crlf == TRUE_UNSET)
+    first_line_ended_crlf = TRUE;
       goto EOL;
       }


diff --git a/src/src/smtp_in.c b/src/src/smtp_in.c
index e19c86ff8..aeaffeb37 100644
--- a/src/src/smtp_in.c
+++ b/src/src/smtp_in.c
@@ -5105,15 +5105,18 @@ while (done <= 0)
     }


       if (chunking_state > CHUNKING_OFFERED)
-    rc = OK;            /* No predata ACL or go-ahead output for BDAT */
+    rc = OK;    /* There is no predata ACL or go-ahead output for BDAT */
       else
     {
-    /* If there is an ACL, re-check the synchronization afterwards, since the
-    ACL may have delayed.  To handle cutthrough delivery enforce a dummy call
-    to get the DATA command sent. */
+    /* If there is a predata-ACL, re-check the synchronization afterwards,
+    since the ACL may have delayed.  To handle cutthrough delivery enforce a
+    dummy call to get the DATA command sent. */


     if (!acl_smtp_predata && cutthrough.cctx.sock < 0)
+      {
+      if (!check_sync()) goto SYNC_FAILURE;
       rc = OK;
+      }
     else
       {
       uschar * acl = acl_smtp_predata ? acl_smtp_predata : US"accept";


--
## subscription configuration (requires account):
## https://lists.exim.org/mailman3/postorius/lists/exim-cvs.lists.exim.org/
## unsubscribe (doesn't require an account):
## exim-cvs-unsubscribe@???
## Exim details at http://www.exim.org/
## Please use the Wiki with this list - http://wiki.exim.org/