diff options
author | Vsevolod Stakhov <vsevolod@rambler-co.ru> | 2011-02-03 20:29:27 +0300 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@rambler-co.ru> | 2011-02-03 20:29:27 +0300 |
commit | 65f15e69284e38d5bbf2177f4466975eca5779b8 (patch) | |
tree | 2966f19baebf839fe02b5823b054a9539d921e6c /src/plugins/lua | |
parent | 99cb83cd06ca693a032616361bd0b1ae1efabdba (diff) | |
download | rspamd-65f15e69284e38d5bbf2177f4466975eca5779b8.tar.gz rspamd-65f15e69284e38d5bbf2177f4466975eca5779b8.zip |
* New module for checking emails inside messages (rules based, like multimap)
* Emails now are separated from urls and urls checks
* Add ability to check text attachements if option is presented in a configuration
Version is 0.3.6 now
Diffstat (limited to 'src/plugins/lua')
-rw-r--r-- | src/plugins/lua/emails.lua | 167 | ||||
-rw-r--r-- | src/plugins/lua/multimap.lua | 10 | ||||
-rw-r--r-- | src/plugins/lua/trie.lua | 2 |
3 files changed, 172 insertions, 7 deletions
diff --git a/src/plugins/lua/emails.lua b/src/plugins/lua/emails.lua new file mode 100644 index 000000000..969c762ec --- /dev/null +++ b/src/plugins/lua/emails.lua @@ -0,0 +1,167 @@ +-- Emails is module for different checks for emails inside messages + +-- Rules format: +-- symbol = sym, map = file:///path/to/file, domain_only = yes +-- symbol = sym2, dnsbl = bl.somehost.com, domain_only = no +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 emails_dns_cb(task, to_resolve, results, err, symbol) + if results then + task:insert_result(symbol, 1) + end +end + +-- Check rule for a single email +function check_email_rule(task, rule, addr) + if rule['dnsbl'] then + local to_resolve = '' + if rule['domain_only'] then + to_resolve = string.format('%s.%s', addr:get_host(), rule['dnsbl']) + else + to_resolve = string.format('%s.%s.%s', addr:get_user(), addr:get_host(), rule['dnsbl']) + end + task:resolve_dns_a(to_resolve, 'emails_dns_cb', rule['symbol']) + elseif rule['map'] then + if rule['domain_only'] then + if rule['map']:get_key(addr:get_host()) then + task:insert_result(rule['symbol'], 1) + end + else + if rule['map']:get_key(string.format('%s@%s', addr:get_user(), addr:get_host())) then + task:insert_result(rule['symbol'], 1) + end + end + end +end + +-- Check email +function check_emails(task) + local emails = task:get_emails() + local checked = {} + if emails then + for _,addr in ipairs(emails) do + local to_check = string.format('%s@%s', addr:get_user(), addr:get_host()) + if not checked['to_check'] then + for _,rule in ipairs(rules) do + check_email_rule(task, rule, addr) + end + checked[to_check] = true + end + end + end +end + +-- Add rule to ruleset +local function add_emails_rule(params) + local newrule = { + name = nil, + dnsbl = nil, + map = nil, + domain_only = false, + symbol = nil + } + for _,param in ipairs(params) do + local _,_,name,value = string.find(param, '([a-zA-Z_0-9]+)%s*=%s*(.+)') + if not name or not value then + rspamd_logger:err('invalid rule: '..param) + return nil + end + if name == 'dnsbl' then + newrule['dnsbl'] = value + newrule['name'] = value + elseif name == 'map' then + newrule['name'] = value + newrule['map'] = rspamd_config:add_hash_map (newrule['name']) + elseif name == 'symbol' then + newrule['symbol'] = value + elseif name == 'domain_only' then + if value == 'yes' or value == 'true' or value == '1' then + newrule['domain_only'] = true + end + else + rspamd_logger:err('invalid rule option: '.. name) + return nil + end + + end + if not newrule['symbol'] or (not newrule['map'] and not newrule['dnsbl']) then + rspamd_logger:err('incomplete rule') + return nil + end + table.insert(rules, newrule) + return newrule +end + + +-- Registration +if type(rspamd_config.get_api_version) ~= 'nil' then + if rspamd_config:get_api_version() >= 2 then + rspamd_config:register_module_option('emails', 'rule', 'string') + else + rspamd_logger:err('Invalid rspamd version for this plugin') + end +end + +local opts = rspamd_config:get_all_opt('emails') +if opts then + local strrules = opts['rule'] + if strrules then + if type(strrules) == 'table' then + for _,value in ipairs(strrules) do + local params = split(value, ',') + local rule = add_emails_rule (params) + if not rule then + rspamd_logger:err('cannot add rule: "'..value..'"') + else + if type(rspamd_config.get_api_version) ~= 'nil' then + rspamd_config:register_virtual_symbol(rule['symbol'], 1.0) + end + end + end + elseif type(strrules) == 'string' then + local params = split(strrules, ',') + local rule = add_emails_rule (params) + if not rule then + rspamd_logger:err('cannot add rule: "'..strrules..'"') + else + if type(rspamd_config.get_api_version) ~= 'nil' then + rspamd_config:register_virtual_symbol(rule['symbol'], 1.0) + end + end + end + end +end + +if table.maxn(rules) > 0 then + -- add fake symbol to check all maps inside a single callback + if type(rspamd_config.get_api_version) ~= 'nil' then + rspamd_config:register_callback_symbol('EMAILS', 1.0, 'check_emails') + else + rspamd_config:register_symbol('EMAILS', 1.0, 'check_emails') + end +end diff --git a/src/plugins/lua/multimap.lua b/src/plugins/lua/multimap.lua index 6986c8c72..9512ff890 100644 --- a/src/plugins/lua/multimap.lua +++ b/src/plugins/lua/multimap.lua @@ -27,7 +27,7 @@ function split(str, delim, maxNb) return result end -function rbl_cb(task, to_resolve, results, err) +function multimap_rbl_cb(task, to_resolve, results, err) if results then local _,_,o4,o3,o2,o1,in_rbl = string.find(to_resolve, '(%d+)%.(%d+)%.(%d+)%.(%d+)%.(.+)') -- Get corresponding rule by rbl name @@ -71,13 +71,13 @@ function check_multimap(task) if ip then local _,_,o1,o2,o3,o4 = string.find(ip, '(%d+)%.(%d+)%.(%d+)%.(%d+)') local rbl_str = o4 .. '.' .. o3 .. '.' .. o2 .. '.' .. o1 .. '.' .. rule['map'] - task:resolve_dns_a(rbl_str, 'rbl_cb') + task:resolve_dns_a(rbl_str, 'multimap_rbl_cb') end end end end -function add_rule(params) +local function add_multimap_rule(params) local newrule = { type = 'ip', header = nil, @@ -143,7 +143,7 @@ if opts then if type(strrules) == 'table' then for _,value in ipairs(strrules) do local params = split(value, ',') - local rule = add_rule (params) + local rule = add_multimap_rule (params) if not rule then rspamd_logger:err('cannot add rule: "'..value..'"') else @@ -154,7 +154,7 @@ if opts then end elseif type(strrules) == 'string' then local params = split(strrules, ',') - local rule = add_rule (params) + local rule = add_multimap_rule (params) if not rule then rspamd_logger:err('cannot add rule: "'..strrules..'"') else diff --git a/src/plugins/lua/trie.lua b/src/plugins/lua/trie.lua index d4bafe943..98248f29f 100644 --- a/src/plugins/lua/trie.lua +++ b/src/plugins/lua/trie.lua @@ -50,7 +50,6 @@ local function add_trie(params) local patterns = split(params[2], ',') local trie = {} trie['trie'] = rspamd_trie:create(true) - print (type(trie['trie'])) for num,pattern in ipairs(patterns) do trie['trie']:add_pattern(pattern, num) end @@ -64,7 +63,6 @@ end function check_trie(task) for _,trie in ipairs(tries) do - print (type(trie['trie'])) if trie['trie']:search_task(task) then task:insert_result(trie['symbol'], 1) end |