From 5c253cc5c977dd82176cd7de880572d425428665 Mon Sep 17 00:00:00 2001 From: Wietse Z Venema Date: Fri, 8 Aug 2025 00:00:00 -0500 Subject: [PATCH] postfix-3.11-20250808 --- postfix/HISTORY | 13 ++++++-- postfix/html/postconf.5.html | 3 +- postfix/man/man5/postconf.5 | 3 +- postfix/proto/postconf.proto | 3 +- postfix/src/global/mail_version.h | 2 +- postfix/src/smtp/Makefile.in | 16 +++++++++ postfix/src/smtp/smtp.h | 17 ++++------ postfix/src/smtp/smtp_connect.c | 53 +++++------------------------- postfix/src/smtp/smtp_tls_policy.c | 9 ++++- 9 files changed, 57 insertions(+), 62 deletions(-) diff --git a/postfix/HISTORY b/postfix/HISTORY index 8aec6eb2d..487698196 100644 --- a/postfix/HISTORY +++ b/postfix/HISTORY @@ -29556,6 +29556,15 @@ Apologies for any names omitted. 20250807 - Bugfix (defect introduced: 20250803): "TLS-Required: no" was - no longer in effect for LMTP deliveries. Viktor Dukhovni. + Bugfix (defect introduced: 20250803): "TLS-Required: no" + was no longer in effect for deliveries over UNIX-domain + sockets (which are supported for LMTP only). Viktor Dukhovni. File: smtp/smtp_connect.c. + +20250808 + + Cleanup: simplify the code to determine if "TLS-Required: + no" is in effect, and improve the tls_required_enable + documentation. This will be back-ported to Postfix 3.10. + Files: Makefile.in, smtp/smtp.h smtp/smtp_connect.c, + smtp/smtp_tls_policy.c, proto/postconf.proto. diff --git a/postfix/html/postconf.5.html b/postfix/html/postconf.5.html index ba54bb4d8..1f4b51a07 100644 --- a/postfix/html/postconf.5.html +++ b/postfix/html/postconf.5.html @@ -20846,7 +20846,8 @@ gives timeout errors.

Enable support for the "TLS-Required: no" message header, defined in RFC 8689. By adding this header to a message, a sender requests -no enforcement of TLS policy. This limits the Postfix SMTP client +no enforcement of TLS policy. This disables TLS policy lookup, and +limits the Postfix SMTP client TLS security level to "may", that is, do not verify remote SMTP server certificates, and fall back to plaintext if TLS is unavailable. If a message contains a "TLS-Required: no" header, then Postfix diff --git a/postfix/man/man5/postconf.5 b/postfix/man/man5/postconf.5 index d3aadfa04..22757a2e1 100644 --- a/postfix/man/man5/postconf.5 +++ b/postfix/man/man5/postconf.5 @@ -14581,7 +14581,8 @@ This feature is available in Postfix 2.2 and later. .SH tls_required_enable (default: yes) Enable support for the "TLS\-Required: no" message header, defined in RFC 8689. By adding this header to a message, a sender requests -no enforcement of TLS policy. This limits the Postfix SMTP client +no enforcement of TLS policy. This disables TLS policy lookup, and +limits the Postfix SMTP client TLS security level to "may", that is, do not verify remote SMTP server certificates, and fall back to plaintext if TLS is unavailable. If a message contains a "TLS\-Required: no" header, then Postfix diff --git a/postfix/proto/postconf.proto b/postfix/proto/postconf.proto index bc95018b5..4b0ca1212 100644 --- a/postfix/proto/postconf.proto +++ b/postfix/proto/postconf.proto @@ -19616,7 +19616,8 @@ including the netstring encapsulation.

Enable support for the "TLS-Required: no" message header, defined in RFC 8689. By adding this header to a message, a sender requests -no enforcement of TLS policy. This limits the Postfix SMTP client +no enforcement of TLS policy. This disables TLS policy lookup, and +limits the Postfix SMTP client TLS security level to "may", that is, do not verify remote SMTP server certificates, and fall back to plaintext if TLS is unavailable. If a message contains a "TLS-Required: no" header, then Postfix diff --git a/postfix/src/global/mail_version.h b/postfix/src/global/mail_version.h index 1836742ea..35107f32b 100644 --- a/postfix/src/global/mail_version.h +++ b/postfix/src/global/mail_version.h @@ -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 "20250807" +#define MAIL_RELEASE_DATE "20250808" #define MAIL_VERSION_NUMBER "3.11" #ifdef SNAPSHOT diff --git a/postfix/src/smtp/Makefile.in b/postfix/src/smtp/Makefile.in index 44add46b2..f8cde6978 100644 --- a/postfix/src/smtp/Makefile.in +++ b/postfix/src/smtp/Makefile.in @@ -113,6 +113,7 @@ smtp.o: ../../include/nvtable.h smtp.o: ../../include/recipient_list.h smtp.o: ../../include/resolve_clnt.h smtp.o: ../../include/scache.h +smtp.o: ../../include/sendopts.h smtp.o: ../../include/sock_addr.h smtp.o: ../../include/string_list.h smtp.o: ../../include/stringops.h @@ -158,6 +159,7 @@ smtp_addr.o: ../../include/own_inet_addr.h smtp_addr.o: ../../include/recipient_list.h smtp_addr.o: ../../include/resolve_clnt.h smtp_addr.o: ../../include/scache.h +smtp_addr.o: ../../include/sendopts.h smtp_addr.o: ../../include/sock_addr.h smtp_addr.o: ../../include/string_list.h smtp_addr.o: ../../include/stringops.h @@ -304,6 +306,7 @@ smtp_key.o: ../../include/nvtable.h 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/sock_addr.h smtp_key.o: ../../include/string_list.h smtp_key.o: ../../include/sys_defs.h @@ -344,6 +347,7 @@ smtp_map11.o: ../../include/quote_flags.h smtp_map11.o: ../../include/recipient_list.h smtp_map11.o: ../../include/resolve_clnt.h smtp_map11.o: ../../include/scache.h +smtp_map11.o: ../../include/sendopts.h smtp_map11.o: ../../include/sock_addr.h smtp_map11.o: ../../include/string_list.h smtp_map11.o: ../../include/sys_defs.h @@ -384,6 +388,7 @@ smtp_misc.o: ../../include/quote_flags.h smtp_misc.o: ../../include/recipient_list.h smtp_misc.o: ../../include/resolve_clnt.h smtp_misc.o: ../../include/scache.h +smtp_misc.o: ../../include/sendopts.h smtp_misc.o: ../../include/sock_addr.h smtp_misc.o: ../../include/string_list.h smtp_misc.o: ../../include/sys_defs.h @@ -491,6 +496,7 @@ smtp_rcpt.o: ../../include/nvtable.h smtp_rcpt.o: ../../include/recipient_list.h smtp_rcpt.o: ../../include/resolve_clnt.h smtp_rcpt.o: ../../include/scache.h +smtp_rcpt.o: ../../include/sendopts.h smtp_rcpt.o: ../../include/sent.h smtp_rcpt.o: ../../include/sock_addr.h smtp_rcpt.o: ../../include/string_list.h @@ -530,6 +536,7 @@ smtp_reuse.o: ../../include/nvtable.h smtp_reuse.o: ../../include/recipient_list.h smtp_reuse.o: ../../include/resolve_clnt.h smtp_reuse.o: ../../include/scache.h +smtp_reuse.o: ../../include/sendopts.h smtp_reuse.o: ../../include/sock_addr.h smtp_reuse.o: ../../include/string_list.h smtp_reuse.o: ../../include/stringops.h @@ -572,6 +579,7 @@ smtp_sasl_auth_cache.o: ../../include/nvtable.h smtp_sasl_auth_cache.o: ../../include/recipient_list.h smtp_sasl_auth_cache.o: ../../include/resolve_clnt.h smtp_sasl_auth_cache.o: ../../include/scache.h +smtp_sasl_auth_cache.o: ../../include/sendopts.h smtp_sasl_auth_cache.o: ../../include/sock_addr.h smtp_sasl_auth_cache.o: ../../include/string_list.h smtp_sasl_auth_cache.o: ../../include/stringops.h @@ -613,6 +621,7 @@ smtp_sasl_glue.o: ../../include/nvtable.h smtp_sasl_glue.o: ../../include/recipient_list.h smtp_sasl_glue.o: ../../include/resolve_clnt.h smtp_sasl_glue.o: ../../include/scache.h +smtp_sasl_glue.o: ../../include/sendopts.h smtp_sasl_glue.o: ../../include/smtp_stream.h smtp_sasl_glue.o: ../../include/sock_addr.h smtp_sasl_glue.o: ../../include/split_at.h @@ -657,6 +666,7 @@ smtp_sasl_proto.o: ../../include/recipient_list.h smtp_sasl_proto.o: ../../include/resolve_clnt.h smtp_sasl_proto.o: ../../include/sasl_mech_filter.h smtp_sasl_proto.o: ../../include/scache.h +smtp_sasl_proto.o: ../../include/sendopts.h smtp_sasl_proto.o: ../../include/sock_addr.h smtp_sasl_proto.o: ../../include/string_list.h smtp_sasl_proto.o: ../../include/stringops.h @@ -697,6 +707,7 @@ smtp_session.o: ../../include/nvtable.h smtp_session.o: ../../include/recipient_list.h smtp_session.o: ../../include/resolve_clnt.h smtp_session.o: ../../include/scache.h +smtp_session.o: ../../include/sendopts.h smtp_session.o: ../../include/sock_addr.h smtp_session.o: ../../include/string_list.h smtp_session.o: ../../include/stringops.h @@ -737,6 +748,7 @@ smtp_state.o: ../../include/nvtable.h smtp_state.o: ../../include/recipient_list.h smtp_state.o: ../../include/resolve_clnt.h smtp_state.o: ../../include/scache.h +smtp_state.o: ../../include/sendopts.h smtp_state.o: ../../include/sock_addr.h smtp_state.o: ../../include/string_list.h smtp_state.o: ../../include/sys_defs.h @@ -778,6 +790,7 @@ smtp_tls_policy.o: ../../include/recipient_list.h smtp_tls_policy.o: ../../include/resolve_clnt.h smtp_tls_policy.o: ../../include/sane_strtol.h smtp_tls_policy.o: ../../include/scache.h +smtp_tls_policy.o: ../../include/sendopts.h smtp_tls_policy.o: ../../include/sock_addr.h smtp_tls_policy.o: ../../include/string_list.h smtp_tls_policy.o: ../../include/stringops.h @@ -821,6 +834,7 @@ smtp_tlsrpt.o: ../../include/nvtable.h smtp_tlsrpt.o: ../../include/recipient_list.h smtp_tlsrpt.o: ../../include/resolve_clnt.h smtp_tlsrpt.o: ../../include/scache.h +smtp_tlsrpt.o: ../../include/sendopts.h smtp_tlsrpt.o: ../../include/sock_addr.h smtp_tlsrpt.o: ../../include/string_list.h smtp_tlsrpt.o: ../../include/stringops.h @@ -864,6 +878,7 @@ smtp_trouble.o: ../../include/nvtable.h smtp_trouble.o: ../../include/recipient_list.h smtp_trouble.o: ../../include/resolve_clnt.h smtp_trouble.o: ../../include/scache.h +smtp_trouble.o: ../../include/sendopts.h smtp_trouble.o: ../../include/smtp_stream.h smtp_trouble.o: ../../include/sock_addr.h smtp_trouble.o: ../../include/string_list.h @@ -903,6 +918,7 @@ smtp_unalias.o: ../../include/nvtable.h smtp_unalias.o: ../../include/recipient_list.h smtp_unalias.o: ../../include/resolve_clnt.h smtp_unalias.o: ../../include/scache.h +smtp_unalias.o: ../../include/sendopts.h smtp_unalias.o: ../../include/sock_addr.h smtp_unalias.o: ../../include/string_list.h smtp_unalias.o: ../../include/sys_defs.h diff --git a/postfix/src/smtp/smtp.h b/postfix/src/smtp/smtp.h index 16aad5c6c..874f9481c 100644 --- a/postfix/src/smtp/smtp.h +++ b/postfix/src/smtp/smtp.h @@ -32,6 +32,7 @@ #include #include #include +#include /* * Postfix TLS library. @@ -59,9 +60,6 @@ typedef struct SMTP_ITERATOR { VSTRING *host; /* hostname or empty */ VSTRING *addr; /* printable address or empty */ unsigned port; /* network byte order or null */ -#ifdef USE_TLS - int tlsreqno; /* "TLS-Required: no" */ -#endif struct DNS_RR *rr; /* DNS resource record or null */ struct DNS_RR *mx; /* DNS resource record or null */ /* Private members. */ @@ -69,18 +67,11 @@ typedef struct SMTP_ITERATOR { struct SMTP_STATE *parent; /* parent linkage */ } SMTP_ITERATOR; -#ifdef USE_TLS -#define IF_USE_TLS(...) (__VA_ARGS__) -#else -#define IF_USE_TLS(...) -#endif - #define SMTP_ITER_INIT(iter, _dest, _host, _addr, _port, state) do { \ vstring_strcpy((iter)->dest, (_dest)); \ vstring_strcpy((iter)->host, (_host)); \ vstring_strcpy((iter)->addr, (_addr)); \ (iter)->port = (_port); \ - IF_USE_TLS((iter)->tlsreqno = 0); \ (iter)->mx = (iter)->rr = 0; \ vstring_strcpy((iter)->saved_dest, ""); \ (iter)->parent = (state); \ @@ -248,6 +239,12 @@ typedef struct SMTP_STATE { unsigned logged_line_length_limit:1; } SMTP_STATE; +#ifdef USE_TLS +#define STATE_TLS_NOT_REQUIRED(state) \ + (var_tls_required_enable && \ + ((state)->request->sendopts & SOPT_REQUIRETLS_HEADER)) +#endif + /* * Primitives to enable/disable/test connection caching and reuse based on * the delivery request next-hop destination (i.e. not smtp_fallback_relay). diff --git a/postfix/src/smtp/smtp_connect.c b/postfix/src/smtp/smtp_connect.c index 24f5c76ce..fb3494523 100644 --- a/postfix/src/smtp/smtp_connect.c +++ b/postfix/src/smtp/smtp_connect.c @@ -575,24 +575,6 @@ static void smtp_connect_local(SMTP_STATE *state, const char *path) SMTP_ITER_INIT(iter, path, var_myhostname, path, NO_PORT, state); - /* - * If a "TLS-Required: no" header is in effect, update the iterator to - * override TLS policy selection and to limit the security level to - * "may". Do not reset the security level after policy selection, as that - * would result in errors. For example, when TLSA records are looked up - * for security level "dane", and then the security level is reset to - * "may", the activation of those TLSA records will fail. - * - * Note that the REQUIRETLS verb in ESMTP overrides the "TLS-Required: no" - * header. - */ -#ifdef USE_TLS - if (var_tls_required_enable - && (state->request->sendopts & SOPT_REQUIRETLS_HEADER)) { - iter->tlsreqno = 1; - } -#endif - /* * Opportunistic TLS for unix domain sockets does not make much sense, * since the channel is private, mere encryption without authentication @@ -600,9 +582,9 @@ static void smtp_connect_local(SMTP_STATE *state, const char *path) * willing to retry after TLS handshake failures here, we downgrade "may" * no "none". Nothing is lost, and much waste is avoided. * - * We don't know who is authenticating whom, so if a client cert is - * available, "encrypt" may be a sensible policy. Otherwise, we also - * downgrade "encrypt" to "none", this time just to avoid waste. + * If a client cert is available, "encrypt" may be a sensible policy. + * Without client cert, "encrypt" and "may" over UNIX-domain sockets are + * not useful. * * We use smtp_reuse_nexthop() instead of smtp_reuse_addr(), so that we can * reuse a SASL-authenticated connection (however unlikely this scenario @@ -970,24 +952,6 @@ static void smtp_connect_inet(SMTP_STATE *state, const char *nexthop, SMTP_ITER_INIT(iter, dest, NO_HOST, NO_ADDR, port, state); - /* - * If a "TLS-Required: no" header is in effect, update the iterator - * to override TLS policy selection and to limit the security level - * to "may". Do not reset the security level after policy selection, - * as that would result in errors. For example, when TLSA records are - * looked up for security level "dane", and then the security level - * is reset to "may", the activation of those TLSA records will fail. - * - * Note that the REQUIRETLS verb in ESMTP overrides the "TLS-Required: - * no" header. - */ -#ifdef USE_TLS - if (var_tls_required_enable - && (state->request->sendopts & SOPT_REQUIRETLS_HEADER)) { - iter->tlsreqno = 1; - } -#endif - /* * TODO(wietse) If the domain publishes a TLSRPT policy, they expect * that clients use SMTP over TLS. Should we upgrade a TLS security @@ -995,15 +959,14 @@ static void smtp_connect_inet(SMTP_STATE *state, const char *nexthop, * plaintext, and could break interoperability with receivers that * crank up security up to 11. * - * As of change 20250803, with "TLS-Required: no", the SMTP client also - * ignores the recipient-side policy mechanism TLSRPT, in addition to - * the already ignored DANE and MTA-STS mechanisms. This prevents - * TLSRPT notifications for all SMTP deliveries that do not require - * TLS. + * With "TLS-Required: no" in effect, the SMTP client ignores the + * recipient-side policy mechanism TLSRPT, in addition to the already + * ignored DANE and MTA-STS mechanisms. This prevents TLSRPT + * notifications for all SMTP deliveries that do not require TLS. */ #ifdef USE_TLSRPT if (smtp_mode && var_smtp_tlsrpt_enable - && iter->tlsreqno == 0 + && STATE_TLS_NOT_REQUIRED(state) == 0 && tls_level_lookup(var_smtp_tls_level) > TLS_LEV_NONE && !valid_hostaddr(domain, DONT_GRIPE)) smtp_tlsrpt_create_wrapper(state, domain); diff --git a/postfix/src/smtp/smtp_tls_policy.c b/postfix/src/smtp/smtp_tls_policy.c index 6b9ee66e6..809ffea05 100644 --- a/postfix/src/smtp/smtp_tls_policy.c +++ b/postfix/src/smtp/smtp_tls_policy.c @@ -647,11 +647,18 @@ static void *policy_create(const char *unused_key, void *context) * Compute the per-site TLS enforcement level. For compatibility with the * original TLS patch, this algorithm is gives equal precedence to host * and next-hop policies. + * + * When "TLS-Required: no" is in effect, skip TLS policy lookup and limit + * the security level to "may". Do not reset the security level after + * policy lookup, as that would result in errors. For example, when TLSA + * records are looked up for security level "dane", and then the security + * level is reset to "may", the activation of those TLSA records will + * fail. */ tls->level = global_tls_level(); site_level = TLS_LEV_NOTFOUND; - if (iter->tlsreqno) { + if (STATE_TLS_NOT_REQUIRED(iter->parent)) { if (msg_verbose) msg_info("%s: no tls policy lookup", __func__); if (tls->level > TLS_LEV_MAY)