more W.I.P
authorTom Kistner <tom@duncanthrax.net>
Thu, 2 Dec 2004 09:15:11 +0000 (09:15 +0000)
committerTom Kistner <tom@duncanthrax.net>
Thu, 2 Dec 2004 09:15:11 +0000 (09:15 +0000)
16 files changed:
src/exim_monitor/em_globals.c
src/src/EDITME
src/src/config.h.defaults
src/src/exim.c
src/src/expand.c
src/src/functions.h
src/src/globals.c
src/src/globals.h
src/src/header.c
src/src/local_scan.h
src/src/macros.h
src/src/readconf.c
src/src/receive.c
src/src/smtp_in.c
src/src/spool_in.c
src/src/spool_out.c

index ae38e9f8a81cf34394f724c58aa45c814ecb18dd..a0b28136d196ce488bab9025ab83db036d352bb8 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/exim_monitor/em_globals.c,v 1.1 2004/10/07 10:39:01 ph10 Exp $ */
+/* $Cambridge: exim/src/exim_monitor/em_globals.c,v 1.1.2.1 2004/12/02 09:15:11 tom Exp $ */
 
 /*************************************************
 *                Exim Monitor                    *
@@ -132,6 +132,10 @@ int     deliver_frozen_at      = 0;
 BOOL    deliver_manual_thaw    = FALSE;
 BOOL    dont_deliver           = FALSE;
 
+#ifdef WITH_CONTENT_SCAN
+BOOL   fake_reject             = FALSE;
+#endif
+
 header_line *header_last       = NULL;
 header_line *header_list       = NULL;
 
@@ -142,6 +146,11 @@ int     interface_port         = 0;
 BOOL    local_error_message    = FALSE;
 uschar *local_scan_data        = NULL;
 BOOL    log_timezone           = FALSE;
+
+#ifdef WITH_CONTENT_SCAN
+uschar *spam_score_int         = NULL;
+#endif
+
 int     message_age            = 0;
 uschar *message_id;
 uschar *message_id_external;
index 0f213aa0ac1fe7f643dd9e36b33ffdaafd00ec9a..b8c39d12ed8a085b932bf1a37e8903c30be4412a 100644 (file)
@@ -1,4 +1,4 @@
-# $Cambridge: exim/src/src/EDITME,v 1.4.2.1 2004/11/25 15:33:54 tom Exp $
+# $Cambridge: exim/src/src/EDITME,v 1.4.2.2 2004/12/02 09:15:11 tom Exp $
 
 ##################################################
 #          The Exim mail transport agent         #
@@ -323,6 +323,16 @@ EXIM_MONITOR=eximon.bin
 
 #WITH_CONTENT_SCAN=yes
 
+# If you want to use the deprecated "demime" condition in the DATA ACL,
+# uncomment the line below. Doing so will also explicitly turn on the
+# WITH_CONTENT_SCAN option. If possible, use the MIME ACL instead of
+# the "demime" condition.
+
+#WITH_OLD_DEMIME=yes
+
+
+
+
 ###############################################################################
 #                 THESE ARE THINGS YOU MIGHT WANT TO SPECIFY                  #
 ###############################################################################
index 9e098b76059bc40e92435ac9b1d91cca465a8164..e5e9f08e6f0c71f2d77598f69b567f46dca56cbb 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/config.h.defaults,v 1.2.2.1 2004/11/30 15:18:58 tom Exp $ */
+/* $Cambridge: exim/src/src/config.h.defaults,v 1.2.2.2 2004/12/02 09:15:11 tom Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -53,7 +53,7 @@ in config.h unless some value is defined in Local/Makefile. */
 #define HAVE_CRYPT16
 #define HAVE_SA_LEN
 #define HEADERS_CHARSET           "ISO-8859-1"
-#define HEADER_ADD_BUFFER_SIZE     8192
+#define HEADER_ADD_BUFFER_SIZE    (8192 * 4)
 #define HEADER_MAXSIZE            (1024*1024)
 
 #define INPUT_DIRECTORY_MODE       0750
@@ -107,7 +107,7 @@ in config.h unless some value is defined in Local/Makefile. */
 #define SPOOL_DIRECTORY
 #define SPOOL_DIRECTORY_MODE       0750
 #define SPOOL_MODE                 0640
-#define STRING_SPRINTF_BUFFER_SIZE 8192
+#define STRING_SPRINTF_BUFFER_SIZE (8192 * 4)
 
 #define SUPPORT_A6
 #define SUPPORT_CRYPTEQ
index 46dcd9100e46e3522e6164d3271bb1dc814d0088..80857a69876b05f5fd12d7ecc82dc6bf38bc51aa 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/exim.c,v 1.10 2004/11/25 13:54:31 ph10 Exp $ */
+/* $Cambridge: exim/src/src/exim.c,v 1.9.2.1 2004/12/02 09:15:11 tom Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -839,6 +839,9 @@ fprintf(f, "Support for:");
   fprintf(f, " OpenSSL");
   #endif
 #endif
+#ifdef WITH_CONTENT_SCAN
+  fprintf(f, " Content_Scanning");
+#endif
 fprintf(f, "\n");
 
 fprintf(f, "Lookups:");
@@ -1169,8 +1172,7 @@ uschar **argv = USS cargv;
 int  arg_receive_timeout = -1;
 int  arg_smtp_receive_timeout = -1;
 int  arg_error_handling = error_handling;
-int  filter_sfd = -1;
-int  filter_ufd = -1;
+int  filter_fd = -1;
 int  group_count;
 int  i;
 int  list_queue_option = 0;
@@ -1216,6 +1218,7 @@ uschar *ftest_prefix = NULL;
 uschar *ftest_suffix = NULL;
 uschar *real_sender_address;
 uschar *originator_home = US"/";
+BOOL ftest_system = FALSE;
 void *reset_point;
 
 struct passwd *pw;
@@ -1581,32 +1584,20 @@ for (i = 1; i < argc; i++)
     else if (*argrest == 'e')
       expansion_test = checking = TRUE;
 
-    /* -bF:  Run system filter test */
-
-    else if (*argrest == 'F')
-      {
-      filter_test |= FTEST_SYSTEM;
-      if (*(++argrest) != 0) { badarg = TRUE; break; }
-      if (++i < argc) filter_test_sfile = argv[i]; else
-        {
-        fprintf(stderr, "exim: file name expected after %s\n", argv[i-1]);
-        exit(EXIT_FAILURE);
-        }
-      }
-
-    /* -bf:  Run user filter test
+    /* -bf:  Run in mail filter testing mode
+       -bF:  Ditto, but for system filters
        -bfd: Set domain for filter testing
        -bfl: Set local part for filter testing
        -bfp: Set prefix for filter testing
        -bfs: Set suffix for filter testing
     */
 
-    else if (*argrest == 'f')
+    else if (*argrest == 'f' || *argrest == 'F')
       {
-      if (*(++argrest) == 0)
+      ftest_system = *argrest++ == 'F';
+      if (*argrest == 0)
         {
-        filter_test |= FTEST_USER;
-        if (++i < argc) filter_test_ufile = argv[i]; else
+        if(++i < argc) filter_test = argv[i]; else
           {
           fprintf(stderr, "exim: file name expected after %s\n", argv[i-1]);
           exit(EXIT_FAILURE);
@@ -2773,7 +2764,7 @@ if ((
     (smtp_input || extract_recipients || recipients_arg < argc) &&
     (daemon_listen || queue_interval >= 0 || bi_option ||
       test_retry_arg >= 0 || test_rewrite_arg >= 0 ||
-      filter_test != FTEST_NONE || (msg_action_arg > 0 && !one_msg_action))
+      filter_test != NULL || (msg_action_arg > 0 && !one_msg_action))
     ) ||
     (
     msg_action_arg > 0 &&
@@ -2791,19 +2782,19 @@ if ((
     (
     list_options &&
     (checking || smtp_input || extract_recipients ||
-      filter_test != FTEST_NONE || bi_option)
+      filter_test != NULL || bi_option)
     ) ||
     (
     verify_address_mode &&
     (address_test_mode || smtp_input || extract_recipients ||
-      filter_test != FTEST_NONE || bi_option)
+      filter_test != NULL || bi_option)
     ) ||
     (
     address_test_mode && (smtp_input || extract_recipients ||
-      filter_test != FTEST_NONE || bi_option)
+      filter_test != NULL || bi_option)
     ) ||
     (
-    smtp_input && (sender_address != NULL || filter_test != FTEST_NONE ||
+    smtp_input && (sender_address != NULL || filter_test != NULL ||
       extract_recipients)
     ) ||
     (
@@ -2963,7 +2954,7 @@ if ((                                            /* EITHER */
     ) ||                                         /*   OR   */
     expansion_test                               /* expansion testing */
     ||                                           /*   OR   */
-    filter_test != FTEST_NONE)                   /* Filter testing */
+    filter_test != NULL)                         /* Filter testing */
   {
   setgroups(group_count, group_list);
   exim_setugid(real_uid, real_gid, FALSE,
@@ -2986,26 +2977,15 @@ privileged user. */
 
 else exim_setugid(geteuid(), getegid(), FALSE, US"forcing real = effective");
 
-/* If testing a filter, open the file(s) now, before wasting time doing other
+/* If testing a filter, open the file now, before wasting time doing other
 setups and reading the message. */
 
-if ((filter_test & FTEST_SYSTEM) != 0)
+if (filter_test != NULL)
   {
-  filter_sfd = Uopen(filter_test_sfile, O_RDONLY, 0);
-  if (filter_sfd < 0)
+  filter_fd = Uopen(filter_test, O_RDONLY,0);
+  if (filter_fd < 0)
     {
-    fprintf(stderr, "exim: failed to open %s: %s\n", filter_test_sfile,
-      strerror(errno));
-    return EXIT_FAILURE;
-    }
-  }
-
-if ((filter_test & FTEST_USER) != 0)
-  {
-  filter_ufd = Uopen(filter_test_ufile, O_RDONLY, 0);
-  if (filter_ufd < 0)
-    {
-    fprintf(stderr, "exim: failed to open %s: %s\n", filter_test_ufile,
+    fprintf(stderr, "exim: failed to open %s: %s\n", filter_test,
       strerror(errno));
     return EXIT_FAILURE;
     }
@@ -3400,11 +3380,11 @@ if (real_uid != root_uid && real_uid != exim_uid &&
   }
 
 /* If the caller is not trusted, certain arguments are ignored when running for
-real, but are permitted when checking things (-be, -bv, -bt, -bh, -bf, -bF).
-Note that authority for performing certain actions on messages is tested in the
+real, but are permitted when checking things (-be, -bv, -bt, -bh, -bf). Note
+that authority for performing certain actions on messages is tested in the
 queue_action() function. */
 
-if (!trusted_caller && !checking && filter_test == FTEST_NONE)
+if (!trusted_caller && !checking && filter_test == NULL)
   {
   sender_host_name = sender_host_address = interface_address =
     sender_ident = received_protocol = NULL;
@@ -3801,7 +3781,7 @@ for (i = 0;;)
     if (originator_name == NULL)
       {
       if (sender_address == NULL ||
-           (!trusted_caller && filter_test == FTEST_NONE))
+           (!trusted_caller && filter_test == NULL))
         {
         uschar *name = US pw->pw_gecos;
         uschar *amp = Ustrchr(name, '&');
@@ -3935,7 +3915,7 @@ unless a trusted caller supplies a sender address with -f, or is passing in the
 message via SMTP (inetd invocation or otherwise). */
 
 if ((sender_address == NULL && !smtp_input) ||
-    (!trusted_caller && filter_test == FTEST_NONE))
+    (!trusted_caller && filter_test == NULL))
   {
   sender_local = TRUE;
 
@@ -3966,7 +3946,7 @@ if ((!smtp_input && sender_address == NULL) ||
        ||                                /*         OR            */
        (sender_address[0] != 0 &&        /* Non-empty sender address, AND */
        !checking &&                      /* Not running tests, AND */
-       filter_test == FTEST_NONE))       /* Not testing a filter */
+       filter_test == NULL))             /* Not testing a filter */
     {
     sender_address = originator_login;
     sender_address_forced = FALSE;
@@ -4176,7 +4156,7 @@ if (recipients_arg >= argc && !extract_recipients && !smtp_input)
     printf("Configuration file is %s\n", config_main_filename);
     return EXIT_SUCCESS;
     }
-  if (filter_test == FTEST_NONE)
+  if (filter_test == NULL)
     {
     fprintf(stderr,
 "Exim is a Mail Transfer Agent. It is normally called by Mail User Agents,\n"
@@ -4530,9 +4510,9 @@ while (more)
         }
       }
 
-    /* Read the data for the message. If filter_test is not FTEST_NONE, this
-    will just read the headers for the message, and not write anything onto the
-    spool. */
+    /* Read the data for the message. If filter_test is true, this will
+    just read the headers for the message, and not write anything onto
+    the spool. */
 
     message_ended = END_NOTENDED;
     more = receive_msg(extract_recipients);
@@ -4551,7 +4531,7 @@ while (more)
   unless specified. The the return path is set to to the sender unless it has
   already been set from a return-path header in the message. */
 
-  if (filter_test != FTEST_NONE)
+  if (filter_test != NULL)
     {
     deliver_domain = (ftest_domain != NULL)?
       ftest_domain : qualify_domain_recipient;
@@ -4586,27 +4566,8 @@ while (more)
     if (ftest_suffix != NULL) printf("Suffix    = %s\n", ftest_suffix);
 
     chdir("/");   /* Get away from wherever the user is running this from */
-    
-    /* Now we run either a system filter test, or a user filter test, or both. 
-    In the latter case, headers added by the system filter will persist and be 
-    available to the user filter. We need to copy the filter variables 
-    explicitly. */
-    
-    if ((filter_test & FTEST_SYSTEM) != 0)
-      {
-      if (!filter_runtest(filter_sfd, filter_test_sfile, TRUE, more))
-        exim_exit(EXIT_FAILURE);
-      }      
-      
-    memcpy(filter_sn, filter_n, sizeof(filter_sn));
-      
-    if ((filter_test & FTEST_USER) != 0)
-      {
-      if (!filter_runtest(filter_ufd, filter_test_ufile, FALSE, more))
-        exim_exit(EXIT_FAILURE);
-      }      
-      
-    exim_exit(EXIT_SUCCESS);
+    exim_exit(filter_runtest(filter_fd, ftest_system, more)?
+      EXIT_SUCCESS : EXIT_FAILURE);
     }
 
   /* Else act on the result of message reception. We should not get here unless
index 1bdcd3760c0d061055d258985232d1ef53a4337c..6c7890861d68d608a024af1145de88ef2c2df8e3 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/expand.c,v 1.7 2004/11/18 11:17:33 ph10 Exp $ */
+/* $Cambridge: exim/src/src/expand.c,v 1.7.2.1 2004/12/02 09:15:11 tom Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -326,6 +326,10 @@ static var_entry var_table[] = {
   { "caller_uid",          vtype_uid,         &real_uid },
   { "compile_date",        vtype_stringptr,   &version_date },
   { "compile_number",      vtype_stringptr,   &version_cnumber },
+#ifdef WITH_OLD_DEMIME
+  { "demime_errorlevel",   vtype_int,         &demime_errorlevel },
+  { "demime_reason",       vtype_stringptr,   &demime_reason },
+#endif
   { "dnslist_domain",      vtype_stringptr,   &dnslist_domain },
   { "dnslist_text",        vtype_stringptr,   &dnslist_text },
   { "dnslist_value",       vtype_stringptr,   &dnslist_value },
@@ -334,6 +338,9 @@ static var_entry var_table[] = {
   { "exim_gid",            vtype_gid,         &exim_gid },
   { "exim_path",           vtype_stringptr,   &exim_path },
   { "exim_uid",            vtype_uid,         &exim_uid },
+#ifdef WITH_OLD_DEMIME
+  { "found_extension",     vtype_stringptr,   &found_extension },
+#endif 
   { "home",                vtype_stringptr,   &deliver_home },
   { "host",                vtype_stringptr,   &deliver_host },
   { "host_address",        vtype_stringptr,   &deliver_host_address },
@@ -357,6 +364,9 @@ static var_entry var_table[] = {
   { "log_inodes",          vtype_pinodes,     (void *)FALSE },
   { "log_space",           vtype_pspace,      (void *)FALSE },  
   { "mailstore_basename",  vtype_stringptr,   &mailstore_basename },
+#ifdef WITH_CONTENT_SCAN
+  { "malware_name",        vtype_stringptr,   &malware_name },
+#endif
   { "message_age",         vtype_int,         &message_age },
   { "message_body",        vtype_msgbody,     &message_body },
   { "message_body_end",    vtype_msgbody_end, &message_body_end },
@@ -364,6 +374,24 @@ static var_entry var_table[] = {
   { "message_headers",     vtype_msgheaders,  NULL },
   { "message_id",          vtype_stringptr,   &message_id },
   { "message_size",        vtype_int,         &message_size },
+#ifdef WITH_CONTENT_SCAN
+  { "mime_anomaly_level",  vtype_int,         &mime_anomaly_level },
+  { "mime_anomaly_text",   vtype_stringptr,   &mime_anomaly_text },
+  { "mime_boundary",       vtype_stringptr,   &mime_boundary },
+  { "mime_charset",        vtype_stringptr,   &mime_charset },
+  { "mime_content_description", vtype_stringptr, &mime_content_description },
+  { "mime_content_disposition", vtype_stringptr, &mime_content_disposition },
+  { "mime_content_id",     vtype_stringptr,   &mime_content_id },
+  { "mime_content_size",   vtype_int,         &mime_content_size },
+  { "mime_content_transfer_encoding",vtype_stringptr, &mime_content_transfer_encoding },
+  { "mime_content_type",   vtype_stringptr,   &mime_content_type },
+  { "mime_decoded_filename", vtype_stringptr, &mime_decoded_filename },
+  { "mime_filename",       vtype_stringptr,   &mime_filename },
+  { "mime_is_coverletter", vtype_int,         &mime_is_coverletter },
+  { "mime_is_multipart",   vtype_int,         &mime_is_multipart },
+  { "mime_is_rfc822",      vtype_int,         &mime_is_rfc822 },
+  { "mime_part_count",     vtype_int,         &mime_part_count },
+#endif
   { "n0",                  vtype_filter_int,  &filter_n[0] },
   { "n1",                  vtype_filter_int,  &filter_n[1] },
   { "n2",                  vtype_filter_int,  &filter_n[2] },
@@ -394,6 +422,9 @@ static var_entry var_table[] = {
   { "recipient_verify_failure",vtype_stringptr,&recipient_verify_failure }, 
   { "recipients",          vtype_recipients,  NULL },
   { "recipients_count",    vtype_int,         &recipients_count },
+#ifdef WITH_CONTENT_SCAN
+  { "regex_match_string",  vtype_stringptr,   &regex_match_string },
+#endif
   { "reply_address",       vtype_reply,       NULL },
   { "return_path",         vtype_stringptr,   &return_path },
   { "return_size_limit",   vtype_int,         &bounce_return_size_limit },
@@ -424,6 +455,12 @@ static var_entry var_table[] = {
   { "sn7",                 vtype_filter_int,  &filter_sn[7] },
   { "sn8",                 vtype_filter_int,  &filter_sn[8] },
   { "sn9",                 vtype_filter_int,  &filter_sn[9] },
+#ifdef WITH_CONTENT_SCAN
+  { "spam_bar",            vtype_stringptr,   &spam_bar },
+  { "spam_report",         vtype_stringptr,   &spam_report },
+  { "spam_score",          vtype_stringptr,   &spam_score },
+  { "spam_score_int",      vtype_stringptr,   &spam_score_int },
+#endif
   { "spool_directory",     vtype_stringptr,   &spool_directory },
   { "spool_inodes",        vtype_pinodes,     (void *)TRUE },
   { "spool_space",         vtype_pspace,      (void *)TRUE },  
index f1180b81fe225384cf739eb117fc6fd4f0097532..5c1b0dab397184e5083183cf0b39ff867d878234 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/functions.h,v 1.5.2.1 2004/11/30 15:18:58 tom Exp $ */
+/* $Cambridge: exim/src/src/functions.h,v 1.5.2.2 2004/12/02 09:15:11 tom Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -68,6 +68,9 @@ extern void    deliver_msglog(const char *, ...);
 extern void    deliver_set_expansions(address_item *);
 extern int     deliver_split_address(address_item *);
 extern void    deliver_succeeded(address_item *);
+#ifdef WITH_OLD_DEMIME
+extern int     demime(uschar **);
+#endif
 extern BOOL    directory_make(uschar *, uschar *, int, BOOL);
 extern dns_address *dns_address_from_rr(dns_answer *, dns_record *);
 extern void    dns_build_reverse(uschar *, uschar *);
@@ -173,6 +176,9 @@ extern void    queue_count(void);
 extern void    queue_run(uschar *, uschar *, BOOL);
 
 extern int     random_number(int);
+#ifdef WITH_CONTENT_SCAN
+extern int     recv_line(int, uschar *, int);
+#endif
 extern int     rda_interpret(redirect_block *, int, uschar *, uschar *, ugid_block *,
                  address_item **, uschar **, error_block **, int *, uschar *);
 extern int     rda_is_filter(const uschar *);
index 1e5eb56590cf94734886939a55f1745dd1280686..da57ba5e29dc8f145fccea450855ff54594c314b 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/globals.c,v 1.6.2.2 2004/11/26 16:04:26 tom Exp $ */
+/* $Cambridge: exim/src/src/globals.c,v 1.6.2.3 2004/12/02 09:15:11 tom Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -447,6 +447,11 @@ uschar *deliver_selectstring   = NULL;
 BOOL    deliver_selectstring_regex = FALSE;
 uschar *deliver_selectstring_sender = NULL;
 BOOL    deliver_selectstring_sender_regex = FALSE;
+#ifdef WITH_OLD_DEMIME
+int     demime_errorlevel      = 0;
+int     demime_ok              = 0;
+uschar *demime_reason          = NULL;
+#endif
 BOOL    disable_logging        = FALSE;
 
 uschar *dns_again_means_nonexist = NULL;
@@ -494,6 +499,9 @@ int     filter_sn[FILTER_VARIABLE_COUNT];
 uschar *filter_test            = NULL;
 uschar *filter_thisaddress     = NULL;
 int     finduser_retries       = 0;
+#ifdef WITH_OLD_DEMIME
+uschar *found_extension        = NULL;
+#endif
 uid_t   fixed_never_users[]    = { FIXED_NEVER_USERS };
 uschar *freeze_tell            = NULL;
 uschar *fudged_queue_times     = US"";
index c63a56bc9661ac31ad28503f5fe99549f757b490..727be71c517b7e4c1dd8b4cf10c49cca7436eb44 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/globals.h,v 1.6.2.1 2004/11/26 16:04:26 tom Exp $ */
+/* $Cambridge: exim/src/src/globals.h,v 1.6.2.2 2004/12/02 09:15:11 tom Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -241,6 +241,11 @@ extern uschar *deliver_selectstring;   /* For selecting by recipient */
 extern BOOL    deliver_selectstring_regex; /* String is regex */
 extern uschar *deliver_selectstring_sender; /* For selecting by sender */
 extern BOOL    deliver_selectstring_sender_regex; /* String is regex */
+#ifdef WITH_OLD_DEMIME
+extern int     demime_errorlevel;      /* Severity of MIME error */
+extern int     demime_ok;              /* Nonzero if message has been demimed */
+extern uschar *demime_reason;          /* Reason for broken MIME container */
+#endif
 extern BOOL    disable_logging;        /* Disables log writing when TRUE */
 
 extern uschar *dns_again_means_nonexist; /* Domains that are badly set up */
@@ -288,6 +293,9 @@ extern uschar *filter_test;            /* Run as a filter tester on this file */
 extern uschar *filter_thisaddress;     /* For address looping */
 extern int     finduser_retries;       /* Retry count for getpwnam() */
 extern uid_t   fixed_never_users[];    /* Can't be overridden */
+#ifdef WITH_OLD_DEMIME
+extern uschar *found_extension;        /* demime acl condition: file extension found */
+#endif
 extern uschar *freeze_tell;            /* Message on (some) freezings */
 extern uschar *fudged_queue_times;     /* For use in test harness */
 
index 2cac551c686e30913e7b6fcb84bc9a1c6a81777e..9b464d25bcd9a0309b3cbb01c4b5800fe9a47473 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/header.c,v 1.1 2004/10/07 10:39:01 ph10 Exp $ */
+/* $Cambridge: exim/src/src/header.c,v 1.1.2.1 2004/12/02 09:15:11 tom Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -40,6 +40,19 @@ while (*tt == ' ' || *tt == '\t') tt++;
 return *tt == ':';
 }
 
+/* This is a copy of the function above, only that it is possible to pass
+   only the beginning of a header name. It simply does a front-anchored
+   substring match. Arguments and Return codes are the same as for
+   header_testname() above. */
+
+BOOL
+header_testname_incomplete(header_line *h, uschar *name, int len, BOOL notdel)
+{
+uschar *tt;
+if (h->type == '*' && notdel) return FALSE;
+if (h->text == NULL || strncmpic(h->text, name, len) != 0) return FALSE;
+return TRUE;
+}
 
 
 /*************************************************
index 4e6f88a31b16e333f07b66409e2fe456f072153f..fd95643a51233c8be4f706c1e65c53c95bf3cea9 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/local_scan.h,v 1.1 2004/10/07 10:39:01 ph10 Exp $ */
+/* $Cambridge: exim/src/src/local_scan.h,v 1.1.2.1 2004/12/02 09:15:11 tom Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -147,6 +147,7 @@ extern void    header_add(int, char *, ...);
 extern void    header_add_at_position(BOOL, uschar *, BOOL, int, char *, ...);
 extern void    header_remove(int, uschar *);
 extern BOOL    header_testname(header_line *, uschar *, int, BOOL);
+extern BOOL    header_testname_incomplete(header_line *, uschar *, int, BOOL);
 extern void    log_write(unsigned int, int, char *format, ...);
 extern int     lss_b64decode(uschar *, uschar **);
 extern uschar *lss_b64encode(uschar *, int);
index d4e7b8a65fe20fac23c050b6f0b3da7f8cf88e81..bff6706b4ac4406121b2f95e6171ba90f4af7222 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/macros.h,v 1.2.2.2 2004/11/30 15:18:58 tom Exp $ */
+/* $Cambridge: exim/src/src/macros.h,v 1.2.2.3 2004/12/02 09:15:11 tom Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -131,12 +131,12 @@ enough to hold all the headers from a normal kind of message. */
 into big_buffer_size and in some circumstances increased. It should be at least
 as long as the maximum path length. */
 
-#if defined PATH_MAX && PATH_MAX > 1024
+#if defined PATH_MAX && PATH_MAX > 16384
 #define BIG_BUFFER_SIZE PATH_MAX
-#elif defined MAXPATHLEN && MAXPATHLEN > 1024
+#elif defined MAXPATHLEN && MAXPATHLEN > 16384
 #define BIG_BUFFER_SIZE MAXPATHLEN
 #else
-#define BIG_BUFFER_SIZE 1024
+#define BIG_BUFFER_SIZE 16384
 #endif
 
 /* This limits the length of data returned by local_scan(). Because it is
@@ -545,6 +545,7 @@ to the header name, by calling header_checkname(). */
 #define htype_add_top       'a'
 #define htype_add_rec       'r'
 #define htype_add_bot       'z'
+#define htype_add_rfc       'f'
 
 /* Types of item in options lists. These are the bottom 8 bits of the "type"
 field, which is an int. The opt_void value is used for entries in tables that
index caa78ee90925f3c7817315f4bc22e92818cf93bb..e1ca32ebcaf85b1d69b63356bdc204abc58c16eb 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/readconf.c,v 1.2 2004/10/18 09:16:57 ph10 Exp $ */
+/* $Cambridge: exim/src/src/readconf.c,v 1.2.2.1 2004/12/02 09:15:11 tom Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -143,6 +143,9 @@ static optionlist optionlist_config[] = {
   { "acl_smtp_helo",            opt_stringptr,   &acl_smtp_helo },
   { "acl_smtp_mail",            opt_stringptr,   &acl_smtp_mail },
   { "acl_smtp_mailauth",        opt_stringptr,   &acl_smtp_mailauth },
+#ifdef WITH_CONTENT_SCAN
+  { "acl_smtp_mime",            opt_stringptr,   &acl_smtp_mime },
+#endif
   { "acl_smtp_predata",         opt_stringptr,   &acl_smtp_predata },
   { "acl_smtp_quit",            opt_stringptr,   &acl_smtp_quit },
   { "acl_smtp_rcpt",            opt_stringptr,   &acl_smtp_rcpt },
@@ -156,6 +159,9 @@ static optionlist optionlist_config[] = {
   { "allow_utf8_domains",       opt_bool,        &allow_utf8_domains },
   { "auth_advertise_hosts",     opt_stringptr,   &auth_advertise_hosts },
   { "auto_thaw",                opt_time,        &auto_thaw },
+#ifdef WITH_CONTENT_SCAN
+  { "av_scanner",               opt_stringptr,   &av_scanner },
+#endif
   { "bi_command",               opt_stringptr,   &bi_command },
   { "bounce_message_file",      opt_stringptr,   &bounce_message_file },
   { "bounce_message_text",      opt_stringptr,   &bounce_message_text },
@@ -318,6 +324,9 @@ static optionlist optionlist_config[] = {
   { "smtp_receive_timeout",     opt_time,        &smtp_receive_timeout },
   { "smtp_reserve_hosts",       opt_stringptr,   &smtp_reserve_hosts },
   { "smtp_return_error_details",opt_bool,        &smtp_return_error_details },
+#ifdef WITH_CONTENT_SCAN
+  { "spamd_address",            opt_stringptr,   &spamd_address },
+#endif
   { "split_spool_directory",    opt_bool,        &split_spool_directory },
   { "spool_directory",          opt_stringptr,   &spool_directory },
   { "strip_excess_angle_brackets", opt_bool,     &strip_excess_angle_brackets },
index 0ed05f1db213f8cacc59c62d4c7ea48991f05646..99a91898178d4cdac2766c2b331384bf7ed638ca 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/receive.c,v 1.5 2004/11/25 13:54:31 ph10 Exp $ */
+/* $Cambridge: exim/src/src/receive.c,v 1.4.2.1 2004/12/02 09:15:11 tom Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -427,7 +427,7 @@ if (smtp_input)
   }
 else
   {
-  if (filter_test == FTEST_NONE)
+  if (filter_test == NULL)
     {
     fprintf(stderr, "\nexim: %s received - message abandoned\n",
       (sig == SIGTERM)? "SIGTERM" : "SIGINT");
@@ -918,6 +918,21 @@ for (h = acl_warn_headers; h != NULL; h = next)
     DEBUG(D_receive|D_acl) debug_printf("  (after Received:)");
     break;
 
+    case htype_add_rfc:
+    /* add header before any header which is NOT Received: or Resent- */
+    last_received = header_list;
+    while ( (last_received->next != NULL) &&
+            ( (header_testname(last_received->next, US"Received", 8, FALSE)) ||
+              (header_testname_incomplete(last_received->next, US"Resent-", 7, FALSE)) ) )
+              last_received = last_received->next;
+    /* last_received now points to the last Received: or Resent-* header
+       in an uninterrupted chain of those header types (seen from the beginning
+       of all headers. Our current header must follow it. */
+    h->next = last_received->next;
+    last_received->next = h;
+    DEBUG(D_receive|D_acl) debug_printf("  (before any non-Received: or Resent-*: header)");        
+    break;
+
     default:
     h->next = NULL;
     header_last->next = h;
@@ -1508,18 +1523,18 @@ for (;;)
           if (domain == 0 && newsender[0] != 0)
             newsender = rewrite_address_qualify(newsender, FALSE);
 
-          if (filter_test != FTEST_NONE || receive_check_set_sender(newsender))
+          if (filter_test != NULL || receive_check_set_sender(newsender))
             {
             sender_address = newsender;
 
-            if (trusted_caller || filter_test != FTEST_NONE)
+            if (trusted_caller || filter_test != NULL)
               {
               authenticated_sender = NULL;
               originator_name = US"";
               sender_local = FALSE;
               }
 
-            if (filter_test != FTEST_NONE)
+            if (filter_test != NULL)
               printf("Sender taken from \"From \" line\n");
             }
           }
@@ -1659,7 +1674,7 @@ if (smtp_input && (receive_feof)())
 /* If this is a filter test run and no headers were read, output a warning
 in case there is a mistake in the test message. */
 
-if (filter_test != FTEST_NONE && header_list->next == NULL)
+if (filter_test != NULL && header_list->next == NULL)
   printf("Warning: no message headers read\n");
 
 
@@ -1781,7 +1796,7 @@ for (h = header_list->next; h != NULL; h = h->next)
     otherwise set. However, remove any <> that surround the address
     because the variable doesn't have these. */
 
-    if (filter_test != FTEST_NONE)
+    if (filter_test != NULL)
       {
       uschar *start = h->text + 12;
       uschar *end = start + Ustrlen(start);
@@ -2378,7 +2393,7 @@ DEBUG(D_receive)
 testing mode, that is all this function does. Return TRUE if the message
 ended with a dot. */
 
-if (filter_test != FTEST_NONE)
+if (filter_test != NULL)
   {
   process_info[process_info_len] = 0;
   return message_ended == END_DOT;
@@ -2716,6 +2731,130 @@ else
 
   if (smtp_input && !smtp_batched_input)
     {
+
+#ifdef WITH_CONTENT_SCAN
+     /* MIME ACL hook */
+    if (acl_smtp_mime != NULL && recipients_count > 0)
+      {
+      FILE *mbox_file;
+      uschar rfc822_file_path[2048];
+      unsigned long long mbox_size;
+      header_line *my_headerlist;
+      uschar *user_msg, *log_msg;
+      int mime_part_count_buffer = -1;
+      
+      memset(CS rfc822_file_path,0,2048);
+      
+      /* check if it is a MIME message */
+      my_headerlist = header_list;
+      while (my_headerlist != NULL) {
+        /* skip deleted headers */
+        if (my_headerlist->type == '*') {
+          my_headerlist = my_headerlist->next;
+          continue;
+        };
+        if (strncmpic(my_headerlist->text, US"Content-Type:", 13) == 0) {
+          DEBUG(D_receive) debug_printf("Found Content-Type: header - executing acl_smtp_mime.\n");
+          goto DO_MIME_ACL;
+        };
+        my_headerlist = my_headerlist->next;
+      };
+      
+      DEBUG(D_receive) debug_printf("No Content-Type: header - presumably not a MIME message.\n");
+      goto NO_MIME_ACL;
+      
+      DO_MIME_ACL:
+      /* make sure the eml mbox file is spooled up */
+      mbox_file = spool_mbox(&mbox_size);
+      if (mbox_file == NULL) {
+        /* error while spooling */
+        log_write(0, LOG_MAIN|LOG_PANIC,
+               "acl_smtp_mime: error while creating mbox spool file, message temporarily rejected.");
+        Uunlink(spool_name);
+        unspool_mbox(); 
+        smtp_respond(451, TRUE, US"temporary local problem");
+        message_id[0] = 0;            /* Indicate no message accepted */
+        smtp_reply = US"";            /* Indicate reply already sent */
+        goto TIDYUP;                  /* Skip to end of function */
+      };
+      
+      mime_is_rfc822 = 0;
+
+      MIME_ACL_CHECK:
+      mime_part_count = -1;
+      rc = mime_acl_check(mbox_file, NULL, &user_msg, &log_msg);
+      fclose(mbox_file);
+      
+      if (Ustrlen(rfc822_file_path) > 0) {
+        mime_part_count = mime_part_count_buffer;
+        
+        if (unlink(CS rfc822_file_path) == -1) {
+          log_write(0, LOG_PANIC,
+               "acl_smtp_mime: can't unlink RFC822 spool file, skipping.");
+            goto END_MIME_ACL;
+        };
+      };
+      
+      /* check if we must check any message/rfc822 attachments */
+      if (rc == OK) {
+        uschar temp_path[1024];
+        int n;
+        struct dirent *entry;
+        DIR *tempdir;
+        snprintf(CS temp_path, 1024, "%s/scan/%s", spool_directory, message_id);
+
+       tempdir = opendir(CS temp_path);
+       n = 0;
+       do {
+         entry = readdir(tempdir);
+         if (entry == NULL) break;
+          if (strncmpic(US entry->d_name,US"__rfc822_",9) == 0) {
+            snprintf(CS rfc822_file_path, 2048,"%s/scan/%s/%s", spool_directory, message_id, entry->d_name);
+           debug_printf("RFC822 attachment detected: running MIME ACL for '%s'\n", rfc822_file_path);
+           break;
+          }; 
+       } while (1);
+       closedir(tempdir);
+        
+        if (entry != NULL) {
+          mbox_file = Ufopen(rfc822_file_path,"r");
+          if (mbox_file == NULL) {
+            log_write(0, LOG_PANIC,
+               "acl_smtp_mime: can't open RFC822 spool file, skipping.");
+            unlink(CS rfc822_file_path);
+            goto END_MIME_ACL;
+          };
+          /* set RFC822 expansion variable */
+          mime_is_rfc822 = 1;
+          mime_part_count_buffer = mime_part_count;
+          goto MIME_ACL_CHECK;
+        };
+      };
+      
+      END_MIME_ACL:
+      add_acl_headers(US"MIME");
+      if (rc == DISCARD)      
+        {
+        recipients_count = 0;
+        blackholed_by = US"MIME ACL";
+        }
+      else if (rc != OK)
+        {
+        Uunlink(spool_name);
+        unspool_mbox();
+        if (smtp_handle_acl_fail(ACL_WHERE_MIME, rc, user_msg, log_msg) != 0)
+          smtp_yield = FALSE;    /* No more messsages after dropped connection */
+        smtp_reply = US"";       /* Indicate reply already sent */
+        message_id[0] = 0;       /* Indicate no message accepted */
+        goto TIDYUP;             /* Skip to end of function */
+        }; 
+      }
+    NO_MIME_ACL:      
+#endif /* WITH_CONTENT_SCAN */
+
+
     if (acl_smtp_data != NULL && recipients_count > 0)
       {
       uschar *user_msg, *log_msg;
@@ -2729,6 +2868,9 @@ else
       else if (rc != OK)
         {
         Uunlink(spool_name);
+#ifdef WITH_CONTENT_SCAN
+        unspool_mbox();
+#endif
         if (smtp_handle_acl_fail(ACL_WHERE_DATA, rc, user_msg, log_msg) != 0)
           smtp_yield = FALSE;    /* No more messsages after dropped connection */
         smtp_reply = US"";       /* Indicate reply already sent */
@@ -2779,6 +2921,10 @@ else
   enable_dollar_recipients = FALSE;
   }
 
+#ifdef WITH_CONTENT_SCAN
+unspool_mbox();
+#endif
+
 /* The final check on the message is to run the scan_local() function. The
 version supplied with Exim always accepts, but this is a hook for sysadmins to
 supply their own checking code. The local_scan() function is run even when all
@@ -3235,12 +3381,37 @@ if (smtp_input)
     {
     if (smtp_reply == NULL)
       {
+#ifndef WITH_CONTENT_SCAN
       smtp_printf("250 OK id=%s\r\n", message_id);
+#elif      
+        if (fake_reject)
+          {
+            smtp_printf("550-FAKE_REJECT id=%s\r\n", message_id);
+            smtp_printf("550-Your message has been rejected but is being kept for evaluation.\r\n");
+            smtp_printf("550 If it was a legit message, it may still be delivered to the target recipient(s).\r\n");
+          }
+        else  
+          smtp_printf("250 OK id=%s\r\n", message_id);      
+#endif     
       if (host_checking)
         fprintf(stdout,
           "\n**** SMTP testing: that is not a real message id!\n\n");
       }
+#ifndef WITH_CONTENT_SCAN
     else if (smtp_reply[0] != 0) smtp_printf("%.1024s\r\n", smtp_reply);
+#elif
+    else if (smtp_reply[0] != 0)
+      {
+        if (fake_reject && (smtp_reply[0] == '2'))
+        {
+          smtp_printf("550-FAKE_REJECT id=%s\r\n", message_id);
+          smtp_printf("550-Your message has been rejected but is being kept for evaluation.\r\n");
+          smtp_printf("550 If it was a legit message, it may still be delivered to the target recipient(s).\r\n");
+        }
+        else 
+          smtp_printf("%.1024s\r\n", smtp_reply);
+      };
+#endif
     }
 
   /* For batched SMTP, generate an error message on failure, and do
index 9b25c23339ee5c9d88d7c329dc7def3eab07f257..dd8747b92f480cbc70aafb9ed10d4dbd2ba54fe0 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/smtp_in.c,v 1.5 2004/11/10 15:21:16 ph10 Exp $ */
+/* $Cambridge: exim/src/src/smtp_in.c,v 1.5.2.1 2004/12/02 09:15:11 tom Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -805,6 +805,10 @@ message_size = -1;
 acl_warn_headers = NULL;
 queue_only_policy = FALSE;
 deliver_freeze = FALSE;                              /* Can be set by ACL */
+#ifdef WITH_CONTENT_SCAN
+fake_reject = FALSE;                                 /* Can be set by ACL */
+no_mbox_unspool = FALSE;                             /* Can be set by ACL */
+#endif
 submission_mode = FALSE;                             /* Can be set by ACL */
 active_local_from_check = local_from_check;          /* Can be set by ACL */
 active_local_sender_retain = local_sender_retain;    /* Can be set by ACL */
@@ -1774,6 +1778,9 @@ BOOL drop = rc == FAIL_DROP;
 uschar *lognl;
 uschar *sender_info = US"";
 uschar *what = (where == ACL_WHERE_PREDATA)? US"DATA" :
+#ifdef WITH_CONTENT_SCAN
+               (where == ACL_WHERE_MIME)? US"during MIME ACL checks" :
+#endif  
                (where == ACL_WHERE_DATA)? US"after DATA" :
   string_sprintf("%s %s", acl_wherenames[where], smtp_data);
 
@@ -1785,7 +1792,11 @@ fixed, sender_address at this point became the rewritten address. I'm not sure
 this is what should be logged, so I've changed to logging the unrewritten
 address to retain backward compatibility. */
 
+#ifndef WITH_CONTENT_SCAN
 if (where == ACL_WHERE_RCPT || where == ACL_WHERE_DATA)
+#elif
+if (where == ACL_WHERE_RCPT || where == ACL_WHERE_DATA || where == ACL_WHERE_MIME)
+#endif
   {
   sender_info = string_sprintf("F=<%s> ", (sender_address_unrewritten != NULL)?
     sender_address_unrewritten : sender_address);
index f43556bfa4b04082deec669bb136d8d532b9a400..29996f6978ba19a07439476fe5da44552956dc8f 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/spool_in.c,v 1.1 2004/10/07 10:39:01 ph10 Exp $ */
+/* $Cambridge: exim/src/src/spool_in.c,v 1.1.2.1 2004/12/02 09:15:11 tom Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -277,6 +277,11 @@ tls_cipher = NULL;
 tls_peerdn = NULL;
 #endif
 
+#ifdef WITH_CONTENT_SCAN
+fake_reject = FALSE;
+spam_score_int = NULL;
+#endif
+
 /* Generate the full name and open the file. If message_subdir is already
 set, just look in the given directory. Otherwise, look in both the split
 and unsplit directories, as for the data file above. */
@@ -369,6 +374,10 @@ for (;;)
     local_error_message = TRUE;
   else if (Ustrncmp(big_buffer, "-local_scan ", 12) == 0)
     local_scan_data = string_copy(big_buffer + 12);
+#ifdef WITH_CONTENT_SCAN    
+  else if (Ustrncmp(big_buffer, "-spam_score_int ", 16) == 0)
+    spam_score_int = string_copy(big_buffer + 16);  
+#endif    
   else if (Ustrcmp(big_buffer, "-host_lookup_failed") == 0)
     host_lookup_failed = TRUE;
   else if (Ustrncmp(big_buffer, "-body_linecount", 15) == 0)
index af36f416931817c52a1f383ac4911b1dcdcfe9fe..8514edfd317966f3be0acfbe648c0916503eb627 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/spool_out.c,v 1.1 2004/10/07 10:39:01 ph10 Exp $ */
+/* $Cambridge: exim/src/src/spool_out.c,v 1.1.2.1 2004/12/02 09:15:11 tom Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -216,6 +216,9 @@ if (host_lookup_failed) fprintf(f, "-host_lookup_failed\n");
 if (sender_local) fprintf(f, "-local\n");
 if (local_error_message) fprintf(f, "-localerror\n");
 if (local_scan_data != NULL) fprintf(f, "-local_scan %s\n", local_scan_data);
+#ifdef WITH_CONTENT_SCAN
+if (spam_score_int != NULL) fprintf(f,"-spam_score_int %s\n", spam_score_int);
+#endif
 if (deliver_manual_thaw) fprintf(f, "-manual_thaw\n");
 if (sender_set_untrusted) fprintf(f, "-sender_set_untrusted\n");