diff options
author | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2021-11-12 12:27:45 +0000 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2021-11-12 12:27:45 +0000 |
commit | 4e7488a38a5785462d0079bcb4d7151866be2c34 (patch) | |
tree | 217ba882e734ba9c395147f82873cab7eab33d2b /lualib/lua_scanners/cloudmark.lua | |
parent | a60d02d527b5af86dfc484b114fe607cc6674856 (diff) | |
download | rspamd-4e7488a38a5785462d0079bcb4d7151866be2c34.tar.gz rspamd-4e7488a38a5785462d0079bcb4d7151866be2c34.zip |
[Minor] Allow to get the maximum message size
Diffstat (limited to 'lualib/lua_scanners/cloudmark.lua')
-rw-r--r-- | lualib/lua_scanners/cloudmark.lua | 88 |
1 files changed, 67 insertions, 21 deletions
diff --git a/lualib/lua_scanners/cloudmark.lua b/lualib/lua_scanners/cloudmark.lua index fc109cb84..18cacc2d6 100644 --- a/lualib/lua_scanners/cloudmark.lua +++ b/lualib/lua_scanners/cloudmark.lua @@ -32,6 +32,62 @@ local N = 'cloudmark' -- Boundary for multipart transfers, generated on module init local static_boundary = rspamd_util.random_hex(32) +local function cloudmark_url(rule, addr, maybe_url) + local url + local port = addr:get_port() + + maybe_url = maybe_url or rule.url + if port == 0 then + port = rule.default_port + end + if rule.use_https then + url = string.format('https://%s:%d%s', tostring(addr), + port, maybe_url) + else + url = string.format('http://%s:%d%s', tostring(addr), + port, maybe_url) + end + + return url +end + +-- Detect cloudmark max size +local function cloudmark_preload(rule, cfg, ev_base, _) + local upstream = rule.upstreams:get_upstream_round_robin() + local addr = upstream:get_addr() + local function max_message_size_cb(http_err, code, body, _) + if http_err then + rspamd_logger.errx(ev_base, 'HTTP error when getting max message size: %s', + http_err) + return + end + if code ~= 200 then + rspamd_logger.errx(ev_base, 'bad HTTP code when getting max message size: %s', code) + end + local parser = ucl.parser() + local ret, err = parser:parse_string(body) + if not ret then + rspamd_logger.errx(ev_base, 'could not parse response body [%s]: %s', body, err) + return + end + local obj = parser:get_object() + local ms = obj.maxMessageSize + if not ms then + rspamd_logger.errx(ev_base, 'missing maxMessageSize in the response body (JSON): %s', obj) + return + end + + rule.max_size = ms + lua_util.debugm(N, cfg, 'set maximum message size set to %s bytes', ms) + end + http.request({ + ev_base = ev_base, + config = cfg, + url = cloudmark_url(rule, addr, '/score/v2/max-message-size'), + callback = max_message_size_cb, + }) +end + local function cloudmark_config(opts) local cloudmark_conf = { @@ -44,6 +100,7 @@ local function cloudmark_config(opts) retransmits = 1, score_threshold = 90, -- minimum score to considerate reply message = '${SCANNER}: spam message found: "${VIRUS}"', + max_message = 0, detection_category = "hash", default_score = 1, action = false, @@ -84,6 +141,7 @@ local function cloudmark_config(opts) if cloudmark_conf.upstreams then cloudmark_conf.symbols = {{ symbol = cloudmark_conf.symbol_spam, score = 5.0 }} + cloudmark_conf.preloads = {cloudmark_preload} lua_util.add_debug_alias('external_services', cloudmark_conf.name) return cloudmark_conf end @@ -149,6 +207,7 @@ local function parse_cloudmark_reply(task, rule, body) return end local obj = parser:get_object() + lua_util.debugm(N, task, 'cloudmark reply is: %s', obj) if not obj.score then rspamd_logger.errx(task, '%s: bad response body (raw): %s', N, body) @@ -165,33 +224,20 @@ end local function cloudmark_check(task, content, digest, rule, maybe_part) local function cloudmark_check_uncached() - local function cloudmark_url(addr) - local url - local port = addr:get_port() - - if port == 0 then - port = rule.default_port - end - if rule.use_https then - url = string.format('https://%s:%d%s', tostring(addr), - port, rule.url) - else - url = string.format('http://%s:%d%s', tostring(addr), - port, rule.url) - end - - return url - end - local upstream = rule.upstreams:get_upstream_round_robin() local addr = upstream:get_addr() local retransmits = rule.retransmits - local url = cloudmark_url(addr) + local url = cloudmark_url(rule, addr) + local message_data = task:get_content() + if rule.max_message and rule.max_message > 0 and #message_data > rule.max_message then + task:insert_result(rule['symbol_fail'], 0.0, 'Message too large: ' .. #message_data) + return + end local request = { rfc822 = { ['Content-Type'] = 'message/rfc822', - data = task:get_content() + data = message_data, } } @@ -253,7 +299,7 @@ local function cloudmark_check(task, content, digest, rule, maybe_part) -- Select a different upstream! upstream = rule.upstreams:get_upstream_round_robin() addr = upstream:get_addr() - url = cloudmark_url(addr) + url = cloudmark_url(rule, addr) lua_util.debugm(rule.name, task, '%s: retry IP: %s:%s', rule.log_prefix, addr, addr:get_port()) |