Annotate

mod_auth_token/token_auth_utils.lib.lua @ 5186:fa3059e653fa

mod_http_oauth2: Implement the Implicit flow Everyone says this is insecure and bad, but it's also the only thing that makes sense for e.g. pure JavaScript clients, but hey implement this even more complicated thing instead!
author Kim Alvefur <zash@zash.se>
date Thu, 02 Mar 2023 22:06:50 +0100
parent 3693:0fb12a4b6106
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
2956
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
1 local base64 = require "util.encodings".base64;
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
2 local hmac = require "openssl.hmac";
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
3 local luatz = require "luatz";
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
4 local otp = require "otp";
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
5
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
6 local DIGEST_TYPE = "SHA256";
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
7 local OTP_DEVIATION = 1;
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
8 local OTP_DIGITS = 8;
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
9 local OTP_INTERVAL = 30;
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
10
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
11 local nonce_cache = {};
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
12
3693
0fb12a4b6106 auth_token: Various updates, see below.
JC Brand <jc@opkode.com>
parents: 3568
diff changeset
13 local function check_nonce(jid, otp_value, nonce)
2956
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
14 -- We cache all nonces used per OTP, to ensure that a token cannot be used
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
15 -- more than once.
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
16 --
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
17 -- We assume that the OTP is valid in the current time window. This is the
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
18 -- case because we only call check_nonce *after* the OTP has been verified.
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
19 --
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
20 -- We only store one OTP per JID, so if a new OTP comes in, we wipe the
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
21 -- previous OTP and its cached nonces.
3693
0fb12a4b6106 auth_token: Various updates, see below.
JC Brand <jc@opkode.com>
parents: 3568
diff changeset
22 if nonce_cache[jid] == nil or nonce_cache[jid][otp_value] == nil then
2956
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
23 nonce_cache[jid] = {}
3693
0fb12a4b6106 auth_token: Various updates, see below.
JC Brand <jc@opkode.com>
parents: 3568
diff changeset
24 nonce_cache[jid][otp_value] = {}
0fb12a4b6106 auth_token: Various updates, see below.
JC Brand <jc@opkode.com>
parents: 3568
diff changeset
25 nonce_cache[jid][otp_value][nonce] = true
2956
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
26 return true;
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
27 end
3693
0fb12a4b6106 auth_token: Various updates, see below.
JC Brand <jc@opkode.com>
parents: 3568
diff changeset
28 if nonce_cache[jid][otp_value][nonce] == true then
2956
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
29 return false;
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
30 else
3693
0fb12a4b6106 auth_token: Various updates, see below.
JC Brand <jc@opkode.com>
parents: 3568
diff changeset
31 nonce_cache[jid][otp_value][nonce] = true;
2956
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
32 return true;
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
33 end
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
34 end
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
35
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
36
3693
0fb12a4b6106 auth_token: Various updates, see below.
JC Brand <jc@opkode.com>
parents: 3568
diff changeset
37 local function verify_token(username, password, otp_seed, token_secret, log)
2956
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
38 local totp = otp.new_totp_from_key(otp_seed, OTP_DIGITS, OTP_INTERVAL)
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
39 local token = string.match(password, "(%d+) ")
3693
0fb12a4b6106 auth_token: Various updates, see below.
JC Brand <jc@opkode.com>
parents: 3568
diff changeset
40 local otp_value = token:sub(1,8)
2956
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
41 local nonce = token:sub(9)
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
42 local signature = base64.decode(string.match(password, " (.+)"))
3693
0fb12a4b6106 auth_token: Various updates, see below.
JC Brand <jc@opkode.com>
parents: 3568
diff changeset
43 local jid = username.."@"..module.host
2956
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
44
3693
0fb12a4b6106 auth_token: Various updates, see below.
JC Brand <jc@opkode.com>
parents: 3568
diff changeset
45 if totp:verify(otp_value, OTP_DEVIATION, luatz.time()) then
3472
ac1f63cdb6d6 mod_auth_token: Check realm against module.host
JC Brand <jc@opkode.com>
parents: 2956
diff changeset
46 log("debug", "The TOTP was verified");
2956
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
47 local hmac_ctx = hmac.new(token_secret, DIGEST_TYPE)
3693
0fb12a4b6106 auth_token: Various updates, see below.
JC Brand <jc@opkode.com>
parents: 3568
diff changeset
48 if signature == hmac_ctx:final(otp_value..nonce..jid) then
3472
ac1f63cdb6d6 mod_auth_token: Check realm against module.host
JC Brand <jc@opkode.com>
parents: 2956
diff changeset
49 log("debug", "The key was verified");
3693
0fb12a4b6106 auth_token: Various updates, see below.
JC Brand <jc@opkode.com>
parents: 3568
diff changeset
50 if check_nonce(jid, otp_value, nonce) then
3472
ac1f63cdb6d6 mod_auth_token: Check realm against module.host
JC Brand <jc@opkode.com>
parents: 2956
diff changeset
51 log("debug", "The nonce was verified");
2956
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
52 return true;
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
53 end
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
54 end
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
55 end
3472
ac1f63cdb6d6 mod_auth_token: Check realm against module.host
JC Brand <jc@opkode.com>
parents: 2956
diff changeset
56 log("debug", "Verification failed");
2956
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
57 return false;
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
58 end
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
59
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
60 return {
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
61 OTP_DEVIATION = OTP_DIGITS,
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
62 OTP_DIGITS = OTP_DIGITS,
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
63 OTP_INTERVAL = OTP_INTERVAL,
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
64 DIGEST_TYPE = DIGEST_TYPE,
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
65 verify_token = verify_token;
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
66 }