From e47252f5116d092a96bad199c9a17783885eeef6 Mon Sep 17 00:00:00 2001 From: Jeremy Harris Date: Sun, 11 Jun 2017 23:47:08 +0100 Subject: [PATCH] In tls-proxy process take case to close unused pipe ends, select also for exception conditions on data fds --- src/src/deliver.c | 7 ++++- src/src/transports/smtp.c | 39 ++++++++++++++++---------- test/log/2113 | 20 +++++++------ test/mail/2113.usera | 18 ++++++++++++ test/mail/2113.userb | 18 ++++++++++++ test/mail/2113.userc | 18 ++++++++++++ test/stderr/2113 | 59 +++++++++++++++++++++++++++++++-------- 7 files changed, 145 insertions(+), 34 deletions(-) create mode 100644 test/mail/2113.usera create mode 100644 test/mail/2113.userb create mode 100644 test/mail/2113.userc diff --git a/src/src/deliver.c b/src/src/deliver.c index fe156c696..0e59d5108 100644 --- a/src/src/deliver.c +++ b/src/src/deliver.c @@ -4468,7 +4468,10 @@ for (delivery_count = 0; addr_remote; delivery_count++) if (!ok) { - DEBUG(D_deliver) debug_printf("not suitable for continue_transport\n"); + DEBUG(D_deliver) debug_printf("not suitable for continue_transport (%s)\n", + Ustrcmp(continue_transport, tp->name) != 0 + ? string_sprintf("tpt %s vs %s", continue_transport, tp->name) + : string_sprintf("no host matching %s", continue_hostname)); if (serialize_key) enq_end(serialize_key); if (addr->fallback_hosts && !fallback) @@ -8467,12 +8470,14 @@ if (cutthrough.fd >= 0 && cutthrough.callout_hold_only) else if (pid == 0) /* child: fork again to totally dosconnect */ { + close(pfd[1]); if ((pid = fork())) _exit(pid ? EXIT_FAILURE : EXIT_SUCCESS); smtp_proxy_tls(big_buffer, big_buffer_size, pfd[0], 5*60); exim_exit(0); } + close(pfd[0]); waitpid(pid, NULL, 0); (void) close(channel_fd); /* release the client socket */ channel_fd = pfd[1]; diff --git a/src/src/transports/smtp.c b/src/src/transports/smtp.c index d6a52034b..fc2c0ea4d 100644 --- a/src/src/transports/smtp.c +++ b/src/src/transports/smtp.c @@ -2568,14 +2568,14 @@ Arguments: void smtp_proxy_tls(uschar * buf, size_t bsize, int proxy_fd, int timeout) { -fd_set fds; +fd_set rfds, efds; int max_fd = MAX(proxy_fd, tls_out.active) + 1; int rc, i, fd_bits, nbytes; set_process_info("proxying TLS connection for continued transport"); -FD_ZERO(&fds); -FD_SET(tls_out.active, &fds); -FD_SET(proxy_fd, &fds); +FD_ZERO(&rfds); +FD_SET(tls_out.active, &rfds); +FD_SET(proxy_fd, &rfds); for (fd_bits = 3; fd_bits; ) { @@ -2583,11 +2583,13 @@ for (fd_bits = 3; fd_bits; ) time_t time_start = time(NULL); /* wait for data */ + efds = rfds; do { struct timeval tv = { time_left, 0 }; - rc = select(max_fd, (SELECT_ARG2_TYPE *)&fds, NULL, NULL, &tv); + rc = select(max_fd, + (SELECT_ARG2_TYPE *)&rfds, NULL, (SELECT_ARG2_TYPE *)&efds, &tv); if (rc < 0 && errno == EINTR) if ((time_left -= time(NULL) - time_start) > 0) continue; @@ -2597,16 +2599,24 @@ for (fd_bits = 3; fd_bits; ) DEBUG(D_transport) if (rc == 0) debug_printf("%s: timed out\n", __FUNCTION__); return; } + + if (FD_ISSET(tls_out.active, &efds) || FD_ISSET(proxy_fd, &efds)) + { + DEBUG(D_transport) debug_printf("select: exceptional cond on %s fd\n", + FD_ISSET(proxy_fd, &efds) ? "proxy" : "tls"); + return; + } } - while (rc < 0 || !(FD_ISSET(tls_out.active, &fds) || FD_ISSET(proxy_fd, &fds))); + while (rc < 0 || !(FD_ISSET(tls_out.active, &rfds) || FD_ISSET(proxy_fd, &rfds))); /* handle inbound data */ - if (FD_ISSET(tls_out.active, &fds)) + if (FD_ISSET(tls_out.active, &rfds)) if ((rc = tls_read(FALSE, buf, bsize)) <= 0) { fd_bits &= ~1; - FD_CLR(tls_out.active, &fds); + FD_CLR(tls_out.active, &rfds); shutdown(proxy_fd, SHUT_WR); + timeout = 5; } else { @@ -2614,15 +2624,14 @@ for (fd_bits = 3; fd_bits; ) if ((i = write(proxy_fd, buf + nbytes, rc - nbytes)) < 0) return; } else if (fd_bits & 1) - FD_SET(tls_out.active, &fds); + FD_SET(tls_out.active, &rfds); /* handle outbound data */ - if (FD_ISSET(proxy_fd, &fds)) + if (FD_ISSET(proxy_fd, &rfds)) if ((rc = read(proxy_fd, buf, bsize)) <= 0) { - fd_bits &= ~2; - FD_CLR(proxy_fd, &fds); - shutdown(tls_out.active, SHUT_WR); + fd_bits = 0; + tls_close(FALSE, TRUE); } else { @@ -2631,7 +2640,7 @@ for (fd_bits = 3; fd_bits; ) return; } else if (fd_bits & 2) - FD_SET(proxy_fd, &fds); + FD_SET(proxy_fd, &rfds); } } #endif @@ -3458,6 +3467,7 @@ propagate it from the initial if (pid > 0) /* parent */ { DEBUG(D_transport) debug_printf("proxy-proc inter-pid %d\n", pid); + close(pfd[0]); waitpid(pid, NULL, 0); tls_close(FALSE, FALSE); (void)close(sx.inblock.sock); @@ -3467,6 +3477,7 @@ propagate it from the initial } else if (pid == 0) /* child; fork again to disconnect totally */ { + close(pfd[1]); if ((pid = fork())) { DEBUG(D_transport) debug_printf("proxy-prox final-pid %d\n", pid); diff --git a/test/log/2113 b/test/log/2113 index 1d3ca3332..056c28298 100644 --- a/test/log/2113 +++ b/test/log/2113 @@ -15,10 +15,10 @@ 1999-03-02 09:44:33 Start queue run: pid=pppp -qqf 1999-03-02 09:44:33 10HmbD-0005vi-00 => usera@test.ex R=cl_override T=send_to_server H=127.0.0.1 [127.0.0.1] X=TLSv1:AES256-SHA:256 CV=no DN="/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock" C="250 OK id=10HmbG-0005vi-00" 1999-03-02 09:44:33 10HmbD-0005vi-00 Completed -1999-03-02 09:44:33 10HmbF-0005vi-00 => userc@test.ex R=cl_override T=send_to_server H=127.0.0.1 [127.0.0.1]* X=TLSv1:AES256-SHA:256 CV=no C="250 OK id=10HmbH-0005vi-00" -1999-03-02 09:44:33 10HmbF-0005vi-00 Completed -1999-03-02 09:44:33 10HmbE-0005vi-00 => userb@test.ex R=cl_override T=send_to_server H=127.0.0.1 [127.0.0.1]* X=TLSv1:AES256-SHA:256 CV=no C="250 OK id=10HmbI-0005vi-00" +1999-03-02 09:44:33 10HmbE-0005vi-00 => userb@test.ex R=cl_override T=send_to_server H=127.0.0.1 [127.0.0.1] X=TLSv1:AES256-SHA:256 CV=no DN="/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock" C="250 OK id=10HmbH-0005vi-00" 1999-03-02 09:44:33 10HmbE-0005vi-00 Completed +1999-03-02 09:44:33 10HmbF-0005vi-00 => userc@test.ex R=cl_override T=send_to_server H=127.0.0.1 [127.0.0.1] X=TLSv1:AES256-SHA:256 CV=no DN="/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock" C="250 OK id=10HmbI-0005vi-00" +1999-03-02 09:44:33 10HmbF-0005vi-00 Completed 1999-03-02 09:44:33 End queue run: pid=pppp -qqf ******** SERVER ******** @@ -39,14 +39,18 @@ 1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225 1999-03-02 09:44:33 SMTP connection from [127.0.0.1]:1112 (TCP/IP connection count = 1) 1999-03-02 09:44:33 10HmbG-0005vi-00 <= CALLER@myhost.test.ex H=localhost (myhost.test.ex) [127.0.0.1]:1112 P=esmtps X=TLSv1:AES256-SHA:256 CV=no S=sss id=E10HmbD-0005vi-00@myhost.test.ex for usera@test.ex -1999-03-02 09:44:33 10HmbH-0005vi-00 <= CALLER@myhost.test.ex H=localhost (myhost.test.ex) [127.0.0.1]:1112 P=esmtps X=TLSv1:AES256-SHA:256 CV=no S=sss id=E10HmbF-0005vi-00@myhost.test.ex for userc@test.ex -1999-03-02 09:44:33 10HmbI-0005vi-00 <= CALLER@myhost.test.ex H=localhost (myhost.test.ex) [127.0.0.1]:1112 P=esmtps X=TLSv1:AES256-SHA:256 CV=no S=sss id=E10HmbE-0005vi-00@myhost.test.ex for userb@test.ex -1999-03-02 09:44:33 SMTP connection from localhost (myhost.test.ex) [127.0.0.1]:1112 closed by QUIT +1999-03-02 09:44:33 SMTP connection from localhost (myhost.test.ex) [127.0.0.1]:1112 lost +1999-03-02 09:44:33 SMTP connection from [127.0.0.1]:1113 (TCP/IP connection count = 1) +1999-03-02 09:44:33 10HmbH-0005vi-00 <= CALLER@myhost.test.ex H=localhost (myhost.test.ex) [127.0.0.1]:1113 P=esmtps X=TLSv1:AES256-SHA:256 CV=no S=sss id=E10HmbE-0005vi-00@myhost.test.ex for userb@test.ex +1999-03-02 09:44:33 SMTP connection from localhost (myhost.test.ex) [127.0.0.1]:1113 closed by QUIT +1999-03-02 09:44:33 SMTP connection from [127.0.0.1]:1114 (TCP/IP connection count = 1) +1999-03-02 09:44:33 10HmbI-0005vi-00 <= CALLER@myhost.test.ex H=localhost (myhost.test.ex) [127.0.0.1]:1114 P=esmtps X=TLSv1:AES256-SHA:256 CV=no S=sss id=E10HmbF-0005vi-00@myhost.test.ex for userc@test.ex +1999-03-02 09:44:33 SMTP connection from localhost (myhost.test.ex) [127.0.0.1]:1114 closed by QUIT 1999-03-02 09:44:33 Start queue run: pid=pppp -qf 1999-03-02 09:44:33 10HmbG-0005vi-00 => usera R=server T=local_delivery 1999-03-02 09:44:33 10HmbG-0005vi-00 Completed -1999-03-02 09:44:33 10HmbH-0005vi-00 => userc R=server T=local_delivery +1999-03-02 09:44:33 10HmbH-0005vi-00 => userb R=server T=local_delivery 1999-03-02 09:44:33 10HmbH-0005vi-00 Completed -1999-03-02 09:44:33 10HmbI-0005vi-00 => userb R=server T=local_delivery +1999-03-02 09:44:33 10HmbI-0005vi-00 => userc R=server T=local_delivery 1999-03-02 09:44:33 10HmbI-0005vi-00 Completed 1999-03-02 09:44:33 End queue run: pid=pppp -qf diff --git a/test/mail/2113.usera b/test/mail/2113.usera new file mode 100644 index 000000000..43e950776 --- /dev/null +++ b/test/mail/2113.usera @@ -0,0 +1,18 @@ +From CALLER@myhost.test.ex Tue Mar 02 09:44:33 1999 +Received: from localhost ([127.0.0.1]:1112 helo=myhost.test.ex) + by myhost.test.ex with esmtps (TLSv1:AES256-SHA:256) + (Exim x.yz) + (envelope-from ) + id 10HmbG-0005vi-00 + for usera@test.ex; Tue, 2 Mar 1999 09:44:33 +0000 +Received: from CALLER by myhost.test.ex with local (Exim x.yz) + (envelope-from ) + id 10HmbD-0005vi-00 + for usera@test.ex; Tue, 2 Mar 1999 09:44:33 +0000 +Message-Id: +From: CALLER_NAME +Date: Tue, 2 Mar 1999 09:44:33 +0000 +TLS: cipher=TLSv1:AES256-SHA:256 peerdn= + +Test message 1 + diff --git a/test/mail/2113.userb b/test/mail/2113.userb new file mode 100644 index 000000000..a19f5fd76 --- /dev/null +++ b/test/mail/2113.userb @@ -0,0 +1,18 @@ +From CALLER@myhost.test.ex Tue Mar 02 09:44:33 1999 +Received: from localhost ([127.0.0.1]:1113 helo=myhost.test.ex) + by myhost.test.ex with esmtps (TLSv1:AES256-SHA:256) + (Exim x.yz) + (envelope-from ) + id 10HmbH-0005vi-00 + for userb@test.ex; Tue, 2 Mar 1999 09:44:33 +0000 +Received: from CALLER by myhost.test.ex with local (Exim x.yz) + (envelope-from ) + id 10HmbE-0005vi-00 + for userb@test.ex; Tue, 2 Mar 1999 09:44:33 +0000 +Message-Id: +From: CALLER_NAME +Date: Tue, 2 Mar 1999 09:44:33 +0000 +TLS: cipher=TLSv1:AES256-SHA:256 peerdn= + +Test message 2 + diff --git a/test/mail/2113.userc b/test/mail/2113.userc new file mode 100644 index 000000000..e623a0664 --- /dev/null +++ b/test/mail/2113.userc @@ -0,0 +1,18 @@ +From CALLER@myhost.test.ex Tue Mar 02 09:44:33 1999 +Received: from localhost ([127.0.0.1]:1114 helo=myhost.test.ex) + by myhost.test.ex with esmtps (TLSv1:AES256-SHA:256) + (Exim x.yz) + (envelope-from ) + id 10HmbI-0005vi-00 + for userc@test.ex; Tue, 2 Mar 1999 09:44:33 +0000 +Received: from CALLER by myhost.test.ex with local (Exim x.yz) + (envelope-from ) + id 10HmbF-0005vi-00 + for userc@test.ex; Tue, 2 Mar 1999 09:44:33 +0000 +Message-Id: +From: CALLER_NAME +Date: Tue, 2 Mar 1999 09:44:33 +0000 +TLS: cipher=TLSv1:AES256-SHA:256 peerdn= + +Test message 3 + diff --git a/test/stderr/2113 b/test/stderr/2113 index 35cdabe47..8d25729d3 100644 --- a/test/stderr/2113 +++ b/test/stderr/2113 @@ -118,26 +118,65 @@ Exim version x.yz .... configuration file is TESTSUITE/test-config trusted user admin user +>>>>>>>>>>>>>>>> Exim pid=pppp terminating with rc=0 >>>>>>>>>>>>>>>> +>>>>>>>>>>>>>>>> Exim pid=pppp terminating with rc=0 >>>>>>>>>>>>>>>> +Connecting to 127.0.0.1 [127.0.0.1]:1225 ... connected + SMTP<< 220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000 + SMTP>> EHLO myhost.test.ex +cmd buf flush ddd bytes + SMTP<< 250-myhost.test.ex Hello localhost [127.0.0.1] + 250-SIZE 52428800 + 250-8BITMIME + 250-PIPELINING + 250-STARTTLS + 250 HELP + SMTP>> STARTTLS +cmd buf flush ddd bytes + SMTP<< 220 TLS go ahead + SMTP>> EHLO myhost.test.ex +cmd buf flush ddd bytes + SMTP<< 250-myhost.test.ex Hello localhost [127.0.0.1] + 250-SIZE 52428800 + 250-8BITMIME + 250-PIPELINING + 250 HELP SMTP>> MAIL FROM: SIZE=ssss - SMTP>> RCPT TO: + SMTP>> RCPT TO: SMTP>> DATA cmd buf flush ddd bytes SMTP<< 250 OK SMTP<< 250 Accepted SMTP<< 354 Enter message, ending with "." on a line by itself SMTP<< 250 OK id=10HmbH-0005vi-00 + SMTP>> QUIT +cmd buf flush ddd bytes SMTP(close)>> LOG: MAIN - => userc@test.ex R=cl_override T=send_to_server H=127.0.0.1 [127.0.0.1]* X=TLSv1:AES256-SHA:256 CV=no C="250 OK id=10HmbH-0005vi-00" + => userb@test.ex R=cl_override T=send_to_server H=127.0.0.1 [127.0.0.1] X=TLSv1:AES256-SHA:256 CV=no DN="/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock" C="250 OK id=10HmbH-0005vi-00" LOG: MAIN Completed ->>>>>>>>>>>>>>>> Exim pid=pppp terminating with rc=0 >>>>>>>>>>>>>>>> -Exim version x.yz .... -configuration file is TESTSUITE/test-config -trusted user -admin user +Connecting to 127.0.0.1 [127.0.0.1]:1225 ... connected + SMTP<< 220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000 + SMTP>> EHLO myhost.test.ex +cmd buf flush ddd bytes + SMTP<< 250-myhost.test.ex Hello localhost [127.0.0.1] + 250-SIZE 52428800 + 250-8BITMIME + 250-PIPELINING + 250-STARTTLS + 250 HELP + SMTP>> STARTTLS +cmd buf flush ddd bytes + SMTP<< 220 TLS go ahead + SMTP>> EHLO myhost.test.ex +cmd buf flush ddd bytes + SMTP<< 250-myhost.test.ex Hello localhost [127.0.0.1] + 250-SIZE 52428800 + 250-8BITMIME + 250-PIPELINING + 250 HELP SMTP>> MAIL FROM: SIZE=ssss - SMTP>> RCPT TO: + SMTP>> RCPT TO: SMTP>> DATA cmd buf flush ddd bytes SMTP<< 250 OK @@ -147,12 +186,10 @@ cmd buf flush ddd bytes SMTP>> QUIT cmd buf flush ddd bytes SMTP(close)>> ->>>>>>>>>>>>>>>> Exim pid=pppp terminating with rc=0 >>>>>>>>>>>>>>>> LOG: MAIN - => userb@test.ex R=cl_override T=send_to_server H=127.0.0.1 [127.0.0.1]* X=TLSv1:AES256-SHA:256 CV=no C="250 OK id=10HmbI-0005vi-00" + => userc@test.ex R=cl_override T=send_to_server H=127.0.0.1 [127.0.0.1] X=TLSv1:AES256-SHA:256 CV=no DN="/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock" C="250 OK id=10HmbI-0005vi-00" LOG: MAIN Completed ->>>>>>>>>>>>>>>> Exim pid=pppp terminating with rc=0 >>>>>>>>>>>>>>>> LOG: queue_run MAIN End queue run: pid=pppp -qqf >>>>>>>>>>>>>>>> Exim pid=pppp terminating with rc=0 >>>>>>>>>>>>>>>> -- 2.25.1