aboutsummaryrefslogtreecommitdiffstats
path: root/lualib/lua_scanners
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2018-12-29 12:13:53 +0000
committerVsevolod Stakhov <vsevolod@highsecure.ru>2018-12-29 12:13:53 +0000
commit2b9ee10f8dd690bfc8c6c244f783d0555de9b0ab (patch)
tree6b987b8022679438c75b5fea3118705570f21f2b /lualib/lua_scanners
parent9fddf731cf2161288d70d50c182831124cbd377b (diff)
downloadrspamd-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.lua81
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)