Re: [Exim] Cyrus NUL problem

Top Page
Delete this message
Reply to this message
Author: Philip Chambers
Date:  
To: exim-users
Subject: Re: [Exim] Cyrus NUL problem
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