]> source.dussan.org Git - rspamd.git/commitdiff
Add new RBL module
authorAndrew Lewis <nerf@judo.za.org>
Sun, 17 Nov 2013 17:37:45 +0000 (19:37 +0200)
committerAndrew Lewis <nerf@judo.za.org>
Sun, 17 Nov 2013 17:37:45 +0000 (19:37 +0200)
src/plugins/lua/rbl.lua [new file with mode: 0644]

diff --git a/src/plugins/lua/rbl.lua b/src/plugins/lua/rbl.lua
new file mode 100644 (file)
index 0000000..91205c0
--- /dev/null
@@ -0,0 +1,147 @@
+-- Configuration:
+-- rbl {
+--    default_ipv4 = true;
+--    default_ipv6 = false;
+--    default_received = true;
+--    default_from = false;
+--    rbls {
+--     xbl {
+--        rbl = "xbl.spamhaus.org";
+--         symbol = "RBL_SPAMHAUSXBL";
+--         ipv4 = true;
+--         ipv6 = false;
+--     }
+--    }
+-- }
+
+local rbls = {}
+
+function revipv6(ip)
+       local c = 0
+       local i = 1
+       local t = {}
+       for o in string.gmatch(ip, "%p-%x+%p-") do
+               o = string.gsub(o, ":", "")
+               while(#o < 4) do
+                       o = "0" .. o
+               end
+               t[i] = o
+               i = i+1
+       end
+       if #t < 8 then
+               for i=1,8 do
+                       if(t[i] == nil) then
+                               c = c+1
+                       end
+               end
+               for i=(8-c),#t do
+                       t[i+c] = t[i]
+                       t[i] = "0000"
+               end
+               for i=1,8 do
+                       if(t[i] == nil) then
+                               t[i] = "0000"
+                       end
+               end
+       end
+       x=table.concat(t,"")
+       x=string.reverse(x)
+       rbl_str = ""
+       for i in string.gmatch(x, "%x") do
+               rbl_str = rbl_str .. i .. "."
+       end
+       return rbl_str
+end
+
+function dns_cb(task, to_resolve, results, err, sym)
+       if results then
+               task:insert_result(sym, 1)
+       end
+end
+
+function rbl_cb (task)
+       local rip = task:get_from_ip()
+       if(rip ~= nil) then
+               if not string.match(rip, ":") then
+                       local _,_,o1,o2,o3,o4 = string.find(rip, '^(%d+)%.(%d+)%.(%d+)%.(%d+)$')
+                       for _,rbl in pairs(rbls) do
+                               if(rbl['ipv4'] and rbl['from']) then
+                                       rbl_str = o4 .. '.' .. o3 .. '.' .. o2 .. '.' .. o1 .. '.' .. rbl['rbl']
+                                       task:resolve_dns_a(rbl_str, 'dns_cb', rbl['symbol'])
+                               end
+                       end
+               else
+                       for _,rbl in pairs(rbls) do
+                               if(rbl['ipv6'] and rbl['from']) then
+                                       rbl_str = revipv6(rip) .. rbl['rbl']
+                                       task:resolve_dns_a(rbl_str, 'dns_cb', rbl['symbol'])
+                               end
+                       end
+               end
+       end
+       local recvh = task:get_received_headers()
+       for _,rh in ipairs(recvh) do
+               if rh['real_ip'] then
+                       if not string.match(rh['real_ip'], ":") then
+                               local _,_,o1,o2,o3,o4 = string.find(rh['real_ip'], '^(%d+)%.(%d+)%.(%d+)%.(%d+)$')
+                               if o1 and o2 and o3 and o4 then
+                                       for _,rbl in pairs(rbls) do
+                                               if(rbl['ipv4'] and rbl['received']) then
+                                                       rbl_str = o4 .. '.' .. o3 .. '.' .. o2 .. '.' .. o1 .. '.' .. rbl['rbl']
+                                                       task:resolve_dns_a(rbl_str, 'dns_cb', rbl['symbol'])
+                                               end
+                                       end
+                               end
+                       else
+                               for _,rbl in pairs(rbls) do
+                                       if(rbl['ipv6'] and rbl['received']) then
+                                               rbl_str = revipv6(rh['real_ip']) .. rbl['rbl']
+                                               task:resolve_dns_a(rbl_str, 'dns_cb', rbl['symbol'])
+                                       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')
+       end
+end
+
+-- Configuration
+local opts = rspamd_config:get_all_opt('rbl')
+if(opts == nil) then
+       return
+end
+if(opts['default_ipv4'] == nil) then
+       opts['default_ipv4'] = true
+end
+if(opts['default_ipv6'] == nil) then
+       opts['default_ipv6'] = false
+end
+if(opts['default_received'] == nil) then
+       opts['default_received'] = true 
+end
+if(opts['default_from'] == nil) then
+       opts['default_from'] = false
+end
+for _,rbl in pairs(opts['rbls']) do
+       local o = { "ipv4", "ipv6", "from", "received" }
+       for i=1,#o do
+               if(rbl[o[i]] == nil) then
+                       rbl[o[i]] = opts['default_' .. o[i]]
+               end
+       end
+       if type(rspamd_config.get_api_version) ~= 'nil' then
+               rspamd_config:register_virtual_symbol(rbl['symbol'], 1)
+       end
+       table.insert(rbls, {symbol = rbl['symbol'], rbl = rbl['rbl'], ipv6 = rbl['ipv6'], ipv4 = rbl['ipv4'], received = rbl['received'], from = rbl['from']})
+       rspamd_config:register_symbol(rbl['symbol'], 1.0, 'rbl_cb')
+end