Changeset

13817:a5f6943a1abd

Merge 13.0->trunk
author Matthew Wild <mwild1@gmail.com>
date Thu, 03 Apr 2025 15:14:07 +0100
parents 13815:a699d611a0ba (current diff) 13816:4122978f2575 (diff)
children 13820:02856974396a
files
diffstat 13 files changed, 237 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/GNUmakefile	Thu Apr 03 12:04:19 2025 +0100
+++ b/GNUmakefile	Thu Apr 03 15:14:07 2025 +0100
@@ -122,6 +122,9 @@
 	$(RUNWITH) prosodyctl --config ./spec/scansion/prosody.cfg.lua stop \
 	exit $$R
 
+integration-test-tls: all
+	cd ./spec/tls && ./run.sh
+
 coverage:
 	-rm -- luacov.*
 	$(BUSTED) --lua=$(RUNWITH) -c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/spec/tls/README	Thu Apr 03 15:14:07 2025 +0100
@@ -0,0 +1,11 @@
+These tests check that SSL/TLS configuration is working as expected.
+
+Just run ./run.sh in this directory (or from the top level,
+`make integration-test-tls`.
+
+Known issues:
+  - The tests do not thorougly clean up after themselves (certs, logs, etc.).
+    This is partly intentional, so they can be inspected in case of failures.
+  - Certs are regenerated every time. Could be smarter about this. But it also
+    helps to guard against incorrect Prosody instances running and hogging the
+    ports, etc.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/spec/tls/config1/assert.sh	Thu Apr 03 15:14:07 2025 +0100
@@ -0,0 +1,10 @@
+#!/bin/bash
+
+#set -x
+
+. ../lib.sh
+
+expect_cert "certs/example.com.crt" "localhost:5222" "example.com" "xmpp"
+expect_cert "certs/share.example.com.crt" "localhost:5281" "share.example.com" "tls"
+
+exit "$failures"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/spec/tls/config1/prepare.sh	Thu Apr 03 15:14:07 2025 +0100
@@ -0,0 +1,14 @@
+#!/bin/bash
+
+certs="./certs"
+
+for domain in {,share.}example.com; do
+	openssl req -x509 \
+	  -newkey rsa:4096 \
+	  -keyout "${certs}/${domain}.key" \
+	  -out "${certs}/${domain}.crt" \
+	  -sha256 \
+	  -days 365 \
+	  -nodes \
+	  -subj "/CN=${domain}" 2>/dev/null;
+done
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/spec/tls/config1/prosody.cfg.lua	Thu Apr 03 15:14:07 2025 +0100
@@ -0,0 +1,6 @@
+Include "prosody-default.cfg.lua"
+
+VirtualHost "example.com"
+	enabled = true
+
+Component "share.example.com" "http_file_share"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/spec/tls/config2/assert.sh	Thu Apr 03 15:14:07 2025 +0100
@@ -0,0 +1,10 @@
+#!/bin/bash
+
+#set -x
+
+. ../lib.sh
+
+expect_cert "certs/xmpp.example.com.crt" "localhost:5281" "xmpp.example.com" "tls"
+expect_cert "certs/example.com.crt" "localhost:5222" "example.com" "xmpp"
+
+exit "$failures"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/spec/tls/config2/prepare.sh	Thu Apr 03 15:14:07 2025 +0100
@@ -0,0 +1,14 @@
+#!/bin/bash
+
+certs="./certs"
+
+for domain in {,xmpp.}example.com; do
+	openssl req -x509 \
+	  -newkey rsa:4096 \
+	  -keyout "${certs}/${domain}.key" \
+	  -out "${certs}/${domain}.crt" \
+	  -sha256 \
+	  -days 365 \
+	  -nodes \
+	  -subj "/CN=${domain}" 2>/dev/null;
+done
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/spec/tls/config2/prosody.cfg.lua	Thu Apr 03 15:14:07 2025 +0100
@@ -0,0 +1,6 @@
+Include "prosody-default.cfg.lua"
+
+VirtualHost "example.com"
+	enabled = true
+	modules_enabled = { "http" }
+	http_host = "xmpp.example.com"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/spec/tls/config3/assert.sh	Thu Apr 03 15:14:07 2025 +0100
@@ -0,0 +1,25 @@
+#!/bin/bash
+
+#set -x
+
+. ../lib.sh
+
+expect_cert "certs/xmpp.example.com.crt" "localhost:5281" "xmpp.example.com" "tls"
+expect_cert "certs/example.com.crt" "localhost:5222" "example.com" "xmpp"
+expect_cert "certs/example.com.crt" "localhost:5223" "example.com" "xmpps"
+
+# Weirdly configured host, just to test manual override behaviour
+expect_cert "certs/example.com.crt" "localhost:5222" "example.net" "xmpp"
+expect_cert "certs/example.com.crt" "localhost:5222" "example.net" "xmpp"
+expect_cert "certs/example.com.crt" "localhost:5223" "example.net" "tls"
+expect_cert "certs/example.com.crt" "localhost:5281" "example.net" "tls"
+
+# Three domains using a single cert with SANs
+expect_cert "certs/example.org.crt" "localhost:5222" "example.org" "xmpp"
+expect_cert "certs/example.org.crt" "localhost:5223" "example.org" "xmpps"
+expect_cert "certs/example.org.crt" "localhost:5269" "example.org" "xmpp-server"
+expect_cert "certs/example.org.crt" "localhost:5269" "share.example.org" "xmpp-server"
+expect_cert "certs/example.org.crt" "localhost:5269" "groups.example.org" "xmpp-server"
+expect_cert "certs/example.org.crt" "localhost:5281" "share.example.org" "tls"
+
+exit "$failures"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/spec/tls/config3/prepare.sh	Thu Apr 03 15:14:07 2025 +0100
@@ -0,0 +1,28 @@
+#!/bin/bash
+
+certs="./certs"
+
+for domain in {,xmpp.}example.com example.net; do
+	openssl req -x509 \
+	  -newkey rsa:4096 \
+	  -keyout "${certs}/${domain}.key" \
+	  -out "${certs}/${domain}.crt" \
+	  -sha256 \
+	  -days 365 \
+	  -nodes \
+	  -quiet \
+	  -subj "/CN=${domain}" 2>/dev/null;
+done
+
+for domain in example.org; do
+	openssl req -x509 \
+	  -newkey rsa:4096 \
+	  -keyout "${certs}/${domain}.key" \
+	  -out "${certs}/${domain}.crt" \
+	  -sha256 \
+	  -days 365 \
+	  -nodes \
+	  -subj "/CN=${domain}" \
+	  -addext "subjectAltName = DNS:${domain}, DNS:groups.${domain}, DNS:share.${domain}" \
+	  2>/dev/null;
+done
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/spec/tls/config3/prosody.cfg.lua	Thu Apr 03 15:14:07 2025 +0100
@@ -0,0 +1,28 @@
+Include "prosody-default.cfg.lua"
+
+c2s_direct_tls_ports = { 5223 }
+
+VirtualHost "example.com"
+	enabled = true
+	modules_enabled = { "http" }
+	http_host = "xmpp.example.com"
+
+VirtualHost "example.net"
+	ssl = {
+		certificate = "certs/example.com.crt";
+		key = "certs/example.com.key";
+	}
+
+	https_ssl = {
+		certificate = "certs/example.com.crt";
+		key = "certs/example.com.key";
+	}
+
+	c2s_direct_tls_ssl = {
+		certificate = "certs/example.com.crt";
+		key = "certs/example.com.key";
+	}
+
+VirtualHost "example.org"
+Component "share.example.org" "http_file_share"
+Component "groups.example.org" "muc"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/spec/tls/lib.sh	Thu Apr 03 15:14:07 2025 +0100
@@ -0,0 +1,45 @@
+#!/bin/bash
+
+test_name="$(basename "$PWD")"
+export failures=0
+
+get_net_cert () {
+	address="${1?}"
+	sni="${2?}"
+	proto="${3?}"
+	local flags=()
+	case "$proto" in
+		"xmpp") flags=(-starttls xmpp -name "$sni");;
+		"xmpps") flags=(-alpn xmpp-client);;
+		"xmpp-server") flags=(-starttls xmpp-server -name "$sni");;
+		"xmpps-server") flags=(-alpn xmpp-server);;
+		"tls") ;;
+		*) printf "EE: Unknown protocol: %s\n" "$proto" >&2; exit 1;;
+	esac
+	openssl s_client -connect "$address" -servername "$sni" "${flags[@]}" 2>/dev/null </dev/null |  sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p'
+}
+
+get_file_cert () {
+	fn="${1?}"
+	sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' "$fn"
+}
+
+expect_cert () {
+	fn="${1?}"
+	address="${2?}"
+	sni="${3?}"
+	proto="${4?}"
+	net_cert="$(get_net_cert "$address" "$sni" "$proto")"
+	file_cert="$(get_file_cert "$fn")"
+	if [[ "$file_cert" != "$net_cert" ]]; then
+		echo "---"
+		echo "NOT OK: $test_name: Expected $fn on $address (SNI $sni)"
+		echo "Received:"
+		openssl x509 -in <(echo "$net_cert") -text
+		echo "---"
+		failures=1;
+		return 1;
+	fi
+	echo "OK: $test_name: $fn observed on $address (SNI $sni)"
+	return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/spec/tls/run.sh	Thu Apr 03 15:14:07 2025 +0100
@@ -0,0 +1,37 @@
+#!/bin/bash
+
+export LUA_PATH="../../../?.lua;;"
+export LUA_CPATH="../../../?.so;;"
+
+any_failed=0
+
+for config in config*; do
+	echo "# Preparing $config"
+	pushd "$config";
+	cp ../../../prosody.cfg.lua.dist ./prosody-default.cfg.lua
+	echo 'VirtualHost "*" {pidfile = "prosody.pid";log={debug="prosody.log"}}' >> ./prosody-default.cfg.lua
+	ln -s ../../../plugins plugins
+	mkdir -p certs data
+	./prepare.sh
+	../../../prosody -D
+	sleep 1;
+	echo "# Testing $config"
+	./assert.sh
+	status=$?
+	../../../prosodyctl stop
+	rm plugins #prosody-default.cfg.lua
+	popd
+	if [[ "$status" != "0" ]]; then
+		echo -n "NOT ";
+		any_failed=1
+	fi
+	echo "OK: $config";
+done
+
+if [[ "$any_failed" != "0" ]]; then
+	echo "NOT OK: One or more TLS tests failed";
+	exit 1;
+fi
+
+echo "OK: All TLS tests passed";
+exit 0;