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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
395
e86144a4eaa1 plugins: Cleanup [luacheck]
Kim Alvefur <zash@zash.se>
parents: 380
diff changeset
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
f2b55ba66e14 plugins.sasl: Add plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
3 local xmlns_sasl = "urn:ietf:params:xml:ns:xmpp-sasl";
f2b55ba66e14 plugins.sasl: Add plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
4
f2b55ba66e14 plugins.sasl: Add plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
5 function verse.plugins.sasl(stream)
f2b55ba66e14 plugins.sasl: Add plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
6 local function handle_features(features_stanza)
f2b55ba66e14 plugins.sasl: Add plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
7 if stream.authenticated then return; end
f2b55ba66e14 plugins.sasl: Add plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
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
f2b55ba66e14 plugins.sasl: Add plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
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
f2b55ba66e14 plugins.sasl: Add plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
49 end
f2b55ba66e14 plugins.sasl: Add plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
50 stream:send(auth_stanza);
f2b55ba66e14 plugins.sasl: Add plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
51 return true;
f2b55ba66e14 plugins.sasl: Add plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
52 end
380
0891b4e27766 Discard trailing whitespace
Kim Alvefur <zash@zash.se>
parents: 360
diff changeset
53
8
f2b55ba66e14 plugins.sasl: Add plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
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
f2b55ba66e14 plugins.sasl: Add plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
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
f2b55ba66e14 plugins.sasl: Add plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
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
f2b55ba66e14 plugins.sasl: Add plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
74 return true;
f2b55ba66e14 plugins.sasl: Add plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
75 end
380
0891b4e27766 Discard trailing whitespace
Kim Alvefur <zash@zash.se>
parents: 360
diff changeset
76
8
f2b55ba66e14 plugins.sasl: Add plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
77 stream:hook("stream-features", handle_features, 300);
f2b55ba66e14 plugins.sasl: Add plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
78 stream:hook("stream/"..xmlns_sasl, handle_sasl);
380
0891b4e27766 Discard trailing whitespace
Kim Alvefur <zash@zash.se>
parents: 360
diff changeset
79
8
f2b55ba66e14 plugins.sasl: Add plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
80 return true;
f2b55ba66e14 plugins.sasl: Add plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
81 end
f2b55ba66e14 plugins.sasl: Add plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
82