git://git.exim.org
/
exim.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Support optional server certificate name checking. Bug 1479
[exim.git]
/
src
/
src
/
transports
/
smtp.c
diff --git
a/src/src/transports/smtp.c
b/src/src/transports/smtp.c
index 57b66b8818ce2f003c10cd61eec9daa9e49a0d38..c175d2ffe941ba1519befcf1bcc438be76ae2f28 100644
(file)
--- a/
src/src/transports/smtp.c
+++ b/
src/src/transports/smtp.c
@@
-55,6
+55,10
@@
optionlist smtp_transport_options[] = {
(void *)offsetof(smtp_transport_options_block, dns_qualify_single) },
{ "dns_search_parents", opt_bool,
(void *)offsetof(smtp_transport_options_block, dns_search_parents) },
(void *)offsetof(smtp_transport_options_block, dns_qualify_single) },
{ "dns_search_parents", opt_bool,
(void *)offsetof(smtp_transport_options_block, dns_search_parents) },
+ { "dnssec_request_domains", opt_stringptr,
+ (void *)offsetof(smtp_transport_options_block, dnssec_request_domains) },
+ { "dnssec_require_domains", opt_stringptr,
+ (void *)offsetof(smtp_transport_options_block, dnssec_require_domains) },
{ "dscp", opt_stringptr,
(void *)offsetof(smtp_transport_options_block, dscp) },
{ "fallback_hosts", opt_stringptr,
{ "dscp", opt_stringptr,
(void *)offsetof(smtp_transport_options_block, dscp) },
{ "fallback_hosts", opt_stringptr,
@@
-98,6
+102,10
@@
optionlist smtp_transport_options[] = {
(void *)offsetof(smtp_transport_options_block, hosts_override) },
{ "hosts_randomize", opt_bool,
(void *)offsetof(smtp_transport_options_block, hosts_randomize) },
(void *)offsetof(smtp_transport_options_block, hosts_override) },
{ "hosts_randomize", opt_bool,
(void *)offsetof(smtp_transport_options_block, hosts_randomize) },
+#if defined(SUPPORT_TLS) && defined(EXPERIMENTAL_OCSP)
+ { "hosts_request_ocsp", opt_stringptr,
+ (void *)offsetof(smtp_transport_options_block, hosts_request_ocsp) },
+#endif
{ "hosts_require_auth", opt_stringptr,
(void *)offsetof(smtp_transport_options_block, hosts_require_auth) },
#ifdef SUPPORT_TLS
{ "hosts_require_auth", opt_stringptr,
(void *)offsetof(smtp_transport_options_block, hosts_require_auth) },
#ifdef SUPPORT_TLS
@@
-110,7
+118,7
@@
optionlist smtp_transport_options[] = {
#endif
{ "hosts_try_auth", opt_stringptr,
(void *)offsetof(smtp_transport_options_block, hosts_try_auth) },
#endif
{ "hosts_try_auth", opt_stringptr,
(void *)offsetof(smtp_transport_options_block, hosts_try_auth) },
-#if
def EXPERIMENTAL
_PRDR
+#if
ndef DISABLE
_PRDR
{ "hosts_try_prdr", opt_stringptr,
(void *)offsetof(smtp_transport_options_block, hosts_try_prdr) },
#endif
{ "hosts_try_prdr", opt_stringptr,
(void *)offsetof(smtp_transport_options_block, hosts_try_prdr) },
#endif
@@
-155,6
+163,10
@@
optionlist smtp_transport_options[] = {
(void *)offsetof(smtp_transport_options_block, tls_tempfail_tryclear) },
{ "tls_try_verify_hosts", opt_stringptr,
(void *)offsetof(smtp_transport_options_block, tls_try_verify_hosts) },
(void *)offsetof(smtp_transport_options_block, tls_tempfail_tryclear) },
{ "tls_try_verify_hosts", opt_stringptr,
(void *)offsetof(smtp_transport_options_block, tls_try_verify_hosts) },
+#ifdef EXPERIMENTAL_CERTNAMES
+ { "tls_verify_cert_hostnames", opt_stringptr,
+ (void *)offsetof(smtp_transport_options_block,tls_verify_cert_hostnames)},
+#endif
{ "tls_verify_certificates", opt_stringptr,
(void *)offsetof(smtp_transport_options_block, tls_verify_certificates) },
{ "tls_verify_hosts", opt_stringptr,
{ "tls_verify_certificates", opt_stringptr,
(void *)offsetof(smtp_transport_options_block, tls_verify_certificates) },
{ "tls_verify_hosts", opt_stringptr,
@@
-188,10
+200,11
@@
smtp_transport_options_block smtp_transport_option_defaults = {
NULL, /* serialize_hosts */
NULL, /* hosts_try_auth */
NULL, /* hosts_require_auth */
NULL, /* serialize_hosts */
NULL, /* hosts_try_auth */
NULL, /* hosts_require_auth */
-#if
def EXPERIMENTAL
_PRDR
+#if
ndef DISABLE
_PRDR
NULL, /* hosts_try_prdr */
#endif
#ifdef EXPERIMENTAL_OCSP
NULL, /* hosts_try_prdr */
#endif
#ifdef EXPERIMENTAL_OCSP
+ US"*", /* hosts_request_ocsp */
NULL, /* hosts_require_ocsp */
#endif
NULL, /* hosts_require_tls */
NULL, /* hosts_require_ocsp */
#endif
NULL, /* hosts_require_tls */
@@
-213,6
+226,8
@@
smtp_transport_options_block smtp_transport_option_defaults = {
FALSE, /* gethostbyname */
TRUE, /* dns_qualify_single */
FALSE, /* dns_search_parents */
FALSE, /* gethostbyname */
TRUE, /* dns_qualify_single */
FALSE, /* dns_search_parents */
+ NULL, /* dnssec_request_domains */
+ NULL, /* dnssec_require_domains */
TRUE, /* delay_after_cutoff */
FALSE, /* hosts_override */
FALSE, /* hosts_randomize */
TRUE, /* delay_after_cutoff */
FALSE, /* hosts_override */
FALSE, /* hosts_randomize */
@@
-234,6
+249,9
@@
smtp_transport_options_block smtp_transport_option_defaults = {
TRUE, /* tls_tempfail_tryclear */
NULL, /* tls_verify_hosts */
NULL /* tls_try_verify_hosts */
TRUE, /* tls_tempfail_tryclear */
NULL, /* tls_verify_hosts */
NULL /* tls_try_verify_hosts */
+# ifdef EXPERIMENTAL_CERTNAMES
+ ,NULL /* tls_verify_cert_hostnames */
+# endif
#endif
#ifndef DISABLE_DKIM
,NULL, /* dkim_canon */
#endif
#ifndef DISABLE_DKIM
,NULL, /* dkim_canon */
@@
-625,7
+643,7
@@
tpda_defer_errstr = addr->message
? string_sprintf("%s: %s", addr->message, strerror(addr->basic_errno))
: string_copy(addr->message)
: addr->basic_errno > 0
? string_sprintf("%s: %s", addr->message, strerror(addr->basic_errno))
: string_copy(addr->message)
: addr->basic_errno > 0
- ? string_copy(strerror(addr->basic_errno))
+ ? string_copy(
US
strerror(addr->basic_errno))
: NULL;
DEBUG(D_transport)
: NULL;
DEBUG(D_transport)
@@
-1174,7
+1192,7
@@
BOOL completed_address = FALSE;
BOOL esmtp = TRUE;
BOOL pending_MAIL;
BOOL pass_message = FALSE;
BOOL esmtp = TRUE;
BOOL pending_MAIL;
BOOL pass_message = FALSE;
-#if
def EXPERIMENTAL
_PRDR
+#if
ndef DISABLE
_PRDR
BOOL prdr_offered = FALSE;
BOOL prdr_active;
#endif
BOOL prdr_offered = FALSE;
BOOL prdr_active;
#endif
@@
-1215,10
+1233,13
@@
outblock.authenticating = FALSE;
tls_out.bits = 0;
tls_out.cipher = NULL; /* the one we may use for this transport */
tls_out.bits = 0;
tls_out.cipher = NULL; /* the one we may use for this transport */
+tls_out.ourcert = NULL;
+tls_out.peercert = NULL;
tls_out.peerdn = NULL;
#if defined(SUPPORT_TLS) && !defined(USE_GNUTLS)
tls_out.sni = NULL;
#endif
tls_out.peerdn = NULL;
#if defined(SUPPORT_TLS) && !defined(USE_GNUTLS)
tls_out.sni = NULL;
#endif
+tls_out.ocsp = OCSP_NOT_REQ;
/* Flip the legacy TLS-related variables over to the outbound set in case
they're used in the context of the transport. Don't bother resetting
/* Flip the legacy TLS-related variables over to the outbound set in case
they're used in the context of the transport. Don't bother resetting
@@
-1229,8
+1250,8
@@
tls_modify_variables(&tls_out);
#ifndef SUPPORT_TLS
if (smtps)
{
#ifndef SUPPORT_TLS
if (smtps)
{
-
set_errno(addrlist, 0, US"TLS support not available", DEFER, FALSE);
-
return ERROR;
+ set_errno(addrlist, 0, US"TLS support not available", DEFER, FALSE);
+ return ERROR;
}
#endif
}
#endif
@@
-1372,7
+1393,7
@@
goto SEND_QUIT;
PCRE_EOPT, NULL, 0) >= 0;
#endif
PCRE_EOPT, NULL, 0) >= 0;
#endif
- #if
def EXPERIMENTAL
_PRDR
+ #if
ndef DISABLE
_PRDR
prdr_offered = esmtp &&
(pcre_exec(regex_PRDR, NULL, CS buffer, Ustrlen(buffer), 0,
PCRE_EOPT, NULL, 0) >= 0) &&
prdr_offered = esmtp &&
(pcre_exec(regex_PRDR, NULL, CS buffer, Ustrlen(buffer), 0,
PCRE_EOPT, NULL, 0) >= 0) &&
@@
-1438,22
+1459,7
@@
if (tls_offered && !suppress_tls &&
else
TLS_NEGOTIATE:
{
else
TLS_NEGOTIATE:
{
- int rc = tls_client_start(inblock.sock,
- host,
- addrlist,
- ob->tls_certificate,
- ob->tls_privatekey,
- ob->tls_sni,
- ob->tls_verify_certificates,
- ob->tls_crl,
- ob->tls_require_ciphers,
-#ifdef EXPERIMENTAL_OCSP
- ob->hosts_require_ocsp,
-#endif
- ob->tls_dh_min_bits,
- ob->command_timeout,
- ob->tls_verify_hosts,
- ob->tls_try_verify_hosts);
+ int rc = tls_client_start(inblock.sock, host, addrlist, ob);
/* TLS negotiation failed; give an error. From outside, this function may
be called again to try in clear on a new connection, if the options permit
/* TLS negotiation failed; give an error. From outside, this function may
be called again to try in clear on a new connection, if the options permit
@@
-1474,7
+1480,10
@@
if (tls_offered && !suppress_tls &&
if (addr->transport_return == PENDING_DEFER)
{
addr->cipher = tls_out.cipher;
if (addr->transport_return == PENDING_DEFER)
{
addr->cipher = tls_out.cipher;
+ addr->ourcert = tls_out.ourcert;
+ addr->peercert = tls_out.peercert;
addr->peerdn = tls_out.peerdn;
addr->peerdn = tls_out.peerdn;
+ addr->ocsp = tls_out.ocsp;
}
}
}
}
}
}
@@
-1583,7
+1592,7
@@
if (continue_hostname == NULL
DEBUG(D_transport) debug_printf("%susing PIPELINING\n",
smtp_use_pipelining? "" : "not ");
DEBUG(D_transport) debug_printf("%susing PIPELINING\n",
smtp_use_pipelining? "" : "not ");
-#if
def EXPERIMENTAL
_PRDR
+#if
ndef DISABLE
_PRDR
prdr_offered = esmtp &&
pcre_exec(regex_PRDR, NULL, CS buffer, Ustrlen(CS buffer), 0,
PCRE_EOPT, NULL, 0) >= 0 &&
prdr_offered = esmtp &&
pcre_exec(regex_PRDR, NULL, CS buffer, Ustrlen(CS buffer), 0,
PCRE_EOPT, NULL, 0) >= 0 &&
@@
-1671,7
+1680,7
@@
if (smtp_use_size)
while (*p) p++;
}
while (*p) p++;
}
-#if
def EXPERIMENTAL
_PRDR
+#if
ndef DISABLE
_PRDR
prdr_active = FALSE;
if (prdr_offered)
{
prdr_active = FALSE;
if (prdr_offered)
{
@@
-1907,7
+1916,7
@@
if (!ok) ok = TRUE; else
smtp_command = US"end of data";
smtp_command = US"end of data";
-#if
def EXPERIMENTAL
_PRDR
+#if
ndef DISABLE
_PRDR
/* For PRDR we optionally get a partial-responses warning
* followed by the individual responses, before going on with
* the overall response. If we don't get the warning then deal
/* For PRDR we optionally get a partial-responses warning
* followed by the individual responses, before going on with
* the overall response. If we don't get the warning then deal
@@
-2002,7
+2011,7
@@
if (!ok) ok = TRUE; else
address. For temporary errors, add a retry item for the address so that
it doesn't get tried again too soon. */
address. For temporary errors, add a retry item for the address so that
it doesn't get tried again too soon. */
-#if
def EXPERIMENTAL
_PRDR
+#if
ndef DISABLE
_PRDR
if (lmtp || prdr_active)
#else
if (lmtp)
if (lmtp || prdr_active)
#else
if (lmtp)
@@
-2013,7
+2022,7
@@
if (!ok) ok = TRUE; else
{
if (errno != 0 || buffer[0] == 0) goto RESPONSE_FAILED;
addr->message = string_sprintf(
{
if (errno != 0 || buffer[0] == 0) goto RESPONSE_FAILED;
addr->message = string_sprintf(
-#if
def EXPERIMENTAL
_PRDR
+#if
ndef DISABLE
_PRDR
"%s error after %s: %s", prdr_active ? "PRDR":"LMTP",
#else
"LMTP error after %s: %s",
"%s error after %s: %s", prdr_active ? "PRDR":"LMTP",
#else
"LMTP error after %s: %s",
@@
-2027,7
+2036,7
@@
if (!ok) ok = TRUE; else
errno = ERRNO_DATA4XX;
addr->more_errno |= ((buffer[1] - '0')*10 + buffer[2] - '0') << 8;
addr->transport_return = DEFER;
errno = ERRNO_DATA4XX;
addr->more_errno |= ((buffer[1] - '0')*10 + buffer[2] - '0') << 8;
addr->transport_return = DEFER;
-#if
def EXPERIMENTAL
_PRDR
+#if
ndef DISABLE
_PRDR
if (!prdr_active)
#endif
retry_add_item(addr, addr->address_retry_key, 0);
if (!prdr_active)
#endif
retry_add_item(addr, addr->address_retry_key, 0);
@@
-2050,12
+2059,12
@@
if (!ok) ok = TRUE; else
addr->host_used = thost;
addr->special_action = flag;
addr->message = conf;
addr->host_used = thost;
addr->special_action = flag;
addr->message = conf;
-#if
def EXPERIMENTAL
_PRDR
+#if
ndef DISABLE
_PRDR
if (prdr_active) addr->flags |= af_prdr_used;
#endif
flag = '-';
if (prdr_active) addr->flags |= af_prdr_used;
#endif
flag = '-';
-#if
def EXPERIMENTAL
_PRDR
+#if
ndef DISABLE
_PRDR
if (!prdr_active)
#endif
{
if (!prdr_active)
#endif
{
@@
-2077,7
+2086,7
@@
if (!ok) ok = TRUE; else
}
}
}
}
-#if
def EXPERIMENTAL
_PRDR
+#if
ndef DISABLE
_PRDR
if (prdr_active)
{
/* PRDR - get the final, overall response. For any non-success
if (prdr_active)
{
/* PRDR - get the final, overall response. For any non-success
@@
-2411,8
+2420,6
@@
tls_close(FALSE, TRUE);
#endif
/* Close the socket, and return the appropriate value, first setting
#endif
/* Close the socket, and return the appropriate value, first setting
-continue_transport and continue_hostname NULL to prevent any other addresses
-that may include the host from trying to re-use a continuation socket. This
works because the NULL setting is passed back to the calling process, and
remote_max_parallel is forced to 1 when delivering over an existing connection,
works because the NULL setting is passed back to the calling process, and
remote_max_parallel is forced to 1 when delivering over an existing connection,
@@
-2513,7
+2520,10
@@
for (addr = addrlist; addr != NULL; addr = addr->next)
addr->message = NULL;
#ifdef SUPPORT_TLS
addr->cipher = NULL;
addr->message = NULL;
#ifdef SUPPORT_TLS
addr->cipher = NULL;
+ addr->ourcert = NULL;
+ addr->peercert = NULL;
addr->peerdn = NULL;
addr->peerdn = NULL;
+ addr->ocsp = OCSP_NOT_REQ;
#endif
}
return first_addr;
#endif
}
return first_addr;
@@
-2816,7
+2826,7
@@
for (cutoff_retry = 0; expired &&
rc = host_find_byname(host, NULL, flags, &canonical_name, TRUE);
else
rc = host_find_bydns(host, NULL, flags, NULL, NULL, NULL,
rc = host_find_byname(host, NULL, flags, &canonical_name, TRUE);
else
rc = host_find_bydns(host, NULL, flags, NULL, NULL, NULL,
- NULL, NULL, /*XXX todo: smtp tpt hosts_require_dnssec */
+ ob->dnssec_request_domains, ob->dnssec_require_domains,
&canonical_name, NULL);
/* Update the host (and any additional blocks, resulting from
&canonical_name, NULL);
/* Update the host (and any additional blocks, resulting from
@@
-2916,6
+2926,9
@@
for (cutoff_retry = 0; expired &&
deliver_host = host->name;
deliver_host_address = host->address;
deliver_host = host->name;
deliver_host_address = host->address;
+ lookup_dnssec_authenticated = host->dnssec == DS_YES ? US"yes"
+ : host->dnssec == DS_NO ? US"no"
+ : US"";
/* Set up a string for adding to the retry key if the port number is not
the standard SMTP port. A host may have its own port setting that overrides
/* Set up a string for adding to the retry key if the port number is not
the standard SMTP port. A host may have its own port setting that overrides
@@
-3429,4
+3442,6
@@
DEBUG(D_transport) debug_printf("Leaving %s transport\n", tblock->name);
return TRUE; /* Each address has its status */
}
return TRUE; /* Each address has its status */
}
+/* vi: aw ai sw=2
+*/
/* End of transport/smtp.c */
/* End of transport/smtp.c */