Integrated SPF Best Guess. Fixes: bug #521
[exim.git] / src / src / acl.c
index 9c613442292ae2fea33ee7635fd5a93fd0586d01..fcafc6b5812dfdb18cdb29eb644b5214ae0931d5 100644 (file)
@@ -1,4 +1,4 @@
-/* $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.82 2008/02/12 12:52:51 nm4 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -55,6 +55,9 @@ enum { ACLC_ACL,
        ACLC_CONDITION,
        ACLC_CONTINUE,
        ACLC_CONTROL,
+#ifdef EXPERIMENTAL_DCC
+       ACLC_DCC,
+#endif
 #ifdef WITH_CONTENT_SCAN
        ACLC_DECODE,
 #endif
@@ -99,6 +102,7 @@ enum { ACLC_ACL,
 #endif
 #ifdef EXPERIMENTAL_SPF
        ACLC_SPF,
+       ACLC_SPF_GUESS,
 #endif
        ACLC_VERIFY };
 
@@ -117,6 +121,9 @@ static uschar *conditions[] = {
   US"condition",
   US"continue",
   US"control",
+#ifdef EXPERIMENTAL_DCC
+  US"dcc",
+#endif
 #ifdef WITH_CONTENT_SCAN
   US"decode",
 #endif
@@ -159,6 +166,7 @@ static uschar *conditions[] = {
 #endif
 #ifdef EXPERIMENTAL_SPF
   US"spf",
+  US"spf_guess",
 #endif
   US"verify" };
 
@@ -174,6 +182,9 @@ enum {
   #ifdef EXPERIMENTAL_DOMAINKEYS
   CONTROL_DK_VERIFY,
   #endif
+  #ifdef EXPERIMENTAL_DKIM
+  CONTROL_DKIM_VERIFY,
+  #endif
   CONTROL_ERROR,
   CONTROL_CASEFUL_LOCAL_PART,
   CONTROL_CASELOWER_LOCAL_PART,
@@ -207,6 +218,9 @@ static uschar *controls[] = {
   #ifdef EXPERIMENTAL_DOMAINKEYS
   US"dk_verify",
   #endif
+  #ifdef EXPERIMENTAL_DKIM
+  US"dkim_verify",
+  #endif
   US"error",
   US"caseful_local_part",
   US"caselower_local_part",
@@ -241,6 +255,9 @@ static uschar cond_expand_at_top[] = {
   TRUE,    /* condition */
   TRUE,    /* continue */
   TRUE,    /* control */
+#ifdef EXPERIMENTAL_DCC
+  TRUE,    /* dcc */
+#endif
 #ifdef WITH_CONTENT_SCAN
   TRUE,    /* decode */
 #endif
@@ -285,6 +302,7 @@ static uschar cond_expand_at_top[] = {
 #endif
 #ifdef EXPERIMENTAL_SPF
   TRUE,    /* spf */
+  TRUE,    /* spf_guess */
 #endif
   TRUE     /* verify */
 };
@@ -301,6 +319,9 @@ static uschar cond_modifiers[] = {
   FALSE,   /* condition */
   TRUE,    /* continue */
   TRUE,    /* control */
+#ifdef EXPERIMENTAL_DCC
+  FALSE,   /* dcc */
+#endif
 #ifdef WITH_CONTENT_SCAN
   FALSE,   /* decode */
 #endif
@@ -345,6 +366,7 @@ static uschar cond_modifiers[] = {
 #endif
 #ifdef EXPERIMENTAL_SPF
   FALSE,   /* spf */
+  FALSE,   /* spf_guess */
 #endif
   FALSE    /* verify */
 };
@@ -387,6 +409,11 @@ static unsigned int cond_forbids[] = {
 
   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 */
@@ -524,6 +551,14 @@ static unsigned int cond_forbids[] = {
     (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
@@ -550,6 +585,11 @@ static unsigned int control_forbids[] = {
     (1<<ACL_WHERE_NOTSMTP_START),
   #endif
 
+  #ifdef EXPERIMENTAL_DKIM
+  (1<<ACL_WHERE_DATA)|(1<<ACL_WHERE_NOTSMTP)|      /* dkim_verify */
+    (1<<ACL_WHERE_NOTSMTP_START),
+  #endif
+
   0,                                               /* error */
 
   (unsigned int)
@@ -628,6 +668,9 @@ static control_def controls_list[] = {
 #endif
 #ifdef EXPERIMENTAL_DOMAINKEYS
   { US"dk_verify",               CONTROL_DK_VERIFY, FALSE },
+#endif
+#ifdef EXPERIMENTAL_DKIM
+  { US"dkim_verify",             CONTROL_DKIM_VERIFY, FALSE },
 #endif
   { US"caseful_local_part",      CONTROL_CASEFUL_LOCAL_PART, FALSE },
   { US"caselower_local_part",    CONTROL_CASELOWER_LOCAL_PART, FALSE },
@@ -2613,6 +2656,12 @@ for (; cb != NULL; cb = cb->next)
       break;
       #endif
 
+      #ifdef EXPERIMENTAL_DKIM
+      case CONTROL_DKIM_VERIFY:
+      dkim_do_verify = 1;
+      break;
+      #endif
+
       case CONTROL_ERROR:
       return ERROR;
 
@@ -2734,6 +2783,26 @@ for (; cb != NULL; cb = cb->next)
       }
     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);
@@ -3077,7 +3146,10 @@ for (; cb != NULL; cb = cb->next)
 
     #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
 
@@ -3456,11 +3528,11 @@ while (acl != NULL)
   *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;
     }