From 0f464be6050efa1f57d60e26cd7caaafcdc52b83 Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Sun, 12 Dec 2021 23:42:18 +0000 Subject: [PATCH] [Minor] Spamtrap: Allow to use multiple recipients --- src/plugins/lua/spamtrap.lua | 99 ++++++++++++++++++++---------------- 1 file changed, 55 insertions(+), 44 deletions(-) diff --git a/src/plugins/lua/spamtrap.lua b/src/plugins/lua/spamtrap.lua index 6147ad680..594d4f225 100644 --- a/src/plugins/lua/spamtrap.lua +++ b/src/plugins/lua/spamtrap.lua @@ -22,6 +22,7 @@ local redis_params local use_redis = false; local M = 'spamtrap' local lua_util = require "lua_util" +local fun = require "fun" local settings = { symbol = 'SPAMTRAP', @@ -31,6 +32,7 @@ local settings = { fuzzy_flag = 1, fuzzy_weight = 10.0, key_prefix = 'sptr_', + allow_multiple_rcpts = false, } local check_authed = true @@ -41,7 +43,6 @@ local function spamtrap_cb(task) local authed_user = task:get_user() local ip_addr = task:get_ip() local called_for_domain = false - local target if ((not check_authed and authed_user) or (not check_local and ip_addr and ip_addr:is_local())) then @@ -81,60 +82,70 @@ local function spamtrap_cb(task) module = 'spamtrap', flags = act_flags} end + + return true end - local function redis_spamtrap_cb(err, data) - if err ~= nil then - rspamd_logger.errx(task, 'redis_spamtrap_cb received error: %1', err) - return - end + local function gen_redis_spamtrap_cb(target) + return function(err, data) + if err ~= nil then + rspamd_logger.errx(task, 'redis_spamtrap_cb received error: %1', err) + return + end - if data and type(data) ~= 'userdata' then - do_action(target) - else - if not called_for_domain then - -- Recurse for @catchall domain - target = rcpts[1]['domain']:lower() - local key = settings['key_prefix'] .. '@' .. target - local ret = rspamd_redis_make_request(task, - redis_params, -- connect params - key, -- hash key - false, -- is write - redis_spamtrap_cb, -- callback - 'GET', -- command - {key} -- arguments - ) - if not ret then - rspamd_logger.errx(task, "redis request wasn't scheduled") - end - called_for_domain = true + if data and type(data) ~= 'userdata' then + do_action(target) else - lua_util.debugm(M, task, 'skip spamtrap for %s', target) + if not called_for_domain then + -- Recurse for @catchall domain + target = rcpts[1]['domain']:lower() + local key = settings['key_prefix'] .. '@' .. target + local ret = rspamd_redis_make_request(task, + redis_params, -- connect params + key, -- hash key + false, -- is write + gen_redis_spamtrap_cb(target), -- callback + 'GET', -- command + {key} -- arguments + ) + if not ret then + rspamd_logger.errx(task, "redis request wasn't scheduled") + end + called_for_domain = true + else + lua_util.debugm(M, task, 'skip spamtrap for %s', target) + end end end end -- Do not risk a FP by checking for more than one recipient - if rcpts and #rcpts == 1 then - target = rcpts[1]['addr']:lower() + if rcpts and (#rcpts == 1 or (#rcpts > 0 and settings.allow_multiple_rcpts)) then + local targets = fun.map(function(r) return r['addr']:lower() end, rcpts) if use_redis then - local key = settings['key_prefix'] .. target - local ret = rspamd_redis_make_request(task, - redis_params, -- connect params - key, -- hash key - false, -- is write - redis_spamtrap_cb, -- callback - 'GET', -- command - {key} -- arguments - ) - if not ret then - rspamd_logger.errx(task, "redis request wasn't scheduled") - end + fun.each(function(target) + local key = settings['key_prefix'] .. target + local ret = rspamd_redis_make_request(task, + redis_params, -- connect params + key, -- hash key + false, -- is write + gen_redis_spamtrap_cb(target), -- callback + 'GET', -- command + {key} -- arguments + ) + if not ret then + rspamd_logger.errx(task, "redis request wasn't scheduled") + end + end, targets) + elseif settings['map'] then - if settings['map']:get_key(target) then - do_action(target) - else - lua_util.debugm(M, task, 'skip spamtrap for %s', target) + local function check_map_functor(target) + if settings['map']:get_key(target) then + return do_action(target) + end + end + if not fun.any(check_map_functor, targets) then + lua_util.debugm(M, task, 'skip spamtrap') end end end -- 2.39.5