X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/59e887032e6e328e62a16566d403715975414ee2..8523533c08c018ac4b750b0e0fab6cfe611e8a49:/src/src/acl.c diff --git a/src/src/acl.c b/src/src/acl.c index 92ebc18ec..247ffbb62 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.6 2004/12/16 15:11:47 tom Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -34,19 +34,77 @@ 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, +#ifdef EXPERIMENTAL_BRIGHTMAIL + ACLC_BMI_OPTIN, +#endif +ACLC_CONDITION, ACLC_CONTROL, +#ifdef WITH_CONTENT_SCAN + ACLC_DECODE, +#endif + ACLC_DELAY, +#ifdef WITH_OLD_DEMIME + ACLC_DEMIME, +#endif + 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 +#ifdef EXPERIMENTAL_SPF + ACLC_SPF, +#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", +static uschar *conditions[] = { US"acl", US"authenticated", +#ifdef EXPERIMENTAL_BRIGHTMAIL + US"bmi_optin", +#endif + US"condition", + US"control", +#ifdef WITH_CONTENT_SCAN + US"decode", +#endif + US"delay", +#ifdef WITH_OLD_DEMIME + US"demime", +#endif + 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 +#ifdef EXPERIMENTAL_SPF + US"spf", +#endif US"verify" }; /* ACL control names */ @@ -62,9 +120,18 @@ checking functions. */ static uschar cond_expand_at_top[] = { TRUE, /* acl */ FALSE, /* authenticated */ +#ifdef EXPERIMENTAL_BRIGHTMAIL + TRUE, /* bmi_optin */ +#endif TRUE, /* condition */ TRUE, /* control */ +#ifdef WITH_CONTENT_SCAN + TRUE, /* decode */ +#endif TRUE, /* delay */ +#ifdef WITH_OLD_DEMIME + TRUE, /* demime */ +#endif TRUE, /* dnslists */ FALSE, /* domains */ FALSE, /* encrypted */ @@ -73,11 +140,26 @@ 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 +#ifdef EXPERIMENTAL_SPF + TRUE, /* spf */ +#endif TRUE /* verify */ }; @@ -86,9 +168,18 @@ static uschar cond_expand_at_top[] = { static uschar cond_modifiers[] = { FALSE, /* acl */ FALSE, /* authenticated */ +#ifdef EXPERIMENTAL_BRIGHTMAIL + TRUE, /* bmi_optin */ +#endif FALSE, /* condition */ TRUE, /* control */ +#ifdef WITH_CONTENT_SCAN + FALSE, /* decode */ +#endif TRUE, /* delay */ +#ifdef WITH_OLD_DEMIME + FALSE, /* demime */ +#endif FALSE, /* dnslists */ FALSE, /* domains */ FALSE, /* encrypted */ @@ -96,12 +187,27 @@ 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 +#ifdef EXPERIMENTAL_SPF + FALSE, /* spf */ +#endif FALSE /* verify */ }; @@ -112,13 +218,46 @@ static unsigned int cond_forbids[] = { 0, /* acl */ (1< 0) newtype = htype_add_rec; p += 16; } + else if (strncmpic(p, US":at_start_rfc:", 14) == 0) + { + newtype = htype_add_rfc; + p += 14; + } else if (strncmpic(p, US":at_start:", 10) == 0) { newtype = htype_add_top; @@ -1253,6 +1469,9 @@ uschar *user_message = NULL; uschar *log_message = NULL; uschar *p; int rc = OK; +#ifdef WITH_CONTENT_SCAN +int sep = '/'; +#endif for (; cb != NULL; cb = cb->next) { @@ -1360,6 +1579,17 @@ for (; cb != NULL; cb = cb->next) TRUE, NULL); break; +#ifdef EXPERIMENTAL_BRIGHTMAIL + case ACLC_BMI_OPTIN: + { + int old_pool = store_pool; + store_pool = POOL_PERM; + bmi_current_optin = string_copy(arg); + store_pool = old_pool; + } + break; +#endif + case ACLC_CONDITION: if (Ustrspn(arg, "0123456789") == Ustrlen(arg)) /* Digits, or empty */ rc = (Uatoi(arg) == 0)? FAIL : OK; @@ -1375,7 +1605,7 @@ for (; cb != NULL; cb = cb->next) case ACLC_CONTROL: control_type = decode_control(arg, &p, where, log_msgptr); - /* Check this control makes sense at this time */ + /* Check if this control makes sense at this time */ if ((control_forbids[control_type] & (1 << where)) != 0) { @@ -1386,6 +1616,12 @@ for (; cb != NULL; cb = cb->next) switch(control_type) { +#ifdef EXPERIMENTAL_BRIGHTMAIL + case CONTROL_BMI_RUN: + bmi_run = 1; + break; +#endif + case CONTROL_ERROR: return ERROR; @@ -1405,10 +1641,34 @@ 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; + if (*p == '/') + { + uschar *pp = p + 1; + while (*pp != 0) pp++; + fake_reject_text = expand_string(string_copyn(p+1, pp-p)); + p = pp; + } + else + { + /* Explicitly reset to default string */ + fake_reject_text = US"Your message has been rejected but is being kept for evaluation.\nIf it was a legit message, it may still be delivered to the target recipient(s)."; + } + break; +#endif + case CONTROL_FREEZE: deliver_freeze = TRUE; deliver_frozen_at = time(NULL); @@ -1446,6 +1706,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); @@ -1469,6 +1735,12 @@ for (; cb != NULL; cb = cb->next) } break; +#ifdef WITH_OLD_DEMIME + case ACLC_DEMIME: + rc = demime(&arg); + break; +#endif + case ACLC_DNSLISTS: rc = verify_check_dnsbl(&arg); break; @@ -1548,12 +1820,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 +1882,32 @@ 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 + +#ifdef EXPERIMENTAL_SPF + case ACLC_SPF: + rc = spf_process(&arg, sender_address); + 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. */