Changeset

595:08ed4fa2f89d

Latin1 support for SASL DIGEST-MD5 (initial commit)
author Waqas Hussain <waqas20@gmail.com>
date Sun, 07 Dec 2008 23:43:08 +0500
parents 592:c6e2c727d0cc
children 596:9fba6b040126 599:30655c5cc531
files plugins/mod_saslauth.lua util/sasl.lua
diffstat 2 files changed, 41 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/plugins/mod_saslauth.lua	Sat Dec 06 23:23:08 2008 +0000
+++ b/plugins/mod_saslauth.lua	Sun Dec 07 23:43:08 2008 +0500
@@ -41,11 +41,13 @@
 local function build_reply(status, ret, err_msg)
 	local reply = st.stanza(status, {xmlns = xmlns_sasl});
 	if status == "challenge" then
+		log("challenge", ret or "");
 		reply:text(base64.encode(ret or ""));
 	elseif status == "failure" then
 		reply:tag(ret):up();
 		if err_msg then reply:tag("text"):text(err_msg); end
 	elseif status == "success" then
+		log("success", ret or "");
 		reply:text(base64.encode(ret or ""));
 	else
 		error("Unknown sasl status: "..status);
@@ -65,13 +67,15 @@
 end
 
 local function password_callback(node, host, mechanism, raw_host)
-	local password = (datamanager.load(node, host, "accounts") or {}).password; -- FIXME handle hashed passwords
+	log("host", host);
+	log("raw_host", raw_host);
+	local password = (datamanager.load(node, raw_host, "accounts") or {}).password; -- FIXME handle hashed passwords
 	local func = function(x) return x; end;
 	if password then
 		if mechanism == "PLAIN" then
 			return func, password;
 		elseif mechanism == "DIGEST-MD5" then
-			return func, md5(node..":"..raw_host..":"..password);
+			return func, md5(node..":"..host..":"..password);
 		end
 	end
 	return func, nil;
@@ -87,6 +91,7 @@
 	local text = stanza[1];
 	if text then
 		text = base64.decode(text);
+		log("recieved", text);
 		if not text then
 			session.sasl_handler = nil;
 			session.send(build_reply("failure", "incorrect-encoding"));
--- a/util/sasl.lua	Sat Dec 06 23:23:08 2008 +0000
+++ b/util/sasl.lua	Sun Dec 07 23:43:08 2008 +0500
@@ -81,6 +81,39 @@
 		return data
 	end
 	
+	local function utf8tolatin1ifpossible(passwd)
+		local i = 1;
+		while i <= #passwd do
+			local passwd_i = to_byte(passwd:sub(i, i));
+			if passwd_i > 0x7F then
+				if passwd_i < 0xC0 or passwd_i > 0xC3 then
+					return passwd;
+				end
+				i = i + 1;
+				passwd_i = to_byte(passwd:sub(i, i));
+				if passwd_i < 0x80 or passwd_i > 0xBF then
+					return passwd;
+				end
+			end
+			i = i + 1;
+		end
+
+		local p = {};
+		local j = 0;
+		i = 1;
+		while (i <= #passwd) do
+			local passwd_i = to_byte(passwd:sub(i, i));
+			if passwd_i > 0x7F then
+				i = i + 1;
+				local passwd_i_1 = to_byte(passwd:sub(i, i));
+				t_insert(p, to_char(passwd_i%4*64 + passwd_i_1%64)); -- I'm so clever
+			else
+				t_insert(p, to_char(passwd_i));
+			end
+			i = i + 1;
+		end
+		return t_concat(p);
+	end
 	local function latin1toutf8(str)
 		local p = {};
 		for ch in gmatch(str, ".") do
@@ -148,7 +181,7 @@
 			
 			if response["charset"] == nil then
 				response["username"] = latin1toutf8(response["username"])
-				response["realm"] = latin1toutf8(response["realm"])
+				response["realm"] = utf8tolatin1ifpossible(response["realm"])
 			elseif response["charset"] ~= "utf-8" then
 				return "failure", "incorrect-encoding", "The client's response uses "..response["charset"].." for encoding with isn't supported by sasl.lua. Supported encodings are latin or utf-8."
 			end