mod_firewall/conditions.lib.lua
author Matthew Wild <mwild1@gmail.com>
Fri, 24 Feb 2017 09:50:49 +0000
changeset 2567 2f1e25706f81
parent 2559 a9eb4d5566f3
child 2568 240985f7d1f7
permissions -rw-r--r--
mod_firewall: TO SELF: Use raw stanza.attr.to directly, as 'to' defaults to bare JID if nil
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";
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     5
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
     6
-- 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
     7
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
     8
	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
     9
	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
    10
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
    11
947
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    12
-- 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
    13
-- 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
    14
-- 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
    15
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
    16
	local conditions = {};
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    17
	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
    18
		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
    19
	end
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    20
	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
    21
end
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    22
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    23
function condition_handlers.KIND(kind)
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    24
	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
    25
end
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    26
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    27
local wildcard_equivs = { ["*"] = ".*", ["?"] = "." };
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 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
    30
	if not match then
2075
4161ff87e5a4 mod_firewall/conditions: Add semicolon
Kim Alvefur <zash@zash.se>
parents: 2074
diff changeset
    31
		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
    32
	end
2076
eda5c54dfa30 mod_firewall: Anchor pattern at beginning and end
Kim Alvefur <zash@zash.se>
parents: 2075
diff changeset
    33
	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
    34
	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
    35
		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
    36
			return part;
947
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    37
		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
    38
		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
    39
			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
    40
		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
    41
			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
    42
		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
    43
		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
    44
	else
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    45
		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
    46
	end
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    47
end
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    48
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    49
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
    50
	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
    51
	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
    52
	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
    53
	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
    54
	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
    55
		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
    56
	end
947
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    57
	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
    58
end
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    59
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    60
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
    61
	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
    62
end
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    63
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    64
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
    65
	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
    66
end
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    67
2040
7ba6ed553c93 mod_firewall/conditions: Add FROM_EXACTLY and TO_EXACTLY
Matthew Wild <mwild1@gmail.com>
parents: 997
diff changeset
    68
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
    69
	local metadeps = {};
18b6a55dd5d6 mod_firewall: Support expressions in TO/FROM EXACTLY
Matthew Wild <mwild1@gmail.com>
parents: 2549
diff changeset
    70
	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
    71
end
7ba6ed553c93 mod_firewall/conditions: Add FROM_EXACTLY and TO_EXACTLY
Matthew Wild <mwild1@gmail.com>
parents: 997
diff changeset
    72
7ba6ed553c93 mod_firewall/conditions: Add FROM_EXACTLY and TO_EXACTLY
Matthew Wild <mwild1@gmail.com>
parents: 997
diff changeset
    73
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
    74
	local metadeps = {};
18b6a55dd5d6 mod_firewall: Support expressions in TO/FROM EXACTLY
Matthew Wild <mwild1@gmail.com>
parents: 2549
diff changeset
    75
	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
    76
end
7ba6ed553c93 mod_firewall/conditions: Add FROM_EXACTLY and TO_EXACTLY
Matthew Wild <mwild1@gmail.com>
parents: 997
diff changeset
    77
2469
bd69ffe071e6 mod_firewall: Add 'TO SELF' check ('NOT TO?' worked until commit 9159f9166893)
Matthew Wild <mwild1@gmail.com>
parents: 2407
diff changeset
    78
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
    79
	-- 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
    80
	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
    81
end
bd69ffe071e6 mod_firewall: Add 'TO SELF' check ('NOT TO?' worked until commit 9159f9166893)
Matthew Wild <mwild1@gmail.com>
parents: 2407
diff changeset
    82
947
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    83
function condition_handlers.TYPE(type)
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
    84
	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
    85
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
    86
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
    87
local function zone_check(zone, which)
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
    88
	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
    89
	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
    90
		.."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
    91
		)
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
    92
		:format(zone, which, zone, which, zone, which,
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
		zone, which_not, zone, which_not, zone, which_not), {
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
			"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
    95
		};
947
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    96
end
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    97
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    98
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
    99
	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
   100
end
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   101
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   102
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
   103
	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
   104
end
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   105
2541
acdc1767a715 mod_firewall: Make parameter to 'IN ROSTER' optional
Matthew Wild <mwild1@gmail.com>
parents: 2538
diff changeset
   106
-- 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
   107
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
   108
	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
   109
	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
   110
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
   111
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_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
   113
	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
   114
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
   115
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
   116
function condition_handlers.SUBSCRIBED()
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
   117
	return "rostermanager.is_contact_subscribed(to_node, to_host, bare_from)",
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
   118
	       { "rostermanager", "split_to", "bare_from" };
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
   119
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
   120
947
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   121
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
   122
	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
   123
end
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   124
954
bec5b6e2eab8 mod_firewall: Add INSPECT conditional, for deeper inspection of stanzas
Kim Alvefur <zash@zash.se>
parents: 947
diff changeset
   125
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
   126
	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
   127
		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
   128
		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
   129
			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
   130
		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
   131
		local meta_deps = {};
2390
00eed68f63bf mod_firewall: INSPECT: support for literal substring search and expressions
Matthew Wild <mwild1@gmail.com>
parents: 2367
diff changeset
   132
		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
   133
		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
   134
			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
   135
			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
   136
		end
00eed68f63bf mod_firewall: INSPECT: support for literal substring search and expressions
Matthew Wild <mwild1@gmail.com>
parents: 2367
diff changeset
   137
		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
   138
			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
   139
		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
   140
			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
   141
		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
   142
			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
   143
		else
2390
00eed68f63bf mod_firewall: INSPECT: support for literal substring search and expressions
Matthew Wild <mwild1@gmail.com>
parents: 2367
diff changeset
   144
			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
   145
		end
954
bec5b6e2eab8 mod_firewall: Add INSPECT conditional, for deeper inspection of stanzas
Kim Alvefur <zash@zash.se>
parents: 947
diff changeset
   146
	end
bec5b6e2eab8 mod_firewall: Add INSPECT conditional, for deeper inspection of stanzas
Kim Alvefur <zash@zash.se>
parents: 947
diff changeset
   147
	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
   148
end
bec5b6e2eab8 mod_firewall: Add INSPECT conditional, for deeper inspection of stanzas
Kim Alvefur <zash@zash.se>
parents: 947
diff changeset
   149
947
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   150
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
   151
	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
   152
end
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   153
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   154
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
   155
	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
   156
end
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   157
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   158
function condition_handlers.FROM_ADMIN_OF(host)
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   159
	return ("is_admin(bare_from, %s)"):format(host ~= "*" and host or nil), { "is_admin", "bare_from" };
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   160
end
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   161
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   162
function condition_handlers.TO_ADMIN_OF(host)
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   163
	return ("is_admin(bare_to, %s)"):format(host ~= "*" and host or nil), { "is_admin", "bare_to" };
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   164
end
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   165
2557
7ed2a66bfabd mod_firewall: Add TO/FROM ADMIN
Matthew Wild <mwild1@gmail.com>
parents: 2556
diff changeset
   166
function condition_handlers.FROM_ADMIN()
7ed2a66bfabd mod_firewall: Add TO/FROM ADMIN
Matthew Wild <mwild1@gmail.com>
parents: 2556
diff changeset
   167
	return ("is_admin(bare_from, from_host)"):format(host ~= "*" and host or nil), { "is_admin", "bare_from", "split_from" };
7ed2a66bfabd mod_firewall: Add TO/FROM ADMIN
Matthew Wild <mwild1@gmail.com>
parents: 2556
diff changeset
   168
end
7ed2a66bfabd mod_firewall: Add TO/FROM ADMIN
Matthew Wild <mwild1@gmail.com>
parents: 2556
diff changeset
   169
7ed2a66bfabd mod_firewall: Add TO/FROM ADMIN
Matthew Wild <mwild1@gmail.com>
parents: 2556
diff changeset
   170
function condition_handlers.TO_ADMIN()
7ed2a66bfabd mod_firewall: Add TO/FROM ADMIN
Matthew Wild <mwild1@gmail.com>
parents: 2556
diff changeset
   171
	return ("is_admin(bare_to, to_host)"):format(host ~= "*" and host or nil), { "is_admin", "bare_to", "split_to" };
7ed2a66bfabd mod_firewall: Add TO/FROM ADMIN
Matthew Wild <mwild1@gmail.com>
parents: 2556
diff changeset
   172
end
7ed2a66bfabd mod_firewall: Add TO/FROM ADMIN
Matthew Wild <mwild1@gmail.com>
parents: 2556
diff changeset
   173
968
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   174
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
   175
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   176
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
   177
	hour, minute = tonumber(hour), tonumber(minute);
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   178
	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
   179
	if minute == 0 then
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   180
		return "(current_hour"..adj_op..hour..")";
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   181
	else
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   182
		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
   183
	end
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   184
end
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   185
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   186
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
   187
	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
   188
end
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   189
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   190
function condition_handlers.DAY(days)
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   191
	local conditions = {};
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   192
	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
   193
		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
   194
		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
   195
			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
   196
			local op = "and";
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   197
			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
   198
				op = "or";
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   199
			end
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   200
			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
   201
		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
   202
			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
   203
			table.insert(conditions, "current_day == "..day);
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   204
		else
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   205
			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
   206
		end
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   207
	end
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   208
	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
   209
	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
   210
end
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   211
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   212
function condition_handlers.TIME(ranges)
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   213
	local conditions = {};
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   214
	for range in ranges:gmatch("([^,]+)") do
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   215
		local clause = {};
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   216
		range = range:lower()
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   217
			: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
   218
			: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
   219
		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
   220
		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
   221
		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
   222
		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
   223
			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
   224
			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
   225
		end
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   226
		if #clause == 0 then
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   227
			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
   228
		end
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   229
		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
   230
	end
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   231
	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
   232
end
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   233
2132
21bc4d7cddae mod_firewall: Add support for throttling based on user-defined properties (experimental)
Matthew Wild <mwild1@gmail.com>
parents: 2131
diff changeset
   234
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
   235
	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
   236
	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
   237
21bc4d7cddae mod_firewall: Add support for throttling based on user-defined properties (experimental)
Matthew Wild <mwild1@gmail.com>
parents: 2131
diff changeset
   238
	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
   239
		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
   240
		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
   241
			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
   242
		end
21bc4d7cddae mod_firewall: Add support for throttling based on user-defined properties (experimental)
Matthew Wild <mwild1@gmail.com>
parents: 2131
diff changeset
   243
	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
   244
		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
   245
	end
21bc4d7cddae mod_firewall: Add support for throttling based on user-defined properties (experimental)
Matthew Wild <mwild1@gmail.com>
parents: 2131
diff changeset
   246
21bc4d7cddae mod_firewall: Add support for throttling based on user-defined properties (experimental)
Matthew Wild <mwild1@gmail.com>
parents: 2131
diff changeset
   247
	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
   248
		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
   249
	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
   250
	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
   251
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
   252
2111
f445f43b9ba1 mod_firewall: Add support for session marking (MARK_ORIGIN, UNMARK_ORIGIN, ORIGIN_MARKED)
Matthew Wild <mwild1@gmail.com>
parents: 2079
diff changeset
   253
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
   254
	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
   255
	if not name then
2131
59023dffbdd4 mod_firewall: Allow underscore in mark names (thanks Ge0rG)
Matthew Wild <mwild1@gmail.com>
parents: 2129
diff changeset
   256
		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
   257
	end
f445f43b9ba1 mod_firewall: Add support for session marking (MARK_ORIGIN, UNMARK_ORIGIN, ORIGIN_MARKED)
Matthew Wild <mwild1@gmail.com>
parents: 2079
diff changeset
   258
	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
   259
		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
   260
	end
f445f43b9ba1 mod_firewall: Add support for session marking (MARK_ORIGIN, UNMARK_ORIGIN, ORIGIN_MARKED)
Matthew Wild <mwild1@gmail.com>
parents: 2079
diff changeset
   261
	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
   262
		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
   263
	end
f445f43b9ba1 mod_firewall: Add support for session marking (MARK_ORIGIN, UNMARK_ORIGIN, ORIGIN_MARKED)
Matthew Wild <mwild1@gmail.com>
parents: 2079
diff changeset
   264
	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
   265
end
f445f43b9ba1 mod_firewall: Add support for session marking (MARK_ORIGIN, UNMARK_ORIGIN, ORIGIN_MARKED)
Matthew Wild <mwild1@gmail.com>
parents: 2079
diff changeset
   266
2558
19bb4606013f mod_firewall: Fix everything wrong with SENT_DIRECTED_PRESENCE_TO_SENDER
Matthew Wild <mwild1@gmail.com>
parents: 2557
diff changeset
   267
function condition_handlers.SENT_DIRECTED_PRESENCE_TO_SENDER()
19bb4606013f mod_firewall: Fix everything wrong with SENT_DIRECTED_PRESENCE_TO_SENDER
Matthew Wild <mwild1@gmail.com>
parents: 2557
diff changeset
   268
	return "not not session.directed[from]", { "from" };
2533
3fe4ca2b55c2 mod_firewall: Add 'SENT DIRECTED PRESENCE TO SENDER?'
Matthew Wild <mwild1@gmail.com>
parents: 2532
diff changeset
   269
end
3fe4ca2b55c2 mod_firewall: Add 'SENT DIRECTED PRESENCE TO SENDER?'
Matthew Wild <mwild1@gmail.com>
parents: 2532
diff changeset
   270
2559
a9eb4d5566f3 mod_firewall: Add TO FULL JID
Matthew Wild <mwild1@gmail.com>
parents: 2558
diff changeset
   271
function condition_handlers.TO_FULL_JID()
a9eb4d5566f3 mod_firewall: Add TO FULL JID
Matthew Wild <mwild1@gmail.com>
parents: 2558
diff changeset
   272
	return "not not full_sessions[to]", { "to" };
a9eb4d5566f3 mod_firewall: Add TO FULL JID
Matthew Wild <mwild1@gmail.com>
parents: 2558
diff changeset
   273
end
a9eb4d5566f3 mod_firewall: Add TO FULL JID
Matthew Wild <mwild1@gmail.com>
parents: 2558
diff changeset
   274
2524
c6fd8975704b mod_firewall: Initial support for lists, in-memory and HTTP
Matthew Wild <mwild1@gmail.com>
parents: 2523
diff changeset
   275
-- 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
   276
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
   277
	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
   278
	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
   279
		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
   280
	end
c6fd8975704b mod_firewall: Initial support for lists, in-memory and HTTP
Matthew Wild <mwild1@gmail.com>
parents: 2523
diff changeset
   281
	local meta_deps = {};
c6fd8975704b mod_firewall: Initial support for lists, in-memory and HTTP
Matthew Wild <mwild1@gmail.com>
parents: 2523
diff changeset
   282
	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
   283
	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
   284
end
c6fd8975704b mod_firewall: Initial support for lists, in-memory and HTTP
Matthew Wild <mwild1@gmail.com>
parents: 2523
diff changeset
   285
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
   286
-- 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
   287
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
   288
	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
   289
	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
   290
		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
   291
	end
2538
13b8c31dce01 mod_firewall: Fix SCAN to pass correct variable to scan_list()
Matthew Wild <mwild1@gmail.com>
parents: 2533
diff changeset
   292
	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
   293
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
   294
2549
9b46d24edf0d mod_firewall: Add and document COUNT condition
Matthew Wild <mwild1@gmail.com>
parents: 2541
diff changeset
   295
local valid_comp_ops = { [">"] = ">", ["<"] = "<", ["="] = "==", ["=="] = "==", ["<="] = "<=", [">="] = ">=" };
9b46d24edf0d mod_firewall: Add and document COUNT condition
Matthew Wild <mwild1@gmail.com>
parents: 2541
diff changeset
   296
function condition_handlers.COUNT(count_expression)
9b46d24edf0d mod_firewall: Add and document COUNT condition
Matthew Wild <mwild1@gmail.com>
parents: 2541
diff changeset
   297
	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
   298
	if not (pattern_name) then
9b46d24edf0d mod_firewall: Add and document COUNT condition
Matthew Wild <mwild1@gmail.com>
parents: 2541
diff changeset
   299
		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
   300
	end
9b46d24edf0d mod_firewall: Add and document COUNT condition
Matthew Wild <mwild1@gmail.com>
parents: 2541
diff changeset
   301
	local value;
9b46d24edf0d mod_firewall: Add and document COUNT condition
Matthew Wild <mwild1@gmail.com>
parents: 2541
diff changeset
   302
	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
   303
		value = tonumber(value_string);
9b46d24edf0d mod_firewall: Add and document COUNT condition
Matthew Wild <mwild1@gmail.com>
parents: 2541
diff changeset
   304
		return "";
9b46d24edf0d mod_firewall: Add and document COUNT condition
Matthew Wild <mwild1@gmail.com>
parents: 2541
diff changeset
   305
	end);
9b46d24edf0d mod_firewall: Add and document COUNT condition
Matthew Wild <mwild1@gmail.com>
parents: 2541
diff changeset
   306
	if not value then
9b46d24edf0d mod_firewall: Add and document COUNT condition
Matthew Wild <mwild1@gmail.com>
parents: 2541
diff changeset
   307
		error("Error parsing COUNT expression, expected value");
9b46d24edf0d mod_firewall: Add and document COUNT condition
Matthew Wild <mwild1@gmail.com>
parents: 2541
diff changeset
   308
	end
9b46d24edf0d mod_firewall: Add and document COUNT condition
Matthew Wild <mwild1@gmail.com>
parents: 2541
diff changeset
   309
	local comp_op = comparator_expression:gsub("%s+", "");
9b46d24edf0d mod_firewall: Add and document COUNT condition
Matthew Wild <mwild1@gmail.com>
parents: 2541
diff changeset
   310
	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
   311
	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
   312
end
9b46d24edf0d mod_firewall: Add and document COUNT condition
Matthew Wild <mwild1@gmail.com>
parents: 2541
diff changeset
   313
947
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   314
return condition_handlers;