From: Vsevolod Stakhov Date: Fri, 16 Aug 2019 15:32:04 +0000 (+0100) Subject: [Feature] RBL: Support bit results in replies X-Git-Tag: 2.0~404 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=f711ce7dfc708fe4814e558b307b060de3466ecb;p=rspamd.git [Feature] RBL: Support bit results in replies --- diff --git a/src/plugins/lua/rbl.lua b/src/plugins/lua/rbl.lua index cf04b8abb..15e1a1a76 100644 --- a/src/plugins/lua/rbl.lua +++ b/src/plugins/lua/rbl.lua @@ -25,6 +25,7 @@ local rspamd_util = require 'rspamd_util' local fun = require 'fun' local lua_util = require 'lua_util' local ts = require("tableshape").types +local bit = require 'bit' -- This plugin implements various types of RBL checks -- Documentation can be found here: @@ -35,8 +36,6 @@ local N = 'rbl' local local_exclusions -local default_monitored = '1.0.0.127' - local function validate_dns(lstr) if lstr:match('%.%.') then -- two dots in a row @@ -176,7 +175,7 @@ local function rbl_dns_process(task, rbl, to_resolve, results, err, orig) to_resolve, true, err, rbl.symbol) end - if rbl.returncodes == nil and rbl.symbol ~= nil then + if rbl.returncodes == nil and rbl.returnbits == nil and rbl.symbol ~= nil then task:insert_result(rbl.symbol, 1, orig) return end @@ -186,15 +185,29 @@ local function rbl_dns_process(task, rbl, to_resolve, results, err, orig) lua_util.debugm(N, task, '%s DNS result %s', to_resolve, ipstr) local foundrc = false -- Check return codes - for s,i in pairs(rbl.returncodes) do - for _,v in ipairs(i) do - if string.find(ipstr, '^' .. v .. '$') then - foundrc = true - task:insert_result(s, 1, orig .. ' : ' .. ipstr) - break + if rbl.returnbits then + local ipnum = result:to_number() + for s,bits in pairs(rbl.returnbits) do + for _,check_bit in ipairs(bits) do + if bit.band(ipnum, check_bit) == check_bit then + foundrc = true + task:insert_result(s, 1, orig .. ' : ' .. ipstr) + -- Here, we continue with other bits + end + end + end + elseif rbl.returncodes then + for s, codes in pairs(rbl.returncodes) do + for _,v in ipairs(codes) do + if string.find(ipstr, '^' .. v .. '$') then + foundrc = true + task:insert_result(s, 1, orig .. ' : ' .. ipstr) + break + end end end end + if not foundrc then if rbl.unknown and rbl.symbol then task:insert_result(rbl.symbol, 1, orig) @@ -204,6 +217,7 @@ local function rbl_dns_process(task, rbl, to_resolve, results, err, orig) end end end + end local function gen_rbl_callback(rule) @@ -516,11 +530,24 @@ local rule_schema = ts.shape({ rbl = ts.string, symbol = ts.string:is_optional(), returncodes = ts.map_of( - ts.string / string.upper, + ts.string / string.upper, -- Symbol name + ( + ts.array_of(ts.string) + + (ts.string / function(s) + return { s } + end) -- List of IP patterns + ) + ):is_optional(), + returnbits = ts.map_of( + ts.string / string.upper, -- Symbol name ( - ts.array_of(ts.string) + (ts.string / function(s) - return { s } - end) + ts.array_of(ts.number + ts.string / tonumber) + + (ts.string / function(s) + return { tonumber(s) } + end) + + (ts.number / function(s) + return { s } + end) ) ):is_optional(), whitelist_exception = ( @@ -538,6 +565,20 @@ local rule_schema = ts.shape({ local monitored_addresses = {} +local function get_monitored(rbl) + local default_monitored = '1.0.0.127' + + if rbl.monitored_address then + return rbl.monitored_address + end + + if rbl.dkim or rbl.url or rbl.email then + default_monitored = 'facebook.com' -- should never be blacklisted + end + + return default_monitored +end + local function add_rbl(key, rbl) if not rbl.symbol then rbl.symbol = key:upper() @@ -571,37 +612,47 @@ local function add_rbl(key, rbl) score = 0.0, } - if rbl.returncodes then - for s,_ in pairs(rbl['returncodes']) do - rspamd_config:register_symbol({ - name = s, - parent = id, - type = 'virtual' - }) - - if rbl.is_whitelist then - if rbl.whitelist_exception then - local foundException = false - for _, e in ipairs(rbl.whitelist_exception) do - if e == s then - foundException = true - break - end - end - if not foundException then - table.insert(white_symbols, s) + local function process_return_code(s) + rspamd_config:register_symbol({ + name = s, + parent = id, + type = 'virtual' + }) + + if rbl.is_whitelist then + if rbl.whitelist_exception then + local found_exception = false + for _, e in ipairs(rbl.whitelist_exception) do + if e == s then + found_exception = true + break end - else + end + if not found_exception then table.insert(white_symbols, s) end else - if rbl.ignore_whitelist == false then - table.insert(black_symbols, s) - end + table.insert(white_symbols, s) + end + else + if rbl.ignore_whitelist == false then + table.insert(black_symbols, s) end end end + if rbl.returncodes then + for s,_ in pairs(rbl.returncodes) do + process_return_code(s) + end + end + + if rbl.returnbits then + for s,_ in pairs(rbl.returnbits) do + process_return_code(s) + end + end + if not rbl.is_whitelist and rbl.ignore_whitelist == false then table.insert(black_symbols, rbl.symbol) end @@ -609,10 +660,10 @@ local function add_rbl(key, rbl) if not rbl.disable_monitoring and not rbl.is_whitelist then if not monitored_addresses[rbl.rbl] then monitored_addresses[rbl.rbl] = true - rbl.monitored = rspamd_config:register_monitored(rbl['rbl'], 'dns', + rbl.monitored = rspamd_config:register_monitored(rbl.rbl, 'dns', { rcode = 'nxdomain', - prefix = rbl.monitored_address or default_monitored + prefix = get_monitored(rbl) }) end end