plugins/tls.lua

Thu, 23 Mar 2023 18:56:32 +0000

author
Matthew Wild <mwild1@gmail.com>
date
Thu, 23 Mar 2023 18:56:32 +0000
changeset 485
c9a144591649
parent 463
98fe3ed54639
permissions
-rw-r--r--

component: Avoid adding to the global stream metatable

This allows component and client connections to be made side-by-side.
Previous to this change, loading this connection module would break the
ability to make client connections, due to overriding stream methods such as
:reopen() and :reset().

A next step would be to share the methods that the two connection modules have
in common.

local verse = require "verse";

local xmlns_tls = "urn:ietf:params:xml:ns:xmpp-tls";

function verse.plugins.tls(stream)
	local function handle_features(features_stanza)
		if stream.authenticated then return; end
		if features_stanza:get_child("starttls", xmlns_tls) and stream.conn.starttls then
			stream:debug("Negotiating TLS...");
			stream:send(verse.stanza("starttls", { xmlns = xmlns_tls }));
			return true;
		elseif not stream.conn.starttls and not stream.secure then
			stream:warn("SSL library (LuaSec) not loaded, so TLS not available");
		elseif not stream.secure then
			stream:debug("Server doesn't offer TLS :(");
		end
	end
	local function handle_tls(tls_status)
		if tls_status.name == "proceed" then
			stream:debug("Server says proceed, handshake starting...");
			local sslctx = verse.tls_builder(".")
				:apply({mode="client", protocol="sslv23", options="no_sslv2",capath="/etc/ssl/certs"})
				:apply(stream.ssl or {});
			stream.conn:starttls(sslctx:build(), true);
		end
	end
	local function handle_status(new_status)
		if new_status == "ssl-handshake-complete" then
			stream.secure = true;
			stream:debug("Re-opening stream...");
			stream:reopen();
		end
	end
	stream:hook("stream-features", handle_features, 400);
	stream:hook("stream/"..xmlns_tls, handle_tls);
	stream:hook("status", handle_status, 400);

	return true;
end

mercurial