local rules = {}
local rspamd_logger = require "rspamd_logger"
local cdb = require "rspamd_cdb"
+local util = require "rspamd_util"
+local regexp = require "rspamd_regexp"
local _ = require "fun"
--local dumper = require 'pl.pretty'.dump
end
local function check_multimap(task)
+ -- Applies specific filter for input
+ local function apply_filter(filter, input, rule)
+ if filter == 'email:addr' or filter == 'email' then
+ local addr = util.parse_mail_address(input)
+ if addr and addr[1] then
+ return addr[1]['addr']
+ end
+ elseif filter == 'email:user' then
+ local addr = util.parse_mail_address(input)
+ if addr and addr[1] then
+ return addr[1]['user']
+ end
+ elseif filter == 'email:domain' then
+ local addr = util.parse_mail_address(input)
+ if addr and addr[1] then
+ return addr[1]['domain']
+ end
+ elseif filter == 'email:name' then
+ local addr = util.parse_mail_address(input)
+ if addr and addr[1] then
+ return addr[1]['name']
+ end
+ else
+ -- regexp case
+ if not rule['regexp'] then
+ local type,pat = string.match(filter, '(regexp:)(.+)')
+ if type and pat then
+ rule['regexp'] = regexp.create(pat)
+ end
+ end
+
+ if not rule['regexp'] then
+ rspamd_logger.errx(task, 'bad search filter: %s', filter)
+ else
+ local results = rule['regexp']:search(input)
+ if results then
+ return results[1]
+ end
+ end
+ end
+
+ return input
+ end
+
+
-- Match a single value for against a single rule
local function match_rule(r, value)
local ret = false
+
+ if r['filter'] then
+ value = apply_filter(r['filter'], value, r)
+ end
+
+ if not value then
+ return false
+ end
+
if r['cdb'] then
local srch = value
if r['type'] == 'ip' then
if ret then
task:insert_result(r['symbol'], 1)
end
-
+
return ret
end
local ret = false
if ls then
if fields then
- _.each(function(e)
+ _.each(function(e)
local match = e[fields[1]]
if match then
if fields[2] then
match = fields[2](match)
end
- ret = match_rule(r, match)
+ ret = match_rule(r, match)
end
end, ls)
else
return ret
end
-
+
local function match_addr(r, addr)
local ret = match_list(r, addr, {'addr'})
-
+
if not ret then
-- Try domain
ret = match_list(r, addr, {'domain', function(d) return '@' .. d end})
-- Try user
ret = match_list(r, addr, {'user', function(d) return d .. '@' end})
end
-
+
return ret
end
+
-- IP rules
local ip = task:get_from_ip()
if ip:is_valid() then
-- Header rules
_.each(function(r)
local hv = task:get_header_full(r['header'])
- match_list(r, hv, 'decoded')
+ match_list(r, hv, {'decoded'})
end,
_.filter(function(r) return r['type'] == 'header' end, rules))
-- Rcpt rules
- local rcpts = task:get_recipients()
- if rcpts then
+ if task:has_recipients() then
+ local rcpts = task:get_recipients()
_.each(function(r)
match_addr(r, rcpts)
end,
end
-- From rules
- local from = task:get_from()
- if from then
- _.each(function(r)
- match_addr(r, from)
- end,
- _.filter(function(r) return r['type'] == 'from' end, rules))
+ if task:has_from() then
+ local from = task:get_from()
+ if from then
+ _.each(function(r)
+ match_addr(r, from)
+ end,
+ _.filter(function(r) return r['type'] == 'from' end, rules))
+ end
end
-- RBL rules
task:insert_result(r['symbol'], 1, r['map'])
end
end
-
+
task:get_resolver():resolve_a({task = task,
name = ip_to_rbl(ip, r['map']),
callback = cb,
local function add_multimap_rule(key, newrule)
if not newrule['map'] then
- rspamd_logger.errx(rspamd_config, 'incomplete rule')
+ rspamd_logger.errx(rspamd_config, 'incomplete rule, missing map')
return nil
end
if not newrule['symbol'] and key then
newrule['symbol'] = key
elseif not newrule['symbol'] then
- rspamd_logger.errx(rspamd_config, 'incomplete rule')
+ rspamd_logger.errx(rspamd_config, 'incomplete rule, missing symbol')
return nil
end
-- Check cdb flag
newrule['map'])
end
elseif newrule['type'] == 'dnsbl' then
- return newrule
+ return newrule
end
end
return nil
end
-- add fake symbol to check all maps inside a single callback
if type(rspamd_config.get_api_version) ~= 'nil' then
- local id = rspamd_config:register_callback_symbol_priority(1.0, -1,
+ local id = rspamd_config:register_callback_symbol_priority(1.0, -1,
check_multimap)
for i,rule in ipairs(rules) do
rspamd_config:register_virtual_symbol(rule['symbol'], 1.0, id)