Changeset

3116:90a98a6b52ac

Merge 0.7->trunk
author Matthew Wild <mwild1@gmail.com>
date Sun, 23 May 2010 23:11:00 +0100
parents 3081:4ee34d07e042 (current diff) 3115:4c35ef27d868 (diff)
children 3117:f4e7ca2aa2f7
files core/usermanager.lua util/sasl.lua util/sasl/anonymous.lua util/sasl/digest-md5.lua util/sasl/scram.lua
diffstat 8 files changed, 77 insertions(+), 60 deletions(-) [+]
line wrap: on
line diff
--- a/core/rostermanager.lua	Sat May 22 20:51:01 2010 +0200
+++ b/core/rostermanager.lua	Sun May 23 23:11:00 2010 +0100
@@ -93,15 +93,18 @@
 	else -- Attempt to load roster for non-loaded user
 		log("debug", "load_roster: loading for offline user: "..username.."@"..host);
 	end
-	roster = datamanager.load(username, host, "roster") or {};
+	local data, err = datamanager.load(username, host, "roster");
+	roster = data or {};
 	if user then user.roster = roster; end
-	if not roster[false] then roster[false] = { }; end
+	if not roster[false] then roster[false] = { broken = err or nil }; end
 	if roster[jid] then
 		roster[jid] = nil;
 		log("warn", "roster for "..jid.." has a self-contact");
 	end
-	hosts[host].events.fire_event("roster-load", username, host, roster);
-	return roster;
+	if not err then
+		hosts[host].events.fire_event("roster-load", username, host, roster);
+	end
+	return roster, err;
 end
 
 function save_roster(username, host, roster)
@@ -122,6 +125,7 @@
 		if metadata.version ~= true then
 			metadata.version = (metadata.version or 0) + 1;
 		end
+		if roster[false].broken then return nil, "Not saving broken roster" end
 		return datamanager.store(username, host, "roster", roster);
 	end
 	log("warn", "save_roster: user had no roster to save");
@@ -187,9 +191,9 @@
 end
 
 function is_contact_subscribed(username, host, jid)
-	local roster = load_roster(username, host);
+	local roster, err = load_roster(username, host);
 	local item = roster[jid];
-	return item and (item.subscription == "from" or item.subscription == "both");
+	return item and (item.subscription == "from" or item.subscription == "both"), err;
 end
 
 function is_contact_pending_in(username, host, jid)
--- a/core/sessionmanager.lua	Sat May 22 20:51:01 2010 +0200
+++ b/core/sessionmanager.lua	Sun May 23 23:11:00 2010 +0100
@@ -136,7 +136,7 @@
 		local sessions = hosts[session.host].sessions[session.username].sessions;
 		local limit = config_get(session.host, "core", "max_resources") or 10;
 		if #sessions >= limit then
-			return nil, "cancel", "conflict", "Resource limit reached; only "..limit.." resources allowed";
+			return nil, "cancel", "resource-constraint", "Resource limit reached; only "..limit.." resources allowed";
 		end
 		if sessions[resource] then
 			-- Resource conflict
@@ -174,7 +174,19 @@
 	hosts[session.host].sessions[session.username].sessions[resource] = session;
 	full_sessions[session.full_jid] = session;
 	
-	session.roster = rm_load_roster(session.username, session.host);
+	local err;
+	session.roster, err = rm_load_roster(session.username, session.host);
+	if err then
+		full_sessions[session.full_jid] = nil;
+		hosts[session.host].sessions[session.username].sessions[resource] = nil;
+		session.full_jid = nil;
+		session.resource = nil;
+		if next(bare_sessions[session.username..'@'..session.host].sessions) == nil then
+			bare_sessions[session.username..'@'..session.host] = nil;
+			hosts[session.host].sessions[session.username] = nil;
+		end
+		return nil, "cancel", "internal-server-error", "Error loading roster";
+	end
 	
 	hosts[session.host].events.fire_event("resource-bind", {session=session});
 	
--- a/core/usermanager.lua	Sat May 22 20:51:01 2010 +0200
+++ b/core/usermanager.lua	Sun May 23 23:11:00 2010 +0100
@@ -74,7 +74,8 @@
 
 	function provider:user_exists(username)
 		if not(require_provisioning) and is_cyrus(host) then return true; end
-		return datamanager.load(username, host, "accounts") ~= nil; -- FIXME also check for empty credentials
+		local account, err = datamanager.load(username, host, "accounts") ~= nil; -- FIXME also check for empty credentials
+		return (account or err) ~= nil; -- FIXME also check for empty credentials
 	end
 
 	function provider:create_user(username, password)
--- a/plugins/mod_presence.lua	Sat May 22 20:51:01 2010 +0200
+++ b/plugins/mod_presence.lua	Sun May 23 23:11:00 2010 +0100
@@ -38,42 +38,23 @@
 	_core_route_stanza(origin, stanza);
 end
 
-local select_top_resources;
-local bare_message_delivery_policy = module:get_option("bare_message_delivery_policy") or "priority";
-if bare_message_delivery_policy == "broadcast" then
-	function select_top_resources(user)
-		local recipients = {};
-		for _, session in pairs(user.sessions) do -- find resources with non-negative priority
+local function select_top_resources(user)
+	local priority = 0;
+	local recipients = {};
+	for _, session in pairs(user.sessions) do -- find resource with greatest priority
+		if session.presence then
+			-- TODO check active privacy list for session
 			local p = session.priority;
-			if p and p >= 0 then
+			if p > priority then
+				priority = p;
+				recipients = {session};
+			elseif p == priority then
 				t_insert(recipients, session);
 			end
 		end
-		return recipients;
 	end
-else
-	if bare_message_delivery_policy ~= "priority" then
-		module:log("warn", "Invalid value for config option bare_message_delivery_policy");
-	end
-	function select_top_resources(user)
-		local priority = 0;
-		local recipients = {};
-		for _, session in pairs(user.sessions) do -- find resource with greatest priority
-			if session.presence then
-				-- TODO check active privacy list for session
-				local p = session.priority;
-				if p > priority then
-					priority = p;
-					recipients = {session};
-				elseif p == priority then
-					t_insert(recipients, session);
-				end
-			end
-		end
-		return recipients;
-	end
+	return recipients;
 end
-
 local function recalc_resource_map(user)
 	if user then
 		user.top_resources = select_top_resources(user);
@@ -81,7 +62,17 @@
 	end
 end
 
+local ignore_presence_priority = module:get_option("ignore_presence_priority");
+
 function handle_normal_presence(origin, stanza, core_route_stanza)
+	if ignore_presence_priority then
+		local priority = stanza:child_with_name("priority");
+		if priority and priority[1] ~= "0" then
+			for i=#priority.tags,1,-1 do priority.tags[i] = nil; end
+			for i=#priority,1,-1 do priority[i] = nil; end
+			priority[1] = "0";
+		end
+	end
 	if full_sessions[origin.full_jid] then -- if user is still connected
 		origin.send(stanza); -- reflect their presence back to them
 	end
@@ -236,16 +227,13 @@
 	stanza.attr.from, stanza.attr.to = from_bare, to_bare;
 	log("debug", "inbound presence "..stanza.attr.type.." from "..from_bare.." for "..to_bare);
 	
-	if not node then
-		log("debug", "dropping presence sent to host or invalid address '%s'", tostring(to_bare));
-	end
-	
 	if stanza.attr.type == "probe" then
-		if rostermanager.is_contact_subscribed(node, host, from_bare) then
+		local result, err = rostermanager.is_contact_subscribed(node, host, from_bare);
+		if result then
 			if 0 == send_presence_of_available_resources(node, host, st_from, origin, core_route_stanza) then
 				core_route_stanza(hosts[host], st.presence({from=to_bare, to=from_bare, type="unavailable"})); -- TODO send last activity
 			end
-		else
+		elseif not err then
 			core_route_stanza(hosts[host], st.presence({from=to_bare, to=from_bare, type="unsubscribed"}));
 		end
 	elseif stanza.attr.type == "subscribe" then
--- a/plugins/mod_privacy.lua	Sat May 22 20:51:01 2010 +0200
+++ b/plugins/mod_privacy.lua	Sun May 23 23:11:00 2010 +0100
@@ -307,7 +307,7 @@
 	local is_to_user = bare_jid == jid_bare(to);
 	local is_from_user = bare_jid == jid_bare(from);
 	
-	module:log("debug", "stanza: %s, to: %s, from: %s", tostring(stanza.name), tostring(to), tostring(from));
+	--module:log("debug", "stanza: %s, to: %s, from: %s", tostring(stanza.name), tostring(to), tostring(from));
 	
 	if privacy_lists.lists == nil or
 		not (session.activePrivacyList or privacy_lists.default)
@@ -315,7 +315,7 @@
 		return; -- Nothing to block, default is Allow all
 	end
 	if is_from_user and is_to_user then
-		module:log("debug", "Not blocking communications between user's resources");
+		--module:log("debug", "Not blocking communications between user's resources");
 		return; -- from one of a user's resource to another => HANDS OFF!
 	end
 	
@@ -325,8 +325,8 @@
 		listname = privacy_lists.default; -- no active list selected, use default list
 	end
 	local list = privacy_lists.lists[listname];
-	if not list then
-		module:log("debug", "given privacy list not found. name: %s", listname);
+	if not list then -- should never happen
+		module:log("warn", "given privacy list not found. name: %s for user %s", listname, bare_jid);
 		return;
 	end
 	for _,item in ipairs(list.items) do
@@ -345,10 +345,10 @@
 			local evilJid = {};
 			apply = false;
 			if is_to_user then
-				module:log("debug", "evil jid is (from): %s", from);
+				--module:log("debug", "evil jid is (from): %s", from);
 				evilJid.node, evilJid.host, evilJid.resource = jid_split(from);
 			else
-				module:log("debug", "evil jid is (to): %s", to);
+				--module:log("debug", "evil jid is (to): %s", to);
 				evilJid.node, evilJid.host, evilJid.resource = jid_split(to);
 			end
 			if	item.type == "jid" and
@@ -394,7 +394,7 @@
 				end
 				return true; -- stanza blocked !
 			else
-				module:log("debug", "stanza explicitly allowed!")
+				--module:log("debug", "stanza explicitly allowed!")
 				return;
 			end
 		end
@@ -425,7 +425,7 @@
 		if session ~= nil then
 			return checkIfNeedToBeBlocked(e, session);
 		else
-			module:log("debug", "preCheckIncoming: Couldn't get session for jid: %s@%s/%s", tostring(node), tostring(host), tostring(resource));
+			--module:log("debug", "preCheckIncoming: Couldn't get session for jid: %s@%s/%s", tostring(node), tostring(host), tostring(resource));
 		end
 	end
 end
--- a/plugins/mod_private.lua	Sat May 22 20:51:01 2010 +0200
+++ b/plugins/mod_private.lua	Sun May 23 23:11:00 2010 +0100
@@ -26,7 +26,11 @@
 				if #query.tags == 1 then
 					local tag = query.tags[1];
 					local key = tag.name..":"..tag.attr.xmlns;
-					local data = datamanager.load(node, host, "private");
+					local data, err = datamanager.load(node, host, "private");
+					if err then
+						session.send(st.error_reply(stanza, "wait", "internal-server-error"));
+						return true;
+					end
 					if stanza.attr.type == "get" then
 						if data and data[key] then
 							session.send(st.reply(stanza):tag("query", {xmlns = "jabber:iq:private"}):add_child(st.deserialize(data[key])));
--- a/util/datamanager.lua	Sat May 22 20:51:01 2010 +0200
+++ b/util/datamanager.lua	Sun May 23 23:11:00 2010 +0100
@@ -21,12 +21,13 @@
 local t_insert = table.insert;
 local append = require "util.serialization".append;
 local path_separator = "/"; if os.getenv("WINDIR") then path_separator = "\\" end
+local lfs = require "lfs";
 local raw_mkdir;
 
 if prosody.platform == "posix" then
 	raw_mkdir = require "util.pposix".mkdir; -- Doesn't trample on umask
 else
-	raw_mkdir = require "lfs".mkdir;
+	raw_mkdir = lfs.mkdir;
 end
 
 module "datamanager"
@@ -111,14 +112,21 @@
 function load(username, host, datastore)
 	local data, ret = loadfile(getpath(username, host, datastore));
 	if not data then
-		log("debug", "Failed to load "..datastore.." storage ('"..ret.."') for user: "..(username or "nil").."@"..(host or "nil"));
-		return nil;
+		local mode = lfs.attributes(getpath(username, host, datastore), "mode");
+		if not mode then
+			log("debug", "Failed to load "..datastore.." storage ('"..ret.."') for user: "..(username or "nil").."@"..(host or "nil"));
+			return nil;
+		else -- file exists, but can't be read
+			-- TODO more detailed error checking and logging?
+			log("error", "Failed to load "..datastore.." storage ('"..ret.."') for user: "..(username or "nil").."@"..(host or "nil"));
+			return nil, "Error reading storage";
+		end
 	end
 	setfenv(data, {});
 	local success, ret = pcall(data);
 	if not success then
 		log("error", "Unable to load "..datastore.." storage ('"..ret.."') for user: "..(username or "nil").."@"..(host or "nil"));
-		return nil;
+		return nil, "Error reading storage";
 	end
 	return ret;
 end
@@ -137,7 +145,7 @@
 	local f, msg = io_open(getpath(username, host, datastore, nil, true), "w+");
 	if not f then
 		log("error", "Unable to write to "..datastore.." storage ('"..msg.."') for user: "..(username or "nil").."@"..(host or "nil"));
-		return;
+		return nil, "Error saving to storage";
 	end
 	f:write("return ");
 	append(f, data);
--- a/util/sasl/scram.lua	Sat May 22 20:51:01 2010 +0200
+++ b/util/sasl/scram.lua	Sun May 23 23:11:00 2010 +0100
@@ -212,4 +212,4 @@
 	registerSCRAMMechanism("SHA-1", sha1, hmac_sha1);
 end
 
-return _M;
\ No newline at end of file
+return _M;