annotate mod_sasl2_bind2/mod_sasl2_bind2.lua @ 5029:56b9f0b1409f

mod_sasl2_bind: Support for Bind 2.0 with SASL2 This is based on an experimental in-progress derivative of the current XEP-0386.
author Matthew Wild <mwild1@gmail.com>
date Fri, 02 Sep 2022 16:22:11 +0100
parents
children 62cdd8170563
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
5029
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
1 local base64 = require "util.encodings".base64;
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
2 local sha1 = require "util.hashes".sha1;
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
3 local st = require "util.stanza";
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
4
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
5 local sm_bind_resource = require "core.sessionmanager".bind_resource;
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
6
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
7 local xmlns_bind2 = "urn:xmpp:bind2:1";
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
8 local xmlns_sasl2 = "urn:xmpp:sasl2:1";
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
9
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
10 -- Advertise what we can do
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
11
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
12 module:hook("stream-features", function(event)
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
13 local origin, features = event.origin, event.features;
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
14
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
15 if origin.type ~= "c2s_unauthed" then
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
16 return;
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
17 end
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
18
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
19 local inline = st.stanza("inline", { xmlns = xmlns_bind2 });
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
20 module:fire_event("advertise-bind-features", { origin = origin, features = inline });
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
21 features:add_direct_child(inline);
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
22 end, 1);
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
23
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
24 module:hook("advertise-sasl-features", function(event)
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
25 event.features:tag("bind", { xmlns = xmlns_bind2 }):up();
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
26 end, 1);
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
27
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
28 -- Helper to actually bind a resource to a session
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
29
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
30 local function do_bind(session, bind_request)
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
31 local resource;
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
32
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
33 local client_id_tag = bind_request:get_child("client-id");
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
34 local client_id = client_id_tag and client_id_tag:text() or session.client_id;
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
35 if client_id and client_id ~= "" then
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
36 local tag = client_id_tag and client_id_tag.attr.tag or "client";
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
37 resource = ("%s~%s"):format(tag, base64.encode(sha1(client_id):sub(1, 9)));
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
38 end
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
39
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
40 local success, err_type, err, err_msg = sm_bind_resource(session, resource);
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
41 if not success then
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
42 session.log("debug", "Resource bind failed: %s", err_msg or err);
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
43 return nil, { type = err_type, condition = err, text = err_msg };
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
44 end
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
45
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
46 session.log("debug", "Resource bound: %s", session.full_jid);
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
47 return st.stanza("bound", { xmlns = xmlns_bind2 })
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
48 :text_tag("jid", session.full_jid)
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
49 end
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
50
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
51 -- Enable inline features requested by the client
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
52
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
53 local function enable_features(session, bind_request, bind_result)
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
54 local features = bind_request:get_child("features");
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
55 if not features then return; end
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
56 module:fire_event("process-bind-features", {
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
57 session = session;
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
58 features = features;
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
59 result = bind_result;
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
60 });
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
61 end
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
62
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
63 -- SASL 2 integration
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
64
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
65 module:hook_tag(xmlns_sasl2, "authenticate", function (session, auth)
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
66 -- Cache action for future processing (after auth success)
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
67 session.sasl2_bind_request = auth:child_with_ns(xmlns_bind2);
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
68 end, 100);
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
69
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
70 module:hook("sasl2/c2s/success", function (event)
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
71 local session = event.session;
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
72
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
73 local bind_request = session.sasl2_bind_request;
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
74 if not bind_request then return; end -- No bind requested
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
75 session.sasl2_bind_request = nil;
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
76
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
77 local sm_success = event.sasl2_sm_success;
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
78 if sm_success and sm_success.type == "resumed" then
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
79 return; -- No need to bind a resource
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
80 end
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
81
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
82 local bind_result, err = do_bind(session, bind_request);
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
83 if not bind_result then
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
84 bind_result = st.stanza("failed", { xmlns = xmlns_bind2 })
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
85 :add_error(err);
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
86 else
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
87 enable_features(session, bind_request, bind_result);
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
88 end
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
89
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
90 event.success:add_child(bind_result);
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
91 end, 100);
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
92
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
93 -- Inline features
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
94
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
95 module:hook("advertise-bind-features", function (event)
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
96 local features = event.features;
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
97 features:tag("feature", { var = "urn:xmpp:carbons:2" }):up();
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
98 features:tag("feature", { var = "urn:xmpp:csi:0" }):up();
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
99 end);
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
100
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
101 module:hook("enable-bind-features", function (event)
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
102 local session, features = event.session, event.features;
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
103
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
104 -- Carbons
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
105 session.want_carbons = not not features:get_child("enable", "urn:xmpp:carbons:2");
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
106
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
107 -- CSI
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
108 local csi_state_tag = features:child_with_ns("urn:xmpp:csi:0");
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
109 if csi_state_tag then
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
110 session.state = csi_state_tag.name;
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
111 end
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
112 end, 10);