I18N: reject SMTPUTF8 MAIL command when facility not advertised
[exim.git] / src / src / smtp_in.c
index 08de923ebe3ebc346d50be760ec2cbd51e20e232..ff0f6acaac71d15cff1c8a0212648fc6df4e0db8 100644 (file)
@@ -340,7 +340,7 @@ fd_set fds;
 struct timeval tzero;
 
 #ifdef SUPPORT_TLS
-if (tls_in.active >= 0)
+if (tls_in.active.sock >= 0)
  return !tls_could_read();
 #endif
 
@@ -429,7 +429,7 @@ smtp_command_timeout_exit(void)
 {
 log_write(L_lost_incoming_connection,
          LOG_MAIN, "SMTP command timeout on%s connection from %s",
-         tls_in.active >= 0 ? " TLS" : "", host_and_ident(FALSE));
+         tls_in.active.sock >= 0 ? " TLS" : "", host_and_ident(FALSE));
 if (smtp_batched_input)
   moan_smtp_batch(NULL, "421 SMTP command timeout"); /* Does not return */
 smtp_notquit_exit(US"command-timeout", US"421",
@@ -595,7 +595,7 @@ uschar * log_msg;
 for(;;)
   {
 #ifndef DISABLE_DKIM
-  BOOL dkim_save;
+  unsigned dkim_save;
 #endif
 
   if (chunking_data_left > 0)
@@ -606,7 +606,7 @@ for(;;)
   receive_ungetc = lwr_receive_ungetc;
 #ifndef DISABLE_DKIM
   dkim_save = dkim_collect_input;
-  dkim_collect_input = FALSE;
+  dkim_collect_input = 0;
 #endif
 
   /* Unless PIPELINING was offered, there should be no next command
@@ -922,9 +922,9 @@ if (rcpt_in_progress)
 /* Now write the string */
 
 #ifdef SUPPORT_TLS
-if (tls_in.active >= 0)
+if (tls_in.active.sock >= 0)
   {
-  if (tls_write(TRUE, big_buffer, Ustrlen(big_buffer), more) < 0)
+  if (tls_write(NULL, big_buffer, Ustrlen(big_buffer), more) < 0)
     smtp_write_error = -1;
   }
 else
@@ -951,7 +951,7 @@ Returns:    0 for no error; -1 after an error
 int
 smtp_fflush(void)
 {
-if (tls_in.active < 0 && fflush(smtp_out) != 0) smtp_write_error = -1;
+if (tls_in.active.sock < 0 && fflush(smtp_out) != 0) smtp_write_error = -1;
 return smtp_write_error;
 }
 
@@ -2037,26 +2037,27 @@ bmi_run = 0;
 bmi_verdicts = NULL;
 #endif
 dnslist_domain = dnslist_matched = NULL;
+#ifdef SUPPORT_SPF
+spf_header_comment = spf_received = spf_result = spf_smtp_comment = NULL;
+spf_result_guessed = FALSE;
+#endif
 #ifndef DISABLE_DKIM
 dkim_cur_signer = dkim_signers =
 dkim_signing_domain = dkim_signing_selector = dkim_signatures = NULL;
 dkim_cur_signer = dkim_signers = dkim_signing_domain = dkim_signing_selector = NULL;
-dkim_disable_verify = dkim_collect_input = FALSE;
+dkim_disable_verify = FALSE;
+dkim_collect_input = 0;
 dkim_verify_overall = dkim_verify_status = dkim_verify_reason = NULL;
 dkim_key_length = 0;
 dkim_verify_signers = US"$dkim_signers";
 #endif
 #ifdef EXPERIMENTAL_DMARC
 dmarc_has_been_checked = dmarc_disable_verify = dmarc_enable_forensic = FALSE;
-dmarc_ar_header = dmarc_domain_policy = dmarc_forensic_sender =
-dmarc_history_file = dmarc_status = dmarc_status_text = dmarc_tld_file =
+dmarc_domain_policy = dmarc_status = dmarc_status_text =
 dmarc_used_domain = NULL;
 #endif
-#ifdef EXPERIMENTAL_DMARC
-dmarc_has_been_checked = dmarc_disable_verify = dmarc_enable_forensic = FALSE;
-dmarc_ar_header = dmarc_domain_policy = dmarc_forensic_sender =
-dmarc_history_file = dmarc_status = dmarc_status_text = dmarc_tld_file =
-dmarc_used_domain = NULL;
+#ifdef EXPERIMENTAL_ARC
+arc_state = arc_state_reason = NULL;
 #endif
 dsn_ret = 0;
 dsn_envid = NULL;
@@ -2064,17 +2065,6 @@ deliver_host = deliver_host_address = NULL;      /* Can be set by ACL */
 #ifndef DISABLE_PRDR
 prdr_requested = FALSE;
 #endif
-#ifdef SUPPORT_SPF
-spf_header_comment = spf_received = spf_result = spf_smtp_comment = NULL;
-spf_result_guessed = FALSE;
-#endif
-#ifdef EXPERIMENTAL_DMARC
-dmarc_has_been_checked = dmarc_disable_verify = dmarc_enable_forensic = FALSE;
-dmarc_domain_policy = dmarc_status = dmarc_status_text = dmarc_used_domain = NULL;
-#endif
-#ifdef EXPERIMENTAL_ARC
-arc_state = arc_state_reason = NULL;
-#endif
 #ifdef SUPPORT_I18N
 message_smtputf8 = FALSE;
 #endif
@@ -3696,7 +3686,7 @@ switch(rc)
 
     received_protocol =
       (sender_host_address ? protocols : protocols_local)
-       [pextend + pauthed + (tls_in.active >= 0 ? pcrpted:0)];
+       [pextend + pauthed + (tls_in.active.sock >= 0 ? pcrpted:0)];
     *s = *ss = US"235 Authentication succeeded";
     authenticated_by = au;
     break;
@@ -3790,7 +3780,7 @@ else
   smtp_printf("221 %s closing connection\r\n", FALSE, smtp_active_hostname);
 
 #ifdef SUPPORT_TLS
-tls_close(TRUE, TLS_SHUTDOWN_NOWAIT);
+tls_close(NULL, TLS_SHUTDOWN_NOWAIT);
 #endif
 
 log_write(L_smtp_connection, LOG_MAIN, "%s closed by QUIT",
@@ -3901,7 +3891,7 @@ while (done <= 0)
 
 #ifdef AUTH_TLS
   /* Check once per STARTTLS or SSL-on-connect for a TLS AUTH */
-  if (  tls_in.active >= 0
+  if (  tls_in.active.sock >= 0
      && tls_in.peercert
      && tls_in.certificate_verified
      && cmd_list[CMD_LIST_TLS_AUTH].is_mail_cmd
@@ -4118,7 +4108,7 @@ while (done <= 0)
 
       host_build_sender_fullhost();  /* Rebuild */
       set_process_info("handling%s incoming connection from %s",
-        (tls_in.active >= 0)? " TLS" : "", host_and_ident(FALSE));
+        (tls_in.active.sock >= 0)? " TLS" : "", host_and_ident(FALSE));
 
       /* Verify if configured. This doesn't give much security, but it does
       make some people happy to be able to do it. If helo_required is set,
@@ -4374,7 +4364,7 @@ while (done <= 0)
       secure connection. */
 
 #ifdef SUPPORT_TLS
-      if (tls_in.active < 0 &&
+      if (tls_in.active.sock < 0 &&
           verify_check_host(&tls_advertise_hosts) != FAIL)
         {
         g = string_catn(g, smtp_code, 3);
@@ -4412,7 +4402,7 @@ while (done <= 0)
     has been seen. */
 
 #ifdef SUPPORT_TLS
-    if (tls_in.active >= 0) (void)tls_write(TRUE, g->s, g->ptr, FALSE); else
+    if (tls_in.active.sock >= 0) (void)tls_write(NULL, g->s, g->ptr, FALSE); else
 #endif
 
       {
@@ -4435,7 +4425,7 @@ while (done <= 0)
        [ (esmtp
          ? pextend + (sender_host_authenticated ? pauthed : 0)
          : pnormal)
-       + (tls_in.active >= 0 ? pcrpted : 0)
+       + (tls_in.active.sock >= 0 ? pcrpted : 0)
        ];
     cancel_cutthrough_connection(TRUE, US"sent EHLO response");
     smtp_reset(reset_point);
@@ -4590,7 +4580,7 @@ while (done <= 0)
           if (dsn_advertised)
            {
             /* Check if the dsn envid has been already set */
-            if (dsn_envid != NULL)
+            if (dsn_envid)
              {
               synprot_error(L_smtp_syntax_error, 501, NULL,
                 US"ENVID can be specified once only");
@@ -4679,12 +4669,18 @@ while (done <= 0)
 
 #ifdef SUPPORT_I18N
         case ENV_MAIL_OPT_UTF8:
-         if (smtputf8_advertised)
+         if (!smtputf8_advertised)
            {
-           int old_pool = store_pool;
+           synprot_error(L_smtp_syntax_error, 501, NULL,
+             US"SMTPUTF8 used when not advertised");
+           goto COMMAND_LOOP;
+           }
 
-           DEBUG(D_receive) debug_printf("smtputf8 requested\n");
-           message_smtputf8 = allow_utf8_domains = TRUE;
+         DEBUG(D_receive) debug_printf("smtputf8 requested\n");
+         message_smtputf8 = allow_utf8_domains = TRUE;
+         if (Ustrncmp(received_protocol, US"utf8", 4) != 0)
+           {
+           int old_pool = store_pool;
            store_pool = POOL_PERM;
            received_protocol = string_sprintf("utf8%s", received_protocol);
            store_pool = old_pool;
@@ -5223,7 +5219,7 @@ while (done <= 0)
       ACL may have delayed.  To handle cutthrough delivery enforce a dummy call
       to get the DATA command sent. */
 
-      if (acl_smtp_predata == NULL && cutthrough.fd < 0)
+      if (acl_smtp_predata == NULL && cutthrough.cctx.sock < 0)
        rc = OK;
       else
        {
@@ -5377,7 +5373,7 @@ while (done <= 0)
       {
       DEBUG(D_any)
         debug_printf("Non-empty input buffer after STARTTLS; naive attack?\n");
-      if (tls_in.active < 0)
+      if (tls_in.active.sock < 0)
         smtp_inend = smtp_inptr = smtp_inbuffer;
       /* and if TLS is already active, tls_server_start() should fail */
       }
@@ -5420,7 +5416,7 @@ while (done <= 0)
          [ (esmtp
            ? pextend + (sender_host_authenticated ? pauthed : 0)
            : pnormal)
-         + (tls_in.active >= 0 ? pcrpted : 0)
+         + (tls_in.active.sock >= 0 ? pcrpted : 0)
          ];
 
       sender_host_auth_pubname = sender_host_authenticated = NULL;
@@ -5480,7 +5476,7 @@ while (done <= 0)
        smtp_printf("554 Security failure\r\n", FALSE);
        break;
       }
-    tls_close(TRUE, TLS_SHUTDOWN_NOWAIT);
+    tls_close(NULL, TLS_SHUTDOWN_NOWAIT);
     break;
     #endif
 
@@ -5522,7 +5518,7 @@ while (done <= 0)
       buffer[0] = 0;
       Ustrcat(buffer, " AUTH");
       #ifdef SUPPORT_TLS
-      if (tls_in.active < 0 &&
+      if (tls_in.active.sock < 0 &&
           verify_check_host(&tls_advertise_hosts) != FAIL)
         Ustrcat(buffer, " STARTTLS");
       #endif