summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJeremy Harris <jgh146exb@wizmail.org>2017-04-30 22:11:27 +0100
committerJeremy Harris <jgh146exb@wizmail.org>2017-04-30 22:57:21 +0100
commitb7d3afcfad94edf99a8dbc50ab670ded417e6bea (patch)
tree4be6ecc504d39f91e35e6e0325a4902f61eae643 /src
parentadc03e34897563d1b7a6ff6252083b0003c34eef (diff)
Fix continue_more on TLS connection. Bug 2104
Diffstat (limited to 'src')
-rw-r--r--src/src/deliver.c5
-rw-r--r--src/src/transport.c8
-rw-r--r--src/src/transports/smtp.c37
3 files changed, 33 insertions, 17 deletions
diff --git a/src/src/deliver.c b/src/src/deliver.c
index 262ae454f..56642c6aa 100644
--- a/src/src/deliver.c
+++ b/src/src/deliver.c
@@ -4500,8 +4500,11 @@ for (delivery_count = 0; addr_remote; delivery_count++)
/* Set a flag indicating whether there are further addresses that list
the continued host. This tells the transport to leave the channel open,
but not to pass it to another delivery process. */
+ /*XXX really the flag should be settable even by an initial proces
+ (not continue_transport dependent). Need to check that uses of it
+ are independent. */
- for (next = addr_remote; next; next = next->next)
+ for (next = addr_remote; next && !continue_more; next = next->next)
{
host_item *h;
for (h = next->host_list; h; h = h->next)
diff --git a/src/src/transport.c b/src/src/transport.c
index 71fd9dac2..0dc8785cb 100644
--- a/src/src/transport.c
+++ b/src/src/transport.c
@@ -1940,7 +1940,11 @@ if ((pid = fork()) == 0)
write the log, etc., so that the output is always in the same order for
automatic comparison. */
- if ((pid = fork()) != 0) _exit(EXIT_SUCCESS);
+ if ((pid = fork()) != 0)
+ {
+ DEBUG(D_transport) debug_printf("transport_pass_socket succeeded (final-pid %d)\n", pid);
+ _exit(EXIT_SUCCESS);
+ }
if (running_in_test_harness) sleep(1);
transport_do_pass_socket(transport_name, hostname, hostaddress,
@@ -1955,7 +1959,7 @@ if (pid > 0)
{
int rc;
while ((rc = wait(&status)) != pid && (rc >= 0 || errno != ECHILD));
- DEBUG(D_transport) debug_printf("transport_pass_socket succeeded\n");
+ DEBUG(D_transport) debug_printf("transport_pass_socket succeeded (inter-pid %d)\n", pid);
return TRUE;
}
else
diff --git a/src/src/transports/smtp.c b/src/src/transports/smtp.c
index ecba054a2..758f1143a 100644
--- a/src/src/transports/smtp.c
+++ b/src/src/transports/smtp.c
@@ -2202,12 +2202,7 @@ tls_close(FALSE, TRUE);
/* Close the socket, and return the appropriate value, first setting
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,
-
-If all went well and continue_more is set, we shouldn't actually get here if
-there are further addresses, as the return above will be taken. However,
-writing RSET might have failed, or there may be other addresses whose hosts are
-specified in the transports, and therefore not visible at top level, in which
-case continue_more won't get set. */
+*/
HDEBUG(D_transport|D_acl|D_v) debug_printf_indent(" SMTP(close)>>\n");
if (sx->send_quit)
@@ -3373,18 +3368,22 @@ if (sx.completed_addr && sx.ok && sx.send_quit)
continue_sequence++; /* Causes * in logging */
goto SEND_MESSAGE;
}
- if (continue_more) return yield; /* More addresses for another run */
- /* Pass the connection on to a new Exim process. */
+ /* Unless caller said it already has more messages listed for this host,
+ pass the connection on to a new Exim process (below, the call to
+ transport_pass_socket). If the caller has more ready, just return with
+ the connection still open. */
+
#ifdef SUPPORT_TLS
if (tls_out.active >= 0)
- if (verify_check_given_host(&sx.ob->hosts_noproxy_tls, host) == OK)
+ if ( continue_more
+ || verify_check_given_host(&sx.ob->hosts_noproxy_tls, host) == OK)
{
- /* Pass the socket, for direct use, to a new Exim process. Before
- doing so, we must shut down TLS. Not all MTAs allow for the
- continuation of the SMTP session when TLS is shut down. We test for
- this by sending a new EHLO. If we don't get a good response, we don't
- attempt to pass the socket on. */
+ /* Before passing the socket on, or returning to caller with it still
+ open, we must shut down TLS. Not all MTAs allow for the continuation
+ of the SMTP session when TLS is shut down. We test for this by sending
+ a new EHLO. If we don't get a good response, we don't attempt to pass
+ the socket on. */
tls_close(FALSE, TRUE);
smtp_peer_options = smtp_peer_options_wrap;
@@ -3393,6 +3392,9 @@ if (sx.completed_addr && sx.ok && sx.send_quit)
"EHLO %s\r\n", sx.helo_data) >= 0
&& smtp_read_response(&sx.inblock, sx.buffer, sizeof(sx.buffer),
'2', sx.ob->command_timeout);
+
+ if (sx.ok && continue_more)
+ return yield; /* More addresses for another run */
}
else
{
@@ -3409,7 +3411,10 @@ if (sx.completed_addr && sx.ok && sx.send_quit)
# endif
);
}
+ else
#endif
+ if (continue_more)
+ return yield; /* More addresses for another run */
/* If the socket is successfully passed, we mustn't send QUIT (or
indeed anything!) from here. */
@@ -3432,6 +3437,7 @@ propagate it from the initial
int pid = fork();
if (pid > 0) /* parent */
{
+ DEBUG(D_transport) debug_printf("proxy-proc inter-pid %d\n", pid);
waitpid(pid, NULL, 0);
tls_close(FALSE, FALSE);
(void)close(sx.inblock.sock);
@@ -3442,7 +3448,10 @@ propagate it from the initial
else if (pid == 0) /* child; fork again to disconnect totally */
{
if ((pid = fork()))
+ {
+ DEBUG(D_transport) debug_printf("proxy-prox final-pid %d\n", pid);
_exit(pid ? EXIT_FAILURE : EXIT_SUCCESS);
+ }
smtp_proxy_tls(sx.buffer, sizeof(sx.buffer), pfd[0], sx.ob->command_timeout);
exim_exit(0);
}