Software / code / prosody-modules
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 |
| child | 5066: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); |