Software / code / verse
Annotate
plugins/sasl.lua @ 506:3610196c5e83 default tip
Merge with Zash.
| author | Trần H. Trung <xmpp:trần.h.trung@trung.fun> |
|---|---|
| date | Sat, 08 Jul 2023 02:17:52 +0700 |
| parent | 490:6b2f31da9610 |
| rev | line source |
|---|---|
| 395 | 1 local verse = require"verse"; |
|
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
|
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 = {}; |
|
467
8e6a7a5e70b3
sasl: Expose what mechanisms were offered on authentication-failure
Matthew Wild <mwild1@gmail.com>
parents:
456
diff
changeset
|
14 local offered = {}; |
|
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
|
15 |
|
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 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
|
17 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
|
18 stream:debug("Server offers %s", mech); |
|
467
8e6a7a5e70b3
sasl: Expose what mechanisms were offered on authentication-failure
Matthew Wild <mwild1@gmail.com>
parents:
456
diff
changeset
|
19 offered[mech] = true; |
|
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
|
20 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
|
21 local name = mech:match("[^-]+"); |
|
490
6b2f31da9610
Update for new Prosody module namespace
Kim Alvefur <zash@zash.se>
parents:
467
diff
changeset
|
22 local ok, impl = pcall(require, "verse.util.sasl."..name:lower()); |
|
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
|
23 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
|
24 stream:debug("Loaded SASL %s module", name); |
|
360
ac3940bad1bf
plugins.sasl: Store mechanisms with the correct name
Kim Alvefur <zash@zash.se>
parents:
358
diff
changeset
|
25 mechanisms[mech], preference[mech] = impl(stream, mech); |
|
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
|
26 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
|
27 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
|
28 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
|
29 end |
|
315
3742107e2505
plugins/sasl: Use ANONYMOUS authentication when no username provided
James Callahan <james@chatid.com>
parents:
302
diff
changeset
|
30 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
|
31 |
|
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 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
|
33 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
|
34 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
|
35 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
|
36 if not supported[1] then |
|
467
8e6a7a5e70b3
sasl: Expose what mechanisms were offered on authentication-failure
Matthew Wild <mwild1@gmail.com>
parents:
456
diff
changeset
|
37 stream:event("authentication-failure", { condition = "no-supported-sasl-mechanisms", mechanisms = offered }); |
|
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
|
38 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
|
39 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
|
40 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
|
41 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
|
42 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
|
43 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
|
44 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
|
45 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
|
46 local auth_stanza = verse.stanza("auth", { xmlns = xmlns_sasl, mechanism = mechanism }); |
| 8 | 47 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
|
48 auth_stanza:text(base64(initial_data)); |
| 8 | 49 end |
| 50 stream:send(auth_stanza); | |
| 51 return true; | |
| 52 end | |
| 380 | 53 |
| 8 | 54 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
|
55 if sasl_stanza.name == "failure" then |
| 8 | 56 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
|
57 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
|
58 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
|
59 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
|
60 return false; |
| 8 | 61 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
|
62 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
|
63 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
|
64 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
|
65 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
|
66 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
|
67 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
|
68 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
|
69 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
|
70 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
|
71 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
|
72 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
|
73 end |
| 8 | 74 return true; |
| 75 end | |
| 380 | 76 |
| 8 | 77 stream:hook("stream-features", handle_features, 300); |
| 78 stream:hook("stream/"..xmlns_sasl, handle_sasl); | |
| 380 | 79 |
| 8 | 80 return true; |
| 81 end | |
| 82 |