# HG changeset patch # User Carl Byington # Date 1484594020 28800 # Node ID 17f21fcd44a88bbe6158d3fd9d59f784df07843e # Parent 3dfa93d657010cd3907d1be31e0cc02e453740e6 allow quoted comma separated multiple signers in the dkim_from config entries diff -r 3dfa93d65701 -r 17f21fcd44a8 src/context.cpp --- 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); } } } diff -r 3dfa93d65701 -r 17f21fcd44a8 src/context.h --- a/src/context.h Mon Jan 16 08:28:37 2017 -0800 +++ b/src/context.h Mon Jan 16 11:13:40 2017 -0800 @@ -313,6 +313,7 @@ dnswlp_list& get_dnswl_list(); void log(const char *queueid, const char *msg, const char *v); + bool in_signing_set(const char *s, const char *signers); const char *acceptable_content(recorder &memory, int score, int bulk, const char *queueid, string_set &signers, const char *from, string& msg); bool ignore_host(const char *host); diff -r 3dfa93d65701 -r 17f21fcd44a8 xml/dnsbl.in --- a/xml/dnsbl.in Mon Jan 16 08:28:37 2017 -0800 +++ b/xml/dnsbl.in Mon Jan 16 11:13:40 2017 -0800 @@ -744,8 +744,9 @@ DCCBULK = "dcc_bulk_threshold" (INTEGER | "many" | "off") DKIMSIGNER = "dkim_signer" "{" {SIGNING_DOMAIN DEF [";"]}+ "}" -DKIMFROM = "dkim_from" "{" {HEADER_FROM_DOMAIN DKIMVALUE SIGNING_DOMAIN [";"]}+ "}" +DKIMFROM = "dkim_from" "{" {HEADER_FROM_DOMAIN DKIMVALUE SIGNERS [";"]}+ "}" DKIMVALUE = "signed_white" | "signed_black" | "require_signed" +SIGNERS = quoted comma separated SIGNING_DOMAINs no whitespace ENV-TO = "env_to" "{" {(TO-ADDR | DCC-TO)}+ "}" TO-ADDR = ADDRESS [";"] @@ -771,10 +772,10 @@ DEFAULT_IP_LIMIT = INTEGER DAILY_MULTIPLE_IP = INTEGER -DEF = ("white" | "black") -DEFAULT = (DEF | "unknown" | "inherit" | "") +DEF = ("white" | "black" | "unknown") +DEFAULT = (DEF | "inherit" | "") ADDRESS = (USER@ | DOMAIN | USER@DOMAIN) -VALUE = ("white" | "black" | "unknown" | "inherit" | CHILD-CONTEXT-NAME)]]> +VALUE = (DEF | "inherit" | CHILD-CONTEXT-NAME)]]> @@ -835,6 +836,15 @@ require_rdns yes; content on { + dkim_signer { + credit.paypal.com require_signed credit.paypal.com; + paypal.com require_signed paypal.com; + dhl.com require_signed dhl.com; + adp.com require_signed "adp.com,bmi.adp.com"; + }; + dkim_from { + accounts.google.com white; + }; filter sbl-xbl.spamhaus.org "Mail containing %s rejected - sbl; see http://www.spamhaus.org/query/bl?ip=%s"; uribl multi.surbl.org "Mail containing %s rejected - surbl; see http://www.surbl.org/surbl-analysis?d=%s"; #uribl multi.uribl.com "Mail containing %s rejected - uribl; see http://l.uribl.com/?d=%s";