plugins/tls.lua

1
local verse = require "verse";
2
 
3
local xmlns_tls = "urn:ietf:params:xml:ns:xmpp-tls";
4
 
5
function verse.plugins.tls(stream)
6
	local function handle_features(features_stanza)
7
		if stream.authenticated then return; end
8
		if features_stanza:get_child("starttls", xmlns_tls) and stream.conn.starttls then
9
			stream:debug("Negotiating TLS...");
10
			stream:send(verse.stanza("starttls", { xmlns = xmlns_tls }));
11
			return true;
12
		elseif not stream.conn.starttls and not stream.secure then
13
			stream:warn("SSL library (LuaSec) not loaded, so TLS not available");
14
		elseif not stream.secure then
15
			stream:debug("Server doesn't offer TLS :(");
16
		end
17
	end
18
	local function handle_tls(tls_status)
19
		if tls_status.name == "proceed" then
20
			stream:debug("Server says proceed, handshake starting...");
21
			local sslctx = verse.tls_builder(".")
22
				:apply({mode="client", protocol="sslv23", options="no_sslv2",capath="/etc/ssl/certs"})
23
				:apply(stream.ssl or {});
24
			stream.conn:starttls(sslctx:build(), true);
25
		end
26
	end
27
	local function handle_status(new_status)
28
		if new_status == "ssl-handshake-complete" then
29
			stream.secure = true;
30
			stream:debug("Re-opening stream...");
31
			stream:reopen();
32
		end
33
	end
34
	stream:hook("stream-features", handle_features, 400);
35
	stream:hook("stream/"..xmlns_tls, handle_tls);
36
	stream:hook("status", handle_status, 400);
37
 
38
	return true;
39
end