# HG changeset patch # User Matthew Wild # Date 1487929100 0 # Node ID 2b533a7b5236bbc6f9de8a24fd04728c86ccdbb4 # Parent 56db2ab3b85353e05ccda673ad43706363991e3c mod_firewall: Make PASS bubble up through all chains, and add DEFAULT and RETURN diff -r 56db2ab3b853 -r 2b533a7b5236 mod_firewall/actions.lib.lua --- a/mod_firewall/actions.lib.lua Thu Feb 23 14:26:19 2017 +0000 +++ b/mod_firewall/actions.lib.lua Fri Feb 24 09:38:20 2017 +0000 @@ -50,13 +50,21 @@ end function action_handlers.PASS() - return "do return end" + return "do return pass_return end" end function action_handlers.DROP() return "do return true end"; end +function action_handlers.DEFAULT() + return "do return false end"; +end + +function action_handlers.RETURN() + return "do return end" +end + function action_handlers.STRIP(tag_desc) local code = {}; local name, xmlns = tag_desc:match("^(%S+) (.+)$"); @@ -185,7 +193,16 @@ end function action_handlers.JUMP_CHAIN(name) - return ("if fire_event(%q, event) then return true; end"):format("firewall/chains/"..name); + return ([[do + local ret = fire_event(%q, event); + log('debug', 'chain \"%%s\" returned %%s', %q, tostring(ret)); + if ret ~= nil then + if ret == false then + return pass_return; + end + return ret; + end + end]]):format("firewall/chains/"..name, name); end function action_handlers.MARK_ORIGIN(name) diff -r 56db2ab3b853 -r 2b533a7b5236 mod_firewall/mod_firewall.lua --- a/mod_firewall/mod_firewall.lua Thu Feb 23 14:26:19 2017 +0000 +++ b/mod_firewall/mod_firewall.lua Fri Feb 24 09:38:20 2017 +0000 @@ -348,7 +348,7 @@ local chain_info = chains[chain]; if not chain_info then if chain:match("^user/") then - chains[chain] = { type = "event", priority = 1, "firewall/chains/"..chain }; + chains[chain] = { type = "event", priority = 1, pass_return = false }; else return nil, errmsg("Unknown chain: "..chain); end @@ -504,7 +504,7 @@ table.insert(code.global_header, 1, "local "..name:lower().."s = definitions."..name..";"); end - local code_string = "return function (definitions, fire_event, log, module)\n\t" + local code_string = "return function (definitions, fire_event, log, module, pass_return)\n\t" ..table.concat(code.global_header, "\n\t") .."\n\tlocal db = require 'util.debug';\n\n\t" .."return function (event)\n\t\t" @@ -525,6 +525,8 @@ return chain_handlers; end +-- Compile handler code into a factory that produces a valid event handler. Factory accepts +-- a value to be returned on PASS local function compile_handler(code_string, filename) -- Prepare event handler function local chunk, err = loadstring(code_string, "="..filename); @@ -534,8 +536,9 @@ local function fire_event(name, data) return module:fire_event(name, data); end - chunk = chunk()(active_definitions, fire_event, logger(filename), module); -- Returns event handler with 'zones' upvalue. - return chunk; + return function (pass_return) + return chunk()(active_definitions, fire_event, logger(filename), module, pass_return); -- Returns event handler with upvalues + end end local function resolve_script_path(script_path) @@ -559,19 +562,20 @@ module:log("error", "Error compiling %s: %s", script, err or "unknown error"); else for chain, handler_code in pairs(chain_functions) do - local handler, err = compile_handler(handler_code, "mod_firewall::"..chain); - if not handler then + local new_handler, err = compile_handler(handler_code, "mod_firewall::"..chain); + if not new_handler then module:log("error", "Compilation error for %s: %s", script, err); else local chain_definition = chains[chain]; if chain_definition and chain_definition.type == "event" then + local handler = new_handler(chain_definition.pass_return); for _, event_name in ipairs(chain_definition) do module:hook(event_name, handler, chain_definition.priority); end elseif not chain:sub(1, 5) == "user/" then module:log("warn", "Unknown chain %q", chain); end - module:hook("firewall/chains/"..chain, handler); + module:hook("firewall/chains/"..chain, new_handler(false)); end end end