plugins/mod_saslauth.lua

changeset 281
826308c07627
parent 120
ef964468f174
child 282
80e7de32b618
child 284
4f540755260c
equal deleted inserted replaced
270:837c7f701a56 281:826308c07627
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'>");

mercurial