Browse Source

[Feature] Add remove_ar_from option for selective Authentication-Results header removal

pull/5784/head
Vsevolod Stakhov 2 weeks ago
parent
commit
d90b8e0066
No known key found for this signature in database GPG Key ID: 7647B6790081437
  1. 15
      lualib/lua_auth_results.lua
  2. 79
      src/plugins/lua/milter_headers.lua

15
lualib/lua_auth_results.lua

@ -298,4 +298,19 @@ local function parse_ar_element(elt)
end
exports.parse_ar_element = parse_ar_element
local function get_ar_hostname(ar_value)
if not ar_value or ar_value == '' then
return nil
end
local hostname = ar_value:match('^%s*([^;%s%(]+)')
if hostname then
return hostname:lower()
end
return nil
end
exports.get_ar_hostname = get_ar_hostname
return exports

79
src/plugins/lua/milter_headers.lua

@ -112,6 +112,7 @@ local settings = {
['authentication-results'] = {
header = 'Authentication-Results',
remove = 0,
remove_ar_from = nil,
add_smtp_user = true,
stop_chars = ';',
},
@ -538,14 +539,70 @@ local function milter_headers(task)
return
end
local ar = require "lua_auth_results"
local local_mod = settings.routines['authentication-results']
if local_mod.remove_ar_from then
local hdr_name = local_mod.header
local existing_hdrs = task:get_header_full(hdr_name)
if existing_hdrs and #existing_hdrs > 0 then
local indices_to_remove = {}
for idx, hdr in ipairs(existing_hdrs) do
local ar_hostname = ar.get_ar_hostname(hdr.decoded or hdr.value)
if ar_hostname then
local should_remove = false
if type(local_mod.remove_ar_from) == 'userdata' then
if local_mod.remove_ar_from:get_key(ar_hostname) then
should_remove = true
else
local domain_part = ar_hostname:match('%.(.+)$')
if domain_part and local_mod.remove_ar_from:get_key('.' .. domain_part) then
should_remove = true
end
end
elseif type(local_mod.remove_ar_from) == 'table' then
for _, pattern in ipairs(local_mod.remove_ar_from) do
local pattern_lower = pattern:lower()
if pattern_lower == ar_hostname then
should_remove = true
break
elseif pattern_lower:sub(1, 1) == '.' then
if ar_hostname:sub(-#pattern_lower) == pattern_lower then
should_remove = true
break
end
end
end
elseif type(local_mod.remove_ar_from) == 'string' then
local pattern_lower = local_mod.remove_ar_from:lower()
if pattern_lower == ar_hostname then
should_remove = true
elseif pattern_lower:sub(1, 1) == '.' then
if ar_hostname:sub(-#pattern_lower) == pattern_lower then
should_remove = true
end
end
end
if should_remove then
lua_util.debugm(N, task, 'removing AR header from %s (idx %d)', ar_hostname, idx)
table.insert(indices_to_remove, idx)
end
end
end
if settings.routines['authentication-results'].remove then
remove[settings.routines['authentication-results'].header] = settings.routines['authentication-results'].remove
if #indices_to_remove > 0 then
remove[hdr_name] = indices_to_remove
end
end
elseif local_mod.remove then
remove[local_mod.header] = local_mod.remove
end
local res = ar.gen_auth_results(task,
lua_util.override_defaults(ar.default_settings,
settings.routines['authentication-results']))
lua_util.override_defaults(ar.default_settings, local_mod))
if res then
add_header('authentication-results', res, ';', 1)
@ -766,6 +823,20 @@ if opts.extended_headers_rcpt then
'set', 'Extended headers recipients')
end
if settings.routines['authentication-results'] and
settings.routines['authentication-results'].remove_ar_from then
local ar_from = settings.routines['authentication-results'].remove_ar_from
if type(ar_from) == 'table' and (ar_from.url or ar_from.file or ar_from.name) then
settings.routines['authentication-results'].remove_ar_from =
lua_maps.rspamd_map_add_from_ucl(ar_from, 'set', 'AR headers removal hostnames')
elseif type(ar_from) == 'string' then
if ar_from:match('^[/~]') or ar_from:match('^https?://') or ar_from:match('^file://') then
settings.routines['authentication-results'].remove_ar_from =
lua_maps.rspamd_map_add_from_ucl(ar_from, 'set', 'AR headers removal hostnames')
end
end
end
rspamd_config:register_symbol({
name = 'MILTER_HEADERS',
type = 'idempotent',

Loading…
Cancel
Save