aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/lua
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@rambler-co.ru>2011-02-03 20:29:27 +0300
committerVsevolod Stakhov <vsevolod@rambler-co.ru>2011-02-03 20:29:27 +0300
commit65f15e69284e38d5bbf2177f4466975eca5779b8 (patch)
tree2966f19baebf839fe02b5823b054a9539d921e6c /src/plugins/lua
parent99cb83cd06ca693a032616361bd0b1ae1efabdba (diff)
downloadrspamd-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.lua167
-rw-r--r--src/plugins/lua/multimap.lua10
-rw-r--r--src/plugins/lua/trie.lua2
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