- {
- int oldtimeout = ob->command_timeout;
- int rc;
-
- ob->command_timeout = callout;
- rc = tls_client_start(inblock.sock, host, addr, addr->transport
-# ifdef EXPERIMENTAL_DANE
- , dane ? &tlsa_dnsa : NULL
-# endif
- );
- ob->command_timeout = oldtimeout;
-
- /* TLS negotiation failed; give an error. Try in clear on a new
- connection, if the options permit it for this host. */
- if (rc != OK)
- {
- if (rc == DEFER)
- {
- (void)close(inblock.sock);
-# ifndef DISABLE_EVENT
- (void) event_raise(addr->transport->event_action,
- US"tcp:close", NULL);
-# endif
- if ( ob->tls_tempfail_tryclear
- && !smtps
- && verify_check_given_host(&ob->hosts_require_tls, host) != OK
- )
- {
- log_write(0, LOG_MAIN, "TLS session failure:"
- " delivering unencrypted to %s [%s] (not in hosts_require_tls)",
- host->name, host->address);
- suppress_tls = TRUE;
- goto tls_retry_connection;
- }
- }
-
- /*save_errno = ERRNO_TLSFAILURE;*/
- /*message = US"failure while setting up TLS session";*/
- send_quit = FALSE;
- done= FALSE;
- goto TLS_FAILED;
- }
-
- /* TLS session is set up. Copy info for logging. */
- addr->cipher = tls_out.cipher;
- addr->peerdn = tls_out.peerdn;
-
- /* For SMTPS we need to wait for the initial OK response, then do HELO. */
- if (smtps)
- goto smtps_redo_greeting;
-
- /* For STARTTLS we need to redo EHLO */
- goto tls_redo_helo;
- }
- }
-
- /* If the host is required to use a secure channel, ensure that we have one. */
- if (tls_out.active < 0)
- if (
-# ifdef EXPERIMENTAL_DANE
- dane ||
-# endif
- verify_check_given_host(&ob->hosts_require_tls, host) == OK
- )
- {
- /*save_errno = ERRNO_TLSREQUIRED;*/
- log_write(0, LOG_MAIN,
- "H=%s [%s]: a TLS session is required for this host, but %s",
- host->name, host->address,
- peer_offered & PEER_OFFERED_TLS
- ? "an attempt to start TLS failed"
- : "the server did not offer TLS support");
- done= FALSE;
- goto TLS_FAILED;
- }
-
-#endif /*SUPPORT_TLS*/
-
- done = TRUE; /* so far so good; have response to HELO */
-
- /* For now, transport_filter by cutthrough-delivery is not supported */
- /* Need proper integration with the proper transport mechanism. */
- if (cutthrough.delivery)
- {
-#ifndef DISABLE_DKIM
- uschar * s;
-#endif
- if (addr->transport->filter_command)
- {
- cutthrough.delivery = FALSE;
- HDEBUG(D_acl|D_v) debug_printf("Cutthrough cancelled by presence of transport filter\n");
- }
-#ifndef DISABLE_DKIM
- else if ((s = ob->dkim.dkim_domain) && (s = expand_string(s)) && *s)
- {
- cutthrough.delivery = FALSE;
- HDEBUG(D_acl|D_v) debug_printf("Cutthrough cancelled by presence of DKIM signing\n");
- }
-#endif
- }
-
- SEND_FAILED:
- RESPONSE_FAILED:
- TLS_FAILED:
- ;
- /* Clear down of the TLS, SMTP and TCP layers on error is handled below. */
-
- /* Failure to accept HELO is cached; this blocks the whole domain for all
- senders. I/O errors and defer responses are not cached. */
-
- if (!done)
- {
- *failure_ptr = US"mail"; /* At or before MAIL */
- if (errno == 0 && responsebuffer[0] == '5')
- {
- setflag(addr, af_verify_nsfail);
- new_domain_record.result = ccache_reject;
- }
- }
-
-#ifdef SUPPORT_I18N
- else if ( addr->prop.utf8_msg
- && !addr->prop.utf8_downcvt
- && !(peer_offered & PEER_OFFERED_UTF8)
- )
- {
- HDEBUG(D_acl|D_v) debug_printf("utf8 required but not offered\n");
- errno = ERRNO_UTF8_FWD;
- setflag(addr, af_verify_nsfail);
- done = FALSE;
- }
- else if ( addr->prop.utf8_msg
- && (addr->prop.utf8_downcvt || !(peer_offered & PEER_OFFERED_UTF8))
- && (setflag(addr, af_utf8_downcvt),
- from_address = string_address_utf8_to_alabel(from_address,
- &addr->message),
- addr->message
- ) )
- {
- errno = ERRNO_EXPANDFAIL;
- setflag(addr, af_verify_nsfail);
- done = FALSE;