util/sasl.lua

changeset 297
15b375870b40
parent 294
5d861d6e5bbd
child 401
96e2019d112d
equal deleted inserted replaced
294:5d861d6e5bbd 297:15b375870b40
14 14
15 module "sasl" 15 module "sasl"
16 16
17 local function new_plain(realm, password_handler) 17 local function new_plain(realm, password_handler)
18 local object = { mechanism = "PLAIN", realm = realm, password_handler = password_handler} 18 local object = { mechanism = "PLAIN", realm = realm, password_handler = password_handler}
19 object.feed = function(self, message) 19 function object.feed(self, message)
20 --print(message:gsub("%W", function (c) return string.format("\\%d", string.byte(c)) end)); 20
21 21 if message == "" or message == nil then return "failure", "malformed-request" end
22 if message == "" or message == nil then return "failure", "malformed-request" end 22 local response = message
23 local response = message 23 local authorization = s_match(response, "([^&%z]+)")
24 local authorization = s_match(response, "([^&%z]+)") 24 local authentication = s_match(response, "%z([^&%z]+)%z")
25 local authentication = s_match(response, "%z([^&%z]+)%z") 25 local password = s_match(response, "%z[^&%z]+%z([^&%z]+)")
26 local password = s_match(response, "%z[^&%z]+%z([^&%z]+)") 26
27 27 local password_encoding, correct_password = self.password_handler(authentication, self.realm, "PLAIN")
28 local password_encoding, correct_password = self.password_handler(authentication, self.realm, "PLAIN") 28
29 29 local claimed_password = ""
30 local claimed_password = "" 30 if password_encoding == nil then claimed_password = password
31 if password_encoding == nil then claimed_password = password 31 else claimed_password = password_encoding(password) end
32 else claimed_password = password_encoding(password) end 32
33 33 self.username = authentication
34 self.username = authentication 34 if claimed_password == correct_password then
35 if claimed_password == correct_password then 35 log("debug", "success")
36 log("debug", "success") 36 return "success"
37 return "success" 37 else
38 else 38 log("debug", "failure")
39 log("debug", "failure") 39 return "failure", "not-authorized"
40 return "failure", "not-authorized" 40 end
41 end 41 end
42 end
43 return object 42 return object
44 end 43 end
45 44
46 local function new_digest_md5(realm, password_handler) 45 local function new_digest_md5(realm, password_handler)
47 --TODO maybe support for authzid 46 --TODO maybe support for authzid
109 else 108 else
110 -- check if it's the right nonce 109 -- check if it's the right nonce
111 if response["nonce"] ~= tostring(self.nonce) then return "failure", "malformed-request" end 110 if response["nonce"] ~= tostring(self.nonce) then return "failure", "malformed-request" end
112 end 111 end
113 112
114 if not response["cnonce"] then return "failure", "malformed-request" end 113 if not response["cnonce"] then return "failure", "malformed-request", "Missing entry for cnonce in SASL message." end
115 if not response["qop"] then response["qop"] = "auth" end 114 if not response["qop"] then response["qop"] = "auth" end
116 115
117 if response["realm"] == nil then response["realm"] = "" end 116 if response["realm"] == nil then response["realm"] = "" end
118 117
119 local domain = "" 118 local domain = ""
145 HA1 = md5.sumhexa(A1) 144 HA1 = md5.sumhexa(A1)
146 HA2 = md5.sumhexa(A2) 145 HA2 = md5.sumhexa(A2)
147 146
148 KD = HA1..":"..response["nonce"]..":"..response["nc"]..":"..response["cnonce"]..":"..response["qop"]..":"..HA2 147 KD = HA1..":"..response["nonce"]..":"..response["nc"]..":"..response["cnonce"]..":"..response["qop"]..":"..HA2
149 local rspauth = md5.sumhexa(KD) 148 local rspauth = md5.sumhexa(KD)
150 149 self.authenticated = true
151 return "challenge", serialize({rspauth = rspauth}) 150 return "challenge", serialize({rspauth = rspauth})
152 else 151 else
153 return "failure", "not-authorized", "The response provided by the client doesn't match the one we calculated." 152 return "failure", "not-authorized", "The response provided by the client doesn't match the one we calculated."
154 end 153 end
155 elseif self.step == 3 then 154 elseif self.step == 3 then
156 return "success" 155 if self.authenticated ~= nil then return "success"
156 else return "failure", "malformed-request" end
157 end 157 end
158 end 158 end
159 return object 159 return object
160 end 160 end
161 161

mercurial