1 |
1 |
2 local st = require "util.stanza"; |
2 local st = require "util.stanza"; |
3 local send = require "core.sessionmanager".send_to_session; |
3 local send = require "core.sessionmanager".send_to_session; |
4 local sm_bind_resource = require "core.sessionmanager".bind_resource; |
4 local sm_bind_resource = require "core.sessionmanager".bind_resource; |
|
5 local jid |
5 |
6 |
6 local usermanager_validate_credentials = require "core.usermanager".validate_credentials; |
7 local usermanager_validate_credentials = require "core.usermanager".validate_credentials; |
7 local t_concat, t_insert = table.concat, table.insert; |
8 local t_concat, t_insert = table.concat, table.insert; |
8 local tostring = tostring; |
9 local tostring = tostring; |
9 |
10 |
13 local xmlns_bind ='urn:ietf:params:xml:ns:xmpp-bind'; |
14 local xmlns_bind ='urn:ietf:params:xml:ns:xmpp-bind'; |
14 local xmlns_stanzas ='urn:ietf:params:xml:ns:xmpp-stanzas'; |
15 local xmlns_stanzas ='urn:ietf:params:xml:ns:xmpp-stanzas'; |
15 |
16 |
16 local new_sasl = require "util.sasl".new; |
17 local new_sasl = require "util.sasl".new; |
17 |
18 |
|
19 local function build_reply(status, ret) |
|
20 local reply = st.stanza(status, {xmlns = xmlns_sasl}); |
|
21 if status == "challenge" then |
|
22 reply:text(ret or ""); |
|
23 elseif status == "failure" then |
|
24 reply:tag(ret):up(); |
|
25 elseif status == "success" then |
|
26 reply:text(ret or ""); |
|
27 else |
|
28 error("Unknown sasl status: "..status); |
|
29 end |
|
30 return reply; |
|
31 end |
|
32 |
|
33 local function handle_status(session, status) |
|
34 if status == "failure" then |
|
35 session.sasl_handler = nil; |
|
36 elseif status == "success" then |
|
37 session.sasl_handler = nil; |
|
38 session:reset_stream(); |
|
39 end |
|
40 end |
|
41 |
|
42 local function password_callback(jid, mechanism) |
|
43 local node, host = jid_split(jid); |
|
44 local password = (datamanager.load(node, host, "accounts") or {}).password; -- FIXME handle hashed passwords |
|
45 local func = function(x) return x; end; |
|
46 if password then |
|
47 if mechanism == "PLAIN" then |
|
48 return func, password; |
|
49 elseif mechanism == "DIGEST-MD5" then |
|
50 return func, require "hashes".md5(node.."::"..password); |
|
51 end |
|
52 end |
|
53 return func, nil; |
|
54 end |
|
55 |
18 add_handler("c2s_unauthed", "auth", xmlns_sasl, |
56 add_handler("c2s_unauthed", "auth", xmlns_sasl, |
19 function (session, stanza) |
57 function (session, stanza) |
20 if not session.sasl_handler then |
58 if not session.sasl_handler then |
21 session.sasl_handler = new_sasl(stanza.attr.mechanism, |
59 session.sasl_handler = new_sasl(stanza.attr.mechanism, session.host, password_callback); |
|
60 local status, ret = session.sasl_handler:feed(stanza[1]); |
|
61 handle_status(session, status); |
|
62 session.send(build_reply(status, ret)); |
|
63 --[[session.sasl_handler = new_sasl(stanza.attr.mechanism, |
22 function (username, password) |
64 function (username, password) |
23 -- onAuth |
65 -- onAuth |
24 require "core.usermanager" |
66 require "core.usermanager" |
25 if usermanager_validate_credentials(session.host, username, password) then |
67 if usermanager_validate_credentials(session.host, username, password) then |
26 return true; |
68 return true; |
45 -- onWrite |
87 -- onWrite |
46 log("debug", "SASL writes: %s", tostring(stanza)); |
88 log("debug", "SASL writes: %s", tostring(stanza)); |
47 send(session, stanza); |
89 send(session, stanza); |
48 end |
90 end |
49 ); |
91 ); |
50 session.sasl_handler:feed(stanza); |
92 session.sasl_handler:feed(stanza); ]] |
51 else |
93 else |
52 error("Client tried to negotiate SASL again", 0); |
94 error("Client tried to negotiate SASL again", 0); |
53 end |
95 end |
54 |
|
55 end); |
96 end); |
|
97 |
|
98 add_handler("c2s_unauthed", "abort", xmlns_sasl, |
|
99 function(session, stanza) |
|
100 if not session.sasl_handler then error("Attempt to abort when sasl has not started"); end |
|
101 local status, ret = session.sasl_handler:feed(stanza[1]); |
|
102 handle_status(session, status); |
|
103 session.send(build_reply(status, ret)); |
|
104 end); |
|
105 |
|
106 add_handler("c2s_unauthed", "response", xmlns_sasl, |
|
107 function(session, stanza) |
|
108 if not session.sasl_handler then error("Attempt to respond when sasl has not started"); end |
|
109 local status, ret = session.sasl_handler:feed(stanza[1]); |
|
110 handle_status(session, status); |
|
111 session.send(build_reply(status, ret)); |
|
112 end); |
56 |
113 |
57 add_event_hook("stream-features", |
114 add_event_hook("stream-features", |
58 function (session, features) |
115 function (session, features) |
59 if not session.username then |
116 if not session.username then |
60 t_insert(features, "<mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>"); |
117 t_insert(features, "<mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>"); |