author | Matthew Wild <mwild1@gmail.com> |
Sat, 15 Oct 2022 19:47:05 +0100 | |
changeset 5079 | ba2f1292d5fe |
parent 5078 | 1726050e9a4b |
child 5080 | eb46abc65dfd |
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 |
|
38a0e3621181
mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
9 |
local fast_token_ttl = module:get_option_number("sasl2_fast_token_ttl", 86400*21); |
38a0e3621181
mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
10 |
|
38a0e3621181
mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
11 |
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
|
12 |
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
|
13 |
|
5070
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
14 |
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
|
15 |
|
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
16 |
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
|
17 |
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
|
18 |
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
|
19 |
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
|
20 |
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
|
21 |
mechanism = mechanism; |
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
22 |
secret = new_token; |
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
23 |
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
|
24 |
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
|
25 |
}; |
5cc6f3749376
mod_sasl2_fast: Fix make_token() to return appropriate result
Matthew Wild <mwild1@gmail.com>
parents:
5073
diff
changeset
|
26 |
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
|
27 |
return nil; |
5cc6f3749376
mod_sasl2_fast: Fix make_token() to return appropriate result
Matthew Wild <mwild1@gmail.com>
parents:
5073
diff
changeset
|
28 |
end |
5cc6f3749376
mod_sasl2_fast: Fix make_token() to return appropriate result
Matthew Wild <mwild1@gmail.com>
parents:
5073
diff
changeset
|
29 |
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
|
30 |
end |
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
31 |
|
5075
bc983da908e6
mod_sasl2_fast: Take username from SASL exchange rather than stream@from
Matthew Wild <mwild1@gmail.com>
parents:
5074
diff
changeset
|
32 |
local function new_token_tester(hmac_f) |
bc983da908e6
mod_sasl2_fast: Take username from SASL exchange rather than stream@from
Matthew Wild <mwild1@gmail.com>
parents:
5074
diff
changeset
|
33 |
return function (mechanism, username, client_id, token_hash, cb_data) |
5070
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
34 |
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
|
35 |
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
|
36 |
local token; |
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
37 |
repeat |
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
38 |
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
|
39 |
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
|
40 |
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
|
41 |
if hash.equals(expected_hash, token_hash) then |
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
42 |
if token.expires_at < now() then |
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
43 |
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
|
44 |
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
|
45 |
end |
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
46 |
if not tried_current_token then |
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
47 |
-- 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
|
48 |
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
|
49 |
[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
|
50 |
[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
|
51 |
}); |
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
52 |
end |
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
53 |
return true, username, hmac_f(token.secret, "Responder"..cb_data); |
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
54 |
end |
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
55 |
end |
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
56 |
if not tried_current_token then |
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
57 |
-- 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
|
58 |
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
|
59 |
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
|
60 |
else |
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
61 |
return nil; |
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
62 |
end |
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
63 |
until false; |
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
64 |
end |
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
65 |
end |
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
66 |
|
5075
bc983da908e6
mod_sasl2_fast: Take username from SASL exchange rather than stream@from
Matthew Wild <mwild1@gmail.com>
parents:
5074
diff
changeset
|
67 |
function get_sasl_handler() |
5066
38a0e3621181
mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
68 |
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
|
69 |
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
|
70 |
token_test = function (_, client_id, token, mech_name, counter) --luacheck: ignore |
38a0e3621181
mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
71 |
return false; -- FIXME |
38a0e3621181
mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
72 |
end; |
38a0e3621181
mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
73 |
}; |
38a0e3621181
mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
74 |
return sasl.new(module.host, token_auth_profile); |
38a0e3621181
mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
75 |
end |
38a0e3621181
mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
76 |
|
38a0e3621181
mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
77 |
-- Advertise FAST to connecting clients |
38a0e3621181
mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
78 |
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
|
79 |
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
|
80 |
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
|
81 |
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
|
82 |
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
|
83 |
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
|
84 |
end |
20e635eb4cdc
mod_sasl2_fast: More robust handling of stream@from and user-agent@id
Matthew Wild <mwild1@gmail.com>
parents:
5070
diff
changeset
|
85 |
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
|
86 |
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
|
87 |
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
|
88 |
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
|
89 |
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
|
90 |
fast:text_tag("mechanism", mech); |
38a0e3621181
mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
91 |
end |
38a0e3621181
mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
92 |
event.features:add_child(fast); |
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 |
-- 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
|
96 |
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
|
97 |
-- 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
|
98 |
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
|
99 |
if fast_auth then |
38a0e3621181
mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
100 |
-- 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
|
101 |
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
|
102 |
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
|
103 |
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
|
104 |
session.log("debug", "Client is authenticating using FAST"); |
5076
d41677929f68
mod_sasl2_fast: Fixes for <authenticate> processing
Matthew Wild <mwild1@gmail.com>
parents:
5075
diff
changeset
|
105 |
fast_sasl_handler.profile._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
|
106 |
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
|
107 |
fast_sasl_handler.userdata = session.sasl_handler.userdata; |
5072
20e635eb4cdc
mod_sasl2_fast: More robust handling of stream@from and user-agent@id
Matthew Wild <mwild1@gmail.com>
parents:
5070
diff
changeset
|
108 |
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
|
109 |
else |
20e635eb4cdc
mod_sasl2_fast: More robust handling of stream@from and user-agent@id
Matthew Wild <mwild1@gmail.com>
parents:
5070
diff
changeset
|
110 |
session.log("warn", "Client asked to auth via FAST, but no SASL handler available"); |
20e635eb4cdc
mod_sasl2_fast: More robust handling of stream@from and user-agent@id
Matthew Wild <mwild1@gmail.com>
parents:
5070
diff
changeset
|
111 |
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
|
112 |
: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
|
113 |
: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
|
114 |
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
|
115 |
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
|
116 |
end |
5066
38a0e3621181
mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
117 |
end |
38a0e3621181
mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
118 |
session.fast_sasl_handler = nil; |
5076
d41677929f68
mod_sasl2_fast: Fixes for <authenticate> processing
Matthew Wild <mwild1@gmail.com>
parents:
5075
diff
changeset
|
119 |
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
|
120 |
if fast_token_request then |
38a0e3621181
mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
121 |
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
|
122 |
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
|
123 |
session.fast_token_request = { |
38a0e3621181
mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
124 |
mechanism = mech; |
38a0e3621181
mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
125 |
}; |
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 |
end, 100); |
38a0e3621181
mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
128 |
|
38a0e3621181
mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
129 |
-- 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
|
130 |
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
|
131 |
local session = event.session; |
38a0e3621181
mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
132 |
|
38a0e3621181
mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
133 |
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
|
134 |
local client_id = session.client_id; |
5066
38a0e3621181
mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
135 |
if token_request 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
|
136 |
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
|
137 |
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
|
138 |
return; |
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
139 |
end |
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
140 |
local token_info = make_token(session.username, client_id, token_request.mechanism) |
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
141 |
if token_info then |
5066
38a0e3621181
mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
142 |
event.success:tag("token", { |
38a0e3621181
mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
143 |
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
|
144 |
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
|
145 |
token = token_info.secret; |
5066
38a0e3621181
mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
146 |
}):up(); |
38a0e3621181
mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
147 |
end |
38a0e3621181
mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
148 |
end |
38a0e3621181
mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
149 |
end, 75); |
38a0e3621181
mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
150 |
|
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 |
-- X-PLAIN-TOKEN mechanism |
38a0e3621181
mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
153 |
|
38a0e3621181
mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
154 |
local function x_plain_token(self, message) --luacheck: ignore 212/self |
38a0e3621181
mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
155 |
if not message then |
38a0e3621181
mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
156 |
return nil, "malformed-request"; |
38a0e3621181
mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
157 |
end |
38a0e3621181
mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
158 |
return nil, "temporary-auth-failure"; -- FIXME |
38a0e3621181
mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
159 |
end |
38a0e3621181
mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
160 |
|
38a0e3621181
mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
161 |
sasl.registerMechanism("X-PLAIN-TOKEN", { "token_test" }, x_plain_token); |
5070
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
162 |
|
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
163 |
|
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
164 |
-- HT-* mechanisms |
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
165 |
|
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
166 |
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
|
167 |
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
|
168 |
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
|
169 |
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
|
170 |
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
|
171 |
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
|
172 |
end |
bc983da908e6
mod_sasl2_fast: Take username from SASL exchange rather than stream@from
Matthew Wild <mwild1@gmail.com>
parents:
5074
diff
changeset
|
173 |
local cb_data = cb_name and sasl_handler.profile.cb[cb_name](sasl_handler) or ""; |
bc983da908e6
mod_sasl2_fast: Take username from SASL exchange rather than stream@from
Matthew Wild <mwild1@gmail.com>
parents:
5074
diff
changeset
|
174 |
local ok, status, response = backend(mechanism_name, username, sasl_handler.profile._client_id, token_hash, cb_data); |
5070
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
175 |
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
|
176 |
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
|
177 |
end |
5075
bc983da908e6
mod_sasl2_fast: Take username from SASL exchange rather than stream@from
Matthew Wild <mwild1@gmail.com>
parents:
5074
diff
changeset
|
178 |
sasl_handler.username = status; |
5070
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
179 |
return "success", response; |
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
180 |
end |
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
181 |
end |
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
182 |
|
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
183 |
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
|
184 |
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
|
185 |
name, |
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
186 |
backend_profile_name, |
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
187 |
cb_name |
5079
ba2f1292d5fe
mod_sasl2_fast: Register HT-* mechanisms with the required channel binding
Matthew Wild <mwild1@gmail.com>
parents:
5078
diff
changeset
|
188 |
), |
ba2f1292d5fe
mod_sasl2_fast: Register HT-* mechanisms with the required channel binding
Matthew Wild <mwild1@gmail.com>
parents:
5078
diff
changeset
|
189 |
{ cb_name }); |
5070
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
190 |
end |
74145faceba2
mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents:
5066
diff
changeset
|
191 |
|
5073
e8342ae5ae12
mod_sasl2_fast: Improve backend profile name and correctly use it everywhere
Matthew Wild <mwild1@gmail.com>
parents:
5072
diff
changeset
|
192 |
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
|
193 |
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
|
194 |
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
|
195 |
register_ht_mechanism("HT-SHA-256-EXPR", "ht_sha_256", "tls-exporter"); |