On Wed, 30 Jun 2004 09:39:35 +0100 (BST) Philip Hazel <ph10@???> wrote:
> On Fri, 25 Jun 2004, Philip Chambers wrote:
>
> > I know Exim was written to be 8 bit clean, but is there any chance of a "reject-nul"
> > configuration option for thos of us who use Cyrus?
>
> Noted.
>
Thanks for putting it on the wish-list.
Working on the principle that you are more likely to implemet a wish-list item if
the code-changes are already available, I submit a patch which I have prepared
(version 3.34) and tested. It is now working on my live systems.
Phil.
---------------------------------------
Phil Chambers (postmaster@???)
University of Exeter
smtp_reject_nul patch for exim-3.34:
--- macros.h.orig Fri Jul 2 14:48:01 2004
+++ macros.h Fri Jul 2 15:24:32 2004
@@ -265,6 +265,7 @@
#define END_NOTENDED 3 /* Message reading not yet ended */
#define END_SIZE 4 /* Reading ended because message too big */
#define END_WERROR 5 /* Write error while reading the message */
+#define END_NUL 6 /* NUL character detected in DATA input */
/* Options bits for debugging; D_v and D_local_scan are also in local_scan.h */
@@ -343,6 +344,7 @@
#define L_smtp_incomplete_transaction 0x00002000
#define L_smtp_protocol_error 0x00004000
#define L_smtp_syntax_error 0x00008000
+#define L_smtp_reject_nul 0x00010000
#define LX_arguments 0x80000001
#define LX_deliver_time 0x80000002
@@ -372,7 +374,8 @@
L_queue_run | \
L_retry_defer | \
L_size_reject | \
- L_skip_delivery)
+ L_skip_delivery | \
+ L_smtp_reject_nul)
#define LX_default ((LX_rejected_header | \
LX_tls_cipher) & 0x7fffffff)
--- globals.h.orig Fri Jul 2 14:47:43 2004
+++ globals.h Fri Jul 2 14:51:30 2004
@@ -523,6 +523,7 @@
extern uschar *smtp_ratelimit_rcpt; /* Parameters for RCPT limiting */
extern uschar *smtp_read_error; /* Message for SMTP input error */
extern int smtp_receive_timeout; /* Applies to each received line */
+extern BOOL smtp_reject_nul; /* Applies SMTP DATA input */
extern uschar *smtp_reserve_hosts; /* Hosts for reserved slots */
extern BOOL smtp_return_error_details; /* TRUE to return full info */
extern int smtp_rlm_base; /* Base interval for MAIL rate limit */
--- globals.c.orig Fri Jul 2 14:48:10 2004
+++ globals.c Fri Jul 2 15:26:47 2004
@@ -590,6 +590,7 @@
{ US"smtp_connection", L_smtp_connection },
{ US"smtp_incomplete_transaction", L_smtp_incomplete_transaction },
{ US"smtp_protocol_error", L_smtp_protocol_error },
+ { US"smtp_reject_nul", L_smtp_reject_nul },
{ US"smtp_syntax_error", L_smtp_syntax_error },
{ US"subject", LX_subject },
{ US"tls_certificate_verified", LX_tls_certificate_verified },
@@ -895,6 +896,7 @@
uschar *smtp_ratelimit_rcpt = NULL;
uschar *smtp_read_error = US"";
int smtp_receive_timeout = 5*60;
+BOOL smtp_reject_nul = FALSE;
uschar *smtp_reserve_hosts = NULL;
BOOL smtp_return_error_details = FALSE;
int smtp_rlm_base = 0;
--- readconf.c.orig Fri Jul 2 14:47:24 2004
+++ readconf.c Fri Jul 2 14:50:16 2004
@@ -310,6 +310,7 @@
{ "smtp_ratelimit_mail", opt_stringptr, &smtp_ratelimit_mail },
{ "smtp_ratelimit_rcpt", opt_stringptr, &smtp_ratelimit_rcpt },
{ "smtp_receive_timeout", opt_time, &smtp_receive_timeout },
+ { "smtp_reject_nul", opt_bool, &smtp_reject_nul },
{ "smtp_reserve_hosts", opt_stringptr, &smtp_reserve_hosts },
{ "smtp_return_error_details",opt_bool, &smtp_return_error_details },
{ "split_spool_directory", opt_bool, &split_spool_directory },
--- receive.c.orig Fri Jul 2 14:48:21 2004
+++ receive.c Tue Jul 6 17:28:21 2004
@@ -622,6 +622,9 @@
while ((ch = (receive_getc)()) != EOF)
{
+ /* check if we should reject NUL in data */
+ if(ch == 0 && fout != NULL && smtp_reject_nul) return END_NUL;
+
switch (ch_state)
{
case 0: /* After LF or CRLF */
@@ -2284,6 +2287,25 @@
smtp_reply = handle_lost_connection(US"");
smtp_yield = FALSE;
goto TIDYUP; /* Skip to end of function */
+ }
+
+ /* Handle NUL in DATA input */
+
+ else if (smtp_input && message_ended == END_NUL)
+ {
+ Uunlink(spool_name); /* Lose the data file when closed */
+ receive_swallow_smtp(); /* Swallow incoming SMTP */
+
+ log_write(L_smtp_reject_nul, LOG_MAIN|LOG_REJECT, "rejected from <%s>%s%s%s%s: "
+ "NUL character in message (size %d)", sender_address,
+ (sender_fullhost == NULL)? "" : " H=",
+ (sender_fullhost == NULL)? US"" : sender_fullhost,
+ (sender_ident == NULL)? "" : " U=",
+ (sender_ident == NULL)? US"" : sender_ident,
+ message_size);
+ smtp_reply = US"554 Message contained a NUL character";
+ message_id[0] = 0; /* Indicate no message accepted */
+ goto TIDYUP; /* Skip to end of function */
}
/* Handle message that is too big. Don't use host_or_ident() in the log