Changeset

12938:055b03d3059b

util.sasl.oauthbearer: Return username from callback instead using authzid (BC) RFC 6120 states that > If the initiating entity does not wish to act on behalf of another > entity, it MUST NOT provide an authorization identity. Thus it seems weird to require it here. We can instead expect an username from the token data passed back from the profile. This follows the practice of util.sasl.external where the profile callback returns the selected username, making the authentication module responsible for extracting the username from the token.
author Kim Alvefur <zash@zash.se>
date Thu, 16 Mar 2023 12:18:23 +0100
parents 12937:23b20ede9c34
children 12939:bb6a98a7b0b4
files plugins/mod_tokenauth.lua util/sasl/oauthbearer.lua
diffstat 2 files changed, 10 insertions(+), 38 deletions(-) [+]
line wrap: on
line diff
--- a/plugins/mod_tokenauth.lua	Wed Mar 15 12:02:23 2023 +0000
+++ b/plugins/mod_tokenauth.lua	Thu Mar 16 12:18:23 2023 +0100
@@ -125,19 +125,21 @@
 end
 
 function sasl_handler(auth_provider, purpose, extra)
-	return function (_, username, token, realm)
+	return function (sasl, token, realm, _authzid)
 		local token_info, err = get_token_info(token);
 		if not token_info then
 			module:log("debug", "SASL handler failed to verify token: %s", err);
 			return nil, nil, extra;
 		end
-		local token_user, token_host = jid.split(token_info.jid);
-		if username ~= token_user or realm ~= token_host or (purpose and token_info.purpose ~= purpose) then
+		local token_user, token_host, resource = jid.split(token_info.jid);
+		if realm ~= token_host or (purpose and token_info.purpose ~= purpose) then
 			return nil, nil, extra;
 		end
-		if auth_provider.is_enabled and not auth_provider.is_enabled(username) then
+		if auth_provider.is_enabled and not auth_provider.is_enabled(token_user) then
 			return true, false, token_info;
 		end
-		return true, true, token_info;
+		sasl.resource = resource;
+		sasl.token_info = token_info;
+		return token_user, true, token_info;
 	end;
 end
--- a/util/sasl/oauthbearer.lua	Wed Mar 15 12:02:23 2023 +0000
+++ b/util/sasl/oauthbearer.lua	Thu Mar 16 12:18:23 2023 +0100
@@ -1,8 +1,4 @@
-local saslprep = require "util.encodings".stringprep.saslprep;
-local nodeprep = require "util.encodings".stringprep.nodeprep;
-local jid = require "util.jid";
 local json = require "util.json";
-local log = require "util.logger".init("sasl");
 local _ENV = nil;
 
 
@@ -32,37 +28,13 @@
 		return "failure", "malformed-request";
 	end
 
-	local username = jid.prepped_split(gs2_authzid);
-
-	if not username or username == "" then
-		return "failure", "malformed-request", "Expected authorization identity in the username@hostname format";
-	end
-
-	-- SASLprep username
-	username = saslprep(username);
-
-	if not username or username == "" then
-		log("debug", "Username violates SASLprep.");
-		return "failure", "malformed-request", "Invalid username.";
-	end
-
-	local _nodeprep = self.profile.nodeprep;
-	if _nodeprep ~= false then
-		username = (_nodeprep or nodeprep)(username);
-		if not username or username == "" then
-			return "failure", "malformed-request", "Invalid username or password."
-		end
-	end
-
-	self.username = username;
-
 	local token = auth_header:match("^Bearer (.+)$");
 
-	local correct, state, token_info = self.profile.oauthbearer(self, username, token, self.realm);
+	local username, state, token_info = self.profile.oauthbearer(self, token, self.realm, gs2_authzid);
 
 	if state == false then
 		return "failure", "account-disabled";
-	elseif state == nil or not correct then
+	elseif state == nil or not username then
 		-- For token-level errors, RFC 7628 demands use of a JSON-encoded
 		-- challenge response upon failure. We relay additional info from
 		-- the auth backend if available.
@@ -72,9 +44,7 @@
 			["openid-configuration"] = token_info and token_info.oidc_discovery_url or nil;
 		});
 	end
-
-	self.resource = token_info.resource;
-	self.role = token_info.role;
+	self.username = username;
 	self.token_info = token_info;
 
 	return "success";