Changeset

2098:1124758cac7f

Merge
author Matthew Wild <mwild1@gmail.com>
date Wed, 16 Mar 2016 12:55:47 +0000
parents 2097:4454f124465a (diff) 2091:ea95637cf041 (current diff)
children 2099:a8c701631d0b
files
diffstat 3 files changed, 70 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- 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.
--- 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)
--- 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