annotate mod_firewall/conditions.lib.lua @ 6513:5fb466693e85

mod_storage_xmlarchive: Ensure list index files are removed using os.remove() on the list files leaves the new index files behind since util.datamanager does not know they are removed. Thanks Link Mauve
author Kim Alvefur <zash@zash.se>
date Tue, 07 Apr 2026 21:10:54 +0200
parents f61564e11d3b
children d4da95d6d977
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
2125
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: 2119
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";
6502
b15601203d0d mod_firewall: Support 'FROM IP' and 'FROM SUBNET' conditions
Matthew Wild <mwild1@gmail.com>
parents: 6029
diff changeset
5 local iplib = require "util.ip";
b15601203d0d mod_firewall: Support 'FROM IP' and 'FROM SUBNET' conditions
Matthew Wild <mwild1@gmail.com>
parents: 6029
diff changeset
6 local sha256 = require "util.hashes".sha256;
3973
df6227e288e5 mod_firewall: Fix use of unpack() on Lua 5.3
Kim Alvefur <zash@zash.se>
parents: 2928
diff changeset
7 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
8
2342
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: 2128
diff changeset
9 -- 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: 2128
diff changeset
10 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: 2128
diff changeset
11 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: 2128
diff changeset
12 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: 2128
diff changeset
13 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: 2128
diff changeset
14
947
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
15 -- 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
16 -- 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
17 -- 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
18 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
19 local conditions = {};
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
20 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
21 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
22 end
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
23 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
24 end
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
25
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
26 function condition_handlers.KIND(kind)
2582
ac3140cd89a2 mod_firewall: Fix compilation error if TYPE/KIND had no parameter
Matthew Wild <mwild1@gmail.com>
parents: 2577
diff changeset
27 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
28 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
29 end
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 wildcard_equivs = { ["*"] = ".*", ["?"] = "." };
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
32
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
33 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
34 if not match then
2071
4161ff87e5a4 mod_firewall/conditions: Add semicolon
Kim Alvefur <zash@zash.se>
parents: 2070
diff changeset
35 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
36 end
2072
eda5c54dfa30 mod_firewall: Anchor pattern at beginning and end
Kim Alvefur <zash@zash.se>
parents: 2071
diff changeset
37 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
38 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
39 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
40 return part;
947
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
41 end
2070
2356114ff505 mod_firewall: Optimize string match operations, string.find is faster than .match since no string is returned
Kim Alvefur <zash@zash.se>
parents: 2036
diff changeset
42 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
43 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
44 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
45 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
46 end
2074
86427261e3c4 mod_firewall: Use string.find in JID match, faster since the result is unused
Kim Alvefur <zash@zash.se>
parents: 2073
diff changeset
47 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
48 else
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
49 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
50 end
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
51 end
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
52
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
53 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
54 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
55 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
56 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
57 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
58 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
59 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
60 end
947
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
61 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
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.TO(to)
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("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
66 end
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
67
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
68 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
69 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
70 end
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
71
5530
8226ac08484e mod_firewall: Add 'FROM FULL JID?' condition
Matthew Wild <mwild1@gmail.com>
parents: 5002
diff changeset
72 function condition_handlers.FROM_FULL_JID()
5534
7b4e0c3642bf mod_firewall: Fix inverted logic of 'FROM FULL JID?'
Matthew Wild <mwild1@gmail.com>
parents: 5530
diff changeset
73 return "not "..compile_jid_match_part("from_resource", nil), { "split_from" };
5530
8226ac08484e mod_firewall: Add 'FROM FULL JID?' condition
Matthew Wild <mwild1@gmail.com>
parents: 5002
diff changeset
74 end
8226ac08484e mod_firewall: Add 'FROM FULL JID?' condition
Matthew Wild <mwild1@gmail.com>
parents: 5002
diff changeset
75
2036
7ba6ed553c93 mod_firewall/conditions: Add FROM_EXACTLY and TO_EXACTLY
Matthew Wild <mwild1@gmail.com>
parents: 997
diff changeset
76 function condition_handlers.FROM_EXACTLY(from)
2552
18b6a55dd5d6 mod_firewall: Support expressions in TO/FROM EXACTLY
Matthew Wild <mwild1@gmail.com>
parents: 2545
diff changeset
77 local metadeps = {};
18b6a55dd5d6 mod_firewall: Support expressions in TO/FROM EXACTLY
Matthew Wild <mwild1@gmail.com>
parents: 2545
diff changeset
78 return ("from == %s"):format(metaq(from, metadeps)), { "from", unpack(metadeps) };
2036
7ba6ed553c93 mod_firewall/conditions: Add FROM_EXACTLY and TO_EXACTLY
Matthew Wild <mwild1@gmail.com>
parents: 997
diff changeset
79 end
7ba6ed553c93 mod_firewall/conditions: Add FROM_EXACTLY and TO_EXACTLY
Matthew Wild <mwild1@gmail.com>
parents: 997
diff changeset
80
7ba6ed553c93 mod_firewall/conditions: Add FROM_EXACTLY and TO_EXACTLY
Matthew Wild <mwild1@gmail.com>
parents: 997
diff changeset
81 function condition_handlers.TO_EXACTLY(to)
2552
18b6a55dd5d6 mod_firewall: Support expressions in TO/FROM EXACTLY
Matthew Wild <mwild1@gmail.com>
parents: 2545
diff changeset
82 local metadeps = {};
18b6a55dd5d6 mod_firewall: Support expressions in TO/FROM EXACTLY
Matthew Wild <mwild1@gmail.com>
parents: 2545
diff changeset
83 return ("to == %s"):format(metaq(to, metadeps)), { "to", unpack(metadeps) };
2036
7ba6ed553c93 mod_firewall/conditions: Add FROM_EXACTLY and TO_EXACTLY
Matthew Wild <mwild1@gmail.com>
parents: 997
diff changeset
84 end
7ba6ed553c93 mod_firewall/conditions: Add FROM_EXACTLY and TO_EXACTLY
Matthew Wild <mwild1@gmail.com>
parents: 997
diff changeset
85
2465
bd69ffe071e6 mod_firewall: Add 'TO SELF' check ('NOT TO?' worked until commit 9159f9166893)
Matthew Wild <mwild1@gmail.com>
parents: 2403
diff changeset
86 function condition_handlers.TO_SELF()
2563
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: 2555
diff changeset
87 -- 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: 2555
diff changeset
88 return ("stanza.attr.to == nil");
2465
bd69ffe071e6 mod_firewall: Add 'TO SELF' check ('NOT TO?' worked until commit 9159f9166893)
Matthew Wild <mwild1@gmail.com>
parents: 2403
diff changeset
89 end
bd69ffe071e6 mod_firewall: Add 'TO SELF' check ('NOT TO?' worked until commit 9159f9166893)
Matthew Wild <mwild1@gmail.com>
parents: 2403
diff changeset
90
947
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
91 function condition_handlers.TYPE(type)
2582
ac3140cd89a2 mod_firewall: Fix compilation error if TYPE/KIND had no parameter
Matthew Wild <mwild1@gmail.com>
parents: 2577
diff changeset
92 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
93 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
94 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
95
d4e24fb289c0 mod_firewall: Improve zone handling, make it more efficient, and support dynamic dependencies in the compiler. ENTERING and LEAVING conditions now work at expected (not matching stanzas flowing within a zone).
Matthew Wild <mwild1@gmail.com>
parents: 964
diff changeset
96 local function zone_check(zone, which)
2928
b0d92332b87f mod_firewall: Add special case for $local zone (fixes #1090)
Kim Alvefur <zash@zash.se>
parents: 2916
diff changeset
97 local zone_var = zone;
b0d92332b87f mod_firewall: Add special case for $local zone (fixes #1090)
Kim Alvefur <zash@zash.se>
parents: 2916
diff changeset
98 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
99 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
100 return ("(zone_%s[%s_host] or zone_%s[%s] or zone_%s[bare_%s]) "
2119
5f6c18fd0161 mod_firewall: Correct zone condition to check bare JID
Kim Alvefur <zash@zash.se>
parents: 2116
diff changeset
101 .."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
102 )
2928
b0d92332b87f mod_firewall: Add special case for $local zone (fixes #1090)
Kim Alvefur <zash@zash.se>
parents: 2916
diff changeset
103 :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: 2916
diff changeset
104 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
105 "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
106 };
947
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
107 end
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
108
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
109 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
110 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
111 end
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
112
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
113 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
114 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
115 end
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
116
2537
acdc1767a715 mod_firewall: Make parameter to 'IN ROSTER' optional
Matthew Wild <mwild1@gmail.com>
parents: 2534
diff changeset
117 -- IN ROSTER? (parameter is deprecated)
2342
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: 2128
diff changeset
118 function condition_handlers.IN_ROSTER(yes_no)
2537
acdc1767a715 mod_firewall: Make parameter to 'IN ROSTER' optional
Matthew Wild <mwild1@gmail.com>
parents: 2534
diff changeset
119 local in_roster_requirement = string_to_boolean(yes_no or "yes"); -- COMPAT w/ older scripts
2342
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: 2128
diff changeset
120 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: 2128
diff changeset
121 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: 2128
diff changeset
122
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: 2128
diff changeset
123 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: 2128
diff changeset
124 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: 2128
diff changeset
125 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: 2128
diff changeset
126
2403
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: 2386
diff changeset
127 function condition_handlers.SUBSCRIBED()
6029
cc665f343690 mod_firewall: SUBSCRIBED: Flip subscription check to match documentation
Matthew Wild <mwild1@gmail.com>
parents: 5793
diff changeset
128 return "(bare_to == bare_from or to_node and rostermanager.is_user_subscribed(to_node, to_host, bare_from))",
2857
ff1666716d10 mod_firewall: Make SUBSCRIBED match for stanzas sent to self (fixes #1052)
Kim Alvefur <zash@zash.se>
parents: 2618
diff changeset
129 { "rostermanager", "split_to", "bare_to", "bare_from" };
2403
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: 2386
diff changeset
130 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: 2386
diff changeset
131
2916
b1cdcbcd1c90 mod_firewall: Add PENDING SUBSCRIPTION FROM SENDER? condition
Matthew Wild <mwild1@gmail.com>
parents: 2894
diff changeset
132 function condition_handlers.PENDING_SUBSCRIPTION_FROM_SENDER()
b1cdcbcd1c90 mod_firewall: Add PENDING SUBSCRIPTION FROM SENDER? condition
Matthew Wild <mwild1@gmail.com>
parents: 2894
diff changeset
133 return "(bare_to == bare_from or to_node and rostermanager.is_contact_pending_in(to_node, to_host, bare_from))",
3982
ab065ff4628b mod_firewall: Remove trailing whitespace
Kim Alvefur <zash@zash.se>
parents: 3973
diff changeset
134 { "rostermanager", "split_to", "bare_to", "bare_from" };
2916
b1cdcbcd1c90 mod_firewall: Add PENDING SUBSCRIPTION FROM SENDER? condition
Matthew Wild <mwild1@gmail.com>
parents: 2894
diff changeset
135 end
b1cdcbcd1c90 mod_firewall: Add PENDING SUBSCRIPTION FROM SENDER? condition
Matthew Wild <mwild1@gmail.com>
parents: 2894
diff changeset
136
947
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
137 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
138 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
139 end
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
140
954
bec5b6e2eab8 mod_firewall: Add INSPECT conditional, for deeper inspection of stanzas
Kim Alvefur <zash@zash.se>
parents: 947
diff changeset
141 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
142 if path:find("=") then
2386
00eed68f63bf mod_firewall: INSPECT: support for literal substring search and expressions
Matthew Wild <mwild1@gmail.com>
parents: 2363
diff changeset
143 local query, match_type, value = path:match("(.-)([~/$]*)=(.*)");
2362
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: 2342
diff changeset
144 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: 2342
diff changeset
145 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: 2342
diff changeset
146 end
2519
d4bc434a60a4 mod_firewall: Update functions that use meta() to allow functions with deps inside expressions
Matthew Wild <mwild1@gmail.com>
parents: 2465
diff changeset
147 local meta_deps = {};
2386
00eed68f63bf mod_firewall: INSPECT: support for literal substring search and expressions
Matthew Wild <mwild1@gmail.com>
parents: 2363
diff changeset
148 local quoted_value = ("%q"):format(value);
00eed68f63bf mod_firewall: INSPECT: support for literal substring search and expressions
Matthew Wild <mwild1@gmail.com>
parents: 2363
diff changeset
149 if match_type:find("$", 1, true) then
00eed68f63bf mod_firewall: INSPECT: support for literal substring search and expressions
Matthew Wild <mwild1@gmail.com>
parents: 2363
diff changeset
150 match_type = match_type:gsub("%$", "");
2519
d4bc434a60a4 mod_firewall: Update functions that use meta() to allow functions with deps inside expressions
Matthew Wild <mwild1@gmail.com>
parents: 2465
diff changeset
151 quoted_value = meta(quoted_value, meta_deps);
2386
00eed68f63bf mod_firewall: INSPECT: support for literal substring search and expressions
Matthew Wild <mwild1@gmail.com>
parents: 2363
diff changeset
152 end
00eed68f63bf mod_firewall: INSPECT: support for literal substring search and expressions
Matthew Wild <mwild1@gmail.com>
parents: 2363
diff changeset
153 if match_type == "~" then -- Lua pattern match
2519
d4bc434a60a4 mod_firewall: Update functions that use meta() to allow functions with deps inside expressions
Matthew Wild <mwild1@gmail.com>
parents: 2465
diff changeset
154 return ("(stanza:find(%q) or ''):match(%s)"):format(query, quoted_value), meta_deps;
2386
00eed68f63bf mod_firewall: INSPECT: support for literal substring search and expressions
Matthew Wild <mwild1@gmail.com>
parents: 2363
diff changeset
155 elseif match_type == "/" then -- find literal substring
2519
d4bc434a60a4 mod_firewall: Update functions that use meta() to allow functions with deps inside expressions
Matthew Wild <mwild1@gmail.com>
parents: 2465
diff changeset
156 return ("(stanza:find(%q) or ''):find(%s, 1, true)"):format(query, quoted_value), meta_deps;
2386
00eed68f63bf mod_firewall: INSPECT: support for literal substring search and expressions
Matthew Wild <mwild1@gmail.com>
parents: 2363
diff changeset
157 elseif match_type == "" then -- exact match
2519
d4bc434a60a4 mod_firewall: Update functions that use meta() to allow functions with deps inside expressions
Matthew Wild <mwild1@gmail.com>
parents: 2465
diff changeset
158 return ("stanza:find(%q) == %s"):format(query, quoted_value), meta_deps;
2109
9db4113d0cb5 mod_firewall: INSPECT: Support for pattern matches (confusingly using ~= instead of =)
Matthew Wild <mwild1@gmail.com>
parents: 2107
diff changeset
159 else
2386
00eed68f63bf mod_firewall: INSPECT: support for literal substring search and expressions
Matthew Wild <mwild1@gmail.com>
parents: 2363
diff changeset
160 error("Unrecognised comparison '"..match_type.."='", 0);
2109
9db4113d0cb5 mod_firewall: INSPECT: Support for pattern matches (confusingly using ~= instead of =)
Matthew Wild <mwild1@gmail.com>
parents: 2107
diff changeset
161 end
954
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 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
164 end
bec5b6e2eab8 mod_firewall: Add INSPECT conditional, for deeper inspection of stanzas
Kim Alvefur <zash@zash.se>
parents: 947
diff changeset
165
947
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
166 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
167 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
168 end
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
169
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
170 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
171 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
172 end
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
173
2594
1e1c929c1aa5 mod_firewall: Add and document CROSSING GROUPS condition
Matthew Wild <mwild1@gmail.com>
parents: 2584
diff changeset
174 function condition_handlers.CROSSING_GROUPS(group_names)
1e1c929c1aa5 mod_firewall: Add and document CROSSING GROUPS condition
Matthew Wild <mwild1@gmail.com>
parents: 2584
diff changeset
175 local code = {};
6509
f61564e11d3b various: Adjust for loop variables becoming constants in Lua 5.5
Kim Alvefur <zash@zash.se>
parents: 6502
diff changeset
176 for wgroup_name in group_names:gmatch("([^, ][^,]+)") do
f61564e11d3b various: Adjust for loop variables becoming constants in Lua 5.5
Kim Alvefur <zash@zash.se>
parents: 6502
diff changeset
177 local group_name = wgroup_name:match("^%s*(.-)%s*$"); -- Trim leading/trailing whitespace
2594
1e1c929c1aa5 mod_firewall: Add and document CROSSING GROUPS condition
Matthew Wild <mwild1@gmail.com>
parents: 2584
diff changeset
178 -- 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: 2584
diff changeset
179 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: 2584
diff changeset
180 end
1e1c929c1aa5 mod_firewall: Add and document CROSSING GROUPS condition
Matthew Wild <mwild1@gmail.com>
parents: 2584
diff changeset
181 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: 2584
diff changeset
182 end
1e1c929c1aa5 mod_firewall: Add and document CROSSING GROUPS condition
Matthew Wild <mwild1@gmail.com>
parents: 2584
diff changeset
183
5002
84997bc3f92e mod_firewall: Update for role-auth (backwards compatible)
Matthew Wild <mwild1@gmail.com>
parents: 4608
diff changeset
184 -- 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
185 function condition_handlers.FROM_ADMIN_OF(host)
2577
00cef058df8d mod_firewall: TO/FROM ADMIN OF: Fix string quoting
Matthew Wild <mwild1@gmail.com>
parents: 2575
diff changeset
186 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
187 end
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
188
5002
84997bc3f92e mod_firewall: Update for role-auth (backwards compatible)
Matthew Wild <mwild1@gmail.com>
parents: 4608
diff changeset
189 -- 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
190 function condition_handlers.TO_ADMIN_OF(host)
2577
00cef058df8d mod_firewall: TO/FROM ADMIN OF: Fix string quoting
Matthew Wild <mwild1@gmail.com>
parents: 2575
diff changeset
191 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
192 end
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
193
5002
84997bc3f92e mod_firewall: Update for role-auth (backwards compatible)
Matthew Wild <mwild1@gmail.com>
parents: 4608
diff changeset
194 -- COMPAT w/0.12: Deprecated
2553
7ed2a66bfabd mod_firewall: Add TO/FROM ADMIN
Matthew Wild <mwild1@gmail.com>
parents: 2552
diff changeset
195 function condition_handlers.FROM_ADMIN()
2575
214b49d05ea1 mod_firewall: Fix TO/FROM ADMIN to use current (module) host
Matthew Wild <mwild1@gmail.com>
parents: 2564
diff changeset
196 return ("is_admin(bare_from, current_host)"), { "is_admin", "bare_from", "current_host" };
2553
7ed2a66bfabd mod_firewall: Add TO/FROM ADMIN
Matthew Wild <mwild1@gmail.com>
parents: 2552
diff changeset
197 end
7ed2a66bfabd mod_firewall: Add TO/FROM ADMIN
Matthew Wild <mwild1@gmail.com>
parents: 2552
diff changeset
198
5002
84997bc3f92e mod_firewall: Update for role-auth (backwards compatible)
Matthew Wild <mwild1@gmail.com>
parents: 4608
diff changeset
199 -- COMPAT w/0.12: Deprecated
2553
7ed2a66bfabd mod_firewall: Add TO/FROM ADMIN
Matthew Wild <mwild1@gmail.com>
parents: 2552
diff changeset
200 function condition_handlers.TO_ADMIN()
2575
214b49d05ea1 mod_firewall: Fix TO/FROM ADMIN to use current (module) host
Matthew Wild <mwild1@gmail.com>
parents: 2564
diff changeset
201 return ("is_admin(bare_to, current_host)"), { "is_admin", "bare_to", "current_host" };
2553
7ed2a66bfabd mod_firewall: Add TO/FROM ADMIN
Matthew Wild <mwild1@gmail.com>
parents: 2552
diff changeset
202 end
7ed2a66bfabd mod_firewall: Add TO/FROM ADMIN
Matthew Wild <mwild1@gmail.com>
parents: 2552
diff changeset
203
5002
84997bc3f92e mod_firewall: Update for role-auth (backwards compatible)
Matthew Wild <mwild1@gmail.com>
parents: 4608
diff changeset
204 -- MAY: permission_to_check
84997bc3f92e mod_firewall: Update for role-auth (backwards compatible)
Matthew Wild <mwild1@gmail.com>
parents: 4608
diff changeset
205 function condition_handlers.MAY(permission_to_check)
84997bc3f92e mod_firewall: Update for role-auth (backwards compatible)
Matthew Wild <mwild1@gmail.com>
parents: 4608
diff changeset
206 return ("module:may(%q, event)"):format(permission_to_check);
84997bc3f92e mod_firewall: Update for role-auth (backwards compatible)
Matthew Wild <mwild1@gmail.com>
parents: 4608
diff changeset
207 end
84997bc3f92e mod_firewall: Update for role-auth (backwards compatible)
Matthew Wild <mwild1@gmail.com>
parents: 4608
diff changeset
208
84997bc3f92e mod_firewall: Update for role-auth (backwards compatible)
Matthew Wild <mwild1@gmail.com>
parents: 4608
diff changeset
209 function condition_handlers.TO_ROLE(role_name)
5793
e304e19536f2 mod_firewall: TO/FROM ROLE: Handle JIDs with no role (thanks Zash)
Matthew Wild <mwild1@gmail.com>
parents: 5792
diff changeset
210 return ("recipient_role and recipient_role.name == %q"):format(role_name), { "recipient_role" };
5002
84997bc3f92e mod_firewall: Update for role-auth (backwards compatible)
Matthew Wild <mwild1@gmail.com>
parents: 4608
diff changeset
211 end
84997bc3f92e mod_firewall: Update for role-auth (backwards compatible)
Matthew Wild <mwild1@gmail.com>
parents: 4608
diff changeset
212
84997bc3f92e mod_firewall: Update for role-auth (backwards compatible)
Matthew Wild <mwild1@gmail.com>
parents: 4608
diff changeset
213 function condition_handlers.FROM_ROLE(role_name)
5793
e304e19536f2 mod_firewall: TO/FROM ROLE: Handle JIDs with no role (thanks Zash)
Matthew Wild <mwild1@gmail.com>
parents: 5792
diff changeset
214 return ("sender_role and sender_role.name == %q"):format(role_name), { "sender_role" };
5002
84997bc3f92e mod_firewall: Update for role-auth (backwards compatible)
Matthew Wild <mwild1@gmail.com>
parents: 4608
diff changeset
215 end
84997bc3f92e mod_firewall: Update for role-auth (backwards compatible)
Matthew Wild <mwild1@gmail.com>
parents: 4608
diff changeset
216
968
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
217 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
218
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
219 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
220 hour, minute = tonumber(hour), tonumber(minute);
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
221 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
222 if minute == 0 then
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
223 return "(current_hour"..adj_op..hour..")";
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
224 else
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
225 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
226 end
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
227 end
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
228
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
229 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
230 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
231 end
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
232
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
233 function condition_handlers.DAY(days)
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
234 local conditions = {};
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
235 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
236 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
237 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
238 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
239 local op = "and";
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
240 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
241 op = "or";
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
242 end
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
243 table.insert(conditions, ("current_day >= %d %s current_day <= %d"):format(day_start_num, op, day_end_num));
2070
2356114ff505 mod_firewall: Optimize string match operations, string.find is faster than .match since no string is returned
Kim Alvefur <zash@zash.se>
parents: 2036
diff changeset
244 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
245 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
246 table.insert(conditions, "current_day == "..day);
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
247 else
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
248 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
249 end
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
250 end
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
251 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
252 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
253 end
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
254
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
255 function condition_handlers.TIME(ranges)
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
256 local conditions = {};
6509
f61564e11d3b various: Adjust for loop variables becoming constants in Lua 5.5
Kim Alvefur <zash@zash.se>
parents: 6502
diff changeset
257 for rawrange in ranges:gmatch("([^,]+)") do
968
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
258 local clause = {};
6509
f61564e11d3b various: Adjust for loop variables becoming constants in Lua 5.5
Kim Alvefur <zash@zash.se>
parents: 6502
diff changeset
259 local range = rawrange:lower()
968
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
260 :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
261 :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
262 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
263 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
264 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
265 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
266 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
267 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
268 end
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
269 if #clause == 0 then
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
270 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
271 end
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
272 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
273 end
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
274 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
275 end
f3b0ddeebd9d mod_firewall/conditions: Add DAY and TIME conditions
Matthew Wild <mwild1@gmail.com>
parents: 965
diff changeset
276
2128
21bc4d7cddae mod_firewall: Add support for throttling based on user-defined properties (experimental)
Matthew Wild <mwild1@gmail.com>
parents: 2127
diff changeset
277 function condition_handlers.LIMIT(spec)
21bc4d7cddae mod_firewall: Add support for throttling based on user-defined properties (experimental)
Matthew Wild <mwild1@gmail.com>
parents: 2127
diff changeset
278 local name, param = spec:match("^(%w+) on (.+)$");
2519
d4bc434a60a4 mod_firewall: Update functions that use meta() to allow functions with deps inside expressions
Matthew Wild <mwild1@gmail.com>
parents: 2465
diff changeset
279 local meta_deps = {};
2128
21bc4d7cddae mod_firewall: Add support for throttling based on user-defined properties (experimental)
Matthew Wild <mwild1@gmail.com>
parents: 2127
diff changeset
280
21bc4d7cddae mod_firewall: Add support for throttling based on user-defined properties (experimental)
Matthew Wild <mwild1@gmail.com>
parents: 2127
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: 2127
diff changeset
282 name = spec:match("^%w+$");
21bc4d7cddae mod_firewall: Add support for throttling based on user-defined properties (experimental)
Matthew Wild <mwild1@gmail.com>
parents: 2127
diff changeset
283 if not name then
21bc4d7cddae mod_firewall: Add support for throttling based on user-defined properties (experimental)
Matthew Wild <mwild1@gmail.com>
parents: 2127
diff changeset
284 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: 2127
diff changeset
285 end
21bc4d7cddae mod_firewall: Add support for throttling based on user-defined properties (experimental)
Matthew Wild <mwild1@gmail.com>
parents: 2127
diff changeset
286 else
2519
d4bc434a60a4 mod_firewall: Update functions that use meta() to allow functions with deps inside expressions
Matthew Wild <mwild1@gmail.com>
parents: 2465
diff changeset
287 param = meta(("%q"):format(param), meta_deps);
2128
21bc4d7cddae mod_firewall: Add support for throttling based on user-defined properties (experimental)
Matthew Wild <mwild1@gmail.com>
parents: 2127
diff changeset
288 end
21bc4d7cddae mod_firewall: Add support for throttling based on user-defined properties (experimental)
Matthew Wild <mwild1@gmail.com>
parents: 2127
diff changeset
289
21bc4d7cddae mod_firewall: Add support for throttling based on user-defined properties (experimental)
Matthew Wild <mwild1@gmail.com>
parents: 2127
diff changeset
290 if not param then
2519
d4bc434a60a4 mod_firewall: Update functions that use meta() to allow functions with deps inside expressions
Matthew Wild <mwild1@gmail.com>
parents: 2465
diff changeset
291 return ("not global_throttle_%s:poll(1)"):format(name), { "globalthrottle:"..name, unpack(meta_deps) };
2128
21bc4d7cddae mod_firewall: Add support for throttling based on user-defined properties (experimental)
Matthew Wild <mwild1@gmail.com>
parents: 2127
diff changeset
292 end
2859
22e11645a895 mod_firewall: Trim trailing whitespace [luacheck]
Kim Alvefur <zash@zash.se>
parents: 2857
diff changeset
293 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
294 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
295
2107
f445f43b9ba1 mod_firewall: Add support for session marking (MARK_ORIGIN, UNMARK_ORIGIN, ORIGIN_MARKED)
Matthew Wild <mwild1@gmail.com>
parents: 2075
diff changeset
296 function condition_handlers.ORIGIN_MARKED(name_and_time)
2127
59023dffbdd4 mod_firewall: Allow underscore in mark names (thanks Ge0rG)
Matthew Wild <mwild1@gmail.com>
parents: 2125
diff changeset
297 local name, time = name_and_time:match("^%s*([%w_]+)%s+%(([^)]+)s%)%s*$");
2107
f445f43b9ba1 mod_firewall: Add support for session marking (MARK_ORIGIN, UNMARK_ORIGIN, ORIGIN_MARKED)
Matthew Wild <mwild1@gmail.com>
parents: 2075
diff changeset
298 if not name then
2127
59023dffbdd4 mod_firewall: Allow underscore in mark names (thanks Ge0rG)
Matthew Wild <mwild1@gmail.com>
parents: 2125
diff changeset
299 name = name_and_time:match("^%s*([%w_]+)%s*$");
2107
f445f43b9ba1 mod_firewall: Add support for session marking (MARK_ORIGIN, UNMARK_ORIGIN, ORIGIN_MARKED)
Matthew Wild <mwild1@gmail.com>
parents: 2075
diff changeset
300 end
f445f43b9ba1 mod_firewall: Add support for session marking (MARK_ORIGIN, UNMARK_ORIGIN, ORIGIN_MARKED)
Matthew Wild <mwild1@gmail.com>
parents: 2075
diff changeset
301 if not name then
f445f43b9ba1 mod_firewall: Add support for session marking (MARK_ORIGIN, UNMARK_ORIGIN, ORIGIN_MARKED)
Matthew Wild <mwild1@gmail.com>
parents: 2075
diff changeset
302 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: 2075
diff changeset
303 end
f445f43b9ba1 mod_firewall: Add support for session marking (MARK_ORIGIN, UNMARK_ORIGIN, ORIGIN_MARKED)
Matthew Wild <mwild1@gmail.com>
parents: 2075
diff changeset
304 if time then
2116
2bb42ba342f3 mod_firewall: Fix usage of incorrect variable current_time in ORIGIN_MARKED condition (thanks Ge0rG)
Matthew Wild <mwild1@gmail.com>
parents: 2109
diff changeset
305 return ("(current_timestamp - (session.firewall_marked_%s or 0)) < %d"):format(idsafe(name), tonumber(time)), { "timestamp" };
2107
f445f43b9ba1 mod_firewall: Add support for session marking (MARK_ORIGIN, UNMARK_ORIGIN, ORIGIN_MARKED)
Matthew Wild <mwild1@gmail.com>
parents: 2075
diff changeset
306 end
f445f43b9ba1 mod_firewall: Add support for session marking (MARK_ORIGIN, UNMARK_ORIGIN, ORIGIN_MARKED)
Matthew Wild <mwild1@gmail.com>
parents: 2075
diff changeset
307 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: 2075
diff changeset
308 end
f445f43b9ba1 mod_firewall: Add support for session marking (MARK_ORIGIN, UNMARK_ORIGIN, ORIGIN_MARKED)
Matthew Wild <mwild1@gmail.com>
parents: 2075
diff changeset
309
2894
165d2877eeac mod_firewall: Add experimental user-centric persistent marks behind a feature flag
Kim Alvefur <zash@zash.se>
parents: 2882
diff changeset
310 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: 2882
diff changeset
311 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: 2882
diff changeset
312 if not name then
165d2877eeac mod_firewall: Add experimental user-centric persistent marks behind a feature flag
Kim Alvefur <zash@zash.se>
parents: 2882
diff changeset
313 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: 2882
diff changeset
314 end
165d2877eeac mod_firewall: Add experimental user-centric persistent marks behind a feature flag
Kim Alvefur <zash@zash.se>
parents: 2882
diff changeset
315 if not name then
165d2877eeac mod_firewall: Add experimental user-centric persistent marks behind a feature flag
Kim Alvefur <zash@zash.se>
parents: 2882
diff changeset
316 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: 2882
diff changeset
317 end
165d2877eeac mod_firewall: Add experimental user-centric persistent marks behind a feature flag
Kim Alvefur <zash@zash.se>
parents: 2882
diff changeset
318 if time then
5535
eeccec0955a1 mod_firewall: Split some long lines [luacheck]
Matthew Wild <mwild1@gmail.com>
parents: 5534
diff changeset
319 return ([[(
eeccec0955a1 mod_firewall: Split some long lines [luacheck]
Matthew Wild <mwild1@gmail.com>
parents: 5534
diff changeset
320 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: 5534
diff changeset
321 ) < %d]]):format(idsafe(name), tonumber(time)), { "timestamp" };
2894
165d2877eeac mod_firewall: Add experimental user-centric persistent marks behind a feature flag
Kim Alvefur <zash@zash.se>
parents: 2882
diff changeset
322 end
165d2877eeac mod_firewall: Add experimental user-centric persistent marks behind a feature flag
Kim Alvefur <zash@zash.se>
parents: 2882
diff changeset
323 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: 2882
diff changeset
324 end
165d2877eeac mod_firewall: Add experimental user-centric persistent marks behind a feature flag
Kim Alvefur <zash@zash.se>
parents: 2882
diff changeset
325
2554
19bb4606013f mod_firewall: Fix everything wrong with SENT_DIRECTED_PRESENCE_TO_SENDER
Matthew Wild <mwild1@gmail.com>
parents: 2553
diff changeset
326 function condition_handlers.SENT_DIRECTED_PRESENCE_TO_SENDER()
2882
6f289283feb1 mod_firewall: Prevent traceback if no directed presence has been sent (fixes #1081)
Kim Alvefur <zash@zash.se>
parents: 2859
diff changeset
327 return "not not (session.directed and session.directed[from])", { "from" };
2529
3fe4ca2b55c2 mod_firewall: Add 'SENT DIRECTED PRESENCE TO SENDER?'
Matthew Wild <mwild1@gmail.com>
parents: 2528
diff changeset
328 end
3fe4ca2b55c2 mod_firewall: Add 'SENT DIRECTED PRESENCE TO SENDER?'
Matthew Wild <mwild1@gmail.com>
parents: 2528
diff changeset
329
2618
c6652d055ba3 mod_firewall: Add some more comments
Matthew Wild <mwild1@gmail.com>
parents: 2594
diff changeset
330 -- TO FULL JID?
2555
a9eb4d5566f3 mod_firewall: Add TO FULL JID
Matthew Wild <mwild1@gmail.com>
parents: 2554
diff changeset
331 function condition_handlers.TO_FULL_JID()
4608
4e8fa75cc678 mod_firewall: Remove reliance on full_sessions being a global
Kim Alvefur <zash@zash.se>
parents: 3982
diff changeset
332 return "not not full_sessions[to]", { "to", "full_sessions" };
2555
a9eb4d5566f3 mod_firewall: Add TO FULL JID
Matthew Wild <mwild1@gmail.com>
parents: 2554
diff changeset
333 end
a9eb4d5566f3 mod_firewall: Add TO FULL JID
Matthew Wild <mwild1@gmail.com>
parents: 2554
diff changeset
334
2520
c6fd8975704b mod_firewall: Initial support for lists, in-memory and HTTP
Matthew Wild <mwild1@gmail.com>
parents: 2519
diff changeset
335 -- CHECK LIST: spammers contains $<@from>
c6fd8975704b mod_firewall: Initial support for lists, in-memory and HTTP
Matthew Wild <mwild1@gmail.com>
parents: 2519
diff changeset
336 function condition_handlers.CHECK_LIST(list_condition)
c6fd8975704b mod_firewall: Initial support for lists, in-memory and HTTP
Matthew Wild <mwild1@gmail.com>
parents: 2519
diff changeset
337 local list_name, expr = list_condition:match("(%S+) contains (.+)$");
2521
66b81e144ded mod_firewall: Fix CHECK LIST syntax check
Matthew Wild <mwild1@gmail.com>
parents: 2520
diff changeset
338 if not (list_name and expr) then
2520
c6fd8975704b mod_firewall: Initial support for lists, in-memory and HTTP
Matthew Wild <mwild1@gmail.com>
parents: 2519
diff changeset
339 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: 2519
diff changeset
340 end
c6fd8975704b mod_firewall: Initial support for lists, in-memory and HTTP
Matthew Wild <mwild1@gmail.com>
parents: 2519
diff changeset
341 local meta_deps = {};
c6fd8975704b mod_firewall: Initial support for lists, in-memory and HTTP
Matthew Wild <mwild1@gmail.com>
parents: 2519
diff changeset
342 expr = meta(("%q"):format(expr), meta_deps);
c6fd8975704b mod_firewall: Initial support for lists, in-memory and HTTP
Matthew Wild <mwild1@gmail.com>
parents: 2519
diff changeset
343 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: 2519
diff changeset
344 end
c6fd8975704b mod_firewall: Initial support for lists, in-memory and HTTP
Matthew Wild <mwild1@gmail.com>
parents: 2519
diff changeset
345
2528
44a71584521d mod_firewall: Add SEARCH, PATTERN definitions and SCAN condition to check tokenized stanza:find() against a list
Matthew Wild <mwild1@gmail.com>
parents: 2521
diff changeset
346 -- 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: 2521
diff changeset
347 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: 2521
diff changeset
348 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: 2521
diff changeset
349 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: 2521
diff changeset
350 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: 2521
diff changeset
351 end
5535
eeccec0955a1 mod_firewall: Split some long lines [luacheck]
Matthew Wild <mwild1@gmail.com>
parents: 5534
diff changeset
352 return ("scan_list(list_%s, %s)"):format(
eeccec0955a1 mod_firewall: Split some long lines [luacheck]
Matthew Wild <mwild1@gmail.com>
parents: 5534
diff changeset
353 list_name,
eeccec0955a1 mod_firewall: Split some long lines [luacheck]
Matthew Wild <mwild1@gmail.com>
parents: 5534
diff changeset
354 "tokens_"..search_name.."_"..pattern_name
eeccec0955a1 mod_firewall: Split some long lines [luacheck]
Matthew Wild <mwild1@gmail.com>
parents: 5534
diff changeset
355 ), {
eeccec0955a1 mod_firewall: Split some long lines [luacheck]
Matthew Wild <mwild1@gmail.com>
parents: 5534
diff changeset
356 "scan_list",
eeccec0955a1 mod_firewall: Split some long lines [luacheck]
Matthew Wild <mwild1@gmail.com>
parents: 5534
diff changeset
357 "tokens:"..search_name.."-"..pattern_name, "list:"..list_name
eeccec0955a1 mod_firewall: Split some long lines [luacheck]
Matthew Wild <mwild1@gmail.com>
parents: 5534
diff changeset
358 };
2528
44a71584521d mod_firewall: Add SEARCH, PATTERN definitions and SCAN condition to check tokenized stanza:find() against a list
Matthew Wild <mwild1@gmail.com>
parents: 2521
diff changeset
359 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: 2521
diff changeset
360
2618
c6652d055ba3 mod_firewall: Add some more comments
Matthew Wild <mwild1@gmail.com>
parents: 2594
diff changeset
361 -- COUNT: lines in body < 10
2545
9b46d24edf0d mod_firewall: Add and document COUNT condition
Matthew Wild <mwild1@gmail.com>
parents: 2537
diff changeset
362 local valid_comp_ops = { [">"] = ">", ["<"] = "<", ["="] = "==", ["=="] = "==", ["<="] = "<=", [">="] = ">=" };
9b46d24edf0d mod_firewall: Add and document COUNT condition
Matthew Wild <mwild1@gmail.com>
parents: 2537
diff changeset
363 function condition_handlers.COUNT(count_expression)
9b46d24edf0d mod_firewall: Add and document COUNT condition
Matthew Wild <mwild1@gmail.com>
parents: 2537
diff changeset
364 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: 2537
diff changeset
365 if not (pattern_name) then
9b46d24edf0d mod_firewall: Add and document COUNT condition
Matthew Wild <mwild1@gmail.com>
parents: 2537
diff changeset
366 error("Error parsing COUNT expression, syntax: PATTERN in SEARCH COMPARATOR");
9b46d24edf0d mod_firewall: Add and document COUNT condition
Matthew Wild <mwild1@gmail.com>
parents: 2537
diff changeset
367 end
9b46d24edf0d mod_firewall: Add and document COUNT condition
Matthew Wild <mwild1@gmail.com>
parents: 2537
diff changeset
368 local value;
9b46d24edf0d mod_firewall: Add and document COUNT condition
Matthew Wild <mwild1@gmail.com>
parents: 2537
diff changeset
369 comparator_expression = comparator_expression:gsub("%d+", function (value_string)
9b46d24edf0d mod_firewall: Add and document COUNT condition
Matthew Wild <mwild1@gmail.com>
parents: 2537
diff changeset
370 value = tonumber(value_string);
9b46d24edf0d mod_firewall: Add and document COUNT condition
Matthew Wild <mwild1@gmail.com>
parents: 2537
diff changeset
371 return "";
9b46d24edf0d mod_firewall: Add and document COUNT condition
Matthew Wild <mwild1@gmail.com>
parents: 2537
diff changeset
372 end);
9b46d24edf0d mod_firewall: Add and document COUNT condition
Matthew Wild <mwild1@gmail.com>
parents: 2537
diff changeset
373 if not value then
9b46d24edf0d mod_firewall: Add and document COUNT condition
Matthew Wild <mwild1@gmail.com>
parents: 2537
diff changeset
374 error("Error parsing COUNT expression, expected value");
9b46d24edf0d mod_firewall: Add and document COUNT condition
Matthew Wild <mwild1@gmail.com>
parents: 2537
diff changeset
375 end
9b46d24edf0d mod_firewall: Add and document COUNT condition
Matthew Wild <mwild1@gmail.com>
parents: 2537
diff changeset
376 local comp_op = comparator_expression:gsub("%s+", "");
9b46d24edf0d mod_firewall: Add and document COUNT condition
Matthew Wild <mwild1@gmail.com>
parents: 2537
diff changeset
377 assert(valid_comp_ops[comp_op], "Error parsing COUNT expression, unknown comparison operator: "..comp_op);
5535
eeccec0955a1 mod_firewall: Split some long lines [luacheck]
Matthew Wild <mwild1@gmail.com>
parents: 5534
diff changeset
378 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: 5534
diff changeset
379 search_name, pattern_name, comp_op, value
eeccec0955a1 mod_firewall: Split some long lines [luacheck]
Matthew Wild <mwild1@gmail.com>
parents: 5534
diff changeset
380 ), {
eeccec0955a1 mod_firewall: Split some long lines [luacheck]
Matthew Wild <mwild1@gmail.com>
parents: 5534
diff changeset
381 "it_count",
eeccec0955a1 mod_firewall: Split some long lines [luacheck]
Matthew Wild <mwild1@gmail.com>
parents: 5534
diff changeset
382 "search:"..search_name, "pattern:"..pattern_name
eeccec0955a1 mod_firewall: Split some long lines [luacheck]
Matthew Wild <mwild1@gmail.com>
parents: 5534
diff changeset
383 };
2545
9b46d24edf0d mod_firewall: Add and document COUNT condition
Matthew Wild <mwild1@gmail.com>
parents: 2537
diff changeset
384 end
9b46d24edf0d mod_firewall: Add and document COUNT condition
Matthew Wild <mwild1@gmail.com>
parents: 2537
diff changeset
385
6502
b15601203d0d mod_firewall: Support 'FROM IP' and 'FROM SUBNET' conditions
Matthew Wild <mwild1@gmail.com>
parents: 6029
diff changeset
386 function condition_handlers.FROM_IP(ip_spec)
b15601203d0d mod_firewall: Support 'FROM IP' and 'FROM SUBNET' conditions
Matthew Wild <mwild1@gmail.com>
parents: 6029
diff changeset
387 local parsed_ip, err = iplib.new_ip(ip_spec);
b15601203d0d mod_firewall: Support 'FROM IP' and 'FROM SUBNET' conditions
Matthew Wild <mwild1@gmail.com>
parents: 6029
diff changeset
388 if not parsed_ip then
b15601203d0d mod_firewall: Support 'FROM IP' and 'FROM SUBNET' conditions
Matthew Wild <mwild1@gmail.com>
parents: 6029
diff changeset
389 error("Cannot parse IP address: "..(err or "unknown error"));
b15601203d0d mod_firewall: Support 'FROM IP' and 'FROM SUBNET' conditions
Matthew Wild <mwild1@gmail.com>
parents: 6029
diff changeset
390 end
b15601203d0d mod_firewall: Support 'FROM IP' and 'FROM SUBNET' conditions
Matthew Wild <mwild1@gmail.com>
parents: 6029
diff changeset
391 local normal_ip = tostring(parsed_ip);
b15601203d0d mod_firewall: Support 'FROM IP' and 'FROM SUBNET' conditions
Matthew Wild <mwild1@gmail.com>
parents: 6029
diff changeset
392 return ("session.ip == %q"):format(normal_ip);
b15601203d0d mod_firewall: Support 'FROM IP' and 'FROM SUBNET' conditions
Matthew Wild <mwild1@gmail.com>
parents: 6029
diff changeset
393 end
b15601203d0d mod_firewall: Support 'FROM IP' and 'FROM SUBNET' conditions
Matthew Wild <mwild1@gmail.com>
parents: 6029
diff changeset
394
b15601203d0d mod_firewall: Support 'FROM IP' and 'FROM SUBNET' conditions
Matthew Wild <mwild1@gmail.com>
parents: 6029
diff changeset
395 function condition_handlers.FROM_SUBNET(subnet_spec)
b15601203d0d mod_firewall: Support 'FROM IP' and 'FROM SUBNET' conditions
Matthew Wild <mwild1@gmail.com>
parents: 6029
diff changeset
396 local subnet, bits = iplib.parse_cidr(subnet_spec);
b15601203d0d mod_firewall: Support 'FROM IP' and 'FROM SUBNET' conditions
Matthew Wild <mwild1@gmail.com>
parents: 6029
diff changeset
397 if not subnet then
b15601203d0d mod_firewall: Support 'FROM IP' and 'FROM SUBNET' conditions
Matthew Wild <mwild1@gmail.com>
parents: 6029
diff changeset
398 error("Cannot parse subnet CIDR");
b15601203d0d mod_firewall: Support 'FROM IP' and 'FROM SUBNET' conditions
Matthew Wild <mwild1@gmail.com>
parents: 6029
diff changeset
399 end
b15601203d0d mod_firewall: Support 'FROM IP' and 'FROM SUBNET' conditions
Matthew Wild <mwild1@gmail.com>
parents: 6029
diff changeset
400 local spec_hash = sha256(subnet_spec, true):sub(1, 8);
b15601203d0d mod_firewall: Support 'FROM IP' and 'FROM SUBNET' conditions
Matthew Wild <mwild1@gmail.com>
parents: 6029
diff changeset
401 return ("iplib.match(session_parsed_ip, parsed_ip_%s, %d)"):format(
b15601203d0d mod_firewall: Support 'FROM IP' and 'FROM SUBNET' conditions
Matthew Wild <mwild1@gmail.com>
parents: 6029
diff changeset
402 spec_hash, bits
b15601203d0d mod_firewall: Support 'FROM IP' and 'FROM SUBNET' conditions
Matthew Wild <mwild1@gmail.com>
parents: 6029
diff changeset
403 ), {
b15601203d0d mod_firewall: Support 'FROM IP' and 'FROM SUBNET' conditions
Matthew Wild <mwild1@gmail.com>
parents: 6029
diff changeset
404 "iplib", "session_parsed_ip", "parsed_ip:"..spec_hash..":"..tostring(subnet)
b15601203d0d mod_firewall: Support 'FROM IP' and 'FROM SUBNET' conditions
Matthew Wild <mwild1@gmail.com>
parents: 6029
diff changeset
405 };
b15601203d0d mod_firewall: Support 'FROM IP' and 'FROM SUBNET' conditions
Matthew Wild <mwild1@gmail.com>
parents: 6029
diff changeset
406 end
b15601203d0d mod_firewall: Support 'FROM IP' and 'FROM SUBNET' conditions
Matthew Wild <mwild1@gmail.com>
parents: 6029
diff changeset
407
5704
ad5c77793750 mod_firewall: Add FROM COUNTRY condition based on GeoIP DB
Kim Alvefur <zash@zash.se>
parents: 5535
diff changeset
408 -- FROM COUNTRY: SE
ad5c77793750 mod_firewall: Add FROM COUNTRY condition based on GeoIP DB
Kim Alvefur <zash@zash.se>
parents: 5535
diff changeset
409 -- FROM COUNTRY: code=SE
ad5c77793750 mod_firewall: Add FROM COUNTRY condition based on GeoIP DB
Kim Alvefur <zash@zash.se>
parents: 5535
diff changeset
410 -- FROM COUNTRY: SWE
ad5c77793750 mod_firewall: Add FROM COUNTRY condition based on GeoIP DB
Kim Alvefur <zash@zash.se>
parents: 5535
diff changeset
411 -- FROM COUNTRY: code3=SWE
ad5c77793750 mod_firewall: Add FROM COUNTRY condition based on GeoIP DB
Kim Alvefur <zash@zash.se>
parents: 5535
diff changeset
412 -- FROM COUNTRY: continent=EU
ad5c77793750 mod_firewall: Add FROM COUNTRY condition based on GeoIP DB
Kim Alvefur <zash@zash.se>
parents: 5535
diff changeset
413 -- 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: 5535
diff changeset
414 -- TODO list support?
ad5c77793750 mod_firewall: Add FROM COUNTRY condition based on GeoIP DB
Kim Alvefur <zash@zash.se>
parents: 5535
diff changeset
415 function condition_handlers.FROM_COUNTRY(geoip_spec)
ad5c77793750 mod_firewall: Add FROM COUNTRY condition based on GeoIP DB
Kim Alvefur <zash@zash.se>
parents: 5535
diff changeset
416 local condition = "==";
ad5c77793750 mod_firewall: Add FROM COUNTRY condition based on GeoIP DB
Kim Alvefur <zash@zash.se>
parents: 5535
diff changeset
417 if not geoip_spec then
ad5c77793750 mod_firewall: Add FROM COUNTRY condition based on GeoIP DB
Kim Alvefur <zash@zash.se>
parents: 5535
diff changeset
418 geoip_spec = "--";
ad5c77793750 mod_firewall: Add FROM COUNTRY condition based on GeoIP DB
Kim Alvefur <zash@zash.se>
parents: 5535
diff changeset
419 condition = "~=";
ad5c77793750 mod_firewall: Add FROM COUNTRY condition based on GeoIP DB
Kim Alvefur <zash@zash.se>
parents: 5535
diff changeset
420 end
ad5c77793750 mod_firewall: Add FROM COUNTRY condition based on GeoIP DB
Kim Alvefur <zash@zash.se>
parents: 5535
diff changeset
421 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: 5535
diff changeset
422 if not field then
ad5c77793750 mod_firewall: Add FROM COUNTRY condition based on GeoIP DB
Kim Alvefur <zash@zash.se>
parents: 5535
diff changeset
423 if #geoip_spec == 3 then
ad5c77793750 mod_firewall: Add FROM COUNTRY condition based on GeoIP DB
Kim Alvefur <zash@zash.se>
parents: 5535
diff changeset
424 field, country = "code3", geoip_spec;
ad5c77793750 mod_firewall: Add FROM COUNTRY condition based on GeoIP DB
Kim Alvefur <zash@zash.se>
parents: 5535
diff changeset
425 elseif #geoip_spec == 2 then
ad5c77793750 mod_firewall: Add FROM COUNTRY condition based on GeoIP DB
Kim Alvefur <zash@zash.se>
parents: 5535
diff changeset
426 field, country = "code", geoip_spec;
ad5c77793750 mod_firewall: Add FROM COUNTRY condition based on GeoIP DB
Kim Alvefur <zash@zash.se>
parents: 5535
diff changeset
427 else
ad5c77793750 mod_firewall: Add FROM COUNTRY condition based on GeoIP DB
Kim Alvefur <zash@zash.se>
parents: 5535
diff changeset
428 error("Unknown country code type");
ad5c77793750 mod_firewall: Add FROM COUNTRY condition based on GeoIP DB
Kim Alvefur <zash@zash.se>
parents: 5535
diff changeset
429 end
ad5c77793750 mod_firewall: Add FROM COUNTRY condition based on GeoIP DB
Kim Alvefur <zash@zash.se>
parents: 5535
diff changeset
430 end
ad5c77793750 mod_firewall: Add FROM COUNTRY condition based on GeoIP DB
Kim Alvefur <zash@zash.se>
parents: 5535
diff changeset
431 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: 5535
diff changeset
432 end
ad5c77793750 mod_firewall: Add FROM COUNTRY condition based on GeoIP DB
Kim Alvefur <zash@zash.se>
parents: 5535
diff changeset
433
947
c91cac3b823f mod_firewall: General stanza filtering plugin with a declarative rule-based syntax
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
434 return condition_handlers;