Merge branch '4.next'
authorJeremy Harris <jgh146exb@wizmail.org>
Sat, 4 Nov 2023 14:20:45 +0000 (14:20 +0000)
committerJeremy Harris <jgh146exb@wizmail.org>
Sat, 4 Nov 2023 14:29:25 +0000 (14:29 +0000)
28 files changed:
doc/doc-docbook/spec.xfpt
doc/doc-txt/ChangeLog
doc/doc-txt/NewStuff
src/src/acl.c
src/src/auths/get_data.c
src/src/auths/get_no64_data.c
src/src/daemon.c
src/src/macros.h
src/src/pdkim/pdkim.c
src/src/receive.c
src/src/smtp_in.c
src/src/tls-gnu.c
src/src/tls-openssl.c
test/confs/4500
test/log/0010
test/log/0900
test/log/0901
test/log/4500
test/log/4501
test/log/4502
test/log/4503
test/log/4504
test/log/4506
test/log/4540
test/scripts/4500-DKIM/4500
test/stderr/4507
test/stdout/0900
test/stdout/0901

index 2bdb2bbdf9b730af9f758428073de9688fa63700..f856af346219587ee3183e046472cf55bb70e02a 100644 (file)
@@ -41733,8 +41733,9 @@ RFC 6376 lists these tags as RECOMMENDED.
 
 Verification of DKIM signatures in SMTP incoming email is done for all
 messages for which an ACL control &%dkim_disable_verify%& has not been set.
+
 .cindex DKIM "selecting signature algorithms"
-Individual classes of signature algorithm can be ignored by changing
+Individual classes of DKIM signature algorithm can be ignored by changing
 the main options &%dkim_verify_hashes%& or &%dkim_verify_keytypes%&.
 The &%dkim_verify_minimal%& option can be set to cease verification
 processing for a message once the first passing signature is found.
@@ -41747,7 +41748,7 @@ For most purposes the default option settings suffice and the remainder
 of this section can be ignored.
 
 The results of verification are made available to the
-&%acl_smtp_dkim%& ACL, which can examine and modify them.
+&%acl_smtp_dkim%& ACL, which (for complex needs) can examine and modify them.
 A missing ACL definition defaults to accept.
 By default, the ACL is called once for each
 syntactically(!) correct signature in the incoming message.
@@ -41812,6 +41813,12 @@ an identity. This is one of the list items from the expanded main option
 &%dkim_verify_signers%& (see above).
 
 .vitem &%$dkim_verify_status%&
+So long as a DKIM ACL is defined
+(it need do no more than accept, which is the default),
+after all the DKIM ACL runs have completed, the value becomes a
+colon-separated list of the values after each run.
+The value is maintained for the MIME, PRDR and DATA ACLs.
+
 Within the DKIM ACL,
 a string describing the general status of the signature. One of
 .ilist
@@ -41840,11 +41847,6 @@ hash-method or key-size:
        set dkim_verify_reason = hash too weak or key too short
 .endd
 
-So long as a DKIM ACL is defined (it need do no more than accept),
-after all the DKIM ACL runs have completed, the value becomes a
-colon-separated list of the values after each run.
-This is maintained for the mime, prdr and data ACLs.
-
 .vitem &%$dkim_verify_reason%&
 A string giving a little bit more detail when &%$dkim_verify_status%& is either
 "fail" or "invalid". One of
@@ -41969,13 +41971,15 @@ option.
 
 .endlist
 
-In addition, two ACL conditions are provided, usable only in a DKIM ACL:
+In addition, two ACL conditions are provided:
 
 .vlist
 .vitem &%dkim_signers%&
 ACL condition that checks a colon-separated list of domains or identities
 for a match against the domain or identity that the ACL is currently verifying
-(reflected by &%$dkim_cur_signer%&). This is typically used to restrict an ACL
+(reflected by &%$dkim_cur_signer%&).
+This condition is only usable in a DKIM ACL.
+This is typically used to restrict an ACL
 verb to a group of domains or identities. For example:
 
 .code
@@ -41991,7 +41995,18 @@ for that check for empty &$h_DKIM-Signature:$& in the data ACL.
 
 .vitem &%dkim_status%&
 ACL condition that checks a colon-separated list of possible DKIM verification
-results against the actual result of verification. This is typically used
+results against the actual result of verification,
+given by &$dkim_verify_status$& if that is non-empty or "none" if empty.
+.new
+This condition may be used in DKIM, MIME, PRDR and DATA ACLs.
+.wen
+
+A basic verification might be:
+.code
+deny !dkim_status = pass:none:invalid
+.endd
+
+A more complex use could be
 to restrict an ACL verb to a list of verification outcomes, for example:
 
 .code
@@ -42004,6 +42019,12 @@ deny sender_domains = paypal.com:paypal.de
 The possible status keywords are: 'none','invalid','fail' and 'pass'. Please
 see the documentation of the &%$dkim_verify_status%& expansion variable above
 for more information of what they mean.
+
+The condition is true if the status
+.new
+(or any of the list of status values)
+.wen
+is any one of the supplied list.
 .endlist
 
 
index 4306cabc0c7693313451ba43bc062c0ae6599e88..990e72823a4b2b9465dd6aabe1631a8db95a11b2 100644 (file)
@@ -2,6 +2,20 @@ This document describes *changes* to previous versions, that might
 affect Exim's operation, with an unchanged configuration file.  For new
 options, and new features, see the NewStuff file next to this ChangeLog.
 
+Exim version 4.98
+-----------------
+
+JH/01 Support list of dkim results in the dkim_status ACL condition, making
+      it more usable in the data ACL.
+
+JH/02 Handle error on close of the spool data file during reception.  Previously
+      This was only logged, on the assumption that errors would be seen for
+      a previous fflush().  However, a fuse filesystem has been reported as
+      showing this an error for the fclose().  The spool is now in an uncertain
+      state, and we have logged and responded acceptance.  Change this to
+      respond with a temp-reject, wipe spoolfiles, and log the error detail.
+
+
 Exim version 4.97
 -----------------
 
@@ -214,6 +228,7 @@ JH/44 Bug 3033: Harden dnsdb lookups against crafted DNS responses.
 
 HS/02 Fix string_is_ip_address() CVE-2023-42117 (Bug 3031)
 
+
 Exim version 4.96
 -----------------
 
index af084448b51376f1d73310c80e619dab425b424b..6aef41e50b53022180e0bdc9b1e4ce7aa8cfe2ef 100644 (file)
@@ -6,6 +6,10 @@ Before a formal release, there may be quite a lot of detail so that people can
 test from the snapshots or the Git before the documentation is updated. Once
 the documentation is updated, this file is reduced to a short list.
 
+Version 4.98
+------------
+ 1. The dkim_status ACL condition may now be used in data ACLs
+
 Version 4.97
 ------------
 
index 578cf32cb7e31a83412764db40fa7d71a42dfb43..cdf60bbb84084390a4a35b91e0e3f3d0512feca6 100644 (file)
@@ -203,7 +203,14 @@ static condition_def conditions[] = {
   [ACLC_DELAY] =               { US"delay",            TRUE, TRUE, ACL_BIT_NOTQUIT },
 #ifndef DISABLE_DKIM
   [ACLC_DKIM_SIGNER] =         { US"dkim_signers",     TRUE, FALSE, (unsigned int) ~ACL_BIT_DKIM },
-  [ACLC_DKIM_STATUS] =         { US"dkim_status",      TRUE, FALSE, (unsigned int) ~ACL_BIT_DKIM },
+  [ACLC_DKIM_STATUS] =         { US"dkim_status",      TRUE, FALSE,
+                                 (unsigned int)
+                                 ~(ACL_BIT_DKIM | ACL_BIT_DATA | ACL_BIT_MIME
+# ifndef DISABLE_PRDR
+                                 | ACL_BIT_PRDR
+# endif
+      ),
+  },
 #endif
 #ifdef SUPPORT_DMARC
   [ACLC_DMARC_STATUS] =                { US"dmarc_status",     TRUE, FALSE, (unsigned int) ~ACL_BIT_DATA },
@@ -3764,8 +3771,14 @@ for (; cb; cb = cb->next)
       break;
 
     case ACLC_DKIM_STATUS:
-      rc = match_isinlist(dkim_verify_status,
-                         &arg, 0, NULL, NULL, MCL_STRING, TRUE, NULL);
+      {                /* return good for any match */
+      const uschar * s = dkim_verify_status ? dkim_verify_status : US"none";
+      int sep = 0;
+      for (uschar * ss; ss = string_nextinlist(&s, &sep, NULL, 0); )
+       if (   (rc = match_isinlist(ss, &arg,
+                                   0, NULL, NULL, MCL_STRING, TRUE, NULL))
+           == OK) break;
+      }
       break;
 #endif
 
index 4c67f17e23a2f39e367761e84b1f46eae314f215..0c9fb37fe8455b86d7e3e17dc2f7d0f878730710 100644 (file)
@@ -77,7 +77,7 @@ auth_get_data(uschar ** aptr, const uschar * challenge, int challen)
 {
 int c;
 int p = 0;
-smtp_printf("334 %s\r\n", FALSE, b64encode(challenge, challen));
+smtp_printf("334 %s\r\n", SP_NO_MORE, b64encode(challenge, challen));
 while ((c = receive_getc(GETC_BUFFER_UNLIMITED)) != '\n' && c != EOF)
   {
   if (p >= big_buffer_size - 1) return BAD64;
index e2cadfbc632c55d68753cc2cafb31fa0c34fc9b6..ae11ae5dc7c8b241d3e0c2c944181237f5f1ddf9 100644 (file)
@@ -32,7 +32,7 @@ auth_get_no64_data(uschar **aptr, uschar *challenge)
 {
 int c;
 int p = 0;
-smtp_printf("334 %s\r\n", FALSE, challenge);
+smtp_printf("334 %s\r\n", SP_NO_MORE, challenge);
 while ((c = receive_getc(GETC_BUFFER_UNLIMITED)) != '\n' && c != EOF)
   {
   if (p >= big_buffer_size - 1) return BAD64;
index 9709845e5f8abf8b4d9b0a91742b95ae29e506c3..f2183c735f6acb3f9813cb8c01844491230cb9c0 100644 (file)
@@ -128,7 +128,7 @@ never_error(uschar *log_msg, uschar *smtp_msg, int was_errno)
 uschar *emsg = was_errno <= 0
   ? US"" : string_sprintf(": %s", strerror(was_errno));
 log_write(0, LOG_MAIN|LOG_PANIC, "%s%s", log_msg, emsg);
-if (smtp_out) smtp_printf("421 %s\r\n", FALSE, smtp_msg);
+if (smtp_out) smtp_printf("421 %s\r\n", SP_NO_MORE, smtp_msg);
 }
 
 
@@ -233,7 +233,7 @@ if (getsockname(accept_socket, (struct sockaddr *)(&interface_sockaddr),
   {
   log_write(0, LOG_MAIN | ((errno == ECONNRESET)? 0 : LOG_PANIC),
     "getsockname() failed: %s", strerror(errno));
-  smtp_printf("421 Local problem: getsockname() failed; please try again later\r\n", FALSE);
+  smtp_printf("421 Local problem: getsockname() failed; please try again later\r\n", SP_NO_MORE);
   goto ERROR_RETURN;
   }
 
@@ -263,7 +263,7 @@ if (smtp_accept_max > 0 && smtp_accept_count >= smtp_accept_max)
   DEBUG(D_any) debug_printf("rejecting SMTP connection: count=%d max=%d\n",
     smtp_accept_count, smtp_accept_max);
   smtp_printf("421 Too many concurrent SMTP connections; "
-    "please try again later.\r\n", FALSE);
+    "please try again later.\r\n", SP_NO_MORE);
   log_write(L_connection_reject,
             LOG_MAIN, "Connection from %Y refused: too many connections",
     whofrom);
@@ -282,7 +282,7 @@ if (smtp_load_reserve >= 0)
     {
     DEBUG(D_any) debug_printf("rejecting SMTP connection: load average = %.2f\n",
       (double)load_average/1000.0);
-    smtp_printf("421 Too much load; please try again later.\r\n", FALSE);
+    smtp_printf("421 Too much load; please try again later.\r\n", SP_NO_MORE);
     log_write(L_connection_reject,
               LOG_MAIN, "Connection from %Y refused: load average = %.2f",
       whofrom, (double)load_average/1000.0);
@@ -351,7 +351,7 @@ if (max_for_this_host > 0 && smtp_accept_count >= max_for_this_host)
       "IP address: count=%d max=%d\n",
       host_accept_count, max_for_this_host);
     smtp_printf("421 Too many concurrent SMTP connections "
-      "from this IP address; please try again later.\r\n", FALSE);
+      "from this IP address; please try again later.\r\n", SP_NO_MORE);
     log_write(L_connection_reject,
               LOG_MAIN, "Connection from %Y refused: too many connections "
       "from that IP address", whofrom);
@@ -445,7 +445,7 @@ if (pid == 0)
           "(smtp_active_hostname): %s", raw_active_hostname,
           expand_string_message);
         smtp_printf("421 Local configuration error; "
-          "please try again later.\r\n", FALSE);
+          "please try again later.\r\n", SP_NO_MORE);
         mac_smtp_fflush();
         search_tidyup();
         exim_underbar_exit(EXIT_FAILURE);
index 2658b9ab7d91f1a106ba6e68565ef80810cf81d3..9693935614c26b59be6b791dc94b4f00690f8bd7 100644 (file)
@@ -1159,4 +1159,12 @@ typedef unsigned mcs_flags;
 #define TSUC_ALLOW_TAINTED_ARGS        BIT(1)
 #define TSUC_ALLOW_RECIPIENTS  BIT(2)
 
+/* Flags for smtp_printf */
+#define SP_MORE                TRUE
+#define SP_NO_MORE     FALSE
+
+/* Flags for smtp_respond */
+#define SR_FINAL       TRUE
+#define SR_NOT_FINAL   FALSE
+
 /* End of macros.h */
index 36e559b59db292478da38104006b79c5a7037657..c723ae6c876817b322f89b83c35d77d35cad919b 100644 (file)
@@ -1868,9 +1868,9 @@ for (pdkim_signature * sig = ctx->sig; sig; sig = sig->next)
     if (*dkim_verify_min_keysizes)
       {
       unsigned minbits;
-      uschar * ss = expand_getkeyed(US pdkim_keytypes[sig->keytype],
+      const uschar * ss = expand_getkeyed(US pdkim_keytypes[sig->keytype],
                                    dkim_verify_min_keysizes);
-      if (ss &&  (minbits = atoi(CS ss)) > sig->keybits)
+      if (ss &&  (minbits = atoi(CCS ss)) > sig->keybits)
        {
        DEBUG(D_acl) debug_printf("Key too short: Actual: %s %u  Minima '%s'\n",
          pdkim_keytypes[sig->keytype], sig->keybits, dkim_verify_min_keysizes);
index 8a400caf0517f0a929eabcd67eb0efdcc8dab5e4..8190c594130ab36f6735961fd119c8149648400f 100644 (file)
@@ -570,7 +570,7 @@ smtp_user_msg(uschar *code, uschar *user_msg)
 {
 int len = 3;
 smtp_message_code(&code, &len, &user_msg, NULL, TRUE);
-smtp_respond(code, len, TRUE, user_msg);
+smtp_respond(code, len, SR_FINAL, user_msg);
 }
 #endif
 
@@ -1457,7 +1457,7 @@ if (!(mbox_file = spool_mbox(&mbox_size, NULL, &mbox_filename)))
 #ifdef EXPERIMENTAL_DCC
   dcc_ok = 0;
 #endif
-  smtp_respond(US"451", 3, TRUE, US"temporary local problem");
+  smtp_respond(US"451", 3, SR_FINAL, US"temporary local problem");
   message_id[0] = 0;            /* Indicate no message accepted */
   *smtp_reply_ptr = US"";       /* Indicate reply already sent */
   return FALSE;                 /* Indicate skip to end of receive function */
@@ -2309,7 +2309,7 @@ OVERSIZE:
       sender_address,
       sender_fullhost ? " H=" : "", sender_fullhost ? sender_fullhost : US"",
       sender_ident ? " U=" : "",    sender_ident ? sender_ident : US"");
-    smtp_printf("552 Message header not CRLF terminated\r\n", FALSE);
+    smtp_printf("552 Message header not CRLF terminated\r\n", SP_NO_MORE);
     bdat_flush_data();
     smtp_reply = US"";
     goto TIDYUP;                             /* Skip to end of function */
@@ -3251,10 +3251,9 @@ if (!ferror(spool_data_file) && !(receive_feof)() && message_ended != END_DOT)
        {
        Uunlink(spool_name);            /* Lose data file when closed */
        cancel_cutthrough_connection(TRUE, US"sender closed connection");
-       message_id[0] = 0;              /* Indicate no message_accepted */
        smtp_reply = handle_lost_connection(US"");
        smtp_yield = FALSE;
-       goto TIDYUP;                            /* Skip to end of function */
+       goto NOT_ACCEPTED;                              /* Skip to end of function */
        }
       break;
 
@@ -3597,7 +3596,7 @@ else
       int all_pass = OK;
       int all_fail = FAIL;
 
-      smtp_printf("353 PRDR content analysis beginning\r\n", TRUE);
+      smtp_printf("353 PRDR content analysis beginning\r\n", SP_MORE);
       /* Loop through recipients, responses must be in same order received */
       for (unsigned int c = 0; recipients_count > c; c++)
         {
@@ -3661,7 +3660,7 @@ else
     /* Check the recipients count again, as the MIME ACL might have changed
     them. */
 
-    if (acl_smtp_data != NULL && recipients_count > 0)
+    if (acl_smtp_data && recipients_count > 0)
       {
       rc = acl_check(ACL_WHERE_DATA, NULL, acl_smtp_data, &user_msg, &log_msg);
       add_acl_headers(ACL_WHERE_DATA, US"DATA");
@@ -3922,7 +3921,7 @@ else
   if (smtp_input)
     if (!smtp_batched_input)
       {
-      smtp_respond(smtp_code, 3, TRUE, errmsg);
+      smtp_respond(smtp_code, 3, SR_FINAL, errmsg);
       smtp_reply = US"";            /* Indicate reply already sent */
       goto NOT_ACCEPTED;                       /* Skip to end of function */
       }
@@ -4030,11 +4029,6 @@ else
 
 receive_messagecount++;
 
-/* Add data size to written header size. We do not count the initial file name
-that is in the file, but we do add one extra for the notional blank line that
-precedes the data. This total differs from message_size in that it include the
-added Received: header and any other headers that got created locally. */
-
 if (fflush(spool_data_file))
   {
   errmsg = string_sprintf("Spool write error: %s", strerror(errno));
@@ -4054,8 +4048,13 @@ if (fflush(spool_data_file))
     /* Does not return */
     }
   }
-fstat(data_fd, &statbuf);
 
+/* Add data size to written header size. We do not count the initial file name
+that is in the file, but we do add one extra for the notional blank line that
+precedes the data. This total differs from message_size in that it include the
+added Received: header and any other headers that got created locally. */
+
+fstat(data_fd, &statbuf);
 msg_size += statbuf.st_size - spool_data_start_offset(message_id) + 1;
 
 /* Generate a "message received" log entry. We do this by building up a dynamic
@@ -4349,9 +4348,9 @@ if(!smtp_reply)
 #endif
   {
   log_write(0, LOG_MAIN |
-    (LOGGING(received_recipients) ? LOG_RECIPIENTS : 0) |
-    (LOGGING(received_sender) ? LOG_SENDER : 0),
-    "%Y", g);
+               (LOGGING(received_recipients) ? LOG_RECIPIENTS : 0) |
+               (LOGGING(received_sender) ? LOG_SENDER : 0),
+           "%Y", g);
 
   /* Log any control actions taken by an ACL or local_scan(). */
 
@@ -4389,9 +4388,16 @@ a queue-runner could grab it in the window.
 
 A fflush() was done earlier in the expectation that any write errors on the
 data file will be flushed(!) out thereby. Nevertheless, it is theoretically
-possible for fclose() to fail - but what to do? What has happened to the lock
-if this happens?  We can at least log it; if it is observed on some platform
-then we can think about properly declaring the message not-received. */
+possible for fclose() to fail - and this has been seen on obscure filesystems
+(probably one that delayed the actual media write as long as possible)
+but what to do? What has happened to the lock if this happens?
+It's a mes because we already logged the acceptance.
+We can at least log the issue, try to remove spoolfiles and respond with
+a temp-reject.  We do not want to close before logging acceptance because
+we want to hold the lock until we know that logging worked.
+Could we make this less likely by doing an fdatasync() just after the fflush()?
+That seems like a good thing on data-security grounds, but how much will it hit
+performance? */
 
 
 goto TIDYUP;
@@ -4404,8 +4410,27 @@ process_info[process_info_len] = 0;                      /* Remove message id */
 if (spool_data_file && cutthrough_done == NOT_TRIED)
   {
   if (fclose(spool_data_file))                         /* Frees the lock */
-    log_write(0, LOG_MAIN|LOG_PANIC,
-      "spoolfile error on close: %s", strerror(errno));
+    {
+    log_msg = string_sprintf("spoolfile error on close: %s", strerror(errno));
+    log_write(0, LOG_MAIN|LOG_PANIC |
+                 (LOGGING(received_recipients) ? LOG_RECIPIENTS : 0) |
+                 (LOGGING(received_sender) ? LOG_SENDER : 0),
+             "%s", log_msg);
+    log_write(0, LOG_MAIN |
+                 (LOGGING(received_recipients) ? LOG_RECIPIENTS : 0) |
+                 (LOGGING(received_sender) ? LOG_SENDER : 0),
+             "rescind the above message-accept");
+
+    Uunlink(spool_name);
+    Uunlink(spool_fname(US"input", message_subdir, message_id, US"-H"));
+    Uunlink(spool_fname(US"msglog", message_subdir, message_id, US""));
+
+    /* Claim a data ACL temp-reject, just to get reject logging and resposponse */
+    smtp_handle_acl_fail(ACL_WHERE_DATA, rc, NULL, log_msg);
+    smtp_reply = US"";         /* Indicate reply already sent */
+
+    message_id[0] = 0;         /* no message accepted */
+    }
   spool_data_file = NULL;
   }
 
@@ -4434,7 +4459,7 @@ if (smtp_input)
       {
       if (fake_response != OK)
         smtp_respond(fake_response == DEFER ? US"450" : US"550",
-         3, TRUE, fake_response_text);
+         3, SR_FINAL, fake_response_text);
 
       /* An OK response is required; use "message" text if present. */
 
@@ -4443,7 +4468,7 @@ if (smtp_input)
         uschar *code = US"250";
         int len = 3;
         smtp_message_code(&code, &len, &user_msg, NULL, TRUE);
-        smtp_respond(code, len, TRUE, user_msg);
+        smtp_respond(code, len, SR_FINAL, user_msg);
         }
 
       /* Default OK response */
@@ -4471,10 +4496,10 @@ if (smtp_input)
 
     else if (smtp_reply[0] != 0)
       if (fake_response != OK && smtp_reply[0] == '2')
-        smtp_respond(fake_response == DEFER ? US"450" : US"550", 3, TRUE,
-          fake_response_text);
+        smtp_respond(fake_response == DEFER ? US"450" : US"550",
+                     3, SR_FINAL, fake_response_text);
       else
-        smtp_printf("%.1024s\r\n", FALSE, smtp_reply);
+        smtp_printf("%.1024s\r\n", SP_NO_MORE, smtp_reply);
 
     switch (cutthrough_done)
       {
index 8cc9f74bf6c9635432a0e90c3b8ca12487810623..c565d522d9a27779a85ae73695ee3937fc2b1d2d 100644 (file)
@@ -764,7 +764,7 @@ for(;;)
     return EOD;
     }
 
-  smtp_printf("250 %u byte chunk received\r\n", FALSE, chunking_datasize);
+  smtp_printf("250 %u byte chunk received\r\n", SP_NO_MORE, chunking_datasize);
   chunking_state = CHUNKING_OFFERED;
   DEBUG(D_receive) debug_printf("chunking state %d\n", (int)chunking_state);
 
@@ -802,7 +802,7 @@ next_cmd:
 
     case NOOP_CMD:
       HAD(SCH_NOOP);
-      smtp_printf("250 OK\r\n", FALSE);
+      smtp_printf("250 OK\r\n", SP_NO_MORE);
       goto next_cmd;
 
     case BDAT_CMD:
@@ -1298,7 +1298,7 @@ smtp_closedown(uschar * message)
 {
 if (!smtp_in || smtp_batched_input) return;
 receive_swallow_smtp();
-smtp_printf("421 %s\r\n", FALSE, message);
+smtp_printf("421 %s\r\n", SP_NO_MORE, message);
 
 for (;;) switch(smtp_read_command(FALSE, GETC_BUFFER_UNLIMITED))
   {
@@ -1307,16 +1307,16 @@ for (;;) switch(smtp_read_command(FALSE, GETC_BUFFER_UNLIMITED))
 
   case QUIT_CMD:
     f.smtp_in_quit = TRUE;
-    smtp_printf("221 %s closing connection\r\n", FALSE, smtp_active_hostname);
+    smtp_printf("221 %s closing connection\r\n", SP_NO_MORE, smtp_active_hostname);
     mac_smtp_fflush();
     return;
 
   case RSET_CMD:
-    smtp_printf("250 Reset OK\r\n", FALSE);
+    smtp_printf("250 Reset OK\r\n", SP_NO_MORE);
     break;
 
   default:
-    smtp_printf("421 %s\r\n", FALSE, message);
+    smtp_printf("421 %s\r\n", SP_NO_MORE, message);
     break;
   }
 }
@@ -2266,7 +2266,7 @@ if (!f.sender_host_unknown)
         {
         log_write(0, LOG_MAIN, "getsockopt() failed from %s: %s",
           host_and_ident(FALSE), strerror(errno));
-        smtp_printf("451 SMTP service not available\r\n", FALSE);
+        smtp_printf("451 SMTP service not available\r\n", SP_NO_MORE);
         return FALSE;
         }
       }
@@ -2370,7 +2370,7 @@ if (!f.sender_host_unknown)
       log_write(0, LOG_MAIN|LOG_REJECT,
         "connection from %s refused (IP options)", host_and_ident(FALSE));
 
-      smtp_printf("554 SMTP service not available\r\n", FALSE);
+      smtp_printf("554 SMTP service not available\r\n", SP_NO_MORE);
       return FALSE;
       }
 
@@ -2425,7 +2425,7 @@ if (!f.sender_host_unknown)
 #ifndef DISABLE_TLS
     if (!tls_in.on_connect)
 #endif
-      smtp_printf("554 SMTP service not available\r\n", FALSE);
+      smtp_printf("554 SMTP service not available\r\n", SP_NO_MORE);
     return FALSE;
     }
 
@@ -2456,7 +2456,7 @@ if (!f.sender_host_unknown)
       log_write(L_connection_reject,
                 LOG_MAIN|LOG_REJECT, "refused connection from %s "
                 "(tcp wrappers)", host_and_ident(FALSE));
-      smtp_printf("554 SMTP service not available\r\n", FALSE);
+      smtp_printf("554 SMTP service not available\r\n", SP_NO_MORE);
       }
     else
       {
@@ -2466,7 +2466,7 @@ if (!f.sender_host_unknown)
       log_write(L_connection_reject,
                 LOG_MAIN|LOG_REJECT, "temporarily refused connection from %s "
                 "(tcp wrappers errno=%d)", host_and_ident(FALSE), save_errno);
-      smtp_printf("451 Temporary local problem - please try later\r\n", FALSE);
+      smtp_printf("451 Temporary local problem - please try later\r\n", SP_NO_MORE);
       }
     return FALSE;
     }
@@ -2486,7 +2486,7 @@ if (!f.sender_host_unknown)
         host_and_ident(FALSE), smtp_accept_count - 1, smtp_accept_max,
         smtp_accept_reserve, (rc == DEFER)? " (lookup deferred)" : "");
       smtp_printf("421 %s: Too many concurrent SMTP connections; "
-        "please try again later\r\n", FALSE, smtp_active_hostname);
+        "please try again later\r\n", SP_NO_MORE, smtp_active_hostname);
       return FALSE;
       }
     reserved_host = TRUE;
@@ -2507,7 +2507,7 @@ if (!f.sender_host_unknown)
       LOG_MAIN, "temporarily refused connection from %s: not in "
       "reserve list and load average = %.2f", host_and_ident(FALSE),
       (double)load_average/1000.0);
-    smtp_printf("421 %s: Too much load; please try again later\r\n", FALSE,
+    smtp_printf("421 %s: Too much load; please try again later\r\n", SP_NO_MORE,
       smtp_active_hostname);
     return FALSE;
     }
@@ -2681,7 +2681,7 @@ if (!check_sync())
       "synchronization error (input sent without waiting for greeting): "
       "rejected connection from %s input=\"%s\"", host_and_ident(TRUE),
       string_printing(string_copyn(smtp_inptr, n)));
-    smtp_printf("554 SMTP synchronization error\r\n", FALSE);
+    smtp_printf("554 SMTP synchronization error\r\n", SP_NO_MORE);
     return FALSE;
     }
 
@@ -2692,7 +2692,7 @@ smtp_printf("%Y",
 #ifndef DISABLE_PIPE_CONNECT
   fl.pipe_connect_acceptable && pipeline_connect_sends(),
 #else
-  FALSE,
+  SP_NO_MORE,
 #endif
   ss);
 
@@ -2751,10 +2751,10 @@ if (++synprot_error_count > smtp_max_synprot_errors)
 
 if (code > 0)
   {
-  smtp_printf("%d%c%s%s%s\r\n", FALSE, code, yield == 1 ? '-' : ' ',
+  smtp_printf("%d%c%s%s%s\r\n", SP_NO_MORE, code, yield == 1 ? '-' : ' ',
     data ? data : US"", data ? US": " : US"", errmess);
   if (yield == 1)
-    smtp_printf("%d Too many syntax or protocol errors\r\n", FALSE, code);
+    smtp_printf("%d Too many syntax or protocol errors\r\n", SP_NO_MORE, code);
   }
 
 return yield;
@@ -2781,7 +2781,7 @@ Returns:        nothing
 */
 
 void
-smtp_respond(uschar* code, int codelen, BOOL final, uschar *msg)
+smtp_respond(uschar * code, int codelen, BOOL final, uschar * msg)
 {
 int esclen = 0;
 uschar *esc = US"";
@@ -2830,7 +2830,7 @@ for (;;)
     }
   else
     {
-    smtp_printf("%.3s-%.*s%.*s\r\n", TRUE, code, esclen, esc, (int)(nl - msg), msg);
+    smtp_printf("%.3s-%.*s%.*s\r\n", SP_MORE, code, esclen, esc, (int)(nl - msg), msg);
     msg = nl + 1;
     Uskip_whitespace(&msg);
     }
@@ -2936,7 +2936,7 @@ Returns:     0 in most cases
 */
 
 int
-smtp_handle_acl_fail(int where, int rc, uschar *user_msg, uschar *log_msg)
+smtp_handle_acl_fail(int where, int rc, uschar * user_msg, uschar * log_msg)
 {
 BOOL drop = rc == FAIL_DROP;
 int codelen = 3;
@@ -3022,7 +3022,7 @@ if (sender_verified_failed &&
       string_sprintf(": %s", sender_verified_failed->message));
 
   if (rc == FAIL && sender_verified_failed->user_message)
-    smtp_respond(smtp_code, codelen, FALSE, string_sprintf(
+    smtp_respond(smtp_code, codelen, SR_NOT_FINAL, string_sprintf(
         testflag(sender_verified_failed, af_verify_pmfail)?
           "Postmaster verification failed while checking <%s>\n%s\n"
           "Several RFCs state that you are required to have a postmaster\n"
@@ -3054,7 +3054,7 @@ always a 5xx one - see comments at the start of this function. If the original
 rc was FAIL_DROP we drop the connection and yield 2. */
 
 if (rc == FAIL)
-  smtp_respond(smtp_code, codelen, TRUE,
+  smtp_respond(smtp_code, codelen, SR_FINAL,
     user_msg ? user_msg : US"Administrative prohibition");
 
 /* Send temporary failure response to the command. Don't give any details,
@@ -3072,12 +3072,12 @@ else
        && sender_verified_failed
        && sender_verified_failed->message
        )
-      smtp_respond(smtp_code, codelen, FALSE, sender_verified_failed->message);
+      smtp_respond(smtp_code, codelen, SR_NOT_FINAL, sender_verified_failed->message);
 
-    smtp_respond(smtp_code, codelen, TRUE, user_msg);
+    smtp_respond(smtp_code, codelen, SR_FINAL, user_msg);
     }
   else
-    smtp_respond(smtp_code, codelen, TRUE,
+    smtp_respond(smtp_code, codelen, SR_FINAL,
       US"Temporary local problem - please try later");
 
 /* Log the incident to the logs that are specified by log_reject_target
@@ -3194,7 +3194,7 @@ responses are all internal, they should be reasonable size. */
 if (code && defaultrespond)
   {
   if (user_msg)
-    smtp_respond(code, 3, TRUE, user_msg);
+    smtp_respond(code, 3, SR_FINAL, user_msg);
   else
     {
     gstring * g;
@@ -3203,7 +3203,7 @@ if (code && defaultrespond)
     va_start(ap, defaultrespond);
     g = string_vformat(NULL, SVFMT_EXTEND|SVFMT_REBUFFER, CS defaultrespond, ap);
     va_end(ap);
-    smtp_printf("%s %Y\r\n", FALSE, code, g);
+    smtp_printf("%s %Y\r\n", SP_NO_MORE, code, g);
     }
   mac_smtp_fflush();
   }
@@ -3360,7 +3360,7 @@ smtp_user_msg(uschar *code, uschar *user_msg)
 {
 int len = 3;
 smtp_message_code(&code, &len, &user_msg, NULL, TRUE);
-smtp_respond(code, len, TRUE, user_msg);
+smtp_respond(code, len, SR_FINAL, user_msg);
 }
 
 
@@ -3495,7 +3495,7 @@ if (f.allow_unqualified_recipient || strcmpic(*recipient, US"postmaster") == 0)
   *recipient = US rewrite_address_qualify(*recipient, TRUE);
   return rd;
   }
-smtp_printf("501 %s: recipient address must contain a domain\r\n", FALSE,
+smtp_printf("501 %s: recipient address must contain a domain\r\n", SP_NO_MORE,
   smtp_cmd_data);
 log_write(L_smtp_syntax_error,
   LOG_MAIN|LOG_REJECT, "unqualified %s rejected: <%s> %s%s",
@@ -3523,9 +3523,9 @@ if (  acl_smtp_quit
 #endif
 
 if (*user_msgp)
-  smtp_respond(US"221", 3, TRUE, *user_msgp);
+  smtp_respond(US"221", 3, SR_FINAL, *user_msgp);
 else
-  smtp_printf("221 %s closing connection\r\n", FALSE, smtp_active_hostname);
+  smtp_printf("221 %s closing connection\r\n", SP_NO_MORE, smtp_active_hostname);
 
 #ifdef SERVERSIDE_CLOSE_NOWAIT
 # ifndef DISABLE_TLS
@@ -3554,7 +3554,7 @@ smtp_rset_handler(void)
 {
 HAD(SCH_RSET);
 incomplete_transaction_log(US"RSET");
-smtp_printf("250 Reset OK\r\n", FALSE);
+smtp_printf("250 Reset OK\r\n", SP_NO_MORE);
 cmd_list[CL_RSET].is_mail_cmd = FALSE;
 if (chunking_state > CHUNKING_OFFERED)
   chunking_state = CHUNKING_OFFERED;
@@ -3809,7 +3809,7 @@ while (done <= 0)
          {
          int rc = smtp_in_auth(au, &smtp_resp, &errmsg);
 
-         smtp_printf("%s\r\n", FALSE, smtp_resp);
+         smtp_printf("%s\r\n", SP_NO_MORE, smtp_resp);
          if (rc != OK)
            {
            uschar * logmsg = NULL;
@@ -3870,7 +3870,7 @@ while (done <= 0)
 
       if (!check_helo(smtp_cmd_data))
        {
-       smtp_printf("501 Syntactically invalid %s argument(s)\r\n", FALSE, hello);
+       smtp_printf("501 Syntactically invalid %s argument(s)\r\n", SP_NO_MORE, hello);
 
        log_write(0, LOG_MAIN|LOG_REJECT, "rejected %s from %s: syntactically "
          "invalid argument(s): %s", hello, host_and_ident(FALSE),
@@ -3935,7 +3935,7 @@ while (done <= 0)
            {
            if (fl.helo_verify_required)
              {
-             smtp_printf("%d %s argument does not match calling host\r\n", FALSE,
+             smtp_printf("%d %s argument does not match calling host\r\n", SP_NO_MORE,
                tempfail? 451 : 550, hello);
              log_write(0, LOG_MAIN|LOG_REJECT, "%srejected \"%s %s\" from %s",
                tempfail? "temporarily " : "",
@@ -4288,7 +4288,7 @@ while (done <= 0)
          done = synprot_error(L_smtp_syntax_error, resp, NULL, errmsg);
        else
          {
-         smtp_printf("%d %s\r\n", FALSE, resp, errmsg);
+         smtp_printf("%d %s\r\n", SP_NO_MORE, resp, errmsg);
          log_write(0, LOG_MAIN|LOG_REJECT, "rejected XCLIENT from %s: %s",
            host_and_ident(FALSE), errmsg);
          }
@@ -4302,7 +4302,7 @@ while (done <= 0)
        We require that we do; the following HELO/EHLO handling will set
        sender_helo_name as normal. */
 
-       smtp_printf("%s XCLIENT success\r\n", FALSE, smtp_code);
+       smtp_printf("%s XCLIENT success\r\n", SP_NO_MORE, smtp_code);
        }
       break; /* XCLIENT */
       }
@@ -4326,7 +4326,7 @@ while (done <= 0)
        if (  fl.helo_verify_required
           || verify_check_host(&hosts_require_helo) == OK)
          {
-         smtp_printf("503 HELO or EHLO required\r\n", FALSE);
+         smtp_printf("503 HELO or EHLO required\r\n", SP_NO_MORE);
          log_write(0, LOG_MAIN|LOG_REJECT, "rejected MAIL from %s: no "
            "HELO/EHLO given", host_and_ident(FALSE));
          break;
@@ -4353,7 +4353,7 @@ while (done <= 0)
 
       if (smtp_mailcmd_max > 0 && smtp_mailcmd_count > smtp_mailcmd_max)
        {
-       smtp_printf("421 too many messages in this connection\r\n", FALSE);
+       smtp_printf("421 too many messages in this connection\r\n", SP_NO_MORE);
        log_write(0, LOG_MAIN|LOG_REJECT, "rejected MAIL command %s: too many "
          "messages in one connection", host_and_ident(TRUE));
        break;
@@ -4626,7 +4626,7 @@ while (done <= 0)
 
       if (thismessage_size_limit > 0 && message_size > thismessage_size_limit)
        {
-       smtp_printf("552 Message size exceeds maximum permitted\r\n", FALSE);
+       smtp_printf("552 Message size exceeds maximum permitted\r\n", SP_NO_MORE);
        log_write(L_size_reject,
            LOG_MAIN|LOG_REJECT, "rejected MAIL FROM:<%s> %s: "
            "message too big: size%s=%d max=%d",
@@ -4651,7 +4651,7 @@ while (done <= 0)
           smtp_check_spool_space && message_size >= 0
              ? message_size + 5000 : 0))
        {
-       smtp_printf("452 Space shortage, please try later\r\n", FALSE);
+       smtp_printf("452 Space shortage, please try later\r\n", SP_NO_MORE);
        sender_address = NULL;
        break;
        }
@@ -4673,7 +4673,7 @@ while (done <= 0)
          }
        else
          {
-         smtp_printf("501 %s: sender address must contain a domain\r\n", FALSE,
+         smtp_printf("501 %s: sender address must contain a domain\r\n", SP_NO_MORE,
            smtp_cmd_data);
          log_write(L_smtp_syntax_error,
            LOG_MAIN|LOG_REJECT,
@@ -4753,7 +4753,7 @@ while (done <= 0)
        {
        if (f.smtp_in_pipelining_advertised && last_was_rej_mail)
          {
-         smtp_printf("503 sender not yet given\r\n", FALSE);
+         smtp_printf("503 sender not yet given\r\n", SP_NO_MORE);
          was_rej_mail = TRUE;
          }
        else
@@ -4902,7 +4902,7 @@ while (done <= 0)
        if (recipients_max_reject)
          {
          rcpt_fail_count++;
-         smtp_printf("552 too many recipients\r\n", FALSE);
+         smtp_printf("552 too many recipients\r\n", SP_NO_MORE);
          if (!toomany)
            log_write(0, LOG_MAIN|LOG_REJECT, "too many recipients: message "
              "rejected: sender=<%s> %s", sender_address, host_and_ident(TRUE));
@@ -4910,7 +4910,7 @@ while (done <= 0)
        else
          {
          rcpt_defer_count++;
-         smtp_printf("452 too many recipients\r\n", FALSE);
+         smtp_printf("452 too many recipients\r\n", SP_NO_MORE);
          if (!toomany)
            log_write(0, LOG_MAIN|LOG_REJECT, "too many recipients: excess "
              "temporarily rejected: sender=<%s> %s", sender_address,
@@ -4976,7 +4976,7 @@ while (done <= 0)
        if (user_msg)
          smtp_user_msg(US"250", user_msg);
        else
-         smtp_printf("250 Accepted\r\n", FALSE);
+         smtp_printf("250 Accepted\r\n", SP_NO_MORE);
        rcpt_fail_count++;
        discarded = TRUE;
        log_write(0, LOG_MAIN|LOG_REJECT, "%s F=<%s> RCPT %s: "
@@ -5063,15 +5063,15 @@ while (done <= 0)
          {
          uschar *code = US"503";
          int len = Ustrlen(rcpt_smtp_response);
-         smtp_respond(code, 3, FALSE, US"All RCPT commands were rejected with "
+         smtp_respond(code, 3, SR_NOT_FINAL, US"All RCPT commands were rejected with "
            "this error:");
          /* Responses from smtp_printf() will have \r\n on the end */
          if (len > 2 && rcpt_smtp_response[len-2] == '\r')
            rcpt_smtp_response[len-2] = 0;
-         smtp_respond(code, 3, FALSE, rcpt_smtp_response);
+         smtp_respond(code, 3, SR_NOT_FINAL, rcpt_smtp_response);
          }
        if (f.smtp_in_pipelining_advertised && last_was_rcpt)
-         smtp_printf("503 Valid RCPT command must precede %s\r\n", FALSE,
+         smtp_printf("503 Valid RCPT command must precede %s\r\n", SP_NO_MORE,
            smtp_names[smtp_connection_had[SMTP_HBUFF_PREV(smtp_ch_index)]]);
        else
          done = synprot_error(L_smtp_protocol_error, 503, NULL,
@@ -5091,7 +5091,7 @@ while (done <= 0)
        {
        sender_address = NULL;  /* This will allow a new MAIL without RSET */
        sender_address_unrewritten = NULL;
-       smtp_printf("554 Too many recipients\r\n", FALSE);
+       smtp_printf("554 Too many recipients\r\n", SP_NO_MORE);
 
        if (chunking_state > CHUNKING_OFFERED)
          {
@@ -5132,7 +5132,7 @@ while (done <= 0)
          smtp_user_msg(US"354", user_msg);
        else
          smtp_printf(
-           "354 Enter message, ending with \".\" on a line by itself\r\n", FALSE);
+           "354 Enter message, ending with \".\" on a line by itself\r\n", SP_NO_MORE);
        }
 
       if (f.bdat_readers_wanted)
@@ -5158,7 +5158,7 @@ while (done <= 0)
       if (!(address = parse_extract_address(smtp_cmd_data, &errmess,
             &start, &end, &recipient_domain, FALSE)))
        {
-       smtp_printf("501 %s\r\n", FALSE, errmess);
+       smtp_printf("501 %s\r\n", SP_NO_MORE, errmess);
        break;
        }
 
@@ -5197,7 +5197,7 @@ while (done <= 0)
            break;
          }
 
-       smtp_printf("%s\r\n", FALSE, s);
+       smtp_printf("%s\r\n", SP_NO_MORE, s);
        }
       break;
       }
@@ -5325,7 +5325,7 @@ while (done <= 0)
 
       if (rc == DEFER)
        {
-       smtp_printf("454 TLS currently unavailable\r\n", FALSE);
+       smtp_printf("454 TLS currently unavailable\r\n", SP_NO_MORE);
        break;
        }
 
@@ -5358,15 +5358,15 @@ while (done <= 0)
              log_write(0, LOG_MAIN|LOG_PANIC, "ACL for QUIT returned ERROR: %s",
                log_msg);
          if (user_msg)
-           smtp_respond(US"221", 3, TRUE, user_msg);
+           smtp_respond(US"221", 3, SR_FINAL, user_msg);
          else
-           smtp_printf("221 %s closing connection\r\n", FALSE, smtp_active_hostname);
+           smtp_printf("221 %s closing connection\r\n", SP_NO_MORE, smtp_active_hostname);
          log_close_event(US"by QUIT");
          done = 2;
          break;
 
        default:
-         smtp_printf("554 Security failure\r\n", FALSE);
+         smtp_printf("554 Security failure\r\n", SP_NO_MORE);
          break;
        }
       tls_close(NULL, TLS_SHUTDOWN_NOWAIT);
@@ -5394,7 +5394,7 @@ while (done <= 0)
 
     case NOOP_CMD:
       HAD(SCH_NOOP);
-      smtp_printf("250 OK\r\n", FALSE);
+      smtp_printf("250 OK\r\n", SP_NO_MORE);
       break;
 
 
@@ -5405,23 +5405,23 @@ while (done <= 0)
 
     case HELP_CMD:
       HAD(SCH_HELP);
-      smtp_printf("214-Commands supported:\r\n214", TRUE);
-      smtp_printf(" AUTH", TRUE);
+      smtp_printf("214-Commands supported:\r\n214", SP_MORE);
+      smtp_printf(" AUTH", SP_MORE);
 #ifndef DISABLE_TLS
       if (tls_in.active.sock < 0 &&
          verify_check_host(&tls_advertise_hosts) != FAIL)
-       smtp_printf(" STARTTLS", TRUE);
+       smtp_printf(" STARTTLS", SP_MORE);
 #endif
-      smtp_printf(" HELO EHLO MAIL RCPT DATA BDAT", TRUE);
-      smtp_printf(" NOOP QUIT RSET HELP", TRUE);
-      if (acl_smtp_etrn) smtp_printf(" ETRN", TRUE);
-      if (acl_smtp_expn) smtp_printf(" EXPN", TRUE);
-      if (acl_smtp_vrfy) smtp_printf(" VRFY", TRUE);
+      smtp_printf(" HELO EHLO MAIL RCPT DATA BDAT", SP_MORE);
+      smtp_printf(" NOOP QUIT RSET HELP", SP_MORE);
+      if (acl_smtp_etrn) smtp_printf(" ETRN", SP_MORE);
+      if (acl_smtp_expn) smtp_printf(" EXPN", SP_MORE);
+      if (acl_smtp_vrfy) smtp_printf(" VRFY", SP_MORE);
 #ifdef EXPERIMENTAL_XCLIENT
       if (proxy_session || verify_check_host(&hosts_xclient) != FAIL)
-       smtp_printf(" XCLIENT", TRUE);
+       smtp_printf(" XCLIENT", SP_MORE);
 #endif
-      smtp_printf("\r\n", FALSE);
+      smtp_printf("\r\n", SP_NO_MORE);
       break;
 
 
@@ -5500,7 +5500,7 @@ while (done <= 0)
          {
          log_write(0, LOG_MAIN|LOG_PANIC, "failed to set up ETRN command: %s",
            error);
-         smtp_printf("458 Internal failure\r\n", FALSE);
+         smtp_printf("458 Internal failure\r\n", SP_NO_MORE);
          break;
          }
        }
@@ -5531,7 +5531,7 @@ while (done <= 0)
          debug_printf("ETRN command is: %s\n", etrn_command);
          debug_printf("ETRN command execution skipped\n");
          }
-       if (user_msg == NULL) smtp_printf("250 OK\r\n", FALSE);
+       if (user_msg == NULL) smtp_printf("250 OK\r\n", SP_NO_MORE);
          else smtp_user_msg(US"250", user_msg);
        break;
        }
@@ -5542,7 +5542,7 @@ while (done <= 0)
 
       if (smtp_etrn_serialize && !enq_start(etrn_serialize_key, 1))
        {
-       smtp_printf("458 Already processing %s\r\n", FALSE, smtp_cmd_data);
+       smtp_printf("458 Already processing %s\r\n", SP_NO_MORE, smtp_cmd_data);
        break;
        }
 
@@ -5607,12 +5607,12 @@ while (done <= 0)
        {
        log_write(0, LOG_MAIN|LOG_PANIC, "fork of process for ETRN failed: %s",
          strerror(errno));
-       smtp_printf("458 Unable to fork process\r\n", FALSE);
+       smtp_printf("458 Unable to fork process\r\n", SP_NO_MORE);
        if (smtp_etrn_serialize) enq_end(etrn_serialize_key);
        }
       else
        if (!user_msg)
-         smtp_printf("250 OK\r\n", FALSE);
+         smtp_printf("250 OK\r\n", SP_NO_MORE);
        else
          smtp_user_msg(US"250", user_msg);
 
@@ -5632,7 +5632,7 @@ while (done <= 0)
       done = synprot_error(L_smtp_syntax_error, 0, NULL,       /* Just logs */
        US"NUL character(s) present (shown as '?')");
       smtp_printf("501 NUL characters are not allowed in SMTP commands\r\n",
-                 FALSE);
+                 SP_NO_MORE);
       break;
 
 
@@ -5669,7 +5669,7 @@ while (done <= 0)
 
 #ifdef SUPPORT_PROXY
     case PROXY_FAIL_IGNORE_CMD:
-      smtp_printf("503 Command refused, required Proxy negotiation failed\r\n", FALSE);
+      smtp_printf("503 Command refused, required Proxy negotiation failed\r\n", SP_NO_MORE);
       break;
 #endif
 
index efa6004a38d1b7af1b45530c1d82cd7abfd0ebee..a17597e8bf3a68ab8eed83754bd364f0104f7fc9 100644 (file)
@@ -3000,7 +3000,7 @@ exim_gnutls_state_st * state = NULL;
 if (tls_in.active.sock >= 0)
   {
   tls_error(US"STARTTLS received after TLS started", US "", NULL, errstr);
-  smtp_printf("554 Already in TLS\r\n", FALSE);
+  smtp_printf("554 Already in TLS\r\n", SP_NO_MORE);
   return FAIL;
   }
 
@@ -3079,7 +3079,7 @@ mode, the fflush() happens when smtp_getc() is called. */
 
 if (!state->tlsp->on_connect)
   {
-  smtp_printf("220 TLS go ahead\r\n", FALSE);
+  smtp_printf("220 TLS go ahead\r\n", SP_NO_MORE);
   fflush(smtp_out);
   }
 
index b02605eae6bbb83334390f7a5fee1e337dd688cb..ef11de593590b313eb581537693b64650085feff 100644 (file)
@@ -3504,7 +3504,7 @@ static uschar peerdn[256];
 if (tls_in.active.sock >= 0)
   {
   tls_error(US"STARTTLS received after TLS started", NULL, US"", errstr);
-  smtp_printf("554 Already in TLS\r\n", FALSE);
+  smtp_printf("554 Already in TLS\r\n", SP_NO_MORE);
   return FAIL;
   }
 
@@ -3624,7 +3624,7 @@ mode, the fflush() happens when smtp_getc() is called. */
 SSL_set_session_id_context(ssl, sid_ctx, Ustrlen(sid_ctx));
 if (!tls_in.on_connect)
   {
-  smtp_printf("220 TLS go ahead\r\n", FALSE);
+  smtp_printf("220 TLS go ahead\r\n", SP_NO_MORE);
   fflush(smtp_out);
   }
 
index 9f0829c1a2b23e8379e64cfebf8bf05723b4a989..46cffa39a92122b64fe102ab777f9759f124c06c 100644 (file)
@@ -42,6 +42,9 @@ check_dkim:
 .endif
 
 check_data:
-  accept logwrite = ${authresults {$primary_hostname}}
+  warn         logwrite =      ${authresults {$primary_hostname}}
+  accept       dkim_status =   pass
+               logwrite =      dkim_status includes pass
+  accept       logwrite =      dkim_state DOES NOT include pass
 
 # End
index 5a25a722fe65816f10793bae3d4fc1b21b6c8d89..341f32558d2aaa1d66b822653039abf3475aeaba 100644 (file)
@@ -1,4 +1,4 @@
 1999-03-02 09:44:33 10HmaX-000000005vi-0000 <= someone@some.where U=CALLER P=local-bsmtp S=sss
 1999-03-02 09:44:33 10HmaX-000000005vi-0000 => CALLER <CALLER@the.local.host.name> R=localuser T=local_delivery
 1999-03-02 09:44:33 10HmaX-000000005vi-0000 Completed
-1999-03-02 09:44:33 SMTP connection from CALLER lost while reading message data
+1999-03-02 09:44:33 10HmaY-000000005vi-0000 SMTP connection from CALLER lost while reading message data
index c3e2bb8e78a302fba5dc3074a2b2b81c610f4c1c..00d13e443d9ae68da69ebb44692ab49742f036c1 100644 (file)
@@ -7,12 +7,12 @@
 2017-07-30 18:51:05.712 10HmbA-000000005vi-0000 <= some_ne@some.domain H=(tester) [127.0.0.1] Ci=p1239 P=esmtp K S=sss for CALLER@test.ex
 2017-07-30 18:51:05.712 10HmbB-000000005vi-0000 <= someone@some.domain H=(tester) [127.0.0.1] Ci=p1239 P=esmtp K S=sss for CALLER@test.ex
 2017-07-30 18:51:05.712 10HmbC-000000005vi-0000 SMTP data timeout (message abandoned) on connection from (tester) [127.0.0.1] F=<someone@some.domain> D=q.qqqs
-2017-07-30 18:51:05.712 SMTP connection Ci=p1240 from (tester) [127.0.0.1] lost while reading message data
-2017-07-30 18:51:05.712 SMTP connection Ci=p1241 from (tester) [127.0.0.1] lost while reading message data
-2017-07-30 18:51:05.712 10HmbD-000000005vi-0000 <= someone@some.domain H=(tester) [127.0.0.1] Ci=p1242 P=esmtp K S=sss for CALLER@test.ex
+2017-07-30 18:51:05.712 10HmbD-000000005vi-0000 SMTP connection Ci=p1240 from (tester) [127.0.0.1] lost while reading message data
+2017-07-30 18:51:05.712 10HmbE-000000005vi-0000 SMTP connection Ci=p1241 from (tester) [127.0.0.1] lost while reading message data
+2017-07-30 18:51:05.712 10HmbF-000000005vi-0000 <= someone@some.domain H=(tester) [127.0.0.1] Ci=p1242 P=esmtp K S=sss for CALLER@test.ex
 2017-07-30 18:51:05.712 H=(tester) [127.0.0.1] Ci=p1234 F=<someone@some.domain> rejected RCPT <dummy@reject.ex>: relay not permitted
 2017-07-30 18:51:05.712 H=(tester) [127.0.0.1] Ci=p1235 F=<some3ne@some.domain> rejected RCPT <dummy@reject.ex>: relay not permitted
 2017-07-30 18:51:05.712 H=(tester) [127.0.0.1] Ci=p1235 F=<some4ne@some.domain> rejected RCPT <dummy@reject.ex>: relay not permitted
-2017-07-30 18:51:05.712 10HmbE-000000005vi-0000 <= some6ne@some.domain H=(tester) [127.0.0.1] Ci=p1243 P=esmtp K S=sss for CALLER@test.ex
+2017-07-30 18:51:05.712 10HmbG-000000005vi-0000 <= some6ne@some.domain H=(tester) [127.0.0.1] Ci=p1243 P=esmtp K S=sss for CALLER@test.ex
 2017-07-30 18:51:05.712 rejected from <someone@some.domain> H=(tester) [127.0.0.1]: Non-CRLF-terminated header, under CHUNKING: message abandoned
-2017-07-30 18:51:05.712 10HmbF-000000005vi-0000 <= someone@some.domain H=(tester) [127.0.0.1] Ci=p1244 P=esmtp K S=sss for CALLER@test.ex
+2017-07-30 18:51:05.712 10HmbH-000000005vi-0000 <= someone@some.domain H=(tester) [127.0.0.1] Ci=p1244 P=esmtp K S=sss for CALLER@test.ex
index 8f4f5086a9555063fcdf9983f1cbc21b2138ff56..7d4a715b5334e9afff7003776dba13ce7f24deeb 100644 (file)
@@ -7,9 +7,9 @@
 1999-03-02 09:44:33 10HmbA-000000005vi-0000 <= someone2A@some.domain H=(tester) [127.0.0.1] P=esmtp K S=sss for CALLER@test.ex
 1999-03-02 09:44:33 10HmbB-000000005vi-0000 <= someone3A@some.domain H=(tester) [127.0.0.1] P=esmtp K S=sss for CALLER@test.ex
 1999-03-02 09:44:33 10HmbC-000000005vi-0000 SMTP data timeout (message abandoned) on connection from (tester) [127.0.0.1] F=<someone4@some.domain> D=qqs
-1999-03-02 09:44:33 SMTP connection from (tester) [127.0.0.1] lost while reading message data
-1999-03-02 09:44:33 SMTP connection from (tester) [127.0.0.1] lost while reading message data
-1999-03-02 09:44:33 10HmbD-000000005vi-0000 <= someone8@some.domain H=(tester) [127.0.0.1] P=esmtp K S=sss for CALLER@test.ex
+1999-03-02 09:44:33 10HmbD-000000005vi-0000 SMTP connection from (tester) [127.0.0.1] lost while reading message data
+1999-03-02 09:44:33 10HmbE-000000005vi-0000 SMTP connection from (tester) [127.0.0.1] lost while reading message data
+1999-03-02 09:44:33 10HmbF-000000005vi-0000 <= someone8@some.domain H=(tester) [127.0.0.1] P=esmtp K S=sss for CALLER@test.ex
 1999-03-02 09:44:33 SMTP protocol synchronization error (next input sent too soon: pipelining was not advertised): rejected "BDAT 1" H=(tester) [127.0.0.1] next input="BDAT 87 last\r\no: Susan@random.co"...
 1999-03-02 09:44:33 SMTP call from (tester) [127.0.0.1] dropped: too many syntax or protocol errors (last command was "From: Sam@random.com",  C=EHLO,MAIL,RCPT,BDAT)
 1999-03-02 09:44:33 SMTP connection from (tester) [127.0.0.1] lost while reading message data (header)
index 322c5a5bea1426cf0e8534de8f13460b6168ca13..be7ab89f0f8aac737326c3c9c0409e6f98b7f67e 100644 (file)
@@ -4,27 +4,40 @@
 1999-03-02 09:44:33 10HmaX-000000005vi-0000 signer: test.ex bits: 1024
 1999-03-02 09:44:33 10HmaX-000000005vi-0000 DKIM: d=test.ex s=sel c=simple/simple a=rsa-sha1 b=1024 [verification succeeded]
 1999-03-02 09:44:33 10HmaX-000000005vi-0000 Authentication-Results: myhost.test.ex;\n  dkim=pass header.d=test.ex header.s=sel header.a=rsa-sha1
+1999-03-02 09:44:33 10HmaX-000000005vi-0000 dkim_status includes pass
 1999-03-02 09:44:33 10HmaX-000000005vi-0000 <= CALLER@bloggs.com H=(xxx) [127.0.0.1] P=smtp S=sss DKIM=test.ex id=qwerty1234@disco-zombie.net
 1999-03-02 09:44:33 10HmaY-000000005vi-0000 signer: test.ex bits: 512
 1999-03-02 09:44:33 10HmaY-000000005vi-0000 DKIM: d=test.ex s=ses c=simple/simple a=rsa-sha1 b=512 [verification succeeded]
 1999-03-02 09:44:33 10HmaY-000000005vi-0000 Authentication-Results: myhost.test.ex;\n  dkim=pass header.d=test.ex header.s=ses header.a=rsa-sha1
+1999-03-02 09:44:33 10HmaY-000000005vi-0000 dkim_status includes pass
 1999-03-02 09:44:33 10HmaY-000000005vi-0000 <= CALLER@bloggs.com H=(xxx) [127.0.0.1] P=smtp S=sss DKIM=test.ex id=qwerty1234@disco-zombie.net
 1999-03-02 09:44:33 10HmaZ-000000005vi-0000 signer: test.ex bits: 1024
 1999-03-02 09:44:33 10HmaZ-000000005vi-0000 DKIM: d=test.ex s=sel c=simple/simple a=rsa-sha256 b=1024 [verification succeeded]
 1999-03-02 09:44:33 10HmaZ-000000005vi-0000 Authentication-Results: myhost.test.ex;\n  dkim=pass header.d=test.ex header.s=sel header.a=rsa-sha256
+1999-03-02 09:44:33 10HmaZ-000000005vi-0000 dkim_status includes pass
 1999-03-02 09:44:33 10HmaZ-000000005vi-0000 <= CALLER@bloggs.com H=(xxx) [127.0.0.1] P=smtp S=sss DKIM=test.ex id=qwerty1234@disco-zombie.net
 1999-03-02 09:44:33 10HmbA-000000005vi-0000 signer: test.ex bits: 512
 1999-03-02 09:44:33 10HmbA-000000005vi-0000 DKIM: d=test.ex s=ses_sha1 c=simple/simple a=rsa-sha1 b=512 [verification succeeded]
 1999-03-02 09:44:33 10HmbA-000000005vi-0000 Authentication-Results: myhost.test.ex;\n  dkim=pass header.d=test.ex header.s=ses_sha1 header.a=rsa-sha1
+1999-03-02 09:44:33 10HmbA-000000005vi-0000 dkim_status includes pass
 1999-03-02 09:44:33 10HmbA-000000005vi-0000 <= CALLER@bloggs.com H=(xxx) [127.0.0.1] P=smtp S=sss DKIM=test.ex id=qwerty1234@disco-zombie.net
 1999-03-02 09:44:33 exim x.yz daemon started: pid=p1235, no queue runs, listening for SMTP on port PORT_D
 1999-03-02 09:44:33 10HmbB-000000005vi-0000 NOTE: forcing dkim verify fail (was pass)
 1999-03-02 09:44:33 10HmbB-000000005vi-0000 signer: test.ex bits: 1024
 1999-03-02 09:44:33 10HmbB-000000005vi-0000 DKIM: d=test.ex s=sel c=simple/simple a=rsa-sha1 b=1024 [fail - hash too weak]
 1999-03-02 09:44:33 10HmbB-000000005vi-0000 Authentication-Results: myhost.test.ex;\n  dkim=policy (fail - hash too weak) header.d=test.ex header.s=sel header.a=rsa-sha1
+1999-03-02 09:44:33 10HmbB-000000005vi-0000 dkim_state DOES NOT include pass
 1999-03-02 09:44:33 10HmbB-000000005vi-0000 <= CALLER@bloggs.com H=(xxx) [127.0.0.1] P=smtp S=sss id=qwerty1234@disco-zombie.net
 1999-03-02 09:44:33 exim x.yz daemon started: pid=p1236, no queue runs, listening for SMTP on port PORT_D
 1999-03-02 09:44:33 10HmbC-000000005vi-0000 signer: test.ex bits: 512
 1999-03-02 09:44:33 10HmbC-000000005vi-0000 DKIM: d=test.ex s=ses c=simple/simple a=rsa-sha1 b=512 [verification failed - signature invalid (key too short)]
 1999-03-02 09:44:33 10HmbC-000000005vi-0000 Authentication-Results: myhost.test.ex;\n  dkim=fail (public key too short: 512 bits)\n             header.d=test.ex header.s=ses header.a=rsa-sha1
+1999-03-02 09:44:33 10HmbC-000000005vi-0000 dkim_state DOES NOT include pass
 1999-03-02 09:44:33 10HmbC-000000005vi-0000 <= CALLER@bloggs.com H=(xxx) [127.0.0.1] P=smtp S=sss id=qwerty1234@disco-zombie.net
+1999-03-02 09:44:33 10HmbD-000000005vi-0000 signer: test.ex bits: 1024
+1999-03-02 09:44:33 10HmbD-000000005vi-0000 DKIM: d=test.ex s=sel c=simple/simple a=rsa-sha256 b=1024 [verification succeeded]
+1999-03-02 09:44:33 10HmbD-000000005vi-0000 signer: test.ex bits: 512
+1999-03-02 09:44:33 10HmbD-000000005vi-0000 DKIM: d=test.ex s=ses c=simple/simple a=rsa-sha1 b=512 [verification failed - signature invalid (key too short)]
+1999-03-02 09:44:33 10HmbD-000000005vi-0000 Authentication-Results: myhost.test.ex;\n  dkim=pass header.d=test.ex header.s=sel header.a=rsa-sha256;\n  dkim=fail (public key too short: 512 bits)\n             header.d=test.ex header.s=ses header.a=rsa-sha1
+1999-03-02 09:44:33 10HmbD-000000005vi-0000 dkim_status includes pass
+1999-03-02 09:44:33 10HmbD-000000005vi-0000 <= CALLER@bloggs.com H=(xxx) [127.0.0.1] P=smtp S=sss DKIM=test.ex id=qwerty1234@disco-zombie.net
index 2a1934c05073c012206f8f469ae72f4e762585a7..ed8bb3d825c92be55ff55835b5e9ff2cf1e45fef 100644 (file)
@@ -4,8 +4,10 @@
 1999-03-02 09:44:33 10HmaX-000000005vi-0000 signer: test.ex bits: 1024
 1999-03-02 09:44:33 10HmaX-000000005vi-0000 DKIM: d=test.ex s=sel c=simple/simple a=rsa-sha1 b=1024 [verification succeeded]
 1999-03-02 09:44:33 10HmaX-000000005vi-0000 Authentication-Results: myhost.test.ex;\n  dkim=pass header.d=test.ex header.s=sel header.a=rsa-sha1
+1999-03-02 09:44:33 10HmaX-000000005vi-0000 dkim_status includes pass
 1999-03-02 09:44:33 10HmaX-000000005vi-0000 <= pass@bloggs.com H=(xxx) [127.0.0.1] P=smtp S=sss DKIM=test.ex id=qwerty1234@disco-zombie.net
 1999-03-02 09:44:33 10HmaY-000000005vi-0000 signer: test.ex bits: 0
 1999-03-02 09:44:33 10HmaY-000000005vi-0000 DKIM: d=test.ex s=sel c=simple/simple a=rsa-sha1 b=1024 [verification failed - body hash mismatch (body probably modified in transit)]
 1999-03-02 09:44:33 10HmaY-000000005vi-0000 Authentication-Results: myhost.test.ex;\n  dkim=fail (body hash mismatch; body probably modified in transit)\n              header.d=test.ex header.s=sel header.a=rsa-sha1
+1999-03-02 09:44:33 10HmaY-000000005vi-0000 dkim_state DOES NOT include pass
 1999-03-02 09:44:33 10HmaY-000000005vi-0000 <= fail@bloggs.com H=(xxx) [127.0.0.1] P=smtp S=sss id=qwerty1234@disco-zombie.net
index de5fbd478fa692b2b05830d8aa3e3de98e302931..4a1e8658896ac2f35cff0f5db389744415e5a3d4 100644 (file)
@@ -4,17 +4,21 @@
 1999-03-02 09:44:33 10HmaX-000000005vi-0000 signer: test.ex bits: 1024
 1999-03-02 09:44:33 10HmaX-000000005vi-0000 DKIM: d=test.ex s=sel c=relaxed/relaxed a=rsa-sha1 b=1024 [verification succeeded]
 1999-03-02 09:44:33 10HmaX-000000005vi-0000 Authentication-Results: myhost.test.ex;\n  dkim=pass header.d=test.ex header.s=sel header.a=rsa-sha1
+1999-03-02 09:44:33 10HmaX-000000005vi-0000 dkim_status includes pass
 1999-03-02 09:44:33 10HmaX-000000005vi-0000 <= CALLER@bloggs.com H=(xxx) [127.0.0.1] P=smtp S=sss DKIM=test.ex id=564CFC9B.1040905@yahoo.com
 1999-03-02 09:44:33 10HmaY-000000005vi-0000 signer: test.ex bits: 1024
 1999-03-02 09:44:33 10HmaY-000000005vi-0000 DKIM: d=test.ex s=sel c=relaxed/simple a=rsa-sha1 b=1024 [verification succeeded]
 1999-03-02 09:44:33 10HmaY-000000005vi-0000 Authentication-Results: myhost.test.ex;\n  dkim=pass header.d=test.ex header.s=sel header.a=rsa-sha1
+1999-03-02 09:44:33 10HmaY-000000005vi-0000 dkim_status includes pass
 1999-03-02 09:44:33 10HmaY-000000005vi-0000 <= CALLER@bloggs.com H=(xxx) [127.0.0.1] P=smtp S=sss DKIM=test.ex
 1999-03-02 09:44:33 10HmaZ-000000005vi-0000 signer: test.ex bits: 1024
 1999-03-02 09:44:33 10HmaZ-000000005vi-0000 DKIM: d=test.ex s=sel c=relaxed/simple a=rsa-sha1 b=1024 [verification succeeded]
 1999-03-02 09:44:33 10HmaZ-000000005vi-0000 Authentication-Results: myhost.test.ex;\n  dkim=pass header.d=test.ex header.s=sel header.a=rsa-sha1
+1999-03-02 09:44:33 10HmaZ-000000005vi-0000 dkim_status includes pass
 1999-03-02 09:44:33 10HmaZ-000000005vi-0000 <= CALLER@bloggs.com H=(xxx) [127.0.0.1] P=smtp S=sss DKIM=test.ex
 1999-03-02 09:44:33 10HmbA-000000005vi-0000 DKIM: d=test.ex s=sel_bad [failed key import]
 1999-03-02 09:44:33 10HmbA-000000005vi-0000 signer: test.ex bits: 0
 1999-03-02 09:44:33 10HmbA-000000005vi-0000 DKIM: d=test.ex s=sel_bad c=relaxed/relaxed a=rsa-sha1 b=1024 [invalid - syntax error in public key record]
 1999-03-02 09:44:33 10HmbA-000000005vi-0000 Authentication-Results: myhost.test.ex;\n  dkim=neutral (public key record import problem)\n                header.d=test.ex header.s=sel_bad header.a=rsa-sha1
+1999-03-02 09:44:33 10HmbA-000000005vi-0000 dkim_state DOES NOT include pass
 1999-03-02 09:44:33 10HmbA-000000005vi-0000 <= CALLER@bloggs.com H=(xxx) [127.0.0.1] P=smtp S=sss id=564CFC9B.1040905@yahoo.com
index ea4791a9141a42f4820a8fc486681bd0d584d412..2d5d8c42bee1a81d118b121e5f3b6c9b983f07bd 100644 (file)
@@ -4,4 +4,5 @@
 1999-03-02 09:44:33 10HmaX-000000005vi-0000 signer: test.ex bits: 1024
 1999-03-02 09:44:33 10HmaX-000000005vi-0000 DKIM: d=test.ex s=sel c=relaxed/relaxed a=rsa-sha512 b=1024 [verification succeeded]
 1999-03-02 09:44:33 10HmaX-000000005vi-0000 Authentication-Results: myhost.test.ex;\n  dkim=pass header.d=test.ex header.s=sel header.a=rsa-sha512
+1999-03-02 09:44:33 10HmaX-000000005vi-0000 dkim_status includes pass
 1999-03-02 09:44:33 10HmaX-000000005vi-0000 <= CALLER@bloggs.com H=(xxx) [127.0.0.1] P=smtp S=sss DKIM=test.ex id=E10HmaX-0005vi-00@myhost.test.ex
index ea4791a9141a42f4820a8fc486681bd0d584d412..2d5d8c42bee1a81d118b121e5f3b6c9b983f07bd 100644 (file)
@@ -4,4 +4,5 @@
 1999-03-02 09:44:33 10HmaX-000000005vi-0000 signer: test.ex bits: 1024
 1999-03-02 09:44:33 10HmaX-000000005vi-0000 DKIM: d=test.ex s=sel c=relaxed/relaxed a=rsa-sha512 b=1024 [verification succeeded]
 1999-03-02 09:44:33 10HmaX-000000005vi-0000 Authentication-Results: myhost.test.ex;\n  dkim=pass header.d=test.ex header.s=sel header.a=rsa-sha512
+1999-03-02 09:44:33 10HmaX-000000005vi-0000 dkim_status includes pass
 1999-03-02 09:44:33 10HmaX-000000005vi-0000 <= CALLER@bloggs.com H=(xxx) [127.0.0.1] P=smtp S=sss DKIM=test.ex id=E10HmaX-0005vi-00@myhost.test.ex
index adace8e4a05ba91a1b56a231c04311fa2fd59305..00139412faba5e8a6abb95011cee2701d31e182c 100644 (file)
@@ -4,32 +4,39 @@
 1999-03-02 09:44:33 10HmaY-000000005vi-0000 signer: test.ex bits: 0
 1999-03-02 09:44:33 10HmaY-000000005vi-0000 DKIM: d=test.ex s=sel c=simple/simple a=rsa-sha1 b=0 [invalid - signature tag missing or invalid]
 1999-03-02 09:44:33 10HmaY-000000005vi-0000 Authentication-Results: myhost.test.ex;\n  dkim=neutral (signature tag missing or invalid)\n                header.d=test.ex header.s=sel header.a=rsa-sha1
+1999-03-02 09:44:33 10HmaY-000000005vi-0000 dkim_state DOES NOT include pass
 1999-03-02 09:44:33 10HmaY-000000005vi-0000 <= CALLER@bloggs.com H=(xxx) [127.0.0.1] P=smtp S=sss id=qwerty1234@disco-zombie.net
 1999-03-02 09:44:33 10HmaZ-000000005vi-0000 signer: test.ex bits: 0
 1999-03-02 09:44:33 10HmaZ-000000005vi-0000 DKIM: d=test.ex s=sel c=simple/simple a=rsa-sha1 b=1024 [verification failed - body hash mismatch (body probably modified in transit)]
 1999-03-02 09:44:33 10HmaZ-000000005vi-0000 Authentication-Results: myhost.test.ex;\n  dkim=fail (body hash mismatch; body probably modified in transit)\n              header.d=test.ex header.s=sel header.a=rsa-sha1
+1999-03-02 09:44:33 10HmaZ-000000005vi-0000 dkim_state DOES NOT include pass
 1999-03-02 09:44:33 10HmaZ-000000005vi-0000 <= CALLER@bloggs.com H=(xxx) [127.0.0.1] P=smtp S=sss id=qwerty1234@disco-zombie.net
 1999-03-02 09:44:33 10HmbA-000000005vi-0000 signer: test.ex bits: 0
 1999-03-02 09:44:33 10HmbA-000000005vi-0000 DKIM: d=test.ex s=sel c=simple/simple a=rsa-sha1 b=1024 [verification failed - body hash mismatch (body probably modified in transit)]
 1999-03-02 09:44:33 10HmbA-000000005vi-0000 Authentication-Results: myhost.test.ex;\n  dkim=fail (body hash mismatch; body probably modified in transit)\n              header.d=test.ex header.s=sel header.a=rsa-sha1
+1999-03-02 09:44:33 10HmbA-000000005vi-0000 dkim_state DOES NOT include pass
 1999-03-02 09:44:33 10HmbA-000000005vi-0000 <= CALLER@bloggs.com H=(xxx) [127.0.0.1] P=smtp S=sss id=qwerty1234@disco-zombie.net
 1999-03-02 09:44:33 10HmbB-000000005vi-0000 DKIM: validation error: LONG_LINE
 1999-03-02 09:44:33 10HmbB-000000005vi-0000 DKIM: Error during validation, disabling signature verification: LONG_LINE
 1999-03-02 09:44:33 10HmbB-000000005vi-0000 Authentication-Results: myhost.test.ex
+1999-03-02 09:44:33 10HmbB-000000005vi-0000 dkim_state DOES NOT include pass
 1999-03-02 09:44:33 10HmbB-000000005vi-0000 <= CALLER@bloggs.com H=(xxx) [127.0.0.1] P=smtp S=sss id=qwerty1234@disco-zombie.net
 1999-03-02 09:44:33 10HmbC-000000005vi-0000 signer: test.ex bits: 512
 1999-03-02 09:44:33 10HmbC-000000005vi-0000 DKIM: d=test.ex s=ses_sha256 c=simple/simple a=rsa-sha1 b=512 [verification failed - unspecified reason]
 1999-03-02 09:44:33 10HmbC-000000005vi-0000 Authentication-Results: myhost.test.ex;\n  dkim=fail (unspecified reason)\n                 header.d=test.ex header.s=ses_sha256 header.a=rsa-sha1
+1999-03-02 09:44:33 10HmbC-000000005vi-0000 dkim_state DOES NOT include pass
 1999-03-02 09:44:33 10HmbC-000000005vi-0000 <= CALLER@bloggs.com H=(xxx) [127.0.0.1] P=smtp S=sss id=qwerty1234@disco-zombie.net
 1999-03-02 09:44:33 DKIM: validation error: EXCESS_SIGS
 1999-03-02 09:44:33 10HmbD-000000005vi-0000 DKIM: Error during validation, disabling signature verification: EXCESS_SIGS
 1999-03-02 09:44:33 10HmbD-000000005vi-0000 Authentication-Results: myhost.test.ex
+1999-03-02 09:44:33 10HmbD-000000005vi-0000 dkim_state DOES NOT include pass
 1999-03-02 09:44:33 10HmbD-000000005vi-0000 <= CALLER@bloggs.com H=(xxx) [127.0.0.1] P=smtp S=sss id=20180418125440.Horde.vVKB6E7UvpLfJsPzv2ZPs6z@webmail.sego.es
 1999-03-02 09:44:33 exim x.yz daemon started: pid=p1235, no queue runs, listening for SMTP on port PORT_D
 1999-03-02 09:44:33 10HmbE-000000005vi-0000 unknown
 1999-03-02 09:44:33 10HmbE-000000005vi-0000 signer: test.ex bits: 0
 1999-03-02 09:44:33 10HmbE-000000005vi-0000 DKIM: d=test.ex s=sel c=simple/simple a=rsa-sha1 b=0 [invalid - signature tag missing or invalid]
 1999-03-02 09:44:33 10HmbE-000000005vi-0000 Authentication-Results: myhost.test.ex;\n  dkim=neutral (signature tag missing or invalid)\n                header.d=test.ex header.s=sel header.a=rsa-sha1
+1999-03-02 09:44:33 10HmbE-000000005vi-0000 dkim_state DOES NOT include pass
 1999-03-02 09:44:33 10HmbE-000000005vi-0000 <= CALLER@bloggs.com H=(xxx) [127.0.0.1] P=smtp S=sss id=qwerty1234@disco-zombie.net
 1999-03-02 09:44:33 exim x.yz daemon started: pid=p1236, no queue runs, listening for SMTP on port PORT_D
 1999-03-02 09:44:33 10HmaX-000000005vi-0000 signer: test.ex bits: 0
index 80aa4ca28a562cfcbbae0ef223b51ad37c4b6c9f..e283729ed4f7d746c5f7f93c16c8b80bf066b092 100644 (file)
@@ -4,19 +4,23 @@
 1999-03-02 09:44:33 10HmaX-000000005vi-0000 signer: test.ex bits: 253
 1999-03-02 09:44:33 10HmaX-000000005vi-0000 DKIM: d=test.ex s=sed c=relaxed/relaxed a=ed25519-sha256 b=512 [verification succeeded]
 1999-03-02 09:44:33 10HmaX-000000005vi-0000 Authentication-Results: myhost.test.ex;\n  dkim=pass header.d=test.ex header.s=sed header.a=ed25519-sha256
+1999-03-02 09:44:33 10HmaX-000000005vi-0000 dkim_status includes pass
 1999-03-02 09:44:33 10HmaX-000000005vi-0000 <= CALLER@bloggs.com H=(xxx) [127.0.0.1] P=smtp S=sss DKIM=test.ex id=E10HmaX-0005vi-00@myhost.test.ex
 1999-03-02 09:44:33 10HmaY-000000005vi-0000 signer: test.ex bits: 253
 1999-03-02 09:44:33 10HmaY-000000005vi-0000 DKIM: d=test.ex s=sedw c=relaxed/relaxed a=ed25519-sha256 b=512 [verification succeeded]
 1999-03-02 09:44:33 10HmaY-000000005vi-0000 Authentication-Results: myhost.test.ex;\n  dkim=pass header.d=test.ex header.s=sedw header.a=ed25519-sha256
+1999-03-02 09:44:33 10HmaY-000000005vi-0000 dkim_status includes pass
 1999-03-02 09:44:33 10HmaY-000000005vi-0000 <= CALLER@bloggs.com H=(xxx) [127.0.0.1] P=smtp S=sss DKIM=test.ex id=E10HmaX-0005vi-00@myhost.test.ex
 1999-03-02 09:44:33 10HmaZ-000000005vi-0000 signer: kitterman.org bits: 253
 1999-03-02 09:44:33 10HmaZ-000000005vi-0000 DKIM: d=kitterman.org s=ed25519 c=relaxed/simple a=ed25519-sha256 b=512 i=@kitterman.org t=1517847601 [verification succeeded]
 1999-03-02 09:44:33 10HmaZ-000000005vi-0000 signer: @kitterman.org bits: 253
 1999-03-02 09:44:33 10HmaZ-000000005vi-0000 DKIM: d=kitterman.org s=ed25519 c=relaxed/simple a=ed25519-sha256 b=512 i=@kitterman.org t=1517847601 [verification succeeded]
 1999-03-02 09:44:33 10HmaZ-000000005vi-0000 Authentication-Results: myhost.test.ex;\n  dkim=pass header.d=kitterman.org header.i=@kitterman.org header.s=ed25519 header.a=ed25519-sha256
+1999-03-02 09:44:33 10HmaZ-000000005vi-0000 dkim_status includes pass
 1999-03-02 09:44:33 10HmaZ-000000005vi-0000 <= CALLER@bloggs.com H=(xxx) [127.0.0.1] P=smtp S=sss DKIM=kitterman.org id=example@example.com
 1999-03-02 09:44:33 exim x.yz daemon started: pid=p1235, no queue runs, listening for SMTP on port PORT_D
 1999-03-02 09:44:33 10HmbA-000000005vi-0000 signer: test.ex bits: 253
 1999-03-02 09:44:33 10HmbA-000000005vi-0000 DKIM: d=test.ex s=sed c=relaxed/relaxed a=ed25519-sha256 b=512 [verification failed - signature invalid (key too short)]
 1999-03-02 09:44:33 10HmbA-000000005vi-0000 Authentication-Results: myhost.test.ex;\n  dkim=fail (public key too short: 253 bits)\n             header.d=test.ex header.s=sed header.a=ed25519-sha256
+1999-03-02 09:44:33 10HmbA-000000005vi-0000 dkim_state DOES NOT include pass
 1999-03-02 09:44:33 10HmbA-000000005vi-0000 <= CALLER@bloggs.com H=(xxx) [127.0.0.1] P=smtp S=sss id=E10HmaX-0005vi-00@myhost.test.ex
index d1cc646f983d8513dc76ed265e8e2560842d66c9..112fda5069ed83f00d4b1fe57339456b066ea2b4 100644 (file)
@@ -3,6 +3,7 @@
 exim -DSERVER=server -DMSIZE='rsa=512 ed25519=250' -bd -oX PORT_D
 ****
 #
+# (A)
 # This should pass.
 #  - sha1, 1024b
 # Mail original in aux-fixed/4500.msg1.txt
@@ -37,6 +38,7 @@ QUIT
 ??? 221
 ****
 #
+# (B)
 # This should pass.
 #  - sha1, 512b
 # Mail original in aux-fixed/4500.msg1.txt
@@ -69,6 +71,7 @@ QUIT
 ??? 221
 ****
 #
+# (C)
 # This should pass.
 #  - sha256, 1024b
 # Mail original in aux-fixed/4500.msg1.txt
@@ -103,6 +106,7 @@ QUIT
 ****
 #
 #
+# (D)
 # This should pass.  The pubkey dns decord has a additional sha1-only h= field
 #
 #  - sha1, 512b
@@ -143,6 +147,7 @@ killdaemon
 exim -DSERVER=server -DOPTION -DMSIZE='rsa=512 ed25519c=32' -bd -oX PORT_D
 ****
 #
+# (E)
 # This should fail despite being a passing submission above (with the unlimited verifier).
 #  - sha1, 1024b
 # Mail original in aux-fixed/4500.msg1.txt
@@ -181,6 +186,7 @@ killdaemon
 #
 #
 #
+# (F)
 # With the default keysize minima, a 512b key should fail
 exim -DSERVER=server -bd -oX PORT_D
 ****
@@ -208,6 +214,42 @@ Date: Thu, 19 Nov 2015 17:00:07 -0700
 Message-ID: <qwerty1234@disco-zombie.net>
 Subject: simple test
 
+This is a simple test.
+.
+??? 250
+QUIT
+??? 221
+****
+#
+#
+# (G)
+# Two signature, one pass one fail.  Checking for "at least one pass".
+# Sigs from (F) and (C) above
+client 127.0.0.1 PORT_D
+??? 220
+HELO xxx
+??? 250
+MAIL FROM:<CALLER@bloggs.com>
+??? 250
+RCPT TO:<a@test.ex>
+??? 250
+DATA
+??? 354
+DKIM-Signature: v=1; a=rsa-sha1; c=simple/simple; d=test.ex; h=from:to
+       :date:message-id:subject; s=ses; bh=OB9dZVu7+5/ufs3TH9leIcEpXSo=; b=
+       cIErF1eueIT9AU4qG54FyT3yrlVDDM7RZnuU6fWTevZpAuMqhYcRO8tU3U4vtKWB
+       +I2vd+F1gzqCzBcRtfLhZg==
+DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=test.ex; h=from:to
+       :date:message-id:subject; s=sel; bh=3UbbJTudPxmejzh7U1Zg33U3QT+1
+       6kfV2eOTvMeiEis=; b=xQSD/JMqz0C+xKf0A1NTkPTbkDuDdJbpBuyjjT9iYvyP
+       Zez+xl0TkoPobFGVa6EN8+ZeYV18zjifhtWYLSsNmPinUtcpKQLG1zxAKmmS0JEh
+       +qihlWbeGJ5+tK588ugUzXHPj+4JBW0H6kxHvdH0l2SlQE5xs/cdggnx5QX5USY=
+From: mrgus@text.ex
+To: bakawolf@yahoo.com
+Date: Thu, 19 Nov 2015 17:00:07 -0700
+Message-ID: <qwerty1234@disco-zombie.net>
+Subject: simple test
+
 This is a simple test.
 .
 ??? 250
index 6fcd8bd8d1cbed226c7589d9e8f0c9a0dc45dba8..d82f5d95e723c5d79decda94287b076a10018f81 100644 (file)
@@ -12,7 +12,7 @@
 >>>  list element: @
 >>>  list element: @[]
 >>> xxx in helo_lookup_domains? no (end of list)
->>> processing "accept" (TESTSUITE/test-config 47)
+>>> processing "accept" (TESTSUITE/test-config 50)
 >>> accept: condition test succeeded in inline ACL
 >>> end of inline ACL: ACCEPT
 >>> host in ignore_fromline_hosts? no (option unset)
@@ -27,11 +27,19 @@ LOG: 10HmaX-000000005vi-0000 signer: test.ex bits: 1024
 >>> end of ACL "check_dkim": ACCEPT
 LOG: 10HmaX-000000005vi-0000 DKIM: d=test.ex s=sel c=simple/simple a=rsa-sha1 b=1024 [verification succeeded]
 >>> using ACL "check_data"
->>> processing "accept" (TESTSUITE/test-config 45)
+>>> processing "warn" (TESTSUITE/test-config 45)
 >>> check logwrite = ${authresults {$primary_hostname}}
 >>>                = Authentication-Results: myhost.test.ex;
 >>>    dkim=pass header.d=test.ex header.s=sel header.a=rsa-sha1
 LOG: 10HmaX-000000005vi-0000 Authentication-Results: myhost.test.ex;\n dkim=pass header.d=test.ex header.s=sel header.a=rsa-sha1
+>>> warn: condition test succeeded in ACL "check_data"
+>>> processing "accept" (TESTSUITE/test-config 46)
+>>> check dkim_status = pass
+>>> pass in "pass"?
+>>>  list element: pass
+>>>  pass in "pass"? yes (matched "pass")
+>>> check logwrite = dkim_status includes pass
+LOG: 10HmaX-000000005vi-0000 dkim_status includes pass
 >>> accept: condition test succeeded in ACL "check_data"
 >>> end of ACL "check_data": ACCEPT
 LOG: 10HmaX-000000005vi-0000 <= CALLER@bloggs.com H=(xxx) [127.0.0.1] P=smtp S=sss DKIM=test.ex id=qwerty1234@disco-zombie.net
index fbebcf5f0a53cbd167b734860a4c2242ac73e750..9fe0eb7dea2ca65b039a58ed6925205baaec40e2 100644 (file)
@@ -317,7 +317,7 @@ Connecting to 127.0.0.1 port 1225 ... connected
 ??? 250-
 <<< 250- 88 byte chunk, total 88
 ??? 250
-<<< 250 OK id=10HmbD-000000005vi-0000
+<<< 250 OK id=10HmbF-000000005vi-0000
 >>> quit
 ??? 221
 <<< 221 testhost.test.ex closing connection
@@ -454,7 +454,7 @@ Connecting to 127.0.0.1 port 1225 ... connected
 ??? 250- 6 byte chunk, total 93
 <<< 250- 6 byte chunk, total 93
 ??? 250 OK
-<<< 250 OK id=10HmbE-000000005vi-0000
+<<< 250 OK id=10HmbG-000000005vi-0000
 >>> QUIT
 ??? 221
 <<< 221 testhost.test.ex closing connection
@@ -523,7 +523,7 @@ Connecting to 127.0.0.1 port 1225 ... connected
 ??? 250-
 <<< 250- 98 byte chunk, total 100
 ??? 250
-<<< 250 OK id=10HmbF-000000005vi-0000
+<<< 250 OK id=10HmbH-000000005vi-0000
 >>> quit
 ??? 221
 <<< 221 testhost.test.ex closing connection
index b2797046a0881e7fa02b8191c528f4e3bb52ef50..efd578a7daf1bca128135ba8683da74d3c5ac7ee 100644 (file)
@@ -305,7 +305,7 @@ Connecting to 127.0.0.1 port 1225 ... connected
 ??? 250-
 <<< 250- 88 byte chunk, total 88
 ??? 250
-<<< 250 OK id=10HmbD-000000005vi-0000
+<<< 250 OK id=10HmbF-000000005vi-0000
 >>> quit
 ??? 221
 <<< 221 testhost.test.ex closing connection