diff src/context.cpp @ 360:17f21fcd44a8

allow quoted comma separated multiple signers in the dkim_from config entries
author Carl Byington <carl@five-ten-sg.com>
date Mon, 16 Jan 2017 11:13:40 -0800
parents ed04479a8e12
children bcfbffe254ed
line wrap: on
line diff
--- a/src/context.cpp	Mon Jan 16 08:28:37 2017 -0800
+++ b/src/context.cpp	Mon Jan 16 11:13:40 2017 -0800
@@ -1110,9 +1110,48 @@
 }
 
 
+bool CONTEXT::in_signing_set(const char *s, const char *signers) {
+    size_t n = strlen(s);
+    const char *p = signers;
+    do {
+        if ((strncasecmp(p, s, n) == 0) && ((p[n] == '\0') || (p[n] == ','))) return true;
+        p = strchr(p, ',');
+        if (!p) return false;
+    } while (true);
+}
+
+
 const char *CONTEXT::acceptable_content(recorder &memory, int score, int bulk, const char *queueid, string_set &signers, const char *from, string& msg) {
     DKIMP dk = find_dkim_from(from);
-    bool requirement = false;
+    if (dk) {
+        const char *st = dk->action;
+        for (string_set::iterator s=signers.begin(); s!=signers.end(); s++) {
+            // signed by a white listed signer
+            if ((st == token_signed_white)   && in_signing_set(*s,dk->signer)) {
+                log(queueid, "whitelisted dkim signer %s", *s);
+                return token_white;
+            }
+            // signed by the required signer
+            if ((st == token_require_signed) && in_signing_set(*s,dk->signer)) {
+                log(queueid, "required dkim signer %s", *s);
+                return token_white;
+            }
+            // signed by a black listed signer
+            if ((st == token_signed_black)   && in_signing_set(*s,dk->signer)) {
+                char buf[maxlen];
+                snprintf(buf, sizeof(buf), "Mail rejected - dkim signed by %s", *s);
+                msg = string(buf);
+                return token_black;
+            }
+        }
+        if (st == token_require_signed) {
+            char buf[maxlen];
+            snprintf(buf, sizeof(buf), "Mail rejected - not dkim signed by %s", dk->signer);
+            msg = string(buf);
+            return token_black;
+        }
+    }
+
     for (string_set::iterator s=signers.begin(); s!=signers.end(); s++) {
         const char *st = find_dkim_signer(*s);
         // signed by a white listed signer
@@ -1120,6 +1159,10 @@
             log(queueid, "whitelisted dkim signer %s", *s);
             return token_white;
         }
+    }
+
+    for (string_set::iterator s=signers.begin(); s!=signers.end(); s++) {
+        const char *st = find_dkim_signer(*s);
         // signed by a black listed signer
         if (st == token_black) {
             char buf[maxlen];
@@ -1127,37 +1170,6 @@
             msg = string(buf);
             return token_black;
         }
-
-        if (dk) {
-            st = dk->action;
-            // signed by a white listed signer
-            if ((st == token_signed_white)   && (strcasecmp(*s,dk->signer) == 0)) {
-                log(queueid, "whitelisted dkim signer %s", *s);
-                return token_white;
-            }
-            // signed by the required signer
-            if ((st == token_require_signed) && (strcasecmp(*s,dk->signer) == 0)) {
-                log(queueid, "required dkim signer %s", *s);
-                requirement = true;
-            }
-            // signed by a black listed signer
-            if ((st == token_signed_black)   && (strcasecmp(*s,dk->signer) == 0)) {
-                char buf[maxlen];
-                snprintf(buf, sizeof(buf), "Mail rejected - dkim signed by %s", dk->signer);
-                msg = string(buf);
-                return token_black;
-            }
-        }
-    }
-
-    if (dk && (dk->action == token_require_signed)) {
-        if (requirement) return token_white;
-        else {
-            char buf[maxlen];
-            snprintf(buf, sizeof(buf), "Mail rejected - not dkim signed by %s", dk->signer);
-            msg = string(buf);
-            return token_black;
-        }
     }
 
     if (spamassassin_limit && (score > spamassassin_limit)) {
@@ -1239,7 +1251,7 @@
         for (dkimp_map::iterator i=dkim_from_names.begin(); i!=dkim_from_names.end(); i++) {
             const char *n = (*i).first;
             DKIM &d = *(*i).second;
-            printf("%s             %s %s %s; \n", indent, n, d.action, d.signer);
+            printf("%s             %s %s \"%s\"; \n", indent, n, d.action, d.signer);
         }
         printf("%s         }; \n", indent);
         if (content_suffix) {
@@ -1533,11 +1545,11 @@
         else {
             const char *signer = have;
             const char *action = tok.next();
-            if ((action == token_white) || (action == token_black)) {
+            if ((action == token_white) || (action == token_black) || (action == token_unknown)) {
                 me.add_dkim_signer(signer, action);
             }
             else {
-                tok.token_error("white/black", action);
+                tok.token_error("white/black/unknown", action);
             }
         }
     }