From 8a6b4e02cd384193a5566e8601bdd97249b22284 Mon Sep 17 00:00:00 2001 From: Jeremy Harris Date: Thu, 9 Aug 2018 20:37:42 +0100 Subject: [PATCH] Fix cutthrough delivery for more than one iteration of address redirection. Bug 2296 --- doc/doc-txt/ChangeLog | 5 ++ src/src/verify.c | 19 +++-- test/confs/5400 | 5 ++ test/confs/5408 | 1 + test/log/5408 | 17 +++++ test/scripts/5400-cutthrough/5408 | 115 ++++++++++++++++++++++++++++++ 6 files changed, 157 insertions(+), 5 deletions(-) create mode 120000 test/confs/5408 create mode 100644 test/log/5408 create mode 100644 test/scripts/5400-cutthrough/5408 diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog index b0fbf9178..bf5afe0af 100644 --- a/doc/doc-txt/ChangeLog +++ b/doc/doc-txt/ChangeLog @@ -87,6 +87,11 @@ JH/19 Reject MAIL FROM commands with SMTPUTF8 when the facility was not advertis PP/02 Let -n work with printing macros too, not just options. +JH/20 Bug 2296: Fix cutthrough for >1 address redirection. Previously only + one parent address was copied, and bogus data was used at delivery-logging + time. Either a crash (after delivery) or bogus log data could result. + Discovery and analysis by Tim Stewart. + Exim version 4.91 ----------------- diff --git a/src/src/verify.c b/src/src/verify.c index 35b21a54d..6411899c8 100644 --- a/src/src/verify.c +++ b/src/src/verify.c @@ -1070,6 +1070,8 @@ no_conn: && !sx.lmtp ) { + address_item * parent, * caddr; + HDEBUG(D_acl|D_v) debug_printf_indent("holding verify callout open for %s\n", cutthrough.delivery ? "cutthrough delivery" : "potential further verifies and delivery"); @@ -1092,12 +1094,16 @@ no_conn: cutthrough.host.address = string_copy(host->address); store_pool = oldpool; } - cutthrough.addr = *addr; /* Save the address_item for later logging */ + + /* Save the address_item and parent chain for later logging */ + cutthrough.addr = *addr; cutthrough.addr.next = NULL; cutthrough.addr.host_used = &cutthrough.host; - if (addr->parent) - *(cutthrough.addr.parent = store_get(sizeof(address_item))) = - *addr->parent; + for (caddr = &cutthrough.addr, parent = addr->parent; + parent; + parent = parent->parent) + *(caddr->parent = store_get(sizeof(address_item))) = *parent; + ctblock.buffer = ctbuffer; ctblock.buffersize = sizeof(ctbuffer); ctblock.ptr = ctbuffer; @@ -1194,7 +1200,7 @@ return yield; one was requested and a recipient-verify wasn't subsequently done. */ int -open_cutthrough_connection( address_item * addr ) +open_cutthrough_connection(address_item * addr) { address_item addr2; int rc; @@ -1942,6 +1948,9 @@ while (addr_new) #endif rc = do_callout(addr, host_list, &tf, callout, callout_overall, callout_connect, options, se_mailfrom, pm_mailfrom); +#ifdef SUPPORT_TLS + deliver_set_expansions(NULL); +#endif } } else diff --git a/test/confs/5400 b/test/confs/5400 index 5a5e60a88..ad48ebda8 100644 --- a/test/confs/5400 +++ b/test/confs/5400 @@ -34,6 +34,11 @@ ar: begin routers +redir: + driver = redirect + local_parts = ^r + data = ${substr_1:$local_part}@$domain + dns: driver = dnslookup domains = localhost.test.ex : localhost4.test.ex : thishost.test.ex diff --git a/test/confs/5408 b/test/confs/5408 new file mode 120000 index 000000000..8f6811b7e --- /dev/null +++ b/test/confs/5408 @@ -0,0 +1 @@ +5400 \ No newline at end of file diff --git a/test/log/5408 b/test/log/5408 new file mode 100644 index 000000000..2b367ac3c --- /dev/null +++ b/test/log/5408 @@ -0,0 +1,17 @@ +**NOTE: The delivery lines in this file have been sorted. +1999-03-02 09:44:33 rcpt for userx@domain.com +1999-03-02 09:44:33 10HmaX-0005vi-00 >> userx@domain.com R=all T=smtp H=127.0.0.1 [127.0.0.1] C="250 OK" +1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local-esmtp S=sss for userx@domain.com +1999-03-02 09:44:33 10HmaX-0005vi-00 Completed +1999-03-02 09:44:33 rcpt for ruserx@domain.com +1999-03-02 09:44:33 10HmaY-0005vi-00 >> userx@domain.com R=all T=smtp H=127.0.0.1 [127.0.0.1] C="250 OK" +1999-03-02 09:44:33 10HmaY-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local-esmtp S=sss for ruserx@domain.com +1999-03-02 09:44:33 10HmaY-0005vi-00 Completed +1999-03-02 09:44:33 rcpt for rruserx@domain.com +1999-03-02 09:44:33 10HmaZ-0005vi-00 >> userx@domain.com R=all T=smtp H=127.0.0.1 [127.0.0.1] C="250 OK" +1999-03-02 09:44:33 10HmaZ-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local-esmtp S=sss for rruserx@domain.com +1999-03-02 09:44:33 10HmaZ-0005vi-00 Completed +1999-03-02 09:44:33 rcpt for rrruserx@domain.com +1999-03-02 09:44:33 10HmbA-0005vi-00 >> userx@domain.com R=all T=smtp H=127.0.0.1 [127.0.0.1] C="250 OK" +1999-03-02 09:44:33 10HmbA-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local-esmtp S=sss for rrruserx@domain.com +1999-03-02 09:44:33 10HmbA-0005vi-00 Completed diff --git a/test/scripts/5400-cutthrough/5408 b/test/scripts/5400-cutthrough/5408 new file mode 100644 index 000000000..93f4d3593 --- /dev/null +++ b/test/scripts/5400-cutthrough/5408 @@ -0,0 +1,115 @@ +# cutthrough_delivery with router redirections +need_ipv4 +munge loopback +# +# Plain, no redirect +server PORT_S +220 ESMTP +EHLO +250 OK +MAIL FROM: +250 Sender OK +RCPT TO: +250 Recipient OK +DATA +354 Send data +. +250 OK +QUIT +250 OK +**** +exim -bs +EHLO myhost.test.ex +MAIL FROM: +RCPT TO: +DATA + +. +QUIT +**** +# +# +# One redirect +server PORT_S +220 ESMTP +EHLO +250 OK +MAIL FROM: +250 Sender OK +RCPT TO: +250 Recipient OK +DATA +354 Send data +. +250 OK +QUIT +250 OK +**** +exim -bs +EHLO myhost.test.ex +MAIL FROM: +RCPT TO: +DATA + +. +QUIT +**** +# +# +# Two redirects +server PORT_S +220 ESMTP +EHLO +250 OK +MAIL FROM: +250 Sender OK +RCPT TO: +250 Recipient OK +DATA +354 Send data +. +250 OK +QUIT +250 OK +**** +exim -bs +EHLO myhost.test.ex +MAIL FROM: +RCPT TO: +DATA + +. +QUIT +**** +# +# +# Three redirects +server PORT_S +220 ESMTP +EHLO +250 OK +MAIL FROM: +250 Sender OK +RCPT TO: +250 Recipient OK +DATA +354 Send data +. +250 OK +QUIT +250 OK +**** +exim -bs +EHLO myhost.test.ex +MAIL FROM: +RCPT TO: +DATA + +. +QUIT +**** +# +# +sortlog +no_stdout_check +# End -- 2.25.1