mod_sasl2_bind2/mod_sasl2_bind2.lua
author Ben Smith <bens@effortlessis.com>
Tue, 14 May 2024 07:31:34 -0700
changeset 5912 dcea4b4c415d
parent 5184 6361afcda1a3
permissions -rw-r--r--
Tweaking documentation to clarify that Oauth2 can be used for VirtualHosts and Component installations.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
5033
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     1
local base64 = require "util.encodings".base64;
5051
023f21bfcc08 mod_sasl2_bind2: Generate resource from client tag if provided
Matthew Wild <mwild1@gmail.com>
parents: 5050
diff changeset
     2
local id = require "util.id";
5033
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     3
local sha1 = require "util.hashes".sha1;
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     4
local st = require "util.stanza";
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     5
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     6
local sm_bind_resource = require "core.sessionmanager".bind_resource;
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     7
5049
6db64f64c8c9 mod_sasl2_bind2: Update xmlns to match latest XEP proposal (thanks Andrzej)
Matthew Wild <mwild1@gmail.com>
parents: 5048
diff changeset
     8
local xmlns_bind2 = "urn:xmpp:bind:0";
5043
c0d243b27e64 mod_sasl2, mod_sasl_bind2, mod_sasl2_sm: Bump XEP-0388 namespace
Matthew Wild <mwild1@gmail.com>
parents: 5041
diff changeset
     9
local xmlns_sasl2 = "urn:xmpp:sasl:2";
5033
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    10
5097
f2dfbcc676a6 mod_sasl2_bind2: Add explicit dependency on mod_sasl2
Kim Alvefur <zash@zash.se>
parents: 5064
diff changeset
    11
module:depends("sasl2");
f2dfbcc676a6 mod_sasl2_bind2: Add explicit dependency on mod_sasl2
Kim Alvefur <zash@zash.se>
parents: 5064
diff changeset
    12
5033
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    13
-- Advertise what we can do
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    14
5047
17b87fffdb91 mod_sasl2_bind2: Move <inline> into <bind> feature element
Matthew Wild <mwild1@gmail.com>
parents: 5043
diff changeset
    15
module:hook("advertise-sasl-features", function(event)
17b87fffdb91 mod_sasl2_bind2: Move <inline> into <bind> feature element
Matthew Wild <mwild1@gmail.com>
parents: 5043
diff changeset
    16
	local bind = st.stanza("bind", { xmlns = xmlns_bind2 });
17b87fffdb91 mod_sasl2_bind2: Move <inline> into <bind> feature element
Matthew Wild <mwild1@gmail.com>
parents: 5043
diff changeset
    17
	local inline = st.stanza("inline");
5048
f64d834ba744 mod_sasl2, mod_sasl2_bind2: rename event.session -> .origin for consistency
Matthew Wild <mwild1@gmail.com>
parents: 5047
diff changeset
    18
	module:fire_event("advertise-bind-features", { origin = event.origin, features = inline });
5047
17b87fffdb91 mod_sasl2_bind2: Move <inline> into <bind> feature element
Matthew Wild <mwild1@gmail.com>
parents: 5043
diff changeset
    19
	bind:add_direct_child(inline);
5033
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    20
5047
17b87fffdb91 mod_sasl2_bind2: Move <inline> into <bind> feature element
Matthew Wild <mwild1@gmail.com>
parents: 5043
diff changeset
    21
	event.features:add_direct_child(bind);
5033
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    22
end, 1);
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    23
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    24
-- Helper to actually bind a resource to a session
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    25
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    26
local function do_bind(session, bind_request)
5184
6361afcda1a3 mod_sasl2_bind2: Support for SASL handlers forcing a specific resource
Matthew Wild <mwild1@gmail.com>
parents: 5097
diff changeset
    27
	local resource = session.sasl_handler.resource;
5033
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    28
5184
6361afcda1a3 mod_sasl2_bind2: Support for SASL handlers forcing a specific resource
Matthew Wild <mwild1@gmail.com>
parents: 5097
diff changeset
    29
	if not resource then
6361afcda1a3 mod_sasl2_bind2: Support for SASL handlers forcing a specific resource
Matthew Wild <mwild1@gmail.com>
parents: 5097
diff changeset
    30
		local client_name_tag = bind_request:get_child_text("tag");
6361afcda1a3 mod_sasl2_bind2: Support for SASL handlers forcing a specific resource
Matthew Wild <mwild1@gmail.com>
parents: 5097
diff changeset
    31
		if client_name_tag then
6361afcda1a3 mod_sasl2_bind2: Support for SASL handlers forcing a specific resource
Matthew Wild <mwild1@gmail.com>
parents: 5097
diff changeset
    32
			local client_id = session.client_id;
6361afcda1a3 mod_sasl2_bind2: Support for SASL handlers forcing a specific resource
Matthew Wild <mwild1@gmail.com>
parents: 5097
diff changeset
    33
			local tag_suffix = client_id and base64.encode(sha1(client_id):sub(1, 9)) or id.medium();
6361afcda1a3 mod_sasl2_bind2: Support for SASL handlers forcing a specific resource
Matthew Wild <mwild1@gmail.com>
parents: 5097
diff changeset
    34
			resource = ("%s~%s"):format(client_name_tag, tag_suffix);
6361afcda1a3 mod_sasl2_bind2: Support for SASL handlers forcing a specific resource
Matthew Wild <mwild1@gmail.com>
parents: 5097
diff changeset
    35
		end
5033
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    36
	end
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    37
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    38
	local success, err_type, err, err_msg = sm_bind_resource(session, resource);
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    39
	if not success then
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    40
		session.log("debug", "Resource bind failed: %s", err_msg or err);
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    41
		return nil, { type = err_type, condition = err, text = err_msg };
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    42
	end
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    43
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    44
	session.log("debug", "Resource bound: %s", session.full_jid);
5050
904dde7be981 mod_sasl2_bind2: Remove deprecated <jid> element from <bound>
Matthew Wild <mwild1@gmail.com>
parents: 5049
diff changeset
    45
	return st.stanza("bound", { xmlns = xmlns_bind2 });
5033
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    46
end
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    47
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    48
-- Enable inline features requested by the client
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    49
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    50
local function enable_features(session, bind_request, bind_result)
5037
9afd98178011 mod_sasl2_bind2: Fix event name
Matthew Wild <mwild1@gmail.com>
parents: 5036
diff changeset
    51
	module:fire_event("enable-bind-features", {
5033
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    52
		session = session;
5064
bc491065c221 mod_sasl2_bind2, mod_sasl2_sm: Remove bind2 <features/> wrapper element
Matthew Wild <mwild1@gmail.com>
parents: 5051
diff changeset
    53
		request = bind_request;
5033
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    54
		result = bind_result;
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    55
	});
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    56
end
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    57
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    58
-- SASL 2 integration
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    59
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    60
module:hook_tag(xmlns_sasl2, "authenticate", function (session, auth)
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    61
	-- Cache action for future processing (after auth success)
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    62
	session.sasl2_bind_request = auth:child_with_ns(xmlns_bind2);
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    63
end, 100);
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    64
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    65
module:hook("sasl2/c2s/success", function (event)
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    66
	local session = event.session;
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    67
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    68
	local bind_request = session.sasl2_bind_request;
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    69
	if not bind_request then return; end -- No bind requested
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    70
	session.sasl2_bind_request = nil;
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    71
5041
8a8100fff580 mod_sasl2_bind2, mod_sasl2_sm: Move sasl2_sm_success to session
Matthew Wild <mwild1@gmail.com>
parents: 5040
diff changeset
    72
	local sm_success = session.sasl2_sm_success;
5033
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    73
	if sm_success and sm_success.type == "resumed" then
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    74
		return; -- No need to bind a resource
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    75
	end
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    76
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    77
	local bind_result, err = do_bind(session, bind_request);
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    78
	if not bind_result then
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    79
		bind_result = st.stanza("failed", { xmlns = xmlns_bind2 })
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    80
			:add_error(err);
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    81
	else
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    82
		enable_features(session, bind_request, bind_result);
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    83
	end
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    84
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    85
	event.success:add_child(bind_result);
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    86
end, 100);
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    87
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    88
-- Inline features
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    89
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    90
module:hook("advertise-bind-features", function (event)
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    91
	local features = event.features;
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    92
	features:tag("feature", { var = "urn:xmpp:carbons:2" }):up();
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    93
	features:tag("feature", { var = "urn:xmpp:csi:0" }):up();
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    94
end);
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    95
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    96
module:hook("enable-bind-features", function (event)
5064
bc491065c221 mod_sasl2_bind2, mod_sasl2_sm: Remove bind2 <features/> wrapper element
Matthew Wild <mwild1@gmail.com>
parents: 5051
diff changeset
    97
	local session, request = event.session, event.request;
5033
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    98
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    99
	-- Carbons
5064
bc491065c221 mod_sasl2_bind2, mod_sasl2_sm: Remove bind2 <features/> wrapper element
Matthew Wild <mwild1@gmail.com>
parents: 5051
diff changeset
   100
	if request:get_child("enable", "urn:xmpp:carbons:2") then
5040
9ef5625d0d39 mod_sasl2_bind2: Indicate to the client when carbons has been enabled
Matthew Wild <mwild1@gmail.com>
parents: 5037
diff changeset
   101
		session.want_carbons = true;
9ef5625d0d39 mod_sasl2_bind2: Indicate to the client when carbons has been enabled
Matthew Wild <mwild1@gmail.com>
parents: 5037
diff changeset
   102
		event.result:tag("enabled", { xmlns = "urn:xmpp:carbons:2" }):up();
9ef5625d0d39 mod_sasl2_bind2: Indicate to the client when carbons has been enabled
Matthew Wild <mwild1@gmail.com>
parents: 5037
diff changeset
   103
	end
5033
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   104
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   105
	-- CSI
5064
bc491065c221 mod_sasl2_bind2, mod_sasl2_sm: Remove bind2 <features/> wrapper element
Matthew Wild <mwild1@gmail.com>
parents: 5051
diff changeset
   106
	local csi_state_tag = request:child_with_ns("urn:xmpp:csi:0");
5033
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   107
	if csi_state_tag then
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   108
		session.state = csi_state_tag.name;
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   109
	end
56b9f0b1409f mod_sasl2_bind: Support for Bind 2.0 with SASL2
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   110
end, 10);