Diff

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
parent 5066:74145faceba2
child 5069:e8342ae5ae12
line wrap: on
line diff
--- a/mod_sasl2_fast/mod_sasl2_fast.lua	Fri Oct 14 15:43:22 2022 +0100
+++ b/mod_sasl2_fast/mod_sasl2_fast.lua	Fri Oct 14 15:44:00 2022 +0100
@@ -1,6 +1,7 @@
 local sasl = require "util.sasl";
 local dt = require "util.datetime";
 local id = require "util.id";
+local jid = require "util.jid";
 local st = require "util.stanza";
 local now = require "util.time".now;
 local hash = require "util.hashes";
@@ -59,8 +60,7 @@
 	end
 end
 
-function get_sasl_handler(session)
-	local username = session.username;
+function get_sasl_handler(username)
 	local token_auth_profile = {
 		ht_256 = new_token_tester(username, hash.hmac_sha256);
 		token_test = function (_, client_id, token, mech_name, counter) --luacheck: ignore
@@ -73,7 +73,12 @@
 -- Advertise FAST to connecting clients
 module:hook("advertise-sasl-features", function (event)
 	local session = event.origin;
-	local sasl_handler = get_sasl_handler(session);
+	local username = session.username;
+	if not username then
+		username = jid.node(event.stream.from);
+		if not username then return; end
+	end
+	local sasl_handler = get_sasl_handler(username);
 	if not sasl_handler then return; end
 	session.fast_sasl_handler = sasl_handler;
 	local fast = st.stanza("fast", { xmlns = xmlns_fast });
@@ -89,10 +94,19 @@
 	local fast_auth = auth:get_child(xmlns_fast, "fast");
 	if fast_auth then
 		-- Client says it is using FAST auth, so set our SASL handler
-		session.log("debug", "Client is authenticating using FAST");
 		local fast_sasl_handler = session.fast_sasl_handler;
-		fast_sasl_handler.profile._client_id = session.client_id;
-		session.sasl_handler = fast_sasl_handler;
+		if fast_sasl_handler then
+			session.log("debug", "Client is authenticating using FAST");
+			fast_sasl_handler.profile._client_id = session.client_id;
+			session.sasl_handler = fast_sasl_handler;
+		else
+			session.log("warn", "Client asked to auth via FAST, but no SASL handler available");
+			local failure = st.stanza("failure", { xmlns = xmlns_sasl2 })
+				:tag("malformed-request"):up()
+				:text_tag("text", "FAST is not available on this stream");
+			session.send(failure);
+			return true;
+		end
 	end
 	session.fast_sasl_handler = nil;
 	local fast_token_request = auth:get_child(xmlns_fast, "request-token");
@@ -111,9 +125,8 @@
 
 	local token_request = session.fast_token_request;
 	local client_id = session.client_id;
-	local stream_from = event.stream.from;
 	if token_request then
-		if not client_id or not stream_from then
+		if not client_id then
 			session.log("warn", "FAST token requested, but missing client id");
 			return;
 		end