Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package postfix for openSUSE:Factory checked 
in at 2024-01-26 22:46:24
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/postfix (Old)
 and      /work/SRC/openSUSE:Factory/.postfix.new.1815 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "postfix"

Fri Jan 26 22:46:24 2024 rev:234 rq:1141719 version:3.8.5

Changes:
--------
--- /work/SRC/openSUSE:Factory/postfix/postfix-bdb.changes      2024-01-19 
23:01:42.868971627 +0100
+++ /work/SRC/openSUSE:Factory/.postfix.new.1815/postfix-bdb.changes    
2024-01-26 22:46:30.462556839 +0100
@@ -1,0 +2,8 @@
+Tue Jan 23 18:24:16 UTC 2024 - Arjen de Korte <suse+bu...@de-korte.org>
+
+- update to 3.8.5
+  * Security: this release improves support to defend against an email
+    spoofing attack (SMTP smuggling) on recipients at a Postfix server.
+    For background, see https://www.postfix.org/smtp-smuggling.html.
+
+-------------------------------------------------------------------
postfix.changes: same change

Old:
----
  postfix-3.8.4.tar.gz
  postfix-3.8.4.tar.gz.asc

New:
----
  postfix-3.8.5.tar.gz
  postfix-3.8.5.tar.gz.asc

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ postfix-bdb.spec ++++++
--- /var/tmp/diff_new_pack.ndWRYf/_old  2024-01-26 22:46:32.158617919 +0100
+++ /var/tmp/diff_new_pack.ndWRYf/_new  2024-01-26 22:46:32.158617919 +0100
@@ -59,7 +59,7 @@
 %endif
 %bcond_without ldap
 Name:           postfix-bdb
-Version:        3.8.4
+Version:        3.8.5
 Release:        0
 Summary:        A fast, secure, and flexible mailer
 License:        EPL-2.0 OR IPL-1.0

postfix.spec: same change
++++++ postfix-3.8.4.tar.gz -> postfix-3.8.5.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/postfix-3.8.4/HISTORY new/postfix-3.8.5/HISTORY
--- old/postfix-3.8.4/HISTORY   2023-12-21 19:37:37.000000000 +0100
+++ new/postfix-3.8.5/HISTORY   2024-01-19 16:26:29.000000000 +0100
@@ -27213,16 +27213,36 @@
        a configured recipient delimiter value. Reported by Tod
        A. Sandman. Files: proto/postconf.proto, local/local_expand.c.
 
-20231221
+20240109
 
-       Security: with "smtpd_forbid_bare_newline = yes" (default
-       "no" for Postfix < 3.9), reply with "Error: bare <LF>
-       received" and disconnect when an SMTP client sends a line
-       ending in <LF>, violating the RFC 5321 requirement that
-       lines must end in <CR><LF>. This prevents SMTP smuggling
-       attacks that target a recipient at a Postfix server. For
-       backwards compatibility, local clients are excluded by
+       Security (outbound SMTP smuggling): with the default setting
+       "cleanup_replace_stray_cr_lf = yes" Postfix will replace
+       stray <CR> or <LF> characters in message content with a
+       space character. This prevents Postfix from enabling
+       outbound (remote) SMTP smuggling, and it also makes evaluation
+       of Postfix-added DKIM etc. signatures independent from how
+       a remote mail server handles stray <CR> or <LF> characters.
+       Files: global/mail_params.h, cleanup/cleanup.c,
+       cleanup/cleanup_message.c, mantools/postlink, proto/postconf.proto.
+
+20240112
+
+       Security (inbound SMTP smuggling): with "smtpd_forbid_bare_newline
+       = normalize" (default "no" for Postfix < 3.9), the Postfix
+       SMTP server requires the standard End-of-DATA sequence
+       <CR><LF>.<CR><LF>, and otherwise allows command or message
+       content lines ending in the non-standard <LF>, processing
+       them as if the client sent the standard <CR><LF>.
+
+       The alternative setting, "smtpd_forbid_bare_newline = reject"
+       will reject any command or message that contains a bare
+       <LF>, and is more likely to cause problems with legitimate
+       clients.
+
+       For backwards compatibility, local clients are excluded by
        default with "smtpd_forbid_bare_newline_exclusions =
-       $mynetworks". Files: mantools/postlink, proto/postconf.proto,
+       $mynetworks".
+
+       Files: mantools/postlink, proto/postconf.proto,
        global/mail_params.h, global/smtp_stream.c, global/smtp_stream.h,
-       smtpd/smtpd.c.
+       smtpd/smtpd.c, smtpd/smtpd_check.[hc].
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/postfix-3.8.4/RELEASE_NOTES 
new/postfix-3.8.5/RELEASE_NOTES
--- old/postfix-3.8.4/RELEASE_NOTES     2023-12-21 19:28:49.000000000 +0100
+++ new/postfix-3.8.5/RELEASE_NOTES     2024-01-21 23:46:01.000000000 +0100
@@ -25,31 +25,104 @@
 (EPL) 2.0. Recipients can choose to take the software under the
 license of their choice. Those who are more comfortable with the
 IPL can continue with that license.
-  
-Major changes with Postfix 3.8.4
-================================
 
-Security: the Postfix SMTP server optionally disconnects a remote
-SMTP client that sends a 'bare newline' line ending in SMTP. This
-prevents an SMTP smuggling attack on recipients at a Postfix server.
-For background, see https://www.postfix.org/smtp-smuggling.html
-
-Sites concerned about SMTP smuggling attacks should enable this
-feature in Internet-facing Postfix servers. For compatibility with
-non-standard clients, Postfix by default excludes clients in
-mynetworks from this countermeasure.
-
-The default settings are:
-
-    # Optionally disconnect remote SMTP clients that send bare newlines,
-    # but allow local clients with non-standard SMTP implementations
-    # such as netcat, fax machines, or load balancer health checks.
+Incompatibility with Postfix 3.8.5, 3.7.10, 3.6.14, and 3.5.24
+==============================================================
+
+Improvements for outbound SMTP smuggling defense:
+
+- With "cleanup_replace_stray_cr_lf = yes" (the default), the cleanup
+  daemon replaces each stray <CR> or <LF> character in message
+  content with a space character. The replacement happens before
+  any other content management (header/body_checks, Milters, etc).
+
+  This prevents outbound SMTP smuggling, where an attacker uses
+  Postfix to send email containing a non-standard End-of-DATA
+  sequence, to exploit inbound SMTP smuggling at a vulnerable remote
+  SMTP server.
+
+  This also improves the remote evaluation of Postfix-added DKIM
+  and other signatures, as the evaluation result will not depend
+  on how a remote email server handles stray <CR> or <LF> characters.
+
+This feature applies to all email that Postfix locally or remotely
+sends out. It is not allowlisted based on client identity.
+
+Major changes with Postfix 3.8.5, 3.7.10, 3.6.14, and 3.5.24
+============================================================
+
+Improvements for inbound SMTP smuggling defense:
+
+- Better compatibility: the recommended setting "smtpd_forbid_bare_newline
+  = normalize" requires the standard End-of-DATA sequence
+  <CR><LF>.<CR><LF>, but allows bare newlines from SMTP clients,
+  maintaining more compatibility with existing infrastructure.
+
+- Improved logging for rejected input (it now includes queue ID,
+  helo, mail, and rcpt, if available).
+
+- The setting "smtpd_forbid_bare_newline = reject" requires
+  that input lines end in <CR><LF>, requires the standard End-of-DATA
+  sequence <CR><LF>.<CR><LF>, and rejects a command or message that
+  contains a bare newline. To disconnect the client, specify
+  "smtpd_forbid_bare_newline_reject_code = 521".
+
+- The Postfix SMTP server no longer strips extra <CR> as in
+  <CR><LF>.<CR><CR><LF>, to silence false alarms from test tools
+  that send attack sequences that real mail servers cannot send.
+  Details at https://www.postfix.org/false-smuggling-claims.html
+
+- The old setting "yes" has become an alias for "normalize".
+
+- The old setting "no" has not changed, and allows SMTP smuggling.
+
+The recommended settings are now:
+
+    # Require the standard End-of-DATA sequence <CR><LF>.<CR><LF>.
+    # Otherwise, allow bare <LF> and process it as if the client sent
+    # <CR><LF>.
+    #
+    # This maintains compatibility with many legitimate SMTP client
+    # applications that send a mix of standard and non-standard line
+    # endings, but will fail to receive email from client implementations
+    # that do not terminate DATA content with the standard End-of-DATA
+    # sequence <CR><LF>.<CR><LF>.
     #
-    smtpd_forbid_bare_newline = no
+    # Such clients can be allowlisted with 
smtpd_forbid_bare_newline_exclusions.
+    # The example below allowlists SMTP clients in trusted networks.
+    #
+    smtpd_forbid_bare_newline = normalize
     smtpd_forbid_bare_newline_exclusions = $mynetworks
 
-This feature is back-ported from Postfix 3.9, with the difference
-that "smtpd_forbid_bare_newline = no" by default.
+Alternative settings:
+
+    # Reject input lines that contain <LF> and log a "bare <LF> received"
+    # error. Require that input lines end in <CR><LF>, and require the
+    # standard End-of-DATA sequence <CR><LF>.<CR><LF>.
+    #
+    # This will reject email from SMTP clients that send any non-standard
+    # line endings such as web applications, netcat, or load balancer
+    # health checks.
+    #
+    # This will also reject email from services that use BDAT to send
+    # MIME text containing a bare newline (RFC 3030 Section 3 requires
+    # canonical MIME format for text message types, defined in RFC 2045
+    # Sections 2.7 and 2.8).
+    #
+    # Such clients can be allowlisted with 
smtpd_forbid_bare_newline_exclusions.
+    # The example below allowlists SMTP clients in trusted networks.
+    #
+    smtpd_forbid_bare_newline = reject
+    smtpd_forbid_bare_newline_exclusions = $mynetworks
+    #
+    # Alternatively, in the case of BDAT violations, BDAT can be selectively
+    # disabled with smtpd_discard_ehlo_keyword_address_maps, or globally
+    # disabled with smtpd_discard_ehlo_keywords.
+    #
+    # smtpd_discard_ehlo_keyword_address_maps = cidr:/path/to/file
+    # /path/to/file:
+    #     10.0.0.0/24 chunking, silent-discard
+    # smtpd_discard_ehlo_keywords = chunking, silent-discard
 
 Major changes with Postfix 3.8.1
 ================================
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/postfix-3.8.4/html/cleanup.8.html 
new/postfix-3.8.5/html/cleanup.8.html
--- old/postfix-3.8.4/html/cleanup.8.html       2023-03-09 00:37:29.000000000 
+0100
+++ new/postfix-3.8.5/html/cleanup.8.html       2024-01-19 17:27:58.000000000 
+0100
@@ -160,6 +160,16 @@
               The set of characters that Postfix will remove from message con-
               tent.
 
+       Available in Postfix version 3.9, 3.8.5, 3.7.10,  3.6.14,  3.5.24,  and
+       later:
+
+       <b><a 
href="postconf.5.html#cleanup_replace_stray_cr_lf">cleanup_replace_stray_cr_lf</a>
 (yes)</b>
+              Replace  each  stray  &lt;CR&gt;  or &lt;LF&gt; character in 
message content
+              with a space character, to prevent outbound SMTP smuggling,  and
+              to make the evaluation of Postfix-added DKIM or other signatures
+              independent from how a remote mail server handles  such  charac-
+              ters.
+
 <b>BEFORE QUEUE MILTER CONTROLS</b>
        As of version 2.3, Postfix supports the Sendmail version 8 Milter (mail
        filter)  protocol.  When  mail is not received via the <a 
href="smtpd.8.html">smtpd(8)</a> server,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/postfix-3.8.4/html/postconf.5.html 
new/postfix-3.8.5/html/postconf.5.html
--- old/postfix-3.8.4/html/postconf.5.html      2023-12-21 19:48:56.000000000 
+0100
+++ new/postfix-3.8.5/html/postconf.5.html      2024-01-21 23:25:57.000000000 
+0100
@@ -1465,6 +1465,40 @@
 
 </DD>
 
+<DT><b><a name="cleanup_replace_stray_cr_lf">cleanup_replace_stray_cr_lf</a>
+(default: yes)</b></DT><DD>
+
+<p> Replace each stray &lt;CR&gt; or &lt;LF&gt; character in message
+content with a space character, to prevent outbound SMTP smuggling,
+and to make the evaluation of Postfix-added DKIM or other signatures
+independent from how a remote mail server handles such characters.
+</p>
+
+<p> SMTP does not allow such characters unless they are part of a
+&lt;CR&gt;&lt;LF&gt; sequence, and different mail systems handle
+such stray characters in an implementation-dependent manner. Stray
+&lt;CR&gt; or &lt;LF&gt; characters could be used for outbound
+SMTP smuggling, where an attacker uses a Postfix server to send
+message content with a non-standard End-of-DATA sequence that
+triggers inbound SMTP smuggling at a remote SMTP server.</p>
+
+<p> The replacement happens before all other content management,
+and before Postfix may add a DKIM etc. signature; if the signature
+were created first, the replacement could invalidate the signature.
+</p>
+
+<p> In addition to preventing SMTP smuggling, replacing stray
+&lt;CR&gt; or &lt;LF&gt; characters ensures that the result of
+signature validation by later mail system will not depend on how
+that mail system handles those stray characters in an
+implementation-dependent manner. </p>
+
+<p> This feature is available in Postfix &ge; 3.9, 3.8.5, 3.7.10,
+3.6.14, and 3.5.24. </p>
+
+
+</DD>
+
 <DT><b><a name="cleanup_service_name">cleanup_service_name</a>
 (default: cleanup)</b></DT><DD>
 
@@ -15609,32 +15643,118 @@
 <DT><b><a name="smtpd_forbid_bare_newline">smtpd_forbid_bare_newline</a>
 (default: Postfix &lt; 3.9: no)</b></DT><DD>
 
-<p> Reply with "Error: bare &lt;LF&gt; received" and disconnect
-when a remote SMTP client sends a line ending in &lt;LF&gt;, violating
-the <a href="https://tools.ietf.org/html/rfc5321";>RFC 5321</a> requirement 
that lines must end in &lt;CR&gt;&lt;LF&gt;.
-This feature is disbled by default with Postfix &lt; 3.9. Use
-<a 
href="postconf.5.html#smtpd_forbid_bare_newline_exclusions">smtpd_forbid_bare_newline_exclusions</a>
 to exclude non-standard clients
-such as netcat. Specify "<a 
href="postconf.5.html#smtpd_forbid_bare_newline">smtpd_forbid_bare_newline</a> 
= no" to disable
-(not recommended for an Internet-connected MTA). </p>
+<p> Reject or restrict input lines from an SMTP client that end in
+&lt;LF&gt; instead of the standard &lt;CR&gt;&lt;LF&gt;. Such line
+endings are commonly allowed with UNIX-based SMTP servers, but they
+violate <a href="https://tools.ietf.org/html/rfc5321";>RFC 5321</a>, and 
allowing such line endings can make a server
+vulnerable to <a href="https://www.postfix.org/smtp-smuggling.html";>
+SMTP smuggling</a>.  </p>
 
-<p> See <a href="https://www.postfix.org/smtp-smuggling.html";>
-https://www.postfix.org/smtp-smuggling.html</a> for details.
+<p> Specify one of the following values (case does not matter): </p>
 
-<p> Example: </p>
+<dl compact>
+
+<dt> <b>normalize</b></dt> <dd> Require the standard
+End-of-DATA sequence &lt;CR&gt;&lt;LF&gt;.&lt;CR&gt;&lt;LF&gt;.
+Otherwise, allow command or message content lines ending in the
+non-standard &lt;LF&gt;, and process them as if the client sent the
+standard &lt;CR&gt;&lt;LF&gt;. <br> <br> This maintains compatibility
+with many legitimate SMTP client applications that send a mix of
+standard and non-standard line endings, but will fail to receive
+email from client implementations that do not terminate DATA content
+with the standard End-of-DATA sequence
+&lt;CR&gt;&lt;LF&gt;.&lt;CR&gt;&lt;LF&gt;. <br> <br> Such clients
+can be excluded with <a 
href="postconf.5.html#smtpd_forbid_bare_newline_exclusions">smtpd_forbid_bare_newline_exclusions</a>.
 </dd>
+
+<dt> <b>yes</b> </dt> <dd> Compatibility alias for <b>normalize</b>. </dd>
+
+<dt> <b>reject</b> </dt> <dd> Require the standard End-of-DATA
+sequence &lt;CR&gt;&lt;LF&gt;.&lt;CR&gt;&lt;LF&gt;. Reject a command
+or message content when a line contains bare &lt;LF&gt;, log a "bare
+&lt;LF&gt; received" error, and reply with the SMTP status code in
+$<a 
href="postconf.5.html#smtpd_forbid_bare_newline_reject_code">smtpd_forbid_bare_newline_reject_code</a>.
 <br> <br> This will reject
+email from SMTP clients that send any non-standard line endings
+such as web applications, netcat, or load balancer health checks.
+<br> <br> This will also reject email from services that use BDAT
+to send MIME text containing a bare newline (<a 
href="https://tools.ietf.org/html/rfc3030";>RFC 3030</a> Section 3
+requires canonical MIME format for text message types, defined in
+<a href="https://tools.ietf.org/html/rfc2045";>RFC 2045</a> Sections 2.7 and 
2.8). <br> <br> Such clients can be
+excluded with <a 
href="postconf.5.html#smtpd_forbid_bare_newline_exclusions">smtpd_forbid_bare_newline_exclusions</a>
 (or, in the case
+of BDAT violations, BDAT can be selectively disabled with
+<a 
href="postconf.5.html#smtpd_discard_ehlo_keyword_address_maps">smtpd_discard_ehlo_keyword_address_maps</a>,
 or globally disabled with
+<a 
href="postconf.5.html#smtpd_discard_ehlo_keywords">smtpd_discard_ehlo_keywords</a>).
 </dd>
+
+<dt> <b>no</b> (default)</dt> <dd> Do not require the standard
+End-of-DATA
+sequence &lt;CR&gt;&lt;LF&gt;.&lt;CR&gt;&lt;LF&gt;. Always process
+a bare &lt;LF&gt; as if the client sent &lt;CR&gt;&lt;LF&gt;. This
+option is fully backwards compatible, but is not recommended for
+an Internet-facing SMTP server, because it is vulnerable to <a
+href="https://www.postfix.org/smtp-smuggling.html";> SMTP smuggling</a>.
+</dd>
+
+</dl>
+
+<p> Recommended settings: </p>
 
 <blockquote>
 <pre>
-# Disconnect remote SMTP clients that send bare newlines, but allow
-# local clients with non-standard SMTP implementations such as netcat,
-# fax machines, or load balancer health checks.
+# Require the standard End-of-DATA sequence 
&lt;CR&gt;&lt;LF&gt;.&lt;CR&gt;&lt;LF&gt;.
+# Otherwise, allow bare &lt;LF&gt; and process it as if the client sent
+# &lt;CR&gt;&lt;LF&gt;.
+#
+# This maintains compatibility with many legitimate SMTP client
+# applications that send a mix of standard and non-standard line
+# endings, but will fail to receive email from client implementations
+# that do not terminate DATA content with the standard End-of-DATA
+# sequence &lt;CR&gt;&lt;LF&gt;.&lt;CR&gt;&lt;LF&gt;.
+#
+# Such clients can be allowlisted with <a 
href="postconf.5.html#smtpd_forbid_bare_newline_exclusions">smtpd_forbid_bare_newline_exclusions</a>.
+# The example below allowlists SMTP clients in trusted networks.
 #
-<a 
href="postconf.5.html#smtpd_forbid_bare_newline">smtpd_forbid_bare_newline</a> 
= yes
+<a 
href="postconf.5.html#smtpd_forbid_bare_newline">smtpd_forbid_bare_newline</a> 
= normalize
 <a 
href="postconf.5.html#smtpd_forbid_bare_newline_exclusions">smtpd_forbid_bare_newline_exclusions</a>
 = $<a href="postconf.5.html#mynetworks">mynetworks</a>
 </pre>
 </blockquote>
 
-<p> This feature is available in Postfix &ge; 3.9, 3.8.4, 3.7.9,
-3.6.13, and 3.5.23. </p>
+<p> Alternative: </p>
+
+<blockquote>
+<pre>
+# Reject input lines that contain &lt;LF&gt; and log a "bare &lt;LF&gt; 
received"
+# error. Require that input lines end in &lt;CR&gt;&lt;LF&gt;, and require the
+# standard End-of-DATA sequence &lt;CR&gt;&lt;LF&gt;.&lt;CR&gt;&lt;LF&gt;.
+#
+# This will reject email from SMTP clients that send any non-standard
+# line endings such as web applications, netcat, or load balancer
+# health checks.
+#
+# This will also reject email from services that use BDAT to send
+# MIME text containing a bare newline (<a 
href="https://tools.ietf.org/html/rfc3030";>RFC 3030</a> Section 3 requires
+# canonical MIME format for text message types, defined in <a 
href="https://tools.ietf.org/html/rfc2045";>RFC 2045</a>
+# Sections 2.7 and 2.8).
+#
+# Such clients can be allowlisted with <a 
href="postconf.5.html#smtpd_forbid_bare_newline_exclusions">smtpd_forbid_bare_newline_exclusions</a>.
+# The example below allowlists SMTP clients in trusted networks.
+#
+<a 
href="postconf.5.html#smtpd_forbid_bare_newline">smtpd_forbid_bare_newline</a> 
= reject
+<a 
href="postconf.5.html#smtpd_forbid_bare_newline_exclusions">smtpd_forbid_bare_newline_exclusions</a>
 = $<a href="postconf.5.html#mynetworks">mynetworks</a>
+#
+# Alternatively, in the case of BDAT violations, BDAT can be selectively
+# disabled with <a 
href="postconf.5.html#smtpd_discard_ehlo_keyword_address_maps">smtpd_discard_ehlo_keyword_address_maps</a>,
 or globally
+# disabled with <a 
href="postconf.5.html#smtpd_discard_ehlo_keywords">smtpd_discard_ehlo_keywords</a>.
+#
+# <a 
href="postconf.5.html#smtpd_discard_ehlo_keyword_address_maps">smtpd_discard_ehlo_keyword_address_maps</a>
 = <a href="cidr_table.5.html">cidr</a>:/path/to/file
+# /path/to/file:
+#     10.0.0.0/24 chunking, silent-discard
+# <a 
href="postconf.5.html#smtpd_discard_ehlo_keywords">smtpd_discard_ehlo_keywords</a>
 = chunking, silent-discard
+</pre>
+</blockquote>
+
+<p> This feature with settings <b>yes</b> and <b>no</b> is available
+in Postfix 3.8.4, 3.7.9, 3.6.13, and 3.5.23. Additionally, the
+settings <b>reject</b>, and <b>normalize</b> are available with
+Postfix &ge; 3.9, 3.8.5, 3.7.10, 3.6.14, and 3.5.24. </p>
 
 
 </DD>
@@ -15643,27 +15763,29 @@
 (default: $<a href="postconf.5.html#mynetworks">mynetworks</a>)</b></DT><DD>
 
 <p> Exclude the specified clients from <a 
href="postconf.5.html#smtpd_forbid_bare_newline">smtpd_forbid_bare_newline</a>
-enforcement. It uses the same syntax and parent-domain matching
-behavior as <a href="postconf.5.html#mynetworks">mynetworks</a>. </p>
-
-<p> Example: </p>
-
-<blockquote>
-<pre>
-# Disconnect remote SMTP clients that send bare newlines, but allow
-# local clients with non-standard SMTP implementations such as netcat,
-# fax machines, or load balancer health checks.
-#
-<a 
href="postconf.5.html#smtpd_forbid_bare_newline">smtpd_forbid_bare_newline</a> 
= yes
-<a 
href="postconf.5.html#smtpd_forbid_bare_newline_exclusions">smtpd_forbid_bare_newline_exclusions</a>
 = $<a href="postconf.5.html#mynetworks">mynetworks</a>
-</pre>
-</blockquote>
+enforcement. This setting uses the same syntax and parent-domain
+matching behavior as <a href="postconf.5.html#mynetworks">mynetworks</a>. </p>
 
 <p> This feature is available in Postfix &ge; 3.9, 3.8.4, 3.7.9,
 3.6.13, and 3.5.23. </p>
 
 
 </DD>
+
+<DT><b><a 
name="smtpd_forbid_bare_newline_reject_code">smtpd_forbid_bare_newline_reject_code</a>
+(default: 550)</b></DT><DD>
+
+<p>
+The numerical Postfix SMTP server response code when rejecting a
+request with "<a 
href="postconf.5.html#smtpd_forbid_bare_newline">smtpd_forbid_bare_newline</a> 
= reject".
+Specify a 5XX status code (521 to disconnect).
+</p>
+
+<p> This feature is available in Postfix &ge; 3.9, 3.8.5, 3.7.10,
+3.6.14, and 3.5.24. </p>
+
+
+</DD>
 
 <DT><b><a 
name="smtpd_forbid_unauth_pipelining">smtpd_forbid_unauth_pipelining</a>
 (default: Postfix &ge; 3.9: yes)</b></DT><DD>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/postfix-3.8.4/html/smtpd.8.html 
new/postfix-3.8.5/html/smtpd.8.html
--- old/postfix-3.8.4/html/smtpd.8.html 2023-12-22 15:01:21.000000000 +0100
+++ new/postfix-3.8.5/html/smtpd.8.html 2024-01-19 16:00:21.000000000 +0100
@@ -990,14 +990,19 @@
        Available in Postfix 3.9, 3.8.4, 3.7.9, 3.6.13, 3.5.23 and later:
 
        <b><a 
href="postconf.5.html#smtpd_forbid_bare_newline">smtpd_forbid_bare_newline</a> 
(Postfix</b> &lt; <b>3.9: no)</b>
-              Reply with "Error: bare &lt;LF&gt; received"  and  disconnect  
when  a
-              remote  SMTP  client  sends a line ending in &lt;LF&gt;, 
violating the
-              <a href="https://tools.ietf.org/html/rfc5321";>RFC 5321</a> 
requirement that lines must end in &lt;CR&gt;&lt;LF&gt;.
+              Reject or restrict input lines from an SMTP client that  end  in
+              &lt;LF&gt; instead of the standard &lt;CR&gt;&lt;LF&gt;.
 
        <b><a 
href="postconf.5.html#smtpd_forbid_bare_newline_exclusions">smtpd_forbid_bare_newline_exclusions</a>
 ($<a href="postconf.5.html#mynetworks">mynetworks</a>)</b>
-              Exclude the  specified  clients  from  <a 
href="postconf.5.html#smtpd_forbid_bare_newline">smtpd_forbid_bare_newline</a>
+              Exclude  the  specified  clients  from <a 
href="postconf.5.html#smtpd_forbid_bare_newline">smtpd_forbid_bare_newline</a>
               enforcement.
 
+       Available in Postfix 3.9, 3.8.5, 3.7.10, 3.6.14, 3.5.24 and later:
+
+       <b><a 
href="postconf.5.html#smtpd_forbid_bare_newline_reject_code">smtpd_forbid_bare_newline_reject_code</a>
 (550)</b>
+              The numerical Postfix SMTP server response code when rejecting a
+              request with "<a 
href="postconf.5.html#smtpd_forbid_bare_newline">smtpd_forbid_bare_newline</a> 
= reject".
+
 <b>TARPIT CONTROLS</b>
        When  a  remote  SMTP  client makes errors, the Postfix SMTP server can
        insert delays before responding. This can help to  slow  down  run-away
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/postfix-3.8.4/man/man5/postconf.5 
new/postfix-3.8.5/man/man5/postconf.5
--- old/postfix-3.8.4/man/man5/postconf.5       2023-12-21 19:48:56.000000000 
+0100
+++ new/postfix-3.8.5/man/man5/postconf.5       2024-01-21 23:25:57.000000000 
+0100
@@ -878,6 +878,32 @@
 .fi
 .ad
 .ft R
+.SH cleanup_replace_stray_cr_lf (default: yes)
+Replace each stray <CR> or <LF> character in message
+content with a space character, to prevent outbound SMTP smuggling,
+and to make the evaluation of Postfix\-added DKIM or other signatures
+independent from how a remote mail server handles such characters.
+.PP
+SMTP does not allow such characters unless they are part of a
+<CR><LF> sequence, and different mail systems handle
+such stray characters in an implementation\-dependent manner. Stray
+<CR> or <LF> characters could be used for outbound
+SMTP smuggling, where an attacker uses a Postfix server to send
+message content with a non\-standard End\-of\-DATA sequence that
+triggers inbound SMTP smuggling at a remote SMTP server.
+.PP
+The replacement happens before all other content management,
+and before Postfix may add a DKIM etc. signature; if the signature
+were created first, the replacement could invalidate the signature.
+.PP
+In addition to preventing SMTP smuggling, replacing stray
+<CR> or <LF> characters ensures that the result of
+signature validation by later mail system will not depend on how
+that mail system handles those stray characters in an
+implementation\-dependent manner.
+.PP
+This feature is available in Postfix >= 3.9, 3.8.5, 3.7.10,
+3.6.14, and 3.5.24.
 .SH cleanup_service_name (default: cleanup)
 The name of the \fBcleanup\fR(8) service. This service rewrites addresses
 into the standard form, and performs \fBcanonical\fR(5) address mapping
@@ -10727,60 +10753,153 @@
 .PP
 This feature is available in Postfix 2.0 and later.
 .SH smtpd_forbid_bare_newline (default: Postfix < 3.9: no)
-Reply with "Error: bare <LF> received" and disconnect
-when a remote SMTP client sends a line ending in <LF>, violating
-the RFC 5321 requirement that lines must end in <CR><LF>.
-This feature is disbled by default with Postfix < 3.9. Use
-smtpd_forbid_bare_newline_exclusions to exclude non\-standard clients
-such as netcat. Specify "smtpd_forbid_bare_newline = no" to disable
-(not recommended for an Internet\-connected MTA).
-.PP
-See
-https://www.postfix.org/smtp\-smuggling.html for details.
+Reject or restrict input lines from an SMTP client that end in
+<LF> instead of the standard <CR><LF>. Such line
+endings are commonly allowed with UNIX\-based SMTP servers, but they
+violate RFC 5321, and allowing such line endings can make a server
+vulnerable to
+SMTP smuggling.
+.PP
+Specify one of the following values (case does not matter):
+.IP "\fBnormalize\fR"
+Require the standard
+End\-of\-DATA sequence <CR><LF>.<CR><LF>.
+Otherwise, allow command or message content lines ending in the
+non\-standard <LF>, and process them as if the client sent the
+standard <CR><LF>.
+.br
+.br
+This maintains compatibility
+with many legitimate SMTP client applications that send a mix of
+standard and non\-standard line endings, but will fail to receive
+email from client implementations that do not terminate DATA content
+with the standard End\-of\-DATA sequence
+<CR><LF>.<CR><LF>.
+.br
+.br
+Such clients
+can be excluded with smtpd_forbid_bare_newline_exclusions.
+.br
+.IP "\fByes\fR"
+Compatibility alias for \fBnormalize\fR.
+.br
+.IP "\fBreject\fR"
+Require the standard End\-of\-DATA
+sequence <CR><LF>.<CR><LF>. Reject a command
+or message content when a line contains bare <LF>, log a "bare
+<LF> received" error, and reply with the SMTP status code in
+$smtpd_forbid_bare_newline_reject_code.
+.br
+.br
+This will reject
+email from SMTP clients that send any non\-standard line endings
+such as web applications, netcat, or load balancer health checks.
+.br
+.br
+This will also reject email from services that use BDAT
+to send MIME text containing a bare newline (RFC 3030 Section 3
+requires canonical MIME format for text message types, defined in
+RFC 2045 Sections 2.7 and 2.8).
+.br
+.br
+Such clients can be
+excluded with smtpd_forbid_bare_newline_exclusions (or, in the case
+of BDAT violations, BDAT can be selectively disabled with
+smtpd_discard_ehlo_keyword_address_maps, or globally disabled with
+smtpd_discard_ehlo_keywords).
+.br
+.IP "\fBno\fR (default)"
+Do not require the standard
+End\-of\-DATA
+sequence <CR><LF>.<CR><LF>. Always process
+a bare <LF> as if the client sent <CR><LF>. This
+option is fully backwards compatible, but is not recommended for
+an Internet\-facing SMTP server, because it is vulnerable to  SMTP smuggling.
+.br
+.br
 .PP
-Example:
+Recommended settings:
 .sp
 .in +4
 .nf
 .na
 .ft C
-# Disconnect remote SMTP clients that send bare newlines, but allow
-# local clients with non\-standard SMTP implementations such as netcat,
-# fax machines, or load balancer health checks.
+# Require the standard End\-of\-DATA sequence <CR><LF>.<CR><LF>.
+# Otherwise, allow bare <LF> and process it as if the client sent
+# <CR><LF>.
 #
-smtpd_forbid_bare_newline = yes
+# This maintains compatibility with many legitimate SMTP client
+# applications that send a mix of standard and non\-standard line
+# endings, but will fail to receive email from client implementations
+# that do not terminate DATA content with the standard End\-of\-DATA
+# sequence <CR><LF>.<CR><LF>.
+#
+# Such clients can be allowlisted with smtpd_forbid_bare_newline_exclusions.
+# The example below allowlists SMTP clients in trusted networks.
+#
+smtpd_forbid_bare_newline = normalize
 smtpd_forbid_bare_newline_exclusions = $mynetworks
 .fi
 .ad
 .ft R
 .in -4
 .PP
-This feature is available in Postfix >= 3.9, 3.8.4, 3.7.9,
-3.6.13, and 3.5.23.
-.SH smtpd_forbid_bare_newline_exclusions (default: $mynetworks)
-Exclude the specified clients from smtpd_forbid_bare_newline
-enforcement. It uses the same syntax and parent\-domain matching
-behavior as mynetworks.
-.PP
-Example:
+Alternative:
 .sp
 .in +4
 .nf
 .na
 .ft C
-# Disconnect remote SMTP clients that send bare newlines, but allow
-# local clients with non\-standard SMTP implementations such as netcat,
-# fax machines, or load balancer health checks.
+# Reject input lines that contain <LF> and log a "bare <LF> received"
+# error. Require that input lines end in <CR><LF>, and require the
+# standard End\-of\-DATA sequence <CR><LF>.<CR><LF>.
+#
+# This will reject email from SMTP clients that send any non\-standard
+# line endings such as web applications, netcat, or load balancer
+# health checks.
 #
-smtpd_forbid_bare_newline = yes
+# This will also reject email from services that use BDAT to send
+# MIME text containing a bare newline (RFC 3030 Section 3 requires
+# canonical MIME format for text message types, defined in RFC 2045
+# Sections 2.7 and 2.8).
+#
+# Such clients can be allowlisted with smtpd_forbid_bare_newline_exclusions.
+# The example below allowlists SMTP clients in trusted networks.
+#
+smtpd_forbid_bare_newline = reject
 smtpd_forbid_bare_newline_exclusions = $mynetworks
+#
+# Alternatively, in the case of BDAT violations, BDAT can be selectively
+# disabled with smtpd_discard_ehlo_keyword_address_maps, or globally
+# disabled with smtpd_discard_ehlo_keywords.
+#
+# smtpd_discard_ehlo_keyword_address_maps = cidr:/path/to/file
+# /path/to/file:
+#     10.0.0.0/24 chunking, silent\-discard
+# smtpd_discard_ehlo_keywords = chunking, silent\-discard
 .fi
 .ad
 .ft R
 .in -4
 .PP
+This feature with settings \fByes\fR and \fBno\fR is available
+in Postfix 3.8.4, 3.7.9, 3.6.13, and 3.5.23. Additionally, the
+settings \fBreject\fR, and \fBnormalize\fR are available with
+Postfix >= 3.9, 3.8.5, 3.7.10, 3.6.14, and 3.5.24.
+.SH smtpd_forbid_bare_newline_exclusions (default: $mynetworks)
+Exclude the specified clients from smtpd_forbid_bare_newline
+enforcement. This setting uses the same syntax and parent\-domain
+matching behavior as mynetworks.
+.PP
 This feature is available in Postfix >= 3.9, 3.8.4, 3.7.9,
 3.6.13, and 3.5.23.
+.SH smtpd_forbid_bare_newline_reject_code (default: 550)
+The numerical Postfix SMTP server response code when rejecting a
+request with "smtpd_forbid_bare_newline = reject".
+Specify a 5XX status code (521 to disconnect).
+.PP
+This feature is available in Postfix >= 3.9, 3.8.5, 3.7.10,
+3.6.14, and 3.5.24.
 .SH smtpd_forbid_unauth_pipelining (default: Postfix >= 3.9: yes)
 Disconnect remote SMTP clients that violate RFC 2920 (or 5321)
 command pipelining constraints. The server replies with "554 5.5.0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/postfix-3.8.4/man/man8/cleanup.8 
new/postfix-3.8.5/man/man8/cleanup.8
--- old/postfix-3.8.4/man/man8/cleanup.8        2021-10-02 17:40:28.000000000 
+0200
+++ new/postfix-3.8.5/man/man8/cleanup.8        2024-01-19 17:24:40.000000000 
+0100
@@ -165,6 +165,14 @@
 .IP "\fBmessage_strip_characters (empty)\fR"
 The set of characters that Postfix will remove from message
 content.
+.PP
+Available in Postfix version 3.9, 3.8.5, 3.7.10, 3.6.14,
+3.5.24, and later:
+.IP "\fBcleanup_replace_stray_cr_lf (yes)\fR"
+Replace each stray <CR> or <LF> character in message
+content with a space character, to prevent outbound SMTP smuggling,
+and to make the evaluation of Postfix\-added DKIM or other signatures
+independent from how a remote mail server handles such characters.
 .SH "BEFORE QUEUE MILTER CONTROLS"
 .na
 .nf
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/postfix-3.8.4/man/man8/smtpd.8 
new/postfix-3.8.5/man/man8/smtpd.8
--- old/postfix-3.8.4/man/man8/smtpd.8  2023-12-22 15:01:20.000000000 +0100
+++ new/postfix-3.8.5/man/man8/smtpd.8  2024-01-19 16:00:20.000000000 +0100
@@ -864,12 +864,17 @@
 .PP
 Available in Postfix 3.9, 3.8.4, 3.7.9, 3.6.13, 3.5.23 and later:
 .IP "\fBsmtpd_forbid_bare_newline (Postfix < 3.9: no)\fR"
-Reply with "Error: bare <LF> received" and disconnect
-when a remote SMTP client sends a line ending in <LF>, violating
-the RFC 5321 requirement that lines must end in <CR><LF>.
+Reject or restrict input lines from an SMTP client that end in
+<LF> instead of the standard <CR><LF>.
 .IP "\fBsmtpd_forbid_bare_newline_exclusions ($mynetworks)\fR"
 Exclude the specified clients from smtpd_forbid_bare_newline
 enforcement.
+.PP
+Available in Postfix 3.9, 3.8.5, 3.7.10, 3.6.14, 3.5.24 and
+later:
+.IP "\fBsmtpd_forbid_bare_newline_reject_code (550)\fR"
+The numerical Postfix SMTP server response code when rejecting a
+request with "smtpd_forbid_bare_newline = reject".
 .SH "TARPIT CONTROLS"
 .na
 .nf
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/postfix-3.8.4/mantools/postlink 
new/postfix-3.8.5/mantools/postlink
--- old/postfix-3.8.4/mantools/postlink 2023-12-21 19:33:14.000000000 +0100
+++ new/postfix-3.8.5/mantools/postlink 2024-01-19 00:39:04.000000000 +0100
@@ -557,8 +557,10 @@
     s;\bsmtpd_etrn_restrictions\b;<a 
href="postconf.5.html#smtpd_etrn_restrictions">$&</a>;g;
     s;\bsmtpd_expansion_filter\b;<a 
href="postconf.5.html#smtpd_expansion_filter">$&</a>;g;
     s;\bsmtpd_for[-</bB>]*\n*[ <bB>]*bidden_commands\b;<a 
href="postconf.5.html#smtpd_forbidden_commands">$&</a>;g;
-    s;\bsmtpd_for[-</bB>]*\n*[ <bB>]*bid_bare_newline\b;<a 
href="postconf.5.html#smtpd_forbid_bare_newline">$&</a>;g;
-    s;\bsmtpd_for[-</bB>]*\n*[ <bB>]*bid_bare_newline_exclusions\b;<a 
href="postconf.5.html#smtpd_forbid_bare_newline_exclusions">$&</a>;g;
+    s;\bsmtpd_for[-</bB>]*\n*[ <bB>]*bid_bare_new[-</bB>]*\n*[ <bB>]*line\b;<a 
href="postconf.5.html#smtpd_forbid_bare_newline">$&</a>;g;
+    s;\bsmtpd_for[-</bB>]*\n*[ <bB>]*bid_bare_new[-</bB>]*\n*[ 
<bB>]*line_reject_code\b;<a 
href="postconf.5.html#smtpd_forbid_bare_newline_reject_code">$&</a>;g;
+    s;\bsmtpd_for[-</bB>]*\n*[ <bB>]*bid_bare_new[-</bB>]*\n*[ 
<bB>]*line_exclusions\b;<a 
href="postconf.5.html#smtpd_forbid_bare_newline_exclusions">$&</a>;g;
+    s;\bcleanup_replace_stray_cr_lf\b;<a 
href="postconf.5.html#cleanup_replace_stray_cr_lf">$&</a>;g;
     s;\bsmtpd_for[-</bB>]*\n*[ <bB>]*bid_unauth_pipelining\b;<a 
href="postconf.5.html#smtpd_forbid_unauth_pipelining">$&</a>;g;
     s;\bsmtpd_hard_error_limit\b;<a 
href="postconf.5.html#smtpd_hard_error_limit">$&</a>;g;
     s;\bsmtpd_helo_required\b;<a 
href="postconf.5.html#smtpd_helo_required">$&</a>;g;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/postfix-3.8.4/proto/postconf.proto 
new/postfix-3.8.5/proto/postconf.proto
--- old/postfix-3.8.4/proto/postconf.proto      2023-12-21 19:47:58.000000000 
+0100
+++ new/postfix-3.8.5/proto/postconf.proto      2024-01-21 22:20:04.000000000 
+0100
@@ -18721,55 +18721,169 @@
 
 %PARAM smtpd_forbid_bare_newline Postfix &lt; 3.9: no
 
-<p> Reply with "Error: bare &lt;LF&gt; received" and disconnect
-when a remote SMTP client sends a line ending in &lt;LF&gt;, violating
-the RFC 5321 requirement that lines must end in &lt;CR&gt;&lt;LF&gt;.
-This feature is disbled by default with Postfix &lt; 3.9. Use
-smtpd_forbid_bare_newline_exclusions to exclude non-standard clients
-such as netcat. Specify "smtpd_forbid_bare_newline = no" to disable
-(not recommended for an Internet-connected MTA). </p>
+<p> Reject or restrict input lines from an SMTP client that end in
+&lt;LF&gt; instead of the standard &lt;CR&gt;&lt;LF&gt;. Such line
+endings are commonly allowed with UNIX-based SMTP servers, but they
+violate RFC 5321, and allowing such line endings can make a server
+vulnerable to <a href="https://www.postfix.org/smtp-smuggling.html";>
+SMTP smuggling</a>.  </p>
+
+<p> Specify one of the following values (case does not matter): </p>
+
+<dl compact>
+
+<dt> <b>normalize</b></dt> <dd> Require the standard
+End-of-DATA sequence &lt;CR&gt;&lt;LF&gt;.&lt;CR&gt;&lt;LF&gt;.
+Otherwise, allow command or message content lines ending in the
+non-standard &lt;LF&gt;, and process them as if the client sent the
+standard &lt;CR&gt;&lt;LF&gt;. <br> <br> This maintains compatibility
+with many legitimate SMTP client applications that send a mix of
+standard and non-standard line endings, but will fail to receive
+email from client implementations that do not terminate DATA content
+with the standard End-of-DATA sequence
+&lt;CR&gt;&lt;LF&gt;.&lt;CR&gt;&lt;LF&gt;. <br> <br> Such clients
+can be excluded with smtpd_forbid_bare_newline_exclusions. </dd>
+
+<dt> <b>yes</b> </dt> <dd> Compatibility alias for <b>normalize</b>. </dd>
+
+<dt> <b>reject</b> </dt> <dd> Require the standard End-of-DATA
+sequence &lt;CR&gt;&lt;LF&gt;.&lt;CR&gt;&lt;LF&gt;. Reject a command
+or message content when a line contains bare &lt;LF&gt;, log a "bare
+&lt;LF&gt; received" error, and reply with the SMTP status code in
+$smtpd_forbid_bare_newline_reject_code. <br> <br> This will reject
+email from SMTP clients that send any non-standard line endings
+such as web applications, netcat, or load balancer health checks.
+<br> <br> This will also reject email from services that use BDAT
+to send MIME text containing a bare newline (RFC 3030 Section 3
+requires canonical MIME format for text message types, defined in
+RFC 2045 Sections 2.7 and 2.8). <br> <br> Such clients can be
+excluded with smtpd_forbid_bare_newline_exclusions (or, in the case
+of BDAT violations, BDAT can be selectively disabled with
+smtpd_discard_ehlo_keyword_address_maps, or globally disabled with
+smtpd_discard_ehlo_keywords). </dd>
+
+<dt> <b>no</b> (default)</dt> <dd> Do not require the standard
+End-of-DATA
+sequence &lt;CR&gt;&lt;LF&gt;.&lt;CR&gt;&lt;LF&gt;. Always process
+a bare &lt;LF&gt; as if the client sent &lt;CR&gt;&lt;LF&gt;. This
+option is fully backwards compatible, but is not recommended for
+an Internet-facing SMTP server, because it is vulnerable to <a
+href="https://www.postfix.org/smtp-smuggling.html";> SMTP smuggling</a>.
+</dd>
 
-<p> See <a href="https://www.postfix.org/smtp-smuggling.html";>
-https://www.postfix.org/smtp-smuggling.html</a> for details.
+</dl>
 
-<p> Example: </p>
+<p> Recommended settings: </p>
 
 <blockquote>
 <pre>
-# Disconnect remote SMTP clients that send bare newlines, but allow
-# local clients with non-standard SMTP implementations such as netcat,
-# fax machines, or load balancer health checks.
+# Require the standard End-of-DATA sequence 
&lt;CR&gt;&lt;LF&gt;.&lt;CR&gt;&lt;LF&gt;.
+# Otherwise, allow bare &lt;LF&gt; and process it as if the client sent
+# &lt;CR&gt;&lt;LF&gt;.
 #
-smtpd_forbid_bare_newline = yes
+# This maintains compatibility with many legitimate SMTP client
+# applications that send a mix of standard and non-standard line
+# endings, but will fail to receive email from client implementations
+# that do not terminate DATA content with the standard End-of-DATA
+# sequence &lt;CR&gt;&lt;LF&gt;.&lt;CR&gt;&lt;LF&gt;.
+#
+# Such clients can be allowlisted with smtpd_forbid_bare_newline_exclusions.
+# The example below allowlists SMTP clients in trusted networks.
+#
+smtpd_forbid_bare_newline = normalize
 smtpd_forbid_bare_newline_exclusions = $mynetworks
 </pre>
 </blockquote>
 
-<p> This feature is available in Postfix &ge; 3.9, 3.8.4, 3.7.9,
-3.6.13, and 3.5.23. </p>
-
-%PARAM smtpd_forbid_bare_newline_exclusions $mynetworks
-
-<p> Exclude the specified clients from smtpd_forbid_bare_newline
-enforcement. It uses the same syntax and parent-domain matching 
-behavior as mynetworks. </p>
-
-<p> Example: </p>
+<p> Alternative: </p>
 
 <blockquote>
 <pre>
-# Disconnect remote SMTP clients that send bare newlines, but allow
-# local clients with non-standard SMTP implementations such as netcat,
-# fax machines, or load balancer health checks.
+# Reject input lines that contain &lt;LF&gt; and log a "bare &lt;LF&gt; 
received"
+# error. Require that input lines end in &lt;CR&gt;&lt;LF&gt;, and require the
+# standard End-of-DATA sequence &lt;CR&gt;&lt;LF&gt;.&lt;CR&gt;&lt;LF&gt;.
+#
+# This will reject email from SMTP clients that send any non-standard
+# line endings such as web applications, netcat, or load balancer
+# health checks.
+#
+# This will also reject email from services that use BDAT to send
+# MIME text containing a bare newline (RFC 3030 Section 3 requires
+# canonical MIME format for text message types, defined in RFC 2045
+# Sections 2.7 and 2.8).
 #
-smtpd_forbid_bare_newline = yes
+# Such clients can be allowlisted with smtpd_forbid_bare_newline_exclusions.
+# The example below allowlists SMTP clients in trusted networks.
+#
+smtpd_forbid_bare_newline = reject
 smtpd_forbid_bare_newline_exclusions = $mynetworks
+#
+# Alternatively, in the case of BDAT violations, BDAT can be selectively
+# disabled with smtpd_discard_ehlo_keyword_address_maps, or globally
+# disabled with smtpd_discard_ehlo_keywords.
+#
+# smtpd_discard_ehlo_keyword_address_maps = cidr:/path/to/file
+# /path/to/file:
+#     10.0.0.0/24 chunking, silent-discard
+# smtpd_discard_ehlo_keywords = chunking, silent-discard
 </pre>
 </blockquote>
 
+<p> This feature with settings <b>yes</b> and <b>no</b> is available
+in Postfix 3.8.4, 3.7.9, 3.6.13, and 3.5.23. Additionally, the
+settings <b>reject</b>, and <b>normalize</b> are available with
+Postfix &ge; 3.9, 3.8.5, 3.7.10, 3.6.14, and 3.5.24. </p>
+
+%PARAM smtpd_forbid_bare_newline_exclusions $mynetworks
+
+<p> Exclude the specified clients from smtpd_forbid_bare_newline
+enforcement. This setting uses the same syntax and parent-domain
+matching behavior as mynetworks. </p>
+
 <p> This feature is available in Postfix &ge; 3.9, 3.8.4, 3.7.9,
 3.6.13, and 3.5.23. </p>
 
+%PARAM smtpd_forbid_bare_newline_reject_code 550
+
+<p>
+The numerical Postfix SMTP server response code when rejecting a
+request with "smtpd_forbid_bare_newline = reject".
+Specify a 5XX status code (521 to disconnect).
+</p>
+
+<p> This feature is available in Postfix &ge; 3.9, 3.8.5, 3.7.10,
+3.6.14, and 3.5.24. </p>
+
+%PARAM cleanup_replace_stray_cr_lf yes
+
+<p> Replace each stray &lt;CR&gt; or &lt;LF&gt; character in message
+content with a space character, to prevent outbound SMTP smuggling,
+and to make the evaluation of Postfix-added DKIM or other signatures
+independent from how a remote mail server handles such characters.
+</p>
+
+<p> SMTP does not allow such characters unless they are part of a
+&lt;CR&gt;&lt;LF&gt; sequence, and different mail systems handle
+such stray characters in an implementation-dependent manner. Stray
+&lt;CR&gt; or &lt;LF&gt; characters could be used for outbound
+SMTP smuggling, where an attacker uses a Postfix server to send
+message content with a non-standard End-of-DATA sequence that
+triggers inbound SMTP smuggling at a remote SMTP server.</p>
+
+<p> The replacement happens before all other content management,
+and before Postfix may add a DKIM etc. signature; if the signature
+were created first, the replacement could invalidate the signature.
+</p>
+
+<p> In addition to preventing SMTP smuggling, replacing stray
+&lt;CR&gt; or &lt;LF&gt; characters ensures that the result of
+signature validation by later mail system will not depend on how
+that mail system handles those stray characters in an
+implementation-dependent manner. </p>
+
+<p> This feature is available in Postfix &ge; 3.9, 3.8.5, 3.7.10,
+3.6.14, and 3.5.24. </p>
+
 %PARAM smtpd_forbid_unauth_pipelining Postfix &ge; 3.9: yes
 
 <p> Disconnect remote SMTP clients that violate RFC 2920 (or 5321)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/postfix-3.8.4/src/cleanup/cleanup.c 
new/postfix-3.8.5/src/cleanup/cleanup.c
--- old/postfix-3.8.4/src/cleanup/cleanup.c     2021-10-02 16:46:46.000000000 
+0200
+++ new/postfix-3.8.5/src/cleanup/cleanup.c     2024-01-19 17:20:58.000000000 
+0100
@@ -147,6 +147,14 @@
 /* .IP "\fBmessage_strip_characters (empty)\fR"
 /*     The set of characters that Postfix will remove from message
 /*     content.
+/* .PP
+/*     Available in Postfix version 3.9, 3.8.5, 3.7.10, 3.6.14,
+/*     3.5.24, and later:
+/* .IP "\fBcleanup_replace_stray_cr_lf (yes)\fR"
+/*     Replace each stray <CR> or <LF> character in message
+/*     content with a space character, to prevent outbound SMTP smuggling,
+/*     and to make the evaluation of Postfix-added DKIM or other signatures
+/*     independent from how a remote mail server handles such characters.
 /* BEFORE QUEUE MILTER CONTROLS
 /* .ad
 /* .fi
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/postfix-3.8.4/src/cleanup/cleanup_init.c 
new/postfix-3.8.5/src/cleanup/cleanup_init.c
--- old/postfix-3.8.4/src/cleanup/cleanup_init.c        2022-04-07 
15:00:17.000000000 +0200
+++ new/postfix-3.8.5/src/cleanup/cleanup_init.c        2024-01-19 
00:43:05.000000000 +0100
@@ -174,6 +174,7 @@
 int     var_always_add_hdrs;           /* always add missing headers */
 int     var_virt_addrlen_limit;                /* stop exponential growth */
 char   *var_hfrom_format;              /* header_from_format */
+int     var_cleanup_mask_stray_cr_lf;  /* replace stray CR or LF with space */
 
 const CONFIG_INT_TABLE cleanup_int_table[] = {
     VAR_HOPCOUNT_LIMIT, DEF_HOPCOUNT_LIMIT, &var_hopcount_limit, 1, 0,
@@ -190,6 +191,7 @@
     VAR_VERP_BOUNCE_OFF, DEF_VERP_BOUNCE_OFF, &var_verp_bounce_off,
     VAR_AUTO_8BIT_ENC_HDR, DEF_AUTO_8BIT_ENC_HDR, &var_auto_8bit_enc_hdr,
     VAR_ALWAYS_ADD_HDRS, DEF_ALWAYS_ADD_HDRS, &var_always_add_hdrs,
+    VAR_CLEANUP_MASK_STRAY_CR_LF, DEF_CLEANUP_MASK_STRAY_CR_LF, 
&var_cleanup_mask_stray_cr_lf,
     0,
 };
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/postfix-3.8.4/src/cleanup/cleanup_message.c 
new/postfix-3.8.5/src/cleanup/cleanup_message.c
--- old/postfix-3.8.4/src/cleanup/cleanup_message.c     2021-12-19 
14:03:34.000000000 +0100
+++ new/postfix-3.8.5/src/cleanup/cleanup_message.c     2024-01-19 
00:39:04.000000000 +0100
@@ -925,6 +925,23 @@
     char   *dst;
 
     /*
+     * Replace each stray CR or LF with one space. These are not allowed in
+     * SMTP, and can be used to enable outbound (remote) SMTP smuggling.
+     * Replacing these early ensures that our later DKIM etc. signature will
+     * not be invalidated. Besides preventing SMTP smuggling, replacing stray
+     * <CR> or <LF> ensures that the result of signature validation by a
+     * later mail system will not depend on how that mail system handles
+     * those stray characters in an implementation-dependent manner.
+     * 
+     * The input length is not changed, therefore it is safe to overwrite the
+     * input.
+     */
+    if (var_cleanup_mask_stray_cr_lf)
+       for (dst = (char *) buf; dst < buf + len; dst++)
+           if (*dst == '\r' || *dst == '\n')
+               *dst = ' ';
+
+    /*
      * Reject unwanted characters.
      * 
      * XXX Possible optimization: simplify the loop when the "reject" set
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/postfix-3.8.4/src/global/cleanup_strerror.c 
new/postfix-3.8.5/src/global/cleanup_strerror.c
--- old/postfix-3.8.4/src/global/cleanup_strerror.c     2020-11-05 
01:37:47.000000000 +0100
+++ new/postfix-3.8.5/src/global/cleanup_strerror.c     2024-01-19 
00:39:04.000000000 +0100
@@ -73,6 +73,7 @@
     CLEANUP_STAT_CONT, 550, "5.7.1", "message content rejected",
     CLEANUP_STAT_WRITE, 451, "4.3.0", "queue file write error",
     CLEANUP_STAT_NOPERM, 550, "5.7.1", "service denied",
+    CLEANUP_STAT_BARE_LF, 521, "5.5.2", "bare <LF> received",
 };
 
 static CLEANUP_STAT_DETAIL cleanup_stat_success = {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/postfix-3.8.4/src/global/cleanup_user.h 
new/postfix-3.8.5/src/global/cleanup_user.h
--- old/postfix-3.8.4/src/global/cleanup_user.h 2020-11-05 01:37:47.000000000 
+0100
+++ new/postfix-3.8.5/src/global/cleanup_user.h 2024-01-19 00:39:04.000000000 
+0100
@@ -65,6 +65,12 @@
 #define CLEANUP_STAT_NOPERM    (1<<9)  /* Denied by non-content policy */
 
  /*
+  * Non-cleanup errors that live in the same bitmask space, to centralize
+  * error handling.
+  */
+#define CLEANUP_STAT_BARE_LF   (1<<16) /* Bare <LF> received */
+
+ /*
   * These are set when we can't bounce even if we were asked to.
   */
 #define CLEANUP_STAT_MASK_CANT_BOUNCE \
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/postfix-3.8.4/src/global/mail_params.h 
new/postfix-3.8.5/src/global/mail_params.h
--- old/postfix-3.8.4/src/global/mail_params.h  2023-12-21 19:43:17.000000000 
+0100
+++ new/postfix-3.8.5/src/global/mail_params.h  2024-01-19 00:39:04.000000000 
+0100
@@ -4282,11 +4282,18 @@
   * Backwards compatibility.
   */
 #define VAR_SMTPD_FORBID_BARE_LF       "smtpd_forbid_bare_newline"
-#define DEF_SMTPD_FORBID_BARE_LF       0
+#define DEF_SMTPD_FORBID_BARE_LF       "no"
 
 #define VAR_SMTPD_FORBID_BARE_LF_EXCL  "smtpd_forbid_bare_newline_exclusions"
 #define DEF_SMTPD_FORBID_BARE_LF_EXCL  "$" VAR_MYNETWORKS
 
+#define VAR_SMTPD_FORBID_BARE_LF_CODE  "smtpd_forbid_bare_newline_reject_code"
+#define DEF_SMTPD_FORBID_BARE_LF_CODE  550
+
+#define VAR_CLEANUP_MASK_STRAY_CR_LF   "cleanup_replace_stray_cr_lf"
+#define DEF_CLEANUP_MASK_STRAY_CR_LF   1
+extern int var_cleanup_mask_stray_cr_lf;
+
  /*
   * Share TLS sessions through tlsproxy(8).
   */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/postfix-3.8.4/src/global/mail_version.h 
new/postfix-3.8.5/src/global/mail_version.h
--- old/postfix-3.8.4/src/global/mail_version.h 2023-12-22 00:03:56.000000000 
+0100
+++ new/postfix-3.8.5/src/global/mail_version.h 2024-01-19 00:44:21.000000000 
+0100
@@ -20,8 +20,8 @@
   * Patches change both the patchlevel and the release date. Snapshots have no
   * patchlevel; they change the release date only.
   */
-#define MAIL_RELEASE_DATE      "20231222"
-#define MAIL_VERSION_NUMBER    "3.8.4"
+#define MAIL_RELEASE_DATE      "20240121"
+#define MAIL_VERSION_NUMBER    "3.8.5"
 
 #ifdef SNAPSHOT
 #define MAIL_VERSION_DATE      "-" MAIL_RELEASE_DATE
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/postfix-3.8.4/src/global/smtp_stream.c 
new/postfix-3.8.5/src/global/smtp_stream.c
--- old/postfix-3.8.4/src/global/smtp_stream.c  2023-12-21 19:33:14.000000000 
+0100
+++ new/postfix-3.8.5/src/global/smtp_stream.c  2024-01-19 00:39:04.000000000 
+0100
@@ -53,7 +53,8 @@
 /*     char    *format;
 /*     va_list ap;
 /*
-/*     int     smtp_forbid_bare_lf;
+/*     int     smtp_detect_bare_lf;
+/*     int     smtp_got_bare_lf;
 /* AUXILIARY API
 /*     int     smtp_get_noexcept(vp, stream, maxlen, flags)
 /*     VSTRING *vp;
@@ -133,16 +134,16 @@
 /*     smtp_vprintf() is the machine underneath smtp_printf().
 /*
 /*     smtp_get_noexcept() implements the subset of smtp_get()
-/*     without long jumps for timeout or EOF errors. Instead,
+/*     without timeouts and without making long jumps. Instead,
 /*     query the stream status with vstream_feof() etc.
-/*     This function will make a VSTREAM long jump (error code
-/*     SMTP_ERR_LF) when rejecting input with a bare newline byte.
+/*
+/*     This function assigns smtp_got_bare_lf = smtp_detect_bare_lf,
+/*     if smtp_detect_bare_lf is non-zero and the last read line
+/*     was terminated with a bare newline. Otherwise, this function
+/*     sets smtp_got_bare_lf to zero.
 /*
 /*     smtp_timeout_setup() is a backwards-compatibility interface
 /*     for programs that don't require deadline or data-rate support.
-/*
-/*     smtp_forbid_bare_lf controls whether smtp_get_noexcept()
-/*     will reject input with a bare newline byte.
 /* DIAGNOSTICS
 /* .fi
 /* .ad
@@ -221,7 +222,8 @@
   * the buffer. Such system calls would really hurt when receiving or sending
   * body content one line at a time.
   */
-int     smtp_forbid_bare_lf;
+int     smtp_detect_bare_lf;
+int     smtp_got_bare_lf;
 
 /* smtp_timeout_reset - reset per-stream error flags */
 
@@ -384,6 +386,8 @@
     int     last_char;
     int     next_char;
 
+    smtp_got_bare_lf = 0;
+
     /*
      * It's painful to do I/O with records that may span multiple buffers.
      * Allow for partial long lines (we will read the remainder later) and
@@ -426,11 +430,15 @@
         */
     case '\n':
        vstring_truncate(vp, VSTRING_LEN(vp) - 1);
-       if (smtp_forbid_bare_lf
-           && (VSTRING_LEN(vp) == 0 || vstring_end(vp)[-1] != '\r'))
-           vstream_longjmp(stream, SMTP_ERR_LF);
-       while (VSTRING_LEN(vp) > 0 && vstring_end(vp)[-1] == '\r')
-           vstring_truncate(vp, VSTRING_LEN(vp) - 1);
+       if (smtp_detect_bare_lf) {
+           if (VSTRING_LEN(vp) == 0 || vstring_end(vp)[-1] != '\r')
+               smtp_got_bare_lf = smtp_detect_bare_lf;
+           else
+               vstring_truncate(vp, VSTRING_LEN(vp) - 1);
+       } else {
+           while (VSTRING_LEN(vp) > 0 && vstring_end(vp)[-1] == '\r')
+               vstring_truncate(vp, VSTRING_LEN(vp) - 1);
+       }
        VSTRING_TERMINATE(vp);
        /* FALLTRHOUGH */
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/postfix-3.8.4/src/global/smtp_stream.h 
new/postfix-3.8.5/src/global/smtp_stream.h
--- old/postfix-3.8.4/src/global/smtp_stream.h  2023-12-21 19:33:14.000000000 
+0100
+++ new/postfix-3.8.5/src/global/smtp_stream.h  2024-01-19 00:39:04.000000000 
+0100
@@ -32,7 +32,6 @@
 #define SMTP_ERR_QUIET 3               /* silent cleanup (application) */
 #define SMTP_ERR_NONE  4               /* non-error case */
 #define SMTP_ERR_DATA  5               /* application data error */
-#define SMTP_ERR_LF    6               /* bare <LF> protocol error */
 
 extern void smtp_stream_setup(VSTREAM *, int, int, int);
 extern void PRINTFLIKE(2, 3) smtp_printf(VSTREAM *, const char *,...);
@@ -44,7 +43,8 @@
 extern void smtp_fwrite(const char *, ssize_t len, VSTREAM *);
 extern void smtp_fread_buf(VSTRING *, ssize_t len, VSTREAM *);
 extern void smtp_fputc(int, VSTREAM *);
-extern int smtp_forbid_bare_lf;
+extern int smtp_detect_bare_lf;
+extern int smtp_got_bare_lf;
 
 extern void smtp_vprintf(VSTREAM *, const char *, va_list);
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/postfix-3.8.4/src/smtpd/smtpd.c 
new/postfix-3.8.5/src/smtpd/smtpd.c
--- old/postfix-3.8.4/src/smtpd/smtpd.c 2023-12-22 14:40:28.000000000 +0100
+++ new/postfix-3.8.5/src/smtpd/smtpd.c 2024-01-19 01:00:24.000000000 +0100
@@ -818,12 +818,17 @@
 /* .PP
 /*     Available in Postfix 3.9, 3.8.4, 3.7.9, 3.6.13, 3.5.23 and later:
 /* .IP "\fBsmtpd_forbid_bare_newline (Postfix < 3.9: no)\fR"
-/*     Reply with "Error: bare <LF> received" and disconnect
-/*     when a remote SMTP client sends a line ending in <LF>, violating
-/*     the RFC 5321 requirement that lines must end in <CR><LF>.
+/*     Reject or restrict input lines from an SMTP client that end in
+/*     <LF> instead of the standard <CR><LF>.
 /* .IP "\fBsmtpd_forbid_bare_newline_exclusions ($mynetworks)\fR"
 /*     Exclude the specified clients from smtpd_forbid_bare_newline
 /*     enforcement.
+/* .PP
+/*     Available in Postfix 3.9, 3.8.5, 3.7.10, 3.6.14, 3.5.24 and
+/*     later:
+/* .IP "\fBsmtpd_forbid_bare_newline_reject_code (550)\fR"
+/*     The numerical Postfix SMTP server response code when rejecting a
+/*     request with "smtpd_forbid_bare_newline = reject".
 /* TARPIT CONTROLS
 /* .ad
 /* .fi
@@ -1534,8 +1539,10 @@
 bool    var_smtpd_req_deadline;
 int     var_smtpd_min_data_rate;
 char   *var_hfrom_format;
-bool    var_smtpd_forbid_bare_lf;
+char   *var_smtpd_forbid_bare_lf;
 char   *var_smtpd_forbid_bare_lf_excl;
+int     var_smtpd_forbid_bare_lf_code;
+static int bare_lf_mask;
 static NAMADR_LIST *bare_lf_excl;
 
  /*
@@ -1612,7 +1619,6 @@
 #define REASON_TIMEOUT         "timeout"
 #define REASON_LOST_CONNECTION "lost connection"
 #define REASON_ERROR_LIMIT     "too many errors"
-#define REASON_BARE_LF         "bare <LF> received"
 
 #ifdef USE_TLS
 
@@ -1636,6 +1642,40 @@
   */
 int     smtpd_hfrom_format;
 
+ /*
+  * Bare LF and End-of-DATA controls (bare CR is handled elsewhere).
+  * 
+  * At the smtp_get*() line reader level, setting any of these flags in the
+  * smtp_detect_bare_lf variable enables the detection of bare newlines. The
+  * line reader will set the same flags in the smtp_got_bare_lf variable
+  * after it detects a bare newline, otherwise it clears smtp_got_bare_lf.
+  * 
+  * At the SMTP command level, the flags in smtp_got_bare_lf control whether
+  * commands ending in a bare newline are rejected.
+  * 
+  * At the DATA and BDAT content level, the flags in smtp_got_bare_lf control
+  * whether the standard End-of-DATA sequence CRLF.CRLF is required, and
+  * whether lines ending in bare newlines are rejected.
+  * 
+  * Postfix implements "delayed reject" after detecting a bare newline in BDAT
+  * or DATA content. The SMTP server delays a REJECT response until the
+  * command is finished, instead of replying and hanging up immediately. The
+  * End-of-DATA detection is secured with BARE_LF_FLAG_WANT_STD_EOD.
+  */
+#define BARE_LF_FLAG_WANT_STD_EOD      (1<<0)  /* Require CRLF.CRLF */
+#define BARE_LF_FLAG_REPLY_REJECT      (1<<1)  /* Reject bare newline */
+
+#define IS_BARE_LF_WANT_STD_EOD(m)     ((m) & BARE_LF_FLAG_WANT_STD_EOD)
+#define IS_BARE_LF_REPLY_REJECT(m)     ((m) & BARE_LF_FLAG_REPLY_REJECT)
+
+static const NAME_CODE bare_lf_mask_table[] = {
+    "normalize", BARE_LF_FLAG_WANT_STD_EOD,    /* Default */
+    "yes", BARE_LF_FLAG_WANT_STD_EOD,  /* Migration aid */
+    "reject", BARE_LF_FLAG_WANT_STD_EOD | BARE_LF_FLAG_REPLY_REJECT,
+    "no", 0,
+    0, -1,                             /* error */
+};
+
 #ifdef USE_SASL_AUTH
 
  /*
@@ -3578,6 +3618,7 @@
     int     curr_rec_type;
     int     prev_rec_type;
     int     first = 1;
+    int     prev_got_bare_lf = 0;
 
     /*
      * If deadlines are enabled, increase the time budget as message content
@@ -3598,12 +3639,15 @@
      * XXX Deal with UNIX-style From_ lines at the start of message content
      * because sendmail permits it.
      */
-    for (prev_rec_type = 0; /* void */ ; prev_rec_type = curr_rec_type) {
+    for (prev_rec_type = 0; /* void */ ; prev_rec_type = curr_rec_type,
+        prev_got_bare_lf = smtp_got_bare_lf) {
        if (smtp_get(state->buffer, state->client, var_line_limit,
                     SMTP_GET_FLAG_NONE) == '\n')
            curr_rec_type = REC_TYPE_NORM;
        else
            curr_rec_type = REC_TYPE_CONT;
+       if (IS_BARE_LF_REPLY_REJECT(smtp_got_bare_lf))
+           state->err |= CLEANUP_STAT_BARE_LF;
        start = vstring_str(state->buffer);
        len = VSTRING_LEN(state->buffer);
        if (first) {
@@ -3616,9 +3660,14 @@
            if (len > 0 && IS_SPACE_TAB(start[0]))
                out_record(out_stream, REC_TYPE_NORM, "", 0);
        }
-       if (prev_rec_type != REC_TYPE_CONT && *start == '.'
-           && (proxy == 0 ? (++start, --len) == 0 : len == 1))
-           break;
+       if (prev_rec_type != REC_TYPE_CONT && *start == '.') {
+           if (len == 1 && IS_BARE_LF_WANT_STD_EOD(smtp_detect_bare_lf)
+               && (smtp_got_bare_lf || prev_got_bare_lf))
+               /* Do not store or send to proxy filter. */
+               continue;
+           if (proxy == 0 ? (++start, --len) == 0 : len == 1)
+               break;
+       }
        if (state->err == CLEANUP_STAT_OK) {
            if (ENFORCING_SIZE_LIMIT(var_message_limit)
                && var_message_limit - state->act_size < len + 2) {
@@ -3771,6 +3820,11 @@
        else
            smtpd_chat_reply(state,
                             "250 2.0.0 Ok: queued as %s", state->queue_id);
+    } else if ((state->err & CLEANUP_STAT_BARE_LF) != 0) {
+       state->error_mask |= MAIL_ERROR_PROTOCOL;
+       log_whatsup(state, "reject", "bare <LF> received");
+       smtpd_chat_reply(state, "%d 5.5.2 %s Error: bare <LF> received",
+                        var_smtpd_forbid_bare_lf_code, var_myhostname);
     } else if (why && IS_SMTP_REJECT(STR(why))) {
        state->error_mask |= MAIL_ERROR_POLICY;
        smtpd_chat_reply(state, "%s", STR(why));
@@ -4058,7 +4112,6 @@
      */
     done = 0;
     do {
-       int     payload_err;
 
        /*
         * Do not skip the smtp_fread_buf() call if read_len == 0. We still
@@ -4072,10 +4125,6 @@
        smtp_fread_buf(state->buffer, read_len, state->client);
        state->bdat_get_stream = vstream_memreopen(
                           state->bdat_get_stream, state->buffer, O_RDONLY);
-       vstream_control(state->bdat_get_stream, CA_VSTREAM_CTL_EXCEPT,
-                       CA_VSTREAM_CTL_END);
-       if ((payload_err = vstream_setjmp(state->bdat_get_stream)) != 0)
-           vstream_longjmp(state->client, payload_err);
 
        /*
         * Read lines from the fragment. The last line may continue in the
@@ -4100,6 +4149,8 @@
                /* Skip the out_record() and VSTRING_RESET() calls below. */
                break;
            }
+           if (IS_BARE_LF_REPLY_REJECT(smtp_got_bare_lf))
+               state->err |= CLEANUP_STAT_BARE_LF;
            start = vstring_str(state->bdat_get_buffer);
            len = VSTRING_LEN(state->bdat_get_buffer);
            if (state->err == CLEANUP_STAT_OK) {
@@ -4751,9 +4802,9 @@
      */
     xclient_allowed =
        namadr_list_match(xclient_hosts, state->name, state->addr);
-    smtp_forbid_bare_lf = SMTPD_STAND_ALONE((state)) == 0
-       && var_smtpd_forbid_bare_lf
-       && !namadr_list_match(bare_lf_excl, state->name, state->addr);
+    smtp_detect_bare_lf = (SMTPD_STAND_ALONE((state)) == 0 && bare_lf_mask
+           && !namadr_list_match(bare_lf_excl, state->name, state->addr)) ?
+       bare_lf_mask : 0;
     /* NOT: tls_reset() */
     if (got_helo == 0)
        helo_reset(state);
@@ -5575,13 +5626,6 @@
                             var_myhostname);
        break;
 
-    case SMTP_ERR_LF:
-       state->reason = REASON_BARE_LF;
-       if (vstream_setjmp(state->client) == 0)
-           smtpd_chat_reply(state, "521 5.5.2 %s Error: bare <LF> received",
-                            var_myhostname);
-       break;
-
     case 0:
 
        /*
@@ -5801,6 +5845,13 @@
            }
            watchdog_pat();
            smtpd_chat_query(state);
+           if (IS_BARE_LF_REPLY_REJECT(smtp_got_bare_lf)) {
+               log_whatsup(state, "reject", "bare <LF> received");
+               state->error_mask |= MAIL_ERROR_PROTOCOL;
+               smtpd_chat_reply(state, "%d 5.5.2 %s Error: bare <LF> received",
+                            var_smtpd_forbid_bare_lf_code, var_myhostname);
+               break;
+           }
            /* Safety: protect internal interfaces against malformed UTF-8. */
            if (var_smtputf8_enable && valid_utf8_string(STR(state->buffer),
                                                 LEN(state->buffer)) == 0) {
@@ -6150,11 +6201,11 @@
        namadr_list_match(xforward_hosts, state.name, state.addr);
 
     /*
-     * Enforce strict SMTP line endings, with compatibility exclusions.
+     * Reject or normalize bare LF, with compatibility exclusions.
      */
-    smtp_forbid_bare_lf = SMTPD_STAND_ALONE((&state)) == 0
-       && var_smtpd_forbid_bare_lf
-       && !namadr_list_match(bare_lf_excl, state.name, state.addr);
+    smtp_detect_bare_lf = (SMTPD_STAND_ALONE((&state)) == 0 && bare_lf_mask
+             && !namadr_list_match(bare_lf_excl, state.name, state.addr)) ?
+       bare_lf_mask : 0;
 
     /*
      * See if we need to turn on verbose logging for this client.
@@ -6221,6 +6272,10 @@
                                    MATCH_FLAG_RETURN
                                    | match_parent_style(VAR_MYNETWORKS),
                                    var_smtpd_forbid_bare_lf_excl);
+    if ((bare_lf_mask = name_code(bare_lf_mask_table, NAME_CODE_FLAG_NONE,
+                                 var_smtpd_forbid_bare_lf)) < 0)
+       msg_fatal("bad parameter value: '%s = %s'",
+                 VAR_SMTPD_FORBID_BARE_LF, var_smtpd_forbid_bare_lf);
 
     /*
      * Open maps before dropping privileges so we can read passwords etc.
@@ -6521,6 +6576,7 @@
        VAR_VIRT_MAILBOX_CODE, DEF_VIRT_MAILBOX_CODE, &var_virt_mailbox_code, 
0, 0,
        VAR_RELAY_RCPT_CODE, DEF_RELAY_RCPT_CODE, &var_relay_rcpt_code, 0, 0,
        VAR_PLAINTEXT_CODE, DEF_PLAINTEXT_CODE, &var_plaintext_code, 0, 0,
+       VAR_SMTPD_FORBID_BARE_LF_CODE, DEF_SMTPD_FORBID_BARE_LF_CODE, 
&var_smtpd_forbid_bare_lf_code, 500, 599,
        VAR_SMTPD_CRATE_LIMIT, DEF_SMTPD_CRATE_LIMIT, &var_smtpd_crate_limit, 
0, 0,
        VAR_SMTPD_CCONN_LIMIT, DEF_SMTPD_CCONN_LIMIT, &var_smtpd_cconn_limit, 
0, 0,
        VAR_SMTPD_CMAIL_LIMIT, DEF_SMTPD_CMAIL_LIMIT, &var_smtpd_cmail_limit, 
0, 0,
@@ -6587,7 +6643,6 @@
        VAR_SMTPD_DELAY_OPEN, DEF_SMTPD_DELAY_OPEN, &var_smtpd_delay_open,
        VAR_SMTPD_CLIENT_PORT_LOG, DEF_SMTPD_CLIENT_PORT_LOG, 
&var_smtpd_client_port_log,
        VAR_SMTPD_FORBID_UNAUTH_PIPE, DEF_SMTPD_FORBID_UNAUTH_PIPE, 
&var_smtpd_forbid_unauth_pipe,
-       VAR_SMTPD_FORBID_BARE_LF, DEF_SMTPD_FORBID_BARE_LF, 
&var_smtpd_forbid_bare_lf,
        0,
     };
     static const CONFIG_NBOOL_TABLE nbool_table[] = {
@@ -6705,6 +6760,7 @@
        VAR_SMTPD_REJ_FTR_MAPS, DEF_SMTPD_REJ_FTR_MAPS, 
&var_smtpd_rej_ftr_maps, 0, 0,
        VAR_HFROM_FORMAT, DEF_HFROM_FORMAT, &var_hfrom_format, 1, 0,
        VAR_SMTPD_FORBID_BARE_LF_EXCL, DEF_SMTPD_FORBID_BARE_LF_EXCL, 
&var_smtpd_forbid_bare_lf_excl, 0, 0,
+       VAR_SMTPD_FORBID_BARE_LF, DEF_SMTPD_FORBID_BARE_LF, 
&var_smtpd_forbid_bare_lf, 1, 0,
        0,
     };
     static const CONFIG_RAW_TABLE raw_table[] = {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/postfix-3.8.4/src/smtpd/smtpd_check.c 
new/postfix-3.8.5/src/smtpd/smtpd_check.c
--- old/postfix-3.8.4/src/smtpd/smtpd_check.c   2023-03-14 20:02:38.000000000 
+0100
+++ new/postfix-3.8.5/src/smtpd/smtpd_check.c   2024-01-19 00:39:04.000000000 
+0100
@@ -48,6 +48,11 @@
 /*
 /*     char    *smtpd_check_queue(state)
 /*     SMTPD_STATE *state;
+/* AUXILIARY FUNCTIONS
+/*     void    log_whatsup(state, action, text)
+/*     SMTPD_STATE *state;
+/*     const char *action;
+/*     const char *text;
 /* DESCRIPTION
 /*     This module implements additional checks on SMTP client requests.
 /*     A client request is validated in the context of the session state.
@@ -146,6 +151,11 @@
 /*     The recipient address given with the RCPT TO or VRFY command.
 /* .IP size
 /*     The message size given with the MAIL FROM command (zero if unknown).
+/* .PP
+/*     log_whatsup() logs "<queueid>: <action>: <protocol state>
+/*     from: <client-name[client-addr]>: <text>" plus the protocol
+/*     (SMTP or ESMTP), and if available, EHLO, MAIL FROM, or RCPT
+/*     TO.
 /* BUGS
 /*     Policies like these should not be hard-coded in C, but should
 /*     be user-programmable instead.
@@ -988,8 +998,8 @@
 
 /* log_whatsup - log as much context as we have */
 
-static void log_whatsup(SMTPD_STATE *state, const char *whatsup,
-                               const char *text)
+void    log_whatsup(SMTPD_STATE *state, const char *whatsup,
+                           const char *text)
 {
     VSTRING *buf = vstring_alloc(100);
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/postfix-3.8.4/src/smtpd/smtpd_check.h 
new/postfix-3.8.5/src/smtpd/smtpd_check.h
--- old/postfix-3.8.4/src/smtpd/smtpd_check.h   2017-12-27 23:29:45.000000000 
+0100
+++ new/postfix-3.8.5/src/smtpd/smtpd_check.h   2024-01-19 00:51:23.000000000 
+0100
@@ -25,6 +25,7 @@
 extern char *smtpd_check_data(SMTPD_STATE *);
 extern char *smtpd_check_eod(SMTPD_STATE *);
 extern char *smtpd_check_policy(SMTPD_STATE *, char *);
+extern void log_whatsup(SMTPD_STATE *, const char *, const char *);
 
 /* LICENSE
 /* .ad

Reply via email to