Debug: indentation
[exim.git] / src / src / smtp_in.c
index 1a66e183587bdea0dc8ecd4ebf5adf734b191efb..c52d3f4d64da3ee3679d53182783bff8bc284452 100644 (file)
@@ -2,7 +2,7 @@
 *     Exim - an Internet mail transport agent    *
 *************************************************/
 
-/* Copyright (c) The Exim Maintainers 2020 - 2022 */
+/* Copyright (c) The Exim Maintainers 2020 - 2024 */
 /* Copyright (c) University of Cambridge 1995 - 2018 */
 /* See the file NOTICE for conditions of use and distribution. */
 /* SPDX-License-Identifier: GPL-2.0-or-later */
@@ -86,6 +86,9 @@ enum {
   /* These commands need not be synchronized when pipelining */
 
   MAIL_CMD, RCPT_CMD, RSET_CMD,
+#ifndef DISABLE_WELLKNOWN
+  WELLKNOWN_CMD,
+#endif
 
   /* This is a dummy to identify the non-sync commands when not pipelining */
 
@@ -121,7 +124,8 @@ enum {
   /* These are specials that don't correspond to actual commands */
 
   EOF_CMD, OTHER_CMD, BADARG_CMD, BADCHAR_CMD, BADSYN_CMD,
-  TOO_MANY_NONMAIL_CMD };
+  TOO_MANY_NONMAIL_CMD
+};
 
 
 /* This is a convenience macro for adding the identity of an SMTP command
@@ -230,7 +234,10 @@ static smtp_cmd_list cmd_list[] = {
   { "etrn",       sizeof("etrn")-1,       ETRN_CMD, TRUE,  FALSE },
   { "vrfy",       sizeof("vrfy")-1,       VRFY_CMD, TRUE,  FALSE },
   { "expn",       sizeof("expn")-1,       EXPN_CMD, TRUE,  FALSE },
-  { "help",       sizeof("help")-1,       HELP_CMD, TRUE,  FALSE }
+  { "help",       sizeof("help")-1,       HELP_CMD, TRUE,  FALSE },
+#ifndef DISABLE_WELLKNOWN
+  { "wellknown",  sizeof("wellknown")-1,  WELLKNOWN_CMD, TRUE,  FALSE },
+#endif
 };
 
 /* This list of names is used for performing the smtp_no_mail logging action. */
@@ -253,6 +260,9 @@ uschar * smtp_names[] =
   [SCH_RSET] = US"RSET",
   [SCH_STARTTLS] = US"STARTTLS",
   [SCH_VRFY] = US"VRFY",
+#ifndef DISABLE_WELLKNOWN
+  [SCH_WELLKNOWN] = US"WELLKNOWN",
+#endif
 #ifdef EXPERIMENTAL_XCLIENT
   [SCH_XCLIENT] = US"XCLIENT",
 #endif
@@ -1227,7 +1237,7 @@ for (smtp_cmd_list * p = cmd_list; p < cmd_list + nelem(cmd_list); p++)
     follow the sender address. */
 
     smtp_cmd_argument = smtp_cmd_buffer + p->len;
-    while (isspace(*smtp_cmd_argument)) smtp_cmd_argument++;
+    Uskip_whitespace(&smtp_cmd_argument);
     Ustrcpy(smtp_data_buffer, smtp_cmd_argument);
     smtp_cmd_data = smtp_data_buffer;
 
@@ -1352,7 +1362,7 @@ if (host_checking)
   g = string_cat(g, hostname);
 
 else if (f.sender_host_unknown || f.sender_host_notsocket)
-  g = string_cat(g, sender_ident);
+  g = string_cat(g, sender_ident ? sender_ident : US"NULL");
 
 else if (f.is_inetd)
   g = string_append(g, 2, hostname, US" (via inetd)");
@@ -1876,10 +1886,11 @@ while (done <= 0)
 
       /* Check maximum number allowed */
 
-      if (recipients_max > 0 && recipients_count + 1 > recipients_max)
+      if (  recipients_max_expanded > 0
+        && recipients_count + 1 > recipients_max_expanded)
        /* The function moan_smtp_batch() does not return. */
        moan_smtp_batch(smtp_cmd_buffer, "%s too many recipients",
-         recipients_max_reject? "552": "452");
+         recipients_max_reject ? "552": "452");
 
       /* Apply SMTP rewrite, then extract address. Don't allow "<>" as a
       recipient address */
@@ -1945,6 +1956,9 @@ while (done <= 0)
     case HELP_CMD:
     case NOOP_CMD:
     case ETRN_CMD:
+#ifndef DISABLE_WELLKNOWN
+    case WELLKNOWN_CMD:
+#endif
       bsmtp_transaction_linecount = receive_linecount;
       break;
 
@@ -2051,16 +2065,22 @@ else DEBUG(D_receive)
 static void
 log_connect_tls_drop(const uschar * what, const uschar * log_msg)
 {
-gstring * g = s_tlslog(NULL);
-uschar * tls = string_from_gstring(g);
-
-log_write(L_connection_reject,
-  log_reject_target, "%s%s%s dropped by %s%s%s",
-  LOGGING(dnssec) && sender_host_dnssec ? US" DS" : US"",
-  host_and_ident(TRUE),
-  tls ? tls : US"",
-  what,
-  log_msg ? US": " : US"", log_msg);
+if (log_reject_target)
+  {
+#ifdef DISABLE_TLS
+  uschar * tls = NULL;
+#else
+  gstring * g = s_tlslog(NULL);
+  uschar * tls = string_from_gstring(g);
+#endif
+  log_write(L_connection_reject,
+    log_reject_target, "%s%s%s dropped by %s%s%s",
+    LOGGING(dnssec) && sender_host_dnssec ? US" DS" : US"",
+    host_and_ident(TRUE),
+    tls ? tls : US"",
+    what,
+    log_msg ? US": " : US"", log_msg);
+  }
 }
 
 
@@ -2168,6 +2188,7 @@ lwr_receive_ungetc = NULL;
 
 /* Set up the message size limit; this may be host-specific */
 
+GET_OPTION("message_size_limit");
 thismessage_size_limit = expand_string_integer(message_size_limit, TRUE);
 if (expand_string_message)
   {
@@ -2537,11 +2558,16 @@ if (!f.sender_host_unknown)
   fl.helo_accept_junk = verify_check_host(&helo_accept_junk_hosts) == OK;
   }
 
+/* Expand recipients_max, if needed */
+ {
+  uschar * rme = expand_string(recipients_max);
+  recipients_max_expanded = atoi(CCS rme);
+ }
 /* For batch SMTP input we are now done. */
 
 if (smtp_batched_input) return TRUE;
 
-#if defined(SUPPORT_PROXY) || defined(SUPPORT_SOCKS) || defined(EXPERIMETAL_XCLIENT)
+#if defined(SUPPORT_PROXY) || defined(SUPPORT_SOCKS) || defined(EXPERIMENTAL_XCLIENT)
 proxy_session = FALSE;
 #endif
 
@@ -2560,6 +2586,7 @@ if (proxy_protocol_host())
 /* Run the connect ACL if it exists */
 
 user_msg = NULL;
+GET_OPTION("acl_smtp_connect");
 if (acl_smtp_connect)
   {
   int rc;
@@ -2606,16 +2633,20 @@ if (user_msg)
     esclen = codelen - 4;
     }
   }
-else if (!(s = expand_string(smtp_banner)))
+else
   {
-  log_write(0, f.expand_string_forcedfail ? LOG_MAIN : LOG_MAIN|LOG_PANIC_DIE,
-    "Expansion of \"%s\" (smtp_banner) failed: %s",
-    smtp_banner, expand_string_message);
-  /* for force-fail */
-#ifndef DISABLE_TLS
-  if (tls_in.on_connect) tls_close(NULL, TLS_SHUTDOWN_WAIT);
-#endif
-  return FALSE;
+  GET_OPTION("smtp_banner");
+  if (!(s = expand_string(smtp_banner)))
+    {
+    log_write(0, f.expand_string_forcedfail ? LOG_MAIN : LOG_MAIN|LOG_PANIC_DIE,
+      "Expansion of \"%s\" (smtp_banner) failed: %s",
+      smtp_banner, expand_string_message);
+    /* for force-fail */
+  #ifndef DISABLE_TLS
+    if (tls_in.on_connect) tls_close(NULL, TLS_SHUTDOWN_WAIT);
+  #endif
+    return FALSE;
+    }
   }
 
 /* Remove any terminating newlines; might as well remove trailing space too */
@@ -2814,10 +2845,8 @@ if (fl.rcpt_in_progress)
 We only handle pipelining these responses as far as nonfinal/final groups,
 not the whole MAIL/RCPT/DATA response set. */
 
-for (;;)
-  {
-  uschar *nl = Ustrchr(msg, '\n');
-  if (!nl)
+for (uschar * nl;;)
+  if (!(nl = Ustrchr(msg, '\n')))
     {
     smtp_printf("%.3s%c%.*s%s\r\n", !final, code, final ? ' ':'-', esclen, esc, msg);
     return;
@@ -2834,7 +2863,6 @@ for (;;)
     msg = nl + 1;
     Uskip_whitespace(&msg);
     }
-  }
 }
 
 
@@ -2936,7 +2964,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;
@@ -2953,7 +2981,8 @@ smtp_code = rc == FAIL ? acl_wherecodes[where] : US"451";
 smtp_message_code(&smtp_code, &codelen, &user_msg, &log_msg,
   where != ACL_WHERE_VRFY);
 
-/* We used to have sender_address here; however, there was a bug that was not
+/* Get info for logging.
+We used to have sender_address here; however, there was a bug that was not
 updating sender_address after a rewrite during a verify. When this bug was
 fixed, sender_address at this point became the rewritten address. I'm not sure
 this is what should be logged, so I've changed to logging the unrewritten
@@ -2976,9 +3005,9 @@ switch (where)
 
     if (where == ACL_WHERE_AUTH)       /* avoid logging auth creds */
       {
-      uschar * s;
-      for (s = smtp_cmd_data; *s && !isspace(*s); ) s++;
-      lim = s - smtp_cmd_data; /* atop after method */
+      uschar * s = smtp_cmd_data;
+      Uskip_nonwhite(&s);
+      lim = s - smtp_cmd_data; /* stop after method */
       }
     what = string_sprintf("%s %.*s", acl_wherenames[where], lim, place);
     }
@@ -3085,7 +3114,7 @@ else
 the connection is not forcibly to be dropped, return 0. Otherwise, log why it
 is closing if required and return 2.  */
 
-if (log_reject_target != 0)
+if (log_reject_target)
   {
 #ifndef DISABLE_TLS
   gstring * g = s_tlslog(NULL);
@@ -3176,6 +3205,7 @@ fl.smtp_exit_function_called = TRUE;
 
 /* Call the not-QUIT ACL, if there is one, unless no reason is given. */
 
+GET_OPTION("acl_smtp_notquit");
 if (acl_smtp_notquit && reason)
   {
   smtp_notquit_reason = reason;
@@ -3356,7 +3386,7 @@ Returns:       nothing
 */
 
 static void
-smtp_user_msg(uschar *code, uschar *user_msg)
+smtp_user_msg(uschar * code, uschar * user_msg)
 {
 int len = 3;
 smtp_message_code(&code, &len, &user_msg, NULL, TRUE);
@@ -3512,6 +3542,7 @@ smtp_quit_handler(uschar ** user_msgp, uschar ** log_msgp)
 HAD(SCH_QUIT);
 f.smtp_in_quit = TRUE;
 incomplete_transaction_log(US"QUIT");
+GET_OPTION("acl_smtp_quit");
 if (  acl_smtp_quit
    && acl_check(ACL_WHERE_QUIT, NULL, acl_smtp_quit, user_msgp, log_msgp)
        == ERROR)
@@ -3561,6 +3592,36 @@ if (chunking_state > CHUNKING_OFFERED)
 }
 
 
+#ifndef DISABLE_WELLKNOWN
+static int
+smtp_wellknown_handler(void)
+{
+if (verify_check_host(&wellknown_advertise_hosts) != FAIL)
+  {
+  GET_OPTION("acl_smtp_wellknown");
+  if (acl_smtp_wellknown)
+    {
+    uschar * user_msg = NULL, * log_msg;
+    int rc;
+
+    if ((rc = acl_check(ACL_WHERE_WELLKNOWN, NULL, acl_smtp_wellknown,
+               &user_msg, &log_msg)) != OK)
+      return smtp_handle_acl_fail(ACL_WHERE_WELLKNOWN, rc, user_msg, log_msg);
+    else if (!wellknown_response)
+      return smtp_handle_acl_fail(ACL_WHERE_WELLKNOWN, ERROR, user_msg, log_msg);
+    smtp_user_msg(US"250", wellknown_response);
+    return 0;
+    }
+  }
+
+smtp_printf("554 not permitted\r\n", SP_NO_MORE);
+log_write(0, LOG_MAIN|LOG_REJECT, "rejected \"%s\" from %s",
+             smtp_cmd_buffer, sender_helo_name, host_and_ident(FALSE));
+return 0;
+}
+#endif
+
+
 static int
 expand_mailmax(const uschar * s)
 {
@@ -3666,9 +3727,8 @@ while (done <= 0)
   void (*oldsignal)(int);
   pid_t pid;
   int start, end, sender_domain, recipient_domain;
-  int rc;
-  int c;
-  uschar *orcpt = NULL;
+  int rc, c;
+  uschar * orcpt = NULL;
   int dsn_flags;
   gstring * g;
 
@@ -3685,6 +3745,7 @@ while (done <= 0)
     for (auth_instance * au = auths; au; au = au->next)
       if (strcmpic(US"tls", au->driver_name) == 0)
        {
+       GET_OPTION("acl_smtp_auth");
        if (  acl_smtp_auth
           && (rc = acl_check(ACL_WHERE_AUTH, NULL, acl_smtp_auth,
                      &user_msg, &log_msg)) != OK
@@ -3763,6 +3824,7 @@ while (done <= 0)
 
       /* Check the ACL */
 
+      GET_OPTION("acl_smtp_auth");
       if (  acl_smtp_auth
         && (rc = acl_check(ACL_WHERE_AUTH, NULL, acl_smtp_auth,
                    &user_msg, &log_msg)) != OK
@@ -3788,8 +3850,8 @@ while (done <= 0)
 
       if (*smtp_cmd_data)
        {
-       *smtp_cmd_data++ = 0;
-       while (isspace(*smtp_cmd_data)) smtp_cmd_data++;
+       *smtp_cmd_data++ = '\0';
+       Uskip_whitespace(&smtp_cmd_data);
        }
 
       /* Search for an authentication mechanism which is configured for use
@@ -3900,10 +3962,10 @@ while (done <= 0)
       if (!f.sender_host_unknown)
        {
        BOOL old_helo_verified = f.helo_verified;
-       uschar *p = smtp_cmd_data;
+       uschar * p = smtp_cmd_data;
 
-       while (*p != 0 && !isspace(*p)) { *p = tolower(*p); p++; }
-       *p = 0;
+       while (*p && !isspace(*p)) { *p = tolower(*p); p++; }
+       *p = '\0';
 
        /* Force a reverse lookup if HELO quoted something in helo_lookup_domains
        because otherwise the log can be confusing. */
@@ -3957,6 +4019,7 @@ while (done <= 0)
       /* Apply an ACL check if one is defined; afterwards, recheck
       synchronization in case the client started sending in a delay. */
 
+      GET_OPTION("acl_smtp_helo");
       if (acl_smtp_helo)
        if ((rc = acl_check(ACL_WHERE_HELO, NULL, acl_smtp_helo,
                  &user_msg, &log_msg)) != OK)
@@ -4051,15 +4114,15 @@ while (done <= 0)
          g = string_catn(g, US"-SIZE\r\n", 7);
          }
 
-#ifdef EXPERIMENTAL_ESMTP_LIMITS
-       if (  (smtp_mailcmd_max > 0 || recipients_max)
+#ifndef DISABLE_ESMTP_LIMITS
+       if (  (smtp_mailcmd_max > 0 || recipients_max_expanded > 0)
           && verify_check_host(&limits_advertise_hosts) == OK)
          {
          g = string_fmt_append(g, "%.3s-LIMITS", smtp_code);
          if (smtp_mailcmd_max > 0)
            g = string_fmt_append(g, " MAILMAX=%d", smtp_mailcmd_max);
-         if (recipients_max)
-           g = string_fmt_append(g, " RCPTMAX=%d", recipients_max);
+         if (recipients_max_expanded > 0)
+           g = string_fmt_append(g, " RCPTMAX=%d", recipients_max_expanded);
          g = string_catn(g, US"\r\n", 2);
          }
 #endif
@@ -4088,16 +4151,19 @@ while (done <= 0)
        /* Advertise ETRN/VRFY/EXPN if there's are ACL checking whether a host is
        permitted to issue them; a check is made when any host actually tries. */
 
+       GET_OPTION("acl_smtp_etrn");
        if (acl_smtp_etrn)
          {
          g = string_catn(g, smtp_code, 3);
          g = string_catn(g, US"-ETRN\r\n", 7);
          }
+       GET_OPTION("acl_smtp_vrfy");
        if (acl_smtp_vrfy)
          {
          g = string_catn(g, smtp_code, 3);
          g = string_catn(g, US"-VRFY\r\n", 7);
          }
+       GET_OPTION("acl_smtp_expn");
        if (acl_smtp_expn)
          {
          g = string_catn(g, smtp_code, 3);
@@ -4187,12 +4253,12 @@ while (done <= 0)
          chunking_state = CHUNKING_OFFERED;
          }
 
+#ifndef DISABLE_TLS
        /* Advertise TLS (Transport Level Security) aka SSL (Secure Socket Layer)
        if it has been included in the binary, and the host matches
        tls_advertise_hosts. We must *not* advertise if we are already in a
        secure connection. */
 
-#ifndef DISABLE_TLS
        if (tls_in.active.sock < 0 &&
            verify_check_host(&tls_advertise_hosts) != FAIL)
          {
@@ -4226,6 +4292,13 @@ while (done <= 0)
          fl.smtputf8_advertised = TRUE;
          }
 #endif
+#ifndef DISABLE_WELLKNOWN
+       if (verify_check_host(&wellknown_advertise_hosts) != FAIL)
+         {
+         g = string_catn(g, smtp_code, 3);
+         g = string_catn(g, US"-WELLKNOWN\r\n", 12);
+         }
+#endif
 
        /* Finish off the multiline reply with one that is always available. */
 
@@ -4273,6 +4346,14 @@ while (done <= 0)
       toomany = FALSE;
       break;   /* HELO/EHLO */
 
+#ifndef DISABLE_WELLKNOWN
+    case WELLKNOWN_CMD:
+      HAD(SCH_WELLKNOWN);
+      smtp_mailcmd_count++;
+      smtp_wellknown_handler();
+      break;
+#endif
+
 #ifdef EXPERIMENTAL_XCLIENT
     case XCLIENT_CMD:
       {
@@ -4326,9 +4407,10 @@ while (done <= 0)
        if (  fl.helo_verify_required
           || verify_check_host(&hosts_require_helo) == OK)
          {
-         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));
+         done = synprot_error(L_smtp_protocol_error, 503, NULL,
+                     US"HELO or EHLO required");
          break;
          }
        else if (smtp_mailcmd_max < 0)
@@ -4493,6 +4575,7 @@ while (done <= 0)
                  US"invalid data for AUTH");
                goto COMMAND_LOOP;
                }
+             GET_OPTION("acl_smtp_mailauth");
              if (!acl_smtp_mailauth)
                {
                ignore_msg = US"client not authenticated";
@@ -4689,6 +4772,7 @@ while (done <= 0)
       when pipelining is not advertised, do another sync check in case the ACL
       delayed and the client started sending in the meantime. */
 
+      GET_OPTION("acl_smtp_mail");
       if (acl_smtp_mail)
        {
        rc = acl_check(ACL_WHERE_MAIL, NULL, acl_smtp_mail, &user_msg, &log_msg);
@@ -4897,7 +4981,8 @@ while (done <= 0)
 
       /* Check maximum allowed */
 
-      if (rcpt_count+1 < 0 || rcpt_count > recipients_max && recipients_max > 0)
+      if (  rcpt_count+1 < 0
+         || rcpt_count > recipients_max_expanded && recipients_max_expanded > 0)
        {
        if (recipients_max_reject)
          {
@@ -4943,10 +5028,13 @@ while (done <= 0)
       if (f.recipients_discarded)
        rc = DISCARD;
       else
+       {
+       GET_OPTION("acl_smtp_rcpt");
        if (  (rc = acl_check(ACL_WHERE_RCPT, recipient, acl_smtp_rcpt, &user_msg,
                      &log_msg)) == OK
           && !f.smtp_in_pipelining_advertised && !check_sync())
          goto SYNC_FAILURE;
+       }
 
       /* The ACL was happy */
 
@@ -5102,13 +5190,14 @@ while (done <= 0)
        }
 
       if (chunking_state > CHUNKING_OFFERED)
-       rc = OK;                        /* No predata ACL or go-ahead output for BDAT */
+       rc = OK;        /* There is no predata ACL or go-ahead output for BDAT */
       else
        {
-       /* If there is an ACL, re-check the synchronization afterwards, since the
-       ACL may have delayed.  To handle cutthrough delivery enforce a dummy call
-       to get the DATA command sent. */
+       /* If there is a predata-ACL, re-check the synchronization afterwards,
+       since the ACL may have delayed.  To handle cutthrough delivery enforce a
+       dummy call to get the DATA command sent. */
 
+       GET_OPTION("acl_smtp_predata");
        if (!acl_smtp_predata && cutthrough.cctx.sock < 0)
          rc = OK;
        else
@@ -5167,6 +5256,7 @@ while (done <= 0)
                                    US"verify")))
          break;
 
+      GET_OPTION("acl_smtp_vrfy");
       if ((rc = acl_check(ACL_WHERE_VRFY, address, acl_smtp_vrfy,
                    &user_msg, &log_msg)) != OK)
        done = smtp_handle_acl_fail(ACL_WHERE_VRFY, rc, user_msg, log_msg);
@@ -5205,6 +5295,7 @@ while (done <= 0)
 
     case EXPN_CMD:
       HAD(SCH_EXPN);
+      GET_OPTION("acl_smtp_expn");
       rc = acl_check(ACL_WHERE_EXPN, NULL, acl_smtp_expn, &user_msg, &log_msg);
       if (rc != OK)
        done = smtp_handle_acl_fail(ACL_WHERE_EXPN, rc, user_msg, log_msg);
@@ -5234,6 +5325,7 @@ while (done <= 0)
 
       /* Apply an ACL check if one is defined */
 
+      GET_OPTION("acl_smtp_starttls");
       if (  acl_smtp_starttls
         && (rc = acl_check(ACL_WHERE_STARTTLS, NULL, acl_smtp_starttls,
                    &user_msg, &log_msg)) != OK
@@ -5352,6 +5444,7 @@ while (done <= 0)
        case QUIT_CMD:
          f.smtp_in_quit = TRUE;
          user_msg = NULL;
+         GET_OPTION("acl_smtp_quit");
          if (  acl_smtp_quit
             && ((rc = acl_check(ACL_WHERE_QUIT, NULL, acl_smtp_quit, &user_msg,
                                &log_msg)) == ERROR))
@@ -5417,6 +5510,10 @@ while (done <= 0)
       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);
+#ifndef DISABLE_WELLKNOWN
+      if (verify_check_host(&wellknown_advertise_hosts) != FAIL)
+       smtp_printf(" WELLKNOWN", SP_MORE);
+#endif
 #ifdef EXPERIMENTAL_XCLIENT
       if (proxy_session || verify_check_host(&hosts_xclient) != FAIL)
        smtp_printf(" XCLIENT", SP_MORE);
@@ -5471,6 +5568,7 @@ while (done <= 0)
       log_write(L_etrn, LOG_MAIN, "ETRN %s received from %s", smtp_cmd_argument,
        host_and_ident(FALSE));
 
+      GET_OPTION("acl_smtp_etrn");
       if ((rc = acl_check(ACL_WHERE_ETRN, NULL, acl_smtp_etrn,
                  &user_msg, &log_msg)) != OK)
        {
@@ -5487,6 +5585,7 @@ while (done <= 0)
       since that is strictly the only kind of ETRN that can be implemented
       according to the RFC. */
 
+      GET_OPTION("smtp_etrn_command");
       if (smtp_etrn_command)
        {
        uschar *error;
@@ -5658,7 +5757,7 @@ while (done <= 0)
 
     case TOO_MANY_NONMAIL_CMD:
       s = smtp_cmd_buffer;
-      while (*s && !isspace(*s)) s++;
+      Uskip_nonwhite(&s);
       incomplete_transaction_log(US"too many non-mail commands");
       log_write(0, LOG_MAIN|LOG_REJECT, "SMTP call from %s dropped: too many "
        "nonmail commands (last was \"%.*s\")",  host_and_ident(FALSE),