From 43f5da169c57c2aba7522162a7707dec32894343 Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Mon, 9 Dec 2013 15:23:14 +0000 Subject: [PATCH] Rework emails plugin. --- src/plugins/lua/emails.lua | 119 +++++++++++-------------------------- 1 file changed, 34 insertions(+), 85 deletions(-) diff --git a/src/plugins/lua/emails.lua b/src/plugins/lua/emails.lua index 8b4ba5970..162809541 100644 --- a/src/plugins/lua/emails.lua +++ b/src/plugins/lua/emails.lua @@ -5,40 +5,16 @@ -- 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.gmatch(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 - rspamd_logger.info(string.format('<%s> email: [%s] resolved for symbol: %s', task:get_message():get_message_id(), to_resolve, symbol)) - task:insert_result(symbol, 1) - end -end - -- Check rule for a single email -function check_email_rule(task, rule, addr) +local function check_email_rule(task, rule, addr) + local function emails_dns_cb(resolver, to_resolve, results, err) + task:inc_dns_req() + if results then + rspamd_logger.info(string.format('<%s> email: [%s] resolved for symbol: %s', + task:get_message():get_message_id(), to_resolve, rule['symbol'])) + task:insert_result(rule['symbol'], 1) + end + end if rule['dnsbl'] then local to_resolve = '' if rule['domain_only'] then @@ -46,26 +22,29 @@ function check_email_rule(task, rule, addr) 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']) + task:get_resolver():resolve_a(task:get_session(), task:get_mempool(), + to_resolve, emails_dns_cb) elseif rule['map'] then if rule['domain_only'] then local key = addr:get_host() if rule['map']:get_key(key) then task:insert_result(rule['symbol'], 1) - rspamd_logger.info(string.format('<%s> email: \'%s\' is found in list: %s', task:get_message():get_message_id(), key, rule['symbol'])) + rspamd_logger.info(string.format('<%s> email: \'%s\' is found in list: %s', + task:get_message():get_message_id(), key, rule['symbol'])) end else local key = string.format('%s@%s', addr:get_user(), addr:get_host()) if rule['map']:get_key(key) then task:insert_result(rule['symbol'], 1) - rspamd_logger.info(string.format('<%s> email: \'%s\' is found in list: %s', task:get_message():get_message_id(), key, rule['symbol'])) + rspamd_logger.info(string.format('<%s> email: \'%s\' is found in list: %s', + task:get_message():get_message_id(), key, rule['symbol'])) end end end end -- Check email -function check_emails(task) +local function check_emails(task) local emails = task:get_emails() local checked = {} if emails then @@ -81,40 +60,6 @@ function check_emails(task) end end --- Add rule to ruleset -local function add_emails_rule(key, obj) - local newrule = { - name = nil, - dnsbl = nil, - map = nil, - domain_only = false, - symbol = key - } - for name,value in pairs(obj) do - 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 - newrule['domain_only'] = value - 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 @@ -125,19 +70,23 @@ if type(rspamd_config.get_api_version) ~= 'nil' then end end -local opts = rspamd_config:get_all_opt('emails') -if opts then - for k,m in pairs(opts) do - if type(m) ~= 'table' then - rspamd_logger.err('parameter ' .. k .. ' is invalid, must be an object') - else - local rule = add_emails_rule(k, m) - if not rule then - rspamd_logger.err('cannot add rule: "'..k..'"') +local opts = rspamd_config:get_all_opt('emails', 'rule') +if opts and type(opts) == 'table' then + for k,v in pairs(opts) do + if k == 'rule' and type(v) == 'table' then + local rule = v + if not rule['symbol'] then + rule['symbol'] = k + end + if rule['map'] then + rule['name'] = rule['map'] + rule['map'] = rspamd_config:add_hash_map (rule['name']) + end + if not rule['symbol'] or (not rule['map'] and not rule['dnsbl']) then + rspamd_logger.err('incomplete rule') else - if type(rspamd_config.get_api_version) ~= 'nil' then - rspamd_config:register_virtual_symbol(rule['symbol'], 1.0) - end + table.insert(rules, rule) + rspamd_config:register_virtual_symbol(rule['symbol'], 1.0) end end end @@ -146,8 +95,8 @@ 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') + rspamd_config:register_callback_symbol('EMAILS', 1.0, check_emails) else - rspamd_config:register_symbol('EMAILS', 1.0, 'check_emails') + rspamd_config:register_symbol('EMAILS', 1.0, check_emails) end end -- 2.39.5