]> source.dussan.org Git - rspamd.git/commitdiff
Update RBL module: fix indentation; collapse loops; avoid calling for un-needed infor...
authorAndrew Lewis <nerf@judo.za.org>
Wed, 11 Feb 2015 13:43:26 +0000 (15:43 +0200)
committerAndrew Lewis <nerf@judo.za.org>
Wed, 11 Feb 2015 13:48:46 +0000 (15:48 +0200)
conf/modules.conf
doc/markdown/modules/rbl.md
src/plugins/lua/rbl.lua

index 719b86793264f91f733e3fe9f8d68826c6045088..a72eb181880e4fd350e77a5dca4a893fa92474b2 100644 (file)
@@ -86,6 +86,7 @@ rbl {
 
  default_from = true;
  default_received = false;
+ default_user = false;
 
  rbls {
        
index 84bb91478058ed4f5fe710cd18193ef7b0dcc4b2..3bcbf839bcf62e151b92566ba02a763b2f7763fb 100644 (file)
@@ -19,7 +19,7 @@ rbl {
 
 The default settings define the ways in which the RBLs are used unless overridden in an RBL-specific subsection.
 
-Defaults may be set for the following parameters (default values used if these are not set are shown in brackets):
+Defaults may be set for the following parameters (default values used if these are not set are shown in brackets - note that these may be redefined in the default config):
 
 - default_ipv4 (true)
 
@@ -49,6 +49,10 @@ Use this RBL to test parameters sent for HELO/EHLO at SMTP time.
 
 If set to false, do not yield a result unless the response received from the RBL is defined in its related returncodes {} subsection, else return the default symbol for the RBL.
 
+- deault_user (true)
+
+If set to false, do not use this RBL if the message sender is authenticated.
+
 RBL-specific subsection is structured as follows:
 
 ~~~nginx
index 5b6165d80859534b874be73b86724a2659b4e690..9258c1e8636cd47d9a6a46333d9dae7a301ef50e 100644 (file)
@@ -3,159 +3,235 @@ local rbls = {}
 local rspamd_logger = require "rspamd_logger"
 
 local function ip_to_rbl(ip, rbl)
-       return table.concat(ip:inversed_str_octets(), ".") .. '.' .. rbl
+  return table.concat(ip:inversed_str_octets(), ".") .. '.' .. rbl
 end
 
 local function rbl_cb (task)
-       local function rbl_dns_cb(resolver, to_resolve, results, err, key)
-               if results then
-                       local thisrbl = nil
-                       for k,r in pairs(rbls) do
-                               if k == key then
-                                       thisrbl = r
-                                       break
-                               end
-                       end
-                       if thisrbl ~= nil then
-                               if thisrbl['returncodes'] == nil then
-                                       if thisrbl['symbol'] ~= nil then
-                                               task:insert_result(thisrbl['symbol'], 1)
-                                       end
-                               else
-                                       for _,result in pairs(results) do 
-                                               local ipstr = result:to_string()
-                                               local foundrc = false
-                                               for s,i in pairs(thisrbl['returncodes']) do
-                                                       if type(i) == 'string' then
-                                                               if string.find(ipstr, "^" .. i .. "$") then
-                                                                       foundrc = true
-                                                                       task:insert_result(s, 1)
-                                                                       break
-                                                               end
-                                                       elseif type(i) == 'table' then
-                                                               for _,v in pairs(i) do
-                                                                       if string.find(ipstr, "^" .. v .. "$") then
-                                                                               foundrc = true
-                                                                               task:insert_result(s, 1)
-                                                                               break
-                                                                       end
-                                                               end
-                                                       end
-                                               end
-                                               if not foundrc then
-                                                       if thisrbl['unknown'] and thisrbl['symbol'] then
-                                                               task:insert_result(thisrbl['symbol'], 1)
-                                                       else
-                                                               rspamd_logger.err('RBL ' .. thisrbl['rbl'] .. ' returned unknown result ' .. ipstr)
-                                                       end
-                                               end
-                                       end
-                               end
-                       end
-               end
-               task:inc_dns_req()
-       end
+  local function rbl_dns_cb(resolver, to_resolve, results, err, key)
+    if results then
+      local thisrbl = nil
+      for k,r in pairs(rbls) do
+        if k == key then
+          thisrbl = r
+          break
+        end
+      end
+      if thisrbl ~= nil then
+        if thisrbl['returncodes'] == nil then
+          if thisrbl['symbol'] ~= nil then
+            task:insert_result(thisrbl['symbol'], 1)
+          end
+        else
+          for _,result in pairs(results) do 
+            local ipstr = result:to_string()
+            local foundrc = false
+            for s,i in pairs(thisrbl['returncodes']) do
+              if type(i) == 'string' then
+                if string.find(ipstr, "^" .. i .. "$") then
+                  foundrc = true
+                  task:insert_result(s, 1)
+                  break
+                end
+              elseif type(i) == 'table' then
+                for _,v in pairs(i) do
+                  if string.find(ipstr, "^" .. v .. "$") then
+                    foundrc = true
+                    task:insert_result(s, 1)
+                    break
+                  end
+                end
+              end
+            end
+            if not foundrc then
+              if thisrbl['unknown'] and thisrbl['symbol'] then
+                task:insert_result(thisrbl['symbol'], 1)
+              else
+                rspamd_logger.err('RBL ' .. thisrbl['rbl'] ..
+                  ' returned unknown result ' .. ipstr)
+              end
+            end
+          end
+        end
+      end
+    end
+    task:inc_dns_req()
+  end
 
-       local helo = task:get_helo()
-       if helo and string.sub(helo,1,1) ~= '[' then
-               for k,rbl in pairs(rbls) do
-                       if rbl['helo'] then
-                               task:get_resolver():resolve_a(task:get_session(), task:get_mempool(), helo .. '.' .. rbl['rbl'], rbl_dns_cb, k)
-                       end
-               end
-       end
-       local sender_dns = task:get_hostname()
-       if sender_dns ~= nil and sender_dns ~= 'unknown' then
-               for k,rbl in pairs(rbls) do
-                       if rbl['rdns'] then
-                               task:get_resolver():resolve_a(task:get_session(), task:get_mempool(), sender_dns .. '.' .. rbl['rbl'], rbl_dns_cb, k)
-                       end
-               end
-       end
-       local rip = task:get_from_ip()
-       if rip and (rip:to_string() ~= '0.0.0.0') then
-               for k,rbl in pairs(rbls) do
-                       if (rip:get_version() == 6 and rbl['ipv6'] and rbl['from']) or 
-                               (rip:get_version() == 4 and rbl['ipv4'] and rbl['from']) then
-                       task:get_resolver():resolve_a(task:get_session(), task:get_mempool(), 
-                               ip_to_rbl(rip, rbl['rbl']), rbl_dns_cb, k)
-                       end
-               end
-       end
-       local recvh = task:get_received_headers()
-       for _,rh in ipairs(recvh) do
-               if rh['real_ip'] and rh['real_ip']:to_string() ~= '0.0.0.0' then
-                       for k,rbl in pairs(rbls) do
-                               if (rh['real_ip']:get_version() == 6 and rbl['ipv6'] and rbl['received']) or
-                                       (rh['real_ip']:get_version() == 4 and rbl['ipv4'] and rbl['received']) then
-                               task:get_resolver():resolve_a(task:get_session(), task:get_mempool(), 
-                                       ip_to_rbl(rh['real_ip'], rbl['rbl']), rbl_dns_cb, k)
-                               end
-                       end
-       end
-       end
+  local havegot = {}
+  local notgot = {}
+  local function check_user() 
+    if not havegot['user'] and not notgot['user'] then
+      havegot['user'] = task:get_user()
+      if havegot['user'] == nil then
+        notgot['user'] = true
+      end
+    end
+    if havegot['user'] ~= nil then
+      return true
+    end
+    return false
+  end
+
+  for k,rbl in pairs(rbls) do
+
+    if rbl['helo'] then
+      (function()
+        if notgot['helo'] then
+          return
+        end
+        if not havegot['helo'] then
+          havegot['helo'] = task:get_helo()
+          if havegot['helo'] == nil or string.sub(havegot['helo'],1,1) == '[' then
+            notgot['helo'] = true
+            return
+          end
+        end
+        if rbl['user'] == false and check_user() == true then
+          return
+        end
+        task:get_resolver():resolve_a(task:get_session(), task:get_mempool(),
+          havegot['helo'] .. '.' .. rbl['rbl'], rbl_dns_cb, k)
+      end)()
+    end
+
+    if rbl['rdns'] then
+      (function()
+        if notgot['rdns'] then
+          return
+        end
+        if not havegot['rdns'] then
+          havegot['rdns'] = task:get_hostname()
+          if havegot['rdns'] == nil or havegot['rdns'] == 'unknown' then
+            notgot['rdns'] = true
+            return
+          end
+        end
+        if rbl['user'] == false and check_user() == true then
+          return
+        end
+        task:get_resolver():resolve_a(task:get_session(), task:get_mempool(),
+          havegot['rdns'] .. '.' .. rbl['rbl'], rbl_dns_cb, k)
+      end)()
+    end
+
+    if rbl['from'] then
+      (function()
+        if notgot['from'] then
+          return
+        end
+        if not havegot['from'] then
+          havegot['from'] = task:get_from_ip()
+          if havegot['from'] == nil then
+            notgot['from'] = true
+            return
+          end
+        end
+        if (havegot['from']:get_version() == 6 and rbl['ipv6']) or
+          (havegot['from']:get_version() == 4 and rbl['ipv4']) then
+          if rbl['user'] == false and check_user() == true then
+            return
+          end
+          task:get_resolver():resolve_a(task:get_session(), task:get_mempool(),
+            ip_to_rbl(havegot['from'], rbl['rbl']), rbl_dns_cb, k)
+        end
+      end)()
+    end
+
+    if rbl['received'] then
+      (function()
+        if notgot['received'] then
+          return
+        end
+        if not havegot['received'] then
+          havegot['received'] = task:get_received_headers()
+          if havegot['received'] == nil then
+            notgot['received'] = true
+            return
+          end
+        end
+        if rbl['user'] == false and check_user() == true then
+          return
+        end
+        for _,rh in ipairs(havegot['received']) do
+          if rh['real_ip'] and rh['real_ip']:to_string() ~= '0.0.0.0' then
+            for k,rbl in pairs(rbls) do
+              if (rh['real_ip']:get_version() == 6 and rbl['ipv6']) or
+                (rh['real_ip']:get_version() == 4 and rbl['ipv4']) then
+                task:get_resolver():resolve_a(task:get_session(), task:get_mempool(),
+                  ip_to_rbl(rh['real_ip'], rbl['rbl']), rbl_dns_cb, k)
+              end
+            end
+          end
+        end
+      end)()
+    end
+  end
 end
 
 -- Registration
 if type(rspamd_config.get_api_version) ~= 'nil' then
-       if rspamd_config:get_api_version() >= 1 then
-               rspamd_config:register_module_option('rbl', 'rbls', 'map')
-               rspamd_config:register_module_option('rbl', 'default_ipv4', 'string')
-               rspamd_config:register_module_option('rbl', 'default_ipv6', 'string')
-               rspamd_config:register_module_option('rbl', 'default_received', 'string')
-               rspamd_config:register_module_option('rbl', 'default_from', 'string')
-               rspamd_config:register_module_option('rbl', 'default_rdns', 'string')
-               rspamd_config:register_module_option('rbl', 'default_helo', 'string')
-               rspamd_config:register_module_option('rbl', 'default_unknown', 'string')
-       end
+  if rspamd_config:get_api_version() >= 1 then
+    rspamd_config:register_module_option('rbl', 'rbls', 'map')
+    rspamd_config:register_module_option('rbl', 'default_ipv4', 'string')
+    rspamd_config:register_module_option('rbl', 'default_ipv6', 'string')
+    rspamd_config:register_module_option('rbl', 'default_received', 'string')
+    rspamd_config:register_module_option('rbl', 'default_from', 'string')
+    rspamd_config:register_module_option('rbl', 'default_rdns', 'string')
+    rspamd_config:register_module_option('rbl', 'default_helo', 'string')
+    rspamd_config:register_module_option('rbl', 'default_unknown', 'string')
+    rspamd_config:register_module_option('rbl', 'default_user', 'string')
+  end
 end
 
 -- Configuration
 local opts = rspamd_config:get_all_opt('rbl')
 if not opts or type(opts) ~= 'table' then
-       return
+  return
 end
 if(opts['default_ipv4'] == nil) then
-       opts['default_ipv4'] = true
+  opts['default_ipv4'] = true
 end
 if(opts['default_ipv6'] == nil) then
-       opts['default_ipv6'] = false
+  opts['default_ipv6'] = false
 end
 if(opts['default_received'] == nil) then
-       opts['default_received'] = true
+  opts['default_received'] = true
 end
 if(opts['default_from'] == nil) then
-       opts['default_from'] = false
+  opts['default_from'] = false
 end
 if(opts['default_unknown'] == nil) then
-       opts['default_unknown'] = false
+  opts['default_unknown'] = false
 end
 if(opts['default_rdns'] == nil) then
-        opts['default_rdns'] = false
+  opts['default_rdns'] = false
 end
 if(opts['default_helo'] == nil) then
-        opts['default_helo'] = false
+  opts['default_helo'] = false
+end
+if(opts['default_user'] == nil) then
+  opts['default_user'] = true
 end
 for key,rbl in pairs(opts['rbls']) do
-       local o = { "ipv4", "ipv6", "from", "received", "unknown", "rdns", "helo" }
-       for i=1,table.maxn(o) do
-               if(rbl[o[i]] == nil) then
-                       rbl[o[i]] = opts['default_' .. o[i]]
-               end
-       end
-       if type(rbl['returncodes']) == 'table' then
-               for s,_ in pairs(rbl['returncodes']) do
-                       if type(rspamd_config.get_api_version) ~= 'nil' then
-                               rspamd_config:register_virtual_symbol(s, 1)
-                       end
-               end
-       end
-       if not rbl['symbol'] and type(rbl['returncodes']) ~= 'nil' and not rbl['unknown'] then
-               rbl['symbol'] = key
-       end
-       if type(rspamd_config.get_api_version) ~= 'nil' and rbl['symbol'] then
-               rspamd_config:register_virtual_symbol(rbl['symbol'], 1)
-       end
-       rbls[key] = rbl
+  local o = { "ipv4", "ipv6", "from", "received", "unknown", "rdns", "helo", "user" }
+  for i=1,table.maxn(o) do
+    if(rbl[o[i]] == nil) then
+      rbl[o[i]] = opts['default_' .. o[i]]
+    end
+  end
+  if type(rbl['returncodes']) == 'table' then
+    for s,_ in pairs(rbl['returncodes']) do
+      if type(rspamd_config.get_api_version) ~= 'nil' then
+        rspamd_config:register_virtual_symbol(s, 1)
+      end
+    end
+  end
+  if not rbl['symbol'] and type(rbl['returncodes']) ~= 'nil' and not rbl['unknown'] then
+    rbl['symbol'] = key
+  end
+  if type(rspamd_config.get_api_version) ~= 'nil' and rbl['symbol'] then
+    rspamd_config:register_virtual_symbol(rbl['symbol'], 1)
+  end
+  rbls[key] = rbl
 end
 rspamd_config:register_callback_symbol_priority('RBL', 1.0, 0, rbl_cb)