소스 검색

[Rework] Settings: Rework settings check

tags/1.9.0
Vsevolod Stakhov 5 년 전
부모
커밋
c82b20c9ee
1개의 변경된 파일98개의 추가작업 그리고 108개의 파일을 삭제
  1. 98
    108
      src/plugins/lua/settings.lua

+ 98
- 108
src/plugins/lua/settings.lua 파일 보기

@@ -199,126 +199,112 @@ local function check_settings(task)
return false
end

local function check_specific_setting(rule_name, rule, ip, client_ip, from, rcpt,
user, auth_user, hostname, matched)
local function check_specific_setting(rule_name, rule, data, matched)
local res = false

if rule.authenticated then
if auth_user then
res = true
matched[#matched + 1] = 'authenticated'
end
if not res then
return nil
end
local function ip_valid(ip)
return ip:is_valid()
end

if rule['local'] then
if not ip or not ip:is_valid() then
return nil
local function not_empty(s)
return #s > 0
end

local function generic_check(value, to_check, check_func, what, valid_func)
if not to_check then return true end

if type(value) == 'function' then
value = value()
end

if ip:is_local() then
matched[#matched + 1] = 'local'
res = true
if value then
if valid_func then
if not valid_func(value) then
return false
end
end

if not check_func then
check_func = function(a, b) return a == b end
end

local ret = fun.any(function(d)
return check_func(value, d)
end, to_check)
if ret then
res = true
matched[#matched + 1] = what
else
return false
end
else
return nil
return false
end

return true
end

if rule.ip then
if not ip or not ip:is_valid() then
return nil
end
for _, ip_check in ipairs(rule.ip) do
res = check_ip_setting(ip_check, ip)
if res then
matched[#matched + 1] = 'ip'
break
end
end
if not res then
return nil
end
if not generic_check(data.ip, rule.ip,
check_ip_setting, 'ip', ip_valid) then
return nil
end

if rule.client_ip then
if not client_ip or not client_ip:is_valid() then
return nil
end
for _, ip_check in ipairs(rule.client_ip) do
res = check_ip_setting(ip_check, client_ip)
if res then
matched[#matched + 1] = 'client_ip'
break
end
end
if not res then
return nil
end
if not generic_check(data.client_ip, rule.client_ip,
check_ip_setting, 'client_ip', ip_valid) then
return nil
end

if rule.from then
if not from then
return nil
end
for _, from_check in ipairs(rule.from) do
res = check_addr_setting(from_check, from)
if res then
matched[#matched + 1] = 'from'
break
end
end
if not res then
return nil
end
if not generic_check(data.from, rule.from,
check_addr_setting, 'from') then
return nil
end

if rule.rcpt then
if not rcpt then
return nil
end
for _, rcpt_check in ipairs(rule.rcpt) do
res = check_addr_setting(rcpt_check, rcpt)
if not generic_check(data.from_mime, rule.from_mime,
check_addr_setting, 'from_mime') then
return nil
end

if res then
matched[#matched + 1] = 'rcpt'
break
end
end
if not res then
return nil
end
if not generic_check(data.rcpt, rule.rcpt,
check_addr_setting, 'rcpt') then
return nil
end

if rule.user then
if not user then
return nil
end
for _, user_check in ipairs(rule.user) do
res = check_addr_setting(user_check, user)
if res then
matched[#matched + 1] = 'user'
break
end
if not generic_check(data.rcpt_mime, rule.rcpt_mime,
check_addr_setting, 'rcpt_mime') then
return nil
end

if not generic_check(data.user, rule.user,
check_addr_setting, 'user') then
return nil
end

if not generic_check(data.hostname, rule.hostname,
check_addr_setting, 'hostname', not_empty) then
return nil
end

-- Non generic checks

if rule.authenticated then
if data.user[1] then
res = true
matched[#matched + 1] = 'authenticated'
end
if not res then
return nil
end
end

if rule.hostname then
if #hostname == 0 then
if rule['local'] then
if not data.ip or not data.ip:is_valid() then
return nil
end
for _, hname_check in ipairs(rule.hostname) do
res = check_addr_setting(hname_check, hostname)
if res then
matched[#matched + 1] = 'hostname'
break
end
end
if not res then

if data.ip:is_local() then
matched[#matched + 1] = 'local'
res = true
else
return nil
end
end
@@ -391,23 +377,28 @@ local function check_settings(task)
end

lua_util.debugm(N, task, "check for settings")
local ip = task:get_from_ip()
local client_ip = task:get_client_ip()
local from = task:get_from()
local rcpt = task:get_recipients()
local data = {
ip = task:get_from_ip(),
client_ip = task:get_client_ip(),
from = task:get_from(1),
from_mime = task:get_from(2),
rcpt = task:get_recipients(1),
rcpt_mime = task:get_recipients(2),
hostname = task:get_hostname() or '',
user = {}
}

local uname = task:get_user()
local hostname = task:get_hostname() or ''
local user = {}
if uname then
user[1] = {}
data.user[1] = {}
local localpart, domainpart = string.gmatch(uname, "(.+)@(.+)")()
if localpart then
user[1]["user"] = localpart
user[1]["domain"] = domainpart
user[1]["addr"] = uname
data.user[1]["user"] = localpart
data.user[1]["domain"] = domainpart
data.user[1]["addr"] = uname
else
user[1]["user"] = uname
user[1]["addr"] = uname
data.user[1]["user"] = uname
data.user[1]["addr"] = uname
end
end
-- Match rules according their order
@@ -417,11 +408,10 @@ local function check_settings(task)
if not applied and settings[pri] then
for _,s in ipairs(settings[pri]) do
local matched = {}
local rule = check_specific_setting(s.name, s.rule,
ip, client_ip, from, rcpt, user, uname, hostname, matched)
local result = check_specific_setting(s.name, s.rule, data, matched)

-- Can use xor here but more complicated for reading
if (rule and not s.rule.inverse) or (not rule and s.rule.inverse) then
if (result and not s.rule.inverse) or (not result and s.rule.inverse) then
rspamd_logger.infox(task, "<%s> apply settings according to rule %s (%s matched)",
task:get_message_id(), s.name, table.concat(matched, ','))
if s.rule['apply'] then

Loading…
취소
저장