author | Matthew Wild <mwild1@gmail.com> |
Sat, 15 Oct 2022 21:01:04 +0100 | |
changeset 5082 | 36d3f11724c8 |
parent 5081 | e900bbd2e70d |
child 5086 | ddb1940b08e0 |
permissions | -rw-r--r-- |
5066
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"; |
5070
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
3 |
local id = require "util.id"; |
5072
20e635eb4cdc
mod_sasl2_fast: More robust handling of stream@from and user-agent@id
Matthew Wild <mwild1@gmail.com>
parents:
5070
diff
changeset
|
4 |
local jid = require "util.jid"; |
5066
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"; |
5070
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
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:
5066
diff
changeset
|
7 |
local hash = require "util.hashes"; |
5066
38a0e3621181
mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
8 |
|
5082
36d3f11724c8
mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents:
5081
diff
changeset
|
9 |
-- Tokens expire after 21 days by default |
5066
38a0e3621181
mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
10 |
local fast_token_ttl = module:get_option_number("sasl2_fast_token_ttl", 86400*21); |
5082
36d3f11724c8
mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents:
5081
diff
changeset
|
11 |
-- Tokens are automatically rotated daily |
36d3f11724c8
mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents:
5081
diff
changeset
|
12 |
local fast_token_min_ttl = module:get_option_number("sasl2_fast_token_min_ttl", 86400); |
5066
38a0e3621181
mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
13 |
|
38a0e3621181
mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
14 |
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
|
15 |
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
|
16 |
|
5070
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
17 |
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:
5066
diff
changeset
|
18 |
|
5080
eb46abc65dfd
mod_sasl2_fast: Improved logging
Matthew Wild <mwild1@gmail.com>
parents:
5079
diff
changeset
|
19 |
local log = module._log; |
eb46abc65dfd
mod_sasl2_fast: Improved logging
Matthew Wild <mwild1@gmail.com>
parents:
5079
diff
changeset
|
20 |
|
5070
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
21 |
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:
5066
diff
changeset
|
22 |
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:
5066
diff
changeset
|
23 |
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:
5066
diff
changeset
|
24 |
local issued_at = now(); |
5074
5cc6f3749376
mod_sasl2_fast: Fix make_token() to return appropriate result
Matthew Wild <mwild1@gmail.com>
parents:
5073
diff
changeset
|
25 |
local token_info = { |
5070
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
26 |
mechanism = mechanism; |
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
27 |
secret = new_token; |
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
28 |
issued_at = issued_at; |
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
29 |
expires_at = issued_at + fast_token_ttl; |
5074
5cc6f3749376
mod_sasl2_fast: Fix make_token() to return appropriate result
Matthew Wild <mwild1@gmail.com>
parents:
5073
diff
changeset
|
30 |
}; |
5cc6f3749376
mod_sasl2_fast: Fix make_token() to return appropriate result
Matthew Wild <mwild1@gmail.com>
parents:
5073
diff
changeset
|
31 |
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:
5073
diff
changeset
|
32 |
return nil; |
5cc6f3749376
mod_sasl2_fast: Fix make_token() to return appropriate result
Matthew Wild <mwild1@gmail.com>
parents:
5073
diff
changeset
|
33 |
end |
5cc6f3749376
mod_sasl2_fast: Fix make_token() to return appropriate result
Matthew Wild <mwild1@gmail.com>
parents:
5073
diff
changeset
|
34 |
return token_info; |
5070
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
35 |
end |
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
36 |
|
5075
bc983da908e6
mod_sasl2_fast: Take username from SASL exchange rather than stream@from
Matthew Wild <mwild1@gmail.com>
parents:
5074
diff
changeset
|
37 |
local function new_token_tester(hmac_f) |
5082
36d3f11724c8
mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents:
5081
diff
changeset
|
38 |
return function (mechanism, username, client_id, token_hash, cb_data, invalidate) |
5070
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
39 |
local tried_current_token = false; |
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
40 |
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:
5066
diff
changeset
|
41 |
local token; |
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
42 |
repeat |
5080
eb46abc65dfd
mod_sasl2_fast: Improved logging
Matthew Wild <mwild1@gmail.com>
parents:
5079
diff
changeset
|
43 |
log("debug", "Looking for %s token %s/%s", mechanism, username, key); |
5070
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
44 |
token = token_store:get(username, key); |
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
45 |
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:
5066
diff
changeset
|
46 |
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:
5066
diff
changeset
|
47 |
if hash.equals(expected_hash, token_hash) then |
5082
36d3f11724c8
mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents:
5081
diff
changeset
|
48 |
local current_time = now(); |
36d3f11724c8
mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents:
5081
diff
changeset
|
49 |
if token.expires_at < current_time then |
5070
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
50 |
token_store:set(username, key, nil); |
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
51 |
return nil, "credentials-expired"; |
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
52 |
end |
5082
36d3f11724c8
mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents:
5081
diff
changeset
|
53 |
if not tried_current_token and not invalidate then |
5070
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
54 |
-- 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:
5066
diff
changeset
|
55 |
token_store:set_keys(username, { |
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
56 |
[key] = token_store.remove; |
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
57 |
[key:sub(1, -4).."-cur"] = token; |
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
58 |
}); |
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
59 |
end |
5082
36d3f11724c8
mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents:
5081
diff
changeset
|
60 |
local rotation_needed; |
36d3f11724c8
mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents:
5081
diff
changeset
|
61 |
if invalidate then |
36d3f11724c8
mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents:
5081
diff
changeset
|
62 |
token_store:set(username, key, nil); |
36d3f11724c8
mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents:
5081
diff
changeset
|
63 |
elseif current_time - token.issued_at > fast_token_min_ttl then |
36d3f11724c8
mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents:
5081
diff
changeset
|
64 |
rotation_needed = true; |
36d3f11724c8
mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents:
5081
diff
changeset
|
65 |
end |
36d3f11724c8
mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents:
5081
diff
changeset
|
66 |
return true, username, hmac_f(token.secret, "Responder"..cb_data), token, rotation_needed; |
5070
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
67 |
end |
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
68 |
end |
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
69 |
if not tried_current_token then |
5080
eb46abc65dfd
mod_sasl2_fast: Improved logging
Matthew Wild <mwild1@gmail.com>
parents:
5079
diff
changeset
|
70 |
log("debug", "Trying next token..."); |
5070
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
71 |
-- 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:
5066
diff
changeset
|
72 |
tried_current_token = true; |
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
73 |
key = key:sub(1, -4).."-cur"; |
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
74 |
else |
5080
eb46abc65dfd
mod_sasl2_fast: Improved logging
Matthew Wild <mwild1@gmail.com>
parents:
5079
diff
changeset
|
75 |
log("debug", "No matching %s token found for %s/%s", mechanism, username, key); |
5070
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
76 |
return nil; |
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
77 |
end |
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
78 |
until false; |
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
79 |
end |
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
80 |
end |
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
81 |
|
5075
bc983da908e6
mod_sasl2_fast: Take username from SASL exchange rather than stream@from
Matthew Wild <mwild1@gmail.com>
parents:
5074
diff
changeset
|
82 |
function get_sasl_handler() |
5066
38a0e3621181
mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
83 |
local token_auth_profile = { |
5075
bc983da908e6
mod_sasl2_fast: Take username from SASL exchange rather than stream@from
Matthew Wild <mwild1@gmail.com>
parents:
5074
diff
changeset
|
84 |
ht_sha_256 = new_token_tester(hash.hmac_sha256); |
5066
38a0e3621181
mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
85 |
}; |
5082
36d3f11724c8
mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents:
5081
diff
changeset
|
86 |
local handler = sasl.new(module.host, token_auth_profile); |
36d3f11724c8
mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents:
5081
diff
changeset
|
87 |
handler.fast = true; |
36d3f11724c8
mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents:
5081
diff
changeset
|
88 |
return handler; |
5066
38a0e3621181
mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
89 |
end |
38a0e3621181
mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
90 |
|
38a0e3621181
mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
91 |
-- Advertise FAST to connecting clients |
38a0e3621181
mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
92 |
module:hook("advertise-sasl-features", function (event) |
5070
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
93 |
local session = event.origin; |
5072
20e635eb4cdc
mod_sasl2_fast: More robust handling of stream@from and user-agent@id
Matthew Wild <mwild1@gmail.com>
parents:
5070
diff
changeset
|
94 |
local username = session.username; |
20e635eb4cdc
mod_sasl2_fast: More robust handling of stream@from and user-agent@id
Matthew Wild <mwild1@gmail.com>
parents:
5070
diff
changeset
|
95 |
if not username then |
20e635eb4cdc
mod_sasl2_fast: More robust handling of stream@from and user-agent@id
Matthew Wild <mwild1@gmail.com>
parents:
5070
diff
changeset
|
96 |
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:
5070
diff
changeset
|
97 |
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:
5070
diff
changeset
|
98 |
end |
20e635eb4cdc
mod_sasl2_fast: More robust handling of stream@from and user-agent@id
Matthew Wild <mwild1@gmail.com>
parents:
5070
diff
changeset
|
99 |
local sasl_handler = get_sasl_handler(username); |
5066
38a0e3621181
mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
100 |
if not sasl_handler then return; end |
5070
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
101 |
session.fast_sasl_handler = sasl_handler; |
5066
38a0e3621181
mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
102 |
local fast = st.stanza("fast", { xmlns = xmlns_fast }); |
5070
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
103 |
for mech in pairs(sasl_handler:mechanisms()) do |
5066
38a0e3621181
mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
104 |
fast:text_tag("mechanism", mech); |
38a0e3621181
mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
105 |
end |
38a0e3621181
mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
106 |
event.features:add_child(fast); |
38a0e3621181
mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
107 |
end); |
38a0e3621181
mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
108 |
|
38a0e3621181
mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
109 |
-- 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
|
110 |
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
|
111 |
-- Cache action for future processing (after auth success) |
5076
d41677929f68
mod_sasl2_fast: Fixes for <authenticate> processing
Matthew Wild <mwild1@gmail.com>
parents:
5075
diff
changeset
|
112 |
local fast_auth = auth:get_child("fast", xmlns_fast); |
5066
38a0e3621181
mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
113 |
if fast_auth then |
38a0e3621181
mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
114 |
-- Client says it is using FAST auth, so set our SASL handler |
5070
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
115 |
local fast_sasl_handler = session.fast_sasl_handler; |
5076
d41677929f68
mod_sasl2_fast: Fixes for <authenticate> processing
Matthew Wild <mwild1@gmail.com>
parents:
5075
diff
changeset
|
116 |
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:
5075
diff
changeset
|
117 |
if fast_sasl_handler and client_id then |
5072
20e635eb4cdc
mod_sasl2_fast: More robust handling of stream@from and user-agent@id
Matthew Wild <mwild1@gmail.com>
parents:
5070
diff
changeset
|
118 |
session.log("debug", "Client is authenticating using FAST"); |
5082
36d3f11724c8
mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents:
5081
diff
changeset
|
119 |
fast_sasl_handler.client_id = client_id; |
5077
f158f18704c0
mod_sasl2_fast: Copy channel binding data state from original SASL handler
Matthew Wild <mwild1@gmail.com>
parents:
5076
diff
changeset
|
120 |
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:
5076
diff
changeset
|
121 |
fast_sasl_handler.userdata = session.sasl_handler.userdata; |
5082
36d3f11724c8
mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents:
5081
diff
changeset
|
122 |
local invalidate = fast_auth.attr.invalidate; |
36d3f11724c8
mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents:
5081
diff
changeset
|
123 |
fast_sasl_handler.invalidate = invalidate == "1" or invalidate == "true"; |
36d3f11724c8
mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents:
5081
diff
changeset
|
124 |
-- Set our SASL handler as the session's SASL handler |
5072
20e635eb4cdc
mod_sasl2_fast: More robust handling of stream@from and user-agent@id
Matthew Wild <mwild1@gmail.com>
parents:
5070
diff
changeset
|
125 |
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:
5070
diff
changeset
|
126 |
else |
5080
eb46abc65dfd
mod_sasl2_fast: Improved logging
Matthew Wild <mwild1@gmail.com>
parents:
5079
diff
changeset
|
127 |
session.log("warn", "Client asked to auth via FAST, but SASL handler or client id missing"); |
5072
20e635eb4cdc
mod_sasl2_fast: More robust handling of stream@from and user-agent@id
Matthew Wild <mwild1@gmail.com>
parents:
5070
diff
changeset
|
128 |
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:
5070
diff
changeset
|
129 |
:tag("malformed-request"):up() |
20e635eb4cdc
mod_sasl2_fast: More robust handling of stream@from and user-agent@id
Matthew Wild <mwild1@gmail.com>
parents:
5070
diff
changeset
|
130 |
: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:
5070
diff
changeset
|
131 |
session.send(failure); |
20e635eb4cdc
mod_sasl2_fast: More robust handling of stream@from and user-agent@id
Matthew Wild <mwild1@gmail.com>
parents:
5070
diff
changeset
|
132 |
return true; |
20e635eb4cdc
mod_sasl2_fast: More robust handling of stream@from and user-agent@id
Matthew Wild <mwild1@gmail.com>
parents:
5070
diff
changeset
|
133 |
end |
5066
38a0e3621181
mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
134 |
end |
38a0e3621181
mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
135 |
session.fast_sasl_handler = nil; |
5076
d41677929f68
mod_sasl2_fast: Fixes for <authenticate> processing
Matthew Wild <mwild1@gmail.com>
parents:
5075
diff
changeset
|
136 |
local fast_token_request = auth:get_child("request-token", xmlns_fast); |
5066
38a0e3621181
mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
137 |
if fast_token_request then |
38a0e3621181
mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
138 |
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
|
139 |
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
|
140 |
session.fast_token_request = { |
38a0e3621181
mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
141 |
mechanism = mech; |
38a0e3621181
mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
142 |
}; |
38a0e3621181
mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
143 |
end |
38a0e3621181
mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
144 |
end, 100); |
38a0e3621181
mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
145 |
|
38a0e3621181
mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
146 |
-- 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
|
147 |
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
|
148 |
local session = event.session; |
38a0e3621181
mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
149 |
|
38a0e3621181
mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
150 |
local token_request = session.fast_token_request; |
5070
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
151 |
local client_id = session.client_id; |
5082
36d3f11724c8
mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents:
5081
diff
changeset
|
152 |
local sasl_handler = session.sasl_handler; |
36d3f11724c8
mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents:
5081
diff
changeset
|
153 |
if token_request or sasl_handler.fast and sasl_handler.rotation_needed then |
5072
20e635eb4cdc
mod_sasl2_fast: More robust handling of stream@from and user-agent@id
Matthew Wild <mwild1@gmail.com>
parents:
5070
diff
changeset
|
154 |
if not client_id then |
5070
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
155 |
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:
5066
diff
changeset
|
156 |
return; |
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
157 |
end |
5082
36d3f11724c8
mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents:
5081
diff
changeset
|
158 |
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:
5081
diff
changeset
|
159 |
local token_info = make_token(session.username, client_id, mechanism) |
5070
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
160 |
if token_info then |
5082
36d3f11724c8
mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents:
5081
diff
changeset
|
161 |
session.log("debug", "Provided new FAST token to client"); |
5066
38a0e3621181
mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
162 |
event.success:tag("token", { |
38a0e3621181
mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
163 |
xmlns = xmlns_fast; |
5070
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
164 |
expiry = dt.datetime(token_info.expires_at); |
5078
1726050e9a4b
mod_sasl2_fast: Fix field name for returned secret
Matthew Wild <mwild1@gmail.com>
parents:
5077
diff
changeset
|
165 |
token = token_info.secret; |
5066
38a0e3621181
mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
166 |
}):up(); |
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 |
end |
38a0e3621181
mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
169 |
end, 75); |
38a0e3621181
mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
170 |
|
5070
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
171 |
-- HT-* mechanisms |
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
172 |
|
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
173 |
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:
5066
diff
changeset
|
174 |
return function (sasl_handler, message) |
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
175 |
local backend = sasl_handler.profile[backend_profile_name]; |
5075
bc983da908e6
mod_sasl2_fast: Take username from SASL exchange rather than stream@from
Matthew Wild <mwild1@gmail.com>
parents:
5074
diff
changeset
|
176 |
local username, token_hash = message:match("^([^%z]+)%z(.+)$"); |
bc983da908e6
mod_sasl2_fast: Take username from SASL exchange rather than stream@from
Matthew Wild <mwild1@gmail.com>
parents:
5074
diff
changeset
|
177 |
if not username then |
bc983da908e6
mod_sasl2_fast: Take username from SASL exchange rather than stream@from
Matthew Wild <mwild1@gmail.com>
parents:
5074
diff
changeset
|
178 |
return "failure", "malformed-request"; |
bc983da908e6
mod_sasl2_fast: Take username from SASL exchange rather than stream@from
Matthew Wild <mwild1@gmail.com>
parents:
5074
diff
changeset
|
179 |
end |
bc983da908e6
mod_sasl2_fast: Take username from SASL exchange rather than stream@from
Matthew Wild <mwild1@gmail.com>
parents:
5074
diff
changeset
|
180 |
local cb_data = cb_name and sasl_handler.profile.cb[cb_name](sasl_handler) or ""; |
5082
36d3f11724c8
mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents:
5081
diff
changeset
|
181 |
local ok, status, response, rotation_needed = backend( |
36d3f11724c8
mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents:
5081
diff
changeset
|
182 |
mechanism_name, |
36d3f11724c8
mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents:
5081
diff
changeset
|
183 |
username, |
36d3f11724c8
mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents:
5081
diff
changeset
|
184 |
sasl_handler.client_id, |
36d3f11724c8
mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents:
5081
diff
changeset
|
185 |
token_hash, |
36d3f11724c8
mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents:
5081
diff
changeset
|
186 |
cb_data, |
36d3f11724c8
mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents:
5081
diff
changeset
|
187 |
sasl_handler.invalidate |
36d3f11724c8
mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents:
5081
diff
changeset
|
188 |
); |
5070
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
189 |
if not ok then |
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
190 |
return "failure", status or "not-authorized"; |
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
191 |
end |
5075
bc983da908e6
mod_sasl2_fast: Take username from SASL exchange rather than stream@from
Matthew Wild <mwild1@gmail.com>
parents:
5074
diff
changeset
|
192 |
sasl_handler.username = status; |
5082
36d3f11724c8
mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents:
5081
diff
changeset
|
193 |
sasl_handler.rotation_needed = rotation_needed; |
5070
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
194 |
return "success", response; |
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
195 |
end |
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
196 |
end |
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
197 |
|
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
198 |
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:
5066
diff
changeset
|
199 |
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:
5066
diff
changeset
|
200 |
name, |
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
201 |
backend_profile_name, |
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
202 |
cb_name |
5079
ba2f1292d5fe
mod_sasl2_fast: Register HT-* mechanisms with the required channel binding
Matthew Wild <mwild1@gmail.com>
parents:
5078
diff
changeset
|
203 |
), |
ba2f1292d5fe
mod_sasl2_fast: Register HT-* mechanisms with the required channel binding
Matthew Wild <mwild1@gmail.com>
parents:
5078
diff
changeset
|
204 |
{ cb_name }); |
5070
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
205 |
end |
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
206 |
|
5073
e8342ae5ae12
mod_sasl2_fast: Improve backend profile name and correctly use it everywhere
Matthew Wild <mwild1@gmail.com>
parents:
5072
diff
changeset
|
207 |
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:
5072
diff
changeset
|
208 |
register_ht_mechanism("HT-SHA-256-UNIQ", "ht_sha_256", "tls-unique"); |
e8342ae5ae12
mod_sasl2_fast: Improve backend profile name and correctly use it everywhere
Matthew Wild <mwild1@gmail.com>
parents:
5072
diff
changeset
|
209 |
register_ht_mechanism("HT-SHA-256-ENDP", "ht_sha_256", "tls-endpoint"); |
e8342ae5ae12
mod_sasl2_fast: Improve backend profile name and correctly use it everywhere
Matthew Wild <mwild1@gmail.com>
parents:
5072
diff
changeset
|
210 |
register_ht_mechanism("HT-SHA-256-EXPR", "ht_sha_256", "tls-exporter"); |