aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@rambler-co.ru>2010-07-27 19:09:41 +0400
committerVsevolod Stakhov <vsevolod@rambler-co.ru>2010-07-27 19:09:41 +0400
commitbe555f381e6b72d76c72a91b78291217e6a77c0b (patch)
tree604fa848de0aebd7fbe06363f65c31a8c3f43904
parent6d12fe03df4b366baa3ab7e5046a8a74bb6afecb (diff)
downloadrspamd-be555f381e6b72d76c72a91b78291217e6a77c0b.tar.gz
rspamd-be555f381e6b72d76c72a91b78291217e6a77c0b.zip
* Fix lua representing of invalid ip (nil, not 255.255.255.255)
* Fix R_TO_SEEMS_AUTO rule (by citrin) * Add multimap lua plugin
-rw-r--r--conf/lua/regexp/headers.lua2
-rw-r--r--src/lua/lua_task.c6
-rw-r--r--src/plugins/lua/multimap.lua125
3 files changed, 129 insertions, 4 deletions
diff --git a/conf/lua/regexp/headers.lua b/conf/lua/regexp/headers.lua
index 07f9a785c..d296b3653 100644
--- a/conf/lua/regexp/headers.lua
+++ b/conf/lua/regexp/headers.lua
@@ -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);
diff --git a/src/lua/lua_task.c b/src/lua/lua_task.c
index 71a36aba1..3630462f9 100644
--- a/src/lua/lua_task.c
+++ b/src/lua/lua_task.c
@@ -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
index 000000000..ebf419b12
--- /dev/null
+++ b/src/plugins/lua/multimap.lua
@@ -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