On Thu, Jun 19, 2025 at 09:53:38PM +1000, Viktor Dukhovni via Postfix-users wrote:
> However, there's a problematic interaction with DANE TLSA records. > Patch below. I should not have trimmed the patch context so radically, better patch below, in case your sources are slightly older or newer. The patch merge base is 3.11-20250606. -- Viktor. --- a/src/smtp/smtp.h +++ b/src/smtp/smtp.h @@ -57,10 +57,11 @@ typedef struct SMTP_ITERATOR { VSTRING *request_nexthop; /* delivery request nexhop or empty */ VSTRING *dest; /* current nexthop */ VSTRING *host; /* hostname or empty */ VSTRING *addr; /* printable address or empty */ unsigned port; /* network byte order or null */ + int tlsreqno; /* "TLS-Required: no" */ struct DNS_RR *rr; /* DNS resource record or null */ struct DNS_RR *mx; /* DNS resource record or null */ /* Private members. */ VSTRING *saved_dest; /* saved current nexthop */ struct SMTP_STATE *parent; /* parent linkage */ @@ -69,10 +70,11 @@ typedef struct SMTP_ITERATOR { #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); \ + (iter)->tlsreqno = 0; \ (iter)->mx = (iter)->rr = 0; \ vstring_strcpy((iter)->saved_dest, ""); \ (iter)->parent = (state); \ } while (0) --- a/src/smtp/smtp_connect.c +++ b/src/smtp/smtp_connect.c @@ -505,10 +505,23 @@ static void smtp_cache_policy(SMTP_STATE *state, const char *dest) static int smtp_get_effective_tls_level(DSN_BUF *why, SMTP_STATE *state) { SMTP_ITERATOR *iter = state->iterator; SMTP_TLS_POLICY *tls = state->tls; + /* + * If the message contains a "TLS-Required: no" header, update the iterator + * to cap the policy at TLS_LEV_MAY. + * + * We must do this early to avoid possible failure if TLSA record lookups + * fail, of if TLSA records are found, but can't be activated because the + * security level has been reset to "may". + */ + if (var_tls_required_enable + && (state->request->sendopts & SOPT_REQUIRETLS_HEADER)) { + iter->tlsreqno = 1; + } + /* * Determine the TLS level for this destination. */ if (!smtp_tls_policy_cache_query(why, tls, iter)) { return (0); @@ -527,20 +540,10 @@ static int smtp_get_effective_tls_level(DSN_BUF *why, SMTP_STATE *state) return (0); } } #endif - /* - * Otherwise, if the TLS level is not TLS_LEV_NONE or some non-level, and - * the message contains a "TLS-Required: no" header, limit the level to - * TLS_LEV_MAY. - */ - else if (var_tls_required_enable && tls->level > TLS_LEV_NONE - && (state->request->sendopts & SOPT_REQUIRETLS_HEADER)) { - tls->level = TLS_LEV_MAY; - } - /* * Success. */ return (1); } --- a/src/smtp/smtp_tls_policy.c +++ b/src/smtp/smtp_tls_policy.c @@ -649,11 +649,14 @@ static void *policy_create(const char *unused_key, void *context) * and next-hop policies. */ tls->level = global_tls_level(); site_level = TLS_LEV_NOTFOUND; - if (tls_policy) { + if (iter->tlsreqno) { + if (tls->level > TLS_LEV_MAY) + tls->level = TLS_LEV_MAY; + } else if (tls_policy) { tls_policy_lookup(tls, &site_level, dest, "next-hop destination"); } else if (tls_per_site) { tls_site_lookup(tls, &site_level, dest, "next-hop destination"); if (site_level != TLS_LEV_INVALID && strcasecmp_utf8(dest, host) != 0) _______________________________________________ Postfix-users mailing list -- postfix-users@postfix.org To unsubscribe send an email to postfix-users-le...@postfix.org