aboutsummaryrefslogtreecommitdiffstats
path: root/spec
diff options
context:
space:
mode:
authorMatthew Wild <mwild1@gmail.com>2025-04-03 15:11:58 +0100
committerMatthew Wild <mwild1@gmail.com>2025-04-03 15:11:58 +0100
commite6849bb76ee3682ece53d7434bb1e94a89c91cbc (patch)
treeb8fa5ad7b955d5735bcbd8cc6ab257acf1729d0a /spec
parent3905dcae02962457bfa8d426c472944358cfcf20 (diff)
downloadprosody-e6849bb76ee3682ece53d7434bb1e94a89c91cbc.tar.gz
prosody-e6849bb76ee3682ece53d7434bb1e94a89c91cbc.zip
spec/tls: Add TLS/certificate integration tests
These tests help to verify that various configurations translate into the expected running TLS setups. Specifically right now we are checking the correct certificate is served.
Diffstat (limited to 'spec')
-rw-r--r--spec/tls/README11
-rwxr-xr-xspec/tls/config1/assert.sh10
-rwxr-xr-xspec/tls/config1/prepare.sh14
-rw-r--r--spec/tls/config1/prosody.cfg.lua6
-rwxr-xr-xspec/tls/config2/assert.sh10
-rwxr-xr-xspec/tls/config2/prepare.sh14
-rw-r--r--spec/tls/config2/prosody.cfg.lua6
-rwxr-xr-xspec/tls/config3/assert.sh25
-rwxr-xr-xspec/tls/config3/prepare.sh28
-rw-r--r--spec/tls/config3/prosody.cfg.lua28
-rw-r--r--spec/tls/lib.sh45
-rwxr-xr-xspec/tls/run.sh37
12 files changed, 234 insertions, 0 deletions
diff --git a/spec/tls/README b/spec/tls/README
new file mode 100644
index 00000000..58201728
--- /dev/null
+++ b/spec/tls/README
@@ -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.
diff --git a/spec/tls/config1/assert.sh b/spec/tls/config1/assert.sh
new file mode 100755
index 00000000..f7d41c26
--- /dev/null
+++ b/spec/tls/config1/assert.sh
@@ -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"
diff --git a/spec/tls/config1/prepare.sh b/spec/tls/config1/prepare.sh
new file mode 100755
index 00000000..a8ec2822
--- /dev/null
+++ b/spec/tls/config1/prepare.sh
@@ -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
diff --git a/spec/tls/config1/prosody.cfg.lua b/spec/tls/config1/prosody.cfg.lua
new file mode 100644
index 00000000..9e94de58
--- /dev/null
+++ b/spec/tls/config1/prosody.cfg.lua
@@ -0,0 +1,6 @@
+Include "prosody-default.cfg.lua"
+
+VirtualHost "example.com"
+ enabled = true
+
+Component "share.example.com" "http_file_share"
diff --git a/spec/tls/config2/assert.sh b/spec/tls/config2/assert.sh
new file mode 100755
index 00000000..d1af0f51
--- /dev/null
+++ b/spec/tls/config2/assert.sh
@@ -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"
diff --git a/spec/tls/config2/prepare.sh b/spec/tls/config2/prepare.sh
new file mode 100755
index 00000000..1d67af4e
--- /dev/null
+++ b/spec/tls/config2/prepare.sh
@@ -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
diff --git a/spec/tls/config2/prosody.cfg.lua b/spec/tls/config2/prosody.cfg.lua
new file mode 100644
index 00000000..a5728516
--- /dev/null
+++ b/spec/tls/config2/prosody.cfg.lua
@@ -0,0 +1,6 @@
+Include "prosody-default.cfg.lua"
+
+VirtualHost "example.com"
+ enabled = true
+ modules_enabled = { "http" }
+ http_host = "xmpp.example.com"
diff --git a/spec/tls/config3/assert.sh b/spec/tls/config3/assert.sh
new file mode 100755
index 00000000..e36f7fb1
--- /dev/null
+++ b/spec/tls/config3/assert.sh
@@ -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"
diff --git a/spec/tls/config3/prepare.sh b/spec/tls/config3/prepare.sh
new file mode 100755
index 00000000..89269d73
--- /dev/null
+++ b/spec/tls/config3/prepare.sh
@@ -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
diff --git a/spec/tls/config3/prosody.cfg.lua b/spec/tls/config3/prosody.cfg.lua
new file mode 100644
index 00000000..a92dbfa8
--- /dev/null
+++ b/spec/tls/config3/prosody.cfg.lua
@@ -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"
diff --git a/spec/tls/lib.sh b/spec/tls/lib.sh
new file mode 100644
index 00000000..d072802a
--- /dev/null
+++ b/spec/tls/lib.sh
@@ -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;
+}
diff --git a/spec/tls/run.sh b/spec/tls/run.sh
new file mode 100755
index 00000000..8bceddb2
--- /dev/null
+++ b/spec/tls/run.sh
@@ -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;