summaryrefslogtreecommitdiffstats
path: root/src/plugins
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 /src/plugins
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
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/lua/multimap.lua125
1 files changed, 125 insertions, 0 deletions
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