mod_firewall/conditions.lib.lua
author Matthew Wild <mwild1@gmail.com>
Tue, 16 Apr 2024 12:41:52 +0100
changeset 5888 49b0873932ca
parent 5797 e304e19536f2
permissions -rw-r--r--
mod_pubsub_serverinfo: Don't default to non-local pubsub servers (thanks roughnecks)
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
5534
8226ac08484e mod_firewall: Add 'FROM FULL JID?' condition
Matthew Wild <mwild1@gmail.com>
parents: 5006
diff changeset
    70
function condition_handlers.FROM_FULL_JID()
5538
7b4e0c3642bf mod_firewall: Fix inverted logic of 'FROM FULL JID?'
Matthew Wild <mwild1@gmail.com>
parents: 5534
diff changeset
    71
	return "not "..compile_jid_match_part("from_resource", nil), { "split_from" };
5534
8226ac08484e mod_firewall: Add 'FROM FULL JID?' condition
Matthew Wild <mwild1@gmail.com>
parents: 5006
diff changeset
    72
end
8226ac08484e mod_firewall: Add 'FROM FULL JID?' condition
Matthew Wild <mwild1@gmail.com>
parents: 5006
diff changeset
    73
2040
7ba6ed553c93 mod_firewall/conditions: Add FROM_EXACTLY and TO_EXACTLY
Matthew Wild <mwild1@gmail.com>
parents: 997
diff changeset
    74
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
    75
	local metadeps = {};
18b6a55dd5d6 mod_firewall: Support expressions in TO/FROM EXACTLY
Matthew Wild <mwild1@gmail.com>
parents: 2549
diff changeset
    76
	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
    77
end
7ba6ed553c93 mod_firewall/conditions: Add FROM_EXACTLY and TO_EXACTLY
Matthew Wild <mwild1@gmail.com>
parents: 997
diff changeset
    78
7ba6ed553c93 mod_firewall/conditions: Add FROM_EXACTLY and TO_EXACTLY
Matthew Wild <mwild1@gmail.com>
parents: 997
diff changeset
    79
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
    80
	local metadeps = {};
18b6a55dd5d6 mod_firewall: Support expressions in TO/FROM EXACTLY
Matthew Wild <mwild1@gmail.com>
parents: 2549
diff changeset
    81
	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
    82
end
7ba6ed553c93 mod_firewall/conditions: Add FROM_EXACTLY and TO_EXACTLY
Matthew Wild <mwild1@gmail.com>
parents: 997
diff changeset
    83
2469
bd69ffe071e6 mod_firewall: Add 'TO SELF' check ('NOT TO?' worked until commit 9159f9166893)
Matthew Wild <mwild1@gmail.com>
parents: 2407
diff changeset
    84
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
    85
	-- 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
    86
	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
    87
end
bd69ffe071e6 mod_firewall: Add 'TO SELF' check ('NOT TO?' worked until commit 9159f9166893)
Matthew Wild <mwild1@gmail.com>
parents: 2407
diff changeset
    88
947
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    89
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
    90
	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
    91
	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
    92
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
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
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
    95
	local zone_var = zone;
b0d92332b87f mod_firewall: Add special case for $local zone (fixes #1090)
Kim Alvefur <zash@zash.se>
parents: 2920
diff changeset
    96
	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
    97
	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
    98
	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
    99
		.."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
   100
		)
2932
b0d92332b87f mod_firewall: Add special case for $local zone (fixes #1090)
Kim Alvefur <zash@zash.se>
parents: 2920
diff changeset
   101
		: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
   102
		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
   103
			"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
   104
		};
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.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
   108
	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
   109
end
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   110
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   111
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
   112
	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
   113
end
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   114
2541
acdc1767a715 mod_firewall: Make parameter to 'IN ROSTER' optional
Matthew Wild <mwild1@gmail.com>
parents: 2538
diff changeset
   115
-- 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
   116
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
   117
	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
   118
	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
   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
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
   121
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
   122
	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
   123
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
   124
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
   125
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
   126
	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
   127
	       { "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
   128
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
   129
2920
b1cdcbcd1c90 mod_firewall: Add PENDING SUBSCRIPTION FROM SENDER? condition
Matthew Wild <mwild1@gmail.com>
parents: 2898
diff changeset
   130
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
   131
	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
   132
	       { "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
   133
end
b1cdcbcd1c90 mod_firewall: Add PENDING SUBSCRIPTION FROM SENDER? condition
Matthew Wild <mwild1@gmail.com>
parents: 2898
diff changeset
   134
947
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   135
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
   136
	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
   137
end
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   138
954
bec5b6e2eab8 mod_firewall: Add INSPECT conditional, for deeper inspection of stanzas
Kim Alvefur <zash@zash.se>
parents: 947
diff changeset
   139
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
   140
	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
   141
		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
   142
		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
   143
			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
   144
		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
   145
		local meta_deps = {};
2390
00eed68f63bf mod_firewall: INSPECT: support for literal substring search and expressions
Matthew Wild <mwild1@gmail.com>
parents: 2367
diff changeset
   146
		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
   147
		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
   148
			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
   149
			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
   150
		end
00eed68f63bf mod_firewall: INSPECT: support for literal substring search and expressions
Matthew Wild <mwild1@gmail.com>
parents: 2367
diff changeset
   151
		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
   152
			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
   153
		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
   154
			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
   155
		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
   156
			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
   157
		else
2390
00eed68f63bf mod_firewall: INSPECT: support for literal substring search and expressions
Matthew Wild <mwild1@gmail.com>
parents: 2367
diff changeset
   158
			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
   159
		end
954
bec5b6e2eab8 mod_firewall: Add INSPECT conditional, for deeper inspection of stanzas
Kim Alvefur <zash@zash.se>
parents: 947
diff changeset
   160
	end
bec5b6e2eab8 mod_firewall: Add INSPECT conditional, for deeper inspection of stanzas
Kim Alvefur <zash@zash.se>
parents: 947
diff changeset
   161
	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
   162
end
bec5b6e2eab8 mod_firewall: Add INSPECT conditional, for deeper inspection of stanzas
Kim Alvefur <zash@zash.se>
parents: 947
diff changeset
   163
947
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.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
   165
	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
   166
end
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   167
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   168
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
   169
	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
   170
end
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   171
2598
1e1c929c1aa5 mod_firewall: Add and document CROSSING GROUPS condition
Matthew Wild <mwild1@gmail.com>
parents: 2588
diff changeset
   172
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
   173
	local code = {};
1e1c929c1aa5 mod_firewall: Add and document CROSSING GROUPS condition
Matthew Wild <mwild1@gmail.com>
parents: 2588
diff changeset
   174
	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
   175
		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
   176
		-- 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
   177
		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
   178
	end
1e1c929c1aa5 mod_firewall: Add and document CROSSING GROUPS condition
Matthew Wild <mwild1@gmail.com>
parents: 2588
diff changeset
   179
	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
   180
end
1e1c929c1aa5 mod_firewall: Add and document CROSSING GROUPS condition
Matthew Wild <mwild1@gmail.com>
parents: 2588
diff changeset
   181
5006
84997bc3f92e mod_firewall: Update for role-auth (backwards compatible)
Matthew Wild <mwild1@gmail.com>
parents: 4612
diff changeset
   182
-- 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
   183
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
   184
	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
   185
end
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   186
5006
84997bc3f92e mod_firewall: Update for role-auth (backwards compatible)
Matthew Wild <mwild1@gmail.com>
parents: 4612
diff changeset
   187
-- 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
   188
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
   189
	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
   190
end
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   191
5006
84997bc3f92e mod_firewall: Update for role-auth (backwards compatible)
Matthew Wild <mwild1@gmail.com>
parents: 4612
diff changeset
   192
-- COMPAT w/0.12: Deprecated
2557
7ed2a66bfabd mod_firewall: Add TO/FROM ADMIN
Matthew Wild <mwild1@gmail.com>
parents: 2556
diff changeset
   193
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
   194
	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
   195
end
7ed2a66bfabd mod_firewall: Add TO/FROM ADMIN
Matthew Wild <mwild1@gmail.com>
parents: 2556
diff changeset
   196
5006
84997bc3f92e mod_firewall: Update for role-auth (backwards compatible)
Matthew Wild <mwild1@gmail.com>
parents: 4612
diff changeset
   197
-- COMPAT w/0.12: Deprecated
2557
7ed2a66bfabd mod_firewall: Add TO/FROM ADMIN
Matthew Wild <mwild1@gmail.com>
parents: 2556
diff changeset
   198
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
   199
	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
   200
end
7ed2a66bfabd mod_firewall: Add TO/FROM ADMIN
Matthew Wild <mwild1@gmail.com>
parents: 2556
diff changeset
   201
5006
84997bc3f92e mod_firewall: Update for role-auth (backwards compatible)
Matthew Wild <mwild1@gmail.com>
parents: 4612
diff changeset
   202
-- MAY: permission_to_check
84997bc3f92e mod_firewall: Update for role-auth (backwards compatible)
Matthew Wild <mwild1@gmail.com>
parents: 4612
diff changeset
   203
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
   204
	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
   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.TO_ROLE(role_name)
5797
e304e19536f2 mod_firewall: TO/FROM ROLE: Handle JIDs with no role (thanks Zash)
Matthew Wild <mwild1@gmail.com>
parents: 5796
diff changeset
   208
	return ("recipient_role and recipient_role.name == %q"):format(role_name), { "recipient_role" };
5006
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
84997bc3f92e mod_firewall: Update for role-auth (backwards compatible)
Matthew Wild <mwild1@gmail.com>
parents: 4612
diff changeset
   211
function condition_handlers.FROM_ROLE(role_name)
5797
e304e19536f2 mod_firewall: TO/FROM ROLE: Handle JIDs with no role (thanks Zash)
Matthew Wild <mwild1@gmail.com>
parents: 5796
diff changeset
   212
	return ("sender_role and sender_role.name == %q"):format(role_name), { "sender_role" };
5006
84997bc3f92e mod_firewall: Update for role-auth (backwards compatible)
Matthew Wild <mwild1@gmail.com>
parents: 4612
diff changeset
   213
end
84997bc3f92e mod_firewall: Update for role-auth (backwards compatible)
Matthew Wild <mwild1@gmail.com>
parents: 4612
diff changeset
   214
968
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   215
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
   216
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   217
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
   218
	hour, minute = tonumber(hour), tonumber(minute);
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   219
	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
   220
	if minute == 0 then
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   221
		return "(current_hour"..adj_op..hour..")";
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   222
	else
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   223
		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
   224
	end
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
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
   228
	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
   229
end
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   230
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   231
function condition_handlers.DAY(days)
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   232
	local conditions = {};
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   233
	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
   234
		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
   235
		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
   236
			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
   237
			local op = "and";
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   238
			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
   239
				op = "or";
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   240
			end
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   241
			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
   242
		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
   243
			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
   244
			table.insert(conditions, "current_day == "..day);
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   245
		else
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   246
			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
   247
		end
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   248
	end
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   249
	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
   250
	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
   251
end
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   252
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   253
function condition_handlers.TIME(ranges)
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   254
	local conditions = {};
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   255
	for range in ranges:gmatch("([^,]+)") do
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   256
		local clause = {};
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   257
		range = range:lower()
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   258
			: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
   259
			: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
   260
		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
   261
		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
   262
		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
   263
		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
   264
			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
   265
			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
   266
		end
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   267
		if #clause == 0 then
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   268
			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
   269
		end
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   270
		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
   271
	end
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   272
	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
   273
end
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
   274
2132
21bc4d7cddae mod_firewall: Add support for throttling based on user-defined properties (experimental)
Matthew Wild <mwild1@gmail.com>
parents: 2131
diff changeset
   275
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
   276
	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
   277
	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
   278
21bc4d7cddae mod_firewall: Add support for throttling based on user-defined properties (experimental)
Matthew Wild <mwild1@gmail.com>
parents: 2131
diff changeset
   279
	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
   280
		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
   281
		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
   282
			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
   283
		end
21bc4d7cddae mod_firewall: Add support for throttling based on user-defined properties (experimental)
Matthew Wild <mwild1@gmail.com>
parents: 2131
diff changeset
   284
	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
   285
		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
   286
	end
21bc4d7cddae mod_firewall: Add support for throttling based on user-defined properties (experimental)
Matthew Wild <mwild1@gmail.com>
parents: 2131
diff changeset
   287
21bc4d7cddae mod_firewall: Add support for throttling based on user-defined properties (experimental)
Matthew Wild <mwild1@gmail.com>
parents: 2131
diff changeset
   288
	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
   289
		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
   290
	end
2863
22e11645a895 mod_firewall: Trim trailing whitespace [luacheck]
Kim Alvefur <zash@zash.se>
parents: 2861
diff changeset
   291
	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
   292
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
   293
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
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
   295
	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
   296
	if not name then
2131
59023dffbdd4 mod_firewall: Allow underscore in mark names (thanks Ge0rG)
Matthew Wild <mwild1@gmail.com>
parents: 2129
diff changeset
   297
		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
   298
	end
f445f43b9ba1 mod_firewall: Add support for session marking (MARK_ORIGIN, UNMARK_ORIGIN, ORIGIN_MARKED)
Matthew Wild <mwild1@gmail.com>
parents: 2079
diff changeset
   299
	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
   300
		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
   301
	end
f445f43b9ba1 mod_firewall: Add support for session marking (MARK_ORIGIN, UNMARK_ORIGIN, ORIGIN_MARKED)
Matthew Wild <mwild1@gmail.com>
parents: 2079
diff changeset
   302
	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
   303
		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
   304
	end
f445f43b9ba1 mod_firewall: Add support for session marking (MARK_ORIGIN, UNMARK_ORIGIN, ORIGIN_MARKED)
Matthew Wild <mwild1@gmail.com>
parents: 2079
diff changeset
   305
	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
   306
end
f445f43b9ba1 mod_firewall: Add support for session marking (MARK_ORIGIN, UNMARK_ORIGIN, ORIGIN_MARKED)
Matthew Wild <mwild1@gmail.com>
parents: 2079
diff changeset
   307
2898
165d2877eeac mod_firewall: Add experimental user-centric persistent marks behind a feature flag
Kim Alvefur <zash@zash.se>
parents: 2886
diff changeset
   308
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
   309
	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
   310
	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
   311
		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
   312
	end
165d2877eeac mod_firewall: Add experimental user-centric persistent marks behind a feature flag
Kim Alvefur <zash@zash.se>
parents: 2886
diff changeset
   313
	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
   314
		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
   315
	end
165d2877eeac mod_firewall: Add experimental user-centric persistent marks behind a feature flag
Kim Alvefur <zash@zash.se>
parents: 2886
diff changeset
   316
	if time then
5539
eeccec0955a1 mod_firewall: Split some long lines [luacheck]
Matthew Wild <mwild1@gmail.com>
parents: 5538
diff changeset
   317
		return ([[(
eeccec0955a1 mod_firewall: Split some long lines [luacheck]
Matthew Wild <mwild1@gmail.com>
parents: 5538
diff changeset
   318
			current_timestamp - (session.firewall_marks and session.firewall_marks.%s or 0)
eeccec0955a1 mod_firewall: Split some long lines [luacheck]
Matthew Wild <mwild1@gmail.com>
parents: 5538
diff changeset
   319
		) < %d]]):format(idsafe(name), tonumber(time)), { "timestamp" };
2898
165d2877eeac mod_firewall: Add experimental user-centric persistent marks behind a feature flag
Kim Alvefur <zash@zash.se>
parents: 2886
diff changeset
   320
	end
165d2877eeac mod_firewall: Add experimental user-centric persistent marks behind a feature flag
Kim Alvefur <zash@zash.se>
parents: 2886
diff changeset
   321
	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
   322
end
165d2877eeac mod_firewall: Add experimental user-centric persistent marks behind a feature flag
Kim Alvefur <zash@zash.se>
parents: 2886
diff changeset
   323
2558
19bb4606013f mod_firewall: Fix everything wrong with SENT_DIRECTED_PRESENCE_TO_SENDER
Matthew Wild <mwild1@gmail.com>
parents: 2557
diff changeset
   324
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
   325
	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
   326
end
3fe4ca2b55c2 mod_firewall: Add 'SENT DIRECTED PRESENCE TO SENDER?'
Matthew Wild <mwild1@gmail.com>
parents: 2532
diff changeset
   327
2622
c6652d055ba3 mod_firewall: Add some more comments
Matthew Wild <mwild1@gmail.com>
parents: 2598
diff changeset
   328
-- TO FULL JID?
2559
a9eb4d5566f3 mod_firewall: Add TO FULL JID
Matthew Wild <mwild1@gmail.com>
parents: 2558
diff changeset
   329
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
   330
	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
   331
end
a9eb4d5566f3 mod_firewall: Add TO FULL JID
Matthew Wild <mwild1@gmail.com>
parents: 2558
diff changeset
   332
2524
c6fd8975704b mod_firewall: Initial support for lists, in-memory and HTTP
Matthew Wild <mwild1@gmail.com>
parents: 2523
diff changeset
   333
-- 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
   334
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
   335
	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
   336
	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
   337
		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
   338
	end
c6fd8975704b mod_firewall: Initial support for lists, in-memory and HTTP
Matthew Wild <mwild1@gmail.com>
parents: 2523
diff changeset
   339
	local meta_deps = {};
c6fd8975704b mod_firewall: Initial support for lists, in-memory and HTTP
Matthew Wild <mwild1@gmail.com>
parents: 2523
diff changeset
   340
	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
   341
	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
   342
end
c6fd8975704b mod_firewall: Initial support for lists, in-memory and HTTP
Matthew Wild <mwild1@gmail.com>
parents: 2523
diff changeset
   343
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
   344
-- 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
   345
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
   346
	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
   347
	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
   348
		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
   349
	end
5539
eeccec0955a1 mod_firewall: Split some long lines [luacheck]
Matthew Wild <mwild1@gmail.com>
parents: 5538
diff changeset
   350
	return ("scan_list(list_%s, %s)"):format(
eeccec0955a1 mod_firewall: Split some long lines [luacheck]
Matthew Wild <mwild1@gmail.com>
parents: 5538
diff changeset
   351
		list_name,
eeccec0955a1 mod_firewall: Split some long lines [luacheck]
Matthew Wild <mwild1@gmail.com>
parents: 5538
diff changeset
   352
		"tokens_"..search_name.."_"..pattern_name
eeccec0955a1 mod_firewall: Split some long lines [luacheck]
Matthew Wild <mwild1@gmail.com>
parents: 5538
diff changeset
   353
	), {
eeccec0955a1 mod_firewall: Split some long lines [luacheck]
Matthew Wild <mwild1@gmail.com>
parents: 5538
diff changeset
   354
			"scan_list",
eeccec0955a1 mod_firewall: Split some long lines [luacheck]
Matthew Wild <mwild1@gmail.com>
parents: 5538
diff changeset
   355
			"tokens:"..search_name.."-"..pattern_name, "list:"..list_name
eeccec0955a1 mod_firewall: Split some long lines [luacheck]
Matthew Wild <mwild1@gmail.com>
parents: 5538
diff changeset
   356
	};
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
   357
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
   358
2622
c6652d055ba3 mod_firewall: Add some more comments
Matthew Wild <mwild1@gmail.com>
parents: 2598
diff changeset
   359
-- COUNT: lines in body < 10
2549
9b46d24edf0d mod_firewall: Add and document COUNT condition
Matthew Wild <mwild1@gmail.com>
parents: 2541
diff changeset
   360
local valid_comp_ops = { [">"] = ">", ["<"] = "<", ["="] = "==", ["=="] = "==", ["<="] = "<=", [">="] = ">=" };
9b46d24edf0d mod_firewall: Add and document COUNT condition
Matthew Wild <mwild1@gmail.com>
parents: 2541
diff changeset
   361
function condition_handlers.COUNT(count_expression)
9b46d24edf0d mod_firewall: Add and document COUNT condition
Matthew Wild <mwild1@gmail.com>
parents: 2541
diff changeset
   362
	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
   363
	if not (pattern_name) then
9b46d24edf0d mod_firewall: Add and document COUNT condition
Matthew Wild <mwild1@gmail.com>
parents: 2541
diff changeset
   364
		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
   365
	end
9b46d24edf0d mod_firewall: Add and document COUNT condition
Matthew Wild <mwild1@gmail.com>
parents: 2541
diff changeset
   366
	local value;
9b46d24edf0d mod_firewall: Add and document COUNT condition
Matthew Wild <mwild1@gmail.com>
parents: 2541
diff changeset
   367
	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
   368
		value = tonumber(value_string);
9b46d24edf0d mod_firewall: Add and document COUNT condition
Matthew Wild <mwild1@gmail.com>
parents: 2541
diff changeset
   369
		return "";
9b46d24edf0d mod_firewall: Add and document COUNT condition
Matthew Wild <mwild1@gmail.com>
parents: 2541
diff changeset
   370
	end);
9b46d24edf0d mod_firewall: Add and document COUNT condition
Matthew Wild <mwild1@gmail.com>
parents: 2541
diff changeset
   371
	if not value then
9b46d24edf0d mod_firewall: Add and document COUNT condition
Matthew Wild <mwild1@gmail.com>
parents: 2541
diff changeset
   372
		error("Error parsing COUNT expression, expected value");
9b46d24edf0d mod_firewall: Add and document COUNT condition
Matthew Wild <mwild1@gmail.com>
parents: 2541
diff changeset
   373
	end
9b46d24edf0d mod_firewall: Add and document COUNT condition
Matthew Wild <mwild1@gmail.com>
parents: 2541
diff changeset
   374
	local comp_op = comparator_expression:gsub("%s+", "");
9b46d24edf0d mod_firewall: Add and document COUNT condition
Matthew Wild <mwild1@gmail.com>
parents: 2541
diff changeset
   375
	assert(valid_comp_ops[comp_op], "Error parsing COUNT expression, unknown comparison operator: "..comp_op);
5539
eeccec0955a1 mod_firewall: Split some long lines [luacheck]
Matthew Wild <mwild1@gmail.com>
parents: 5538
diff changeset
   376
	return ("it_count(search_%s:gmatch(pattern_%s)) %s %d"):format(
eeccec0955a1 mod_firewall: Split some long lines [luacheck]
Matthew Wild <mwild1@gmail.com>
parents: 5538
diff changeset
   377
		search_name, pattern_name, comp_op, value
eeccec0955a1 mod_firewall: Split some long lines [luacheck]
Matthew Wild <mwild1@gmail.com>
parents: 5538
diff changeset
   378
	), {
eeccec0955a1 mod_firewall: Split some long lines [luacheck]
Matthew Wild <mwild1@gmail.com>
parents: 5538
diff changeset
   379
		"it_count",
eeccec0955a1 mod_firewall: Split some long lines [luacheck]
Matthew Wild <mwild1@gmail.com>
parents: 5538
diff changeset
   380
		"search:"..search_name, "pattern:"..pattern_name
eeccec0955a1 mod_firewall: Split some long lines [luacheck]
Matthew Wild <mwild1@gmail.com>
parents: 5538
diff changeset
   381
	};
2549
9b46d24edf0d mod_firewall: Add and document COUNT condition
Matthew Wild <mwild1@gmail.com>
parents: 2541
diff changeset
   382
end
9b46d24edf0d mod_firewall: Add and document COUNT condition
Matthew Wild <mwild1@gmail.com>
parents: 2541
diff changeset
   383
5708
ad5c77793750 mod_firewall: Add FROM COUNTRY condition based on GeoIP DB
Kim Alvefur <zash@zash.se>
parents: 5539
diff changeset
   384
-- FROM COUNTRY: SE
ad5c77793750 mod_firewall: Add FROM COUNTRY condition based on GeoIP DB
Kim Alvefur <zash@zash.se>
parents: 5539
diff changeset
   385
-- FROM COUNTRY: code=SE
ad5c77793750 mod_firewall: Add FROM COUNTRY condition based on GeoIP DB
Kim Alvefur <zash@zash.se>
parents: 5539
diff changeset
   386
-- FROM COUNTRY: SWE
ad5c77793750 mod_firewall: Add FROM COUNTRY condition based on GeoIP DB
Kim Alvefur <zash@zash.se>
parents: 5539
diff changeset
   387
-- FROM COUNTRY: code3=SWE
ad5c77793750 mod_firewall: Add FROM COUNTRY condition based on GeoIP DB
Kim Alvefur <zash@zash.se>
parents: 5539
diff changeset
   388
-- FROM COUNTRY: continent=EU
ad5c77793750 mod_firewall: Add FROM COUNTRY condition based on GeoIP DB
Kim Alvefur <zash@zash.se>
parents: 5539
diff changeset
   389
-- FROM COUNTRY? --> NOT FROM COUNTRY: -- (for unknown/invalid)
ad5c77793750 mod_firewall: Add FROM COUNTRY condition based on GeoIP DB
Kim Alvefur <zash@zash.se>
parents: 5539
diff changeset
   390
-- TODO list support?
ad5c77793750 mod_firewall: Add FROM COUNTRY condition based on GeoIP DB
Kim Alvefur <zash@zash.se>
parents: 5539
diff changeset
   391
function condition_handlers.FROM_COUNTRY(geoip_spec)
ad5c77793750 mod_firewall: Add FROM COUNTRY condition based on GeoIP DB
Kim Alvefur <zash@zash.se>
parents: 5539
diff changeset
   392
	local condition = "==";
ad5c77793750 mod_firewall: Add FROM COUNTRY condition based on GeoIP DB
Kim Alvefur <zash@zash.se>
parents: 5539
diff changeset
   393
	if not geoip_spec then
ad5c77793750 mod_firewall: Add FROM COUNTRY condition based on GeoIP DB
Kim Alvefur <zash@zash.se>
parents: 5539
diff changeset
   394
		geoip_spec = "--";
ad5c77793750 mod_firewall: Add FROM COUNTRY condition based on GeoIP DB
Kim Alvefur <zash@zash.se>
parents: 5539
diff changeset
   395
		condition = "~=";
ad5c77793750 mod_firewall: Add FROM COUNTRY condition based on GeoIP DB
Kim Alvefur <zash@zash.se>
parents: 5539
diff changeset
   396
	end
ad5c77793750 mod_firewall: Add FROM COUNTRY condition based on GeoIP DB
Kim Alvefur <zash@zash.se>
parents: 5539
diff changeset
   397
	local field, country = geoip_spec:match("(%w+)=(%w+)");
ad5c77793750 mod_firewall: Add FROM COUNTRY condition based on GeoIP DB
Kim Alvefur <zash@zash.se>
parents: 5539
diff changeset
   398
	if not field then
ad5c77793750 mod_firewall: Add FROM COUNTRY condition based on GeoIP DB
Kim Alvefur <zash@zash.se>
parents: 5539
diff changeset
   399
		if #geoip_spec == 3 then
ad5c77793750 mod_firewall: Add FROM COUNTRY condition based on GeoIP DB
Kim Alvefur <zash@zash.se>
parents: 5539
diff changeset
   400
			field, country = "code3", geoip_spec;
ad5c77793750 mod_firewall: Add FROM COUNTRY condition based on GeoIP DB
Kim Alvefur <zash@zash.se>
parents: 5539
diff changeset
   401
		elseif #geoip_spec == 2 then
ad5c77793750 mod_firewall: Add FROM COUNTRY condition based on GeoIP DB
Kim Alvefur <zash@zash.se>
parents: 5539
diff changeset
   402
			field, country = "code", geoip_spec;
ad5c77793750 mod_firewall: Add FROM COUNTRY condition based on GeoIP DB
Kim Alvefur <zash@zash.se>
parents: 5539
diff changeset
   403
		else
ad5c77793750 mod_firewall: Add FROM COUNTRY condition based on GeoIP DB
Kim Alvefur <zash@zash.se>
parents: 5539
diff changeset
   404
			error("Unknown country code type");
ad5c77793750 mod_firewall: Add FROM COUNTRY condition based on GeoIP DB
Kim Alvefur <zash@zash.se>
parents: 5539
diff changeset
   405
		end
ad5c77793750 mod_firewall: Add FROM COUNTRY condition based on GeoIP DB
Kim Alvefur <zash@zash.se>
parents: 5539
diff changeset
   406
	end
ad5c77793750 mod_firewall: Add FROM COUNTRY condition based on GeoIP DB
Kim Alvefur <zash@zash.se>
parents: 5539
diff changeset
   407
	return ("get_geoip(session.ip, %q) %s %q"):format(field:lower(), condition, country:upper()), { "geoip_country" };
ad5c77793750 mod_firewall: Add FROM COUNTRY condition based on GeoIP DB
Kim Alvefur <zash@zash.se>
parents: 5539
diff changeset
   408
end
ad5c77793750 mod_firewall: Add FROM COUNTRY condition based on GeoIP DB
Kim Alvefur <zash@zash.se>
parents: 5539
diff changeset
   409
947
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   410
return condition_handlers;