diff options
Diffstat (limited to 'debian/patches/82_TLS-use-RFC-6125-rules-for-certifucate-name-checks-w.patch')
-rw-r--r-- | debian/patches/82_TLS-use-RFC-6125-rules-for-certifucate-name-checks-w.patch | 188 |
1 files changed, 188 insertions, 0 deletions
diff --git a/debian/patches/82_TLS-use-RFC-6125-rules-for-certifucate-name-checks-w.patch b/debian/patches/82_TLS-use-RFC-6125-rules-for-certifucate-name-checks-w.patch new file mode 100644 index 0000000..10e54e3 --- /dev/null +++ b/debian/patches/82_TLS-use-RFC-6125-rules-for-certifucate-name-checks-w.patch @@ -0,0 +1,188 @@ +Description: TLS: use RFC 6125 rules for certificate name checks when + CNAMES are present. Bug 2594 +Origin: upstream https://git.exim.org/exim.git/commit/0851a3bbf4667081d47f5d85b6b3a5cb33cbdba6 +Bug: https://bugs.exim.org/show_bug.cgi?id=2594 +Forwarded: not-needed +Last-Update: 2021-03-02 + +--- a/doc/ChangeLog ++++ b/doc/ChangeLog +@@ -41,10 +41,15 @@ JH/10 OpenSSL: Fix aggregation of messag + + JH/11 Harden plaintext authenticator against a badly misconfigured client-send + string. Previously it was possible to cause undefined behaviour in a + library routine (usually a crash). Found by "zerons". + ++JH/06 Bug 2594: Change the name used for certificate name checks in the smtp ++ transport. Previously it was the name on the DNS A-record; use instead ++ the head of the CNAME chain leading there (if there is one). This seems ++ to align better with RFC 6125. ++ + + JH/18 GnuTLS: fix $tls_out_ocsp under hosts_request_ocsp. Previously the + verification result was not updated unless hosts_require_ocsp applied. + + JH/20 Bug 2389: fix server advertising of usable certificates, under GnuTLS in +--- a/src/host.c ++++ b/src/host.c +@@ -1966,10 +1966,17 @@ host_item *last = NULL; + BOOL temp_error = FALSE; + #if HAVE_IPV6 + int af; + #endif + ++#ifndef DISABLE_TLS ++/* Copy the host name at this point to the value which is used for ++TLS certificate name checking, before anything modifies it. */ ++ ++host->certname = host->name; ++#endif ++ + /* Make sure DNS options are set as required. This appears to be necessary in + some circumstances when the get..byname() function actually calls the DNS. */ + + dns_init((flags & HOST_FIND_QUALIFY_SINGLE) != 0, + (flags & HOST_FIND_SEARCH_PARENTS) != 0, +@@ -2132,10 +2139,13 @@ for (i = 1; i <= times; + + else + { + host_item *next = store_get(sizeof(host_item)); + next->name = host->name; ++#ifndef DISABLE_TLS ++ next->certname = host->certname; ++#endif + next->mx = host->mx; + next->address = text_address; + next->port = PORT_NONE; + next->status = hstatus_unknown; + next->why = hwhy_unknown; +@@ -2150,16 +2160,16 @@ for (i = 1; i <= times; + + /* If no hosts were found, the address field in the original host block will be + NULL. If temp_error is set, at least one of the lookups gave a temporary error, + so we pass that back. */ + +-if (host->address == NULL) ++if (!host->address) + { + uschar *msg = + #ifndef STAND_ALONE +- (message_id[0] == 0 && smtp_in != NULL)? +- string_sprintf("no IP address found for host %s (during %s)", host->name, ++ message_id[0] == 0 && smtp_in ++ ? string_sprintf("no IP address found for host %s (during %s)", host->name, + smtp_get_connection_info()) : + #endif + string_sprintf("no IP address found for host %s", host->name); + + HDEBUG(D_host_lookup) debug_printf("%s\n", msg); +@@ -2277,10 +2287,17 @@ dns_record *rr; + host_item *thishostlast = NULL; /* Indicates not yet filled in anything */ + BOOL v6_find_again = FALSE; + BOOL dnssec_fail = FALSE; + int i; + ++#ifndef DISABLE_TLS ++/* Copy the host name at this point to the value which is used for ++TLS certificate name checking, before any CNAME-following modifies it. */ ++ ++host->certname = host->name; ++#endif ++ + /* If allow_ip is set, a name which is an IP address returns that value + as its address. This is used for MX records when allow_mx_to_ip is set, for + those sites that feel they have to flaunt the RFC rules. */ + + if (allow_ip && string_is_ip_address(host->name, NULL) != 0) +--- a/src/structs.h ++++ b/src/structs.h +@@ -77,18 +77,21 @@ host addresses is done using this struct + + typedef enum {DS_UNK=-1, DS_NO, DS_YES} dnssec_status_t; + + typedef struct host_item { + struct host_item *next; +- const uschar *name; /* Host name */ +- const uschar *address; /* IP address in text form */ +- int port; /* port value in host order (if SRV lookup) */ +- int mx; /* MX value if found via MX records */ +- int sort_key; /* MX*1000 plus random "fraction" */ +- int status; /* Usable, unusable, or unknown */ +- int why; /* Why host is unusable */ +- int last_try; /* Time of last try if known */ ++ const uschar *name; /* Host name */ ++#ifndef DISABLE_TLS ++ const uschar *certname; /* Name used for certificate checks */ ++#endif ++ const uschar *address; /* IP address in text form */ ++ int port; /* port value in host order (if SRV lookup) */ ++ int mx; /* MX value if found via MX records */ ++ int sort_key; /* MX*1000 plus random "fraction" */ ++ int status; /* Usable, unusable, or unknown */ ++ int why; /* Why host is unusable */ ++ int last_try; /* Time of last try if known */ + dnssec_status_t dnssec; + } host_item; + + /* Chain of rewrite rules, read from the rewrite config, or parsed from the + rewrite_headers field of a transport. */ +--- a/src/tls-gnu.c ++++ b/src/tls-gnu.c +@@ -2191,13 +2191,13 @@ tls_client_setup_hostname_checks(host_it + { + if (verify_check_given_host(CUSS &ob->tls_verify_cert_hostnames, host) == OK) + { + state->exp_tls_verify_cert_hostnames = + #ifdef SUPPORT_I18N +- string_domain_utf8_to_alabel(host->name, NULL); ++ string_domain_utf8_to_alabel(host->certname, NULL); + #else +- host->name; ++ host->certname; + #endif + DEBUG(D_tls) + debug_printf("TLS: server cert verification includes hostname: \"%s\".\n", + state->exp_tls_verify_cert_hostnames); + } +--- a/src/tls-openssl.c ++++ b/src/tls-openssl.c +@@ -309,18 +309,18 @@ typedef struct tls_ext_ctx_cb { + X509_STORE *verify_store; /* non-null if status requested */ + BOOL verify_required; + } client; + } u_ocsp; + #endif +- uschar *dhparam; ++ uschar * dhparam; + /* these are cached from first expand */ +- uschar *server_cipher_list; ++ uschar * server_cipher_list; + /* only passed down to tls_error: */ +- host_item *host; ++ host_item * host; + const uschar * verify_cert_hostnames; + #ifndef DISABLE_EVENT +- uschar * event_action; ++ uschar * event_action; + #endif + } tls_ext_ctx_cb; + + /* should figure out a cleanup of API to handle state preserved per + implementation, for various reasons, which can be void * in the APIs. +@@ -2359,13 +2359,13 @@ if ((rc = setup_certs(ctx, ob->tls_verif + + if (verify_check_given_host(CUSS &ob->tls_verify_cert_hostnames, host) == OK) + { + cbinfo->verify_cert_hostnames = + #ifdef SUPPORT_I18N +- string_domain_utf8_to_alabel(host->name, NULL); ++ string_domain_utf8_to_alabel(host->certname, NULL); + #else +- host->name; ++ host->certname; + #endif + DEBUG(D_tls) debug_printf("Cert hostname to check: \"%s\"\n", + cbinfo->verify_cert_hostnames); + } + return OK; |