diff options
author | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2017-12-16 18:18:19 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-12-16 18:18:19 +0000 |
commit | c8f445ed9b5608426a61d526c1bab02f8bc9068a (patch) | |
tree | 850c383b8258bae824fee42c9a6ac1357b16cbad | |
parent | e41ef725c8700da8530b112ad198788bd15ae83c (diff) | |
parent | 655a1116e05bbbb641a7f88bbfad8d806f02438a (diff) | |
download | rspamd-c8f445ed9b5608426a61d526c1bab02f8bc9068a.tar.gz rspamd-c8f445ed9b5608426a61d526c1bab02f8bc9068a.zip |
Merge pull request #1962 from fatalbanana/rbl_rcvd
[Feature] RBL: received: filtering by position & flags
-rw-r--r-- | src/plugins/lua/rbl.lua | 92 |
1 files changed, 79 insertions, 13 deletions
diff --git a/src/plugins/lua/rbl.lua b/src/plugins/lua/rbl.lua index 59d1de2d5..82c1fb975 100644 --- a/src/plugins/lua/rbl.lua +++ b/src/plugins/lua/rbl.lua @@ -87,6 +87,72 @@ local function ip_to_rbl(ip, rbl) return table.concat(ip:inversed_str_octets(), '.') .. '.' .. rbl end +local function gen_check_rcvd_conditions(rbl, received_total) + local min_pos = tonumber(rbl['received_min_pos']) + local max_pos = tonumber(rbl['received_max_pos']) + local match_flags = rbl['received_flags'] + local nmatch_flags = rbl['received_nflags'] + local function basic_received_check(rh) + if ((rh['real_ip']:get_version() == 6 and rbl['ipv6']) or + (rh['real_ip']:get_version() == 4 and rbl['ipv4'])) and + ((rbl['exclude_private_ips'] and not rh['real_ip']:is_local()) or + not rbl['exclude_private_ips']) and ((rbl['exclude_local_ips'] and + not is_excluded_ip(rh['real_ip'])) or not rbl['exclude_local_ips']) then + return true + else + return false + end + end + if not (max_pos or min_pos or match_flags or nmatch_flags) then + return basic_received_check + end + return function(rh, pos) + if not basic_received_check() then return false end + local got_flags = rh['flags'] + if min_pos then + if min_pos < 0 then + if min_pos == -1 then + if (pos ~= received_total) then + return false + end + else + if pos <= (received_total - (min_pos*-1)) then + return false + end + end + elseif pos < min_pos then + return false + end + end + if max_pos then + if max_pos < -1 then + if (received_total - (max_pos*-1)) >= pos then + return false + end + elseif max_pos > 0 then + if pos > max_pos then + return false + end + end + end + if match_flags then + for _, flag in ipairs(match_flags) do + if not got_flags[flag] then + return false + end + end + end + if nmatch_flags then + for _, flag in ipairs(nmatch_flags) do + if got_flags[flag] then + return false + end + end + end + return true + end +end + local function rbl_cb (task) local function gen_rbl_callback(rule) return function (_, to_resolve, results, err) @@ -380,21 +446,21 @@ local function rbl_cb (task) return false end, enabled_rbls)) + havegot['received'] = fun.filter(function(h) + return not h['flags']['artificial'] + end, havegot['received']):totable() + + local received_total = #havegot['received'] -- Received lists fun.each(function(_, rbl) - for _,rh in ipairs(havegot['received']) do - if rh['real_ip'] and rh['real_ip']:is_valid() then - if ((rh['real_ip']:get_version() == 6 and rbl['ipv6']) or - (rh['real_ip']:get_version() == 4 and rbl['ipv4'])) and - ((rbl['exclude_private_ips'] and not rh['real_ip']:is_local()) or - not rbl['exclude_private_ips']) and ((rbl['exclude_local_ips'] and - not is_excluded_ip(rh['real_ip'])) or not rbl['exclude_local_ips']) then - -- Disable forced for received resolving, as we have no control on - -- those headers count - local to_resolve = ip_to_rbl(rh['real_ip'], rbl['rbl']) - local rule = gen_rbl_rule(to_resolve, rbl) - rule.forced = false - end + local check_conditions = gen_check_rcvd_conditions(rbl, received_total) + for pos,rh in ipairs(havegot['received']) do + if check_conditions(rh, pos) then + local to_resolve = ip_to_rbl(rh['real_ip'], rbl['rbl']) + local rule = gen_rbl_rule(to_resolve, rbl) + -- Disable forced for received resolving, as we have no control on + -- those headers count + rule.forced = false end end end, |