diff options
author | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2018-11-04 10:01:41 +0000 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2018-11-04 10:01:41 +0000 |
commit | 27c212d3e34088522477cf4dc9cdd8fb75accd6f (patch) | |
tree | 9507a687eb94b4d175a24a8229e082a01ffcb518 /src | |
parent | 2e286c4f43876143a416dd9fa50f9dfceb480a3e (diff) | |
download | rspamd-27c212d3e34088522477cf4dc9cdd8fb75accd6f.tar.gz rspamd-27c212d3e34088522477cf4dc9cdd8fb75accd6f.zip |
[Feature] Add support of cookies in replies module
Diffstat (limited to 'src')
-rw-r--r-- | src/plugins/lua/replies.lua | 94 |
1 files changed, 88 insertions, 6 deletions
diff --git a/src/plugins/lua/replies.lua b/src/plugins/lua/replies.lua index fe15211ef..7e9816fb8 100644 --- a/src/plugins/lua/replies.lua +++ b/src/plugins/lua/replies.lua @@ -37,6 +37,9 @@ local settings = { score = -4, -- Default score use_auth = true, use_local = true, + cookie = nil, + cookie_key = nil, + cookie_is_pattern = false } local N = "replies" @@ -128,16 +131,99 @@ local function replies_set(task) end end +local function replies_check_cookie(task) + local function cookie_matched(extra) + + if extra then + task:insert_result(settings['symbol'], 1.0, string.format('cookie:%s', extra)) + else + task:insert_result(settings['symbol'], 1.0, 'cookie') + end + if settings['action'] ~= nil then + local ip_addr = task:get_ip() + if (settings.use_auth and + task:get_user()) or + (settings.use_local and ip_addr and ip_addr:is_local()) then + rspamd_logger.infox(task, "not forcing action for local network or authorized user"); + else + task:set_pre_result(settings['action'], settings['message'], N) + end + end + end + + -- If in-reply-to header not present return + local irt = task:get_header('in-reply-to') + if irt == nil then + return + end + + local cr = require "rspamd_cryptobox" + -- Extract user part if needed + local extracted_cookie = irt:match('^%<?([^@]+)@.*$') + if not extracted_cookie then + -- Assume full message id as a cookie + extracted_cookie = irt + end + + local dec_cookie = cr.decrypt_cookie(settings.cookie_key, extracted_cookie) + + if dec_cookie then + -- We have something that looks like a cookie + if settings.cookie_is_pattern then + local m = dec_cookie:match(settings.cookie) + + if m then + cookie_matched(m) + end + else + -- Direct match + if dec_cookie == settings.cookie then + cookie_matched() + end + end + end +end + local opts = rspamd_config:get_all_opt('replies') if not (opts and type(opts) == 'table') then rspamd_logger.infox(rspamd_config, 'module is unconfigured') return end if opts then + settings = lua_util.override_defaults(settings, opts) redis_params = lua_redis.parse_redis_server('replies') if not redis_params then - rspamd_logger.infox(rspamd_config, 'no servers are specified, disabling module') - lua_util.disable_module(N, "redis") + if not (settings.cookie and settings.cookie_key) then + rspamd_logger.infox(rspamd_config, 'no servers are specified, disabling module') + lua_util.disable_module(N, "redis") + else + -- Cookies mode + -- Check key sanity: + local pattern = {'^'} + for i=1,32 do pattern[i + 1] = '[a-zA-Z0-9]' end + pattern[34] = '$' + if not settings.cookie_key:match(table.concat(pattern, '')) then + rspamd_logger.errx(rspamd_config, + 'invalid cookies key: %s, must be 32 hex digits', settings.cookie_key) + lua_util.disable_module(N, "config") + + return + end + local id = rspamd_config:register_symbol({ + name = 'REPLIES_CHECK', + type = 'prefilter,nostat', + callback = replies_check_cookie, + priority = 10, + group = "replies" + }) + rspamd_config:register_symbol({ + name = settings['symbol'], + parent = id, + type = 'virtual', + score = settings.score, + group = "replies", + }) + end else rspamd_config:register_symbol({ name = 'REPLIES_SET', @@ -161,8 +247,4 @@ if opts then group = "replies", }) end - - for k,v in pairs(opts) do - settings[k] = v - end end |