aboutsummaryrefslogtreecommitdiffstats
path: root/lualib/lua_dkim_tools.lua
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2018-02-23 13:20:14 +0000
committerVsevolod Stakhov <vsevolod@highsecure.ru>2018-02-23 13:20:14 +0000
commiteb75c68f30b346b352e69eae90c363c8ef113175 (patch)
tree4a48cfb4654e5b97f9ec2b93c5c7adc5e47e649a /lualib/lua_dkim_tools.lua
parent24aec6cd1d0fc0ebbf7baa0f0b78a858e16b5ce1 (diff)
downloadrspamd-eb75c68f30b346b352e69eae90c363c8ef113175.tar.gz
rspamd-eb75c68f30b346b352e69eae90c363c8ef113175.zip
[Refactor] Rename all lua libraries in the common way
Diffstat (limited to 'lualib/lua_dkim_tools.lua')
-rw-r--r--lualib/lua_dkim_tools.lua206
1 files changed, 206 insertions, 0 deletions
diff --git a/lualib/lua_dkim_tools.lua b/lualib/lua_dkim_tools.lua
new file mode 100644
index 000000000..a0c93b4ff
--- /dev/null
+++ b/lualib/lua_dkim_tools.lua
@@ -0,0 +1,206 @@
+--[[
+Copyright (c) 2016, Andrew Lewis <nerf@judo.za.org>
+Copyright (c) 2017, Vsevolod Stakhov <vsevolod@highsecure.ru>
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+]]--
+
+local exports = {}
+
+local E = {}
+local rspamd_logger = require "rspamd_logger"
+local rspamd_util = require "rspamd_util"
+
+local function prepare_dkim_signing(N, task, settings)
+ local is_local, is_sign_networks
+ local auser = task:get_user()
+ local ip = task:get_from_ip()
+
+ if ip and ip:is_local() then
+ is_local = true
+ end
+
+ if settings.auth_only and auser then
+ rspamd_logger.debugm(N, task, 'user is authenticated')
+ elseif (settings.sign_networks and settings.sign_networks:get_key(ip)) then
+ is_sign_networks = true
+ rspamd_logger.debugm(N, task, 'mail is from address in sign_networks')
+ elseif settings.sign_local and is_local then
+ rspamd_logger.debugm(N, task, 'mail is from local address')
+ elseif settings.sign_inbound and not is_local and not auser then
+ rspamd_logger.debugm(N, task, 'mail was sent to us')
+ else
+ rspamd_logger.debugm(N, task, 'ignoring unauthenticated mail')
+ return false,{}
+ end
+
+ local efrom = task:get_from('smtp')
+ if not settings.allow_envfrom_empty and
+ #(((efrom or E)[1] or E).addr or '') == 0 then
+ rspamd_logger.debugm(N, task, 'empty envelope from not allowed')
+ return false,{}
+ end
+
+ local hfrom = task:get_from('mime')
+ if not settings.allow_hdrfrom_multiple and (hfrom or E)[2] then
+ rspamd_logger.debugm(N, task, 'multiple header from not allowed')
+ return false,{}
+ end
+
+ local eto = task:get_recipients(0)
+
+ local dkim_domain
+ local hdom = ((hfrom or E)[1] or E).domain
+ local edom = ((efrom or E)[1] or E).domain
+ local tdom = ((eto or E)[1] or E).domain
+ local udom = string.match(auser or '', '.*@(.*)')
+
+ local function get_dkim_domain(dtype)
+ if settings[dtype] == 'header' then
+ return hdom
+ elseif settings[dtype] == 'envelope' then
+ return edom
+ elseif settings[dtype] == 'auth' then
+ return udom
+ elseif settings[dtype] == 'recipient' then
+ return tdom
+ end
+ end
+
+ if hdom then
+ hdom = hdom:lower()
+ end
+ if edom then
+ edom = edom:lower()
+ end
+ if udom then
+ udom = udom:lower()
+ end
+ if tdom then
+ tdom = tdom:lower()
+ end
+
+ if settings.use_domain_sign_networks and is_sign_networks then
+ dkim_domain = get_dkim_domain('use_domain_sign_networks')
+ rspamd_logger.debugm(N, task, 'sign_networks: use domain(%s) for signature: %s',
+ settings.use_domain_sign_networks, dkim_domain)
+ elseif settings.use_domain_local and is_local then
+ dkim_domain = get_dkim_domain('use_domain_local')
+ rspamd_logger.debugm(N, task, 'local: use domain(%s) for signature: %s',
+ settings.use_domain_local, dkim_domain)
+ else
+ dkim_domain = get_dkim_domain('use_domain')
+ rspamd_logger.debugm(N, task, 'use domain(%s) for signature: %s',
+ settings.use_domain, dkim_domain)
+ end
+
+ if not dkim_domain then
+ rspamd_logger.debugm(N, task, 'could not extract dkim domain')
+ return false,{}
+ end
+
+ if settings.use_esld then
+ dkim_domain = rspamd_util.get_tld(dkim_domain)
+ if hdom then
+ hdom = rspamd_util.get_tld(hdom)
+ end
+ if edom then
+ edom = rspamd_util.get_tld(edom)
+ end
+ end
+ if edom and hdom and not settings.allow_hdrfrom_mismatch and hdom ~= edom then
+ if settings.allow_hdrfrom_mismatch_local and is_local then
+ rspamd_logger.debugm(N, task, 'domain mismatch allowed for local IP: %1 != %2', hdom, edom)
+ elseif settings.allow_hdrfrom_mismatch_sign_networks and is_sign_networks then
+ rspamd_logger.debugm(N, task, 'domain mismatch allowed for sign_networks: %1 != %2', hdom, edom)
+ else
+ rspamd_logger.debugm(N, task, 'domain mismatch not allowed: %1 != %2', hdom, edom)
+ return false,{}
+ end
+ end
+
+ if auser and not settings.allow_username_mismatch then
+ if not udom then
+ rspamd_logger.debugm(N, task, 'couldnt find domain in username')
+ return false,{}
+ end
+ if settings.use_esld then
+ udom = rspamd_util.get_tld(udom)
+ end
+ if udom ~= dkim_domain then
+ rspamd_logger.debugm(N, task, 'user domain mismatch')
+ return false,{}
+ end
+ end
+
+ local p = {}
+
+ if settings.domain[dkim_domain] then
+ p.selector = settings.domain[dkim_domain].selector
+ p.key = settings.domain[dkim_domain].path
+ end
+
+ if not p.key and p.selector then
+ local key_var = "dkim_key"
+ local selector_var = "dkim_selector"
+ if N == "arc" then
+ key_var = "arc_key"
+ selector_var = "arc_selector"
+ end
+
+ p.key = task:get_mempool():get_variable(key_var)
+ p.selector = task:get_mempool():get_variable(selector_var)
+
+ if (not p.key or not p.selector) and (not (settings.try_fallback or
+ settings.use_redis or settings.selector_map
+ or settings.path_map)) then
+ rspamd_logger.debugm(N, task, 'dkim unconfigured and fallback disabled')
+ return false,{}
+ end
+ end
+
+ if not p.selector and settings.selector_map then
+ local data = settings.selector_map:get_key(dkim_domain)
+ if data then
+ p.selector = data
+ elseif not settings.try_fallback then
+ return false,{}
+ end
+ end
+
+ if not p.key and settings.path_map then
+ local data = settings.path_map:get_key(dkim_domain)
+ if data then
+ p.key = data
+ elseif not settings.try_fallback then
+ return false,{}
+ end
+ end
+
+ if not p.key then
+ if not settings.use_redis then
+ p.key = settings.path
+ end
+ end
+
+ if not p.selector then
+ p.selector = settings.selector
+ end
+ p.domain = dkim_domain
+
+ return true,p
+end
+
+exports.prepare_dkim_signing = prepare_dkim_signing
+
+return exports