From 21619069a406d42c1bc497016558258317049fe0 Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Tue, 2 Mar 2021 15:02:09 +0000 Subject: [PATCH] [Minor] Dmarc: Implement other munging options --- src/plugins/lua/dmarc.lua | 68 +++++++++++++++++++++++++++++++-------- 1 file changed, 54 insertions(+), 14 deletions(-) diff --git a/src/plugins/lua/dmarc.lua b/src/plugins/lua/dmarc.lua index 5a7122c8c..4276f2bd6 100644 --- a/src/plugins/lua/dmarc.lua +++ b/src/plugins/lua/dmarc.lua @@ -1453,7 +1453,8 @@ if opts.munging then local munging_defaults = { reply_goes_to_list = false, - dmarc_mitigate_allow_only = true, -- perform munging based on DMARC_POLICY_ALLOW only + mitigate_allow_only = true, -- perform munging based on DMARC_POLICY_ALLOW only + mitigate_strict_only = false, -- perform mugning merely for reject/quarantine policies munge_from = true, -- replace from with something like via list_map = nil, -- map of maillist domains munge_map_condition = nil, -- maps expression to enable munging @@ -1482,13 +1483,45 @@ if opts.munging then end local function dmarc_munge_callback(task) - if not task:has_symbol(dmarc_symbols.allow) then - lua_util.debugm(N, task, 'skip munging, no %s symbol', - dmarc_symbols.allow) - -- Excepted - return + if munging_opts.mitigate_allow_only then + if not task:has_symbol(dmarc_symbols.allow) then + lua_util.debugm(N, task, 'skip munging, no %s symbol', + dmarc_symbols.allow) + -- Excepted + return + end + else + local has_dmarc = task:has_symbol(dmarc_symbols.allow) or + task:has_symbol(dmarc_symbols.quarantine) or + task:has_symbol(dmarc_symbols.reject) or + task:has_symbol(dmarc_symbols.softfail) + + if not has_dmarc then + lua_util.debugm(N, task, 'skip munging, no %s symbol', + dmarc_symbols.allow) + -- Excepted + return + end + end + if munging_opts.mitigate_strict_only then + local s = task:get_symbol(dmarc_symbols.allow) or {[1] = {}} + local sopts = s[1].options or {} + + local seen_strict + for _,o in ipairs(sopts) do + if o == 'reject' or o == 'quarantine' then + seen_strict = true + break + end + end + + if not seen_strict then + lua_util.debugm(N, task, 'skip munging, no strict policy found in %s', + dmarc_symbols.allow) + -- Excepted + return + end end - -- TODO: Add policy check to skip munging for non-strict policies if munging_opts.munge_map_condition then local accepted,trace = munging_opts.munge_map_condition:process(task) if not accepted then @@ -1516,9 +1549,6 @@ if opts.munging then return end - local via_name = rcpt_found.user - local via_addr = rcpt_found.addr - local from = task:get_from({ 'mime', 'orig'}) if not from or not from[1] then @@ -1528,6 +1558,8 @@ if opts.munging then end from = from[1] + local via_name = rcpt_found.user + local via_addr = rcpt_found.addr if from.name then from.name = string.format('%s via %s', from.name, via_name) @@ -1538,12 +1570,20 @@ if opts.munging then local hdr_encoded = rspamd_util.fold_header('From', rspamd_util.mime_header_encode(string.format('%s <%s>', from.name, via_addr))) + local add_hdrs = { + ['From'] = { order = 1, value = hdr_encoded }, + } + + if munging_opts.reply_goes_to_list then + -- Add another reply-to + table.insert(add_hdrs['Reply-To'], {order = 0, value = via_addr}) + add_hdrs['X-Original-From'] = { order = 0, value = hdr_encoded} + else + add_hdrs['Reply-To'] = {order = 0, value = via_addr} + end lua_mime.modify_headers(task, { remove = {['From'] = {0}}, - add = { - ['From'] = {order = 1, value = hdr_encoded}, - ['Reply-To'] = {order = 0, value = from.addr} - } + add = add_hdrs }) lua_util.debugm(N, task, 'munged DMARC header for %s: %s -> %s', from.domain, hdr_encoded, from.addr) -- 2.39.5