comparison mod_sasl2_fast/mod_sasl2_fast.lua @ 5062:38a0e3621181

mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
author Matthew Wild <mwild1@gmail.com>
date Thu, 13 Oct 2022 22:47:35 +0100
parents
children 74145faceba2
comparison
equal deleted inserted replaced
5061:e44b868cc575 5062:38a0e3621181
1 local tokenauth = module:depends("tokenauth");
2 local sasl = require "util.sasl";
3 local dt = require "util.datetime";
4 local st = require "util.stanza";
5
6 local fast_token_ttl = module:get_option_number("sasl2_fast_token_ttl", 86400*21);
7
8 local xmlns_fast = "urn:xmpp:fast:0";
9 local xmlns_sasl2 = "urn:xmpp:sasl:2";
10
11 function get_sasl_handler(session) --luacheck: ignore session
12 local token_auth_profile = {
13 token_test = function (_, client_id, token, mech_name, counter) --luacheck: ignore
14 return false; -- FIXME
15 end;
16 };
17 return sasl.new(module.host, token_auth_profile);
18 end
19
20 -- Advertise FAST to connecting clients
21 module:hook("advertise-sasl-features", function (event)
22 local sasl_handler = get_sasl_handler(event.session);
23 if not sasl_handler then return; end
24 event.session.fast_sasl_handler = sasl_handler;
25 local fast = st.stanza("fast", { xmlns = xmlns_fast });
26 for mech in sasl_handler:mechanisms() do
27 fast:text_tag("mechanism", mech);
28 end
29 event.features:add_child(fast);
30 end);
31
32 -- Process any FAST elements in <authenticate/>
33 module:hook_tag(xmlns_sasl2, "authenticate", function (session, auth)
34 -- Cache action for future processing (after auth success)
35 local fast_auth = auth:get_child(xmlns_fast, "fast");
36 if fast_auth then
37 -- Client says it is using FAST auth, so set our SASL handler
38 session.log("debug", "Client is authenticating using FAST");
39 session.sasl_handler = session.fast_sasl_handler;
40 end
41 session.fast_sasl_handler = nil;
42 local fast_token_request = auth:get_child(xmlns_fast, "request-token");
43 if fast_token_request then
44 local mech = fast_token_request.attr.mechanism;
45 session.log("debug", "Client requested new FAST token for %s", mech);
46 session.fast_token_request = {
47 mechanism = mech;
48 };
49 end
50 end, 100);
51
52 -- Process post-success (new token generation, etc.)
53 module:hook("sasl2/c2s/success", function (event)
54 local session = event.session;
55
56 local token_request = session.fast_token_request;
57 if token_request then
58 local token, token_info = tokenauth.create_jid_token(
59 session.full_jid,
60 session.full_jid,
61 session.role,
62 fast_token_ttl,
63 {
64 fast_token = true;
65 fast_mechanism = token_request.mechanism;
66 }
67 );
68 if token then
69 event.success:tag("token", {
70 xmlns = xmlns_fast;
71 expiry = dt.datetime(token_info.expiry);
72 token = token;
73 }):up();
74 end
75 end
76 end, 75);
77
78
79 -- X-PLAIN-TOKEN mechanism
80
81 local function x_plain_token(self, message) --luacheck: ignore 212/self
82 if not message then
83 return nil, "malformed-request";
84 end
85 return nil, "temporary-auth-failure"; -- FIXME
86 end
87
88 sasl.registerMechanism("X-PLAIN-TOKEN", { "token_test" }, x_plain_token);