diff options
author | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2017-05-28 15:24:52 +0100 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2017-05-28 15:24:52 +0100 |
commit | 392e2946371f5cf4f3f76fbaa11dd8c00515b967 (patch) | |
tree | 35439397789c5826e15d5f7ce05679c4057fb87d /lualib | |
parent | b7d9a2c37603859d0d614733e68328b55d71f3dc (diff) | |
download | rspamd-392e2946371f5cf4f3f76fbaa11dd8c00515b967.tar.gz rspamd-392e2946371f5cf4f3f76fbaa11dd8c00515b967.zip |
[Rework] Move common DKIM functions to a separate lua module
Diffstat (limited to 'lualib')
-rw-r--r-- | lualib/dkim_sign_tools.lua | 175 |
1 files changed, 175 insertions, 0 deletions
diff --git a/lualib/dkim_sign_tools.lua b/lualib/dkim_sign_tools.lua new file mode 100644 index 000000000..e19d96ce3 --- /dev/null +++ b/lualib/dkim_sign_tools.lua @@ -0,0 +1,175 @@ +--[[ +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 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 not auser then + if (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') + else + rspamd_logger.debugm(N, task, 'ignoring unauthenticated mail') + return false,{} + end + 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 dkim_domain + local hdom = ((hfrom or E)[1] or E).domain + local edom = ((efrom or E)[1] or E).domain + local udom = string.match(auser or '', '.*@(.*)') + + local function get_dkim_domain(type) + if settings[type] == 'header' then + return hdom + elseif settings[type] == 'envelope' then + return edom + elseif settings[type] == 'auth' then + return udom + end + end + + if hdom then + hdom = hdom:lower() + end + if edom then + edom = edom:lower() + end + if udom then + udom = udom:lower() + end + + if settings.use_domain_sign_networks and is_sign_networks then + dkim_domain = get_dkim_domain('use_domain_sign_networks') + elseif settings.use_domain_local and is_local then + dkim_domain = get_dkim_domain('use_domain_local') + else + dkim_domain = get_dkim_domain('use_domain') + end + + if not dkim_domain then + rspamd_logger.debugm(N, task, 'could not extract dkim domain') + return false,{} + else + rspamd_logger.debugm(N, task, 'use domain(%s) for sugnature: %s', + settings.use_domain, dkim_domain) + end + + if settings.use_esld then + dkim_domain = rspamd_util.get_tld(dkim_domain) + + if settings.use_domain == 'envelope' and hdom then + hdom = rspamd_util.get_tld(hdom) + elseif settings.use_domain == 'header' and 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) 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 + + 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 + + if settings.selector_map then + local data = settings.selector_map:get_key(dkim_domain) + if data then + p.selector = data + end + end + + if settings.path_map then + local data = settings.path_map:get_key(dkim_domain) + if data then + p.key = data + end + end + + return true,p +end + +exports.prepare_dkim_signing = prepare_dkim_signing + +return exports
\ No newline at end of file |