aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2015-04-19 10:21:09 +0100
committerVsevolod Stakhov <vsevolod@highsecure.ru>2015-04-19 10:21:09 +0100
commit8ce6a39f2a83dd9b9e781d2c3a21bd7a1951e4f3 (patch)
treee098e1506b51b9fb97cdb3117729d77c4388ed74
parent9973cb75c88a989dc635149db68a3aac09230591 (diff)
parent7f42f3c839f4d94a9b2bb0e7c1d49ce0377fa065 (diff)
downloadrspamd-8ce6a39f2a83dd9b9e781d2c3a21bd7a1951e4f3.tar.gz
rspamd-8ce6a39f2a83dd9b9e781d2c3a21bd7a1951e4f3.zip
Merge pull request #266 from fatalbanana/master
DMARC: check for subdomain policy
-rw-r--r--src/plugins/lua/dmarc.lua53
1 files changed, 35 insertions, 18 deletions
diff --git a/src/plugins/lua/dmarc.lua b/src/plugins/lua/dmarc.lua
index 0ca3ac4fd..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()
@@ -131,26 +139,28 @@ local function dmarc_callback(task)
quarantine_policy = true
elseif (policy ~= 'none') then
failed_policy = true
+ return
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
else
failed_policy = true
+ return
end
end
pct = string.match(e, '^pct=(%d+)$')
@@ -166,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
@@ -178,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
@@ -191,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
@@ -203,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
@@ -232,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