Software /
code /
verse
Annotate
plugins/sasl.lua @ 498:50d0bd035bb7
util.sasl.oauthbearer: Don't send authzid
It's not needed and not recommended in XMPP unless we want to act as
someone other than who we authenticate as. We find out the JID during
resource binding.
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Fri, 23 Jun 2023 12:09:49 +0200 (22 months ago) |
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 |