]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
postfix-3.11-20250910-nonprod 20250906-nonprod
authorWietse Z Venema <wietse@porcupine.org>
Wed, 10 Sep 2025 05:00:00 +0000 (00:00 -0500)
committerViktor Dukhovni <ietf-dane@dukhovni.org>
Fri, 12 Sep 2025 11:05:47 +0000 (21:05 +1000)
53 files changed:
postfix/.indent.pro
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/proto/postconf.proto
postfix/proto/stop.double-cc
postfix/proto/stop.double-history
postfix/proto/stop.double-proto-html
postfix/proto/stop.spell-cc
postfix/src/cleanup/cleanup_bounce.c
postfix/src/cleanup/cleanup_out_recipient.c
postfix/src/discard/discard.c
postfix/src/error/error.c
postfix/src/global/Makefile.in
postfix/src/global/bounce.c
postfix/src/global/bounce.h
postfix/src/global/defer.c
postfix/src/global/defer.h
postfix/src/global/deliver_pass.c
postfix/src/global/log_adhoc.c
postfix/src/global/log_adhoc.h
postfix/src/global/mail_params.h
postfix/src/global/mail_version.h
postfix/src/global/reject_deliver_request.c
postfix/src/global/sent.c
postfix/src/global/sent.h
postfix/src/global/tls_stats.c [new file with mode: 0644]
postfix/src/global/tls_stats.h [new file with mode: 0644]
postfix/src/global/trace.c
postfix/src/global/trace.h
postfix/src/global/verify.c
postfix/src/global/verify.h
postfix/src/local/local.h
postfix/src/oqmgr/qmgr_bounce.c
postfix/src/oqmgr/qmgr_defer.c
postfix/src/oqmgr/qmgr_message.c
postfix/src/pipe/pipe.c
postfix/src/qmgr/qmgr_bounce.c
postfix/src/qmgr/qmgr_defer.c
postfix/src/qmgr/qmgr_message.c
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_proto.c
postfix/src/smtp/smtp_rcpt.c
postfix/src/smtp/smtp_state.c
postfix/src/smtp/smtp_trouble.c
postfix/src/virtual/virtual.h

index 78948c7aa523f969b5de3a989806ad17a5d629ef..c3e46389777540c2fe51fde03a45783d2f9aab94 100644 (file)
 -TTLS_SERVER_INIT_PROPS
 -TTLS_SERVER_START_PROPS
 -TTLS_SESS_STATE
+-TTLS_STAT
+-TTLS_STATS
 -TTLS_TICKET_KEY
 -TTLS_TLSA
 -TTLS_USAGE
index ca33b511ea9b66f8d87b14119cfef144ed6bb9b4..c50a459cc50c66cb109aef0499615734ef505cf4 100644 (file)
@@ -29747,63 +29747,30 @@ NONPROD CODE
        production release; renamed enforce_reqtls to the more
        meaningful reqtls_level.
 
-TODO
-
-       Make it easy to find out by domain what the REQUIRETLS
-       success rates are, and what the failure modes are.
-
-       Add optional statistics logging for "REQUIRETLS sent" and
-       for "all REQUIRETLS requirements pass". But these say
-       nothing about connections that failed to establish an
-       acceptable TLS session.
-
-       Other logging: RFC 8689 prescribes enhanced status codes:
-
-       - REQUIRETLS not supported by server: 5.7.30 REQUIRETLS
-         support required
-
-       - Unable to establish TLS-protected SMTP session: 5.7.10
-         Encryption needed
-
-       These will show up in logging.
+       Completed 20250910: TLS feature policy status logging in
+       delivery status logging. This shows the TLS security level
+       enforcement status and, if a message requests REQUIRETLS,
+       the REQUIRETLS policy enforcement status. Files: .indent.pro,
+       cleanup/cleanup_bounce.c, cleanup/cleanup_out_recipient.c,
+       discard/discard.c, error/error.c, global/Makefile.in,
+       global/bounce.c, global/bounce.h, global/defer.c, global/defer.h,
+       global/deliver_pass.c, global/log_adhoc.c, global/log_adhoc.h,
+       global/mail_version.h, global/reject_deliver_request.c,
+       global/sent.c, global/sent.h, global/tls_stats.c,
+       global/tls_stats.h, global/trace.c, global/trace.h,
+       global/verify.c, global/verify.h, local/local.h,
+       oqmgr/qmgr_bounce.c, oqmgr/qmgr_defer.c, oqmgr/qmgr_message.c,
+       pipe/pipe.c, qmgr/qmgr_bounce.c, qmgr/qmgr_defer.c,
+       qmgr/qmgr_message.c, smtp/smtp.h, smtp/smtp_connect.c,
+       smtp/smtp_proto.c, smtp/smtp_rcpt.c, smtp/smtp_state.c,
+       smtp/smtp_trouble.c, virtual/virtual.h.
 
-       Known failure modes
-       misc problems at DNS, TCP, or SMTP level
-       misc errors with TLS policy or REQUIRETLS policy
-       smtp_connect.c:
-           TLS policy disables certificate matching
-           TLS policy disables encryption (opportunistic only)
-       smtp_proto.c.
-           STARTTLS rejected (sender requested REQUIRETLS...)
-           STARTTLS not offered (sender requested REQUIRETLS...)
-           (TLS is required, but our TLS engine is unavailable)
-           (TLS is required, but unavailable)
-           CERT not trusted|matched (sender requested REQUIRETLS...)
-
-       Revert $requiretls in pipe daemon?
-
-       Which enforcement levels can we implement?
-
-           enforce: require that the server supports REQUIRETLS,
-           and that the connection satisfies RFC XXX requirements.
-
-           no-plaintext: skip servers that don't announce STARTTLS;
-           request REQUIRETLS if the server supports REQUIRETLS,
-           otherwise deliver the message as if the sender did not
-           request REQUIRETLS.
-
-           ????/ignore/disable/none: request REQUIRETLS if the
-           server supports REQUIRETLS, otherwise deliver the message
-           as if the sender did not request REQUIRETLS.
+TODO
 
        Maybe log "server announces REQUIRETLS" if we're not
        enforcing REQUIRETLS.
 
-       Delete $requiretls from pipe daemon?
-
-       Verify that SMTPUTF8 and REQUIRETLS flags propagate from
-       sendmail(1) and smtpd(8) through cleanup(8) and qmgr(8) to
-       delivery agents and bounce services.
+       Remove $requiretls from pipe daemon?
 
        Add support to propagate REQUIRETLS (Not: TLS-Required:)
        header through cleanup to queue files.
index c0ce2ddb3964cbf1860372195634bcb3a14fa46d..26d645f9ae9b9748f71b6fa9061826ba6452581a 100644 (file)
@@ -784,41 +784,45 @@ SMTP(8)                                                                SMTP(8)
               How the Postfix SMTP and LMTP client will enforce REQUIRETLS for
               messages received with the REQUIRETLS option.
 
+       <b>smtp_log_tls_feature_status (yes)</b>
+              Enable  logging  of  TLS  feature information in delivery status
+              logging.
+
 <b><a name="obsolete_tls_controls">OBSOLETE TLS 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>
@@ -830,19 +834,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>
@@ -856,13 +860,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>
@@ -872,17 +876,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>
@@ -896,23 +900,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:
@@ -923,13 +927,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>.
 
@@ -937,54 +941,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>
@@ -992,46 +996,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>
@@ -1045,21 +1049,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>
@@ -1079,7 +1083,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:
@@ -1091,14 +1095,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:
@@ -1120,7 +1124,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 a9e03fe25fba1cfbf35b8f1b0f9fa59916c0181f..291fcf6f7125a300f5e69d06050fd1442e95239a 100644 (file)
@@ -12223,6 +12223,76 @@ and earlier.
 </p>
 
 
+</DD>
+
+<DT><b><a name="smtp_log_tls_feature_status">smtp_log_tls_feature_status</a>
+(default: yes)</b></DT><DD>
+
+<p> Enable logging of TLS feature information in delivery status
+logging. This summarizes how features such as TLS and REQUIRETLS
+were used. </p>
+
+<ul>
+
+<li> The logging is inserted between the "delays=a/b/c/d" and the
+"status=" information.
+
+<li> The general format is "tls=feature/feature/...". See below for
+examples.
+
+<li> The first feature name is the TLS security level: 'none',
+'may',' encrypt', ..., 'dane'. Other features are omitted if not
+activated. The REQUIRETLS extension's feature name will be 'requiretls'.
+
+<li> When 'disabled:' is prepended to a feature name, the remote server
+did not support this feature.
+
+<li> When the above is enclosed in "(" and ")", the feature was used
+successfully, but policy enforcement was relaxed.
+
+<li> When "!" is prepended to the above, the policy for that feature
+was not satisfied and the feature was not used..
+
+<li> When "?" is appended to the above, the policy for that feature
+is undecided, usually due to a lost connection.
+
+</ul>
+
+<p> Examples: </p>
+
+<dl>
+
+<dt> tls=none </dt> <dd> A connection that does not use TLS. </dd>
+
+<dt> tls=may </dt> <dd> Opportunistic TLS after a successful
+handshake. </dd>
+
+<dt> tls=(disabled:may) </dt> <dd> Opportunistic TLS after fallback
+to plaintext, because the server did not announce STARTTLS support
+or the server rejected the STARTTLS command. </dd>
+
+<dt> tls=dane </dt> <dd> DANE policy compliant, no downgrade. </dd>
+
+<dt> tls=(dane) </dt> <dd> Relaxed DANE after allowing MX records
+without DNSSEC signature, or after falling back to the TLS security
+level 'encrypt'. </dd>
+
+<dt> tls=dane/requiretls </dt> <dd> DANE and REQUIRETLS policies were
+fully enforced, non-error case. </dd>
+
+<dt> tls=dane?/requiretls? </dt> <dd> DANE and REQUIRETLS policies
+were undecided, because the connection failed before or in the TLS
+handshake. </dd>
+
+<dt> tls=may/(disabled:requiretls) </dt> <dd> Opportunistic TLS +
+opportunistic REQUIRETLS, server did not announce REQUIRETLS support.
+</dd>
+
+</dl>
+
+<p> This feature is available in Postfix 3.11 and later. </p>
+
+
 </DD>
 
 <DT><b><a name="smtp_mail_timeout">smtp_mail_timeout</a>
index c0ce2ddb3964cbf1860372195634bcb3a14fa46d..26d645f9ae9b9748f71b6fa9061826ba6452581a 100644 (file)
@@ -784,41 +784,45 @@ SMTP(8)                                                                SMTP(8)
               How the Postfix SMTP and LMTP client will enforce REQUIRETLS for
               messages received with the REQUIRETLS option.
 
+       <b>smtp_log_tls_feature_status (yes)</b>
+              Enable  logging  of  TLS  feature information in delivery status
+              logging.
+
 <b><a name="obsolete_tls_controls">OBSOLETE TLS 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>
@@ -830,19 +834,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>
@@ -856,13 +860,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>
@@ -872,17 +876,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>
@@ -896,23 +900,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:
@@ -923,13 +927,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>.
 
@@ -937,54 +941,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>
@@ -992,46 +996,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>
@@ -1045,21 +1049,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>
@@ -1079,7 +1083,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:
@@ -1091,14 +1095,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:
@@ -1120,7 +1124,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 e38135a80dd4aef6e1f5a896e26a73129a04b45c..e670cdf7e96ad2a2dc93a53244873c88924849ff 100644 (file)
@@ -7721,6 +7721,71 @@ The Postfix limit of 998 characters not including <CR><LF>
 is consistent with the SMTP limit of 1000 characters including
 <CR><LF>.  The Postfix limit was 990 with Postfix 2.8
 and earlier.
+.SH smtp_log_tls_feature_status (default: yes)
+Enable logging of TLS feature information in delivery status
+logging. This summarizes how features such as TLS and REQUIRETLS
+were used.
+.IP \(bu
+The logging is inserted between the "delays=a/b/c/d" and the
+"status=" information.
+.IP \(bu
+The general format is "tls=feature/feature/...". See below for
+examples.
+.IP \(bu
+The first feature name is the TLS security level: 'none',
+\&'may',' encrypt', ..., 'dane'. Other features are omitted if not
+activated. The REQUIRETLS extension's feature name will be 'requiretls'.
+.IP \(bu
+When 'disabled:' is prepended to a feature name, the remote server
+did not support this feature.
+.IP \(bu
+When the above is enclosed in "(" and ")", the feature was used
+successfully, but policy enforcement was relaxed.
+.IP \(bu
+When "!" is prepended to the above, the policy for that feature
+was not satisfied and the feature was not used..
+.IP \(bu
+When "?" is appended to the above, the policy for that feature
+is undecided, usually due to a lost connection.
+.br
+.PP
+Examples:
+.IP "tls=none"
+A connection that does not use TLS.
+.br
+.IP "tls=may"
+Opportunistic TLS after a successful
+handshake.
+.br
+.IP "tls=(disabled:may)"
+Opportunistic TLS after fallback
+to plaintext, because the server did not announce STARTTLS support
+or the server rejected the STARTTLS command.
+.br
+.IP "tls=dane"
+DANE policy compliant, no downgrade.
+.br
+.IP "tls=(dane)"
+Relaxed DANE after allowing MX records
+without DNSSEC signature, or after falling back to the TLS security
+level 'encrypt'.
+.br
+.IP "tls=dane/requiretls"
+DANE and REQUIRETLS policies were
+fully enforced, non\-error case.
+.br
+.IP "tls=dane?/requiretls?"
+DANE and REQUIRETLS policies
+were undecided, because the connection failed before or in the TLS
+handshake.
+.br
+.IP "tls=may/(disabled:requiretls)"
+Opportunistic TLS +
+opportunistic REQUIRETLS, server did not announce REQUIRETLS support.
+.br
+.br
+.PP
+This feature is available in Postfix 3.11 and later.
 .SH smtp_mail_timeout (default: 300s)
 The Postfix SMTP client time limit for sending the MAIL FROM command,
 and for receiving the remote SMTP server response.
index b12529b3edd883b94cb509cf57bba4bc61ff9f69..950ebd7b998ca2d9794afb6fbd3f2308f3c28246 100644 (file)
@@ -701,6 +701,9 @@ FROM" command.
 .IP "\fBsmtp_requiretls_policy (see 'postconf -d smtp_requiretls_policy' output)\fR"
 How the Postfix SMTP and LMTP client will enforce REQUIRETLS
 for messages received with the REQUIRETLS option.
+.IP "\fBsmtp_log_tls_feature_status (yes)\fR"
+Enable logging of TLS feature information in delivery status
+logging.
 .SH "OBSOLETE TLS CONTROLS"
 .na
 .nf
index a06248a7be1dec8ed0330f838125c14064e4dd88..65d1336b48e44117c22a7a72286393d461663a4a 100644 (file)
@@ -19866,6 +19866,71 @@ configuration parameter. See there for details. </p>
 
 <p> This feature is available in Postfix &ge; 3.11. </p>
 
+%PARAM smtp_log_tls_feature_status yes
+
+<p> Enable logging of TLS feature information in delivery status
+logging. This summarizes how features such as TLS and REQUIRETLS
+were used. </p>
+
+<ul>
+
+<li> The logging is inserted between the "delays=a/b/c/d" and the
+"status=" information. 
+
+<li> The general format is "tls=feature/feature/...". See below for
+examples.
+
+<li> The first feature name is the TLS security level: 'none',
+'may',' encrypt', ..., 'dane'. Other features are omitted if not
+activated. The REQUIRETLS extension's feature name will be 'requiretls'.
+
+<li> When 'disabled:' is prepended to a feature name, the remote server
+did not support this feature.
+
+<li> When the above is enclosed in "(" and ")", the feature was used
+successfully, but policy enforcement was relaxed.
+
+<li> When "!" is prepended to the above, the policy for that feature
+was not satisfied and the feature was not used..
+
+<li> When "?" is appended to the above, the policy for that feature 
+is undecided, usually due to a lost connection.
+
+</ul>
+
+<p> Examples: </p>
+
+<dl>
+
+<dt> tls=none </dt> <dd> A connection that does not use TLS. </dd>
+
+<dt> tls=may </dt> <dd> Opportunistic TLS after a successful
+handshake. </dd>
+
+<dt> tls=(disabled:may) </dt> <dd> Opportunistic TLS after fallback
+to plaintext, because the server did not announce STARTTLS support
+or the server rejected the STARTTLS command. </dd>
+
+<dt> tls=dane </dt> <dd> DANE policy compliant, no downgrade. </dd>
+
+<dt> tls=(dane) </dt> <dd> Relaxed DANE after allowing MX records
+without DNSSEC signature, or after falling back to the TLS security
+level 'encrypt'. </dd>
+
+<dt> tls=dane/requiretls </dt> <dd> DANE and REQUIRETLS policies were
+fully enforced, non-error case. </dd>
+
+<dt> tls=dane?/requiretls? </dt> <dd> DANE and REQUIRETLS policies
+were undecided, because the connection failed before or in the TLS
+handshake. </dd>
+
+<dt> tls=may/(disabled:requiretls) </dt> <dd> Opportunistic TLS +
+opportunistic REQUIRETLS, server did not announce REQUIRETLS support.
+</dd>
+
+</dl>
+
+<p> This feature is available in Postfix 3.11 and later. </p>
 %PARAM smtpd_hide_client_session no
 
 <p> Do not include SMTP client session information in the Postfix
index 1da83181c1c8df4cdca6da46d4af9898afea5a95..19f79fbcd9ccd35eafbe0cbc7316d422ea2b5a5b 100644 (file)
@@ -346,3 +346,4 @@ encoded  encoded text can contain only alpha digit
 ossl_digest_new  ossl_digest_new returns NULL after error ossl_digest_data 
  Richard Hansen rhansen rhansen org 
  long long or long integer 
+void  void tls_stats_revert TLS_STATS tstats 
index f22598cebbf0e57f127d1862c1a0b0ca0d0036d3..374d1516113d117c099f956d4e0e6a7c2b0e756c 100644 (file)
@@ -208,3 +208,8 @@ proto  proto COMPATIBILITY_README html
  smtp smtp h smtp smtp_params c smtp smtp_proto c 
  information Files sendmail sendmail c pickup pickup c 
  postcat postcat c showq showq c 
+ discard discard c error error c global Makefile in 
+ global verify c global verify h local local h 
+ pipe pipe c qmgr qmgr_bounce c qmgr qmgr_defer c 
+ qmgr qmgr_message c smtp smtp h smtp smtp_connect c 
+ smtp smtp_trouble c virtual virtual h 
index f0dd67d2c3fef2b32b41c7b065490aef412475ec..40bea178461dd53893e807b273fa9305147533ed 100644 (file)
@@ -366,3 +366,4 @@ Postfix  Postfix legacy TLS Support
  The recommended socket location is still to be determined A good socket location would be under the Postfix queue directory for example smtp_tlsrpt_socket_name run tlsrpt tlsrpt sock The advantage of using a relative name is that it
 enhanced status code and text format 45 number number text 
 opportunistic  opportunistic starttls
+ li The general format is tls feature feature 
index 02b3d46b4eb3609f85e275d5fa746ffd37038bb6..a87c1a5c71ffeb1a0b060933e6d64895b9dec773 100644 (file)
@@ -1874,3 +1874,5 @@ finalizer
 REQTLS
 reqtls
 Esmtp
+ENF
+tstats
index 8358d122785b0a976e6b8ea27f32a628255c441c..87de4cc62b4bbb21bd6efce38b260856a031de40 100644 (file)
@@ -75,7 +75,7 @@ static void cleanup_bounce_append(CLEANUP_STATE *state, RECIPIENT *rcpt,
      */
     if (bounce_append(BOUNCE_FLAG_CLEAN, state->queue_id,
                      CLEANUP_MSG_STATS(&stats, state),
-                     rcpt, "none", dsn) != 0) {
+                     rcpt, "none", NO_TLS_STATS, dsn) != 0) {
        state->errs |= CLEANUP_STAT_WRITE;
     }
 }
index 003983b71920008699df2bd07d12557b092201e8..e4b059116d6724a8c1af77216754028bd5a65c8b 100644 (file)
@@ -104,7 +104,7 @@ static void cleanup_trace_append(CLEANUP_STATE *state, RECIPIENT *rcpt,
     }
     if (trace_append(BOUNCE_FLAG_CLEAN, state->queue_id,
                     CLEANUP_MSG_STATS(&stats, state),
-                    rcpt, "none", dsn) != 0) {
+                    rcpt, "none", NO_TLS_STATS, dsn) != 0) {
        msg_warn("%s: trace logfile update error", state->queue_id);
        state->errs |= CLEANUP_STAT_WRITE;
     }
@@ -118,7 +118,7 @@ static void cleanup_verify_append(CLEANUP_STATE *state, RECIPIENT *rcpt,
     MSG_STATS stats;
 
     if (verify_append(state->queue_id, CLEANUP_MSG_STATS(&stats, state),
-                     rcpt, "none", dsn, verify_status) != 0) {
+                     rcpt, "none", NO_TLS_STATS, dsn, verify_status) != 0) {
        msg_warn("%s: verify service update error", state->queue_id);
        state->errs |= CLEANUP_STAT_WRITE;
     }
index f21b95cbc36d2f0c7b938c214adbf392ef40d3c7..43b728a9c077b1737c1ac0eef66ca98ed60cc85d 100644 (file)
@@ -186,7 +186,8 @@ static int deliver_message(DELIVER_REQUEST *request)
     for (nrcpt = 0; nrcpt < request->rcpt_list.len; nrcpt++) {
        rcpt = request->rcpt_list.info + nrcpt;
        status = sent(BOUNCE_FLAGS(request), request->queue_id,
-                     &request->msg_stats, rcpt, "none", &dsn);
+                     &request->msg_stats, rcpt, "none", 
+                     NO_TLS_STATS, &dsn);
        if (status == 0 && (request->flags & DEL_REQ_FLAG_SUCCESS))
            deliver_completed(src, rcpt->offset);
        result |= status;
index e1ff1cb7ccafc1be4279d6add1f86988f9db59aa..a1f70d6626248486a648c503c6802bddb6bf57eb 100644 (file)
 
 static int deliver_message(DELIVER_REQUEST *request, const char *def_dsn,
                 int (*append) (int, const char *, MSG_STATS *, RECIPIENT *,
-                                       const char *, DSN *))
+                                       const char *, const TLS_STATS *, DSN *))
 {
     const char *myname = "deliver_message";
     VSTREAM *src;
@@ -194,7 +194,8 @@ static int deliver_message(DELIVER_REQUEST *request, const char *def_dsn,
     for (nrcpt = 0; nrcpt < request->rcpt_list.len; nrcpt++) {
        rcpt = request->rcpt_list.info + nrcpt;
        status = append(BOUNCE_FLAGS(request), request->queue_id,
-                       &request->msg_stats, rcpt, "none", &dsn);
+                       &request->msg_stats, rcpt, "none", NO_TLS_STATS,
+                       &dsn);
        if (status == 0)
            deliver_completed(src, rcpt->offset);
        result |= status;
index cc7086cfa95b69eec75574c4095c712df17cc62e..7a1034cd051f5644840254482b32e782d9204668 100644 (file)
@@ -37,7 +37,8 @@ SRCS  = abounce.c anvil_clnt.c been_here.c bounce.c bounce_log.c \
        normalize_mailhost_addr.c map_search.c reject_deliver_request.c \
        info_log_addr_form.c sasl_mech_filter.c login_sender_match.c \
        test_main.c compat_level.c config_known_tcp_ports.c \
-       hfrom_format.c rfc2047_code.c ascii_header_text.c sendopts.c
+       hfrom_format.c rfc2047_code.c ascii_header_text.c sendopts.c \
+       tls_stats.c
 OBJS   = abounce.o anvil_clnt.o been_here.o bounce.o bounce_log.o \
        canon_addr.o cfg_parser.o cleanup_strerror.o cleanup_strflags.o \
        clnt_stream.o conv_time.o db_common.o debug_peer.o debug_process.o \
@@ -76,7 +77,8 @@ OBJS  = abounce.o anvil_clnt.o been_here.o bounce.o bounce_log.o \
        normalize_mailhost_addr.o map_search.o reject_deliver_request.o \
        info_log_addr_form.o sasl_mech_filter.o login_sender_match.o \
        test_main.o compat_level.o config_known_tcp_ports.o \
-       hfrom_format.o rfc2047_code.o ascii_header_text.o sendopts.o
+       hfrom_format.o rfc2047_code.o ascii_header_text.o sendopts.o \
+       tls_stats.o
 # MAP_OBJ is for maps that may be dynamically loaded with dynamicmaps.cf.
 # When hard-linking these maps, makedefs sets NON_PLUGIN_MAP_OBJ=$(MAP_OBJ),
 # otherwise it sets the PLUGIN_* macros.
@@ -113,7 +115,8 @@ HDRS        = abounce.h anvil_clnt.h been_here.h bounce.h bounce_log.h \
        maillog_client.h normalize_mailhost_addr.h map_search.h \
        info_log_addr_form.h sasl_mech_filter.h login_sender_match.h \
        test_main.h compat_level.h config_known_tcp_ports.h \
-       hfrom_format.h rfc2047_code.h ascii_header_text.h sendopts.h
+       hfrom_format.h rfc2047_code.h ascii_header_text.h sendopts.h \
+       tls_stats.h
 TESTSRC        = rec2stream.c stream2rec.c recdump.c
 DEFS   = -I. -I$(INC_DIR) -D$(SYSTYPE)
 CFLAGS = $(DEBUG) $(OPT) $(DEFS)
@@ -836,6 +839,7 @@ abounce.o: mail_params.h
 abounce.o: mail_proto.h
 abounce.o: msg_stats.h
 abounce.o: recipient_list.h
+abounce.o: tls_stats.h
 addr_match_list.o: ../../include/argv.h
 addr_match_list.o: ../../include/check_arg.h
 addr_match_list.o: ../../include/match_list.h
@@ -919,6 +923,7 @@ bounce.o: mail_proto.h
 bounce.o: msg_stats.h
 bounce.o: rcpt_print.h
 bounce.o: recipient_list.h
+bounce.o: tls_stats.h
 bounce.o: trace.h
 bounce.o: verify.h
 bounce_log.o: ../../include/attr.h
@@ -1109,6 +1114,7 @@ defer.o: mail_queue.h
 defer.o: msg_stats.h
 defer.o: rcpt_print.h
 defer.o: recipient_list.h
+defer.o: tls_stats.h
 defer.o: trace.h
 defer.o: verify.h
 deliver_completed.o: ../../include/check_arg.h
@@ -1156,6 +1162,7 @@ deliver_pass.o: mail_proto.h
 deliver_pass.o: msg_stats.h
 deliver_pass.o: rcpt_print.h
 deliver_pass.o: recipient_list.h
+deliver_pass.o: tls_stats.h
 deliver_request.o: ../../include/attr.h
 deliver_request.o: ../../include/check_arg.h
 deliver_request.o: ../../include/htable.h
@@ -1668,6 +1675,7 @@ log_adhoc.o: log_adhoc.h
 log_adhoc.o: mail_params.h
 log_adhoc.o: msg_stats.h
 log_adhoc.o: recipient_list.h
+log_adhoc.o: tls_stats.h
 login_sender_match.o: ../../include/argv.h
 login_sender_match.o: ../../include/check_arg.h
 login_sender_match.o: ../../include/dict.h
@@ -2574,9 +2582,11 @@ reject_deliver_request.o: deliver_completed.h
 reject_deliver_request.o: deliver_request.h
 reject_deliver_request.o: dsn.h
 reject_deliver_request.o: dsn_buf.h
+reject_deliver_request.o: mail_params.h
 reject_deliver_request.o: msg_stats.h
 reject_deliver_request.o: recipient_list.h
 reject_deliver_request.o: reject_deliver_request.c
+reject_deliver_request.o: tls_stats.h
 remove.o: ../../include/check_arg.h
 remove.o: ../../include/sys_defs.h
 remove.o: ../../include/vbuf.h
@@ -2762,6 +2772,7 @@ sent.o: msg_stats.h
 sent.o: recipient_list.h
 sent.o: sent.c
 sent.o: sent.h
+sent.o: tls_stats.h
 sent.o: trace.h
 sent.o: verify.h
 server_acl.o: ../../include/argv.h
@@ -2887,6 +2898,12 @@ timed_ipc.o: ../../include/vstream.h
 timed_ipc.o: mail_params.h
 timed_ipc.o: timed_ipc.c
 timed_ipc.o: timed_ipc.h
+tls_stats.o: ../../include/msg.h
+tls_stats.o: ../../include/mymalloc.h
+tls_stats.o: ../../include/sys_defs.h
+tls_stats.o: mail_params.h
+tls_stats.o: tls_stats.c
+tls_stats.o: tls_stats.h
 tok822_find.o: ../../include/check_arg.h
 tok822_find.o: ../../include/sys_defs.h
 tok822_find.o: ../../include/vbuf.h
@@ -2968,6 +2985,7 @@ trace.o: mail_proto.h
 trace.o: msg_stats.h
 trace.o: rcpt_print.h
 trace.o: recipient_list.h
+trace.o: tls_stats.h
 trace.o: trace.c
 trace.o: trace.h
 user_acl.o: ../../include/argv.h
@@ -3016,6 +3034,7 @@ verify.o: mail_params.h
 verify.o: mail_proto.h
 verify.o: msg_stats.h
 verify.o: recipient_list.h
+verify.o: tls_stats.h
 verify.o: verify.c
 verify.o: verify.h
 verify.o: verify_clnt.h
index a11ee7da86d39d52541c86b160d64c631ca2ad4f..47cbc9718c7ad66b9cbef7ab7ac3016faccee025 100644 (file)
@@ -6,12 +6,13 @@
 /* SYNOPSIS
 /*     #include <bounce.h>
 /*
-/*     int     bounce_append(flags, id, stats, recipient, relay, dsn)
+/*     int     bounce_append(flags, id, stats, recipient, relay, tstats, dsn)
 /*     int     flags;
 /*     const char *id;
 /*     MSG_STATS *stats;
 /*     RECIPIENT *rcpt;
 /*     const char *relay;
+/*     const TLS_STATS *tstats;
 /*     DSN     *dsn;
 /*
 /*     int     bounce_flush(flags, queue, id, encoding, sendopts, sender,
@@ -38,7 +39,8 @@
 /*     const char *verp_delims;
 /*
 /*     int     bounce_one(flags, queue, id, encoding, sendopts, sender,
-/*                             dsn_envid, ret, stats, recipient, relay, dsn)
+/*                             dsn_envid, ret, stats, recipient, relay,
+/*                             tstats, dsn)
 /*     int     flags;
 /*     const char *queue;
 /*     const char *id;
@@ -50,6 +52,7 @@
 /*     MSG_STATS *stats;
 /*     RECIPIENT *rcpt;
 /*     const char *relay;
+/*     const TLS_STATS *tstats;
 /*     DSN     *dsn;
 /*
 /*     void    bounce_client_init(title, maps)
 /* INTERNAL API
 /*     DSN_FILTER *delivery_status_filter;
 /*
-/*     int     bounce_append_intern(flags, id, stats, recipient, relay, dsn)
+/*     int     bounce_append_intern(flags, id, stats, recipient, relay, tstats, dsn)
 /*     int     flags;
 /*     const char *id;
 /*     MSG_STATS *stats;
 /*     RECIPIENT *rcpt;
 /*     const char *relay;
+/*     const TLS_STATS *tstats;
+/*     DSN     *dsn;
 /*
 /*     int     bounce_one_intern(flags, queue, id, encoding, sendopts, sender,
-/*                             dsn_envid, ret, stats, recipient, relay, dsn)
+/*                     dsn_envid, ret, stats, recipient, relay, tstats, dsn)
 /*     int     flags;
 /*     const char *queue;
 /*     const char *id;
@@ -78,6 +83,7 @@
 /*     MSG_STATS *stats;
 /*     RECIPIENT *rcpt;
 /*     const char *relay;
+/*     const TLS_STATS *tstats;
 /*     DSN     *dsn;
 /* DESCRIPTION
 /*     This module implements the client interface to the message
 /*     Sender-requested SMTPUTF8 or RequireTLS support.
 /* .IP sender
 /*     The sender envelope address.
+/* .IP tstats
+/*     TLS per-feature status.
 /* .IP dsn_envid
 /*     Optional DSN envelope ID.
 /* .IP dsn_ret
@@ -229,7 +237,7 @@ DSN_FILTER *delivery_status_filter;
 
 int     bounce_append(int flags, const char *id, MSG_STATS *stats,
                              RECIPIENT *rcpt, const char *relay,
-                             DSN *dsn)
+                             const TLS_STATS *tstats, DSN *dsn)
 {
     DSN     my_dsn = *dsn;
     DSN    *dsn_res;
@@ -249,17 +257,19 @@ int     bounce_append(int flags, const char *id, MSG_STATS *stats,
     if (delivery_status_filter != 0
     && (dsn_res = dsn_filter_lookup(delivery_status_filter, &my_dsn)) != 0) {
        if (dsn_res->status[0] == '4')
-           return (defer_append_intern(flags, id, stats, rcpt, relay, dsn_res));
+           return (defer_append_intern(flags, id, stats, rcpt, relay, tstats,
+                                       dsn_res));
        my_dsn = *dsn_res;
     }
-    return (bounce_append_intern(flags, id, stats, rcpt, relay, &my_dsn));
+    return (bounce_append_intern(flags, id, stats, rcpt, relay, tstats,
+                                &my_dsn));
 }
 
 /* bounce_append_intern - append delivery status to per-message bounce log */
 
 int     bounce_append_intern(int flags, const char *id, MSG_STATS *stats,
                                     RECIPIENT *rcpt, const char *relay,
-                                    DSN *dsn)
+                                    const TLS_STATS *tstats, DSN *dsn)
 {
     DSN     my_dsn = *dsn;
     int     status;
@@ -270,7 +280,7 @@ int     bounce_append_intern(int flags, const char *id, MSG_STATS *stats,
      */
     if (flags & DEL_REQ_FLAG_MTA_VRFY) {
        my_dsn.action = "undeliverable";
-       status = verify_append(id, stats, rcpt, relay, &my_dsn,
+       status = verify_append(id, stats, rcpt, relay, tstats, &my_dsn,
                               DEL_RCPT_STAT_BOUNCE);
        return (status);
     }
@@ -281,7 +291,7 @@ int     bounce_append_intern(int flags, const char *id, MSG_STATS *stats,
      */
     if (flags & DEL_REQ_FLAG_USR_VRFY) {
        my_dsn.action = "undeliverable";
-       status = trace_append(flags, id, stats, rcpt, relay, &my_dsn);
+       status = trace_append(flags, id, stats, rcpt, relay, tstats, &my_dsn);
        return (status);
     }
 
@@ -326,9 +336,9 @@ int     bounce_append_intern(int flags, const char *id, MSG_STATS *stats,
                          SEND_ATTR_FUNC(dsn_print, (const void *) &my_dsn),
                                ATTR_TYPE_END) == 0
            && ((flags & DEL_REQ_FLAG_RECORD) == 0
-               || trace_append(flags, id, stats, rcpt, relay,
+               || trace_append(flags, id, stats, rcpt, relay, tstats,
                                &my_dsn) == 0)) {
-           log_adhoc(id, stats, rcpt, relay, &my_dsn, log_status);
+           log_adhoc(id, stats, rcpt, relay, tstats, &my_dsn, log_status);
            status = (var_soft_bounce ? -1 : 0);
        } else if ((flags & BOUNCE_FLAG_CLEAN) == 0) {
            VSTRING *junk = vstring_alloc(100);
@@ -337,7 +347,8 @@ int     bounce_append_intern(int flags, const char *id, MSG_STATS *stats,
            vstring_sprintf(junk, "%s or %s service failure",
                            var_bounce_service, var_trace_service);
            my_dsn.reason = vstring_str(junk);
-           status = defer_append_intern(flags, id, stats, rcpt, relay, &my_dsn);
+           status = defer_append_intern(flags, id, stats, rcpt, relay, tstats,
+                                        &my_dsn);
            vstring_free(junk);
        } else {
            status = -1;
@@ -424,7 +435,7 @@ int     bounce_one(int flags, const char *queue, const char *id,
                           const char *encoding, int sendopts,
                           const char *sender, const char *dsn_envid,
                           int dsn_ret, MSG_STATS *stats, RECIPIENT *rcpt,
-                          const char *relay, DSN *dsn)
+                      const char *relay, const TLS_STATS *tstats, DSN *dsn)
 {
     DSN     my_dsn = *dsn;
     DSN    *dsn_res;
@@ -443,11 +454,13 @@ int     bounce_one(int flags, const char *queue, const char *id,
     if (delivery_status_filter != 0
     && (dsn_res = dsn_filter_lookup(delivery_status_filter, &my_dsn)) != 0) {
        if (dsn_res->status[0] == '4')
-           return (defer_append_intern(flags, id, stats, rcpt, relay, dsn_res));
+           return (defer_append_intern(flags, id, stats, rcpt, relay, tstats,
+                                       dsn_res));
        my_dsn = *dsn_res;
     }
     return (bounce_one_intern(flags, queue, id, encoding, sendopts, sender,
-                         dsn_envid, dsn_ret, stats, rcpt, relay, &my_dsn));
+                             dsn_envid, dsn_ret, stats, rcpt, relay, tstats,
+                             &my_dsn));
 }
 
 /* bounce_one_intern - send notice for one recipient */
@@ -457,7 +470,7 @@ int     bounce_one_intern(int flags, const char *queue, const char *id,
                                  const char *sender, const char *dsn_envid,
                                  int dsn_ret, MSG_STATS *stats,
                                  RECIPIENT *rcpt, const char *relay,
-                                 DSN *dsn)
+                                 const TLS_STATS *tstats, DSN *dsn)
 {
     DSN     my_dsn = *dsn;
     int     status;
@@ -468,7 +481,7 @@ int     bounce_one_intern(int flags, const char *queue, const char *id,
      */
     if (flags & DEL_REQ_FLAG_MTA_VRFY) {
        my_dsn.action = "undeliverable";
-       status = verify_append(id, stats, rcpt, relay, &my_dsn,
+       status = verify_append(id, stats, rcpt, relay, tstats, &my_dsn,
                               DEL_RCPT_STAT_BOUNCE);
        return (status);
     }
@@ -479,7 +492,7 @@ int     bounce_one_intern(int flags, const char *queue, const char *id,
      */
     if (flags & DEL_REQ_FLAG_USR_VRFY) {
        my_dsn.action = "undeliverable";
-       status = trace_append(flags, id, stats, rcpt, relay, &my_dsn);
+       status = trace_append(flags, id, stats, rcpt, relay, tstats, &my_dsn);
        return (status);
     }
 
@@ -488,7 +501,8 @@ int     bounce_one_intern(int flags, const char *queue, const char *id,
      * based procedure.
      */
     else if (var_soft_bounce) {
-       return (bounce_append_intern(flags, id, stats, rcpt, relay, &my_dsn));
+       return (bounce_append_intern(flags, id, stats, rcpt, relay, tstats,
+                                    &my_dsn));
     }
 
     /*
@@ -519,9 +533,9 @@ int     bounce_one_intern(int flags, const char *queue, const char *id,
                          SEND_ATTR_FUNC(dsn_print, (const void *) &my_dsn),
                                ATTR_TYPE_END) == 0
            && ((flags & DEL_REQ_FLAG_RECORD) == 0
-               || trace_append(flags, id, stats, rcpt, relay,
+               || trace_append(flags, id, stats, rcpt, relay, tstats,
                                &my_dsn) == 0)) {
-           log_adhoc(id, stats, rcpt, relay, &my_dsn, "bounced");
+           log_adhoc(id, stats, rcpt, relay, tstats, &my_dsn, "bounced");
            status = 0;
        } else if ((flags & BOUNCE_FLAG_CLEAN) == 0) {
            VSTRING *junk = vstring_alloc(100);
@@ -530,7 +544,8 @@ int     bounce_one_intern(int flags, const char *queue, const char *id,
            vstring_sprintf(junk, "%s or %s service failure",
                            var_bounce_service, var_trace_service);
            my_dsn.reason = vstring_str(junk);
-           status = defer_append_intern(flags, id, stats, rcpt, relay, &my_dsn);
+           status = defer_append_intern(flags, id, stats, rcpt, relay, tstats,
+                                        &my_dsn);
            vstring_free(junk);
        } else {
            status = -1;
index e2d67bd3a86c2a44c9830fe8063efedb935065e9..7e99aab7587b945f36139ae9633ae2654855df53 100644 (file)
   */
 #include <deliver_request.h>
 #include <dsn_buf.h>
+#include <tls_stats.h>
 
  /*
   * Client interface.
   */
 extern int bounce_append(int, const char *, MSG_STATS *, RECIPIENT *,
-                                const char *, DSN *);
+                                const char *, const TLS_STATS *, DSN *);
 extern int bounce_flush(int, const char *, const char *, const char *, int,
                                const char *, const char *, int);
 extern int bounce_flush_verp(int, const char *, const char *, const char *, int,
@@ -34,7 +35,7 @@ extern int bounce_flush_verp(int, const char *, const char *, const char *, int,
 extern int bounce_one(int, const char *, const char *, const char *, int,
                              const char *, const char *,
                              int, MSG_STATS *, RECIPIENT *,
-                             const char *, DSN *);
+                             const char *, const TLS_STATS *, DSN *);
 extern void bounce_client_init(const char *, const char *);
 
  /*
@@ -77,11 +78,11 @@ extern void bounce_client_init(const char *, const char *);
 extern DSN_FILTER *delivery_status_filter;
 
 extern int bounce_append_intern(int, const char *, MSG_STATS *, RECIPIENT *,
-                                       const char *, DSN *);
+                                   const char *, const TLS_STATS *, DSN *);
 extern int bounce_one_intern(int, const char *, const char *, const char *,
                                     int, const char *, const char *,
                                     int, MSG_STATS *, RECIPIENT *,
-                                    const char *, DSN *);
+                                    const char *, const TLS_STATS *, DSN *);
 
 #endif
 
@@ -94,6 +95,9 @@ extern int bounce_one_intern(int, const char *, const char *, const char *,
 /*     IBM T.J. Watson Research
 /*     P.O. Box 704
 /*     Yorktown Heights, NY 10598, USA
+/*
+/*     Wietse Venema
+/*     porcupine.org
 /*--*/
 
 #endif
index 919484d63d6db60d4c0d588c97075d0a947d04c5..8c1a17b3e81d3897875de6760cf29149e883a6cb 100644 (file)
@@ -6,12 +6,13 @@
 /* SYNOPSIS
 /*     #include <defer.h>
 /*
-/*     int     defer_append(flags, id, stats, rcpt, relay, dsn)
+/*     int     defer_append(flags, id, stats, rcpt, relay, tstats, dsn)
 /*     int     flags;
 /*     const char *id;
 /*     MSG_STATS *stats;
 /*     RECIPIENT *rcpt;
 /*     const char *relay;
+/*     const TLS_STATS *tstats;
 /*     DSN     *dsn;
 /*
 /*     int     defer_flush(flags, queue, id, encoding, sendopts, sender,
@@ -37,7 +38,8 @@
 /*     int     dsn_ret;
 /*
 /*     int     defer_one(flags, queue, id, encoding, sendopts, sender,
-/*                             dsn_envid, ret, stats, recipient, relay, dsn)
+/*                             dsn_envid, ret, stats, recipient, relay,
+/*                             tstats, dsn)
 /*     int     flags;
 /*     const char *queue;
 /*     const char *id;
 /*     MSG_STATS *stats;
 /*     RECIPIENT *rcpt;
 /*     const char *relay;
+/*     const TLS_STATS *tstats;
 /*     DSN     *dsn;
 /* INTERNAL API
-/*     int     defer_append_intern(flags, id, stats, rcpt, relay, dsn)
+/*     int     defer_append_intern(flags, id, stats, rcpt, relay, tstats, dsn)
 /*     int     flags;
 /*     const char *id;
 /*     MSG_STATS *stats;
 /*     RECIPIENT *rcpt;
 /*     const char *relay;
+/*     const TLS_STATS *tstats;
+/*     DSN     *dsn;
 /* DESCRIPTION
 /*     This module implements a client interface to the defer service,
 /*     which maintains a per-message logfile with status records for
 /*     Recipient information. See recipient_list(3).
 /* .IP relay
 /*     Host we could not talk to.
+/* .IP tstats
+/*     TLS per-feature status.
 /* .IP dsn
 /*     Delivery status. See dsn(3). The specified action is ignored.
 /* .IP encoding
 
 int     defer_append(int flags, const char *id, MSG_STATS *stats,
                             RECIPIENT *rcpt, const char *relay,
-                            DSN *dsn)
+                            const TLS_STATS *tstats, DSN *dsn)
 {
     DSN     my_dsn = *dsn;
     DSN    *dsn_res;
@@ -213,17 +220,19 @@ int     defer_append(int flags, const char *id, MSG_STATS *stats,
     if (delivery_status_filter != 0
     && (dsn_res = dsn_filter_lookup(delivery_status_filter, &my_dsn)) != 0) {
        if (dsn_res->status[0] == '5')
-           return (bounce_append_intern(flags, id, stats, rcpt, relay, dsn_res));
+           return (bounce_append_intern(flags, id, stats, rcpt, relay, tstats,
+                                        dsn_res));
        my_dsn = *dsn_res;
     }
-    return (defer_append_intern(flags, id, stats, rcpt, relay, &my_dsn));
+    return (defer_append_intern(flags, id, stats, rcpt, relay, tstats,
+                               &my_dsn));
 }
 
 /* defer_append_intern - defer message delivery */
 
 int     defer_append_intern(int flags, const char *id, MSG_STATS *stats,
                                    RECIPIENT *rcpt, const char *relay,
-                                   DSN *dsn)
+                                   const TLS_STATS *tstats, DSN *dsn)
 {
     const char *rcpt_domain;
     DSN     my_dsn = *dsn;
@@ -235,7 +244,7 @@ int     defer_append_intern(int flags, const char *id, MSG_STATS *stats,
      */
     if (flags & DEL_REQ_FLAG_MTA_VRFY) {
        my_dsn.action = "undeliverable";
-       status = verify_append(id, stats, rcpt, relay, &my_dsn,
+       status = verify_append(id, stats, rcpt, relay, tstats, &my_dsn,
                               DEL_RCPT_STAT_DEFER);
        return (status);
     }
@@ -246,7 +255,7 @@ int     defer_append_intern(int flags, const char *id, MSG_STATS *stats,
      */
     if (flags & DEL_REQ_FLAG_USR_VRFY) {
        my_dsn.action = "undeliverable";
-       status = trace_append(flags, id, stats, rcpt, relay, &my_dsn);
+       status = trace_append(flags, id, stats, rcpt, relay, tstats, &my_dsn);
        return (status);
     }
 
@@ -273,13 +282,14 @@ int     defer_append_intern(int flags, const char *id, MSG_STATS *stats,
                          SEND_ATTR_FUNC(dsn_print, (const void *) &my_dsn),
                                ATTR_TYPE_END) != 0)
            msg_warn("%s: %s service failure", id, var_defer_service);
-       log_adhoc(id, stats, rcpt, relay, &my_dsn, "deferred");
+       log_adhoc(id, stats, rcpt, relay, tstats, &my_dsn, "deferred");
 
        /*
         * Traced delivery.
         */
        if (flags & DEL_REQ_FLAG_RECORD)
-           if (trace_append(flags, id, stats, rcpt, relay, &my_dsn) != 0)
+           if (trace_append(flags, id, stats, rcpt, relay, tstats,
+                            &my_dsn) != 0)
                msg_warn("%s: %s service failure", id, var_trace_service);
 
        /*
@@ -358,7 +368,7 @@ int     defer_one(int flags, const char *queue, const char *id,
                          const char *encoding, int sendopts,
                          const char *sender, const char *dsn_envid,
                          int dsn_ret, MSG_STATS *stats, RECIPIENT *rcpt,
-                         const char *relay, DSN *dsn)
+                      const char *relay, const TLS_STATS *tstats, DSN *dsn)
 {
     DSN     my_dsn = *dsn;
     DSN    *dsn_res;
@@ -379,8 +389,9 @@ int     defer_one(int flags, const char *queue, const char *id,
        if (dsn_res->status[0] == '5')
            return (bounce_one_intern(flags, queue, id, encoding, sendopts,
                                      sender, dsn_envid, dsn_ret, stats,
-                                     rcpt, relay, dsn_res));
+                                     rcpt, relay, tstats, dsn_res));
        my_dsn = *dsn_res;
     }
-    return (defer_append_intern(flags, id, stats, rcpt, relay, &my_dsn));
+    return (defer_append_intern(flags, id, stats, rcpt, relay, tstats,
+                               &my_dsn));
 }
index a015052f5da1ca073eee5556053d4a7d52d572e1..c0e93b7f6193cc275740b9386dfb0d4eccf73a31 100644 (file)
@@ -20,7 +20,7 @@
   * External interface.
   */
 extern int defer_append(int, const char *, MSG_STATS *, RECIPIENT *,
-                               const char *, DSN *);
+                               const char *, const TLS_STATS *, DSN *);
 extern int defer_flush(int, const char *, const char *, const char *, int,
                               const char *, const char *, int);
 extern int defer_warn(int, const char *, const char *, const char *, int,
@@ -28,7 +28,7 @@ extern int defer_warn(int, const char *, const char *, const char *, int,
 extern int defer_one(int, const char *, const char *, const char *, int,
                             const char *, const char *,
                             int, MSG_STATS *, RECIPIENT *,
-                            const char *, DSN *);
+                            const char *, const TLS_STATS *, DSN *);
 
  /*
   * Start of private API.
@@ -36,7 +36,7 @@ extern int defer_one(int, const char *, const char *, const char *, int,
 #ifdef DSN_INTERN
 
 extern int defer_append_intern(int, const char *, MSG_STATS *, RECIPIENT *,
-                                      const char *, DSN *);
+                                   const char *, const TLS_STATS *, DSN *);
 
 #endif
 
@@ -49,6 +49,9 @@ extern int defer_append_intern(int, const char *, MSG_STATS *, RECIPIENT *,
 /*     IBM T.J. Watson Research
 /*     P.O. Box 704
 /*     Yorktown Heights, NY 10598, USA
+/*
+/*     Wietse Venema
+/*     porcupine.org
 /*--*/
 
 #endif
index 5452829459886094dc2b08fc62764ac792b22971..111e51865e208a7e6ab7b762643a2155aa53311b 100644 (file)
@@ -210,13 +210,13 @@ int     deliver_pass(const char *class, const char *service,
        (void) DSN_SIMPLE(&dsn, "4.3.0", "mail transport unavailable");
        status = defer_append(DEL_REQ_TRACE_FLAGS(request->flags),
                              request->queue_id, &request->msg_stats,
-                             rcpt, "none", &dsn);
+                             rcpt, "none", NO_TLS_STATS, &dsn);
     } else if ((status = deliver_pass_final_reply(stream, dsb))
               == DELIVER_PASS_UNKNOWN) {
        (void) DSN_SIMPLE(&dsn, "4.3.0", "unknown mail transport error");
        status = defer_append(DEL_REQ_TRACE_FLAGS(request->flags),
                              request->queue_id, &request->msg_stats,
-                             rcpt, "none", &dsn);
+                             rcpt, "none", NO_TLS_STATS, &dsn);
     }
 
     /*
index e00e93054e48a948f75baea2737cc4f481ef6276..58d281dddb76b1eefad3881808c0f7e917bbb01e 100644 (file)
@@ -6,11 +6,12 @@
 /* SYNOPSIS
 /*     #include <log_adhoc.h>
 /*
-/*     void    log_adhoc(id, stats, recipient, relay, dsn, status)
+/*     void    log_adhoc(id, stats, recipient, relay, tstats, dsn, status)
 /*     const char *id;
 /*     MSG_STATS *stats;
 /*     RECIPIENT *recipient;
 /*     const char *relay;
+/*     const TLS_STATS *tstats;
 /*     DSN *dsn;
 /*     const char *status;
 /* DESCRIPTION
@@ -33,6 +34,8 @@
 /*     Host we could (not) talk to.
 /* .IP status
 /*     bounced, deferred, sent, and so on.
+/* .IP tstats
+/*     TLS per-feature status.
 /* .IP dsn
 /*     Delivery status information. See dsn(3).
 /* BUGS
@@ -52,6 +55,9 @@
 /*     Google, Inc.
 /*     111 8th Avenue
 /*     New York, NY 10011, USA
+/*
+/*     Wietse Venema
+/*     porcupine.org
 /*--*/
 
 /* System library. */
@@ -71,6 +77,7 @@
 #include <log_adhoc.h>
 #include <mail_params.h>
 #include <info_log_addr_form.h>
+#include <tls_stats.h>
 
  /*
   * Don't use "struct timeval" for time differences; use explicit signed
@@ -85,8 +92,8 @@ typedef struct {
 /* log_adhoc - ad-hoc logging */
 
 void    log_adhoc(const char *id, MSG_STATS *stats, RECIPIENT *recipient,
-                         const char *relay, DSN *dsn,
-                         const char *status)
+                         const char *relay, const TLS_STATS *tstats,
+                         DSN *dsn, const char *status)
 {
     static VSTRING *buf;
     DELTA_TIME delay;                  /* end-to-end delay */
@@ -140,6 +147,8 @@ void    log_adhoc(const char *id, MSG_STATS *stats, RECIPIENT *recipient,
      * 
      * XXX Apparently, Solaris gettimeofday() can return out-of-range
      * microsecond values.
+     * 
+     * TODO(wietse) move this to msg_stats.c
      */
 #define DELTA(x, y, z) \
     do { \
@@ -208,6 +217,41 @@ void    log_adhoc(const char *id, MSG_STATS *stats, RECIPIENT *recipient,
     PRETTY_FORMAT(buf, "/", sdelay);
     PRETTY_FORMAT(buf, "/", xdelay);
 
+    /*
+     * Optional: TLS per-feature status summary. TODO(wietse) move this to
+     * tls_stats.c.
+     */
+#ifdef USE_TLS
+    if (tstats && tls_stats_used(tstats)) {
+       int     idx;
+       const TLS_STAT *tstat;
+       int     field_count = 0;
+       const char *if_disabled[2] = {"", "disabled:"};
+
+#define RELAXED(tstat) ((tstat)->enforce == TLS_STAT_ENF_RELAXED)
+#define DISABLED(tstat) ((tstat)->status == TLS_STAT_DISABLED)
+
+       vstring_sprintf_append(buf, ", tls=");
+       for (idx = 0; idx < TLS_STATS_SIZE; idx++) {
+           tstat = tls_stat_access(tstats, idx);
+           if (tstat->status == TLS_STAT_INACTIVE)
+               continue;
+           if (field_count > 0)
+               vstring_strcat(buf, "/");
+           if (tstat->status == TLS_STAT_VIOLATION)
+               vstring_strcat(buf, "!");
+           vstring_sprintf_append(buf, "%s%s%s%s",
+                                  "(" + !RELAXED(tstat),
+                                  if_disabled[DISABLED(tstat)],
+                                  tstat->name,
+                                  ")" + !RELAXED(tstat));
+           if (tstat->status == TLS_STAT_UNDECIDED)
+               vstring_strcat(buf, "?");
+           field_count += 1;
+       }
+    }
+#endif
+
     /*
      * Finally, the delivery status.
      */
index 583cb6122b2b976355fc1e9add6341dc6639e63a..cb691a120906198c51796e0bd133cff41466c49b 100644 (file)
 #include <recipient_list.h>
 #include <dsn.h>
 #include <msg_stats.h>
+#include <tls_stats.h>
 
  /*
   * Client interface.
   */
 extern void log_adhoc(const char *, MSG_STATS *, RECIPIENT *, const char *,
-                             DSN *, const char *);
+                             const TLS_STATS *, DSN *, const char *);
 
 /* LICENSE
 /* .ad
@@ -38,6 +39,9 @@ extern void log_adhoc(const char *, MSG_STATS *, RECIPIENT *, const char *,
 /*     IBM T.J. Watson Research
 /*     P.O. Box 704
 /*     Yorktown Heights, NY 10598, USA
+/*
+/*     Wietse Venema
+/*     porcupine.org
 /*--*/
 
 #endif
index 6ca72325761d03b864bbf72e5610049318a443da..5b9cf7c018f70e8b41a7d402fffce0be375cdd1e 100644 (file)
@@ -4424,6 +4424,15 @@ extern char *var_smtp_reqtls_policy;
 #define DEF_REQTLS_REDACT_DSN          "yes"
 extern int var_reqtls_redact_dsn;
 
+ /*
+  * TS per-feature policy status.
+  */
+#define VAR_SMTP_LOG_TLS_FEATURE_STATUS        "smtp_log_tls_feature_status"
+#define DEF_SMTP_LOG_TLS_FEATURE_STATUS        "yes"
+#define VAR_LMTP_LOG_TLS_FEATURE_STATUS        "lmtp_log_tls_feature_status"
+#define DEF_LMTP_LOG_TLS_FEATURE_STATUS        "yes"
+extern bool var_log_tls_feature_status;
+
  /*
   * Workaround for future incompatibility. Our implementation of RFC 2308
   * negative reply caching relies on the promise that res_query() and
index 564e97222ff7b005b6be191967b53b497698d8c1..afae49718848311d7ca84c3442ce18810761d92c 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      "20250906"
+#define MAIL_RELEASE_DATE      "20250910"
 #define MAIL_VERSION_NUMBER    "3.11"
 
 #ifdef SNAPSHOT
@@ -104,6 +104,9 @@ extern void check_mail_version(const char *);
 /*     Google, Inc.
 /*     111 8th Avenue
 /*     New York, NY 10011, USA
+/*
+/*     Wietse Venema
+/*     porcupine.org
 /*--*/
 
 #endif
index 1b1b2a57a7904a47cf471a8da3ca6191024c8c5e..8a7bcb4fc8e3f6ae1c27ef9c03959721c7f23dad 100644 (file)
@@ -38,6 +38,9 @@
 /*     Google, Inc.
 /*     111 8th Avenue
 /*     New York, NY 10011, USA
+/*
+/*     Wietse Venema
+/*     porcupine.org
 /*--*/
 
  /*
@@ -95,7 +98,7 @@ int     reject_deliver_request(const char *service, DELIVER_REQUEST *request,
            (DEL_REQ_TRACE_FLAGS(request->flags),
             request->queue_id,
             &request->msg_stats, rcpt,
-            service, &why->dsn);
+            service, NO_TLS_STATS, &why->dsn);
        if (status == 0)
            deliver_completed(request->fp, rcpt->offset);
        result |= status;
index c81ccebdcc1bf7f2a196f175960528ef6e5735c2..66f62d7fa9a4146d8c7ff610f2cb07b02a5e2c45 100644 (file)
@@ -6,12 +6,13 @@
 /* SYNOPSIS
 /*     #include <sent.h>
 /*
-/*     int     sent(flags, queue_id, stats, recipient, relay, dsn)
+/*     int     sent(flags, queue_id, stats, recipient, relay, tstats, dsn)
 /*     int     flags;
 /*     const char *queue_id;
 /*     MSG_STATS *stats;
 /*     RECIPIENT *recipient;
 /*     const char *relay;
+/*     const TLS_STATS *tstats;
 /*     DSN *dsn;
 /* DESCRIPTION
 /*     sent() logs that a message was successfully delivered,
@@ -44,6 +45,8 @@
 /*     Recipient information. See recipient_list(3).
 /* .IP relay
 /*     Name of the host we're talking to.
+/* .IP tstats
+/*     TLS per-feature status.
 /* .IP dsn
 /*     Delivery status. See dsn(3). The action is ignored in case
 /*     of a probe message. Otherwise, "delivered" is assumed when
@@ -69,6 +72,9 @@
 /*     Google, Inc.
 /*     111 8th Avenue
 /*     New York, NY 10011, USA
+/*
+/*     Wietse Venema
+/*     porcupine.org
 /*--*/
 
 /* System library. */
 
 int     sent(int flags, const char *id, MSG_STATS *stats,
                     RECIPIENT *recipient, const char *relay,
-                    DSN *dsn)
+                    const TLS_STATS *tstats, DSN *dsn)
 {
     DSN     my_dsn = *dsn;
     DSN    *dsn_res;
@@ -126,7 +132,7 @@ int     sent(int flags, const char *id, MSG_STATS *stats,
      */
     if (flags & DEL_REQ_FLAG_MTA_VRFY) {
        my_dsn.action = "deliverable";
-       status = verify_append(id, stats, recipient, relay, &my_dsn,
+       status = verify_append(id, stats, recipient, relay, tstats, &my_dsn,
                               DEL_RCPT_STAT_OK);
        return (status);
     }
@@ -137,7 +143,8 @@ int     sent(int flags, const char *id, MSG_STATS *stats,
      */
     if (flags & DEL_REQ_FLAG_USR_VRFY) {
        my_dsn.action = "deliverable";
-       status = trace_append(flags, id, stats, recipient, relay, &my_dsn);
+       status = trace_append(flags, id, stats, recipient, relay, tstats,
+                             &my_dsn);
        return (status);
     }
 
@@ -156,10 +163,10 @@ int     sent(int flags, const char *id, MSG_STATS *stats,
            my_dsn.action = "delivered";
 
        if (((REC_ALL_SENT(flags) == 0 && REC_DLY_SENT(flags, recipient) == 0)
-         || trace_append(flags, id, stats, recipient, relay, &my_dsn) == 0)
+            || trace_append(flags, id, stats, recipient, relay, tstats, &my_dsn) == 0)
            && ((recipient->dsn_notify & DSN_NOTIFY_SUCCESS) == 0
-       || trace_append(flags, id, stats, recipient, relay, &my_dsn) == 0)) {
-           log_adhoc(id, stats, recipient, relay, &my_dsn, "sent");
+               || trace_append(flags, id, stats, recipient, relay, tstats, &my_dsn) == 0)) {
+           log_adhoc(id, stats, recipient, relay, tstats, &my_dsn, "sent");
            status = 0;
        } else {
            VSTRING *junk = vstring_alloc(100);
@@ -168,7 +175,8 @@ int     sent(int flags, const char *id, MSG_STATS *stats,
                            id, var_trace_service);
            my_dsn.reason = vstring_str(junk);
            my_dsn.status = "4.3.0";
-           status = defer_append(flags, id, stats, recipient, relay, &my_dsn);
+           status = defer_append(flags, id, stats, recipient, relay, tstats,
+                                 &my_dsn);
            vstring_free(junk);
        }
        return (status);
index 2ed3856a583d3f1a50ac14fe658a1b5498464d14..8846be5dd3df021d9e3a8d8a153e38e358081d77 100644 (file)
@@ -29,7 +29,7 @@
 #define SENT_FLAG_NONE (0)
 
 extern int sent(int, const char *, MSG_STATS *, RECIPIENT *, const char *,
-                       DSN *);
+                       const TLS_STATS *, DSN *);
 
 /* LICENSE
 /* .ad
@@ -40,6 +40,9 @@ extern int sent(int, const char *, MSG_STATS *, RECIPIENT *, const char *,
 /*     IBM T.J. Watson Research
 /*     P.O. Box 704
 /*     Yorktown Heights, NY 10598, USA
+/*
+/*     Wietse Venema
+/*     porcupine.org
 /*--*/
 
 #endif
diff --git a/postfix/src/global/tls_stats.c b/postfix/src/global/tls_stats.c
new file mode 100644 (file)
index 0000000..e64205e
--- /dev/null
@@ -0,0 +1,188 @@
+/*++
+/* NAME
+/*     tls_stats 3
+/* SUMMARY
+/*     manage TLS per-feature policy compliance status
+/* SYNOPSIS
+/*     #include <tls_stats.h>
+/*
+/*     TLS_STATS *tls_stats_create(void)
+/*
+/*     void    tls_stats_revert(TLS_STATS *tstats)
+/*
+/*     void    tls_stats_free(TLS_STATS *tstats)
+/*
+/*     void    tls_stat_activate(
+/*     TLS_STATS *tstats,
+/*     int     idx,
+/*     const char *name,
+/*     bool    enforce)
+/*
+/*     void    tls_stat_decide(
+/*     TLS_STATS *tstats,
+/*     int     idx,
+/*     const char *name,
+/*     int     status,
+/*     bool    enforce)
+/*
+/*     const TLS_STAT *tls_stats_access(
+/*     TLS_STATS *tstats,
+/*     int     idx)
+/*
+/*     int     tls_stats_used(TLS_STATS *tstats)
+/* DESCRIPTION
+/*     This module maintains for each active TLS feature whether
+/*     the current outbound SMTP connection satisfies the policy
+/*     requirements for that feature. For example, whether a server
+/*     certificate matches DANE or STS requirements.
+/*
+/*     tls_stats_create() creates one TLS_STATS instance with all status
+/*     information set to TLS_STAT_INACTIVE.
+/*
+/*     tls_stats_revert() reverts changes after tls_stats_create().
+/*
+/*     tls_stats_free() recycles storage for a TLS_STATS instance.
+/*
+/*     Specific status information is accessed with an index. Valid
+/*     indices are 0 or 1 (the caller decides their purpose).
+/*
+/*     The enforcement level of a feature is either TLS_STAT_ENF_FULL
+/*     (full enforcement) or TLS_STAT_ENF_RELAXED (some requirements
+/*     are relaxed).
+/*
+/*     tls_stat_activate() changes the status in tstats at index idx
+/*     from TLS_STAT_INACTIVE to TLS_STAT_UNDECIDED, and updates the
+/*     name (pointer copy) and 'enforce' level. Calls with an invalid
+/*     index result in a panic(), and calls with an already active
+/*     index result in a warning.
+/*
+/*     tls_stat_decide() updates the status in tstats at index idx from
+/*     TLS_STAT_UNDECIDED to TLS_STAT_COMPLIANT, TLS_STAT_VIOLATION,
+/*     or TLS_STAT_DISABLED, and updates its name and enforcement
+/*     level. Calls with an invalid index or an unexpected decision
+/*     status result in a panic(), and calls with an inactive or
+/*     already decided index status result in a warning.
+/*
+/*     tls_stats_access() returns a const pointer to the status
+/*     information in tstats at index idx.
+/*
+/*     tls_stats_used() returns the number of activated categories for
+/*     its argument.
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     porcupine.org
+/*--*/
+
+#ifdef USE_TLS
+
+ /*
+  * System library.
+  */
+#include <sys_defs.h>
+
+ /*
+  * Utility library.
+  */
+#include <msg.h>
+#include <mymalloc.h>
+
+ /*
+  * Global library.
+  */
+#include <tls_stats.h>
+
+/* tls_stats_create - create an all-inactive TLS_STATS instance */
+
+TLS_STATS *tls_stats_create(void)
+{
+    TLS_STATS *tstats;
+    TLS_STAT *tp;
+
+#define TLS_STAT_INIT(tp) do { \
+       (tp)->name = 0; \
+       (tp)->status = TLS_STAT_INACTIVE; \
+       (tp)->enforce = 0; \
+    } while (0);
+
+    tstats = (TLS_STATS *) mymalloc(sizeof(*tstats));
+    tstats->used = 0;
+    for (tp = tstats->st; tp < tstats->st + TLS_STATS_SIZE; tp++)
+       TLS_STAT_INIT(tp);
+    return tstats;
+}
+
+/* tls_stats_revert - revert changes after tls_stats_create() */
+
+void    tls_stats_revert(TLS_STATS *tstats)
+{
+    TLS_STAT *tp;
+
+    tstats->used = 0;
+    for (tp = tstats->st; tp < tstats->st + TLS_STATS_SIZE; tp++)
+       if (tp->status != TLS_STAT_INACTIVE)
+           TLS_STAT_INIT(tp);
+}
+
+/* tls_stats_free - TLS_STATS destructor */
+
+void    tls_stats_free(TLS_STATS *tstats)
+{
+    myfree(tstats);
+}
+
+/* tls_stat_activate - activate status at index */
+
+void    tls_stat_activate(TLS_STATS *tstats, int idx, const char *name,
+                                 bool enforce)
+{
+    TLS_STAT *tls_stat;
+
+    if (idx < 0 || idx >= TLS_STATS_SIZE)
+       msg_panic("%s: bad index: %d", __func__, idx);
+    tls_stat = tstats->st + idx;
+    if (tls_stat->status != TLS_STAT_INACTIVE)
+       msg_warn("%s: already active TLS_STAT at index %d", __func__, idx);
+    tls_stat->name = name;
+    tls_stat->status = TLS_STAT_UNDECIDED;
+    tls_stat->enforce = enforce;
+    tstats->used += 1;
+}
+
+/* tls_stat_decide - update undecided status at index */
+
+extern void tls_stat_decide(TLS_STATS *tstats, int idx, const char *name,
+                                   int status, bool enforce)
+{
+    TLS_STAT *tls_stat;
+
+    if (status != TLS_STAT_VIOLATION && status != TLS_STAT_COMPLIANT
+       && status != TLS_STAT_DISABLED)
+       msg_panic("%s: bad new status: %d", __func__, status);
+    if (idx < 0 || idx >= TLS_STATS_SIZE)
+       msg_panic("%s: bad index: %d", __func__, idx);
+    tls_stat = tstats->st + idx;
+    if (tls_stat->status != TLS_STAT_UNDECIDED)
+       msg_warn("%s: unexpected status %d at index %d",
+                __func__, tls_stat->status, idx);
+    tls_stat->name = name;
+    tls_stat->status = status;
+    tls_stat->enforce = enforce;
+}
+
+/* tls_stat_access - peek at specific TLS_STAT instance. */
+
+const TLS_STAT *tls_stat_access(const TLS_STATS *tstats, int idx)
+{
+    const TLS_STAT *tls_stat;
+
+    if (idx < 0 || idx >= TLS_STATS_SIZE)
+       msg_panic("%s: bad index: %d", __func__, idx);
+    tls_stat = tstats->st + idx;
+    return (tls_stat);
+}
+
+#endif                                 /* USE_TLS */
diff --git a/postfix/src/global/tls_stats.h b/postfix/src/global/tls_stats.h
new file mode 100644 (file)
index 0000000..93e334c
--- /dev/null
@@ -0,0 +1,69 @@
+#ifndef _TLS_STATS_H_INCLUDED_
+#define _TLS_STATS_H_INCLUDED_
+
+/*++
+/* NAME
+/*     tls_stats 3h
+/* SUMMARY
+/*     manage TLS per-feature policy compliance status
+/* SYNOPSIS
+/*     #include <tls_stats.h>
+/* DESCRIPTION
+/* .nf
+
+ /*
+  * TODO(wietse) adopt C99 bool.
+  */
+#include <mail_params.h>
+
+ /*
+  * External interface.
+  */
+typedef struct TLS_STAT {
+    const char *name;                  /* Human-readable feature name */
+    int     status;                    /* See below */
+    bool    enforce;                   /* See below */
+} TLS_STAT;
+
+#define TLS_STAT_INACTIVE      0       /* No data */
+#define TLS_STAT_UNDECIDED     1       /* Pending decision */
+#define TLS_STAT_VIOLATION     2       /* Definitely did not meet policy */
+#define TLS_STAT_COMPLIANT     3       /* Definitely did meet policy */
+#define TLS_STAT_DISABLED      4       /* Definitely disabled */
+#define TLS_STAT_ENF_FULL      1       /* Full enforcement */
+#define TLS_STAT_ENF_RELAXED   0       /* Relaxed enforcement */
+
+ /*
+  * Wrap it in a structure for sanity-checked access.
+  */
+#define TLS_STATS_SIZE 2               /* TLS level and REQUIRETLS */
+
+typedef struct TLS_STATS {
+    int     used;
+    TLS_STAT st[TLS_STATS_SIZE];
+} TLS_STATS;
+
+#ifdef USE_TLS
+
+extern TLS_STATS *tls_stats_create(void);
+extern void tls_stats_revert(TLS_STATS *);
+extern void tls_stats_free(TLS_STATS *);
+
+#define tls_stats_used(t) ((t)->used)
+extern void tls_stat_activate(TLS_STATS *, int, const char *, bool);
+extern void tls_stat_decide(TLS_STATS *, int, const char *, int, bool);
+extern const TLS_STAT *tls_stat_access(const TLS_STATS *, int);
+
+#define NO_TLS_STATS   ((TLS_STATS *) 0)
+
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     porcupine.org
+/*--*/
+
+#endif                                 /* USE_TLS */
+#endif                                 /* _TLS_STATS_H_INCLUDED_ */
index d826a649426fe672c4988c998380271d59076444..019bd25ddd4419a26cdc1d3f9ef5feafa3684ef2 100644 (file)
@@ -6,12 +6,13 @@
 /* SYNOPSIS
 /*     #include <trace.h>
 /*
-/*     int     trace_append(flags, id, stats, rcpt, relay, dsn)
+/*     int     trace_append(flags, id, stats, rcpt, relay, tstats, dsn)
 /*     int     flags;
 /*     const char *id;
 /*     MSG_STATS *stats;
 /*     RECIPIENT *rcpt;
 /*     const char *relay;
+/*     const TLS_STATS *tstats;
 /*     DSN     *dsn;
 /*
 /*     int     trace_flush(flags, queue, id, encoding, sender,
@@ -61,6 +62,8 @@
 /*     Recipient information. See recipient_list(3).
 /* .IP relay
 /*     The host we sent the mail to.
+/* .IP tstats
+/*     TLS per-feature status.
 /* .IP dsn
 /*     Delivery status information. See dsn(3).
 /* DIAGNOSTICS
@@ -84,6 +87,9 @@
 /*     Google, Inc.
 /*     111 8th Avenue
 /*     New York, NY 10011, USA
+/*
+/*     Wietse Venema
+/*     porcupine.org
 /*--*/
 
 /* System library. */
 
 int     trace_append(int flags, const char *id, MSG_STATS *stats,
                             RECIPIENT *rcpt, const char *relay,
-                            DSN *dsn)
+                            const TLS_STATS *tstats, DSN *dsn)
 {
     VSTRING *why = vstring_alloc(100);
     DSN     my_dsn = *dsn;
@@ -137,7 +143,7 @@ int     trace_append(int flags, const char *id, MSG_STATS *stats,
        req_stat = -1;
     } else {
        if (flags & DEL_REQ_FLAG_USR_VRFY)
-           log_adhoc(id, stats, rcpt, relay, dsn, my_dsn.action);
+           log_adhoc(id, stats, rcpt, relay, tstats, dsn, my_dsn.action);
        req_stat = 0;
     }
     vstring_free(why);
index 201360198e995a93556c7a74d35522decc9faae5..d76811edfff789c411bbe3cc20cb03def95f8655 100644 (file)
@@ -20,7 +20,7 @@
   * External interface.
   */
 extern int trace_append(int, const char *, MSG_STATS *, RECIPIENT *,
-                               const char *, DSN *);
+                               const char *, const TLS_STATS *, DSN *);
 extern int trace_flush(int, const char *, const char *, const char *,
                               const char *, const char *, int);
 
@@ -33,6 +33,9 @@ extern int trace_flush(int, const char *, const char *, const char *,
 /*     IBM T.J. Watson Research
 /*     P.O. Box 704
 /*     Yorktown Heights, NY 10598, USA
+/*
+/*     Wietse Venema
+/*     porcupine.org
 /*--*/
 
 #endif
index 2ce091a5d5758a775ed5322bd4ad181b804ce259..53f17f16b6e891aa226e0de0ee625a8665a11f4c 100644 (file)
@@ -6,12 +6,13 @@
 /* SYNOPSIS
 /*     #include <verify.h>
 /*
-/*     int     verify_append(queue_id, stats, recipient, relay, dsn,
+/*     int     verify_append(queue_id, stats, recipient, relay, tstats, dsn,
 /*                             verify_status)
 /*     const char *queue_id;
 /*     MSG_STATS *stats;
 /*     RECIPIENT *recipient;
 /*     const char *relay;
+/*     const TLS_STATS *tstats;
 /*     DSN     *dsn;
 /*     int     verify_status;
 /* DESCRIPTION
@@ -32,6 +33,8 @@
 /*     Recipient information. See recipient_list(3).
 /* .IP relay
 /*     Name of the host we're talking to.
+/* .IP tstats
+/*     TLS per-feature status.
 /* .IP dsn
 /*     Delivery status information. See dsn(3).
 /*     The action is one of "deliverable" or "undeliverable".
@@ -66,6 +69,9 @@
 /*     Google, Inc.
 /*     111 8th Avenue
 /*     New York, NY 10011, USA
+/*
+/*     Wietse Venema
+/*     porcupine.org
 /*--*/
 
 /* System library. */
@@ -91,7 +97,8 @@
 
 int     verify_append(const char *queue_id, MSG_STATS *stats,
                              RECIPIENT *recipient, const char *relay,
-                             DSN *dsn, int vrfy_stat)
+                             const TLS_STATS *tstats, DSN *dsn,
+                             int vrfy_stat)
 {
     int     req_stat;
     DSN     my_dsn = *dsn;
@@ -120,7 +127,8 @@ int     verify_append(const char *queue_id, MSG_STATS *stats,
        req_stat = VRFY_STAT_OK;
     }
     if (req_stat == VRFY_STAT_OK) {
-       log_adhoc(queue_id, stats, recipient, relay, dsn, my_dsn.action);
+       log_adhoc(queue_id, stats, recipient, relay, tstats, dsn,
+                 my_dsn.action);
        req_stat = 0;
     } else {
        msg_warn("%s: %s service failure", queue_id, var_verify_service);
index 250eb6d65e9520bb05dcdc972635add49daca067..5e09d36228f7695ee234cb62310e21bc290eb8e5 100644 (file)
   * Global library.
   */
 #include <deliver_request.h>
+#include <tls_stats.h>
 
  /*
   * External interface.
   */
 extern int verify_append(const char *, MSG_STATS *, RECIPIENT *,
-                                const char *, DSN *, int);
+                                const char *, const TLS_STATS *,
+                                DSN *, int);
 
 /* LICENSE
 /* .ad
@@ -36,6 +38,9 @@ extern int verify_append(const char *, MSG_STATS *, RECIPIENT *,
 /*     IBM T.J. Watson Research
 /*     P.O. Box 704
 /*     Yorktown Heights, NY 10598, USA
+/*
+/*     Wietse Venema
+/*     porcupine.org
 /*--*/
 
 #endif
index 13d0dc79e2e00e9a4c0b6b4b4d5a2caa216e1c5a..0f024e45f09a4aca9ad687710678227a84682256 100644 (file)
@@ -133,15 +133,15 @@ typedef struct LOCAL_STATE {
 
 #define BOUNCE_ATTR(attr) \
        attr.queue_id, &attr.msg_stats, &attr.rcpt, attr.relay, \
-       DSN_FROM_DSN_BUF(attr.why)
+       NO_TLS_STATS, DSN_FROM_DSN_BUF(attr.why)
 #define BOUNCE_ONE_ATTR(attr) \
        attr.queue_name, attr.queue_id, attr.encoding, attr.sendopts, \
        attr.sender, attr.dsn_envid, attr.dsn_ret, \
        &attr.msg_stats, &attr.rcpt, attr.relay, \
-       DSN_FROM_DSN_BUF(attr.why)
+       NO_TLS_STATS, DSN_FROM_DSN_BUF(attr.why)
 #define SENT_ATTR(attr) \
        attr.queue_id, &attr.msg_stats, &attr.rcpt, attr.relay, \
-       DSN_FROM_DSN_BUF(attr.why)
+       NO_TLS_STATS, DSN_FROM_DSN_BUF(attr.why)
 #define OPENED_ATTR(attr) \
        attr.queue_id, attr.sender
 #define COPY_ATTR(attr) \
index 00ba885bf98fb7aea993eed765feb1668fd3edf2..ee9f568634fba999d469a5995fdc50856dc4fc8d 100644 (file)
@@ -62,7 +62,7 @@ void    qmgr_bounce_recipient(QMGR_MESSAGE *message, RECIPIENT *recipient,
 
     status = bounce_append(message->tflags, message->queue_id,
                           QMGR_MSG_STATS(&stats, message), recipient,
-                          "none", dsn);
+                          "none", NO_TLS_STATS, dsn);
 
     if (status == 0)
        deliver_completed(message->fp, recipient->offset);
index dc0319e773a6b3a14961c841248d6a50e88c4501..e87fe0b6e2f685f22f636448c14a2acf7a781e01 100644 (file)
@@ -154,5 +154,5 @@ void    qmgr_defer_recipient(QMGR_MESSAGE *message, RECIPIENT *recipient,
      */
     message->flags |= defer_append(message->tflags, message->queue_id,
                                 QMGR_MSG_STATS(&stats, message), recipient,
-                                  "none", dsn);
+                                  "none", NO_TLS_STATS, dsn);
 }
index a88c8e5e7c6ab4ade7fd5983b776cebcf42e45ea..85b0d714156d6296b91fa609bb7843c9fb278b0a 100644 (file)
@@ -1133,7 +1133,7 @@ static void qmgr_message_resolve(QMGR_MESSAGE *message)
                && !var_double_bounce_sender[len]) {
                status = sent(message->tflags, message->queue_id,
                              QMGR_MSG_STATS(&stats, message), recipient,
-                             "none", DSN_SIMPLE(&dsn, "2.0.0",
+                             "none", NO_TLS_STATS, DSN_SIMPLE(&dsn, "2.0.0",
                        "undeliverable postmaster notification discarded"));
                if (status == 0) {
                    deliver_completed(message->fp, recipient->offset);
index feb35f2520e22d5e90c269d6bdc8669fea1c0767..0788f640aa5df78be9bdfda93341ca18aa949c79 100644 (file)
@@ -1095,7 +1095,7 @@ static int eval_command_status(int command_status, char *service,
            rcpt = request->rcpt_list.info + n;
            status = sent(DEL_REQ_TRACE_FLAGS(request->flags),
                          request->queue_id, &request->msg_stats, rcpt,
-                         service, &why->dsn);
+                         service, NO_TLS_STATS, &why->dsn);
            if (status == 0 && (request->flags & DEL_REQ_FLAG_SUCCESS))
                deliver_completed(request->fp, rcpt->offset);
            result |= status;
@@ -1112,7 +1112,7 @@ static int eval_command_status(int command_status, char *service,
                (DEL_REQ_TRACE_FLAGS(request->flags),
                 request->queue_id,
                 &request->msg_stats, rcpt,
-                service, &why->dsn);
+                service, NO_TLS_STATS, &why->dsn);
            if (status == 0)
                deliver_completed(request->fp, rcpt->offset);
            result |= status;
@@ -1224,7 +1224,7 @@ static int deliver_message(DELIVER_REQUEST *request, char *service, char **argv)
            rcpt = request->rcpt_list.info + n;
            status = sent(DEL_REQ_TRACE_FLAGS(request->flags),
                          request->queue_id, &request->msg_stats,
-                         rcpt, service, &why->dsn);
+                         rcpt, service, NO_TLS_STATS, &why->dsn);
            if (status == 0 && (request->flags & DEL_REQ_FLAG_SUCCESS))
                deliver_completed(request->fp, rcpt->offset);
            deliver_status |= status;
index 00ba885bf98fb7aea993eed765feb1668fd3edf2..ee9f568634fba999d469a5995fdc50856dc4fc8d 100644 (file)
@@ -62,7 +62,7 @@ void    qmgr_bounce_recipient(QMGR_MESSAGE *message, RECIPIENT *recipient,
 
     status = bounce_append(message->tflags, message->queue_id,
                           QMGR_MSG_STATS(&stats, message), recipient,
-                          "none", dsn);
+                          "none", NO_TLS_STATS, dsn);
 
     if (status == 0)
        deliver_completed(message->fp, recipient->offset);
index 79615cc0f760c34cedb8aa856978391e2de6013b..1cce65ca5785e58887ebcd9668fe169824263887 100644 (file)
@@ -159,5 +159,5 @@ void    qmgr_defer_recipient(QMGR_MESSAGE *message, RECIPIENT *recipient,
      */
     message->flags |= defer_append(message->tflags, message->queue_id,
                                 QMGR_MSG_STATS(&stats, message), recipient,
-                                  "none", dsn);
+                                  "none", NO_TLS_STATS, dsn);
 }
index 2e44c1d2205dbe4751eb37fdb5f54515f0732693..56533b2a20f1b60d628ae0153400f3438abffe21 100644 (file)
@@ -1192,7 +1192,7 @@ static void qmgr_message_resolve(QMGR_MESSAGE *message)
                && !var_double_bounce_sender[len]) {
                status = sent(message->tflags, message->queue_id,
                              QMGR_MSG_STATS(&stats, message), recipient,
-                             "none", DSN_SIMPLE(&dsn, "2.0.0",
+                             "none", NO_TLS_STATS, DSN_SIMPLE(&dsn, "2.0.0",
                        "undeliverable postmaster notification discarded"));
                if (status == 0) {
                    deliver_completed(message->fp, recipient->offset);
index 9240370918c7cc786f5f3941f7bed1a857cf3fa1..f50541d590ae7a543def789f5ad23e3d2b7d7c6d 100644 (file)
        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,
+       VAR_LMTP_LOG_TLS_FEATURE_STATUS, DEF_LMTP_LOG_TLS_FEATURE_STATUS, &var_log_tls_feature_status,
        0,
     };
index 1b8d5bc392725d3b666f71af652012375458e64f..4ee1250c97a8edc7b085cd46d51bf6c642716d44 100644 (file)
 /* .IP "\fBsmtp_requiretls_policy (see 'postconf -d smtp_requiretls_policy' output)\fR"
 /*     How the Postfix SMTP and LMTP client will enforce REQUIRETLS
 /*     for messages received with the REQUIRETLS option.
+/* .IP "\fBsmtp_log_tls_feature_status (yes)\fR"
+/*     Enable logging of TLS feature information in delivery status
+/*     logging.
 /* OBSOLETE TLS CONTROLS
 /* .ad
 /* .fi
@@ -1180,6 +1183,7 @@ bool    var_smtp_tlsrpt_enable;
 char   *var_smtp_tlsrpt_sockname;
 bool    var_smtp_tlsrpt_skip_reused_hs;
 char   *var_smtp_reqtls_policy;
+bool   var_log_tls_feature_status;
 
  /* Special handling of 535 AUTH errors. */
 char   *var_smtp_sasl_auth_cache_name;
index 8433828fcdcfaada357470c0a05d31ae4036fe9a..dd5018de7b04d8eb8dd2b74dded4261fb8aacf70 100644 (file)
@@ -33,6 +33,7 @@
 #include <dsn_buf.h>
 #include <header_body_checks.h>
 #include <sendopts.h>
+#include <tls_stats.h>
 
  /*
   * Postfix TLS library.
@@ -200,7 +201,7 @@ typedef struct SMTP_STATE {
     SMTP_ITERATOR iterator[1];         /* Usage: state->iterator->member */
 
     /*
-     * Global iterator.
+     * TLS policy related.
      */
 #ifdef USE_TLS
     SMTP_TLS_POLICY tls[1];            /* Usage: state->tls->member */
@@ -208,6 +209,7 @@ typedef struct SMTP_STATE {
     struct TLSRPT_WRAPPER *tlsrpt;
 #endif
     int     reqtls_level;              /* from smtp_reqtls_policy */
+    TLS_STATS *tls_stats;              /* policy compliance status */
 #endif
 
     /*
@@ -246,6 +248,28 @@ typedef struct SMTP_STATE {
     unsigned logged_line_length_limit:1;
 } SMTP_STATE;
 
+#define SMTP_TLS_STAT_IDX_SEC_LEVEL    0
+#define SMTP_TLS_STAT_IDX_REQTLS       1
+
+/* Use the TLS policy name for the TLS security level status feature. */
+#define SMTP_TLS_STAT_NAME_REQTLS      "requiretls"
+
+#define smtp_tls_stat_activate_sec_level(tstats, level, enforce) \
+       tls_stat_activate((tstats), SMTP_TLS_STAT_IDX_SEC_LEVEL, \
+           str_tls_level(level), (enforce))
+
+#define smtp_tls_stat_decide_sec_level(tstats, level, status, enforce) \
+       tls_stat_decide((tstats), SMTP_TLS_STAT_IDX_SEC_LEVEL, \
+           str_tls_level(level), (status), (enforce))
+
+#define smtp_tls_stat_activate_reqtls(tstats, enforce) \
+       tls_stat_activate((tstats), SMTP_TLS_STAT_IDX_REQTLS, \
+       SMTP_TLS_STAT_NAME_REQTLS, (enforce))
+
+#define smtp_tls_stat_decide_reqtls(tstats, status, enforce) \
+       tls_stat_decide((tstats), SMTP_TLS_STAT_IDX_REQTLS, \
+           SMTP_TLS_STAT_NAME_REQTLS, (status), (enforce))
+
 #ifdef USE_TLS
 #define STATE_TLS_NOT_REQUIRED(state) \
        (var_tls_required_enable \
index ded52ab4acf09cb9afd4df903d11c8e5343df4a9..6ed033e150cd82d1b223bba85776cd1ffb2fca6c 100644 (file)
@@ -526,6 +526,10 @@ static int smtp_get_effective_tls_level(DSN_BUF *why, SMTP_STATE *state)
     switch (state->reqtls_level) {
     case SMTP_REQTLS_POLICY_ACT_ENFORCE:
        if (TLS_MUST_MATCH(tls->level) == 0) {
+           if (state->tls_stats)
+               smtp_tls_stat_decide_reqtls(state->tls_stats,
+                                           TLS_STAT_VIOLATION,
+                                           TLS_STAT_ENF_FULL);
            dsb_simple(why, "5.7.10", "REQUIRETLS Failure: sender "
                       "requested REQUIRETLS, but my configured TLS "
                       "security level '%s' disables certificate "
@@ -536,6 +540,10 @@ static int smtp_get_effective_tls_level(DSN_BUF *why, SMTP_STATE *state)
        break;
     case SMTP_REQTLS_POLICY_ACT_OPP_TLS:
        if (tls->level == TLS_LEV_NONE) {
+           if (state->tls_stats)
+               smtp_tls_stat_decide_reqtls(state->tls_stats,
+                                           TLS_STAT_VIOLATION,
+                                           TLS_STAT_ENF_RELAXED);
            dsb_simple(why, "5.7.10", "REQUIRETLS Failure: sender "
                       "requested REQUIRETLS, but my configured TLS "
                       "security level '%s' disables encryption. The "
@@ -1187,6 +1195,15 @@ static void smtp_connect_inet(SMTP_STATE *state, const char *nexthop,
                continue;
                /* XXX Assume there is no code at the end of this loop. */
            }
+           if (state->tls_stats) {
+               tls_stats_revert(state->tls_stats);
+               smtp_tls_stat_activate_sec_level(state->tls_stats,
+                                                state->tls->level,
+                                         state->tls->level != TLS_LEV_MAY);
+               if (state->reqtls_level > SMTP_REQTLS_POLICY_ACT_DISABLE)
+                   smtp_tls_stat_activate_reqtls(state->tls_stats,
+                    state->reqtls_level == SMTP_REQTLS_POLICY_ACT_ENFORCE);
+           }
            /* Disable TLS when retrying after a handshake failure */
            if (retry_plain) {
                state->tls->level = TLS_LEV_NONE;
index 898689e418b4d2014cfc404c980356124a16d17a..5fe33c078bbf79dc2f0f26afcbcf3f82e28ce15f 100644 (file)
        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,
+       VAR_SMTP_LOG_TLS_FEATURE_STATUS, DEF_SMTP_LOG_TLS_FEATURE_STATUS, &var_log_tls_feature_status,
        0,
     };
index 992763eeb2594612be08bb7b0f80cf3dcdae15ef..59142cea2dfe100b46a64aa3ff81cd7a44b37e15 100644 (file)
@@ -693,25 +693,48 @@ int     smtp_helo(SMTP_STATE *state)
      * that the server does not offer REQUIRETLS.
      */
 #ifdef USE_TLS
-    if (TLS_REQUIRED_BY_REQTLS_POLICY(state->reqtls_level)
-       && (state->misc_flags & SMTP_MISC_FLAG_IN_STARTTLS) != 0
-       && (session->features & SMTP_FEATURE_REQTLS) == 0) {
-       switch (state->reqtls_level) {
-       case SMTP_REQTLS_POLICY_ACT_ENFORCE:
-           return (smtp_misc_fail(state, SMTP_MISC_FAIL_SOFT_NON_FINAL,
-                                  DSN_BY_LOCAL_MTA,
-                                  SMTP_RESP_FAKE(&fake, "5.7.30"),
-                                  "REQUIRETLS Failure: sender "
-                                  "requested REQUIRETLS, but no "
-                                  "server was found that supports "
-                                  "REQUIRETLS. The last attempted "
-                                  "server was %s", session->namaddr));
-       default:
+    if (state->reqtls_level > SMTP_REQTLS_POLICY_ACT_DISABLE
+       && (state->misc_flags & SMTP_MISC_FLAG_IN_STARTTLS) != 0) {
+       if (state->reqtls_level == SMTP_REQTLS_POLICY_ACT_ENFORCE) {
+           if ((session->features & SMTP_FEATURE_REQTLS) != 0) {
+               if (state->tls_stats)
+                   smtp_tls_stat_decide_reqtls(state->tls_stats,
+                                               TLS_STAT_COMPLIANT,
+                                               TLS_STAT_ENF_FULL);
+           } else {
+               if (state->tls_stats)
+                   smtp_tls_stat_decide_reqtls(state->tls_stats,
+                                               TLS_STAT_VIOLATION,
+                                               TLS_STAT_ENF_FULL);
+               return (smtp_misc_fail(state, SMTP_MISC_FAIL_SOFT_NON_FINAL,
+                                      DSN_BY_LOCAL_MTA,
+                                      SMTP_RESP_FAKE(&fake, "5.7.30"),
+                                      "REQUIRETLS Failure: sender "
+                                      "requested REQUIRETLS, but no "
+                                      "server was found that supports "
+                                      "REQUIRETLS. The last attempted "
+                                      "server was %s", session->namaddr));
+           }
+       } else if ((session->features & SMTP_FEATURE_REQTLS) != 0) {
+           if (state->tls_stats)
+               smtp_tls_stat_decide_reqtls(state->tls_stats,
+                                           TLS_STAT_COMPLIANT,
+                                           TLS_STAT_ENF_RELAXED);
+       } else {
+           if (state->tls_stats)
+               smtp_tls_stat_decide_reqtls(state->tls_stats,
+                                           TLS_STAT_DISABLED,
+                                           TLS_STAT_ENF_RELAXED);
            msg_info("%s: REQUIRETLS Debug: sender requested REQUIRETLS, "
                     "but REQUIRETLS support was not offered by host "
                     "%s", request->queue_id, session->namaddr);
        }
     }
+
+    /*
+     * TODO(wietse) Maybe log servers that announce REQUIRETLS and whether
+     * the connection is authenticated?
+     */
 #endif
 
     /*
@@ -842,6 +865,13 @@ int     smtp_helo(SMTP_STATE *state)
                state->misc_flags &= ~SMTP_MISC_FLAG_IN_STARTTLS;
                return (tls_helo_status);
            }
+#ifdef USE_TLSRPT
+           if (state->tlsrpt)
+               trw_report_failure(state->tlsrpt,
+                                  TLSRPT_STARTTLS_NOT_SUPPORTED,
+                                   /* additional_info= */ (char *) 0,
+                                   /* failure_reason= */ (char *) 0);
+#endif
 
            /*
             * Give up if we must use TLS but the server rejects STARTTLS
@@ -854,14 +884,23 @@ int     smtp_helo(SMTP_STATE *state)
            session->features &= ~SMTP_FEATURE_STARTTLS;
            if (TLS_REQUIRED_BY_SECURITY_LEVEL(state->tls->level)
                || TLS_REQUIRED_BY_REQTLS_POLICY(state->reqtls_level)) {
-#ifdef USE_TLSRPT
-               if (state->tlsrpt)
-                   trw_report_failure(state->tlsrpt,
-                                      TLSRPT_STARTTLS_NOT_SUPPORTED,
-                                       /* additional_info= */ (char *) 0,
-                                       /* failure_reason= */ (char *) 0);
-#endif
-               if (TLS_REQUIRED_BY_REQTLS_POLICY(state->reqtls_level))
+               /* Before returning, decide all relevant policy status info. */
+               if (TLS_REQUIRED_BY_REQTLS_POLICY(state->reqtls_level)) {
+                   if (state->tls_stats)
+                       smtp_tls_stat_decide_reqtls(state->tls_stats,
+                                                   TLS_STAT_VIOLATION,
+                                                   state->reqtls_level == SMTP_REQTLS_POLICY_ACT_ENFORCE ?
+                                                   TLS_STAT_ENF_FULL :
+                                                   TLS_STAT_ENF_RELAXED);
+               }
+               if (TLS_REQUIRED_BY_SECURITY_LEVEL(state->tls->level))
+                   if (state->tls_stats)
+                       smtp_tls_stat_decide_sec_level(state->tls_stats,
+                                                      state->tls->level,
+                                                      TLS_STAT_VIOLATION,
+                                                      TLS_STAT_ENF_FULL);
+               /* Then, REQUIRETLS failure must take precedence over other. */
+               if (TLS_REQUIRED_BY_REQTLS_POLICY(state->reqtls_level)) {
                    return (smtp_misc_fail(state, SMTP_MISC_FAIL_SOFT_NON_FINAL,
                                           DSN_BY_LOCAL_MTA,
                                           SMTP_RESP_FAKE(&fake, "5.7.10"),
@@ -870,6 +909,7 @@ int     smtp_helo(SMTP_STATE *state)
                                           "but host %s refused to "
                                           "start TLS: %s", session->namaddr,
                                           translit(resp->str, "\n", " ")));
+               }
                /* TLS_REQUIRED_BY_SECURITY_LEVEL */
                return (smtp_site_fail(state, STR(iter->host), resp,
                    "TLS is required, but host %s refused to start TLS: %s",
@@ -900,6 +940,22 @@ int     smtp_helo(SMTP_STATE *state)
                                        /* additional_info= */ (char *) 0,
                                        /* failure_reason= */ (char *) 0);
 #endif
+               /* Before returning, decide all relevant policy status info. */
+               if (TLS_REQUIRED_BY_REQTLS_POLICY(state->reqtls_level)) {
+                   if (state->tls_stats)
+                       smtp_tls_stat_decide_reqtls(state->tls_stats,
+                                                   TLS_STAT_VIOLATION,
+                                                   state->reqtls_level == SMTP_REQTLS_POLICY_ACT_ENFORCE ?
+                                                   TLS_STAT_ENF_FULL :
+                                                   TLS_STAT_ENF_RELAXED);
+               }
+               if (TLS_REQUIRED_BY_SECURITY_LEVEL(state->tls->level))
+                   if (state->tls_stats)
+                       smtp_tls_stat_decide_sec_level(state->tls_stats,
+                                                      state->tls->level,
+                                                      TLS_STAT_VIOLATION,
+                                                      TLS_STAT_ENF_FULL);
+               /* Then, REQUIRETLS failure must take precedence over other. */
                if (TLS_REQUIRED_BY_REQTLS_POLICY(state->reqtls_level))
                    return (smtp_misc_fail(state, SMTP_MISC_FAIL_SOFT_NON_FINAL,
                                           DSN_BY_LOCAL_MTA,
@@ -926,6 +982,17 @@ int     smtp_helo(SMTP_STATE *state)
                                       "TLS is required, but unavailable"));
            }
        }
+       /* Continue in plain-text mode. */
+       if (state->tls_stats) {
+           if (state->tls->level == TLS_LEV_NONE) {
+               /* TODO(wietse) May be fall-back after TLS handshake failed. */
+               smtp_tls_stat_decide_sec_level(state->tls_stats, state->tls->level,
+                                    TLS_STAT_COMPLIANT, TLS_STAT_ENF_FULL);
+           } else {
+               smtp_tls_stat_decide_sec_level(state->tls_stats, state->tls->level,
+                                  TLS_STAT_DISABLED, TLS_STAT_ENF_RELAXED);
+           }
+       }
     }
 #endif
 #ifdef USE_SASL_AUTH
@@ -944,7 +1011,6 @@ static int smtp_start_tls(SMTP_STATE *state)
 {
     SMTP_SESSION *session = state->session;
     SMTP_ITERATOR *iter = state->iterator;
-    DELIVER_REQUEST *request = state->request;
     TLS_CLIENT_START_PROPS start_props;
     VSTRING *serverid;
     SMTP_RESP fake;
@@ -1211,6 +1277,7 @@ static int smtp_start_tls(SMTP_STATE *state)
         */
        if (PLAINTEXT_FALLBACK_OK_AFTER_STARTTLS_FAILURE)
            RETRY_AS_PLAINTEXT;
+       /* Leave all TLS feature policy status info as 'undecided'. */
        return (smtp_misc_fail(state, state->tls->level == TLS_LEV_MAY ?
                               SMTP_MISC_FAIL_NONE : SMTP_MISC_FAIL_THROTTLE,
                               DSN_BY_LOCAL_MTA,
@@ -1253,13 +1320,22 @@ static int smtp_start_tls(SMTP_STATE *state)
                                           /* failure_reason= */ (char *) 0);
            }
 #endif
+           /* Finalize TLS feature policy status info before giving up. */
+           if (state->tls_stats)
+               smtp_tls_stat_decide_sec_level(state->tls_stats,
+                                              session->tls_context->level,
+                                              TLS_STAT_VIOLATION,
+                                              TLS_STAT_ENF_FULL);
 
            /*
             * When the sender requested REQUIRETLS, and REQUIRETLS is
             * enforced, return the message as undeliverable only when there
             * are no more alternative MX hosts.
             */
-           if (TLS_REQUIRED_BY_REQTLS_POLICY(state->reqtls_level))
+           if (state->reqtls_level == SMTP_REQTLS_POLICY_ACT_ENFORCE) {
+               if (state->tls_stats)
+                   smtp_tls_stat_decide_reqtls(state->tls_stats,
+                                    TLS_STAT_VIOLATION, TLS_STAT_ENF_FULL);
                return (smtp_misc_fail(state, SMTP_MISC_FAIL_SOFT_NON_FINAL,
                                       DSN_BY_LOCAL_MTA,
                                       SMTP_RESP_FAKE(&fake, "5.7.10"),
@@ -1270,11 +1346,15 @@ static int smtp_start_tls(SMTP_STATE *state)
                                       "server was %s", trusted ?
                                       "matching" : "trusted",
                                       session->namaddr));
+           } else if (state->reqtls_level > SMTP_REQTLS_POLICY_ACT_DISABLE) {
+               if (state->tls_stats)
+                   smtp_tls_stat_decide_reqtls(state->tls_stats,
+                                               TLS_STAT_VIOLATION,
+                                               TLS_STAT_ENF_RELAXED);
+           }
            return (smtp_site_fail(state, DSN_BY_LOCAL_MTA,
                                   SMTP_RESP_FAKE(&fake, "4.7.5"),
                                   "Server certificate not verified"));
-       } else {
-           /* TODO(wietse) record that this attempt satisfies REQUIRETLS. */
        }
     }
 
@@ -1290,6 +1370,16 @@ static int smtp_start_tls(SMTP_STATE *state)
        (void) trw_report_success(state->tlsrpt);
 #endif
 
+    /*
+     * Report relaxed enforcement for the initial TLS level if it was
+     * degraded.
+     */
+    if (state->tls_stats)
+       smtp_tls_stat_decide_sec_level(state->tls_stats,
+                                      state->tls->level, TLS_STAT_COMPLIANT,
+                          session->tls_context->level < state->tls->level ?
+                                 TLS_STAT_ENF_RELAXED : TLS_STAT_ENF_FULL);
+
     /*
      * At this point we have to re-negotiate the "EHLO" to reget the
      * feature-list.
@@ -1877,7 +1967,6 @@ static int smtp_loop(SMTP_STATE *state, NOCLOBBER int send_state,
            if (state->reqtls_level > SMTP_REQTLS_POLICY_ACT_DISABLE) {
                if ((session->features & SMTP_FEATURE_REQTLS) != 0) {
                    vstring_strcat(next_command, " REQUIRETLS");
-                   /* TODO(wietse) record that REQUIRETLS is active. */
                } else if (state->reqtls_level
                           == SMTP_REQTLS_POLICY_ACT_ENFORCE) {
                    msg_panic("Can't happen: must enforce REQUIRETLS, but "
index 6608ea8804a7af6859729493b3a694fa8fae91df..66b9a41ace161b6244ea6f1b53b4e3e715d435fa 100644 (file)
@@ -179,7 +179,8 @@ void    smtp_rcpt_done(SMTP_STATE *state, SMTP_RESP *resp, RECIPIENT *rcpt)
 
     status = sent(DEL_REQ_TRACE_FLAGS(request->flags),
                  request->queue_id, &request->msg_stats, rcpt,
-                 session->namaddrport, DSN_FROM_DSN_BUF(why));
+                 session->namaddrport, state->tls_stats,
+                 DSN_FROM_DSN_BUF(why));
     if (status == 0)
        if (request->flags & DEL_REQ_FLAG_SUCCESS)
            deliver_completed(state->src, rcpt->offset);
index 30c3bbbf6796ebb145b1deca4414f2dd72755832..8d61564e51e0f4cb9ec2135144c234aaec74256f 100644 (file)
@@ -85,6 +85,10 @@ SMTP_STATE *smtp_state_alloc(void)
 #endif
 #ifdef USE_TLS
     state->reqtls_level = SMTP_REQTLS_POLICY_ACT_DISABLE;
+    if (var_log_tls_feature_status)
+       state->tls_stats = tls_stats_create();
+    else
+       state->tls_stats = 0;
 #endif
     if (var_smtp_cache_conn) {
        state->dest_label = vstring_alloc(10);
@@ -112,6 +116,8 @@ void    smtp_state_free(SMTP_STATE *state)
 #ifdef USE_TLS
     /* The TLS policy cache lifetime is one delivery. */
     smtp_tls_policy_cache_flush();
+    if (state->tls_stats)
+       tls_stats_free(state->tls_stats);
 #endif
     vstring_free(state->iterator->request_nexthop);
     vstring_free(state->iterator->dest);
index dd87f2979dcbc1cf132813255b34bab8aba8ed51..9c182790ed202aa40fdc13edd03c413183f120f6 100644 (file)
@@ -285,7 +285,8 @@ static int smtp_bulk_fail(SMTP_STATE *state, int flags)
            status = (soft_error ? defer_append : bounce_append)
                (DEL_REQ_TRACE_FLAGS(request->flags), request->queue_id,
                 &request->msg_stats, rcpt,
-                session ? session->namaddrport : "none", &why->dsn);
+                session ? session->namaddrport : "none", state->tls_stats,
+                &why->dsn);
            if (status == 0)
                deliver_completed(state->src, rcpt->offset);
            SMTP_RCPT_DROP(state, rcpt);
@@ -433,7 +434,8 @@ void    smtp_rcpt_fail(SMTP_STATE *state, RECIPIENT *rcpt, const char *mta_name,
        status = (soft_error ? defer_append : bounce_append)
            (DEL_REQ_TRACE_FLAGS(request->flags), request->queue_id,
             &request->msg_stats, rcpt,
-            session ? session->namaddrport : "none", &why->dsn);
+            session ? session->namaddrport : "none", state->tls_stats,
+            &why->dsn);
        if (status == 0)
            deliver_completed(state->src, rcpt->offset);
        SMTP_RCPT_DROP(state, rcpt);
index 75dd6cd2ede1d41d12022a8b0ef3c5cd39d86735..cde8035d5b2bbd16b46606058f0c7cc7170093b0 100644 (file)
@@ -102,10 +102,10 @@ typedef struct LOCAL_STATE {
 
 #define BOUNCE_ATTR(attr) \
        attr.queue_id, &attr.msg_stats, &attr.rcpt, attr.relay, \
-       DSN_FROM_DSN_BUF(attr.why)
+       NO_TLS_STATS, DSN_FROM_DSN_BUF(attr.why)
 #define SENT_ATTR(attr) \
        attr.queue_id, &attr.msg_stats, &attr.rcpt, attr.relay, \
-       DSN_FROM_DSN_BUF(attr.why)
+       NO_TLS_STATS, DSN_FROM_DSN_BUF(attr.why)
 #define COPY_ATTR(attr) \
        attr.sender, attr.rcpt.orig_addr, attr.delivered, attr.fp