summaryrefslogtreecommitdiffstats
path: root/debian/patches/82_TLS-use-RFC-6125-rules-for-certifucate-name-checks-w.patch
diff options
context:
space:
mode:
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.patch188
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;