-/* $Cambridge: exim/src/src/acl.c,v 1.5.2.3 2004/12/02 16:33:30 tom Exp $ */
+/* $Cambridge: exim/src/src/acl.c,v 1.5.2.5 2004/12/10 14:59:08 tom Exp $ */
/*************************************************
* Exim - an Internet mail transport agent *
/* ACL condition and modifier codes - keep in step with the table that
follows. */
-enum { ACLC_ACL, ACLC_AUTHENTICATED, ACLC_CONDITION, ACLC_CONTROL,
+enum { ACLC_ACL, ACLC_AUTHENTICATED,
+#ifdef EXPERIMENTAL_BRIGHTMAIL
+ ACLC_BMI_OPTIN,
+#endif
+ACLC_CONDITION, ACLC_CONTROL,
#ifdef WITH_CONTENT_SCAN
ACLC_DECODE,
#endif
ACLC_SENDER_DOMAINS, ACLC_SENDERS, ACLC_SET,
#ifdef WITH_CONTENT_SCAN
ACLC_SPAM,
+#endif
+#ifdef EXPERIMENTAL_SPF
+ ACLC_SPF,
#endif
ACLC_VERIFY };
"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",
+static uschar *conditions[] = { US"acl", US"authenticated",
+#ifdef EXPERIMENTAL_BRIGHTMAIL
+ US"bmi_optin",
+#endif
+ US"condition",
US"control",
#ifdef WITH_CONTENT_SCAN
US"decode",
US"sender_domains", US"senders", US"set",
#ifdef WITH_CONTENT_SCAN
US"spam",
+#endif
+#ifdef EXPERIMENTAL_SPF
+ US"spf",
#endif
US"verify" };
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, /* set */
#ifdef WITH_CONTENT_SCAN
TRUE, /* spam */
+#endif
+#ifdef EXPERIMENTAL_SPF
+ TRUE, /* spf */
#endif
TRUE /* verify */
};
static uschar cond_modifiers[] = {
FALSE, /* acl */
FALSE, /* authenticated */
+#ifdef EXPERIMENTAL_BRIGHTMAIL
+ TRUE, /* bmi_optin */
+#endif
FALSE, /* condition */
TRUE, /* control */
#ifdef WITH_CONTENT_SCAN
TRUE, /* set */
#ifdef WITH_CONTENT_SCAN
FALSE, /* spam */
+#endif
+#ifdef EXPERIMENTAL_SPF
+ FALSE, /* spf */
#endif
FALSE /* verify */
};
0, /* acl */
(1<<ACL_WHERE_NOTSMTP)|(1<<ACL_WHERE_CONNECT)| /* authenticated */
(1<<ACL_WHERE_HELO),
+
+#ifdef EXPERIMENTAL_BRIGHTMAIL
+ (1<<ACL_WHERE_NOTSMTP)|(1<<ACL_WHERE_AUTH)| /* bmi_optin */
+ (1<<ACL_WHERE_CONNECT)|(1<<ACL_WHERE_HELO)|
+ (1<<ACL_WHERE_DATA)|(1<<ACL_WHERE_MIME)|
+ (1<<ACL_WHERE_ETRN)|(1<<ACL_WHERE_EXPN)|
+ (1<<ACL_WHERE_MAILAUTH)|
+ (1<<ACL_WHERE_MAIL)|(1<<ACL_WHERE_STARTTLS)|
+ (1<<ACL_WHERE_VRFY)|(1<<ACL_WHERE_PREDATA),
+#endif
+
0, /* condition */
-
+
/* Certain types of control are always allowed, so we let it through
always and check in the control processing itself */
-
+
0, /* control */
-
+
#ifdef WITH_CONTENT_SCAN
(1<<ACL_WHERE_NOTSMTP)|(1<<ACL_WHERE_AUTH)| /* decode */
(1<<ACL_WHERE_CONNECT)|(1<<ACL_WHERE_HELO)|
(1<<ACL_WHERE_VRFY)|(1<<ACL_WHERE_MIME),
#endif
+#ifdef EXPERIMENTAL_SPF
+ (1<<ACL_WHERE_AUTH)|(1<<ACL_WHERE_CONNECT)| /* spf */
+ (1<<ACL_WHERE_HELO)|
+ (1<<ACL_WHERE_MAILAUTH)|
+ (1<<ACL_WHERE_ETRN)|(1<<ACL_WHERE_EXPN)|
+ (1<<ACL_WHERE_STARTTLS)|(1<<ACL_WHERE_VRFY),
+#endif
+
/* Certain types of verify are always allowed, so we let it through
always and check in the verify function itself */
/* Return values from decode_control() */
-enum { CONTROL_ERROR, CONTROL_CASEFUL_LOCAL_PART, CONTROL_CASELOWER_LOCAL_PART,
+enum {
+#ifdef EXPERIMENTAL_BRIGHTMAIL
+ CONTROL_BMI_RUN,
+#endif
+ CONTROL_ERROR, CONTROL_CASEFUL_LOCAL_PART, CONTROL_CASELOWER_LOCAL_PART,
CONTROL_ENFORCE_SYNC, CONTROL_NO_ENFORCE_SYNC, CONTROL_FREEZE,
CONTROL_QUEUE_ONLY, CONTROL_SUBMISSION,
#ifdef WITH_CONTENT_SCAN
specify the negation of a small number of allowed times. */
static unsigned int control_forbids[] = {
+#ifdef EXPERIMENTAL_BRIGHTMAIL
+ 0, /* bmi_run */
+#endif
0, /* error */
~(1<<ACL_WHERE_RCPT), /* caseful_local_part */
~(1<<ACL_WHERE_RCPT), /* caselower_local_part */
} control_def;
static control_def controls_list[] = {
+#ifdef EXPERIMENTAL_BRIGHTMAIL
+ { US"bmi_run", CONTROL_BMI_RUN, FALSE},
+#endif
{ US"caseful_local_part", CONTROL_CASEFUL_LOCAL_PART, FALSE},
{ US"caselower_local_part", CONTROL_CASELOWER_LOCAL_PART, FALSE},
{ US"enforce_sync", CONTROL_ENFORCE_SYNC, FALSE},
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;
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;
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)
{
switch(control_type)
{
+#ifdef EXPERIMENTAL_BRIGHTMAIL
+ case CONTROL_BMI_RUN:
+ bmi_run = 1;
+ break;
+#endif
+
case CONTROL_ERROR:
return ERROR;
#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
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. */