changeset 613:b5a8e8492570

Merge
author Matthew Wild <mwild1@gmail.com>
date Tue, 14 Feb 2012 15:17:16 +0000
parents 15763c1d085c (diff) b1d82ae063e1 (current diff)
children 40ab83736f6e
files
diffstat 7 files changed, 133 insertions(+), 92 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mod_c2s_conn_throttle/mod_c2s_conn_throttle.lua	Tue Feb 14 15:17:16 2012 +0000
@@ -0,0 +1,42 @@
+-- Clients Connection Throttler.
+-- Usage:
+-- Add the module into modules loaded into the virtual host section
+--
+-- cthrottler_logins_count = 3 -> number of logins attempt allowed
+-- cthrottler_time = 120 -> in x seconds
+
+local time = os.time
+local in_count = {}
+local logins_count = module:get_option_number("cthrottler_logins_count", 3)
+local throttle_time = module:get_option_number("cthrottler_time", 60)
+
+local function handle_sessions(event)
+	local session = event.origin
+
+	if not in_count[session.ip] and session.type == "c2s_unauthed" then
+		in_count[session.ip] = { t = time(), c = 1 }
+	elseif in_count[session.ip] and session.type == "c2s_unauthed" then
+		if in_count[session.ip].starttls_c then in_count[session.ip].c = in_count[session.ip].starttls_c else in_count[session.ip].c = in_count[session.ip].c + 1 end
+		
+		if in_count[session.ip].c > logins_count and time() - in_count[session.ip].t < throttle_time then
+			module:log("error", "Exceeded login count for %s, closing connection", session.ip)
+			session:close{ condition = "policy-violation", text = "You exceeded the number of connections/logins allowed in "..throttle_time.." seconds, good bye." }
+			return true
+		elseif time() - in_count[session.ip].t > throttle_time then
+			in_count[session.ip] = nil ; return
+		end
+	end	
+end
+
+local function check_starttls(event)
+	local session = event.origin
+
+	if in_count[session.ip] and type(in_count[session.ip].starttls_c) ~= "number" and session.type == "c2s_unauthed" then
+		in_count[session.ip].starttls_c = 1
+	elseif in_count[session.ip] and type(in_count[session.ip].starttls_c) == "number" and session.type == "c2s_unauthed" then
+		in_count[session.ip].starttls_c = in_count[session.ip].starttls_c + 1
+	end
+end
+
+module:hook("stream-features", handle_sessions, 100)
+module:hook("stanza/urn:ietf:params:xml:ns:xmpp-tls:starttls", check_starttls, 100)
--- a/mod_carbons/mod_carbons.lua	Tue Feb 14 15:16:38 2012 +0000
+++ b/mod_carbons/mod_carbons.lua	Tue Feb 14 15:17:16 2012 +0000
@@ -44,7 +44,7 @@
 
 	local bare_jid, user_sessions;
 	local no_carbon_to = {};
-	module:log("debug", "origin (%s) type: %s", tostring(origin), origin.type)
+	module:log("debug", "Message from %s to %s", orig_from, orig_to);
 	if c2s then -- Stanza sent by a local client
 		bare_jid = (origin.username.."@"..origin.host)
 		user_sessions = host_sessions[origin.username];
@@ -53,11 +53,13 @@
 		bare_jid = jid_bare(orig_to);
 		user_sessions = host_sessions[username];
 		if resource then
+			module:log("debug", "Message was to resource %s, it will not get carbon", resource);
 			no_carbon_to[resource] = true;
 		elseif user_sessions then
 			local top_resources = user_sessions.top_resources;
 			if top_resources then
 				for _, session in ipairs(top_resources) do
+					module:log("debug", "Not sending carbons to top resource %s", session.resource);
 					no_carbon_to[session.resource] = true;
 				end
 			end
@@ -65,6 +67,7 @@
 	end
 
 	if not user_sessions then
+		module:log("debug", "Skip carbons for offline user");
 		return -- No use in sending carbons to an offline user
 	end
 
@@ -73,6 +76,7 @@
 			return tag.attr.xmlns == xmlns_carbons
 				and tag.name == "private" and tag or nil;
 		end);
+		module:log("debug", "Message tagged private, ignoring");
 		return
 	end
 
@@ -80,7 +84,13 @@
 		user_sessions = user_sessions and user_sessions.sessions;
 		for resource, session in pairs(user_sessions) do
 			local full_jid = bare_jid .. "/" .. resource;
+			module:log("debug", "%s wants carbons: %s", session.full_jid, tostring(session.want_carbons));
 			if session.want_carbons then
+				if c2s then
+					module:log("debug", "Session is origin: %s", tostring(session == origin));
+				else
+					module:log("debug", "Session is in ignore list: %s", tostring(no_carbon_to[resource]));
+				end
 				if (c2s and session ~= origin) or (not c2s and not no_carbon_to[resource]) then
 					local msg = st.clone(stanza);
 					msg.attr.xmlns = msg.attr.xmlns or "jabber:client";
@@ -92,7 +102,8 @@
 						:tag(c2s and "sent" or "received", { xmlns = xmlns_carbons }):up()
 						:tag("forwarded", { xmlns = xmlns_forward })
 							:add_child(msg);
-					core_post_stanza(origin, fwd);
+					module:log("debug", "Sending carbon");
+					session.send(fwd);
 				end
 			end
 		end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mod_cleanup_http/mod_cleanup_http.lua	Tue Feb 14 15:17:16 2012 +0000
@@ -0,0 +1,40 @@
+-- Auto-cleanup for Global BOSH modules.
+-- Should take care of spring cleaning without messing in either the console, or restarting
+
+module:set_global()
+
+local http_modules = module:get_option("cleanup_http_modules", {})
+if type(http_modules) ~= "table" then module:log("error", "cleanup_http_modules needs to be a module.") ; return false end
+
+local function cleanup(data)
+	if data.module == "cleanup_http" then -- it's us getting unloaded destroy handler.
+		prosody.events.remove_handler("module-unloaded", cleanup)
+	elseif http_modules[data.module] then
+		local ports = http_modules[data.module]
+
+		module:log("debug", "Cleaning up http handlers and ports as module %s is being unloaded.", data.module)
+		for _, options in ipairs(ports) do
+			if options.port then
+                        	httpserver.new.http_servers[options.port].handlers[options.path or "register_account"] = nil
+			end
+		end
+
+		-- if there are no handlers left clean and close the socket, doesn't work with server_event
+		local event = require "core.configmanager".get("*", "core", "use_libevent")
+
+		if not event then
+        	        for _, options in ipairs(ports) do
+                	        if options.port and not next(httpserver.new.http_servers[options.port].handlers) then
+                        	        httpserver.new.http_servers[options.port] = nil
+					if options.interface then
+						for _, value in ipairs(options.interface) do
+							if server.getserver(value, options.port) then server.removeserver(value, options.port) end
+						end
+					else if server.getserver("*", options.port) then server.removeserver("*", options.port) end end
+				end
+			end
+		end
+	end
+end
+
+prosody.events.add_handler("module-unloaded", cleanup)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mod_conformance_restricted/mod_conformance_restricted.lua	Tue Feb 14 15:17:16 2012 +0000
@@ -0,0 +1,34 @@
+-- Prosody IM
+-- Copyright (C) 2012 Florian Zeitz
+-- 
+-- This project is MIT/X11 licensed. Please see the
+-- COPYING file in the source package for more information.
+--
+
+local st = require "util.stanza";
+
+module:hook("message/host", function (event)
+	local origin, stanza = event.origin, event.stanza;
+	local node, host, resource = jid.split(stanza.attr.to);
+	local body = stanza:get_child_text("body");
+	
+	if resource ~= "conformance" then
+		return; -- Not interop testing
+	end
+
+	if body == "PI" then
+		origin.send("<?testing this='out'?>");
+	elseif body == "comment" then
+		origin.send("<!-- no comment -->");
+	elseif body == "DTD" then
+		origin.send("<!DOCTYPE greeting [\n<!ENTITY test 'You should not see this'>\n]>");
+	elseif body == "entity" then
+		origin.send("<message type='chat' to='"..stanza.attr.from.."'><body>&test;</body></message>");
+	else
+		local reply = st.reply(stanza);
+		reply:body("Send me one of: PI, comment, DTD, or entity");
+		origin.send(reply);
+	end
+	
+	return true;
+end);
--- a/mod_register_json/mod_register_json.lua	Tue Feb 14 15:16:38 2012 +0000
+++ b/mod_register_json/mod_register_json.lua	Tue Feb 14 15:17:16 2012 +0000
@@ -75,17 +75,14 @@
 			if blacklist:contains(req_body["ip"]) then module:log("warn", "Attempt of reg. submission to the JSON servlet from blacklisted address: %s", req_body["ip"]) ; return http_response(403, "The specified address is blacklisted, sorry sorry.") end
 			if throttle_time and not whitelist:contains(req_body["ip"]) then
 				if not recent_ips[req_body["ip"]] then
-					recent_ips[req_body["ip"]] = { time = os_time(), count = 1 }
+					recent_ips[req_body["ip"]] = os_time()
 				else
-					local ip = recent_ips[req_body["ip"]]
-					ip.count = ip.count + 1
-
-					if os_time() - ip.time < throttle_time then
-						ip.time = os_time()
+					if os_time() - recent_ips[req_body["ip"]] < throttle_time then
+						recent_ips[req_body["ip"]] = os_time()
 						module:log("warn", "JSON Registration request from %s has been throttled.", req_body["ip"])
 						return http_response(503, "Woah... How many users you want to register..? Request throttled, wait a bit and try again.")
 					end
-					ip.time = os_time()
+					recent_ips[req_body["ip"]] = os_time()
 				end
 			end
 
@@ -116,32 +113,6 @@
 end
 
 -- Set it up!
-function cleanup() -- it could be better if module:hook("module-unloaded", ...) actually worked.
-	module:log("debug", "Cleaning up handlers and stuff as module is being unloaded.")
-	for _, options in ipairs(ports) do
-		if options.port then
-			httpserver.new.http_servers[options.port].handlers[options.path or "register_account"] = nil
-		end
-	end
-
-	-- if there are no handlers left clean and close the socket, doesn't work with server_event
-	local event = module:get_option_boolen("use_libevent", false)
-
-	if not event then
-		for _, options in ipairs(ports) do
-			if options.port and not next(httpserver.new.http_servers[options.port].handlers) then
-				httpserver.new.http_servers[options.port] = nil
-				if options.interface then
-					for _, value in ipairs(options.interface) do
-						if server.getserver(value, options.port) then server.removeserver(value, options.port) end
-					end
-				else if server.getserver("*", options.port) then server.removeserver("*", options.port) end end
-			end
-		end
-	end
-
-	prosody.events.remove_handler("module-unloaded", cleanup)
-end
 
 function setup()
 	for id, options in ipairs(ports) do 
@@ -150,7 +121,6 @@
 			else ports[id].port = 9443 end
 		elseif options.port == 9280 and options.ssl then ports[id].port = 9443 end end
 	httpserver.new_from_config(ports, handle_req, { base = "register_account" })
-	prosody.events.add_handler("module-unloaded", cleanup)
 end
 
 if prosody.start_time then -- already started
--- a/mod_server_status/mod_server_status.lua	Tue Feb 14 15:16:38 2012 +0000
+++ b/mod_server_status/mod_server_status.lua	Tue Feb 14 15:17:16 2012 +0000
@@ -130,36 +130,8 @@
 -- initialization.
 -- init http interface
 
-function cleanup() -- handy, recycled from mod_register_json
-        module:log("debug", "Cleaning up handlers and stuff as module is being unloaded.")
-        for _, options in ipairs(ports) do
-                if options.port then
-                        httpserver.new.http_servers[options.port].handlers[options.path or "server-status"] = nil
-                end
-        end
-
-	local event = module:get_option_boolen("use_libevent", false)
-
-	-- if there're no handlers left clean the socket, not sure if it works with server_select
-	if not event then
-	        for _, options in ipairs(ports) do
-	                if options.port and not next(httpserver.new.http_servers[options.port].handlers) then
-                	        httpserver.new.http_servers[options.port] = nil
-        	                if options.interface then
-	                                for _, value in ipairs(options.interface) do
-                                	        if server.getserver(value, options.port) then server.removeserver(value, options.port) end
-                        	        end
-                	        else if server.getserver("*", options.port) then server.removeserver("*", options.port) end end
-        	        end
-	        end
-	end
-
-        prosody.events.remove_handler("module-unloaded", cleanup)
-end
-
 local function setup()
 	httpserver.new_from_config(ports, request, { base = "server-status" })
-	prosody.events.add_handler("module-unloaded", cleanup)
 end
 
 if prosody.start_time then
--- a/mod_stanza_counter/mod_stanza_counter_http.lua	Tue Feb 14 15:16:38 2012 +0000
+++ b/mod_stanza_counter/mod_stanza_counter_http.lua	Tue Feb 14 15:17:16 2012 +0000
@@ -44,36 +44,8 @@
 -- initialization.
 -- init http and cleanup interface
 
-function cleanup() -- recycled from mod_register_json, it's handy
-        module:log("debug", "Cleaning up handlers and stuff as module is being unloaded.")
-        for _, options in ipairs(ports) do
-                if options.port then
-                        httpserver.new.http_servers[options.port].handlers[options.path or "stanza-counter"] = nil
-                end
-        end
-
-        -- if there are no handlers left clean and close the socket, doesn't work with server_event
-        local event = module:get_option_boolen("use_libevent", false)
-
-        if not event then
-                for _, options in ipairs(ports) do
-                        if options.port and not next(httpserver.new.http_servers[options.port].handlers) then
-                                httpserver.new.http_servers[options.port] = nil
-                                if options.interface then
-                                        for _, value in ipairs(options.interface) do
-                                                if server.getserver(value, options.port) then server.removeserver(value, options.port) end
-                                        end
-                                else if server.getserver("*", options.port) then server.removeserver("*", options.port) end end
-                        end
-                end
-        end
-
-        prosody.events.remove_handler("module-unloaded", cleanup)
-end
-
 local function setup()
 	httpserver.new_from_config(ports, req, { base = "stanza-counter" })
-	prosody.events.add_handler("module-unloaded", cleanup)
 end
 
 -- set it