]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
postfix-3.11-20250906
authorWietse Z Venema <wietse@porcupine.org>
Sat, 6 Sep 2025 05:00:00 +0000 (00:00 -0500)
committerViktor Dukhovni <ietf-dane@dukhovni.org>
Sun, 7 Sep 2025 01:50:05 +0000 (11:50 +1000)
19 files changed:
postfix/HISTORY
postfix/html/lmtp.8.html
postfix/html/postconf.5.html
postfix/html/smtp.8.html
postfix/man/man5/postconf.5
postfix/man/man8/smtp.8
postfix/mantools/postlink
postfix/proto/postconf.proto
postfix/proto/stop.spell-cc
postfix/src/global/mail_params.h
postfix/src/global/mail_version.h
postfix/src/smtp/Makefile.in
postfix/src/smtp/lmtp_params.c
postfix/src/smtp/smtp.c
postfix/src/smtp/smtp.h
postfix/src/smtp/smtp_connect.c
postfix/src/smtp/smtp_params.c
postfix/src/smtp/smtp_tls_policy.c
postfix/src/smtp/smtp_tls_policy_test.c [new file with mode: 0644]

index 53b03a9122bac323c70cf0075fa92d7808b2043e..bd2c2beecc2980fc79c398edf6b5112dfda8dab2 100644 (file)
@@ -29593,3 +29593,14 @@ Apologies for any names omitted.
        when dict_open() was called recursively, after dict_proxy_open()
        changed the name of a dictionary on-the-fly by skipping a
        proxy: prefix). File: util/dict_open.c.
+
+20250906
+
+       Bugfix: with "smtp_tls_enforce_sts_mx_patterns = yes" (the
+       default) transform the TLS policy from an STS policy plugin
+       as follows: connect to an MX host only if its name matches
+       an STS policy MX host pattern, and match the server
+       certificate against the MX hostname. Files: mantools/postlink,
+       proto/postconf.proto, global/mail_params.h, smtp/lmtp_params.c,
+       smtp/smtp.c, smtp/smtp.h, smtp/smtp_connect.c, smtp/smtp_params.c,
+       smtp/smtp_tls_policy.c, smtp/smtp_tls_policy_test.c.
index ba706a170e9278ac7f4c395016b429812905335a..e116f43aa938dfd020400c6db507a4bf41f389dc 100644 (file)
@@ -762,45 +762,54 @@ SMTP(8)                                                                SMTP(8)
               When set to "yes", report the TLSRPT status only for  "new"  TLS
               sessions.
 
+       Available in Postfix version 3.10.5 and later:
+
+       <b><a href="postconf.5.html#smtp_tls_enforce_sts_mx_patterns">smtp_tls_enforce_sts_mx_patterns</a> (yes)</b>
+              Transform  the  TLS policy from an STS policy plugin: connect to
+              an MX host only if its name matches the STS policy MX host  pat-
+              tern,  and match the server certificate against the MX hostname.
+
+       Available in Postfix version 3.11 and later:
+
        <b><a href="postconf.5.html#tls_required_enable">tls_required_enable</a> (yes)</b>
               Enable  support  for  the  "TLS-Required:  no"  message  header,
               defined in <a href="https://tools.ietf.org/html/rfc8689">RFC 8689</a>.
 
 <b><a name="obsolete_starttls_controls">OBSOLETE STARTTLS CONTROLS</a></b>
-       The following configuration parameters  exist  for  compatibility  with
-       Postfix  versions  before  2.3.  Support for these will be removed in a
+       The  following  configuration  parameters  exist for compatibility with
+       Postfix versions before 2.3. Support for these will  be  removed  in  a
        future release.
 
        <b><a href="postconf.5.html#smtp_use_tls">smtp_use_tls</a> (no)</b>
-              Opportunistic mode: use TLS when a remote SMTP server  announces
+              Opportunistic  mode: use TLS when a remote SMTP server announces
               STARTTLS support, otherwise send the mail in the clear.
 
        <b><a href="postconf.5.html#smtp_enforce_tls">smtp_enforce_tls</a> (no)</b>
-              Enforcement  mode:  require  that  remote  SMTP  servers use TLS
+              Enforcement mode: require  that  remote  SMTP  servers  use  TLS
               encryption, and never send mail in the clear.
 
        <b><a href="postconf.5.html#smtp_tls_enforce_peername">smtp_tls_enforce_peername</a> (yes)</b>
-              With mandatory TLS encryption,  require  that  the  remote  SMTP
-              server  hostname  matches  the  information  in  the remote SMTP
+              With  mandatory  TLS  encryption,  require  that the remote SMTP
+              server hostname matches  the  information  in  the  remote  SMTP
               server certificate.
 
        <b><a href="postconf.5.html#smtp_tls_per_site">smtp_tls_per_site</a> (empty)</b>
-              Optional lookup tables with the Postfix SMTP  client  TLS  usage
-              policy  by  next-hop destination and by remote SMTP server host-
+              Optional  lookup  tables  with the Postfix SMTP client TLS usage
+              policy by next-hop destination and by remote SMTP  server  host-
               name.
 
        <b><a href="postconf.5.html#smtp_tls_cipherlist">smtp_tls_cipherlist</a> (empty)</b>
-              Obsolete Postfix &lt; 2.3 control for the Postfix SMTP  client  TLS
+              Obsolete  Postfix  &lt; 2.3 control for the Postfix SMTP client TLS
               cipher list.
 
 <b><a name="resource_and_rate_controls">RESOURCE AND RATE CONTROLS</a></b>
        <b><a href="postconf.5.html#smtp_connect_timeout">smtp_connect_timeout</a> (30s)</b>
-              The  Postfix SMTP client time limit for completing a TCP connec-
+              The Postfix SMTP client time limit for completing a TCP  connec-
               tion, or zero (use the operating system built-in time limit).
 
        <b><a href="postconf.5.html#smtp_helo_timeout">smtp_helo_timeout</a> (300s)</b>
-              The Postfix SMTP client time limit for sending the HELO or  EHLO
-              command,  and  for  receiving  the  initial  remote  SMTP server
+              The  Postfix SMTP client time limit for sending the HELO or EHLO
+              command, and  for  receiving  the  initial  remote  SMTP  server
               response.
 
        <b><a href="postconf.5.html#lmtp_lhlo_timeout">lmtp_lhlo_timeout</a> (300s)</b>
@@ -812,19 +821,19 @@ SMTP(8)                                                                SMTP(8)
               mand, and for receiving the remote SMTP server response.
 
        <b><a href="postconf.5.html#smtp_mail_timeout">smtp_mail_timeout</a> (300s)</b>
-              The Postfix SMTP client time limit for  sending  the  MAIL  FROM
+              The  Postfix  SMTP  client  time limit for sending the MAIL FROM
               command, and for receiving the remote SMTP server response.
 
        <b><a href="postconf.5.html#smtp_rcpt_timeout">smtp_rcpt_timeout</a> (300s)</b>
-              The  Postfix SMTP client time limit for sending the SMTP RCPT TO
+              The Postfix SMTP client time limit for sending the SMTP RCPT  TO
               command, and for receiving the remote SMTP server response.
 
        <b><a href="postconf.5.html#smtp_data_init_timeout">smtp_data_init_timeout</a> (120s)</b>
-              The Postfix SMTP client time limit for  sending  the  SMTP  DATA
+              The  Postfix  SMTP  client  time limit for sending the SMTP DATA
               command, and for receiving the remote SMTP server response.
 
        <b><a href="postconf.5.html#smtp_data_xfer_timeout">smtp_data_xfer_timeout</a> (180s)</b>
-              The  Postfix SMTP client time limit for sending the SMTP message
+              The Postfix SMTP client time limit for sending the SMTP  message
               content.
 
        <b><a href="postconf.5.html#smtp_data_done_timeout">smtp_data_done_timeout</a> (600s)</b>
@@ -838,13 +847,13 @@ SMTP(8)                                                                SMTP(8)
        Available in Postfix version 2.1 and later:
 
        <b><a href="postconf.5.html#smtp_mx_address_limit">smtp_mx_address_limit</a> (5)</b>
-              The maximal number of MX (mail exchanger) IP addresses that  can
-              result  from Postfix SMTP client mail exchanger lookups, or zero
+              The  maximal number of MX (mail exchanger) IP addresses that can
+              result from Postfix SMTP client mail exchanger lookups, or  zero
               (no limit).
 
        <b><a href="postconf.5.html#smtp_mx_session_limit">smtp_mx_session_limit</a> (2)</b>
-              The maximal number of SMTP sessions per delivery request  before
-              the  Postfix  SMTP  client  gives  up or delivers to a fall-back
+              The  maximal number of SMTP sessions per delivery request before
+              the Postfix SMTP client gives up  or  delivers  to  a  fall-back
               <a href="postconf.5.html#relayhost">relay host</a>, or zero (no limit).
 
        <b><a href="postconf.5.html#smtp_rset_timeout">smtp_rset_timeout</a> (20s)</b>
@@ -854,17 +863,17 @@ SMTP(8)                                                                SMTP(8)
        Available in Postfix version 2.2 and earlier:
 
        <b><a href="postconf.5.html#lmtp_cache_connection">lmtp_cache_connection</a> (yes)</b>
-              Keep  Postfix  LMTP  client connections open for up to $<a href="postconf.5.html#max_idle">max_idle</a>
+              Keep Postfix LMTP client connections open for  up  to  $<a href="postconf.5.html#max_idle">max_idle</a>
               seconds.
 
        Available in Postfix version 2.2 and later:
 
        <b><a href="postconf.5.html#smtp_connection_cache_destinations">smtp_connection_cache_destinations</a> (empty)</b>
-              Permanently enable SMTP connection  caching  for  the  specified
+              Permanently  enable  SMTP  connection  caching for the specified
               destinations.
 
        <b><a href="postconf.5.html#smtp_connection_cache_on_demand">smtp_connection_cache_on_demand</a> (yes)</b>
-              Temporarily  enable  SMTP connection caching while a destination
+              Temporarily enable SMTP connection caching while  a  destination
               has a high volume of mail in the <a href="QSHAPE_README.html#active_queue">active queue</a>.
 
        <b><a href="postconf.5.html#smtp_connection_reuse_time_limit">smtp_connection_reuse_time_limit</a> (300s)</b>
@@ -878,23 +887,23 @@ SMTP(8)                                                                SMTP(8)
        Available in Postfix version 2.3 and later:
 
        <b><a href="postconf.5.html#connection_cache_protocol_timeout">connection_cache_protocol_timeout</a> (5s)</b>
-              Time limit for connection cache connect, send or receive  opera-
+              Time  limit for connection cache connect, send or receive opera-
               tions.
 
        Available in Postfix version 2.9 - 3.6:
 
        <b><a href="postconf.5.html#smtp_per_record_deadline">smtp_per_record_deadline</a> (no)</b>
-              Change  the  behavior  of the smtp_*_timeout time limits, from a
-              time limit per read or write system call, to  a  time  limit  to
-              send  or  receive  a complete record (an SMTP command line, SMTP
-              response line, SMTP message content line, or TLS  protocol  mes-
+              Change the behavior of the smtp_*_timeout time  limits,  from  a
+              time  limit  per  read  or write system call, to a time limit to
+              send or receive a complete record (an SMTP  command  line,  SMTP
+              response  line,  SMTP message content line, or TLS protocol mes-
               sage).
 
        Available in Postfix version 2.11 and later:
 
        <b><a href="postconf.5.html#smtp_connection_reuse_count_limit">smtp_connection_reuse_count_limit</a> (0)</b>
-              When  SMTP  connection  caching  is enabled, the number of times
-              that an SMTP session may be reused before it is closed, or  zero
+              When SMTP connection caching is enabled,  the  number  of  times
+              that  an SMTP session may be reused before it is closed, or zero
               (no limit).
 
        Available in Postfix version 3.4 and later:
@@ -905,13 +914,13 @@ SMTP(8)                                                                SMTP(8)
        Available in Postfix version 3.7 and later:
 
        <b><a href="postconf.5.html#smtp_per_request_deadline">smtp_per_request_deadline</a> (no)</b>
-              Change  the  behavior  of the smtp_*_timeout time limits, from a
-              time limit per plaintext or TLS read or write call,  to  a  com-
-              bined  time  limit  for  sending a complete SMTP request and for
+              Change the behavior of the smtp_*_timeout time  limits,  from  a
+              time  limit  per  plaintext or TLS read or write call, to a com-
+              bined time limit for sending a complete  SMTP  request  and  for
               receiving a complete SMTP response.
 
        <b><a href="postconf.5.html#smtp_min_data_rate">smtp_min_data_rate</a> (500)</b>
-              The minimum plaintext data transfer  rate  in  bytes/second  for
+              The  minimum  plaintext  data  transfer rate in bytes/second for
               DATA    requests,    when    deadlines    are    enabled    with
               <a href="postconf.5.html#smtp_per_request_deadline">smtp_per_request_deadline</a>.
 
@@ -919,54 +928,54 @@ SMTP(8)                                                                SMTP(8)
 
        <b><a href="postconf.5.html#transport_destination_concurrency_limit">transport_destination_concurrency_limit</a>   ($<a href="postconf.5.html#default_destination_concurrency_limit">default_destination_concur</a>-</b>
        <b><a href="postconf.5.html#default_destination_concurrency_limit">rency_limit</a>)</b>
-              A transport-specific override for  the  <a href="postconf.5.html#default_destination_concurrency_limit">default_destination_con</a>-
+              A  transport-specific  override for the <a href="postconf.5.html#default_destination_concurrency_limit">default_destination_con</a>-
               <a href="postconf.5.html#default_destination_concurrency_limit">currency_limit</a> parameter value, where <i>transport</i> is the <a href="master.5.html">master.cf</a>
               name of the message delivery transport.
 
        <b><a href="postconf.5.html#transport_destination_recipient_limit">transport_destination_recipient_limit</a>     ($<a href="postconf.5.html#default_destination_recipient_limit">default_destination_recipi</a>-</b>
        <b><a href="postconf.5.html#default_destination_recipient_limit">ent_limit</a>)</b>
               A transport-specific override for the <a href="postconf.5.html#default_destination_recipient_limit">default_destination_recip</a>-
-              <a href="postconf.5.html#default_destination_recipient_limit">ient_limit</a>  parameter  value,  where  <i>transport</i> is the <a href="master.5.html">master.cf</a>
+              <a href="postconf.5.html#default_destination_recipient_limit">ient_limit</a> parameter value, where  <i>transport</i>  is  the  <a href="master.5.html">master.cf</a>
               name of the message delivery transport.
 
 <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="trouble_shooting_controls">TROUBLE SHOOTING CONTROLS</a></b>
        <b><a href="postconf.5.html#debug_peer_level">debug_peer_level</a> (2)</b>
-              The increment in verbose logging level when a  nexthop  destina-
-              tion,  remote client or server name or network address matches a
+              The  increment  in verbose logging level when a nexthop destina-
+              tion, remote client or server name or network address matches  a
               pattern given with the <a href="postconf.5.html#debug_peer_list">debug_peer_list</a> parameter.
 
        <b><a href="postconf.5.html#debug_peer_list">debug_peer_list</a> (empty)</b>
-              Optional list of nexthop destination, remote  client  or  server
-              name  or  network  address  patterns that, if matched, cause the
-              verbose logging level to increase by  the  amount  specified  in
+              Optional  list  of  nexthop destination, remote client or server
+              name or network address patterns that,  if  matched,  cause  the
+              verbose  logging  level  to  increase by the amount specified in
               $<a href="postconf.5.html#debug_peer_level">debug_peer_level</a>.
 
        <b><a href="postconf.5.html#error_notice_recipient">error_notice_recipient</a> (postmaster)</b>
-              The  recipient  of  postmaster notifications about mail delivery
+              The recipient of postmaster notifications  about  mail  delivery
               problems that are caused by policy, resource, software or proto-
               col errors.
 
        <b><a href="postconf.5.html#internal_mail_filter_classes">internal_mail_filter_classes</a> (empty)</b>
-              What   categories  of  Postfix-generated  mail  are  subject  to
-              before-queue   content    inspection    by    <a href="postconf.5.html#non_smtpd_milters">non_smtpd_milters</a>,
+              What  categories  of  Postfix-generated  mail  are  subject   to
+              before-queue    content    inspection    by   <a href="postconf.5.html#non_smtpd_milters">non_smtpd_milters</a>,
               <a href="postconf.5.html#header_checks">header_checks</a> and <a href="postconf.5.html#body_checks">body_checks</a>.
 
        <b><a href="postconf.5.html#notify_classes">notify_classes</a> (resource, software)</b>
@@ -974,46 +983,46 @@ SMTP(8)                                                                SMTP(8)
 
 <b><a name="miscellaneous_controls">MISCELLANEOUS CONTROLS</a></b>
        <b><a href="postconf.5.html#best_mx_transport">best_mx_transport</a> (empty)</b>
-              Where  the  Postfix  SMTP  client  should  deliver  mail when it
+              Where the Postfix  SMTP  client  should  deliver  mail  when  it
               detects a "mail loops back to myself" error condition.
 
        <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#disable_dns_lookups">disable_dns_lookups</a> (no)</b>
               Disable DNS lookups in the Postfix SMTP and LMTP clients.
 
        <b><a href="postconf.5.html#inet_interfaces">inet_interfaces</a> (all)</b>
-              The  local  network  interface  addresses  that this mail system
+              The local network interface  addresses  that  this  mail  system
               receives mail on.
 
        <b><a href="postconf.5.html#inet_protocols">inet_protocols</a> (see 'postconf -d' output)</b>
-              The Internet protocols Postfix will attempt to use  when  making
+              The  Internet  protocols Postfix will attempt to use when making
               or accepting connections.
 
        <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#lmtp_assume_final">lmtp_assume_final</a> (no)</b>
-              When a remote LMTP server announces no DSN support, assume  that
-              the  server performs final delivery, and send "delivered" deliv-
+              When  a remote LMTP server announces no DSN support, assume that
+              the server performs final delivery, and send "delivered"  deliv-
               ery status notifications instead of "relayed".
 
        <b><a href="postconf.5.html#lmtp_tcp_port">lmtp_tcp_port</a> (24)</b>
               The default TCP port that the Postfix LMTP client connects to.
 
        <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>
@@ -1027,21 +1036,21 @@ SMTP(8)                                                                SMTP(8)
               The process name of a Postfix command or daemon process.
 
        <b><a href="postconf.5.html#proxy_interfaces">proxy_interfaces</a> (empty)</b>
-              The  remote  network  interface  addresses that this mail system
-              receives mail on by way of a proxy or network  address  transla-
+              The remote network interface addresses  that  this  mail  system
+              receives  mail  on by way of a proxy or network address transla-
               tion unit.
 
        <b><a href="postconf.5.html#smtp_address_preference">smtp_address_preference</a> (any)</b>
               The address type ("ipv6", "ipv4" or "any") that the Postfix SMTP
-              client will try first, when a  destination  has  IPv6  and  IPv4
+              client  will  try  first,  when  a destination has IPv6 and IPv4
               addresses with equal MX preference.
 
        <b><a href="postconf.5.html#smtp_bind_address">smtp_bind_address</a> (empty)</b>
-              An  optional  numerical  network  address  that the Postfix SMTP
+              An optional numerical network  address  that  the  Postfix  SMTP
               client should bind to when making an IPv4 connection.
 
        <b><a href="postconf.5.html#smtp_bind_address6">smtp_bind_address6</a> (empty)</b>
-              An optional numerical network  address  that  the  Postfix  SMTP
+              An  optional  numerical  network  address  that the Postfix SMTP
               client should bind to when making an IPv6 connection.
 
        <b><a href="postconf.5.html#smtp_helo_name">smtp_helo_name</a> ($<a href="postconf.5.html#myhostname">myhostname</a>)</b>
@@ -1061,7 +1070,7 @@ SMTP(8)                                                                SMTP(8)
               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 with Postfix 2.2 and earlier:
@@ -1073,14 +1082,14 @@ SMTP(8)                                                                SMTP(8)
        Available with Postfix 2.3 and later:
 
        <b><a href="postconf.5.html#smtp_fallback_relay">smtp_fallback_relay</a> ($<a href="postconf.5.html#fallback_relay">fallback_relay</a>)</b>
-              Optional list of relay destinations that will be  used  when  an
-              SMTP  destination  is not found, or when delivery fails due to a
+              Optional  list  of  relay destinations that will be used when an
+              SMTP destination is not found, or when delivery fails due  to  a
               non-permanent error.
 
        Available with Postfix 3.0 and later:
 
        <b><a href="postconf.5.html#smtp_address_verify_target">smtp_address_verify_target</a> (rcpt)</b>
-              In the context of email address verification, the SMTP  protocol
+              In  the context of email address verification, the SMTP protocol
               stage that determines whether an email address is deliverable.
 
        Available with Postfix 3.1 and later:
@@ -1102,7 +1111,7 @@ SMTP(8)                                                                SMTP(8)
        Available in Postfix 3.7 and later:
 
        <b><a href="postconf.5.html#smtp_bind_address_enforce">smtp_bind_address_enforce</a> (no)</b>
-              Defer delivery when the Postfix SMTP  client  cannot  apply  the
+              Defer  delivery  when  the  Postfix SMTP client cannot apply the
               <a href="postconf.5.html#smtp_bind_address">smtp_bind_address</a> or <a href="postconf.5.html#smtp_bind_address6">smtp_bind_address6</a> setting.
 
 <b><a name="see_also">SEE ALSO</a></b>
index 1f4b51a078b4f48059a80f0deaae1bc904f3f1f2..e3ad237024e2a185c76e5b8541055bf59df5f99a 100644 (file)
@@ -5787,6 +5787,16 @@ configuration parameter.  See there for details. </p>
 <p> This feature is available in Postfix 2.3 and later. </p>
 
 
+</DD>
+
+<DT><b><a name="lmtp_tls_enforce_sts_mx_patterns">lmtp_tls_enforce_sts_mx_patterns</a>
+(default: yes)</b></DT><DD>
+
+<p> See <a href="postconf.5.html#smtp_tls_enforce_sts_mx_patterns">smtp_tls_enforce_sts_mx_patterns</a>. </p>
+
+<p> This feature is available in Postfix &ge; 3.10.5. </p>
+
+
 </DD>
 
 <DT><b><a name="lmtp_tls_exclude_ciphers">lmtp_tls_exclude_ciphers</a>
@@ -13539,6 +13549,18 @@ CommonName of this attacker will be logged). </p>
 Postfix 2.3 and later use <a href="postconf.5.html#smtp_tls_security_level">smtp_tls_security_level</a> instead. </p>
 
 
+</DD>
+
+<DT><b><a name="smtp_tls_enforce_sts_mx_patterns">smtp_tls_enforce_sts_mx_patterns</a>
+(default: yes)</b></DT><DD>
+
+<p> Transform the TLS policy from an STS policy plugin: connect to
+an MX host only if its name matches the STS policy MX host pattern,
+and match the server certificate against the MX hostname. </p>
+
+<p> This feature is available in Postfix &ge; 3.10.5. </p>
+
+
 </DD>
 
 <DT><b><a name="smtp_tls_exclude_ciphers">smtp_tls_exclude_ciphers</a>
index ba706a170e9278ac7f4c395016b429812905335a..e116f43aa938dfd020400c6db507a4bf41f389dc 100644 (file)
@@ -762,45 +762,54 @@ SMTP(8)                                                                SMTP(8)
               When set to "yes", report the TLSRPT status only for  "new"  TLS
               sessions.
 
+       Available in Postfix version 3.10.5 and later:
+
+       <b><a href="postconf.5.html#smtp_tls_enforce_sts_mx_patterns">smtp_tls_enforce_sts_mx_patterns</a> (yes)</b>
+              Transform  the  TLS policy from an STS policy plugin: connect to
+              an MX host only if its name matches the STS policy MX host  pat-
+              tern,  and match the server certificate against the MX hostname.
+
+       Available in Postfix version 3.11 and later:
+
        <b><a href="postconf.5.html#tls_required_enable">tls_required_enable</a> (yes)</b>
               Enable  support  for  the  "TLS-Required:  no"  message  header,
               defined in <a href="https://tools.ietf.org/html/rfc8689">RFC 8689</a>.
 
 <b><a name="obsolete_starttls_controls">OBSOLETE STARTTLS CONTROLS</a></b>
-       The following configuration parameters  exist  for  compatibility  with
-       Postfix  versions  before  2.3.  Support for these will be removed in a
+       The  following  configuration  parameters  exist for compatibility with
+       Postfix versions before 2.3. Support for these will  be  removed  in  a
        future release.
 
        <b><a href="postconf.5.html#smtp_use_tls">smtp_use_tls</a> (no)</b>
-              Opportunistic mode: use TLS when a remote SMTP server  announces
+              Opportunistic  mode: use TLS when a remote SMTP server announces
               STARTTLS support, otherwise send the mail in the clear.
 
        <b><a href="postconf.5.html#smtp_enforce_tls">smtp_enforce_tls</a> (no)</b>
-              Enforcement  mode:  require  that  remote  SMTP  servers use TLS
+              Enforcement mode: require  that  remote  SMTP  servers  use  TLS
               encryption, and never send mail in the clear.
 
        <b><a href="postconf.5.html#smtp_tls_enforce_peername">smtp_tls_enforce_peername</a> (yes)</b>
-              With mandatory TLS encryption,  require  that  the  remote  SMTP
-              server  hostname  matches  the  information  in  the remote SMTP
+              With  mandatory  TLS  encryption,  require  that the remote SMTP
+              server hostname matches  the  information  in  the  remote  SMTP
               server certificate.
 
        <b><a href="postconf.5.html#smtp_tls_per_site">smtp_tls_per_site</a> (empty)</b>
-              Optional lookup tables with the Postfix SMTP  client  TLS  usage
-              policy  by  next-hop destination and by remote SMTP server host-
+              Optional  lookup  tables  with the Postfix SMTP client TLS usage
+              policy by next-hop destination and by remote SMTP  server  host-
               name.
 
        <b><a href="postconf.5.html#smtp_tls_cipherlist">smtp_tls_cipherlist</a> (empty)</b>
-              Obsolete Postfix &lt; 2.3 control for the Postfix SMTP  client  TLS
+              Obsolete  Postfix  &lt; 2.3 control for the Postfix SMTP client TLS
               cipher list.
 
 <b><a name="resource_and_rate_controls">RESOURCE AND RATE CONTROLS</a></b>
        <b><a href="postconf.5.html#smtp_connect_timeout">smtp_connect_timeout</a> (30s)</b>
-              The  Postfix SMTP client time limit for completing a TCP connec-
+              The Postfix SMTP client time limit for completing a TCP  connec-
               tion, or zero (use the operating system built-in time limit).
 
        <b><a href="postconf.5.html#smtp_helo_timeout">smtp_helo_timeout</a> (300s)</b>
-              The Postfix SMTP client time limit for sending the HELO or  EHLO
-              command,  and  for  receiving  the  initial  remote  SMTP server
+              The  Postfix SMTP client time limit for sending the HELO or EHLO
+              command, and  for  receiving  the  initial  remote  SMTP  server
               response.
 
        <b><a href="postconf.5.html#lmtp_lhlo_timeout">lmtp_lhlo_timeout</a> (300s)</b>
@@ -812,19 +821,19 @@ SMTP(8)                                                                SMTP(8)
               mand, and for receiving the remote SMTP server response.
 
        <b><a href="postconf.5.html#smtp_mail_timeout">smtp_mail_timeout</a> (300s)</b>
-              The Postfix SMTP client time limit for  sending  the  MAIL  FROM
+              The  Postfix  SMTP  client  time limit for sending the MAIL FROM
               command, and for receiving the remote SMTP server response.
 
        <b><a href="postconf.5.html#smtp_rcpt_timeout">smtp_rcpt_timeout</a> (300s)</b>
-              The  Postfix SMTP client time limit for sending the SMTP RCPT TO
+              The Postfix SMTP client time limit for sending the SMTP RCPT  TO
               command, and for receiving the remote SMTP server response.
 
        <b><a href="postconf.5.html#smtp_data_init_timeout">smtp_data_init_timeout</a> (120s)</b>
-              The Postfix SMTP client time limit for  sending  the  SMTP  DATA
+              The  Postfix  SMTP  client  time limit for sending the SMTP DATA
               command, and for receiving the remote SMTP server response.
 
        <b><a href="postconf.5.html#smtp_data_xfer_timeout">smtp_data_xfer_timeout</a> (180s)</b>
-              The  Postfix SMTP client time limit for sending the SMTP message
+              The Postfix SMTP client time limit for sending the SMTP  message
               content.
 
        <b><a href="postconf.5.html#smtp_data_done_timeout">smtp_data_done_timeout</a> (600s)</b>
@@ -838,13 +847,13 @@ SMTP(8)                                                                SMTP(8)
        Available in Postfix version 2.1 and later:
 
        <b><a href="postconf.5.html#smtp_mx_address_limit">smtp_mx_address_limit</a> (5)</b>
-              The maximal number of MX (mail exchanger) IP addresses that  can
-              result  from Postfix SMTP client mail exchanger lookups, or zero
+              The  maximal number of MX (mail exchanger) IP addresses that can
+              result from Postfix SMTP client mail exchanger lookups, or  zero
               (no limit).
 
        <b><a href="postconf.5.html#smtp_mx_session_limit">smtp_mx_session_limit</a> (2)</b>
-              The maximal number of SMTP sessions per delivery request  before
-              the  Postfix  SMTP  client  gives  up or delivers to a fall-back
+              The  maximal number of SMTP sessions per delivery request before
+              the Postfix SMTP client gives up  or  delivers  to  a  fall-back
               <a href="postconf.5.html#relayhost">relay host</a>, or zero (no limit).
 
        <b><a href="postconf.5.html#smtp_rset_timeout">smtp_rset_timeout</a> (20s)</b>
@@ -854,17 +863,17 @@ SMTP(8)                                                                SMTP(8)
        Available in Postfix version 2.2 and earlier:
 
        <b><a href="postconf.5.html#lmtp_cache_connection">lmtp_cache_connection</a> (yes)</b>
-              Keep  Postfix  LMTP  client connections open for up to $<a href="postconf.5.html#max_idle">max_idle</a>
+              Keep Postfix LMTP client connections open for  up  to  $<a href="postconf.5.html#max_idle">max_idle</a>
               seconds.
 
        Available in Postfix version 2.2 and later:
 
        <b><a href="postconf.5.html#smtp_connection_cache_destinations">smtp_connection_cache_destinations</a> (empty)</b>
-              Permanently enable SMTP connection  caching  for  the  specified
+              Permanently  enable  SMTP  connection  caching for the specified
               destinations.
 
        <b><a href="postconf.5.html#smtp_connection_cache_on_demand">smtp_connection_cache_on_demand</a> (yes)</b>
-              Temporarily  enable  SMTP connection caching while a destination
+              Temporarily enable SMTP connection caching while  a  destination
               has a high volume of mail in the <a href="QSHAPE_README.html#active_queue">active queue</a>.
 
        <b><a href="postconf.5.html#smtp_connection_reuse_time_limit">smtp_connection_reuse_time_limit</a> (300s)</b>
@@ -878,23 +887,23 @@ SMTP(8)                                                                SMTP(8)
        Available in Postfix version 2.3 and later:
 
        <b><a href="postconf.5.html#connection_cache_protocol_timeout">connection_cache_protocol_timeout</a> (5s)</b>
-              Time limit for connection cache connect, send or receive  opera-
+              Time  limit for connection cache connect, send or receive opera-
               tions.
 
        Available in Postfix version 2.9 - 3.6:
 
        <b><a href="postconf.5.html#smtp_per_record_deadline">smtp_per_record_deadline</a> (no)</b>
-              Change  the  behavior  of the smtp_*_timeout time limits, from a
-              time limit per read or write system call, to  a  time  limit  to
-              send  or  receive  a complete record (an SMTP command line, SMTP
-              response line, SMTP message content line, or TLS  protocol  mes-
+              Change the behavior of the smtp_*_timeout time  limits,  from  a
+              time  limit  per  read  or write system call, to a time limit to
+              send or receive a complete record (an SMTP  command  line,  SMTP
+              response  line,  SMTP message content line, or TLS protocol mes-
               sage).
 
        Available in Postfix version 2.11 and later:
 
        <b><a href="postconf.5.html#smtp_connection_reuse_count_limit">smtp_connection_reuse_count_limit</a> (0)</b>
-              When  SMTP  connection  caching  is enabled, the number of times
-              that an SMTP session may be reused before it is closed, or  zero
+              When SMTP connection caching is enabled,  the  number  of  times
+              that  an SMTP session may be reused before it is closed, or zero
               (no limit).
 
        Available in Postfix version 3.4 and later:
@@ -905,13 +914,13 @@ SMTP(8)                                                                SMTP(8)
        Available in Postfix version 3.7 and later:
 
        <b><a href="postconf.5.html#smtp_per_request_deadline">smtp_per_request_deadline</a> (no)</b>
-              Change  the  behavior  of the smtp_*_timeout time limits, from a
-              time limit per plaintext or TLS read or write call,  to  a  com-
-              bined  time  limit  for  sending a complete SMTP request and for
+              Change the behavior of the smtp_*_timeout time  limits,  from  a
+              time  limit  per  plaintext or TLS read or write call, to a com-
+              bined time limit for sending a complete  SMTP  request  and  for
               receiving a complete SMTP response.
 
        <b><a href="postconf.5.html#smtp_min_data_rate">smtp_min_data_rate</a> (500)</b>
-              The minimum plaintext data transfer  rate  in  bytes/second  for
+              The  minimum  plaintext  data  transfer rate in bytes/second for
               DATA    requests,    when    deadlines    are    enabled    with
               <a href="postconf.5.html#smtp_per_request_deadline">smtp_per_request_deadline</a>.
 
@@ -919,54 +928,54 @@ SMTP(8)                                                                SMTP(8)
 
        <b><a href="postconf.5.html#transport_destination_concurrency_limit">transport_destination_concurrency_limit</a>   ($<a href="postconf.5.html#default_destination_concurrency_limit">default_destination_concur</a>-</b>
        <b><a href="postconf.5.html#default_destination_concurrency_limit">rency_limit</a>)</b>
-              A transport-specific override for  the  <a href="postconf.5.html#default_destination_concurrency_limit">default_destination_con</a>-
+              A  transport-specific  override for the <a href="postconf.5.html#default_destination_concurrency_limit">default_destination_con</a>-
               <a href="postconf.5.html#default_destination_concurrency_limit">currency_limit</a> parameter value, where <i>transport</i> is the <a href="master.5.html">master.cf</a>
               name of the message delivery transport.
 
        <b><a href="postconf.5.html#transport_destination_recipient_limit">transport_destination_recipient_limit</a>     ($<a href="postconf.5.html#default_destination_recipient_limit">default_destination_recipi</a>-</b>
        <b><a href="postconf.5.html#default_destination_recipient_limit">ent_limit</a>)</b>
               A transport-specific override for the <a href="postconf.5.html#default_destination_recipient_limit">default_destination_recip</a>-
-              <a href="postconf.5.html#default_destination_recipient_limit">ient_limit</a>  parameter  value,  where  <i>transport</i> is the <a href="master.5.html">master.cf</a>
+              <a href="postconf.5.html#default_destination_recipient_limit">ient_limit</a> parameter value, where  <i>transport</i>  is  the  <a href="master.5.html">master.cf</a>
               name of the message delivery transport.
 
 <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="trouble_shooting_controls">TROUBLE SHOOTING CONTROLS</a></b>
        <b><a href="postconf.5.html#debug_peer_level">debug_peer_level</a> (2)</b>
-              The increment in verbose logging level when a  nexthop  destina-
-              tion,  remote client or server name or network address matches a
+              The  increment  in verbose logging level when a nexthop destina-
+              tion, remote client or server name or network address matches  a
               pattern given with the <a href="postconf.5.html#debug_peer_list">debug_peer_list</a> parameter.
 
        <b><a href="postconf.5.html#debug_peer_list">debug_peer_list</a> (empty)</b>
-              Optional list of nexthop destination, remote  client  or  server
-              name  or  network  address  patterns that, if matched, cause the
-              verbose logging level to increase by  the  amount  specified  in
+              Optional  list  of  nexthop destination, remote client or server
+              name or network address patterns that,  if  matched,  cause  the
+              verbose  logging  level  to  increase by the amount specified in
               $<a href="postconf.5.html#debug_peer_level">debug_peer_level</a>.
 
        <b><a href="postconf.5.html#error_notice_recipient">error_notice_recipient</a> (postmaster)</b>
-              The  recipient  of  postmaster notifications about mail delivery
+              The recipient of postmaster notifications  about  mail  delivery
               problems that are caused by policy, resource, software or proto-
               col errors.
 
        <b><a href="postconf.5.html#internal_mail_filter_classes">internal_mail_filter_classes</a> (empty)</b>
-              What   categories  of  Postfix-generated  mail  are  subject  to
-              before-queue   content    inspection    by    <a href="postconf.5.html#non_smtpd_milters">non_smtpd_milters</a>,
+              What  categories  of  Postfix-generated  mail  are  subject   to
+              before-queue    content    inspection    by   <a href="postconf.5.html#non_smtpd_milters">non_smtpd_milters</a>,
               <a href="postconf.5.html#header_checks">header_checks</a> and <a href="postconf.5.html#body_checks">body_checks</a>.
 
        <b><a href="postconf.5.html#notify_classes">notify_classes</a> (resource, software)</b>
@@ -974,46 +983,46 @@ SMTP(8)                                                                SMTP(8)
 
 <b><a name="miscellaneous_controls">MISCELLANEOUS CONTROLS</a></b>
        <b><a href="postconf.5.html#best_mx_transport">best_mx_transport</a> (empty)</b>
-              Where  the  Postfix  SMTP  client  should  deliver  mail when it
+              Where the Postfix  SMTP  client  should  deliver  mail  when  it
               detects a "mail loops back to myself" error condition.
 
        <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#disable_dns_lookups">disable_dns_lookups</a> (no)</b>
               Disable DNS lookups in the Postfix SMTP and LMTP clients.
 
        <b><a href="postconf.5.html#inet_interfaces">inet_interfaces</a> (all)</b>
-              The  local  network  interface  addresses  that this mail system
+              The local network interface  addresses  that  this  mail  system
               receives mail on.
 
        <b><a href="postconf.5.html#inet_protocols">inet_protocols</a> (see 'postconf -d' output)</b>
-              The Internet protocols Postfix will attempt to use  when  making
+              The  Internet  protocols Postfix will attempt to use when making
               or accepting connections.
 
        <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#lmtp_assume_final">lmtp_assume_final</a> (no)</b>
-              When a remote LMTP server announces no DSN support, assume  that
-              the  server performs final delivery, and send "delivered" deliv-
+              When  a remote LMTP server announces no DSN support, assume that
+              the server performs final delivery, and send "delivered"  deliv-
               ery status notifications instead of "relayed".
 
        <b><a href="postconf.5.html#lmtp_tcp_port">lmtp_tcp_port</a> (24)</b>
               The default TCP port that the Postfix LMTP client connects to.
 
        <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>
@@ -1027,21 +1036,21 @@ SMTP(8)                                                                SMTP(8)
               The process name of a Postfix command or daemon process.
 
        <b><a href="postconf.5.html#proxy_interfaces">proxy_interfaces</a> (empty)</b>
-              The  remote  network  interface  addresses that this mail system
-              receives mail on by way of a proxy or network  address  transla-
+              The remote network interface addresses  that  this  mail  system
+              receives  mail  on by way of a proxy or network address transla-
               tion unit.
 
        <b><a href="postconf.5.html#smtp_address_preference">smtp_address_preference</a> (any)</b>
               The address type ("ipv6", "ipv4" or "any") that the Postfix SMTP
-              client will try first, when a  destination  has  IPv6  and  IPv4
+              client  will  try  first,  when  a destination has IPv6 and IPv4
               addresses with equal MX preference.
 
        <b><a href="postconf.5.html#smtp_bind_address">smtp_bind_address</a> (empty)</b>
-              An  optional  numerical  network  address  that the Postfix SMTP
+              An optional numerical network  address  that  the  Postfix  SMTP
               client should bind to when making an IPv4 connection.
 
        <b><a href="postconf.5.html#smtp_bind_address6">smtp_bind_address6</a> (empty)</b>
-              An optional numerical network  address  that  the  Postfix  SMTP
+              An  optional  numerical  network  address  that the Postfix SMTP
               client should bind to when making an IPv6 connection.
 
        <b><a href="postconf.5.html#smtp_helo_name">smtp_helo_name</a> ($<a href="postconf.5.html#myhostname">myhostname</a>)</b>
@@ -1061,7 +1070,7 @@ SMTP(8)                                                                SMTP(8)
               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 with Postfix 2.2 and earlier:
@@ -1073,14 +1082,14 @@ SMTP(8)                                                                SMTP(8)
        Available with Postfix 2.3 and later:
 
        <b><a href="postconf.5.html#smtp_fallback_relay">smtp_fallback_relay</a> ($<a href="postconf.5.html#fallback_relay">fallback_relay</a>)</b>
-              Optional list of relay destinations that will be  used  when  an
-              SMTP  destination  is not found, or when delivery fails due to a
+              Optional  list  of  relay destinations that will be used when an
+              SMTP destination is not found, or when delivery fails due  to  a
               non-permanent error.
 
        Available with Postfix 3.0 and later:
 
        <b><a href="postconf.5.html#smtp_address_verify_target">smtp_address_verify_target</a> (rcpt)</b>
-              In the context of email address verification, the SMTP  protocol
+              In  the context of email address verification, the SMTP protocol
               stage that determines whether an email address is deliverable.
 
        Available with Postfix 3.1 and later:
@@ -1102,7 +1111,7 @@ SMTP(8)                                                                SMTP(8)
        Available in Postfix 3.7 and later:
 
        <b><a href="postconf.5.html#smtp_bind_address_enforce">smtp_bind_address_enforce</a> (no)</b>
-              Defer delivery when the Postfix SMTP  client  cannot  apply  the
+              Defer  delivery  when  the  Postfix SMTP client cannot apply the
               <a href="postconf.5.html#smtp_bind_address">smtp_bind_address</a> or <a href="postconf.5.html#smtp_bind_address6">smtp_bind_address6</a> setting.
 
 <b><a name="see_also">SEE ALSO</a></b>
index 22757a2e1cba7107717a67e1134de1325cd024b9..31bfc03755078761107f0ad57f8295b865ad2a14 100644 (file)
@@ -3499,6 +3499,10 @@ The LMTP\-specific version of the smtp_tls_enforce_peername
 configuration parameter.  See there for details.
 .PP
 This feature is available in Postfix 2.3 and later.
+.SH lmtp_tls_enforce_sts_mx_patterns (default: yes)
+See smtp_tls_enforce_sts_mx_patterns.
+.PP
+This feature is available in Postfix >= 3.10.5.
 .SH lmtp_tls_exclude_ciphers (default: empty)
 The LMTP\-specific version of the smtp_tls_exclude_ciphers
 configuration parameter.  See there for details.
@@ -8697,6 +8701,12 @@ CommonName of this attacker will be logged).
 .PP
 This feature is available in Postfix 2.2 and later. With
 Postfix 2.3 and later use smtp_tls_security_level instead.
+.SH smtp_tls_enforce_sts_mx_patterns (default: yes)
+Transform the TLS policy from an STS policy plugin: connect to
+an MX host only if its name matches the STS policy MX host pattern,
+and match the server certificate against the MX hostname.
+.PP
+This feature is available in Postfix >= 3.10.5.
 .SH smtp_tls_exclude_ciphers (default: empty)
 List of ciphers or cipher types to exclude from the Postfix
 SMTP client cipher
index ff7921bd8555c7b73b90780c667b1162b2bc37e5..dde3d5c7dbf998237b28edb35a459337df53ee21 100644 (file)
@@ -684,6 +684,14 @@ by a local TLSRPT reporting service.
 .IP "\fBsmtp_tlsrpt_skip_reused_handshakes (Postfix >= 3.11: no, Postfix 3.10: yes)\fR"
 When set to "yes", report the TLSRPT status only for "new" TLS
 sessions.
+.PP
+Available in Postfix version 3.10.5 and later:
+.IP "\fBsmtp_tls_enforce_sts_mx_patterns (yes)\fR"
+Transform the TLS policy from an STS policy plugin: connect to
+an MX host only if its name matches the STS policy MX host pattern,
+and match the server certificate against the MX hostname.
+.PP
+Available in Postfix version 3.11 and later:
 .IP "\fBtls_required_enable (yes)\fR"
 Enable support for the "TLS\-Required: no" message header, defined
 in RFC 8689.
index 061e0aef1c49be2667d1db93e5cf7e562bf46684..2b174bcacd1e57586e6a5aa70217477fd5970b12 100755 (executable)
@@ -729,6 +729,8 @@ while (<>) {
     s;\blmtp_tlsrpt_enable\b;<a href="postconf.5.html#lmtp_tlsrpt_enable">$&</a>;g;
     s;\blmtp_tlsrpt_socket_name\b;<a href="postconf.5.html#lmtp_tlsrpt_socket_name">$&</a>;g;
     s;\blmtp_tlsrpt_skip_reused_handshakes\b;<a href="postconf.5.html#lmtp_tlsrpt_skip_reused_handshakes">$&</a>;g;
+    s;\blmtp_tls_enforce_sts_mx_patterns\b;<a href="postconf.5.html#lmtp_tls_enforce_sts_mx_patterns">$&</a>;g;
+    s;\bsmtp_tls_enforce_sts_mx_patterns\b;<a href="postconf.5.html#smtp_tls_enforce_sts_mx_patterns">$&</a>;g;
     s;\bsmtpd_enforce_tls\b;<a href="postconf.5.html#smtpd_enforce_tls">$&</a>;g;
     s;\bsmtpd_sasl_tls_security_options\b;<a href="postconf.5.html#smtpd_sasl_tls_security_options">$&</a>;g;
     s;\bsmtpd_sasl_type\b;<a href="postconf.5.html#smtpd_sasl_type">$&</a>;g;
index 4b0ca121265f053290ada23432772b4722066063..cbaf202ec5ba1e255f73d6610b20bf25b67a8462 100644 (file)
@@ -19566,6 +19566,20 @@ second etc. TLS handshake to report. </p>
 
 <p> This feature is available in Postfix &ge; 3.10. </p>
 
+%PARAM lmtp_tls_enforce_sts_mx_patterns yes
+
+<p> See smtp_tls_enforce_sts_mx_patterns. </p>
+
+<p> This feature is available in Postfix &ge; 3.10.5. </p>
+
+%PARAM smtp_tls_enforce_sts_mx_patterns yes
+
+<p> Transform the TLS policy from an STS policy plugin: connect to
+an MX host only if its name matches the STS policy MX host pattern,
+and match the server certificate against the MX hostname. </p>
+
+<p> This feature is available in Postfix &ge; 3.10.5. </p>
+
 %PARAM full_name_encoding_charset utf-8
 
 <p> The character set name (also called "charset") that Postfix
index ff05172104c13a95014b5d036ab029b5bf1bab4f..4313fb9d7d821416580685d5d6a0812e019d7e64 100644 (file)
@@ -1868,3 +1868,5 @@ deduplicates
 intmax
 lflag
 REPLYCODE
+PTEST
+finalizer
index 551020a8614028dbb186a8d6c72f5ddd6e0bf45a..28a879f1c9159e989de3237aae9890716e11da7e 100644 (file)
@@ -4514,6 +4514,12 @@ extern char *var_smtp_tlsrpt_sockname;
 #define DEF_LMTP_TLSRPT_SKIP_REUSED_HS DEF_SMTP_TLSRPT_SKIP_REUSED_HS
 extern int var_smtp_tlsrpt_skip_reused_hs;
 
+#define VAR_SMTP_TLS_ENF_STS_MX_PAT    "smtp_tls_enforce_sts_mx_patterns"
+#define DEF_SMTP_TLS_ENF_STS_MX_PAT    "yes"
+#define VAR_LMTP_TLS_ENF_STS_MX_PAT    "lmtp_tls_enforce_sts_mx_patterns"
+#define DEF_LMTP_TLS_ENF_STS_MX_PAT    "yes"
+extern bool var_smtp_tls_enf_sts_mx_pat;
+
  /*
   * RFC 2047 encoding of full name info.
   */
index 85e924775ce37e21d1668ff9d2630ee7f8df2cfb..564e97222ff7b005b6be191967b53b497698d8c1 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      "20250825"
+#define MAIL_RELEASE_DATE      "20250906"
 #define MAIL_VERSION_NUMBER    "3.11"
 
 #ifdef SNAPSHOT
index f8cde6978f4f750a9a31b15410ef04bb7b7e0517..25002c658d5ec83d6d58e2a09c53ba31ad85cc63 100644 (file)
@@ -8,10 +8,10 @@ OBJS  = smtp.o smtp_connect.o smtp_proto.o smtp_chat.o smtp_session.o \
        smtp_sasl_proto.o smtp_sasl_glue.o smtp_reuse.o smtp_map11.o \
        smtp_sasl_auth_cache.o smtp_key.o smtp_misc.o smtp_tlsrpt.o
 HDRS   = smtp.h smtp_sasl.h smtp_addr.h smtp_reuse.h smtp_sasl_auth_cache.h
-TESTSRC        = 
+TESTSRC        = smtp_policy_test.c
 DEFS   = -I. -I$(INC_DIR) -D$(SYSTYPE)
 CFLAGS = $(DEBUG) $(OPT) $(DEFS)
-TESTPROG= smtp_unalias smtp_map11
+TESTPROG= smtp_unalias smtp_map11 smtp_tls_policy_test
 PROG   = smtp
 INC_DIR        = ../../include
 LIBS   = ../../lib/lib$(LIB_PREFIX)master$(LIB_SUFFIX) \
@@ -33,7 +33,7 @@ Makefile: Makefile.in
 
 test:  $(TESTPROG)
 
-tests: smtp_map11_test
+tests: smtp_map11_test test_smtp_tls_policy
 
 root_tests:
 
@@ -64,6 +64,14 @@ smtp_map11_test: smtp_map11 smtp_map11.ref
        diff smtp_map11.ref smtp_map11.tmp
        rm -f smtp_map11.tmp
 
+SMTP_POLICY_TEST_OBJ = smtp_tls_policy_test.o smtp_tls_policy.o smtp_state.o smtp_key.o
+
+smtp_tls_policy_test: $(SMTP_POLICY_TEST_OBJ) $(LIBS)
+       $(CC) $(CFLAGS) -o $@ $(SMTP_POLICY_TEST_OBJ) $(LIBS) $(SYSLIBS)
+
+test_smtp_tls_policy: smtp_tls_policy_test
+       $(SHLIB_ENV) $(VALGRIND) ./smtp_tls_policy_test
+
 depend: $(MAKES)
        (sed '1,/^# do not edit/!d' Makefile.in; \
        set -e; for i in [a-z][a-z0-9]*.c; do \
@@ -777,6 +785,7 @@ smtp_tls_policy.o: ../../include/htable.h
 smtp_tls_policy.o: ../../include/mail_params.h
 smtp_tls_policy.o: ../../include/maps.h
 smtp_tls_policy.o: ../../include/match_list.h
+smtp_tls_policy.o: ../../include/midna_domain.h
 smtp_tls_policy.o: ../../include/mime_state.h
 smtp_tls_policy.o: ../../include/msg.h
 smtp_tls_policy.o: ../../include/msg_stats.h
@@ -806,6 +815,46 @@ smtp_tls_policy.o: ../../include/vstream.h
 smtp_tls_policy.o: ../../include/vstring.h
 smtp_tls_policy.o: smtp.h
 smtp_tls_policy.o: smtp_tls_policy.c
+smtp_tls_policy_test.o: ../../include/argv.h
+smtp_tls_policy_test.o: ../../include/attr.h
+smtp_tls_policy_test.o: ../../include/check_arg.h
+smtp_tls_policy_test.o: ../../include/deliver_request.h
+smtp_tls_policy_test.o: ../../include/dict.h
+smtp_tls_policy_test.o: ../../include/dns.h
+smtp_tls_policy_test.o: ../../include/dsn.h
+smtp_tls_policy_test.o: ../../include/dsn_buf.h
+smtp_tls_policy_test.o: ../../include/header_body_checks.h
+smtp_tls_policy_test.o: ../../include/header_opts.h
+smtp_tls_policy_test.o: ../../include/htable.h
+smtp_tls_policy_test.o: ../../include/mail_params.h
+smtp_tls_policy_test.o: ../../include/maps.h
+smtp_tls_policy_test.o: ../../include/match_list.h
+smtp_tls_policy_test.o: ../../include/mime_state.h
+smtp_tls_policy_test.o: ../../include/msg.h
+smtp_tls_policy_test.o: ../../include/msg_stats.h
+smtp_tls_policy_test.o: ../../include/msg_vstream.h
+smtp_tls_policy_test.o: ../../include/myaddrinfo.h
+smtp_tls_policy_test.o: ../../include/myflock.h
+smtp_tls_policy_test.o: ../../include/mymalloc.h
+smtp_tls_policy_test.o: ../../include/name_code.h
+smtp_tls_policy_test.o: ../../include/name_mask.h
+smtp_tls_policy_test.o: ../../include/nvtable.h
+smtp_tls_policy_test.o: ../../include/recipient_list.h
+smtp_tls_policy_test.o: ../../include/resolve_clnt.h
+smtp_tls_policy_test.o: ../../include/scache.h
+smtp_tls_policy_test.o: ../../include/sendopts.h
+smtp_tls_policy_test.o: ../../include/sock_addr.h
+smtp_tls_policy_test.o: ../../include/string_list.h
+smtp_tls_policy_test.o: ../../include/stringops.h
+smtp_tls_policy_test.o: ../../include/sys_defs.h
+smtp_tls_policy_test.o: ../../include/tls.h
+smtp_tls_policy_test.o: ../../include/tls_proxy.h
+smtp_tls_policy_test.o: ../../include/tok822.h
+smtp_tls_policy_test.o: ../../include/vbuf.h
+smtp_tls_policy_test.o: ../../include/vstream.h
+smtp_tls_policy_test.o: ../../include/vstring.h
+smtp_tls_policy_test.o: smtp.h
+smtp_tls_policy_test.o: smtp_tls_policy_test.c
 smtp_tlsrpt.o: ../../include/argv.h
 smtp_tlsrpt.o: ../../include/attr.h
 smtp_tlsrpt.o: ../../include/check_arg.h
index b77500326e186fc10ecdf89cb4a37fb8b5bb9ae4..963081b5438f411bc27f48a07df4ed30e651d665 100644 (file)
        VAR_LMTP_REQ_DEADLINE, DEF_LMTP_REQ_DEADLINE, &var_smtp_req_deadline,
        VAR_LMTP_TLSRPT_ENABLE, DEF_LMTP_TLSRPT_ENABLE, &var_smtp_tlsrpt_enable,
        VAR_LMTP_TLSRPT_SKIP_REUSED_HS, DEF_LMTP_TLSRPT_SKIP_REUSED_HS, &var_smtp_tlsrpt_skip_reused_hs,
+       VAR_LMTP_TLS_ENF_STS_MX_PAT, DEF_LMTP_TLS_ENF_STS_MX_PAT, &var_smtp_tls_enf_sts_mx_pat,
        0,
     };
index 76e1a38014bc72ba7b18343740d2ff4310da2ff8..beb46033c95a36dfa7cd7cc51aa39116d87e213d 100644 (file)
 /* .IP "\fBsmtp_tlsrpt_skip_reused_handshakes (Postfix >= 3.11: no, Postfix 3.10: yes)\fR"
 /*     When set to "yes", report the TLSRPT status only for "new" TLS
 /*     sessions.
+/* .PP
+/*     Available in Postfix version 3.10.5 and later:
+/* .IP "\fBsmtp_tls_enforce_sts_mx_patterns (yes)\fR"
+/*     Transform the TLS policy from an STS policy plugin: connect to
+/*     an MX host only if its name matches the STS policy MX host pattern,
+/*     and match the server certificate against the MX hostname.
+/* .PP
+/*     Available in Postfix version 3.11 and later:
 /* .IP "\fBtls_required_enable (yes)\fR"
 /*     Enable support for the "TLS-Required: no" message header, defined
 /*     in RFC 8689.
@@ -1132,6 +1140,7 @@ bool    var_smtp_tls_blk_early_mail_reply;
 bool    var_smtp_tls_force_tlsa;
 char   *var_smtp_tls_insecure_mx_policy;
 bool    var_smtp_tls_enable_rpk;
+bool    var_smtp_tls_enf_sts_mx_pat;
 
 #endif
 
index 874f9481cd27f897150f79fe5abe74223fc61e86..28cca83a44bd2f2d564bcd26a3bdb96f3d8de7e4 100644 (file)
@@ -137,6 +137,7 @@ typedef struct SMTP_TLS_POLICY {
 extern void smtp_tls_list_init(void);
 extern int smtp_tls_policy_cache_query(DSN_BUF *, SMTP_TLS_POLICY *, SMTP_ITERATOR *);
 extern void smtp_tls_policy_cache_flush(void);
+extern int  smtp_tls_authorize_mx_hostname(SMTP_TLS_POLICY *, const char *);
 
  /*
   * Macros must use distinct names for local temporary variables, otherwise
index fb34945232f8e0cb37ad5611243545f6535924a1..7a93e638c661e57bc82314f53ee822fce406f287 100644 (file)
@@ -1124,6 +1124,11 @@ static void smtp_connect_inet(SMTP_STATE *state, const char *nexthop,
                continue;
                /* XXX Assume there is no code at the end of this loop. */
            }
+           /* Skip MX hosts that lack authorization. */
+           if (!smtp_tls_authorize_mx_hostname(state->tls, addr->qname)) {
+               continue;
+               /* XXX Assume there is no code at the end of this loop. */
+           }
            /* Disable TLS when retrying after a handshake failure */
            if (retry_plain) {
                state->tls->level = TLS_LEV_NONE;
index 6d80ef105dc915db38cdb6832871a035492cbc25..8569cb9f58ae8571d8e9b34cfabc29e5883283a1 100644 (file)
        VAR_SMTP_REQ_DEADLINE, DEF_SMTP_REQ_DEADLINE, &var_smtp_req_deadline,
        VAR_SMTP_TLSRPT_ENABLE, DEF_SMTP_TLSRPT_ENABLE, &var_smtp_tlsrpt_enable,
        VAR_SMTP_TLSRPT_SKIP_REUSED_HS, DEF_SMTP_TLSRPT_SKIP_REUSED_HS, &var_smtp_tlsrpt_skip_reused_hs,
+       VAR_SMTP_TLS_ENF_STS_MX_PAT, DEF_SMTP_TLS_ENF_STS_MX_PAT, &var_smtp_tls_enf_sts_mx_pat,
        0,
     };
index 809ffea05349c8c6db443051fce4c1c0caa145a2..76f38aa3e9b0e1124066b8beefba8f6f45a99a14 100644 (file)
 /*     SMTP_TLS_POLICY *tls;
 /*
 /*     void    smtp_tls_policy_cache_flush()
+/*
+/*     int     smtp_tls_authorize_mx_hostname(tls, qname)
+/*     SMTP_TLS_POLICY *tls;
+/*     const char *qname;
 /* DESCRIPTION
 /*     smtp_tls_list_init() initializes lookup tables used by the TLS
 /*     policy engine.
 /*     smtp_tls_policy_cache_flush() destroys the TLS policy cache
 /*     and contents.
 /*
+/*     smtp_tls_authorize_mx_hostname() authorizes an MX host if the
+/*     name used for host lookup satisfies a TLS policy MX name
+/*     constraint (for example, an STS policy MX pattern), or if the
+/*     TLS policy has no name constraint.
+/*
 /*     Arguments:
 /* .IP why
 /*     A pointer to a DSN_BUF which holds error status information when
 #include <valid_hostname.h>
 #include <valid_utf8_hostname.h>
 #include <ctable.h>
+#include <midna_domain.h>
 
 /* Global library. */
 
@@ -136,6 +146,51 @@ static void dane_init(SMTP_TLS_POLICY *, SMTP_ITERATOR *);
 static MAPS *tls_policy;               /* lookup table(s) */
 static MAPS *tls_per_site;             /* lookup table(s) */
 
+/* match_sts_mx_host_pattern -  match hostname against STS policy MX pattern */
+
+static int match_sts_mx_host_pattern(const char *pattern, const char *qname)
+{
+    const char *first_dot_in_qname;
+
+    /* Caller guarantees that inputs are in ASCII form. */
+    return (strcasecmp(qname, pattern) == 0
+           || (pattern[0] == '*' && pattern[1] == '.' && pattern[2] != 0
+               && (first_dot_in_qname = strchr(qname, '.')) != 0
+               && first_dot_in_qname > qname
+               && strcasecmp(first_dot_in_qname + 1, pattern + 2) == 0));
+}
+
+/* smtp_tls_authorize_mx_hostname - enforce applicable MX hostname policy */
+
+int     smtp_tls_authorize_mx_hostname(SMTP_TLS_POLICY *tls, const char *name)
+{
+
+#define SAFE_FOR_SMTP_TLS_ENF_STS_MX_PAT(tls) (var_smtp_tls_enf_sts_mx_pat \
+           && (tls)->ext_policy_type != 0 \
+           && strcasecmp((tls)->ext_policy_type, "sts") == 0 \
+           && (tls)->matchargv != 0 && (tls)->ext_mx_host_patterns != 0)
+
+    /* Enforce STS policy MX patterns. */
+    if (SAFE_FOR_SMTP_TLS_ENF_STS_MX_PAT(tls)) {
+       const char *aname;
+       char  **pattp;
+
+#ifndef NO_EAI
+       if (!allascii(name) && (aname = midna_domain_to_ascii(name)) != 0) {
+           if (msg_verbose)
+               msg_info("%s asciified to %s", name, aname);
+       } else
+#endif
+           aname = name;
+       for (pattp = tls->ext_mx_host_patterns->argv; *pattp; pattp++)
+           if (match_sts_mx_host_pattern(*pattp, aname))
+               return (1);
+       return (0);
+    }
+    /* No applicable policy name patterns. */
+    return (1);
+}
+
 /* smtp_tls_list_init - initialize per-site policy lists */
 
 void    smtp_tls_list_init(void)
@@ -517,6 +572,10 @@ static void tls_policy_lookup_one(SMTP_TLS_POLICY *tls, int *site_level,
            INVALID_RETURN(tls->why, site_level);
        }
     }
+    if (SAFE_FOR_SMTP_TLS_ENF_STS_MX_PAT(tls)) {
+       argv_truncate(tls->matchargv, 0);
+       argv_add(tls->matchargv, "hostname", (char *) 0);
+    }
     FREE_RETURN;
 }
 
diff --git a/postfix/src/smtp/smtp_tls_policy_test.c b/postfix/src/smtp/smtp_tls_policy_test.c
new file mode 100644 (file)
index 0000000..f37ac98
--- /dev/null
@@ -0,0 +1,503 @@
+/*++
+/* NAME
+/*      smtp_tls_policy_test 1t
+/* SUMMARY
+/*      smtp_tls_policy unit tests
+/* SYNOPSIS
+/*      ./smtp_tls_policy_test
+/* DESCRIPTION
+/*      smtp_tls_policy_test runs and logs each configured test, reports
+/*      if a test is a PASS or FAIL, and returns an exit status of zero
+/*      if all tests are a PASS.
+/* LICENSE
+/* .ad
+/* .fi
+/*      The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*      Wietse Venema
+/*      porcupine.org
+/*--*/
+
+ /*
+  * System library.
+  */
+#include <sys_defs.h>
+#include <stdlib.h>
+
+ /*
+  * Utility library.
+  */
+#include <argv.h>
+#include <msg.h>
+#include <msg_vstream.h>
+#include <stringops.h>
+#include <vstream.h>
+#include <vstring.h>
+
+#ifdef USE_TLS
+
+#define PASS    (0)
+#define FAIL    (1)
+
+ /*
+  * Global library.
+  */
+#include <mail_params.h>
+
+ /*
+  * TLS library.
+  */
+
+ /*
+  * SMTP client.
+  */
+#include <smtp.h>
+
+ /*
+  * Surrogate dependencies. Parameters are initialized without $name
+  * expansion, and can be changed by tests.
+  */
+char   *var_smtp_tls_policy;
+char   *var_smtp_tls_per_site;
+char   *var_smtp_tls_ciph;
+bool    var_smtp_tls_conn_reuse;
+bool    var_smtp_tls_enable_rpk;
+char   *var_smtp_tls_level;
+int     smtp_host_lookup_mask;
+int     var_smtp_cache_conn;
+char   *var_smtp_tls_mand_ciph;
+char   *var_smtp_tls_mand_excl;
+char   *var_smtp_dns_res_opt;
+char   *var_smtp_dns_support;
+char   *var_smtp_tls_insecure_mx_policy;
+int     var_ign_mx_lookup_err;
+bool    var_smtp_enforce_tls;
+bool    var_smtp_tls_enforce_peername;
+bool    var_smtp_tls_force_tlsa;
+char   *var_smtp_tls_fpt_cmatch;
+char   *var_smtp_tls_mand_proto;
+char   *var_smtp_tls_proto;
+char   *var_smtp_tls_sec_cmatch;
+char   *var_smtp_tls_sni;
+char   *var_smtp_tls_tafile;
+char   *var_smtp_tls_vfy_cmatch;
+bool    var_smtp_use_tls;
+char   *var_smtp_tls_excl_ciph;
+bool    var_smtp_tls_enf_sts_mx_pat;
+
+ /*
+  * Other globals.
+  */
+int     smtp_mode;
+int     smtp_tls_insecure_mx_policy;
+unsigned smtp_dns_res_opt;
+int     smtp_dns_support;
+int     smtp_host_lookup_mask;
+
+ /*
+  * Pre-test initializer to make tests independent.
+  */
+static void test_setup(void)
+{
+    var_smtp_tls_policy = DEF_SMTP_TLS_POLICY;
+    var_smtp_tls_per_site = DEF_SMTP_TLS_PER_SITE;
+    var_smtp_tls_ciph = DEF_SMTP_TLS_CIPH;
+    var_smtp_tls_conn_reuse = DEF_SMTP_TLS_CONN_REUSE;
+    var_smtp_tls_enable_rpk = DEF_SMTP_TLS_ENABLE_RPK;
+    var_smtp_tls_level = "may";
+    var_smtp_cache_conn = 2;
+    var_smtp_tls_mand_ciph = DEF_SMTP_TLS_MAND_CIPH;
+    var_smtp_tls_mand_excl = DEF_SMTP_TLS_MAND_EXCL;
+    var_smtp_dns_res_opt = DEF_SMTP_DNS_RES_OPT;
+    var_smtp_dns_support = DEF_SMTP_DNS_SUPPORT;
+    var_smtp_tls_insecure_mx_policy = DEF_SMTP_TLS_INSECURE_MX_POLICY;
+    var_ign_mx_lookup_err = DEF_IGN_MX_LOOKUP_ERR;
+    var_smtp_enforce_tls = DEF_SMTP_ENFORCE_TLS;
+    var_smtp_tls_enforce_peername = DEF_SMTP_TLS_ENFORCE_PN;
+    var_smtp_tls_force_tlsa = DEF_SMTP_TLS_FORCE_TLSA;
+    var_smtp_tls_fpt_cmatch = DEF_SMTP_TLS_FPT_CMATCH;
+    var_smtp_tls_mand_proto = DEF_SMTP_TLS_MAND_PROTO;
+    var_smtp_tls_proto = DEF_SMTP_TLS_PROTO;
+    var_smtp_tls_sec_cmatch = DEF_SMTP_TLS_SEC_CMATCH;
+    var_smtp_tls_sni = DEF_SMTP_TLS_SNI;
+    var_smtp_tls_tafile = DEF_SMTP_TLS_TAFILE;
+    var_smtp_tls_vfy_cmatch = DEF_SMTP_TLS_VFY_CMATCH;
+    var_smtp_use_tls = DEF_SMTP_USE_TLS;
+    var_smtp_tls_excl_ciph = DEF_SMTP_TLS_EXCL_CIPH;
+    var_smtp_tls_enf_sts_mx_pat = 1;
+
+    smtp_mode = 1;
+
+    smtp_tls_policy_cache_flush();
+}
+
+ /*
+  * Post-test finalizer to help memory leak tests.
+  */
+static void test_teardown(void)
+{
+    smtp_tls_policy_cache_flush();
+}
+
+ /*
+  * Test helpers. TODO(wietse) adopt PTEST which does a nicer job.
+  */
+static int match_int(const char *what, int want, int got)
+{
+    if (want != got) {
+       msg_warn("%s: got %d, want %d", what, got, want);
+       return (0);
+    }
+    return (1);
+}
+
+#define STR_OR_NULL(s) ((s)? (s) : "NULL")
+
+static int match_cstr(const char *what, const char *want, const char *got)
+{
+    if (!want != !got) {
+       msg_warn("%s: got '%s', want '%s'", what, STR_OR_NULL(got),
+                STR_OR_NULL(want));
+       return (0);
+    }
+    if (want != 0 && strcmp(got, want) != 0) {
+       msg_warn("%s: got '%s', want '%s'", what, got, want);
+       return (0);
+    }
+    return (1);
+}
+
+#define WANT_ARGV_MAX  5
+
+struct WANT_ARGV {
+    ssize_t argc;
+    char   *argv[WANT_ARGV_MAX];
+};
+
+#define ARGV_OR_NULL(a) ((a)? ("argv") : "NULL")
+
+static int match_argv(const char *what, const struct WANT_ARGV * want,
+                             const ARGV *got)
+{
+    if (!want != !got) {
+       msg_warn("%s: got '%s', want '%s'", what, ARGV_OR_NULL(got),
+                ARGV_OR_NULL(want));
+       return (0);
+    }
+    if (match_int("argc", want->argc, got->argc) == 0) {
+       return (0);
+    } else {
+       VSTRING *buf;
+       int     idx;
+       int     equal;
+
+       buf = vstring_alloc(100);
+       for (equal = 1, idx = 0; idx < want->argc; idx++) {
+           vstring_sprintf(buf, "%s->argv[%d]", what, idx);
+           if (match_cstr(STR(buf), want->argv[idx], got->argv[idx]) == 0)
+               equal = 0;
+       }
+       vstring_free(buf);
+       return (equal);
+    }
+}
+
+ /*
+  * Limited policy for STS tests.
+  */
+struct WANT_SMTP_TLS_POLICY {
+    int     level;                     /* TLS enforcement level */
+#if 0
+    char   *protocols;                 /* Acceptable SSL protocols */
+    char   *grade;                     /* Cipher grade: "export", ... */
+    VSTRING *exclusions;               /* Excluded SSL ciphers */
+    char   *protocols;                 /* Acceptable SSL protocols */
+    char   *grade;                     /* Cipher grade: "export", ... */
+    VSTRING *exclusions;               /* Excluded SSL ciphers */
+#endif
+    struct WANT_ARGV matchargv;                /* Cert match patterns */
+#if 0
+    DSN_BUF *why;                      /* Lookup error status */
+    TLS_DANE *dane;                    /* DANE TLSA digests */
+#endif
+    char   *sni;                       /* Optional SNI name when not DANE */
+#if 0
+    int     conn_reuse;                        /* enable connection reuse */
+    int     enable_rpk;                        /* Enable server->client RPK */
+#endif
+    int     ext_policy_ttl;            /* TTL from DNS etc. */
+    char   *ext_policy_type;           /* (sts) */
+    struct WANT_ARGV ext_policy_strings;/* policy strings from DNS etc. */
+    char   *ext_policy_domain;         /* policy scope */
+    struct WANT_ARGV ext_mx_host_patterns;     /* (sts) MX host patterns */
+    char   *ext_policy_failure;                /* (sts) policy failure */
+};
+
+#define POLICY_OR_NULL(p) ((p)? ("policy") : "NULL")
+
+static int match_smtp_tls_policy(const char *what,
+                                  const struct WANT_SMTP_TLS_POLICY * want,
+                                        const SMTP_TLS_POLICY *got)
+{
+    int     equal = 1;
+
+    if (!want != !got) {
+       msg_warn("%s: got '%s', want '%s'", what, POLICY_OR_NULL(got),
+                POLICY_OR_NULL(want));
+       return (0);
+    }
+    if (match_int("level", want->level, got->level) == 0) {
+       msg_warn("%s->level mismatch", what);
+       equal = 0;
+    }
+    if (match_argv("matchargv", &want->matchargv, got->matchargv) == 0) {
+       msg_warn("%s->matchargv mismatch", what);
+       equal = 0;
+    }
+    if (match_cstr("sni", want->sni, got->sni) == 0) {
+       msg_warn("%s->sni mismatch", what);
+       equal = 0;
+    }
+    if (match_int("ext_policy_ttl", want->ext_policy_ttl, got->ext_policy_ttl) == 0) {
+       msg_warn("%s->ext_policy_ttl mismatch", what);
+       equal = 0;
+    }
+    if (match_cstr("ext_policy_type", want->ext_policy_type,
+                  got->ext_policy_type) == 0) {
+       msg_warn("%s->ext_policy_type mismatch", what);
+       equal = 0;
+    }
+    if (match_argv("ext_policy_strings", &want->ext_policy_strings,
+                  got->ext_policy_strings) == 0) {
+       msg_warn("%s->ext_policy_strings mismatch", what);
+       equal = 0;
+    }
+    if (match_cstr("ext_policy_domain", want->ext_policy_domain,
+                  got->ext_policy_domain) == 0) {
+       msg_warn("%s->ext_policy_domain mismatch", what);
+       equal = 0;
+    }
+    if (match_argv("ext_mx_host_patterns", &want->ext_mx_host_patterns,
+                  got->ext_mx_host_patterns) == 0) {
+       msg_warn("%s->ext_mx_host_patterns mismatch", what);
+       equal = 0;
+    }
+    if (match_cstr("ext_policy_failure", want->ext_policy_failure,
+                  got->ext_policy_failure) == 0) {
+       msg_warn("%s->ext_policy_failure mismatch", what);
+       equal = 0;
+    }
+    return (equal);
+}
+
+ /*
+  * Test structure. Some tests may bring their own.
+  */
+typedef struct TEST_CASE {
+    const char *label;
+    int     (*action) (const struct TEST_CASE *);
+} TEST_CASE;
+
+ /*
+  * Verify that policies from an STS plugin are converted into Postfix TLS
+  * policies that match a certificate against the server hostname, and that
+  * other policy attributes are stored appropriately. A later test will
+  * verify that MX hostnames are matched against the STS policy MX hostname
+  * patterns.
+  */
+static int sts_policy_smoke_test(const struct TEST_CASE *tp)
+{
+    var_smtp_tls_policy =
+    "static:{secure match=example:.example "
+    "servername=example policy_ttl=123 "
+    "policy_type=sts policy_string=one "
+    "policy_string=two policy_domain=example "
+    "mx_host_pattern=example mx_host_pattern=*.example}";
+    static const struct WANT_SMTP_TLS_POLICY want_policy = {
+       .level = TLS_LEV_SECURE,
+       .matchargv = {.argc = 1,.argv = {"hostname"}},
+       .sni = "example",
+       .ext_policy_ttl = 123,
+       .ext_policy_type = "sts",
+       .ext_policy_strings = {.argc = 2,.argv = {"one", "two"}},
+       .ext_policy_domain = "example",
+       .ext_mx_host_patterns = {.argc = 2,.argv = {"example", "*.example"}}
+    };
+    SMTP_STATE *state = smtp_state_alloc();
+    const char *domain = "example";
+    const char *host = "mail.example";
+    const char *addr = "10.0.1.1";
+    int     port = 25;
+    int     match;
+
+    var_smtp_tls_enf_sts_mx_pat = 1;
+    var_smtp_tls_level = "secure";
+    smtp_tls_list_init();
+    SMTP_ITER_INIT(state->iterator, domain, host, addr, port, state);
+    if ((match = smtp_tls_policy_cache_query(state->why, state->tls,
+                                            state->iterator)) == 0) {
+       msg_warn("smtp_tls_policy_cache_query failed: %s",
+                STR(state->why->reason));
+    } else {
+       match = match_smtp_tls_policy("policy", &want_policy, state->tls);
+    }
+    smtp_state_free(state);
+    smtp_tls_policy_cache_flush();
+    return (match ? PASS : FAIL);
+}
+
+ /*
+  * Verify that the historical support for policies from STS plugins is still
+  * available. STS plugins generate a policy that will match a certificate
+  * against all MX patterns, after converting a pattern "*.domain" to
+  * ".domain", and do not constrain the allowed MX hostnames.
+  */
+static int obs_sts_policy_smoke_test(const struct TEST_CASE *tp)
+{
+    var_smtp_tls_policy =
+    "static:{secure match=example:.example "
+    "servername=example policy_ttl=123 "
+    "policy_type=sts policy_string=one "
+    "policy_string=two policy_domain=example "
+    "mx_host_pattern=example mx_host_pattern=*.example}";
+    static const struct WANT_SMTP_TLS_POLICY want_policy = {
+       .level = TLS_LEV_SECURE,
+       .matchargv = {.argc = 2,.argv = {"example", ".example"}},
+       .sni = "example",
+       .ext_policy_ttl = 123,
+       .ext_policy_type = "sts",
+       .ext_policy_strings = {.argc = 2,.argv = {"one", "two"}},
+       .ext_policy_domain = "example",
+       .ext_mx_host_patterns = {.argc = 2,.argv = {"example", "*.example"}}
+    };
+    SMTP_STATE *state = smtp_state_alloc();
+    const char *domain = "example";
+    const char *host = "mail.example";
+    const char *addr = "10.0.1.1";
+    int     port = 25;
+    int     match;
+
+    var_smtp_tls_enf_sts_mx_pat = 0;
+    var_smtp_tls_level = "secure";
+    smtp_tls_list_init();
+    SMTP_ITER_INIT(state->iterator, domain, host, addr, port, state);
+    if ((match = smtp_tls_policy_cache_query(state->why, state->tls,
+                                            state->iterator)) == 0) {
+       msg_warn("smtp_tls_policy_cache_query failed: %s",
+                STR(state->why->reason));
+    } else {
+       match = match_smtp_tls_policy("policy", &want_policy, state->tls);
+    }
+    smtp_state_free(state);
+    smtp_tls_policy_cache_flush();
+    return (match ? PASS : FAIL);
+}
+
+ /*
+  * Test the MX host authorization constraints.
+  */
+static int test_hostname_authorization(const struct TEST_CASE *tp)
+{
+    var_smtp_tls_policy =
+    "static:{secure match=example.com:.example.com "
+    "servername=example.com policy_ttl=123 "
+    "policy_type=sts policy_string=one "
+    "policy_string=two policy_domain=example.com "
+    "mx_host_pattern=example.com mx_host_pattern=*.example.com}";
+    static const struct WANT_SMTP_TLS_POLICY want_policy = {
+       .level = TLS_LEV_SECURE,
+       .matchargv = {.argc = 1,.argv = {"hostname"}},
+       .sni = "example.com",
+       .ext_policy_ttl = 123,
+       .ext_policy_type = "sts",
+       .ext_policy_strings = {.argc = 2,.argv = {"one", "two"}},
+       .ext_policy_domain = "example.com",
+       .ext_mx_host_patterns = {.argc = 2,.argv = {"example.com", "*.example.com"}}
+    };
+    SMTP_STATE *state = smtp_state_alloc();
+    const char *domain = "example.com";
+    const char *host = "mail.example.com";
+    const char *addr = "10.0.1.1";
+    int     port = 25;
+    int     match;
+    static const char *permit_domains[] = {
+       "example.com", "mail.example.com", 0,
+    };
+    static const char *reject_domains[] = {
+       ".example.com", "foo.bar.example.com", 0,
+    };
+    const char *const * cpp;
+
+    var_smtp_tls_enf_sts_mx_pat = 1;
+    var_smtp_tls_level = "secure";
+    smtp_tls_list_init();
+    SMTP_ITER_INIT(state->iterator, domain, host, addr, port, state);
+    if ((match = smtp_tls_policy_cache_query(state->why, state->tls,
+                                            state->iterator)) == 0) {
+       msg_warn("smtp_tls_policy_cache_query failed: %s",
+                STR(state->why->reason));
+    } else {
+       match = match_smtp_tls_policy("policy", &want_policy, state->tls);
+    }
+    if (match == 0)
+       return (FAIL);
+
+    /* Verify that 'good' MX host names are authorized. */
+    for (cpp = permit_domains; *cpp; cpp++) {
+       if (!smtp_tls_authorize_mx_hostname(state->tls, *cpp)) {
+           msg_warn("hostname '%s' is not authorized", *cpp);
+           match = 0;
+       }
+    }
+    /* Verify that 'wrong' MX host names are not authorized. */
+    for (cpp = reject_domains; *cpp; cpp++) {
+       if (smtp_tls_authorize_mx_hostname(state->tls, *cpp)) {
+           msg_warn("hostname '%s' is authorized", *cpp);
+           match = 0;
+       }
+    }
+
+    smtp_state_free(state);
+    smtp_tls_policy_cache_flush();
+    return (match ? PASS : FAIL);
+}
+
+static const struct TEST_CASE test_cases[] = {
+    {"sts_policy_smoke_test", sts_policy_smoke_test,},
+    {"obs_sts_policy_smoke_test", obs_sts_policy_smoke_test,},
+    {"test_hostname_authorization", test_hostname_authorization},
+    {0},
+};
+
+int     main(int argc, char **argv)
+{
+    static int tests_passed = 0;
+    static int tests_failed = 0;
+    const struct TEST_CASE *tp;
+
+    msg_vstream_init(sane_basename((VSTRING *) 0, argv[0]), VSTREAM_ERR);
+
+    for (tp = test_cases; tp->label; tp++) {
+       msg_info("RUN  %s", tp->label);
+       test_setup();
+       if (tp->action(tp) == PASS) {
+           msg_info("PASS %s", tp->label);
+           tests_passed += 1;
+       } else {
+           msg_info("FAIL %s", tp->label);
+           tests_failed += 1;
+       }
+       test_teardown();
+    }
+    msg_info("PASS=%d FAIL=%d", tests_passed, tests_failed);
+    exit(tests_failed != 0);
+}
+
+#else
+
+int     main(int argc, char **argv)
+{
+    msg_fatal("this program requires `#define USE_TLS'");
+}
+
+#endif