annotate mod_sasl2_fast/mod_sasl2_fast.lua @ 5119:048e339706ba

mod_rest: Remove manual reference expansion in schema This hack was originally added to reduce the number of definitions of common attributes (type, to, from etc) and payloads (e.g. delay). This predated pointers and references, and until now was needed because parsing picked out the correct stanza kind from the schema, which broke internal references. Removing this hack paves the way for allowing the schema to be configured or customized more easily.
author Kim Alvefur <zash@zash.se>
date Tue, 20 Dec 2022 21:48:28 +0100
parents 745c7f4cca40
children 471cbb583a1d
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
5062
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
1 local sasl = require "util.sasl";
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
2 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
3 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
4 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
5 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
6 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
7 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
8
5095
745c7f4cca40 mod_sasl2_fast: Add explicit dependency on mod_sasl2
Kim Alvefur <zash@zash.se>
parents: 5084
diff changeset
9 module:depends("sasl2");
745c7f4cca40 mod_sasl2_fast: Add explicit dependency on mod_sasl2
Kim Alvefur <zash@zash.se>
parents: 5084
diff changeset
10
5078
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5077
diff changeset
11 -- 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
12 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
13 -- Tokens are automatically rotated daily
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5077
diff changeset
14 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
15
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
16 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
17 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
18
5066
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
19 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
20
5076
eb46abc65dfd mod_sasl2_fast: Improved logging
Matthew Wild <mwild1@gmail.com>
parents: 5075
diff changeset
21 local log = module._log;
eb46abc65dfd mod_sasl2_fast: Improved logging
Matthew Wild <mwild1@gmail.com>
parents: 5075
diff changeset
22
5066
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
23 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
24 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
25 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
26 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
27 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
28 mechanism = mechanism;
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
29 secret = new_token;
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
30 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
31 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
32 };
5cc6f3749376 mod_sasl2_fast: Fix make_token() to return appropriate result
Matthew Wild <mwild1@gmail.com>
parents: 5069
diff changeset
33 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
34 return nil;
5cc6f3749376 mod_sasl2_fast: Fix make_token() to return appropriate result
Matthew Wild <mwild1@gmail.com>
parents: 5069
diff changeset
35 end
5cc6f3749376 mod_sasl2_fast: Fix make_token() to return appropriate result
Matthew Wild <mwild1@gmail.com>
parents: 5069
diff changeset
36 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
37 end
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
38
5071
bc983da908e6 mod_sasl2_fast: Take username from SASL exchange rather than stream@from
Matthew Wild <mwild1@gmail.com>
parents: 5070
diff changeset
39 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
40 return function (mechanism, username, client_id, token_hash, cb_data, invalidate)
5066
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
41 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
42 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
43 local token;
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
44 repeat
5076
eb46abc65dfd mod_sasl2_fast: Improved logging
Matthew Wild <mwild1@gmail.com>
parents: 5075
diff changeset
45 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
46 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
47 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
48 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
49 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
50 local current_time = now();
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5077
diff changeset
51 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
52 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
53 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
54 return nil, "credentials-expired";
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
55 end
5078
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5077
diff changeset
56 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
57 -- 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
58 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
59 [key] = token_store.remove;
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
60 [key:sub(1, -4).."-cur"] = token;
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
61 });
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
62 end
5078
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5077
diff changeset
63 local rotation_needed;
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5077
diff changeset
64 if invalidate then
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5077
diff changeset
65 token_store:set(username, key, nil);
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5077
diff changeset
66 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
67 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
68 rotation_needed = true;
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5077
diff changeset
69 end
5082
ddb1940b08e0 mod_sasl2_fast: Clean up backend return values (fixes constant rotation)
Matthew Wild <mwild1@gmail.com>
parents: 5078
diff changeset
70 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
71 end
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
72 end
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
73 if not tried_current_token then
5076
eb46abc65dfd mod_sasl2_fast: Improved logging
Matthew Wild <mwild1@gmail.com>
parents: 5075
diff changeset
74 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
75 -- 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
76 tried_current_token = true;
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
77 key = key:sub(1, -4).."-cur";
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
78 else
5076
eb46abc65dfd mod_sasl2_fast: Improved logging
Matthew Wild <mwild1@gmail.com>
parents: 5075
diff changeset
79 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
80 return nil;
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 until false;
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
83 end
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
84 end
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
85
5071
bc983da908e6 mod_sasl2_fast: Take username from SASL exchange rather than stream@from
Matthew Wild <mwild1@gmail.com>
parents: 5070
diff changeset
86 function get_sasl_handler()
5062
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
87 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
88 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
89 };
5078
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5077
diff changeset
90 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
91 handler.fast = true;
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5077
diff changeset
92 return handler;
5062
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
93 end
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
94
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
95 -- Advertise FAST to connecting clients
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
96 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
97 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
98 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
99 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
100 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
101 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
102 end
20e635eb4cdc mod_sasl2_fast: More robust handling of stream@from and user-agent@id
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
103 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
104 if not sasl_handler then return; end
5083
4837232474ca mod_sasl2_fast: Fixes to make channel binding work again
Matthew Wild <mwild1@gmail.com>
parents: 5082
diff changeset
105 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
106 sasl_handler.userdata = session.sasl_handler.userdata;
5066
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
107 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
108 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
109 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
110 fast:text_tag("mechanism", mech);
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
111 end
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
112 event.features:add_child(fast);
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
113 end);
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
114
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
115 -- 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
116 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
117 -- 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
118 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
119 if fast_auth then
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
120 -- 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
121 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
122 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
123 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
124 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
125 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
126 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
127 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
128 local invalidate = fast_auth.attr.invalidate;
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5077
diff changeset
129 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
130 -- 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
131 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
132 else
5076
eb46abc65dfd mod_sasl2_fast: Improved logging
Matthew Wild <mwild1@gmail.com>
parents: 5075
diff changeset
133 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
134 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
135 :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
136 :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
137 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
138 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
139 end
5062
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 session.fast_sasl_handler = nil;
5072
d41677929f68 mod_sasl2_fast: Fixes for <authenticate> processing
Matthew Wild <mwild1@gmail.com>
parents: 5071
diff changeset
142 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
143 if fast_token_request then
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
144 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
145 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
146 session.fast_token_request = {
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
147 mechanism = mech;
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
148 };
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
149 end
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
150 end, 100);
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
151
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
152 -- 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
153 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
154 local session = event.session;
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
155
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
156 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
157 local client_id = session.client_id;
5078
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5077
diff changeset
158 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
159 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
160 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
161 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
162 return;
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
163 end
5078
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5077
diff changeset
164 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
165 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
166 if token_info then
5078
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5077
diff changeset
167 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
168 event.success:tag("token", {
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
169 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
170 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
171 token = token_info.secret;
5062
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
172 }):up();
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
173 end
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
174 end
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
175 end, 75);
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
176
5066
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
177 -- HT-* mechanisms
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
178
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
179 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
180 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
181 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
182 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
183 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
184 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
185 end
bc983da908e6 mod_sasl2_fast: Take username from SASL exchange rather than stream@from
Matthew Wild <mwild1@gmail.com>
parents: 5070
diff changeset
186 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
187 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
188 mechanism_name,
5082
ddb1940b08e0 mod_sasl2_fast: Clean up backend return values (fixes constant rotation)
Matthew Wild <mwild1@gmail.com>
parents: 5078
diff changeset
189 authc_username,
5078
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5077
diff changeset
190 sasl_handler.client_id,
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5077
diff changeset
191 token_hash,
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5077
diff changeset
192 cb_data,
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5077
diff changeset
193 sasl_handler.invalidate
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5077
diff changeset
194 );
5066
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
195 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
196 -- 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
197 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
198 end
5082
ddb1940b08e0 mod_sasl2_fast: Clean up backend return values (fixes constant rotation)
Matthew Wild <mwild1@gmail.com>
parents: 5078
diff changeset
199 sasl_handler.username = authz_username;
5078
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5077
diff changeset
200 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
201 return "success", response;
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
202 end
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
203 end
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
204
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
205 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
206 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
207 name,
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
208 backend_profile_name,
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
209 cb_name
5075
ba2f1292d5fe mod_sasl2_fast: Register HT-* mechanisms with the required channel binding
Matthew Wild <mwild1@gmail.com>
parents: 5074
diff changeset
210 ),
5083
4837232474ca mod_sasl2_fast: Fixes to make channel binding work again
Matthew Wild <mwild1@gmail.com>
parents: 5082
diff changeset
211 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
212 end
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5062
diff changeset
213
5069
e8342ae5ae12 mod_sasl2_fast: Improve backend profile name and correctly use it everywhere
Matthew Wild <mwild1@gmail.com>
parents: 5068
diff changeset
214 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
215 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
216 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
217 register_ht_mechanism("HT-SHA-256-EXPR", "ht_sha_256", "tls-exporter");