diff mod_s2s_v6mesh/mod_s2s_v6mesh.lua @ 6478:bd785f524fd2

mod_s2s_v6mesh: Fix various bugs, s2s auth policies now work as expected
author Matthew Wild <mwild1@gmail.com>
date Wed, 18 Mar 2026 18:54:30 +0000
parents 88852e4f81bf
children 771944f2a7c7
line wrap: on
line diff
--- a/mod_s2s_v6mesh/mod_s2s_v6mesh.lua	Tue Mar 17 23:08:39 2026 +0000
+++ b/mod_s2s_v6mesh/mod_s2s_v6mesh.lua	Wed Mar 18 18:54:30 2026 +0000
@@ -1,5 +1,7 @@
 --% requires: s2sout-pre-connect-event
 
+module:set_global();
+
 local basic_resolver = require "net.resolvers.basic";
 local base32 = module:require("base32");
 local net = require "prosody.util.net";
@@ -36,47 +38,57 @@
 	return net.ntop(raw), raw;
 end
 
-module:hook("s2sout-pre-connect", function(event)
-	local host = event.session.to_host;
-	local dom = host:match("([%w-]+)%.v6%.alt$");
-	if not dom then return; end
+function module.add_host(host_module)
+	host_module:hook("s2sout-pre-connect", function(event)
+		local session = event.session;
+		local host = session.to_host;
+		local dom = host:match("([%w-]+)%.v6%.alt$");
+		if not dom then return; end
 
-	local target_ip = lookup(dom);
-	if not target_ip then
-		return;
-	end
+		local target_ip = lookup(dom);
+		if not target_ip then
+			return;
+		end
 
-	module:log("debug", "Resolved %s to [%s]:%d", target_ip, 5269);
+		host_module:log("debug", "Resolved %s to [%s]:%d", host, target_ip, 5269);
 
-	event.resolver = basic_resolver.new(target_ip, 5269, "tcp", {});
+		event.resolver = basic_resolver.new(target_ip, 5269, "tcp", {});
 
-	if is_secure_range(ip.new_ip(target_ip, "IPv6")) then
-		module:log("debug", "Treating non-TLS connection to %s as secure because it's in a secure IP range", host);
-		event.session.secure = true;
-	end
-end);
+		if is_secure_range(ip.new_ip(target_ip, "IPv6")) then
+			host_module:log("debug", "Treating non-TLS connection to %s as secure because it's in a secure IP range", host);
+			session.secure = true;
+			session.authenticated_remote = true;
+			session.cert_chain_status = "valid";
+			session.cert_identity_status = "valid";
+		end
+	end);
 
-module:hook("s2s-stream-features", function (event)
-	local host = event.origin.from_host;
+	host_module:hook("s2s-stream-features", function (event)
+		local session = event.origin;
+		local host = session.from_host;
 
-	local dom = host:match("([%w-]+)%.v6%.alt$");
-	if not dom then
-		return;
-	end
+		local dom = host:match("([%w-]+)%.v6%.alt$");
+		if not dom then
+			return;
+		end
 
-	local remote_ip = ip.new_ip(event.origin.ip);
+		local remote_ip = ip.new_ip(session.ip);
 
-	if select(2, lookup(dom)) ~= remote_ip.packed then
-		module:log("warn", "Rejecting incoming connection from %s: unexpected IP %s", host, remote_ip);
-		event.origin:close({ condition = "not-authorized", text = "Hostname does not match IP address" });
-		return;
-	end
+		if select(2, lookup(dom)) ~= remote_ip.packed then
+			host_module:log("warn", "Rejecting incoming connection from %s: unexpected IP %s", host, remote_ip);
+			session:close({ condition = "not-authorized", text = "Hostname does not match IP address" });
+			return;
+		end
 
-	if is_secure_range(remote_ip) then
-		module:log("debug", "Treating non-TLS connection from %s as secure because it's in a secure IP range", host);
-		event.origin.secure = true;
-	end
-end, 100);
+		if is_secure_range(remote_ip) then
+			host_module:log("debug", "Treating non-TLS connection from %s as secure because it's in a secure IP range", host);
+			session.secure = true;
+			session.authenticated_remote = true;
+			session.cert_chain_status = "valid";
+			session.cert_identity_status = "valid";
+		end
+	end, 200);
+end
 
 module:hook("s2s-check-certificate", function(event)
 	local session, host = event.session, event.host;
@@ -97,7 +109,7 @@
 	session.cert_chain_status = "valid";
 	session.cert_identity_status = "valid";
 	return true;
-end, 100);
+end, 600);
 
 module:add_item("shell-command", {
 	section = "v6alt";
@@ -105,11 +117,9 @@
 	name = "get_domain";
 	desc = "Convert an IPv6 address to a .v6.alt domain";
 	args = {
-		{ name = "host", type = "string" };
 		{ name = "ip", type = "string" };
 	};
-	host_selector = "host";
-	handler = function(self, host, ip_str) --luacheck: ignore 212/self 212/host
+	handler = function(self, ip_str) --luacheck: ignore 212/self 212/host
 		local user_ip = ip.new_ip(ip_str, "IPv6");
 		if not user_ip then
 			return nil, "Invalid IP address: "..tostring(ip_str);
@@ -135,11 +145,9 @@
 	name = "get_ip";
 	desc = "Convert a .v6.alt domain to an IP address";
 	args = {
-		{ name = "host", type = "string" };
 		{ name = "domain", type = "string" };
 	};
-	host_selector = "host";
-	handler = function(self, host, domain) --luacheck: ignore 212/self 212/host
+	handler = function(self, domain) --luacheck: ignore 212/self 212/host
 		local encoded = domain:match("([%w-]+)%.v6%.alt$");
 		if not encoded then
 			return nil, "Invalid domain: "..domain;
@@ -155,11 +163,9 @@
 	name = "is_secure_range";
 	desc = "Check whether an IP address is considered secure";
 	args = {
-		{ name = "host", type = "string" };
 		{ name = "ip", type = "string" };
 	};
-	host_selector = "host";
-	handler = function(self, host, ip_str) --luacheck: ignore 212/self 212/host
+	handler = function(self, ip_str) --luacheck: ignore 212/self 212/host
 		local user_ip = ip.new_ip(ip_str, "IPv6");
 		if not user_ip then
 			return nil, "Invalid IP address: "..tostring(ip_str);