]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
postfix-3.11-20251105
authorWietse Z Venema <wietse@porcupine.org>
Wed, 5 Nov 2025 05:00:00 +0000 (00:00 -0500)
committerViktor Dukhovni <ietf-dane@dukhovni.org>
Wed, 5 Nov 2025 21:04:05 +0000 (08:04 +1100)
22 files changed:
postfix/HISTORY
postfix/README_FILES/OVERVIEW
postfix/html/OVERVIEW.html
postfix/html/cleanup.8.html
postfix/html/postconf.5.html
postfix/man/man5/postconf.5
postfix/man/man8/cleanup.8
postfix/mantools/postlink
postfix/proto/OVERVIEW.html
postfix/proto/postconf.proto
postfix/src/cleanup/cleanup.c
postfix/src/cleanup/cleanup.h
postfix/src/cleanup/cleanup_init.c
postfix/src/cleanup/cleanup_message.c
postfix/src/global/mail_params.h
postfix/src/global/mail_version.h
postfix/src/global/mime_garb3.ref
postfix/src/global/mime_state.c
postfix/src/global/mime_state.h
postfix/src/tls/Makefile.in
postfix/src/tls/tls_dane.c
postfix/src/tls/tls_dane.sh

index eba515c894fa957624d56f5d070c673a190b7a36..69a471f42f2b968334cb7512a685c1ab8c9b3772 100644 (file)
@@ -29785,3 +29785,25 @@ Apologies for any names omitted.
        avoid problems with infrastructure that mis-handles TLS
        hello messages larger than one (Ethernet) TCP segment.
        Viktor Dukhovni. Files: global/mail_params.h, proto/postconf.proto.
+
+20251103
+
+       Testing: fix bitrot in TLS DANE tests. Viktor Dukhovni.
+       Files: tls/tls_dane.c, tls/tls_dane.sh.
+
+20251104
+
+       Feature: non_empty_end_of_header_action specifies the
+       cleanup(8) server action when a primary message header is
+       terminated with a non-empty line: 1) insert an empty line
+       before the offending text (the backwards-compatible default),
+       2) insert a MIME-Error: header before inserting an empty
+       line, or 3) log an error and reject the message. Files:
+       global/mime-state.[hc], global/mime_garb3.ref,
+       global/mail_params.h, cleanup/cleanup_message.c.
+
+20251104
+
+       Documentation: in OVERVIEW_README, added a missing link
+       between smtpd(8) and trivial-rewrite(8). File:
+       proto/OVERVIEW_README.html.
index 45762f65ee03363c183117ec6806b6acb917a50f..08a7284dc70ae9d9b84b8bc42118cb7e3df0afee 100644 (file)
@@ -24,7 +24,7 @@ the incoming queue. The figure below shows the main processes that are involved
 with new mail. Names followed by a number are Postfix commands or server
 programs, while unnumbered names inside shaded areas represent Postfix queues.
 
-                               trivial-
+                           /   trivial-
                               rewrite(8)
 
     Network ->   smtpd(8)
index bd7b8c4a6a942c655b311d2d4b4a43445dec1fcd..a1c26292369cd2609a22e9dec6647284c2eb35b7 100644 (file)
@@ -56,12 +56,16 @@ names inside shaded areas represent Postfix queues. </p>
 
 <tr>
 
-<td colspan="4"> </td>
+<td colspan="3"> </td>
 
-<td bgcolor="#f0f0ff" align="center"> <a href="trivial-rewrite.8.html">trivial-<br>rewrite(8)</a> </td>
+<td> &nbsp; </td>
+
+<td rowspan="2" bgcolor="#f0f0ff" align="center"> <a href="trivial-rewrite.8.html">trivial-<br>rewrite(8)</a> </td>
 
 </tr>
 
+<tr> <td colspan="3"> </td> <td> / </td> </tr>
+
 <tr>
 
 <td> Network </td> <td> <tt> -&gt; </tt> </td>
index 655275a9e5ddee2b27efc5531cb23b56ad83e645..bc1a835c04a842186bc0aa84bdd8b99c68222f35 100644 (file)
@@ -132,77 +132,81 @@ CLEANUP(8)                                                          CLEANUP(8)
               output  when it automatically generates an <a href="https://tools.ietf.org/html/rfc2047">RFC 2047</a> encoded full
               name.
 
+       <b><a href="postconf.5.html#non_empty_end_of_header_action">non_empty_end_of_header_action</a> (fix_quietly)</b>
+              How the <a href="cleanup.8.html"><b>cleanup</b>(8)</a> daemon will process a message when  the  pri-
+              mary message header is terminated with a non-empty line.
+
 <b><a name="built-in_content_filtering_controls">BUILT-IN CONTENT FILTERING CONTROLS</a></b>
        Postfix built-in content filtering is meant to stop a flood of worms or
        viruses. It is not a general content filter.
 
        <b><a href="postconf.5.html#body_checks">body_checks</a> (empty)</b>
-              Optional  lookup  tables  for content inspection as specified in
+              Optional lookup tables for content inspection  as  specified  in
               the <a href="header_checks.5.html"><b>body_checks</b>(5)</a> manual page.
 
        <b><a href="postconf.5.html#header_checks">header_checks</a> (empty)</b>
-              Optional  lookup  tables  for  content  inspection  of   primary
-              non-MIME  message  headers, as specified in the <a href="header_checks.5.html"><b>header_checks</b>(5)</a>
+              Optional   lookup  tables  for  content  inspection  of  primary
+              non-MIME message headers, as specified in  the  <a href="header_checks.5.html"><b>header_checks</b>(5)</a>
               manual page.
 
        Available in Postfix version 2.0 and later:
 
        <b><a href="postconf.5.html#body_checks_size_limit">body_checks_size_limit</a> (51200)</b>
-              How much text in a message body segment (or attachment,  if  you
+              How  much  text in a message body segment (or attachment, if you
               prefer to use that term) is subjected to <a href="postconf.5.html#body_checks">body_checks</a> inspection.
 
        <b><a href="postconf.5.html#mime_header_checks">mime_header_checks</a> ($<a href="postconf.5.html#header_checks">header_checks</a>)</b>
-              Optional lookup tables for content inspection  of  MIME  related
-              message  headers,  as  described  in the <a href="header_checks.5.html"><b>header_checks</b>(5)</a> manual
+              Optional  lookup  tables  for content inspection of MIME related
+              message headers, as described  in  the  <a href="header_checks.5.html"><b>header_checks</b>(5)</a>  manual
               page.
 
        <b><a href="postconf.5.html#nested_header_checks">nested_header_checks</a> ($<a href="postconf.5.html#header_checks">header_checks</a>)</b>
-              Optional lookup tables for content inspection of  non-MIME  mes-
-              sage   headers   in  attached  messages,  as  described  in  the
+              Optional  lookup  tables for content inspection of non-MIME mes-
+              sage  headers  in  attached  messages,  as  described   in   the
               <a href="header_checks.5.html"><b>header_checks</b>(5)</a> manual page.
 
        Available in Postfix version 2.3 and later:
 
        <b><a href="postconf.5.html#message_reject_characters">message_reject_characters</a> (empty)</b>
-              The set of characters that Postfix will reject in  message  con-
+              The  set  of characters that Postfix will reject in message con-
               tent.
 
        <b><a href="postconf.5.html#message_strip_characters">message_strip_characters</a> (empty)</b>
               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
+       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
+              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-
+              independent  from  how a remote mail server handles such charac-
               ters.
 
 <b><a name="before_queue_milter_controls">BEFORE QUEUE MILTER CONTROLS</a></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,
+       filter)  protocol.  When  mail is not received via the <a href="smtpd.8.html">smtpd(8)</a> server,
        the <a href="cleanup.8.html">cleanup(8)</a> server will simulate SMTP events to the extent that this
        is possible. For details see the <a href="MILTER_README.html">MILTER_README</a> document.
 
        <b><a href="postconf.5.html#non_smtpd_milters">non_smtpd_milters</a> (empty)</b>
-              A list of Milter (mail filter) applications for  new  mail  that
+              A  list  of  Milter (mail filter) applications for new mail that
               does not arrive via the Postfix <a href="smtpd.8.html"><b>smtpd</b>(8)</a> server.
 
        <b><a href="postconf.5.html#milter_protocol">milter_protocol</a> (6)</b>
-              The  mail  filter  protocol version and optional protocol exten-
-              sions for communication with  a  Milter  application;  prior  to
+              The mail filter protocol version and  optional  protocol  exten-
+              sions  for  communication  with  a  Milter application; prior to
               Postfix 2.6 the default protocol is 2.
 
        <b><a href="postconf.5.html#milter_default_action">milter_default_action</a> (tempfail)</b>
-              The  default  action  when  a  Milter  (mail filter) response is
-              unavailable (for example, bad Postfix  configuration  or  Milter
+              The default action when  a  Milter  (mail  filter)  response  is
+              unavailable  (for  example,  bad Postfix configuration or Milter
               failure).
 
        <b><a href="postconf.5.html#milter_macro_daemon_name">milter_macro_daemon_name</a> ($<a href="postconf.5.html#myhostname">myhostname</a>)</b>
-              The  {daemon_name} macro value for Milter (mail filter) applica-
+              The {daemon_name} macro value for Milter (mail filter)  applica-
               tions.
 
        <b><a href="postconf.5.html#milter_macro_v">milter_macro_v</a> ($<a href="postconf.5.html#mail_name">mail_name</a> $<a href="postconf.5.html#mail_version">mail_version</a>)</b>
@@ -213,45 +217,45 @@ CLEANUP(8)                                                          CLEANUP(8)
               tion, and for negotiating protocol options.
 
        <b><a href="postconf.5.html#milter_command_timeout">milter_command_timeout</a> (30s)</b>
-              The  time  limit  for  sending an SMTP command to a Milter (mail
+              The time limit for sending an SMTP command  to  a  Milter  (mail
               filter) application, and for receiving the response.
 
        <b><a href="postconf.5.html#milter_content_timeout">milter_content_timeout</a> (300s)</b>
-              The time limit for sending message content  to  a  Milter  (mail
+              The  time  limit  for  sending message content to a Milter (mail
               filter) application, and for receiving the response.
 
        <b><a href="postconf.5.html#milter_connect_macros">milter_connect_macros</a> (see 'postconf -d' output)</b>
-              The  macros  that  are sent to Milter (mail filter) applications
+              The macros that are sent to Milter  (mail  filter)  applications
               after completion of an SMTP connection.
 
        <b><a href="postconf.5.html#milter_helo_macros">milter_helo_macros</a> (see 'postconf -d' output)</b>
-              The macros that are sent to Milter  (mail  filter)  applications
+              The  macros  that  are sent to Milter (mail filter) applications
               after the SMTP HELO or EHLO command.
 
        <b><a href="postconf.5.html#milter_mail_macros">milter_mail_macros</a> (see 'postconf -d' output)</b>
-              The  macros  that  are sent to Milter (mail filter) applications
+              The macros that are sent to Milter  (mail  filter)  applications
               after the SMTP MAIL FROM command.
 
        <b><a href="postconf.5.html#milter_rcpt_macros">milter_rcpt_macros</a> (see 'postconf -d' output)</b>
-              The macros that are sent to Milter  (mail  filter)  applications
+              The  macros  that  are sent to Milter (mail filter) applications
               after the SMTP RCPT TO command.
 
        <b><a href="postconf.5.html#milter_data_macros">milter_data_macros</a> (see 'postconf -d' output)</b>
-              The  macros  that  are  sent to version 4 or higher Milter (mail
+              The macros that are sent to version 4  or  higher  Milter  (mail
               filter) applications after the SMTP DATA command.
 
        <b><a href="postconf.5.html#milter_unknown_command_macros">milter_unknown_command_macros</a> (see 'postconf -d' output)</b>
-              The macros that are sent to version 3  or  higher  Milter  (mail
+              The  macros  that  are  sent to version 3 or higher Milter (mail
               filter) applications after an unknown SMTP command.
 
        <b><a href="postconf.5.html#milter_end_of_data_macros">milter_end_of_data_macros</a> (see 'postconf -d' output)</b>
-              The  macros  that  are sent to Milter (mail filter) applications
+              The macros that are sent to Milter  (mail  filter)  applications
               after the message end-of-data.
 
        Available in Postfix version 2.5 and later:
 
        <b><a href="postconf.5.html#milter_end_of_header_macros">milter_end_of_header_macros</a> (see 'postconf -d' output)</b>
-              The macros that are sent to Milter  (mail  filter)  applications
+              The  macros  that  are sent to Milter (mail filter) applications
               after the end of the message header.
 
        Available in Postfix version 2.7 and later:
@@ -263,8 +267,8 @@ CLEANUP(8)                                                          CLEANUP(8)
        Available in Postfix version 3.1 and later:
 
        <b><a href="postconf.5.html#milter_macro_defaults">milter_macro_defaults</a> (empty)</b>
-              Optional list of <i>name=value</i> pairs that  specify  default  values
-              for  arbitrary  macros  that Postfix may send to Milter applica-
+              Optional  list  of  <i>name=value</i> pairs that specify default values
+              for arbitrary macros that Postfix may send  to  Milter  applica-
               tions.
 
 <b><a name="mime_processing_controls">MIME PROCESSING CONTROLS</a></b>
@@ -290,74 +294,74 @@ CLEANUP(8)                                                          CLEANUP(8)
               ing information.
 
        <b><a href="postconf.5.html#strict_mime_encoding_domain">strict_mime_encoding_domain</a> (no)</b>
-              Reject mail with invalid Content-Transfer-Encoding:  information
+              Reject  mail with invalid Content-Transfer-Encoding: information
               for the message/* or multipart/* MIME content types.
 
        Available in Postfix version 2.5 and later:
 
        <b><a href="postconf.5.html#detect_8bit_encoding_header">detect_8bit_encoding_header</a> (yes)</b>
-              Automatically  detect  8BITMIME  body content by looking at Con-
-              tent-Transfer-Encoding:  message  headers;  historically,   this
+              Automatically detect 8BITMIME body content by  looking  at  Con-
+              tent-Transfer-Encoding:   message  headers;  historically,  this
               behavior was hard-coded to be "always on".
 
 <b><a name="automatic_bcc_recipient_controls">AUTOMATIC BCC RECIPIENT CONTROLS</a></b>
-       Postfix  can automatically add BCC (blind carbon copy) when mail enters
+       Postfix can automatically add BCC (blind carbon copy) when mail  enters
        the mail system:
 
        <b><a href="postconf.5.html#always_bcc">always_bcc</a> (empty)</b>
-              Optional address that receives a "blind  carbon  copy"  of  each
+              Optional  address  that  receives  a "blind carbon copy" of each
               message that is received by the Postfix mail system.
 
        Available in Postfix version 2.1 and later:
 
        <b><a href="postconf.5.html#sender_bcc_maps">sender_bcc_maps</a> (empty)</b>
-              Optional  BCC (blind carbon-copy) address lookup tables, indexed
+              Optional BCC (blind carbon-copy) address lookup tables,  indexed
               by envelope sender address.
 
        <b><a href="postconf.5.html#recipient_bcc_maps">recipient_bcc_maps</a> (empty)</b>
-              Optional BCC (blind carbon-copy) address lookup tables,  indexed
+              Optional  BCC (blind carbon-copy) address lookup tables, indexed
               by envelope recipient address.
 
 <b><a name="address_transformation_controls">ADDRESS TRANSFORMATION CONTROLS</a></b>
-       Address  rewriting  is delegated to the <a href="trivial-rewrite.8.html"><b>trivial-rewrite</b>(8)</a> daemon.  The
+       Address rewriting is delegated to the <a href="trivial-rewrite.8.html"><b>trivial-rewrite</b>(8)</a>  daemon.   The
        <a href="cleanup.8.html"><b>cleanup</b>(8)</a> server implements table driven address mapping.
 
        <b><a href="postconf.5.html#empty_address_recipient">empty_address_recipient</a> (MAILER-DAEMON)</b>
               The recipient of mail addressed to the null address.
 
        <b><a href="postconf.5.html#canonical_maps">canonical_maps</a> (empty)</b>
-              Optional address mapping lookup tables for message  headers  and
+              Optional  address  mapping lookup tables for message headers and
               envelopes.
 
        <b><a href="postconf.5.html#recipient_canonical_maps">recipient_canonical_maps</a> (empty)</b>
-              Optional  address  mapping lookup tables for envelope and header
+              Optional address mapping lookup tables for envelope  and  header
               recipient addresses.
 
        <b><a href="postconf.5.html#sender_canonical_maps">sender_canonical_maps</a> (empty)</b>
-              Optional address mapping lookup tables for envelope  and  header
+              Optional  address  mapping lookup tables for envelope and header
               sender addresses.
 
        <b><a href="postconf.5.html#masquerade_classes">masquerade_classes</a> (envelope_sender, header_sender, header_recipient)</b>
               What addresses are subject to address masquerading.
 
        <b><a href="postconf.5.html#masquerade_domains">masquerade_domains</a> (empty)</b>
-              Optional  list  of  domains  whose  subdomain  structure will be
+              Optional list of  domains  whose  subdomain  structure  will  be
               stripped off in email addresses.
 
        <b><a href="postconf.5.html#masquerade_exceptions">masquerade_exceptions</a> (empty)</b>
-              Optional list of user names that are not  subjected  to  address
-              masquerading,   even   when   their  addresses  match  $<a href="postconf.5.html#masquerade_domains">masquer</a>-
+              Optional  list  of  user names that are not subjected to address
+              masquerading,  even  when  their   addresses   match   $<a href="postconf.5.html#masquerade_domains">masquer</a>-
               <a href="postconf.5.html#masquerade_domains">ade_domains</a>.
 
        <b><a href="postconf.5.html#propagate_unmatched_extensions">propagate_unmatched_extensions</a> (canonical, virtual)</b>
-              What address lookup tables copy an address  extension  from  the
+              What  address  lookup  tables copy an address extension from the
               lookup key to the lookup result.
 
        Available before Postfix version 2.0:
 
        <b><a href="postconf.5.html#virtual_maps">virtual_maps</a> (empty)</b>
-              Optional  lookup  tables  with a) names of domains for which all
-              addresses are aliased to addresses  in  other  local  or  remote
+              Optional lookup tables with a) names of domains  for  which  all
+              addresses  are  aliased  to  addresses  in other local or remote
               domains, and b) addresses that are aliased to addresses in other
               local or remote domains.
 
@@ -365,19 +369,19 @@ CLEANUP(8)                                                          CLEANUP(8)
 
        <b><a href="postconf.5.html#virtual_alias_maps">virtual_alias_maps</a> ($<a href="postconf.5.html#virtual_maps">virtual_maps</a>)</b>
               Optional lookup tables that are often searched with a full email
-              address  (including  domain)  and  that apply to all recipients:
-              <a href="local.8.html"><b>local</b>(8)</a>, virtual, and remote; this is  unlike  <a href="postconf.5.html#alias_maps">alias_maps</a>  that
-              are  only  searched  with an email address localpart (no domain)
+              address (including domain) and that  apply  to  all  recipients:
+              <a href="local.8.html"><b>local</b>(8)</a>,  virtual,  and  remote; this is unlike <a href="postconf.5.html#alias_maps">alias_maps</a> that
+              are only searched with an email address  localpart  (no  domain)
               and that apply only to <a href="local.8.html"><b>local</b>(8)</a> recipients.
 
        Available in Postfix version 2.2 and later:
 
-       <b><a href="postconf.5.html#canonical_classes">canonical_classes</a> (envelope_sender, envelope_recipient,  header_sender,</b>
+       <b><a href="postconf.5.html#canonical_classes">canonical_classes</a>  (envelope_sender, envelope_recipient, header_sender,</b>
        <b>header_recipient)</b>
               What addresses are subject to <a href="postconf.5.html#canonical_maps">canonical_maps</a> address mapping.
 
        <b><a href="postconf.5.html#recipient_canonical_classes">recipient_canonical_classes</a> (envelope_recipient, header_recipient)</b>
-              What addresses are subject to  <a href="postconf.5.html#recipient_canonical_maps">recipient_canonical_maps</a>  address
+              What  addresses  are subject to <a href="postconf.5.html#recipient_canonical_maps">recipient_canonical_maps</a> address
               mapping.
 
        <b><a href="postconf.5.html#sender_canonical_classes">sender_canonical_classes</a> (envelope_sender, header_sender)</b>
@@ -385,9 +389,9 @@ CLEANUP(8)                                                          CLEANUP(8)
               ping.
 
        <b><a href="postconf.5.html#remote_header_rewrite_domain">remote_header_rewrite_domain</a> (empty)</b>
-              Rewrite or add message headers in mail from  remote  clients  if
-              the  <a href="postconf.5.html#remote_header_rewrite_domain">remote_header_rewrite_domain</a>  parameter value is non-empty,
-              updating incomplete addresses with the domain specified  in  the
+              Rewrite  or  add  message headers in mail from remote clients if
+              the <a href="postconf.5.html#remote_header_rewrite_domain">remote_header_rewrite_domain</a> parameter value  is  non-empty,
+              updating  incomplete  addresses with the domain specified in the
               <a href="postconf.5.html#remote_header_rewrite_domain">remote_header_rewrite_domain</a> parameter, and adding missing head-
               ers.
 
@@ -398,7 +402,7 @@ CLEANUP(8)                                                          CLEANUP(8)
               <a href="showq.8.html"><b>showq</b>(8)</a> queue displays.
 
        <b><a href="postconf.5.html#header_size_limit">header_size_limit</a> (102400)</b>
-              The maximal amount of memory in  bytes  for  storing  a  message
+              The  maximal  amount  of  memory  in bytes for storing a message
               header.
 
        <b><a href="postconf.5.html#hopcount_limit">hopcount_limit</a> (50)</b>
@@ -406,17 +410,17 @@ CLEANUP(8)                                                          CLEANUP(8)
               in the primary message headers.
 
        <b><a href="postconf.5.html#in_flow_delay">in_flow_delay</a> (1s)</b>
-              Time to pause before accepting a new message, when  the  message
+              Time  to  pause before accepting a new message, when the message
               arrival rate exceeds the message delivery rate.
 
        <b><a href="postconf.5.html#message_size_limit">message_size_limit</a> (10240000)</b>
-              The  maximal  size  in  bytes  of  a message, including envelope
+              The maximal size in  bytes  of  a  message,  including  envelope
               information.
 
        Available in Postfix version 2.0 and later:
 
        <b><a href="postconf.5.html#header_address_token_limit">header_address_token_limit</a> (10240)</b>
-              The maximal number of address tokens are allowed in  an  address
+              The  maximal  number of address tokens are allowed in an address
               message header.
 
        <b><a href="postconf.5.html#mime_boundary_length_limit">mime_boundary_length_limit</a> (2048)</b>
@@ -432,7 +436,7 @@ CLEANUP(8)                                                          CLEANUP(8)
        Available in Postfix version 2.1 and later:
 
        <b><a href="postconf.5.html#virtual_alias_expansion_limit">virtual_alias_expansion_limit</a> (1000)</b>
-              The  maximal  number  of  addresses that virtual alias expansion
+              The maximal number of addresses  that  virtual  alias  expansion
               produces from each original recipient.
 
        <b><a href="postconf.5.html#virtual_alias_recursion_limit">virtual_alias_recursion_limit</a> (1000)</b>
@@ -441,25 +445,25 @@ CLEANUP(8)                                                          CLEANUP(8)
        Available in Postfix version 3.0 and later:
 
        <b><a href="postconf.5.html#virtual_alias_address_length_limit">virtual_alias_address_length_limit</a> (1000)</b>
-              The maximal length of  an  email  address  after  virtual  alias
+              The  maximal  length  of  an  email  address after virtual alias
               expansion.
 
 <b><a name="smtputf8_controls">SMTPUTF8 CONTROLS</a></b>
        Preliminary SMTPUTF8 support is introduced with Postfix 3.0.
 
        <b><a href="postconf.5.html#smtputf8_enable">smtputf8_enable</a> (yes)</b>
-              Enable  preliminary SMTPUTF8 support for the protocols described
+              Enable preliminary SMTPUTF8 support for the protocols  described
               in <a href="https://tools.ietf.org/html/rfc6531">RFC 6531</a>, <a href="https://tools.ietf.org/html/rfc6532">RFC 6532</a>, and <a href="https://tools.ietf.org/html/rfc6533">RFC 6533</a>.
 
        <b><a href="postconf.5.html#smtputf8_autodetect_classes">smtputf8_autodetect_classes</a> (sendmail, verify)</b>
-              Detect that a message requires SMTPUTF8 support for  the  speci-
+              Detect  that  a message requires SMTPUTF8 support for the speci-
               fied mail origin classes.
 
        Available in Postfix version 3.2 and later:
 
        <b><a href="postconf.5.html#enable_idna2003_compatibility">enable_idna2003_compatibility</a> (no)</b>
-              Enable   'transitional'   compatibility   between  IDNA2003  and
-              IDNA2008, when converting UTF-8 domain names to/from  the  ASCII
+              Enable  'transitional'  compatibility   between   IDNA2003   and
+              IDNA2008,  when  converting UTF-8 domain names to/from the ASCII
               form that is used for DNS lookups.
 
 <b><a name="tls_support">TLS SUPPORT</a></b>
@@ -471,27 +475,27 @@ CLEANUP(8)                                                          CLEANUP(8)
 
 <b><a name="miscellaneous_controls">MISCELLANEOUS CONTROLS</a></b>
        <b><a href="postconf.5.html#config_directory">config_directory</a> (see 'postconf -d' output)</b>
-              The default location of the Postfix <a href="postconf.5.html">main.cf</a> and  <a href="master.5.html">master.cf</a>  con-
+              The  default  location of the Postfix <a href="postconf.5.html">main.cf</a> and <a href="master.5.html">master.cf</a> con-
               figuration files.
 
        <b><a href="postconf.5.html#daemon_timeout">daemon_timeout</a> (18000s)</b>
-              How  much  time  a  Postfix  daemon process may take to handle a
+              How much time a Postfix daemon process  may  take  to  handle  a
               request before it is terminated by a built-in watchdog timer.
 
        <b><a href="postconf.5.html#delay_logging_resolution_limit">delay_logging_resolution_limit</a> (2)</b>
-              The maximal number of digits after the decimal point  when  log-
+              The  maximal  number of digits after the decimal point when log-
               ging delay values.
 
        <b><a href="postconf.5.html#delay_warning_time">delay_warning_time</a> (0h)</b>
-              The  time  after which the sender receives a copy of the message
+              The time after which the sender receives a copy of  the  message
               headers of mail that is still queued.
 
        <b><a href="postconf.5.html#ipc_timeout">ipc_timeout</a> (3600s)</b>
-              The time limit for sending  or  receiving  information  over  an
+              The  time  limit  for  sending  or receiving information over an
               internal communication channel.
 
        <b><a href="postconf.5.html#max_idle">max_idle</a> (100s)</b>
-              The  maximum  amount of time that an idle Postfix daemon process
+              The maximum amount of time that an idle Postfix  daemon  process
               waits for an incoming connection before terminating voluntarily.
 
        <b><a href="postconf.5.html#max_use">max_use</a> (100)</b>
@@ -502,7 +506,7 @@ CLEANUP(8)                                                          CLEANUP(8)
               The internet hostname of this mail system.
 
        <b><a href="postconf.5.html#myorigin">myorigin</a> ($<a href="postconf.5.html#myhostname">myhostname</a>)</b>
-              The domain name that locally-posted mail appears to  come  from,
+              The  domain  name that locally-posted mail appears to come from,
               and that locally posted mail is delivered to.
 
        <b><a href="postconf.5.html#process_id">process_id</a> (read-only)</b>
@@ -515,21 +519,21 @@ CLEANUP(8)                                                          CLEANUP(8)
               The location of the Postfix top-level queue directory.
 
        <b><a href="postconf.5.html#soft_bounce">soft_bounce</a> (no)</b>
-              Safety  net to keep mail queued that would otherwise be returned
+              Safety net to keep mail queued that would otherwise be  returned
               to the sender.
 
        <b><a href="postconf.5.html#syslog_facility">syslog_facility</a> (mail)</b>
               The syslog facility of Postfix logging.
 
        <b><a href="postconf.5.html#syslog_name">syslog_name</a> (see 'postconf -d' output)</b>
-              A prefix that  is  prepended  to  the  process  name  in  syslog
+              A  prefix  that  is  prepended  to  the  process  name in syslog
               records, so that, for example, "smtpd" becomes "prefix/smtpd".
 
        Available in Postfix version 2.1 and later:
 
        <b><a href="postconf.5.html#enable_original_recipient">enable_original_recipient</a> (yes)</b>
-              Enable  support  for  the  original  recipient  address after an
-              address is rewritten to a different address  (for  example  with
+              Enable support for  the  original  recipient  address  after  an
+              address  is  rewritten  to a different address (for example with
               aliasing or with canonical mapping).
 
        Available in Postfix 3.3 and later:
@@ -540,14 +544,14 @@ CLEANUP(8)                                                          CLEANUP(8)
        Available in Postfix 3.5 and later:
 
        <b><a href="postconf.5.html#info_log_address_format">info_log_address_format</a> (external)</b>
-              The  email  address  form that will be used in non-debug logging
+              The email address form that will be used  in  non-debug  logging
               (info, warning, etc.).
 
        Available in Postfix 3.9 and later:
 
        <b><a href="postconf.5.html#force_mime_input_conversion">force_mime_input_conversion</a> (no)</b>
-              Convert body content that claims to be 8-bit into  quoted-print-
-              able,  before  <a href="postconf.5.html#header_checks">header_checks</a>,  <a href="postconf.5.html#body_checks">body_checks</a>,  Milters, and before
+              Convert  body content that claims to be 8-bit into quoted-print-
+              able, before <a href="postconf.5.html#header_checks">header_checks</a>,  <a href="postconf.5.html#body_checks">body_checks</a>,  Milters,  and  before
               after-queue content filters.
 
 <b><a name="files">FILES</a></b>
index de47f73e7726c0b6092813d96a092d8cd0657793..c6a02d86c83e8048a60f74abedbffc14c5badfa0 100644 (file)
@@ -8020,6 +8020,42 @@ Sendmail compatibility feature that specifies the location of the
 </p>
 
 
+</DD>
+
+<DT><b><a name="non_empty_end_of_header_action">non_empty_end_of_header_action</a>
+(default: fix_quietly)</b></DT><DD>
+
+<p> How the <a href="cleanup.8.html">cleanup(8)</a> daemon will process a message when the primary
+message header is terminated with a non-empty line. </p>
+
+<dl>
+
+<dt> <b> fix_quietly </b> </dt> <dd> <p> Default behavior: insert
+an empty line before the erroneous text. This behavior is backwards
+compatible with Postfix &le; 3.10. </p> </dd>
+
+<dt> <b> add_header </b> </dt><dd> <p> Insert a MIME-Error:
+header and an empty line before the erroneous text. </p>
+<p> Example: </p>
+<pre>
+MIME-Error: message header was not terminated by empty line
+</pre> </dd>
+
+<dt> <b> reject </b> </dt>  <dd> <p> Log the erroneous text and
+reject the message content. </p>
+<p> Example: </p>
+<pre>
+<i>queueid</i> reject: mime-error message header was terminated
+with non-empty line: <i>erroneous text</i>; from=&lt;<i>sender</i>&gt;
+to=&lt;<i>recipient</i>&gt;
+</pre>
+</dd>
+
+<dl>
+
+<p> This feature is available in Postfix &ge; 3.11. </p>
+
+
 </DD>
 
 <DT><b><a name="non_fqdn_reject_code">non_fqdn_reject_code</a>
index 819d18ae49acd4b55691d4771d8e326ab0e982c1..1905321c2eb04120fef4310aa753cae7a0eea8d5 100644 (file)
@@ -4913,6 +4913,38 @@ This feature is available in Postfix 2.0 and later.
 Sendmail compatibility feature that specifies the location of the
 \fBnewaliases\fR(1) command. This command can be used to rebuild the
 \fBlocal\fR(8) \fBaliases\fR(5) database.
+.SH non_empty_end_of_header_action (default: fix_quietly)
+How the \fBcleanup\fR(8) daemon will process a message when the primary
+message header is terminated with a non\-empty line.
+.IP "\fB fix_quietly \fR"
+Default behavior: insert
+an empty line before the erroneous text. This behavior is backwards
+compatible with Postfix <= 3.10.
+.br
+.IP "\fB add_header \fR"
+Insert a MIME\-Error:
+header and an empty line before the erroneous text.
+Example:
+.nf
+.na
+MIME\-Error: message header was not terminated by empty line
+.fi
+.ad
+.br
+.IP "\fB reject \fR"
+Log the erroneous text and
+reject the message content.
+Example:
+.nf
+.na
+\fIqueueid\fR reject: mime\-error message header was terminated
+with non\-empty line: \fIerroneous text\fR; from=<\fIsender\fR>
+to=<\fIrecipient\fR>
+.fi
+.ad
+.br
+.PP
+This feature is available in Postfix >= 3.11.
 .SH non_fqdn_reject_code (default: 504)
 The numerical Postfix SMTP server reply code when a client request
 is rejected by the reject_non_fqdn_helo_hostname, reject_non_fqdn_sender
index 66a7578383af68711055988f3210c4ef4a970680..916c080f4bc9d689f08c3c0444077f32b2cdcc70 100644 (file)
@@ -146,6 +146,9 @@ Available in Postfix version 3.10 and later:
 The character set name (also called "charset") that Postfix
 will output when it automatically generates an RFC 2047 encoded
 full name.
+.IP "\fBnon_empty_end_of_header_action (fix_quietly)\fR"
+How the \fBcleanup\fR(8) daemon will process a message when the primary
+message header is terminated with a non\-empty line.
 .SH "BUILT-IN CONTENT FILTERING CONTROLS"
 .na
 .nf
index 3ed4999777c073ce01898ba6cc6ad98e6b53e543..e09c450d5403bb20fd5cc417547bf3247483a2eb 100755 (executable)
@@ -426,6 +426,7 @@ while (<>) {
     s;\breadme_directory\b;<a href="postconf.5.html#readme_directory">$&</a>;g;
     s;\breceive_override_options\b;<a href="postconf.5.html#receive_override_options">$&</a>;g;
     s;\bremote_header_re[-</bB>]*\n* *[<bB>]*write_domain\b;<a href="postconf.5.html#remote_header_rewrite_domain">$&</a>;g;
+    s;\bnon_empty_end_of_header_action\b;<a href="postconf.5.html#non_empty_end_of_header_action">$&</a>;g;
     s;\bno_unknown_recip[-</bB>]*\n* *[<bB>]*ient_checks\b;<a href="postconf.5.html#no_unknown_recipient_checks">$&</a>;g;
     s;\bno_address_mappings\b;<a href="postconf.5.html#no_address_mappings">$&</a>;g;
     s;\bno_header_body_checks\b;<a href="postconf.5.html#no_header_body_checks">$&</a>;g;
index 1c52dd696fbcb524dcd25cc533a48ab481ab38ee..56500ba5a87b8806315d2b03d85fdbaaa4555ecf 100644 (file)
@@ -56,12 +56,16 @@ names inside shaded areas represent Postfix queues. </p>
 
 <tr>
 
-<td colspan="4"> </td>
+<td colspan="3"> </td>
 
-<td bgcolor="#f0f0ff" align="center"> trivial-<br>rewrite(8) </td>
+<td> &nbsp; </td>
+
+<td rowspan="2" bgcolor="#f0f0ff" align="center"> trivial-<br>rewrite(8) </td>
 
 </tr>
 
+<tr> <td colspan="3"> </td> <td> / </td> </tr>
+
 <tr>
 
 <td> Network </td> <td> <tt> -&gt; </tt> </td>
index 33349122c83b340bdac2c86c83ae2c2577ed8606..f82e4b37192e2fdabb8fd03bb1c5f0203c6d1a5c 100644 (file)
@@ -19746,3 +19746,35 @@ filter out").
 </pre>
 
 <p> This feature is available in Postfix &ge; 3.11. </p>
+
+%PARAM non_empty_end_of_header_action fix_quietly
+
+<p> How the cleanup(8) daemon will process a message when the primary
+message header is terminated with a non-empty line. </p>
+
+<dl>
+
+<dt> <b> fix_quietly </b> </dt> <dd> <p> Default behavior: insert
+an empty line before the erroneous text. This behavior is backwards
+compatible with Postfix &le; 3.10. </p> </dd>
+
+<dt> <b> add_header </b> </dt><dd> <p> Insert a MIME-Error: 
+header and an empty line before the erroneous text. </p>
+<p> Example: </p>
+<pre>
+MIME-Error: message header was not terminated by empty line
+</pre> </dd>
+
+<dt> <b> reject </b> </dt>  <dd> <p> Log the erroneous text and
+reject the message content. </p>
+<p> Example: </p>
+<pre> 
+<i>queueid</i> reject: mime-error message header was terminated
+with non-empty line: <i>erroneous text</i>; from=&lt;<i>sender</i>&gt;
+to=&lt;<i>recipient</i>&gt;
+</pre>
+</dd>
+
+<dl>
+
+<p> This feature is available in Postfix &ge; 3.11. </p>
index 46b225218ffb5fde979307dc43130e187d1a5b98..f9861d1f10daec5653ffc4469ad2387102b42b13 100644 (file)
 /*     The character set name (also called "charset") that Postfix
 /*     will output when it automatically generates an RFC 2047 encoded
 /*     full name.
+/* .IP "\fBnon_empty_end_of_header_action (fix_quietly)\fR"
+/*     How the \fBcleanup\fR(8) daemon will process a message when the primary
+/*     message header is terminated with a non-empty line.
 /* BUILT-IN CONTENT FILTERING CONTROLS
 /* .ad
 /* .fi
index 82bd482efed858c34f083250c4a0b5034657816c..58b747450a8ff36cbe0726f94503feec05970c77 100644 (file)
@@ -361,6 +361,16 @@ extern void cleanup_body_edit_free(CLEANUP_STATE *);
   */
 extern int cleanup_hfrom_format;
 
+ /*
+  * How to handle garbage at end of the primary message header.
+  */
+#define NON_EMPTY_EOH_CODE_ERROR       -1      /* sentinel */
+#define NON_EMPTY_EOH_CODE_FIX_QUIETLY 0
+#define NON_EMPTY_EOH_CODE_ADD_HDR     1
+#define NON_EMPTY_EOH_CODE_REJECT      2
+
+extern int cleanup_non_empty_eoh_action;
+
 /* LICENSE
 /* .ad
 /* .fi
index 8f6b3e14d246fd8d089698ce92b4466b856b4e9d..f7872d881c7a20c07158966b7dd1b47a91b812da 100644 (file)
@@ -77,6 +77,9 @@
 /*     Google, Inc.
 /*     111 8th Avenue
 /*     New York, NY 10011, USA
+/*
+/*     Wietse Venema
+/*     porcupine.org
 /*--*/
 
 /* System library. */
@@ -177,6 +180,7 @@ char   *var_hfrom_format;           /* header_from_format */
 char   *var_full_name_encoding_charset;        /* in =?charset?encoding?gibberish=? */
 int     var_force_mime_iconv;          /* force mime downgrade on input */
 int     var_cleanup_mask_stray_cr_lf;  /* replace stray CR or LF with space */
+char   *var_non_empty_eoh_action;      /* handle non-empty header terminator */
 
 const CONFIG_INT_TABLE cleanup_int_table[] = {
     VAR_HOPCOUNT_LIMIT, DEF_HOPCOUNT_LIMIT, &var_hopcount_limit, 1, 0,
@@ -247,6 +251,7 @@ const CONFIG_STR_TABLE cleanup_str_table[] = {
     VAR_MILT_MACRO_DEFLTS, DEF_MILT_MACRO_DEFLTS, &var_milt_macro_deflts, 0, 0,
     VAR_HFROM_FORMAT, DEF_HFROM_FORMAT, &var_hfrom_format, 1, 0,
     VAR_FULL_NAME_ENCODING_CHARSET, DEF_FULL_NAME_ENCODING_CHARSET, &var_full_name_encoding_charset, 1, 0,
+    VAR_NON_EMPTY_EOH_ACTION, DEF_NON_EMPTY_EOH_ACTION, &var_non_empty_eoh_action, 1, 0,
     0,
 };
 
@@ -291,6 +296,11 @@ MILTERS *cleanup_milters;
   */
 int     cleanup_hfrom_format;
 
+ /*
+  * Garbage after message header.
+  */
+int     cleanup_non_empty_eoh_action;
+
 /* cleanup_all - callback for the runtime error handler */
 
 void    cleanup_all(void)
@@ -443,6 +453,12 @@ void    cleanup_pre_jail(char *unused_name, char **unused_argv)
 
 void    cleanup_post_jail(char *unused_name, char **unused_argv)
 {
+    static NAME_CODE non_empty_eoh_actions[] = {
+       {NON_EMPTY_EOH_NAME_FIX_QUIETLY, NON_EMPTY_EOH_CODE_FIX_QUIETLY},
+       {NON_EMPTY_EOH_NAME_ADD_HDR, NON_EMPTY_EOH_CODE_ADD_HDR},
+       {NON_EMPTY_EOH_NAME_REJECT, NON_EMPTY_EOH_CODE_REJECT},
+       {0, NON_EMPTY_EOH_CODE_ERROR},
+    };
 
     /*
      * Optionally set the file size resource limit. XXX This limits the
@@ -477,4 +493,13 @@ void    cleanup_post_jail(char *unused_name, char **unused_argv)
      * From: header formatting.
      */
     cleanup_hfrom_format = hfrom_format_parse(VAR_HFROM_FORMAT, var_hfrom_format);
+
+    /*
+     * Garbage after message header.
+     */
+    if ((cleanup_non_empty_eoh_action =
+        name_code(non_empty_eoh_actions, NAME_CODE_FLAG_NONE,
+                  var_non_empty_eoh_action)) == NON_EMPTY_EOH_CODE_ERROR)
+       msg_fatal("bad %s value: '%s'", VAR_NON_EMPTY_EOH_ACTION,
+                 var_non_empty_eoh_action);
 }
index 7259de188056f0845c1c42bd8603fb804e28de33..9f84bdcf3587fb9cf5b6394f34620042950fd663 100644 (file)
@@ -722,6 +722,7 @@ static void cleanup_header_done_callback(void *context)
     char    time_stamp[1024];          /* XXX locale dependent? */
     struct tm *tp;
     time_t  tv;
+    int     mime_errs;
 
     /*
      * XXX Workaround: when we reach the end of headers, mime_state_update()
@@ -906,6 +907,15 @@ static void cleanup_header_done_callback(void *context)
            msg_fatal("%s: vstream_ftell %s: %m", myname, cleanup_path);
        state->body_offset = state->append_hdr_pt_target;
     }
+
+    /*
+     * Get the current error state before mime_state_update() can return it.
+     */
+    mime_errs = mime_state_status(state->mime_state);
+    if ((mime_errs && MIME_ERR_NON_EMPTY_EOH)
+       && cleanup_non_empty_eoh_action == NON_EMPTY_EOH_CODE_ADD_HDR)
+       cleanup_out_string(state, REC_TYPE_NORM,
+            "MIME-Error: message header was not terminated by empty line");
 }
 
 /* cleanup_body_callback - output one body record */
@@ -1047,6 +1057,8 @@ static void cleanup_message_headerbody(CLEANUP_STATE *state, int type,
            cleanup_out_format(state, REC_TYPE_PTR, REC_TYPE_PTR_FORMAT, 0L);
        /* Ignore header truncation after primary message headers. */
        state->mime_errs &= ~MIME_ERR_TRUNC_HEADER;
+       if (cleanup_non_empty_eoh_action != NON_EMPTY_EOH_CODE_REJECT)
+           state->mime_errs &= ~MIME_ERR_NON_EMPTY_EOH;
        if (state->mime_errs && state->reason == 0) {
            state->errs |= CLEANUP_STAT_CONT;
            detail = mime_state_detail(state->mime_errs);
@@ -1081,16 +1093,22 @@ static void cleanup_mime_error_callback(void *context, int err_code,
      * Message header too large errors are handled after the end of the
      * primary message headers.
      */
-    if ((err_code & ~MIME_ERR_TRUNC_HEADER) != 0) {
-       if ((origin = nvtable_find(state->attr, MAIL_ATTR_LOG_ORIGIN)) == 0)
-           origin = MAIL_ATTR_ORG_NONE;
-#define TEXT_LEN (len < 100 ? (int) len : 100)
-       msg_info("%s: reject: mime-error %s: %.*s from %s; from=<%s> to=<%s>",
-                state->queue_id, mime_state_error(err_code), TEXT_LEN, text,
-                origin, info_log_addr_form_sender(state->sender),
-                info_log_addr_form_recipient(state->recip ?
-                                             state->recip : "unknown"));
+    switch (err_code) {
+    case MIME_ERR_TRUNC_HEADER:
+       /* TODO(wietse) Unconditional? */
+       return;
+    case MIME_ERR_NON_EMPTY_EOH:
+       if (cleanup_non_empty_eoh_action != NON_EMPTY_EOH_CODE_REJECT)
+           return;
     }
+    if ((origin = nvtable_find(state->attr, MAIL_ATTR_LOG_ORIGIN)) == 0)
+       origin = MAIL_ATTR_ORG_NONE;
+#define TEXT_LEN (len < 100 ? (int) len : 100)
+    msg_info("%s: reject: mime-error %s: %.*s from %s; from=<%s> to=<%s>",
+            state->queue_id, mime_state_error(err_code), TEXT_LEN, text,
+            origin, info_log_addr_form_sender(state->sender),
+            info_log_addr_form_recipient(state->recip ?
+                                         state->recip : "unknown"));
 }
 
 /* cleanup_message - initialize message content segment */
@@ -1127,6 +1145,8 @@ void    cleanup_message(CLEANUP_STATE *state, int type, const char *buf, ssize_t
                mime_options |= MIME_OPT_REPORT_8BIT_IN_7BIT_BODY;
            if (var_strict_encoding)
                mime_options |= MIME_OPT_REPORT_ENCODING_DOMAIN;
+           if (cleanup_non_empty_eoh_action != NON_EMPTY_EOH_CODE_FIX_QUIETLY)
+               mime_options |= MIME_OPT_REPORT_NON_EMPTY_EOH;
            if (var_strict_8bitmime || var_strict_7bit_hdrs
                || var_strict_8bit_body || var_strict_encoding
                || *var_header_checks || *var_mimehdr_checks
index 7583c8b556619a3c52b6317a0c883740c22a7382..563e4c625927d7765811e89f825ba71fdd3eaf46 100644 (file)
@@ -440,6 +440,17 @@ extern char *var_drop_hdrs;
 #define DEF_HFROM_FORMAT       HFROM_FORMAT_NAME_STD
 extern char *var_hfrom_format;
 
+ /*
+  * How to handle malformed header ending.
+  */
+#define NON_EMPTY_EOH_NAME_FIX_QUIETLY "fix_quietly"
+#define NON_EMPTY_EOH_NAME_ADD_HDR     "add_header"
+#define NON_EMPTY_EOH_NAME_REJECT      "reject"
+
+#define VAR_NON_EMPTY_EOH_ACTION       "non_empty_end_of_header_action"
+#define DEF_NON_EMPTY_EOH_ACTION       NON_EMPTY_EOH_NAME_FIX_QUIETLY
+extern char *var_non_empty_eoh_action;
+
  /*
   * Standards violation: allow/permit RFC 822-style addresses in SMTP
   * commands.
index 19e1a0cd0e10075f707468bc3ac9ef58e466a7a4..c51f2806761b31a6830f57c088fdb44e3d8f9bcf 100644 (file)
@@ -20,7 +20,7 @@
   * Patches change both the patchlevel and the release date. Snapshots have no
   * patchlevel; they change the release date only.
   */
-#define MAIL_RELEASE_DATE      "20251102"
+#define MAIL_RELEASE_DATE      "20251105"
 #define MAIL_VERSION_NUMBER    "3.11"
 
 #ifdef SNAPSHOT
index ee8ef36b88c817215c63648b96bb1e4305e0e643..a5de693e46f1abd553a98e49ce02b24cd87caa1d 100644 (file)
@@ -7,6 +7,7 @@ mime_state: header_token: boundary = Boundary-00=_mvhpFky0yqNhsa4
 mime_state: PUSH boundary Boundary-00=_mvhpFky0yqNhsa4
 MAIN 95        |Content-Type: Multipart/Mixed;
   boundary="Boundary-00=_mvhpFky0yqNhsa4"
+mime_state: warning: primary header was terminated with non-empty line: junk in primary header
 HEADER END
 mime_state: garbage in primary header
 BODY N 0       |
@@ -42,4 +43,5 @@ BODY N 135    |Blah
 BODY N 140     |
 BODY END
 mime_state: warning: improper message/* or multipart/* encoding domain
+mime_state: warning: non-empty end-of-header
 mime_state: POP boundary Boundary-00=_mvhpFky0yqNhsa4
index e1b6a65ceb7a41bac9f6037c65f21fdc20851f8e..798e13de7d89605aef4a55df716a6b3154841177 100644 (file)
@@ -27,6 +27,9 @@
 /*     const char *buf;
 /*     ssize_t len;
 /*
+/*     int     mime_state_status(state)
+/*     MIME_STATE *state;
+/*
 /*     MIME_STATE *mime_state_free(state)
 /*     MIME_STATE *state;
 /*
 /*     content transfer encoding domain, or specifies a transformation
 /*     (quoted-printable, base64) instead of a domain (7bit, 8bit,
 /*     or binary).
+/* .IP MIME_ERR_NON_EMPTY_EOH
+/*     The primary message header was terminated with a non-empty line.
 /* .PP
+/*     mime_state_status() reports the same result as
+/*     mime_state_update(), but without changing state.
+/*
 /*     mime_state_free() releases storage for a MIME state machine,
 /*     and conveniently returns a null pointer.
 /*
 /* .IP MIME_OPT_REPORT_NESTING
 /*     Report errors that set the MIME_ERR_NESTING error flag
 /*     (see above).
+/* .IP MIME_OPT_REPORT_NON_EMPTY_EOH
+/*     Report errors that terminate the primary message header with a
+/*     non-empty line.
 /* .IP MIME_OPT_DOWNGRADE
 /*     Transform content that claims to be 8-bit into quoted-printable.
 /*     Where appropriate, update Content-Transfer-Encoding: message
@@ -915,8 +926,13 @@ int     mime_state_update(MIME_STATE *state, int rec_type,
         * This input terminates a block of message headers. Call the
         * optional header end routine at the end of the first header block.
         */
-       if (state->curr_state == MIME_STATE_PRIMARY && state->head_end)
-           state->head_end(state->app_context);
+       if (state->curr_state == MIME_STATE_PRIMARY) {
+           if (len > 0
+               && (state->static_flags & MIME_OPT_REPORT_NON_EMPTY_EOH))
+               REPORT_ERROR_LEN(state, MIME_ERR_NON_EMPTY_EOH, text, len);
+           if (state->head_end)
+               state->head_end(state->app_context);
+       }
 
        /*
         * This is the right place to check if the sender specified an
@@ -1130,6 +1146,13 @@ int     mime_state_update(MIME_STATE *state, int rec_type,
     }
 }
 
+/* mime_state_status - return mime_state_update() like result */
+
+int     mime_state_status(MIME_STATE *state)
+{
+    return (state->err_flags);
+}
+
  /*
   * Mime error to (DSN, text) mapping. Order matters; more serious errors
   * must precede less serious errors, because the error-to-text conversion
@@ -1141,6 +1164,7 @@ static const MIME_STATE_DETAIL mime_err_detail[] = {
     MIME_ERR_8BIT_IN_HEADER, "5.6.0", "improper use of 8-bit data in message header",
     MIME_ERR_8BIT_IN_7BIT_BODY, "5.6.0", "improper use of 8-bit data in message body",
     MIME_ERR_ENCODING_DOMAIN, "5.6.0", "invalid message/* or multipart/* encoding domain",
+    MIME_ERR_NON_EMPTY_EOH, "5.6.0", "primary header was terminated with non-empty line",
     0,
 };
 
@@ -1254,6 +1278,7 @@ int     main(int unused_argc, char **argv)
            | MIME_OPT_REPORT_ENCODING_DOMAIN \
            | MIME_OPT_REPORT_TRUNC_HEADER \
            | MIME_OPT_REPORT_NESTING \
+           | MIME_OPT_REPORT_NON_EMPTY_EOH \
            | MIME_OPT_DOWNGRADE)
 
     msg_vstream_init(basename(argv[0]), VSTREAM_OUT);
@@ -1288,6 +1313,8 @@ int     main(int unused_argc, char **argv)
        msg_warn("improper use of 8-bit data in message body");
     if (err & MIME_ERR_ENCODING_DOMAIN)
        msg_warn("improper message/* or multipart/* encoding domain");
+    if (err & MIME_ERR_NON_EMPTY_EOH)
+       msg_warn("non-empty end-of-header");
 
     /*
      * Cleanup.
index 88a4d7cf39ed68797aa9f6d35c62f926b8a1fe84..c4514a119c699a79cff778cd295732f75ee3ec05 100644 (file)
@@ -32,6 +32,7 @@ typedef void (*MIME_STATE_ERR_PRINT) (void *, int, const char *, ssize_t);
 
 extern MIME_STATE *mime_state_alloc(int, MIME_STATE_HEAD_OUT, MIME_STATE_ANY_END, MIME_STATE_BODY_OUT, MIME_STATE_ANY_END, MIME_STATE_ERR_PRINT, void *);
 extern int mime_state_update(MIME_STATE *, int, const char *, ssize_t);
+extern int mime_state_status(MIME_STATE *);
 extern MIME_STATE *mime_state_free(MIME_STATE *);
 
  /*
@@ -46,6 +47,7 @@ extern MIME_STATE *mime_state_free(MIME_STATE *);
 #define MIME_OPT_REPORT_TRUNC_HEADER           (1<<5)
 #define MIME_OPT_DISABLE_MIME                  (1<<6)
 #define MIME_OPT_REPORT_NESTING                        (1<<7)
+#define MIME_OPT_REPORT_NON_EMPTY_EOH          (1<<8)
 
  /*
   * Body encoding domains.
@@ -68,6 +70,7 @@ typedef struct {
 #define MIME_ERR_8BIT_IN_HEADER                (1<<2)
 #define MIME_ERR_8BIT_IN_7BIT_BODY     (1<<3)
 #define MIME_ERR_ENCODING_DOMAIN       (1<<4)
+#define MIME_ERR_NON_EMPTY_EOH         (1<<5)
 
 extern const MIME_STATE_DETAIL *mime_state_detail(int);
 extern const char *mime_state_error(int);
index c97efb1cbaf1f43c6bfb02902826d604a1e78394..328e25ae486306ab9f7d953df4e49ddf9dc11bf9 100644 (file)
@@ -45,7 +45,7 @@ Makefile: Makefile.in
 
 test:  $(TESTPROG)
 
-tests: tls_certkey_tests
+tests: tls_certkey_tests tls_dane_tests
 
 tls_certkey_tests: test
        @echo Testing loading of keys and certs
@@ -76,6 +76,9 @@ tls_certkey_tests: test
            echo "  $$pem: OK"; \
        done
 
+tls_dane_tests: tls_dane tls_dane.sh
+       $(SHLIB_ENV) $(VALGRIND) bash tls_dane.sh
+
 root_tests:
 
 $(LIB):        $(OBJS)
index 0b62b520b8e099f6a1a459a51d19caf2eba30141..33b5a21d693e4bfcd0298d9dc228e2b233155fd8 100644 (file)
@@ -1292,9 +1292,6 @@ static SSL_CTX *ctx_init(const char *CAfile)
     tls_param_init();
     tls_check_version();
 
-    if (!tls_validate_digest(LN_sha1))
-       msg_fatal("%s digest algorithm not available", LN_sha1);
-
     if (TLScontext_index < 0)
        if ((TLScontext_index = SSL_get_ex_new_index(0, 0, 0, 0, 0)) < 0)
            msg_fatal("Cannot allocate SSL application data index");
@@ -1339,7 +1336,7 @@ int     main(int argc, char *argv[])
 
     tctx = tls_alloc_sess_context(TLS_LOG_NONE, argv[7]);
     tctx->namaddr = argv[7];
-    tctx->mdalg = LN_sha256;
+    tctx->mdalg = atoi(argv[3]) == 2 ? LN_sha512 : LN_sha256;
     tctx->dane = tls_dane_alloc();
 
     if ((fpt_alg = tls_validate_digest(tctx->mdalg)) == 0)
@@ -1376,9 +1373,10 @@ int     main(int argc, char *argv[])
            peername = argv[7];
        msg_info("Verified %s", peername);
     } else {
-       i = SSL_get_verify_result(tctx->con);
+       int r = SSL_get_verify_result(tctx->con);
+
        msg_info("certificate verification failed for %s:%s: num=%d:%s",
-                argv[6], argv[7], i, X509_verify_cert_error_string(i));
+                argv[6], argv[7], r, X509_verify_cert_error_string(r));
     }
 
     return (i <= 0);
index a950857bb228f230d3dbd3b0bf2dbe166fd80994..ac7b8a228cd31a991b7a66e101da7330f6378b6a 100644 (file)
@@ -23,7 +23,7 @@ req() {
     key "$key"
     openssl req -new -sha256 -key "${key}.pem" 2>/dev/null \
        -config <(printf "[req]\n%s\n%s\n[dn]\nCN=%s\n" \
-                  "prompt = no" "distinguished_name = dn" "${cn}") 
+                  "prompt = no" "distinguished_name = dn" "${cn}")
 }
 
 req_nocn() {
@@ -32,7 +32,7 @@ req_nocn() {
     key "$key"
     openssl req -new -sha256 -subj / -key "${key}.pem" 2>/dev/null \
        -config <(printf "[req]\n%s\n[dn]\nCN_default =\n" \
-                  "distinguished_name = dn") 
+                  "distinguished_name = dn")
 }
 
 cert() {
@@ -131,7 +131,7 @@ runtest() {
     printf "%d %d %d %-24s %s: " "$usage" "$selector" "$mtype" "$tlsa" "$desc"
 
     if [ -n "$ca" ]; then ca="$ca.pem"; fi
-    "$TEST" "$usage" "$selector" "$digest" "$tlsa.pem" "$ca" "$chain.pem" \
+    "$TEST" "$usage" "$selector" "$mtype" "$tlsa.pem" "$ca" "$chain.pem" \
        "$@" > /dev/null
 }
 
@@ -191,16 +191,21 @@ done
 done
 done
 
-# These tests don't depend in the akid/skid chaining:
+# These tests don't depend on the akid/skid chaining:
 #
 for s in 0 1
 do
   checkfail "missing TA" 2 "$s" 1 rootcert "" chain1 "$HOST"
   for m in 0 1 2
   do
-    checkpass "depth 0 TA" 2 "$s" "$m" sscert "" sscert "$HOST" 
+    # Special-case "2 1 0" TLSA records. These match as issuer public keys of a
+    # self-signed EE cert.  The same key as part of a "2 0 0" certificate would
+    # not match.
+    #
+    if [ "$s" -ne 1 -o "$m" -ne 0 ]; then
+        checkfail "depth 0 TA" 2 "$s" "$m" sscert "" sscert "$HOST"
+    fi
     checkfail "non-TA" 2 "$s" "$m" eecert rootcert chain "$HOST"
-    checkfail "depth 0 TA namecheck" 2 "$s" "$m" sscert sscert sscert whatever
 
     checkpass "valid EE" 3 "$s" "$m" eecert "" chain whatever
     checkpass "key-only EE" 3 "$s" "$m" acert "" acert whatever
@@ -208,4 +213,9 @@ do
   done
 done
 
-rm -f *.pem
+rm -f acert.pem akey.pem \
+    eecert.pem eekey.pem \
+    cacert?.pem cakey?.pem \
+    rootcert.pem rootkey.pem \
+    sscert.pem sskey.pem \
+    chain.pem chain1.pem