]> source.dussan.org Git - rspamd.git/commitdiff
Rework `register_symbols` function.
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Fri, 21 Nov 2014 15:39:04 +0000 (15:39 +0000)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Fri, 21 Nov 2014 15:39:04 +0000 (15:39 +0000)
conf/lua/hfilter.lua
src/lua/lua_config.c

index dd1a21b103b00b482539fb62e1fd58ac0765546e..cd6d7d3dc77d1ad4c058c1159ac1c71aaefb00a5 100644 (file)
@@ -7,7 +7,10 @@
 -- Weight for checks_hellohost and checks_hello: 5 - very hard, 4 - hard, 3 - meduim, 2 - low, 1 - very low.
 -- From HFILTER_HELO_* and HFILTER_HOSTNAME_* symbols the maximum weight is selected in case of their actuating.
 
+
+--local dumper = require 'pl.pretty'.dump
 local rspamd_regexp = require "rspamd_regexp"
+
 local checks_hellohost = {
   ['[.-]dynamic[.-]'] = 5, ['dynamic[.-][0-9]'] = 5, ['[0-9][.-]?dynamic'] = 5, 
   ['[.-]dyn[.-]'] = 5, ['dyn[.-][0-9]'] = 5, ['[0-9][.-]?dyn'] = 5, 
@@ -50,6 +53,14 @@ local checks_hello = {
   ['^\\[*\\d+[x.-]\\d+[x.-]\\d+[x.-]\\d+\\]*$'] = 4, ['^\\[*\\d+:'] = 4 --bareip ipv4, ipv6
 }
 
+local config = {
+  ['helo_enabled'] = false,
+  ['hostname_enabled'] = false,
+  ['from_enabled'] = false,
+  ['mid_enabled'] = false,
+  ['url_enabled'] = false
+}
+
 local function trim1(s)
   return (s:gsub("^%s*(.-)%s*$", "%1"))
 end
@@ -155,11 +166,6 @@ end
 
 --
 local function hfilter(task)
-  local recvh = task:get_received_headers()
-
-  if table.maxn(recvh) == 0 then 
-    return false
-  end
 
   --IP--
   local ip = false
@@ -178,105 +184,115 @@ local function hfilter(task)
 
   -- Check's HELO
   local weight_helo = 0
-  if helo then
-    -- Regexp check HELO (checks_hello)
-    for regexp,weight in pairs(checks_hello) do
-      if check_regexp(helo, regexp) then
-        weight_helo = weight
-        break
+  if config['helo_enabled'] then
+    if helo then
+      -- Regexp check HELO (checks_hello)
+      for regexp,weight in pairs(checks_hello) do
+        if check_regexp(helo, regexp) then
+          weight_helo = weight
+          break
+        end
       end
-    end
 
-    -- Regexp check HELO (checks_hellohost)
-    for regexp,weight in pairs(checks_hellohost) do
-      if check_regexp(helo, regexp) then
-        if weight > weight_helo then
-          weight_helo = weight
+      -- Regexp check HELO (checks_hellohost)
+      for regexp,weight in pairs(checks_hellohost) do
+        if check_regexp(helo, regexp) then
+          if weight > weight_helo then
+            weight_helo = weight
+          end
+          break
         end
-        break
       end
-    end
 
-    --FQDN check HELO
-    if ip and helo then
-      check_host(task, helo, 'HELO', ip, hostname)
+      --FQDN check HELO
+      if ip and helo then
+        check_host(task, helo, 'HELO', ip, hostname)
+      end
     end
   end
 
   -- Check's HOSTNAME
-  local weight_hostname = 0
-  if hostname then
-    -- Check regexp HOSTNAME
-    if hostname == 'unknown' then
-      task:insert_result('HFILTER_HOSTNAME_UNKNOWN', 1.00)
-    else
-      for regexp,weight in pairs(checks_hellohost) do
-        if check_regexp(hostname, regexp) then
-          weight_hostname = weight
-          break
+  if config['hostname_enabled'] then
+    local weight_hostname = 0
+    if hostname then
+      -- Check regexp HOSTNAME
+      if hostname == 'unknown' then
+        task:insert_result('HFILTER_HOSTNAME_UNKNOWN', 1.00)
+      else
+        for regexp,weight in pairs(checks_hellohost) do
+          if check_regexp(hostname, regexp) then
+            weight_hostname = weight
+            break
+          end
         end
       end
     end
-  end
 
-  --Insert weight's for HELO or HOSTNAME
-  if weight_helo > 0 and weight_helo >= weight_hostname then
-    task:insert_result('HFILTER_HELO_' .. weight_helo, 1.0)
-  elseif weight_hostname > 0 and weight_hostname > weight_helo then
-    task:insert_result('HFILTER_HOSTNAME_' .. weight_hostname, 1.0)
+    --Insert weight's for HELO or HOSTNAME
+    if weight_helo > 0 and weight_helo >= weight_hostname then
+      task:insert_result('HFILTER_HELO_' .. weight_helo, 1.0)
+    elseif weight_hostname > 0 and weight_hostname > weight_helo then
+      task:insert_result('HFILTER_HOSTNAME_' .. weight_hostname, 1.0)
+    end
   end
-
-  -- MAILFROM checks --
-  local from = task:get_from(1)
-  if from then
-    --FROM host check
-    for _,fr in ipairs(from) do
-      local fr_split = split(fr['addr'], '@', 0)
-      if table.maxn(fr_split) == 2 then
-        check_host(task, fr_split[2], 'FROMHOST', '', '')
+  
+  if config['from_enabled'] then
+    -- MAILFROM checks --
+    local from = task:get_from(1)
+    if from then
+      --FROM host check
+      for _,fr in ipairs(from) do
+        local fr_split = split(fr['addr'], '@', 0)
+        if table.maxn(fr_split) == 2 then
+          check_host(task, fr_split[2], 'FROMHOST', '', '')
+        end
       end
     end
   end
 
   --Message ID host check
-  local message_id = task:get_message_id()
-  if message_id then
-    local mid_split = split(message_id, '@', 0)
-    if table.maxn(mid_split) == 2 and not string.find(mid_split[2], 'local') then
-      check_host(task, mid_split[2], 'MID', '', '')
+  if config['mid_enabled'] then
+    local message_id = task:get_message_id()
+    if message_id then
+      local mid_split = split(message_id, '@', 0)
+      if table.maxn(mid_split) == 2 and not string.find(mid_split[2], 'local') then
+        check_host(task, mid_split[2], 'MID', '', '')
+      end
     end
   end
-
+  
   -- Links checks
-  local parts = task:get_text_parts()
-  if parts then
-    --One text part--
-    local total_parts_len = 0
-    local text_parts_count = 0
-    local selected_text_part = nil
-    for _,p in ipairs(parts) do
-      total_parts_len = total_parts_len + p:get_length()
-
-      if not p:is_html() then
-        text_parts_count = text_parts_count + 1
-        selected_text_part = p
-      end
-    end
-    if total_parts_len > 0 then
-      local urls = task:get_urls()
-      if urls then
-        local total_url_len = 0
-        for _,url in ipairs(urls) do
-          total_url_len = total_url_len + url:get_length()
+  if config['url_enabled'] then
+    local parts = task:get_text_parts()
+    if parts then
+      --One text part--
+      local total_parts_len = 0
+      local text_parts_count = 0
+      local selected_text_part = nil
+      for _,p in ipairs(parts) do
+        total_parts_len = total_parts_len + p:get_length()
+
+        if not p:is_html() then
+          text_parts_count = text_parts_count + 1
+          selected_text_part = p
         end
-        if total_url_len > 0 then
-          if total_url_len + 7 > total_parts_len then
-            task:insert_result('HFILTER_URL_ONLY', 1.00)
-          elseif text_parts_count == 1 and selected_text_part and selected_text_part:get_length() < 1024 then
-            -- We got a single text part with the total length < 1024 symbols.
-            local part_text = selected_text_part:get_content()
-            if part_text and not string.find(trim1(part_text), "\n") then
-              task:insert_result('HFILTER_URL_ONELINE', 1.00)
+      end
+      if total_parts_len > 0 then
+        local urls = task:get_urls()
+        if urls then
+          local total_url_len = 0
+          for _,url in ipairs(urls) do
+            total_url_len = total_url_len + url:get_length()
+          end
+          if total_url_len > 0 then
+            if total_url_len + 7 > total_parts_len then
+              task:insert_result('HFILTER_URL_ONLY', 1.00)
+            elseif text_parts_count == 1 and selected_text_part and selected_text_part:get_length() < 1024 then
+              -- We got a single text part with the total length < 1024 symbols.
+              local part_text = selected_text_part:get_content()
+              if part_text and not string.find(trim1(part_text), "\n") then
+                task:insert_result('HFILTER_URL_ONELINE', 1.00)
+              end
             end
           end
         end
@@ -287,12 +303,70 @@ local function hfilter(task)
   return false
 end
 
-rspamd_config:register_symbols(hfilter, 1.0, 
-  "HFILTER_HELO_1", "HFILTER_HELO_2", "HFILTER_HELO_3", "HFILTER_HELO_4", "HFILTER_HELO_5", 
-  "HFILTER_HOSTNAME_1", "HFILTER_HOSTNAME_2", "HFILTER_HOSTNAME_3", "HFILTER_HOSTNAME_4", "HFILTER_HOSTNAME_5", 
-  "HFILTER_HELO_NORESOLVE_MX", "HFILTER_HELO_NORES_A_OR_MX", "HFILTER_HELO_IP_A", "HFILTER_HELO_NOT_FQDN", 
-  "HFILTER_FROMHOST_NORESOLVE_MX", "HFILTER_FROMHOST_NORES_A_OR_MX", "HFILTER_FROMHOST_NOT_FQDN",  
-  "HFILTER_MID_NORESOLVE_MX", "HFILTER_MID_NORES_A_OR_MX", "HFILTER_MID_NOT_FQDN",
+local symbols_enabled = {}
+
+local symbols_helo = {
+  "HFILTER_HELO_1",
+  "HFILTER_HELO_2",
+  "HFILTER_HELO_3", 
+  "HFILTER_HELO_4",
+  "HFILTER_HELO_5",
+  "HFILTER_HELO_NORESOLVE_MX", 
+  "HFILTER_HELO_NORES_A_OR_MX",
+  "HFILTER_HELO_IP_A",
+  "HFILTER_HELO_NOT_FQDN"
+}
+local symbols_hostname = {
+  "HFILTER_HOSTNAME_1",
+  "HFILTER_HOSTNAME_2",
+  "HFILTER_HOSTNAME_3",
+  "HFILTER_HOSTNAME_4",
+  "HFILTER_HOSTNAME_5",
+  "HFILTER_HOSTNAME_UNKNOWN"
+}
+local symbols_mid = {
+  "HFILTER_MID_NORESOLVE_MX",
+  "HFILTER_MID_NORES_A_OR_MX",
   "HFILTER_MID_NOT_FQDN",
-  "HFILTER_HOSTNAME_UNKNOWN",
-  "HFILTER_URL_ONLY", "HFILTER_URL_ONELINE");
+  "HFILTER_MID_NOT_FQDN"
+}
+local symbols_url = {
+  "HFILTER_URL_ONLY",
+  "HFILTER_URL_ONELINE"
+}
+local symbols_from = {
+  "HFILTER_FROMHOST_NORESOLVE_MX",
+  "HFILTER_FROMHOST_NORES_A_OR_MX",
+  "HFILTER_FROMHOST_NOT_FQDN"
+}
+
+local opts = rspamd_config:get_all_opt('hfilter')
+if opts then
+  for k,v in pairs(opts) do
+    config[k] = v
+  end
+end
+
+local function append_t(t, a)
+  for _,v in ipairs(a) do table.insert(t, v) end
+end
+if config['helo_enabled'] then
+  append_t(symbols_enabled, symbols_helo)
+end
+if config['hostname_enabled'] then
+  append_t(symbols_enabled, symbols_hostname)
+end
+if config['from_enabled'] then
+  append_t(symbols_enabled, symbols_from)
+end
+if config['mid_enabled'] then
+  append_t(symbols_enabled, symbols_mid)
+end
+if config['url_enabled'] then
+  append_t(symbols_enabled, symbols_url)
+end
+
+--dumper(symbols_enabled)
+if table.maxn(symbols_enabled) > 0 then
+  rspamd_config:register_symbols(hfilter, 1.0, "HFILTER", symbols_enabled);
+end
index 9533c17d1a5f83a2817f2d16d6dd5e0bbde51327..5e67af9d9dbd573529803cdfb62237e5df694237 100644 (file)
@@ -181,10 +181,11 @@ LUA_FUNCTION_DEF (config, get_classifier);
  */
 LUA_FUNCTION_DEF (config, register_symbol);
 /***
- * @method rspamd_config:register_symbols(weight, callback, symbol[, symbol, ...])
+ * @method rspamd_config:register_symbols(weight, callback, callback_name, [, symbol, ...])
  * Register callback function to be called for a set of symbols with initial weight.
  * @param {number} weight initial weight of symbol (can be less than zero to specify non-spam symbols)
  * @param {function} callback callback function to be called for a specified symbol
+ * @param {string} callback_name symbolic name of callback
  * @param {list of strings} symbol list of symbols registered by this function
  */
 LUA_FUNCTION_DEF (config, register_symbols);
@@ -975,19 +976,33 @@ lua_config_register_symbols (lua_State *L)
                else {
                        top = 3;
                }
-               sym = rspamd_mempool_strdup (cfg->cfg_pool, luaL_checkstring (L, top));
+               sym = rspamd_mempool_strdup (cfg->cfg_pool, luaL_checkstring (L, top ++));
                rspamd_register_symbol_fromlua (L,
                                cfg,
                                sym,
                                idx,
                                weight,
                                0,
-                               SYMBOL_TYPE_NORMAL);
-               for (i = top; i < lua_gettop (L); i++) {
-                       sym =
-                               rspamd_mempool_strdup (cfg->cfg_pool, luaL_checkstring (L,
-                                       i + 1));
-                       register_virtual_symbol (&cfg->cache, sym, weight);
+                               SYMBOL_TYPE_CALLBACK);
+               for (i = top; i <= lua_gettop (L); i++) {
+                       if (lua_type (L, i) == LUA_TTABLE) {
+                               lua_pushvalue (L, i);
+                               lua_pushnil (L);
+                               while (lua_next (L, -2)) {
+                                       lua_pushvalue (L, -2);
+                                       sym = rspamd_mempool_strdup (cfg->cfg_pool,
+                                                       luaL_checkstring (L, -2));
+                                       register_virtual_symbol (&cfg->cache, sym, weight);
+                                       lua_pop (L, 2);
+                               }
+                               lua_pop (L, 1);
+                       }
+                       else if (lua_type (L, i) == LUA_TSTRING) {
+                               sym =
+                                               rspamd_mempool_strdup (cfg->cfg_pool, luaL_checkstring (L,
+                                                               i + 1));
+                               register_virtual_symbol (&cfg->cache, sym, weight);
+                       }
                }
        }