Annotate

plugins/sasl.lua @ 445:b119dc4d8bc2

plugins.smacks: Don't warn about zero stanzas acked It's only if the count somehow goes backwards that something is really wrong. An ack for zero stanzas is fine and we don't need to do anything.
author Kim Alvefur <zash@zash.se>
date Thu, 10 Jun 2021 11:58:23 +0200
parent 395:e86144a4eaa1
child 456:6a65142052c8
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 = {};
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);
360
ac3940bad1bf plugins.sasl: Store mechanisms with the correct name
Kim Alvefur <zash@zash.se>
parents: 358
diff changeset
23 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
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
f2b55ba66e14 plugins.sasl: Add plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
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
f2b55ba66e14 plugins.sasl: Add plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
47 end
f2b55ba66e14 plugins.sasl: Add plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
48 stream:send(auth_stanza);
f2b55ba66e14 plugins.sasl: Add plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
49 return true;
f2b55ba66e14 plugins.sasl: Add plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
50 end
380
0891b4e27766 Discard trailing whitespace
Kim Alvefur <zash@zash.se>
parents: 360
diff changeset
51
8
f2b55ba66e14 plugins.sasl: Add plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
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
f2b55ba66e14 plugins.sasl: Add plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
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
f2b55ba66e14 plugins.sasl: Add plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
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
f2b55ba66e14 plugins.sasl: Add plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
72 return true;
f2b55ba66e14 plugins.sasl: Add plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
73 end
380
0891b4e27766 Discard trailing whitespace
Kim Alvefur <zash@zash.se>
parents: 360
diff changeset
74
8
f2b55ba66e14 plugins.sasl: Add plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
75 stream:hook("stream-features", handle_features, 300);
f2b55ba66e14 plugins.sasl: Add plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
76 stream:hook("stream/"..xmlns_sasl, handle_sasl);
380
0891b4e27766 Discard trailing whitespace
Kim Alvefur <zash@zash.se>
parents: 360
diff changeset
77
8
f2b55ba66e14 plugins.sasl: Add plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
78 return true;
f2b55ba66e14 plugins.sasl: Add plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
79 end
f2b55ba66e14 plugins.sasl: Add plugin
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
80