mod_sasl2/mod_sasl2.lua
author Matthew Wild <mwild1@gmail.com>
Fri, 23 Sep 2022 22:41:15 +0100
changeset 5058 62480053c87b
parent 5053 e89aad13a52a
child 5067 53145c6b6b0b
permissions -rw-r--r--
mod_cloud_notify_encrypted: Additional debug logging when enabling/skipping
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
3909
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     1
-- Prosody IM
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     2
-- Copyright (C) 2019 Kim Alvefur
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     3
--
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     4
-- This project is MIT/X11 licensed. Please see the
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     5
-- COPYING file in the source package for more information.
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     6
--
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     7
-- XEP-0388: Extensible SASL Profile
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     8
--
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     9
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    10
local st = require "util.stanza";
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    11
local errors = require "util.error";
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    12
local base64 = require "util.encodings".base64;
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    13
local jid_join = require "util.jid".join;
5042
88980b2dd986 mod_sasl2: Hacky support for channel binding
Matthew Wild <mwild1@gmail.com>
parents: 5032
diff changeset
    14
local set = require "util.set";
3909
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    15
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    16
local usermanager_get_sasl_handler = require "core.usermanager".get_sasl_handler;
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    17
local sm_make_authenticated = require "core.sessionmanager".make_authenticated;
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    18
5043
c0d243b27e64 mod_sasl2, mod_sasl_bind2, mod_sasl2_sm: Bump XEP-0388 namespace
Matthew Wild <mwild1@gmail.com>
parents: 5042
diff changeset
    19
local xmlns_sasl2 = "urn:xmpp:sasl:2";
3909
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    20
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    21
local allow_unencrypted_plain_auth = module:get_option_boolean("allow_unencrypted_plain_auth", false)
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    22
local insecure_mechanisms = module:get_option_set("insecure_sasl_mechanisms", allow_unencrypted_plain_auth and {} or {"PLAIN", "LOGIN"});
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    23
local disabled_mechanisms = module:get_option_set("disable_sasl_mechanisms", { "DIGEST-MD5" });
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    24
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    25
local host = module.host;
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    26
5042
88980b2dd986 mod_sasl2: Hacky support for channel binding
Matthew Wild <mwild1@gmail.com>
parents: 5032
diff changeset
    27
local function tls_unique(self)
88980b2dd986 mod_sasl2: Hacky support for channel binding
Matthew Wild <mwild1@gmail.com>
parents: 5032
diff changeset
    28
	return self.userdata["tls-unique"]:ssl_peerfinished();
88980b2dd986 mod_sasl2: Hacky support for channel binding
Matthew Wild <mwild1@gmail.com>
parents: 5032
diff changeset
    29
end
88980b2dd986 mod_sasl2: Hacky support for channel binding
Matthew Wild <mwild1@gmail.com>
parents: 5032
diff changeset
    30
88980b2dd986 mod_sasl2: Hacky support for channel binding
Matthew Wild <mwild1@gmail.com>
parents: 5032
diff changeset
    31
local function tls_exporter(conn)
88980b2dd986 mod_sasl2: Hacky support for channel binding
Matthew Wild <mwild1@gmail.com>
parents: 5032
diff changeset
    32
	if not conn.ssl_exportkeyingmaterial then return end
88980b2dd986 mod_sasl2: Hacky support for channel binding
Matthew Wild <mwild1@gmail.com>
parents: 5032
diff changeset
    33
	return conn:ssl_exportkeyingmaterial("EXPORTER-Channel-Binding", 32, "");
88980b2dd986 mod_sasl2: Hacky support for channel binding
Matthew Wild <mwild1@gmail.com>
parents: 5032
diff changeset
    34
end
88980b2dd986 mod_sasl2: Hacky support for channel binding
Matthew Wild <mwild1@gmail.com>
parents: 5032
diff changeset
    35
88980b2dd986 mod_sasl2: Hacky support for channel binding
Matthew Wild <mwild1@gmail.com>
parents: 5032
diff changeset
    36
local function sasl_tls_exporter(self)
88980b2dd986 mod_sasl2: Hacky support for channel binding
Matthew Wild <mwild1@gmail.com>
parents: 5032
diff changeset
    37
	return tls_exporter(self.userdata["tls-exporter"]);
88980b2dd986 mod_sasl2: Hacky support for channel binding
Matthew Wild <mwild1@gmail.com>
parents: 5032
diff changeset
    38
end
88980b2dd986 mod_sasl2: Hacky support for channel binding
Matthew Wild <mwild1@gmail.com>
parents: 5032
diff changeset
    39
3909
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    40
module:hook("stream-features", function(event)
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    41
	local origin, features = event.origin, event.features;
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    42
	local log = origin.log or module._log;
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    43
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    44
	if origin.type ~= "c2s_unauthed" then
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    45
		log("debug", "Already authenticated");
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    46
		return
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    47
	end
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    48
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    49
	local sasl_handler = usermanager_get_sasl_handler(host, origin)
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    50
	origin.sasl_handler = sasl_handler;
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    51
5042
88980b2dd986 mod_sasl2: Hacky support for channel binding
Matthew Wild <mwild1@gmail.com>
parents: 5032
diff changeset
    52
	local channel_bindings = set.new()
88980b2dd986 mod_sasl2: Hacky support for channel binding
Matthew Wild <mwild1@gmail.com>
parents: 5032
diff changeset
    53
	if origin.encrypted then
88980b2dd986 mod_sasl2: Hacky support for channel binding
Matthew Wild <mwild1@gmail.com>
parents: 5032
diff changeset
    54
		-- check whether LuaSec has the nifty binding to the function needed for tls-unique
88980b2dd986 mod_sasl2: Hacky support for channel binding
Matthew Wild <mwild1@gmail.com>
parents: 5032
diff changeset
    55
		-- FIXME: would be nice to have this check only once and not for every socket
88980b2dd986 mod_sasl2: Hacky support for channel binding
Matthew Wild <mwild1@gmail.com>
parents: 5032
diff changeset
    56
		if sasl_handler.add_cb_handler then
88980b2dd986 mod_sasl2: Hacky support for channel binding
Matthew Wild <mwild1@gmail.com>
parents: 5032
diff changeset
    57
			local info = origin.conn:ssl_info();
88980b2dd986 mod_sasl2: Hacky support for channel binding
Matthew Wild <mwild1@gmail.com>
parents: 5032
diff changeset
    58
			if info and info.protocol == "TLSv1.3" then
88980b2dd986 mod_sasl2: Hacky support for channel binding
Matthew Wild <mwild1@gmail.com>
parents: 5032
diff changeset
    59
				log("debug", "Channel binding 'tls-unique' undefined in context of TLS 1.3");
88980b2dd986 mod_sasl2: Hacky support for channel binding
Matthew Wild <mwild1@gmail.com>
parents: 5032
diff changeset
    60
				if tls_exporter(origin.conn) then
88980b2dd986 mod_sasl2: Hacky support for channel binding
Matthew Wild <mwild1@gmail.com>
parents: 5032
diff changeset
    61
					log("debug", "Channel binding 'tls-exporter' supported");
88980b2dd986 mod_sasl2: Hacky support for channel binding
Matthew Wild <mwild1@gmail.com>
parents: 5032
diff changeset
    62
					sasl_handler:add_cb_handler("tls-exporter", sasl_tls_exporter);
88980b2dd986 mod_sasl2: Hacky support for channel binding
Matthew Wild <mwild1@gmail.com>
parents: 5032
diff changeset
    63
					channel_bindings:add("tls-exporter");
88980b2dd986 mod_sasl2: Hacky support for channel binding
Matthew Wild <mwild1@gmail.com>
parents: 5032
diff changeset
    64
				end
88980b2dd986 mod_sasl2: Hacky support for channel binding
Matthew Wild <mwild1@gmail.com>
parents: 5032
diff changeset
    65
			elseif origin.conn.ssl_peerfinished and origin.conn:ssl_peerfinished() then
88980b2dd986 mod_sasl2: Hacky support for channel binding
Matthew Wild <mwild1@gmail.com>
parents: 5032
diff changeset
    66
				log("debug", "Channel binding 'tls-unique' supported");
88980b2dd986 mod_sasl2: Hacky support for channel binding
Matthew Wild <mwild1@gmail.com>
parents: 5032
diff changeset
    67
				sasl_handler:add_cb_handler("tls-unique", tls_unique);
88980b2dd986 mod_sasl2: Hacky support for channel binding
Matthew Wild <mwild1@gmail.com>
parents: 5032
diff changeset
    68
				channel_bindings:add("tls-unique");
88980b2dd986 mod_sasl2: Hacky support for channel binding
Matthew Wild <mwild1@gmail.com>
parents: 5032
diff changeset
    69
			else
88980b2dd986 mod_sasl2: Hacky support for channel binding
Matthew Wild <mwild1@gmail.com>
parents: 5032
diff changeset
    70
				log("debug", "Channel binding 'tls-unique' not supported (by LuaSec?)");
88980b2dd986 mod_sasl2: Hacky support for channel binding
Matthew Wild <mwild1@gmail.com>
parents: 5032
diff changeset
    71
			end
88980b2dd986 mod_sasl2: Hacky support for channel binding
Matthew Wild <mwild1@gmail.com>
parents: 5032
diff changeset
    72
			sasl_handler["userdata"] = {
88980b2dd986 mod_sasl2: Hacky support for channel binding
Matthew Wild <mwild1@gmail.com>
parents: 5032
diff changeset
    73
				["tls-unique"] = origin.conn;
88980b2dd986 mod_sasl2: Hacky support for channel binding
Matthew Wild <mwild1@gmail.com>
parents: 5032
diff changeset
    74
				["tls-exporter"] = origin.conn;
88980b2dd986 mod_sasl2: Hacky support for channel binding
Matthew Wild <mwild1@gmail.com>
parents: 5032
diff changeset
    75
			};
88980b2dd986 mod_sasl2: Hacky support for channel binding
Matthew Wild <mwild1@gmail.com>
parents: 5032
diff changeset
    76
		else
88980b2dd986 mod_sasl2: Hacky support for channel binding
Matthew Wild <mwild1@gmail.com>
parents: 5032
diff changeset
    77
			log("debug", "Channel binding not supported by SASL handler");
88980b2dd986 mod_sasl2: Hacky support for channel binding
Matthew Wild <mwild1@gmail.com>
parents: 5032
diff changeset
    78
		end
3909
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    79
	end
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    80
5043
c0d243b27e64 mod_sasl2, mod_sasl_bind2, mod_sasl2_sm: Bump XEP-0388 namespace
Matthew Wild <mwild1@gmail.com>
parents: 5042
diff changeset
    81
	local mechanisms = st.stanza("authentication", { xmlns = xmlns_sasl2 });
3909
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    82
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    83
	local available_mechanisms = sasl_handler:mechanisms()
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    84
	for mechanism in pairs(available_mechanisms) do
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    85
		if disabled_mechanisms:contains(mechanism) then
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    86
			log("debug", "Not offering disabled mechanism %s", mechanism);
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    87
		elseif not origin.secure and insecure_mechanisms:contains(mechanism) then
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    88
			log("debug", "Not offering mechanism %s on insecure connection", mechanism);
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    89
		else
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    90
			log("debug", "Offering mechanism %s", mechanism);
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    91
			mechanisms:text_tag("mechanism", mechanism);
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    92
		end
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    93
	end
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    94
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    95
	features:add_direct_child(mechanisms);
5032
1f2d2bfd29dd mod_sasl2: Add event for other modules to advertise inline features
Matthew Wild <mwild1@gmail.com>
parents: 5029
diff changeset
    96
5046
166fd192f39c mod_sasl2: Move <inline/> into <authentication>
Matthew Wild <mwild1@gmail.com>
parents: 5045
diff changeset
    97
	local inline = st.stanza("inline");
5048
f64d834ba744 mod_sasl2, mod_sasl2_bind2: rename event.session -> .origin for consistency
Matthew Wild <mwild1@gmail.com>
parents: 5046
diff changeset
    98
	module:fire_event("advertise-sasl-features", { origin = origin, features = inline });
5046
166fd192f39c mod_sasl2: Move <inline/> into <authentication>
Matthew Wild <mwild1@gmail.com>
parents: 5045
diff changeset
    99
	mechanisms:add_direct_child(inline);
3909
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   100
end, 1);
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   101
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   102
local function handle_status(session, status, ret, err_msg)
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   103
	local err = nil;
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   104
	if status == "error" then
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   105
		ret, err = nil, ret;
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   106
		if not errors.is_err(err) then
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   107
			err = errors.new({ condition = err, text = err_msg }, { session = session });
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   108
		end
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   109
	end
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   110
5022
ed2a9a4c4f01 mod_sasl2: Return status from event handlers
Matthew Wild <mwild1@gmail.com>
parents: 4800
diff changeset
   111
	return module:fire_event("sasl2/"..session.base_type.."/"..status, {
3909
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   112
			session = session,
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   113
			message = ret;
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   114
			error = err;
5029
fd154db7c8fc mod_sasl2: Fix handling of various failure/error cases
Matthew Wild <mwild1@gmail.com>
parents: 5027
diff changeset
   115
			error_text = err_msg;
3909
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   116
		});
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   117
end
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   118
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   119
module:hook("sasl2/c2s/failure", function (event)
5029
fd154db7c8fc mod_sasl2: Fix handling of various failure/error cases
Matthew Wild <mwild1@gmail.com>
parents: 5027
diff changeset
   120
	local session, condition, text = event.session, event.message, event.error_text;
fd154db7c8fc mod_sasl2: Fix handling of various failure/error cases
Matthew Wild <mwild1@gmail.com>
parents: 5027
diff changeset
   121
	local failure = st.stanza("failure", { xmlns = xmlns_sasl2 })
5045
afa09e069afb mod_sasl2: Fix missing namespace on failure condition (thanks tmolitor)
Matthew Wild <mwild1@gmail.com>
parents: 5043
diff changeset
   122
		:tag(condition, { xmlns = "urn:ietf:params:xml:ns:xmpp-sasl" }):up();
5029
fd154db7c8fc mod_sasl2: Fix handling of various failure/error cases
Matthew Wild <mwild1@gmail.com>
parents: 5027
diff changeset
   123
	if text then
fd154db7c8fc mod_sasl2: Fix handling of various failure/error cases
Matthew Wild <mwild1@gmail.com>
parents: 5027
diff changeset
   124
		failure:text_tag("text", text);
fd154db7c8fc mod_sasl2: Fix handling of various failure/error cases
Matthew Wild <mwild1@gmail.com>
parents: 5027
diff changeset
   125
	end
fd154db7c8fc mod_sasl2: Fix handling of various failure/error cases
Matthew Wild <mwild1@gmail.com>
parents: 5027
diff changeset
   126
	session.send(failure);
fd154db7c8fc mod_sasl2: Fix handling of various failure/error cases
Matthew Wild <mwild1@gmail.com>
parents: 5027
diff changeset
   127
	return true;
fd154db7c8fc mod_sasl2: Fix handling of various failure/error cases
Matthew Wild <mwild1@gmail.com>
parents: 5027
diff changeset
   128
end);
fd154db7c8fc mod_sasl2: Fix handling of various failure/error cases
Matthew Wild <mwild1@gmail.com>
parents: 5027
diff changeset
   129
fd154db7c8fc mod_sasl2: Fix handling of various failure/error cases
Matthew Wild <mwild1@gmail.com>
parents: 5027
diff changeset
   130
module:hook("sasl2/c2s/error", function (event)
3909
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   131
	local session = event.session
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   132
	session.send(st.stanza("failure", { xmlns = xmlns_sasl2 })
5029
fd154db7c8fc mod_sasl2: Fix handling of various failure/error cases
Matthew Wild <mwild1@gmail.com>
parents: 5027
diff changeset
   133
		:tag(event.error and event.error.condition));
3909
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   134
	return true;
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   135
end);
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   136
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   137
module:hook("sasl2/c2s/challenge", function (event)
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   138
	local session = event.session;
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   139
	session.send(st.stanza("challenge", { xmlns = xmlns_sasl2 })
5023
c83ce822f105 mod_sasl2: Fix <challenge> generation
Matthew Wild <mwild1@gmail.com>
parents: 5022
diff changeset
   140
		:text(base64.encode(event.message)));
5024
6a36dae4a88d mod_sasl2: Return true to indicate challenge was handled successfully
Matthew Wild <mwild1@gmail.com>
parents: 5023
diff changeset
   141
	return true;
3909
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   142
end);
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   143
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   144
module:hook("sasl2/c2s/success", function (event)
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   145
	local session = event.session
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   146
	local ok, err = sm_make_authenticated(session, session.sasl_handler.username);
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   147
	if not ok then
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   148
		handle_status(session, "failure", err);
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   149
		return true;
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   150
	end
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   151
	event.success = st.stanza("success", { xmlns = xmlns_sasl2 });
5027
90772a9c92a0 mod_sasl2: Include additional-data in SASL success response
Matthew Wild <mwild1@gmail.com>
parents: 5025
diff changeset
   152
	if event.message then
90772a9c92a0 mod_sasl2: Include additional-data in SASL success response
Matthew Wild <mwild1@gmail.com>
parents: 5025
diff changeset
   153
		event.success:text_tag("additional-data", base64.encode(event.message));
90772a9c92a0 mod_sasl2: Include additional-data in SASL success response
Matthew Wild <mwild1@gmail.com>
parents: 5025
diff changeset
   154
	end
3909
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   155
end, 1000);
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   156
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   157
module:hook("sasl2/c2s/success", function (event)
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   158
	local session = event.session
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   159
	event.success:text_tag("authorization-identifier", jid_join(session.username, session.host, session.resource));
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   160
	session.send(event.success);
5053
e89aad13a52a mod_sasl2: Further break up success handling, into pre/post stream:features
Matthew Wild <mwild1@gmail.com>
parents: 5052
diff changeset
   161
end, -1000);
e89aad13a52a mod_sasl2: Further break up success handling, into pre/post stream:features
Matthew Wild <mwild1@gmail.com>
parents: 5052
diff changeset
   162
e89aad13a52a mod_sasl2: Further break up success handling, into pre/post stream:features
Matthew Wild <mwild1@gmail.com>
parents: 5052
diff changeset
   163
module:hook("sasl2/c2s/success", function (event)
e89aad13a52a mod_sasl2: Further break up success handling, into pre/post stream:features
Matthew Wild <mwild1@gmail.com>
parents: 5052
diff changeset
   164
	local session = event.session;
3909
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   165
	local features = st.stanza("stream:features");
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   166
	module:fire_event("stream-features", { origin = session, features = features });
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   167
	session.send(features);
5053
e89aad13a52a mod_sasl2: Further break up success handling, into pre/post stream:features
Matthew Wild <mwild1@gmail.com>
parents: 5052
diff changeset
   168
end, -1500);
3909
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   169
5025
f62b091b1c81 mod_sasl2: Eventually return true from success handler
Matthew Wild <mwild1@gmail.com>
parents: 5024
diff changeset
   170
-- The gap here is to allow modules to do stuff to the stream after the stanza
f62b091b1c81 mod_sasl2: Eventually return true from success handler
Matthew Wild <mwild1@gmail.com>
parents: 5024
diff changeset
   171
-- is sent, but before we proceed with anything else. This is expected to be
f62b091b1c81 mod_sasl2: Eventually return true from success handler
Matthew Wild <mwild1@gmail.com>
parents: 5024
diff changeset
   172
-- a common pattern with SASL2, which allows atomic negotiation of a bunch of
f62b091b1c81 mod_sasl2: Eventually return true from success handler
Matthew Wild <mwild1@gmail.com>
parents: 5024
diff changeset
   173
-- stream features.
f62b091b1c81 mod_sasl2: Eventually return true from success handler
Matthew Wild <mwild1@gmail.com>
parents: 5024
diff changeset
   174
module:hook("sasl2/c2s/success", function (event) --luacheck: ignore 212/event
f62b091b1c81 mod_sasl2: Eventually return true from success handler
Matthew Wild <mwild1@gmail.com>
parents: 5024
diff changeset
   175
	return true;
f62b091b1c81 mod_sasl2: Eventually return true from success handler
Matthew Wild <mwild1@gmail.com>
parents: 5024
diff changeset
   176
end, -2000);
f62b091b1c81 mod_sasl2: Eventually return true from success handler
Matthew Wild <mwild1@gmail.com>
parents: 5024
diff changeset
   177
3909
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   178
local function process_cdata(session, cdata)
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   179
	if cdata then
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   180
		cdata = base64.decode(cdata);
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   181
		if not cdata then
5029
fd154db7c8fc mod_sasl2: Fix handling of various failure/error cases
Matthew Wild <mwild1@gmail.com>
parents: 5027
diff changeset
   182
			return handle_status(session, "failure", "incorrect-encoding");
3909
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   183
		end
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   184
	end
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   185
	return handle_status(session, session.sasl_handler:process(cdata));
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   186
end
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   187
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   188
module:hook_tag(xmlns_sasl2, "authenticate", function (session, auth)
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   189
	local sasl_handler = session.sasl_handler;
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   190
	if not sasl_handler then
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   191
		sasl_handler = usermanager_get_sasl_handler(host, session);
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   192
		session.sasl_handler = sasl_handler;
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   193
	end
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   194
	local mechanism = assert(auth.attr.mechanism);
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   195
	if not sasl_handler:select(mechanism) then
5029
fd154db7c8fc mod_sasl2: Fix handling of various failure/error cases
Matthew Wild <mwild1@gmail.com>
parents: 5027
diff changeset
   196
		return handle_status(session, "failure", "invalid-mechanism");
3909
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   197
	end
5052
3697d19d5fd9 mod_sasl2: Store client id if provided
Matthew Wild <mwild1@gmail.com>
parents: 5048
diff changeset
   198
	local user_agent = auth:get_child("user-agent");
3697d19d5fd9 mod_sasl2: Store client id if provided
Matthew Wild <mwild1@gmail.com>
parents: 5048
diff changeset
   199
	if user_agent then
3697d19d5fd9 mod_sasl2: Store client id if provided
Matthew Wild <mwild1@gmail.com>
parents: 5048
diff changeset
   200
		session.client_id = user_agent.attr.id;
3697d19d5fd9 mod_sasl2: Store client id if provided
Matthew Wild <mwild1@gmail.com>
parents: 5048
diff changeset
   201
	end
3909
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   202
	local initial = auth:get_child_text("initial-response");
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   203
	return process_cdata(session, initial);
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   204
end);
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   205
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   206
module:hook_tag(xmlns_sasl2, "response", function (session, response)
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   207
	local sasl_handler = session.sasl_handler;
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   208
	if not sasl_handler or not sasl_handler.selected then
5029
fd154db7c8fc mod_sasl2: Fix handling of various failure/error cases
Matthew Wild <mwild1@gmail.com>
parents: 5027
diff changeset
   209
		return handle_status(session, "failure", "invalid-mechanism");
3909
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   210
	end
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   211
	return process_cdata(session, response:get_text());
5ae2e865eea0 mod_sasl2: Experimental implementation of XEP-0388
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   212
end);