mod_sasl2_fast/mod_sasl2_fast.lua
author Matthew Wild <mwild1@gmail.com>
Tue, 16 Apr 2024 10:42:25 +0100
changeset 5886 563c2c70cb9f
parent 5307 b10a7082b3c3
permissions -rw-r--r--
mod_sasl2_fast: Improve handling when SASL profile unexpectedly lacks CB This fixes a traceback reported by riau, but likely does not solve the underlying cause, whatever that is.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
5286
0566a71a7076 mod_sasl2_fast: Invalidate tokens issued prior to last password change
Matthew Wild <mwild1@gmail.com>
parents: 5141
diff changeset
     1
local usermanager = require "core.usermanager";
0566a71a7076 mod_sasl2_fast: Invalidate tokens issued prior to last password change
Matthew Wild <mwild1@gmail.com>
parents: 5141
diff changeset
     2
5066
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     3
local sasl = require "util.sasl";
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     4
local dt = require "util.datetime";
5070
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
     5
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
     6
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
     7
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
     8
local now = require "util.time".now;
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
     9
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
    10
5099
745c7f4cca40 mod_sasl2_fast: Add explicit dependency on mod_sasl2
Kim Alvefur <zash@zash.se>
parents: 5088
diff changeset
    11
module:depends("sasl2");
745c7f4cca40 mod_sasl2_fast: Add explicit dependency on mod_sasl2
Kim Alvefur <zash@zash.se>
parents: 5088
diff changeset
    12
5082
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5081
diff changeset
    13
-- 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
    14
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
    15
-- Tokens are automatically rotated daily
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5081
diff changeset
    16
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
    17
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    18
local xmlns_fast = "urn:xmpp:fast:0";
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    19
local xmlns_sasl2 = "urn:xmpp:sasl:2";
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    20
5070
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
    21
local token_store = module:open_store("fast_tokens", "map");
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
    22
5080
eb46abc65dfd mod_sasl2_fast: Improved logging
Matthew Wild <mwild1@gmail.com>
parents: 5079
diff changeset
    23
local log = module._log;
eb46abc65dfd mod_sasl2_fast: Improved logging
Matthew Wild <mwild1@gmail.com>
parents: 5079
diff changeset
    24
5070
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
    25
local function make_token(username, client_id, mechanism)
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
    26
	local new_token = "secret-token:fast-"..id.long();
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
    27
	local key = hash.sha256(client_id, true).."-new";
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
    28
	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
    29
	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
    30
		mechanism = mechanism;
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
    31
		secret = new_token;
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
    32
		issued_at = issued_at;
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
    33
		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
    34
	};
5cc6f3749376 mod_sasl2_fast: Fix make_token() to return appropriate result
Matthew Wild <mwild1@gmail.com>
parents: 5073
diff changeset
    35
	if not token_store:set(username, key, token_info) then
5cc6f3749376 mod_sasl2_fast: Fix make_token() to return appropriate result
Matthew Wild <mwild1@gmail.com>
parents: 5073
diff changeset
    36
		return nil;
5cc6f3749376 mod_sasl2_fast: Fix make_token() to return appropriate result
Matthew Wild <mwild1@gmail.com>
parents: 5073
diff changeset
    37
	end
5cc6f3749376 mod_sasl2_fast: Fix make_token() to return appropriate result
Matthew Wild <mwild1@gmail.com>
parents: 5073
diff changeset
    38
	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
    39
end
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
    40
5075
bc983da908e6 mod_sasl2_fast: Take username from SASL exchange rather than stream@from
Matthew Wild <mwild1@gmail.com>
parents: 5074
diff changeset
    41
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
    42
	return function (mechanism, username, client_id, token_hash, cb_data, invalidate)
5286
0566a71a7076 mod_sasl2_fast: Invalidate tokens issued prior to last password change
Matthew Wild <mwild1@gmail.com>
parents: 5141
diff changeset
    43
		local account_info = usermanager.get_account_info(username, module.host);
0566a71a7076 mod_sasl2_fast: Invalidate tokens issued prior to last password change
Matthew Wild <mwild1@gmail.com>
parents: 5141
diff changeset
    44
		local last_password_change = account_info and account_info.password_updated;
5070
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
    45
		local tried_current_token = false;
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
    46
		local key = hash.sha256(client_id, true).."-new";
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
    47
		local token;
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
    48
		repeat
5080
eb46abc65dfd mod_sasl2_fast: Improved logging
Matthew Wild <mwild1@gmail.com>
parents: 5079
diff changeset
    49
			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
    50
			token = token_store:get(username, key);
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
    51
			if token and token.mechanism == mechanism then
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
    52
				local expected_hash = hmac_f(token.secret, "Initiator"..cb_data);
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
    53
				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
    54
					local current_time = now();
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5081
diff changeset
    55
					if token.expires_at < current_time then
5088
dda2af7ed02f mod_sasl2_fast: Add more debug logging
Matthew Wild <mwild1@gmail.com>
parents: 5087
diff changeset
    56
						log("debug", "Token found, but it has expired (%ds ago). Cleaning up...", current_time - token.expires_at);
5070
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
    57
						token_store:set(username, key, nil);
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
    58
						return nil, "credentials-expired";
5286
0566a71a7076 mod_sasl2_fast: Invalidate tokens issued prior to last password change
Matthew Wild <mwild1@gmail.com>
parents: 5141
diff changeset
    59
					elseif last_password_change and token.issued_at < last_password_change then
0566a71a7076 mod_sasl2_fast: Invalidate tokens issued prior to last password change
Matthew Wild <mwild1@gmail.com>
parents: 5141
diff changeset
    60
						log("debug", "Token found, but issued prior to password change (%ds ago). Cleaning up...",
0566a71a7076 mod_sasl2_fast: Invalidate tokens issued prior to last password change
Matthew Wild <mwild1@gmail.com>
parents: 5141
diff changeset
    61
							current_time - last_password_change
0566a71a7076 mod_sasl2_fast: Invalidate tokens issued prior to last password change
Matthew Wild <mwild1@gmail.com>
parents: 5141
diff changeset
    62
						);
0566a71a7076 mod_sasl2_fast: Invalidate tokens issued prior to last password change
Matthew Wild <mwild1@gmail.com>
parents: 5141
diff changeset
    63
						token_store:set(username, key, nil);
0566a71a7076 mod_sasl2_fast: Invalidate tokens issued prior to last password change
Matthew Wild <mwild1@gmail.com>
parents: 5141
diff changeset
    64
						return nil, "credentials-expired";
5070
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
    65
					end
5082
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5081
diff changeset
    66
					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
    67
						-- The new token is becoming the current token
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
    68
						token_store:set_keys(username, {
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
    69
							[key] = token_store.remove;
5289
8e1f1eb00b58 mod_sasl2_fast: Fix harmless off-by-one error (invalidates existing tokens!)
Matthew Wild <mwild1@gmail.com>
parents: 5286
diff changeset
    70
							[key:sub(1, -5).."-cur"] = token;
5070
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
    71
						});
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
    72
					end
5082
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5081
diff changeset
    73
					local rotation_needed;
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5081
diff changeset
    74
					if invalidate then
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5081
diff changeset
    75
						token_store:set(username, key, nil);
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5081
diff changeset
    76
					elseif current_time - token.issued_at > fast_token_min_ttl then
5088
dda2af7ed02f mod_sasl2_fast: Add more debug logging
Matthew Wild <mwild1@gmail.com>
parents: 5087
diff changeset
    77
						log("debug", "FAST token due for rotation (age: %d)", current_time - token.issued_at);
5082
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5081
diff changeset
    78
						rotation_needed = true;
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5081
diff changeset
    79
					end
5086
ddb1940b08e0 mod_sasl2_fast: Clean up backend return values (fixes constant rotation)
Matthew Wild <mwild1@gmail.com>
parents: 5082
diff changeset
    80
					return true, username, hmac_f(token.secret, "Responder"..cb_data), rotation_needed;
5070
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
    81
				end
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
    82
			end
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
    83
			if not tried_current_token then
5080
eb46abc65dfd mod_sasl2_fast: Improved logging
Matthew Wild <mwild1@gmail.com>
parents: 5079
diff changeset
    84
				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
    85
				-- Try again with the current token instead
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
    86
				tried_current_token = true;
5289
8e1f1eb00b58 mod_sasl2_fast: Fix harmless off-by-one error (invalidates existing tokens!)
Matthew Wild <mwild1@gmail.com>
parents: 5286
diff changeset
    87
				key = key:sub(1, -5).."-cur";
5070
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
    88
			else
5080
eb46abc65dfd mod_sasl2_fast: Improved logging
Matthew Wild <mwild1@gmail.com>
parents: 5079
diff changeset
    89
				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
    90
				return nil;
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
    91
			end
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
    92
		until false;
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
    93
	end
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
    94
end
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
    95
5075
bc983da908e6 mod_sasl2_fast: Take username from SASL exchange rather than stream@from
Matthew Wild <mwild1@gmail.com>
parents: 5074
diff changeset
    96
function get_sasl_handler()
5066
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    97
	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
    98
		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
    99
	};
5082
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5081
diff changeset
   100
	local handler = sasl.new(module.host, token_auth_profile);
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5081
diff changeset
   101
	handler.fast = true;
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5081
diff changeset
   102
	return handler;
5066
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   103
end
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   104
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   105
-- Advertise FAST to connecting clients
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   106
module:hook("advertise-sasl-features", function (event)
5070
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
   107
	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
   108
	local username = session.username;
20e635eb4cdc mod_sasl2_fast: More robust handling of stream@from and user-agent@id
Matthew Wild <mwild1@gmail.com>
parents: 5070
diff changeset
   109
	if not username then
20e635eb4cdc mod_sasl2_fast: More robust handling of stream@from and user-agent@id
Matthew Wild <mwild1@gmail.com>
parents: 5070
diff changeset
   110
		username = jid.node(event.stream.from);
20e635eb4cdc mod_sasl2_fast: More robust handling of stream@from and user-agent@id
Matthew Wild <mwild1@gmail.com>
parents: 5070
diff changeset
   111
		if not username then return; end
20e635eb4cdc mod_sasl2_fast: More robust handling of stream@from and user-agent@id
Matthew Wild <mwild1@gmail.com>
parents: 5070
diff changeset
   112
	end
20e635eb4cdc mod_sasl2_fast: More robust handling of stream@from and user-agent@id
Matthew Wild <mwild1@gmail.com>
parents: 5070
diff changeset
   113
	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
   114
	if not sasl_handler then return; end
5290
a91adc164566 mod_sasl2_fast: Add flag to FAST sasl_handler for easier identification
Matthew Wild <mwild1@gmail.com>
parents: 5289
diff changeset
   115
	sasl_handler.fast_auth = true; -- For informational purposes
5141
471cbb583a1d mod_sasl2_fast: Add some comments
Matthew Wild <mwild1@gmail.com>
parents: 5099
diff changeset
   116
	-- Copy channel binding info from primary SASL handler
5087
4837232474ca mod_sasl2_fast: Fixes to make channel binding work again
Matthew Wild <mwild1@gmail.com>
parents: 5086
diff changeset
   117
	sasl_handler.profile.cb = session.sasl_handler.profile.cb;
4837232474ca mod_sasl2_fast: Fixes to make channel binding work again
Matthew Wild <mwild1@gmail.com>
parents: 5086
diff changeset
   118
	sasl_handler.userdata = session.sasl_handler.userdata;
5141
471cbb583a1d mod_sasl2_fast: Add some comments
Matthew Wild <mwild1@gmail.com>
parents: 5099
diff changeset
   119
	-- Store this handler, in case we later want to use it for authenticating
5070
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
   120
	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
   121
	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
   122
	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
   123
		fast:text_tag("mechanism", mech);
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   124
	end
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   125
	event.features:add_child(fast);
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   126
end);
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   127
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   128
-- Process any FAST elements in <authenticate/>
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   129
module:hook_tag(xmlns_sasl2, "authenticate", function (session, auth)
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   130
	-- Cache action for future processing (after auth success)
5076
d41677929f68 mod_sasl2_fast: Fixes for <authenticate> processing
Matthew Wild <mwild1@gmail.com>
parents: 5075
diff changeset
   131
	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
   132
	if fast_auth then
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   133
		-- Client says it is using FAST auth, so set our SASL handler
5070
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
   134
		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
   135
		local client_id = auth:get_child_attr("user-agent", nil, "id");
d41677929f68 mod_sasl2_fast: Fixes for <authenticate> processing
Matthew Wild <mwild1@gmail.com>
parents: 5075
diff changeset
   136
		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
   137
			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
   138
			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
   139
			fast_sasl_handler.profile.cb = session.sasl_handler.profile.cb;
f158f18704c0 mod_sasl2_fast: Copy channel binding data state from original SASL handler
Matthew Wild <mwild1@gmail.com>
parents: 5076
diff changeset
   140
			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
   141
			local invalidate = fast_auth.attr.invalidate;
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5081
diff changeset
   142
			fast_sasl_handler.invalidate = invalidate == "1" or invalidate == "true";
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5081
diff changeset
   143
			-- 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
   144
			session.sasl_handler = fast_sasl_handler;
20e635eb4cdc mod_sasl2_fast: More robust handling of stream@from and user-agent@id
Matthew Wild <mwild1@gmail.com>
parents: 5070
diff changeset
   145
		else
5080
eb46abc65dfd mod_sasl2_fast: Improved logging
Matthew Wild <mwild1@gmail.com>
parents: 5079
diff changeset
   146
			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
   147
			local failure = st.stanza("failure", { xmlns = xmlns_sasl2 })
20e635eb4cdc mod_sasl2_fast: More robust handling of stream@from and user-agent@id
Matthew Wild <mwild1@gmail.com>
parents: 5070
diff changeset
   148
				:tag("malformed-request"):up()
20e635eb4cdc mod_sasl2_fast: More robust handling of stream@from and user-agent@id
Matthew Wild <mwild1@gmail.com>
parents: 5070
diff changeset
   149
				:text_tag("text", "FAST is not available on this stream");
20e635eb4cdc mod_sasl2_fast: More robust handling of stream@from and user-agent@id
Matthew Wild <mwild1@gmail.com>
parents: 5070
diff changeset
   150
			session.send(failure);
20e635eb4cdc mod_sasl2_fast: More robust handling of stream@from and user-agent@id
Matthew Wild <mwild1@gmail.com>
parents: 5070
diff changeset
   151
			return true;
20e635eb4cdc mod_sasl2_fast: More robust handling of stream@from and user-agent@id
Matthew Wild <mwild1@gmail.com>
parents: 5070
diff changeset
   152
		end
5066
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   153
	end
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   154
	session.fast_sasl_handler = nil;
5076
d41677929f68 mod_sasl2_fast: Fixes for <authenticate> processing
Matthew Wild <mwild1@gmail.com>
parents: 5075
diff changeset
   155
	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
   156
	if fast_token_request then
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   157
		local mech = fast_token_request.attr.mechanism;
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   158
		session.log("debug", "Client requested new FAST token for %s", mech);
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   159
		session.fast_token_request = {
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   160
			mechanism = mech;
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   161
		};
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   162
	end
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   163
end, 100);
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   164
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   165
-- Process post-success (new token generation, etc.)
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   166
module:hook("sasl2/c2s/success", function (event)
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   167
	local session = event.session;
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   168
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   169
	local token_request = session.fast_token_request;
5070
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
   170
	local client_id = session.client_id;
5082
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5081
diff changeset
   171
	local sasl_handler = session.sasl_handler;
5087
4837232474ca mod_sasl2_fast: Fixes to make channel binding work again
Matthew Wild <mwild1@gmail.com>
parents: 5086
diff changeset
   172
	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
   173
		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
   174
			session.log("warn", "FAST token requested, but missing client id");
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
   175
			return;
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
   176
		end
5082
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5081
diff changeset
   177
		local mechanism = token_request and token_request.mechanism or session.sasl_handler.selected;
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5081
diff changeset
   178
		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
   179
		if token_info then
5082
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5081
diff changeset
   180
			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
   181
			event.success:tag("token", {
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   182
				xmlns = xmlns_fast;
5070
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
   183
				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
   184
				token = token_info.secret;
5066
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   185
			}):up();
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   186
		end
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   187
	end
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   188
end, 75);
38a0e3621181 mod_sasl2_fast: New module for SASL2 FAST authentication (WIP)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   189
5070
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
   190
-- HT-* mechanisms
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
   191
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
   192
local function new_ht_mechanism(mechanism_name, backend_profile_name, cb_name)
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
   193
	return function (sasl_handler, message)
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
   194
		local backend = sasl_handler.profile[backend_profile_name];
5086
ddb1940b08e0 mod_sasl2_fast: Clean up backend return values (fixes constant rotation)
Matthew Wild <mwild1@gmail.com>
parents: 5082
diff changeset
   195
		local authc_username, token_hash = message:match("^([^%z]+)%z(.+)$");
ddb1940b08e0 mod_sasl2_fast: Clean up backend return values (fixes constant rotation)
Matthew Wild <mwild1@gmail.com>
parents: 5082
diff changeset
   196
		if not authc_username then
5075
bc983da908e6 mod_sasl2_fast: Take username from SASL exchange rather than stream@from
Matthew Wild <mwild1@gmail.com>
parents: 5074
diff changeset
   197
			return "failure", "malformed-request";
bc983da908e6 mod_sasl2_fast: Take username from SASL exchange rather than stream@from
Matthew Wild <mwild1@gmail.com>
parents: 5074
diff changeset
   198
		end
5886
563c2c70cb9f mod_sasl2_fast: Improve handling when SASL profile unexpectedly lacks CB
Matthew Wild <mwild1@gmail.com>
parents: 5307
diff changeset
   199
		if not sasl_handler.profile.cb then
563c2c70cb9f mod_sasl2_fast: Improve handling when SASL profile unexpectedly lacks CB
Matthew Wild <mwild1@gmail.com>
parents: 5307
diff changeset
   200
			module:log("warn", "Attempt to use channel binding %s with SASL profile that does not support any channel binding (FAST: %s)", cb_name, sasl_handler.fast);
563c2c70cb9f mod_sasl2_fast: Improve handling when SASL profile unexpectedly lacks CB
Matthew Wild <mwild1@gmail.com>
parents: 5307
diff changeset
   201
			return "failure", "malformed-request";
563c2c70cb9f mod_sasl2_fast: Improve handling when SASL profile unexpectedly lacks CB
Matthew Wild <mwild1@gmail.com>
parents: 5307
diff changeset
   202
		elseif not sasl_handler.profile.cb[cb_name] then
563c2c70cb9f mod_sasl2_fast: Improve handling when SASL profile unexpectedly lacks CB
Matthew Wild <mwild1@gmail.com>
parents: 5307
diff changeset
   203
			module:log("warn", "SASL profile does not support %s channel binding (FAST: %s)", cb_name, sasl_handler.fast);
563c2c70cb9f mod_sasl2_fast: Improve handling when SASL profile unexpectedly lacks CB
Matthew Wild <mwild1@gmail.com>
parents: 5307
diff changeset
   204
			return "failure", "malformed-request";
563c2c70cb9f mod_sasl2_fast: Improve handling when SASL profile unexpectedly lacks CB
Matthew Wild <mwild1@gmail.com>
parents: 5307
diff changeset
   205
		end
5075
bc983da908e6 mod_sasl2_fast: Take username from SASL exchange rather than stream@from
Matthew Wild <mwild1@gmail.com>
parents: 5074
diff changeset
   206
		local cb_data = cb_name and sasl_handler.profile.cb[cb_name](sasl_handler) or "";
5086
ddb1940b08e0 mod_sasl2_fast: Clean up backend return values (fixes constant rotation)
Matthew Wild <mwild1@gmail.com>
parents: 5082
diff changeset
   207
		local ok, authz_username, response, rotation_needed = backend(
5082
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5081
diff changeset
   208
			mechanism_name,
5086
ddb1940b08e0 mod_sasl2_fast: Clean up backend return values (fixes constant rotation)
Matthew Wild <mwild1@gmail.com>
parents: 5082
diff changeset
   209
			authc_username,
5082
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5081
diff changeset
   210
			sasl_handler.client_id,
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5081
diff changeset
   211
			token_hash,
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5081
diff changeset
   212
			cb_data,
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5081
diff changeset
   213
			sasl_handler.invalidate
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5081
diff changeset
   214
		);
5070
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
   215
		if not ok then
5086
ddb1940b08e0 mod_sasl2_fast: Clean up backend return values (fixes constant rotation)
Matthew Wild <mwild1@gmail.com>
parents: 5082
diff changeset
   216
			-- authz_username is error condition
ddb1940b08e0 mod_sasl2_fast: Clean up backend return values (fixes constant rotation)
Matthew Wild <mwild1@gmail.com>
parents: 5082
diff changeset
   217
			return "failure", authz_username or "not-authorized";
5070
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
   218
		end
5086
ddb1940b08e0 mod_sasl2_fast: Clean up backend return values (fixes constant rotation)
Matthew Wild <mwild1@gmail.com>
parents: 5082
diff changeset
   219
		sasl_handler.username = authz_username;
5082
36d3f11724c8 mod_sasl2_fast: Implement rotation and invalidation
Matthew Wild <mwild1@gmail.com>
parents: 5081
diff changeset
   220
		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
   221
		return "success", response;
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
   222
	end
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
   223
end
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
   224
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
   225
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
   226
	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
   227
		name,
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
   228
		backend_profile_name,
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
   229
		cb_name
5079
ba2f1292d5fe mod_sasl2_fast: Register HT-* mechanisms with the required channel binding
Matthew Wild <mwild1@gmail.com>
parents: 5078
diff changeset
   230
	),
5087
4837232474ca mod_sasl2_fast: Fixes to make channel binding work again
Matthew Wild <mwild1@gmail.com>
parents: 5086
diff changeset
   231
	cb_name and { cb_name } or nil);
5070
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
   232
end
74145faceba2 mod_sasl2_fast: Implement most of FAST + SASL HT-SHA-256
Matthew Wild <mwild1@gmail.com>
parents: 5066
diff changeset
   233
5073
e8342ae5ae12 mod_sasl2_fast: Improve backend profile name and correctly use it everywhere
Matthew Wild <mwild1@gmail.com>
parents: 5072
diff changeset
   234
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
   235
register_ht_mechanism("HT-SHA-256-UNIQ", "ht_sha_256", "tls-unique");
5087
4837232474ca mod_sasl2_fast: Fixes to make channel binding work again
Matthew Wild <mwild1@gmail.com>
parents: 5086
diff changeset
   236
register_ht_mechanism("HT-SHA-256-ENDP", "ht_sha_256", "tls-server-end-point");
5073
e8342ae5ae12 mod_sasl2_fast: Improve backend profile name and correctly use it everywhere
Matthew Wild <mwild1@gmail.com>
parents: 5072
diff changeset
   237
register_ht_mechanism("HT-SHA-256-EXPR", "ht_sha_256", "tls-exporter");
5291
4834eaf24fc1 mod_sasl2_fast: Add an API that allows modules to check if a client has FAST
Matthew Wild <mwild1@gmail.com>
parents: 5290
diff changeset
   238
4834eaf24fc1 mod_sasl2_fast: Add an API that allows modules to check if a client has FAST
Matthew Wild <mwild1@gmail.com>
parents: 5290
diff changeset
   239
-- Public API
4834eaf24fc1 mod_sasl2_fast: Add an API that allows modules to check if a client has FAST
Matthew Wild <mwild1@gmail.com>
parents: 5290
diff changeset
   240
4834eaf24fc1 mod_sasl2_fast: Add an API that allows modules to check if a client has FAST
Matthew Wild <mwild1@gmail.com>
parents: 5290
diff changeset
   241
--luacheck: ignore 131
4834eaf24fc1 mod_sasl2_fast: Add an API that allows modules to check if a client has FAST
Matthew Wild <mwild1@gmail.com>
parents: 5290
diff changeset
   242
function is_client_fast(username, client_id, last_password_change)
4834eaf24fc1 mod_sasl2_fast: Add an API that allows modules to check if a client has FAST
Matthew Wild <mwild1@gmail.com>
parents: 5290
diff changeset
   243
	local client_id_hash = hash.sha256(client_id, true);
4834eaf24fc1 mod_sasl2_fast: Add an API that allows modules to check if a client has FAST
Matthew Wild <mwild1@gmail.com>
parents: 5290
diff changeset
   244
	local curr_time = now();
4834eaf24fc1 mod_sasl2_fast: Add an API that allows modules to check if a client has FAST
Matthew Wild <mwild1@gmail.com>
parents: 5290
diff changeset
   245
	local cur = token_store:get(username, client_id_hash.."-cur");
4834eaf24fc1 mod_sasl2_fast: Add an API that allows modules to check if a client has FAST
Matthew Wild <mwild1@gmail.com>
parents: 5290
diff changeset
   246
	if cur and cur.expires_at >= curr_time and (not last_password_change or last_password_change < cur.issued_at) then
4834eaf24fc1 mod_sasl2_fast: Add an API that allows modules to check if a client has FAST
Matthew Wild <mwild1@gmail.com>
parents: 5290
diff changeset
   247
		return true;
4834eaf24fc1 mod_sasl2_fast: Add an API that allows modules to check if a client has FAST
Matthew Wild <mwild1@gmail.com>
parents: 5290
diff changeset
   248
	end
4834eaf24fc1 mod_sasl2_fast: Add an API that allows modules to check if a client has FAST
Matthew Wild <mwild1@gmail.com>
parents: 5290
diff changeset
   249
	local new = token_store:get(username, client_id_hash.."-new");
4834eaf24fc1 mod_sasl2_fast: Add an API that allows modules to check if a client has FAST
Matthew Wild <mwild1@gmail.com>
parents: 5290
diff changeset
   250
	if new and new.expires_at >= curr_time and (not last_password_change or last_password_change < new.issued_at) then
4834eaf24fc1 mod_sasl2_fast: Add an API that allows modules to check if a client has FAST
Matthew Wild <mwild1@gmail.com>
parents: 5290
diff changeset
   251
		return true;
4834eaf24fc1 mod_sasl2_fast: Add an API that allows modules to check if a client has FAST
Matthew Wild <mwild1@gmail.com>
parents: 5290
diff changeset
   252
	end
4834eaf24fc1 mod_sasl2_fast: Add an API that allows modules to check if a client has FAST
Matthew Wild <mwild1@gmail.com>
parents: 5290
diff changeset
   253
	return false;
4834eaf24fc1 mod_sasl2_fast: Add an API that allows modules to check if a client has FAST
Matthew Wild <mwild1@gmail.com>
parents: 5290
diff changeset
   254
end
5307
b10a7082b3c3 mod_sasl2_fast: Add API method to revoke FAST tokens for a given client
Matthew Wild <mwild1@gmail.com>
parents: 5291
diff changeset
   255
b10a7082b3c3 mod_sasl2_fast: Add API method to revoke FAST tokens for a given client
Matthew Wild <mwild1@gmail.com>
parents: 5291
diff changeset
   256
function revoke_fast_tokens(username, client_id)
b10a7082b3c3 mod_sasl2_fast: Add API method to revoke FAST tokens for a given client
Matthew Wild <mwild1@gmail.com>
parents: 5291
diff changeset
   257
	local client_id_hash = hash.sha256(client_id, true);
b10a7082b3c3 mod_sasl2_fast: Add API method to revoke FAST tokens for a given client
Matthew Wild <mwild1@gmail.com>
parents: 5291
diff changeset
   258
	local cur_ok = token_store:set(username, client_id_hash.."-cur", nil);
b10a7082b3c3 mod_sasl2_fast: Add API method to revoke FAST tokens for a given client
Matthew Wild <mwild1@gmail.com>
parents: 5291
diff changeset
   259
	local new_ok = token_store:set(username, client_id_hash.."-new", nil);
b10a7082b3c3 mod_sasl2_fast: Add API method to revoke FAST tokens for a given client
Matthew Wild <mwild1@gmail.com>
parents: 5291
diff changeset
   260
	return cur_ok and new_ok;
b10a7082b3c3 mod_sasl2_fast: Add API method to revoke FAST tokens for a given client
Matthew Wild <mwild1@gmail.com>
parents: 5291
diff changeset
   261
end