Annotate

mod_sasl2_fast/mod_sasl2_fast.lua @ 6195:886c985ece61

mod_lastlog2: Skip initializing internal API (and storage) in prosodyctl Initializing storage in the global context under prosodyctl causes the module.command to fail to execute because the storage module has already been loaded. Introduced in 7b722955c59b
author Kim Alvefur <zash@zash.se>
date Sat, 08 Feb 2025 14:12:18 +0100
parent 6150:f77f5e408d6a
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
5282
0566a71a7076 mod_sasl2_fast: Invalidate tokens issued prior to last password change
Matthew Wild <mwild1@gmail.com>
parents: 5137
diff changeset
1 local usermanager = require "core.usermanager";
0566a71a7076 mod_sasl2_fast: Invalidate tokens issued prior to last password change
Matthew Wild <mwild1@gmail.com>
parents: 5137
diff changeset
2
5062
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
3 local sasl = require "util.sasl";
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
4 local dt = require "util.datetime";
5066
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
5 local id = require "util.id";
5068
20e635eb4cdc mod_sasl2_fast: More robust handling of stream@from and user-agent@id
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
6 local jid = require "util.jid";
5062
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
7 local st = require "util.stanza";
5066
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
8 local now = require "util.time".now;
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
9 local hash = require "util.hashes";
5062
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
10
6060
c7c17fac41b3 mod_sasl2_fast: Only copy SASL handler internals from util.sasl instance
Kim Alvefur <zash@zash.se>
parents: 5951
diff changeset
11 local sasl_mt = getmetatable(sasl.new("", { mechanisms = {} }));
c7c17fac41b3 mod_sasl2_fast: Only copy SASL handler internals from util.sasl instance
Kim Alvefur <zash@zash.se>
parents: 5951
diff changeset
12 local function is_util_sasl(sasl_handler)
c7c17fac41b3 mod_sasl2_fast: Only copy SASL handler internals from util.sasl instance
Kim Alvefur <zash@zash.se>
parents: 5951
diff changeset
13 return getmetatable(sasl_handler) == sasl_mt;
c7c17fac41b3 mod_sasl2_fast: Only copy SASL handler internals from util.sasl instance
Kim Alvefur <zash@zash.se>
parents: 5951
diff changeset
14 end
c7c17fac41b3 mod_sasl2_fast: Only copy SASL handler internals from util.sasl instance
Kim Alvefur <zash@zash.se>
parents: 5951
diff changeset
15
5095
745c7f4cca40 mod_sasl2_fast: Add explicit dependency on mod_sasl2
Kim Alvefur <zash@zash.se>
parents: 5084
diff changeset
16 module:depends("sasl2");
745c7f4cca40 mod_sasl2_fast: Add explicit dependency on mod_sasl2
Kim Alvefur <zash@zash.se>
parents: 5084
diff changeset
17
5078
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5077
diff changeset
18 -- Tokens expire after 21 days by default
5062
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
19 local fast_token_ttl = module:get_option_number("sasl2_fast_token_ttl", 86400*21);
5078
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5077
diff changeset
20 -- Tokens are automatically rotated daily
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5077
diff changeset
21 local fast_token_min_ttl = module:get_option_number("sasl2_fast_token_min_ttl", 86400);
5062
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
22
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
23 local xmlns_fast = "urn:xmpp:fast:0";
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
24 local xmlns_sasl2 = "urn:xmpp:sasl:2";
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
25
5066
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
26 local token_store = module:open_store("fast_tokens", "map");
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
27
5076
eb46abc65dfd mod_sasl2_fast: Improved logging
Matthew Wild <mwild1@gmail.com>
parents: 5075
diff changeset
28 local log = module._log;
eb46abc65dfd mod_sasl2_fast: Improved logging
Matthew Wild <mwild1@gmail.com>
parents: 5075
diff changeset
29
5066
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
30 local function make_token(username, client_id, mechanism)
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
31 local new_token = "secret-token:fast-"..id.long();
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
32 local key = hash.sha256(client_id, true).."-new";
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
33 local issued_at = now();
5070
5cc6f3749376 mod_sasl2_fast: Fix make_token() to return appropriate result
Matthew Wild <mwild1@gmail.com>
parents: 5069
diff changeset
34 local token_info = {
5066
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
35 mechanism = mechanism;
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
36 secret = new_token;
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
37 issued_at = issued_at;
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
38 expires_at = issued_at + fast_token_ttl;
5070
5cc6f3749376 mod_sasl2_fast: Fix make_token() to return appropriate result
Matthew Wild <mwild1@gmail.com>
parents: 5069
diff changeset
39 };
5cc6f3749376 mod_sasl2_fast: Fix make_token() to return appropriate result
Matthew Wild <mwild1@gmail.com>
parents: 5069
diff changeset
40 if not token_store:set(username, key, token_info) then
5cc6f3749376 mod_sasl2_fast: Fix make_token() to return appropriate result
Matthew Wild <mwild1@gmail.com>
parents: 5069
diff changeset
41 return nil;
5cc6f3749376 mod_sasl2_fast: Fix make_token() to return appropriate result
Matthew Wild <mwild1@gmail.com>
parents: 5069
diff changeset
42 end
5cc6f3749376 mod_sasl2_fast: Fix make_token() to return appropriate result
Matthew Wild <mwild1@gmail.com>
parents: 5069
diff changeset
43 return token_info;
5066
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
44 end
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
45
5071
bc983da908e6 mod_sasl2_fast: Take username from SASL exchange rather than stream@from
Matthew Wild <mwild1@gmail.com>
parents: 5070
diff changeset
46 local function new_token_tester(hmac_f)
5078
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5077
diff changeset
47 return function (mechanism, username, client_id, token_hash, cb_data, invalidate)
5282
0566a71a7076 mod_sasl2_fast: Invalidate tokens issued prior to last password change
Matthew Wild <mwild1@gmail.com>
parents: 5137
diff changeset
48 local account_info = usermanager.get_account_info(username, module.host);
0566a71a7076 mod_sasl2_fast: Invalidate tokens issued prior to last password change
Matthew Wild <mwild1@gmail.com>
parents: 5137
diff changeset
49 local last_password_change = account_info and account_info.password_updated;
5066
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
50 local tried_current_token = false;
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
51 local key = hash.sha256(client_id, true).."-new";
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
52 local token;
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
53 repeat
5076
eb46abc65dfd mod_sasl2_fast: Improved logging
Matthew Wild <mwild1@gmail.com>
parents: 5075
diff changeset
54 log("debug", "Looking for %s token %s/%s", mechanism, username, key);
5066
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
55 token = token_store:get(username, key);
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
56 if token and token.mechanism == mechanism then
5951
87441b567277 mod_sasl2_fast: Fix traceback when no cb_data is available (thanks riau)
Matthew Wild <mwild1@gmail.com>
parents: 5949
diff changeset
57 local expected_hash = hmac_f(token.secret, "Initiator"..(cb_data or ""));
5066
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
58 if hash.equals(expected_hash, token_hash) then
5078
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5077
diff changeset
59 local current_time = now();
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5077
diff changeset
60 if token.expires_at < current_time then
5084
dda2af7ed02f mod_sasl2_fast: Add more debug logging
Matthew Wild <mwild1@gmail.com>
parents: 5083
diff changeset
61 log("debug", "Token found, but it has expired (%ds ago). Cleaning up...", current_time - token.expires_at);
5066
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
62 token_store:set(username, key, nil);
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
63 return nil, "credentials-expired";
5282
0566a71a7076 mod_sasl2_fast: Invalidate tokens issued prior to last password change
Matthew Wild <mwild1@gmail.com>
parents: 5137
diff changeset
64 elseif last_password_change and token.issued_at < last_password_change then
0566a71a7076 mod_sasl2_fast: Invalidate tokens issued prior to last password change
Matthew Wild <mwild1@gmail.com>
parents: 5137
diff changeset
65 log("debug", "Token found, but issued prior to password change (%ds ago). Cleaning up...",
0566a71a7076 mod_sasl2_fast: Invalidate tokens issued prior to last password change
Matthew Wild <mwild1@gmail.com>
parents: 5137
diff changeset
66 current_time - last_password_change
0566a71a7076 mod_sasl2_fast: Invalidate tokens issued prior to last password change
Matthew Wild <mwild1@gmail.com>
parents: 5137
diff changeset
67 );
0566a71a7076 mod_sasl2_fast: Invalidate tokens issued prior to last password change
Matthew Wild <mwild1@gmail.com>
parents: 5137
diff changeset
68 token_store:set(username, key, nil);
0566a71a7076 mod_sasl2_fast: Invalidate tokens issued prior to last password change
Matthew Wild <mwild1@gmail.com>
parents: 5137
diff changeset
69 return nil, "credentials-expired";
5066
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
70 end
5078
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5077
diff changeset
71 if not tried_current_token and not invalidate then
5066
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
72 -- The new token is becoming the current token
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
73 token_store:set_keys(username, {
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
74 [key] = token_store.remove;
5285
8e1f1eb00b58 mod_sasl2_fast: Fix harmless off-by-one error (invalidates existing tokens!)
Matthew Wild <mwild1@gmail.com>
parents: 5282
diff changeset
75 [key:sub(1, -5).."-cur"] = token;
5066
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
76 });
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
77 end
5078
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5077
diff changeset
78 local rotation_needed;
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5077
diff changeset
79 if invalidate then
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5077
diff changeset
80 token_store:set(username, key, nil);
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5077
diff changeset
81 elseif current_time - token.issued_at > fast_token_min_ttl then
5084
dda2af7ed02f mod_sasl2_fast: Add more debug logging
Matthew Wild <mwild1@gmail.com>
parents: 5083
diff changeset
82 log("debug", "FAST token due for rotation (age: %d)", current_time - token.issued_at);
5078
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5077
diff changeset
83 rotation_needed = true;
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5077
diff changeset
84 end
5951
87441b567277 mod_sasl2_fast: Fix traceback when no cb_data is available (thanks riau)
Matthew Wild <mwild1@gmail.com>
parents: 5949
diff changeset
85 return true, username, hmac_f(token.secret, "Responder"..(cb_data or "")), rotation_needed;
5066
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
86 end
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
87 end
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
88 if not tried_current_token then
5076
eb46abc65dfd mod_sasl2_fast: Improved logging
Matthew Wild <mwild1@gmail.com>
parents: 5075
diff changeset
89 log("debug", "Trying next token...");
5066
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
90 -- Try again with the current token instead
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
91 tried_current_token = true;
5285
8e1f1eb00b58 mod_sasl2_fast: Fix harmless off-by-one error (invalidates existing tokens!)
Matthew Wild <mwild1@gmail.com>
parents: 5282
diff changeset
92 key = key:sub(1, -5).."-cur";
5066
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
93 else
5076
eb46abc65dfd mod_sasl2_fast: Improved logging
Matthew Wild <mwild1@gmail.com>
parents: 5075
diff changeset
94 log("debug", "No matching %s token found for %s/%s", mechanism, username, key);
5066
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
95 return nil;
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
96 end
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
97 until false;
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
98 end
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
99 end
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
100
6150
f77f5e408d6a mod_sasl2_fast: Restore non-FAST SASL handler upon reset
Matthew Wild <mwild1@gmail.com>
parents: 6060
diff changeset
101 -- If FAST fails, we want to restore back to a non-FAST handler
f77f5e408d6a mod_sasl2_fast: Restore non-FAST SASL handler upon reset
Matthew Wild <mwild1@gmail.com>
parents: 6060
diff changeset
102 local function _clean_clone_shim(self)
f77f5e408d6a mod_sasl2_fast: Restore non-FAST SASL handler upon reset
Matthew Wild <mwild1@gmail.com>
parents: 6060
diff changeset
103 return self.nonfast_sasl_handler:clean_clone();
f77f5e408d6a mod_sasl2_fast: Restore non-FAST SASL handler upon reset
Matthew Wild <mwild1@gmail.com>
parents: 6060
diff changeset
104 end
f77f5e408d6a mod_sasl2_fast: Restore non-FAST SASL handler upon reset
Matthew Wild <mwild1@gmail.com>
parents: 6060
diff changeset
105
f77f5e408d6a mod_sasl2_fast: Restore non-FAST SASL handler upon reset
Matthew Wild <mwild1@gmail.com>
parents: 6060
diff changeset
106 function get_sasl_handler(username, nonfast_sasl_handler) -- luacheck: ignore 212/username
5062
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
107 local token_auth_profile = {
5071
bc983da908e6 mod_sasl2_fast: Take username from SASL exchange rather than stream@from
Matthew Wild <mwild1@gmail.com>
parents: 5070
diff changeset
108 ht_sha_256 = new_token_tester(hash.hmac_sha256);
5062
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
109 };
5078
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5077
diff changeset
110 local handler = sasl.new(module.host, token_auth_profile);
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5077
diff changeset
111 handler.fast = true;
6150
f77f5e408d6a mod_sasl2_fast: Restore non-FAST SASL handler upon reset
Matthew Wild <mwild1@gmail.com>
parents: 6060
diff changeset
112 handler.nonfast_sasl_handler = nonfast_sasl_handler;
f77f5e408d6a mod_sasl2_fast: Restore non-FAST SASL handler upon reset
Matthew Wild <mwild1@gmail.com>
parents: 6060
diff changeset
113 handler.clean_clone = _clean_clone_shim;
5078
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5077
diff changeset
114 return handler;
5062
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
115 end
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
116
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
117 -- Advertise FAST to connecting clients
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
118 module:hook("advertise-sasl-features", function (event)
5066
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
119 local session = event.origin;
5068
20e635eb4cdc mod_sasl2_fast: More robust handling of stream@from and user-agent@id
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
120 local username = session.username;
20e635eb4cdc mod_sasl2_fast: More robust handling of stream@from and user-agent@id
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
121 if not username then
20e635eb4cdc mod_sasl2_fast: More robust handling of stream@from and user-agent@id
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
122 username = jid.node(event.stream.from);
20e635eb4cdc mod_sasl2_fast: More robust handling of stream@from and user-agent@id
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
123 if not username then return; end
20e635eb4cdc mod_sasl2_fast: More robust handling of stream@from and user-agent@id
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
124 end
6150
f77f5e408d6a mod_sasl2_fast: Restore non-FAST SASL handler upon reset
Matthew Wild <mwild1@gmail.com>
parents: 6060
diff changeset
125 local sasl_handler = get_sasl_handler(username, session.sasl_handler);
5062
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
126 if not sasl_handler then return; end
5286
a91adc164566 mod_sasl2_fast: Add flag to FAST sasl_handler for easier identification
Matthew Wild <mwild1@gmail.com>
parents: 5285
diff changeset
127 sasl_handler.fast_auth = true; -- For informational purposes
6060
c7c17fac41b3 mod_sasl2_fast: Only copy SASL handler internals from util.sasl instance
Kim Alvefur <zash@zash.se>
parents: 5951
diff changeset
128 -- Copy channel binding info from primary SASL handler if it's compatible
c7c17fac41b3 mod_sasl2_fast: Only copy SASL handler internals from util.sasl instance
Kim Alvefur <zash@zash.se>
parents: 5951
diff changeset
129 if is_util_sasl(session.sasl_handler) then
c7c17fac41b3 mod_sasl2_fast: Only copy SASL handler internals from util.sasl instance
Kim Alvefur <zash@zash.se>
parents: 5951
diff changeset
130 sasl_handler.profile.cb = session.sasl_handler.profile.cb;
c7c17fac41b3 mod_sasl2_fast: Only copy SASL handler internals from util.sasl instance
Kim Alvefur <zash@zash.se>
parents: 5951
diff changeset
131 sasl_handler.userdata = session.sasl_handler.userdata;
c7c17fac41b3 mod_sasl2_fast: Only copy SASL handler internals from util.sasl instance
Kim Alvefur <zash@zash.se>
parents: 5951
diff changeset
132 end
5137
471cbb583a1d mod_sasl2_fast: Add some comments
Matthew Wild <mwild1@gmail.com>
parents: 5095
diff changeset
133 -- Store this handler, in case we later want to use it for authenticating
5066
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
134 session.fast_sasl_handler = sasl_handler;
5062
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
135 local fast = st.stanza("fast", { xmlns = xmlns_fast });
5066
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
136 for mech in pairs(sasl_handler:mechanisms()) do
5062
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
137 fast:text_tag("mechanism", mech);
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
138 end
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
139 event.features:add_child(fast);
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
140 end);
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
141
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
142 -- Process any FAST elements in <authenticate/>
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
143 module:hook_tag(xmlns_sasl2, "authenticate", function (session, auth)
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
144 -- Cache action for future processing (after auth success)
5072
d41677929f68 mod_sasl2_fast: Fixes for <authenticate> processing
Matthew Wild <mwild1@gmail.com>
parents: 5071
diff changeset
145 local fast_auth = auth:get_child("fast", xmlns_fast);
5062
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
146 if fast_auth then
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
147 -- Client says it is using FAST auth, so set our SASL handler
5066
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
148 local fast_sasl_handler = session.fast_sasl_handler;
5072
d41677929f68 mod_sasl2_fast: Fixes for <authenticate> processing
Matthew Wild <mwild1@gmail.com>
parents: 5071
diff changeset
149 local client_id = auth:get_child_attr("user-agent", nil, "id");
d41677929f68 mod_sasl2_fast: Fixes for <authenticate> processing
Matthew Wild <mwild1@gmail.com>
parents: 5071
diff changeset
150 if fast_sasl_handler and client_id then
5068
20e635eb4cdc mod_sasl2_fast: More robust handling of stream@from and user-agent@id
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
151 session.log("debug", "Client is authenticating using FAST");
5078
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5077
diff changeset
152 fast_sasl_handler.client_id = client_id;
5073
f158f18704c0 mod_sasl2_fast: Copy channel binding data state from original SASL handler
Matthew Wild <mwild1@gmail.com>
parents: 5072
diff changeset
153 fast_sasl_handler.profile.cb = session.sasl_handler.profile.cb;
f158f18704c0 mod_sasl2_fast: Copy channel binding data state from original SASL handler
Matthew Wild <mwild1@gmail.com>
parents: 5072
diff changeset
154 fast_sasl_handler.userdata = session.sasl_handler.userdata;
5078
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5077
diff changeset
155 local invalidate = fast_auth.attr.invalidate;
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5077
diff changeset
156 fast_sasl_handler.invalidate = invalidate == "1" or invalidate == "true";
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5077
diff changeset
157 -- Set our SASL handler as the session's SASL handler
5068
20e635eb4cdc mod_sasl2_fast: More robust handling of stream@from and user-agent@id
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
158 session.sasl_handler = fast_sasl_handler;
20e635eb4cdc mod_sasl2_fast: More robust handling of stream@from and user-agent@id
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
159 else
5076
eb46abc65dfd mod_sasl2_fast: Improved logging
Matthew Wild <mwild1@gmail.com>
parents: 5075
diff changeset
160 session.log("warn", "Client asked to auth via FAST, but SASL handler or client id missing");
5068
20e635eb4cdc mod_sasl2_fast: More robust handling of stream@from and user-agent@id
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
161 local failure = st.stanza("failure", { xmlns = xmlns_sasl2 })
20e635eb4cdc mod_sasl2_fast: More robust handling of stream@from and user-agent@id
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
162 :tag("malformed-request"):up()
20e635eb4cdc mod_sasl2_fast: More robust handling of stream@from and user-agent@id
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
163 :text_tag("text", "FAST is not available on this stream");
20e635eb4cdc mod_sasl2_fast: More robust handling of stream@from and user-agent@id
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
164 session.send(failure);
20e635eb4cdc mod_sasl2_fast: More robust handling of stream@from and user-agent@id
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
165 return true;
20e635eb4cdc mod_sasl2_fast: More robust handling of stream@from and user-agent@id
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
166 end
5062
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
167 end
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
168 session.fast_sasl_handler = nil;
5072
d41677929f68 mod_sasl2_fast: Fixes for <authenticate> processing
Matthew Wild <mwild1@gmail.com>
parents: 5071
diff changeset
169 local fast_token_request = auth:get_child("request-token", xmlns_fast);
5062
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
170 if fast_token_request then
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
171 local mech = fast_token_request.attr.mechanism;
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
172 session.log("debug", "Client requested new FAST token for %s", mech);
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
173 session.fast_token_request = {
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
174 mechanism = mech;
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
175 };
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
176 end
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
177 end, 100);
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
178
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
179 -- Process post-success (new token generation, etc.)
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
180 module:hook("sasl2/c2s/success", function (event)
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
181 local session = event.session;
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
182
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
183 local token_request = session.fast_token_request;
5066
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
184 local client_id = session.client_id;
5078
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5077
diff changeset
185 local sasl_handler = session.sasl_handler;
5083
4837232474ca mod_sasl2_fast: Fixes to make channel binding work again
Matthew Wild <mwild1@gmail.com>
parents: 5082
diff changeset
186 if token_request or (sasl_handler.fast and sasl_handler.rotation_needed) then
5068
20e635eb4cdc mod_sasl2_fast: More robust handling of stream@from and user-agent@id
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
187 if not client_id then
5066
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
188 session.log("warn", "FAST token requested, but missing client id");
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
189 return;
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
190 end
5078
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5077
diff changeset
191 local mechanism = token_request and token_request.mechanism or session.sasl_handler.selected;
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5077
diff changeset
192 local token_info = make_token(session.username, client_id, mechanism)
5066
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
193 if token_info then
5078
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5077
diff changeset
194 session.log("debug", "Provided new FAST token to client");
5062
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
195 event.success:tag("token", {
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
196 xmlns = xmlns_fast;
5066
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
197 expiry = dt.datetime(token_info.expires_at);
5074
1726050e9a4b mod_sasl2_fast: Fix field name for returned secret
Matthew Wild <mwild1@gmail.com>
parents: 5073
diff changeset
198 token = token_info.secret;
5062
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
199 }):up();
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
200 end
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
201 end
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
202 end, 75);
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
203
5066
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
204 -- HT-* mechanisms
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
205
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
206 local function new_ht_mechanism(mechanism_name, backend_profile_name, cb_name)
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
207 return function (sasl_handler, message)
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
208 local backend = sasl_handler.profile[backend_profile_name];
5082
ddb1940b08e0 mod_sasl2_fast: Clean up backend return values (fixes constant rotation)
Matthew Wild <mwild1@gmail.com>
parents: 5078
diff changeset
209 local authc_username, token_hash = message:match("^([^%z]+)%z(.+)$");
ddb1940b08e0 mod_sasl2_fast: Clean up backend return values (fixes constant rotation)
Matthew Wild <mwild1@gmail.com>
parents: 5078
diff changeset
210 if not authc_username then
5071
bc983da908e6 mod_sasl2_fast: Take username from SASL exchange rather than stream@from
Matthew Wild <mwild1@gmail.com>
parents: 5070
diff changeset
211 return "failure", "malformed-request";
bc983da908e6 mod_sasl2_fast: Take username from SASL exchange rather than stream@from
Matthew Wild <mwild1@gmail.com>
parents: 5070
diff changeset
212 end
5949
e67fc7b66c13 mod_sasl2_fast: Fix malformed-request when using HT-*-NONE (thanks lnj!)
Matthew Wild <mwild1@gmail.com>
parents: 5906
diff changeset
213 local cb_data;
e67fc7b66c13 mod_sasl2_fast: Fix malformed-request when using HT-*-NONE (thanks lnj!)
Matthew Wild <mwild1@gmail.com>
parents: 5906
diff changeset
214 if cb_name then
e67fc7b66c13 mod_sasl2_fast: Fix malformed-request when using HT-*-NONE (thanks lnj!)
Matthew Wild <mwild1@gmail.com>
parents: 5906
diff changeset
215 if not sasl_handler.profile.cb then
e67fc7b66c13 mod_sasl2_fast: Fix malformed-request when using HT-*-NONE (thanks lnj!)
Matthew Wild <mwild1@gmail.com>
parents: 5906
diff changeset
216 module:log("warn", "Attempt to use channel binding %s with SASL profile that does not support any channel binding (FAST: %s)", cb_name, sasl_handler.fast);
e67fc7b66c13 mod_sasl2_fast: Fix malformed-request when using HT-*-NONE (thanks lnj!)
Matthew Wild <mwild1@gmail.com>
parents: 5906
diff changeset
217 return "failure", "malformed-request";
e67fc7b66c13 mod_sasl2_fast: Fix malformed-request when using HT-*-NONE (thanks lnj!)
Matthew Wild <mwild1@gmail.com>
parents: 5906
diff changeset
218 elseif not sasl_handler.profile.cb[cb_name] then
e67fc7b66c13 mod_sasl2_fast: Fix malformed-request when using HT-*-NONE (thanks lnj!)
Matthew Wild <mwild1@gmail.com>
parents: 5906
diff changeset
219 module:log("warn", "SASL profile does not support %s channel binding (FAST: %s)", cb_name, sasl_handler.fast);
e67fc7b66c13 mod_sasl2_fast: Fix malformed-request when using HT-*-NONE (thanks lnj!)
Matthew Wild <mwild1@gmail.com>
parents: 5906
diff changeset
220 return "failure", "malformed-request";
e67fc7b66c13 mod_sasl2_fast: Fix malformed-request when using HT-*-NONE (thanks lnj!)
Matthew Wild <mwild1@gmail.com>
parents: 5906
diff changeset
221 end
e67fc7b66c13 mod_sasl2_fast: Fix malformed-request when using HT-*-NONE (thanks lnj!)
Matthew Wild <mwild1@gmail.com>
parents: 5906
diff changeset
222 cb_data = sasl_handler.profile.cb[cb_name](sasl_handler) or "";
5906
563c2c70cb9f mod_sasl2_fast: Improve handling when SASL profile unexpectedly lacks CB
Matthew Wild <mwild1@gmail.com>
parents: 5303
diff changeset
223 end
5082
ddb1940b08e0 mod_sasl2_fast: Clean up backend return values (fixes constant rotation)
Matthew Wild <mwild1@gmail.com>
parents: 5078
diff changeset
224 local ok, authz_username, response, rotation_needed = backend(
5078
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5077
diff changeset
225 mechanism_name,
5082
ddb1940b08e0 mod_sasl2_fast: Clean up backend return values (fixes constant rotation)
Matthew Wild <mwild1@gmail.com>
parents: 5078
diff changeset
226 authc_username,
5078
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5077
diff changeset
227 sasl_handler.client_id,
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5077
diff changeset
228 token_hash,
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5077
diff changeset
229 cb_data,
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5077
diff changeset
230 sasl_handler.invalidate
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5077
diff changeset
231 );
5066
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
232 if not ok then
5082
ddb1940b08e0 mod_sasl2_fast: Clean up backend return values (fixes constant rotation)
Matthew Wild <mwild1@gmail.com>
parents: 5078
diff changeset
233 -- authz_username is error condition
ddb1940b08e0 mod_sasl2_fast: Clean up backend return values (fixes constant rotation)
Matthew Wild <mwild1@gmail.com>
parents: 5078
diff changeset
234 return "failure", authz_username or "not-authorized";
5066
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
235 end
5082
ddb1940b08e0 mod_sasl2_fast: Clean up backend return values (fixes constant rotation)
Matthew Wild <mwild1@gmail.com>
parents: 5078
diff changeset
236 sasl_handler.username = authz_username;
5078
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5077
diff changeset
237 sasl_handler.rotation_needed = rotation_needed;
5066
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
238 return "success", response;
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
239 end
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
240 end
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
241
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
242 local function register_ht_mechanism(name, backend_profile_name, cb_name)
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
243 return sasl.registerMechanism(name, { backend_profile_name }, new_ht_mechanism(
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
244 name,
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
245 backend_profile_name,
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
246 cb_name
5075
ba2f1292d5fe mod_sasl2_fast: Register HT-* mechanisms with the required channel binding
Matthew Wild <mwild1@gmail.com>
parents: 5074
diff changeset
247 ),
5083
4837232474ca mod_sasl2_fast: Fixes to make channel binding work again
Matthew Wild <mwild1@gmail.com>
parents: 5082
diff changeset
248 cb_name and { cb_name } or nil);
5066
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
249 end
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
250
5069
e8342ae5ae12 mod_sasl2_fast: Improve backend profile name and correctly use it everywhere
Matthew Wild <mwild1@gmail.com>
parents: 5068
diff changeset
251 register_ht_mechanism("HT-SHA-256-NONE", "ht_sha_256", nil);
e8342ae5ae12 mod_sasl2_fast: Improve backend profile name and correctly use it everywhere
Matthew Wild <mwild1@gmail.com>
parents: 5068
diff changeset
252 register_ht_mechanism("HT-SHA-256-UNIQ", "ht_sha_256", "tls-unique");
5083
4837232474ca mod_sasl2_fast: Fixes to make channel binding work again
Matthew Wild <mwild1@gmail.com>
parents: 5082
diff changeset
253 register_ht_mechanism("HT-SHA-256-ENDP", "ht_sha_256", "tls-server-end-point");
5069
e8342ae5ae12 mod_sasl2_fast: Improve backend profile name and correctly use it everywhere
Matthew Wild <mwild1@gmail.com>
parents: 5068
diff changeset
254 register_ht_mechanism("HT-SHA-256-EXPR", "ht_sha_256", "tls-exporter");
5287
4834eaf24fc1 mod_sasl2_fast: Add an API that allows modules to check if a client has FAST
Matthew Wild <mwild1@gmail.com>
parents: 5286
diff changeset
255
4834eaf24fc1 mod_sasl2_fast: Add an API that allows modules to check if a client has FAST
Matthew Wild <mwild1@gmail.com>
parents: 5286
diff changeset
256 -- Public API
4834eaf24fc1 mod_sasl2_fast: Add an API that allows modules to check if a client has FAST
Matthew Wild <mwild1@gmail.com>
parents: 5286
diff changeset
257
4834eaf24fc1 mod_sasl2_fast: Add an API that allows modules to check if a client has FAST
Matthew Wild <mwild1@gmail.com>
parents: 5286
diff changeset
258 --luacheck: ignore 131
4834eaf24fc1 mod_sasl2_fast: Add an API that allows modules to check if a client has FAST
Matthew Wild <mwild1@gmail.com>
parents: 5286
diff changeset
259 function is_client_fast(username, client_id, last_password_change)
4834eaf24fc1 mod_sasl2_fast: Add an API that allows modules to check if a client has FAST
Matthew Wild <mwild1@gmail.com>
parents: 5286
diff changeset
260 local client_id_hash = hash.sha256(client_id, true);
4834eaf24fc1 mod_sasl2_fast: Add an API that allows modules to check if a client has FAST
Matthew Wild <mwild1@gmail.com>
parents: 5286
diff changeset
261 local curr_time = now();
4834eaf24fc1 mod_sasl2_fast: Add an API that allows modules to check if a client has FAST
Matthew Wild <mwild1@gmail.com>
parents: 5286
diff changeset
262 local cur = token_store:get(username, client_id_hash.."-cur");
4834eaf24fc1 mod_sasl2_fast: Add an API that allows modules to check if a client has FAST
Matthew Wild <mwild1@gmail.com>
parents: 5286
diff changeset
263 if cur and cur.expires_at >= curr_time and (not last_password_change or last_password_change < cur.issued_at) then
4834eaf24fc1 mod_sasl2_fast: Add an API that allows modules to check if a client has FAST
Matthew Wild <mwild1@gmail.com>
parents: 5286
diff changeset
264 return true;
4834eaf24fc1 mod_sasl2_fast: Add an API that allows modules to check if a client has FAST
Matthew Wild <mwild1@gmail.com>
parents: 5286
diff changeset
265 end
4834eaf24fc1 mod_sasl2_fast: Add an API that allows modules to check if a client has FAST
Matthew Wild <mwild1@gmail.com>
parents: 5286
diff changeset
266 local new = token_store:get(username, client_id_hash.."-new");
4834eaf24fc1 mod_sasl2_fast: Add an API that allows modules to check if a client has FAST
Matthew Wild <mwild1@gmail.com>
parents: 5286
diff changeset
267 if new and new.expires_at >= curr_time and (not last_password_change or last_password_change < new.issued_at) then
4834eaf24fc1 mod_sasl2_fast: Add an API that allows modules to check if a client has FAST
Matthew Wild <mwild1@gmail.com>
parents: 5286
diff changeset
268 return true;
4834eaf24fc1 mod_sasl2_fast: Add an API that allows modules to check if a client has FAST
Matthew Wild <mwild1@gmail.com>
parents: 5286
diff changeset
269 end
4834eaf24fc1 mod_sasl2_fast: Add an API that allows modules to check if a client has FAST
Matthew Wild <mwild1@gmail.com>
parents: 5286
diff changeset
270 return false;
4834eaf24fc1 mod_sasl2_fast: Add an API that allows modules to check if a client has FAST
Matthew Wild <mwild1@gmail.com>
parents: 5286
diff changeset
271 end
5303
b10a7082b3c3 mod_sasl2_fast: Add API method to revoke FAST tokens for a given client
Matthew Wild <mwild1@gmail.com>
parents: 5287
diff changeset
272
b10a7082b3c3 mod_sasl2_fast: Add API method to revoke FAST tokens for a given client
Matthew Wild <mwild1@gmail.com>
parents: 5287
diff changeset
273 function revoke_fast_tokens(username, client_id)
b10a7082b3c3 mod_sasl2_fast: Add API method to revoke FAST tokens for a given client
Matthew Wild <mwild1@gmail.com>
parents: 5287
diff changeset
274 local client_id_hash = hash.sha256(client_id, true);
b10a7082b3c3 mod_sasl2_fast: Add API method to revoke FAST tokens for a given client
Matthew Wild <mwild1@gmail.com>
parents: 5287
diff changeset
275 local cur_ok = token_store:set(username, client_id_hash.."-cur", nil);
b10a7082b3c3 mod_sasl2_fast: Add API method to revoke FAST tokens for a given client
Matthew Wild <mwild1@gmail.com>
parents: 5287
diff changeset
276 local new_ok = token_store:set(username, client_id_hash.."-new", nil);
b10a7082b3c3 mod_sasl2_fast: Add API method to revoke FAST tokens for a given client
Matthew Wild <mwild1@gmail.com>
parents: 5287
diff changeset
277 return cur_ok and new_ok;
b10a7082b3c3 mod_sasl2_fast: Add API method to revoke FAST tokens for a given client
Matthew Wild <mwild1@gmail.com>
parents: 5287
diff changeset
278 end