Merge 0.9->0.10
[prosody.git] / util / sasl / digest-md5.lua
index 73b310bc3e6326c783ea4709c03c0a2a1b81233d..591d85371ace5db490cd90c5ab78b91d9f699709 100644 (file)
@@ -23,8 +23,9 @@ 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 "digest-md5"
+module "sasl.digest-md5"
 
 --=========================
 --SASL DIGEST-MD5 according to RFC 2831
@@ -32,13 +33,13 @@ module "digest-md5"
 --[[
 Supported Authentication Backends
 
-digest-md5:
+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:
+digest_md5_test:
        function(username, domain, realm, encoding, digesthash)
                return true or false, state;
        end
@@ -50,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
@@ -141,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
@@ -180,15 +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
-                       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
@@ -242,4 +245,4 @@ function init(registerMechanism)
        registerMechanism("DIGEST-MD5", {"plain"}, digest);
 end
 
-return _M;
\ No newline at end of file
+return _M;