--- /dev/null
+--[[
+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
local rspamd_logger = require "rspamd_logger"
local lua_util = require "lua_util"
+local dkim_sign_tools = require "dkim_sign_tools"
local rspamd_util = require "rspamd_util"
local rspamd_rsa_privkey = require "rspamd_rsa_privkey"
local rspamd_rsa = require "rspamd_rsa"
local function arc_signing_cb(task)
local arc_sigs = task:cache_get('arc-sigs')
local arc_seals = task:cache_get('arc-seals')
- 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
- 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
+ local ret,p = dkim_sign_tools.prepare_dkim_signing(N, task, settings)
- 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
+ if not ret then
+ return
end
p.arc_cv = 'none'
]]--
local rspamd_logger = require "rspamd_logger"
-local rspamd_util = require "rspamd_util"
+local dkim_sign_tools = require "dkim_sign_tools"
if confighelp then
return
end
local function dkim_signing_cb(task)
- 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
- 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
- if hdom then
- hdom = hdom:lower()
- end
- if edom then
- edom = edom:lower()
- end
- if settings.use_domain_sign_networks and is_sign_networks then
- if settings.use_domain_sign_networks == 'header' then
- dkim_domain = hdom
- else
- dkim_domain = edom
- end
- elseif settings.use_domain_local and is_local then
- if settings.use_domain_local == 'header' then
- dkim_domain = hdom
- else
- dkim_domain = edom
- end
- else
- if settings.use_domain == 'header' then
- dkim_domain = hdom
- else
- dkim_domain = edom
- end
- 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 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
- local udom = string.match(auser, '.*@(.*)')
- 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
+ local ret,p = dkim_sign_tools.prepare_dkim_signing(N, task, settings)
- 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
+ if not ret then
+ return
end
if settings.use_redis then