]> source.dussan.org Git - rspamd.git/commitdiff
[Minor] Spamtrap: Allow to use multiple recipients
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Sun, 12 Dec 2021 23:42:18 +0000 (23:42 +0000)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Sun, 12 Dec 2021 23:42:18 +0000 (23:42 +0000)
src/plugins/lua/spamtrap.lua

index 6147ad6800c9702d6fa40ec63a58a323a1d4b4f4..594d4f2255969a5eaebd02716715031aa27c5e48 100644 (file)
@@ -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