Mercurial > prosody-modules
comparison mod_sasl2_fast/mod_sasl2_fast.lua @ 5068:20e635eb4cdc
mod_sasl2_fast: More robust handling of stream@from and user-agent@id
author | Matthew Wild <mwild1@gmail.com> |
---|---|
date | Fri, 14 Oct 2022 15:44:00 +0100 |
parents | 74145faceba2 |
children | e8342ae5ae12 |
comparison
equal
deleted
inserted
replaced
5067:54c6b4595f86 | 5068:20e635eb4cdc |
---|---|
1 local sasl = require "util.sasl"; | 1 local sasl = require "util.sasl"; |
2 local dt = require "util.datetime"; | 2 local dt = require "util.datetime"; |
3 local id = require "util.id"; | 3 local id = require "util.id"; |
4 local jid = require "util.jid"; | |
4 local st = require "util.stanza"; | 5 local st = require "util.stanza"; |
5 local now = require "util.time".now; | 6 local now = require "util.time".now; |
6 local hash = require "util.hashes"; | 7 local hash = require "util.hashes"; |
7 | 8 |
8 local fast_token_ttl = module:get_option_number("sasl2_fast_token_ttl", 86400*21); | 9 local fast_token_ttl = module:get_option_number("sasl2_fast_token_ttl", 86400*21); |
57 end | 58 end |
58 until false; | 59 until false; |
59 end | 60 end |
60 end | 61 end |
61 | 62 |
62 function get_sasl_handler(session) | 63 function get_sasl_handler(username) |
63 local username = session.username; | |
64 local token_auth_profile = { | 64 local token_auth_profile = { |
65 ht_256 = new_token_tester(username, hash.hmac_sha256); | 65 ht_256 = new_token_tester(username, hash.hmac_sha256); |
66 token_test = function (_, client_id, token, mech_name, counter) --luacheck: ignore | 66 token_test = function (_, client_id, token, mech_name, counter) --luacheck: ignore |
67 return false; -- FIXME | 67 return false; -- FIXME |
68 end; | 68 end; |
71 end | 71 end |
72 | 72 |
73 -- Advertise FAST to connecting clients | 73 -- Advertise FAST to connecting clients |
74 module:hook("advertise-sasl-features", function (event) | 74 module:hook("advertise-sasl-features", function (event) |
75 local session = event.origin; | 75 local session = event.origin; |
76 local sasl_handler = get_sasl_handler(session); | 76 local username = session.username; |
77 if not username then | |
78 username = jid.node(event.stream.from); | |
79 if not username then return; end | |
80 end | |
81 local sasl_handler = get_sasl_handler(username); | |
77 if not sasl_handler then return; end | 82 if not sasl_handler then return; end |
78 session.fast_sasl_handler = sasl_handler; | 83 session.fast_sasl_handler = sasl_handler; |
79 local fast = st.stanza("fast", { xmlns = xmlns_fast }); | 84 local fast = st.stanza("fast", { xmlns = xmlns_fast }); |
80 for mech in pairs(sasl_handler:mechanisms()) do | 85 for mech in pairs(sasl_handler:mechanisms()) do |
81 fast:text_tag("mechanism", mech); | 86 fast:text_tag("mechanism", mech); |
87 module:hook_tag(xmlns_sasl2, "authenticate", function (session, auth) | 92 module:hook_tag(xmlns_sasl2, "authenticate", function (session, auth) |
88 -- Cache action for future processing (after auth success) | 93 -- Cache action for future processing (after auth success) |
89 local fast_auth = auth:get_child(xmlns_fast, "fast"); | 94 local fast_auth = auth:get_child(xmlns_fast, "fast"); |
90 if fast_auth then | 95 if fast_auth then |
91 -- Client says it is using FAST auth, so set our SASL handler | 96 -- Client says it is using FAST auth, so set our SASL handler |
92 session.log("debug", "Client is authenticating using FAST"); | |
93 local fast_sasl_handler = session.fast_sasl_handler; | 97 local fast_sasl_handler = session.fast_sasl_handler; |
94 fast_sasl_handler.profile._client_id = session.client_id; | 98 if fast_sasl_handler then |
95 session.sasl_handler = fast_sasl_handler; | 99 session.log("debug", "Client is authenticating using FAST"); |
100 fast_sasl_handler.profile._client_id = session.client_id; | |
101 session.sasl_handler = fast_sasl_handler; | |
102 else | |
103 session.log("warn", "Client asked to auth via FAST, but no SASL handler available"); | |
104 local failure = st.stanza("failure", { xmlns = xmlns_sasl2 }) | |
105 :tag("malformed-request"):up() | |
106 :text_tag("text", "FAST is not available on this stream"); | |
107 session.send(failure); | |
108 return true; | |
109 end | |
96 end | 110 end |
97 session.fast_sasl_handler = nil; | 111 session.fast_sasl_handler = nil; |
98 local fast_token_request = auth:get_child(xmlns_fast, "request-token"); | 112 local fast_token_request = auth:get_child(xmlns_fast, "request-token"); |
99 if fast_token_request then | 113 if fast_token_request then |
100 local mech = fast_token_request.attr.mechanism; | 114 local mech = fast_token_request.attr.mechanism; |
109 module:hook("sasl2/c2s/success", function (event) | 123 module:hook("sasl2/c2s/success", function (event) |
110 local session = event.session; | 124 local session = event.session; |
111 | 125 |
112 local token_request = session.fast_token_request; | 126 local token_request = session.fast_token_request; |
113 local client_id = session.client_id; | 127 local client_id = session.client_id; |
114 local stream_from = event.stream.from; | |
115 if token_request then | 128 if token_request then |
116 if not client_id or not stream_from then | 129 if not client_id then |
117 session.log("warn", "FAST token requested, but missing client id"); | 130 session.log("warn", "FAST token requested, but missing client id"); |
118 return; | 131 return; |
119 end | 132 end |
120 local token_info = make_token(session.username, client_id, token_request.mechanism) | 133 local token_info = make_token(session.username, client_id, token_request.mechanism) |
121 if token_info then | 134 if token_info then |