From 717d7d98ab74330bc05abf768b8b6a3fa73244ab Mon Sep 17 00:00:00 2001 From: Tom Kistner Date: Thu, 25 Nov 2004 15:33:54 +0000 Subject: [PATCH] Exiscan inclusion - ACL hooks --- src/src/EDITME | 9 +- src/src/acl.c | 219 +++++++++++++++++++++++++++++++++++++++++++--- src/src/globals.c | 13 +-- src/src/macros.h | 46 +++++----- 4 files changed, 247 insertions(+), 40 deletions(-) diff --git a/src/src/EDITME b/src/src/EDITME index cea00d2c8..0f213aa0a 100644 --- a/src/src/EDITME +++ b/src/src/EDITME @@ -1,4 +1,4 @@ -# $Cambridge: exim/src/src/EDITME,v 1.4 2004/11/05 12:33:59 ph10 Exp $ +# $Cambridge: exim/src/src/EDITME,v 1.4.2.1 2004/11/25 15:33:54 tom Exp $ ################################################## # The Exim mail transport agent # @@ -314,7 +314,14 @@ LOOKUP_LSEARCH=yes EXIM_MONITOR=eximon.bin +#------------------------------------------------------------------------------ +# Compiling Exim with content scanning support: If you want to compile Exim +# with support for message body content scanning, set WITH_CONTENT_SCAN to +# the value "yes". This will give you malware and spam scanning in the DATA ACL, +# and the MIME ACL. Please read the documentation to learn more about these +# features. +#WITH_CONTENT_SCAN=yes ############################################################################### # THESE ARE THINGS YOU MIGHT WANT TO SPECIFY # diff --git a/src/src/acl.c b/src/src/acl.c index 92ebc18ec..ffd7e9451 100644 --- a/src/src/acl.c +++ b/src/src/acl.c @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/acl.c,v 1.5 2004/11/04 12:19:48 ph10 Exp $ */ +/* $Cambridge: exim/src/src/acl.c,v 1.5.2.1 2004/11/25 15:33:55 tom Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -34,19 +34,55 @@ static int msgcond[] = { FAIL, OK, OK, FAIL, OK, FAIL, OK }; /* ACL condition and modifier codes - keep in step with the table that follows. */ -enum { ACLC_ACL, ACLC_AUTHENTICATED, ACLC_CONDITION, ACLC_CONTROL, ACLC_DELAY, - ACLC_DNSLISTS, ACLC_DOMAINS, ACLC_ENCRYPTED, ACLC_ENDPASS, ACLC_HOSTS, - ACLC_LOCAL_PARTS, ACLC_LOG_MESSAGE, ACLC_LOGWRITE, ACLC_MESSAGE, - ACLC_RECIPIENTS, ACLC_SENDER_DOMAINS, ACLC_SENDERS, ACLC_SET, ACLC_VERIFY }; +enum { ACLC_ACL, ACLC_AUTHENTICATED, ACLC_CONDITION, ACLC_CONTROL, +#ifdef WITH_CONTENT_SCAN + ACLC_DECODE, +#endif + ACLC_DELAY, ACLC_DNSLISTS, ACLC_DOMAINS, ACLC_ENCRYPTED, ACLC_ENDPASS, + ACLC_HOSTS, ACLC_LOCAL_PARTS, ACLC_LOG_MESSAGE, ACLC_LOGWRITE, +#ifdef WITH_CONTENT_SCAN + ACLC_MALWARE, +#endif + ACLC_MESSAGE, +#ifdef WITH_CONTENT_SCAN + ACLC_MIME_REGEX, +#endif + ACLC_RECIPIENTS, +#ifdef WITH_CONTENT_SCAN + ACLC_REGEX +#endif + ACLC_SENDER_DOMAINS, ACLC_SENDERS, ACLC_SET, +#ifdef WITH_CONTENT_SCAN + ACLC_SPAM, +#endif + ACLC_VERIFY }; /* ACL conditions/modifiers: "delay", "control", "endpass", "message", "log_message", "logwrite", and "set" are modifiers that look like conditions but always return TRUE. They are used for their side effects. */ static uschar *conditions[] = { US"acl", US"authenticated", US"condition", - US"control", US"delay", US"dnslists", US"domains", US"encrypted", + US"control", +#ifdef WITH_CONTENT_SCAN + US"decode", +#endif + US"delay", US"dnslists", US"domains", US"encrypted", US"endpass", US"hosts", US"local_parts", US"log_message", US"logwrite", - US"message", US"recipients", US"sender_domains", US"senders", US"set", +#ifdef WITH_CONTENT_SCAN + US"malware", +#endif + US"message", +#ifdef WITH_CONTENT_SCAN + US"mime_regex", +#endif + US"recipients", +#ifdef WITH_CONTENT_SCAN + US"regex", +#endif + US"sender_domains", US"senders", US"set", +#ifdef WITH_CONTENT_SCAN + US"spam", +#endif US"verify" }; /* ACL control names */ @@ -64,6 +100,9 @@ static uschar cond_expand_at_top[] = { FALSE, /* authenticated */ TRUE, /* condition */ TRUE, /* control */ +#ifdef WITH_CONTENT_SCAN + TRUE, /* decode */ +#endif TRUE, /* delay */ TRUE, /* dnslists */ FALSE, /* domains */ @@ -73,11 +112,23 @@ static uschar cond_expand_at_top[] = { FALSE, /* local_parts */ TRUE, /* log_message */ TRUE, /* logwrite */ +#ifdef WITH_CONTENT_SCAN + TRUE, /* malware */ +#endif TRUE, /* message */ +#ifdef WITH_CONTENT_SCAN + TRUE, /* mime_regex */ +#endif FALSE, /* recipients */ +#ifdef WITH_CONTENT_SCAN + TRUE, /* regex */ +#endif FALSE, /* sender_domains */ FALSE, /* senders */ TRUE, /* set */ +#ifdef WITH_CONTENT_SCAN + TRUE, /* spam */ +#endif TRUE /* verify */ }; @@ -88,6 +139,9 @@ static uschar cond_modifiers[] = { FALSE, /* authenticated */ FALSE, /* condition */ TRUE, /* control */ +#ifdef WITH_CONTENT_SCAN + FALSE, /* decode */ +#endif TRUE, /* delay */ FALSE, /* dnslists */ FALSE, /* domains */ @@ -96,12 +150,24 @@ static uschar cond_modifiers[] = { FALSE, /* hosts */ FALSE, /* local_parts */ TRUE, /* log_message */ - TRUE, /* log_write */ + TRUE, /* logwrite */ +#ifdef WITH_CONTENT_SCAN + FALSE, /* malware */ +#endif TRUE, /* message */ +#ifdef WITH_CONTENT_SCAN + FALSE, /* mime_regex */ +#endif FALSE, /* recipients */ +#ifdef WITH_CONTENT_SCAN + FALSE, /* regex */ +#endif FALSE, /* sender_domains */ FALSE, /* senders */ TRUE, /* set */ +#ifdef WITH_CONTENT_SCAN + FALSE, /* spam */ +#endif FALSE /* verify */ }; @@ -118,6 +184,17 @@ static unsigned int cond_forbids[] = { always and check in the control processing itself */ 0, /* control */ + +#ifdef WITH_CONTENT_SCAN + (1<next) smtp_enforce_sync = FALSE; break; +#ifdef WITH_CONTENT_SCAN + case CONTROL_NO_MBOX_UNSPOOL: + no_mbox_unspool = TRUE; + break; +#endif + case CONTROL_NO_MULTILINE: no_multiline_responses = TRUE; break; +#ifdef WITH_CONTENT_SCAN + case CONTROL_FAKEREJECT: + fake_reject = TRUE; + break; +#endif + case CONTROL_FREEZE: deliver_freeze = TRUE; deliver_frozen_at = time(NULL); @@ -1446,6 +1589,12 @@ for (; cb != NULL; cb = cb->next) } break; +#ifdef WITH_CONTENT_SCAN + case ACLC_DECODE: + rc = mime_decode(&arg); + break; +#endif + case ACLC_DELAY: { int delay = readconf_readtime(arg, 0, FALSE); @@ -1548,12 +1697,42 @@ for (; cb != NULL; cb = cb->next) log_write(0, logbits, "%s", string_printing(s)); } break; + +#ifdef WITH_CONTENT_SCAN + case ACLC_MALWARE: + { + /* Seperate the regular expression and any optional parameters. */ + uschar *ss = string_nextinlist(&arg, &sep, big_buffer, big_buffer_size); + /* Run the malware backend. */ + rc = malware(&ss); + /* Modify return code based upon the existance of options. */ + while ((ss = string_nextinlist(&arg, &sep, big_buffer, big_buffer_size)) + != NULL) { + if (strcmpic(ss, US"defer_ok") == 0 && rc == DEFER) + { + /* FAIL so that the message is passed to the next ACL */ + rc = FAIL; + } + } + } + break; + + case ACLC_MIME_REGEX: + rc = mime_regex(&arg); + break; +#endif case ACLC_RECIPIENTS: rc = match_address_list(addr->address, TRUE, TRUE, &arg, NULL, -1, 0, &recipient_data); break; +#ifdef WITH_CONTENT_SCAN + case ACLC_REGEX: + rc = regex(&arg); + break; +#endif + case ACLC_SENDER_DOMAINS: { uschar *sdomain; @@ -1580,6 +1759,26 @@ for (; cb != NULL; cb = cb->next) } break; +#ifdef WITH_CONTENT_SCAN + case ACLC_SPAM: + { + /* Seperate the regular expression and any optional parameters. */ + uschar *ss = string_nextinlist(&arg, &sep, big_buffer, big_buffer_size); + /* Run the spam backend. */ + rc = spam(&ss); + /* Modify return code based upon the existance of options. */ + while ((ss = string_nextinlist(&arg, &sep, big_buffer, big_buffer_size)) + != NULL) { + if (strcmpic(ss, US"defer_ok") == 0 && rc == DEFER) + { + /* FAIL so that the message is passed to the next ACL */ + rc = FAIL; + } + } + } + break; +#endif + /* If the verb is WARN, discard any user message from verification, because such messages are SMTP responses, not header additions. The latter come only from explicit "message" modifiers. */ diff --git a/src/src/globals.c b/src/src/globals.c index f51033dcb..6fc688654 100644 --- a/src/src/globals.c +++ b/src/src/globals.c @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/globals.c,v 1.8 2004/11/25 13:54:31 ph10 Exp $ */ +/* $Cambridge: exim/src/src/globals.c,v 1.6.2.1 2004/11/25 15:33:55 tom Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -181,6 +181,9 @@ error codes - keep in step with definitions of ACL_WHERE_xxxx in macros.h. */ uschar *acl_wherenames[] = { US"RCPT", US"MAIL", US"PREDATA", +#ifdef WITH_CONTENT_SCAN + US"MIME", +#endif US"DATA", US"non-SMTP", US"AUTH", @@ -197,6 +200,9 @@ uschar *acl_wherenames[] = { US"RCPT", int acl_wherecodes[] = { 550, /* RCPT */ 550, /* MAIL */ 550, /* PREDATA */ +#ifdef WITH_CONTENT_SCAN + 550, /* MIME */ +#endif 550, /* DATA */ 0, /* not SMTP; not relevant */ 503, /* AUTH */ @@ -476,9 +482,7 @@ uschar *extra_local_interfaces = NULL; int filter_n[FILTER_VARIABLE_COUNT]; BOOL filter_running = FALSE; int filter_sn[FILTER_VARIABLE_COUNT]; -int filter_test = FTEST_NONE; -uschar *filter_test_sfile = NULL; -uschar *filter_test_ufile = NULL; +uschar *filter_test = NULL; uschar *filter_thisaddress = NULL; int finduser_retries = 0; uid_t fixed_never_users[] = { FIXED_NEVER_USERS }; @@ -603,7 +607,6 @@ bit_table log_options[] = { { US"outgoing_port", LX_outgoing_port }, { US"queue_run", L_queue_run }, { US"queue_time", LX_queue_time }, - { US"queue_time_overall", LX_queue_time_overall }, { US"received_recipients", LX_received_recipients }, { US"received_sender", LX_received_sender }, { US"rejected_header", LX_rejected_header }, diff --git a/src/src/macros.h b/src/src/macros.h index 996e2e089..94431fc93 100644 --- a/src/src/macros.h +++ b/src/src/macros.h @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/macros.h,v 1.4 2004/11/25 13:54:31 ph10 Exp $ */ +/* $Cambridge: exim/src/src/macros.h,v 1.2.2.1 2004/11/25 15:33:55 tom Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -227,12 +227,6 @@ enum { CEE_EXEC_PANIC /* Panic-die if exec fails */ }; -/* Bit values for filter_test */ - -#define FTEST_NONE 0 /* Not filter testing */ -#define FTEST_USER 1 /* Testing user filter */ -#define FTEST_SYSTEM 2 /* Testing system filter */ - /* Returns from the routing, transport and authentication functions (not all apply to all of them). Some other functions also use these convenient values, and some additional values are used only by non-driver functions. @@ -240,10 +234,10 @@ and some additional values are used only by non-driver functions. OK, FAIL, DEFER, and ERROR are also declared in local_scan.h for use in the local_scan() function. Do not change them unilaterally. */ -#define OK 0 /* Successful match */ -#define DEFER 1 /* Defer - some problem */ -#define FAIL 2 /* Matching failed */ -#define ERROR 3 /* Internal or config error */ +#define OK 0 /* Successful match */ +#define DEFER 1 /* Defer - some problem */ +#define FAIL 2 /* Matching failed */ +#define ERROR 3 /* Internal or config error */ /***********/ #define DECLINE 4 /* Declined to handle the address, pass to next router unless no_more is set */ @@ -367,17 +361,16 @@ only in the name table to set all options in both bit maps. */ #define LX_incoming_port 0x80000020 #define LX_outgoing_port 0x80000040 #define LX_queue_time 0x80000080 -#define LX_queue_time_overall 0x80000100 -#define LX_received_sender 0x80000200 -#define LX_received_recipients 0x80000400 -#define LX_rejected_header 0x80000800 -#define LX_return_path_on_delivery 0x80001000 -#define LX_sender_on_delivery 0x80002000 -#define LX_smtp_confirmation 0x80004000 -#define LX_subject 0x80008000 -#define LX_tls_certificate_verified 0x80010000 -#define LX_tls_cipher 0x80020000 -#define LX_tls_peerdn 0x80040000 +#define LX_received_sender 0x80000100 +#define LX_received_recipients 0x80000200 +#define LX_rejected_header 0x80000400 +#define LX_return_path_on_delivery 0x80000800 +#define LX_sender_on_delivery 0x80001000 +#define LX_smtp_confirmation 0x80002000 +#define LX_subject 0x80004000 +#define LX_tls_certificate_verified 0x80008000 +#define LX_tls_cipher 0x80010000 +#define LX_tls_peerdn 0x80020000 #define L_default (L_connection_reject | \ L_delay_delivery | \ @@ -744,8 +737,13 @@ with the tables of names and response codes in globals.c. */ enum { ACL_WHERE_RCPT, /* Some controls are for RCPT only */ ACL_WHERE_MAIL, /* ) */ ACL_WHERE_PREDATA, /* ) There are several tests for "in message", */ - ACL_WHERE_DATA, /* ) implemented by <= WHERE_NOTSMTP */ - ACL_WHERE_NOTSMTP, /* ) */ + /* ) implemented by <= WHERE_NOTSMTP */ + /* ) */ +#ifdef WITH_CONTENT_SCAN + ACL_WHERE_MIME, +#endif + ACL_WHERE_DATA, + ACL_WHERE_NOTSMTP, ACL_WHERE_AUTH, /* These remaining ones are not currently */ ACL_WHERE_CONNECT, /* required to be in a special order so they */ -- 2.30.2