aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2017-12-16 18:18:19 +0000
committerGitHub <noreply@github.com>2017-12-16 18:18:19 +0000
commitc8f445ed9b5608426a61d526c1bab02f8bc9068a (patch)
tree850c383b8258bae824fee42c9a6ac1357b16cbad
parente41ef725c8700da8530b112ad198788bd15ae83c (diff)
parent655a1116e05bbbb641a7f88bbfad8d806f02438a (diff)
downloadrspamd-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.lua92
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,