aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2016-12-12 14:03:19 +0000
committerGitHub <noreply@github.com>2016-12-12 14:03:19 +0000
commit5bb89372e9eed24a38c9caf768d7e43c4d8f3870 (patch)
tree70af125206e899f2a2b9a0e95df2c312f4fa8833 /src
parent19282700d956783616360d8b278bb13f1b07806e (diff)
parent80cb19b3109c5893eef79ff1310f19c1ab34dde8 (diff)
downloadrspamd-5bb89372e9eed24a38c9caf768d7e43c4d8f3870.tar.gz
rspamd-5bb89372e9eed24a38c9caf768d7e43c4d8f3870.zip
Merge pull request #1252 from fatalbanana/a
[Feature] rmilter_headers: authentication-results (#78)
Diffstat (limited to 'src')
-rw-r--r--src/plugins/lua/rmilter_headers.lua123
1 files changed, 122 insertions, 1 deletions
diff --git a/src/plugins/lua/rmilter_headers.lua b/src/plugins/lua/rmilter_headers.lua
index 9e2f99ac1..98a778058 100644
--- a/src/plugins/lua/rmilter_headers.lua
+++ b/src/plugins/lua/rmilter_headers.lua
@@ -38,6 +38,35 @@ local settings = {
header = 'X-Spam-Status',
remove = 1,
},
+ ['authentication-results'] = {
+ header = 'Authentication-Results',
+ remove = 1,
+ spf_symbols = {
+ pass = 'R_SPF_ALLOW',
+ fail = 'R_SPF_FAIL',
+ softfail = 'R_SPF_SOFTFAIL',
+ neutral = 'R_SPF_NEUTRAL',
+ temperror = 'R_SPF_DNSFAIL',
+ none = 'R_SPF_NA',
+ permerror = 'R_SPF_PERMFAIL',
+ },
+ dkim_symbols = {
+ pass = 'R_DKIM_ALLOW',
+ fail = 'R_DKIM_REJECT',
+ temperror = 'R_DKIM_TEMPFAIL',
+ none = 'R_DKIM_NA',
+ permerror = 'R_DKIM_PERMFAIL',
+ },
+ dmarc_symbols = {
+ pass = 'DMARC_POLICY_ALLOW',
+ permerror = 'DMARC_BAD_POLICY',
+ temperror = 'DMARC_DNSFAIL',
+ none = 'DMARC_NA',
+ reject = 'DMARC_POLICY_REJECT',
+ softfail = 'DMARC_POLICY_SOFTFAIL',
+ quarantine = 'DMARC_POLICY_QUARANTINE',
+ },
+ },
},
}
@@ -112,6 +141,92 @@ routines['x-spam-status'] = function(task, common_meta)
return nil, add, remove, common
end
+routines['authentication-results'] = function(task, common_meta)
+ local add, remove, auth_results, hdr_parts = {}, {}, {}, {}
+ local common = {symbols = {}}
+ local auth_types = {
+ dkim = settings.routines['authentication-results'].dkim_symbols,
+ dmarc = settings.routines['authentication-results'].dmarc_symbols,
+ spf = settings.routines['authentication-results'].spf_symbols,
+ }
+ if not common_meta.symbols then common_meta.symbols = {} end
+ for auth_type, symbols in pairs(auth_types) do
+ for key, sym in pairs(symbols) do
+ if not (common_meta.symbols[sym] == false) then
+ local s = task:get_symbol(sym)
+ if not s then
+ common_meta.symbols[sym] = false
+ common.symbols[sym] = false
+ else
+ common_meta.symbols[sym] = s
+ common.symbols[sym] = s
+ if not auth_results[auth_type] then
+ auth_results[auth_type] = {key}
+ else
+ table.insert(auth_results[auth_type], key)
+ end
+ if auth_type ~= 'dkim' then
+ break
+ end
+ end
+ end
+ end
+ end
+ if settings.routines['authentication-results'].remove then
+ remove[settings.routines['authentication-results'].header] = settings.routines['authentication-results'].remove
+ end
+ for auth_type, keys in pairs(auth_results) do
+ for _, key in ipairs(keys) do
+ local hdr = ''
+ if auth_type == 'dmarc' and key ~= 'none' then
+ hdr = hdr .. 'dmarc='
+ if key == 'reject' or key == 'quarantine' or key == 'softfail' then
+ hdr = hdr .. 'fail'
+ else
+ hdr = hdr .. key
+ end
+ if key == 'pass' then
+ hdr = hdr .. ' policy=' .. common_meta.symbols[auth_types['dmarc'][key]][1]['options'][2]
+ hdr = hdr .. ' header.from=' .. common_meta.symbols[auth_types['dmarc'][key]][1]['options'][1]
+ elseif key ~= 'none' then
+ local dom, rsn = rspamd_str_split(common_meta.symbols[auth_types['dmarc'][key]][1]['options'][1], ' : ')
+ hdr = hdr .. ' reason="' .. rsn .. '"'
+ hdr = hdr .. ' header.from=' .. dom
+ if key == 'softfail' then
+ hdr = hdr .. ' policy=none'
+ else
+ hdr = hdr .. ' policy=' .. key
+ end
+ end
+ table.insert(hdr_parts, hdr)
+ elseif auth_type == 'dkim' and key ~= 'none' then
+ if common_meta.symbols[auth_types['dkim'][key]][1] then
+ for _, v in ipairs(common_meta.symbols[auth_types['dkim'][key]][1]['options']) do
+ hdr = hdr .. auth_type .. '=' .. key .. ' header.d=' .. v
+ table.insert(hdr_parts, hdr)
+ end
+ end
+ elseif auth_type == 'spf' and key ~= 'none' then
+ hdr = hdr .. auth_type .. '=' .. key
+ local smtp_from = task:get_from('smtp')
+ if smtp_from['addr'] ~= '' and smtp_from['addr'] ~= nil then
+ hdr = hdr .. ' smtp.mailfrom=' .. smtp_from['addr']
+ else
+ local helo = task:get_helo()
+ if helo then
+ hdr = hdr .. ' smtp.helo=' .. task:get_helo()
+ end
+ end
+ table.insert(hdr_parts, hdr)
+ end
+ end
+ end
+ if #hdr_parts > 0 then
+ add[settings.routines['authentication-results'].header] = table.concat(hdr_parts, '; ')
+ end
+ return nil, add, remove, common
+end
+
local function rmilter_headers(task)
local common_meta, to_add, to_remove = {}, {}, {}
for n, f in pairs(active_routines) do
@@ -126,7 +241,13 @@ local function rmilter_headers(task)
to_remove[k] = v
end
for k, v in pairs(common) do
- common_meta[k] = v
+ if type(v) == 'table' then
+ for sk, sv in pairs(v) do
+ common_meta[k][sk] = sv
+ end
+ else
+ common_meta[k] = v
+ end
end
end
end