X-Git-Url: https://vcs.fsf.org/?a=blobdiff_plain;f=src%2Fsrc%2Ftransports%2Fsmtp.c;h=3d12988e8969ce5aa1fd4451e87541e6cdbbeafe;hb=b4b3528b6ffe0a1bd405893052f9ce0788e8d46b;hp=848a4ce2103efdd9aded6ce55e36330e6e8f93a5;hpb=789f8a4f4046120b7ae2aafa45f7f45c3ae4c8f5;p=exim.git diff --git a/src/src/transports/smtp.c b/src/src/transports/smtp.c index 848a4ce21..3d12988e8 100644 --- a/src/src/transports/smtp.c +++ b/src/src/transports/smtp.c @@ -72,17 +72,6 @@ optionlist smtp_transport_options[] = { (void *)offsetof(smtp_transport_options_block, final_timeout) }, { "gethostbyname", opt_bool, (void *)offsetof(smtp_transport_options_block, gethostbyname) }, -#ifdef SUPPORT_TLS - /* These are no longer honoured, as of Exim 4.80; for now, we silently - ignore; 4.83 will warn, and a later-still release will remove - these options, so that using them becomes an error. */ - { "gnutls_require_kx", opt_stringptr, - (void *)offsetof(smtp_transport_options_block, gnutls_require_kx) }, - { "gnutls_require_mac", opt_stringptr, - (void *)offsetof(smtp_transport_options_block, gnutls_require_mac) }, - { "gnutls_require_protocols", opt_stringptr, - (void *)offsetof(smtp_transport_options_block, gnutls_require_proto) }, -#endif { "helo_data", opt_stringptr, (void *)offsetof(smtp_transport_options_block, helo_data) }, { "hosts", opt_stringptr, @@ -257,9 +246,6 @@ smtp_transport_options_block smtp_transport_option_defaults = { NULL, /* tls_crl */ NULL, /* tls_privatekey */ NULL, /* tls_require_ciphers */ - NULL, /* gnutls_require_kx */ - NULL, /* gnutls_require_mac */ - NULL, /* gnutls_require_proto */ NULL, /* tls_sni */ US"system", /* tls_verify_certificates */ EXIM_CLIENT_DH_DEFAULT_MIN_BITS, @@ -411,15 +397,6 @@ if (ob->hosts_override && ob->hosts != NULL) tblock->overrides_hosts = TRUE; for them, but do not do any lookups at this time. */ host_build_hostlist(&(ob->fallback_hostlist), ob->fallback_hosts, FALSE); - -#ifdef SUPPORT_TLS -if ( ob->gnutls_require_kx - || ob->gnutls_require_mac - || ob->gnutls_require_proto) - log_write(0, LOG_MAIN, "WARNING: smtp transport options" - " gnutls_require_kx, gnutls_require_mac and gnutls_require_protocols" - " are obsolete\n"); -#endif } @@ -1215,6 +1192,13 @@ return FALSE; #ifdef EXPERIMENTAL_DANE +/* Lookup TLSA record for host/port. +Return: OK success with dnssec; DANE mode + DEFER Do not use this host now, may retry later + FAIL_FORCED No TLSA record; DANE not usable + FAIL Do not use this connection +*/ + int tlsa_lookup(const host_item * host, dns_answer * dnsa, BOOL dane_required) { @@ -1227,13 +1211,6 @@ const uschar * fullname = buffer; switch (dns_lookup(dnsa, buffer, T_TLSA, &fullname)) { - case DNS_AGAIN: - return DEFER; /* just defer this TLS'd conn */ - - default: - case DNS_FAIL: - return dane_required ? FAIL : DEFER; - case DNS_SUCCEED: if (!dns_is_secure(dnsa)) { @@ -1241,6 +1218,16 @@ switch (dns_lookup(dnsa, buffer, T_TLSA, &fullname)) return DEFER; } return OK; + + case DNS_AGAIN: + return DEFER; /* just defer this TLS'd conn */ + + case DNS_NOMATCH: + return dane_required ? FAIL : FAIL_FORCED; + + default: + case DNS_FAIL: + return dane_required ? FAIL : DEFER; } } #endif @@ -1542,17 +1529,16 @@ if (continue_hostname == NULL) if( dane_required || verify_check_given_host(&ob->hosts_try_dane, host) == OK ) - { - if ((rc = tlsa_lookup(host, &tlsa_dnsa, dane_required)) != OK) + switch (rc = tlsa_lookup(host, &tlsa_dnsa, dane_required)) { - set_errno_nohost(addrlist, ERRNO_DNSDEFER, - string_sprintf("DANE error: tlsa lookup %s", - rc == DEFER ? "DEFER" : "FAIL"), - rc, FALSE); - return rc; + case OK: dane = TRUE; break; + case FAIL_FORCED: break; + default: set_errno_nohost(addrlist, ERRNO_DNSDEFER, + string_sprintf("DANE error: tlsa lookup %s", + rc == DEFER ? "DEFER" : "FAIL"), + rc, FALSE); + return rc; } - dane = TRUE; - } } else if (dane_required) { @@ -1903,17 +1889,17 @@ if (tls_out.active >= 0) /* If the host is required to use a secure channel, ensure that we have one. */ -else if ( +else if ( smtps # ifdef EXPERIMENTAL_DANE - dane || + || dane # endif - verify_check_given_host(&ob->hosts_require_tls, host) == OK + || verify_check_given_host(&ob->hosts_require_tls, host) == OK ) { save_errno = ERRNO_TLSREQUIRED; message = string_sprintf("a TLS session is required, but %s", - tls_offered? "an attempt to start TLS failed" : - "the server did not offer TLS support"); + tls_offered ? "an attempt to start TLS failed" + : "the server did not offer TLS support"); goto TLS_FAILED; } #endif /*SUPPORT_TLS*/ @@ -3912,7 +3898,7 @@ If queue_smtp is set, or this transport was called to send a subsequent message down an existing TCP/IP connection, and something caused the host not to be found, we end up here, but can detect these cases and handle them specially. */ -for (addr = addrlist; addr != NULL; addr = addr->next) +for (addr = addrlist; addr; addr = addr->next) { /* If host is not NULL, it means that we stopped processing the host list because of hosts_max_try or hosts_max_try_hardlimit. In the former case, this @@ -3921,8 +3907,7 @@ for (addr = addrlist; addr != NULL; addr = addr->next) However, if we have hit hosts_max_try_hardlimit, we want to behave as if all hosts were tried. */ - if (host != NULL) - { + if (host) if (total_hosts_tried >= ob->hosts_max_try_hardlimit) { DEBUG(D_transport) @@ -3935,7 +3920,6 @@ for (addr = addrlist; addr != NULL; addr = addr->next) debug_printf("hosts_max_try limit caused some hosts to be skipped\n"); setflag(addr, af_retry_skipped); } - } if (queue_smtp) /* no deliveries attempted */ { @@ -3944,28 +3928,28 @@ for (addr = addrlist; addr != NULL; addr = addr->next) addr->message = US"SMTP delivery explicitly queued"; } - else if (addr->transport_return == DEFER && - (addr->basic_errno == ERRNO_UNKNOWNERROR || addr->basic_errno == 0) && - addr->message == NULL) + else if ( addr->transport_return == DEFER + && (addr->basic_errno == ERRNO_UNKNOWNERROR || addr->basic_errno == 0) + && !addr->message + ) { addr->basic_errno = ERRNO_HRETRY; - if (continue_hostname != NULL) - { + if (continue_hostname) addr->message = US"no host found for existing SMTP connection"; - } else if (expired) { setflag(addr, af_pass_message); /* This is not a security risk */ - addr->message = ob->delay_after_cutoff - ? US"retry time not reached for any host after a long failure period" - : US"all hosts have been failing for a long time and were last tried " - "after this message arrived"; + addr->message = string_sprintf( + "all hosts%s have been failing for a long time %s", + addr->domain ? string_sprintf(" for '%s'", addr->domain) : US"", + ob->delay_after_cutoff + ? US"(and retry time not reached)" + : US"and were last tried after this message arrived"); /* If we are already using fallback hosts, or there are no fallback hosts defined, convert the result to FAIL to cause a bounce. */ - if (addr->host_list == addr->fallback_hosts || - addr->fallback_hosts == NULL) + if (addr->host_list == addr->fallback_hosts || !addr->fallback_hosts) addr->transport_return = FAIL; } else