mod_firewall: Add 'test' subcommand to read stanzas from stdin and test them against rules
--- a/mod_firewall/mod_firewall.lua Sun Feb 26 09:50:16 2017 +0000
+++ b/mod_firewall/mod_firewall.lua Sun Feb 26 09:58:07 2017 +0000
@@ -672,6 +672,11 @@
local verbose = arg[1] == "-v";
if verbose then table.remove(arg, 1); end
+ if arg[1] == "test" then
+ table.remove(arg, 1);
+ return module:require("test")(arg);
+ end
+
local serialize = require "util.serialization".serialize;
if verbose then
print("local logger = require \"util.logger\".init;");
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mod_firewall/test.lib.lua Sun Feb 26 09:58:07 2017 +0000
@@ -0,0 +1,70 @@
+local set = require "util.set";
+
+local xmppstream = require "util.xmppstream";
+
+local function stderr(...)
+ io.stderr:write("** ", table.concat({...}, "\t", 1, select("#", ...)), "\n");
+end
+
+return function (arg)
+ require "net.http".request = function (url, ex, cb)
+ stderr("Making HTTP request to "..url);
+ local body_table = {};
+ local ok, response_status, response_headers = require "ssl.https".request({
+ url = url;
+ headers = ex.headers;
+ method = ex.body and "POST" or "GET";
+ sink = ltn12.sink.table(body_table);
+ source = ex.body and ltn12.source.string(ex.body) or nil;
+ });
+ stderr("HTTP response "..response_status);
+ cb(table.concat(body_table), response_status, { headers = response_headers });
+ return true;
+ end;
+
+ local stats_dropped, stats_passed = 0, 0;
+
+ load_unload_scripts(set.new(arg));
+ local session = { notopen = true };
+ local stream_callbacks = { default_ns = "jabber:client" };
+
+ function stream_callbacks.streamopened()
+ session.notopen = nil;
+ end
+ function stream_callbacks.streamclosed()
+ end
+ function stream_callbacks.error(session, error_name, error_message)
+ stderr("Fatal error parsing XML stream: "..error_name..": "..tostring(error_message))
+ assert(false);
+ end
+ function stream_callbacks.handlestanza(session, stanza)
+ if not module:fire_event("firewall/chains/deliver", { origin = session, stanza = stanza }) then
+ stats_passed = stats_passed + 1;
+ print(stanza);
+ print("");
+ else
+ stats_dropped = stats_dropped + 1;
+ end
+ end
+
+ local stream = xmppstream.new(session, stream_callbacks);
+ stream:feed("<stream:stream xmlns:stream='http://etherx.jabber.org/streams' xmlns='jabber:client'>");
+ local line_count = 0;
+ for line in io.lines() do
+ line_count = line_count + 1;
+ local ok, err = stream:feed(line.."\n");
+ if not ok then
+ stderr("Fatal XML parse error on line "..line_count..": "..err);
+ return 1;
+ end
+ end
+
+ stderr("Summary");
+ stderr("-------");
+ stderr("");
+ stderr(stats_dropped + stats_passed, "processed");
+ stderr(stats_passed, "passed");
+ stderr(stats_dropped, "droppped");
+ stderr(line_count, "input lines");
+ stderr("");
+end