Changeset

3693:0fb12a4b6106

auth_token: Various updates, see below. * Defer to usermanager when testing the password * Because of this, don't assume the realm is available when verifying the token * Fix linting errors By using the `usermanager`, other modules can now ask the user manager to verify token credentials.
author JC Brand <jc@opkode.com>
date Thu, 03 Oct 2019 12:13:44 +0200
parents 3692:96c6d9b0969f
children 3694:e45a3d04367b
files mod_auth_token/mod_auth_token.lua mod_auth_token/token_auth_utils.lib.lua
diffstat 2 files changed, 15 insertions(+), 21 deletions(-) [+]
line wrap: on
line diff
--- a/mod_auth_token/mod_auth_token.lua	Mon Sep 30 00:51:05 2019 +0200
+++ b/mod_auth_token/mod_auth_token.lua	Thu Oct 03 12:13:44 2019 +0200
@@ -6,17 +6,17 @@
 local host = module.host;
 local log = module._log;
 local new_sasl = require "util.sasl".new;
+local usermanager = require "core.usermanager";
 local verify_token = module:require "token_auth_utils".verify_token;
 
 local provider = {};
 
 
-function provider.test_password(username, password, realm)
+function provider.test_password(username, password)
 	log("debug", "Testing signed OTP for user %s at host %s", username, host);
 	return verify_token(
 		username,
 		password,
-		realm,
 		module:get_option_string("otp_seed"),
 		module:get_option_string("token_secret"),
 		log
@@ -50,7 +50,7 @@
 	supported_mechanisms["X-TOKEN"] = true;
 	return new_sasl(host, {
 		token = function(sasl, username, password, realm)
-			return provider.test_password(username, password, realm), true;
+			return usermanager.test_password(username, realm, password), true;
 		end,
         mechanisms = supported_mechanisms
 	});
--- a/mod_auth_token/token_auth_utils.lib.lua	Mon Sep 30 00:51:05 2019 +0200
+++ b/mod_auth_token/token_auth_utils.lib.lua	Thu Oct 03 12:13:44 2019 +0200
@@ -1,5 +1,4 @@
 local base64 = require "util.encodings".base64;
-local digest = require "openssl.digest";
 local hmac = require "openssl.hmac";
 local luatz = require "luatz";
 local otp = require "otp";
@@ -11,7 +10,7 @@
 
 local nonce_cache = {};
 
-function check_nonce(jid, otp, nonce)
+local function check_nonce(jid, otp_value, nonce)
 	-- We cache all nonces used per OTP, to ensure that a token cannot be used
 	-- more than once.
 	--
@@ -20,40 +19,35 @@
 	--
 	-- We only store one OTP per JID, so if a new OTP comes in, we wipe the
 	-- previous OTP and its cached nonces.
-	if nonce_cache[jid] == nil or nonce_cache[jid][otp] == nil then
+	if nonce_cache[jid] == nil or nonce_cache[jid][otp_value] == nil then
 		nonce_cache[jid] = {}
-		nonce_cache[jid][otp] = {}
-		nonce_cache[jid][otp][nonce] = true
+		nonce_cache[jid][otp_value] = {}
+		nonce_cache[jid][otp_value][nonce] = true
 		return true;
 	end
-	if nonce_cache[jid][otp][nonce] == true then
+	if nonce_cache[jid][otp_value][nonce] == true then
 		return false;
 	else
-		nonce_cache[jid][otp][nonce] = true;
+		nonce_cache[jid][otp_value][nonce] = true;
 		return true;
 	end
 end
 
 
-function verify_token(username, password, realm, otp_seed, token_secret, log)
-	if (realm ~= module.host) then
-		log("debug", "Verification failed: realm ~= module.host");
-		return false;
-	end
-
+local function verify_token(username, password, otp_seed, token_secret, log)
 	local totp = otp.new_totp_from_key(otp_seed, OTP_DIGITS, OTP_INTERVAL)
 	local token = string.match(password, "(%d+) ")
-	local otp = token:sub(1,8)
+	local otp_value = token:sub(1,8)
 	local nonce = token:sub(9)
 	local signature = base64.decode(string.match(password, " (.+)"))
-	local jid = username.."@"..realm
+	local jid = username.."@"..module.host
 
-	if totp:verify(otp, OTP_DEVIATION, luatz.time()) then
+	if totp:verify(otp_value, OTP_DEVIATION, luatz.time()) then
 		log("debug", "The TOTP was verified");
 		local hmac_ctx = hmac.new(token_secret, DIGEST_TYPE)
-		if signature == hmac_ctx:final(otp..nonce..jid) then
+		if signature == hmac_ctx:final(otp_value..nonce..jid) then
 			log("debug", "The key was verified");
-			if check_nonce(jid, otp, nonce) then
+			if check_nonce(jid, otp_value, nonce) then
 				log("debug", "The nonce was verified");
 				return true;
 			end