]> source.dussan.org Git - rspamd.git/commitdiff
Rework emails plugin.
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Mon, 9 Dec 2013 15:23:14 +0000 (15:23 +0000)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Mon, 9 Dec 2013 15:23:14 +0000 (15:23 +0000)
src/plugins/lua/emails.lua

index 8b4ba5970232d5230810c00ede0b742f867b1f96..162809541c5b0a12751f0d833ab1ce24bda5747b 100644 (file)
@@ -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