From: Vsevolod Stakhov Date: Mon, 8 Dec 2025 09:10:46 +0000 (+0000) Subject: [Feature] Add remove_ar_from option for selective Authentication-Results header removal X-Git-Tag: 3.14.2~5^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d90b8e006619eeb10f16006f6a93d1dcfab7c41c;p=thirdparty%2Frspamd.git [Feature] Add remove_ar_from option for selective Authentication-Results header removal --- diff --git a/lualib/lua_auth_results.lua b/lualib/lua_auth_results.lua index 8c907d9b71..d82d6ee73f 100644 --- a/lualib/lua_auth_results.lua +++ b/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 diff --git a/src/plugins/lua/milter_headers.lua b/src/plugins/lua/milter_headers.lua index 26406a5c4b..0894480cfb 100644 --- a/src/plugins/lua/milter_headers.lua +++ b/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',