Changeset

3197:f1db45e89317

Merge trunk/MattJ->trunk
author Matthew Wild <mwild1@gmail.com>
date Mon, 07 Jun 2010 12:21:57 +0100
parents 3196:d35b181a895a (current diff) 3192:8ad50989d79e (diff)
children 3198:5a4e766a3577 3202:1a8a5b89a5ad 3205:2dcd826bbbc6
files
diffstat 6 files changed, 210 insertions(+), 40 deletions(-) [+]
line wrap: on
line diff
--- a/core/usermanager.lua	Mon Jun 07 12:19:14 2010 +0100
+++ b/core/usermanager.lua	Mon Jun 07 12:21:57 2010 +0100
@@ -81,8 +81,8 @@
 	return hosts[host].users.create_user(username, password);
 end
 
-function get_supported_methods(host)
-	return hosts[host].users.get_supported_methods();
+function get_sasl_handler(host)
+	return hosts[host].users.get_sasl_handler();
 end
 
 function get_provider(host)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/mod_auth_anonymous.lua	Mon Jun 07 12:21:57 2010 +0100
@@ -0,0 +1,85 @@
+-- Prosody IM
+-- Copyright (C) 2008-2010 Matthew Wild
+-- Copyright (C) 2008-2010 Waqas Hussain
+-- Copyright (C) 2010 Jeff Mitchell
+--
+-- This project is MIT/X11 licensed. Please see the
+-- COPYING file in the source package for more information.
+--
+
+local log = require "util.logger".init("usermanager");
+local type = type;
+local ipairs = ipairs;
+local jid_bare = require "util.jid".bare;
+local config = require "core.configmanager";
+local new_sasl = require "util.sasl".new;
+local datamanager = require "util.datamanager";
+
+function new_default_provider(host)
+	local provider = { name = "anonymous" };
+
+	function provider.test_password(username, password)
+		return nil, "Password based auth not supported.";
+	end
+
+	function provider.get_password(username)
+		return nil, "Password not available.";
+	end
+	
+	function provider.set_password(username, password)
+		return nil, "Password based auth not supported.";
+	end
+
+	function provider.user_exists(username)
+		return nil, "Only anonymous users are supported."; -- FIXME check if anonymous user is connected?
+	end
+
+	function provider.create_user(username, password)
+		return nil, "Account creation/modification not supported.";
+	end
+
+	function provider.get_sasl_handler()
+		local realm = module:get_option("sasl_realm") or module.host;
+		local anonymous_authentication_profile = {
+			anonymous = function(username, realm)
+				return true; -- for normal usage you should always return true here
+			end
+		};
+		return new_sasl(realm, anonymous_authentication_profile);
+	end
+
+	function provider.is_admin(jid)
+		local admins = config.get(host, "core", "admins");
+		if admins ~= config.get("*", "core", "admins") and type(admins) == "table" then
+			jid = jid_bare(jid);
+			for _,admin in ipairs(admins) do
+				if admin == jid then return true; end
+			end
+		elseif admins then
+			log("error", "Option 'admins' for host '%s' is not a table", host);
+		end
+		return is_admin(jid); -- Test whether it's a global admin instead
+	end
+	return provider;
+end
+
+local function dm_callback(username, host, datastore, data)
+	if host == module.host then
+		return false;
+	end
+	return username, host, datastore, data;
+end
+local host = hosts[module.host];
+local _saved_disallow_s2s = host.disallow_s2s;
+function module.load()
+	_saved_disallow_s2s = host.disallow_s2s;
+	host.disallow_s2s = module:get_option("disallow_s2s") ~= false;
+	datamanager.add_callback(dm_callback);
+end
+function module.unload()
+	host.disallow_s2s = _saved_disallow_s2s;
+	datamanager.remove_callback(dm_callback);
+end
+
+module:add_item("auth-provider", new_default_provider(module.host));
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/mod_auth_cyrus.lua	Mon Jun 07 12:21:57 2010 +0100
@@ -0,0 +1,77 @@
+-- Prosody IM
+-- Copyright (C) 2008-2010 Matthew Wild
+-- Copyright (C) 2008-2010 Waqas Hussain
+-- Copyright (C) 2010 Jeff Mitchell
+--
+-- This project is MIT/X11 licensed. Please see the
+-- COPYING file in the source package for more information.
+--
+
+local log = require "util.logger".init("usermanager");
+local type = type;
+local ipairs = ipairs;
+local jid_bare = require "util.jid".bare;
+local config = require "core.configmanager";
+
+local cyrus_service_realm = module:get_option("cyrus_service_realm");
+local cyrus_service_name = module:get_option("cyrus_service_name");
+local cyrus_application_name = module:get_option("cyrus_application_name");
+
+prosody.unlock_globals(); --FIXME: Figure out why this is needed and
+						  -- why cyrussasl isn't caught by the sandbox
+local cyrus_new = require "util.sasl_cyrus".new;
+prosody.lock_globals();
+local new_sasl = function(realm)
+	return cyrus_new(
+		cyrus_service_realm or realm,
+		cyrus_service_name or "xmpp",
+		cyrus_application_name or "prosody"
+	);
+end
+
+function new_default_provider(host)
+	local provider = { name = "cyrus" };
+	log("debug", "initializing default authentication provider for host '%s'", host);
+
+	function provider.test_password(username, password)
+		return nil, "Legacy auth not supported with Cyrus SASL.";
+	end
+
+	function provider.get_password(username)
+		return nil, "Passwords unavailable for Cyrus SASL.";
+	end
+	
+	function provider.set_password(username, password)
+		return nil, "Passwords unavailable for Cyrus SASL.";
+	end
+
+	function provider.user_exists(username)
+		return true;
+	end
+
+	function provider.create_user(username, password)
+		return nil, "Account creation/modification not available with Cyrus SASL.";
+	end
+
+	function provider.get_sasl_handler()
+		local realm = module:get_option("sasl_realm") or module.host;
+		return new_sasl(realm);
+	end
+
+	function provider.is_admin(jid)
+		local admins = config.get(host, "core", "admins");
+		if admins ~= config.get("*", "core", "admins") and type(admins) == "table" then
+			jid = jid_bare(jid);
+			for _,admin in ipairs(admins) do
+				if admin == jid then return true; end
+			end
+		elseif admins then
+			log("error", "Option 'admins' for host '%s' is not a table", host);
+		end
+		return is_admin(jid); -- Test whether it's a global admin instead
+	end
+	return provider;
+end
+
+module:add_item("auth-provider", new_default_provider(module.host));
+
--- a/plugins/mod_auth_internal.lua	Mon Jun 07 12:19:14 2010 +0100
+++ b/plugins/mod_auth_internal.lua	Mon Jun 07 12:21:57 2010 +0100
@@ -16,6 +16,8 @@
 local jid_bare = require "util.jid".bare;
 local config = require "core.configmanager";
 local usermanager = require "core.usermanager";
+local new_sasl = require "util.sasl".new;
+local nodeprep = require "util.encodings".stringprep.nodeprep;
 local hosts = hosts;
 
 local prosody = _G.prosody;
@@ -73,8 +75,23 @@
 		return datamanager.store(username, host, "accounts", {password = password});
 	end
 
-	function provider.get_supported_methods()
-		return {["PLAIN"] = true, ["DIGEST-MD5"] = true}; -- TODO this should be taken from the config
+	function provider.get_sasl_handler()
+		local realm = module:get_option("sasl_realm") or module.host;
+		local getpass_authentication_profile = {
+			plain = function(username, realm)
+				local prepped_username = nodeprep(username);
+				if not prepped_username then
+					log("debug", "NODEprep failed on username: %s", username);
+					return "", nil;
+				end
+				local password = usermanager.get_password(prepped_username, realm);
+				if not password then
+					return "", nil;
+				end
+				return password, true;
+			end
+		};
+		return new_sasl(realm, getpass_authentication_profile);
 	end
 
 	function provider.is_admin(jid)
--- a/plugins/mod_auth_internal_hashed.lua	Mon Jun 07 12:19:14 2010 +0100
+++ b/plugins/mod_auth_internal_hashed.lua	Mon Jun 07 12:21:57 2010 +0100
@@ -18,6 +18,8 @@
 local config = require "core.configmanager";
 local usermanager = require "core.usermanager";
 local generate_uuid = require "util.uuid".generate;
+local new_sasl = require "util.sasl".new;
+local nodeprep = require "util.encodings".stringprep.nodeprep;
 local hosts = hosts;
 
 local prosody = _G.prosody;
@@ -105,8 +107,29 @@
 		return datamanager.store(username, host, "accounts", {hashpass = hexpass, salt = salt, iteration_count = iteration_count});
 	end
 
-	function provider.get_supported_methods()
-		return {["PLAIN"] = true}; -- TODO this should be taken from the config
+	function provider.get_sasl_handler()
+		local realm = module:get_option("sasl_realm") or module.host;
+		local testpass_authentication_profile = {
+			plain_test = function(username, password, realm)
+				local prepped_username = nodeprep(username);
+				if not prepped_username then
+					log("debug", "NODEprep failed on username: %s", username);
+					return "", nil;
+				end
+				return usermanager.test_password(prepped_username, password, realm), true;
+			end,
+			scram_sha_1 = function(username, realm)
+				local credentials = datamanager.load(username, host, "accounts") or {};
+				if credentials.password then
+					usermanager.set_password(username, credentials.password);
+					credentials = datamanager.load(username, host, "accounts") or {};
+				end
+				local salted_password, iteration_count, salt = credentials.hashpass, credentials.iteration_count, credentials.salt;
+				salted_password = salted_password and salted_password:gsub("..", function(x) return string.char(tonumber(x, 16)); end);
+				return salted_password, iteration_count, salt, true;
+			end
+		};
+		return new_sasl(realm, testpass_authentication_profile);
 	end
 
 	function provider.is_admin(jid)
--- a/plugins/mod_saslauth.lua	Mon Jun 07 12:19:14 2010 +0100
+++ b/plugins/mod_saslauth.lua	Mon Jun 07 12:21:57 2010 +0100
@@ -16,7 +16,7 @@
 local nodeprep = require "util.encodings".stringprep.nodeprep;
 local datamanager_load = require "util.datamanager".load;
 local usermanager_get_provider = require "core.usermanager".get_provider;
-local usermanager_get_supported_methods = require "core.usermanager".get_supported_methods;
+local usermanager_get_sasl_handler = require "core.usermanager".get_sasl_handler;
 local usermanager_user_exists = require "core.usermanager".user_exists;
 local usermanager_get_password = require "core.usermanager".get_password;
 local usermanager_test_password = require "core.usermanager".test_password;
@@ -67,32 +67,6 @@
 	error("Unknown SASL backend");
 end
 
-local getpass_authentication_profile = {
-	plain = function(username, realm)
-		local prepped_username = nodeprep(username);
-		if not prepped_username then
-			log("debug", "NODEprep failed on username: %s", username);
-			return "", nil;
-		end
-		local password = usermanager_get_password(prepped_username, realm);
-		if not password then
-			return "", nil;
-		end
-		return password, true;
-	end
-};
-
-local testpass_authentication_profile = {
-	plain_test = 	function(username, password, realm)
-			local prepped_username = nodeprep(username);
-			if not prepped_username then
-				log("debug", "NODEprep failed on username: %s", username);
-				return "", nil;
-			end
-			return usermanager_test_password(prepped_username, password, realm), true;
-			end
-};
-
 local anonymous_authentication_profile = {
 	anonymous = function(username, realm)
 		return true; -- for normal usage you should always return true here
@@ -195,13 +169,7 @@
 		if module:get_option("anonymous_login") then
 			origin.sasl_handler = new_sasl(realm, anonymous_authentication_profile);
 		else
-			if usermanager_get_provider(realm).get_password then
-				origin.sasl_handler = new_sasl(realm, getpass_authentication_profile);
-			elseif usermanager_get_provider(realm).test_password then
-				origin.sasl_handler = new_sasl(realm, testpass_authentication_profile);
-			else
-				log("warn", "AUTH: Could not load an authentication profile for the given provider.");
-			end
+			origin.sasl_handler = usermanager_get_sasl_handler(module.host);
 			if not (module:get_option("allow_unencrypted_plain_auth")) and not origin.secure then
 				origin.sasl_handler:forbidden({"PLAIN"});
 			end