[exim-dev] message_linecount

Top Page
Delete this message
Reply to this message
Author: Tony Finch
Date:  
To: exim-dev
Subject: [exim-dev] message_linecount
The following patch makes the message_linecount available as an expansion
variable. This allows slightly more flexibility in protecting against
abusive messages (e.g. excessively long headers). The header_maxsize and
header_line_maxsize settings only restrict the aggregate size rather than
the number of lines, but it's often the number of lines that may cause
problems for other software. You can now write:

  deny
    message        = Too many lines in message header
    condition      = ${if <{250}{${eval: $message_linecount - $body_linecount }} }


  deny
    message        = Too many short lines in message body
    condition      = ${if and{{ <{100000}{$body_linecount} } \
                              { >{30}{${eval: $message_body_size / $body_linecount }} }} }


In order for the message_linecount to be useful in the ACLs, it must
actually be computed when receiving a message. In the current Exim code
it's only computed after re-reading a spool file for delivery, when it is
used for computing the SIZE= SMTP envelope parameter.


--- expand.c    22 Mar 2005 16:52:06 -0000      1.18
+++ expand.c    11 Apr 2005 16:57:38 -0000
@@ -394,6 +394,7 @@
   { "message_body_size",   vtype_int,         &message_body_size },
   { "message_headers",     vtype_msgheaders,  NULL },
   { "message_id",          vtype_stringptr,   &message_id },
+  { "message_linecount",   vtype_int,         &message_linecount },
   { "message_size",        vtype_int,         &message_size },
 #ifdef WITH_CONTENT_SCAN
   { "mime_anomaly_level",  vtype_int,         &mime_anomaly_level },
--- receive.c   7 Apr 2005 15:40:50 -0000       1.15
+++ receive.c   11 Apr 2005 16:57:38 -0000
@@ -1339,11 +1339,9 @@


if (thismessage_size_limit <= 0) thismessage_size_limit = INT_MAX;

-/* While reading the message, body_linecount and body_zerocount is computed.
-The full message_ linecount is set up only when the headers are read back in
-from the spool for delivery. */
+/* While reading the message, the following counts are computed. */

-body_linecount = body_zerocount = 0;
+message_linecount = body_linecount = body_zerocount = 0;

#ifdef EXPERIMENTAL_DOMAINKEYS
/* Call into DK to set up the context. Check if DK is to be run are
carried out
@@ -1573,7 +1571,9 @@
/* End of header line reached */

   EOL:
-  receive_linecount++;          /* For BSMTP errors */
+  /* Keep track of lines for BSMTP errors and overall message_linecount. */
+  receive_linecount++;
+  message_linecount++;


/* Now put in the terminating newline. There is always space for
at least two more characters. */
@@ -2633,6 +2633,7 @@
else message_ended = read_message_data(data_file);

receive_linecount += body_linecount; /* For BSMTP errors mainly */
+ message_linecount += body_linecount;

/* Handle premature termination of SMTP */

--- smtp_in.c   29 Mar 2005 15:53:12 -0000      1.15
+++ smtp_in.c   11 Apr 2005 16:57:38 -0000
@@ -804,6 +804,7 @@
 recipients_list = NULL;
 rcpt_count = rcpt_defer_count = rcpt_fail_count =
   raw_recipients_count = recipients_count = recipients_list_max = 0;
+message_linecount = 0;
 message_size = -1;
 acl_warn_headers = NULL;
 queue_only_policy = FALSE;



Tony.
--
<fanf@???> <dot@???> http://dotat.at/ ${sg{\N${sg{\
N\}{([^N]*)(.)(.)(.*)}{\$1\$3\$2\$1\$3\n\$2\$3\$4\$3\n\$3\$2\$4}}\
\N}{([^N]*)(.)(.)(.*)}{\$1\$3\$2\$1\$3\n\$2\$3\$4\$3\n\$3\$2\$4}}