Fix dkim_verify_signers option. Bug 2366
[exim.git] / src / src / smtp_in.c
index 2d213305ece036b724da3c186a00327e6ce7c961..2a933b82f42da35caa07698b614eb5490f835880 100644 (file)
@@ -424,6 +424,53 @@ log_write(L_smtp_incomplete_transaction, LOG_MAIN|LOG_SENDER|LOG_RECIPIENTS,
 
 
 
+void
+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));
+if (smtp_batched_input)
+  moan_smtp_batch(NULL, "421 SMTP command timeout"); /* Does not return */
+smtp_notquit_exit(US"command-timeout", US"421",
+  US"%s: SMTP command timeout - closing connection",
+  smtp_active_hostname);
+exim_exit(EXIT_FAILURE, US"receiving");
+}
+
+void
+smtp_command_sigterm_exit(void)
+{
+log_write(0, LOG_MAIN, "%s closed after SIGTERM", smtp_get_connection_info());
+if (smtp_batched_input)
+  moan_smtp_batch(NULL, "421 SIGTERM received");  /* Does not return */
+smtp_notquit_exit(US"signal-exit", US"421",
+  US"%s: Service not available - closing connection", smtp_active_hostname);
+exim_exit(EXIT_FAILURE, US"receiving");
+}
+
+void
+smtp_data_timeout_exit(void)
+{
+log_write(L_lost_incoming_connection,
+  LOG_MAIN, "SMTP data timeout (message abandoned) on connection from %s F=<%s>",
+  sender_fullhost ? sender_fullhost : US"local process", sender_address);
+receive_bomb_out(US"data-timeout", US"SMTP incoming data timeout");
+/* Does not return */
+}
+
+void
+smtp_data_sigint_exit(void)
+{
+log_write(0, LOG_MAIN, "%s closed after %s",
+  smtp_get_connection_info(), had_data_sigint == SIGTERM ? "SIGTERM":"SIGINT");
+receive_bomb_out(US"signal-exit",
+  US"Service not available - SIGTERM or SIGINT received");
+/* Does not return */
+}
+
+
+
 /* Refill the buffer, and notify DKIM verification code.
 Return false for error or EOF.
 */
@@ -441,18 +488,28 @@ Take care to not touch the safety NUL at the end of the buffer. */
 
 rc = read(fileno(smtp_in), smtp_inbuffer, MIN(IN_BUFFER_SIZE-1, lim));
 save_errno = errno;
-alarm(0);
+if (smtp_receive_timeout > 0) alarm(0);
 if (rc <= 0)
   {
   /* Must put the error text in fixed store, because this might be during
   header reading, where it releases unused store above the header. */
   if (rc < 0)
     {
+    if (had_command_timeout)           /* set by signal handler */
+      smtp_command_timeout_exit();     /* does not return */
+    if (had_command_sigterm)
+      smtp_command_sigterm_exit();
+    if (had_data_timeout)
+      smtp_data_timeout_exit();
+    if (had_data_sigint)
+      smtp_data_sigint_exit();
+
     smtp_had_error = save_errno;
     smtp_read_error = string_copy_malloc(
       string_sprintf(" (error: %s)", strerror(save_errno)));
     }
-  else smtp_had_eof = 1;
+  else
+    smtp_had_eof = 1;
   return FALSE;
   }
 #ifndef DISABLE_DKIM
@@ -538,7 +595,7 @@ uschar * log_msg;
 for(;;)
   {
 #ifndef DISABLE_DKIM
-  BOOL dkim_save;
+  unsigned dkim_save;
 #endif
 
   if (chunking_data_left > 0)
@@ -549,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
@@ -914,16 +971,7 @@ Returns:  nothing
 static void
 command_timeout_handler(int sig)
 {
-sig = sig;    /* Keep picky compilers happy */
-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));
-if (smtp_batched_input)
-  moan_smtp_batch(NULL, "421 SMTP command timeout");  /* Does not return */
-smtp_notquit_exit(US"command-timeout", US"421",
-  US"%s: SMTP command timeout - closing connection", smtp_active_hostname);
-exim_exit(EXIT_FAILURE, US"receiving");
+had_command_timeout = sig;
 }
 
 
@@ -941,13 +989,7 @@ Returns:  nothing
 static void
 command_sigterm_handler(int sig)
 {
-sig = sig;    /* Keep picky compilers happy */
-log_write(0, LOG_MAIN, "%s closed after SIGTERM", smtp_get_connection_info());
-if (smtp_batched_input)
-  moan_smtp_batch(NULL, "421 SIGTERM received");  /* Does not return */
-smtp_notquit_exit(US"signal-exit", US"421",
-  US"%s: Service not available - closing connection", smtp_active_hostname);
-exim_exit(EXIT_FAILURE, US"receiving");
+had_command_sigterm = sig;
 }
 
 
@@ -1507,6 +1549,7 @@ int ptr = 0;
 smtp_cmd_list *p;
 BOOL hadnull = FALSE;
 
+had_command_timeout = 0;
 os_non_restarting_signal(SIGALRM, command_timeout_handler);
 
 while ((c = (receive_getc)(buffer_lim)) != '\n' && c != EOF)
@@ -1995,8 +2038,13 @@ bmi_verdicts = NULL;
 #endif
 dnslist_domain = dnslist_matched = NULL;
 #ifndef DISABLE_DKIM
-dkim_cur_signer = dkim_signers = NULL;
-dkim_disable_verify = dkim_collect_input = FALSE;
+dkim_cur_signer = dkim_signers =
+dkim_signing_domain = dkim_signing_selector = NULL;
+dkim_cur_signer = dkim_signers = dkim_signing_domain = dkim_signing_selector = NULL;
+dkim_disable_verify = FALSE;
+dkim_collect_input = 0;
+dkim_verify_overall = dkim_verify_status = dkim_verify_reason = NULL;
+dkim_key_length = 0;
 #endif
 dsn_ret = 0;
 dsn_envid = NULL;
@@ -2006,6 +2054,11 @@ 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;
@@ -3801,6 +3854,7 @@ cmd_list[CMD_LIST_STARTTLS].is_mail_cmd = TRUE;
 
 /* Set the local signal handler for SIGTERM - it tries to end off tidily */
 
+had_command_sigterm = 0;
 os_non_restarting_signal(SIGTERM, command_sigterm_handler);
 
 /* Batched SMTP is handled in a different function. */
@@ -4041,11 +4095,10 @@ while (done <= 0)
       /* Force a reverse lookup if HELO quoted something in helo_lookup_domains
       because otherwise the log can be confusing. */
 
-      if (  !sender_host_name
-         && (deliver_domain = sender_helo_name,  /* set $domain */
-             match_isinlist(sender_helo_name, CUSS &helo_lookup_domains, 0,
-              &domainlist_anchor, NULL, MCL_DOMAIN, TRUE, NULL)) == OK)
-        (void)host_name_lookup();
+       if (  !sender_host_name
+          && match_isinlist(sender_helo_name, CUSS &helo_lookup_domains, 0,
+               &domainlist_anchor, NULL, MCL_DOMAIN, TRUE, NULL) == OK)
+         (void)host_name_lookup();
 
       /* Rebuild the fullhost info to include the HELO name (and the real name
       if it was looked up.) */
@@ -4615,13 +4668,15 @@ while (done <= 0)
         case ENV_MAIL_OPT_UTF8:
          if (smtputf8_advertised)
            {
-           int old_pool = store_pool;
-
            DEBUG(D_receive) debug_printf("smtputf8 requested\n");
            message_smtputf8 = allow_utf8_domains = TRUE;
-           store_pool = POOL_PERM;
-           received_protocol = string_sprintf("utf8%s", received_protocol);
-           store_pool = old_pool;
+           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;
+             }
            }
          break;
 #endif