local opts = rspamd_config:get_all_opt('dcc')
local logger = require "rspamd_logger"
local tcp = require "rspamd_tcp"
-require "fun" ()
+local fun = require "fun"
local function check_dcc (task)
-- Connection
local envrcpt = 'test@example.com'
local rcpts = task:get_recipients();
if rcpts then
- local r = table.concat(totable(map(function(rcpt)
+ local r = table.concat(fun.totable(map(function(rcpt)
return rcpt['addr'] end,
rcpts)), '\n')
if r then
local rspamd_redis = require 'rspamd_redis'
local redis_params
local ucl = require "ucl"
-require "fun" ()
+local fun = require "fun"
local settings = {
redis_key = "dynamic_conf",
end
if not addr then
- logger.errx(task, 'cannot select server to make redis request')
+ rspamd_logger.errx(cfg, 'cannot select server to make redis request')
end
local options = {
end
local function apply_dynamic_actions(cfg, acts)
- each(function(k, v)
+ fun.each(function(k, v)
if type(v) == 'table' then
v['name'] = k
if not v['priority'] then
priority = settings.priority
})
end
- end, filter(function(k, v)
+ end, fun.filter(function(k, v)
local act = rspamd_config:get_metric_action(k)
if (act and alpha_cmp(act, v)) or cur_settings.updates.actions[k] then
return false
end
local function apply_dynamic_scores(cfg, sc)
- each(function(k, v)
+ fun.each(function(k, v)
if type(v) == 'table' then
v['name'] = k
if not v['priority'] then
priority = settings.priority
})
end
- end, filter(function(k, v)
+ end, fun.filter(function(k, v)
-- Select elts with scores that are different from local ones
local sym = rspamd_config:get_metric_symbol(k)
if (sym and alpha_cmp(sym.score, v)) or cur_settings.updates.symbols[k] then
end
if data['symbols_enabled'] then
- each(function(i, v)
+ fun.each(function(i, v)
cfg:enable_symbol(v)
end, data['symbols_enabled'])
end
if data['symbols_disabled'] then
- each(function(i, v)
+ fun.each(function(i, v)
cfg:disable_symbol(v)
end, data['symbols_disabled'])
end
if not cur_settings.data.scores then
cur_settings.data.scores = {}
end
- each(function(k, v)
+ fun.each(function(k, v)
cur_settings.data.scores[k] = v
end,
- filter(function(k,v)
+ fun.filter(function(k,v)
if cur_settings.updates.symbols[k] then
return false
end
if not cur_settings.data.actions then
cur_settings.data.actions = {}
end
- each(function(k, v)
+ fun.each(function(k, v)
cur_settings.data.actions[k] = v
end,
- filter(function(k,v)
+ fun.filter(function(k,v)
if cur_settings.updates.actions[k] then
return false
end
local rspamd_util = require "rspamd_util"
local fann_symbol_spam = 'FANN_SPAM'
local fann_symbol_ham = 'FANN_HAM'
-require "fun" ()
+local fun = require "fun"
local ucl = require "ucl"
local module_log_id = 0x100
end
if not addr then
- logger.errx(task, 'cannot select server to make redis request')
+ rspamd_logger.errx(cfg, 'cannot select server to make redis request')
end
local options = {
local matched_symbols = {}
local n = rspamd_config:get_symbols_count()
- each(function(s, score)
+ fun.each(function(s, score)
matched_symbols[s + 1] = rspamd_util.tanh(score)
- end, zip(syms, scores))
+ end, fun.zip(syms, scores))
for i=1,n do
if matched_symbols[i] then
local function can_train_cb(err, data)
if not err and tonumber(data) > 0 then
local learn_data = symbols_to_fann_vector(
- map(function(r) return r[1] end, results),
- map(function(r) return r[2] end, results)
+ fun.map(function(r) return r[1] end, results),
+ fun.map(function(r) return r[2] end, results)
)
-- Add filtered meta tokens
- each(function(e) table.insert(learn_data, e) end, extra)
+ fun.each(function(e) table.insert(learn_data, e) end, extra)
local str = rspamd_util.zstd_compress(table.concat(learn_data, ';'))
redis_make_request(ev_base,
if err then
rspamd_logger.errx(rspamd_config, 'cannot get FANNS list from redis: %s', err)
elseif type(data) == 'table' then
- each(function(i, elt)
+ fun.each(function(i, elt)
local redis_len_cb = function(err, data)
if err then
rspamd_logger.errx(rspamd_config, 'cannot get FANN trains %s from redis: %s', elt, err)
if err then
rspamd_logger.errx(rspamd_config, 'cannot get FANNS list from redis: %s', err)
elseif type(data) == 'table' then
- each(function(i, elt)
+ fun.each(function(i, elt)
local redis_update_cb = function(err, data)
if err then
rspamd_logger.errx(rspamd_config, 'cannot get FANN version %s from redis: %s', elt, err)
local ret = cfg:register_worker_script("log_helper",
function(score, req_score, results, cf, id, extra, ev_base)
-- map (snd x) (filter (fst x == module_id) extra)
- local extra_fann = map(function(e) return e[2] end,
- filter(function(e) return e[1] == module_log_id end, extra))
+ local extra_fann = fun.map(function(e) return e[2] end,
+ fun.filter(function(e) return e[1] == module_log_id end, extra))
if use_settings then
fann_train_callback(score, req_score, results, cf,
tostring(id), opts['train'], extra_fann, ev_base)
-- This is needed to pass extra tokens from worker to log_helper
rspamd_plugins["fann_score"] = {
log_callback = function(task)
- return totable(map(
+ return fun.totable(fun.map(
function(tok) return {module_log_id, tok} end,
gen_metatokens(task)))
end
local rspamd_expression = require "rspamd_expression"
local rspamd_redis = require "rspamd_redis"
local redis_params
-require "fun" ()
+local fun = require "fun"
local urls = {}
local function match_list(r, ls, fields)
if ls then
if fields then
- each(function(e)
+ fun.each(function(e)
local match = e[fields[1]]
if match then
if fields[2] then
end
end, ls)
else
- each(function(e) match_rule(r, e) end, ls)
+ fun.each(function(e) match_rule(r, e) end, ls)
end
end
end
local atoms = {}
local function parse_atom(str)
- local atom = table.concat(totable(take_while(function(c)
+ local atom = table.concat(fun.totable(fun.take_while(function(c)
if string.find(', \t()><+!|&\n', c) then
return false
end
return true
- end, iter(str))), '')
+ end, fun.iter(str))), '')
table.insert(atoms, atom)
return atom
end
if expression then
newrule['expression'] = expression
- each(function(v)
+ fun.each(function(v)
rspamd_logger.debugx(rspamd_config, 'add dependency %s -> %s',
newrule['symbol'], v)
rspamd_config:register_dependency(newrule['symbol'], v)
end
end
-- add fake symbol to check all maps inside a single callback
- each(function(rule)
+ fun.each(function(rule)
local id = rspamd_config:register_symbol({
type = 'normal',
name = rule['symbol'],
if rule['symbols'] then
-- Find allowed symbols by this map
rule['symbols_set'] = {}
- each(function(s)
+ fun.each(function(s)
rspamd_config:register_symbol({
type = 'virtual',
name = s,
})
end
end,
- filter(function(r) return not r['prefilter'] end, rules))
+ fun.filter(function(r) return not r['prefilter'] end, rules))
- each(function(r)
+ fun.each(function(r)
rspamd_config:register_symbol({
type = 'prefilter',
name = r['symbol'],
callback = gen_multimap_callback(r),
})
end,
- filter(function(r) return r['prefilter'] end, rules))
+ fun.filter(function(r) return r['prefilter'] end, rules))
end
local rspamd_tcp = require "rspamd_tcp"
local rspamd_redis = require "rspamd_redis"
local rspamd_util = require "rspamd_util"
-require "fun" ()
+local fun = require "fun"
local settings = {
timeout = 1.0, -- connect timeout
local valid = false
local function check_results(mxes)
- if all(function(k, elt) return elt.checked end, mxes) then
+ if fun.all(function(k, elt) return elt.checked end, mxes) then
-- Save cache
local key = settings.key_prefix .. mx_domain
local function redis_cache_cb(err, data)
)
else
local valid_mx = {}
- each(function(k, mx)
+ fun.each(function(k, mx)
table.insert(valid_mx, k)
- end, filter(function (k, elt) return elt.working end, mxes))
+ end, fun.filter(function (k, elt) return elt.working end, mxes))
task:insert_result(settings.symbol_good_mx, 1.0, valid_mx)
local ret,_,_ = rspamd_redis_make_request(task,
redis_params, -- connect params
-- This plugin implements dynamic updates for rspamd
local ucl = require "ucl"
-require "fun" ()
+local fun = require "fun"
local rspamd_logger = require "rspamd_logger"
local updates_priority = 2
local rspamd_config = rspamd_config
local maps = {}
local function process_symbols(obj, priority)
- each(function(sym, score)
+ fun.each(function(sym, score)
rspamd_config:set_metric_symbol({
name = sym,
score = score,
end
local function process_actions(obj, priority)
- each(function(act, score)
+ fun.each(function(act, score)
rspamd_config:set_metric_action({
action = act,
score = score,
end
local function process_rules(obj)
- each(function(key, code)
+ fun.each(function(key, code)
local f = loadstring(code)
if f then
f()
local section = rspamd_config:get_all_opt("rspamd_update")
if section then
local trusted_key
- each(function(k, elt)
+ fun.each(function(k, elt)
if k == 'priority' then
updates_priority = tonumber(elt)
elseif k == 'key' then
end
end, section)
- each(function(k, map)
+ fun.each(function(k, map)
-- Check sanity for maps
local proto = map:get_proto()
if (proto == 'http' or proto == 'https') and not map:get_sign_key() then
local rspamd_ip = require "rspamd_ip"
local rspamd_regexp = require "rspamd_regexp"
local ucl = require "ucl"
-require "fun" ()
+local fun = require "fun"
-- Checks for overrided settings within query params and returns 'true' if
-- settings are overrided
end
if rule['symbols'] then
-- Add symbols, specified in the settings
- each(function(val)
+ fun.each(function(val)
task:insert_result(val, 1.0)
end, rule['symbols'])
end
settings_ids = {}
for k,v in pairs(settings) do settings[k]={} end
-- fill new settings by priority
- for_each(function(k, v)
+ fun.for_each(function(k, v)
local pri = get_priority(v)
if pri > max_pri then max_pri = pri end
if not settings[pri] then
end
end
- each(function(id, h)
+ fun.each(function(id, h)
rspamd_config:register_symbol({
name = 'REDIS_SETTINGS' .. tostring(id),
type = 'prefilter',
local rspamd_mempool = require "rspamd_mempool"
local rspamd_trie = require "rspamd_trie"
local util = require "rspamd_util"
-require "fun" ()
+local fun = require "fun"
-- Known plugins
local known_plugins = {
ordinary = false
end
- each(function(func)
+ fun.each(function(func)
if func == 'addr' then
cur_param['function'] = function(str)
local addr_parsed = util.parse_addr(str)
rspamd_logger.warnx(rspamd_config, 'Function %1 is not supported in %2',
func, cur_rule['symbol'])
end
- end, tail(args))
+ end, fun.tail(args))
local function split_hdr_param(param, headers)
for i,h in ipairs(headers) do
end
local function words_to_re(words, start)
- return table.concat(totable(drop_n(start, words)), " ");
+ return table.concat(fun.totable(fun.drop_n(start, words)), " ");
end
local function process_tflags(rule, flags)
- each(function(flag)
+ fun.each(function(flag)
if flag == 'publish' then
rule['publish'] = true
elseif flag == 'multiple' then
elseif flag == 'nice' then
rule['nice'] = true
end
- end, drop_n(1, flags))
+ end, fun.drop_n(1, flags))
if rule['re'] then
if rule['maxhits'] then
if string.match(l, '^ifplugin') then
local ls = split(l)
- if not any(function(pl)
+ if not fun.any(function(pl)
if pl == ls[2] then return true end
return false
end, known_plugins) then
end
elseif string.match(l, '^if !plugin%(') then
local pname = string.match(l, '^if !plugin%(([A-Za-z:]+)%)')
- if any(function(pl)
+ if fun.any(function(pl)
if pl == pname then return true end
return false
end, known_plugins) then
local slash = string.find(l, '/')
-- Skip comments
- words = totable(take_while(
+ local words = fun.totable(fun.take_while(
function(w) return string.sub(w, 1, 1) ~= '#' end,
- filter(function(w)
+ fun.filter(function(w)
return w ~= "" end,
- iter(split(l)))))
+ fun.iter(split(l)))))
if words[1] == "header" or words[1] == 'mimeheader' then
-- header SYMBOL Header ~= /regexp/
local unset_comp = string.find(cur_rule['re_expr'], '%s+%[if%-unset:')
if unset_comp then
-- We have optional part that needs to be processed
- unset = string.match(string.sub(cur_rule['re_expr'], unset_comp),
+ local unset = string.match(string.sub(cur_rule['re_expr'], unset_comp),
'%[if%-unset:%s*([^%]%s]+)]')
cur_rule['unset'] = unset
-- Cut it down
})
end
else
- h['mime'] = cur_rule[mime]
+ h['mime'] = cur_rule['mime']
if cur_rule['mime'] then
rspamd_config:register_regexp({
re = cur_rule['re'],
elseif words[1] == "score" then
scores[words[2]] = parse_score(words)
elseif words[1] == 'freemail_domains' then
- each(function(dom)
+ fun.each(function(dom)
table.insert(freemail_domains, '@' .. dom)
- end, drop_n(1, words))
+ end, fun.drop_n(1, words))
elseif words[1] == 'blacklist_from' then
sa_lists['from_blacklist'][words[2]] = 1
sa_lists['elts'] = sa_lists['elts'] + 1
elseif words[1] == 'replace_post' then
process_replace(words, replace['post'])
elseif words[1] == 'replace_rules' then
- each(function(r) table.insert(replace['rules'], r) end,
- drop_n(1, words))
+ fun.each(function(r) table.insert(replace['rules'], r) end,
+ fun.drop_n(1, words))
end
end)()
end
-- Now check all valid rules and add the according rspamd rules
local function calculate_score(sym, rule)
- if all(function(c) return c == '_' end, take_n(2, iter(sym))) then
+ if fun.all(function(c) return c == '_' end, fun.take_n(2, fun.iter(sym))) then
return 0.0
end
local function check_specific_tag(prefix, s, tbl)
local replacement = nil
local ret = s
- each(function(n, t)
+ fun.each(function(n, t)
local ns,matches = string.gsub(s, string.format("<%s%s>", prefix, n), "")
if matches > 0 then
replacement = t
local function replace_all_tags(s)
local str, matches
str = s
- each(function(n, t)
+ fun.each(function(n, t)
str,matches = string.gsub(str, string.format("<%s>", n),
string.format("%s%s%s", pre, t, post))
end, replace['tags'])
end
local function parse_atom(str)
- local atom = table.concat(totable(take_while(function(c)
+ local atom = table.concat(fun.totable(fun.take_while(function(c)
if string.find(', \t()><+!|&\n', c) then
return false
end
return true
- end, iter(str))), '')
+ end, fun.iter(str))), '')
return atom
end
local ntags = {}
local function rec_replace_tags(tag, tagv)
if ntags[tag] then return ntags[tag] end
- each(function(n, t)
+ fun.each(function(n, t)
if n ~= tag then
local s, matches = string.gsub(tagv, string.format("<%s>", n), t)
if matches > 0 then
return ntags[tag]
end
- each(function(n, t)
+ fun.each(function(n, t)
rec_replace_tags(n, t)
end, replace['tags'])
- each(function(n, t)
+ fun.each(function(n, t)
replace['tags'][n] = t
end, ntags)
- each(function(r)
+ fun.each(function(r)
local rule = rules[r]
if rule['re_expr'] and rule['re'] then
end
end, replace['rules'])
- each(function(key, score)
+ fun.each(function(key, score)
if rules[key] then
rules[key]['score'] = score
end
end, scores)
-- Header rules
- each(function(k, r)
+ fun.each(function(k, r)
local f = function(task)
local raw = false
end
-- Slow path
- each(function(h)
+ fun.each(function(h)
local headers = {}
local hname = h['header']
end
atoms[k] = f
end,
- filter(function(k, r)
+ fun.filter(function(k, r)
return r['type'] == 'header' and r['header']
end,
rules))
-- Custom function rules
- each(function(k, r)
+ fun.each(function(k, r)
local f = function(task)
local res = r['function'](task)
if res and res > 0 then
end
atoms[k] = f
end,
- filter(function(k, r)
+ fun.filter(function(k, r)
return r['type'] == 'function' and r['function']
end,
rules))
-- Parts rules
- each(function(k, r)
+ fun.each(function(k, r)
local f = function(task)
if not r['re'] then
rspamd_logger.errx(task, 're is missing for rule %1', k)
end
atoms[k] = f
end,
- filter(function(k, r)
+ fun.filter(function(k, r)
return r['type'] == 'part'
end, rules))
-- SA body rules
- each(function(k, r)
+ fun.each(function(k, r)
local f = function(task)
if not r['re'] then
rspamd_logger.errx(task, 're is missing for rule %1', k)
end
atoms[k] = f
end,
- filter(function(k, r)
+ fun.filter(function(k, r)
return r['type'] == 'sabody' or r['type'] == 'message' or r['type'] == 'sarawbody'
end, rules))
-- URL rules
- each(function(k, r)
+ fun.each(function(k, r)
local f = function(task)
if not r['re'] then
rspamd_logger.errx(task, 're is missing for rule %1', k)
end
atoms[k] = f
end,
- filter(function(k, r)
+ fun.filter(function(k, r)
return r['type'] == 'uri'
end,
rules))
-- Meta rules
- each(function(k, r)
+ fun.each(function(k, r)
local expression = nil
-- Meta function callback
local meta_cb = function(task)
end
end
end,
- filter(function(k, r)
+ fun.filter(function(k, r)
return r['type'] == 'meta'
end,
rules))
-- Check meta rules for foreign symbols and register dependencies
-- First direct dependencies:
- each(function(k, r)
+ fun.each(function(k, r)
if r['expression'] then
local expr_atoms = r['expression']:atoms()
end
end
end,
- filter(function(k, r)
+ fun.filter(function(k, r)
return r['type'] == 'meta'
end,
rules))
-- ... And then indirect ones ...
- each(function(k, r)
+ fun.each(function(k, r)
if r['expression'] then
local expr_atoms = r['expression']:atoms()
for i,a in ipairs(expr_atoms) do
end
end
end,
- filter(function(k, r)
+ fun.filter(function(k, r)
return r['type'] == 'meta'
end,
rules))
-- Set missing symbols
- each(function(key, score)
+ fun.each(function(key, score)
if not scores_added[key] then
rspamd_config:set_metric_symbol({
name = key, score = score,
local files = util.glob(elt)
for i,matched in ipairs(files) do
- f = io.open(matched, "r")
+ local f = io.open(matched, "r")
if f then
process_sa_conf(f)
has_rules = true
local files = util.glob(fn)
for i,matched in ipairs(files) do
- f = io.open(matched, "r")
+ local f = io.open(matched, "r")
if f then
process_sa_conf(f)
has_rules = true
local rspamd_logger = require "rspamd_logger"
local rspamd_util = require "rspamd_util"
local ucl = require "ucl"
-require "fun" ()
+local fun = require "fun"
local options = {
dmarc_allow_symbol = 'DMARC_POLICY_ALLOW',
local dkim_opts = sym[1]['options']
if dkim_opts then
- each(function(val)
+ fun.each(function(val)
if not found then
local tld = rspamd_util.get_tld(val)
end
if options['rules'] then
- each(function(symbol, rule)
+ fun.each(function(symbol, rule)
if rule['domains'] then
if type(rule['domains']) == 'string' then
rule['map'] = rspamd_config:add_kv_map(rule['domains'],
elseif type(rule['domains']) == 'table' then
-- Transform ['domain1', 'domain2' ...] to indexes:
-- {'domain1' = 1, 'domain2' = 1 ...]
- rule['domains'] = tomap(map(function(d)
+ rule['domains'] = fun.tomap(fun.map(function(d)
local name = d
local value = 1