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