annotate mod_auth_token/token_auth_utils.lib.lua @ 3503:882180b459a0

mod_pubsub_post: Restructure authentication and authorization (BC) This deprecates the default "superuser" actor model and makes the default equivalent to the previous "request.id". A single actor and secret per node is supported because HTTP and WebHooks don't normally include any authorization identity. Allowing authentication bypass when no secret is given should be relatively safe when the actor is unprivileged, as will be unless explicitly configured otherwise.
author Kim Alvefur <zash@zash.se>
date Sat, 30 Mar 2019 21:16:13 +0100
parents ac1f63cdb6d6
children 6b3181fe5617
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 digest = require "openssl.digest";
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
3 local hmac = require "openssl.hmac";
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
4 local luatz = require "luatz";
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
5 local otp = require "otp";
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
6
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
7 local DIGEST_TYPE = "SHA256";
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
8 local OTP_DEVIATION = 1;
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
9 local OTP_DIGITS = 8;
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
10 local OTP_INTERVAL = 30;
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
11
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
12 local nonce_cache = {};
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
13
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
14 function check_nonce(jid, otp, nonce)
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
15 -- 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
16 -- more than once.
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
17 --
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
18 -- 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
19 -- 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
20 --
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
21 -- 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
22 -- previous OTP and its cached nonces.
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
23 if nonce_cache[jid] == nil or nonce_cache[jid][otp] == nil then
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
24 nonce_cache[jid] = {}
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
25 nonce_cache[jid][otp] = {}
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
26 nonce_cache[jid][otp][nonce] = true
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
27 return true;
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
28 end
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
29 if nonce_cache[jid][otp][nonce] == true then
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
30 return false;
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
31 else
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
32 nonce_cache[jid][otp][nonce] = true;
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
33 return true;
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 end
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
36
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
37
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
38 function verify_token(username, password, realm, otp_seed, token_secret, log)
3472
ac1f63cdb6d6 mod_auth_token: Check realm against module.host
JC Brand <jc@opkode.com>
parents: 2956
diff changeset
39 if (realm ~= module.host) then
ac1f63cdb6d6 mod_auth_token: Check realm against module.host
JC Brand <jc@opkode.com>
parents: 2956
diff changeset
40 log("debug", "Verification failed: realm ~= module.host");
ac1f63cdb6d6 mod_auth_token: Check realm against module.host
JC Brand <jc@opkode.com>
parents: 2956
diff changeset
41 return false;
ac1f63cdb6d6 mod_auth_token: Check realm against module.host
JC Brand <jc@opkode.com>
parents: 2956
diff changeset
42 end
ac1f63cdb6d6 mod_auth_token: Check realm against module.host
JC Brand <jc@opkode.com>
parents: 2956
diff changeset
43
2956
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
44 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
45 local token = string.match(password, "(%d+) ")
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
46 local otp = token:sub(1,8)
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
47 local nonce = token:sub(9)
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
48 local signature = base64.decode(string.match(password, " (.+)"))
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
49 local jid = username.."@"..realm
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
50
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
51 if totp:verify(otp, OTP_DEVIATION, luatz.gmtime(luatz.time())) then
3472
ac1f63cdb6d6 mod_auth_token: Check realm against module.host
JC Brand <jc@opkode.com>
parents: 2956
diff changeset
52 log("debug", "The TOTP was verified");
2956
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
53 local hmac_ctx = hmac.new(token_secret, DIGEST_TYPE)
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
54 if signature == hmac_ctx:final(otp..nonce..jid) then
3472
ac1f63cdb6d6 mod_auth_token: Check realm against module.host
JC Brand <jc@opkode.com>
parents: 2956
diff changeset
55 log("debug", "The key was verified");
2956
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
56 if check_nonce(jid, otp, nonce) then
3472
ac1f63cdb6d6 mod_auth_token: Check realm against module.host
JC Brand <jc@opkode.com>
parents: 2956
diff changeset
57 log("debug", "The nonce was verified");
2956
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
58 return true;
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
59 end
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
60 end
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
61 end
3472
ac1f63cdb6d6 mod_auth_token: Check realm against module.host
JC Brand <jc@opkode.com>
parents: 2956
diff changeset
62 log("debug", "Verification failed");
2956
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
63 return false;
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
64 end
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
65
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
66 return {
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
67 OTP_DEVIATION = OTP_DIGITS,
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
68 OTP_DIGITS = OTP_DIGITS,
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
69 OTP_INTERVAL = OTP_INTERVAL,
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
70 DIGEST_TYPE = DIGEST_TYPE,
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
71 verify_token = verify_token;
d0ca211e1b0e New HMAC token authentication module for Prosody.
JC Brand <jc@opkode.com>
parents:
diff changeset
72 }