mod_firewall/mod_firewall.lua
author Kim Alvefur <zash@zash.se>
Sun, 19 Apr 2020 23:37:13 +0200
changeset 3985 7e8f2e36419d
parent 2932 b0d92332b87f
child 4586 cc20493018f6
permissions -rw-r--r--
mod_firewall: Use util.envload instead of deprecated loadstring (thanks Martin) loadstring was deprecated in Lua 5.2 and removed from in 5.3
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
947
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     1
2582
6dbd07f9a868 mod_firewall: Various improvements allowing dynamic load/reload/unload of scripts
Matthew Wild <mwild1@gmail.com>
parents: 2578
diff changeset
     2
local lfs = require "lfs";
947
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     3
local resolve_relative_path = require "core.configmanager".resolve_relative_path;
3985
7e8f2e36419d mod_firewall: Use util.envload instead of deprecated loadstring (thanks Martin)
Kim Alvefur <zash@zash.se>
parents: 2932
diff changeset
     4
local envload = require "util.envload".envload;
947
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     5
local logger = require "util.logger".init;
971
53e158e44a44 mod_firewall: Add rate limiting capabilities, and keep zones and throttle objects in shared tables
Matthew Wild <mwild1@gmail.com>
parents: 967
diff changeset
     6
local it = require "util.iterators";
2582
6dbd07f9a868 mod_firewall: Various improvements allowing dynamic load/reload/unload of scripts
Matthew Wild <mwild1@gmail.com>
parents: 2578
diff changeset
     7
local set = require "util.set";
947
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     8
2583
5e948d1392a5 mod_firewall: Add some comments
Matthew Wild <mwild1@gmail.com>
parents: 2582
diff changeset
     9
-- [definition_type] = definition_factory(param)
999
197af8440ffb mod_firewall: Make defining objects generic (currently zones and rate limits), so more can easily be added. Also a syntax change... definition lines must begin with %
Matthew Wild <mwild1@gmail.com>
parents: 998
diff changeset
    10
local definitions = module:shared("definitions");
2583
5e948d1392a5 mod_firewall: Add some comments
Matthew Wild <mwild1@gmail.com>
parents: 2582
diff changeset
    11
5e948d1392a5 mod_firewall: Add some comments
Matthew Wild <mwild1@gmail.com>
parents: 2582
diff changeset
    12
-- When a definition instance has been instantiated, it lives here
5e948d1392a5 mod_firewall: Add some comments
Matthew Wild <mwild1@gmail.com>
parents: 2582
diff changeset
    13
-- [definition_type][definition_name] = definition_object
2378
d630fa0d4dba mod_firewall: Add default zone called '$local' containing all local hosts (dynamically)
Matthew Wild <mwild1@gmail.com>
parents: 2372
diff changeset
    14
local active_definitions = {
d630fa0d4dba mod_firewall: Add default zone called '$local' containing all local hosts (dynamically)
Matthew Wild <mwild1@gmail.com>
parents: 2372
diff changeset
    15
	ZONE = {
d630fa0d4dba mod_firewall: Add default zone called '$local' containing all local hosts (dynamically)
Matthew Wild <mwild1@gmail.com>
parents: 2372
diff changeset
    16
		-- Default zone that includes all local hosts
d630fa0d4dba mod_firewall: Add default zone called '$local' containing all local hosts (dynamically)
Matthew Wild <mwild1@gmail.com>
parents: 2372
diff changeset
    17
		["$local"] = setmetatable({}, { __index = prosody.hosts });
2531
5ff7eb601d60 mod_firewall: Code formatting
Matthew Wild <mwild1@gmail.com>
parents: 2530
diff changeset
    18
	};
2378
d630fa0d4dba mod_firewall: Add default zone called '$local' containing all local hosts (dynamically)
Matthew Wild <mwild1@gmail.com>
parents: 2372
diff changeset
    19
};
947
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    20
2117
d75145297bf9 mod_firewall: Support for defining extra chains in the config file
Matthew Wild <mwild1@gmail.com>
parents: 2105
diff changeset
    21
local default_chains = {
947
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    22
	preroute = {
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    23
		type = "event";
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    24
		priority = 0.1;
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    25
		"pre-message/bare", "pre-message/full", "pre-message/host";
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    26
		"pre-presence/bare", "pre-presence/full", "pre-presence/host";
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    27
		"pre-iq/bare", "pre-iq/full", "pre-iq/host";
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    28
	};
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    29
	deliver = {
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    30
		type = "event";
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    31
		priority = 0.1;
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    32
		"message/bare", "message/full", "message/host";
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    33
		"presence/bare", "presence/full", "presence/host";
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    34
		"iq/bare", "iq/full", "iq/host";
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    35
	};
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    36
	deliver_remote = {
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    37
		type = "event"; "route/remote";
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    38
		priority = 0.1;
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    39
	};
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    40
};
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    41
2117
d75145297bf9 mod_firewall: Support for defining extra chains in the config file
Matthew Wild <mwild1@gmail.com>
parents: 2105
diff changeset
    42
local extra_chains = module:get_option("firewall_extra_chains", {});
d75145297bf9 mod_firewall: Support for defining extra chains in the config file
Matthew Wild <mwild1@gmail.com>
parents: 2105
diff changeset
    43
d75145297bf9 mod_firewall: Support for defining extra chains in the config file
Matthew Wild <mwild1@gmail.com>
parents: 2105
diff changeset
    44
local chains = {};
d75145297bf9 mod_firewall: Support for defining extra chains in the config file
Matthew Wild <mwild1@gmail.com>
parents: 2105
diff changeset
    45
for k,v in pairs(default_chains) do
d75145297bf9 mod_firewall: Support for defining extra chains in the config file
Matthew Wild <mwild1@gmail.com>
parents: 2105
diff changeset
    46
	chains[k] = v;
d75145297bf9 mod_firewall: Support for defining extra chains in the config file
Matthew Wild <mwild1@gmail.com>
parents: 2105
diff changeset
    47
end
d75145297bf9 mod_firewall: Support for defining extra chains in the config file
Matthew Wild <mwild1@gmail.com>
parents: 2105
diff changeset
    48
for k,v in pairs(extra_chains) do
d75145297bf9 mod_firewall: Support for defining extra chains in the config file
Matthew Wild <mwild1@gmail.com>
parents: 2105
diff changeset
    49
	chains[k] = v;
d75145297bf9 mod_firewall: Support for defining extra chains in the config file
Matthew Wild <mwild1@gmail.com>
parents: 2105
diff changeset
    50
end
d75145297bf9 mod_firewall: Support for defining extra chains in the config file
Matthew Wild <mwild1@gmail.com>
parents: 2105
diff changeset
    51
2128
89363766202c mod_firewall: Add comment to document idsafe()
Matthew Wild <mwild1@gmail.com>
parents: 2122
diff changeset
    52
-- Returns the input if it is safe to be used as a variable name, otherwise nil
2103
a8c701631d0b mod_firewall: Make idsafe() a global function so libraries can re-use it
Matthew Wild <mwild1@gmail.com>
parents: 2084
diff changeset
    53
function idsafe(name)
2531
5ff7eb601d60 mod_firewall: Code formatting
Matthew Wild <mwild1@gmail.com>
parents: 2530
diff changeset
    54
	return name:match("^%a[%w_]*$");
971
53e158e44a44 mod_firewall: Add rate limiting capabilities, and keep zones and throttle objects in shared tables
Matthew Wild <mwild1@gmail.com>
parents: 967
diff changeset
    55
end
53e158e44a44 mod_firewall: Add rate limiting capabilities, and keep zones and throttle objects in shared tables
Matthew Wild <mwild1@gmail.com>
parents: 967
diff changeset
    56
2522
0e1054c19f9d mod_firewall: More meta! Allow simple functions to be applied to $<> expressions
Matthew Wild <mwild1@gmail.com>
parents: 2521
diff changeset
    57
local meta_funcs = {
0e1054c19f9d mod_firewall: More meta! Allow simple functions to be applied to $<> expressions
Matthew Wild <mwild1@gmail.com>
parents: 2521
diff changeset
    58
	bare = function (code)
0e1054c19f9d mod_firewall: More meta! Allow simple functions to be applied to $<> expressions
Matthew Wild <mwild1@gmail.com>
parents: 2521
diff changeset
    59
		return "jid_bare("..code..")", {"jid_bare"};
0e1054c19f9d mod_firewall: More meta! Allow simple functions to be applied to $<> expressions
Matthew Wild <mwild1@gmail.com>
parents: 2521
diff changeset
    60
	end;
0e1054c19f9d mod_firewall: More meta! Allow simple functions to be applied to $<> expressions
Matthew Wild <mwild1@gmail.com>
parents: 2521
diff changeset
    61
	node = function (code)
0e1054c19f9d mod_firewall: More meta! Allow simple functions to be applied to $<> expressions
Matthew Wild <mwild1@gmail.com>
parents: 2521
diff changeset
    62
		return "(jid_split("..code.."))", {"jid_split"};
0e1054c19f9d mod_firewall: More meta! Allow simple functions to be applied to $<> expressions
Matthew Wild <mwild1@gmail.com>
parents: 2521
diff changeset
    63
	end;
0e1054c19f9d mod_firewall: More meta! Allow simple functions to be applied to $<> expressions
Matthew Wild <mwild1@gmail.com>
parents: 2521
diff changeset
    64
	host = function (code)
0e1054c19f9d mod_firewall: More meta! Allow simple functions to be applied to $<> expressions
Matthew Wild <mwild1@gmail.com>
parents: 2521
diff changeset
    65
		return "(select(2, jid_split("..code..")))", {"jid_split"};
0e1054c19f9d mod_firewall: More meta! Allow simple functions to be applied to $<> expressions
Matthew Wild <mwild1@gmail.com>
parents: 2521
diff changeset
    66
	end;
0e1054c19f9d mod_firewall: More meta! Allow simple functions to be applied to $<> expressions
Matthew Wild <mwild1@gmail.com>
parents: 2521
diff changeset
    67
	resource = function (code)
0e1054c19f9d mod_firewall: More meta! Allow simple functions to be applied to $<> expressions
Matthew Wild <mwild1@gmail.com>
parents: 2521
diff changeset
    68
		return "(select(3, jid_split("..code..")))", {"jid_split"};
0e1054c19f9d mod_firewall: More meta! Allow simple functions to be applied to $<> expressions
Matthew Wild <mwild1@gmail.com>
parents: 2521
diff changeset
    69
	end;
0e1054c19f9d mod_firewall: More meta! Allow simple functions to be applied to $<> expressions
Matthew Wild <mwild1@gmail.com>
parents: 2521
diff changeset
    70
};
0e1054c19f9d mod_firewall: More meta! Allow simple functions to be applied to $<> expressions
Matthew Wild <mwild1@gmail.com>
parents: 2521
diff changeset
    71
2129
edf5cf3c474b mod_firewall: Move meta() function to main module, and make it a global so libs can use it
Matthew Wild <mwild1@gmail.com>
parents: 2128
diff changeset
    72
-- Run quoted (%q) strings through this to allow them to contain code. e.g.: LOG=Received: $(stanza:top_tag())
2522
0e1054c19f9d mod_firewall: More meta! Allow simple functions to be applied to $<> expressions
Matthew Wild <mwild1@gmail.com>
parents: 2521
diff changeset
    73
function meta(s, deps, extra)
2389
c0c2f8665c3e mod_firewall: Fix for raw code expressions that contain escape-worthy characters
Matthew Wild <mwild1@gmail.com>
parents: 2378
diff changeset
    74
	return (s:gsub("$(%b())", function (expr)
c0c2f8665c3e mod_firewall: Fix for raw code expressions that contain escape-worthy characters
Matthew Wild <mwild1@gmail.com>
parents: 2378
diff changeset
    75
			expr = expr:gsub("\\(.)", "%1");
c0c2f8665c3e mod_firewall: Fix for raw code expressions that contain escape-worthy characters
Matthew Wild <mwild1@gmail.com>
parents: 2378
diff changeset
    76
			return [["..tostring(]]..expr..[[).."]];
c0c2f8665c3e mod_firewall: Fix for raw code expressions that contain escape-worthy characters
Matthew Wild <mwild1@gmail.com>
parents: 2378
diff changeset
    77
		end)
2129
edf5cf3c474b mod_firewall: Move meta() function to main module, and make it a global so libs can use it
Matthew Wild <mwild1@gmail.com>
parents: 2128
diff changeset
    78
		:gsub("$(%b<>)", function (expr)
edf5cf3c474b mod_firewall: Move meta() function to main module, and make it a global so libs can use it
Matthew Wild <mwild1@gmail.com>
parents: 2128
diff changeset
    79
			expr = expr:sub(2,-2);
2542
a1b6a6b0aabb mod_firewall: Reinstate the ability to set a default for stanza expressions
Matthew Wild <mwild1@gmail.com>
parents: 2537
diff changeset
    80
			local default = "<undefined>";
2565
3da0e3c917cc mod_firewall: Accept backslash escapes in definitions
Matthew Wild <mwild1@gmail.com>
parents: 2562
diff changeset
    81
			expr = expr:gsub("||(%b\"\")$", function (default_string)
3da0e3c917cc mod_firewall: Accept backslash escapes in definitions
Matthew Wild <mwild1@gmail.com>
parents: 2562
diff changeset
    82
				default = stripslashes(default_string:sub(2,-2));
2542
a1b6a6b0aabb mod_firewall: Reinstate the ability to set a default for stanza expressions
Matthew Wild <mwild1@gmail.com>
parents: 2537
diff changeset
    83
				return "";
a1b6a6b0aabb mod_firewall: Reinstate the ability to set a default for stanza expressions
Matthew Wild <mwild1@gmail.com>
parents: 2537
diff changeset
    84
			end);
2522
0e1054c19f9d mod_firewall: More meta! Allow simple functions to be applied to $<> expressions
Matthew Wild <mwild1@gmail.com>
parents: 2521
diff changeset
    85
			local func_chain = expr:match("|[%w|]+$");
0e1054c19f9d mod_firewall: More meta! Allow simple functions to be applied to $<> expressions
Matthew Wild <mwild1@gmail.com>
parents: 2521
diff changeset
    86
			if func_chain then
0e1054c19f9d mod_firewall: More meta! Allow simple functions to be applied to $<> expressions
Matthew Wild <mwild1@gmail.com>
parents: 2521
diff changeset
    87
				expr = expr:sub(1, -1-#func_chain);
0e1054c19f9d mod_firewall: More meta! Allow simple functions to be applied to $<> expressions
Matthew Wild <mwild1@gmail.com>
parents: 2521
diff changeset
    88
			end
0e1054c19f9d mod_firewall: More meta! Allow simple functions to be applied to $<> expressions
Matthew Wild <mwild1@gmail.com>
parents: 2521
diff changeset
    89
			local code;
0e1054c19f9d mod_firewall: More meta! Allow simple functions to be applied to $<> expressions
Matthew Wild <mwild1@gmail.com>
parents: 2521
diff changeset
    90
			if expr:match("^@") then
0e1054c19f9d mod_firewall: More meta! Allow simple functions to be applied to $<> expressions
Matthew Wild <mwild1@gmail.com>
parents: 2521
diff changeset
    91
				-- Skip stanza:find() for simple attribute lookup
0e1054c19f9d mod_firewall: More meta! Allow simple functions to be applied to $<> expressions
Matthew Wild <mwild1@gmail.com>
parents: 2521
diff changeset
    92
				local attr_name = expr:sub(2);
0e1054c19f9d mod_firewall: More meta! Allow simple functions to be applied to $<> expressions
Matthew Wild <mwild1@gmail.com>
parents: 2521
diff changeset
    93
				if deps and (attr_name == "to" or attr_name == "from" or attr_name == "type") then
0e1054c19f9d mod_firewall: More meta! Allow simple functions to be applied to $<> expressions
Matthew Wild <mwild1@gmail.com>
parents: 2521
diff changeset
    94
					-- These attributes may be cached in locals
0e1054c19f9d mod_firewall: More meta! Allow simple functions to be applied to $<> expressions
Matthew Wild <mwild1@gmail.com>
parents: 2521
diff changeset
    95
					code = attr_name;
0e1054c19f9d mod_firewall: More meta! Allow simple functions to be applied to $<> expressions
Matthew Wild <mwild1@gmail.com>
parents: 2521
diff changeset
    96
					table.insert(deps, attr_name);
0e1054c19f9d mod_firewall: More meta! Allow simple functions to be applied to $<> expressions
Matthew Wild <mwild1@gmail.com>
parents: 2521
diff changeset
    97
				else
0e1054c19f9d mod_firewall: More meta! Allow simple functions to be applied to $<> expressions
Matthew Wild <mwild1@gmail.com>
parents: 2521
diff changeset
    98
					code = "stanza.attr["..("%q"):format(attr_name).."]";
0e1054c19f9d mod_firewall: More meta! Allow simple functions to be applied to $<> expressions
Matthew Wild <mwild1@gmail.com>
parents: 2521
diff changeset
    99
				end
2528
0404476ecfe3 mod_firewall: More meta() enhancements
Matthew Wild <mwild1@gmail.com>
parents: 2524
diff changeset
   100
			elseif expr:match("^%w+#$") then
0404476ecfe3 mod_firewall: More meta() enhancements
Matthew Wild <mwild1@gmail.com>
parents: 2524
diff changeset
   101
				code = ("stanza:get_child_text(%q)"):format(expr:sub(1, -2));
2372
7e1d8c46d788 mod_firewall: Support for default values in stanza paths
Matthew Wild <mwild1@gmail.com>
parents: 2371
diff changeset
   102
			else
2528
0404476ecfe3 mod_firewall: More meta() enhancements
Matthew Wild <mwild1@gmail.com>
parents: 2524
diff changeset
   103
				code = ("stanza:find(%q)"):format(expr);
2372
7e1d8c46d788 mod_firewall: Support for default values in stanza paths
Matthew Wild <mwild1@gmail.com>
parents: 2371
diff changeset
   104
			end
2522
0e1054c19f9d mod_firewall: More meta! Allow simple functions to be applied to $<> expressions
Matthew Wild <mwild1@gmail.com>
parents: 2521
diff changeset
   105
			if func_chain then
0e1054c19f9d mod_firewall: More meta! Allow simple functions to be applied to $<> expressions
Matthew Wild <mwild1@gmail.com>
parents: 2521
diff changeset
   106
				for func_name in func_chain:gmatch("|(%w+)") do
2577
24dbad147aef mod_firewall: Fix meta functions with to/from that weren't JID-based
Matthew Wild <mwild1@gmail.com>
parents: 2566
diff changeset
   107
					-- to/from are already available in local variables, use those if possible
24dbad147aef mod_firewall: Fix meta functions with to/from that weren't JID-based
Matthew Wild <mwild1@gmail.com>
parents: 2566
diff changeset
   108
					if (code == "to" or code == "from") and func_name == "bare" then
24dbad147aef mod_firewall: Fix meta functions with to/from that weren't JID-based
Matthew Wild <mwild1@gmail.com>
parents: 2566
diff changeset
   109
						code = "bare_"..code;
24dbad147aef mod_firewall: Fix meta functions with to/from that weren't JID-based
Matthew Wild <mwild1@gmail.com>
parents: 2566
diff changeset
   110
						table.insert(deps, code);
24dbad147aef mod_firewall: Fix meta functions with to/from that weren't JID-based
Matthew Wild <mwild1@gmail.com>
parents: 2566
diff changeset
   111
					elseif (code == "to" or code == "from") and (func_name == "node" or func_name == "host" or func_name == "resource") then
24dbad147aef mod_firewall: Fix meta functions with to/from that weren't JID-based
Matthew Wild <mwild1@gmail.com>
parents: 2566
diff changeset
   112
						table.insert(deps, "split_"..code);
24dbad147aef mod_firewall: Fix meta functions with to/from that weren't JID-based
Matthew Wild <mwild1@gmail.com>
parents: 2566
diff changeset
   113
						code = code.."_"..func_name;
2522
0e1054c19f9d mod_firewall: More meta! Allow simple functions to be applied to $<> expressions
Matthew Wild <mwild1@gmail.com>
parents: 2521
diff changeset
   114
					else
0e1054c19f9d mod_firewall: More meta! Allow simple functions to be applied to $<> expressions
Matthew Wild <mwild1@gmail.com>
parents: 2521
diff changeset
   115
						assert(meta_funcs[func_name], "unknown function: "..func_name);
0e1054c19f9d mod_firewall: More meta! Allow simple functions to be applied to $<> expressions
Matthew Wild <mwild1@gmail.com>
parents: 2521
diff changeset
   116
						local new_code, new_deps = meta_funcs[func_name](code);
0e1054c19f9d mod_firewall: More meta! Allow simple functions to be applied to $<> expressions
Matthew Wild <mwild1@gmail.com>
parents: 2521
diff changeset
   117
						code = new_code;
0e1054c19f9d mod_firewall: More meta! Allow simple functions to be applied to $<> expressions
Matthew Wild <mwild1@gmail.com>
parents: 2521
diff changeset
   118
						if new_deps and #new_deps > 0 then
0e1054c19f9d mod_firewall: More meta! Allow simple functions to be applied to $<> expressions
Matthew Wild <mwild1@gmail.com>
parents: 2521
diff changeset
   119
							assert(deps, "function not supported here: "..func_name);
0e1054c19f9d mod_firewall: More meta! Allow simple functions to be applied to $<> expressions
Matthew Wild <mwild1@gmail.com>
parents: 2521
diff changeset
   120
							for _, dep in ipairs(new_deps) do
0e1054c19f9d mod_firewall: More meta! Allow simple functions to be applied to $<> expressions
Matthew Wild <mwild1@gmail.com>
parents: 2521
diff changeset
   121
								table.insert(deps, dep);
0e1054c19f9d mod_firewall: More meta! Allow simple functions to be applied to $<> expressions
Matthew Wild <mwild1@gmail.com>
parents: 2521
diff changeset
   122
							end
0e1054c19f9d mod_firewall: More meta! Allow simple functions to be applied to $<> expressions
Matthew Wild <mwild1@gmail.com>
parents: 2521
diff changeset
   123
						end
0e1054c19f9d mod_firewall: More meta! Allow simple functions to be applied to $<> expressions
Matthew Wild <mwild1@gmail.com>
parents: 2521
diff changeset
   124
					end
0e1054c19f9d mod_firewall: More meta! Allow simple functions to be applied to $<> expressions
Matthew Wild <mwild1@gmail.com>
parents: 2521
diff changeset
   125
				end
2129
edf5cf3c474b mod_firewall: Move meta() function to main module, and make it a global so libs can use it
Matthew Wild <mwild1@gmail.com>
parents: 2128
diff changeset
   126
			end
2542
a1b6a6b0aabb mod_firewall: Reinstate the ability to set a default for stanza expressions
Matthew Wild <mwild1@gmail.com>
parents: 2537
diff changeset
   127
			return "\"..tostring("..code.." or "..("%q"):format(default)..")..\"";
2129
edf5cf3c474b mod_firewall: Move meta() function to main module, and make it a global so libs can use it
Matthew Wild <mwild1@gmail.com>
parents: 2128
diff changeset
   128
		end)
edf5cf3c474b mod_firewall: Move meta() function to main module, and make it a global so libs can use it
Matthew Wild <mwild1@gmail.com>
parents: 2128
diff changeset
   129
		:gsub("$$(%a+)", extra or {})
edf5cf3c474b mod_firewall: Move meta() function to main module, and make it a global so libs can use it
Matthew Wild <mwild1@gmail.com>
parents: 2128
diff changeset
   130
		:gsub([[^""%.%.]], "")
edf5cf3c474b mod_firewall: Move meta() function to main module, and make it a global so libs can use it
Matthew Wild <mwild1@gmail.com>
parents: 2128
diff changeset
   131
		:gsub([[%.%.""$]], ""));
edf5cf3c474b mod_firewall: Move meta() function to main module, and make it a global so libs can use it
Matthew Wild <mwild1@gmail.com>
parents: 2128
diff changeset
   132
end
edf5cf3c474b mod_firewall: Move meta() function to main module, and make it a global so libs can use it
Matthew Wild <mwild1@gmail.com>
parents: 2128
diff changeset
   133
2551
eb4f45bd7fef mod_firewall: Add metaq(), like meta() but takes an unquoted string
Matthew Wild <mwild1@gmail.com>
parents: 2550
diff changeset
   134
function metaq(s, ...)
eb4f45bd7fef mod_firewall: Add metaq(), like meta() but takes an unquoted string
Matthew Wild <mwild1@gmail.com>
parents: 2550
diff changeset
   135
	return meta(("%q"):format(s), ...);
eb4f45bd7fef mod_firewall: Add metaq(), like meta() but takes an unquoted string
Matthew Wild <mwild1@gmail.com>
parents: 2550
diff changeset
   136
end
eb4f45bd7fef mod_firewall: Add metaq(), like meta() but takes an unquoted string
Matthew Wild <mwild1@gmail.com>
parents: 2550
diff changeset
   137
2550
6e4494772328 mod_firewall: Add stripslashes() function
Matthew Wild <mwild1@gmail.com>
parents: 2548
diff changeset
   138
local escape_chars = {
6e4494772328 mod_firewall: Add stripslashes() function
Matthew Wild <mwild1@gmail.com>
parents: 2548
diff changeset
   139
	a = "\a", b = "\b", f = "\f", n = "\n", r = "\r", t = "\t",
6e4494772328 mod_firewall: Add stripslashes() function
Matthew Wild <mwild1@gmail.com>
parents: 2548
diff changeset
   140
	v = "\v", ["\\"] = "\\", ["\""] = "\"", ["\'"] = "\'"
6e4494772328 mod_firewall: Add stripslashes() function
Matthew Wild <mwild1@gmail.com>
parents: 2548
diff changeset
   141
};
6e4494772328 mod_firewall: Add stripslashes() function
Matthew Wild <mwild1@gmail.com>
parents: 2548
diff changeset
   142
function stripslashes(s)
6e4494772328 mod_firewall: Add stripslashes() function
Matthew Wild <mwild1@gmail.com>
parents: 2548
diff changeset
   143
	return (s:gsub("\\(.)", escape_chars));
6e4494772328 mod_firewall: Add stripslashes() function
Matthew Wild <mwild1@gmail.com>
parents: 2548
diff changeset
   144
end
6e4494772328 mod_firewall: Add stripslashes() function
Matthew Wild <mwild1@gmail.com>
parents: 2548
diff changeset
   145
947
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   146
-- Dependency locations:
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   147
-- <type lib>
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   148
-- <type global>
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   149
-- function handler()
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   150
--   <local deps>
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   151
--   if <conditions> then
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   152
--     <actions>
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   153
--   end
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   154
-- end
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   155
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   156
local available_deps = {
1303
8a3f3f485675 mod_firewall: Produce code with nicer indentation
Florian Zeitz <florob@babelmonkeys.de>
parents: 1052
diff changeset
   157
	st = { global_code = [[local st = require "util.stanza";]]};
2548
223eea31588d mod_firewall: Add it(erators) and it_count dependencies
Matthew Wild <mwild1@gmail.com>
parents: 2547
diff changeset
   158
	it = { global_code = [[local it = require "util.iterators";]]};
223eea31588d mod_firewall: Add it(erators) and it_count dependencies
Matthew Wild <mwild1@gmail.com>
parents: 2547
diff changeset
   159
	it_count = { global_code = [[local it_count = it.count;]], depends = { "it" } };
2552
ce08a57e516b mod_firewall: Add 'current_host' variable/dependency
Matthew Wild <mwild1@gmail.com>
parents: 2551
diff changeset
   160
	current_host = { global_code = [[local current_host = module.host;]] };
947
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   161
	jid_split = {
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   162
		global_code = [[local jid_split = require "util.jid".split;]];
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   163
	};
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   164
	jid_bare = {
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   165
		global_code = [[local jid_bare = require "util.jid".bare;]];
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   166
	};
2416
9159f9166893 mod_firewall: Use the sender bare JID instead of 'to' for stanzas to self
Kim Alvefur <zash@zash.se>
parents: 2408
diff changeset
   167
	to = { local_code = [[local to = stanza.attr.to or jid_bare(session.full_jid);]]; depends = { "jid_bare" } };
947
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   168
	from = { local_code = [[local from = stanza.attr.from;]] };
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   169
	type = { local_code = [[local type = stanza.attr.type;]] };
2419
07d7036040ee mod_firewall: Insert semicolons after some statements to prevent ambiguous syntax in output (fixes #797)
Kim Alvefur <zash@zash.se>
parents: 2416
diff changeset
   170
	name = { local_code = [[local name = stanza.name;]] };
947
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   171
	split_to = { -- The stanza's split to address
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   172
		depends = { "jid_split", "to" };
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   173
		local_code = [[local to_node, to_host, to_resource = jid_split(to);]];
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   174
	};
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   175
	split_from = { -- The stanza's split from address
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   176
		depends = { "jid_split", "from" };
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   177
		local_code = [[local from_node, from_host, from_resource = jid_split(from);]];
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   178
	};
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   179
	bare_to = { depends = { "jid_bare", "to" }, local_code = "local bare_to = jid_bare(to)"};
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   180
	bare_from = { depends = { "jid_bare", "from" }, local_code = "local bare_from = jid_bare(from)"};
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   181
	group_contains = {
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   182
		global_code = [[local group_contains = module:depends("groups").group_contains]];
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   183
	};
2422
ef95853cf900 mod_firewall: More semicolons
Kim Alvefur <zash@zash.se>
parents: 2420
diff changeset
   184
	is_admin = { global_code = [[local is_admin = require "core.usermanager".is_admin;]]};
ef95853cf900 mod_firewall: More semicolons
Kim Alvefur <zash@zash.se>
parents: 2420
diff changeset
   185
	core_post_stanza = { global_code = [[local core_post_stanza = prosody.core_post_stanza;]] };
965
d4e24fb289c0 mod_firewall: Improve zone handling, make it more efficient, and support dynamic dependencies in the compiler. ENTERING and LEAVING conditions now work at expected (not matching stanzas flowing within a zone).
Matthew Wild <mwild1@gmail.com>
parents: 960
diff changeset
   186
	zone = { global_code = function (zone)
2932
b0d92332b87f mod_firewall: Add special case for $local zone (fixes #1090)
Kim Alvefur <zash@zash.se>
parents: 2898
diff changeset
   187
		local var = zone;
b0d92332b87f mod_firewall: Add special case for $local zone (fixes #1090)
Kim Alvefur <zash@zash.se>
parents: 2898
diff changeset
   188
		if var == "$local" then
b0d92332b87f mod_firewall: Add special case for $local zone (fixes #1090)
Kim Alvefur <zash@zash.se>
parents: 2898
diff changeset
   189
			var = "_local"; -- See #1090
b0d92332b87f mod_firewall: Add special case for $local zone (fixes #1090)
Kim Alvefur <zash@zash.se>
parents: 2898
diff changeset
   190
		else
b0d92332b87f mod_firewall: Add special case for $local zone (fixes #1090)
Kim Alvefur <zash@zash.se>
parents: 2898
diff changeset
   191
			assert(idsafe(var), "Invalid zone name: "..zone);
b0d92332b87f mod_firewall: Add special case for $local zone (fixes #1090)
Kim Alvefur <zash@zash.se>
parents: 2898
diff changeset
   192
		end
b0d92332b87f mod_firewall: Add special case for $local zone (fixes #1090)
Kim Alvefur <zash@zash.se>
parents: 2898
diff changeset
   193
		return ("local zone_%s = zones[%q] or {};"):format(var, zone);
965
d4e24fb289c0 mod_firewall: Improve zone handling, make it more efficient, and support dynamic dependencies in the compiler. ENTERING and LEAVING conditions now work at expected (not matching stanzas flowing within a zone).
Matthew Wild <mwild1@gmail.com>
parents: 960
diff changeset
   194
	end };
966
a65df6e97d94 mod_firewall: Add time and date deps
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   195
	date_time = { global_code = [[local os_date = os.date]]; local_code = [[local current_date_time = os_date("*t");]] };
a65df6e97d94 mod_firewall: Add time and date deps
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   196
	time = { local_code = function (what)
a65df6e97d94 mod_firewall: Add time and date deps
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   197
		local defs = {};
a65df6e97d94 mod_firewall: Add time and date deps
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   198
		for field in what:gmatch("%a+") do
a65df6e97d94 mod_firewall: Add time and date deps
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   199
			table.insert(defs, ("local current_%s = current_date_time.%s;"):format(field, field));
a65df6e97d94 mod_firewall: Add time and date deps
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   200
		end
a65df6e97d94 mod_firewall: Add time and date deps
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   201
		return table.concat(defs, " ");
a65df6e97d94 mod_firewall: Add time and date deps
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   202
	end, depends = { "date_time" }; };
2422
ef95853cf900 mod_firewall: More semicolons
Kim Alvefur <zash@zash.se>
parents: 2420
diff changeset
   203
	timestamp = { global_code = [[local get_time = require "socket".gettime;]]; local_code = [[local current_timestamp = get_time();]]; };
2132
21bc4d7cddae mod_firewall: Add support for throttling based on user-defined properties (experimental)
Matthew Wild <mwild1@gmail.com>
parents: 2130
diff changeset
   204
	globalthrottle = {
971
53e158e44a44 mod_firewall: Add rate limiting capabilities, and keep zones and throttle objects in shared tables
Matthew Wild <mwild1@gmail.com>
parents: 967
diff changeset
   205
		global_code = function (throttle)
53e158e44a44 mod_firewall: Add rate limiting capabilities, and keep zones and throttle objects in shared tables
Matthew Wild <mwild1@gmail.com>
parents: 967
diff changeset
   206
			assert(idsafe(throttle), "Invalid rate limit name: "..throttle);
999
197af8440ffb mod_firewall: Make defining objects generic (currently zones and rate limits), so more can easily be added. Also a syntax change... definition lines must begin with %
Matthew Wild <mwild1@gmail.com>
parents: 998
diff changeset
   207
			assert(active_definitions.RATE[throttle], "Unknown rate limit: "..throttle);
2132
21bc4d7cddae mod_firewall: Add support for throttling based on user-defined properties (experimental)
Matthew Wild <mwild1@gmail.com>
parents: 2130
diff changeset
   208
			return ("local global_throttle_%s = rates.%s:single();"):format(throttle, throttle);
21bc4d7cddae mod_firewall: Add support for throttling based on user-defined properties (experimental)
Matthew Wild <mwild1@gmail.com>
parents: 2130
diff changeset
   209
		end;
21bc4d7cddae mod_firewall: Add support for throttling based on user-defined properties (experimental)
Matthew Wild <mwild1@gmail.com>
parents: 2130
diff changeset
   210
	};
21bc4d7cddae mod_firewall: Add support for throttling based on user-defined properties (experimental)
Matthew Wild <mwild1@gmail.com>
parents: 2130
diff changeset
   211
	multithrottle = {
21bc4d7cddae mod_firewall: Add support for throttling based on user-defined properties (experimental)
Matthew Wild <mwild1@gmail.com>
parents: 2130
diff changeset
   212
		global_code = function (throttle)
2134
9239893a2400 mod_firewall: Don't use util.cache unless it's needed, and add explanatory error if it is not available
Matthew Wild <mwild1@gmail.com>
parents: 2132
diff changeset
   213
			assert(pcall(require, "util.cache"), "Using LIMIT with 'on' requires Prosody 0.10 or higher");
2132
21bc4d7cddae mod_firewall: Add support for throttling based on user-defined properties (experimental)
Matthew Wild <mwild1@gmail.com>
parents: 2130
diff changeset
   214
			assert(idsafe(throttle), "Invalid rate limit name: "..throttle);
21bc4d7cddae mod_firewall: Add support for throttling based on user-defined properties (experimental)
Matthew Wild <mwild1@gmail.com>
parents: 2130
diff changeset
   215
			assert(active_definitions.RATE[throttle], "Unknown rate limit: "..throttle);
21bc4d7cddae mod_firewall: Add support for throttling based on user-defined properties (experimental)
Matthew Wild <mwild1@gmail.com>
parents: 2130
diff changeset
   216
			return ("local multi_throttle_%s = rates.%s:multi();"):format(throttle, throttle);
971
53e158e44a44 mod_firewall: Add rate limiting capabilities, and keep zones and throttle objects in shared tables
Matthew Wild <mwild1@gmail.com>
parents: 967
diff changeset
   217
		end;
53e158e44a44 mod_firewall: Add rate limiting capabilities, and keep zones and throttle objects in shared tables
Matthew Wild <mwild1@gmail.com>
parents: 967
diff changeset
   218
	};
2406
2040330586e4 mod_firewall: Split import of rostermanager into its own dependency
Kim Alvefur <zash@zash.se>
parents: 2389
diff changeset
   219
	rostermanager = {
2040330586e4 mod_firewall: Split import of rostermanager into its own dependency
Kim Alvefur <zash@zash.se>
parents: 2389
diff changeset
   220
		global_code = [[local rostermanager = require "core.rostermanager";]];
2040330586e4 mod_firewall: Split import of rostermanager into its own dependency
Kim Alvefur <zash@zash.se>
parents: 2389
diff changeset
   221
	};
2346
6848297cf40a mod_firewall: Add conditions for testing whether a sender of a stanza is in the recipient's roster (or in a certain roster group)
Matthew Wild <mwild1@gmail.com>
parents: 2134
diff changeset
   222
	roster_entry = {
2420
ade918cd9ca7 mod_firewall: Only call rostermanager if username is available (fixes #796)
Kim Alvefur <zash@zash.se>
parents: 2419
diff changeset
   223
		local_code = [[local roster_entry = (to_node and rostermanager.load_roster(to_node, to_host) or {})[bare_from];]];
2406
2040330586e4 mod_firewall: Split import of rostermanager into its own dependency
Kim Alvefur <zash@zash.se>
parents: 2389
diff changeset
   224
		depends = { "rostermanager", "split_to", "bare_from" };
2040330586e4 mod_firewall: Split import of rostermanager into its own dependency
Kim Alvefur <zash@zash.se>
parents: 2389
diff changeset
   225
	};
2524
c6fd8975704b mod_firewall: Initial support for lists, in-memory and HTTP
Matthew Wild <mwild1@gmail.com>
parents: 2522
diff changeset
   226
	list = { global_code = function (list)
c6fd8975704b mod_firewall: Initial support for lists, in-memory and HTTP
Matthew Wild <mwild1@gmail.com>
parents: 2522
diff changeset
   227
			assert(idsafe(list), "Invalid list name: "..list);
c6fd8975704b mod_firewall: Initial support for lists, in-memory and HTTP
Matthew Wild <mwild1@gmail.com>
parents: 2522
diff changeset
   228
			assert(active_definitions.LIST[list], "Unknown list: "..list);
c6fd8975704b mod_firewall: Initial support for lists, in-memory and HTTP
Matthew Wild <mwild1@gmail.com>
parents: 2522
diff changeset
   229
			return ("local list_%s = lists[%q];"):format(list, list);
c6fd8975704b mod_firewall: Initial support for lists, in-memory and HTTP
Matthew Wild <mwild1@gmail.com>
parents: 2522
diff changeset
   230
		end
c6fd8975704b mod_firewall: Initial support for lists, in-memory and HTTP
Matthew Wild <mwild1@gmail.com>
parents: 2522
diff changeset
   231
	};
2532
44a71584521d mod_firewall: Add SEARCH, PATTERN definitions and SCAN condition to check tokenized stanza:find() against a list
Matthew Wild <mwild1@gmail.com>
parents: 2531
diff changeset
   232
	search = {
44a71584521d mod_firewall: Add SEARCH, PATTERN definitions and SCAN condition to check tokenized stanza:find() against a list
Matthew Wild <mwild1@gmail.com>
parents: 2531
diff changeset
   233
		local_code = function (search_name)
44a71584521d mod_firewall: Add SEARCH, PATTERN definitions and SCAN condition to check tokenized stanza:find() against a list
Matthew Wild <mwild1@gmail.com>
parents: 2531
diff changeset
   234
			local search_path = assert(active_definitions.SEARCH[search_name], "Undefined search path: "..search_name);
44a71584521d mod_firewall: Add SEARCH, PATTERN definitions and SCAN condition to check tokenized stanza:find() against a list
Matthew Wild <mwild1@gmail.com>
parents: 2531
diff changeset
   235
			return ("local search_%s = tostring(stanza:find(%q) or \"\")"):format(search_name, search_path);
44a71584521d mod_firewall: Add SEARCH, PATTERN definitions and SCAN condition to check tokenized stanza:find() against a list
Matthew Wild <mwild1@gmail.com>
parents: 2531
diff changeset
   236
		end;
44a71584521d mod_firewall: Add SEARCH, PATTERN definitions and SCAN condition to check tokenized stanza:find() against a list
Matthew Wild <mwild1@gmail.com>
parents: 2531
diff changeset
   237
	};
2547
3c16f0a8d66c mod_firewall: Do patterns properly, instead of cheating
Matthew Wild <mwild1@gmail.com>
parents: 2543
diff changeset
   238
	pattern = {
3c16f0a8d66c mod_firewall: Do patterns properly, instead of cheating
Matthew Wild <mwild1@gmail.com>
parents: 2543
diff changeset
   239
		local_code = function (pattern_name)
3c16f0a8d66c mod_firewall: Do patterns properly, instead of cheating
Matthew Wild <mwild1@gmail.com>
parents: 2543
diff changeset
   240
			local pattern = assert(active_definitions.PATTERN[pattern_name], "Undefined pattern: "..pattern_name);
3c16f0a8d66c mod_firewall: Do patterns properly, instead of cheating
Matthew Wild <mwild1@gmail.com>
parents: 2543
diff changeset
   241
			return ("local pattern_%s = %q"):format(pattern_name, pattern);
3c16f0a8d66c mod_firewall: Do patterns properly, instead of cheating
Matthew Wild <mwild1@gmail.com>
parents: 2543
diff changeset
   242
		end;
3c16f0a8d66c mod_firewall: Do patterns properly, instead of cheating
Matthew Wild <mwild1@gmail.com>
parents: 2543
diff changeset
   243
	};
2532
44a71584521d mod_firewall: Add SEARCH, PATTERN definitions and SCAN condition to check tokenized stanza:find() against a list
Matthew Wild <mwild1@gmail.com>
parents: 2531
diff changeset
   244
	tokens = {
44a71584521d mod_firewall: Add SEARCH, PATTERN definitions and SCAN condition to check tokenized stanza:find() against a list
Matthew Wild <mwild1@gmail.com>
parents: 2531
diff changeset
   245
		local_code = function (search_and_pattern)
2588
d64fc9c3cffd mod_firewall: Remove ambiguity from tokens dep parameter
Matthew Wild <mwild1@gmail.com>
parents: 2587
diff changeset
   246
			local search_name, pattern_name = search_and_pattern:match("^([^%-]+)-(.+)$");
2532
44a71584521d mod_firewall: Add SEARCH, PATTERN definitions and SCAN condition to check tokenized stanza:find() against a list
Matthew Wild <mwild1@gmail.com>
parents: 2531
diff changeset
   247
			local code = ([[local tokens_%s_%s = {};
44a71584521d mod_firewall: Add SEARCH, PATTERN definitions and SCAN condition to check tokenized stanza:find() against a list
Matthew Wild <mwild1@gmail.com>
parents: 2531
diff changeset
   248
			if search_%s then
2547
3c16f0a8d66c mod_firewall: Do patterns properly, instead of cheating
Matthew Wild <mwild1@gmail.com>
parents: 2543
diff changeset
   249
				for s in search_%s:gmatch(pattern_%s) do
2532
44a71584521d mod_firewall: Add SEARCH, PATTERN definitions and SCAN condition to check tokenized stanza:find() against a list
Matthew Wild <mwild1@gmail.com>
parents: 2531
diff changeset
   250
					tokens_%s_%s[s] = true;
44a71584521d mod_firewall: Add SEARCH, PATTERN definitions and SCAN condition to check tokenized stanza:find() against a list
Matthew Wild <mwild1@gmail.com>
parents: 2531
diff changeset
   251
				end
44a71584521d mod_firewall: Add SEARCH, PATTERN definitions and SCAN condition to check tokenized stanza:find() against a list
Matthew Wild <mwild1@gmail.com>
parents: 2531
diff changeset
   252
			end
44a71584521d mod_firewall: Add SEARCH, PATTERN definitions and SCAN condition to check tokenized stanza:find() against a list
Matthew Wild <mwild1@gmail.com>
parents: 2531
diff changeset
   253
			]]):format(search_name, pattern_name, search_name, search_name, pattern_name, search_name, pattern_name);
2547
3c16f0a8d66c mod_firewall: Do patterns properly, instead of cheating
Matthew Wild <mwild1@gmail.com>
parents: 2543
diff changeset
   254
			return code, { "search:"..search_name, "pattern:"..pattern_name };
2532
44a71584521d mod_firewall: Add SEARCH, PATTERN definitions and SCAN condition to check tokenized stanza:find() against a list
Matthew Wild <mwild1@gmail.com>
parents: 2531
diff changeset
   255
		end;
44a71584521d mod_firewall: Add SEARCH, PATTERN definitions and SCAN condition to check tokenized stanza:find() against a list
Matthew Wild <mwild1@gmail.com>
parents: 2531
diff changeset
   256
	};
44a71584521d mod_firewall: Add SEARCH, PATTERN definitions and SCAN condition to check tokenized stanza:find() against a list
Matthew Wild <mwild1@gmail.com>
parents: 2531
diff changeset
   257
	scan_list = {
2537
9aed7f4e9f07 mod_firewall: Fix scan_list() syntax error in generated code
Matthew Wild <mwild1@gmail.com>
parents: 2532
diff changeset
   258
		global_code = [[local function scan_list(list, items) for item in pairs(items) do if list:contains(item) then return true; end end end]];
2532
44a71584521d mod_firewall: Add SEARCH, PATTERN definitions and SCAN condition to check tokenized stanza:find() against a list
Matthew Wild <mwild1@gmail.com>
parents: 2531
diff changeset
   259
	}
947
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   260
};
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   261
2081
368b091e723b mod_firewall: Rename argument to avoid name clash [luacheck]
Kim Alvefur <zash@zash.se>
parents: 2080
diff changeset
   262
local function include_dep(dependency, code)
368b091e723b mod_firewall: Rename argument to avoid name clash [luacheck]
Kim Alvefur <zash@zash.se>
parents: 2080
diff changeset
   263
	local dep, dep_param = dependency:match("^([^:]+):?(.*)$");
947
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   264
	local dep_info = available_deps[dep];
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   265
	if not dep_info then
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   266
		module:log("error", "Dependency not found: %s", dep);
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   267
		return;
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   268
	end
2587
b6b10f57aa56 mod_firewall: Fix for including the same dependency with different parameters
Matthew Wild <mwild1@gmail.com>
parents: 2584
diff changeset
   269
	if code.included_deps[dependency] ~= nil then
b6b10f57aa56 mod_firewall: Fix for including the same dependency with different parameters
Matthew Wild <mwild1@gmail.com>
parents: 2584
diff changeset
   270
		if code.included_deps[dependency] ~= true then
947
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   271
			module:log("error", "Circular dependency on %s", dep);
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   272
		end
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   273
		return;
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   274
	end
2587
b6b10f57aa56 mod_firewall: Fix for including the same dependency with different parameters
Matthew Wild <mwild1@gmail.com>
parents: 2584
diff changeset
   275
	code.included_deps[dependency] = false; -- Pending flag (used to detect circular references)
947
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   276
	for _, dep_dep in ipairs(dep_info.depends or {}) do
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   277
		include_dep(dep_dep, code);
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   278
	end
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   279
	if dep_info.global_code then
965
d4e24fb289c0 mod_firewall: Improve zone handling, make it more efficient, and support dynamic dependencies in the compiler. ENTERING and LEAVING conditions now work at expected (not matching stanzas flowing within a zone).
Matthew Wild <mwild1@gmail.com>
parents: 960
diff changeset
   280
		if dep_param ~= "" then
2529
a35d85cfda92 mod_firewall: Fix for deps dynamically including deps
Matthew Wild <mwild1@gmail.com>
parents: 2528
diff changeset
   281
			local global_code, deps = dep_info.global_code(dep_param);
a35d85cfda92 mod_firewall: Fix for deps dynamically including deps
Matthew Wild <mwild1@gmail.com>
parents: 2528
diff changeset
   282
			if deps then
2566
78efd064aef3 mod_firewall: Rename variables to avoid shadowing #luacheck
Matthew Wild <mwild1@gmail.com>
parents: 2565
diff changeset
   283
				for _, dep_dep in ipairs(deps) do
78efd064aef3 mod_firewall: Rename variables to avoid shadowing #luacheck
Matthew Wild <mwild1@gmail.com>
parents: 2565
diff changeset
   284
					include_dep(dep_dep, code);
2529
a35d85cfda92 mod_firewall: Fix for deps dynamically including deps
Matthew Wild <mwild1@gmail.com>
parents: 2528
diff changeset
   285
				end
a35d85cfda92 mod_firewall: Fix for deps dynamically including deps
Matthew Wild <mwild1@gmail.com>
parents: 2528
diff changeset
   286
			end
a35d85cfda92 mod_firewall: Fix for deps dynamically including deps
Matthew Wild <mwild1@gmail.com>
parents: 2528
diff changeset
   287
			table.insert(code.global_header, global_code);
965
d4e24fb289c0 mod_firewall: Improve zone handling, make it more efficient, and support dynamic dependencies in the compiler. ENTERING and LEAVING conditions now work at expected (not matching stanzas flowing within a zone).
Matthew Wild <mwild1@gmail.com>
parents: 960
diff changeset
   288
		else
d4e24fb289c0 mod_firewall: Improve zone handling, make it more efficient, and support dynamic dependencies in the compiler. ENTERING and LEAVING conditions now work at expected (not matching stanzas flowing within a zone).
Matthew Wild <mwild1@gmail.com>
parents: 960
diff changeset
   289
			table.insert(code.global_header, dep_info.global_code);
d4e24fb289c0 mod_firewall: Improve zone handling, make it more efficient, and support dynamic dependencies in the compiler. ENTERING and LEAVING conditions now work at expected (not matching stanzas flowing within a zone).
Matthew Wild <mwild1@gmail.com>
parents: 960
diff changeset
   290
		end
947
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   291
	end
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   292
	if dep_info.local_code then
965
d4e24fb289c0 mod_firewall: Improve zone handling, make it more efficient, and support dynamic dependencies in the compiler. ENTERING and LEAVING conditions now work at expected (not matching stanzas flowing within a zone).
Matthew Wild <mwild1@gmail.com>
parents: 960
diff changeset
   293
		if dep_param ~= "" then
2529
a35d85cfda92 mod_firewall: Fix for deps dynamically including deps
Matthew Wild <mwild1@gmail.com>
parents: 2528
diff changeset
   294
			local local_code, deps = dep_info.local_code(dep_param);
a35d85cfda92 mod_firewall: Fix for deps dynamically including deps
Matthew Wild <mwild1@gmail.com>
parents: 2528
diff changeset
   295
			if deps then
2566
78efd064aef3 mod_firewall: Rename variables to avoid shadowing #luacheck
Matthew Wild <mwild1@gmail.com>
parents: 2565
diff changeset
   296
				for _, dep_dep in ipairs(deps) do
78efd064aef3 mod_firewall: Rename variables to avoid shadowing #luacheck
Matthew Wild <mwild1@gmail.com>
parents: 2565
diff changeset
   297
					include_dep(dep_dep, code);
2529
a35d85cfda92 mod_firewall: Fix for deps dynamically including deps
Matthew Wild <mwild1@gmail.com>
parents: 2528
diff changeset
   298
				end
a35d85cfda92 mod_firewall: Fix for deps dynamically including deps
Matthew Wild <mwild1@gmail.com>
parents: 2528
diff changeset
   299
			end
a35d85cfda92 mod_firewall: Fix for deps dynamically including deps
Matthew Wild <mwild1@gmail.com>
parents: 2528
diff changeset
   300
			table.insert(code, "\n\t\t-- "..dep.."\n\t\t"..local_code.."\n");
965
d4e24fb289c0 mod_firewall: Improve zone handling, make it more efficient, and support dynamic dependencies in the compiler. ENTERING and LEAVING conditions now work at expected (not matching stanzas flowing within a zone).
Matthew Wild <mwild1@gmail.com>
parents: 960
diff changeset
   301
		else
1303
8a3f3f485675 mod_firewall: Produce code with nicer indentation
Florian Zeitz <florob@babelmonkeys.de>
parents: 1052
diff changeset
   302
			table.insert(code, "\n\t\t-- "..dep.."\n\t\t"..dep_info.local_code.."\n");
965
d4e24fb289c0 mod_firewall: Improve zone handling, make it more efficient, and support dynamic dependencies in the compiler. ENTERING and LEAVING conditions now work at expected (not matching stanzas flowing within a zone).
Matthew Wild <mwild1@gmail.com>
parents: 960
diff changeset
   303
		end
947
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   304
	end
2587
b6b10f57aa56 mod_firewall: Fix for including the same dependency with different parameters
Matthew Wild <mwild1@gmail.com>
parents: 2584
diff changeset
   305
	code.included_deps[dependency] = true;
947
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   306
end
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   307
999
197af8440ffb mod_firewall: Make defining objects generic (currently zones and rate limits), so more can easily be added. Also a syntax change... definition lines must begin with %
Matthew Wild <mwild1@gmail.com>
parents: 998
diff changeset
   308
local definition_handlers = module:require("definitions");
947
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   309
local condition_handlers = module:require("conditions");
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   310
local action_handlers = module:require("actions");
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   311
2898
165d2877eeac mod_firewall: Add experimental user-centric persistent marks behind a feature flag
Kim Alvefur <zash@zash.se>
parents: 2863
diff changeset
   312
if module:get_option_boolean("firewall_experimental_user_marks", false) then
165d2877eeac mod_firewall: Add experimental user-centric persistent marks behind a feature flag
Kim Alvefur <zash@zash.se>
parents: 2863
diff changeset
   313
	module:require"marks";
165d2877eeac mod_firewall: Add experimental user-centric persistent marks behind a feature flag
Kim Alvefur <zash@zash.se>
parents: 2863
diff changeset
   314
end
165d2877eeac mod_firewall: Add experimental user-centric persistent marks behind a feature flag
Kim Alvefur <zash@zash.se>
parents: 2863
diff changeset
   315
947
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   316
local function new_rule(ruleset, chain)
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   317
	assert(chain, "no chain specified");
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   318
	local rule = { conditions = {}, actions = {}, deps = {} };
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   319
	table.insert(ruleset[chain], rule);
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   320
	return rule;
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   321
end
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   322
2082
11539785cb92 mod_firewall: Split compile function into two parts in order to separate their scopes
Kim Alvefur <zash@zash.se>
parents: 2081
diff changeset
   323
local function parse_firewall_rules(filename)
947
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   324
	local line_no = 0;
1343
7dbde05b48a9 all the things: Remove trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents: 1325
diff changeset
   325
956
33d6642f4db7 mod_firewall: Tighten up error handling, and split rules->Lua and Lua->bytecode compilation into separate functions
Matthew Wild <mwild1@gmail.com>
parents: 955
diff changeset
   326
	local function errmsg(err)
33d6642f4db7 mod_firewall: Tighten up error handling, and split rules->Lua and Lua->bytecode compilation into separate functions
Matthew Wild <mwild1@gmail.com>
parents: 955
diff changeset
   327
		return "Error compiling "..filename.." on line "..line_no..": "..err;
33d6642f4db7 mod_firewall: Tighten up error handling, and split rules->Lua and Lua->bytecode compilation into separate functions
Matthew Wild <mwild1@gmail.com>
parents: 955
diff changeset
   328
	end
1343
7dbde05b48a9 all the things: Remove trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents: 1325
diff changeset
   329
947
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   330
	local ruleset = {
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   331
		deliver = {};
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   332
	};
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   333
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   334
	local chain = "deliver"; -- Default chain
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   335
	local rule;
1343
7dbde05b48a9 all the things: Remove trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents: 1325
diff changeset
   336
947
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   337
	local file, err = io.open(filename);
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   338
	if not file then return nil, err; end
1343
7dbde05b48a9 all the things: Remove trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents: 1325
diff changeset
   339
947
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   340
	local state; -- nil -> "rules" -> "actions" -> nil -> ...
1343
7dbde05b48a9 all the things: Remove trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents: 1325
diff changeset
   341
947
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   342
	local line_hold;
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   343
	for line in file:lines() do
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   344
		line = line:match("^%s*(.-)%s*$");
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   345
		if line_hold and line:sub(-1,-1) ~= "\\" then
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   346
			line = line_hold..line;
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   347
			line_hold = nil;
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   348
		elseif line:sub(-1,-1) == "\\" then
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   349
			line_hold = (line_hold or "")..line:sub(1,-2);
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   350
		end
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   351
		line_no = line_no + 1;
1343
7dbde05b48a9 all the things: Remove trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents: 1325
diff changeset
   352
2084
a435db77a5e5 mod_firewall: Silence warning about empty if branch [luacheck]
Kim Alvefur <zash@zash.se>
parents: 2082
diff changeset
   353
		if line_hold or line:find("^[#;]") then -- luacheck: ignore 542
947
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   354
			-- No action; comment or partial line
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   355
		elseif line == "" then
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   356
			if state == "rules" then
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   357
				return nil, ("Expected an action on line %d for preceding criteria")
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   358
					:format(line_no);
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   359
			end
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   360
			state = nil;
2074
2356114ff505 mod_firewall: Optimize string match operations, string.find is faster than .match since no string is returned
Kim Alvefur <zash@zash.se>
parents: 1343
diff changeset
   361
		elseif not(state) and line:sub(1, 2) == "::" then
947
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   362
			chain = line:gsub("^::%s*", "");
980
aeb11522a44f mod_firewall: Fix variable name
Kim Alvefur <zash@zash.se>
parents: 971
diff changeset
   363
			local chain_info = chains[chain];
956
33d6642f4db7 mod_firewall: Tighten up error handling, and split rules->Lua and Lua->bytecode compilation into separate functions
Matthew Wild <mwild1@gmail.com>
parents: 955
diff changeset
   364
			if not chain_info then
2368
17d236129118 mod_firewall: Allow implicit defitions of chains in scripts if they begin with 'user/'
Matthew Wild <mwild1@gmail.com>
parents: 2346
diff changeset
   365
				if chain:match("^user/") then
2562
2b533a7b5236 mod_firewall: Make PASS bubble up through all chains, and add DEFAULT and RETURN
Matthew Wild <mwild1@gmail.com>
parents: 2554
diff changeset
   366
					chains[chain] = { type = "event", priority = 1, pass_return = false };
2368
17d236129118 mod_firewall: Allow implicit defitions of chains in scripts if they begin with 'user/'
Matthew Wild <mwild1@gmail.com>
parents: 2346
diff changeset
   367
				else
17d236129118 mod_firewall: Allow implicit defitions of chains in scripts if they begin with 'user/'
Matthew Wild <mwild1@gmail.com>
parents: 2346
diff changeset
   368
					return nil, errmsg("Unknown chain: "..chain);
17d236129118 mod_firewall: Allow implicit defitions of chains in scripts if they begin with 'user/'
Matthew Wild <mwild1@gmail.com>
parents: 2346
diff changeset
   369
				end
956
33d6642f4db7 mod_firewall: Tighten up error handling, and split rules->Lua and Lua->bytecode compilation into separate functions
Matthew Wild <mwild1@gmail.com>
parents: 955
diff changeset
   370
			elseif chain_info.type ~= "event" then
33d6642f4db7 mod_firewall: Tighten up error handling, and split rules->Lua and Lua->bytecode compilation into separate functions
Matthew Wild <mwild1@gmail.com>
parents: 955
diff changeset
   371
				return nil, errmsg("Only event chains supported at the moment");
33d6642f4db7 mod_firewall: Tighten up error handling, and split rules->Lua and Lua->bytecode compilation into separate functions
Matthew Wild <mwild1@gmail.com>
parents: 955
diff changeset
   372
			end
947
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   373
			ruleset[chain] = ruleset[chain] or {};
2074
2356114ff505 mod_firewall: Optimize string match operations, string.find is faster than .match since no string is returned
Kim Alvefur <zash@zash.se>
parents: 1343
diff changeset
   374
		elseif not(state) and line:sub(1,1) == "%" then -- Definition (zone, limit, etc.)
999
197af8440ffb mod_firewall: Make defining objects generic (currently zones and rate limits), so more can easily be added. Also a syntax change... definition lines must begin with %
Matthew Wild <mwild1@gmail.com>
parents: 998
diff changeset
   375
			local what, name = line:match("^%%%s*(%w+) +([^ :]+)");
197af8440ffb mod_firewall: Make defining objects generic (currently zones and rate limits), so more can easily be added. Also a syntax change... definition lines must begin with %
Matthew Wild <mwild1@gmail.com>
parents: 998
diff changeset
   376
			if not definition_handlers[what] then
197af8440ffb mod_firewall: Make defining objects generic (currently zones and rate limits), so more can easily be added. Also a syntax change... definition lines must begin with %
Matthew Wild <mwild1@gmail.com>
parents: 998
diff changeset
   377
				return nil, errmsg("Definition of unknown object: "..what);
197af8440ffb mod_firewall: Make defining objects generic (currently zones and rate limits), so more can easily be added. Also a syntax change... definition lines must begin with %
Matthew Wild <mwild1@gmail.com>
parents: 998
diff changeset
   378
			elseif not name or not idsafe(name) then
197af8440ffb mod_firewall: Make defining objects generic (currently zones and rate limits), so more can easily be added. Also a syntax change... definition lines must begin with %
Matthew Wild <mwild1@gmail.com>
parents: 998
diff changeset
   379
				return nil, errmsg("Invalid "..what.." name");
947
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   380
			end
999
197af8440ffb mod_firewall: Make defining objects generic (currently zones and rate limits), so more can easily be added. Also a syntax change... definition lines must begin with %
Matthew Wild <mwild1@gmail.com>
parents: 998
diff changeset
   381
197af8440ffb mod_firewall: Make defining objects generic (currently zones and rate limits), so more can easily be added. Also a syntax change... definition lines must begin with %
Matthew Wild <mwild1@gmail.com>
parents: 998
diff changeset
   382
			local val = line:match(": ?(.*)$");
2074
2356114ff505 mod_firewall: Optimize string match operations, string.find is faster than .match since no string is returned
Kim Alvefur <zash@zash.se>
parents: 1343
diff changeset
   383
			if not val and line:find(":<") then -- Read from file
999
197af8440ffb mod_firewall: Make defining objects generic (currently zones and rate limits), so more can easily be added. Also a syntax change... definition lines must begin with %
Matthew Wild <mwild1@gmail.com>
parents: 998
diff changeset
   384
				local fn = line:match(":< ?(.-)%s*$");
197af8440ffb mod_firewall: Make defining objects generic (currently zones and rate limits), so more can easily be added. Also a syntax change... definition lines must begin with %
Matthew Wild <mwild1@gmail.com>
parents: 998
diff changeset
   385
				if not fn then
197af8440ffb mod_firewall: Make defining objects generic (currently zones and rate limits), so more can easily be added. Also a syntax change... definition lines must begin with %
Matthew Wild <mwild1@gmail.com>
parents: 998
diff changeset
   386
					return nil, errmsg("Unable to parse filename");
197af8440ffb mod_firewall: Make defining objects generic (currently zones and rate limits), so more can easily be added. Also a syntax change... definition lines must begin with %
Matthew Wild <mwild1@gmail.com>
parents: 998
diff changeset
   387
				end
197af8440ffb mod_firewall: Make defining objects generic (currently zones and rate limits), so more can easily be added. Also a syntax change... definition lines must begin with %
Matthew Wild <mwild1@gmail.com>
parents: 998
diff changeset
   388
				local f, err = io.open(fn);
197af8440ffb mod_firewall: Make defining objects generic (currently zones and rate limits), so more can easily be added. Also a syntax change... definition lines must begin with %
Matthew Wild <mwild1@gmail.com>
parents: 998
diff changeset
   389
				if not f then return nil, errmsg(err); end
2530
b2fc41001c8e mod_firewall: Fix pattern
Matthew Wild <mwild1@gmail.com>
parents: 2529
diff changeset
   390
				val = f:read("*a"):gsub("\r?\n", " "):gsub("%s+$", "");
999
197af8440ffb mod_firewall: Make defining objects generic (currently zones and rate limits), so more can easily be added. Also a syntax change... definition lines must begin with %
Matthew Wild <mwild1@gmail.com>
parents: 998
diff changeset
   391
			end
197af8440ffb mod_firewall: Make defining objects generic (currently zones and rate limits), so more can easily be added. Also a syntax change... definition lines must begin with %
Matthew Wild <mwild1@gmail.com>
parents: 998
diff changeset
   392
			if not val then
197af8440ffb mod_firewall: Make defining objects generic (currently zones and rate limits), so more can easily be added. Also a syntax change... definition lines must begin with %
Matthew Wild <mwild1@gmail.com>
parents: 998
diff changeset
   393
				return nil, errmsg("No value given for definition");
197af8440ffb mod_firewall: Make defining objects generic (currently zones and rate limits), so more can easily be added. Also a syntax change... definition lines must begin with %
Matthew Wild <mwild1@gmail.com>
parents: 998
diff changeset
   394
			end
2554
19a182651a9b mod_firewall: Allow backslash escapes in definitions
Matthew Wild <mwild1@gmail.com>
parents: 2553
diff changeset
   395
			val = stripslashes(val);
999
197af8440ffb mod_firewall: Make defining objects generic (currently zones and rate limits), so more can easily be added. Also a syntax change... definition lines must begin with %
Matthew Wild <mwild1@gmail.com>
parents: 998
diff changeset
   396
			local ok, ret = pcall(definition_handlers[what], name, val);
197af8440ffb mod_firewall: Make defining objects generic (currently zones and rate limits), so more can easily be added. Also a syntax change... definition lines must begin with %
Matthew Wild <mwild1@gmail.com>
parents: 998
diff changeset
   397
			if not ok then
197af8440ffb mod_firewall: Make defining objects generic (currently zones and rate limits), so more can easily be added. Also a syntax change... definition lines must begin with %
Matthew Wild <mwild1@gmail.com>
parents: 998
diff changeset
   398
				return nil, errmsg(ret);
197af8440ffb mod_firewall: Make defining objects generic (currently zones and rate limits), so more can easily be added. Also a syntax change... definition lines must begin with %
Matthew Wild <mwild1@gmail.com>
parents: 998
diff changeset
   399
			end
197af8440ffb mod_firewall: Make defining objects generic (currently zones and rate limits), so more can easily be added. Also a syntax change... definition lines must begin with %
Matthew Wild <mwild1@gmail.com>
parents: 998
diff changeset
   400
197af8440ffb mod_firewall: Make defining objects generic (currently zones and rate limits), so more can easily be added. Also a syntax change... definition lines must begin with %
Matthew Wild <mwild1@gmail.com>
parents: 998
diff changeset
   401
			if not active_definitions[what] then
197af8440ffb mod_firewall: Make defining objects generic (currently zones and rate limits), so more can easily be added. Also a syntax change... definition lines must begin with %
Matthew Wild <mwild1@gmail.com>
parents: 998
diff changeset
   402
				active_definitions[what] = {};
197af8440ffb mod_firewall: Make defining objects generic (currently zones and rate limits), so more can easily be added. Also a syntax change... definition lines must begin with %
Matthew Wild <mwild1@gmail.com>
parents: 998
diff changeset
   403
			end
197af8440ffb mod_firewall: Make defining objects generic (currently zones and rate limits), so more can easily be added. Also a syntax change... definition lines must begin with %
Matthew Wild <mwild1@gmail.com>
parents: 998
diff changeset
   404
			active_definitions[what][name] = ret;
2543
1510b66a43fc mod_firewall: Allow using spaces instead of underscores in actions, as well as conditions
Matthew Wild <mwild1@gmail.com>
parents: 2542
diff changeset
   405
		elseif line:find("^[%w_ ]+[%.=]") then
947
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   406
			-- Action
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   407
			if state == nil then
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   408
				-- This is a standalone action with no conditions
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   409
				rule = new_rule(ruleset, chain);
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   410
			end
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   411
			state = "actions";
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   412
			-- Action handlers?
2543
1510b66a43fc mod_firewall: Allow using spaces instead of underscores in actions, as well as conditions
Matthew Wild <mwild1@gmail.com>
parents: 2542
diff changeset
   413
			local action = line:match("^[%w_ ]+"):upper():gsub(" ", "_");
947
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   414
			if not action_handlers[action] then
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   415
				return nil, ("Unknown action on line %d: %s"):format(line_no, action or "<unknown>");
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   416
			end
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   417
			table.insert(rule.actions, "-- "..line)
956
33d6642f4db7 mod_firewall: Tighten up error handling, and split rules->Lua and Lua->bytecode compilation into separate functions
Matthew Wild <mwild1@gmail.com>
parents: 955
diff changeset
   418
			local ok, action_string, action_deps = pcall(action_handlers[action], line:match("=(.+)$"));
33d6642f4db7 mod_firewall: Tighten up error handling, and split rules->Lua and Lua->bytecode compilation into separate functions
Matthew Wild <mwild1@gmail.com>
parents: 955
diff changeset
   419
			if not ok then
33d6642f4db7 mod_firewall: Tighten up error handling, and split rules->Lua and Lua->bytecode compilation into separate functions
Matthew Wild <mwild1@gmail.com>
parents: 955
diff changeset
   420
				return nil, errmsg(action_string);
33d6642f4db7 mod_firewall: Tighten up error handling, and split rules->Lua and Lua->bytecode compilation into separate functions
Matthew Wild <mwild1@gmail.com>
parents: 955
diff changeset
   421
			end
947
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   422
			table.insert(rule.actions, action_string);
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   423
			for _, dep in ipairs(action_deps or {}) do
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   424
				table.insert(rule.deps, dep);
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   425
			end
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   426
		elseif state == "actions" then -- state is actions but action pattern did not match
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   427
			state = nil; -- Awaiting next rule, etc.
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   428
			table.insert(ruleset[chain], rule);
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   429
			rule = nil;
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   430
		else
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   431
			if not state then
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   432
				state = "rules";
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   433
				rule = new_rule(ruleset, chain);
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   434
			end
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   435
			-- Check standard modifiers for the condition (e.g. NOT)
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   436
			local negated;
2408
9af2d36567a8 mod_firewall: Allow conditions to end with a question mark
Kim Alvefur <zash@zash.se>
parents: 2406
diff changeset
   437
			local condition = line:match("^[^:=%.?]*");
2074
2356114ff505 mod_firewall: Optimize string match operations, string.find is faster than .match since no string is returned
Kim Alvefur <zash@zash.se>
parents: 1343
diff changeset
   438
			if condition:find("%f[%w]NOT%f[^%w]") then
947
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   439
				local s, e = condition:match("%f[%w]()NOT()%f[^%w]");
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   440
				condition = (condition:sub(1,s-1)..condition:sub(e+1, -1)):match("^%s*(.-)%s*$");
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   441
				negated = true;
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   442
			end
998
6fdcebbd2284 mod_firewall: Fix conditions with spaces
Matthew Wild <mwild1@gmail.com>
parents: 996
diff changeset
   443
			condition = condition:gsub(" ", "_");
947
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   444
			if not condition_handlers[condition] then
998
6fdcebbd2284 mod_firewall: Fix conditions with spaces
Matthew Wild <mwild1@gmail.com>
parents: 996
diff changeset
   445
				return nil, ("Unknown condition on line %d: %s"):format(line_no, (condition:gsub("_", " ")));
947
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   446
			end
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   447
			-- Get the code for this condition
956
33d6642f4db7 mod_firewall: Tighten up error handling, and split rules->Lua and Lua->bytecode compilation into separate functions
Matthew Wild <mwild1@gmail.com>
parents: 955
diff changeset
   448
			local ok, condition_code, condition_deps = pcall(condition_handlers[condition], line:match(":%s?(.+)$"));
33d6642f4db7 mod_firewall: Tighten up error handling, and split rules->Lua and Lua->bytecode compilation into separate functions
Matthew Wild <mwild1@gmail.com>
parents: 955
diff changeset
   449
			if not ok then
33d6642f4db7 mod_firewall: Tighten up error handling, and split rules->Lua and Lua->bytecode compilation into separate functions
Matthew Wild <mwild1@gmail.com>
parents: 955
diff changeset
   450
				return nil, errmsg(condition_code);
33d6642f4db7 mod_firewall: Tighten up error handling, and split rules->Lua and Lua->bytecode compilation into separate functions
Matthew Wild <mwild1@gmail.com>
parents: 955
diff changeset
   451
			end
947
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   452
			if negated then condition_code = "not("..condition_code..")"; end
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   453
			table.insert(rule.conditions, condition_code);
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   454
			for _, dep in ipairs(condition_deps or {}) do
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   455
				table.insert(rule.deps, dep);
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   456
			end
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   457
		end
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   458
	end
2082
11539785cb92 mod_firewall: Split compile function into two parts in order to separate their scopes
Kim Alvefur <zash@zash.se>
parents: 2081
diff changeset
   459
	return ruleset;
11539785cb92 mod_firewall: Split compile function into two parts in order to separate their scopes
Kim Alvefur <zash@zash.se>
parents: 2081
diff changeset
   460
end
1343
7dbde05b48a9 all the things: Remove trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents: 1325
diff changeset
   461
2082
11539785cb92 mod_firewall: Split compile function into two parts in order to separate their scopes
Kim Alvefur <zash@zash.se>
parents: 2081
diff changeset
   462
local function process_firewall_rules(ruleset)
947
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   463
	-- Compile ruleset and return complete code
1343
7dbde05b48a9 all the things: Remove trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents: 1325
diff changeset
   464
947
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   465
	local chain_handlers = {};
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   466
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   467
	-- Loop through the chains in the parsed ruleset (e.g. incoming, outgoing)
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   468
	for chain_name, rules in pairs(ruleset) do
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   469
		local code = { included_deps = {}, global_header = {} };
1304
9f24ccaa66a6 mod_firewall: Do not cache conditions with only a single use
Florian Zeitz <florob@babelmonkeys.de>
parents: 1303
diff changeset
   470
		local condition_uses = {};
947
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   471
		-- This inner loop assumes chain is an event-based, not a filter-based
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   472
		-- chain (filter-based will be added later)
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   473
		for _, rule in ipairs(rules) do
1304
9f24ccaa66a6 mod_firewall: Do not cache conditions with only a single use
Florian Zeitz <florob@babelmonkeys.de>
parents: 1303
diff changeset
   474
			for _, condition in ipairs(rule.conditions) do
2074
2356114ff505 mod_firewall: Optimize string match operations, string.find is faster than .match since no string is returned
Kim Alvefur <zash@zash.se>
parents: 1343
diff changeset
   475
				if condition:find("^not%(.+%)$") then
1304
9f24ccaa66a6 mod_firewall: Do not cache conditions with only a single use
Florian Zeitz <florob@babelmonkeys.de>
parents: 1303
diff changeset
   476
					condition = condition:match("^not%((.+)%)$");
9f24ccaa66a6 mod_firewall: Do not cache conditions with only a single use
Florian Zeitz <florob@babelmonkeys.de>
parents: 1303
diff changeset
   477
				end
9f24ccaa66a6 mod_firewall: Do not cache conditions with only a single use
Florian Zeitz <florob@babelmonkeys.de>
parents: 1303
diff changeset
   478
				condition_uses[condition] = (condition_uses[condition] or 0) + 1;
9f24ccaa66a6 mod_firewall: Do not cache conditions with only a single use
Florian Zeitz <florob@babelmonkeys.de>
parents: 1303
diff changeset
   479
			end
9f24ccaa66a6 mod_firewall: Do not cache conditions with only a single use
Florian Zeitz <florob@babelmonkeys.de>
parents: 1303
diff changeset
   480
		end
9f24ccaa66a6 mod_firewall: Do not cache conditions with only a single use
Florian Zeitz <florob@babelmonkeys.de>
parents: 1303
diff changeset
   481
9f24ccaa66a6 mod_firewall: Do not cache conditions with only a single use
Florian Zeitz <florob@babelmonkeys.de>
parents: 1303
diff changeset
   482
		local condition_cache, n_conditions = {}, 0;
9f24ccaa66a6 mod_firewall: Do not cache conditions with only a single use
Florian Zeitz <florob@babelmonkeys.de>
parents: 1303
diff changeset
   483
		for _, rule in ipairs(rules) do
947
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   484
			for _, dep in ipairs(rule.deps) do
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   485
				include_dep(dep, code);
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   486
			end
1303
8a3f3f485675 mod_firewall: Produce code with nicer indentation
Florian Zeitz <florob@babelmonkeys.de>
parents: 1052
diff changeset
   487
			table.insert(code, "\n\t\t");
8a3f3f485675 mod_firewall: Produce code with nicer indentation
Florian Zeitz <florob@babelmonkeys.de>
parents: 1052
diff changeset
   488
			local rule_code;
967
a88f33fe6970 mod_firewall: Don't add empty conditions check when no conditions are listed in a rule
Matthew Wild <mwild1@gmail.com>
parents: 966
diff changeset
   489
			if #rule.conditions > 0 then
996
37af655ca575 mod_firewall: Cache conditions, so that they are only calculated once per chain execution
Matthew Wild <mwild1@gmail.com>
parents: 980
diff changeset
   490
				for i, condition in ipairs(rule.conditions) do
1001
c0850793b716 mod_firewall: don't use %b() (not technically correct)
Matthew Wild <mwild1@gmail.com>
parents: 999
diff changeset
   491
					local negated = condition:match("^not%(.+%)$");
996
37af655ca575 mod_firewall: Cache conditions, so that they are only calculated once per chain execution
Matthew Wild <mwild1@gmail.com>
parents: 980
diff changeset
   492
					if negated then
37af655ca575 mod_firewall: Cache conditions, so that they are only calculated once per chain execution
Matthew Wild <mwild1@gmail.com>
parents: 980
diff changeset
   493
						condition = condition:match("^not%((.+)%)$");
37af655ca575 mod_firewall: Cache conditions, so that they are only calculated once per chain execution
Matthew Wild <mwild1@gmail.com>
parents: 980
diff changeset
   494
					end
1304
9f24ccaa66a6 mod_firewall: Do not cache conditions with only a single use
Florian Zeitz <florob@babelmonkeys.de>
parents: 1303
diff changeset
   495
					if condition_uses[condition] > 1 then
9f24ccaa66a6 mod_firewall: Do not cache conditions with only a single use
Florian Zeitz <florob@babelmonkeys.de>
parents: 1303
diff changeset
   496
						local name = condition_cache[condition];
9f24ccaa66a6 mod_firewall: Do not cache conditions with only a single use
Florian Zeitz <florob@babelmonkeys.de>
parents: 1303
diff changeset
   497
						if not name then
9f24ccaa66a6 mod_firewall: Do not cache conditions with only a single use
Florian Zeitz <florob@babelmonkeys.de>
parents: 1303
diff changeset
   498
							n_conditions = n_conditions + 1;
9f24ccaa66a6 mod_firewall: Do not cache conditions with only a single use
Florian Zeitz <florob@babelmonkeys.de>
parents: 1303
diff changeset
   499
							name = "condition"..n_conditions;
9f24ccaa66a6 mod_firewall: Do not cache conditions with only a single use
Florian Zeitz <florob@babelmonkeys.de>
parents: 1303
diff changeset
   500
							condition_cache[condition] = name;
9f24ccaa66a6 mod_firewall: Do not cache conditions with only a single use
Florian Zeitz <florob@babelmonkeys.de>
parents: 1303
diff changeset
   501
							table.insert(code, "local "..name.." = "..condition..";\n\t\t");
9f24ccaa66a6 mod_firewall: Do not cache conditions with only a single use
Florian Zeitz <florob@babelmonkeys.de>
parents: 1303
diff changeset
   502
						end
9f24ccaa66a6 mod_firewall: Do not cache conditions with only a single use
Florian Zeitz <florob@babelmonkeys.de>
parents: 1303
diff changeset
   503
						rule.conditions[i] = (negated and "not(" or "")..name..(negated and ")" or "");
996
37af655ca575 mod_firewall: Cache conditions, so that they are only calculated once per chain execution
Matthew Wild <mwild1@gmail.com>
parents: 980
diff changeset
   504
					else
1304
9f24ccaa66a6 mod_firewall: Do not cache conditions with only a single use
Florian Zeitz <florob@babelmonkeys.de>
parents: 1303
diff changeset
   505
						rule.conditions[i] = (negated and "not(" or "(")..condition..")";
996
37af655ca575 mod_firewall: Cache conditions, so that they are only calculated once per chain execution
Matthew Wild <mwild1@gmail.com>
parents: 980
diff changeset
   506
					end
37af655ca575 mod_firewall: Cache conditions, so that they are only calculated once per chain execution
Matthew Wild <mwild1@gmail.com>
parents: 980
diff changeset
   507
				end
1304
9f24ccaa66a6 mod_firewall: Do not cache conditions with only a single use
Florian Zeitz <florob@babelmonkeys.de>
parents: 1303
diff changeset
   508
1303
8a3f3f485675 mod_firewall: Produce code with nicer indentation
Florian Zeitz <florob@babelmonkeys.de>
parents: 1052
diff changeset
   509
				rule_code = "if "..table.concat(rule.conditions, " and ").." then\n\t\t\t"
8a3f3f485675 mod_firewall: Produce code with nicer indentation
Florian Zeitz <florob@babelmonkeys.de>
parents: 1052
diff changeset
   510
					..table.concat(rule.actions, "\n\t\t\t")
8a3f3f485675 mod_firewall: Produce code with nicer indentation
Florian Zeitz <florob@babelmonkeys.de>
parents: 1052
diff changeset
   511
					.."\n\t\tend\n";
8a3f3f485675 mod_firewall: Produce code with nicer indentation
Florian Zeitz <florob@babelmonkeys.de>
parents: 1052
diff changeset
   512
			else
8a3f3f485675 mod_firewall: Produce code with nicer indentation
Florian Zeitz <florob@babelmonkeys.de>
parents: 1052
diff changeset
   513
				rule_code = table.concat(rule.actions, "\n\t\t");
967
a88f33fe6970 mod_firewall: Don't add empty conditions check when no conditions are listed in a rule
Matthew Wild <mwild1@gmail.com>
parents: 966
diff changeset
   514
			end
947
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   515
			table.insert(code, rule_code);
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   516
		end
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   517
999
197af8440ffb mod_firewall: Make defining objects generic (currently zones and rate limits), so more can easily be added. Also a syntax change... definition lines must begin with %
Matthew Wild <mwild1@gmail.com>
parents: 998
diff changeset
   518
		for name in pairs(definition_handlers) do
197af8440ffb mod_firewall: Make defining objects generic (currently zones and rate limits), so more can easily be added. Also a syntax change... definition lines must begin with %
Matthew Wild <mwild1@gmail.com>
parents: 998
diff changeset
   519
			table.insert(code.global_header, 1, "local "..name:lower().."s = definitions."..name..";");
197af8440ffb mod_firewall: Make defining objects generic (currently zones and rate limits), so more can easily be added. Also a syntax change... definition lines must begin with %
Matthew Wild <mwild1@gmail.com>
parents: 998
diff changeset
   520
		end
197af8440ffb mod_firewall: Make defining objects generic (currently zones and rate limits), so more can easily be added. Also a syntax change... definition lines must begin with %
Matthew Wild <mwild1@gmail.com>
parents: 998
diff changeset
   521
2562
2b533a7b5236 mod_firewall: Make PASS bubble up through all chains, and add DEFAULT and RETURN
Matthew Wild <mwild1@gmail.com>
parents: 2554
diff changeset
   522
		local code_string = "return function (definitions, fire_event, log, module, pass_return)\n\t"
1303
8a3f3f485675 mod_firewall: Produce code with nicer indentation
Florian Zeitz <florob@babelmonkeys.de>
parents: 1052
diff changeset
   523
			..table.concat(code.global_header, "\n\t")
8a3f3f485675 mod_firewall: Produce code with nicer indentation
Florian Zeitz <florob@babelmonkeys.de>
parents: 1052
diff changeset
   524
			.."\n\tlocal db = require 'util.debug';\n\n\t"
8a3f3f485675 mod_firewall: Produce code with nicer indentation
Florian Zeitz <florob@babelmonkeys.de>
parents: 1052
diff changeset
   525
			.."return function (event)\n\t\t"
8a3f3f485675 mod_firewall: Produce code with nicer indentation
Florian Zeitz <florob@babelmonkeys.de>
parents: 1052
diff changeset
   526
			.."local stanza, session = event.stanza, event.origin;\n"
8a3f3f485675 mod_firewall: Produce code with nicer indentation
Florian Zeitz <florob@babelmonkeys.de>
parents: 1052
diff changeset
   527
			..table.concat(code, "")
8a3f3f485675 mod_firewall: Produce code with nicer indentation
Florian Zeitz <florob@babelmonkeys.de>
parents: 1052
diff changeset
   528
			.."\n\tend;\nend";
947
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   529
956
33d6642f4db7 mod_firewall: Tighten up error handling, and split rules->Lua and Lua->bytecode compilation into separate functions
Matthew Wild <mwild1@gmail.com>
parents: 955
diff changeset
   530
		chain_handlers[chain_name] = code_string;
947
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   531
	end
1343
7dbde05b48a9 all the things: Remove trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents: 1325
diff changeset
   532
947
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   533
	return chain_handlers;
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   534
end
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   535
2082
11539785cb92 mod_firewall: Split compile function into two parts in order to separate their scopes
Kim Alvefur <zash@zash.se>
parents: 2081
diff changeset
   536
local function compile_firewall_rules(filename)
11539785cb92 mod_firewall: Split compile function into two parts in order to separate their scopes
Kim Alvefur <zash@zash.se>
parents: 2081
diff changeset
   537
	local ruleset, err = parse_firewall_rules(filename);
11539785cb92 mod_firewall: Split compile function into two parts in order to separate their scopes
Kim Alvefur <zash@zash.se>
parents: 2081
diff changeset
   538
	if not ruleset then return nil, err; end
11539785cb92 mod_firewall: Split compile function into two parts in order to separate their scopes
Kim Alvefur <zash@zash.se>
parents: 2081
diff changeset
   539
	local chain_handlers = process_firewall_rules(ruleset);
11539785cb92 mod_firewall: Split compile function into two parts in order to separate their scopes
Kim Alvefur <zash@zash.se>
parents: 2081
diff changeset
   540
	return chain_handlers;
11539785cb92 mod_firewall: Split compile function into two parts in order to separate their scopes
Kim Alvefur <zash@zash.se>
parents: 2081
diff changeset
   541
end
11539785cb92 mod_firewall: Split compile function into two parts in order to separate their scopes
Kim Alvefur <zash@zash.se>
parents: 2081
diff changeset
   542
2562
2b533a7b5236 mod_firewall: Make PASS bubble up through all chains, and add DEFAULT and RETURN
Matthew Wild <mwild1@gmail.com>
parents: 2554
diff changeset
   543
-- Compile handler code into a factory that produces a valid event handler. Factory accepts
2b533a7b5236 mod_firewall: Make PASS bubble up through all chains, and add DEFAULT and RETURN
Matthew Wild <mwild1@gmail.com>
parents: 2554
diff changeset
   544
-- a value to be returned on PASS
956
33d6642f4db7 mod_firewall: Tighten up error handling, and split rules->Lua and Lua->bytecode compilation into separate functions
Matthew Wild <mwild1@gmail.com>
parents: 955
diff changeset
   545
local function compile_handler(code_string, filename)
33d6642f4db7 mod_firewall: Tighten up error handling, and split rules->Lua and Lua->bytecode compilation into separate functions
Matthew Wild <mwild1@gmail.com>
parents: 955
diff changeset
   546
	-- Prepare event handler function
3985
7e8f2e36419d mod_firewall: Use util.envload instead of deprecated loadstring (thanks Martin)
Kim Alvefur <zash@zash.se>
parents: 2932
diff changeset
   547
	local chunk, err = envload(code_string, "="..filename, _G);
956
33d6642f4db7 mod_firewall: Tighten up error handling, and split rules->Lua and Lua->bytecode compilation into separate functions
Matthew Wild <mwild1@gmail.com>
parents: 955
diff changeset
   548
	if not chunk then
33d6642f4db7 mod_firewall: Tighten up error handling, and split rules->Lua and Lua->bytecode compilation into separate functions
Matthew Wild <mwild1@gmail.com>
parents: 955
diff changeset
   549
		return nil, "Error compiling (probably a compiler bug, please report): "..err;
33d6642f4db7 mod_firewall: Tighten up error handling, and split rules->Lua and Lua->bytecode compilation into separate functions
Matthew Wild <mwild1@gmail.com>
parents: 955
diff changeset
   550
	end
33d6642f4db7 mod_firewall: Tighten up error handling, and split rules->Lua and Lua->bytecode compilation into separate functions
Matthew Wild <mwild1@gmail.com>
parents: 955
diff changeset
   551
	local function fire_event(name, data)
33d6642f4db7 mod_firewall: Tighten up error handling, and split rules->Lua and Lua->bytecode compilation into separate functions
Matthew Wild <mwild1@gmail.com>
parents: 955
diff changeset
   552
		return module:fire_event(name, data);
33d6642f4db7 mod_firewall: Tighten up error handling, and split rules->Lua and Lua->bytecode compilation into separate functions
Matthew Wild <mwild1@gmail.com>
parents: 955
diff changeset
   553
	end
2562
2b533a7b5236 mod_firewall: Make PASS bubble up through all chains, and add DEFAULT and RETURN
Matthew Wild <mwild1@gmail.com>
parents: 2554
diff changeset
   554
	return function (pass_return)
2b533a7b5236 mod_firewall: Make PASS bubble up through all chains, and add DEFAULT and RETURN
Matthew Wild <mwild1@gmail.com>
parents: 2554
diff changeset
   555
		return chunk()(active_definitions, fire_event, logger(filename), module, pass_return); -- Returns event handler with upvalues
2b533a7b5236 mod_firewall: Make PASS bubble up through all chains, and add DEFAULT and RETURN
Matthew Wild <mwild1@gmail.com>
parents: 2554
diff changeset
   556
	end
956
33d6642f4db7 mod_firewall: Tighten up error handling, and split rules->Lua and Lua->bytecode compilation into separate functions
Matthew Wild <mwild1@gmail.com>
parents: 955
diff changeset
   557
end
33d6642f4db7 mod_firewall: Tighten up error handling, and split rules->Lua and Lua->bytecode compilation into separate functions
Matthew Wild <mwild1@gmail.com>
parents: 955
diff changeset
   558
2370
14021c93a962 mod_firewall: Allow prefixing script paths with 'module:' to specify path relative to module file
Matthew Wild <mwild1@gmail.com>
parents: 2369
diff changeset
   559
local function resolve_script_path(script_path)
14021c93a962 mod_firewall: Allow prefixing script paths with 'module:' to specify path relative to module file
Matthew Wild <mwild1@gmail.com>
parents: 2369
diff changeset
   560
	local relative_to = prosody.paths.config;
14021c93a962 mod_firewall: Allow prefixing script paths with 'module:' to specify path relative to module file
Matthew Wild <mwild1@gmail.com>
parents: 2369
diff changeset
   561
	if script_path:match("^module:") then
14021c93a962 mod_firewall: Allow prefixing script paths with 'module:' to specify path relative to module file
Matthew Wild <mwild1@gmail.com>
parents: 2369
diff changeset
   562
		relative_to = module.path:sub(1, -#("/mod_"..module.name..".lua"));
14021c93a962 mod_firewall: Allow prefixing script paths with 'module:' to specify path relative to module file
Matthew Wild <mwild1@gmail.com>
parents: 2369
diff changeset
   563
		script_path = script_path:match("^module:(.+)$");
14021c93a962 mod_firewall: Allow prefixing script paths with 'module:' to specify path relative to module file
Matthew Wild <mwild1@gmail.com>
parents: 2369
diff changeset
   564
	end
14021c93a962 mod_firewall: Allow prefixing script paths with 'module:' to specify path relative to module file
Matthew Wild <mwild1@gmail.com>
parents: 2369
diff changeset
   565
	return resolve_relative_path(relative_to, script_path);
14021c93a962 mod_firewall: Allow prefixing script paths with 'module:' to specify path relative to module file
Matthew Wild <mwild1@gmail.com>
parents: 2369
diff changeset
   566
end
14021c93a962 mod_firewall: Allow prefixing script paths with 'module:' to specify path relative to module file
Matthew Wild <mwild1@gmail.com>
parents: 2369
diff changeset
   567
2582
6dbd07f9a868 mod_firewall: Various improvements allowing dynamic load/reload/unload of scripts
Matthew Wild <mwild1@gmail.com>
parents: 2578
diff changeset
   568
-- [filename] = { last_modified = ..., events_hooked = { [name] = handler } }
6dbd07f9a868 mod_firewall: Various improvements allowing dynamic load/reload/unload of scripts
Matthew Wild <mwild1@gmail.com>
parents: 2578
diff changeset
   569
local loaded_scripts = {};
6dbd07f9a868 mod_firewall: Various improvements allowing dynamic load/reload/unload of scripts
Matthew Wild <mwild1@gmail.com>
parents: 2578
diff changeset
   570
2578
f65c5927ee8e mod_firewall: Factor out script loading
Matthew Wild <mwild1@gmail.com>
parents: 2577
diff changeset
   571
function load_script(script)
f65c5927ee8e mod_firewall: Factor out script loading
Matthew Wild <mwild1@gmail.com>
parents: 2577
diff changeset
   572
	script = resolve_script_path(script);
2582
6dbd07f9a868 mod_firewall: Various improvements allowing dynamic load/reload/unload of scripts
Matthew Wild <mwild1@gmail.com>
parents: 2578
diff changeset
   573
	local last_modified = (lfs.attributes(script) or {}).modification or os.time();
6dbd07f9a868 mod_firewall: Various improvements allowing dynamic load/reload/unload of scripts
Matthew Wild <mwild1@gmail.com>
parents: 2578
diff changeset
   574
	if loaded_scripts[script] then
6dbd07f9a868 mod_firewall: Various improvements allowing dynamic load/reload/unload of scripts
Matthew Wild <mwild1@gmail.com>
parents: 2578
diff changeset
   575
		if loaded_scripts[script].last_modified == last_modified then
6dbd07f9a868 mod_firewall: Various improvements allowing dynamic load/reload/unload of scripts
Matthew Wild <mwild1@gmail.com>
parents: 2578
diff changeset
   576
			return; -- Already loaded, and source file hasn't changed
6dbd07f9a868 mod_firewall: Various improvements allowing dynamic load/reload/unload of scripts
Matthew Wild <mwild1@gmail.com>
parents: 2578
diff changeset
   577
		end
6dbd07f9a868 mod_firewall: Various improvements allowing dynamic load/reload/unload of scripts
Matthew Wild <mwild1@gmail.com>
parents: 2578
diff changeset
   578
		module:log("debug", "Reloading %s", script);
6dbd07f9a868 mod_firewall: Various improvements allowing dynamic load/reload/unload of scripts
Matthew Wild <mwild1@gmail.com>
parents: 2578
diff changeset
   579
		-- Already loaded, but the source file has changed
6dbd07f9a868 mod_firewall: Various improvements allowing dynamic load/reload/unload of scripts
Matthew Wild <mwild1@gmail.com>
parents: 2578
diff changeset
   580
		-- unload it now, and we'll load the new version below
6dbd07f9a868 mod_firewall: Various improvements allowing dynamic load/reload/unload of scripts
Matthew Wild <mwild1@gmail.com>
parents: 2578
diff changeset
   581
		unload_script(script, true);
6dbd07f9a868 mod_firewall: Various improvements allowing dynamic load/reload/unload of scripts
Matthew Wild <mwild1@gmail.com>
parents: 2578
diff changeset
   582
	end
6dbd07f9a868 mod_firewall: Various improvements allowing dynamic load/reload/unload of scripts
Matthew Wild <mwild1@gmail.com>
parents: 2578
diff changeset
   583
	local chain_functions, err = compile_firewall_rules(script);
2863
22e11645a895 mod_firewall: Trim trailing whitespace [luacheck]
Kim Alvefur <zash@zash.se>
parents: 2589
diff changeset
   584
2578
f65c5927ee8e mod_firewall: Factor out script loading
Matthew Wild <mwild1@gmail.com>
parents: 2577
diff changeset
   585
	if not chain_functions then
f65c5927ee8e mod_firewall: Factor out script loading
Matthew Wild <mwild1@gmail.com>
parents: 2577
diff changeset
   586
		module:log("error", "Error compiling %s: %s", script, err or "unknown error");
2582
6dbd07f9a868 mod_firewall: Various improvements allowing dynamic load/reload/unload of scripts
Matthew Wild <mwild1@gmail.com>
parents: 2578
diff changeset
   587
		return;
6dbd07f9a868 mod_firewall: Various improvements allowing dynamic load/reload/unload of scripts
Matthew Wild <mwild1@gmail.com>
parents: 2578
diff changeset
   588
	end
6dbd07f9a868 mod_firewall: Various improvements allowing dynamic load/reload/unload of scripts
Matthew Wild <mwild1@gmail.com>
parents: 2578
diff changeset
   589
6dbd07f9a868 mod_firewall: Various improvements allowing dynamic load/reload/unload of scripts
Matthew Wild <mwild1@gmail.com>
parents: 2578
diff changeset
   590
	-- Loop through the chains in the script, and for each chain attach the compiled code to the
6dbd07f9a868 mod_firewall: Various improvements allowing dynamic load/reload/unload of scripts
Matthew Wild <mwild1@gmail.com>
parents: 2578
diff changeset
   591
	-- relevant events, keeping track in events_hooked so we can cleanly unload later
6dbd07f9a868 mod_firewall: Various improvements allowing dynamic load/reload/unload of scripts
Matthew Wild <mwild1@gmail.com>
parents: 2578
diff changeset
   592
	local events_hooked = {};
6dbd07f9a868 mod_firewall: Various improvements allowing dynamic load/reload/unload of scripts
Matthew Wild <mwild1@gmail.com>
parents: 2578
diff changeset
   593
	for chain, handler_code in pairs(chain_functions) do
6dbd07f9a868 mod_firewall: Various improvements allowing dynamic load/reload/unload of scripts
Matthew Wild <mwild1@gmail.com>
parents: 2578
diff changeset
   594
		local new_handler, err = compile_handler(handler_code, "mod_firewall::"..chain);
6dbd07f9a868 mod_firewall: Various improvements allowing dynamic load/reload/unload of scripts
Matthew Wild <mwild1@gmail.com>
parents: 2578
diff changeset
   595
		if not new_handler then
6dbd07f9a868 mod_firewall: Various improvements allowing dynamic load/reload/unload of scripts
Matthew Wild <mwild1@gmail.com>
parents: 2578
diff changeset
   596
			module:log("error", "Compilation error for %s: %s", script, err);
6dbd07f9a868 mod_firewall: Various improvements allowing dynamic load/reload/unload of scripts
Matthew Wild <mwild1@gmail.com>
parents: 2578
diff changeset
   597
		else
6dbd07f9a868 mod_firewall: Various improvements allowing dynamic load/reload/unload of scripts
Matthew Wild <mwild1@gmail.com>
parents: 2578
diff changeset
   598
			local chain_definition = chains[chain];
6dbd07f9a868 mod_firewall: Various improvements allowing dynamic load/reload/unload of scripts
Matthew Wild <mwild1@gmail.com>
parents: 2578
diff changeset
   599
			if chain_definition and chain_definition.type == "event" then
6dbd07f9a868 mod_firewall: Various improvements allowing dynamic load/reload/unload of scripts
Matthew Wild <mwild1@gmail.com>
parents: 2578
diff changeset
   600
				local handler = new_handler(chain_definition.pass_return);
6dbd07f9a868 mod_firewall: Various improvements allowing dynamic load/reload/unload of scripts
Matthew Wild <mwild1@gmail.com>
parents: 2578
diff changeset
   601
				for _, event_name in ipairs(chain_definition) do
6dbd07f9a868 mod_firewall: Various improvements allowing dynamic load/reload/unload of scripts
Matthew Wild <mwild1@gmail.com>
parents: 2578
diff changeset
   602
					events_hooked[event_name] = handler;
6dbd07f9a868 mod_firewall: Various improvements allowing dynamic load/reload/unload of scripts
Matthew Wild <mwild1@gmail.com>
parents: 2578
diff changeset
   603
					module:hook(event_name, handler, chain_definition.priority);
2578
f65c5927ee8e mod_firewall: Factor out script loading
Matthew Wild <mwild1@gmail.com>
parents: 2577
diff changeset
   604
				end
2582
6dbd07f9a868 mod_firewall: Various improvements allowing dynamic load/reload/unload of scripts
Matthew Wild <mwild1@gmail.com>
parents: 2578
diff changeset
   605
			elseif not chain:sub(1, 5) == "user/" then
6dbd07f9a868 mod_firewall: Various improvements allowing dynamic load/reload/unload of scripts
Matthew Wild <mwild1@gmail.com>
parents: 2578
diff changeset
   606
				module:log("warn", "Unknown chain %q", chain);
2578
f65c5927ee8e mod_firewall: Factor out script loading
Matthew Wild <mwild1@gmail.com>
parents: 2577
diff changeset
   607
			end
2582
6dbd07f9a868 mod_firewall: Various improvements allowing dynamic load/reload/unload of scripts
Matthew Wild <mwild1@gmail.com>
parents: 2578
diff changeset
   608
			local event_name, handler = "firewall/chains/"..chain, new_handler(false);
6dbd07f9a868 mod_firewall: Various improvements allowing dynamic load/reload/unload of scripts
Matthew Wild <mwild1@gmail.com>
parents: 2578
diff changeset
   609
			events_hooked[event_name] = handler;
6dbd07f9a868 mod_firewall: Various improvements allowing dynamic load/reload/unload of scripts
Matthew Wild <mwild1@gmail.com>
parents: 2578
diff changeset
   610
			module:hook(event_name, handler);
2578
f65c5927ee8e mod_firewall: Factor out script loading
Matthew Wild <mwild1@gmail.com>
parents: 2577
diff changeset
   611
		end
f65c5927ee8e mod_firewall: Factor out script loading
Matthew Wild <mwild1@gmail.com>
parents: 2577
diff changeset
   612
	end
2582
6dbd07f9a868 mod_firewall: Various improvements allowing dynamic load/reload/unload of scripts
Matthew Wild <mwild1@gmail.com>
parents: 2578
diff changeset
   613
	loaded_scripts[script] = { last_modified = last_modified, events_hooked = events_hooked };
6dbd07f9a868 mod_firewall: Various improvements allowing dynamic load/reload/unload of scripts
Matthew Wild <mwild1@gmail.com>
parents: 2578
diff changeset
   614
	module:log("debug", "Loaded %s", script);
6dbd07f9a868 mod_firewall: Various improvements allowing dynamic load/reload/unload of scripts
Matthew Wild <mwild1@gmail.com>
parents: 2578
diff changeset
   615
end
6dbd07f9a868 mod_firewall: Various improvements allowing dynamic load/reload/unload of scripts
Matthew Wild <mwild1@gmail.com>
parents: 2578
diff changeset
   616
2584
aaff2716f022 mod_firewall: Compatibility fix for 0.9 (no module:unhook())
Matthew Wild <mwild1@gmail.com>
parents: 2583
diff changeset
   617
--COMPAT w/0.9 (no module:unhook()!)
aaff2716f022 mod_firewall: Compatibility fix for 0.9 (no module:unhook())
Matthew Wild <mwild1@gmail.com>
parents: 2583
diff changeset
   618
local function module_unhook(event, handler)
aaff2716f022 mod_firewall: Compatibility fix for 0.9 (no module:unhook())
Matthew Wild <mwild1@gmail.com>
parents: 2583
diff changeset
   619
	return module:unhook_object_event((hosts[module.host] or prosody).events, event, handler);
aaff2716f022 mod_firewall: Compatibility fix for 0.9 (no module:unhook())
Matthew Wild <mwild1@gmail.com>
parents: 2583
diff changeset
   620
end
aaff2716f022 mod_firewall: Compatibility fix for 0.9 (no module:unhook())
Matthew Wild <mwild1@gmail.com>
parents: 2583
diff changeset
   621
2582
6dbd07f9a868 mod_firewall: Various improvements allowing dynamic load/reload/unload of scripts
Matthew Wild <mwild1@gmail.com>
parents: 2578
diff changeset
   622
function unload_script(script, is_reload)
6dbd07f9a868 mod_firewall: Various improvements allowing dynamic load/reload/unload of scripts
Matthew Wild <mwild1@gmail.com>
parents: 2578
diff changeset
   623
	script = resolve_script_path(script);
6dbd07f9a868 mod_firewall: Various improvements allowing dynamic load/reload/unload of scripts
Matthew Wild <mwild1@gmail.com>
parents: 2578
diff changeset
   624
	local script_info = loaded_scripts[script];
6dbd07f9a868 mod_firewall: Various improvements allowing dynamic load/reload/unload of scripts
Matthew Wild <mwild1@gmail.com>
parents: 2578
diff changeset
   625
	if not script_info then
6dbd07f9a868 mod_firewall: Various improvements allowing dynamic load/reload/unload of scripts
Matthew Wild <mwild1@gmail.com>
parents: 2578
diff changeset
   626
		return; -- Script not loaded
6dbd07f9a868 mod_firewall: Various improvements allowing dynamic load/reload/unload of scripts
Matthew Wild <mwild1@gmail.com>
parents: 2578
diff changeset
   627
	end
6dbd07f9a868 mod_firewall: Various improvements allowing dynamic load/reload/unload of scripts
Matthew Wild <mwild1@gmail.com>
parents: 2578
diff changeset
   628
	local events_hooked = script_info.events_hooked;
6dbd07f9a868 mod_firewall: Various improvements allowing dynamic load/reload/unload of scripts
Matthew Wild <mwild1@gmail.com>
parents: 2578
diff changeset
   629
	for event_name, event_handler in pairs(events_hooked) do
2584
aaff2716f022 mod_firewall: Compatibility fix for 0.9 (no module:unhook())
Matthew Wild <mwild1@gmail.com>
parents: 2583
diff changeset
   630
		module_unhook(event_name, event_handler);
2582
6dbd07f9a868 mod_firewall: Various improvements allowing dynamic load/reload/unload of scripts
Matthew Wild <mwild1@gmail.com>
parents: 2578
diff changeset
   631
		events_hooked[event_name] = nil;
6dbd07f9a868 mod_firewall: Various improvements allowing dynamic load/reload/unload of scripts
Matthew Wild <mwild1@gmail.com>
parents: 2578
diff changeset
   632
	end
6dbd07f9a868 mod_firewall: Various improvements allowing dynamic load/reload/unload of scripts
Matthew Wild <mwild1@gmail.com>
parents: 2578
diff changeset
   633
	loaded_scripts[script] = nil;
6dbd07f9a868 mod_firewall: Various improvements allowing dynamic load/reload/unload of scripts
Matthew Wild <mwild1@gmail.com>
parents: 2578
diff changeset
   634
	if not is_reload then
6dbd07f9a868 mod_firewall: Various improvements allowing dynamic load/reload/unload of scripts
Matthew Wild <mwild1@gmail.com>
parents: 2578
diff changeset
   635
		module:log("debug", "Unloaded %s", script);
6dbd07f9a868 mod_firewall: Various improvements allowing dynamic load/reload/unload of scripts
Matthew Wild <mwild1@gmail.com>
parents: 2578
diff changeset
   636
	end
6dbd07f9a868 mod_firewall: Various improvements allowing dynamic load/reload/unload of scripts
Matthew Wild <mwild1@gmail.com>
parents: 2578
diff changeset
   637
end
6dbd07f9a868 mod_firewall: Various improvements allowing dynamic load/reload/unload of scripts
Matthew Wild <mwild1@gmail.com>
parents: 2578
diff changeset
   638
6dbd07f9a868 mod_firewall: Various improvements allowing dynamic load/reload/unload of scripts
Matthew Wild <mwild1@gmail.com>
parents: 2578
diff changeset
   639
-- Given a set of scripts (e.g. from config) figure out which ones need to
6dbd07f9a868 mod_firewall: Various improvements allowing dynamic load/reload/unload of scripts
Matthew Wild <mwild1@gmail.com>
parents: 2578
diff changeset
   640
-- be loaded, which are already loaded but need unloading, and which to reload
6dbd07f9a868 mod_firewall: Various improvements allowing dynamic load/reload/unload of scripts
Matthew Wild <mwild1@gmail.com>
parents: 2578
diff changeset
   641
function load_unload_scripts(script_list)
6dbd07f9a868 mod_firewall: Various improvements allowing dynamic load/reload/unload of scripts
Matthew Wild <mwild1@gmail.com>
parents: 2578
diff changeset
   642
	local wanted_scripts = script_list / resolve_script_path;
6dbd07f9a868 mod_firewall: Various improvements allowing dynamic load/reload/unload of scripts
Matthew Wild <mwild1@gmail.com>
parents: 2578
diff changeset
   643
	local currently_loaded = set.new(it.to_array(it.keys(loaded_scripts)));
6dbd07f9a868 mod_firewall: Various improvements allowing dynamic load/reload/unload of scripts
Matthew Wild <mwild1@gmail.com>
parents: 2578
diff changeset
   644
	local scripts_to_unload = currently_loaded - wanted_scripts;
6dbd07f9a868 mod_firewall: Various improvements allowing dynamic load/reload/unload of scripts
Matthew Wild <mwild1@gmail.com>
parents: 2578
diff changeset
   645
	for script in wanted_scripts do
6dbd07f9a868 mod_firewall: Various improvements allowing dynamic load/reload/unload of scripts
Matthew Wild <mwild1@gmail.com>
parents: 2578
diff changeset
   646
		-- If the script is already loaded, this is fine - it will
6dbd07f9a868 mod_firewall: Various improvements allowing dynamic load/reload/unload of scripts
Matthew Wild <mwild1@gmail.com>
parents: 2578
diff changeset
   647
		-- reload the script for us if the file has changed
6dbd07f9a868 mod_firewall: Various improvements allowing dynamic load/reload/unload of scripts
Matthew Wild <mwild1@gmail.com>
parents: 2578
diff changeset
   648
		load_script(script);
6dbd07f9a868 mod_firewall: Various improvements allowing dynamic load/reload/unload of scripts
Matthew Wild <mwild1@gmail.com>
parents: 2578
diff changeset
   649
	end
6dbd07f9a868 mod_firewall: Various improvements allowing dynamic load/reload/unload of scripts
Matthew Wild <mwild1@gmail.com>
parents: 2578
diff changeset
   650
	for script in scripts_to_unload do
6dbd07f9a868 mod_firewall: Various improvements allowing dynamic load/reload/unload of scripts
Matthew Wild <mwild1@gmail.com>
parents: 2578
diff changeset
   651
		unload_script(script);
6dbd07f9a868 mod_firewall: Various improvements allowing dynamic load/reload/unload of scripts
Matthew Wild <mwild1@gmail.com>
parents: 2578
diff changeset
   652
	end
2578
f65c5927ee8e mod_firewall: Factor out script loading
Matthew Wild <mwild1@gmail.com>
parents: 2577
diff changeset
   653
end
f65c5927ee8e mod_firewall: Factor out script loading
Matthew Wild <mwild1@gmail.com>
parents: 2577
diff changeset
   654
947
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   655
function module.load()
1052
80f0a3231c59 mod_firewall: Add support for being called as a prosodyctl command
Kim Alvefur <zash@zash.se>
parents: 1051
diff changeset
   656
	if not prosody.arg then return end -- Don't run in prosodyctl
947
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   657
	local firewall_scripts = module:get_option_set("firewall_scripts", {});
2582
6dbd07f9a868 mod_firewall: Various improvements allowing dynamic load/reload/unload of scripts
Matthew Wild <mwild1@gmail.com>
parents: 2578
diff changeset
   658
	load_unload_scripts(firewall_scripts);
999
197af8440ffb mod_firewall: Make defining objects generic (currently zones and rate limits), so more can easily be added. Also a syntax change... definition lines must begin with %
Matthew Wild <mwild1@gmail.com>
parents: 998
diff changeset
   659
	-- Replace contents of definitions table (shared) with active definitions
197af8440ffb mod_firewall: Make defining objects generic (currently zones and rate limits), so more can easily be added. Also a syntax change... definition lines must begin with %
Matthew Wild <mwild1@gmail.com>
parents: 998
diff changeset
   660
	for k in it.keys(definitions) do definitions[k] = nil; end
197af8440ffb mod_firewall: Make defining objects generic (currently zones and rate limits), so more can easily be added. Also a syntax change... definition lines must begin with %
Matthew Wild <mwild1@gmail.com>
parents: 998
diff changeset
   661
	for k,v in pairs(active_definitions) do definitions[k] = v; end
947
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   662
end
1052
80f0a3231c59 mod_firewall: Add support for being called as a prosodyctl command
Kim Alvefur <zash@zash.se>
parents: 1051
diff changeset
   663
2582
6dbd07f9a868 mod_firewall: Various improvements allowing dynamic load/reload/unload of scripts
Matthew Wild <mwild1@gmail.com>
parents: 2578
diff changeset
   664
function module.save()
6dbd07f9a868 mod_firewall: Various improvements allowing dynamic load/reload/unload of scripts
Matthew Wild <mwild1@gmail.com>
parents: 2578
diff changeset
   665
	return { active_definitions = active_definitions, loaded_scripts = loaded_scripts };
6dbd07f9a868 mod_firewall: Various improvements allowing dynamic load/reload/unload of scripts
Matthew Wild <mwild1@gmail.com>
parents: 2578
diff changeset
   666
end
6dbd07f9a868 mod_firewall: Various improvements allowing dynamic load/reload/unload of scripts
Matthew Wild <mwild1@gmail.com>
parents: 2578
diff changeset
   667
6dbd07f9a868 mod_firewall: Various improvements allowing dynamic load/reload/unload of scripts
Matthew Wild <mwild1@gmail.com>
parents: 2578
diff changeset
   668
function module.restore(state)
6dbd07f9a868 mod_firewall: Various improvements allowing dynamic load/reload/unload of scripts
Matthew Wild <mwild1@gmail.com>
parents: 2578
diff changeset
   669
	active_definitions = state.active_definitions;
6dbd07f9a868 mod_firewall: Various improvements allowing dynamic load/reload/unload of scripts
Matthew Wild <mwild1@gmail.com>
parents: 2578
diff changeset
   670
	loaded_scripts = state.loaded_scripts;
6dbd07f9a868 mod_firewall: Various improvements allowing dynamic load/reload/unload of scripts
Matthew Wild <mwild1@gmail.com>
parents: 2578
diff changeset
   671
end
6dbd07f9a868 mod_firewall: Various improvements allowing dynamic load/reload/unload of scripts
Matthew Wild <mwild1@gmail.com>
parents: 2578
diff changeset
   672
6dbd07f9a868 mod_firewall: Various improvements allowing dynamic load/reload/unload of scripts
Matthew Wild <mwild1@gmail.com>
parents: 2578
diff changeset
   673
module:hook_global("config-reloaded", function ()
6dbd07f9a868 mod_firewall: Various improvements allowing dynamic load/reload/unload of scripts
Matthew Wild <mwild1@gmail.com>
parents: 2578
diff changeset
   674
	load_unload_scripts(module:get_option_set("firewall_scripts", {}));
6dbd07f9a868 mod_firewall: Various improvements allowing dynamic load/reload/unload of scripts
Matthew Wild <mwild1@gmail.com>
parents: 2578
diff changeset
   675
end);
6dbd07f9a868 mod_firewall: Various improvements allowing dynamic load/reload/unload of scripts
Matthew Wild <mwild1@gmail.com>
parents: 2578
diff changeset
   676
1052
80f0a3231c59 mod_firewall: Add support for being called as a prosodyctl command
Kim Alvefur <zash@zash.se>
parents: 1051
diff changeset
   677
function module.command(arg)
80f0a3231c59 mod_firewall: Add support for being called as a prosodyctl command
Kim Alvefur <zash@zash.se>
parents: 1051
diff changeset
   678
	if not arg[1] or arg[1] == "--help" then
80f0a3231c59 mod_firewall: Add support for being called as a prosodyctl command
Kim Alvefur <zash@zash.se>
parents: 1051
diff changeset
   679
		require"util.prosodyctl".show_usage([[mod_firewall <firewall.pfw>]], [[Compile files with firewall rules to Lua code]]);
80f0a3231c59 mod_firewall: Add support for being called as a prosodyctl command
Kim Alvefur <zash@zash.se>
parents: 1051
diff changeset
   680
		return 1;
80f0a3231c59 mod_firewall: Add support for being called as a prosodyctl command
Kim Alvefur <zash@zash.se>
parents: 1051
diff changeset
   681
	end
2122
643b254e75de mod_firewall: Disable more realistic output by default, activated by adding a -v flag
Kim Alvefur <zash@zash.se>
parents: 2121
diff changeset
   682
	local verbose = arg[1] == "-v";
643b254e75de mod_firewall: Disable more realistic output by default, activated by adding a -v flag
Kim Alvefur <zash@zash.se>
parents: 2121
diff changeset
   683
	if verbose then table.remove(arg, 1); end
1052
80f0a3231c59 mod_firewall: Add support for being called as a prosodyctl command
Kim Alvefur <zash@zash.se>
parents: 1051
diff changeset
   684
2589
02c6ae745c4f mod_firewall: Add 'test' subcommand to read stanzas from stdin and test them against rules
Matthew Wild <mwild1@gmail.com>
parents: 2588
diff changeset
   685
	if arg[1] == "test" then
02c6ae745c4f mod_firewall: Add 'test' subcommand to read stanzas from stdin and test them against rules
Matthew Wild <mwild1@gmail.com>
parents: 2588
diff changeset
   686
		table.remove(arg, 1);
02c6ae745c4f mod_firewall: Add 'test' subcommand to read stanzas from stdin and test them against rules
Matthew Wild <mwild1@gmail.com>
parents: 2588
diff changeset
   687
		return module:require("test")(arg);
02c6ae745c4f mod_firewall: Add 'test' subcommand to read stanzas from stdin and test them against rules
Matthew Wild <mwild1@gmail.com>
parents: 2588
diff changeset
   688
	end
02c6ae745c4f mod_firewall: Add 'test' subcommand to read stanzas from stdin and test them against rules
Matthew Wild <mwild1@gmail.com>
parents: 2588
diff changeset
   689
2121
5aa3b93cd37a mod_firewall: Make prosodyctl command output more realistic source (not guaranteed to work)
Kim Alvefur <zash@zash.se>
parents: 2117
diff changeset
   690
	local serialize = require "util.serialization".serialize;
2122
643b254e75de mod_firewall: Disable more realistic output by default, activated by adding a -v flag
Kim Alvefur <zash@zash.se>
parents: 2121
diff changeset
   691
	if verbose then
643b254e75de mod_firewall: Disable more realistic output by default, activated by adding a -v flag
Kim Alvefur <zash@zash.se>
parents: 2121
diff changeset
   692
		print("local logger = require \"util.logger\".init;");
643b254e75de mod_firewall: Disable more realistic output by default, activated by adding a -v flag
Kim Alvefur <zash@zash.se>
parents: 2121
diff changeset
   693
		print();
643b254e75de mod_firewall: Disable more realistic output by default, activated by adding a -v flag
Kim Alvefur <zash@zash.se>
parents: 2121
diff changeset
   694
		print("local function fire_event(name, data)\n\tmodule:fire_event(name, data)\nend");
643b254e75de mod_firewall: Disable more realistic output by default, activated by adding a -v flag
Kim Alvefur <zash@zash.se>
parents: 2121
diff changeset
   695
		print();
643b254e75de mod_firewall: Disable more realistic output by default, activated by adding a -v flag
Kim Alvefur <zash@zash.se>
parents: 2121
diff changeset
   696
	end
2121
5aa3b93cd37a mod_firewall: Make prosodyctl command output more realistic source (not guaranteed to work)
Kim Alvefur <zash@zash.se>
parents: 2117
diff changeset
   697
1052
80f0a3231c59 mod_firewall: Add support for being called as a prosodyctl command
Kim Alvefur <zash@zash.se>
parents: 1051
diff changeset
   698
	for _, filename in ipairs(arg) do
2370
14021c93a962 mod_firewall: Allow prefixing script paths with 'module:' to specify path relative to module file
Matthew Wild <mwild1@gmail.com>
parents: 2369
diff changeset
   699
		filename = resolve_script_path(filename);
2121
5aa3b93cd37a mod_firewall: Make prosodyctl command output more realistic source (not guaranteed to work)
Kim Alvefur <zash@zash.se>
parents: 2117
diff changeset
   700
		print("do -- File "..filename);
2369
05dae9adf778 mod_firewall: Fix for when compiling on the command line and specifying multiple files
Matthew Wild <mwild1@gmail.com>
parents: 2368
diff changeset
   701
		local chain_functions = assert(compile_firewall_rules(filename));
2122
643b254e75de mod_firewall: Disable more realistic output by default, activated by adding a -v flag
Kim Alvefur <zash@zash.se>
parents: 2121
diff changeset
   702
		if verbose then
643b254e75de mod_firewall: Disable more realistic output by default, activated by adding a -v flag
Kim Alvefur <zash@zash.se>
parents: 2121
diff changeset
   703
			print();
643b254e75de mod_firewall: Disable more realistic output by default, activated by adding a -v flag
Kim Alvefur <zash@zash.se>
parents: 2121
diff changeset
   704
			print("local active_definitions = "..serialize(active_definitions)..";");
643b254e75de mod_firewall: Disable more realistic output by default, activated by adding a -v flag
Kim Alvefur <zash@zash.se>
parents: 2121
diff changeset
   705
			print();
643b254e75de mod_firewall: Disable more realistic output by default, activated by adding a -v flag
Kim Alvefur <zash@zash.se>
parents: 2121
diff changeset
   706
		end
2371
3ebd3cb4d7d2 mod_firewall: When compiling on the command-line with -v, ensure chain function names are unique and valid ids
Matthew Wild <mwild1@gmail.com>
parents: 2370
diff changeset
   707
		local c = 0;
1052
80f0a3231c59 mod_firewall: Add support for being called as a prosodyctl command
Kim Alvefur <zash@zash.se>
parents: 1051
diff changeset
   708
		for chain, handler_code in pairs(chain_functions) do
2371
3ebd3cb4d7d2 mod_firewall: When compiling on the command-line with -v, ensure chain function names are unique and valid ids
Matthew Wild <mwild1@gmail.com>
parents: 2370
diff changeset
   709
			c = c + 1;
2121
5aa3b93cd37a mod_firewall: Make prosodyctl command output more realistic source (not guaranteed to work)
Kim Alvefur <zash@zash.se>
parents: 2117
diff changeset
   710
			print("---- Chain "..chain:gsub("_", " "));
2371
3ebd3cb4d7d2 mod_firewall: When compiling on the command-line with -v, ensure chain function names are unique and valid ids
Matthew Wild <mwild1@gmail.com>
parents: 2370
diff changeset
   711
			local chain_func_name = "chain_"..tostring(c).."_"..chain:gsub("%p", "_");
2122
643b254e75de mod_firewall: Disable more realistic output by default, activated by adding a -v flag
Kim Alvefur <zash@zash.se>
parents: 2121
diff changeset
   712
			if not verbose then
2371
3ebd3cb4d7d2 mod_firewall: When compiling on the command-line with -v, ensure chain function names are unique and valid ids
Matthew Wild <mwild1@gmail.com>
parents: 2370
diff changeset
   713
				print(("%s = %s;"):format(chain_func_name, handler_code:sub(8)));
2122
643b254e75de mod_firewall: Disable more realistic output by default, activated by adding a -v flag
Kim Alvefur <zash@zash.se>
parents: 2121
diff changeset
   714
			else
2121
5aa3b93cd37a mod_firewall: Make prosodyctl command output more realistic source (not guaranteed to work)
Kim Alvefur <zash@zash.se>
parents: 2117
diff changeset
   715
2371
3ebd3cb4d7d2 mod_firewall: When compiling on the command-line with -v, ensure chain function names are unique and valid ids
Matthew Wild <mwild1@gmail.com>
parents: 2370
diff changeset
   716
				print(("local %s = (%s)(active_definitions, fire_event, logger(%q));"):format(chain_func_name, handler_code:sub(8), filename));
2122
643b254e75de mod_firewall: Disable more realistic output by default, activated by adding a -v flag
Kim Alvefur <zash@zash.se>
parents: 2121
diff changeset
   717
				print();
2121
5aa3b93cd37a mod_firewall: Make prosodyctl command output more realistic source (not guaranteed to work)
Kim Alvefur <zash@zash.se>
parents: 2117
diff changeset
   718
2122
643b254e75de mod_firewall: Disable more realistic output by default, activated by adding a -v flag
Kim Alvefur <zash@zash.se>
parents: 2121
diff changeset
   719
				local chain_definition = chains[chain];
643b254e75de mod_firewall: Disable more realistic output by default, activated by adding a -v flag
Kim Alvefur <zash@zash.se>
parents: 2121
diff changeset
   720
				if chain_definition and chain_definition.type == "event" then
643b254e75de mod_firewall: Disable more realistic output by default, activated by adding a -v flag
Kim Alvefur <zash@zash.se>
parents: 2121
diff changeset
   721
					for _, event_name in ipairs(chain_definition) do
2371
3ebd3cb4d7d2 mod_firewall: When compiling on the command-line with -v, ensure chain function names are unique and valid ids
Matthew Wild <mwild1@gmail.com>
parents: 2370
diff changeset
   722
						print(("module:hook(%q, %s, %d);"):format(event_name, chain_func_name, chain_definition.priority or 0));
2122
643b254e75de mod_firewall: Disable more realistic output by default, activated by adding a -v flag
Kim Alvefur <zash@zash.se>
parents: 2121
diff changeset
   723
					end
2121
5aa3b93cd37a mod_firewall: Make prosodyctl command output more realistic source (not guaranteed to work)
Kim Alvefur <zash@zash.se>
parents: 2117
diff changeset
   724
				end
2371
3ebd3cb4d7d2 mod_firewall: When compiling on the command-line with -v, ensure chain function names are unique and valid ids
Matthew Wild <mwild1@gmail.com>
parents: 2370
diff changeset
   725
				print(("module:hook(%q, %s, %d);"):format("firewall/chains/"..chain, chain_func_name, chain_definition.priority or 0));
2121
5aa3b93cd37a mod_firewall: Make prosodyctl command output more realistic source (not guaranteed to work)
Kim Alvefur <zash@zash.se>
parents: 2117
diff changeset
   726
			end
5aa3b93cd37a mod_firewall: Make prosodyctl command output more realistic source (not guaranteed to work)
Kim Alvefur <zash@zash.se>
parents: 2117
diff changeset
   727
5aa3b93cd37a mod_firewall: Make prosodyctl command output more realistic source (not guaranteed to work)
Kim Alvefur <zash@zash.se>
parents: 2117
diff changeset
   728
			print("---- End of chain "..chain);
5aa3b93cd37a mod_firewall: Make prosodyctl command output more realistic source (not guaranteed to work)
Kim Alvefur <zash@zash.se>
parents: 2117
diff changeset
   729
			print();
1052
80f0a3231c59 mod_firewall: Add support for being called as a prosodyctl command
Kim Alvefur <zash@zash.se>
parents: 1051
diff changeset
   730
		end
2121
5aa3b93cd37a mod_firewall: Make prosodyctl command output more realistic source (not guaranteed to work)
Kim Alvefur <zash@zash.se>
parents: 2117
diff changeset
   731
		print("end -- End of file "..filename);
1052
80f0a3231c59 mod_firewall: Add support for being called as a prosodyctl command
Kim Alvefur <zash@zash.se>
parents: 1051
diff changeset
   732
	end
80f0a3231c59 mod_firewall: Add support for being called as a prosodyctl command
Kim Alvefur <zash@zash.se>
parents: 1051
diff changeset
   733
end