Fix condition and control permission tables for the MIME ACL
[exim.git] / src / src / acl.c
index dc3951221933385b81fec912ee03d4d3e28816ca..70ce7368c0096ff7114e65f8e3248cc83d8d0565 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/acl.c,v 1.14 2005/01/12 12:51:55 ph10 Exp $ */
+/* $Cambridge: exim/src/src/acl.c,v 1.23 2005/03/09 14:36:54 tom Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -45,7 +45,15 @@ ACLC_CONDITION, ACLC_CONTROL,
        ACLC_DELAY,
 #ifdef WITH_OLD_DEMIME
        ACLC_DEMIME,
-#endif        
+#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,
 #ifdef WITH_CONTENT_SCAN
@@ -61,7 +69,7 @@ ACLC_CONDITION, ACLC_CONTROL,
 #endif
        ACLC_SENDER_DOMAINS, ACLC_SENDERS, ACLC_SET,
 #ifdef WITH_CONTENT_SCAN
-       ACLC_SPAM,       
+       ACLC_SPAM,
 #endif
 #ifdef EXPERIMENTAL_SPF
        ACLC_SPF,
@@ -77,13 +85,21 @@ static uschar *conditions[] = { US"acl", US"authenticated",
   US"bmi_optin",
 #endif
   US"condition",
-  US"control", 
+  US"control",
 #ifdef WITH_CONTENT_SCAN
   US"decode",
 #endif
   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",
@@ -106,12 +122,12 @@ static uschar *conditions[] = { US"acl", US"authenticated",
   US"spf",
 #endif
   US"verify" };
-  
+
 /* ACL control names */
 
 static uschar *controls[] = { US"error", US"caseful_local_part",
   US"caselower_local_part", US"enforce_sync", US"no_enforce_sync", US"freeze",
-  US"queue_only", US"submission", US"no_multiline"}; 
+  US"queue_only", US"submission", US"no_multiline"};
 
 /* Flags to indicate for which conditions /modifiers a string expansion is done
 at the outer level. In the other cases, expansion already occurs in the
@@ -122,7 +138,7 @@ static uschar cond_expand_at_top[] = {
   FALSE,   /* authenticated */
 #ifdef EXPERIMENTAL_BRIGHTMAIL
   TRUE,    /* bmi_optin */
-#endif  
+#endif
   TRUE,    /* condition */
   TRUE,    /* control */
 #ifdef WITH_CONTENT_SCAN
@@ -131,6 +147,14 @@ static uschar cond_expand_at_top[] = {
   TRUE,    /* delay */
 #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 */            
 #endif
   TRUE,    /* dnslists */
   FALSE,   /* domains */
@@ -170,7 +194,7 @@ static uschar cond_modifiers[] = {
   FALSE,   /* authenticated */
 #ifdef EXPERIMENTAL_BRIGHTMAIL
   TRUE,    /* bmi_optin */
-#endif  
+#endif
   FALSE,   /* condition */
   TRUE,    /* control */
 #ifdef WITH_CONTENT_SCAN
@@ -179,6 +203,14 @@ static uschar cond_modifiers[] = {
   TRUE,    /* delay */
 #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 */            
 #endif
   FALSE,   /* dnslists */
   FALSE,   /* domains */
@@ -216,27 +248,27 @@ each condition, there's a bitmap of dis-allowed times. */
 
 static unsigned int cond_forbids[] = {
   0,                                               /* acl */
-   
+
   (1<<ACL_WHERE_NOTSMTP)|(1<<ACL_WHERE_CONNECT)|   /* authenticated */
     (1<<ACL_WHERE_HELO),
-  
+
 #ifdef EXPERIMENTAL_BRIGHTMAIL
   (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_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_AUTH)|                             /* decode */
     (1<<ACL_WHERE_CONNECT)|(1<<ACL_WHERE_HELO)|
@@ -248,7 +280,7 @@ static unsigned int cond_forbids[] = {
 #endif
 
   0,                                               /* delay */
-  
+
 #ifdef WITH_OLD_DEMIME
   (1<<ACL_WHERE_AUTH)|                             /* demime */
     (1<<ACL_WHERE_CONNECT)|(1<<ACL_WHERE_HELO)|
@@ -258,7 +290,57 @@ static unsigned int cond_forbids[] = {
     (1<<ACL_WHERE_MAIL)|(1<<ACL_WHERE_STARTTLS)|
     (1<<ACL_WHERE_VRFY)|(1<<ACL_WHERE_MIME),
 #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_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_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_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_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_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),
+#endif
+
   (1<<ACL_WHERE_NOTSMTP),                          /* dnslists */
 
   (1<<ACL_WHERE_NOTSMTP)|(1<<ACL_WHERE_AUTH)|      /* domains */
@@ -271,9 +353,9 @@ static unsigned int cond_forbids[] = {
 
   (1<<ACL_WHERE_NOTSMTP)|(1<<ACL_WHERE_CONNECT)|   /* encrypted */
     (1<<ACL_WHERE_HELO),
-     
+
   0,                                               /* endpass */
-   
+
   (1<<ACL_WHERE_NOTSMTP),                          /* hosts */
 
   (1<<ACL_WHERE_NOTSMTP)|(1<<ACL_WHERE_AUTH)|      /* local_parts */
@@ -285,9 +367,9 @@ static unsigned int cond_forbids[] = {
     (1<<ACL_WHERE_VRFY),
 
   0,                                               /* log_message */
-   
+
   0,                                               /* logwrite */
-  
+
 #ifdef WITH_CONTENT_SCAN
   (1<<ACL_WHERE_AUTH)|                             /* malware */
     (1<<ACL_WHERE_CONNECT)|(1<<ACL_WHERE_HELO)|
@@ -325,7 +407,7 @@ static unsigned int cond_forbids[] = {
     (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_MIME),
+    (1<<ACL_WHERE_VRFY),
 #endif
 
   (1<<ACL_WHERE_AUTH)|(1<<ACL_WHERE_CONNECT)|      /* sender_domains */
@@ -369,15 +451,18 @@ static unsigned int cond_forbids[] = {
 
 /* Return values from decode_control() */
 
-enum { 
+enum {
 #ifdef EXPERIMENTAL_BRIGHTMAIL
   CONTROL_BMI_RUN,
-#endif  
+#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,
   CONTROL_QUEUE_ONLY, CONTROL_SUBMISSION,
 #ifdef WITH_CONTENT_SCAN
-  CONTROL_NO_MBOX_UNSPOOL, 
+  CONTROL_NO_MBOX_UNSPOOL,
 #endif
   CONTROL_FAKEREJECT, CONTROL_NO_MULTILINE };
 
@@ -389,40 +474,47 @@ static unsigned int control_forbids[] = {
 #ifdef EXPERIMENTAL_BRIGHTMAIL
   0,                                               /* bmi_run */
 #endif
+#ifdef EXPERIMENTAL_DOMAINKEYS
+  (1<<ACL_WHERE_DATA)|(1<<ACL_WHERE_NOTSMTP),      /* dk_verify */
+#endif
 
   0,                                               /* error */
-  
-  (unsigned int) 
+
+  (unsigned int)
   ~(1<<ACL_WHERE_RCPT),                            /* caseful_local_part */
-   
-  (unsigned int) 
+
+  (unsigned int)
   ~(1<<ACL_WHERE_RCPT),                            /* caselower_local_part */
-   
+
   (1<<ACL_WHERE_NOTSMTP),                          /* enforce_sync */
-   
+
   (1<<ACL_WHERE_NOTSMTP),                          /* no_enforce_sync */
-   
-  (unsigned int) 
+
+  (unsigned int)
   ~((1<<ACL_WHERE_MAIL)|(1<<ACL_WHERE_RCPT)|       /* freeze */
     (1<<ACL_WHERE_PREDATA)|(1<<ACL_WHERE_DATA)|
-    (1<<ACL_WHERE_NOTSMTP)),
-     
-  (unsigned int) 
+    (1<<ACL_WHERE_NOTSMTP)|(1<<ACL_WHERE_MIME)),
+
+  (unsigned int)
   ~((1<<ACL_WHERE_MAIL)|(1<<ACL_WHERE_RCPT)|       /* queue_only */
     (1<<ACL_WHERE_PREDATA)|(1<<ACL_WHERE_DATA)|
-    (1<<ACL_WHERE_NOTSMTP)),
-     
-  (unsigned int) 
+    (1<<ACL_WHERE_NOTSMTP)|(1<<ACL_WHERE_MIME)),
+
+  (unsigned int)
   ~((1<<ACL_WHERE_MAIL)|(1<<ACL_WHERE_RCPT)|       /* submission */
-    (1<<ACL_WHERE_PREDATA)),                       
+    (1<<ACL_WHERE_PREDATA)),
 
 #ifdef WITH_CONTENT_SCAN
-  (1<<ACL_WHERE_NOTSMTP),                          /* no_mbox_unspool */
+  (unsigned int)
+  ~((1<<ACL_WHERE_MAIL)|(1<<ACL_WHERE_RCPT)|       /* no_mbox_unspool */
+    (1<<ACL_WHERE_PREDATA)|(1<<ACL_WHERE_DATA)|
+    (1<<ACL_WHERE_MIME)),
 #endif
 
-  (unsigned int) 
+  (unsigned int)
   ~((1<<ACL_WHERE_MAIL)|(1<<ACL_WHERE_RCPT)|       /* fakereject */
-    (1<<ACL_WHERE_PREDATA)|(1<<ACL_WHERE_DATA)),
+    (1<<ACL_WHERE_PREDATA)|(1<<ACL_WHERE_DATA)|
+    (1<<ACL_WHERE_MIME)),
 
   (1<<ACL_WHERE_NOTSMTP)                           /* no_multiline */
 };
@@ -438,6 +530,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},
@@ -779,7 +874,7 @@ if (hlen > 0)
         {
         newtype = htype_add_rfc;
         p += 14;
-        }        
+        }
       else if (strncmpic(p, US":at_start:", 10) == 0)
         {
         newtype = htype_add_top;
@@ -1069,11 +1164,11 @@ while ((ss = string_nextinlist(&list, &sep, big_buffer, big_buffer_size))
         uschar *opt;
         uschar buffer[256];
         while (isspace(*ss)) ss++;
-        
-        /* This callout option handling code has become a mess as new options 
-        have been added in an ad hoc manner. It should be tidied up into some 
+
+        /* This callout option handling code has become a mess as new options
+        have been added in an ad hoc manner. It should be tidied up into some
         kind of table-driven thing. */
+
         while ((opt = string_nextinlist(&ss, &optsep, buffer, sizeof(buffer)))
               != NULL)
           {
@@ -1205,13 +1300,19 @@ message if giving out verification details. */
 
 if (verify_header_sender)
   {
+  int verrno;
   rc = verify_check_header_address(user_msgptr, log_msgptr, callout,
-    callout_overall, callout_connect, se_mailfrom, pm_mailfrom, verify_options);
-  if (smtp_return_error_details)
+    callout_overall, callout_connect, se_mailfrom, pm_mailfrom, verify_options,
+    &verrno);
+  if (rc != OK)
     {
-    if (*user_msgptr == NULL && *log_msgptr != NULL)
-      *user_msgptr = string_sprintf("Rejected after DATA: %s", *log_msgptr);
-    if (rc == DEFER) acl_temp_details = TRUE;
+    *basic_errno = verrno;
+    if (smtp_return_error_details)
+      {
+      if (*user_msgptr == NULL && *log_msgptr != NULL)
+        *user_msgptr = string_sprintf("Rejected after DATA: %s", *log_msgptr);
+      if (rc == DEFER) acl_temp_details = TRUE;
+      }
     }
   }
 
@@ -1271,7 +1372,7 @@ else if (verify_sender_address != NULL)
     {
     BOOL routed = TRUE;
     uschar *save_address_data = deliver_address_data;
-      
+
     sender_vaddr = deliver_make_addr(verify_sender_address, TRUE);
     if (no_details) setflag(sender_vaddr, af_sverify_told);
     if (verify_sender_address[0] != 0)
@@ -1317,16 +1418,16 @@ else if (verify_sender_address != NULL)
     sender_vaddr->special_action = rc;
     sender_vaddr->next = sender_verified_list;
     sender_verified_list = sender_vaddr;
-    
-    /* Restore the recipient address data, which might have been clobbered by 
+
+    /* Restore the recipient address data, which might have been clobbered by
     the sender verification. */
-  
+
     deliver_address_data = save_address_data;
     }
-    
+
   /* Put the sender address_data value into $sender_address_data */
 
-  sender_address_data = sender_vaddr->p.address_data; 
+  sender_address_data = sender_vaddr->p.address_data;
   }
 
 /* A recipient address just gets a straightforward verify; again we must handle
@@ -1343,8 +1444,10 @@ else
   rc = verify_address(&addr2, NULL, verify_options|vopt_is_recipient, callout,
     callout_overall, callout_connect, se_mailfrom, pm_mailfrom, NULL);
   HDEBUG(D_acl) debug_printf("----------- end verify ------------\n");
+
   *log_msgptr = addr2.message;
-  *user_msgptr = addr2.user_message;
+  *user_msgptr = (addr2.user_message != NULL)?
+    addr2.user_message : addr2.message;
   *basic_errno = addr2.basic_errno;
 
   /* Make $address_data visible */
@@ -1493,7 +1596,7 @@ int sep = '/';
 for (; cb != NULL; cb = cb->next)
   {
   uschar *arg;
-  int control_type; 
+  int control_type;
 
   /* The message and log_message items set up messages to be used in
   case of rejection. They are expanded later. */
@@ -1629,7 +1732,7 @@ for (; cb != NULL; cb = cb->next)
       *log_msgptr = string_sprintf("cannot use \"control=%s\" in %s ACL",
         controls[control_type], acl_wherenames[where]);
       return ERROR;
-      }                                                     
+      }
 
     switch(control_type)
       {
@@ -1638,7 +1741,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;
 
@@ -1671,16 +1778,16 @@ for (; cb != NULL; cb = cb->next)
       case CONTROL_FAKEREJECT:
       fake_reject = TRUE;
       if (*p == '/')
-        { 
+        {
         uschar *pp = p + 1;
-        while (*pp != 0) pp++; 
+        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).";
+        fake_reject_text = US"Your message has been rejected but is being kept for evaluation.\nIf it was a legitimate message, it may still be delivered to the target recipient(s).";
         }
       break;
 
@@ -1696,22 +1803,22 @@ for (; cb != NULL; cb = cb->next)
       case CONTROL_SUBMISSION:
       submission_mode = TRUE;
       while (*p == '/')
-        { 
+        {
         if (Ustrncmp(p, "/sender_retain", 14) == 0)
           {
           p += 14;
           active_local_sender_retain = TRUE;
-          active_local_from_check = FALSE;   
-          }  
+          active_local_from_check = FALSE;
+          }
         else if (Ustrncmp(p, "/domain=", 8) == 0)
           {
           uschar *pp = p + 8;
-          while (*pp != 0 && *pp != '/') pp++; 
+          while (*pp != 0 && *pp != '/') pp++;
           submission_domain = string_copyn(p+8, pp-p);
-          p = pp; 
+          p = pp;
           }
-        else break;   
-        }   
+        else break;
+        }
       if (*p != 0)
         {
         *log_msgptr = string_sprintf("syntax error in \"control=%s\"", arg);
@@ -1745,10 +1852,10 @@ for (; cb != NULL; cb = cb->next)
           HDEBUG(D_acl)
             debug_printf("delay skipped in -bh checking mode\n");
           }
-        else 
+        else
           {
           while (delay > 0) delay = sleep(delay);
-          } 
+          }
         }
       }
     break;
@@ -1759,6 +1866,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;
@@ -1838,7 +2032,7 @@ for (; cb != NULL; cb = cb->next)
       log_write(0, logbits, "%s", string_printing(s));
       }
     break;
-    
+
 #ifdef WITH_CONTENT_SCAN
     case ACLC_MALWARE:
       {