]> git.ipfire.org Git - thirdparty/rspamd.git/commitdiff
Improve handling of IP conditions in settings
authorDmitry Petrov <dpetrov67@gmail.com>
Wed, 5 Mar 2025 13:51:56 +0000 (08:51 -0500)
committerDmitry Petrov <dpetrov67@gmail.com>
Wed, 5 Mar 2025 13:51:56 +0000 (08:51 -0500)
 * Skip invalid IPs (with appropriate error logging)
   (previously a bad IP would cause the subsequent IPs in a list to be ignored or make the whole IP condition to be ignored)
 * Add validated IPs/maps into a flat table
 * Log complete IP in case of invalid mask

src/plugins/lua/settings.lua

index 2c9d5b2f987133ae36cb0410fa39d6244b6caccf..51622fb91dc093f6f1d0b790310412ef430d3e48 100644 (file)
@@ -460,20 +460,19 @@ local function gen_settings_external_cb(name)
 end
 
 -- Process IP address: converted to a table {ip, mask}
-local function process_ip_condition(ip)
+local function process_ip_condition(ip, out)
   if type(ip) == "table" then
-    local out = {}
     for _, v in ipairs(ip) do
-      -- should we check/abort on nil here?
-      table.insert(out, process_ip_condition(v))
+      process_ip_condition(v, out)
     end
-    return out
+    return
   end
 
   if type(ip) == "string" then
     if string.sub(ip, 1, 4) == "map:" then
       -- It is a map, don't apply any extra logic
-      return ip
+      table.insert(out, ip)
+      return
     end
 
     local mask
@@ -490,19 +489,23 @@ local function process_ip_condition(ip)
         if mask_num then
           -- normalize IP
           res = res:apply_mask(mask_num)
-          if res then
-            return { res:to_string(), mask_num }
-          end 
+          if res:is_valid() then
+            table.insert(out, { res:to_string(), mask_num })
+            return
+          end
         end
-        rspamd_logger.errx(rspamd_config, "bad IP mask: " .. mask)
-        return nil
+
+        rspamd_logger.errx(rspamd_config, "bad IP mask: %s/%s", ip, mask)
+        return
       end
-      return ip
+
+      -- Just a plain IP address
+      table.insert(out, res:to_string())
+      return
     end
   end
 
   rspamd_logger.errx(rspamd_config, "bad IP address: " .. ip)
-  return nil
 end
 
 -- Process email like condition, converted to a table with fields:
@@ -660,22 +663,21 @@ local function process_settings_table(tbl, allow_ids, mempool, is_static)
 
     local checks = {}
     if elt.ip then
-      local ips_table = process_ip_condition(elt['ip'])
+      local ips_table = {}
+      process_ip_condition(elt.ip, ips_table)
 
-      if ips_table then
-        lua_util.debugm(N, rspamd_config, 'added ip condition to "%s": %s',
-            name, ips_table)
-        checks.ip = {
-          check = gen_check_closure(convert_to_table(elt.ip, ips_table), check_ip_setting),
-          extract = function(task)
-            local ip = task:get_from_ip()
-            if ip and ip:is_valid() then
-              return ip
-            end
-            return nil
-          end,
-        }
-      end
+      lua_util.debugm(N, rspamd_config, 'added ip condition to "%s": %s',
+          name, ips_table)
+      checks.ip = {
+        check = gen_check_closure(ips_table, check_ip_setting),
+        extract = function(task)
+          local ip = task:get_from_ip()
+          if ip and ip:is_valid() then
+            return ip
+          end
+          return nil
+        end,
+      }
     end
     if elt.ip_map then
       local ips_map = lua_maps.map_add_from_ucl(elt.ip_map, 'radix',
@@ -698,23 +700,21 @@ local function process_settings_table(tbl, allow_ids, mempool, is_static)
     end
 
     if elt.client_ip then
-      local client_ips_table = process_ip_condition(elt.client_ip)
-
-      if client_ips_table then
-        lua_util.debugm(N, rspamd_config, 'added client_ip condition to "%s": %s',
-            name, client_ips_table)
-        checks.client_ip = {
-          check = gen_check_closure(convert_to_table(elt.client_ip, client_ips_table),
-              check_ip_setting),
-          extract = function(task)
-            local ip = task:get_client_ip()
-            if ip:is_valid() then
-              return ip
-            end
-            return nil
-          end,
-        }
-      end
+      local client_ips_table = {}
+      process_ip_condition(elt.client_ip, client_ips_table)
+
+      lua_util.debugm(N, rspamd_config, 'added client_ip condition to "%s": %s',
+          name, client_ips_table)
+      checks.client_ip = {
+        check = gen_check_closure(client_ips_table, check_ip_setting),
+        extract = function(task)
+          local ip = task:get_client_ip()
+          if ip:is_valid() then
+            return ip
+          end
+          return nil
+        end,
+      }
     end
     if elt.client_ip_map then
       local ips_map = lua_maps.map_add_from_ucl(elt.ip_map, 'radix',