aboutsummaryrefslogtreecommitdiffstats
path: root/util/sasl/digest-md5.lua
diff options
context:
space:
mode:
Diffstat (limited to 'util/sasl/digest-md5.lua')
-rw-r--r--util/sasl/digest-md5.lua52
1 files changed, 34 insertions, 18 deletions
diff --git a/util/sasl/digest-md5.lua b/util/sasl/digest-md5.lua
index ba042933..591d8537 100644
--- a/util/sasl/digest-md5.lua
+++ b/util/sasl/digest-md5.lua
@@ -1,5 +1,5 @@
-- sasl.lua v0.4
--- Copyright (C) 2008-2009 Tobias Markmann
+-- Copyright (C) 2008-2010 Tobias Markmann
--
-- All rights reserved.
--
@@ -23,15 +23,27 @@ local to_byte, to_char = string.byte, string.char;
local md5 = require "util.hashes".md5;
local log = require "util.logger".init("sasl");
local generate_uuid = require "util.uuid".generate;
+local nodeprep = require "util.encodings".stringprep.nodeprep;
-module "plain"
+module "sasl.digest-md5"
--=========================
--SASL DIGEST-MD5 according to RFC 2831
-local function digest_response()
-
- return response, A1, A2
-end
+
+--[[
+Supported Authentication Backends
+
+digest_md5:
+ function(username, domain, realm, encoding) -- domain and realm are usually the same; for some broken
+ -- implementations it's not
+ return digesthash, state;
+ end
+
+digest_md5_test:
+ function(username, domain, realm, encoding, digesthash)
+ return true or false, state;
+ end
+]]
local function digest(self, message)
--TODO complete support for authzid
@@ -39,8 +51,6 @@ local function digest(self, message)
local function serialize(message)
local data = ""
- if type(message) ~= "table" then error("serialize needs an argument of type table.") end
-
-- testing all possible values
if message["realm"] then data = data..[[realm="]]..message.realm..[[",]] end
if message["nonce"] then data = data..[[nonce="]]..message.nonce..[[",]] end
@@ -101,7 +111,8 @@ local function digest(self, message)
end
local function parse(data)
local message = {}
- for k, v in s_gmatch(data, [[([%w%-]+)="?([^",]*)"?,?]]) do -- FIXME The hacky regex makes me shudder
+ -- COMPAT: %z in the pattern to work around jwchat bug (sends "charset=utf-8\0")
+ for k, v in s_gmatch(data, [[([%w%-]+)="?([^",%z]*)"?,?]]) do -- FIXME The hacky regex makes me shudder
message[k] = v;
end
return message;
@@ -129,10 +140,15 @@ local function digest(self, message)
end
-- check for username, it's REQUIRED by RFC 2831
- if not response["username"] then
+ local username = response["username"];
+ local _nodeprep = self.profile.nodeprep;
+ if username and _nodeprep ~= false then
+ username = (_nodeprep or nodeprep)(username); -- FIXME charset
+ end
+ if not username or username == "" then
return "failure", "malformed-request";
end
- self["username"] = response["username"];
+ self.username = username;
-- check for nonce, ...
if not response["nonce"] then
@@ -168,14 +184,14 @@ local function digest(self, message)
end
--TODO maybe realm support
- self.username = response["username"];
+ local Y, state;
if self.profile.plain then
- local password, state = self.profile.plain(response["username"], self.realm)
+ local password, state = self.profile.plain(self, response["username"], self.realm)
if state == nil then return "failure", "not-authorized"
elseif state == false then return "failure", "account-disabled" end
Y = md5(response["username"]..":"..response["realm"]..":"..password);
elseif self.profile["digest-md5"] then
- local Y, state = self.profile["digest-md5"](response["username"], self.realm, response["realm"] response["charset"])
+ Y, state = self.profile["digest-md5"](self, response["username"], self.realm, response["realm"], response["charset"])
if state == nil then return "failure", "not-authorized"
elseif state == false then return "failure", "account-disabled" end
elseif self.profile["digest-md5-test"] then
@@ -186,12 +202,12 @@ local function digest(self, message)
--elseif Y == false then return "failure", "account-disabled" end
local A1 = "";
if response.authzid then
- if response.authzid == self.username.."@"..self.realm then
+ if response.authzid == self.username or response.authzid == self.username.."@"..self.realm then
-- COMPAT
- log("warn", "Client is violating XMPP RFC. See section 6.1 of RFC 3920.");
+ log("warn", "Client is violating RFC 3920 (section 6.1, point 7).");
A1 = Y..":"..response["nonce"]..":"..response["cnonce"]..":"..response.authzid;
else
- A1 = "?";
+ return "failure", "invalid-authzid";
end
else
A1 = Y..":"..response["nonce"]..":"..response["cnonce"];
@@ -229,4 +245,4 @@ function init(registerMechanism)
registerMechanism("DIGEST-MD5", {"plain"}, digest);
end
-return _M; \ No newline at end of file
+return _M;