changeset 2585:02c6ae745c4f

mod_firewall: Add 'test' subcommand to read stanzas from stdin and test them against rules
author Matthew Wild <mwild1@gmail.com>
date Sun, 26 Feb 2017 09:58:07 +0000 (2017-02-26)
parents d64fc9c3cffd
children d28e434cb5fd
files mod_firewall/mod_firewall.lua mod_firewall/test.lib.lua
diffstat 2 files changed, 75 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- 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