[exim-cvs] Verify callout/random: repoen connection if error…

Top Page
Delete this message
Reply to this message
Author: Exim Git Commits Mailing List
Date:  
To: exim-cvs
Subject: [exim-cvs] Verify callout/random: repoen connection if error after random rcpt attempt. Bug 495
Gitweb: http://git.exim.org/exim.git/commitdiff/65f1c92a5c06bb7de867f8d72c7eef5f829daeb4
Commit:     65f1c92a5c06bb7de867f8d72c7eef5f829daeb4
Parent:     dc7b3d368017727e9438fc7463b0841df1e4aa41
Author:     Jeremy Harris <jgh146exb@???>
AuthorDate: Sun Feb 15 20:38:26 2015 +0000
Committer:  Jeremy Harris <jgh146exb@???>
CommitDate: Sun Feb 15 21:05:03 2015 +0000


    Verify callout/random: repoen connection if error after random rcpt attempt.  Bug 495
---
 src/src/verify.c             |   39 +++++++++++++++++++++++++++++----------
 test/scripts/0000-Basic/0473 |   28 ++++++++++++++++++++++++++++
 test/stdout/0473             |   42 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 99 insertions(+), 10 deletions(-)


diff --git a/src/src/verify.c b/src/src/verify.c
index ec75ce5..c1fb177 100644
--- a/src/src/verify.c
+++ b/src/src/verify.c
@@ -388,12 +388,9 @@ else
log the fact, but carry on without randomming. */

   if (callout_random && callout_random_local_part != NULL)
-    {
-    random_local_part = expand_string(callout_random_local_part);
-    if (random_local_part == NULL)
+    if (!(random_local_part = expand_string(callout_random_local_part)))
       log_write(0, LOG_MAIN|LOG_PANIC, "failed to expand "
         "callout_random_local_part: %s", expand_string_message);
-    }


   /* Default the connect and overall callout timeouts if not set, and record the
   time we are starting so that we can enforce it. */
@@ -635,14 +632,14 @@ can do it there for the non-rcpt-verify case.  For this we keep an addresscount.
     outblock.cmd_count = 0;
     outblock.authenticating = FALSE;


-    /* Reset the parameters of a TLS session */
-    tls_out.cipher = tls_out.peerdn = tls_out.peercert = NULL;
-
     /* Connect to the host; on failure, just loop for the next one, but we
     set the error for the last one. Use the callout_connect timeout. */


     tls_retry_connection:


+    /* Reset the parameters of a TLS session */
+    tls_out.cipher = tls_out.peerdn = tls_out.peercert = NULL;
+
     inblock.sock = outblock.sock =
       smtp_connect(host, host_af, port, interface, callout_connect, TRUE, NULL
 #ifdef EXPERIMENTAL_EVENT
@@ -1009,10 +1006,15 @@ can do it there for the non-rcpt-verify case.  For this we keep an addresscount.


         /* Otherwise, cache a real negative response, and get back to the right
         state to send RCPT. Unless there's some problem such as a dropped
-        connection, we expect to succeed, because the commands succeeded above. */
+        connection, we expect to succeed, because the commands succeeded above.
+    However, some servers drop the connection after responding to  an
+    invalid recipient, so on (any) error we drop and remake the connection.
+    */


         else if (errno == 0)
           {
+      /* This would be ok for 1st rcpt a cutthrough, but no way to
+      handle a subsequent.  So refuse to support any */
       cancel_cutthrough_connection("random-recipient");


           if (randombuffer[0] == '5')
@@ -1027,6 +1029,22 @@ can do it there for the non-rcpt-verify case.  For this we keep an addresscount.
               from_address) >= 0 &&
             smtp_read_response(&inblock, responsebuffer, sizeof(responsebuffer),
               '2', callout);
+
+      if (!done)
+        {
+        HDEBUG(D_acl|D_v)
+          debug_printf("problem after random/rset/mfrom; reopen conn\n");
+        random_local_part = NULL;
+#ifdef SUPPORT_TLS
+        tls_close(FALSE, TRUE);
+#endif
+        (void)close(inblock.sock);
+#ifdef EXPERIMENTAL_EVENT
+        (void) event_raise(addr->transport->event_action,
+                  US"tcp:close", NULL);
+#endif
+        goto tls_retry_connection;
+        }
           }
         else done = FALSE;    /* Some timeout/connection problem */
         }                     /* Random check */
@@ -1060,8 +1078,9 @@ can do it there for the non-rcpt-verify case.  For this we keep an addresscount.


         if (done && pm_mailfrom != NULL)
           {
-          /*XXX not suitable for cutthrough - we cannot afford to do an RSET
-      and lose the original mail-from */
+          /* Could possibly shift before main verify, just above, and be ok
+      for cutthrough.  But no way to handle a subsequent rcpt, so just
+      refuse any */
     cancel_cutthrough_connection("postmaster verify");
       HDEBUG(D_acl|D_v) debug_printf("Cutthrough cancelled by presence of postmaster verify\n");


diff --git a/test/scripts/0000-Basic/0473 b/test/scripts/0000-Basic/0473
index 3d17e5e..df613c4 100644
--- a/test/scripts/0000-Basic/0473
+++ b/test/scripts/0000-Basic/0473
@@ -150,6 +150,34 @@ rcpt to: r11@???
quit
****
dump callout
+#
+# callout target dumps after random-reject
+server PORT_S 2
+220 Server ready
+EHLO
+250 OK
+MAIL FROM
+250 OK
+RCPT TO
+550 Bad receipient, dropping conn
+>*eof
+220 Server ready
+EHLO
+250 OK
+MAIL FROM
+250 OK
+RCPT TO
+250 OK
+QUIT
+250 OK
+****
+exim -DUSE_SENDER=,random -bs
+ehlo xxxx
+mail from: x12@???
+rcpt to: r12@???
+quit
+****
+dump callout
server PORT_S
220 Server ready
EHLO
diff --git a/test/stdout/0473 b/test/stdout/0473
index 9fff9a6..59ed36d 100644
--- a/test/stdout/0473
+++ b/test/stdout/0473
@@ -107,6 +107,26 @@
250-PIPELINING
250 HELP
250 OK
+250 Accepted
+221 the.local.host.name closing connection
++++++++++++++++++++++++++++
+07-Mar-2000 12:21:52 r12@??? callout=accept
+07-Mar-2000 12:21:52 r1@??? callout=accept
+07-Mar-2000 12:21:52 r1@???/<postmaster@???> callout=accept
+07-Mar-2000 12:21:52 r1@???/<s1@???> callout=accept
+07-Mar-2000 12:21:52 r1@???/<s2@???> callout=accept
+07-Mar-2000 12:21:52 r9@???/<x9@???> callout=reject
+07-Mar-2000 12:21:52 test.ex callout=accept postmaster=unknown random=unknown
+07-Mar-2000 12:21:52 three.test.ex callout=accept postmaster=unknown random=reject (07-Mar-2000 12:21:52)
+07-Mar-2000 12:21:52 two.test.ex callout=accept postmaster=unknown random=accept (07-Mar-2000 12:21:52)
+07-Mar-2000 12:21:52 x9@??? callout=reject
+220 the.local.host.name ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000
+250-the.local.host.name Hello CALLER at xxxx
+250-SIZE 52428800
+250-8BITMIME
+250-PIPELINING
+250 HELP
+250 OK
451 Could not complete recipient verify callout
221 the.local.host.name closing connection
220 the.local.host.name ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000
@@ -221,6 +241,28 @@ EHLO the.local.host.name
250 OK
MAIL FROM:<>
250 OK
+RCPT TO:<the.local.host.name--testing@???>
+550 Bad receipient, dropping conn
+>*eof
+Listening on port 1224 ...
+Connection request from [127.0.0.1]
+220 Server ready
+EHLO the.local.host.name
+250 OK
+MAIL FROM:<>
+250 OK
+RCPT TO:<r12@???>
+250 OK
+QUIT
+250 OK
+End of script
+Listening on port 1224 ...
+Connection request from [127.0.0.1]
+220 Server ready
+EHLO the.local.host.name
+250 OK
+MAIL FROM:<>
+250 OK
RCPT TO:<r11@???>
*sleep 2
End of script