*************************************************/
/* Copyright (c) University of Cambridge 1995 - 2018 */
+/* Copyright (c) The Exim Maintainers 2020 */
/* See the file NOTICE for conditions of use and distribution. */
#include "../exim.h"
{ "tls_dh_min_bits", opt_int, LOFF(tls_dh_min_bits) },
{ "tls_privatekey", opt_stringptr, LOFF(tls_privatekey) },
{ "tls_require_ciphers", opt_stringptr, LOFF(tls_require_ciphers) },
-# ifdef EXPERIMENTAL_TLS_RESUME
+# ifndef DISABLE_TLS_RESUME
{ "tls_resumption_hosts", opt_stringptr, LOFF(tls_resumption_hosts) },
# endif
{ "tls_sni", opt_stringptr, LOFF(tls_sni) },
.tls_verify_certificates = US"system",
.tls_dh_min_bits = EXIM_CLIENT_DH_DEFAULT_MIN_BITS,
.tls_tempfail_tryclear = TRUE,
-# ifdef EXPERIMENTAL_TLS_RESUME
+# ifndef DISABLE_TLS_RESUME
.tls_resumption_hosts = NULL,
# endif
.tls_verify_hosts = NULL,
.tls_verify_cert_hostnames = US"*",
#endif
#ifdef SUPPORT_I18N
- .utf8_downconvert = NULL,
+ .utf8_downconvert = US"-1",
#endif
#ifndef DISABLE_DKIM
.dkim =
for (au = auths, authnum = 0; au; au = au->next, authnum++) if (au->client)
{
const uschar * list = names;
- int sep = ' ';
- uschar name[32];
-
- while (string_nextinlist(&list, &sep, name, sizeof(name)))
- if (strcmpic(au->public_name, name) == 0)
+ uschar * s;
+ for (int sep = ' '; s = string_nextinlist(&list, &sep, NULL, 0); )
+ if (strcmpic(au->public_name, s) == 0)
{ authbits |= BIT(authnum); break; }
}
if (require_auth == OK && !f.smtp_authenticated)
{
+ invalidate_ehlo_cache_entry(sx);
set_errno_nohost(sx->addrlist, ERRNO_AUTHFAIL,
string_sprintf("authentication required but %s", fail_reason), DEFER,
FALSE, &sx->delivery_start);
smtp_local_identity(s_compare->current_sender_address, s_compare->tblock);
if (!(new_sender_address = deliver_get_sender_address(message_id)))
- return 0;
+ return FALSE;
message_local_identity =
smtp_local_identity(new_sender_address, s_compare->tblock);
tls_out.sni = NULL;
#endif
tls_out.ocsp = OCSP_NOT_REQ;
-#ifdef EXPERIMENTAL_TLS_RESUME
+#ifndef DISABLE_TLS_RESUME
tls_out.resumption = 0;
#endif
tls_out.ver = NULL;
else DEBUG(D_transport)
debug_printf("helo needs $sending_ip_address\n");
+PIPE_CONNECT_RETRY:
if (sx->early_pipe_active)
sx->outblock.conn_args = &sx->conn_args;
else
}
sx->inblock.cctx = sx->outblock.cctx = &sx->cctx;
smtp_command = big_buffer;
+ sx->peer_offered = smtp_peer_options;
sx->helo_data = NULL; /* ensure we re-expand ob->helo_data */
/* For a continued connection with TLS being proxied for us, or a
&& cutthrough.is_tls)
)
{
- sx->peer_offered = smtp_peer_options;
sx->pipelining_used = pipelining_active = !!(smtp_peer_options & OPTION_PIPE);
HDEBUG(D_transport) debug_printf("continued connection, %s TLS\n",
continue_proxy_cipher ? "proxied" : "verify conn with");
{
HDEBUG(D_transport)
debug_printf("failed reaping pipelined cmd responses\n");
- goto RESPONSE_FAILED;
+ close(sx->cctx.sock);
+ sx->cctx.sock = -1;
+ sx->early_pipe_active = FALSE;
+ goto PIPE_CONNECT_RETRY;
}
#endif
int rc, i;
close(pfd[1]);
-if ((rc = fork()))
- {
- DEBUG(D_transport) debug_printf("proxy-proc final-pid %d\n", rc);
+if ((rc = exim_fork(US"tls-proxy")))
_exit(rc < 0 ? EXIT_FAILURE : EXIT_SUCCESS);
- }
-testharness_pause_ms(100); /* let parent debug out */
set_process_info("proxying TLS connection for continued transport");
FD_ZERO(&rfds);
FD_SET(tls_out.active.sock, &rfds);
done:
testharness_pause_ms(100); /* let logging complete */
- exim_exit(0, US"TLS proxy");
+ exim_exit(EXIT_SUCCESS);
}
#endif
/* If continue_hostname is not null, we get here only when continuing to
deliver down an existing channel. The channel was passed as the standard
-input. TLS is never active on a passed channel; the previous process always
-closes it down before passing the connection on.
+input. TLS is never active on a passed channel; the previous process either
+closes it down before passing the connection on, or inserts a TLS-proxy
+process and passes on a cleartext conection.
Otherwise, we have to make a connection to the remote host, and do the
initial protocol exchange.
}
/* If there is a filter command specified for this transport, we can now
-set it up. This cannot be done until the identify of the host is known. */
+set it up. This cannot be done until the identity of the host is known. */
if (tblock->filter_command)
{
if (continue_hostname && continue_sequence == 1)
{
- sx->peer_offered = smtp_peer_options;
/* sx->pending_MAIL = FALSE; */
sx->ok = TRUE;
/* sx->next_addr = NULL; */
#ifndef DISABLE_TLS
if (tls_out.active.sock >= 0)
{
- int pid = fork();
+ int pid = exim_fork(US"tls-proxy-interproc");
if (pid == 0) /* child; fork again to disconnect totally */
{
- testharness_pause_ms(100); /* let parent debug out */
/* does not return */
smtp_proxy_tls(sx->cctx.tls_ctx, sx->buffer, sizeof(sx->buffer), pfd,
ob->command_timeout);
if (pid > 0) /* parent */
{
- DEBUG(D_transport) debug_printf("proxy-proc inter-pid %d\n", pid);
close(pfd[0]);
/* tidy the inter-proc to disconn the proxy proc */
waitpid(pid, NULL, 0);
were not in it. We don't want to hold up all SMTP deliveries! Except when
doing a two-stage queue run, don't do this if forcing. */
- if ((!f.deliver_force || f.queue_2stage) && (f.queue_smtp ||
- match_isinlist(addrlist->domain,
- (const uschar **)&queue_smtp_domains, 0,
- &domainlist_anchor, NULL, MCL_DOMAIN, TRUE, NULL) == OK))
+ if ( (!f.deliver_force || f.queue_2stage)
+ && ( f.queue_smtp
+ || match_isinlist(addrlist->domain,
+ CUSS &queue_smtp_domains, 0,
+ &domainlist_anchor, NULL, MCL_DOMAIN, TRUE, NULL) == OK)
+ )
{
+ DEBUG(D_transport) debug_printf("first-pass routing only\n");
expired = FALSE;
for (address_item * addr = addrlist; addr; addr = addr->next)
if (addr->transport_return == DEFER)
- addr->message = US"domain matches queue_smtp_domains, or -odqs set";
+ addr->message = US"first-pass only routing due to -odqs, "
+ "queue_smtp_domains or control=queue";
continue; /* With next host */
}
#ifndef DISABLE_EVENT
/* If the last host gave a defer raise a per-message event */
- if (!nexthost && (message_defer || rc == DEFER))
+ if ( !( nexthost
+ && unexpired_hosts_tried < ob->hosts_max_try
+ && total_hosts_tried < ob->hosts_max_try_hardlimit
+ )
+ && (message_defer || rc == DEFER)
+ )
deferred_event_raise(first_addr, host, US"msg:defer");
#endif
}