Annotate

mod_sasl2_fast/mod_sasl2_fast.lua @ 5369:1a58a11407ac

mod_client_management: Fix error when last password change is unknown (or never) Fixes attempt to compare nil with number here, due to last_password_change being nil
author Kim Alvefur <zash@zash.se>
date Tue, 25 Apr 2023 22:06:08 +0200
parent 5303:b10a7082b3c3
child 5906:563c2c70cb9f
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
5095
745c7f4cca40 mod_sasl2_fast: Add explicit dependency on mod_sasl2
Kim Alvefur <zash@zash.se>
parents: 5084
diff changeset
11 module:depends("sasl2");
745c7f4cca40 mod_sasl2_fast: Add explicit dependency on mod_sasl2
Kim Alvefur <zash@zash.se>
parents: 5084
diff changeset
12
5078
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5077
diff changeset
13 -- 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
14 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
15 -- Tokens are automatically rotated daily
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5077
diff changeset
16 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
17
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
18 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
19 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
20
5066
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
21 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
22
5076
eb46abc65dfd mod_sasl2_fast: Improved logging
Matthew Wild <mwild1@gmail.com>
parents: 5075
diff changeset
23 local log = module._log;
eb46abc65dfd mod_sasl2_fast: Improved logging
Matthew Wild <mwild1@gmail.com>
parents: 5075
diff changeset
24
5066
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
25 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
26 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
27 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
28 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
29 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
30 mechanism = mechanism;
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
31 secret = new_token;
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
32 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
33 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
34 };
5cc6f3749376 mod_sasl2_fast: Fix make_token() to return appropriate result
Matthew Wild <mwild1@gmail.com>
parents: 5069
diff changeset
35 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
36 return nil;
5cc6f3749376 mod_sasl2_fast: Fix make_token() to return appropriate result
Matthew Wild <mwild1@gmail.com>
parents: 5069
diff changeset
37 end
5cc6f3749376 mod_sasl2_fast: Fix make_token() to return appropriate result
Matthew Wild <mwild1@gmail.com>
parents: 5069
diff changeset
38 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
39 end
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
40
5071
bc983da908e6 mod_sasl2_fast: Take username from SASL exchange rather than stream@from
Matthew Wild <mwild1@gmail.com>
parents: 5070
diff changeset
41 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
42 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
43 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
44 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
45 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
46 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
47 local token;
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
48 repeat
5076
eb46abc65dfd mod_sasl2_fast: Improved logging
Matthew Wild <mwild1@gmail.com>
parents: 5075
diff changeset
49 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
50 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
51 if token and token.mechanism == mechanism then
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
52 local expected_hash = hmac_f(token.secret, "Initiator"..cb_data);
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
53 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
54 local current_time = now();
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5077
diff changeset
55 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
56 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
57 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
58 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
59 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
60 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
61 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
62 );
0566a71a7076 mod_sasl2_fast: Invalidate tokens issued prior to last password change
Matthew Wild <mwild1@gmail.com>
parents: 5137
diff changeset
63 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
64 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
65 end
5078
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5077
diff changeset
66 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
67 -- 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
68 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
69 [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
70 [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
71 });
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
72 end
5078
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5077
diff changeset
73 local rotation_needed;
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5077
diff changeset
74 if invalidate then
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5077
diff changeset
75 token_store:set(username, key, nil);
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5077
diff changeset
76 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
77 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
78 rotation_needed = true;
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5077
diff changeset
79 end
5082
ddb1940b08e0 mod_sasl2_fast: Clean up backend return values (fixes constant rotation)
Matthew Wild <mwild1@gmail.com>
parents: 5078
diff changeset
80 return true, username, hmac_f(token.secret, "Responder"..cb_data), rotation_needed;
5066
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
81 end
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
82 end
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
83 if not tried_current_token then
5076
eb46abc65dfd mod_sasl2_fast: Improved logging
Matthew Wild <mwild1@gmail.com>
parents: 5075
diff changeset
84 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
85 -- 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
86 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
87 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
88 else
5076
eb46abc65dfd mod_sasl2_fast: Improved logging
Matthew Wild <mwild1@gmail.com>
parents: 5075
diff changeset
89 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
90 return nil;
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
91 end
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
92 until false;
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
93 end
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
94 end
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
95
5071
bc983da908e6 mod_sasl2_fast: Take username from SASL exchange rather than stream@from
Matthew Wild <mwild1@gmail.com>
parents: 5070
diff changeset
96 function get_sasl_handler()
5062
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
97 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
98 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
99 };
5078
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5077
diff changeset
100 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
101 handler.fast = true;
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5077
diff changeset
102 return handler;
5062
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
103 end
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
104
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
105 -- Advertise FAST to connecting clients
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
106 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
107 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
108 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
109 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
110 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
111 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
112 end
20e635eb4cdc mod_sasl2_fast: More robust handling of stream@from and user-agent@id
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
113 local sasl_handler = get_sasl_handler(username);
5062
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
114 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
115 sasl_handler.fast_auth = true; -- For informational purposes
5137
471cbb583a1d mod_sasl2_fast: Add some comments
Matthew Wild <mwild1@gmail.com>
parents: 5095
diff changeset
116 -- Copy channel binding info from primary SASL handler
5083
4837232474ca mod_sasl2_fast: Fixes to make channel binding work again
Matthew Wild <mwild1@gmail.com>
parents: 5082
diff changeset
117 sasl_handler.profile.cb = session.sasl_handler.profile.cb;
4837232474ca mod_sasl2_fast: Fixes to make channel binding work again
Matthew Wild <mwild1@gmail.com>
parents: 5082
diff changeset
118 sasl_handler.userdata = session.sasl_handler.userdata;
5137
471cbb583a1d mod_sasl2_fast: Add some comments
Matthew Wild <mwild1@gmail.com>
parents: 5095
diff changeset
119 -- 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
120 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
121 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
122 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
123 fast:text_tag("mechanism", mech);
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
124 end
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
125 event.features:add_child(fast);
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
126 end);
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
127
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
128 -- 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
129 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
130 -- 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
131 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
132 if fast_auth then
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
133 -- 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
134 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
135 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
136 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
137 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
138 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
139 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
140 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
141 local invalidate = fast_auth.attr.invalidate;
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5077
diff changeset
142 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
143 -- 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
144 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
145 else
5076
eb46abc65dfd mod_sasl2_fast: Improved logging
Matthew Wild <mwild1@gmail.com>
parents: 5075
diff changeset
146 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
147 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
148 :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
149 :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
150 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
151 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
152 end
5062
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
153 end
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
154 session.fast_sasl_handler = nil;
5072
d41677929f68 mod_sasl2_fast: Fixes for <authenticate> processing
Matthew Wild <mwild1@gmail.com>
parents: 5071
diff changeset
155 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
156 if fast_token_request then
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
157 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
158 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
159 session.fast_token_request = {
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
160 mechanism = mech;
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
161 };
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
162 end
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
163 end, 100);
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
164
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
165 -- 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
166 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
167 local session = event.session;
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
168
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
169 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
170 local client_id = session.client_id;
5078
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5077
diff changeset
171 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
172 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
173 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
174 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
175 return;
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
176 end
5078
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5077
diff changeset
177 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
178 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
179 if token_info then
5078
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5077
diff changeset
180 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
181 event.success:tag("token", {
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
182 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
183 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
184 token = token_info.secret;
5062
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
185 }):up();
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
186 end
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
187 end
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
188 end, 75);
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
189
5066
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
190 -- HT-* mechanisms
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
191
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
192 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
193 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
194 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
195 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
196 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
197 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
198 end
bc983da908e6 mod_sasl2_fast: Take username from SASL exchange rather than stream@from
Matthew Wild <mwild1@gmail.com>
parents: 5070
diff changeset
199 local cb_data = cb_name and sasl_handler.profile.cb[cb_name](sasl_handler) or "";
5082
ddb1940b08e0 mod_sasl2_fast: Clean up backend return values (fixes constant rotation)
Matthew Wild <mwild1@gmail.com>
parents: 5078
diff changeset
200 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
201 mechanism_name,
5082
ddb1940b08e0 mod_sasl2_fast: Clean up backend return values (fixes constant rotation)
Matthew Wild <mwild1@gmail.com>
parents: 5078
diff changeset
202 authc_username,
5078
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5077
diff changeset
203 sasl_handler.client_id,
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5077
diff changeset
204 token_hash,
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5077
diff changeset
205 cb_data,
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5077
diff changeset
206 sasl_handler.invalidate
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5077
diff changeset
207 );
5066
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
208 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
209 -- 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
210 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
211 end
5082
ddb1940b08e0 mod_sasl2_fast: Clean up backend return values (fixes constant rotation)
Matthew Wild <mwild1@gmail.com>
parents: 5078
diff changeset
212 sasl_handler.username = authz_username;
5078
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5077
diff changeset
213 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
214 return "success", response;
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
215 end
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
216 end
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
217
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
218 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
219 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
220 name,
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
221 backend_profile_name,
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
222 cb_name
5075
ba2f1292d5fe mod_sasl2_fast: Register HT-* mechanisms with the required channel binding
Matthew Wild <mwild1@gmail.com>
parents: 5074
diff changeset
223 ),
5083
4837232474ca mod_sasl2_fast: Fixes to make channel binding work again
Matthew Wild <mwild1@gmail.com>
parents: 5082
diff changeset
224 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
225 end
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
226
5069
e8342ae5ae12 mod_sasl2_fast: Improve backend profile name and correctly use it everywhere
Matthew Wild <mwild1@gmail.com>
parents: 5068
diff changeset
227 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
228 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
229 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
230 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
231
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
232 -- 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
233
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
234 --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
235 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
236 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
237 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
238 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
239 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
240 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
241 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
242 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
243 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
244 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
245 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
246 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
247 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
248
b10a7082b3c3 mod_sasl2_fast: Add API method to revoke FAST tokens for a given client
Matthew Wild <mwild1@gmail.com>
parents: 5287
diff changeset
249 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
250 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
251 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
252 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
253 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
254 end