diff options
author | Jeremy Harris <jgh146exb@wizmail.org> | 2017-04-30 22:11:27 +0100 |
---|---|---|
committer | Jeremy Harris <jgh146exb@wizmail.org> | 2017-04-30 22:57:21 +0100 |
commit | b7d3afcfad94edf99a8dbc50ab670ded417e6bea (patch) | |
tree | 4be6ecc504d39f91e35e6e0325a4902f61eae643 /src | |
parent | adc03e34897563d1b7a6ff6252083b0003c34eef (diff) |
Fix continue_more on TLS connection. Bug 2104
Diffstat (limited to 'src')
-rw-r--r-- | src/src/deliver.c | 5 | ||||
-rw-r--r-- | src/src/transport.c | 8 | ||||
-rw-r--r-- | src/src/transports/smtp.c | 37 |
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); } |