commit d2e75d5: [Project] Preliminary vault support for DKIM signing

Vsevolod Stakhov vsevolod at highsecure.ru
Mon Apr 22 13:35:03 UTC 2019


Author: Vsevolod Stakhov
Date: 2019-04-22 13:46:49 +0100
URL: https://github.com/rspamd/rspamd/commit/d2e75d56b0328553638f214a874988ea5b1ebd42

[Project] Preliminary vault support for DKIM signing

---
 lualib/lua_dkim_tools.lua        | 164 ++++++++++++++++++++++++++-------------
 src/plugins/lua/arc.lua          |  16 +---
 src/plugins/lua/dkim_signing.lua |  17 +---
 3 files changed, 111 insertions(+), 86 deletions(-)

diff --git a/lualib/lua_dkim_tools.lua b/lualib/lua_dkim_tools.lua
index 9e00fdfb1..332fd06f4 100644
--- a/lualib/lua_dkim_tools.lua
+++ b/lualib/lua_dkim_tools.lua
@@ -202,7 +202,7 @@ local function prepare_dkim_signing(N, task, settings)
     tdom = tdom:lower()
   end
 
-  if settings.signing_table and settings.key_table then
+  if settings.signing_table and (settings.key_table or settings.use_vault) then
     -- OpenDKIM style
     if settings.sign_networks and not is_sign_networks then
       lua_util.debugm(N, task,
@@ -224,66 +224,74 @@ local function prepare_dkim_signing(N, task, settings)
         sign_entry = hdom
       end
 
+      if settings.key_table then
       -- Now search in key table
       local key_entry = settings.key_table:get_key(sign_entry)
 
-      if key_entry then
-        local parts = lua_util.str_split(key_entry, ':')
-
-        if #parts == 2 then
-          -- domain + key
-          local selector = settings.selector
-
-          if not selector then
-            logger.errx(task, 'no selector defined for sign_entry %s, key_entry %s',
-                sign_entry, key_entry)
-            return false,{}
-          end
-
-          local res = {
-            selector = selector,
-            domain = parts[1]:gsub('%%', hdom)
-          }
-
-          local st = parts[2]:sub(1, 2)
-
-          if st:sub(1, 1) == '/' or st == './' or st == '..' then
-            res.key = parts[2]:gsub('%%', hdom)
-            lua_util.debugm(N, task, 'perform dkim signing for %s, selector=%s, domain=%s, key file=%s',
-                hdom, selector, res.domain, res.key)
-          else
-            res.rawkey = parts[2] -- No sanity check here
-            lua_util.debugm(N, task, 'perform dkim signing for %s, selector=%s, domain=%s, raw key used',
-                hdom, selector, res.domain)
-          end
-
-          return true,{res}
-        elseif #parts == 3 then
-          -- domain, selector, key
-          local selector = parts[2]
-
-          local res = {
-            selector = selector,
-            domain = parts[1]:gsub('%%', hdom)
-          }
-
-          local st = parts[3]:sub(1, 2)
-
-          if st:sub(1, 1) == '/' or st == './' or st == '..' then
-            res.key = parts[3]:gsub('%%', hdom)
-            lua_util.debugm(N, task, 'perform dkim signing for %s, selector=%s, domain=%s, key file=%s',
-                hdom, selector, res.domain, res.key)
+        if key_entry then
+          local parts = lua_util.str_split(key_entry, ':')
+
+          if #parts == 2 then
+            -- domain + key
+            local selector = settings.selector
+
+            if not selector then
+              logger.errx(task, 'no selector defined for sign_entry %s, key_entry %s',
+                  sign_entry, key_entry)
+              return false,{}
+            end
+
+            local res = {
+              selector = selector,
+              domain = parts[1]:gsub('%%', hdom)
+            }
+
+            local st = parts[2]:sub(1, 2)
+
+            if st:sub(1, 1) == '/' or st == './' or st == '..' then
+              res.key = parts[2]:gsub('%%', hdom)
+              lua_util.debugm(N, task, 'perform dkim signing for %s, selector=%s, domain=%s, key file=%s',
+                  hdom, selector, res.domain, res.key)
+            else
+              res.rawkey = parts[2] -- No sanity check here
+              lua_util.debugm(N, task, 'perform dkim signing for %s, selector=%s, domain=%s, raw key used',
+                  hdom, selector, res.domain)
+            end
+
+            return true,{res}
+          elseif #parts == 3 then
+            -- domain, selector, key
+            local selector = parts[2]
+
+            local res = {
+              selector = selector,
+              domain = parts[1]:gsub('%%', hdom)
+            }
+
+            local st = parts[3]:sub(1, 2)
+
+            if st:sub(1, 1) == '/' or st == './' or st == '..' then
+              res.key = parts[3]:gsub('%%', hdom)
+              lua_util.debugm(N, task, 'perform dkim signing for %s, selector=%s, domain=%s, key file=%s',
+                  hdom, selector, res.domain, res.key)
+            else
+              res.rawkey = parts[3] -- No sanity check here
+              lua_util.debugm(N, task, 'perform dkim signing for %s, selector=%s, domain=%s, raw key used',
+                  hdom, selector, res.domain)
+            end
+
+            return true,{res}
           else
-            res.rawkey = parts[3] -- No sanity check here
-            lua_util.debugm(N, task, 'perform dkim signing for %s, selector=%s, domain=%s, raw key used',
-                hdom, selector, res.domain)
+            logger.errx(task, 'invalid key entry for sign entry %s: %s; when signing %s domain',
+                sign_entry, key_entry, hdom)
+            return false,{}
           end
-
-          return true,{res}
         else
-          logger.errx(task, 'invalid key entry for sign entry %s: %s; when signing %s domain',
-              sign_entry, key_entry, hdom)
-          return false,{}
+          -- Sign table is presented, the rest is covered by vault
+          return true, {
+            domain = sign_entry,
+            vault = true
+          }
         end
       else
         logger.errx(task, 'cannot get key entry for signing entry %s, when signing %s domain',
@@ -358,6 +366,7 @@ local function prepare_dkim_signing(N, task, settings)
 
   lua_util.debugm(N, task, 'final DKIM domain: %s', dkim_domain)
 
+  -- Sanity checks
   if edom and hdom and not settings.allow_hdrfrom_mismatch and hdom ~= edom then
     if settings.allow_hdrfrom_mismatch_local and is_local then
       lua_util.debugm(N, task, 'domain mismatch allowed for local IP: %1 != %2', hdom, edom)
@@ -385,6 +394,27 @@ local function prepare_dkim_signing(N, task, settings)
 
   local p = {}
 
+  if settings.use_vault then
+    if settings.vault_domains then
+      if settings.vault_domains:get_key(dkim_domain) then
+        return true, {
+          domain = dkim_domain,
+          vault = true,
+        }
+      else
+        lua_util.debugm(N, task, 'domain %s is not designated for vault',
+          dkim_domain)
+        return false,{}
+      end
+    else
+      -- TODO: try every domain in the vault
+      return true, {
+        domain = dkim_domain,
+        vault = true,
+      }
+    end
+  end
+
   if settings.domain[dkim_domain] then
     -- support old style selector/paths
     if settings.domain[dkim_domain].selector or
@@ -528,7 +558,29 @@ exports.validate_signing_settings = function(settings)
       settings.path_map or
       settings.selector_map or
       settings.use_http_headers or
-      (settings.signing_table and settings.key_table)
+      (settings.signing_table and settings.key_table) or
+      (settings.use_vault and settings.vault_url and settings.vault_token)
+end
+
+exports.process_signing_settings = function(settings, opts)
+  local lua_maps = require "lua_maps"
+  for k,v in pairs(opts) do
+    if k == 'sign_networks' then
+      settings[k] = lua_maps.map_add(N, k, 'radix', 'DKIM signing networks')
+    elseif k == 'path_map' then
+      settings[k] = lua_maps.map_add(N, k, 'map', 'Paths to DKIM signing keys')
+    elseif k == 'selector_map' then
+      settings[k] = lua_maps.map_add(N, k, 'map', 'DKIM selectors')
+    elseif k == 'signing_table' then
+      settings[k] = lua_maps.map_add(N, k, 'glob', 'DKIM signing table')
+    elseif k == 'key_table' then
+      settings[k] = lua_maps.map_add(N, k, 'glob', 'DKIM keys table')
+    elseif k == 'vault_domains' then
+      settings[k] = lua_maps.map_add(N, k, 'glob', 'DKIM signing domains in vault')
+    else
+      settings[k] = v
+    end
+  end
 end
 
 return exports
diff --git a/src/plugins/lua/arc.lua b/src/plugins/lua/arc.lua
index daca346c0..764a6e5a0 100644
--- a/src/plugins/lua/arc.lua
+++ b/src/plugins/lua/arc.lua
@@ -611,21 +611,7 @@ local function arc_signing_cb(task)
   end
 end
 
-for k,v in pairs(opts) do
-  if k == 'sign_networks' then
-    settings[k] = lua_maps.map_add(N, k, 'radix', 'DKIM signing networks')
-  elseif k == 'path_map' then
-    settings[k] = lua_maps.map_add(N, k, 'map', 'Paths to DKIM signing keys')
-  elseif k == 'selector_map' then
-    settings[k] = lua_maps.map_add(N, k, 'map', 'DKIM selectors')
-  elseif k == 'signing_table' then
-    settings[k] = lua_maps.map_add(N, k, 'glob', 'DKIM signing table')
-  elseif k == 'key_table' then
-    settings[k] = lua_maps.map_add(N, k, 'glob', 'DKIM keys table')
-  else
-    settings[k] = v
-  end
-end
+dkim_sign_tools.process_signing_settings(settings, opts)
 
 if not dkim_sign_tools.validate_signing_settings(settings) then
   rspamd_logger.infox(rspamd_config, 'mandatory parameters missing, disable arc signing')
diff --git a/src/plugins/lua/dkim_signing.lua b/src/plugins/lua/dkim_signing.lua
index 05a7739e7..2a3930b4b 100644
--- a/src/plugins/lua/dkim_signing.lua
+++ b/src/plugins/lua/dkim_signing.lua
@@ -122,21 +122,8 @@ end
 
 local opts =  rspamd_config:get_all_opt('dkim_signing')
 if not opts then return end
-for k,v in pairs(opts) do
-  if k == 'sign_networks' then
-    settings[k] = lua_maps.map_add(N, k, 'radix', 'DKIM signing networks')
-  elseif k == 'path_map' then
-    settings[k] = lua_maps.map_add(N, k, 'map', 'Paths to DKIM signing keys')
-  elseif k == 'selector_map' then
-    settings[k] = lua_maps.map_add(N, k, 'map', 'DKIM selectors')
-  elseif k == 'signing_table' then
-    settings[k] = lua_maps.map_add(N, k, 'glob', 'DKIM signing table')
-  elseif k == 'key_table' then
-    settings[k] = lua_maps.map_add(N, k, 'glob', 'DKIM keys table')
-  else
-    settings[k] = v
-  end
-end
+
+dkim_sign_tools.process_signing_settings(settings, opts)
 
 if not dkim_sign_tools.validate_signing_settings(settings) then
   rspamd_logger.infox(rspamd_config, 'mandatory parameters missing, disable dkim signing')


More information about the Commits mailing list