diff options
author | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2018-12-29 12:13:53 +0000 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2018-12-29 12:13:53 +0000 |
commit | 2b9ee10f8dd690bfc8c6c244f783d0555de9b0ab (patch) | |
tree | 6b987b8022679438c75b5fea3118705570f21f2b /lualib/lua_scanners | |
parent | 9fddf731cf2161288d70d50c182831124cbd377b (diff) | |
download | rspamd-2b9ee10f8dd690bfc8c6c244f783d0555de9b0ab.tar.gz rspamd-2b9ee10f8dd690bfc8c6c244f783d0555de9b0ab.zip |
[Feature] DCC: Add bulkness and reputation checks to dcc
Diffstat (limited to 'lualib/lua_scanners')
-rw-r--r-- | lualib/lua_scanners/dcc.lua | 81 |
1 files changed, 71 insertions, 10 deletions
diff --git a/lualib/lua_scanners/dcc.lua b/lualib/lua_scanners/dcc.lua index 27230fd6f..3d59f0f1b 100644 --- a/lualib/lua_scanners/dcc.lua +++ b/lualib/lua_scanners/dcc.lua @@ -104,7 +104,10 @@ local function dcc_check(task, content, _, rule) timeout = rule.timeout or 2.0, shutdown = true, data = request_data, - callback = dcc_callback + callback = dcc_callback, + body_max = 999999, + fuz1_max = 999999, + fuz2_max = 999999, }) else rspamd_logger.errx(task, '%s: failed to scan, maximum retransmits exceed', rule['symbol'], rule['type']) @@ -117,25 +120,75 @@ local function dcc_check(task, content, _, rule) lua_util.debugm(N, task, 'DCC result=%1 disposition=%2 header="%3"', result, disposition, header) - --[[ - @todo: Implement math function to calc the score dynamically based on return values. Maybe check spamassassin implementation. - ]] -- - if header then local _,_,info = header:find("; (.-)$") + if (result == 'R') then -- Reject common.yield_result(task, rule, info, rule.default_score) elseif (result == 'T') then -- Temporary failure rspamd_logger.warnx(task, 'DCC returned a temporary failure result: %s', result) - task:insert_result(rule['symbol_fail'], 0.0, 'DCC returned a temporary failure result:' .. result) + task:insert_result(rule.symbol_fail, + 0.0, + 'tempfail:' .. result) elseif result == 'A' then - -- do nothing if rule.log_clean then - rspamd_logger.infox(task, '%s: clean, returned result A - info: %s', rule.log_prefix, info) + rspamd_logger.infox(task, '%s: clean, returned result A - info: %s', + rule.log_prefix, info) else - lua_util.debugm(N, task, '%s: returned result A - info: %s', rule.log_prefix, info) + lua_util.debugm(N, task, '%s: returned result A - info: %s', + rule.log_prefix, info) + + local opts = {} + local score = 0.0 + info = info:lower() + local rep = info:match('rep=([^=%s]+)') + + -- Adjust reputation if available + if rep then rep = tonumber(rep) end + if not rep then + rep = 1.0 + end + + local function check_threshold(what, num, lim) + local rnum + if num == 'many' then + rnum = lim + else + rnum = tonumber(num) + end + + if rnum and rnum >= lim then + opts[#opts + 1] = string.format('%s=%s', what, num) + score = score + rep / 3.0 + end + end + + info = info:lower() + local body = info:match('body=([^=%s]+)') + + if body then + check_threshold('body', body, rule.body_max) + end + + local fuz1 = info:match('fuz1=([^=%s]+)') + + if fuz1 then + check_threshold('fuz1', fuz1, rule.fuz1_max) + end + + local fuz2 = info:match('fuz2=([^=%s]+)') + + if fuz2 then + check_threshold('fuz2', fuz2, rule.fuz2_max) + end + + if #opts > 0 and score > 0 then + task:insert_result(rule.symbol_bulk, + score, + opts) + end end elseif result == 'G' then -- do nothing @@ -154,7 +207,9 @@ local function dcc_check(task, content, _, rule) else -- Unknown result rspamd_logger.warnx(task, 'DCC result error: %1', result); - task:insert_result(rule['symbol_fail'], 0.0, 'DCC result error: ' .. result) + task:insert_result(rule.symbol_fail, + 0.0, + 'error: ' .. result) end end end @@ -187,6 +242,12 @@ local function dcc_config(opts) default_score = 1, action = false, client = '0.0.0.0', + symbol_fail = 'DCC_FAIL', + symbol = 'DCC_REJECT', + symbol_bulk = 'DCC_BULK', + body_max = 999999, + fuz1_max = 999999, + fuz2_max = 999999, } dcc_conf = lua_util.override_defaults(dcc_conf, opts) |