mod_firewall/conditions.lib.lua
author Matthew Wild <mwild1@gmail.com>
Sat, 14 Jan 2023 14:31:37 +0000
changeset 5153 fa56ed2bacab
parent 5006 84997bc3f92e
child 5534 8226ac08484e
permissions -rw-r--r--
mod_unified_push: Add support for multiple token backends, including stoage Now that we have ACLs by default, it is no longer necessary to be completely stateless. On 0.12, using storage has benefits over JWT, because it does not expose client JIDs to the push apps/services. In trunk, PASETO is stateless and does not expose client JIDs.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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: 2123
diff changeset
     1
--luacheck: globals meta idsafe
947
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     2
local condition_handlers = {};
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     3
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     4
local jid = require "util.jid";
3977
df6227e288e5 mod_firewall: Fix use of unpack() on Lua 5.3
Kim Alvefur <zash@zash.se>
parents: 2932
diff changeset
     5
local unpack = table.unpack or unpack;
947
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     6
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: 2132
diff changeset
     7
-- Helper to convert user-input strings (yes/true//no/false) to a bool
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: 2132
diff changeset
     8
local function string_to_boolean(s)
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: 2132
diff changeset
     9
	s = s:lower();
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: 2132
diff changeset
    10
	return s == "yes" or s == "true";
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: 2132
diff changeset
    11
end
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: 2132
diff changeset
    12
947
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    13
-- Return a code string for a condition that checks whether the contents
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    14
-- of variable with the name 'name' matches any of the values in the
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    15
-- comma/space/pipe delimited list 'values'.
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    16
local function compile_comparison_list(name, values)
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    17
	local conditions = {};
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    18
	for value in values:gmatch("[^%s,|]+") do
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    19
		table.insert(conditions, ("%s == %q"):format(name, value));
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    20
	end
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    21
	return table.concat(conditions, " or ");
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    22
end
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    23
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    24
function condition_handlers.KIND(kind)
2586
ac3140cd89a2 mod_firewall: Fix compilation error if TYPE/KIND had no parameter
Matthew Wild <mwild1@gmail.com>
parents: 2581
diff changeset
    25
	assert(kind, "Expected stanza kind to match against");
947
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    26
	return compile_comparison_list("name", kind), { "name" };
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    27
end
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
local wildcard_equivs = { ["*"] = ".*", ["?"] = "." };
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    30
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    31
local function compile_jid_match_part(part, match)
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    32
	if not match then
2075
4161ff87e5a4 mod_firewall/conditions: Add semicolon
Kim Alvefur <zash@zash.se>
parents: 2074
diff changeset
    33
		return part.." == nil";
947
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    34
	end
2076
eda5c54dfa30 mod_firewall: Anchor pattern at beginning and end
Kim Alvefur <zash@zash.se>
parents: 2075
diff changeset
    35
	local pattern = match:match("^<(.*)>$");
947
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    36
	if pattern then
962
93ffa3ffc66f mod_firewall/conditions: Support Lua patterns in JID matching, and make <*>@example.com NOT match example.com
Matthew Wild <mwild1@gmail.com>
parents: 954
diff changeset
    37
		if pattern == "*" then
93ffa3ffc66f mod_firewall/conditions: Support Lua patterns in JID matching, and make <*>@example.com NOT match example.com
Matthew Wild <mwild1@gmail.com>
parents: 954
diff changeset
    38
			return part;
947
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    39
		end
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: 2040
diff changeset
    40
		if pattern:find("^<.*>$") then
962
93ffa3ffc66f mod_firewall/conditions: Support Lua patterns in JID matching, and make <*>@example.com NOT match example.com
Matthew Wild <mwild1@gmail.com>
parents: 954
diff changeset
    41
			pattern = pattern:match("^<(.*)>$");
93ffa3ffc66f mod_firewall/conditions: Support Lua patterns in JID matching, and make <*>@example.com NOT match example.com
Matthew Wild <mwild1@gmail.com>
parents: 954
diff changeset
    42
		else
93ffa3ffc66f mod_firewall/conditions: Support Lua patterns in JID matching, and make <*>@example.com NOT match example.com
Matthew Wild <mwild1@gmail.com>
parents: 954
diff changeset
    43
			pattern = pattern:gsub("%p", "%%%0"):gsub("%%(%p)", wildcard_equivs);
93ffa3ffc66f mod_firewall/conditions: Support Lua patterns in JID matching, and make <*>@example.com NOT match example.com
Matthew Wild <mwild1@gmail.com>
parents: 954
diff changeset
    44
		end
2078
86427261e3c4 mod_firewall: Use string.find in JID match, faster since the result is unused
Kim Alvefur <zash@zash.se>
parents: 2077
diff changeset
    45
		return ("(%s and %s:find(%q))"):format(part, part, "^"..pattern.."$");
947
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    46
	else
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    47
		return ("%s == %q"):format(part, match);
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    48
	end
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    49
end
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    50
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    51
local function compile_jid_match(which, match_jid)
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    52
	local match_node, match_host, match_resource = jid.split(match_jid);
963
c7fca2c9e24f mod_firewall/conditions: Don't use table.insert, so things are happy when compile_jid_match() returns nil
Matthew Wild <mwild1@gmail.com>
parents: 962
diff changeset
    53
	local conditions = {};
c7fca2c9e24f mod_firewall/conditions: Don't use table.insert, so things are happy when compile_jid_match() returns nil
Matthew Wild <mwild1@gmail.com>
parents: 962
diff changeset
    54
	conditions[#conditions+1] = compile_jid_match_part(which.."_node", match_node);
c7fca2c9e24f mod_firewall/conditions: Don't use table.insert, so things are happy when compile_jid_match() returns nil
Matthew Wild <mwild1@gmail.com>
parents: 962
diff changeset
    55
	conditions[#conditions+1] = compile_jid_match_part(which.."_host", match_host);
c7fca2c9e24f mod_firewall/conditions: Don't use table.insert, so things are happy when compile_jid_match() returns nil
Matthew Wild <mwild1@gmail.com>
parents: 962
diff changeset
    56
	if match_resource then
c7fca2c9e24f mod_firewall/conditions: Don't use table.insert, so things are happy when compile_jid_match() returns nil
Matthew Wild <mwild1@gmail.com>
parents: 962
diff changeset
    57
		conditions[#conditions+1] = compile_jid_match_part(which.."_resource", match_resource);
c7fca2c9e24f mod_firewall/conditions: Don't use table.insert, so things are happy when compile_jid_match() returns nil
Matthew Wild <mwild1@gmail.com>
parents: 962
diff changeset
    58
	end
947
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    59
	return table.concat(conditions, " and ");
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    60
end
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    61
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    62
function condition_handlers.TO(to)
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    63
	return compile_jid_match("to", to), { "split_to" };
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    64
end
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    65
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    66
function condition_handlers.FROM(from)
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    67
	return compile_jid_match("from", from), { "split_from" };
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    68
end
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    69
2040
7ba6ed553c93 mod_firewall/conditions: Add FROM_EXACTLY and TO_EXACTLY
Matthew Wild <mwild1@gmail.com>
parents: 997
diff changeset
    70
function condition_handlers.FROM_EXACTLY(from)
2556
18b6a55dd5d6 mod_firewall: Support expressions in TO/FROM EXACTLY
Matthew Wild <mwild1@gmail.com>
parents: 2549
diff changeset
    71
	local metadeps = {};
18b6a55dd5d6 mod_firewall: Support expressions in TO/FROM EXACTLY
Matthew Wild <mwild1@gmail.com>
parents: 2549
diff changeset
    72
	return ("from == %s"):format(metaq(from, metadeps)), { "from", unpack(metadeps) };
2040
7ba6ed553c93 mod_firewall/conditions: Add FROM_EXACTLY and TO_EXACTLY
Matthew Wild <mwild1@gmail.com>
parents: 997
diff changeset
    73
end
7ba6ed553c93 mod_firewall/conditions: Add FROM_EXACTLY and TO_EXACTLY
Matthew Wild <mwild1@gmail.com>
parents: 997
diff changeset
    74
7ba6ed553c93 mod_firewall/conditions: Add FROM_EXACTLY and TO_EXACTLY
Matthew Wild <mwild1@gmail.com>
parents: 997
diff changeset
    75
function condition_handlers.TO_EXACTLY(to)
2556
18b6a55dd5d6 mod_firewall: Support expressions in TO/FROM EXACTLY
Matthew Wild <mwild1@gmail.com>
parents: 2549
diff changeset
    76
	local metadeps = {};
18b6a55dd5d6 mod_firewall: Support expressions in TO/FROM EXACTLY
Matthew Wild <mwild1@gmail.com>
parents: 2549
diff changeset
    77
	return ("to == %s"):format(metaq(to, metadeps)), { "to", unpack(metadeps) };
2040
7ba6ed553c93 mod_firewall/conditions: Add FROM_EXACTLY and TO_EXACTLY
Matthew Wild <mwild1@gmail.com>
parents: 997
diff changeset
    78
end
7ba6ed553c93 mod_firewall/conditions: Add FROM_EXACTLY and TO_EXACTLY
Matthew Wild <mwild1@gmail.com>
parents: 997
diff changeset
    79
2469
bd69ffe071e6 mod_firewall: Add 'TO SELF' check ('NOT TO?' worked until commit 9159f9166893)
Matthew Wild <mwild1@gmail.com>
parents: 2407
diff changeset
    80
function condition_handlers.TO_SELF()
2567
2f1e25706f81 mod_firewall: TO SELF: Use raw stanza.attr.to directly, as 'to' defaults to bare JID if nil
Matthew Wild <mwild1@gmail.com>
parents: 2559
diff changeset
    81
	-- Intentionally not using 'to' here, as that defaults to bare JID when nil
2f1e25706f81 mod_firewall: TO SELF: Use raw stanza.attr.to directly, as 'to' defaults to bare JID if nil
Matthew Wild <mwild1@gmail.com>
parents: 2559
diff changeset
    82
	return ("stanza.attr.to == nil");
2469
bd69ffe071e6 mod_firewall: Add 'TO SELF' check ('NOT TO?' worked until commit 9159f9166893)
Matthew Wild <mwild1@gmail.com>
parents: 2407
diff changeset
    83
end
bd69ffe071e6 mod_firewall: Add 'TO SELF' check ('NOT TO?' worked until commit 9159f9166893)
Matthew Wild <mwild1@gmail.com>
parents: 2407
diff changeset
    84
947
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    85
function condition_handlers.TYPE(type)
2586
ac3140cd89a2 mod_firewall: Fix compilation error if TYPE/KIND had no parameter
Matthew Wild <mwild1@gmail.com>
parents: 2581
diff changeset
    86
	assert(type, "Expected 'type' value to match against");
979
cec42f884475 mod_firewall: The default value of the 'type' attribute on message stanzas is 'normal'
Kim Alvefur <zash@zash.se>
parents: 971
diff changeset
    87
	return compile_comparison_list("(type or (name == 'message' and 'normal') or (name == 'presence' and 'available'))", type), { "type", "name" };
964
04e85eb3dfef mod_firewall/conditions: Default types for message and presence
Matthew Wild <mwild1@gmail.com>
parents: 963
diff changeset
    88
end
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: 964
diff changeset
    89
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: 964
diff changeset
    90
local function zone_check(zone, which)
2932
b0d92332b87f mod_firewall: Add special case for $local zone (fixes #1090)
Kim Alvefur <zash@zash.se>
parents: 2920
diff changeset
    91
	local zone_var = zone;
b0d92332b87f mod_firewall: Add special case for $local zone (fixes #1090)
Kim Alvefur <zash@zash.se>
parents: 2920
diff changeset
    92
	if zone == "$local" then zone_var = "_local" end
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: 964
diff changeset
    93
	local which_not = which == "from" and "to" or "from";
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: 964
diff changeset
    94
	return ("(zone_%s[%s_host] or zone_%s[%s] or zone_%s[bare_%s]) "
2123
5f6c18fd0161 mod_firewall: Correct zone condition to check bare JID
Kim Alvefur <zash@zash.se>
parents: 2120
diff changeset
    95
		.."and not(zone_%s[%s_host] or zone_%s[%s] or zone_%s[bare_%s])"
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: 964
diff changeset
    96
		)
2932
b0d92332b87f mod_firewall: Add special case for $local zone (fixes #1090)
Kim Alvefur <zash@zash.se>
parents: 2920
diff changeset
    97
		:format(zone_var, which, zone_var, which, zone_var, which,
b0d92332b87f mod_firewall: Add special case for $local zone (fixes #1090)
Kim Alvefur <zash@zash.se>
parents: 2920
diff changeset
    98
		zone_var, which_not, zone_var, which_not, zone_var, which_not), {
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: 964
diff changeset
    99
			"split_to", "split_from", "bare_to", "bare_from", "zone:"..zone
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: 964
diff changeset
   100
		};
947
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   101
end
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   102
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   103
function condition_handlers.ENTERING(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: 964
diff changeset
   104
	return zone_check(zone, "to");
947
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   105
end
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   106
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   107
function condition_handlers.LEAVING(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: 964
diff changeset
   108
	return zone_check(zone, "from");
947
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   109
end
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   110
2541
acdc1767a715 mod_firewall: Make parameter to 'IN ROSTER' optional
Matthew Wild <mwild1@gmail.com>
parents: 2538
diff changeset
   111
-- IN ROSTER? (parameter is deprecated)
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: 2132
diff changeset
   112
function condition_handlers.IN_ROSTER(yes_no)
2541
acdc1767a715 mod_firewall: Make parameter to 'IN ROSTER' optional
Matthew Wild <mwild1@gmail.com>
parents: 2538
diff changeset
   113
	local in_roster_requirement = string_to_boolean(yes_no or "yes"); -- COMPAT w/ older scripts
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: 2132
diff changeset
   114
	return "not "..(in_roster_requirement and "not" or "").." roster_entry", { "roster_entry" };
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: 2132
diff changeset
   115
end
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: 2132
diff changeset
   116
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: 2132
diff changeset
   117
function condition_handlers.IN_ROSTER_GROUP(group)
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: 2132
diff changeset
   118
	return ("not not (roster_entry and roster_entry.groups[%q])"):format(group), { "roster_entry" };
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: 2132
diff changeset
   119
end
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: 2132
diff changeset
   120
2407
f96bdfd81eba mod_firewall: SUBSCRIBED - condition that is true if the receiver of a stanza is subscribed to the sender
Kim Alvefur <zash@zash.se>
parents: 2390
diff changeset
   121
function condition_handlers.SUBSCRIBED()
2861
ff1666716d10 mod_firewall: Make SUBSCRIBED match for stanzas sent to self (fixes #1052)
Kim Alvefur <zash@zash.se>
parents: 2622
diff changeset
   122
	return "(bare_to == bare_from or to_node and rostermanager.is_contact_subscribed(to_node, to_host, bare_from))",
ff1666716d10 mod_firewall: Make SUBSCRIBED match for stanzas sent to self (fixes #1052)
Kim Alvefur <zash@zash.se>
parents: 2622
diff changeset
   123
	       { "rostermanager", "split_to", "bare_to", "bare_from" };
2407
f96bdfd81eba mod_firewall: SUBSCRIBED - condition that is true if the receiver of a stanza is subscribed to the sender
Kim Alvefur <zash@zash.se>
parents: 2390
diff changeset
   124
end
f96bdfd81eba mod_firewall: SUBSCRIBED - condition that is true if the receiver of a stanza is subscribed to the sender
Kim Alvefur <zash@zash.se>
parents: 2390
diff changeset
   125
2920
b1cdcbcd1c90 mod_firewall: Add PENDING SUBSCRIPTION FROM SENDER? condition
Matthew Wild <mwild1@gmail.com>
parents: 2898
diff changeset
   126
function condition_handlers.PENDING_SUBSCRIPTION_FROM_SENDER()
b1cdcbcd1c90 mod_firewall: Add PENDING SUBSCRIPTION FROM SENDER? condition
Matthew Wild <mwild1@gmail.com>
parents: 2898
diff changeset
   127
	return "(bare_to == bare_from or to_node and rostermanager.is_contact_pending_in(to_node, to_host, bare_from))",
3986
ab065ff4628b mod_firewall: Remove trailing whitespace
Kim Alvefur <zash@zash.se>
parents: 3977
diff changeset
   128
	       { "rostermanager", "split_to", "bare_to", "bare_from" };
2920
b1cdcbcd1c90 mod_firewall: Add PENDING SUBSCRIPTION FROM SENDER? condition
Matthew Wild <mwild1@gmail.com>
parents: 2898
diff changeset
   129
end
b1cdcbcd1c90 mod_firewall: Add PENDING SUBSCRIPTION FROM SENDER? condition
Matthew Wild <mwild1@gmail.com>
parents: 2898
diff changeset
   130
947
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   131
function condition_handlers.PAYLOAD(payload_ns)
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   132
	return ("stanza:get_child(nil, %q)"):format(payload_ns);
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   133
end
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   134
954
bec5b6e2eab8 mod_firewall: Add INSPECT conditional, for deeper inspection of stanzas
Kim Alvefur <zash@zash.se>
parents: 947
diff changeset
   135
function condition_handlers.INSPECT(path)
bec5b6e2eab8 mod_firewall: Add INSPECT conditional, for deeper inspection of stanzas
Kim Alvefur <zash@zash.se>
parents: 947
diff changeset
   136
	if path:find("=") then
2390
00eed68f63bf mod_firewall: INSPECT: support for literal substring search and expressions
Matthew Wild <mwild1@gmail.com>
parents: 2367
diff changeset
   137
		local query, match_type, value = path:match("(.-)([~/$]*)=(.*)");
2366
c065ab67d807 mod_firewall: INSPECT: Emit compilation error when the given stanza path is used for comparison but doesn't return a string
Matthew Wild <mwild1@gmail.com>
parents: 2346
diff changeset
   138
		if not(query:match("#$") or query:match("@[^/]+")) then
c065ab67d807 mod_firewall: INSPECT: Emit compilation error when the given stanza path is used for comparison but doesn't return a string
Matthew Wild <mwild1@gmail.com>
parents: 2346
diff changeset
   139
			error("Stanza path does not return a string (append # for text content or @name for value of named attribute)", 0);
c065ab67d807 mod_firewall: INSPECT: Emit compilation error when the given stanza path is used for comparison but doesn't return a string
Matthew Wild <mwild1@gmail.com>
parents: 2346
diff changeset
   140
		end
2523
d4bc434a60a4 mod_firewall: Update functions that use meta() to allow functions with deps inside expressions
Matthew Wild <mwild1@gmail.com>
parents: 2469
diff changeset
   141
		local meta_deps = {};
2390
00eed68f63bf mod_firewall: INSPECT: support for literal substring search and expressions
Matthew Wild <mwild1@gmail.com>
parents: 2367
diff changeset
   142
		local quoted_value = ("%q"):format(value);
00eed68f63bf mod_firewall: INSPECT: support for literal substring search and expressions
Matthew Wild <mwild1@gmail.com>
parents: 2367
diff changeset
   143
		if match_type:find("$", 1, true) then
00eed68f63bf mod_firewall: INSPECT: support for literal substring search and expressions
Matthew Wild <mwild1@gmail.com>
parents: 2367
diff changeset
   144
			match_type = match_type:gsub("%$", "");
2523
d4bc434a60a4 mod_firewall: Update functions that use meta() to allow functions with deps inside expressions
Matthew Wild <mwild1@gmail.com>
parents: 2469
diff changeset
   145
			quoted_value = meta(quoted_value, meta_deps);
2390
00eed68f63bf mod_firewall: INSPECT: support for literal substring search and expressions
Matthew Wild <mwild1@gmail.com>
parents: 2367
diff changeset
   146
		end
00eed68f63bf mod_firewall: INSPECT: support for literal substring search and expressions
Matthew Wild <mwild1@gmail.com>
parents: 2367
diff changeset
   147
		if match_type == "~" then -- Lua pattern match
2523
d4bc434a60a4 mod_firewall: Update functions that use meta() to allow functions with deps inside expressions
Matthew Wild <mwild1@gmail.com>
parents: 2469
diff changeset
   148
			return ("(stanza:find(%q) or ''):match(%s)"):format(query, quoted_value), meta_deps;
2390
00eed68f63bf mod_firewall: INSPECT: support for literal substring search and expressions
Matthew Wild <mwild1@gmail.com>
parents: 2367
diff changeset
   149
		elseif match_type == "/" then -- find literal substring
2523
d4bc434a60a4 mod_firewall: Update functions that use meta() to allow functions with deps inside expressions
Matthew Wild <mwild1@gmail.com>
parents: 2469
diff changeset
   150
			return ("(stanza:find(%q) or ''):find(%s, 1, true)"):format(query, quoted_value), meta_deps;
2390
00eed68f63bf mod_firewall: INSPECT: support for literal substring search and expressions
Matthew Wild <mwild1@gmail.com>
parents: 2367
diff changeset
   151
		elseif match_type == "" then -- exact match
2523
d4bc434a60a4 mod_firewall: Update functions that use meta() to allow functions with deps inside expressions
Matthew Wild <mwild1@gmail.com>
parents: 2469
diff changeset
   152
			return ("stanza:find(%q) == %s"):format(query, quoted_value), meta_deps;
2113
9db4113d0cb5 mod_firewall: INSPECT: Support for pattern matches (confusingly using ~= instead of =)
Matthew Wild <mwild1@gmail.com>
parents: 2111
diff changeset
   153
		else
2390
00eed68f63bf mod_firewall: INSPECT: support for literal substring search and expressions
Matthew Wild <mwild1@gmail.com>
parents: 2367
diff changeset
   154
			error("Unrecognised comparison '"..match_type.."='", 0);
2113
9db4113d0cb5 mod_firewall: INSPECT: Support for pattern matches (confusingly using ~= instead of =)
Matthew Wild <mwild1@gmail.com>
parents: 2111
diff changeset
   155
		end
954
bec5b6e2eab8 mod_firewall: Add INSPECT conditional, for deeper inspection of stanzas
Kim Alvefur <zash@zash.se>
parents: 947
diff changeset
   156
	end
bec5b6e2eab8 mod_firewall: Add INSPECT conditional, for deeper inspection of stanzas
Kim Alvefur <zash@zash.se>
parents: 947
diff changeset
   157
	return ("stanza:find(%q)"):format(path);
bec5b6e2eab8 mod_firewall: Add INSPECT conditional, for deeper inspection of stanzas
Kim Alvefur <zash@zash.se>
parents: 947
diff changeset
   158
end
bec5b6e2eab8 mod_firewall: Add INSPECT conditional, for deeper inspection of stanzas
Kim Alvefur <zash@zash.se>
parents: 947
diff changeset
   159
947
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   160
function condition_handlers.FROM_GROUP(group_name)
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   161
	return ("group_contains(%q, bare_from)"):format(group_name), { "group_contains", "bare_from" };
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   162
end
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
function condition_handlers.TO_GROUP(group_name)
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   165
	return ("group_contains(%q, bare_to)"):format(group_name), { "group_contains", "bare_to" };
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   166
end
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   167
2598
1e1c929c1aa5 mod_firewall: Add and document CROSSING GROUPS condition
Matthew Wild <mwild1@gmail.com>
parents: 2588
diff changeset
   168
function condition_handlers.CROSSING_GROUPS(group_names)
1e1c929c1aa5 mod_firewall: Add and document CROSSING GROUPS condition
Matthew Wild <mwild1@gmail.com>
parents: 2588
diff changeset
   169
	local code = {};
1e1c929c1aa5 mod_firewall: Add and document CROSSING GROUPS condition
Matthew Wild <mwild1@gmail.com>
parents: 2588
diff changeset
   170
	for group_name in group_names:gmatch("([^, ][^,]+)") do
1e1c929c1aa5 mod_firewall: Add and document CROSSING GROUPS condition
Matthew Wild <mwild1@gmail.com>
parents: 2588
diff changeset
   171
		group_name = group_name:match("^%s*(.-)%s*$"); -- Trim leading/trailing whitespace
1e1c929c1aa5 mod_firewall: Add and document CROSSING GROUPS condition
Matthew Wild <mwild1@gmail.com>
parents: 2588
diff changeset
   172
		-- Just check that's it is crossing from outside group to inside group
1e1c929c1aa5 mod_firewall: Add and document CROSSING GROUPS condition
Matthew Wild <mwild1@gmail.com>
parents: 2588
diff changeset
   173
		table.insert(code, ("(group_contains(%q, bare_to) and group_contains(%q, bare_from))"):format(group_name, group_name))
1e1c929c1aa5 mod_firewall: Add and document CROSSING GROUPS condition
Matthew Wild <mwild1@gmail.com>
parents: 2588
diff changeset
   174
	end
1e1c929c1aa5 mod_firewall: Add and document CROSSING GROUPS condition
Matthew Wild <mwild1@gmail.com>
parents: 2588
diff changeset
   175
	return "not "..table.concat(code, " or "), { "group_contains", "bare_to", "bare_from" };
1e1c929c1aa5 mod_firewall: Add and document CROSSING GROUPS condition
Matthew Wild <mwild1@gmail.com>
parents: 2588
diff changeset
   176
end
1e1c929c1aa5 mod_firewall: Add and document CROSSING GROUPS condition
Matthew Wild <mwild1@gmail.com>
parents: 2588
diff changeset
   177
5006
84997bc3f92e mod_firewall: Update for role-auth (backwards compatible)
Matthew Wild <mwild1@gmail.com>
parents: 4612
diff changeset
   178
-- COMPAT w/0.12: Deprecated
947
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   179
function condition_handlers.FROM_ADMIN_OF(host)
2581
00cef058df8d mod_firewall: TO/FROM ADMIN OF: Fix string quoting
Matthew Wild <mwild1@gmail.com>
parents: 2579
diff changeset
   180
	return ("is_admin(bare_from, %s)"):format(host ~= "*" and metaq(host) or nil), { "is_admin", "bare_from" };
947
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   181
end
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   182
5006
84997bc3f92e mod_firewall: Update for role-auth (backwards compatible)
Matthew Wild <mwild1@gmail.com>
parents: 4612
diff changeset
   183
-- COMPAT w/0.12: Deprecated
947
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   184
function condition_handlers.TO_ADMIN_OF(host)
2581
00cef058df8d mod_firewall: TO/FROM ADMIN OF: Fix string quoting
Matthew Wild <mwild1@gmail.com>
parents: 2579
diff changeset
   185
	return ("is_admin(bare_to, %s)"):format(host ~= "*" and metaq(host) or nil), { "is_admin", "bare_to" };
947
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   186
end
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   187
5006
84997bc3f92e mod_firewall: Update for role-auth (backwards compatible)
Matthew Wild <mwild1@gmail.com>
parents: 4612
diff changeset
   188
-- COMPAT w/0.12: Deprecated
2557
7ed2a66bfabd mod_firewall: Add TO/FROM ADMIN
Matthew Wild <mwild1@gmail.com>
parents: 2556
diff changeset
   189
function condition_handlers.FROM_ADMIN()
2579
214b49d05ea1 mod_firewall: Fix TO/FROM ADMIN to use current (module) host
Matthew Wild <mwild1@gmail.com>
parents: 2568
diff changeset
   190
	return ("is_admin(bare_from, current_host)"), { "is_admin", "bare_from", "current_host" };
2557
7ed2a66bfabd mod_firewall: Add TO/FROM ADMIN
Matthew Wild <mwild1@gmail.com>
parents: 2556
diff changeset
   191
end
7ed2a66bfabd mod_firewall: Add TO/FROM ADMIN
Matthew Wild <mwild1@gmail.com>
parents: 2556
diff changeset
   192
5006
84997bc3f92e mod_firewall: Update for role-auth (backwards compatible)
Matthew Wild <mwild1@gmail.com>
parents: 4612
diff changeset
   193
-- COMPAT w/0.12: Deprecated
2557
7ed2a66bfabd mod_firewall: Add TO/FROM ADMIN
Matthew Wild <mwild1@gmail.com>
parents: 2556
diff changeset
   194
function condition_handlers.TO_ADMIN()
2579
214b49d05ea1 mod_firewall: Fix TO/FROM ADMIN to use current (module) host
Matthew Wild <mwild1@gmail.com>
parents: 2568
diff changeset
   195
	return ("is_admin(bare_to, current_host)"), { "is_admin", "bare_to", "current_host" };
2557
7ed2a66bfabd mod_firewall: Add TO/FROM ADMIN
Matthew Wild <mwild1@gmail.com>
parents: 2556
diff changeset
   196
end
7ed2a66bfabd mod_firewall: Add TO/FROM ADMIN
Matthew Wild <mwild1@gmail.com>
parents: 2556
diff changeset
   197
5006
84997bc3f92e mod_firewall: Update for role-auth (backwards compatible)
Matthew Wild <mwild1@gmail.com>
parents: 4612
diff changeset
   198
-- MAY: permission_to_check
84997bc3f92e mod_firewall: Update for role-auth (backwards compatible)
Matthew Wild <mwild1@gmail.com>
parents: 4612
diff changeset
   199
function condition_handlers.MAY(permission_to_check)
84997bc3f92e mod_firewall: Update for role-auth (backwards compatible)
Matthew Wild <mwild1@gmail.com>
parents: 4612
diff changeset
   200
	return ("module:may(%q, event)"):format(permission_to_check);
84997bc3f92e mod_firewall: Update for role-auth (backwards compatible)
Matthew Wild <mwild1@gmail.com>
parents: 4612
diff changeset
   201
end
84997bc3f92e mod_firewall: Update for role-auth (backwards compatible)
Matthew Wild <mwild1@gmail.com>
parents: 4612
diff changeset
   202
84997bc3f92e mod_firewall: Update for role-auth (backwards compatible)
Matthew Wild <mwild1@gmail.com>
parents: 4612
diff changeset
   203
function condition_handlers.TO_ROLE(role_name)
84997bc3f92e mod_firewall: Update for role-auth (backwards compatible)
Matthew Wild <mwild1@gmail.com>
parents: 4612
diff changeset
   204
	return ("get_jid_role(bare_to, current_host) == %q"):format(role_name), { "get_jid_role", "current_host", "bare_to" };
84997bc3f92e mod_firewall: Update for role-auth (backwards compatible)
Matthew Wild <mwild1@gmail.com>
parents: 4612
diff changeset
   205
end
84997bc3f92e mod_firewall: Update for role-auth (backwards compatible)
Matthew Wild <mwild1@gmail.com>
parents: 4612
diff changeset
   206
84997bc3f92e mod_firewall: Update for role-auth (backwards compatible)
Matthew Wild <mwild1@gmail.com>
parents: 4612
diff changeset
   207
function condition_handlers.FROM_ROLE(role_name)
84997bc3f92e mod_firewall: Update for role-auth (backwards compatible)
Matthew Wild <mwild1@gmail.com>
parents: 4612
diff changeset
   208
	return ("get_jid_role(bare_from, current_host) == %q"):format(role_name), { "get_jid_role", "current_host", "bare_from" };
84997bc3f92e mod_firewall: Update for role-auth (backwards compatible)
Matthew Wild <mwild1@gmail.com>
parents: 4612
diff changeset
   209
end
84997bc3f92e mod_firewall: Update for role-auth (backwards compatible)
Matthew Wild <mwild1@gmail.com>
parents: 4612
diff changeset
   210
968
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   211
local day_numbers = { sun = 0, mon = 2, tue = 3, wed = 4, thu = 5, fri = 6, sat = 7 };
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   212
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   213
local function current_time_check(op, hour, minute)
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   214
	hour, minute = tonumber(hour), tonumber(minute);
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   215
	local adj_op = op == "<" and "<" or ">="; -- Start time inclusive, end time exclusive
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   216
	if minute == 0 then
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   217
		return "(current_hour"..adj_op..hour..")";
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   218
	else
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   219
		return "((current_hour"..op..hour..") or (current_hour == "..hour.." and current_minute"..adj_op..minute.."))";
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   220
	end
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   221
end
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   222
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   223
local function resolve_day_number(day_name)
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   224
	return assert(day_numbers[day_name:sub(1,3):lower()], "Unknown day name: "..day_name);
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   225
end
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   226
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   227
function condition_handlers.DAY(days)
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   228
	local conditions = {};
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   229
	for day_range in days:gmatch("[^,]+") do
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   230
		local day_start, day_end = day_range:match("(%a+)%s*%-%s*(%a+)");
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   231
		if day_start and day_end then
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   232
			local day_start_num, day_end_num = resolve_day_number(day_start), resolve_day_number(day_end);
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   233
			local op = "and";
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   234
			if day_end_num < day_start_num then
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   235
				op = "or";
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   236
			end
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   237
			table.insert(conditions, ("current_day >= %d %s current_day <= %d"):format(day_start_num, op, day_end_num));
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: 2040
diff changeset
   238
		elseif day_range:find("%a") then
968
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   239
			local day = resolve_day_number(day_range:match("%a+"));
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   240
			table.insert(conditions, "current_day == "..day);
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   241
		else
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   242
			error("Unable to parse day/day range: "..day_range);
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   243
		end
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   244
	end
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   245
	assert(#conditions>0, "Expected a list of days or day ranges");
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   246
	return "("..table.concat(conditions, ") or (")..")", { "time:day" };
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   247
end
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   248
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   249
function condition_handlers.TIME(ranges)
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   250
	local conditions = {};
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   251
	for range in ranges:gmatch("([^,]+)") do
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   252
		local clause = {};
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   253
		range = range:lower()
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   254
			:gsub("(%d+):?(%d*) *am", function (h, m) return tostring(tonumber(h)%12)..":"..(tonumber(m) or "00"); end)
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   255
			:gsub("(%d+):?(%d*) *pm", function (h, m) return tostring(tonumber(h)%12+12)..":"..(tonumber(m) or "00"); end);
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   256
		local start_hour, start_minute = range:match("(%d+):(%d+) *%-");
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   257
		local end_hour, end_minute = range:match("%- *(%d+):(%d+)");
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   258
		local op = tonumber(start_hour) > tonumber(end_hour) and " or " or " and ";
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   259
		if start_hour and end_hour then
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   260
			table.insert(clause, current_time_check(">", start_hour, start_minute));
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   261
			table.insert(clause, current_time_check("<", end_hour, end_minute));
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   262
		end
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   263
		if #clause == 0 then
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   264
			error("Unable to parse time range: "..range);
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   265
		end
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   266
		table.insert(conditions, "("..table.concat(clause, " "..op.." ")..")");
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   267
	end
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   268
	return table.concat(conditions, " or "), { "time:hour,min" };
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   269
end
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   270
2132
21bc4d7cddae mod_firewall: Add support for throttling based on user-defined properties (experimental)
Matthew Wild <mwild1@gmail.com>
parents: 2131
diff changeset
   271
function condition_handlers.LIMIT(spec)
21bc4d7cddae mod_firewall: Add support for throttling based on user-defined properties (experimental)
Matthew Wild <mwild1@gmail.com>
parents: 2131
diff changeset
   272
	local name, param = spec:match("^(%w+) on (.+)$");
2523
d4bc434a60a4 mod_firewall: Update functions that use meta() to allow functions with deps inside expressions
Matthew Wild <mwild1@gmail.com>
parents: 2469
diff changeset
   273
	local meta_deps = {};
2132
21bc4d7cddae mod_firewall: Add support for throttling based on user-defined properties (experimental)
Matthew Wild <mwild1@gmail.com>
parents: 2131
diff changeset
   274
21bc4d7cddae mod_firewall: Add support for throttling based on user-defined properties (experimental)
Matthew Wild <mwild1@gmail.com>
parents: 2131
diff changeset
   275
	if not name then
21bc4d7cddae mod_firewall: Add support for throttling based on user-defined properties (experimental)
Matthew Wild <mwild1@gmail.com>
parents: 2131
diff changeset
   276
		name = spec:match("^%w+$");
21bc4d7cddae mod_firewall: Add support for throttling based on user-defined properties (experimental)
Matthew Wild <mwild1@gmail.com>
parents: 2131
diff changeset
   277
		if not name then
21bc4d7cddae mod_firewall: Add support for throttling based on user-defined properties (experimental)
Matthew Wild <mwild1@gmail.com>
parents: 2131
diff changeset
   278
			error("Unable to parse LIMIT specification");
21bc4d7cddae mod_firewall: Add support for throttling based on user-defined properties (experimental)
Matthew Wild <mwild1@gmail.com>
parents: 2131
diff changeset
   279
		end
21bc4d7cddae mod_firewall: Add support for throttling based on user-defined properties (experimental)
Matthew Wild <mwild1@gmail.com>
parents: 2131
diff changeset
   280
	else
2523
d4bc434a60a4 mod_firewall: Update functions that use meta() to allow functions with deps inside expressions
Matthew Wild <mwild1@gmail.com>
parents: 2469
diff changeset
   281
		param = meta(("%q"):format(param), meta_deps);
2132
21bc4d7cddae mod_firewall: Add support for throttling based on user-defined properties (experimental)
Matthew Wild <mwild1@gmail.com>
parents: 2131
diff changeset
   282
	end
21bc4d7cddae mod_firewall: Add support for throttling based on user-defined properties (experimental)
Matthew Wild <mwild1@gmail.com>
parents: 2131
diff changeset
   283
21bc4d7cddae mod_firewall: Add support for throttling based on user-defined properties (experimental)
Matthew Wild <mwild1@gmail.com>
parents: 2131
diff changeset
   284
	if not param then
2523
d4bc434a60a4 mod_firewall: Update functions that use meta() to allow functions with deps inside expressions
Matthew Wild <mwild1@gmail.com>
parents: 2469
diff changeset
   285
		return ("not global_throttle_%s:poll(1)"):format(name), { "globalthrottle:"..name, unpack(meta_deps) };
2132
21bc4d7cddae mod_firewall: Add support for throttling based on user-defined properties (experimental)
Matthew Wild <mwild1@gmail.com>
parents: 2131
diff changeset
   286
	end
2863
22e11645a895 mod_firewall: Trim trailing whitespace [luacheck]
Kim Alvefur <zash@zash.se>
parents: 2861
diff changeset
   287
	return ("not multi_throttle_%s:poll_on(%s, 1)"):format(name, param), { "multithrottle:"..name, unpack(meta_deps) };
971
53e158e44a44 mod_firewall: Add rate limiting capabilities, and keep zones and throttle objects in shared tables
Matthew Wild <mwild1@gmail.com>
parents: 968
diff changeset
   288
end
53e158e44a44 mod_firewall: Add rate limiting capabilities, and keep zones and throttle objects in shared tables
Matthew Wild <mwild1@gmail.com>
parents: 968
diff changeset
   289
2111
f445f43b9ba1 mod_firewall: Add support for session marking (MARK_ORIGIN, UNMARK_ORIGIN, ORIGIN_MARKED)
Matthew Wild <mwild1@gmail.com>
parents: 2079
diff changeset
   290
function condition_handlers.ORIGIN_MARKED(name_and_time)
2131
59023dffbdd4 mod_firewall: Allow underscore in mark names (thanks Ge0rG)
Matthew Wild <mwild1@gmail.com>
parents: 2129
diff changeset
   291
	local name, time = name_and_time:match("^%s*([%w_]+)%s+%(([^)]+)s%)%s*$");
2111
f445f43b9ba1 mod_firewall: Add support for session marking (MARK_ORIGIN, UNMARK_ORIGIN, ORIGIN_MARKED)
Matthew Wild <mwild1@gmail.com>
parents: 2079
diff changeset
   292
	if not name then
2131
59023dffbdd4 mod_firewall: Allow underscore in mark names (thanks Ge0rG)
Matthew Wild <mwild1@gmail.com>
parents: 2129
diff changeset
   293
		name = name_and_time:match("^%s*([%w_]+)%s*$");
2111
f445f43b9ba1 mod_firewall: Add support for session marking (MARK_ORIGIN, UNMARK_ORIGIN, ORIGIN_MARKED)
Matthew Wild <mwild1@gmail.com>
parents: 2079
diff changeset
   294
	end
f445f43b9ba1 mod_firewall: Add support for session marking (MARK_ORIGIN, UNMARK_ORIGIN, ORIGIN_MARKED)
Matthew Wild <mwild1@gmail.com>
parents: 2079
diff changeset
   295
	if not name then
f445f43b9ba1 mod_firewall: Add support for session marking (MARK_ORIGIN, UNMARK_ORIGIN, ORIGIN_MARKED)
Matthew Wild <mwild1@gmail.com>
parents: 2079
diff changeset
   296
		error("Error parsing mark name, see documentation for usage examples");
f445f43b9ba1 mod_firewall: Add support for session marking (MARK_ORIGIN, UNMARK_ORIGIN, ORIGIN_MARKED)
Matthew Wild <mwild1@gmail.com>
parents: 2079
diff changeset
   297
	end
f445f43b9ba1 mod_firewall: Add support for session marking (MARK_ORIGIN, UNMARK_ORIGIN, ORIGIN_MARKED)
Matthew Wild <mwild1@gmail.com>
parents: 2079
diff changeset
   298
	if time then
2120
2bb42ba342f3 mod_firewall: Fix usage of incorrect variable current_time in ORIGIN_MARKED condition (thanks Ge0rG)
Matthew Wild <mwild1@gmail.com>
parents: 2113
diff changeset
   299
		return ("(current_timestamp - (session.firewall_marked_%s or 0)) < %d"):format(idsafe(name), tonumber(time)), { "timestamp" };
2111
f445f43b9ba1 mod_firewall: Add support for session marking (MARK_ORIGIN, UNMARK_ORIGIN, ORIGIN_MARKED)
Matthew Wild <mwild1@gmail.com>
parents: 2079
diff changeset
   300
	end
f445f43b9ba1 mod_firewall: Add support for session marking (MARK_ORIGIN, UNMARK_ORIGIN, ORIGIN_MARKED)
Matthew Wild <mwild1@gmail.com>
parents: 2079
diff changeset
   301
	return ("not not session.firewall_marked_"..idsafe(name));
f445f43b9ba1 mod_firewall: Add support for session marking (MARK_ORIGIN, UNMARK_ORIGIN, ORIGIN_MARKED)
Matthew Wild <mwild1@gmail.com>
parents: 2079
diff changeset
   302
end
f445f43b9ba1 mod_firewall: Add support for session marking (MARK_ORIGIN, UNMARK_ORIGIN, ORIGIN_MARKED)
Matthew Wild <mwild1@gmail.com>
parents: 2079
diff changeset
   303
2898
165d2877eeac mod_firewall: Add experimental user-centric persistent marks behind a feature flag
Kim Alvefur <zash@zash.se>
parents: 2886
diff changeset
   304
function condition_handlers.USER_MARKED(name_and_time)
165d2877eeac mod_firewall: Add experimental user-centric persistent marks behind a feature flag
Kim Alvefur <zash@zash.se>
parents: 2886
diff changeset
   305
	local name, time = name_and_time:match("^%s*([%w_]+)%s+%(([^)]+)s%)%s*$");
165d2877eeac mod_firewall: Add experimental user-centric persistent marks behind a feature flag
Kim Alvefur <zash@zash.se>
parents: 2886
diff changeset
   306
	if not name then
165d2877eeac mod_firewall: Add experimental user-centric persistent marks behind a feature flag
Kim Alvefur <zash@zash.se>
parents: 2886
diff changeset
   307
		name = name_and_time:match("^%s*([%w_]+)%s*$");
165d2877eeac mod_firewall: Add experimental user-centric persistent marks behind a feature flag
Kim Alvefur <zash@zash.se>
parents: 2886
diff changeset
   308
	end
165d2877eeac mod_firewall: Add experimental user-centric persistent marks behind a feature flag
Kim Alvefur <zash@zash.se>
parents: 2886
diff changeset
   309
	if not name then
165d2877eeac mod_firewall: Add experimental user-centric persistent marks behind a feature flag
Kim Alvefur <zash@zash.se>
parents: 2886
diff changeset
   310
		error("Error parsing mark name, see documentation for usage examples");
165d2877eeac mod_firewall: Add experimental user-centric persistent marks behind a feature flag
Kim Alvefur <zash@zash.se>
parents: 2886
diff changeset
   311
	end
165d2877eeac mod_firewall: Add experimental user-centric persistent marks behind a feature flag
Kim Alvefur <zash@zash.se>
parents: 2886
diff changeset
   312
	if time then
165d2877eeac mod_firewall: Add experimental user-centric persistent marks behind a feature flag
Kim Alvefur <zash@zash.se>
parents: 2886
diff changeset
   313
		return ("(current_timestamp - (session.firewall_marks and session.firewall_marks.%s or 0)) < %d"):format(idsafe(name), tonumber(time)), { "timestamp" };
165d2877eeac mod_firewall: Add experimental user-centric persistent marks behind a feature flag
Kim Alvefur <zash@zash.se>
parents: 2886
diff changeset
   314
	end
165d2877eeac mod_firewall: Add experimental user-centric persistent marks behind a feature flag
Kim Alvefur <zash@zash.se>
parents: 2886
diff changeset
   315
	return ("not not (session.firewall_marks and session.firewall_marks."..idsafe(name)..")");
165d2877eeac mod_firewall: Add experimental user-centric persistent marks behind a feature flag
Kim Alvefur <zash@zash.se>
parents: 2886
diff changeset
   316
end
165d2877eeac mod_firewall: Add experimental user-centric persistent marks behind a feature flag
Kim Alvefur <zash@zash.se>
parents: 2886
diff changeset
   317
2558
19bb4606013f mod_firewall: Fix everything wrong with SENT_DIRECTED_PRESENCE_TO_SENDER
Matthew Wild <mwild1@gmail.com>
parents: 2557
diff changeset
   318
function condition_handlers.SENT_DIRECTED_PRESENCE_TO_SENDER()
2886
6f289283feb1 mod_firewall: Prevent traceback if no directed presence has been sent (fixes #1081)
Kim Alvefur <zash@zash.se>
parents: 2863
diff changeset
   319
	return "not not (session.directed and session.directed[from])", { "from" };
2533
3fe4ca2b55c2 mod_firewall: Add 'SENT DIRECTED PRESENCE TO SENDER?'
Matthew Wild <mwild1@gmail.com>
parents: 2532
diff changeset
   320
end
3fe4ca2b55c2 mod_firewall: Add 'SENT DIRECTED PRESENCE TO SENDER?'
Matthew Wild <mwild1@gmail.com>
parents: 2532
diff changeset
   321
2622
c6652d055ba3 mod_firewall: Add some more comments
Matthew Wild <mwild1@gmail.com>
parents: 2598
diff changeset
   322
-- TO FULL JID?
2559
a9eb4d5566f3 mod_firewall: Add TO FULL JID
Matthew Wild <mwild1@gmail.com>
parents: 2558
diff changeset
   323
function condition_handlers.TO_FULL_JID()
4612
4e8fa75cc678 mod_firewall: Remove reliance on full_sessions being a global
Kim Alvefur <zash@zash.se>
parents: 3986
diff changeset
   324
	return "not not full_sessions[to]", { "to", "full_sessions" };
2559
a9eb4d5566f3 mod_firewall: Add TO FULL JID
Matthew Wild <mwild1@gmail.com>
parents: 2558
diff changeset
   325
end
a9eb4d5566f3 mod_firewall: Add TO FULL JID
Matthew Wild <mwild1@gmail.com>
parents: 2558
diff changeset
   326
2524
c6fd8975704b mod_firewall: Initial support for lists, in-memory and HTTP
Matthew Wild <mwild1@gmail.com>
parents: 2523
diff changeset
   327
-- CHECK LIST: spammers contains $<@from>
c6fd8975704b mod_firewall: Initial support for lists, in-memory and HTTP
Matthew Wild <mwild1@gmail.com>
parents: 2523
diff changeset
   328
function condition_handlers.CHECK_LIST(list_condition)
c6fd8975704b mod_firewall: Initial support for lists, in-memory and HTTP
Matthew Wild <mwild1@gmail.com>
parents: 2523
diff changeset
   329
	local list_name, expr = list_condition:match("(%S+) contains (.+)$");
2525
66b81e144ded mod_firewall: Fix CHECK LIST syntax check
Matthew Wild <mwild1@gmail.com>
parents: 2524
diff changeset
   330
	if not (list_name and expr) then
2524
c6fd8975704b mod_firewall: Initial support for lists, in-memory and HTTP
Matthew Wild <mwild1@gmail.com>
parents: 2523
diff changeset
   331
		error("Error parsing list check, syntax: LISTNAME contains EXPRESSION");
c6fd8975704b mod_firewall: Initial support for lists, in-memory and HTTP
Matthew Wild <mwild1@gmail.com>
parents: 2523
diff changeset
   332
	end
c6fd8975704b mod_firewall: Initial support for lists, in-memory and HTTP
Matthew Wild <mwild1@gmail.com>
parents: 2523
diff changeset
   333
	local meta_deps = {};
c6fd8975704b mod_firewall: Initial support for lists, in-memory and HTTP
Matthew Wild <mwild1@gmail.com>
parents: 2523
diff changeset
   334
	expr = meta(("%q"):format(expr), meta_deps);
c6fd8975704b mod_firewall: Initial support for lists, in-memory and HTTP
Matthew Wild <mwild1@gmail.com>
parents: 2523
diff changeset
   335
	return ("list_%s:contains(%s) == true"):format(list_name, expr), { "list:"..list_name, unpack(meta_deps) };
c6fd8975704b mod_firewall: Initial support for lists, in-memory and HTTP
Matthew Wild <mwild1@gmail.com>
parents: 2523
diff changeset
   336
end
c6fd8975704b mod_firewall: Initial support for lists, in-memory and HTTP
Matthew Wild <mwild1@gmail.com>
parents: 2523
diff changeset
   337
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: 2525
diff changeset
   338
-- SCAN: body for word in badwords
44a71584521d mod_firewall: Add SEARCH, PATTERN definitions and SCAN condition to check tokenized stanza:find() against a list
Matthew Wild <mwild1@gmail.com>
parents: 2525
diff changeset
   339
function condition_handlers.SCAN(scan_expression)
44a71584521d mod_firewall: Add SEARCH, PATTERN definitions and SCAN condition to check tokenized stanza:find() against a list
Matthew Wild <mwild1@gmail.com>
parents: 2525
diff changeset
   340
	local search_name, pattern_name, list_name = scan_expression:match("(%S+) for (%S+) in (%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: 2525
diff changeset
   341
	if not (search_name) then
44a71584521d mod_firewall: Add SEARCH, PATTERN definitions and SCAN condition to check tokenized stanza:find() against a list
Matthew Wild <mwild1@gmail.com>
parents: 2525
diff changeset
   342
		error("Error parsing SCAN expression, syntax: SEARCH for PATTERN in LIST");
44a71584521d mod_firewall: Add SEARCH, PATTERN definitions and SCAN condition to check tokenized stanza:find() against a list
Matthew Wild <mwild1@gmail.com>
parents: 2525
diff changeset
   343
	end
2588
d64fc9c3cffd mod_firewall: Remove ambiguity from tokens dep parameter
Matthew Wild <mwild1@gmail.com>
parents: 2586
diff changeset
   344
	return ("scan_list(list_%s, %s)"):format(list_name, "tokens_"..search_name.."_"..pattern_name), { "scan_list", "tokens:"..search_name.."-"..pattern_name, "list:"..list_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: 2525
diff changeset
   345
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: 2525
diff changeset
   346
2622
c6652d055ba3 mod_firewall: Add some more comments
Matthew Wild <mwild1@gmail.com>
parents: 2598
diff changeset
   347
-- COUNT: lines in body < 10
2549
9b46d24edf0d mod_firewall: Add and document COUNT condition
Matthew Wild <mwild1@gmail.com>
parents: 2541
diff changeset
   348
local valid_comp_ops = { [">"] = ">", ["<"] = "<", ["="] = "==", ["=="] = "==", ["<="] = "<=", [">="] = ">=" };
9b46d24edf0d mod_firewall: Add and document COUNT condition
Matthew Wild <mwild1@gmail.com>
parents: 2541
diff changeset
   349
function condition_handlers.COUNT(count_expression)
9b46d24edf0d mod_firewall: Add and document COUNT condition
Matthew Wild <mwild1@gmail.com>
parents: 2541
diff changeset
   350
	local pattern_name, search_name, comparator_expression = count_expression:match("(%S+) in (%S+) (.+)$");
9b46d24edf0d mod_firewall: Add and document COUNT condition
Matthew Wild <mwild1@gmail.com>
parents: 2541
diff changeset
   351
	if not (pattern_name) then
9b46d24edf0d mod_firewall: Add and document COUNT condition
Matthew Wild <mwild1@gmail.com>
parents: 2541
diff changeset
   352
		error("Error parsing COUNT expression, syntax: PATTERN in SEARCH COMPARATOR");
9b46d24edf0d mod_firewall: Add and document COUNT condition
Matthew Wild <mwild1@gmail.com>
parents: 2541
diff changeset
   353
	end
9b46d24edf0d mod_firewall: Add and document COUNT condition
Matthew Wild <mwild1@gmail.com>
parents: 2541
diff changeset
   354
	local value;
9b46d24edf0d mod_firewall: Add and document COUNT condition
Matthew Wild <mwild1@gmail.com>
parents: 2541
diff changeset
   355
	comparator_expression = comparator_expression:gsub("%d+", function (value_string)
9b46d24edf0d mod_firewall: Add and document COUNT condition
Matthew Wild <mwild1@gmail.com>
parents: 2541
diff changeset
   356
		value = tonumber(value_string);
9b46d24edf0d mod_firewall: Add and document COUNT condition
Matthew Wild <mwild1@gmail.com>
parents: 2541
diff changeset
   357
		return "";
9b46d24edf0d mod_firewall: Add and document COUNT condition
Matthew Wild <mwild1@gmail.com>
parents: 2541
diff changeset
   358
	end);
9b46d24edf0d mod_firewall: Add and document COUNT condition
Matthew Wild <mwild1@gmail.com>
parents: 2541
diff changeset
   359
	if not value then
9b46d24edf0d mod_firewall: Add and document COUNT condition
Matthew Wild <mwild1@gmail.com>
parents: 2541
diff changeset
   360
		error("Error parsing COUNT expression, expected value");
9b46d24edf0d mod_firewall: Add and document COUNT condition
Matthew Wild <mwild1@gmail.com>
parents: 2541
diff changeset
   361
	end
9b46d24edf0d mod_firewall: Add and document COUNT condition
Matthew Wild <mwild1@gmail.com>
parents: 2541
diff changeset
   362
	local comp_op = comparator_expression:gsub("%s+", "");
9b46d24edf0d mod_firewall: Add and document COUNT condition
Matthew Wild <mwild1@gmail.com>
parents: 2541
diff changeset
   363
	assert(valid_comp_ops[comp_op], "Error parsing COUNT expression, unknown comparison operator: "..comp_op);
9b46d24edf0d mod_firewall: Add and document COUNT condition
Matthew Wild <mwild1@gmail.com>
parents: 2541
diff changeset
   364
	return ("it_count(search_%s:gmatch(pattern_%s)) %s %d"):format(search_name, pattern_name, comp_op, value), { "it_count", "search:"..search_name, "pattern:"..pattern_name };
9b46d24edf0d mod_firewall: Add and document COUNT condition
Matthew Wild <mwild1@gmail.com>
parents: 2541
diff changeset
   365
end
9b46d24edf0d mod_firewall: Add and document COUNT condition
Matthew Wild <mwild1@gmail.com>
parents: 2541
diff changeset
   366
947
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   367
return condition_handlers;