if (rc < 0) return TRUE; /* End of file or error */
smtp_ungetc(rc);
-rc = smtp_inend - smtp_inptr;
-if (rc > 150) rc = 150;
-smtp_inptr[rc] = 0;
return FALSE;
}
static BOOL
check_sync(void)
{
-if (!smtp_enforce_sync || sender_host_address == NULL || sender_host_notsocket)
+if (!smtp_enforce_sync || !sender_host_address || sender_host_notsocket)
return TRUE;
return wouldblock_reading();
fflush(smtp_out);
if (smtp_receive_timeout > 0) alarm(smtp_receive_timeout);
-/* Limit amount read, so non-message data is not fed to DKIM */
+/* Limit amount read, so non-message data is not fed to DKIM.
+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, lim));
+rc = read(fileno(smtp_in), smtp_inbuffer, MIN(IN_BUFFER_SIZE-1, lim));
save_errno = errno;
if (smtp_receive_timeout > 0) alarm(0);
if (rc <= 0)
for(;;)
{
#ifndef DISABLE_DKIM
- BOOL dkim_save;
+ unsigned dkim_save;
#endif
if (chunking_data_left > 0)
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
/* Enforce synchronization for unknown commands */
-if (smtp_inptr < smtp_inend && /* Outstanding input */
- check_sync && /* Local flag set */
- smtp_enforce_sync && /* Global flag set */
- sender_host_address != NULL && /* Not local input */
- !sender_host_notsocket) /* Really is a socket */
+if ( smtp_inptr < smtp_inend /* Outstanding input */
+ && check_sync /* Local flag set */
+ && smtp_enforce_sync /* Global flag set */
+ && sender_host_address /* Not local input */
+ && !sender_host_notsocket) /* Really is a socket */
return BADSYN_CMD;
return OTHER_CMD;
sending_ip_address = NULL;
return_path = sender_address = NULL;
sender_data = NULL; /* Can be set by ACL */
-deliver_localpart_orig = NULL;
-deliver_domain_orig = NULL;
+deliver_localpart_parent = deliver_localpart_orig = NULL;
+deliver_domain_parent = deliver_domain_orig = NULL;
callout_address = NULL;
submission_name = NULL; /* Can be set by ACL */
raw_sender = NULL; /* After SMTP rewrite, before qualifying */
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 = NULL;
-dkim_disable_verify = dkim_collect_input = FALSE;
+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 = 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_domain_policy = dmarc_forensic_sender =
+dmarc_history_file = dmarc_status = dmarc_status_text = dmarc_tld_file =
+dmarc_used_domain = NULL;
+#endif
+#ifdef EXPERIMENTAL_ARC
+arc_state = arc_state_reason = NULL;
#endif
dsn_ret = 0;
dsn_envid = NULL;
#ifndef DISABLE_PRDR
prdr_requested = FALSE;
#endif
-#ifdef SUPPORT_SPF
-spf_header_comment = spf_received = spf_result = spf_smtp_comment = NULL;
-#endif
-#ifdef EXPERIMENTAL_ARC
-arc_state = arc_state_reason = NULL;
-#endif
#ifdef SUPPORT_I18N
message_smtputf8 = FALSE;
#endif
(sender_host_address ? protocols : protocols_local) [pnormal];
/* Set up the buffer for inputting using direct read() calls, and arrange to
-call the local functions instead of the standard C ones. */
+call the local functions instead of the standard C ones. Place a NUL at the
+end of the buffer to safety-stop C-string reads from it. */
if (!(smtp_inbuffer = US malloc(IN_BUFFER_SIZE)))
log_write(0, LOG_MAIN|LOG_PANIC_DIE, "malloc() failed for SMTP input buffer");
+smtp_inbuffer[IN_BUFFER_SIZE-1] = '\0';
receive_getc = smtp_getc;
receive_getbuf = smtp_getbuf;
case BADCHAR_CMD:
done = synprot_error(L_smtp_syntax_error, 0, NULL, /* Just logs */
- US"NULL character(s) present (shown as '?')");
- smtp_printf("501 NULL characters are not allowed in SMTP commands\r\n", FALSE);
+ US"NUL character(s) present (shown as '?')");
+ smtp_printf("501 NUL characters are not allowed in SMTP commands\r\n", FALSE);
break;
if (smtp_inend >= smtp_inbuffer + IN_BUFFER_SIZE)
smtp_inend = smtp_inbuffer + IN_BUFFER_SIZE - 1;
c = smtp_inend - smtp_inptr;
- if (c > 150) c = 150;
+ if (c > 150) c = 150; /* limit logged amount */
smtp_inptr[c] = 0;
incomplete_transaction_log(US"sync failure");
log_write(0, LOG_MAIN|LOG_REJECT, "SMTP protocol synchronization error "