]> source.dussan.org Git - rspamd.git/commitdiff
[Rework] Move common DKIM functions to a separate lua module
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Sun, 28 May 2017 14:24:52 +0000 (15:24 +0100)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Sun, 28 May 2017 14:24:52 +0000 (15:24 +0100)
lualib/dkim_sign_tools.lua [new file with mode: 0644]
src/plugins/lua/arc.lua
src/plugins/lua/dkim_signing.lua

diff --git a/lualib/dkim_sign_tools.lua b/lualib/dkim_sign_tools.lua
new file mode 100644 (file)
index 0000000..e19d96c
--- /dev/null
@@ -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
index f6569680f1c3d6c3db2381b416ce46a0ae164bb0..e18f0001c2903d4955b421b08c0f9208e13fc73b 100644 (file)
@@ -16,6 +16,7 @@ limitations under the License.
 
 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"
@@ -418,150 +419,11 @@ end
 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'
index 7cd152ba396c6360d3c5b690060518faa100324b..ab6cf059ee69f7f684168075b29c04fd586c76a0 100644 (file)
@@ -16,7 +16,7 @@ limitations under the License.
 ]]--
 
 local rspamd_logger = require "rspamd_logger"
-local rspamd_util = require "rspamd_util"
+local dkim_sign_tools = require "dkim_sign_tools"
 
 if confighelp then
   return
@@ -60,129 +60,10 @@ local function simple_template(tmpl, keys)
 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