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 |