Software /
code /
prosody-modules
Comparison
mod_firewall/mod_firewall.lua @ 2558:2b533a7b5236
mod_firewall: Make PASS bubble up through all chains, and add DEFAULT and RETURN
author | Matthew Wild <mwild1@gmail.com> |
---|---|
date | Fri, 24 Feb 2017 09:38:20 +0000 |
parent | 2550:19a182651a9b |
child | 2561:3da0e3c917cc |
comparison
equal
deleted
inserted
replaced
2557:56db2ab3b853 | 2558:2b533a7b5236 |
---|---|
346 elseif not(state) and line:sub(1, 2) == "::" then | 346 elseif not(state) and line:sub(1, 2) == "::" then |
347 chain = line:gsub("^::%s*", ""); | 347 chain = line:gsub("^::%s*", ""); |
348 local chain_info = chains[chain]; | 348 local chain_info = chains[chain]; |
349 if not chain_info then | 349 if not chain_info then |
350 if chain:match("^user/") then | 350 if chain:match("^user/") then |
351 chains[chain] = { type = "event", priority = 1, "firewall/chains/"..chain }; | 351 chains[chain] = { type = "event", priority = 1, pass_return = false }; |
352 else | 352 else |
353 return nil, errmsg("Unknown chain: "..chain); | 353 return nil, errmsg("Unknown chain: "..chain); |
354 end | 354 end |
355 elseif chain_info.type ~= "event" then | 355 elseif chain_info.type ~= "event" then |
356 return nil, errmsg("Only event chains supported at the moment"); | 356 return nil, errmsg("Only event chains supported at the moment"); |
502 | 502 |
503 for name in pairs(definition_handlers) do | 503 for name in pairs(definition_handlers) do |
504 table.insert(code.global_header, 1, "local "..name:lower().."s = definitions."..name..";"); | 504 table.insert(code.global_header, 1, "local "..name:lower().."s = definitions."..name..";"); |
505 end | 505 end |
506 | 506 |
507 local code_string = "return function (definitions, fire_event, log, module)\n\t" | 507 local code_string = "return function (definitions, fire_event, log, module, pass_return)\n\t" |
508 ..table.concat(code.global_header, "\n\t") | 508 ..table.concat(code.global_header, "\n\t") |
509 .."\n\tlocal db = require 'util.debug';\n\n\t" | 509 .."\n\tlocal db = require 'util.debug';\n\n\t" |
510 .."return function (event)\n\t\t" | 510 .."return function (event)\n\t\t" |
511 .."local stanza, session = event.stanza, event.origin;\n" | 511 .."local stanza, session = event.stanza, event.origin;\n" |
512 ..table.concat(code, "") | 512 ..table.concat(code, "") |
523 if not ruleset then return nil, err; end | 523 if not ruleset then return nil, err; end |
524 local chain_handlers = process_firewall_rules(ruleset); | 524 local chain_handlers = process_firewall_rules(ruleset); |
525 return chain_handlers; | 525 return chain_handlers; |
526 end | 526 end |
527 | 527 |
528 -- Compile handler code into a factory that produces a valid event handler. Factory accepts | |
529 -- a value to be returned on PASS | |
528 local function compile_handler(code_string, filename) | 530 local function compile_handler(code_string, filename) |
529 -- Prepare event handler function | 531 -- Prepare event handler function |
530 local chunk, err = loadstring(code_string, "="..filename); | 532 local chunk, err = loadstring(code_string, "="..filename); |
531 if not chunk then | 533 if not chunk then |
532 return nil, "Error compiling (probably a compiler bug, please report): "..err; | 534 return nil, "Error compiling (probably a compiler bug, please report): "..err; |
533 end | 535 end |
534 local function fire_event(name, data) | 536 local function fire_event(name, data) |
535 return module:fire_event(name, data); | 537 return module:fire_event(name, data); |
536 end | 538 end |
537 chunk = chunk()(active_definitions, fire_event, logger(filename), module); -- Returns event handler with 'zones' upvalue. | 539 return function (pass_return) |
538 return chunk; | 540 return chunk()(active_definitions, fire_event, logger(filename), module, pass_return); -- Returns event handler with upvalues |
541 end | |
539 end | 542 end |
540 | 543 |
541 local function resolve_script_path(script_path) | 544 local function resolve_script_path(script_path) |
542 local relative_to = prosody.paths.config; | 545 local relative_to = prosody.paths.config; |
543 if script_path:match("^module:") then | 546 if script_path:match("^module:") then |
557 | 560 |
558 if not chain_functions then | 561 if not chain_functions then |
559 module:log("error", "Error compiling %s: %s", script, err or "unknown error"); | 562 module:log("error", "Error compiling %s: %s", script, err or "unknown error"); |
560 else | 563 else |
561 for chain, handler_code in pairs(chain_functions) do | 564 for chain, handler_code in pairs(chain_functions) do |
562 local handler, err = compile_handler(handler_code, "mod_firewall::"..chain); | 565 local new_handler, err = compile_handler(handler_code, "mod_firewall::"..chain); |
563 if not handler then | 566 if not new_handler then |
564 module:log("error", "Compilation error for %s: %s", script, err); | 567 module:log("error", "Compilation error for %s: %s", script, err); |
565 else | 568 else |
566 local chain_definition = chains[chain]; | 569 local chain_definition = chains[chain]; |
567 if chain_definition and chain_definition.type == "event" then | 570 if chain_definition and chain_definition.type == "event" then |
571 local handler = new_handler(chain_definition.pass_return); | |
568 for _, event_name in ipairs(chain_definition) do | 572 for _, event_name in ipairs(chain_definition) do |
569 module:hook(event_name, handler, chain_definition.priority); | 573 module:hook(event_name, handler, chain_definition.priority); |
570 end | 574 end |
571 elseif not chain:sub(1, 5) == "user/" then | 575 elseif not chain:sub(1, 5) == "user/" then |
572 module:log("warn", "Unknown chain %q", chain); | 576 module:log("warn", "Unknown chain %q", chain); |
573 end | 577 end |
574 module:hook("firewall/chains/"..chain, handler); | 578 module:hook("firewall/chains/"..chain, new_handler(false)); |
575 end | 579 end |
576 end | 580 end |
577 end | 581 end |
578 end | 582 end |
579 -- Replace contents of definitions table (shared) with active definitions | 583 -- Replace contents of definitions table (shared) with active definitions |