# HG changeset patch # User Matthew Wild # Date 1458132947 0 # Node ID 1124758cac7f3214c6b6f03ff238afad6cf10eed # Parent 4454f124465a362e4b0f77ef25f4a4e454653d0f# Parent ea95637cf0419751a90eefefcf8c8a68d6c9db49 Merge diff -r ea95637cf041 -r 1124758cac7f mod_firewall/README.markdown --- a/mod_firewall/README.markdown Wed Mar 16 13:30:03 2016 +0100 +++ b/mod_firewall/README.markdown Wed Mar 16 12:55:47 2016 +0000 @@ -292,7 +292,9 @@ `BOUNCE.` Bounce the stanza with the default error (usually service-unavailable) `BOUNCE=error` Bounce the stanza with the given error (MUST be a defined XMPP stanza error, see [RFC6120](http://xmpp.org/rfcs/rfc6120.html#stanzas-error-conditions). `BOUNCE=error (text)` As above, but include the supplied human-readable text with a description of the error - `COPY=jid` Make a copy of the stanza and send the copy to the specified JID. + `COPY=jid` Make a copy of the stanza and send the copy to the specified JID. The copied stanza flows through Prosody's routing code, and as such is affected by firewall rules. Be careful to avoid loops. + +**Note:** It is incorrect behaviour to reply to an 'error' stanza with another error, so BOUNCE will simply act the same as 'DROP' for stanzas that should not be bounced (error stanzas and iq results). ### Stanza modification @@ -310,3 +312,51 @@ Action Description --------------- ------------------------------------------------------------------------------------------------------------------------ `LOG=message` Logs the given message to Prosody's log file. Optionally prefix it with a log level in square brackets, e.g. `[debug]` + +You can include expressions in log messages, using `$(...)` syntax. For example, to log the stanza that matched the rule, you can use $(stanza), +or to log just the top tag of the stanza, use $(stanza:top_tag()). + +Example: + + # Log all stanzas to user@example.com: + TO: user@example.com + LOG=[debug] User received: $(stanza) + +Chains +------ + +Rules are grouped into "chains", which are injected at particular points in Prosody's routing code. + +Available chains are: + + Chain Description + -------------- ------------------------------------------------------------------------------------------- + deliver Applies to stanzas delivered to local recipients (regardless of the stanza's origin) + deliver_remote Applies to stanzas delivered to remote recipients (just before they leave the local server) + preroute Applies to incoming stanzas from local users, before any routing rules are applied + +By default, if no chain is specified, rules are put into the 'deliver' chain. + +Example of chain use: + + # example.com's firewall script + + # This line is optional, because 'deliver' is the default chain anyway: + ::deliver + + # This rule matches any stanzas delivered to our local user bob: + TO: bob@example.com + DROP. + + # Oops! This rule will never match, because alice is not a local user, + # and only stanzas to local users go through the 'deliver' chain: + TO: alice@remote.example.com + DROP. + + # Create a 'preroute' chain of rules: + ::preroute + # These rules are matched for outgoing stanzas from local clients + + # This will match any stanzas sent to alice from a local user: + TO: alice@remote.example.com + DROP. diff -r ea95637cf041 -r 1124758cac7f mod_firewall/actions.lib.lua --- a/mod_firewall/actions.lib.lua Wed Mar 16 13:30:03 2016 +0100 +++ b/mod_firewall/actions.lib.lua Wed Mar 16 12:55:47 2016 +0000 @@ -142,7 +142,11 @@ else text = "nil"; end - return route_modify(("error_reply(stanza, %s, %s, %s)"):format(error_type, error, text), nil, true); + local route_modify_code, deps = route_modify(("error_reply(stanza, %s, %s, %s)"):format(error_type, error, text), nil, true); + deps[#deps+1] = "type"; + deps[#deps+1] = "name"; + return [[if type == "error" or (name == "iq" and type == "result") then return true; end -- Don't reply to 'error' stanzas, or iq results + ]]..route_modify_code, deps; end function action_handlers.REDIRECT(where) diff -r ea95637cf041 -r 1124758cac7f mod_storage_memory/mod_storage_memory.lua --- a/mod_storage_memory/mod_storage_memory.lua Wed Mar 16 13:30:03 2016 +0100 +++ b/mod_storage_memory/mod_storage_memory.lua Wed Mar 16 12:55:47 2016 +0000 @@ -7,15 +7,17 @@ end }); +local NULL = {}; + local keyval_store = {}; keyval_store.__index = keyval_store; function keyval_store:get(username) - return self.store[username]; + return self.store[username or NULL]; end function keyval_store:set(username, data) - self.store[username] = data; + self.store[username or NULL] = data; return true; end @@ -23,17 +25,17 @@ map_store.__index = map_store; function map_store:get(username, key) - local userstore = self.store[username]; + local userstore = self.store[username or NULL]; if type(userstore) == "table" then return userstore[key]; end end function map_store:set(username, key, data) - local userstore = self.store[username]; + local userstore = self.store[username or NULL]; if userstore == nil then userstore = {}; - self.store[username] = userstore; + self.store[username or NULL] = userstore; end userstore[key] = data; return true; @@ -46,10 +48,10 @@ if type(when) ~= "number" then when, with, value = value, when, with; end - local a = self.store[username]; + local a = self.store[username or NULL]; if not a then a = {}; - self.store[username] = a; + self.store[username or NULL] = a; end local i = #a+1; local v = { key = key, when = when, with = with, value = value }; @@ -78,7 +80,7 @@ end function archive_store:find(username, query) - local a = self.store[username] or {}; + local a = self.store[username or NULL] or {}; local start, stop, step = 1, #a, 1; local qstart, qend, qwith = -math.huge, math.huge; local limit; @@ -104,16 +106,16 @@ function archive_store:delete(username, query) if not query or next(query) == nil then - self.store[username] = nil; + self.store[username or NULL] = nil; return true; end - local old = self.store[username]; + local old = self.store[username or NULL]; if not old then return true; end local qstart = query.start or -math.huge; local qend = query["end"] or math.huge; local qwith = query.with; local new = {}; - self.store[username] = new; + self.store[username or NULL] = new; local t; for i = 1, #old do i = old[i]; @@ -123,7 +125,7 @@ end end if #new == 0 then - self.store[username] = nil; + self.store[username or NULL] = nil; end return true; end