X-Git-Url: https://git.exim.org/users/jgh/exim.git/blobdiff_plain/69358f0206debf14a18c7e798e23133d304232b6..717d7d98ab74330bc05abf768b8b6a3fa73244ab:/src/src/acl.c diff --git a/src/src/acl.c b/src/src/acl.c index 31087809b..ffd7e9451 100644 --- a/src/src/acl.c +++ b/src/src/acl.c @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/acl.c,v 1.3 2004/10/19 11:04:26 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<special_action = rc; sender_vaddr->next = sender_verified_list; sender_verified_list = sender_vaddr; + + /* Restore the recipient address data, which might have been clobbered by + the sender verification. */ + + deliver_address_data = save_address_data; } + + /* Put the sender address_data value into $sender_address_data */ + + sender_address_data = sender_vaddr->p.address_data; } /* A recipient address just gets a straightforward verify; again we must handle @@ -1072,7 +1239,7 @@ else addr2 = *addr; rc = verify_address(&addr2, NULL, verify_options|vopt_is_recipient, callout, - callout_overall, se_mailfrom, pm_mailfrom, NULL); + callout_overall, callout_connect, se_mailfrom, pm_mailfrom, NULL); HDEBUG(D_acl) debug_printf("----------- end verify ------------\n"); *log_msgptr = addr2.message; *user_msgptr = addr2.user_message; @@ -1369,10 +1536,22 @@ for (; cb != NULL; cb = cb->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); @@ -1410,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); @@ -1512,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; @@ -1544,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. */ @@ -2109,7 +2344,7 @@ else rc = acl_check_internal(where, addr, s, 0, user_msgptr, log_msgptr); smtp_command_argument = deliver_domain = - deliver_localpart = deliver_address_data = NULL; + deliver_localpart = deliver_address_data = sender_address_data = NULL; /* A DISCARD response is permitted only for message ACLs, excluding the PREDATA ACL, which is really in the middle of an SMTP command. */