]> source.dussan.org Git - rspamd.git/commitdiff
* Fix lua representing of invalid ip (nil, not 255.255.255.255)
authorVsevolod Stakhov <vsevolod@rambler-co.ru>
Tue, 27 Jul 2010 15:09:41 +0000 (19:09 +0400)
committerVsevolod Stakhov <vsevolod@rambler-co.ru>
Tue, 27 Jul 2010 15:09:41 +0000 (19:09 +0400)
* Fix R_TO_SEEMS_AUTO rule (by citrin)
* Add multimap lua plugin

conf/lua/regexp/headers.lua
src/lua/lua_task.c
src/plugins/lua/multimap.lua [new file with mode: 0644]

index 07f9a785c540f6b8a7e79c5d11122cff7f0108c5..d296b365394587050d33825bec9dd96471cd0a51 100644 (file)
@@ -44,7 +44,7 @@ reconf['MISSING_MID'] = '!header_exists(Message-Id)';
 reconf['R_RCVD_SPAMBOTS'] = 'Received=/^from \\[\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\] by [-.\\w+]{5,255}; [SMTWF][a-z][a-z], [\\s\\d]?\\d [JFMAJSOND][a-z][a-z] \\d{4} \\d{2}:\\d{2}:\\d{2} [-+]\\d{4}$/mH'
 
 -- To header seems to be autogenerated
-reconf['R_TO_SEEMS_AUTO'] = 'To=/\\"?(?<bt>[-.\\w]{1,64})\\"?\\s<\\k<bt>\\@/H'
+reconf['R_TO_SEEMS_AUTO'] = 'To=/^\\"?(?<bt>[-.\\w]{1,64})\\"?\\s<\\k<bt>\\@/H'
 
 -- Charset is missing in message
 reconf['R_MISSING_CHARSET']= string.format('content_type_is_type(text) & !content_type_has_param(charset) & !%s', r_cte_7bit);
index 71a36aba1ad4b59c226d92ef242bf19f675d6dd8..3630462f99e59b781a0f80ebb7bb1b2e29337e1c 100644 (file)
@@ -471,7 +471,7 @@ lua_task_get_from_ip (lua_State *L)
        struct worker_task             *task = lua_check_task (L);
        
        if (task) {
-               if (task->from_addr.s_addr != 0) {
+               if (task->from_addr.s_addr != INADDR_NONE && task->from_addr.s_addr != INADDR_ANY) {
                        lua_pushstring (L, inet_ntoa (task->from_addr));
                        return 1;
                }
@@ -487,7 +487,7 @@ lua_task_get_from_ip_num (lua_State *L)
        struct worker_task             *task = lua_check_task (L);
        
        if (task) {
-               if (task->from_addr.s_addr != 0) {
+               if (task->from_addr.s_addr != INADDR_NONE && task->from_addr.s_addr != INADDR_ANY) {
                        lua_pushinteger (L, ntohl (task->from_addr.s_addr));
                        return 1;
                }
@@ -503,7 +503,7 @@ lua_task_get_client_ip_num (lua_State *L)
        struct worker_task             *task = lua_check_task (L);
        
        if (task) {
-               if (task->client_addr.s_addr != 0) {
+               if (task->client_addr.s_addr != INADDR_NONE && task->client_addr.s_addr != INADDR_ANY) {
                        lua_pushinteger (L, ntohl (task->client_addr.s_addr));
                        return 1;
                }
diff --git a/src/plugins/lua/multimap.lua b/src/plugins/lua/multimap.lua
new file mode 100644 (file)
index 0000000..ebf419b
--- /dev/null
@@ -0,0 +1,125 @@
+-- Multimap is rspamd module designed to define and operate with different maps
+
+local rules = {}
+
+function split(str, delim, maxNb)
+       -- Eliminate bad cases...
+       if string.find(str, delim) == nil then
+               return { str }
+       end
+       if maxNb == nil or maxNb < 1 then
+               maxNb = 0    -- No limit
+       end
+       local result = {}
+       local pat = "(.-)" .. delim .. "()"
+       local nb = 0
+       local lastPos
+       for part, pos in string.gfind(str, pat) do
+               nb = nb + 1
+               result[nb] = part
+               lastPos = pos
+               if nb == maxNb then break end
+       end
+       -- Handle the last field
+       if nb ~= maxNb then
+               result[nb + 1] = string.sub(str, lastPos)
+       end
+       return result
+end
+
+function check_multimap(task)
+       for _,rule in ipairs(rules) do
+               if rule['type'] == 'ip' then
+                       local ip = task:get_from_ip_num()
+                       if rule['ips']:get_key(ip) then
+                               task:insert_result(rule['symbol'], 1)
+                       end
+               elseif rule['type'] == 'header' then
+                       local headers = task:get_message():get_header(rule['header'])
+                       if headers then
+                               for _,hv in ipairs(headers) do
+                                       if rule['pattern'] then
+                                               -- extract a part from header
+                                               local _,_,ext = string.find(hv, rule['pattern'])
+                                               if ext then
+                                                       if rule['hash']:get_key(ext) then
+                                                               task:insert_result(rule['symbol'], 1)
+                                                       end
+                                               end
+                                       else
+                                               if rule['hash']:get_key(hv) then
+                                                       task:insert_result(rule['symbol'], 1)
+                                               end
+                                       end
+                               end
+                       end
+               end
+       end
+end
+
+function add_rule(params)
+       local newrule = {
+               type = 'ip',
+               header = nil,
+               pattern = nil,
+               file = nil,
+               symbol = nil
+       }
+       for _,param in ipairs(params) do
+               local _,_,name,value = string.find(param, '(%w+)%s*=%s*(.+)')
+               if not name or not value then
+                       rspamd_logger:err('invalid rule: '..param)
+                       return 0
+               end
+               if name == 'type' then
+                       if value == 'ip' then
+                               newrule['type'] = 'ip'
+                       elseif value == 'header' then
+                               newrule['type'] = 'header'
+                       else
+                               rspamd_logger:err('invalid rule type: '.. value)
+                               return 0
+                       end
+               elseif name == 'header' then
+                       newrule['header'] = value
+               elseif name == 'pattern' then
+                       newrule['pattern'] = value
+               elseif name == 'file' then
+                       newrule['file'] = value
+               elseif name == 'symbol' then
+                       newrule['symbol'] = value
+               else    
+                       rspamd_logger:err('invalid rule option: '.. name)
+                       return 0
+               end
+
+       end
+       if not newrule['symbol'] or not newrule['file'] or not newrule['symbol'] then
+               rspamd_logger:err('incomplete rule')
+               return 0
+       end
+       if newrule['type'] == 'ip' then
+               newrule['ips'] = rspamd_config:add_radix_map (newrule['file'])
+       else
+               newrule['hash'] = rspamd_config:add_hash_map (newrule['file'])
+       end
+       table.insert(rules, newrule)
+       return 1
+end
+
+local opts =  rspamd_config:get_all_opt('multimap')
+if opts then
+       for opt,value in pairs(opts) do
+               if opt == 'rule' then
+                       local params = split(value, ',')
+                       if not add_rule (params) then
+                               rspamd_logger:err('cannot add rule: "'..value..'"')
+                       end
+               end
+       end
+end
+
+if table.maxn(rules) > 0 then
+       -- add fake symbol to check all maps inside a single callback
+       rspamd_config:register_symbol('MULTIMAP', 1.0, 'check_multimap')
+end