# HG changeset patch # User Matthew Wild # Date 1487583090 0 # Node ID 44a71584521dace7ecca5ae95d6564d569b62bed # Parent 5ff7eb601d602232502fb45d811a9c2591511d18 mod_firewall: Add SEARCH, PATTERN definitions and SCAN condition to check tokenized stanza:find() against a list diff -r 5ff7eb601d60 -r 44a71584521d mod_firewall/conditions.lib.lua --- a/mod_firewall/conditions.lib.lua Mon Feb 20 09:29:38 2017 +0000 +++ b/mod_firewall/conditions.lib.lua Mon Feb 20 09:31:30 2017 +0000 @@ -263,4 +263,13 @@ return ("list_%s:contains(%s) == true"):format(list_name, expr), { "list:"..list_name, unpack(meta_deps) }; end +-- SCAN: body for word in badwords +function condition_handlers.SCAN(scan_expression) + local search_name, pattern_name, list_name = scan_expression:match("(%S+) for (%S+) in (%S+)$"); + if not (search_name) then + error("Error parsing SCAN expression, syntax: SEARCH for PATTERN in LIST"); + end + return ("scan_list(%s, %s)"):format(list_name, "tokens_"..search_name.."_"..pattern_name), { "scan_list", "tokens:"..search_name.."_"..pattern_name, "list:"..list_name }; +end + return condition_handlers; diff -r 5ff7eb601d60 -r 44a71584521d mod_firewall/definitions.lib.lua --- a/mod_firewall/definitions.lib.lua Mon Feb 20 09:29:38 2017 +0000 +++ b/mod_firewall/definitions.lib.lua Mon Feb 20 09:31:30 2017 +0000 @@ -170,4 +170,16 @@ return create_list(list_backend, list_definition:match("^%S+"), opts); end +function definition_handlers.PATTERN(name, pattern) + local ok, err = pcall(string.match, "", pattern); + if not ok then + error("Invalid pattern '"..name.."': "..err); + end + return pattern; +end + +function definition_handlers.SEARCH(name, pattern) + return pattern; +end + return definition_handlers; diff -r 5ff7eb601d60 -r 44a71584521d mod_firewall/mod_firewall.lua --- a/mod_firewall/mod_firewall.lua Mon Feb 20 09:29:38 2017 +0000 +++ b/mod_firewall/mod_firewall.lua Mon Feb 20 09:31:30 2017 +0000 @@ -199,6 +199,28 @@ return ("local list_%s = lists[%q];"):format(list, list); end }; + search = { + local_code = function (search_name) + local search_path = assert(active_definitions.SEARCH[search_name], "Undefined search path: "..search_name); + return ("local search_%s = tostring(stanza:find(%q) or \"\")"):format(search_name, search_path); + end; + }; + tokens = { + local_code = function (search_and_pattern) + local search_name, pattern_name = search_and_pattern:match("^([^%-]+)_(.+)$"); + local code = ([[local tokens_%s_%s = {}; + if search_%s then + for s in search_%s:gmatch(patterns.%s) do + tokens_%s_%s[s] = true; + end + end + ]]):format(search_name, pattern_name, search_name, search_name, pattern_name, search_name, pattern_name); + return code, { "search:"..search_name }; + end; + }; + scan_list = { + global_code = [[local function scan_list(list, items) for item in pairs(items) do if list:contains(item) then return true; end end]]; + } }; local function include_dep(dependency, code)