From: Jeremy Harris Date: Mon, 22 Jun 2020 16:27:18 +0000 (+0100) Subject: Cutthrough: handle request when a callout-hold is active. Bug 2604 X-Git-Url: https://git.exim.org/users/heiko/exim.git/commitdiff_plain/cdee8a5f76cc013de5622112cd04e42d0dcf333b?hp=5c608b75d5bd734ddca41e4468fb22544ef96265 Cutthrough: handle request when a callout-hold is active. Bug 2604 (cherry picked from commit 99bfcf2b678e7bd8125a7eb44409e46549bfc111) --- diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog index 1173b3651..de11b4f09 100644 --- a/doc/doc-txt/ChangeLog +++ b/doc/doc-txt/ChangeLog @@ -45,6 +45,10 @@ JH/10 Bug 2603: Fix coding of string copying to only evaluate arguments once. argument as an expression having side-effects, incorrect operation resulted. Use an inlineable function. +JH/11 Bug 2604: Fix request to cutthrough-deliver when a connection is already + held open for a verify callout. Previously this wan not accounted for + and a corrupt onward SMTP conversation resulted. + Exim version 4.94 diff --git a/src/src/acl.c b/src/src/acl.c index 11d1fd028..62cb68561 100644 --- a/src/src/acl.c +++ b/src/src/acl.c @@ -3264,37 +3264,41 @@ for (; cb; cb = cb->next) the case where both sides handle prdr and this-node prdr acl is "accept" */ ignored = US"PRDR active"; + else if (f.deliver_freeze) + ignored = US"frozen"; + else if (f.queue_only_policy) + ignored = US"queue-only"; + else if (fake_response == FAIL) + ignored = US"fakereject"; + else if (rcpt_count != 1) + ignored = US"nonfirst rcpt"; + else if (cutthrough.delivery) + ignored = US"repeated"; + else if (cutthrough.callout_hold_only) + { + DEBUG(D_acl) + debug_printf_indent(" cutthrough request upgrades callout hold\n"); + cutthrough.callout_hold_only = FALSE; + cutthrough.delivery = TRUE; /* control accepted */ + } else { - if (f.deliver_freeze) - ignored = US"frozen"; - else if (f.queue_only_policy) - ignored = US"queue-only"; - else if (fake_response == FAIL) - ignored = US"fakereject"; - else + cutthrough.delivery = TRUE; /* control accepted */ + while (*p == '/') { - if (rcpt_count == 1) + const uschar * pp = p+1; + if (Ustrncmp(pp, "defer=", 6) == 0) { - cutthrough.delivery = TRUE; /* control accepted */ - while (*p == '/') - { - const uschar * pp = p+1; - if (Ustrncmp(pp, "defer=", 6) == 0) - { - pp += 6; - if (Ustrncmp(pp, "pass", 4) == 0) cutthrough.defer_pass = TRUE; - /* else if (Ustrncmp(pp, "spool") == 0) ; default */ - } - else - while (*pp && *pp != '/') pp++; - p = pp; - } + pp += 6; + if (Ustrncmp(pp, "pass", 4) == 0) cutthrough.defer_pass = TRUE; + /* else if (Ustrncmp(pp, "spool") == 0) ; default */ } else - ignored = US"nonfirst rcpt"; + while (*pp && *pp != '/') pp++; + p = pp; } } + DEBUG(D_acl) if (ignored) debug_printf(" cutthrough request ignored on %s item\n", ignored); } diff --git a/src/src/verify.c b/src/src/verify.c index fba1f6e9e..5f4181de9 100644 --- a/src/src/verify.c +++ b/src/src/verify.c @@ -875,12 +875,12 @@ tls_retry_connection: case PENDING_OK: done = TRUE; new_address_record.result = ccache_accept; break; - case FAIL: done = TRUE; + case FAIL: done = TRUE; yield = FAIL; *failure_ptr = US"recipient"; new_address_record.result = ccache_reject; break; - default: break; + default: break; } break; diff --git a/test/confs/5409 b/test/confs/5409 new file mode 100644 index 000000000..be1415e0b --- /dev/null +++ b/test/confs/5409 @@ -0,0 +1,46 @@ +# Exim test configuration 5409 + +.include DIR/aux-var/std_conf_prefix + +primary_hostname = myhost.test.ex + +# ----- Main settings ----- + +domainlist local_domains = test.ex : *.test.ex + +acl_smtp_rcpt = acl_rcpt + +# ----- ACLs ------- + +begin acl + +acl_rcpt: + accept verify = recipient/callout=use_sender,hold,no_cache + control = cutthrough_delivery + + +# ----- Routers ----- + +begin routers + +all: + driver = manualroute + domains = ! +local_domains + route_list = * 127.0.0.1 + self = send + transport = smtp + no_more + + +# ----- Transports ----- + +begin transports + +smtp: + driver = smtp + interface = HOSTIPV4 + port = PORT_S + hosts_try_fastopen = : + + +# End diff --git a/test/log/5409 b/test/log/5409 new file mode 100644 index 000000000..37ad46794 --- /dev/null +++ b/test/log/5409 @@ -0,0 +1,3 @@ +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 +1999-03-02 09:44:33 10HmaX-0005vi-00 Completed diff --git a/test/scripts/5400-cutthrough/5409 b/test/scripts/5400-cutthrough/5409 new file mode 100644 index 000000000..c9d63d185 --- /dev/null +++ b/test/scripts/5400-cutthrough/5409 @@ -0,0 +1,29 @@ +# cutthrough_delivery preceded by recipient-verify/hold +need_ipv4 +# +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 -odf +EHLO myhost.test.ex +MAIL FROM: +RCPT TO: +DATA +Subject: test + +body +. +QUIT +**** diff --git a/test/stdout/5409 b/test/stdout/5409 new file mode 100644 index 000000000..a582bb8c3 --- /dev/null +++ b/test/stdout/5409 @@ -0,0 +1,40 @@ +220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000 +250-myhost.test.ex Hello CALLER at myhost.test.ex +250-SIZE 52428800 +250-8BITMIME +250-PIPELINING +250 HELP +250 OK +250 Accepted +354 Enter message, ending with "." on a line by itself +250 OK id=10HmaX-0005vi-00 +221 myhost.test.ex closing connection + +******** SERVER ******** +Listening on port 1224 ... +Connection request from [ip4.ip4.ip4.ip4] +220 ESMTP +EHLO myhost.test.ex +250 OK +MAIL FROM: +250 Sender OK +RCPT TO: +250 Recipient OK +DATA +354 Send data +Received: from CALLER (helo=myhost.test.ex) + by myhost.test.ex with local-esmtp (Exim x.yz) + (envelope-from ) + id 10HmaX-0005vi-00 + for userx@domain.com; Tue, 2 Mar 1999 09:44:33 +0000 +Subject: test +Message-Id: +From: CALLER_NAME +Date: Tue, 2 Mar 1999 09:44:33 +0000 + +body +. +250 OK +QUIT +250 OK +End of script