X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/eea58ada63dde3265728daccc037d3a376b25f45..e51c7be22dfccad376659a1a46cee93c9979bbf7:/src/src/transports/smtp.c diff --git a/src/src/transports/smtp.c b/src/src/transports/smtp.c index 9e0ab1556..c175d2ffe 100644 --- a/src/src/transports/smtp.c +++ b/src/src/transports/smtp.c @@ -102,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) }, +#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 @@ -114,7 +118,7 @@ optionlist smtp_transport_options[] = { #endif { "hosts_try_auth", opt_stringptr, (void *)offsetof(smtp_transport_options_block, hosts_try_auth) }, -#ifdef EXPERIMENTAL_PRDR +#ifndef DISABLE_PRDR { "hosts_try_prdr", opt_stringptr, (void *)offsetof(smtp_transport_options_block, hosts_try_prdr) }, #endif @@ -159,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) }, +#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, @@ -192,10 +200,11 @@ smtp_transport_options_block smtp_transport_option_defaults = { NULL, /* serialize_hosts */ NULL, /* hosts_try_auth */ NULL, /* hosts_require_auth */ -#ifdef EXPERIMENTAL_PRDR +#ifndef DISABLE_PRDR NULL, /* hosts_try_prdr */ #endif #ifdef EXPERIMENTAL_OCSP + US"*", /* hosts_request_ocsp */ NULL, /* hosts_require_ocsp */ #endif NULL, /* hosts_require_tls */ @@ -240,6 +249,9 @@ smtp_transport_options_block smtp_transport_option_defaults = { 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 */ @@ -631,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_copy(strerror(addr->basic_errno)) + ? string_copy(US strerror(addr->basic_errno)) : NULL; DEBUG(D_transport) @@ -1180,7 +1192,7 @@ BOOL completed_address = FALSE; BOOL esmtp = TRUE; BOOL pending_MAIL; BOOL pass_message = FALSE; -#ifdef EXPERIMENTAL_PRDR +#ifndef DISABLE_PRDR BOOL prdr_offered = FALSE; BOOL prdr_active; #endif @@ -1221,10 +1233,13 @@ outblock.authenticating = FALSE; 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.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 @@ -1235,8 +1250,8 @@ tls_modify_variables(&tls_out); #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 @@ -1378,7 +1393,7 @@ goto SEND_QUIT; PCRE_EOPT, NULL, 0) >= 0; #endif - #ifdef EXPERIMENTAL_PRDR + #ifndef DISABLE_PRDR prdr_offered = esmtp && (pcre_exec(regex_PRDR, NULL, CS buffer, Ustrlen(buffer), 0, PCRE_EOPT, NULL, 0) >= 0) && @@ -1444,22 +1459,7 @@ if (tls_offered && !suppress_tls && 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 @@ -1480,7 +1480,10 @@ if (tls_offered && !suppress_tls && 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->ocsp = tls_out.ocsp; } } } @@ -1589,7 +1592,7 @@ if (continue_hostname == NULL DEBUG(D_transport) debug_printf("%susing PIPELINING\n", smtp_use_pipelining? "" : "not "); -#ifdef EXPERIMENTAL_PRDR +#ifndef DISABLE_PRDR prdr_offered = esmtp && pcre_exec(regex_PRDR, NULL, CS buffer, Ustrlen(CS buffer), 0, PCRE_EOPT, NULL, 0) >= 0 && @@ -1677,7 +1680,7 @@ if (smtp_use_size) while (*p) p++; } -#ifdef EXPERIMENTAL_PRDR +#ifndef DISABLE_PRDR prdr_active = FALSE; if (prdr_offered) { @@ -1913,7 +1916,7 @@ if (!ok) ok = TRUE; else smtp_command = US"end of data"; -#ifdef EXPERIMENTAL_PRDR +#ifndef 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 @@ -2008,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. */ -#ifdef EXPERIMENTAL_PRDR +#ifndef DISABLE_PRDR if (lmtp || prdr_active) #else if (lmtp) @@ -2019,7 +2022,7 @@ if (!ok) ok = TRUE; else { if (errno != 0 || buffer[0] == 0) goto RESPONSE_FAILED; addr->message = string_sprintf( -#ifdef EXPERIMENTAL_PRDR +#ifndef DISABLE_PRDR "%s error after %s: %s", prdr_active ? "PRDR":"LMTP", #else "LMTP error after %s: %s", @@ -2033,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; -#ifdef EXPERIMENTAL_PRDR +#ifndef DISABLE_PRDR if (!prdr_active) #endif retry_add_item(addr, addr->address_retry_key, 0); @@ -2056,12 +2059,12 @@ if (!ok) ok = TRUE; else addr->host_used = thost; addr->special_action = flag; addr->message = conf; -#ifdef EXPERIMENTAL_PRDR +#ifndef DISABLE_PRDR if (prdr_active) addr->flags |= af_prdr_used; #endif flag = '-'; -#ifdef EXPERIMENTAL_PRDR +#ifndef DISABLE_PRDR if (!prdr_active) #endif { @@ -2083,7 +2086,7 @@ if (!ok) ok = TRUE; else } } -#ifdef EXPERIMENTAL_PRDR +#ifndef DISABLE_PRDR if (prdr_active) { /* PRDR - get the final, overall response. For any non-success @@ -2417,8 +2420,6 @@ tls_close(FALSE, TRUE); #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, @@ -2519,7 +2520,10 @@ for (addr = addrlist; addr != NULL; addr = addr->next) addr->message = NULL; #ifdef SUPPORT_TLS addr->cipher = NULL; + addr->ourcert = NULL; + addr->peercert = NULL; addr->peerdn = NULL; + addr->ocsp = OCSP_NOT_REQ; #endif } return first_addr; @@ -2922,6 +2926,9 @@ for (cutoff_retry = 0; expired && 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