From fa127b669afd550da49315833dea5eba52ff830a Mon Sep 17 00:00:00 2001 From: Andrew Lewis Date: Thu, 16 Apr 2015 17:59:49 +0200 Subject: DMARC: Abort processing on policy failure (where this is not happening already) --- src/plugins/lua/dmarc.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/plugins/lua/dmarc.lua b/src/plugins/lua/dmarc.lua index 0ca3ac4fd..25f8d03f3 100644 --- a/src/plugins/lua/dmarc.lua +++ b/src/plugins/lua/dmarc.lua @@ -131,6 +131,7 @@ local function dmarc_callback(task) quarantine_policy = true elseif (policy ~= 'none') then failed_policy = true + return end end subdomain_policy = string.match(e, '^sp=(.+)$') @@ -151,6 +152,7 @@ local function dmarc_callback(task) end else failed_policy = true + return end end pct = string.match(e, '^pct=(%d+)$') -- cgit v1.2.3 From 7f42f3c839f4d94a9b2bb0e7c1d49ce0377fa065 Mon Sep 17 00:00:00 2001 From: Andrew Lewis Date: Sat, 18 Apr 2015 01:02:16 +0200 Subject: DMARC: check for subdomain policy --- src/plugins/lua/dmarc.lua | 51 ++++++++++++++++++++++++++++++----------------- 1 file changed, 33 insertions(+), 18 deletions(-) diff --git a/src/plugins/lua/dmarc.lua b/src/plugins/lua/dmarc.lua index 25f8d03f3..ec3d88e2d 100644 --- a/src/plugins/lua/dmarc.lua +++ b/src/plugins/lua/dmarc.lua @@ -76,6 +76,17 @@ local function dmarc_callback(task) end local function dmarc_dns_cb(resolver, to_resolve, results, err, key) + + local lookup_domain = string.sub(to_resolve, 8) + if not results then + if lookup_domain ~= dmarc_domain then + task:get_resolver():resolve_txt(task:get_session(), + task:get_mempool(), '_dmarc.' .. dmarc_domain, dmarc_dns_cb) + return + else + return + end + local strict_spf = false local strict_dkim = false local strict_policy = false @@ -84,9 +95,6 @@ local function dmarc_callback(task) local failed_policy = false local rua - if not results then - return - end for _,r in ipairs(results) do if failed_policy then break end (function() @@ -135,18 +143,18 @@ local function dmarc_callback(task) end end subdomain_policy = string.match(e, '^sp=(.+)$') - if subdomain_policy then + if subdomain_policy and lookup_domain == dmarc_domain then if (subdomain_policy == 'reject') then - if url_from:get_tld() ~= from[1]['domain'] then + if dmarc_domain ~= from[1]['domain'] then strict_policy = true end elseif (subdomain_policy == 'quarantine') then - if url_from:get_tld() ~= from[1]['domain'] then + if dmarc_domain ~= from[1]['domain'] then strict_policy = true quarantine_policy = true end elseif (subdomain_policy == 'none') then - if url_from:get_tld() ~= from[1]['domain'] then + if dmarc_domain ~= from[1]['domain'] then strict_policy = false quarantine_policy = false end @@ -168,7 +176,15 @@ local function dmarc_callback(task) end)() end - if not found_policy or failed_policy then return end + if not found_policy then + if lookup_domain ~= dmarc_domain then + task:get_resolver():resolve_txt(task:get_session(), + task:get_mempool(), '_dmarc.' .. dmarc_domain, dmarc_dns_cb) + return + else + return + end + if failed_policy then return end -- Check dkim and spf symbols local spf_ok = false @@ -180,8 +196,8 @@ local function dmarc_callback(task) spf_ok = true elseif not strict_spf then if string.sub(efrom[1]['domain'], - -string.len('.' .. dmarc_domain)) - == '.' .. dmarc_domain then + -string.len('.' .. lookup_domain)) + == '.' .. lookup_domain then spf_ok = true end end @@ -193,8 +209,8 @@ local function dmarc_callback(task) dkim_ok = true elseif not strict_dkim then if string.sub(das[1]['options'][0], - -string.len('.' .. dmarc_domain)) - == '.' .. dmarc_domain then + -string.len('.' .. lookup_domain)) + == '.' .. lookup_domain then dkim_ok = true end end @@ -205,17 +221,17 @@ local function dmarc_callback(task) res = 1.0 if quarantine_policy then if not pct or pct == 100 or (math.random(100) <= pct) then - task:insert_result('DMARC_POLICY_QUARANTINE', res, dmarc_domain) + task:insert_result('DMARC_POLICY_QUARANTINE', res, lookup_domain) end elseif strict_policy then if not pct or pct == 100 or (math.random(100) <= pct) then - task:insert_result('DMARC_POLICY_REJECT', res, dmarc_domain) + task:insert_result('DMARC_POLICY_REJECT', res, lookup_domain) end else - task:insert_result('DMARC_POLICY_SOFTFAIL', res, dmarc_domain) + task:insert_result('DMARC_POLICY_SOFTFAIL', res, lookup_domain) end else - task:insert_result('DMARC_POLICY_ALLOW', res, dmarc_domain) + task:insert_result('DMARC_POLICY_ALLOW', res, lookup_domain) end if rua and not(spf_ok or dkim_ok) and upstreams then @@ -234,13 +250,12 @@ local function dmarc_callback(task) -- XXX: handle rua and push data to redis end - -- XXX: Check for DMARC policy record at subdomain if from and from[1]['domain'] and not from[2] then local url_from = rspamd_url.create(task:get_mempool(), from[1]['domain']) if url_from then dmarc_domain = url_from:get_tld() task:get_resolver():resolve_txt(task:get_session(), task:get_mempool(), - '_dmarc.' .. dmarc_domain, dmarc_dns_cb) + '_dmarc.' .. from[1]['domain'], dmarc_dns_cb) end end end -- cgit v1.2.3