Added DomainKeys support. See doc/experimental-spec.txt for documentation.
[exim.git] / src / src / acl.c
index 7b176b690ad6eff339713a2ea99501600cbaf83b..439e9d424568461939478640eaf00fae60d60ff0 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/acl.c,v 1.19 2005/02/17 11:58:25 ph10 Exp $ */
+/* $Cambridge: exim/src/src/acl.c,v 1.20 2005/03/08 15:32:02 tom Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -45,6 +45,14 @@ ACLC_CONDITION, ACLC_CONTROL,
        ACLC_DELAY,
 #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,
 #endif
        ACLC_DNSLISTS, ACLC_DOMAINS, ACLC_ENCRYPTED, ACLC_ENDPASS,
        ACLC_HOSTS, ACLC_LOCAL_PARTS, ACLC_LOG_MESSAGE, ACLC_LOGWRITE,
@@ -84,6 +92,14 @@ static uschar *conditions[] = { US"acl", US"authenticated",
   US"delay",
 #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",
 #endif
   US"dnslists", US"domains", US"encrypted",
   US"endpass", US"hosts", US"local_parts", US"log_message", US"logwrite",
@@ -131,6 +147,14 @@ static uschar cond_expand_at_top[] = {
   TRUE,    /* delay */
 #ifdef WITH_OLD_DEMIME
   TRUE,    /* demime */
+#endif
+#ifdef EXPERIMENTAL_DOMAINKEYS
+  TRUE,
+  TRUE,
+  TRUE,
+  TRUE,
+  TRUE,
+  TRUE,
 #endif
   TRUE,    /* dnslists */
   FALSE,   /* domains */
@@ -179,6 +203,14 @@ static uschar cond_modifiers[] = {
   TRUE,    /* delay */
 #ifdef WITH_OLD_DEMIME
   FALSE,   /* demime */
+#endif
+#ifdef EXPERIMENTAL_DOMAINKEYS
+  FALSE,
+  FALSE,
+  FALSE,
+  FALSE,
+  FALSE,
+  FALSE,
 #endif
   FALSE,   /* dnslists */
   FALSE,   /* domains */
@@ -259,6 +291,56 @@ static unsigned int cond_forbids[] = {
     (1<<ACL_WHERE_VRFY)|(1<<ACL_WHERE_MIME),
 #endif
 
+#ifdef EXPERIMENTAL_DOMAINKEYS
+  (1<<ACL_WHERE_AUTH)|
+    (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_AUTH)|
+    (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_AUTH)|
+    (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_AUTH)|
+    (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_AUTH)|
+    (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_AUTH)|
+    (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),
+#endif
+
   (1<<ACL_WHERE_NOTSMTP),                          /* dnslists */
 
   (1<<ACL_WHERE_NOTSMTP)|(1<<ACL_WHERE_AUTH)|      /* domains */
@@ -372,6 +454,9 @@ static unsigned int cond_forbids[] = {
 enum {
 #ifdef EXPERIMENTAL_BRIGHTMAIL
   CONTROL_BMI_RUN,
+#endif
+#ifdef EXPERIMENTAL_DOMAINKEYS
+  CONTROL_DK_VERIFY,
 #endif
   CONTROL_ERROR, CONTROL_CASEFUL_LOCAL_PART, CONTROL_CASELOWER_LOCAL_PART,
   CONTROL_ENFORCE_SYNC, CONTROL_NO_ENFORCE_SYNC, CONTROL_FREEZE,
@@ -389,6 +474,9 @@ static unsigned int control_forbids[] = {
 #ifdef EXPERIMENTAL_BRIGHTMAIL
   0,                                               /* bmi_run */
 #endif
+#ifdef EXPERIMENTAL_DOMAINKEYS
+  (1<<ACL_WHERE_PREDATA)|(1<<ACL_WHERE_DATA),      /* dk_verify */
+#endif
 
   0,                                               /* error */
 
@@ -440,6 +528,9 @@ typedef struct control_def {
 static control_def controls_list[] = {
 #ifdef EXPERIMENTAL_BRIGHTMAIL
   { US"bmi_run",                CONTROL_BMI_RUN, FALSE},
+#endif
+#ifdef EXPERIMENTAL_DOMAINKEYS
+  { US"dk_verify",              CONTROL_DK_VERIFY, FALSE},
 #endif
   { US"caseful_local_part",     CONTROL_CASEFUL_LOCAL_PART, FALSE},
   { US"caselower_local_part",   CONTROL_CASELOWER_LOCAL_PART, FALSE},
@@ -1648,7 +1739,11 @@ for (; cb != NULL; cb = cb->next)
       bmi_run = 1;
       break;
 #endif
-
+#ifdef EXPERIMENTAL_DOMAINKEYS
+      case CONTROL_DK_VERIFY:
+      dk_do_verify = 1;
+      break;
+#endif
       case CONTROL_ERROR:
       return ERROR;
 
@@ -1769,6 +1864,93 @@ for (; cb != NULL; cb = cb->next)
     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;
+  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;
+      }
+    }
+  break;
+#endif
+
     case ACLC_DNSLISTS:
     rc = verify_check_dnsbl(&arg);
     break;