-/* $Cambridge: exim/src/src/acl.c,v 1.78 2007/08/22 10:10:23 ph10 Exp $ */
+/* $Cambridge: exim/src/src/acl.c,v 1.88 2010/06/06 00:27:52 pdp Exp $ */
/*************************************************
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2007 */
+/* Copyright (c) University of Cambridge 1995 - 2009 */
/* See the file NOTICE for conditions of use and distribution. */
/* Code for handling Access Control Lists (ACLs) */
ACLC_CONDITION,
ACLC_CONTINUE,
ACLC_CONTROL,
+#ifdef EXPERIMENTAL_DCC
+ ACLC_DCC,
+#endif
#ifdef WITH_CONTENT_SCAN
ACLC_DECODE,
#endif
#ifdef WITH_OLD_DEMIME
ACLC_DEMIME,
#endif
-#ifdef EXPERIMENTAL_DOMAINKEYS
- ACLC_DK_DOMAIN_SOURCE,
- ACLC_DK_POLICY,
- ACLC_DK_SENDER_DOMAINS,
- ACLC_DK_SENDER_LOCAL_PARTS,
- ACLC_DK_SENDERS,
- ACLC_DK_STATUS,
+#ifndef DISABLE_DKIM
+ ACLC_DKIM_SIGNER,
+ ACLC_DKIM_STATUS,
#endif
ACLC_DNSLISTS,
ACLC_DOMAINS,
#endif
#ifdef EXPERIMENTAL_SPF
ACLC_SPF,
+ ACLC_SPF_GUESS,
#endif
ACLC_VERIFY };
US"condition",
US"continue",
US"control",
+#ifdef EXPERIMENTAL_DCC
+ US"dcc",
+#endif
#ifdef WITH_CONTENT_SCAN
US"decode",
#endif
#ifdef WITH_OLD_DEMIME
US"demime",
#endif
-#ifdef EXPERIMENTAL_DOMAINKEYS
- US"dk_domain_source",
- US"dk_policy",
- US"dk_sender_domains",
- US"dk_sender_local_parts",
- US"dk_senders",
- US"dk_status",
+#ifndef DISABLE_DKIM
+ US"dkim_signers",
+ US"dkim_status",
#endif
US"dnslists",
US"domains",
#endif
#ifdef EXPERIMENTAL_SPF
US"spf",
+ US"spf_guess",
#endif
US"verify" };
#ifdef EXPERIMENTAL_BRIGHTMAIL
CONTROL_BMI_RUN,
#endif
- #ifdef EXPERIMENTAL_DOMAINKEYS
- CONTROL_DK_VERIFY,
+ CONTROL_DEBUG,
+ #ifndef DISABLE_DKIM
+ CONTROL_DKIM_VERIFY,
#endif
CONTROL_ERROR,
CONTROL_CASEFUL_LOCAL_PART,
#ifdef EXPERIMENTAL_BRIGHTMAIL
US"bmi_run",
#endif
- #ifdef EXPERIMENTAL_DOMAINKEYS
- US"dk_verify",
+ US"debug",
+ #ifndef DISABLE_DKIM
+ US"dkim_disable_verify",
#endif
US"error",
US"caseful_local_part",
TRUE, /* condition */
TRUE, /* continue */
TRUE, /* control */
+#ifdef EXPERIMENTAL_DCC
+ TRUE, /* dcc */
+#endif
#ifdef WITH_CONTENT_SCAN
TRUE, /* decode */
#endif
#ifdef WITH_OLD_DEMIME
TRUE, /* demime */
#endif
-#ifdef EXPERIMENTAL_DOMAINKEYS
- TRUE, /* dk_domain_source */
- TRUE, /* dk_policy */
- TRUE, /* dk_sender_domains */
- TRUE, /* dk_sender_local_parts */
- TRUE, /* dk_senders */
- TRUE, /* dk_status */
+#ifndef DISABLE_DKIM
+ TRUE, /* dkim_signers */
+ TRUE, /* dkim_status */
#endif
TRUE, /* dnslists */
FALSE, /* domains */
#endif
#ifdef EXPERIMENTAL_SPF
TRUE, /* spf */
+ TRUE, /* spf_guess */
#endif
TRUE /* verify */
};
FALSE, /* condition */
TRUE, /* continue */
TRUE, /* control */
+#ifdef EXPERIMENTAL_DCC
+ FALSE, /* dcc */
+#endif
#ifdef WITH_CONTENT_SCAN
FALSE, /* decode */
#endif
#ifdef WITH_OLD_DEMIME
FALSE, /* demime */
#endif
-#ifdef EXPERIMENTAL_DOMAINKEYS
- FALSE, /* dk_domain_source */
- FALSE, /* dk_policy */
- FALSE, /* dk_sender_domains */
- FALSE, /* dk_sender_local_parts */
- FALSE, /* dk_senders */
- FALSE, /* dk_status */
+#ifndef DISABLE_DKIM
+ FALSE, /* dkim_signers */
+ FALSE, /* dkim_status */
#endif
FALSE, /* dnslists */
FALSE, /* domains */
#endif
#ifdef EXPERIMENTAL_SPF
FALSE, /* spf */
+ FALSE, /* spf_guess */
#endif
FALSE /* verify */
};
~((1<<ACL_WHERE_MAIL)|(1<<ACL_WHERE_RCPT)| /* add_header */
(1<<ACL_WHERE_PREDATA)|(1<<ACL_WHERE_DATA)|
(1<<ACL_WHERE_MIME)|(1<<ACL_WHERE_NOTSMTP)|
+ (1<<ACL_WHERE_DKIM)|
(1<<ACL_WHERE_NOTSMTP_START)),
(1<<ACL_WHERE_NOTSMTP)| /* authenticated */
0, /* control */
+ #ifdef EXPERIMENTAL_DCC
+ (unsigned int)
+ ~((1<<ACL_WHERE_DATA)|(1<<ACL_WHERE_NOTSMTP)), /* dcc */
+ #endif
+
#ifdef WITH_CONTENT_SCAN
(unsigned int)
~(1<<ACL_WHERE_MIME), /* decode */
~((1<<ACL_WHERE_DATA)|(1<<ACL_WHERE_NOTSMTP)), /* demime */
#endif
- #ifdef EXPERIMENTAL_DOMAINKEYS
- (1<<ACL_WHERE_AUTH)| /* dk_domain_source */
- (1<<ACL_WHERE_CONNECT)|(1<<ACL_WHERE_HELO)|
- (1<<ACL_WHERE_RCPT)|(1<<ACL_WHERE_PREDATA)|
- (1<<ACL_WHERE_ETRN)|(1<<ACL_WHERE_EXPN)|
- (1<<ACL_WHERE_MAILAUTH)|(1<<ACL_WHERE_QUIT)|
- (1<<ACL_WHERE_MAIL)|(1<<ACL_WHERE_STARTTLS)|
- (1<<ACL_WHERE_VRFY)|(1<<ACL_WHERE_NOTSMTP_START),
-
- (1<<ACL_WHERE_AUTH)| /* dk_policy */
- (1<<ACL_WHERE_CONNECT)|(1<<ACL_WHERE_HELO)|
- (1<<ACL_WHERE_RCPT)|(1<<ACL_WHERE_PREDATA)|
- (1<<ACL_WHERE_ETRN)|(1<<ACL_WHERE_EXPN)|
- (1<<ACL_WHERE_MAILAUTH)|(1<<ACL_WHERE_QUIT)|
- (1<<ACL_WHERE_MAIL)|(1<<ACL_WHERE_STARTTLS)|
- (1<<ACL_WHERE_VRFY)|(1<<ACL_WHERE_NOTSMTP_START),
-
- (1<<ACL_WHERE_AUTH)| /* dk_sender_domains */
- (1<<ACL_WHERE_CONNECT)|(1<<ACL_WHERE_HELO)|
- (1<<ACL_WHERE_RCPT)|(1<<ACL_WHERE_PREDATA)|
- (1<<ACL_WHERE_ETRN)|(1<<ACL_WHERE_EXPN)|
- (1<<ACL_WHERE_MAILAUTH)|(1<<ACL_WHERE_QUIT)|
- (1<<ACL_WHERE_MAIL)|(1<<ACL_WHERE_STARTTLS)|
- (1<<ACL_WHERE_VRFY)|(1<<ACL_WHERE_NOTSMTP_START),
-
- (1<<ACL_WHERE_AUTH)| /* dk_sender_local_parts */
- (1<<ACL_WHERE_CONNECT)|(1<<ACL_WHERE_HELO)|
- (1<<ACL_WHERE_RCPT)|(1<<ACL_WHERE_PREDATA)|
- (1<<ACL_WHERE_ETRN)|(1<<ACL_WHERE_EXPN)|
- (1<<ACL_WHERE_MAILAUTH)|(1<<ACL_WHERE_QUIT)|
- (1<<ACL_WHERE_MAIL)|(1<<ACL_WHERE_STARTTLS)|
- (1<<ACL_WHERE_VRFY)|(1<<ACL_WHERE_NOTSMTP_START),
-
- (1<<ACL_WHERE_AUTH)| /* dk_senders */
- (1<<ACL_WHERE_CONNECT)|(1<<ACL_WHERE_HELO)|
- (1<<ACL_WHERE_RCPT)|(1<<ACL_WHERE_PREDATA)|
- (1<<ACL_WHERE_ETRN)|(1<<ACL_WHERE_EXPN)|
- (1<<ACL_WHERE_MAILAUTH)|(1<<ACL_WHERE_QUIT)|
- (1<<ACL_WHERE_MAIL)|(1<<ACL_WHERE_STARTTLS)|
- (1<<ACL_WHERE_VRFY)|(1<<ACL_WHERE_NOTSMTP_START),
+ #ifndef DISABLE_DKIM
+ (unsigned int)
+ ~(1<<ACL_WHERE_DKIM), /* dkim_signers */
- (1<<ACL_WHERE_AUTH)| /* dk_status */
- (1<<ACL_WHERE_CONNECT)|(1<<ACL_WHERE_HELO)|
- (1<<ACL_WHERE_RCPT)|(1<<ACL_WHERE_PREDATA)|
- (1<<ACL_WHERE_ETRN)|(1<<ACL_WHERE_EXPN)|
- (1<<ACL_WHERE_MAILAUTH)|(1<<ACL_WHERE_QUIT)|
- (1<<ACL_WHERE_MAIL)|(1<<ACL_WHERE_STARTTLS)|
- (1<<ACL_WHERE_VRFY)|(1<<ACL_WHERE_NOTSMTP_START),
+ (unsigned int)
+ ~(1<<ACL_WHERE_DKIM), /* dkim_status */
#endif
(1<<ACL_WHERE_NOTSMTP)| /* dnslists */
(1<<ACL_WHERE_STARTTLS)|(1<<ACL_WHERE_VRFY)|
(1<<ACL_WHERE_NOTSMTP)|
(1<<ACL_WHERE_NOTSMTP_START),
+
+ (1<<ACL_WHERE_AUTH)|(1<<ACL_WHERE_CONNECT)| /* spf_guess */
+ (1<<ACL_WHERE_HELO)|
+ (1<<ACL_WHERE_MAILAUTH)|
+ (1<<ACL_WHERE_ETRN)|(1<<ACL_WHERE_EXPN)|
+ (1<<ACL_WHERE_STARTTLS)|(1<<ACL_WHERE_VRFY)|
+ (1<<ACL_WHERE_NOTSMTP)|
+ (1<<ACL_WHERE_NOTSMTP_START),
#endif
/* Certain types of verify are always allowed, so we let it through
0, /* bmi_run */
#endif
- #ifdef EXPERIMENTAL_DOMAINKEYS
- (1<<ACL_WHERE_DATA)|(1<<ACL_WHERE_NOTSMTP)| /* dk_verify */
+ 0, /* debug */
+
+ #ifndef DISABLE_DKIM
+ (1<<ACL_WHERE_DATA)|(1<<ACL_WHERE_NOTSMTP)| /* dkim_disable_verify */
(1<<ACL_WHERE_NOTSMTP_START),
#endif
#ifdef EXPERIMENTAL_BRIGHTMAIL
{ US"bmi_run", CONTROL_BMI_RUN, FALSE },
#endif
-#ifdef EXPERIMENTAL_DOMAINKEYS
- { US"dk_verify", CONTROL_DK_VERIFY, FALSE },
+ { US"debug", CONTROL_DEBUG, TRUE },
+#ifndef DISABLE_DKIM
+ { US"dkim_disable_verify", CONTROL_DKIM_VERIFY, FALSE },
#endif
{ US"caseful_local_part", CONTROL_CASEFUL_LOCAL_PART, FALSE },
{ US"caselower_local_part", CONTROL_CASELOWER_LOCAL_PART, FALSE },
{
uschar *user_message = NULL;
uschar *log_message = NULL;
+uschar *debug_tag = NULL;
+uschar *debug_opts = NULL;
uschar *p = NULL;
int rc = OK;
#ifdef WITH_CONTENT_SCAN
#endif
case ACLC_CONDITION:
+ /* The true/false parsing here should be kept in sync with that used in
+ expand.c when dealing with ECOND_BOOL so that we don't have too many
+ different definitions of what can be a boolean. */
if (Ustrspn(arg, "0123456789") == Ustrlen(arg)) /* Digits, or empty */
rc = (Uatoi(arg) == 0)? FAIL : OK;
else
break;
#endif
- #ifdef EXPERIMENTAL_DOMAINKEYS
- case CONTROL_DK_VERIFY:
- dk_do_verify = 1;
+ #ifndef DISABLE_DKIM
+ case CONTROL_DKIM_VERIFY:
+ dkim_disable_verify = TRUE;
break;
#endif
}
break;
+ case CONTROL_DEBUG:
+ while (*p == '/')
+ {
+ if (Ustrncmp(p, "/tag=", 5) == 0)
+ {
+ uschar *pp = p + 5;
+ while (*pp != '\0' && *pp != '/') pp++;
+ debug_tag = string_copyn(p+5, pp-p-5);
+ p = pp;
+ }
+ else if (Ustrncmp(p, "/opts=", 6) == 0)
+ {
+ uschar *pp = p + 6;
+ while (*pp != '\0' && *pp != '/') pp++;
+ debug_opts = string_copyn(p+6, pp-p-6);
+ p = pp;
+ }
+ }
+ debug_logging_activate(debug_tag, debug_opts);
+ break;
+
case CONTROL_SUPPRESS_LOCAL_FIXUPS:
suppress_local_fixups = TRUE;
break;
}
break;
+ #ifdef EXPERIMENTAL_DCC
+ case ACLC_DCC:
+ {
+ /* Seperate the regular expression and any optional parameters. */
+ uschar *ss = string_nextinlist(&arg, &sep, big_buffer, big_buffer_size);
+ /* Run the dcc backend. */
+ rc = dcc_process(&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 WITH_CONTENT_SCAN
case ACLC_DECODE:
rc = mime_decode(&arg);
break;
#endif
- #ifdef EXPERIMENTAL_DOMAINKEYS
- case ACLC_DK_DOMAIN_SOURCE:
- if (dk_verify_block == NULL) { rc = FAIL; break; };
- /* check header source of domain against given string */
- switch (dk_verify_block->address_source) {
- case DK_EXIM_ADDRESS_FROM_FROM:
- rc = match_isinlist(US"from", &arg, 0, NULL,
- NULL, MCL_STRING, TRUE, NULL);
- break;
- case DK_EXIM_ADDRESS_FROM_SENDER:
- rc = match_isinlist(US"sender", &arg, 0, NULL,
- NULL, MCL_STRING, TRUE, NULL);
- break;
- case DK_EXIM_ADDRESS_NONE:
- rc = match_isinlist(US"none", &arg, 0, NULL,
- NULL, MCL_STRING, TRUE, NULL);
- break;
- }
- break;
-
- case ACLC_DK_POLICY:
- if (dk_verify_block == NULL) { rc = FAIL; break; };
- /* check policy against given string, default FAIL */
- rc = FAIL;
- if (dk_verify_block->signsall)
- rc = match_isinlist(US"signsall", &arg, 0, NULL,
- NULL, MCL_STRING, TRUE, NULL);
- if (dk_verify_block->testing)
- rc = match_isinlist(US"testing", &arg, 0, NULL,
- NULL, MCL_STRING, TRUE, NULL);
- break;
-
- case ACLC_DK_SENDER_DOMAINS:
- if (dk_verify_block == NULL) { rc = FAIL; break; };
- if (dk_verify_block->domain != NULL)
- rc = match_isinlist(dk_verify_block->domain, &arg, 0, &domainlist_anchor,
- NULL, MCL_DOMAIN, TRUE, NULL);
- else rc = FAIL;
- break;
-
- case ACLC_DK_SENDER_LOCAL_PARTS:
- if (dk_verify_block == NULL) { rc = FAIL; break; };
- if (dk_verify_block->local_part != NULL)
- rc = match_isinlist(dk_verify_block->local_part, &arg, 0, &localpartlist_anchor,
- NULL, MCL_LOCALPART, TRUE, NULL);
- else rc = FAIL;
- break;
-
- case ACLC_DK_SENDERS:
- if (dk_verify_block == NULL) { rc = FAIL; break; };
- if (dk_verify_block->address != NULL)
- rc = match_address_list(dk_verify_block->address, TRUE, TRUE, &arg, NULL, -1, 0, NULL);
- else rc = FAIL;
+ #ifndef DISABLE_DKIM
+ case ACLC_DKIM_SIGNER:
+ if (dkim_cur_signer != NULL)
+ rc = match_isinlist(dkim_cur_signer,
+ &arg,0,NULL,NULL,MCL_STRING,TRUE,NULL);
+ else
+ rc = FAIL;
break;
- case ACLC_DK_STATUS:
- if (dk_verify_block == NULL) { rc = FAIL; break; };
- if (dk_verify_block->result > 0) {
- switch(dk_verify_block->result) {
- case DK_EXIM_RESULT_BAD_FORMAT:
- rc = match_isinlist(US"bad format", &arg, 0, NULL,
- NULL, MCL_STRING, TRUE, NULL);
- break;
- case DK_EXIM_RESULT_NO_KEY:
- rc = match_isinlist(US"no key", &arg, 0, NULL,
- NULL, MCL_STRING, TRUE, NULL);
- break;
- case DK_EXIM_RESULT_NO_SIGNATURE:
- rc = match_isinlist(US"no signature", &arg, 0, NULL,
- NULL, MCL_STRING, TRUE, NULL);
- break;
- case DK_EXIM_RESULT_REVOKED:
- rc = match_isinlist(US"revoked", &arg, 0, NULL,
- NULL, MCL_STRING, TRUE, NULL);
- break;
- case DK_EXIM_RESULT_NON_PARTICIPANT:
- rc = match_isinlist(US"non-participant", &arg, 0, NULL,
- NULL, MCL_STRING, TRUE, NULL);
- break;
- case DK_EXIM_RESULT_GOOD:
- rc = match_isinlist(US"good", &arg, 0, NULL,
- NULL, MCL_STRING, TRUE, NULL);
- break;
- case DK_EXIM_RESULT_BAD:
- rc = match_isinlist(US"bad", &arg, 0, NULL,
- NULL, MCL_STRING, TRUE, NULL);
- break;
- }
- }
+ case ACLC_DKIM_STATUS:
+ rc = match_isinlist(dkim_exim_expand_query(DKIM_VERIFY_STATUS),
+ &arg,0,NULL,NULL,MCL_STRING,TRUE,NULL);
break;
#endif
#ifdef EXPERIMENTAL_SPF
case ACLC_SPF:
- rc = spf_process(&arg, sender_address);
+ rc = spf_process(&arg, sender_address, SPF_PROCESS_NORMAL);
+ break;
+ case ACLC_SPF_GUESS:
+ rc = spf_process(&arg, sender_address, SPF_PROCESS_GUESS);
break;
#endif
*log_msgptr = *user_msgptr = NULL;
acl_temp_details = FALSE;
- if (where == ACL_WHERE_QUIT &&
+ if ((where == ACL_WHERE_QUIT || where == ACL_WHERE_NOTQUIT) &&
acl->verb != ACL_ACCEPT &&
acl->verb != ACL_WARN)
{
- *log_msgptr = string_sprintf("\"%s\" is not allowed in a QUIT ACL",
+ *log_msgptr = string_sprintf("\"%s\" is not allowed in a QUIT or not-QUIT ACL",
verbs[acl->verb]);
return ERROR;
}