Software /
code /
verse
Annotate
plugins/sasl.lua @ 358:a8f6fd6a70ed
plugins.sasl: Alter mechanism loading and pass name of loaded mechanism. Fixes attempting SCRAM-PLUS when only SCRAM is offered
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Thu, 18 Sep 2014 20:32:38 +0200 |
parent | 354:58cd27b74ba5 |
child | 360:ac3940bad1bf |
rev | line source |
---|---|
354
58cd27b74ba5
Almost a SASL framework, supports negotiation and challenge-response, mechanism code split out into util/sasl/
Kim Alvefur <zash@zash.se>
parents:
315
diff
changeset
|
1 -- local verse = require"verse"; |
58cd27b74ba5
Almost a SASL framework, supports negotiation and challenge-response, mechanism code split out into util/sasl/
Kim Alvefur <zash@zash.se>
parents:
315
diff
changeset
|
2 local base64, unbase64 = require "mime".b64, require"mime".unb64; |
8 | 3 local xmlns_sasl = "urn:ietf:params:xml:ns:xmpp-sasl"; |
4 | |
5 function verse.plugins.sasl(stream) | |
6 local function handle_features(features_stanza) | |
7 if stream.authenticated then return; end | |
8 stream:debug("Authenticating with SASL..."); | |
354
58cd27b74ba5
Almost a SASL framework, supports negotiation and challenge-response, mechanism code split out into util/sasl/
Kim Alvefur <zash@zash.se>
parents:
315
diff
changeset
|
9 local sasl_mechanisms = features_stanza:get_child("mechanisms", xmlns_sasl); |
58cd27b74ba5
Almost a SASL framework, supports negotiation and challenge-response, mechanism code split out into util/sasl/
Kim Alvefur <zash@zash.se>
parents:
315
diff
changeset
|
10 if not sasl_mechanisms then return end |
58cd27b74ba5
Almost a SASL framework, supports negotiation and challenge-response, mechanism code split out into util/sasl/
Kim Alvefur <zash@zash.se>
parents:
315
diff
changeset
|
11 |
58cd27b74ba5
Almost a SASL framework, supports negotiation and challenge-response, mechanism code split out into util/sasl/
Kim Alvefur <zash@zash.se>
parents:
315
diff
changeset
|
12 local mechanisms = {}; |
58cd27b74ba5
Almost a SASL framework, supports negotiation and challenge-response, mechanism code split out into util/sasl/
Kim Alvefur <zash@zash.se>
parents:
315
diff
changeset
|
13 local preference = {}; |
58cd27b74ba5
Almost a SASL framework, supports negotiation and challenge-response, mechanism code split out into util/sasl/
Kim Alvefur <zash@zash.se>
parents:
315
diff
changeset
|
14 |
58cd27b74ba5
Almost a SASL framework, supports negotiation and challenge-response, mechanism code split out into util/sasl/
Kim Alvefur <zash@zash.se>
parents:
315
diff
changeset
|
15 for mech in sasl_mechanisms:childtags("mechanism") do |
58cd27b74ba5
Almost a SASL framework, supports negotiation and challenge-response, mechanism code split out into util/sasl/
Kim Alvefur <zash@zash.se>
parents:
315
diff
changeset
|
16 mech = mech:get_text(); |
58cd27b74ba5
Almost a SASL framework, supports negotiation and challenge-response, mechanism code split out into util/sasl/
Kim Alvefur <zash@zash.se>
parents:
315
diff
changeset
|
17 stream:debug("Server offers %s", mech); |
58cd27b74ba5
Almost a SASL framework, supports negotiation and challenge-response, mechanism code split out into util/sasl/
Kim Alvefur <zash@zash.se>
parents:
315
diff
changeset
|
18 if not mechanisms[mech] then |
58cd27b74ba5
Almost a SASL framework, supports negotiation and challenge-response, mechanism code split out into util/sasl/
Kim Alvefur <zash@zash.se>
parents:
315
diff
changeset
|
19 local name = mech:match("[^-]+"); |
58cd27b74ba5
Almost a SASL framework, supports negotiation and challenge-response, mechanism code split out into util/sasl/
Kim Alvefur <zash@zash.se>
parents:
315
diff
changeset
|
20 local ok, impl = pcall(require, "util.sasl."..name:lower()); |
58cd27b74ba5
Almost a SASL framework, supports negotiation and challenge-response, mechanism code split out into util/sasl/
Kim Alvefur <zash@zash.se>
parents:
315
diff
changeset
|
21 if ok then |
58cd27b74ba5
Almost a SASL framework, supports negotiation and challenge-response, mechanism code split out into util/sasl/
Kim Alvefur <zash@zash.se>
parents:
315
diff
changeset
|
22 stream:debug("Loaded SASL %s module", name); |
358
a8f6fd6a70ed
plugins.sasl: Alter mechanism loading and pass name of loaded mechanism. Fixes attempting SCRAM-PLUS when only SCRAM is offered
Kim Alvefur <zash@zash.se>
parents:
354
diff
changeset
|
23 mechanisms[name], preference[name] = impl(stream, name); |
354
58cd27b74ba5
Almost a SASL framework, supports negotiation and challenge-response, mechanism code split out into util/sasl/
Kim Alvefur <zash@zash.se>
parents:
315
diff
changeset
|
24 elseif not tostring(impl):match("not found") then |
58cd27b74ba5
Almost a SASL framework, supports negotiation and challenge-response, mechanism code split out into util/sasl/
Kim Alvefur <zash@zash.se>
parents:
315
diff
changeset
|
25 stream:debug("Loading failed: %s", tostring(impl)); |
58cd27b74ba5
Almost a SASL framework, supports negotiation and challenge-response, mechanism code split out into util/sasl/
Kim Alvefur <zash@zash.se>
parents:
315
diff
changeset
|
26 end |
58cd27b74ba5
Almost a SASL framework, supports negotiation and challenge-response, mechanism code split out into util/sasl/
Kim Alvefur <zash@zash.se>
parents:
315
diff
changeset
|
27 end |
315
3742107e2505
plugins/sasl: Use ANONYMOUS authentication when no username provided
James Callahan <james@chatid.com>
parents:
302
diff
changeset
|
28 end |
354
58cd27b74ba5
Almost a SASL framework, supports negotiation and challenge-response, mechanism code split out into util/sasl/
Kim Alvefur <zash@zash.se>
parents:
315
diff
changeset
|
29 |
58cd27b74ba5
Almost a SASL framework, supports negotiation and challenge-response, mechanism code split out into util/sasl/
Kim Alvefur <zash@zash.se>
parents:
315
diff
changeset
|
30 local supported = {}; -- by the server |
58cd27b74ba5
Almost a SASL framework, supports negotiation and challenge-response, mechanism code split out into util/sasl/
Kim Alvefur <zash@zash.se>
parents:
315
diff
changeset
|
31 for mech in pairs(mechanisms) do |
58cd27b74ba5
Almost a SASL framework, supports negotiation and challenge-response, mechanism code split out into util/sasl/
Kim Alvefur <zash@zash.se>
parents:
315
diff
changeset
|
32 table.insert(supported, mech); |
58cd27b74ba5
Almost a SASL framework, supports negotiation and challenge-response, mechanism code split out into util/sasl/
Kim Alvefur <zash@zash.se>
parents:
315
diff
changeset
|
33 end |
58cd27b74ba5
Almost a SASL framework, supports negotiation and challenge-response, mechanism code split out into util/sasl/
Kim Alvefur <zash@zash.se>
parents:
315
diff
changeset
|
34 if not supported[1] then |
58cd27b74ba5
Almost a SASL framework, supports negotiation and challenge-response, mechanism code split out into util/sasl/
Kim Alvefur <zash@zash.se>
parents:
315
diff
changeset
|
35 stream:event("authentication-failure", { condition = "no-supported-sasl-mechanisms" }); |
58cd27b74ba5
Almost a SASL framework, supports negotiation and challenge-response, mechanism code split out into util/sasl/
Kim Alvefur <zash@zash.se>
parents:
315
diff
changeset
|
36 stream:close(); |
58cd27b74ba5
Almost a SASL framework, supports negotiation and challenge-response, mechanism code split out into util/sasl/
Kim Alvefur <zash@zash.se>
parents:
315
diff
changeset
|
37 return; |
58cd27b74ba5
Almost a SASL framework, supports negotiation and challenge-response, mechanism code split out into util/sasl/
Kim Alvefur <zash@zash.se>
parents:
315
diff
changeset
|
38 end |
58cd27b74ba5
Almost a SASL framework, supports negotiation and challenge-response, mechanism code split out into util/sasl/
Kim Alvefur <zash@zash.se>
parents:
315
diff
changeset
|
39 table.sort(supported, function (a, b) return preference[a] > preference[b]; end); |
58cd27b74ba5
Almost a SASL framework, supports negotiation and challenge-response, mechanism code split out into util/sasl/
Kim Alvefur <zash@zash.se>
parents:
315
diff
changeset
|
40 local mechanism, initial_data = supported[1]; |
58cd27b74ba5
Almost a SASL framework, supports negotiation and challenge-response, mechanism code split out into util/sasl/
Kim Alvefur <zash@zash.se>
parents:
315
diff
changeset
|
41 stream:debug("Selecting %s mechanism...", mechanism); |
58cd27b74ba5
Almost a SASL framework, supports negotiation and challenge-response, mechanism code split out into util/sasl/
Kim Alvefur <zash@zash.se>
parents:
315
diff
changeset
|
42 stream.sasl_mechanism = coroutine.wrap(mechanisms[mechanism]); |
58cd27b74ba5
Almost a SASL framework, supports negotiation and challenge-response, mechanism code split out into util/sasl/
Kim Alvefur <zash@zash.se>
parents:
315
diff
changeset
|
43 initial_data = stream:sasl_mechanism(mechanism); |
315
3742107e2505
plugins/sasl: Use ANONYMOUS authentication when no username provided
James Callahan <james@chatid.com>
parents:
302
diff
changeset
|
44 local auth_stanza = verse.stanza("auth", { xmlns = xmlns_sasl, mechanism = mechanism }); |
8 | 45 if initial_data then |
354
58cd27b74ba5
Almost a SASL framework, supports negotiation and challenge-response, mechanism code split out into util/sasl/
Kim Alvefur <zash@zash.se>
parents:
315
diff
changeset
|
46 auth_stanza:text(base64(initial_data)); |
8 | 47 end |
48 stream:send(auth_stanza); | |
49 return true; | |
50 end | |
51 | |
52 local function handle_sasl(sasl_stanza) | |
354
58cd27b74ba5
Almost a SASL framework, supports negotiation and challenge-response, mechanism code split out into util/sasl/
Kim Alvefur <zash@zash.se>
parents:
315
diff
changeset
|
53 if sasl_stanza.name == "failure" then |
8 | 54 local err = sasl_stanza.tags[1]; |
302
0c83cb476246
plugins.sasl: Collect text message on SASL failure
Kim Alvefur <zash@zash.se>
parents:
197
diff
changeset
|
55 local text = sasl_stanza:get_child_text("text"); |
0c83cb476246
plugins.sasl: Collect text message on SASL failure
Kim Alvefur <zash@zash.se>
parents:
197
diff
changeset
|
56 stream:event("authentication-failure", { condition = err.name, text = text }); |
354
58cd27b74ba5
Almost a SASL framework, supports negotiation and challenge-response, mechanism code split out into util/sasl/
Kim Alvefur <zash@zash.se>
parents:
315
diff
changeset
|
57 stream:close(); |
58cd27b74ba5
Almost a SASL framework, supports negotiation and challenge-response, mechanism code split out into util/sasl/
Kim Alvefur <zash@zash.se>
parents:
315
diff
changeset
|
58 return false; |
8 | 59 end |
354
58cd27b74ba5
Almost a SASL framework, supports negotiation and challenge-response, mechanism code split out into util/sasl/
Kim Alvefur <zash@zash.se>
parents:
315
diff
changeset
|
60 local ok, err = stream.sasl_mechanism(sasl_stanza.name, unbase64(sasl_stanza:get_text())); |
58cd27b74ba5
Almost a SASL framework, supports negotiation and challenge-response, mechanism code split out into util/sasl/
Kim Alvefur <zash@zash.se>
parents:
315
diff
changeset
|
61 if not ok then |
58cd27b74ba5
Almost a SASL framework, supports negotiation and challenge-response, mechanism code split out into util/sasl/
Kim Alvefur <zash@zash.se>
parents:
315
diff
changeset
|
62 stream:event("authentication-failure", { condition = err }); |
58cd27b74ba5
Almost a SASL framework, supports negotiation and challenge-response, mechanism code split out into util/sasl/
Kim Alvefur <zash@zash.se>
parents:
315
diff
changeset
|
63 stream:close(); |
58cd27b74ba5
Almost a SASL framework, supports negotiation and challenge-response, mechanism code split out into util/sasl/
Kim Alvefur <zash@zash.se>
parents:
315
diff
changeset
|
64 return false; |
58cd27b74ba5
Almost a SASL framework, supports negotiation and challenge-response, mechanism code split out into util/sasl/
Kim Alvefur <zash@zash.se>
parents:
315
diff
changeset
|
65 elseif ok == true then |
58cd27b74ba5
Almost a SASL framework, supports negotiation and challenge-response, mechanism code split out into util/sasl/
Kim Alvefur <zash@zash.se>
parents:
315
diff
changeset
|
66 stream:event("authentication-success"); |
58cd27b74ba5
Almost a SASL framework, supports negotiation and challenge-response, mechanism code split out into util/sasl/
Kim Alvefur <zash@zash.se>
parents:
315
diff
changeset
|
67 stream.authenticated = true |
58cd27b74ba5
Almost a SASL framework, supports negotiation and challenge-response, mechanism code split out into util/sasl/
Kim Alvefur <zash@zash.se>
parents:
315
diff
changeset
|
68 stream:reopen(); |
58cd27b74ba5
Almost a SASL framework, supports negotiation and challenge-response, mechanism code split out into util/sasl/
Kim Alvefur <zash@zash.se>
parents:
315
diff
changeset
|
69 else |
58cd27b74ba5
Almost a SASL framework, supports negotiation and challenge-response, mechanism code split out into util/sasl/
Kim Alvefur <zash@zash.se>
parents:
315
diff
changeset
|
70 stream:send(verse.stanza("response", { xmlns = xmlns_sasl }):text(base64(ok))); |
58cd27b74ba5
Almost a SASL framework, supports negotiation and challenge-response, mechanism code split out into util/sasl/
Kim Alvefur <zash@zash.se>
parents:
315
diff
changeset
|
71 end |
8 | 72 return true; |
73 end | |
74 | |
75 stream:hook("stream-features", handle_features, 300); | |
76 stream:hook("stream/"..xmlns_sasl, handle_sasl); | |
77 | |
78 return true; | |
79 end | |
80 |