]> source.dussan.org Git - rspamd.git/commitdiff
[Feature] Allow to get dkim signing data directly from HTTP headers
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Tue, 14 Aug 2018 16:19:58 +0000 (17:19 +0100)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Tue, 14 Aug 2018 16:19:58 +0000 (17:19 +0100)
lualib/lua_dkim_tools.lua
src/plugins/lua/arc.lua
src/plugins/lua/dkim_signing.lua

index 832e8a3ea2b150f5d529b6d4f39c7a65c31e83a9..5ea3f68bf5901273198c688853cc355303f22751 100644 (file)
@@ -21,8 +21,58 @@ local E = {}
 local lua_util = require "lua_util"
 local rspamd_util = require "rspamd_util"
 
+local function parse_dkim_http_headers(N, task, settings)
+  local logger = require "rspamd_logger"
+  -- Configure headers
+  local headers = {
+    sign_header = settings.http_sign_header or "PerformDkimSign",
+    sign_on_reject_header = settings.http_sign_on_reject_header_header or 'SignOnAuthFailed',
+    domain_header = settings.http_domain_header or 'DkimDomain',
+    selector_header = settings.http_selector_header or 'DkimSelector',
+    key_header = settings.http_key_header or 'DkimPrivateKey'
+  }
+
+  if task:get_request_header(headers.sign_header) then
+    local domain = task:get_request_header(headers.domain_header)
+    local selector = task:get_request_header(headers.selector_header)
+    local key = task:get_request_header(headers.key_header)
+
+    if not (domain and selector and key) then
+
+      logger.errx(task, 'missing required headers to sign email')
+      return false,{}
+    end
+
+    -- Now check if we need to check the existing auth
+    local hdr = task:get_request_header(headers.sign_on_reject_header)
+    if not hdr then
+      -- Check for DKIM_REJECT
+      if task:has_symbol('R_DKIM_REJECT') then
+        local sym = task:get_symbol('R_DKIM_REJECT')
+        logger.infox(task, 'skip signing for %s:%s: R_DKIM_REJECT found: %s',
+            domain, selector, sym.options)
+        return false,{}
+      end
+    end
+
+    return true,{
+      rawkey = key,
+      domain = domain,
+      selector = selector
+    }
+  end
+
+  lua_util.debugm(N, task, 'no sign header %s', headers.sign_header)
+  return false,{}
+end
+
 local function prepare_dkim_signing(N, task, settings)
   local is_local, is_sign_networks
+
+  if settings.use_http_headers then
+    return parse_dkim_http_headers(N, task, settings)
+  end
+
   local auser = task:get_user()
   local ip = task:get_from_ip()
 
index ef6a11e71fef01a3912ad08666052c79720c4561..30ae0cd1941cb52068a3d62da7e516169548b73f 100644 (file)
@@ -549,16 +549,22 @@ local function arc_signing_cb(task)
       try_redis_key(p.selector)
     end
   else
-    if (p.key and p.selector) then
-      p.key = lua_util.template(p.key, {domain = p.domain, selector = p.selector})
-      local exists,err = rspamd_util.file_exists(p.key)
-      if not exists then
-        if err and err == 'No such file or directory' then
-          lua_util.debugm(N, task, 'cannot read key from %s: %s', p.key, err)
-        else
-          rspamd_logger.warnx(N, task, 'cannot read key from %s: %s', p.key, err)
+    if ((p.key or p.rawkey) and p.selector) then
+      if p.key then
+        p.key = lua_util.template(p.key, {
+          domain = p.domain,
+          selector = p.selector
+        })
+
+        local exists,err = rspamd_util.file_exists(p.key)
+        if not exists then
+          if err and err == 'No such file or directory' then
+            lua_util.debugm(N, task, 'cannot read key from %s: %s', p.key, err)
+          else
+            rspamd_logger.warnx(N, task, 'cannot read key from %s: %s', p.key, err)
+          end
+          return false
         end
-        return false
       end
 
       local dret, hdr = dkim_sign(task, p)
index 343fb8a84cde459f1810758a4671e6f274884c29..99e1fca6807b23b8abc81195beda20e4a6e6c68d 100644 (file)
@@ -152,20 +152,26 @@ local function dkim_signing_cb(task)
       try_redis_key(p.selector)
     end
   else
-    if (p.key and p.selector) then
-      p.key = lua_util.template(p.key, { domain = p.domain, selector = p.selector})
-      local exists,err = rspamd_util.file_exists(p.key)
-      if not exists then
-        if err and err == 'No such file or directory' then
-          lua_util.debugm(N, task, 'cannot read key from "%s": %s', p.key, err)
-        else
-          rspamd_logger.warnx(N, task, 'cannot read key from "%s": %s', p.key, err)
+    if ((p.key or p.rawkey) and p.selector) then
+      if p.key then
+        -- templates
+        p.key = lua_util.template(p.key, {
+          domain = p.domain,
+          selector = p.selector
+        })
+        local exists,err = rspamd_util.file_exists(p.key)
+        if not exists then
+          if err and err == 'No such file or directory' then
+            lua_util.debugm(N, task, 'cannot read key from "%s": %s', p.key, err)
+          else
+            rspamd_logger.warnx(N, task, 'cannot read key from "%s": %s', p.key, err)
+          end
+          return false
         end
-        return false
-      end
 
-      lua_util.debugm(N, task, 'key found at "%s", use selector "%s" for domain "%s"',
-          p.key, p.selector, p.domain)
+        lua_util.debugm(N, task, 'key found at "%s", use selector "%s" for domain "%s"',
+            p.key, p.selector, p.domain)
+      end
 
       do_sign()
     else