Pass on SIZE to cutthrough connection
authorJeremy Harris <jgh146exb@wizmail.org>
Tue, 2 Feb 2016 21:49:02 +0000 (21:49 +0000)
committerJeremy Harris <jgh146exb@wizmail.org>
Tue, 2 Feb 2016 21:54:33 +0000 (21:54 +0000)
16 files changed:
doc/doc-txt/ChangeLog
doc/doc-txt/NewStuff
src/src/daemon.c
src/src/exim.c
src/src/functions.h
src/src/macros.h
src/src/transports/smtp.c
src/src/verify.c
test/confs/5402 [new symlink]
test/log/5402 [new file with mode: 0644]
test/scripts/5400-cutthrough/5402 [new file with mode: 0644]
test/stderr/0143
test/stderr/0388
test/stderr/0476
test/stderr/5402 [deleted file]
test/stdout/5402

index 1d1a5d9f58ee6c754ebb3890dacea63153a9772e..01848573bb10c4745e5aef72de46ff4249aa964c 100644 (file)
@@ -2,6 +2,13 @@ Change log file for Exim from version 4.21
 -------------------------------------------
 
 
 -------------------------------------------
 
 
+Exim version 4.next
+-----------------
+JH/01 Use SIZE on MAIL FROM in a cutthrough connection, if the destination
+      supports it and a size is available (ie. the sending peer gave us one).
+
+
+
 Exim version 4.87
 -----------------
 JH/01 Bug 1664: Disable OCSP for GnuTLS library versions at/before 3.3.16
 Exim version 4.87
 -----------------
 JH/01 Bug 1664: Disable OCSP for GnuTLS library versions at/before 3.3.16
@@ -287,8 +294,6 @@ JH/35 Bug 1642: Fix support of $spam_ variables at delivery time.  Was
 JH/36 Bug 1659: Guard checking of input smtp commands again pseudo-command
       added for tls authenticator.
 
 JH/36 Bug 1659: Guard checking of input smtp commands again pseudo-command
       added for tls authenticator.
 
-HS/03 Add perl_taintmode main config option
-
 
 Exim version 4.85
 -----------------
 
 Exim version 4.85
 -----------------
index 01bd0111e0b54daac3ed2e756afc0a202069ab03..2e7648a758e280864be9bad01925d909c3efe227 100644 (file)
@@ -6,6 +6,12 @@ Before a formal release, there may be quite a lot of detail so that people can
 test from the snapshots or the CVS before the documentation is updated. Once
 the documentation is updated, this file is reduced to a short list.
 
 test from the snapshots or the CVS before the documentation is updated. Once
 the documentation is updated, this file is reduced to a short list.
 
+Version 4.next
+--------------
+
+ 1. New perl_taintmode main config option.
+
+
 Version 4.87
 ------------
 
 Version 4.87
 ------------
 
index 24874c374f0a9f8d5d61b69eea8eadf7075c2cac..f2c8dbfaf1d71b154aa61d44f0dcf50dc423d4b9 100644 (file)
@@ -1705,7 +1705,6 @@ else
 /* Do any work it might be useful to amortize over our children
 (eg: compile regex) */
 
 /* Do any work it might be useful to amortize over our children
 (eg: compile regex) */
 
-deliver_init();
 dns_pattern_init();
 
 #ifdef WITH_CONTENT_SCAN
 dns_pattern_init();
 
 #ifdef WITH_CONTENT_SCAN
index ebc71dd371929028edd35f69d11745f1a5dd83dd..e6acb0b80b3b221b9d01a91e925fff625983c4cb 100644 (file)
@@ -4559,6 +4559,7 @@ if (list_config)
 #ifndef DISABLE_DKIM
 dkim_exim_init();
 #endif
 #ifndef DISABLE_DKIM
 dkim_exim_init();
 #endif
+deliver_init();
 
 
 /* Handle a request to deliver one or more messages that are already on the
 
 
 /* Handle a request to deliver one or more messages that are already on the
index 97d95dd3d49b697aff07346db801acf357393eda..4cee9bf8b979766f1372ff945633052cbb8d7b3c 100644 (file)
@@ -169,6 +169,7 @@ extern BOOL    enq_start(uschar *, unsigned);
 extern uschar *event_raise(uschar *, const uschar *, uschar *);
 extern void    msg_event_raise(const uschar *, const address_item *);
 #endif
 extern uschar *event_raise(uschar *, const uschar *, uschar *);
 extern void    msg_event_raise(const uschar *, const address_item *);
 #endif
+extern uschar  ehlo_response(uschar *, size_t, uschar);
 extern void    exim_exit(int);
 extern void    exim_nullstd(void);
 extern void    exim_setugid(uid_t, gid_t, BOOL, uschar *);
 extern void    exim_exit(int);
 extern void    exim_nullstd(void);
 extern void    exim_setugid(uid_t, gid_t, BOOL, uschar *);
index 66abffa3750c3cdef72ffc150dd5d6af34480001..645799d9942c1d78639bc80f52cce4459da1152f 100644 (file)
@@ -939,4 +939,15 @@ explicit port number. */
 
 enum { FILTER_UNSET, FILTER_FORWARD, FILTER_EXIM, FILTER_SIEVE };
 
 
 enum { FILTER_UNSET, FILTER_FORWARD, FILTER_EXIM, FILTER_SIEVE };
 
+/* Codes for ESMTP facilities offered by peer */
+
+#define PEER_OFFERED_TLS       BIT(0)
+#define PEER_OFFERED_IGNQ      BIT(1)
+#define PEER_OFFERED_PRDR      BIT(2)
+#define PEER_OFFERED_UTF8      BIT(3)
+#define PEER_OFFERED_DSN       BIT(4)
+#define PEER_OFFERED_PIPE      BIT(5)
+#define PEER_OFFERED_SIZE      BIT(6)
+
+
 /* End of macros.h */
 /* End of macros.h */
index 135069d0f189e487f2cfb304dd155f59c4f9244a..0fa761e75ee01b93bc8dddc3126e2fc87042ef4c 100644 (file)
@@ -1330,6 +1330,49 @@ return Ustrcmp(current_local_identity, message_local_identity) == 0;
 
 
 
 
 
 
+uschar
+ehlo_response(uschar * buf, size_t bsize, uschar checks)
+{
+#ifdef SUPPORT_TLS
+if (checks & PEER_OFFERED_TLS)
+  if (pcre_exec(regex_STARTTLS, NULL, CS buf, bsize, 0, PCRE_EOPT, NULL, 0) < 0)
+    checks &= ~PEER_OFFERED_TLS;
+#endif
+
+  if (  checks & PEER_OFFERED_IGNQ
+     && pcre_exec(regex_IGNOREQUOTA, NULL, CS buf, bsize, 0,
+                 PCRE_EOPT, NULL, 0) < 0)
+    checks &= ~PEER_OFFERED_IGNQ;
+
+#ifndef DISABLE_PRDR
+  if (  checks & PEER_OFFERED_PRDR
+     && pcre_exec(regex_PRDR, NULL, CS buf, bsize, 0, PCRE_EOPT, NULL, 0) < 0)
+    checks &= ~PEER_OFFERED_PRDR;
+#endif
+
+#ifdef SUPPORT_I18N
+  if (  checks & PEER_OFFERED_UTF8
+     && pcre_exec(regex_UTF8, NULL, CS buf, bsize, 0, PCRE_EOPT, NULL, 0) < 0)
+    checks &= ~PEER_OFFERED_UTF8;
+#endif
+
+  if (  checks & PEER_OFFERED_DSN
+     && pcre_exec(regex_DSN, NULL, CS buf, bsize, 0, PCRE_EOPT, NULL, 0) < 0)
+    checks &= ~PEER_OFFERED_DSN;
+
+  if (  checks & PEER_OFFERED_PIPE
+     && pcre_exec(regex_PIPELINING, NULL, CS buf, bsize, 0,
+                 PCRE_EOPT, NULL, 0) < 0)
+    checks &= ~PEER_OFFERED_PIPE;
+
+  if (  checks & PEER_OFFERED_SIZE
+     && pcre_exec(regex_SIZE, NULL, CS buf, bsize, 0, PCRE_EOPT, NULL, 0) < 0)
+    checks &= ~PEER_OFFERED_SIZE;
+
+return checks;
+}
+
+
 /*************************************************
 *       Deliver address list to given host       *
 *************************************************/
 /*************************************************
 *       Deliver address list to given host       *
 *************************************************/
@@ -1399,13 +1442,12 @@ BOOL completed_address = FALSE;
 BOOL esmtp = TRUE;
 BOOL pending_MAIL;
 BOOL pass_message = FALSE;
 BOOL esmtp = TRUE;
 BOOL pending_MAIL;
 BOOL pass_message = FALSE;
+uschar peer_offered = 0;       /*XXX should this be handed on cf. tls_offered, smtp_use_dsn ? */
 #ifndef DISABLE_PRDR
 #ifndef DISABLE_PRDR
-BOOL prdr_offered = FALSE;
 BOOL prdr_active;
 #endif
 #ifdef SUPPORT_I18N
 BOOL utf8_needed = FALSE;
 BOOL prdr_active;
 #endif
 #ifdef SUPPORT_I18N
 BOOL utf8_needed = FALSE;
-BOOL utf8_offered = FALSE;
 #endif
 BOOL dsn_all_lasthop = TRUE;
 #if defined(SUPPORT_TLS) && defined(EXPERIMENTAL_DANE)
 #endif
 BOOL dsn_all_lasthop = TRUE;
 #if defined(SUPPORT_TLS) && defined(EXPERIMENTAL_DANE)
@@ -1684,43 +1726,21 @@ goto SEND_QUIT;
     if (!good_response) goto RESPONSE_FAILED;
     }
 
     if (!good_response) goto RESPONSE_FAILED;
     }
 
-  /* Set IGNOREQUOTA if the response to LHLO specifies support and the
-  lmtp_ignore_quota option was set. */
-
-  igquotstr = (lmtp && ob->lmtp_ignore_quota &&
-    pcre_exec(regex_IGNOREQUOTA, NULL, CS buffer, Ustrlen(CS buffer), 0,
-      PCRE_EOPT, NULL, 0) >= 0)? US" IGNOREQUOTA" : US"";
+  if (esmtp || lmtp)
+    peer_offered = ehlo_response(buffer, Ustrlen(buffer),
+      PEER_OFFERED_TLS
+      | 0      /* IGNQ checked later */
+      | 0      /* PRDR checked later */
+      | 0      /* UTF8 checked later */
+      | 0      /* DSN  checked later */
+      | 0      /* PIPE checked later */
+      | 0      /* SIZE checked later */
+      );
 
   /* Set tls_offered if the response to EHLO specifies support for STARTTLS. */
 
 #ifdef SUPPORT_TLS
 
   /* Set tls_offered if the response to EHLO specifies support for STARTTLS. */
 
 #ifdef SUPPORT_TLS
-  tls_offered = esmtp &&
-    pcre_exec(regex_STARTTLS, NULL, CS buffer, Ustrlen(buffer), 0,
-      PCRE_EOPT, NULL, 0) >= 0;
-#endif
-
-#ifndef DISABLE_PRDR
-  prdr_offered = esmtp
-    && pcre_exec(regex_PRDR, NULL, CS buffer, Ustrlen(buffer), 0,
-                 PCRE_EOPT, NULL, 0) >= 0
-    && verify_check_given_host(&ob->hosts_try_prdr, host) == OK;
-
-  if (prdr_offered)
-    {DEBUG(D_transport) debug_printf("PRDR usable\n");}
-#endif
-
-#ifdef SUPPORT_I18N
-  if (addrlist->prop.utf8_msg)
-    {
-    utf8_needed =  !addrlist->prop.utf8_downcvt
-               && !addrlist->prop.utf8_downcvt_maybe;
-    DEBUG(D_transport) if (!utf8_needed) debug_printf("utf8: %s downconvert\n",
-      addrlist->prop.utf8_downcvt ? "mandatory" : "optional");
-
-    utf8_offered = esmtp
-      && pcre_exec(regex_UTF8, NULL, CS buffer, Ustrlen(buffer), 0,
-                   PCRE_EOPT, NULL, 0) >= 0;
-    }
+  tls_offered = !!(peer_offered & PEER_OFFERED_TLS);
 #endif
   }
 
 #endif
   }
 
@@ -1914,54 +1934,53 @@ if (continue_hostname == NULL
 #endif
     )
   {
 #endif
     )
   {
+  if (esmtp || lmtp)
+    peer_offered = ehlo_response(buffer, Ustrlen(buffer),
+      0 /* no TLS */
+      | (lmtp && ob->lmtp_ignore_quota ? PEER_OFFERED_IGNQ : 0)
+      | PEER_OFFERED_PRDR
+#ifdef SUPPORT_I18N
+      | (addrlist->prop.utf8_msg ? PEER_OFFERED_UTF8 : 0)
+       /*XXX if we hand peercaps on to continued-conn processes,
+             must not depend on this addr */
+#endif
+      | PEER_OFFERED_DSN
+      | PEER_OFFERED_PIPE
+      | (ob->size_addition >= 0 ? PEER_OFFERED_SIZE : 0)
+      );
+
   /* Set for IGNOREQUOTA if the response to LHLO specifies support and the
   lmtp_ignore_quota option was set. */
 
   /* Set for IGNOREQUOTA if the response to LHLO specifies support and the
   lmtp_ignore_quota option was set. */
 
-  igquotstr = (lmtp && ob->lmtp_ignore_quota &&
-    pcre_exec(regex_IGNOREQUOTA, NULL, CS buffer, Ustrlen(CS buffer), 0,
-      PCRE_EOPT, NULL, 0) >= 0)? US" IGNOREQUOTA" : US"";
+  igquotstr = peer_offered & PEER_OFFERED_IGNQ ? US" IGNOREQUOTA" : US"";
 
   /* If the response to EHLO specified support for the SIZE parameter, note
   this, provided size_addition is non-negative. */
 
 
   /* If the response to EHLO specified support for the SIZE parameter, note
   this, provided size_addition is non-negative. */
 
-  smtp_use_size = esmtp && ob->size_addition >= 0 &&
-    pcre_exec(regex_SIZE, NULL, CS buffer, Ustrlen(CS buffer), 0,
-      PCRE_EOPT, NULL, 0) >= 0;
+  smtp_use_size = !!(peer_offered & PEER_OFFERED_SIZE);
 
   /* Note whether the server supports PIPELINING. If hosts_avoid_esmtp matched
   the current host, esmtp will be false, so PIPELINING can never be used. If
   the current host matches hosts_avoid_pipelining, don't do it. */
 
 
   /* Note whether the server supports PIPELINING. If hosts_avoid_esmtp matched
   the current host, esmtp will be false, so PIPELINING can never be used. If
   the current host matches hosts_avoid_pipelining, don't do it. */
 
-  smtp_use_pipelining = esmtp
-    && verify_check_given_host(&ob->hosts_avoid_pipelining, host) != OK
-    && pcre_exec(regex_PIPELINING, NULL, CS buffer, Ustrlen(CS buffer), 0,
-                 PCRE_EOPT, NULL, 0) >= 0;
+  smtp_use_pipelining = peer_offered & PEER_OFFERED_PIPE
+    && verify_check_given_host(&ob->hosts_avoid_pipelining, host) != OK;
 
   DEBUG(D_transport) debug_printf("%susing PIPELINING\n",
 
   DEBUG(D_transport) debug_printf("%susing PIPELINING\n",
-    smtp_use_pipelining? "" : "not ");
+    smtp_use_pipelining ? "" : "not ");
 
 #ifndef DISABLE_PRDR
 
 #ifndef DISABLE_PRDR
-  prdr_offered = esmtp
-    && pcre_exec(regex_PRDR, NULL, CS buffer, Ustrlen(CS buffer), 0,
-                 PCRE_EOPT, NULL, 0) >= 0
-    && verify_check_given_host(&ob->hosts_try_prdr, host) == OK;
+  if (  peer_offered & PEER_OFFERED_PRDR
+     && verify_check_given_host(&ob->hosts_try_prdr, host) != OK)
+    peer_offered &= ~PEER_OFFERED_PRDR;
 
 
-  if (prdr_offered)
+  if (peer_offered & PEER_OFFERED_PRDR)
     {DEBUG(D_transport) debug_printf("PRDR usable\n");}
 #endif
 
     {DEBUG(D_transport) debug_printf("PRDR usable\n");}
 #endif
 
-#ifdef SUPPORT_I18N
-  if (addrlist->prop.utf8_msg)
-    utf8_offered = esmtp
-      && pcre_exec(regex_UTF8, NULL, CS buffer, Ustrlen(buffer), 0,
-                   PCRE_EOPT, NULL, 0) >= 0;
-#endif
-
   /* Note if the server supports DSN */
   /* Note if the server supports DSN */
-  smtp_use_dsn = esmtp
-    && pcre_exec(regex_DSN, NULL, CS buffer, Ustrlen(CS buffer), 0,
-                 PCRE_EOPT, NULL, 0) >= 0;
-  DEBUG(D_transport) debug_printf("use_dsn=%d\n", smtp_use_dsn);
+  smtp_use_dsn = !!(peer_offered & PEER_OFFERED_DSN);
+  DEBUG(D_transport) debug_printf("%susing DSN\n", smtp_use_dsn ? "" : "not ");
 
   /* Note if the response to EHLO specifies support for the AUTH extension.
   If it has, check that this host is one we want to authenticate to, and do
 
   /* Note if the response to EHLO specifies support for the AUTH extension.
   If it has, check that this host is one we want to authenticate to, and do
@@ -1984,8 +2003,16 @@ message-specific. */
 setting_up = FALSE;
 
 #ifdef SUPPORT_I18N
 setting_up = FALSE;
 
 #ifdef SUPPORT_I18N
+if (addrlist->prop.utf8_msg)
+  {
+  utf8_needed =  !addrlist->prop.utf8_downcvt
+             && !addrlist->prop.utf8_downcvt_maybe;
+  DEBUG(D_transport) if (!utf8_needed) debug_printf("utf8: %s downconvert\n",
+    addrlist->prop.utf8_downcvt ? "mandatory" : "optional");
+  }
+
 /* If this is an international message we need the host to speak SMTPUTF8 */
 /* If this is an international message we need the host to speak SMTPUTF8 */
-if (utf8_needed && !utf8_offered)
+if (utf8_needed && !(peer_offered & PEER_OFFERED_UTF8))
   {
   errno = ERRNO_UTF8_FWD;
   goto RESPONSE_FAILED;
   {
   errno = ERRNO_UTF8_FWD;
   goto RESPONSE_FAILED;
@@ -2051,8 +2078,7 @@ if (smtp_use_size)
 
 #ifndef DISABLE_PRDR
 prdr_active = FALSE;
 
 #ifndef DISABLE_PRDR
 prdr_active = FALSE;
-if (prdr_offered)
-  {
+if (peer_offered & PEER_OFFERED_PRDR)
   for (addr = first_addr; addr; addr = addr->next)
     if (addr->transport_return == PENDING_DEFER)
       {
   for (addr = first_addr; addr; addr = addr->next)
     if (addr->transport_return == PENDING_DEFER)
       {
@@ -2065,11 +2091,13 @@ if (prdr_offered)
          }
       break;
       }
          }
       break;
       }
-  }
 #endif
 
 #ifdef SUPPORT_I18N
 #endif
 
 #ifdef SUPPORT_I18N
-if (addrlist->prop.utf8_msg && !addrlist->prop.utf8_downcvt && utf8_offered)
+if (  addrlist->prop.utf8_msg
+   && !addrlist->prop.utf8_downcvt
+   && peer_offered & PEER_OFFERED_UTF8
+   )
   sprintf(CS p, " SMTPUTF8"), p += 9;
 #endif
 
   sprintf(CS p, " SMTPUTF8"), p += 9;
 #endif
 
@@ -2135,7 +2163,9 @@ pending_MAIL = TRUE;     /* The block starts with MAIL */
   for the to-addresses (done below), and also (ugly) for re-doing when building
   the delivery log line. */
 
   for the to-addresses (done below), and also (ugly) for re-doing when building
   the delivery log line. */
 
-  if (addrlist->prop.utf8_msg && (addrlist->prop.utf8_downcvt || !utf8_offered))
+  if (  addrlist->prop.utf8_msg
+     && (addrlist->prop.utf8_downcvt || !(peer_offered & PEER_OFFERED_UTF8))
+     )
     {
     if (s = string_address_utf8_to_alabel(return_path, &errstr), errstr)
       {
     {
     if (s = string_address_utf8_to_alabel(return_path, &errstr), errstr)
       {
index ef95394d36aeaf340c47cc6c596abbae993509b5..53a1daadecde5cde87354d10ba1a3537e258ed6b 100644 (file)
@@ -174,9 +174,7 @@ dbdata_callout_cache new_domain_record;
 dbdata_callout_cache_address new_address_record;
 host_item *host;
 time_t callout_start_time;
 dbdata_callout_cache_address new_address_record;
 host_item *host;
 time_t callout_start_time;
-#ifdef SUPPORT_I18N
-BOOL utf8_offered = FALSE;
-#endif
+uschar peer_offered = 0;
 
 new_domain_record.result = ccache_unknown;
 new_domain_record.postmaster_result = ccache_unknown;
 
 new_domain_record.result = ccache_unknown;
 new_domain_record.postmaster_result = ccache_unknown;
@@ -542,6 +540,7 @@ can do it there for the non-rcpt-verify case.  For this we keep an addresscount.
     uschar inbuffer[4096];
     uschar outbuffer[1024];
     uschar responsebuffer[4096];
     uschar inbuffer[4096];
     uschar outbuffer[1024];
     uschar responsebuffer[4096];
+    uschar * size_str;
 
     clearflag(addr, af_verify_pmfail);  /* postmaster callout flag */
     clearflag(addr, af_verify_nsfail);  /* null sender callout flag */
 
     clearflag(addr, af_verify_pmfail);  /* postmaster callout flag */
     clearflag(addr, af_verify_nsfail);  /* null sender callout flag */
@@ -711,7 +710,7 @@ can do it there for the non-rcpt-verify case.  For this we keep an addresscount.
 #ifdef SUPPORT_TLS
     if (smtps  &&  tls_out.active < 0) /* ssl-on-connect, first pass */
       {
 #ifdef SUPPORT_TLS
     if (smtps  &&  tls_out.active < 0) /* ssl-on-connect, first pass */
       {
-      tls_offered = TRUE;
+      peer_offered &= ~PEER_OFFERED_TLS;
       ob->tls_tempfail_tryclear = FALSE;
       }
     else                               /* all other cases */
       ob->tls_tempfail_tryclear = FALSE;
       }
     else                               /* all other cases */
@@ -730,27 +729,40 @@ can do it there for the non-rcpt-verify case.  For this we keep an addresscount.
          goto RESPONSE_FAILED;
          }
 #ifdef SUPPORT_TLS
          goto RESPONSE_FAILED;
          }
 #ifdef SUPPORT_TLS
-        tls_offered = FALSE;
+       peer_offered &= ~PEER_OFFERED_TLS;
 #endif
         esmtp = FALSE;
         goto esmtp_retry;                      /* fallback to HELO */
         }
 
       /* Set tls_offered if the response to EHLO specifies support for STARTTLS. */
 #endif
         esmtp = FALSE;
         goto esmtp_retry;                      /* fallback to HELO */
         }
 
       /* Set tls_offered if the response to EHLO specifies support for STARTTLS. */
-#ifdef SUPPORT_TLS
-      if (esmtp && !suppress_tls &&  tls_out.active < 0)
-       {
-       if (regex_STARTTLS == NULL) regex_STARTTLS =
-         regex_must_compile(US"\\n250[\\s\\-]STARTTLS(\\s|\\n|$)", FALSE, TRUE);
 
 
-       tls_offered = pcre_exec(regex_STARTTLS, NULL, CS responsebuffer,
-                     Ustrlen(responsebuffer), 0, PCRE_EOPT, NULL, 0) >= 0;
-       }
-      else
-        tls_offered = FALSE;
+      peer_offered = esmtp
+       ? ehlo_response(responsebuffer, sizeof(responsebuffer),
+               (!suppress_tls && tls_out.active < 0 ? PEER_OFFERED_TLS : 0)
+             | 0       /* no IGNQ */
+             | 0       /* no PRDR */
+#ifdef SUPPORT_I18N
+             | (addr->prop.utf8_msg && !addr->prop.utf8_downcvt
+               ? PEER_OFFERED_UTF8 : 0)
 #endif
 #endif
+             | 0       /* no DSN */
+             | 0       /* no PIPE */
+
+             /* only care about SIZE if we have size from inbound */
+             | (message_size > 0 && ob->size_addition >= 0
+               ? PEER_OFFERED_SIZE : 0)
+           )
+       : 0;
       }
 
       }
 
+    size_str = peer_offered & PEER_OFFERED_SIZE
+      ? string_sprintf(" SIZE=%d", message_size + ob->size_addition) : US"";
+
+#ifdef SUPPORT_TLS
+    tls_offered = !!(peer_offered & PEER_OFFERED_TLS);
+#endif
+
     /* If TLS is available on this connection attempt to
     start up a TLS session, unless the host is in hosts_avoid_tls. If successful,
     send another EHLO - the server may give a different answer in secure mode. We
     /* If TLS is available on this connection attempt to
     start up a TLS session, unless the host is in hosts_avoid_tls. If successful,
     send another EHLO - the server may give a different answer in secure mode. We
@@ -760,7 +772,7 @@ can do it there for the non-rcpt-verify case.  For this we keep an addresscount.
     for error analysis. */
 
 #ifdef SUPPORT_TLS
     for error analysis. */
 
 #ifdef SUPPORT_TLS
-    if (  tls_offered
+    if (  peer_offered & PEER_OFFERED_TLS
        && verify_check_given_host(&ob->hosts_avoid_tls, host) != OK
        && verify_check_given_host(&ob->hosts_verify_avoid_tls, host) != OK
        )
        && verify_check_given_host(&ob->hosts_avoid_tls, host) != OK
        && verify_check_given_host(&ob->hosts_verify_avoid_tls, host) != OK
        )
@@ -875,8 +887,9 @@ can do it there for the non-rcpt-verify case.  For this we keep an addresscount.
         log_write(0, LOG_MAIN,
          "H=%s [%s]: a TLS session is required for this host, but %s",
           host->name, host->address,
         log_write(0, LOG_MAIN,
          "H=%s [%s]: a TLS session is required for this host, but %s",
           host->name, host->address,
-         tls_offered ? "an attempt to start TLS failed"
-                     : "the server did not offer TLS support");
+         peer_offered & PEER_OFFERED_TLS
+         ? "an attempt to start TLS failed"
+         : "the server did not offer TLS support");
         done= FALSE;
         goto TLS_FAILED;
         }
         done= FALSE;
         goto TLS_FAILED;
         }
@@ -885,8 +898,6 @@ can do it there for the non-rcpt-verify case.  For this we keep an addresscount.
 
     done = TRUE; /* so far so good; have response to HELO */
 
 
     done = TRUE; /* so far so good; have response to HELO */
 
-    /*XXX the EHLO response would be analyzed here for IGNOREQUOTA, SIZE, PIPELINING */
-
     /* For now, transport_filter by cutthrough-delivery is not supported */
     /* Need proper integration with the proper transport mechanism. */
     if (cutthrough.delivery)
     /* For now, transport_filter by cutthrough-delivery is not supported */
     /* Need proper integration with the proper transport mechanism. */
     if (cutthrough.delivery)
@@ -927,17 +938,8 @@ can do it there for the non-rcpt-verify case.  For this we keep an addresscount.
 #ifdef SUPPORT_I18N
     else if (  addr->prop.utf8_msg
            && !addr->prop.utf8_downcvt
 #ifdef SUPPORT_I18N
     else if (  addr->prop.utf8_msg
            && !addr->prop.utf8_downcvt
-           && !(  esmtp
-               && (  regex_UTF8
-                  || ( (regex_UTF8 = regex_must_compile(
-                         US"\\n250[\\s\\-]SMTPUTF8(\\s|\\n|$)", FALSE, TRUE)),
-                     TRUE
-                  )  )
-               && (  (utf8_offered = pcre_exec(regex_UTF8, NULL,
-                           CS responsebuffer, Ustrlen(responsebuffer),
-                           0, PCRE_EOPT, NULL, 0) >= 0)
-                  || addr->prop.utf8_downcvt_maybe
-           )   )  )
+           && !(peer_offered & PEER_OFFERED_UTF8)
+           )
       {
       HDEBUG(D_acl|D_v) debug_printf("utf8 required but not offered\n");
       errno = ERRNO_UTF8_FWD;
       {
       HDEBUG(D_acl|D_v) debug_printf("utf8 required but not offered\n");
       errno = ERRNO_UTF8_FWD;
@@ -945,7 +947,7 @@ can do it there for the non-rcpt-verify case.  For this we keep an addresscount.
       done = FALSE;
       }
     else if (  addr->prop.utf8_msg
       done = FALSE;
       }
     else if (  addr->prop.utf8_msg
-           && (addr->prop.utf8_downcvt || !utf8_offered)
+           && (addr->prop.utf8_downcvt || !(peer_offered & PEER_OFFERED_UTF8))
            && (setflag(addr, af_utf8_downcvt),
                from_address = string_address_utf8_to_alabel(from_address,
                                      &addr->message),
            && (setflag(addr, af_utf8_downcvt),
                from_address = string_address_utf8_to_alabel(from_address,
                                      &addr->message),
@@ -978,11 +980,11 @@ can do it there for the non-rcpt-verify case.  For this we keep an addresscount.
         (smtp_write_command(&outblock, FALSE,
 #ifdef SUPPORT_I18N
          addr->prop.utf8_msg && !addr->prop.utf8_downcvt
         (smtp_write_command(&outblock, FALSE,
 #ifdef SUPPORT_I18N
          addr->prop.utf8_msg && !addr->prop.utf8_downcvt
-         ? "MAIL FROM:<%s>%s SMTPUTF8\r\n"
+         ? "MAIL FROM:<%s>%s%s SMTPUTF8\r\n"
          :
 #endif
          :
 #endif
-           "MAIL FROM:<%s>%s\r\n",
-          from_address, responsebuffer) >= 0)
+           "MAIL FROM:<%s>%s%s\r\n",
+          from_address, responsebuffer, size_str) >= 0)
       )  &&
 
       smtp_read_response(&inblock, responsebuffer, sizeof(responsebuffer),
       )  &&
 
       smtp_read_response(&inblock, responsebuffer, sizeof(responsebuffer),
diff --git a/test/confs/5402 b/test/confs/5402
new file mode 120000 (symlink)
index 0000000..8f6811b
--- /dev/null
@@ -0,0 +1 @@
+5400
\ No newline at end of file
diff --git a/test/log/5402 b/test/log/5402
new file mode 100644 (file)
index 0000000..9505825
--- /dev/null
@@ -0,0 +1,4 @@
+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
diff --git a/test/scripts/5400-cutthrough/5402 b/test/scripts/5400-cutthrough/5402
new file mode 100644 (file)
index 0000000..dbe7ef3
--- /dev/null
@@ -0,0 +1,30 @@
+# cutthrough_delivery with MAIL SIZE=
+need_ipv4
+munge loopback
+#
+server PORT_S
+220 ESMTP
+EHLO
+250-OK
+250 SIZE 65536
+MAIL FROM:<fred@myhost.test.ex> SIZE=1123
+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:<fred@myhost.test.ex> SIZE=99
+RCPT TO:<userx@domain.com>
+DATA
+
+.
+QUIT
+****
+# End
index cff499045200bded613e794c9400d245153a0412..4be0d5227614f019733d5d2960387edb2918bde8 100644 (file)
@@ -24,7 +24,7 @@ Connecting to 127.0.0.1 [127.0.0.1]:1224 from ip4.ip4.ip4.ip4 ... connected
          250-HELP
          250 AUTH LOGIN
 not using PIPELINING
          250-HELP
          250 AUTH LOGIN
 not using PIPELINING
-use_dsn=0
+not using DSN
   SMTP>> MAIL FROM:<CALLER@myhost.test.ex>
   SMTP<< 250 Sender OK
   SMTP>> RCPT TO:<userx@domain.com>
   SMTP>> MAIL FROM:<CALLER@myhost.test.ex>
   SMTP<< 250 Sender OK
   SMTP>> RCPT TO:<userx@domain.com>
index e9e8c7b5c7430282f88e40e8d4309c7293d885c9..5f46801303c7a10500fafedcc70c86b6125f96bc 100644 (file)
@@ -86,7 +86,6 @@ Connecting to 127.0.0.1 [127.0.0.1]:1224 ... connected
 127.0.0.1 in hosts_avoid_esmtp? no (option unset)
   SMTP>> EHLO myhost.test.ex
   SMTP<< 250 OK
 127.0.0.1 in hosts_avoid_esmtp? no (option unset)
   SMTP>> EHLO myhost.test.ex
   SMTP<< 250 OK
-127.0.0.1 in hosts_avoid_pipelining? no (option unset)
 127.0.0.1 in hosts_require_auth? no (option unset)
   SMTP>> MAIL FROM:<CALLER@myhost.test.ex>
   SMTP<< 250 OK
 127.0.0.1 in hosts_require_auth? no (option unset)
   SMTP>> MAIL FROM:<CALLER@myhost.test.ex>
   SMTP<< 250 OK
index 919413c6bfc933e3bf5a446060693fbbfb8c0b2f..baaa8356f69a958ca6d1f7a90635336822263adb 100644 (file)
@@ -23,7 +23,7 @@ Connecting to 127.0.0.1 [127.0.0.1]:1224 ... connected
          250-PIPELINING
          250 OK
 using PIPELINING
          250-PIPELINING
          250 OK
 using PIPELINING
-use_dsn=0
+not using DSN
   SMTP>> MAIL FROM:<CALLER@the.local.host.name>
   SMTP>> RCPT TO:<userx@test.ex>
   SMTP>> DATA
   SMTP>> MAIL FROM:<CALLER@the.local.host.name>
   SMTP>> RCPT TO:<userx@test.ex>
   SMTP>> DATA
diff --git a/test/stderr/5402 b/test/stderr/5402
deleted file mode 100644 (file)
index 7babe35..0000000
+++ /dev/null
@@ -1,274 +0,0 @@
-Exim version x.yz ....
-configuration file is TESTSUITE/test-config
-admin user
- in hosts_connection_nolog? no (option unset)
-LOG: smtp_connection MAIN
-  SMTP connection from CALLER
-expanding: $smtp_active_hostname ESMTP Exim $version_number $tod_full
-   result: myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000
- in pipelining_advertise_hosts? yes (matched "*")
- in tls_advertise_hosts? yes (matched "*")
-expanding: SERVER
-   result: SERVER
-expanding: server
-   result: server
-condition: eq {SERVER}{server}
-   result: false
-expanding: queue
-   result: queue
-skipping: result is not used
-expanding: cutthrough
-   result: cutthrough
-expanding: ${if eq {SERVER}{server}{queue}{cutthrough}}
-   result: cutthrough
-using ACL "cutthrough"
-processing "accept"
-check control = cutthrough_delivery
-check verify = recipient
-domain.com in "test.ex : *.test.ex"? no (end of list)
-domain.com in "! +local_domains"? yes (end of list)
-expanding: $local_part
-   result: userx
-domain.com in "*"? yes (matched "*")
------------ end verify ------------
-accept: condition test succeeded in ACL "cutthrough"
------------ start cutthrough setup ------------
-domain.com in "test.ex : *.test.ex"? no (end of list)
-domain.com in "! +local_domains"? yes (end of list)
-expanding: $local_part
-   result: userx
-domain.com in "*"? yes (matched "*")
-Connecting to 127.0.0.1 [127.0.0.1]:1225 from ip4.ip4.ip4.ip4 ... connected
-expanding: $primary_hostname
-   result: myhost.test.ex
-  SMTP<< 220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000
-127.0.0.1 in hosts_avoid_esmtp? no (option unset)
-  SMTP>> EHLO myhost.test.ex
-  SMTP<< 250-myhost.test.ex Hello the.local.host.name [ip4.ip4.ip4.ip4]
-         250-SIZE 52428800
-         250-8BITMIME
-         250-PIPELINING
-         250-STARTTLS
-         250 HELP
-expanding: $address_data
-   result: userx
-expanding: usery
-   result: usery
-condition: eq {$address_data}{usery}
-   result: false
-expanding: *
-   result: *
-skipping: result is not used
-expanding: :
-   result: :
-expanding: ${if eq {$address_data}{usery}{*}{:}}
-   result: :
-127.0.0.1 in hosts_avoid_tls? no (end of list)
-  SMTP>> STARTTLS
-  SMTP<< 220 TLS go ahead
-  SMTP>> EHLO myhost.test.ex
-  SMTP<< 250-myhost.test.ex Hello the.local.host.name [ip4.ip4.ip4.ip4]
-         250-SIZE 52428800
-         250-8BITMIME
-         250-PIPELINING
-         250 HELP
-  SMTP>> MAIL FROM:<CALLER@myhost.test.ex>
-  SMTP<< 250 OK
-  SMTP>> RCPT TO:<userx@domain.com>
-  SMTP<< 250 Accepted
------------ end cutthrough setup ------------
-processing "accept"
-accept: condition test succeeded in inline ACL
-  SMTP>> DATA
-  SMTP<< 354 Enter message, ending with "." on a line by itself
-expanding: ${tod_full}
-   result: Tue, 2 Mar 1999 09:44:33 +0000
-condition: def:sender_rcvhost
-   result: false
-expanding: from $sender_rcvhost
-       
-   result: from 
-       
-skipping: result is not used
-condition: def:sender_ident
-   result: true
-expanding: $sender_ident
-   result: CALLER
-expanding: from ${quote_local_part:$sender_ident} 
-   result: from CALLER 
-condition: def:sender_helo_name
-   result: true
-expanding: (helo=$sender_helo_name)
-       
-   result: (helo=myhost.test.ex)
-       
-expanding: ${if def:sender_ident {from ${quote_local_part:$sender_ident} }}${if def:sender_helo_name {(helo=$sender_helo_name)
-       }}
-   result: from CALLER (helo=myhost.test.ex)
-       
-condition: def:received_protocol
-   result: true
-expanding: with $received_protocol
-   result: with local-esmtp
-condition: def:sender_address
-   result: true
-expanding: (envelope-from <$sender_address>)
-       
-   result: (envelope-from <CALLER@myhost.test.ex>)
-       
-condition: def:received_for
-   result: true
-expanding: 
-       for $received_for
-   result: 
-       for userx@domain.com
-PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
-expanding: ${tod_full}
-   result: Tue, 2 Mar 1999 09:44:33 +0000
-  SMTP>> .
-  SMTP<< 250 OK id=10HmaX-0005vi-00
-LOG: MAIN
-  >> userx@domain.com R=all T=smtp H=127.0.0.1 [127.0.0.1] X=TLSv1:AES256-SHA:256 C="250 OK id=10HmaX-0005vi-00"
-  SMTP>> QUIT
------------ cutthrough shutdown (delivered) ------------
-LOG: MAIN
-  <= CALLER@myhost.test.ex U=CALLER P=local-esmtp S=sss
-LOG: MAIN
-  Completed
-LOG: smtp_connection MAIN
-  SMTP connection from CALLER closed by QUIT
->>>>>>>>>>>>>>>> Exim pid=pppp terminating with rc=0 >>>>>>>>>>>>>>>>
-Exim version x.yz ....
-configuration file is TESTSUITE/test-config
-admin user
- in hosts_connection_nolog? no (option unset)
-LOG: smtp_connection MAIN
-  SMTP connection from CALLER
-expanding: $smtp_active_hostname ESMTP Exim $version_number $tod_full
-   result: myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000
- in pipelining_advertise_hosts? yes (matched "*")
- in tls_advertise_hosts? yes (matched "*")
-expanding: SERVER
-   result: SERVER
-expanding: server
-   result: server
-condition: eq {SERVER}{server}
-   result: false
-expanding: queue
-   result: queue
-skipping: result is not used
-expanding: cutthrough
-   result: cutthrough
-expanding: ${if eq {SERVER}{server}{queue}{cutthrough}}
-   result: cutthrough
-using ACL "cutthrough"
-processing "accept"
-check control = cutthrough_delivery
-check verify = recipient
-domain.com in "test.ex : *.test.ex"? no (end of list)
-domain.com in "! +local_domains"? yes (end of list)
-expanding: $local_part
-   result: usery
-domain.com in "*"? yes (matched "*")
------------ end verify ------------
-accept: condition test succeeded in ACL "cutthrough"
------------ start cutthrough setup ------------
-domain.com in "test.ex : *.test.ex"? no (end of list)
-domain.com in "! +local_domains"? yes (end of list)
-expanding: $local_part
-   result: usery
-domain.com in "*"? yes (matched "*")
-Connecting to 127.0.0.1 [127.0.0.1]:1225 from ip4.ip4.ip4.ip4 ... connected
-expanding: $primary_hostname
-   result: myhost.test.ex
-  SMTP<< 220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000
-127.0.0.1 in hosts_avoid_esmtp? no (option unset)
-  SMTP>> EHLO myhost.test.ex
-  SMTP<< 250-myhost.test.ex Hello the.local.host.name [ip4.ip4.ip4.ip4]
-         250-SIZE 52428800
-         250-8BITMIME
-         250-PIPELINING
-         250-STARTTLS
-         250 HELP
-expanding: $address_data
-   result: usery
-expanding: usery
-   result: usery
-condition: eq {$address_data}{usery}
-   result: true
-expanding: *
-   result: *
-expanding: :
-   result: :
-skipping: result is not used
-expanding: ${if eq {$address_data}{usery}{*}{:}}
-   result: *
-127.0.0.1 in hosts_avoid_tls? yes (matched "*")
-  SMTP>> MAIL FROM:<CALLER@myhost.test.ex>
-  SMTP<< 250 OK
-  SMTP>> RCPT TO:<usery@domain.com>
-  SMTP<< 250 Accepted
------------ end cutthrough setup ------------
-processing "accept"
-accept: condition test succeeded in inline ACL
-  SMTP>> DATA
-  SMTP<< 354 Enter message, ending with "." on a line by itself
-expanding: ${tod_full}
-   result: Tue, 2 Mar 1999 09:44:33 +0000
-condition: def:sender_rcvhost
-   result: false
-expanding: from $sender_rcvhost
-       
-   result: from 
-       
-skipping: result is not used
-condition: def:sender_ident
-   result: true
-expanding: $sender_ident
-   result: CALLER
-expanding: from ${quote_local_part:$sender_ident} 
-   result: from CALLER 
-condition: def:sender_helo_name
-   result: true
-expanding: (helo=$sender_helo_name)
-       
-   result: (helo=myhost.test.ex)
-       
-expanding: ${if def:sender_ident {from ${quote_local_part:$sender_ident} }}${if def:sender_helo_name {(helo=$sender_helo_name)
-       }}
-   result: from CALLER (helo=myhost.test.ex)
-       
-condition: def:received_protocol
-   result: true
-expanding: with $received_protocol
-   result: with local-esmtp
-condition: def:sender_address
-   result: true
-expanding: (envelope-from <$sender_address>)
-       
-   result: (envelope-from <CALLER@myhost.test.ex>)
-       
-condition: def:received_for
-   result: true
-expanding: 
-       for $received_for
-   result: 
-       for usery@domain.com
-PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
-expanding: ${tod_full}
-   result: Tue, 2 Mar 1999 09:44:33 +0000
-  SMTP>> .
-  SMTP<< 250 OK id=10HmaZ-0005vi-00
-LOG: MAIN
-  >> usery@domain.com R=all T=smtp H=127.0.0.1 [127.0.0.1] C="250 OK id=10HmaZ-0005vi-00"
-  SMTP>> QUIT
------------ cutthrough shutdown (delivered) ------------
-LOG: MAIN
-  <= CALLER@myhost.test.ex U=CALLER P=local-esmtp S=sss
-LOG: MAIN
-  Completed
-LOG: smtp_connection MAIN
-  SMTP connection from CALLER closed by QUIT
->>>>>>>>>>>>>>>> Exim pid=pppp terminating with rc=0 >>>>>>>>>>>>>>>>
-
-******** SERVER ********
index 252c82917a693cbba24bc254178cfd887c176ed6..aa2bdcaab7ee880a0acc07e236fae6df2806cd69 100644 (file)
@@ -3,22 +3,38 @@
 250-SIZE 52428800\r
 250-8BITMIME\r
 250-PIPELINING\r
 250-SIZE 52428800\r
 250-8BITMIME\r
 250-PIPELINING\r
-250-STARTTLS\r
 250 HELP\r
 250 OK\r
 250 Accepted\r
 354 Enter message, ending with "." on a line by itself\r
 250 HELP\r
 250 OK\r
 250 Accepted\r
 354 Enter message, ending with "." on a line by itself\r
-250 OK id=10HmaY-0005vi-00\r
-221 myhost.test.ex closing connection\r
-220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000\r
-250-myhost.test.ex Hello CALLER at myhost.test.ex\r
-250-SIZE 52428800\r
-250-8BITMIME\r
-250-PIPELINING\r
-250-STARTTLS\r
-250 HELP\r
-250 OK\r
-250 Accepted\r
-354 Enter message, ending with "." on a line by itself\r
-250 OK id=10HmbA-0005vi-00\r
+250 OK id=10HmaX-0005vi-00\r
 221 myhost.test.ex closing connection\r
 221 myhost.test.ex closing connection\r
+
+******** SERVER ********
+Listening on port 1224 ... 
+Connection request from [ip4.ip4.ip4.ip4]
+220 ESMTP
+EHLO myhost.test.ex
+250-OK
+250 SIZE 65536
+MAIL FROM:<fred@myhost.test.ex> SIZE=ssss
+250 Sender OK
+RCPT TO:<userx@domain.com>
+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 <CALLER@myhost.test.ex>)
+       id 10HmaX-0005vi-00
+       for userx@domain.com; Tue, 2 Mar 1999 09:44:33 +0000
+Message-Id: <E10HmaX-0005vi-00@myhost.test.ex>
+From: CALLER_NAME <CALLER@myhost.test.ex>
+Date: Tue, 2 Mar 1999 09:44:33 +0000
+X-hdr-rtr-new: +++
+
+.
+250 OK
+QUIT
+250 OK
+End of script