Merge branch 'debian'
[hcoop/debian/exim4.git] / debian / patches / 82_TLS-use-RFC-6125-rules-for-certifucate-name-checks-w.patch
CommitLineData
0c0c20aa
AM
1Description: TLS: use RFC 6125 rules for certificate name checks when
2 CNAMES are present. Bug 2594
3Origin: upstream https://git.exim.org/exim.git/commit/0851a3bbf4667081d47f5d85b6b3a5cb33cbdba6
4Bug: https://bugs.exim.org/show_bug.cgi?id=2594
5Forwarded: not-needed
6Last-Update: 2021-03-02
7
8--- a/doc/ChangeLog
9+++ b/doc/ChangeLog
10@@ -41,10 +41,15 @@ JH/10 OpenSSL: Fix aggregation of messag
11
12 JH/11 Harden plaintext authenticator against a badly misconfigured client-send
13 string. Previously it was possible to cause undefined behaviour in a
14 library routine (usually a crash). Found by "zerons".
15
16+JH/06 Bug 2594: Change the name used for certificate name checks in the smtp
17+ transport. Previously it was the name on the DNS A-record; use instead
18+ the head of the CNAME chain leading there (if there is one). This seems
19+ to align better with RFC 6125.
20+
21
22 JH/18 GnuTLS: fix $tls_out_ocsp under hosts_request_ocsp. Previously the
23 verification result was not updated unless hosts_require_ocsp applied.
24
25 JH/20 Bug 2389: fix server advertising of usable certificates, under GnuTLS in
26--- a/src/host.c
27+++ b/src/host.c
28@@ -1966,10 +1966,17 @@ host_item *last = NULL;
29 BOOL temp_error = FALSE;
30 #if HAVE_IPV6
31 int af;
32 #endif
33
34+#ifndef DISABLE_TLS
35+/* Copy the host name at this point to the value which is used for
36+TLS certificate name checking, before anything modifies it. */
37+
38+host->certname = host->name;
39+#endif
40+
41 /* Make sure DNS options are set as required. This appears to be necessary in
42 some circumstances when the get..byname() function actually calls the DNS. */
43
44 dns_init((flags & HOST_FIND_QUALIFY_SINGLE) != 0,
45 (flags & HOST_FIND_SEARCH_PARENTS) != 0,
46@@ -2132,10 +2139,13 @@ for (i = 1; i <= times;
47
48 else
49 {
50 host_item *next = store_get(sizeof(host_item));
51 next->name = host->name;
52+#ifndef DISABLE_TLS
53+ next->certname = host->certname;
54+#endif
55 next->mx = host->mx;
56 next->address = text_address;
57 next->port = PORT_NONE;
58 next->status = hstatus_unknown;
59 next->why = hwhy_unknown;
60@@ -2150,16 +2160,16 @@ for (i = 1; i <= times;
61
62 /* If no hosts were found, the address field in the original host block will be
63 NULL. If temp_error is set, at least one of the lookups gave a temporary error,
64 so we pass that back. */
65
66-if (host->address == NULL)
67+if (!host->address)
68 {
69 uschar *msg =
70 #ifndef STAND_ALONE
71- (message_id[0] == 0 && smtp_in != NULL)?
72- string_sprintf("no IP address found for host %s (during %s)", host->name,
73+ message_id[0] == 0 && smtp_in
74+ ? string_sprintf("no IP address found for host %s (during %s)", host->name,
75 smtp_get_connection_info()) :
76 #endif
77 string_sprintf("no IP address found for host %s", host->name);
78
79 HDEBUG(D_host_lookup) debug_printf("%s\n", msg);
80@@ -2277,10 +2287,17 @@ dns_record *rr;
81 host_item *thishostlast = NULL; /* Indicates not yet filled in anything */
82 BOOL v6_find_again = FALSE;
83 BOOL dnssec_fail = FALSE;
84 int i;
85
86+#ifndef DISABLE_TLS
87+/* Copy the host name at this point to the value which is used for
88+TLS certificate name checking, before any CNAME-following modifies it. */
89+
90+host->certname = host->name;
91+#endif
92+
93 /* If allow_ip is set, a name which is an IP address returns that value
94 as its address. This is used for MX records when allow_mx_to_ip is set, for
95 those sites that feel they have to flaunt the RFC rules. */
96
97 if (allow_ip && string_is_ip_address(host->name, NULL) != 0)
98--- a/src/structs.h
99+++ b/src/structs.h
100@@ -77,18 +77,21 @@ host addresses is done using this struct
101
102 typedef enum {DS_UNK=-1, DS_NO, DS_YES} dnssec_status_t;
103
104 typedef struct host_item {
105 struct host_item *next;
106- const uschar *name; /* Host name */
107- const uschar *address; /* IP address in text form */
108- int port; /* port value in host order (if SRV lookup) */
109- int mx; /* MX value if found via MX records */
110- int sort_key; /* MX*1000 plus random "fraction" */
111- int status; /* Usable, unusable, or unknown */
112- int why; /* Why host is unusable */
113- int last_try; /* Time of last try if known */
114+ const uschar *name; /* Host name */
115+#ifndef DISABLE_TLS
116+ const uschar *certname; /* Name used for certificate checks */
117+#endif
118+ const uschar *address; /* IP address in text form */
119+ int port; /* port value in host order (if SRV lookup) */
120+ int mx; /* MX value if found via MX records */
121+ int sort_key; /* MX*1000 plus random "fraction" */
122+ int status; /* Usable, unusable, or unknown */
123+ int why; /* Why host is unusable */
124+ int last_try; /* Time of last try if known */
125 dnssec_status_t dnssec;
126 } host_item;
127
128 /* Chain of rewrite rules, read from the rewrite config, or parsed from the
129 rewrite_headers field of a transport. */
130--- a/src/tls-gnu.c
131+++ b/src/tls-gnu.c
132@@ -2191,13 +2191,13 @@ tls_client_setup_hostname_checks(host_it
133 {
134 if (verify_check_given_host(CUSS &ob->tls_verify_cert_hostnames, host) == OK)
135 {
136 state->exp_tls_verify_cert_hostnames =
137 #ifdef SUPPORT_I18N
138- string_domain_utf8_to_alabel(host->name, NULL);
139+ string_domain_utf8_to_alabel(host->certname, NULL);
140 #else
141- host->name;
142+ host->certname;
143 #endif
144 DEBUG(D_tls)
145 debug_printf("TLS: server cert verification includes hostname: \"%s\".\n",
146 state->exp_tls_verify_cert_hostnames);
147 }
148--- a/src/tls-openssl.c
149+++ b/src/tls-openssl.c
150@@ -309,18 +309,18 @@ typedef struct tls_ext_ctx_cb {
151 X509_STORE *verify_store; /* non-null if status requested */
152 BOOL verify_required;
153 } client;
154 } u_ocsp;
155 #endif
156- uschar *dhparam;
157+ uschar * dhparam;
158 /* these are cached from first expand */
159- uschar *server_cipher_list;
160+ uschar * server_cipher_list;
161 /* only passed down to tls_error: */
162- host_item *host;
163+ host_item * host;
164 const uschar * verify_cert_hostnames;
165 #ifndef DISABLE_EVENT
166- uschar * event_action;
167+ uschar * event_action;
168 #endif
169 } tls_ext_ctx_cb;
170
171 /* should figure out a cleanup of API to handle state preserved per
172 implementation, for various reasons, which can be void * in the APIs.
173@@ -2359,13 +2359,13 @@ if ((rc = setup_certs(ctx, ob->tls_verif
174
175 if (verify_check_given_host(CUSS &ob->tls_verify_cert_hostnames, host) == OK)
176 {
177 cbinfo->verify_cert_hostnames =
178 #ifdef SUPPORT_I18N
179- string_domain_utf8_to_alabel(host->name, NULL);
180+ string_domain_utf8_to_alabel(host->certname, NULL);
181 #else
182- host->name;
183+ host->certname;
184 #endif
185 DEBUG(D_tls) debug_printf("Cert hostname to check: \"%s\"\n",
186 cbinfo->verify_cert_hostnames);
187 }
188 return OK;