]> source.dussan.org Git - rspamd.git/commitdiff
[Minor] Dmarc: Implement other munging options
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Tue, 2 Mar 2021 15:02:09 +0000 (15:02 +0000)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Tue, 2 Mar 2021 15:02:09 +0000 (15:02 +0000)
src/plugins/lua/dmarc.lua

index 5a7122c8c15ec07758783e1314e3e22979bcd390..4276f2bd6ec360191011341dd61384d384296c78 100644 (file)
@@ -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 <orig name> via <rcpt user>
     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)