mod_sasl2_fast/mod_sasl2_fast.lua
author Matthew Wild <mwild1@gmail.com>
Fri, 14 Oct 2022 16:21:01 +0100
changeset 5073 e8342ae5ae12
parent 5072 20e635eb4cdc
child 5074 5cc6f3749376
permissions -rw-r--r--
mod_sasl2_fast: Improve backend profile name and correctly use it everywhere It didn't match before, and the mechanisms didn't show up.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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();
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
    20
	token_store:set(username, key, {
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;
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
    25
	});
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
    26
end
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
    27
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
    28
local function new_token_tester(username, hmac_f)
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
    29
	return function (mechanism, client_id, token_hash, cb_data)
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
    30
		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
    31
		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
    32
		local token;
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
    33
		repeat
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
    34
			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
    35
			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
    36
				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
    37
				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
    38
					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
    39
						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
    40
						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
    41
					end
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
    42
					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
    43
						-- 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
    44
						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
    45
							[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
    46
							[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
    47
						});
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
    48
					end
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
    49
					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
    50
				end
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
    51
			end
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
    52
			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
    53
				-- 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
    54
				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
    55
				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
    56
			else
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
    57
				return nil;
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
    58
			end
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
    59
		until false;
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
    60
	end
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
    61
end
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
    62
5072
20e635eb4cdc mod_sasl2_fast: More robust handling of stream@from and user-agent@id
Matthew Wild <mwild1@gmail.com>
parents: 5070
diff changeset
    63
function get_sasl_handler(username)
5066
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    64
	local token_auth_profile = {
5073
e8342ae5ae12 mod_sasl2_fast: Improve backend profile name and correctly use it everywhere
Matthew Wild <mwild1@gmail.com>
parents: 5072
diff changeset
    65
		ht_sha_256 = new_token_tester(username, hash.hmac_sha256);
5066
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    66
		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
    67
			return false; -- FIXME
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    68
		end;
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    69
	};
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    70
	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
    71
end
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    72
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    73
-- Advertise FAST to connecting clients
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    74
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
    75
	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
    76
	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
    77
	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
    78
		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
    79
		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
    80
	end
20e635eb4cdc mod_sasl2_fast: More robust handling of stream@from and user-agent@id
Matthew Wild <mwild1@gmail.com>
parents: 5070
diff changeset
    81
	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
    82
	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
    83
	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
    84
	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
    85
	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
    86
		fast:text_tag("mechanism", mech);
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    87
	end
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    88
	event.features:add_child(fast);
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
-- 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
    92
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
    93
	-- Cache action for future processing (after auth success)
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    94
	local fast_auth = auth:get_child(xmlns_fast, "fast");
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    95
	if fast_auth then
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    96
		-- 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
    97
		local fast_sasl_handler = session.fast_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
    98
		if fast_sasl_handler then
20e635eb4cdc mod_sasl2_fast: More robust handling of stream@from and user-agent@id
Matthew Wild <mwild1@gmail.com>
parents: 5070
diff changeset
    99
			session.log("debug", "Client is authenticating using FAST");
20e635eb4cdc mod_sasl2_fast: More robust handling of stream@from and user-agent@id
Matthew Wild <mwild1@gmail.com>
parents: 5070
diff changeset
   100
			fast_sasl_handler.profile._client_id = session.client_id;
20e635eb4cdc mod_sasl2_fast: More robust handling of stream@from and user-agent@id
Matthew Wild <mwild1@gmail.com>
parents: 5070
diff changeset
   101
			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
   102
		else
20e635eb4cdc mod_sasl2_fast: More robust handling of stream@from and user-agent@id
Matthew Wild <mwild1@gmail.com>
parents: 5070
diff changeset
   103
			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
   104
			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
   105
				: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
   106
				: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
   107
			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
   108
			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
   109
		end
5066
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   110
	end
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   111
	session.fast_sasl_handler = nil;
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   112
	local fast_token_request = auth:get_child(xmlns_fast, "request-token");
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   113
	if fast_token_request then
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   114
		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
   115
		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
   116
		session.fast_token_request = {
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   117
			mechanism = mech;
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   118
		};
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   119
	end
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   120
end, 100);
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   121
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   122
-- 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
   123
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
   124
	local session = event.session;
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
	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
   127
	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
   128
	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
   129
		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
   130
			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
   131
			return;
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
   132
		end
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
   133
		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
   134
		if token_info then
5066
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   135
			event.success:tag("token", {
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   136
				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
   137
				expiry = dt.datetime(token_info.expires_at);
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
   138
				token = token_info.token;
5066
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   139
			}):up();
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
	end
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   142
end, 75);
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   143
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   144
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   145
-- X-PLAIN-TOKEN mechanism
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   146
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   147
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
   148
	if not message then
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   149
		return nil, "malformed-request";
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   150
	end
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   151
	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
   152
end
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
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
   155
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
   156
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
   157
-- HT-* mechanisms
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
   158
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
   159
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
   160
	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
   161
		local backend = sasl_handler.profile[backend_profile_name];
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
   162
		local ok, status, response = backend(mechanism_name, sasl_handler._client_id, message, cb_name and sasl_handler.profile.cb[cb_name] or "");
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
   163
		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
   164
			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
   165
		end
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
   166
		return "success", response;
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
   167
	end
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
   168
end
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
   169
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
   170
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
   171
	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
   172
		name,
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
   173
		backend_profile_name,
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
   174
		cb_name
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
   175
	));
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
   176
end
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
   177
5073
e8342ae5ae12 mod_sasl2_fast: Improve backend profile name and correctly use it everywhere
Matthew Wild <mwild1@gmail.com>
parents: 5072
diff changeset
   178
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
   179
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
   180
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
   181
register_ht_mechanism("HT-SHA-256-EXPR", "ht_sha_256", "tls-exporter");