]> source.dussan.org Git - rspamd.git/commitdiff
[Feature] Allow to use global lua maps in settings
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Sat, 2 Sep 2017 12:44:04 +0000 (13:44 +0100)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Sat, 2 Sep 2017 12:44:04 +0000 (13:44 +0100)
Issue: #1802

lualib/maps.lua
src/plugins/lua/settings.lua

index 3cd01dcfe9bb18adaf539fd7fb1352995764e57f..917c6ca8e0c3d0b30198fe712a7d743896506b31 100644 (file)
@@ -131,4 +131,35 @@ end
 
 exports.rspamd_map_add = rspamd_map_add
 
+-- Check `what` for being lua_map name, otherwise just compares key with what
+local function rspamd_maybe_check_map(key, what)
+  local fun = require "fun"
+
+  local function starts(where,st)
+    return string.sub(where,1,string.len(st))==st
+  end
+
+  if type(what) == "table" then
+    return fun.any(function(elt) return rspamd_maybe_check_map(key, elt) end, what)
+  end
+  if type(rspamd_maps) == "table" then
+    local mn
+    if starts(what, "map:") then
+      mn = string.sub(what, 4)
+    elseif starts(what, "map://") then
+      mn = string.sub(what, 6)
+    end
+
+    if mn and rspamd_maps[mn] then
+      return rspamd_maps[mn]:get_key(key)
+    end
+  else
+    return what:lower() == key
+  end
+
+  return false
+end
+
+exports.rspamd_maybe_check_map = rspamd_maybe_check_map
+
 return exports
index 7d28f254559f2f5fd93940898f27ef8944a0dda0..4562b8361524682b8f81629e7fcc55340203b24b 100644 (file)
@@ -23,6 +23,7 @@ end
 -- https://rspamd.com/doc/configuration/settings.html
 
 local rspamd_logger = require "rspamd_logger"
+local rspamd_maps = require "maps"
 local redis_params
 
 local settings = {}
@@ -105,17 +106,17 @@ local function check_settings(task)
   local function check_addr_setting(rule, addr)
     local function check_specific_addr(elt)
       if rule['name'] then
-        if rule['name']:lower() == elt['addr']:lower() then
+        if rspamd_maps.rspamd_maybe_check_map(rule['name'], elt['addr']) then
           return true
         end
       end
       if rule['user'] then
-        if rule['user']:lower() == elt['user']:lower() then
+        if rspamd_maps.rspamd_maybe_check_map(rule['user'], elt['user']) then
           return true
         end
       end
       if rule['domain'] and elt['domain'] then
-        if rule['domain']:lower() == elt['domain']:lower() then
+        if rspamd_maps.rspamd_maybe_check_map(rule['domain'], elt['domain']) then
           return true
         end
       end
@@ -137,13 +138,19 @@ local function check_settings(task)
   end
 
   local function check_ip_setting(rule, ip)
-    if rule[2] ~= 0 then
-      local nip = ip:apply_mask(rule[2])
-      if nip and nip:to_string() == rule[1]:to_string() then
+    if not rule[2] then
+      if rspamd_maps.rspamd_maybe_check_map(rule[1], ip:to_string()) then
+        return true
+      end
+    else
+      if rule[2] ~= 0 then
+        local nip = ip:apply_mask(rule[2])
+        if nip and nip:to_string() == rule[1]:to_string() then
+          return true
+        end
+      elseif ip:to_string() == rule[1]:to_string() then
         return true
       end
-    elseif ip:to_string() == rule[1]:to_string() then
-      return true
     end
 
     return false
@@ -376,8 +383,8 @@ local function process_settings_table(tbl)
             out[1] = res
             out[2] = 0
           else
-            rspamd_logger.errx(rspamd_config, "bad IP address: " .. ip)
-            return nil
+            -- It can still be a map
+            out[1] = res
           end
         else
           local res = rspamd_ip.from_string(string.sub(ip, 1, slash - 1))
@@ -405,29 +412,34 @@ local function process_settings_table(tbl)
           table.insert(out, process_addr(v))
         end
       elseif type(addr) == "string" then
-        local start = string.sub(addr, 1, 1)
-        if start == '/' then
-          -- It is a regexp
-          local re = rspamd_regexp.create(addr)
-          if re then
-            out['regexp'] = re
-          else
-            rspamd_logger.errx(rspamd_config, "bad regexp: " .. addr)
-            return nil
-          end
-
-        elseif start == '@' then
-          -- It is a domain if form @domain
-          out['domain'] = string.sub(addr, 2)
+        if string.sub(addr, 1, 4) == "map:" then
+          -- It is map, don't apply any extra logic
+          out['name'] = addr
         else
-          -- Check user@domain parts
-          local at = string.find(addr, '@')
-          if at then
-            -- It is full address
-            out['name'] = addr
+          local start = string.sub(addr, 1, 1)
+          if start == '/' then
+            -- It is a regexp
+            local re = rspamd_regexp.create(addr)
+            if re then
+              out['regexp'] = re
+            else
+              rspamd_logger.errx(rspamd_config, "bad regexp: " .. addr)
+              return nil
+            end
+
+          elseif start == '@' then
+            -- It is a domain if form @domain
+            out['domain'] = string.sub(addr, 2)
           else
-            -- It is a user
-            out['user'] = addr
+            -- Check user@domain parts
+            local at = string.find(addr, '@')
+            if at then
+              -- It is full address
+              out['name'] = addr
+            else
+              -- It is a user
+              out['user'] = addr
+            end
           end
         end
       else