local function dmarc_report_cb(task, err, data) | local function dmarc_report_cb(task, err, data) | ||||
if not err then | if not err then | ||||
rspamd_logger.info(string.format('<%s> dmarc report saved for %s', | |||||
task:get_message_id(), from[1]['domain'])) | |||||
rspamd_logger.infox(task, '<%1> dmarc report saved for %2', | |||||
task:get_message_id(), from[1]['domain']) | |||||
else | else | ||||
rspamd_logger.err(string.format('<%s> dmarc report is not saved for %s: %s', | |||||
task:get_message_id(), from[1]['domain'], err)) | |||||
rspamd_logger.errx(task, '<%1> dmarc report is not saved for %2: %3', | |||||
task:get_message_id(), from[1]['domain'], err) | |||||
end | end | ||||
end | end | ||||
end | end | ||||
if not opts['servers'] then | if not opts['servers'] then | ||||
rspamd_logger.err('no servers are specified for dmarc stats') | |||||
rspamd_logger.errx(rspamd_config, 'no servers are specified for dmarc stats') | |||||
else | else | ||||
upstreams = upstream_list.create(opts['servers'], default_port) | upstreams = upstream_list.create(opts['servers'], default_port) | ||||
if not upstreams then | if not upstreams then | ||||
rspamd_logger.err('cannot parse servers parameter') | |||||
rspamd_logger.errx(rspamd_config, 'cannot parse servers parameter') | |||||
end | end | ||||
end | end | ||||
local 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) | local function emails_dns_cb(resolver, to_resolve, results, err) | ||||
if results then | if results then | ||||
logger.infox('<%1> email: [%2] resolved for symbol: %3', | |||||
logger.infox(task, '<%1> email: [%2] resolved for symbol: %3', | |||||
task:get_message_id(), to_resolve, rule['symbol']) | task:get_message_id(), to_resolve, rule['symbol']) | ||||
task:insert_result(rule['symbol'], 1) | task:insert_result(rule['symbol'], 1) | ||||
end | end | ||||
local key = addr:get_host() | local key = addr:get_host() | ||||
if rule['map']:get_key(key) then | if rule['map']:get_key(key) then | ||||
task:insert_result(rule['symbol'], 1) | task:insert_result(rule['symbol'], 1) | ||||
logger.infox('<%1> email: \'%2\' is found in list: %3', | |||||
logger.infox(task, '<%1> email: \'%2\' is found in list: %3', | |||||
task:get_message_id(), key, rule['symbol']) | task:get_message_id(), key, rule['symbol']) | ||||
end | end | ||||
else | else | ||||
local key = string.format('%s@%s', addr:get_user(), addr:get_host()) | local key = string.format('%s@%s', addr:get_user(), addr:get_host()) | ||||
if rule['map']:get_key(key) then | if rule['map']:get_key(key) then | ||||
task:insert_result(rule['symbol'], 1) | task:insert_result(rule['symbol'], 1) | ||||
logger.infox('<%1> email: \'%2\' is found in list: %3', | |||||
logger.infox(task, '<%1> email: \'%2\' is found in list: %3', | |||||
task:get_message_id(), key, rule['symbol']) | task:get_message_id(), key, rule['symbol']) | ||||
end | end | ||||
end | end | ||||
rule['map'] = rspamd_config:add_hash_map (rule['name']) | rule['map'] = rspamd_config:add_hash_map (rule['name']) | ||||
end | end | ||||
if not rule['symbol'] or (not rule['map'] and not rule['dnsbl']) then | if not rule['symbol'] or (not rule['map'] and not rule['dnsbl']) then | ||||
logger.err('incomplete rule') | |||||
logger.errx(rspamd_config, 'incomplete rule') | |||||
else | else | ||||
table.insert(rules, rule) | table.insert(rules, rule) | ||||
end | end |
local score_set_cb = function(task, err, data) | local score_set_cb = function(task, err, data) | ||||
if err then | if err then | ||||
rspamd_logger.infox('got error while IP score changing: %1', err) | |||||
rspamd_logger.infox(task, 'got error while IP score changing: %1', err) | |||||
end | end | ||||
end | end | ||||
if options['servers'] and options['servers'] ~= '' then | if options['servers'] and options['servers'] ~= '' then | ||||
upstreams = upstream_list.create(options['servers'], default_port) | upstreams = upstream_list.create(options['servers'], default_port) | ||||
if not upstreams then | if not upstreams then | ||||
rspamd_logger.err('no servers are specified') | |||||
rspamd_logger.errx(rspamd_config, 'no servers are specified') | |||||
end | end | ||||
end | end | ||||
if options['whitelist'] then | if options['whitelist'] then |
local function add_multimap_rule(key, newrule) | local function add_multimap_rule(key, newrule) | ||||
if not newrule['map'] then | if not newrule['map'] then | ||||
rspamd_logger.err('incomplete rule') | |||||
rspamd_logger.errx(rspamd_config, 'incomplete rule') | |||||
return nil | return nil | ||||
end | end | ||||
if not newrule['symbol'] and key then | if not newrule['symbol'] and key then | ||||
newrule['symbol'] = key | newrule['symbol'] = key | ||||
elseif not newrule['symbol'] then | elseif not newrule['symbol'] then | ||||
rspamd_logger.err('incomplete rule') | |||||
rspamd_logger.errx(rspamd_config, 'incomplete rule') | |||||
return nil | return nil | ||||
end | end | ||||
-- Check cdb flag | -- Check cdb flag | ||||
if newrule['cdb'] then | if newrule['cdb'] then | ||||
return newrule | return newrule | ||||
else | else | ||||
rspamd_logger.warn('Cannot add rule: map doesn\'t exists: ' .. newrule['map']) | |||||
rspamd_logger.warnx(rspamd_config, 'Cannot add rule: map doesn\'t exists: %1', | |||||
newrule['map']) | |||||
end | end | ||||
else | else | ||||
if newrule['type'] == 'ip' then | if newrule['type'] == 'ip' then | ||||
newrule['radix'] = rspamd_config:add_radix_map (newrule['map'], newrule['description']) | |||||
newrule['radix'] = rspamd_config:add_radix_map (newrule['map'], | |||||
newrule['description']) | |||||
if newrule['radix'] then | if newrule['radix'] then | ||||
return newrule | return newrule | ||||
else | else | ||||
rspamd_logger.warn('Cannot add rule: map doesn\'t exists: ' .. newrule['map']) | |||||
rspamd_logger.warnx(rspamd_config, 'Cannot add rule: map doesn\'t exists: %1', | |||||
newrule['map']) | |||||
end | end | ||||
elseif newrule['type'] == 'header' or newrule['type'] == 'rcpt' or newrule['type'] == 'from' then | elseif newrule['type'] == 'header' or newrule['type'] == 'rcpt' or newrule['type'] == 'from' then | ||||
newrule['hash'] = rspamd_config:add_hash_map (newrule['map'], newrule['description']) | newrule['hash'] = rspamd_config:add_hash_map (newrule['map'], newrule['description']) | ||||
if newrule['hash'] then | if newrule['hash'] then | ||||
return newrule | return newrule | ||||
else | else | ||||
rspamd_logger.warn('Cannot add rule: map doesn\'t exists: ' .. newrule['map']) | |||||
rspamd_logger.warnx(rspamd_config, 'Cannot add rule: map doesn\'t exists: %1', | |||||
newrule['map']) | |||||
end | end | ||||
elseif newrule['type'] == 'dnsbl' then | elseif newrule['type'] == 'dnsbl' then | ||||
return newrule | return newrule | ||||
if type(m) == 'table' then | if type(m) == 'table' then | ||||
local rule = add_multimap_rule(k, m) | local rule = add_multimap_rule(k, m) | ||||
if not rule then | if not rule then | ||||
rspamd_logger.err('cannot add rule: "'..k..'"') | |||||
rspamd_logger.errx(rspamd_config, 'cannot add rule: "'..k..'"') | |||||
else | else | ||||
table.insert(rules, rule) | table.insert(rules, rule) | ||||
end | end | ||||
else | else | ||||
rspamd_logger.err('parameter ' .. k .. ' is invalid, must be an object') | |||||
rspamd_logger.errx(rspamd_config, 'parameter ' .. k .. ' is invalid, must be an object') | |||||
end | end | ||||
end | end | ||||
-- add fake symbol to check all maps inside a single callback | -- add fake symbol to check all maps inside a single callback |
if not results then | if not results then | ||||
task:insert_result(symbol_strict, 1) | task:insert_result(symbol_strict, 1) | ||||
else | else | ||||
rspamd_logger.info(string.format('SMTP resolver failed to resolve: %s is %s', to_resolve, results[1])) | |||||
rspamd_logger.infox(task, 'SMTP resolver failed to resolve: %1 is %2', | |||||
to_resolve, results[1]) | |||||
local i = true | local i = true | ||||
for _,h in ipairs(bad_hosts) do | for _,h in ipairs(bad_hosts) do | ||||
if string.find(results[1], h) then | if string.find(results[1], h) then |
-- Use distance to penalize the total weight | -- Use distance to penalize the total weight | ||||
weight = util.tanh(3 * (1 - dist + 0.1)) | weight = util.tanh(3 * (1 - dist + 0.1)) | ||||
end | end | ||||
rspamd_logger.debugx("distance: %1 -> %2: %3", tld, ptld, dist) | |||||
rspamd_logger.debugx(task, "distance: %1 -> %2: %3", tld, ptld, dist) | |||||
if #redirector_domains > 0 then | if #redirector_domains > 0 then | ||||
for _,rule in ipairs(redirector_domains) do | for _,rule in ipairs(redirector_domains) do | ||||
local rule = {symbol = sym, map = rmap} | local rule = {symbol = sym, map = rmap} | ||||
table.insert(phishmap, rule) | table.insert(phishmap, rule) | ||||
else | else | ||||
rspamd_logger.info('cannot add map: ' .. map .. ' for symbol: ' .. sym) | |||||
rspamd_logger.infox(rspamd_config, 'cannot add map: ' .. map .. ' for symbol: ' .. sym) | |||||
end | end | ||||
else | else | ||||
rspamd_logger.info(mapname .. ' option must be in format <map>:<symbol>') | |||||
rspamd_logger.infox(rspamd_config, mapname .. ' option must be in format <map>:<symbol>') | |||||
end | end | ||||
end | end | ||||
end | end |
--- Called when value was set on server | --- Called when value was set on server | ||||
local function rate_set_key_cb(task, err, data) | local function rate_set_key_cb(task, err, data) | ||||
if err then | if err then | ||||
rspamd_logger.info('got error while getting limit: ' .. err) | |||||
rspamd_logger.infox(task, 'got error while getting limit: %1', err) | |||||
upstream:fail() | upstream:fail() | ||||
else | else | ||||
upstream:ok() | upstream:ok() | ||||
end | end | ||||
end, _.zip(parse_limits(data), _.map(function(a) return a[1] end, args))) | end, _.zip(parse_limits(data), _.map(function(a) return a[1] end, args))) | ||||
elseif err then | elseif err then | ||||
rspamd_logger.info('got error while getting limit: ' .. err) | |||||
rspamd_logger.infox(task, 'got error while getting limit: %1', err) | |||||
upstream:fail() | upstream:fail() | ||||
end | end | ||||
end | end | ||||
local function rate_set_key_cb(task, err, data) | local function rate_set_key_cb(task, err, data) | ||||
if err then | if err then | ||||
rspamd_logger.info('got error while setting limit: ' .. err) | |||||
rspamd_logger.infox(task, 'got error while setting limit: %1', err) | |||||
upstream:fail() | upstream:fail() | ||||
else | else | ||||
upstream:ok() | upstream:ok() | ||||
local cmd = generate_format_string(values, true) | local cmd = generate_format_string(values, true) | ||||
rspamd_redis.make_request(task, addr, rate_set_key_cb, cmd, values) | rspamd_redis.make_request(task, addr, rate_set_key_cb, cmd, values) | ||||
elseif err then | elseif err then | ||||
rspamd_logger.info('got error while setting limit: ' .. err) | |||||
rspamd_logger.infox(task, 'got error while setting limit: %1', err) | |||||
upstream:fail() | upstream:fail() | ||||
end | end | ||||
end | end | ||||
if ip and ip:is_valid() and whitelisted_ip then | if ip and ip:is_valid() and whitelisted_ip then | ||||
if whitelisted_ip:get_key(ip) then | if whitelisted_ip:get_key(ip) then | ||||
-- Do not check whitelisted ip | -- Do not check whitelisted ip | ||||
rspamd_logger.info('skip ratelimit for whitelisted IP') | |||||
rspamd_logger.infox(task, 'skip ratelimit for whitelisted IP') | |||||
return | return | ||||
end | end | ||||
end | end | ||||
_.any(function(w) return r == w end, whitelisted_rcpts) end, | _.any(function(w) return r == w end, whitelisted_rcpts) end, | ||||
rcpts_user) then | rcpts_user) then | ||||
rspamd_logger.info('skip ratelimit for whitelisted recipient') | |||||
rspamd_logger.infox(task, 'skip ratelimit for whitelisted recipient') | |||||
return | return | ||||
end | end | ||||
end | end | ||||
end | end | ||||
if table.maxn(params) ~= 3 then | if table.maxn(params) ~= 3 then | ||||
rspamd_logger.err('invalid limit definition: ' .. str) | |||||
rspamd_logger.errx(rspamd_config, 'invalid limit definition: ' .. str) | |||||
return | return | ||||
end | end | ||||
elseif params[1] == 'user' then | elseif params[1] == 'user' then | ||||
set_limit(settings['user'], params[2], params[3]) | set_limit(settings['user'], params[2], params[3]) | ||||
else | else | ||||
rspamd_logger.err('invalid limit type: ' .. params[1]) | |||||
rspamd_logger.errx(rspamd_config, 'invalid limit type: ' .. params[1]) | |||||
end | end | ||||
end | end | ||||
end | end | ||||
if not opts['servers'] then | if not opts['servers'] then | ||||
rspamd_logger.err('no servers are specified') | |||||
rspamd_logger.errx(rspamd_config, 'no servers are specified') | |||||
else | else | ||||
upstreams = upstream_list.create(opts['servers'], default_port) | upstreams = upstream_list.create(opts['servers'], default_port) | ||||
if not upstreams then | if not upstreams then | ||||
rspamd_logger.err('no servers are specified') | |||||
rspamd_logger.errx(rspamd_config, 'no servers are specified') | |||||
else | else | ||||
rspamd_config:register_pre_filter(rate_test) | rspamd_config:register_pre_filter(rate_test) | ||||
rspamd_config:register_post_filter(rate_set) | rspamd_config:register_post_filter(rate_set) |
if thisrbl['unknown'] and thisrbl['symbol'] then | if thisrbl['unknown'] and thisrbl['symbol'] then | ||||
task:insert_result(thisrbl['symbol'], 1) | task:insert_result(thisrbl['symbol'], 1) | ||||
else | else | ||||
rspamd_logger.err('RBL ' .. thisrbl['rbl'] .. | |||||
' returned unknown result ' .. ipstr) | |||||
rspamd_logger.errx(task, 'RBL %1 returned unknown result: %2', | |||||
thisrbl['rbl'], ipstr) | |||||
end | end | ||||
end | end | ||||
end | end |
return | return | ||||
end | end | ||||
rspamd_logger.info("check for settings") | |||||
rspamd_logger.infox(task, "check for settings") | |||||
local ip = task:get_from_ip() | local ip = task:get_from_ip() | ||||
local from = task:get_from() | local from = task:get_from() | ||||
local rcpt = task:get_recipients() | local rcpt = task:get_recipients() | ||||
for name, rule in pairs(settings[pri]) do | for name, rule in pairs(settings[pri]) do | ||||
local rule = check_specific_setting(name, rule, ip, from, rcpt, user) | local rule = check_specific_setting(name, rule, ip, from, rcpt, user) | ||||
if rule then | if rule then | ||||
rspamd_logger.info(string.format("<%s> apply settings according to rule %s", | |||||
task:get_message_id(), name)) | |||||
rspamd_logger.infox(task, "<%1> apply settings according to rule %2", | |||||
task:get_message_id(), name) | |||||
task:set_settings(rule) | task:set_settings(rule) | ||||
end | end | ||||
end | end | ||||
end | end | ||||
-- Process settings based on their priority | -- Process settings based on their priority | ||||
local function process_settings_table(tbl) | |||||
local function process_settings_table(task, tbl) | |||||
local get_priority = function(elt) | local get_priority = function(elt) | ||||
local pri_tonum = function(p) | local pri_tonum = function(p) | ||||
if p then | if p then | ||||
out[1] = res | out[1] = res | ||||
out[2] = 0 | out[2] = 0 | ||||
else | else | ||||
rspamd_logger.err("bad IP address: " .. ip) | |||||
rspamd_logger.errx(task, "bad IP address: " .. ip) | |||||
return nil | return nil | ||||
end | end | ||||
else | else | ||||
out[1] = res | out[1] = res | ||||
out[2] = mask | out[2] = mask | ||||
else | else | ||||
rspamd_logger.err("bad IP address: " .. ip) | |||||
rspamd_logger.errx(task, "bad IP address: " .. ip) | |||||
return nil | return nil | ||||
end | end | ||||
end | end | ||||
if re then | if re then | ||||
out['regexp'] = re | out['regexp'] = re | ||||
else | else | ||||
rspamd_logger.err("bad regexp: " .. addr) | |||||
rspamd_logger.errx(task, "bad regexp: " .. addr) | |||||
return nil | return nil | ||||
end | end | ||||
elseif elt['whitelist'] or elt['want_spam'] then | elseif elt['whitelist'] or elt['want_spam'] then | ||||
out['whitelist'] = true | out['whitelist'] = true | ||||
else | else | ||||
rspamd_logger.err("no actions in settings: " .. name) | |||||
rspamd_logger.errx(rspamd_config, "no actions in settings: " .. name) | |||||
return nil | return nil | ||||
end | end | ||||
end, ft) | end, ft) | ||||
settings_initialized = true | settings_initialized = true | ||||
rspamd_logger.infox('loaded %1 elements of settings', nrules) | |||||
rspamd_logger.infox(rspamd_config, 'loaded %1 elements of settings', nrules) | |||||
return true | return true | ||||
end | end | ||||
local parser = ucl.parser() | local parser = ucl.parser() | ||||
local res,err = parser:parse_string(string) | local res,err = parser:parse_string(string) | ||||
if not res then | if not res then | ||||
rspamd_logger.warn('cannot parse settings map: ' .. err) | |||||
rspamd_logger.warnx(rspamd_config, 'cannot parse settings map: ' .. err) | |||||
else | else | ||||
local obj = parser:get_object() | local obj = parser:get_object() | ||||
if obj['settings'] then | if obj['settings'] then | ||||
if set_section[1] and type(set_section[1]) == "string" then | if set_section[1] and type(set_section[1]) == "string" then | ||||
-- Just a map of ucl | -- Just a map of ucl | ||||
if not rspamd_config:add_map(set_section[1], "settings map", process_settings_map) then | if not rspamd_config:add_map(set_section[1], "settings map", process_settings_map) then | ||||
rspamd_logger.errx('cannot load settings from %1', set_section) | |||||
rspamd_logger.errx(rspamd_config, 'cannot load settings from %1', set_section) | |||||
end | end | ||||
elseif type(set_section) == "table" then | elseif type(set_section) == "table" then | ||||
process_settings_table(set_section) | process_settings_table(set_section) |
elseif func == 'case' then | elseif func == 'case' then | ||||
cur_param['strong'] = true | cur_param['strong'] = true | ||||
else | else | ||||
rspamd_logger.warn(string.format('Function %s is not supported in %s', | |||||
func, cur_rule['symbol'])) | |||||
rspamd_logger.warnx(rspamd_config, 'Function %1 is not supported in %2', | |||||
func, cur_rule['symbol']) | |||||
end | end | ||||
end, _.tail(args)) | end, _.tail(args)) | ||||
table.insert(hdr_params, cur_param) | table.insert(hdr_params, cur_param) | ||||
if r then | if r then | ||||
r:match(h) | r:match(h) | ||||
else | else | ||||
rspamd_logger.infox('cannot create regexp %1', re) | |||||
rspamd_logger.infox(rspamd_config, 'cannot create regexp %1', re) | |||||
return 0 | return 0 | ||||
end | end | ||||
end | end | ||||
arg = elts[2] | arg = elts[2] | ||||
local func_cache = {} | local func_cache = {} | ||||
rspamd_logger.debugx('trying to parse SA function %1 with args %2', elts[1], elts[2]) | |||||
rspamd_logger.debugx(rspamd_config, 'trying to parse SA function %1 with args %2', | |||||
elts[1], elts[2]) | |||||
local substitutions = { | local substitutions = { | ||||
{'^exists:', | {'^exists:', | ||||
function(task) -- filter | function(task) -- filter | ||||
end | end | ||||
if not func then | if not func then | ||||
rspamd_logger.errx('cannot find appropriate eval rule for function %1', arg) | |||||
rspamd_logger.errx(rspamd_config, 'cannot find appropriate eval rule for function %1', | |||||
arg) | |||||
else | else | ||||
return func(task) | return func(task) | ||||
end | end | ||||
cur_rule['re'] = rspamd_regexp.create_cached(cur_rule['re_expr']) | cur_rule['re'] = rspamd_regexp.create_cached(cur_rule['re_expr']) | ||||
if not cur_rule['re'] then | if not cur_rule['re'] then | ||||
rspamd_logger.warn(string.format("Cannot parse regexp '%s' for %s", | |||||
cur_rule['re_expr'], cur_rule['symbol'])) | |||||
rspamd_logger.warnx(rspamd_config, "Cannot parse regexp '%1' for %2", | |||||
cur_rule['re_expr'], cur_rule['symbol']) | |||||
else | else | ||||
handle_header_def(words[3], cur_rule) | handle_header_def(words[3], cur_rule) | ||||
end | end | ||||
cur_rule['function'] = func | cur_rule['function'] = func | ||||
valid_rule = true | valid_rule = true | ||||
else | else | ||||
rspamd_logger.infox('unknown function %1', args) | |||||
rspamd_logger.infox(rspamd_config, 'unknown function %1', args) | |||||
end | end | ||||
end | end | ||||
elseif words[1] == "body" and slash then | elseif words[1] == "body" and slash then | ||||
if freemail_domains then | if freemail_domains then | ||||
freemail_trie = rspamd_trie.create(freemail_domains) | freemail_trie = rspamd_trie.create(freemail_domains) | ||||
rspamd_logger.infox('loaded %1 freemail domains definitions', #freemail_domains) | |||||
rspamd_logger.infox(rspamd_config, 'loaded %1 freemail domains definitions', | |||||
#freemail_domains) | |||||
end | end | ||||
local function sa_regexp_match(data, re, raw, rule) | local function sa_regexp_match(data, re, raw, rule) | ||||
if res then | if res then | ||||
local nre = rspamd_regexp.create_cached(nexpr) | local nre = rspamd_regexp.create_cached(nexpr) | ||||
if not nre then | if not nre then | ||||
rspamd_logger.errx('cannot apply replacement for rule %1', r) | |||||
rspamd_logger.errx(rspamd_config, 'cannot apply replacement for rule %1', r) | |||||
rule['re'] = nil | rule['re'] = nil | ||||
else | else | ||||
rspamd_logger.debugx('replace %1 -> %2', r, nexpr) | |||||
rspamd_logger.debugx(rspamd_config, 'replace %1 -> %2', r, nexpr) | |||||
rule['re'] = nre | rule['re'] = nre | ||||
rule['re_expr'] = nexpr | rule['re_expr'] = nexpr | ||||
nre:set_limit(match_limit) | nre:set_limit(match_limit) | ||||
end | end | ||||
if not res then | if not res then | ||||
rspamd_logger.debugx('atom: %1, NULL result', atom) | |||||
rspamd_logger.debugx(task, 'atom: %1, NULL result', atom) | |||||
elseif res > 0 then | elseif res > 0 then | ||||
rspamd_logger.debugx('atom: %1, result: %2', atom, res) | |||||
rspamd_logger.debugx(task, 'atom: %1, result: %2', atom, res) | |||||
end | end | ||||
return res | return res | ||||
else | else | ||||
rspamd_logger.debugx('Cannot find atom ' .. atom) | |||||
rspamd_logger.debugx(task, 'Cannot find atom ' .. atom) | |||||
end | end | ||||
return 0 | return 0 | ||||
end | end | ||||
expression = rspamd_expression.create(r['meta'], | expression = rspamd_expression.create(r['meta'], | ||||
{parse_atom, process_atom}, sa_mempool) | {parse_atom, process_atom}, sa_mempool) | ||||
if not expression then | if not expression then | ||||
rspamd_logger.err('Cannot parse expression ' .. r['meta']) | |||||
rspamd_logger.errx(rspamd_config, 'Cannot parse expression ' .. r['meta']) | |||||
else | else | ||||
if r['score'] then | if r['score'] then | ||||
rspamd_config:set_metric_symbol(k, r['score'], r['description']) | rspamd_config:set_metric_symbol(k, r['score'], r['description']) |
local pattern = patterns[idx] | local pattern = patterns[idx] | ||||
if param['multi'] or not matched[pattern] then | if param['multi'] or not matched[pattern] then | ||||
rspamd_logger.debugx("<%1> matched pattern %2 at pos %3", | |||||
rspamd_logger.debugx(task, "<%1> matched pattern %2 at pos %3", | |||||
task:get_message_id(), pattern, pos) | task:get_message_id(), pattern, pos) | ||||
task:insert_result(param['symbol'], 1.0) | task:insert_result(param['symbol'], 1.0) | ||||
if not param['multi'] then | if not param['multi'] then | ||||
file = io.open(cf['file']) | file = io.open(cf['file']) | ||||
if not file then | if not file then | ||||
rspamd_logger.errx('Cannot open trie file %1', cf['file']) | |||||
rspamd_logger.errx(rspamd_config, 'Cannot open trie file %1', cf['file']) | |||||
else | else | ||||
if cf['binary'] then | if cf['binary'] then | ||||
rspamd_logger.errx('binary trie patterns are not implemented yet: %1', | |||||
rspamd_logger.errx(rspamd_config, 'binary trie patterns are not implemented yet: %1', | |||||
cf['file']) | cf['file']) | ||||
else | else | ||||
for line in file:lines() do | for line in file:lines() do | ||||
local raw = false | local raw = false | ||||
if type(cf) ~= 'table' then | if type(cf) ~= 'table' then | ||||
rspamd_logger.errx('invalid value for symbol %1: "%2", expected table', | |||||
rspamd_logger.errx(rspamd_config, 'invalid value for symbol %1: "%2", expected table', | |||||
symbol, cf) | symbol, cf) | ||||
return | return | ||||
end | end | ||||
if #raw_patterns > 0 then | if #raw_patterns > 0 then | ||||
raw_trie = rspamd_trie.create(raw_patterns) | raw_trie = rspamd_trie.create(raw_patterns) | ||||
rspamd_logger.infox('registered raw search trie from %1 patterns', #raw_patterns) | |||||
rspamd_logger.infox(rspamd_config, 'registered raw search trie from %1 patterns', #raw_patterns) | |||||
end | end | ||||
if #mime_patterns > 0 then | if #mime_patterns > 0 then | ||||
mime_trie = rspamd_trie.create(mime_patterns) | mime_trie = rspamd_trie.create(mime_patterns) | ||||
rspamd_logger.infox('registered mime search trie from %1 patterns', #mime_patterns) | |||||
rspamd_logger.infox(rspamd_config, 'registered mime search trie from %1 patterns', #mime_patterns) | |||||
end | end | ||||
local id = -1 | local id = -1 | ||||
if mime_trie or raw_trie then | if mime_trie or raw_trie then | ||||
id = rspamd_config:register_callback_symbol('TRIE', 1.0, tries_callback) | id = rspamd_config:register_callback_symbol('TRIE', 1.0, tries_callback) | ||||
else | else | ||||
rspamd_logger.err('no tries defined') | |||||
rspamd_logger.errx(rspamd_config, 'no tries defined') | |||||
end | end | ||||
if id ~= -1 then | if id ~= -1 then |