]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
postfix-3.11-20250911
authorWietse Z Venema <wietse@porcupine.org>
Thu, 11 Sep 2025 05:00:00 +0000 (00:00 -0500)
committerViktor Dukhovni <ietf-dane@dukhovni.org>
Fri, 12 Sep 2025 11:07:54 +0000 (21:07 +1000)
postfix/HISTORY
postfix/proto/stop.double-history
postfix/src/global/mail_version.h
postfix/src/smtp/Makefile.in
postfix/src/smtp/smtp.h
postfix/src/smtp/smtp_key.c
postfix/src/smtp/smtp_proto.c

index bd2c2beecc2980fc79c398edf6b5112dfda8dab2..c2bc3dca6c0b04b807eb732ecc4958a29704a0b2 100644 (file)
@@ -29604,3 +29604,17 @@ Apologies for any names omitted.
        proto/postconf.proto, global/mail_params.h, smtp/lmtp_params.c,
        smtp/smtp.c, smtp/smtp.h, smtp/smtp_connect.c, smtp/smtp_params.c,
        smtp/smtp_tls_policy.c, smtp/smtp_tls_policy_test.c.
+
+20250911
+
+       Bugfix (defect introduced: Postfix 3.0): the Postfix SMTP
+       client's connection reuse logic did not distinguish between
+       sessions that require SMTPUTF8 support, and sessions that
+       do not. The solution is to store sessions with different
+       SMTPUTF8 requirements under distinct connection cache storage
+       keys, and to preserve the availability of SMTPUTF8 support
+       in the connection cache, so that a reused connection will
+       be stored under the same keys as it was looked up with.
+       Finally, do not cache a connection when SMTPUTF8 is
+       required but the server does not support that feature.
+       Files: smtp/smtp.h, smtp/smtp_key.c, smtp/smtp_proto.c.
index 78427bde68dc131162acaf657195547648f5017c..913a3083f72858feb370cf334e6c4163805ccc1a 100644 (file)
@@ -196,3 +196,5 @@ proto  proto COMPATIBILITY_README html
  request Reported by John Doe File tlsproxy tlsproxy c 
  smtpd smtpd c smtpd smtpd_chat c global mail_params h 
  Files Makefile in smtp smtp h smtp smtp_connect c 
+ smtp smtp c smtp smtp h smtp smtp_connect c smtp smtp_params c 
+ Files smtp smtp h smtp smtp_key c smtp smtp_proto c 
index 564e97222ff7b005b6be191967b53b497698d8c1..14d4e2ad5f67a91de990b3902193673e395f4357 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      "20250911"
 #define MAIL_VERSION_NUMBER    "3.11"
 
 #ifdef SNAPSHOT
index 25002c658d5ec83d6d58e2a09c53ba31ad85cc63..9b812f50ea39b26354b8b961ac6d9a5bb1a21b2f 100644 (file)
@@ -315,6 +315,7 @@ smtp_key.o: ../../include/recipient_list.h
 smtp_key.o: ../../include/resolve_clnt.h
 smtp_key.o: ../../include/scache.h
 smtp_key.o: ../../include/sendopts.h
+smtp_key.o: ../../include/smtputf8.h
 smtp_key.o: ../../include/sock_addr.h
 smtp_key.o: ../../include/string_list.h
 smtp_key.o: ../../include/sys_defs.h
index 28cca83a44bd2f2d564bcd26a3bdb96f3d8de7e4..5ce798d02f36317fa8ca1603c9d29fdf4fdb8cc3 100644 (file)
@@ -137,7 +137,7 @@ typedef struct SMTP_TLS_POLICY {
 extern void smtp_tls_list_init(void);
 extern int smtp_tls_policy_cache_query(DSN_BUF *, SMTP_TLS_POLICY *, SMTP_ITERATOR *);
 extern void smtp_tls_policy_cache_flush(void);
-extern int  smtp_tls_authorize_mx_hostname(SMTP_TLS_POLICY *, const char *);
+extern int smtp_tls_authorize_mx_hostname(SMTP_TLS_POLICY *, const char *);
 
  /*
   * Macros must use distinct names for local temporary variables, otherwise
@@ -692,12 +692,14 @@ char   *smtp_key_prefix(VSTRING *, const char *, SMTP_ITERATOR *, int);
 #define SMTP_KEY_FLAG_ADDR             (1<<5)  /* remote address */
 #define SMTP_KEY_FLAG_PORT             (1<<6)  /* remote port */
 #define SMTP_KEY_FLAG_TLS_LEVEL                (1<<7)  /* requested TLS level */
+#define SMTP_KEY_FLAG_REQ_SMTPUTF8     (1<<8)  /* SMTPUTF8 is required */
 
 #define SMTP_KEY_MASK_ALL \
        (SMTP_KEY_FLAG_SERVICE | SMTP_KEY_FLAG_SENDER | \
        SMTP_KEY_FLAG_REQ_NEXTHOP | \
        SMTP_KEY_FLAG_CUR_NEXTHOP | SMTP_KEY_FLAG_HOSTNAME | \
-       SMTP_KEY_FLAG_ADDR | SMTP_KEY_FLAG_PORT | SMTP_KEY_FLAG_TLS_LEVEL)
+       SMTP_KEY_FLAG_ADDR | SMTP_KEY_FLAG_PORT | SMTP_KEY_FLAG_TLS_LEVEL | \
+       SMTP_KEY_FLAG_REQ_SMTPUTF8)
 
  /*
   * Conditional lookup-key flags for cached connections that may be
@@ -733,10 +735,15 @@ char   *smtp_key_prefix(VSTRING *, const char *, SMTP_ITERATOR *, int);
   * (REQ_NEXTHOP) prevents false sharing of TLS identities (the destination
   * key links only to appropriate endpoint lookup keys). The SERVICE
   * attribute is a proxy for all request-independent configuration details.
+  * 
+  * Be sure to include all features that are preserved in
+  * SMTP_FEATURE_ENDPOINT_MASK, otherwise a reused connection may be stored
+  * under the wrong key.
   */
 #define SMTP_KEY_MASK_SCACHE_DEST_LABEL \
        (SMTP_KEY_FLAG_SERVICE | COND_SASL_SMTP_KEY_FLAG_SENDER \
-       | SMTP_KEY_FLAG_REQ_NEXTHOP | SMTP_KEY_FLAG_TLS_LEVEL)
+       | SMTP_KEY_FLAG_REQ_NEXTHOP | SMTP_KEY_FLAG_TLS_LEVEL \
+       | SMTP_KEY_FLAG_REQ_SMTPUTF8)
 
  /*
   * Connection-cache endpoint lookup key. The SENDER, CUR_NEXTHOP, HOSTNAME,
@@ -745,13 +752,18 @@ char   *smtp_key_prefix(VSTRING *, const char *, SMTP_ITERATOR *, int);
   * when different SASL credentials or TLS identities may be required for
   * different deliveries to the same IP address and port. The SERVICE
   * attribute is a proxy for all request-independent configuration details.
+  * 
+  * Be sure to include all features that are preserved in
+  * SMTP_FEATURE_ENDPOINT_MASK, otherwise a reused connection may be stored
+  * under the wrong key.
   */
 #define SMTP_KEY_MASK_SCACHE_ENDP_LABEL \
        (SMTP_KEY_FLAG_SERVICE | COND_SASL_SMTP_KEY_FLAG_SENDER \
        | COND_SASL_SMTP_KEY_FLAG_CUR_NEXTHOP \
        | COND_SASL_SMTP_KEY_FLAG_HOSTNAME \
-       | COND_TLS_SMTP_KEY_FLAG_CUR_NEXTHOP | SMTP_KEY_FLAG_ADDR | \
-       SMTP_KEY_FLAG_PORT | SMTP_KEY_FLAG_TLS_LEVEL)
+       | COND_TLS_SMTP_KEY_FLAG_CUR_NEXTHOP | SMTP_KEY_FLAG_ADDR \
+       | SMTP_KEY_FLAG_PORT | SMTP_KEY_FLAG_TLS_LEVEL \
+       | SMTP_KEY_FLAG_REQ_SMTPUTF8)
 
  /*
   * Silly little macros.
@@ -808,6 +820,24 @@ extern void smtp_tlsrpt_set_ehlo_resp(SMTP_STATE *, const char *ehlo_resp);
 
 #endif                                 /* USE_TLSRPT && USE_TLS */
 
+ /*
+  * This delivery requires SMTPUTF8 server support if the sender requested
+  * SMTPUTF8 support AND the delivery request involves at least one UTF-8
+  * envelope address or header value.
+  * 
+  * If the sender requested SMTPUTF8 support but the delivery request involves
+  * no UTF-8 envelope address or header value, then we could still deliver
+  * such mail to a non-SMTPUTF8 server, except that we must either
+  * uxtext-encode ORCPT parameters or not send them. We cannot encode the
+  * ORCPT in xtext, because legacy SMTP requires that the unencoded address
+  * consist entirely of printable (graphic and white space) characters from
+  * the US-ASCII repertoire (RFC 3461 section 4). A correct uxtext encoder
+  * will produce a result that an xtext decoder will pass through unchanged.
+  */
+#define DELIVERY_REQUIRES_SMTPUTF8(request) \
+       (((request)->sendopts & SMTPUTF8_FLAG_REQUESTED) \
+       && ((request)->sendopts & SMTPUTF8_FLAG_DERIVED))
+
 /* LICENSE
 /* .ad
 /* .fi
index 643f4db7e61d978e4c35d1efd453cd12df2b9667..7f52f8298d45a9917c47868ffe1dcfd1a45c27e8 100644 (file)
 /*     The current iterator's remote address.
 /* .IP SMTP_KEY_FLAG_PORT
 /*     The current iterator's remote port.
+/* .IP SMTP_KEY_FLAG_TLS_LEVEL
+/*     The requested TLS security level.
+/* .IP SMTP_KEY_FLAG_REQ_SMTPUTF8
+/*     Whether SMTPUTF8 support is required.
 /* .RE
 /* DIAGNOSTICS
 /*     Panic: undefined flag or zero flags. Fatal: out of memory.
   * Global library.
   */
 #include <mail_params.h>
+#include <smtputf8.h>
 
  /*
   * Application-specific.
@@ -209,6 +214,20 @@ char   *smtp_key_prefix(VSTRING *buffer, const char *delim_na,
        smtp_key_append_na(buffer, delim_na);
 #endif
 
+    /*
+     * Require SMTPUTF8 support, if applicable. TODO(wietse) if a delivery
+     * request does not need SMTPUTF8, should we also search the connection
+     * cache for a connection that is known to support it? No, because the
+     * connection would be saved back under a key that does not require
+     * SMTPUTF8 support.
+     */
+    if (flags & SMTP_KEY_FLAG_REQ_SMTPUTF8)
+       smtp_key_append_uint(buffer,
+                            DELIVERY_REQUIRES_SMTPUTF8(state->request),
+                            delim_na);
+    else
+       smtp_key_append_na(buffer, delim_na);
+
     VSTRING_TERMINATE(buffer);
 
     return STR(buffer);
index b8968637819ed93ea397d7a8e5a3dd7985b75a9e..f93d57b5bcde714ab85520cfe484592b5dc5c760 100644 (file)
@@ -626,46 +626,24 @@ int     smtp_helo(SMTP_STATE *state)
        msg_info("server features: 0x%x size %.0f",
                 session->features, (double) session->size_limit);
 
-    /*
-     * Decide if this delivery requires SMTPUTF8 server support.
-     * 
-     * For now, we require that the remote SMTP server supports SMTPUTF8 when
-     * the sender requested SMTPUTF8 support.
-     * 
-     * XXX EAI Refine this to: the sender requested SMTPUTF8 support AND the
-     * delivery request involves at least one UTF-8 envelope address or
-     * header value.
-     * 
-     * If the sender requested SMTPUTF8 support but the delivery request
-     * involves no UTF-8 envelope address or header value, then we could
-     * still deliver such mail to a non-SMTPUTF8 server, except that we must
-     * either uxtext-encode ORCPT parameters or not send them. We cannot
-     * encode the ORCPT in xtext, because legacy SMTP requires that the
-     * unencoded address consist entirely of printable (graphic and white
-     * space) characters from the US-ASCII repertoire (RFC 3461 section 4). A
-     * correct uxtext encoder will produce a result that an xtext decoder
-     * will pass through unchanged.
-     * 
-     * XXX Should we try to encode headers with RFC 2047 when delivering to a
-     * non-SMTPUTF8 server? That could make life easier for mailing lists.
-     */
-#define DELIVERY_REQUIRES_SMTPUTF8 \
-       ((request->sendopts & SMTPUTF8_FLAG_REQUESTED) \
-       && (request->sendopts & SMTPUTF8_FLAG_DERIVED))
-
     /*
      * Require that the server supports SMTPUTF8 when delivery requires
      * SMTPUTF8.
      * 
      * Fix 20140706: moved this before negotiating TLS, AUTH, and so on.
+     * 
+     * Fix 20250911: do not cache this session because it does not satisfy the
+     * requirement expressed in the cache storage key.
      */
     if ((session->features & SMTP_FEATURE_SMTPUTF8) == 0
-       && DELIVERY_REQUIRES_SMTPUTF8)
+       && DELIVERY_REQUIRES_SMTPUTF8(request)) {
+       DONT_CACHE_THIS_SESSION;
        return (smtp_mesg_fail(state, DSN_BY_LOCAL_MTA,
                               SMTP_RESP_FAKE(&fake, "5.6.7"),
                               "SMTPUTF8 is required, "
                               "but was not offered by host %s",
                               session->namaddr));
+    }
 
     /*
      * Fix 20140706: don't do silly things when the remote server announces