aboutsummaryrefslogtreecommitdiffstats
path: root/lualib/lua_scanners/common.lua
diff options
context:
space:
mode:
Diffstat (limited to 'lualib/lua_scanners/common.lua')
-rw-r--r--lualib/lua_scanners/common.lua79
1 files changed, 72 insertions, 7 deletions
diff --git a/lualib/lua_scanners/common.lua b/lualib/lua_scanners/common.lua
index 65dd4aef8..dcd31db30 100644
--- a/lualib/lua_scanners/common.lua
+++ b/lualib/lua_scanners/common.lua
@@ -125,11 +125,68 @@ local function message_not_too_large(task, content, rule)
return true
end
-local function need_av_check(task, content, rule)
- return message_not_too_large(task, content, rule)
+local function message_not_too_small(task, content, rule)
+ local min_size = tonumber(rule.min_size)
+ if not min_size then return true end
+ if #content < min_size then
+ rspamd_logger.infox(task, "skip %s check as it is too small: %s (%s is allowed)",
+ rule.log_prefix, #content, min_size)
+ return false
+ end
+ return true
+end
+
+local function message_min_words(task, rule)
+ if rule.text_part_min_words then
+ local text_parts_empty = false
+ local text_parts = task:get_text_parts()
+
+ local filter_func = function(p)
+ return p:get_words_count() <= tonumber(rule.text_part_min_words)
+ end
+
+ fun.each(function(p)
+ text_parts_empty = true
+ rspamd_logger.infox(task, '%s: #words is less then text_part_min_words: %s',
+ rule.log_prefix, rule.text_part_min_words)
+ end, fun.filter(filter_func, text_parts))
+
+ return text_parts_empty
+ else
+ return true
+ end
end
-local function check_av_cache(task, digest, rule, fn)
+local function dynamic_scan(task, rule)
+ if rule.dynamic_scan then
+ if rule.action ~= 'reject' then
+ local metric_result = task:get_metric_score('default')
+ local metric_action = task:get_metric_action('default')
+ local has_pre_result = task:has_pre_result()
+ -- ToDo: needed?
+ -- Sometimes leads to FPs
+ --if rule.symbol_type == 'postfilter' and metric_action == 'reject' then
+ -- rspamd_logger.infox(task, '%s: aborting: %s', rule.log_prefix, "result is already reject")
+ -- return false
+ --elseif metric_result[1] > metric_result[2]*2 then
+ if metric_result[1] > metric_result[2]*2 then
+ rspamd_logger.infox(task, '%s: aborting: %s', rule.log_prefix, 'score > 2 * reject_level: ' .. metric_result[1])
+ return false
+ elseif has_pre_result and metric_action == 'reject' then
+ rspamd_logger.infox(task, '%s: aborting: %s', rule.log_prefix, 'pre_result reject is set')
+ return false
+ else
+ return true, 'undecided'
+ end
+ else
+ return true, 'dynamic_scan is not possible with config `action=reject;`'
+ end
+ else
+ return true
+ end
+end
+
+local function check_cache(task, digest, rule, fn)
local key = digest
local function redis_av_cb(err, data)
@@ -173,7 +230,15 @@ local function check_av_cache(task, digest, rule, fn)
return false
end
-local function save_av_cache(task, digest, rule, to_save, dyn_weight)
+local function need_check(task, content, rule, digest)
+ return check_cache(task, digest, rule) and
+ message_not_too_large(task, content, rule) and
+ message_not_too_small(task, content, rule) and
+ message_min_words(task, rule) and
+ dynamic_scan(task, rule)
+end
+
+local function save_cache(task, digest, rule, to_save, dyn_weight)
local key = digest
if not dyn_weight then dyn_weight = 1.0 end
@@ -363,9 +428,9 @@ end
exports.log_clean = log_clean
exports.yield_result = yield_result
exports.match_patterns = match_patterns
-exports.need_av_check = need_av_check
-exports.check_av_cache = check_av_cache
-exports.save_av_cache = save_av_cache
+exports.need_check = need_check
+exports.check_cache = check_cache
+exports.save_cache = save_cache
exports.create_regex_table = create_regex_table
exports.check_parts_match = check_parts_match
exports.check_metric_results = check_metric_results