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.
--- 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