X-Git-Url: https://vcs.fsf.org/?a=blobdiff_plain;f=src%2Fsrc%2Ftransports%2Fsmtp.c;h=9e0ab15569ae50a2471ae3aaac29bf675773e597;hb=578897ea8764001d0538b8b645d161524ba1fa4e;hp=b18720cc02ccf625f49ae880d5809c028bec7e06;hpb=4d8d62b965c7379e85aeb6e43534c89d06099ad2;p=exim.git diff --git a/src/src/transports/smtp.c b/src/src/transports/smtp.c index b18720cc0..9e0ab1556 100644 --- a/src/src/transports/smtp.c +++ b/src/src/transports/smtp.c @@ -2,7 +2,7 @@ * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) University of Cambridge 1995 - 2012 */ +/* Copyright (c) University of Cambridge 1995 - 2014 */ /* See the file NOTICE for conditions of use and distribution. */ #include "../exim.h" @@ -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) }, + { "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, @@ -153,8 +157,16 @@ optionlist smtp_transport_options[] = { (void *)offsetof(smtp_transport_options_block, tls_sni) }, { "tls_tempfail_tryclear", opt_bool, (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) }, { "tls_verify_certificates", opt_stringptr, - (void *)offsetof(smtp_transport_options_block, tls_verify_certificates) } + (void *)offsetof(smtp_transport_options_block, tls_verify_certificates) }, + { "tls_verify_hosts", opt_stringptr, + (void *)offsetof(smtp_transport_options_block, tls_verify_hosts) } +#endif +#ifdef EXPERIMENTAL_TPDA + ,{ "tpda_host_defer_action", opt_stringptr, + (void *)offsetof(smtp_transport_options_block, tpda_host_defer_action) }, #endif }; @@ -205,6 +217,8 @@ smtp_transport_options_block smtp_transport_option_defaults = { 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 */ @@ -223,7 +237,9 @@ smtp_transport_options_block smtp_transport_option_defaults = { NULL, /* tls_verify_certificates */ EXIM_CLIENT_DH_DEFAULT_MIN_BITS, /* tls_dh_min_bits */ - TRUE /* tls_tempfail_tryclear */ + TRUE, /* tls_tempfail_tryclear */ + NULL, /* tls_verify_hosts */ + NULL /* tls_try_verify_hosts */ #endif #ifndef DISABLE_DKIM ,NULL, /* dkim_canon */ @@ -233,6 +249,9 @@ smtp_transport_options_block smtp_transport_option_defaults = { NULL, /* dkim_sign_headers */ NULL /* dkim_strict */ #endif +#ifdef EXPERIMENTAL_TPDA + ,NULL /* tpda_host_defer_action */ +#endif }; @@ -577,6 +596,59 @@ else +#ifdef EXPERIMENTAL_TPDA +/************************************************* +* Post-defer action * +*************************************************/ + +/* This expands an arbitrary per-transport string. + It might, for example, be used to write to the database log. + +Arguments: + ob transport options block + addr the address item containing error information + host the current host + +Returns: nothing +*/ + +static void +tpda_deferred(smtp_transport_options_block *ob, address_item *addr, host_item *host) +{ +uschar *action = ob->tpda_host_defer_action; +if (!action) + return; + +tpda_delivery_ip = string_copy(host->address); +tpda_delivery_port = (host->port == PORT_NONE)? 25 : host->port; +tpda_delivery_fqdn = string_copy(host->name); +tpda_delivery_local_part = string_copy(addr->local_part); +tpda_delivery_domain = string_copy(addr->domain); +tpda_defer_errno = addr->basic_errno; + +tpda_defer_errstr = 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)) + : NULL; + +DEBUG(D_transport) + debug_printf(" TPDA(host defer): tpda_host_defer_action=|%s| tpda_delivery_IP=%s\n", + action, tpda_delivery_ip); + +router_name = addr->router->name; +transport_name = addr->transport->name; +if (!expand_string(action) && *expand_string_message) + log_write(0, LOG_MAIN|LOG_PANIC, "failed to expand tpda_defer_action in %s: %s\n", + transport_name, expand_string_message); +router_name = transport_name = NULL; +} +#endif + + + /************************************************* * Synchronize SMTP responses * *************************************************/ @@ -1147,13 +1219,6 @@ outblock.authenticating = FALSE; /* Reset the parameters of a TLS session. */ -tls_in.bits = 0; -tls_in.cipher = NULL; /* for back-compatible behaviour */ -tls_in.peerdn = NULL; -#if defined(SUPPORT_TLS) && !defined(USE_GNUTLS) -tls_in.sni = NULL; -#endif - tls_out.bits = 0; tls_out.cipher = NULL; /* the one we may use for this transport */ tls_out.peerdn = NULL; @@ -1161,6 +1226,12 @@ tls_out.peerdn = NULL; tls_out.sni = NULL; #endif +/* 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 +afterward as we're in a subprocess. */ + +tls_modify_variables(&tls_out); + #ifndef SUPPORT_TLS if (smtps) { @@ -1386,7 +1457,9 @@ if (tls_offered && !suppress_tls && ob->hosts_require_ocsp, #endif ob->tls_dh_min_bits, - ob->command_timeout); + ob->command_timeout, + ob->tls_verify_hosts, + ob->tls_try_verify_hosts); /* 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 @@ -1912,7 +1985,12 @@ if (!ok) ok = TRUE; else /* Set up confirmation if needed - applies only to SMTP */ - if ((log_extra_selector & LX_smtp_confirmation) != 0 && !lmtp) + if ( + #ifndef EXPERIMENTAL_TPDA + (log_extra_selector & LX_smtp_confirmation) != 0 && + #endif + !lmtp + ) { uschar *s = string_printing(buffer); conf = (s == buffer)? (uschar *)string_copy(s) : s; @@ -2744,6 +2822,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, + ob->dnssec_request_domains, ob->dnssec_require_domains, &canonical_name, NULL); /* Update the host (and any additional blocks, resulting from @@ -3051,6 +3130,11 @@ for (cutoff_retry = 0; expired && first_addr->basic_errno != ERRNO_TLSFAILURE) write_logs(first_addr, host); + #ifdef EXPERIMENTAL_TPDA + if (rc == DEFER) + tpda_deferred(ob, first_addr, host); + #endif + /* If STARTTLS was accepted, but there was a failure in setting up the TLS session (usually a certificate screwup), and the host is not in hosts_require_tls, and tls_tempfail_tryclear is true, try again, with @@ -3073,6 +3157,10 @@ for (cutoff_retry = 0; expired && expanded_hosts != NULL, &message_defer, TRUE); if (rc == DEFER && first_addr->basic_errno != ERRNO_AUTHFAIL) write_logs(first_addr, host); + #ifdef EXPERIMENTAL_TPDA + if (rc == DEFER) + tpda_deferred(ob, first_addr, host); + #endif } #endif } @@ -3347,4 +3435,6 @@ DEBUG(D_transport) debug_printf("Leaving %s transport\n", tblock->name); return TRUE; /* Each address has its status */ } +/* vi: aw ai sw=2 +*/ /* End of transport/smtp.c */