14 local error = error |
14 local error = error |
15 local print = print |
15 local print = print |
16 |
16 |
17 module "sasl" |
17 module "sasl" |
18 |
18 |
19 local function new_plain(onAuth, onSuccess, onFail, onWrite) |
19 local function new_plain(realm, password_handler) |
20 local object = { mechanism = "PLAIN", onAuth = onAuth, onSuccess = onSuccess, onFail = onFail, |
20 local object = { mechanism = "PLAIN", realm = realm, password_handler = password_handler} |
21 onWrite = onWrite} |
21 object.feed = function(self, message) |
22 local challenge = base64.encode(""); |
22 log("debug", "feed: "..message) |
23 --onWrite(st.stanza("challenge", {xmlns = "urn:ietf:params:xml:ns:xmpp-sasl"}):text(challenge)) |
23 local response = message |
24 object.feed = function(self, stanza) |
|
25 if stanza.name ~= "response" and stanza.name ~= "auth" then self.onFail("invalid-stanza-tag") end |
|
26 if stanza.attr.xmlns ~= "urn:ietf:params:xml:ns:xmpp-sasl" then self.onFail("invalid-stanza-namespace") end |
|
27 local response = base64.decode(stanza[1]) |
|
28 local authorization = s_match(response, "([^&%z]+)") |
24 local authorization = s_match(response, "([^&%z]+)") |
29 local authentication = s_match(response, "%z([^&%z]+)%z") |
25 local authentication = s_match(response, "%z([^&%z]+)%z") |
30 local password = s_match(response, "%z[^&%z]+%z([^&%z]+)") |
26 local password = s_match(response, "%z[^&%z]+%z([^&%z]+)") |
31 if self.onAuth(authentication, password) == true then |
27 |
32 self.onWrite(st.stanza("success", {xmlns = "urn:ietf:params:xml:ns:xmpp-sasl"})) |
28 local password_encoding, correct_password = self.password_handler(authentication.."@"..self.realm, "PLAIN") |
33 self.onSuccess(authentication) |
29 |
|
30 local claimed_password = "" |
|
31 if password_encoding == nil then claimed_password = password |
|
32 else claimed_password = password_encoding(password) end |
|
33 |
|
34 if claimed_password == correct_password then |
|
35 return "success", nil |
34 else |
36 else |
35 self.onWrite(st.stanza("failure", {xmlns = "urn:ietf:params:xml:ns:xmpp-sasl"}):tag("temporary-auth-failure")); |
37 return "failure", "not-authorized" |
36 self.onFail("Wrong password.") |
|
37 end |
38 end |
38 end |
39 end |
39 return object |
40 return object |
40 end |
41 end |
41 |
42 |
163 end |
164 end |
164 end |
165 end |
165 return object |
166 return object |
166 end |
167 end |
167 |
168 |
168 function new(mechanism, onAuth, onSuccess, onFail, onWrite) |
169 function new(mechanism, realm, password) |
169 local object |
170 local object |
170 if mechanism == "PLAIN" then object = new_plain(onAuth, onSuccess, onFail, onWrite) |
171 if mechanism == "PLAIN" then object = new_plain(realm, password) |
171 elseif mechanism == "DIGEST-MD5" then object = new_digest_md5(onAuth, onSuccess, onFail, onWrite) |
172 --elseif mechanism == "DIGEST-MD5" then object = new_digest_md5(ream, password) |
172 else |
173 else |
173 log("debug", "Unsupported SASL mechanism: "..tostring(mechanism)); |
174 log("debug", "Unsupported SASL mechanism: "..tostring(mechanism)); |
174 onFail("unsupported-mechanism") |
175 return nil |
175 end |
176 end |
176 return object |
177 return object |
177 end |
178 end |
178 |
179 |
179 return _M; |
180 return _M; |