-/* $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 *
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;
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;
-# $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 #
#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 #
###############################################################################
-/* $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 *
#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
#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
-/* $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 *
fprintf(f, " OpenSSL");
#endif
#endif
+#ifdef WITH_CONTENT_SCAN
+ fprintf(f, " Content_Scanning");
+#endif
fprintf(f, "\n");
fprintf(f, "Lookups:");
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;
uschar *ftest_suffix = NULL;
uschar *real_sender_address;
uschar *originator_home = US"/";
+BOOL ftest_system = FALSE;
void *reset_point;
struct passwd *pw;
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);
(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 &&
(
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)
) ||
(
) || /* 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,
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;
}
}
/* 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;
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, '&');
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;
|| /* 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;
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"
}
}
- /* 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);
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;
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
-/* $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 *
{ "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 },
{ "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 },
{ "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 },
{ "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] },
{ "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, ®ex_match_string },
+#endif
{ "reply_address", vtype_reply, NULL },
{ "return_path", vtype_stringptr, &return_path },
{ "return_size_limit", vtype_int, &bounce_return_size_limit },
{ "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 },
-/* $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 *
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 *);
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 *);
-/* $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 *
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;
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"";
-/* $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 *
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 */
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 */
-/* $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 *
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;
+}
/*************************************************
-/* $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 *
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);
-/* $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 *
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
#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
-/* $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 *
{ "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 },
{ "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 },
{ "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 },
-/* $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 *
}
else
{
- if (filter_test == FTEST_NONE)
+ if (filter_test == NULL)
{
fprintf(stderr, "\nexim: %s received - message abandoned\n",
(sig == SIGTERM)? "SIGTERM" : "SIGINT");
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;
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");
}
}
/* 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");
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);
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;
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;
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 */
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
{
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
-/* $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 *
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 */
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);
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);
-/* $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 *
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. */
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)
-/* $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 *
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");