[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#1074019: bullseye-pu: package ngircd/26.1-1+deb11u1



Package: release.debian.org
Severity: normal
Tags: bullseye
X-Debbugs-Cc: ngircd@packages.debian.org, debian.axhn@manchmal.in-ulm.de
Control: affects -1 + src:ngircd
User: release.debian.org@packages.debian.org
Usertags: pu

[ Reason ]
Fix one major and two more "Oh, that's not good" issues. It was agreed
upon with security team to handle them via SPU.

1. In a TLS-based server-server connection, the server certificate is
not validated.

github issue: https://github.com/ngircd/ngircd/issues/120

For reasons neither upstream or I understand, a CVE number request was rejected.

2. In a server-server connection, a connection may still use
plain text despite the connection ought to be TLS-based.

Fix: https://github.com/ngircd/ngircd/commit/21c1751b045b0be49e584a4ba191a330e0c381bb
Debian bug: https://bugs.debian.org/1067237

3. Some IRC services might send an empty string for the hostname to
implement the "uncloak host" functionality, leading to a protocol
violation in subsequent "WHOIS" or other commands against the ngircd
server.

Fix: https://github.com/ngircd/ngircd/commit/1118b0e77ca961a7b082f90cb124210eca8fb6bd

[ Impact ]
1. Server-server links are prone to MITM attacks even when using TLS.

2. Downgrade attacks.

3. Client confusion, possibly crash.

[ Tests ]
1. The unstable version of ngircd now has an autopkgtest for that
situation. For a test, it was manually backported, and it passed.
It's not included however to keep the change small.
2./3. No test in particular, but the change is small.

Also, a private IRC network using ngircd with Debian bookworm was
already upgraded in April, using a preliminary release. No technical
issues were found, only documentation needed a little clarification
(included).

[ Risks ]
1. This might break flawed configurations, most notably if the peer's
   certificate has expired and/or cannot be verified against the configured
   trust store. The ngircd.NEWS and ngircd.README.Debian files have been
   updated.
2./3. No risks are to be expected.

[ Checklist ]
  [x] *all* changes are documented in the d/changelog
  [x] I reviewed all changes and I approve them
  [x] attach debdiff against the package in (old)stable
  [x] the issue is verified as fixed in unstable
      (27~rc1-1, 2024-04-13)

[ Changes ]
All the changes were cherry-pick from upstream.
1. Whopping 19 patches, prefixed "S2S-TLS"
2. patch Respect-SSLConnect-option
3. patch METADATA-Fix-unsetting-cloakhost

Also the mentioned changes to documentation in debian/


[ Other info ]
The same story will follow for bookworm in a moment. In fact,
bullseye and bookworm have the same version of ngircd at the moment.

Regards,

    Christoph

diff -Nru ngircd-26.1/debian/changelog ngircd-26.1/debian/changelog
--- ngircd-26.1/debian/changelog	2021-01-02 23:17:19.000000000 +0100
+++ ngircd-26.1/debian/changelog	2024-05-01 11:00:00.000000000 +0200
@@ -1,3 +1,13 @@
+ngircd (26.1-1+deb11u1) bullseye; urgency=high
+
+  * Cherry-pick "Respect "SSLConnect" option for incoming
+    connections". Closes: #1067237
+  * Cherry-pick "Support for server certificate validation on server
+    links [S2S-TLS]"
+  * Cherry-pick "METADATA: Fix unsetting "cloakhost""
+
+ -- Christoph Biedl <debian.axhn@manchmal.in-ulm.de>  Wed, 01 May 2024 11:00:00 +0200
+
 ngircd (26.1-1) unstable; urgency=medium
 
   * New upstream version 26.1
diff -Nru ngircd-26.1/debian/ngircd.conf ngircd-26.1/debian/ngircd.conf
--- ngircd-26.1/debian/ngircd.conf	2021-01-02 23:17:19.000000000 +0100
+++ ngircd-26.1/debian/ngircd.conf	2024-05-01 11:00:00.000000000 +0200
@@ -273,6 +273,14 @@
 	# is only available when ngIRCd is compiled with support for SSL!
 	# So don't forget to remove the ";" above if this is the case ...
 
+	# SSL Trusted CA Certificates File for verifying peer certificates.
+	# (Default: not set; so no certificates are trusted)
+	;CAFile = /etc/ssl/certs/ca-certificates.crt
+
+	# Certificate Revocation File (for marking otherwise valid
+	# certficates as invalid)
+	;CRLFile = /etc/ssl/CA/crl.pem
+
 	# SSL Server Key Certificate
 	;CertFile = /etc/ssl/certs/server.crt
 
@@ -366,6 +374,10 @@
 	# Connect to the remote server using TLS/SSL (Default: false)
 	;SSLConnect = yes
 
+	# Verify the TLS certificate presented by the remote server
+	# (Default: yes)
+	;SSLVerify = yes
+
 	# Define a (case insensitive) list of masks matching nicknames that
 	# should be treated as IRC services when introduced via this remote
 	# server, separated by commas (",").
diff -Nru ngircd-26.1/debian/ngircd.NEWS ngircd-26.1/debian/ngircd.NEWS
--- ngircd-26.1/debian/ngircd.NEWS	1970-01-01 01:00:00.000000000 +0100
+++ ngircd-26.1/debian/ngircd.NEWS	2024-05-01 11:00:00.000000000 +0200
@@ -0,0 +1,8 @@
+ngircd (26.1-1+deb11u1) bullseye; urgency=high
+
+  * This version introduces x509 certificate validation on TLS-based
+    server-server links. Existing configurations will likely break, for
+    details see </usr/share/doc/ngircd/README.Debian>, starting at
+    "TLS-based server-server links".
+
+ -- Christoph Biedl <debian.axhn@manchmal.in-ulm.de>  Wed, 01 May 2024 11:00:00 +0200
diff -Nru ngircd-26.1/debian/ngircd.README.Debian ngircd-26.1/debian/ngircd.README.Debian
--- ngircd-26.1/debian/ngircd.README.Debian	2021-01-02 21:46:42.000000000 +0100
+++ ngircd-26.1/debian/ngircd.README.Debian	2024-05-01 11:00:00.000000000 +0200
@@ -34,6 +34,25 @@
   ngircd.service the daemon will not be able to load the files.
 
 
+TLS-based server-server links
+-----------------------------
+When linking two ngircd servers, the connection should be TLS-based for
+obvious reasons. To do so, edit ngircd.conf:
+
+* Enable SSLConnect in each [Server] stanza.
+* Define CAFile in the [SSL] stanza. Note that by default *no*
+  certificate is trusted.
+  If the peers's certificate was signed by one of the well-known
+  certificate authorities: Use the suggested value
+  "/etc/ssl/certs/ca-certificates.crt" and install the ca-certificate
+  package.
+  Else set the value to the respective CA's certificate file.
+
+Verfication can be disabled entirely on a per-link base by setting
+SSLVerify to false. This is strongly discouraged as you will lose all
+security by that.
+
+
 DH parameters file
 ------------------
 It is suggested to create a DH params file. If missing, ngIRCd will
diff -Nru ngircd-26.1/debian/patches/0001-Respect-SSLConnect-option-for-incoming-connections.patch ngircd-26.1/debian/patches/0001-Respect-SSLConnect-option-for-incoming-connections.patch
--- ngircd-26.1/debian/patches/0001-Respect-SSLConnect-option-for-incoming-connections.patch	1970-01-01 01:00:00.000000000 +0100
+++ ngircd-26.1/debian/patches/0001-Respect-SSLConnect-option-for-incoming-connections.patch	2024-04-02 21:15:49.000000000 +0200
@@ -0,0 +1,43 @@
+From d09dc33e7d0f148ff9c0afff905414cc13d636fc Mon Sep 17 00:00:00 2001
+From: Alexander Barton <alex@barton.de>
+Date: Mon, 1 Jan 2024 18:20:26 +0100
+Subject: [PATCH 01/20] Respect "SSLConnect" option for incoming connections
+Bug-Debian: https://bugs.debian.org/1067237
+
+Don't accept incoming plain-text ("non SSL") server connections for
+servers configured with "SSLConnect" enabled.
+
+If "SSLConnect" is not set for an incoming connection the server still
+accepts both plain-text and encrypted connections.
+
+This change prevents an authenticated client-server being able to force
+the server-server to send its password on a plain-text connection when
+SSL/TLS was intended.
+
+(cherry picked from commit 21c1751b045b0be49e584a4ba191a330e0c381bb)
+---
+ src/ngircd/irc-server.c | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+--- a/src/ngircd/irc-server.c
++++ b/src/ngircd/irc-server.c
+@@ -87,6 +87,19 @@
+ 			return DISCONNECTED;
+ 		}
+ 
++#ifdef SSL_SUPPORT
++		/* Does this server require an SSL connection? */
++		if (Conf_Server[i].SSLConnect &&
++		    !(Conn_Options(Client_Conn(Client)) & CONN_SSL)) {
++			Log(LOG_ERR,
++			    "Connection %d: Server \"%s\" requires a secure connection!",
++			    Client_Conn(Client), Req->argv[0]);
++			Conn_Close(Client_Conn(Client), NULL,
++				   "Secure connection required", true);
++			return DISCONNECTED;
++		}
++#endif
++
+ 		/* Check server password */
+ 		if (strcmp(Conn_Password(Client_Conn(Client)),
+ 		    Conf_Server[i].pwd_in) != 0) {
diff -Nru ngircd-26.1/debian/patches/0001-S2S-SSL-GnuTLS-Enable-CRL-verification_26.1.patch ngircd-26.1/debian/patches/0001-S2S-SSL-GnuTLS-Enable-CRL-verification_26.1.patch
--- ngircd-26.1/debian/patches/0001-S2S-SSL-GnuTLS-Enable-CRL-verification_26.1.patch	1970-01-01 01:00:00.000000000 +0100
+++ ngircd-26.1/debian/patches/0001-S2S-SSL-GnuTLS-Enable-CRL-verification_26.1.patch	2024-04-15 14:09:13.000000000 +0200
@@ -0,0 +1,21 @@
+From edb8fce8719efb0d887c72495e540d60a3bf4ed7 Mon Sep 17 00:00:00 2001
+From: Christoph Biedl <ngircd.anoy@manchmal.in-ulm.de>
+Date: Sun, 31 Mar 2024 00:36:53 +0100
+Subject: [PATCH] S2S-SSL/GnuTLS: Enable CRL verification
+
+(cherry picked from commit b2c9049af20b12f2fde08f4af0a35968404effdb)
+---
+ src/ngircd/conn-ssl.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/src/ngircd/conn-ssl.c
++++ b/src/ngircd/conn-ssl.c
+@@ -524,6 +524,8 @@
+ 		return false;
+ 
+ 	gnutls_certificate_set_dh_params(x509_cred, dh_params);
++	gnutls_certificate_set_flags(x509_cred, GNUTLS_CERTIFICATE_VERIFY_CRLS);
++
+ 	err = gnutls_certificate_set_x509_key_file(x509_cred, cert_file, Conf_SSLOptions.KeyFile, GNUTLS_X509_FMT_PEM);
+ 	if (err < 0) {
+ 		Log(LOG_ERR,
diff -Nru ngircd-26.1/debian/patches/0002-Support-for-server-certificate-validation-on-server-.patch ngircd-26.1/debian/patches/0002-Support-for-server-certificate-validation-on-server-.patch
--- ngircd-26.1/debian/patches/0002-Support-for-server-certificate-validation-on-server-.patch	1970-01-01 01:00:00.000000000 +0100
+++ ngircd-26.1/debian/patches/0002-Support-for-server-certificate-validation-on-server-.patch	2024-04-15 14:09:06.000000000 +0200
@@ -0,0 +1,682 @@
+From 315125a8bcf6d80c969a3310c43b486b0e422e5b Mon Sep 17 00:00:00 2001
+From: Christoph Biedl <ngircd.anoy@manchmal.in-ulm.de>
+Date: Sun, 2 Nov 2014 14:48:34 +0100
+Subject: [PATCH 02/20] Support for server certificate validation on server
+ links [S2S-TLS]
+
+This patch provides code to validate the server certificate in
+server links, defeating nasty man-in-the-middle attacks on server
+links.
+
+Features:
+
+- Check whether the certificate is signed by a trusted certificate
+  authority (CA).
+- Check the host name, including wildcard certificates and Subject
+  Alternative Names.
+- Optionally check against a certificate revocation list (CRL).
+- Implementation for both OpenSSL and GnuTLS linkage.
+
+Left for another day:
+
+- Parameterize the TLS parameter of an outbound connection. Currently,
+  it's hardcoded to disable all versions before TLSv1.1.
+- Using certificate as CA-certificate. They work for GnuTLS only but
+  perhaps this should rather raise an error there, too.
+- Optional OCSP checking.
+- Checking client certificates. Code is there but this first needs some
+  consideration about the use cases. This could replace all other
+  authentication methods, for both client-server and server-server
+  connections.
+
+This patch is based on a patch by Florian Westphal from 2009, which
+implemented this for OpenSSL only:
+
+  From: Florian Westphal <fw@strlen.de>
+  Date: Mon, 18 May 2009 00:29:02 +0200
+  Subject: SSL/TLS: Add initial certificate support to OpenSSL backend
+
+Commit message modified by Alex Barton.
+
+Closes #120, "Server links using TLS/SSL need certificate validation".
+Supersedes PR #8, "Options for verifying and requiring SSL client
+certificates", which had (incomplete?) code for OpenSSL, no GnuTLS.
+
+(cherry picked from commit 817937b218c4b57515f54216ebc936cd69df0aae)
+---
+ doc/sample-ngircd.conf.tmpl |  11 ++
+ man/ngircd.conf.5.tmpl      |  10 ++
+ src/ngircd/conf.c           |  27 ++-
+ src/ngircd/conf.h           |   3 +
+ src/ngircd/conn-ssl.c       | 323 ++++++++++++++++++++++++++++++++++--
+ src/ngircd/conn.c           |  21 +++
+ src/ngircd/conn.h           |   3 +-
+ 7 files changed, 385 insertions(+), 13 deletions(-)
+
+--- a/doc/sample-ngircd.conf.tmpl
++++ b/doc/sample-ngircd.conf.tmpl
+@@ -266,6 +266,13 @@
+ 	# is only available when ngIRCd is compiled with support for SSL!
+ 	# So don't forget to remove the ";" above if this is the case ...
+ 
++	# SSL Trusted CA Certificates File (for verifying peer certificates)
++	;CAFile = /etc/ssl/CA/cacert.pem
++
++	# Certificate Revocation File (for marking otherwise valid
++	# certficates as invalid)
++	;CRLFile = /etc/ssl/CA/crl.pem
++
+ 	# SSL Server Key Certificate
+ 	;CertFile = :ETCDIR:/ssl/server-cert.pem
+ 
+@@ -357,6 +364,10 @@
+ 	# Connect to the remote server using TLS/SSL (Default: false)
+ 	;SSLConnect = yes
+ 
++	# Verify the TLS certificate presented by the remote server
++	# (Default: yes)
++	;SSLVerify = yes
++
+ 	# Define a (case insensitive) list of masks matching nicknames that
+ 	# should be treated as IRC services when introduced via this remote
+ 	# server, separated by commas (",").
+--- a/man/ngircd.conf.5.tmpl
++++ b/man/ngircd.conf.5.tmpl
+@@ -385,6 +385,13 @@
+ section. Please note that this whole section is only recognized by ngIRCd
+ when it is compiled with support for SSL using OpenSSL or GnuTLS!
+ .TP
++\fBCAFile (string)\fR
++Filename pointing to the Trusted CA Certificates. This is required for
++verifying peer certificates.
++.TP
++\fBCRLFile (string)\fR
++Filename of Certificate Revocation List.
++.TP
+ \fBCertFile\fR (string)
+ SSL Certificate file of the private server key.
+ .TP
+@@ -479,6 +486,9 @@
+ \fBSSLConnect\fR (boolean)
+ Connect to the remote server using TLS/SSL. Default: false.
+ .TP
++\fBSSLVerify\fR (boolean)
++Verify the TLS certificate presented by the remote server. Default: yes.
++.TP
+ \fBServiceMask\fR (string)
+ Define a (case insensitive) list of masks matching nicknames that should be
+ treated as IRC services when introduced via this remote server, separated
+--- a/src/ngircd/conf.c
++++ b/src/ngircd/conf.c
+@@ -112,6 +112,12 @@
+ 	free(Conf_SSLOptions.CertFile);
+ 	Conf_SSLOptions.CertFile = NULL;
+ 
++	free(Conf_SSLOptions.CAFile);
++	Conf_SSLOptions.CAFile = NULL;
++
++	free(Conf_SSLOptions.CRLFile);
++	Conf_SSLOptions.CRLFile = NULL;
++
+ 	free(Conf_SSLOptions.DHFile);
+ 	Conf_SSLOptions.DHFile = NULL;
+ 	array_free_wipe(&Conf_SSLOptions.KeyFilePassword);
+@@ -464,7 +470,10 @@
+ 		printf( "  Host = %s\n", Conf_Server[i].host );
+ 		printf( "  Port = %u\n", (unsigned int)Conf_Server[i].port );
+ #ifdef SSL_SUPPORT
+-		printf( "  SSLConnect = %s\n", Conf_Server[i].SSLConnect?"yes":"no");
++		printf("  SSLConnect = %s\n",
++		       yesno_to_str(Conf_Server[i].SSLConnect));
++		printf("  SSLVerify = %s\n",
++		       yesno_to_str(Conf_Server[i].SSLVerify));
+ #endif
+ 		printf( "  MyPassword = %s\n", Conf_Server[i].pwd_in );
+ 		printf( "  PeerPassword = %s\n", Conf_Server[i].pwd_out );
+@@ -1774,6 +1783,16 @@
+ 		Conf_SSLOptions.CipherList = strdup_warn(Arg);
+ 		return;
+ 	}
++	if (strcasecmp(Var, "CAFile") == 0) {
++		assert(Conf_SSLOptions.CAFile == NULL);
++		Conf_SSLOptions.CAFile = strdup_warn(Arg);
++		return;
++	}
++	if (strcasecmp(Var, "CRLFile") == 0) {
++		assert(Conf_SSLOptions.CRLFile == NULL);
++		Conf_SSLOptions.CRLFile = strdup_warn(Arg);
++		return;
++	}
+ 
+ 	Config_Error_Section(File, Line, Var, "SSL");
+ }
+@@ -1904,7 +1923,11 @@
+ 	if( strcasecmp( Var, "SSLConnect" ) == 0 ) {
+ 		New_Server.SSLConnect = Check_ArgIsTrue(Arg);
+ 		return;
+-        }
++	}
++	if (strcasecmp(Var, "SSLVerify") == 0) {
++		New_Server.SSLVerify = Check_ArgIsTrue(Arg);
++		return;
++	}
+ #endif
+ 	if( strcasecmp( Var, "Group" ) == 0 ) {
+ 		/* Server group */
+--- a/src/ngircd/conf.h
++++ b/src/ngircd/conf.h
+@@ -61,6 +61,7 @@
+ 	ng_ipaddr_t dst_addr[2];	/**< List of addresses to connect to */
+ #ifdef SSL_SUPPORT
+ 	bool SSLConnect;		/**< Establish connection using SSL? */
++	bool SSLVerify;			/**< Verify server certificate using CA? */
+ #endif
+ 	char svs_mask[CLIENT_ID_LEN];	/**< Mask of nicknames that should be
+ 					     treated and counted as services */
+@@ -76,6 +77,8 @@
+ 	array ListenPorts;		/**< Array of listening SSL ports */
+ 	array KeyFilePassword;		/**< Key file password */
+ 	char *CipherList;		/**< Set SSL cipher list to use */
++	char *CAFile;			/**< Trusted CA certificates file */
++	char *CRLFile;			/**< Certificate revocation file */
+ };
+ #endif
+ 
+--- a/src/ngircd/conn-ssl.c
++++ b/src/ngircd/conn-ssl.c
+@@ -43,13 +43,17 @@
+ #include <openssl/err.h>
+ #include <openssl/rand.h>
+ #include <openssl/dh.h>
++#include <openssl/x509v3.h>
+ 
+ static SSL_CTX * ssl_ctx;
+ static DH *dh_params;
+ 
+ static bool ConnSSL_LoadServerKey_openssl PARAMS(( SSL_CTX *c ));
++static bool ConnSSL_SetVerifyProperties_openssl PARAMS((SSL_CTX * c));
+ #endif
+ 
++#define MAX_CERT_CHAIN_LENGTH	10	/* XXX: do not hardcode */
++
+ #ifdef HAVE_LIBGNUTLS
+ #include <sys/types.h>
+ #include <sys/stat.h>
+@@ -74,6 +78,7 @@
+ static gnutls_dh_params_t dh_params;
+ static gnutls_priority_t priorities_cache = NULL;
+ static bool ConnSSL_LoadServerKey_gnutls PARAMS(( void ));
++static bool ConnSSL_SetVerifyProperties_gnutls PARAMS((void));
+ #endif
+ 
+ #define SHA256_STRING_LEN	(32 * 2 + 1)
+@@ -131,10 +136,38 @@
+ /**
+  * Log OpenSSL error message.
+  *
++ * @param level The log level
+  * @param msg The error message.
+  * @param info Additional information text or NULL.
+  */
+ static void
++LogOpenSSL_CertInfo(int level, X509 * cert, const char *msg)
++{
++	BIO *mem;
++	char *memptr;
++	long len;
++
++	assert(cert);
++	assert(msg);
++
++	if (!cert)
++		return;
++	mem = BIO_new(BIO_s_mem());
++	if (!mem)
++		return;
++	X509_NAME_print_ex(mem, X509_get_subject_name(cert), 4,
++			   XN_FLAG_ONELINE);
++	X509_NAME_print_ex(mem, X509_get_issuer_name(cert), 4, XN_FLAG_ONELINE);
++	if (BIO_write(mem, "", 1) == 1) {
++		len = BIO_get_mem_data(mem, &memptr);
++		if (memptr && len > 0)
++			Log(level, "%s: \"%s\"", msg, memptr);
++	}
++	(void)BIO_set_close(mem, BIO_CLOSE);
++	BIO_free(mem);
++}
++
++static void
+ LogOpenSSLError(const char *error, const char *info)
+ {
+ 	unsigned long err = ERR_get_error();
+@@ -176,9 +209,16 @@
+ 
+ 
+ static int
+-Verify_openssl(UNUSED int preverify_ok, UNUSED X509_STORE_CTX *x509_ctx)
++Verify_openssl(int preverify_ok, X509_STORE_CTX * ctx)
+ {
+-	return 1;
++	int err;
++
++	if (!preverify_ok) {
++		err = X509_STORE_CTX_get_error(ctx);
++		Log(LOG_ERR, "Certificate validation failed: %s",
++		    X509_verify_cert_error_string(err));
++	}
++	return preverify_ok;
+ }
+ #endif
+ 
+@@ -354,7 +394,12 @@
+ 	}
+ 
+ 	SSL_CTX_set_session_id_context(newctx, (unsigned char *)"ngircd", 6);
+-	SSL_CTX_set_options(newctx, SSL_OP_SINGLE_DH_USE|SSL_OP_NO_SSLv2);
++	if (!ConnSSL_SetVerifyProperties_openssl(newctx))
++		goto out;
++	SSL_CTX_set_options(newctx,
++			    SSL_OP_SINGLE_DH_USE | SSL_OP_NO_SSLv2 |
++			    SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1 |
++			    SSL_OP_NO_COMPRESSION);
+ 	SSL_CTX_set_mode(newctx, SSL_MODE_ENABLE_PARTIAL_WRITE);
+ 	SSL_CTX_set_verify(newctx, SSL_VERIFY_PEER|SSL_VERIFY_CLIENT_ONCE,
+ 			   Verify_openssl);
+@@ -394,6 +439,9 @@
+ 		goto out;
+ 	}
+ 
++	if (!ConnSSL_SetVerifyProperties_gnutls())
++		goto out;
++
+ 	Log(LOG_INFO, "GnuTLS %s initialized.", gnutls_check_version(NULL));
+ 	initialized = true;
+ 	return true;
+@@ -406,6 +454,37 @@
+ 
+ #ifdef HAVE_LIBGNUTLS
+ static bool
++ConnSSL_SetVerifyProperties_gnutls(void)
++{
++	int err;
++
++	if (!Conf_SSLOptions.CAFile)
++		return true;
++
++	err = gnutls_certificate_set_x509_trust_file(x509_cred,
++						     Conf_SSLOptions.CAFile,
++						     GNUTLS_X509_FMT_PEM);
++	if (err < 0) {
++		Log(LOG_ERR, "Failed to load x509 trust file %s: %s",
++		    Conf_SSLOptions.CAFile, gnutls_strerror(err));
++		return false;
++	}
++	if (Conf_SSLOptions.CRLFile) {
++		err =
++		    gnutls_certificate_set_x509_crl_file(x509_cred,
++							 Conf_SSLOptions.CRLFile,
++							 GNUTLS_X509_FMT_PEM);
++		if (err < 0) {
++			Log(LOG_ERR, "Failed to load x509 crl file %s: %s",
++			    Conf_SSLOptions.CRLFile, gnutls_strerror(err));
++			return false;
++		}
++	}
++	return true;
++}
++
++
++static bool
+ ConnSSL_LoadServerKey_gnutls(void)
+ {
+ 	int err;
+@@ -531,6 +610,56 @@
+ }
+ 
+ 
++static bool
++ConnSSL_SetVerifyProperties_openssl(SSL_CTX * ctx)
++{
++	X509_STORE *store = NULL;
++	X509_LOOKUP *lookup;
++	int verify_flags = SSL_VERIFY_PEER;
++	bool ret = false;
++
++	if (!Conf_SSLOptions.CAFile)
++		return true;
++
++	if (SSL_CTX_load_verify_locations(ctx, Conf_SSLOptions.CAFile, NULL) !=
++	    1) {
++		LogOpenSSLError("SSL_CTX_load_verify_locations", NULL);
++		goto out;
++	}
++
++	if (Conf_SSLOptions.CRLFile) {
++		X509_VERIFY_PARAM *param = X509_VERIFY_PARAM_new();
++		X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_CRL_CHECK);
++		SSL_CTX_set1_param(ctx, param);
++
++		store = SSL_CTX_get_cert_store(ctx);
++		assert(store);
++		lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file());
++		if (!lookup) {
++			LogOpenSSLError("X509_STORE_add_lookup",
++					Conf_SSLOptions.CRLFile);
++			goto out;
++		}
++
++		if (X509_load_crl_file
++		    (lookup, Conf_SSLOptions.CRLFile, X509_FILETYPE_PEM) != 1) {
++			LogOpenSSLError("X509_load_crl_file",
++					Conf_SSLOptions.CRLFile);
++			goto out;
++		}
++	}
++
++	SSL_CTX_set_verify(ctx, verify_flags, Verify_openssl);
++	SSL_CTX_set_verify_depth(ctx, MAX_CERT_CHAIN_LENGTH);
++	ret = true;
++out:
++	if (Conf_SSLOptions.CRLFile)
++		free(Conf_SSLOptions.CRLFile);
++	Conf_SSLOptions.CRLFile = NULL;
++	return ret;
++}
++
++
+ #endif
+ static bool
+ ConnSSL_Init_SSL(CONNECTION *c)
+@@ -602,7 +731,7 @@
+ 
+ 
+ bool
+-ConnSSL_PrepareConnect(CONNECTION *c, UNUSED CONF_SERVER *s)
++ConnSSL_PrepareConnect(CONNECTION * c, CONF_SERVER * s)
+ {
+ 	bool ret;
+ #ifdef HAVE_LIBGNUTLS
+@@ -613,7 +742,7 @@
+ 		Log(LOG_ERR, "Failed to initialize new SSL session: %s",
+ 		    gnutls_strerror(err));
+ 		return false;
+-        }
++	}
+ #endif
+ 	ret = ConnSSL_Init_SSL(c);
+ 	if (!ret)
+@@ -621,7 +750,23 @@
+ 	Conn_OPTION_ADD(c, CONN_SSL_CONNECT);
+ #ifdef HAVE_LIBSSL
+ 	assert(c->ssl_state.ssl);
+-	SSL_set_verify(c->ssl_state.ssl, SSL_VERIFY_NONE, NULL);
++	if (s->SSLVerify) {
++		X509_VERIFY_PARAM *param = NULL;
++		param = SSL_get0_param(c->ssl_state.ssl);
++		X509_VERIFY_PARAM_set_hostflags(param,
++						X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS);
++Log(LOG_ERR, "DEBUG: Setting up hostname verification for '%s'", s->host);
++		int err = X509_VERIFY_PARAM_set1_host(param, s->host, 0);
++		if (err != 1) {
++			Log(LOG_ERR,
++			    "Cannot set up hostname verification for '%s': %u",
++			    s->host, err);
++			return false;
++		}
++		SSL_set_verify(c->ssl_state.ssl, SSL_VERIFY_PEER,
++			       Verify_openssl);
++	} else
++		SSL_set_verify(c->ssl_state.ssl, SSL_VERIFY_NONE, NULL);
+ #endif
+ 	return true;
+ }
+@@ -720,18 +865,102 @@
+ }
+ 
+ 
++#ifdef HAVE_LIBGNUTLS
++static void *
++LogMalloc(size_t s)
++{
++	void *mem = malloc(s);
++	if (!mem)
++		Log(LOG_ERR, "Out of memory: Could not allocate %lu byte",
++		    (unsigned long)s);
++	return mem;
++}
++
++
+ static void
+-ConnSSL_LogCertInfo( CONNECTION *c )
++LogGnuTLS_CertInfo(int level, gnutls_x509_crt_t cert, const char *msg)
+ {
++	char *dn, *issuer_dn;
++	size_t size = 0;
++	int err = gnutls_x509_crt_get_dn(cert, NULL, &size);
++	if (size == 0) {
++		Log(LOG_ERR, "gnutls_x509_crt_get_dn: size == 0");
++		return;
++	}
++	if (err && err != GNUTLS_E_SHORT_MEMORY_BUFFER)
++		goto err_crt_get;
++	dn = LogMalloc(size);
++	if (!dn)
++		return;
++	err = gnutls_x509_crt_get_dn(cert, dn, &size);
++	if (err)
++		goto err_crt_get;
++	gnutls_x509_crt_get_issuer_dn(cert, NULL, &size);
++	assert(size);
++	issuer_dn = LogMalloc(size);
++	if (!issuer_dn) {
++		Log(level, "%s: Distinguished Name: %s", msg, dn);
++		free(dn);
++		return;
++	}
++	gnutls_x509_crt_get_issuer_dn(cert, issuer_dn, &size);
++	Log(level, "%s: Distinguished Name: \"%s\", Issuer \"%s\"", msg, dn,
++	    issuer_dn);
++	free(dn);
++	free(issuer_dn);
++	return;
++
++      err_crt_get:
++	Log(LOG_ERR, "gnutls_x509_crt_get_dn: %s", gnutls_strerror(err));
++	return;
++}
++#endif
++
++
++static void
++ConnSSL_LogCertInfo( CONNECTION * c, bool connect)
++{
++	bool cert_seen = false, cert_ok = false;
++	char msg[128];
+ #ifdef HAVE_LIBSSL
++	const char *comp_alg = "no compression";
++	const void *comp;
++	X509 *peer_cert = NULL;
+ 	SSL *ssl = c->ssl_state.ssl;
+ 
+ 	assert(ssl);
+ 
+-	Log(LOG_INFO, "Connection %d: initialized %s using cipher %s.",
+-		c->sock, SSL_get_version(ssl), SSL_get_cipher(ssl));
++	comp = SSL_get_current_compression(ssl);
++	if (comp)
++		comp_alg = SSL_COMP_get_name(comp);
++	Log(LOG_INFO, "Connection %d: initialized %s using cipher %s, %s.",
++	    c->sock, SSL_get_version(ssl), SSL_get_cipher(ssl), comp_alg);
++	peer_cert = SSL_get_peer_certificate(ssl);
++	if (peer_cert && connect) {
++		cert_seen = true;
++		/* Client: Check server certificate */
++		int err = SSL_get_verify_result(ssl);
++		if (err == X509_V_OK) {
++			const char *peername = SSL_get0_peername(ssl);
++			if (peername != NULL)
++				cert_ok = true;
++
++			Log(LOG_ERR, "X509_V_OK, peername = '%s'", peername);
++
++		} else
++			Log(LOG_ERR, "Certificate validation failed: %s",
++			    X509_verify_cert_error_string(err));
++		snprintf(msg, sizeof(msg), "%svalid peer certificate",
++			 cert_ok ? "" : "in");
++		LogOpenSSL_CertInfo(cert_ok ? LOG_DEBUG : LOG_ERR, peer_cert,
++				    msg);
++
++		X509_free(peer_cert);
++	}
+ #endif
+ #ifdef HAVE_LIBGNUTLS
++	unsigned int status;
++	gnutls_credentials_type_t cred;
+ 	gnutls_session_t sess = c->ssl_state.gnutls_session;
+ 	gnutls_cipher_algorithm_t cipher = gnutls_cipher_get(sess);
+ 
+@@ -740,7 +969,81 @@
+ 	    gnutls_protocol_get_name(gnutls_protocol_get_version(sess)),
+ 	    gnutls_cipher_get_name(cipher),
+ 	    gnutls_mac_get_name(gnutls_mac_get(sess)));
++	cred = gnutls_auth_get_type(c->ssl_state.gnutls_session);
++	if (cred == GNUTLS_CRD_CERTIFICATE && connect) {
++		cert_seen = true;
++		int verify =
++		    gnutls_certificate_verify_peers2(c->
++						     ssl_state.gnutls_session,
++						     &status);
++Log(LOG_ERR, "DEBUG: verify = %d", verify);
++		if (verify < 0) {
++			Log(LOG_ERR,
++			    "gnutls_certificate_verify_peers2 failed: %s",
++			    gnutls_strerror(verify));
++			goto done_cn_validation;
++		} else if (status) {
++			gnutls_datum_t out;
++
++			if (gnutls_certificate_verification_status_print
++			    (status, gnutls_certificate_type_get(sess), &out,
++			     0) == GNUTLS_E_SUCCESS) {
++				Log(LOG_ERR,
++				    "Certificate validation failed: %s",
++				    out.data);
++				gnutls_free(out.data);
++			}
++		}
++Log(LOG_ERR, "DEBUG: status = %d", status);
++
++		gnutls_x509_crt_t cert;
++		unsigned cert_list_size;
++		const gnutls_datum_t *cert_list =
++		    gnutls_certificate_get_peers(sess, &cert_list_size);
++		if (!cert_list || cert_list_size == 0) {
++			Log(LOG_ERR, "No certificates found");
++			goto done_cn_validation;
++		}
++		int err = gnutls_x509_crt_init(&cert);
++		if (err < 0) {
++			Log(LOG_ERR,
++			    "Failed to initialize x509 certificate: %s",
++			    gnutls_strerror(err));
++			goto done_cn_validation;
++		}
++		err = gnutls_x509_crt_import(cert, cert_list,
++					   GNUTLS_X509_FMT_DER);
++		if (err < 0) {
++			Log(LOG_ERR, "Failed to parse the certificate: %s",
++			    gnutls_strerror(err));
++			goto done_cn_validation;
++		}
++		err = gnutls_x509_crt_check_hostname(cert, c->host);
++		if (err == 0)
++			Log(LOG_ERR,
++			    "Failed to verify the hostname, expected \"%s\"",
++			    c->host);
++		else
++			cert_ok = verify == 0 && status == 0;
++
++		snprintf(msg, sizeof(msg), "%svalid peer certificate",
++			cert_ok ? "" : "in");
++		LogGnuTLS_CertInfo(cert_ok ? LOG_DEBUG : LOG_ERR, cert, msg);
++
++		gnutls_x509_crt_deinit(cert);
++done_cn_validation:
++		;
++	}
+ #endif
++	/*
++	 * can be used later to check if connection was authenticated, e.g.
++	 * if inbound connection tries to register itself as server.
++	 * Could also restrict /OPER to authenticated connections, etc.
++	 */
++	if (cert_ok)
++		Conn_OPTION_ADD(c, CONN_SSL_PEERCERT_OK);
++	if (!cert_seen)
++		Log(LOG_INFO, "Peer did not present a certificate");
+ }
+ 
+ 
+@@ -879,7 +1182,7 @@
+ 	(void)ConnSSL_InitCertFp(c);
+ 
+ 	Conn_OPTION_DEL(c, (CONN_SSL_WANT_WRITE|CONN_SSL_WANT_READ|CONN_SSL_CONNECT));
+-	ConnSSL_LogCertInfo(c);
++	ConnSSL_LogCertInfo(c, connect);
+ 
+ 	Conn_StartLogin(CONNECTION2ID(c));
+ 	return 1;
+--- a/src/ngircd/conn.c
++++ b/src/ngircd/conn.c
+@@ -2546,6 +2546,7 @@
+ cb_connserver_login_ssl(int sock, short unused)
+ {
+ 	CONN_ID idx = Socket2Index(sock);
++	int serveridx;
+ 
+ 	(void) unused;
+ 
+@@ -2564,10 +2565,30 @@
+ 			return;
+ 	}
+ 
++	serveridx = Conf_GetServer(idx);
++	assert(serveridx >= 0);
++	if (serveridx < 0)
++		goto err;
++
+ 	Log( LOG_INFO, "SSL connection %d with \"%s:%d\" established.", idx,
+ 	    My_Connections[idx].host, Conf_Server[Conf_GetServer( idx )].port );
+ 
++	if (!Conn_OPTION_ISSET(&My_Connections[idx], CONN_SSL_PEERCERT_OK)) {
++		if (Conf_Server[serveridx].SSLVerify) {
++			Log(LOG_ERR,
++				"SSLVerify enabled for %d, but peer certificate check failed",
++				idx);
++			goto err;
++		}
++		Log(LOG_WARNING,
++			"Peer certificate check failed for %d, but SSLVerify is disabled, continuing",
++			idx);
++	}
+ 	server_login(idx);
++	return;
++      err:
++	Log(LOG_ERR, "SSL connection on socket %d failed!", sock);
++	Conn_Close(idx, "Can't connect!", NULL, false);
+ }
+ 
+ 
+--- a/src/ngircd/conn.h
++++ b/src/ngircd/conn.h
+@@ -40,7 +40,8 @@
+ #define CONN_SSL		32	/* this connection is SSL encrypted */
+ #define CONN_SSL_WANT_WRITE	64	/* SSL/TLS library needs to write protocol data */
+ #define CONN_SSL_WANT_READ	128	/* SSL/TLS library needs to read protocol data */
+-#define CONN_SSL_FLAGS_ALL	(CONN_SSL_CONNECT|CONN_SSL|CONN_SSL_WANT_WRITE|CONN_SSL_WANT_READ)
++#define CONN_SSL_PEERCERT_OK	256	/* peer presented a valid certificate (used to check inbound server auth */
++#define CONN_SSL_FLAGS_ALL	(CONN_SSL_CONNECT|CONN_SSL|CONN_SSL_WANT_WRITE|CONN_SSL_WANT_READ|CONN_SSL_PEERCERT_OK)
+ #endif
+ typedef int CONN_ID;
+ 
diff -Nru ngircd-26.1/debian/patches/0003-S2S-TLS-Add-missing-CAFile-and-CRLFile-options-to-co.patch ngircd-26.1/debian/patches/0003-S2S-TLS-Add-missing-CAFile-and-CRLFile-options-to-co.patch
--- ngircd-26.1/debian/patches/0003-S2S-TLS-Add-missing-CAFile-and-CRLFile-options-to-co.patch	1970-01-01 01:00:00.000000000 +0100
+++ ngircd-26.1/debian/patches/0003-S2S-TLS-Add-missing-CAFile-and-CRLFile-options-to-co.patch	2024-04-15 14:09:06.000000000 +0200
@@ -0,0 +1,28 @@
+From 6a5d4ddeb6aaa63b958aed6ad9a84b1400530ecc Mon Sep 17 00:00:00 2001
+From: Alexander Barton <alex@barton.de>
+Date: Sat, 16 Dec 2023 16:29:05 +0100
+Subject: [PATCH 03/20] S2S-TLS: Add missing CAFile and CRLFile options to
+ "configtest" output
+
+(cherry picked from commit 5ca567a18caf699f93495ba2bc3749fb5f65383b)
+---
+ src/ngircd/conf.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/src/ngircd/conf.c
++++ b/src/ngircd/conf.c
+@@ -441,10 +441,14 @@
+ 
+ #ifdef SSL_SUPPORT
+ 	puts("[SSL]");
++	printf("  CAFile = %s\n", Conf_SSLOptions.CAFile
++					? Conf_SSLOptions.CAFile : "");
+ 	printf("  CertFile = %s\n", Conf_SSLOptions.CertFile
+ 					? Conf_SSLOptions.CertFile : "");
+ 	printf("  CipherList = %s\n", Conf_SSLOptions.CipherList ?
+ 	       Conf_SSLOptions.CipherList : DEFAULT_CIPHERS);
++	printf("  CRLFile = %s\n", Conf_SSLOptions.CRLFile
++					? Conf_SSLOptions.CRLFile : "");
+ 	printf("  DHFile = %s\n", Conf_SSLOptions.DHFile
+ 					? Conf_SSLOptions.DHFile : "");
+ 	printf("  KeyFile = %s\n", Conf_SSLOptions.KeyFile
diff -Nru ngircd-26.1/debian/patches/0004-S2S-TLS-Remove-leftover-debug-messages.patch ngircd-26.1/debian/patches/0004-S2S-TLS-Remove-leftover-debug-messages.patch
--- ngircd-26.1/debian/patches/0004-S2S-TLS-Remove-leftover-debug-messages.patch	1970-01-01 01:00:00.000000000 +0100
+++ ngircd-26.1/debian/patches/0004-S2S-TLS-Remove-leftover-debug-messages.patch	2024-04-15 14:09:06.000000000 +0200
@@ -0,0 +1,47 @@
+From c6c9edfe6ccc99d18cad039f7c10525a79566081 Mon Sep 17 00:00:00 2001
+From: Alexander Barton <alex@barton.de>
+Date: Sat, 16 Dec 2023 16:30:06 +0100
+Subject: [PATCH 04/20] S2S-TLS: Remove leftover debug messages
+
+(cherry picked from commit 8f8bef9faee96a6033e8719fd38167017299847a)
+---
+ src/ngircd/conn-ssl.c | 7 +------
+ 1 file changed, 1 insertion(+), 6 deletions(-)
+
+--- a/src/ngircd/conn-ssl.c
++++ b/src/ngircd/conn-ssl.c
+@@ -755,7 +755,6 @@
+ 		param = SSL_get0_param(c->ssl_state.ssl);
+ 		X509_VERIFY_PARAM_set_hostflags(param,
+ 						X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS);
+-Log(LOG_ERR, "DEBUG: Setting up hostname verification for '%s'", s->host);
+ 		int err = X509_VERIFY_PARAM_set1_host(param, s->host, 0);
+ 		if (err != 1) {
+ 			Log(LOG_ERR,
+@@ -944,9 +943,7 @@
+ 			const char *peername = SSL_get0_peername(ssl);
+ 			if (peername != NULL)
+ 				cert_ok = true;
+-
+-			Log(LOG_ERR, "X509_V_OK, peername = '%s'", peername);
+-
++			LogDebug("X509_V_OK, peername = '%s'", peername);
+ 		} else
+ 			Log(LOG_ERR, "Certificate validation failed: %s",
+ 			    X509_verify_cert_error_string(err));
+@@ -976,7 +973,6 @@
+ 		    gnutls_certificate_verify_peers2(c->
+ 						     ssl_state.gnutls_session,
+ 						     &status);
+-Log(LOG_ERR, "DEBUG: verify = %d", verify);
+ 		if (verify < 0) {
+ 			Log(LOG_ERR,
+ 			    "gnutls_certificate_verify_peers2 failed: %s",
+@@ -994,7 +990,6 @@
+ 				gnutls_free(out.data);
+ 			}
+ 		}
+-Log(LOG_ERR, "DEBUG: status = %d", status);
+ 
+ 		gnutls_x509_crt_t cert;
+ 		unsigned cert_list_size;
diff -Nru ngircd-26.1/debian/patches/0005-S2S-TLS-OpenSSL-Always-setup-host-name-verification.patch ngircd-26.1/debian/patches/0005-S2S-TLS-OpenSSL-Always-setup-host-name-verification.patch
--- ngircd-26.1/debian/patches/0005-S2S-TLS-OpenSSL-Always-setup-host-name-verification.patch	1970-01-01 01:00:00.000000000 +0100
+++ ngircd-26.1/debian/patches/0005-S2S-TLS-OpenSSL-Always-setup-host-name-verification.patch	2024-04-15 14:09:06.000000000 +0200
@@ -0,0 +1,58 @@
+From d7c7b67c0921f2f78350cd2983f38f386d560d1d Mon Sep 17 00:00:00 2001
+From: Alexander Barton <alex@barton.de>
+Date: Mon, 1 Jan 2024 19:58:35 +0100
+Subject: [PATCH 05/20] S2S-TLS/OpenSSL: Always setup host name verification
+
+Setup host name verification even when the "SSLVerify" option is
+disabled, because even then the peer can present a valid certificate and
+validation would always(!) fail because of the missing host name
+verification setup.
+
+(cherry picked from commit 84b019b11f761b71c8239d60e7f8db0b82a55df3)
+---
+ src/ngircd/conn-ssl.c | 28 +++++++++++++++-------------
+ 1 file changed, 15 insertions(+), 13 deletions(-)
+
+--- a/src/ngircd/conn-ssl.c
++++ b/src/ngircd/conn-ssl.c
+@@ -748,25 +748,27 @@
+ 	if (!ret)
+ 		return false;
+ 	Conn_OPTION_ADD(c, CONN_SSL_CONNECT);
++
+ #ifdef HAVE_LIBSSL
+ 	assert(c->ssl_state.ssl);
+-	if (s->SSLVerify) {
+-		X509_VERIFY_PARAM *param = NULL;
+-		param = SSL_get0_param(c->ssl_state.ssl);
+-		X509_VERIFY_PARAM_set_hostflags(param,
+-						X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS);
+-		int err = X509_VERIFY_PARAM_set1_host(param, s->host, 0);
+-		if (err != 1) {
+-			Log(LOG_ERR,
+-			    "Cannot set up hostname verification for '%s': %u",
+-			    s->host, err);
+-			return false;
+-		}
++
++	X509_VERIFY_PARAM *param = SSL_get0_param(c->ssl_state.ssl);
++	X509_VERIFY_PARAM_set_hostflags(param, X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS);
++	int err = X509_VERIFY_PARAM_set1_host(param, s->host, 0);
++	if (err != 1) {
++		Log(LOG_ERR,
++		    "Cannot set up hostname verification for '%s': %u",
++		    s->host, err);
++		return false;
++	}
++
++	if (s->SSLVerify)
+ 		SSL_set_verify(c->ssl_state.ssl, SSL_VERIFY_PEER,
+ 			       Verify_openssl);
+-	} else
++	else
+ 		SSL_set_verify(c->ssl_state.ssl, SSL_VERIFY_NONE, NULL);
+ #endif
++
+ 	return true;
+ }
+ 
diff -Nru ngircd-26.1/debian/patches/0006-S2S-TLS-OpenSSL-Set-the-verification-flags-only-once.patch ngircd-26.1/debian/patches/0006-S2S-TLS-OpenSSL-Set-the-verification-flags-only-once.patch
--- ngircd-26.1/debian/patches/0006-S2S-TLS-OpenSSL-Set-the-verification-flags-only-once.patch	1970-01-01 01:00:00.000000000 +0100
+++ ngircd-26.1/debian/patches/0006-S2S-TLS-OpenSSL-Set-the-verification-flags-only-once.patch	2024-04-15 14:09:06.000000000 +0200
@@ -0,0 +1,45 @@
+From 9fa5c1908e866d9480bfaf0516111c4741adbd59 Mon Sep 17 00:00:00 2001
+From: Alexander Barton <alex@barton.de>
+Date: Tue, 2 Jan 2024 20:55:15 +0100
+Subject: [PATCH 06/20] S2S-TLS/OpenSSL: Set the verification flags only once
+
+Set the verification flags in the ConnSSL_SetVerifyProperties_openssl
+function only, don't override them in ConnSSL_InitLibrary() afterwards.
+
+No functional changes, now ConnSSL_SetVerifyProperties_openssl() sets
+exactly the parameters which ConnSSL_InitLibrary() always overwrote ...
+
+(cherry picked from commit 08647ab1e7cf0d034f2d8987a3cac3201af84e02)
+---
+ src/ngircd/conn-ssl.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+--- a/src/ngircd/conn-ssl.c
++++ b/src/ngircd/conn-ssl.c
+@@ -401,8 +401,6 @@
+ 			    SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1 |
+ 			    SSL_OP_NO_COMPRESSION);
+ 	SSL_CTX_set_mode(newctx, SSL_MODE_ENABLE_PARTIAL_WRITE);
+-	SSL_CTX_set_verify(newctx, SSL_VERIFY_PEER|SSL_VERIFY_CLIENT_ONCE,
+-			   Verify_openssl);
+ 	SSL_CTX_free(ssl_ctx);
+ 	ssl_ctx = newctx;
+ 	Log(LOG_INFO, "%s initialized.", OpenSSL_version(OPENSSL_VERSION));
+@@ -615,7 +613,6 @@
+ {
+ 	X509_STORE *store = NULL;
+ 	X509_LOOKUP *lookup;
+-	int verify_flags = SSL_VERIFY_PEER;
+ 	bool ret = false;
+ 
+ 	if (!Conf_SSLOptions.CAFile)
+@@ -649,7 +646,8 @@
+ 		}
+ 	}
+ 
+-	SSL_CTX_set_verify(ctx, verify_flags, Verify_openssl);
++	SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER|SSL_VERIFY_CLIENT_ONCE,
++			   Verify_openssl);
+ 	SSL_CTX_set_verify_depth(ctx, MAX_CERT_CHAIN_LENGTH);
+ 	ret = true;
+ out:
diff -Nru ngircd-26.1/debian/patches/0007-S2S-TLS-OpenSSL-Fix-handling-of-certificate-informat.patch ngircd-26.1/debian/patches/0007-S2S-TLS-OpenSSL-Fix-handling-of-certificate-informat.patch
--- ngircd-26.1/debian/patches/0007-S2S-TLS-OpenSSL-Fix-handling-of-certificate-informat.patch	1970-01-01 01:00:00.000000000 +0100
+++ ngircd-26.1/debian/patches/0007-S2S-TLS-OpenSSL-Fix-handling-of-certificate-informat.patch	2024-04-15 14:09:06.000000000 +0200
@@ -0,0 +1,81 @@
+From 0bdc552ffe5c47be83c646b61e9a7d211d4568a6 Mon Sep 17 00:00:00 2001
+From: Alexander Barton <alex@barton.de>
+Date: Tue, 2 Jan 2024 21:10:17 +0100
+Subject: [PATCH 07/20] S2S-TLS/OpenSSL: Fix handling of certificate
+ information for incoming connections
+
+Show proper certificate information for incoming connections, too, and
+not "peer did not present a certificate", regardless if the client sent
+a certificate or not.
+
+And free the client certificate structure "peer_cert" on incoming
+connections as well!
+
+(cherry picked from commit 679505aab9fea21b27a3d4bbf99cf2a16cf3d3d5)
+---
+ src/ngircd/conn-ssl.c | 46 ++++++++++++++++++++++++++++---------------
+ 1 file changed, 30 insertions(+), 16 deletions(-)
+
+--- a/src/ngircd/conn-ssl.c
++++ b/src/ngircd/conn-ssl.c
+@@ -935,22 +935,36 @@
+ 	Log(LOG_INFO, "Connection %d: initialized %s using cipher %s, %s.",
+ 	    c->sock, SSL_get_version(ssl), SSL_get_cipher(ssl), comp_alg);
+ 	peer_cert = SSL_get_peer_certificate(ssl);
+-	if (peer_cert && connect) {
++	if (peer_cert) {
+ 		cert_seen = true;
+-		/* Client: Check server certificate */
+-		int err = SSL_get_verify_result(ssl);
+-		if (err == X509_V_OK) {
+-			const char *peername = SSL_get0_peername(ssl);
+-			if (peername != NULL)
+-				cert_ok = true;
+-			LogDebug("X509_V_OK, peername = '%s'", peername);
+-		} else
+-			Log(LOG_ERR, "Certificate validation failed: %s",
+-			    X509_verify_cert_error_string(err));
+-		snprintf(msg, sizeof(msg), "%svalid peer certificate",
+-			 cert_ok ? "" : "in");
+-		LogOpenSSL_CertInfo(cert_ok ? LOG_DEBUG : LOG_ERR, peer_cert,
+-				    msg);
++
++		if (connect) {
++			/* Outgoing connection. Verify the remote server! */
++			int err = SSL_get_verify_result(ssl);
++			if (err == X509_V_OK) {
++				const char *peername = SSL_get0_peername(ssl);
++				if (peername != NULL)
++					cert_ok = true;
++				LogDebug("X509_V_OK, peername = '%s'", peername);
++			} else
++				Log(LOG_WARNING, "Certificate validation failed: %s!",
++				    X509_verify_cert_error_string(err));
++
++			snprintf(msg, sizeof(msg), "Got %svalid server certificate",
++				 cert_ok ? "" : "in");
++			LogOpenSSL_CertInfo(LOG_INFO, peer_cert, msg);
++		} else {
++			/* Incoming connection.
++			 * Accept all certificates, don't depend on their
++			 * validity: for example, we don't know the hostname
++			 * to check, because we not yet even know if this is a
++			 * server connection at all and if so, which one, so we
++			 * don't know a host name to look for. On the other
++			 * hand we want client certificates, for example for
++			 * "CertFP" authentication with services ... */
++			LogOpenSSL_CertInfo(LOG_INFO, peer_cert,
++					    "Got unchecked client certificate");
++		}
+ 
+ 		X509_free(peer_cert);
+ 	}
+@@ -1038,7 +1052,7 @@
+ 	if (cert_ok)
+ 		Conn_OPTION_ADD(c, CONN_SSL_PEERCERT_OK);
+ 	if (!cert_seen)
+-		Log(LOG_INFO, "Peer did not present a certificate");
++		Log(LOG_INFO, "Peer did not present a certificate.");
+ }
+ 
+ 
diff -Nru ngircd-26.1/debian/patches/0008-S2S-TLS-OpenSSL-Postpone-verification-of-TLS-session.patch ngircd-26.1/debian/patches/0008-S2S-TLS-OpenSSL-Postpone-verification-of-TLS-session.patch
--- ngircd-26.1/debian/patches/0008-S2S-TLS-OpenSSL-Postpone-verification-of-TLS-session.patch	1970-01-01 01:00:00.000000000 +0100
+++ ngircd-26.1/debian/patches/0008-S2S-TLS-OpenSSL-Postpone-verification-of-TLS-session.patch	2024-04-15 14:09:06.000000000 +0200
@@ -0,0 +1,72 @@
+From 1a63a5e98b1dfe3a6e31dd6206585a1476f7d242 Mon Sep 17 00:00:00 2001
+From: Alexander Barton <alex@barton.de>
+Date: Tue, 2 Jan 2024 22:02:46 +0100
+Subject: [PATCH 08/20] S2S-TLS/OpenSSL: Postpone verification of TLS session
+ right before server handshake
+
+The verify callback in OpenSSL is called pretty early, and at that time
+it is not possible yet to check which connection it belongs to, and some
+connections may have relaxed requirements.
+
+So always return success in the Verify_openssl() callback, and postpone
+validation of the TLS session until starting the server handshake in
+cb_connserver_login_ssl(), when we know which server this connection
+belongs to and which options (like "SSLVerify") are in effect.
+
+The code doing this was already present in cb_connserver_login_ssl(),
+but this patch adds a more prominent comment to the function.
+
+(cherry picked from commit 3db3b47fc7172a69b7d99d66eddb07a323dc6e74)
+---
+ src/ngircd/conn-ssl.c | 21 +++++++++++++++------
+ src/ngircd/conn.c     |  7 +++++++
+ 2 files changed, 22 insertions(+), 6 deletions(-)
+
+--- a/src/ngircd/conn-ssl.c
++++ b/src/ngircd/conn-ssl.c
+@@ -211,14 +211,23 @@
+ static int
+ Verify_openssl(int preverify_ok, X509_STORE_CTX * ctx)
+ {
+-	int err;
+-
++#ifdef DEBUG
+ 	if (!preverify_ok) {
+-		err = X509_STORE_CTX_get_error(ctx);
+-		Log(LOG_ERR, "Certificate validation failed: %s",
+-		    X509_verify_cert_error_string(err));
++		int err = X509_STORE_CTX_get_error(ctx);
++		LogDebug("Certificate validation failed: %s",
++			 X509_verify_cert_error_string(err));
+ 	}
+-	return preverify_ok;
++#else
++	(void)preverify_ok;
++	(void)ctx;
++#endif
++
++	/* Always(!) return success as we have to deal with invalid
++	 * (self-signed, expired, ...) client certificates and with invalid
++	 * server certificates when "SSLVerify" is disabled, which we don't
++	 * know at this stage. Therefore we postpone this check, it will be
++	 * (and has to be!) handled in cb_connserver_login_ssl(). */
++	return 1;
+ }
+ #endif
+ 
+--- a/src/ngircd/conn.c
++++ b/src/ngircd/conn.c
+@@ -2539,6 +2539,13 @@
+ /**
+  * IO callback for new outgoing SSL-enabled server connections.
+  *
++ * IMPORTANT: The SSL session has been validated before, but all errors have
++ * been ignored so far! The reason for this is that the generic SSL code has no
++ * idea if the new session actually belongs to a server, as this only becomes
++ * clear when the remote peer sends its PASS command (and we have to handle
++ * invalid client certificates!). Therefore, it is important to check the
++ * status of the SSL session first before continuing the server handshake here!
++ *
+  * @param sock		Socket descriptor.
+  * @param unused	(ignored IO specification)
+  */
diff -Nru ngircd-26.1/debian/patches/0009-S2S-TLS-OpenSSL-Streamline-logging.patch ngircd-26.1/debian/patches/0009-S2S-TLS-OpenSSL-Streamline-logging.patch
--- ngircd-26.1/debian/patches/0009-S2S-TLS-OpenSSL-Streamline-logging.patch	1970-01-01 01:00:00.000000000 +0100
+++ ngircd-26.1/debian/patches/0009-S2S-TLS-OpenSSL-Streamline-logging.patch	2024-04-15 14:09:06.000000000 +0200
@@ -0,0 +1,93 @@
+From 51a6339a8e766f1dee0915e6aea022986eab7306 Mon Sep 17 00:00:00 2001
+From: Alexander Barton <alex@barton.de>
+Date: Tue, 2 Jan 2024 22:13:42 +0100
+Subject: [PATCH 09/20] S2S-TLS/OpenSSL: Streamline logging
+
+This includes simplifying cb_connserver_login_ssl() a bit, we do not
+have to code for invalid state which was ruled out by an assert() and
+therefore can get rid of the goto altogether (and don't log the same
+error twice with different messages).
+
+(cherry picked from commit 02bb99b0242ade8af78f957aa1657561374ef1d6)
+---
+ src/ngircd/conn-ssl.c | 15 +++++++++------
+ src/ngircd/conn.c     | 25 +++++++++++--------------
+ 2 files changed, 20 insertions(+), 20 deletions(-)
+
+--- a/src/ngircd/conn-ssl.c
++++ b/src/ngircd/conn-ssl.c
+@@ -155,13 +155,13 @@
+ 	mem = BIO_new(BIO_s_mem());
+ 	if (!mem)
+ 		return;
+-	X509_NAME_print_ex(mem, X509_get_subject_name(cert), 4,
++	X509_NAME_print_ex(mem, X509_get_subject_name(cert), 0,
+ 			   XN_FLAG_ONELINE);
+-	X509_NAME_print_ex(mem, X509_get_issuer_name(cert), 4, XN_FLAG_ONELINE);
++	X509_NAME_print_ex(mem, X509_get_issuer_name(cert), 2, XN_FLAG_ONELINE);
+ 	if (BIO_write(mem, "", 1) == 1) {
+ 		len = BIO_get_mem_data(mem, &memptr);
+ 		if (memptr && len > 0)
+-			Log(level, "%s: \"%s\"", msg, memptr);
++			Log(level, "%s: \"%s\".", msg, memptr);
+ 	}
+ 	(void)BIO_set_close(mem, BIO_CLOSE);
+ 	BIO_free(mem);
+@@ -832,9 +832,12 @@
+ 				    "SSL error, client disconnected [in %s()]!",
+ 				    fname);
+ 				break;
+-			case -1:	/* low level socket I/O error, check errno */
+-				Log(LOG_ERR, "SSL error: %s [in %s()]!",
+-				    strerror(real_errno), fname);
++			case -1:
++				/* Low level socket I/O error, check errno. But
++				 * we don't need to log this here, the generic
++				 * connection layer will take care of it. */
++				LogDebug("SSL error: %s [in %s()]!",
++					 strerror(real_errno), fname);
+ 			}
+ 		}
+ 		break;
+--- a/src/ngircd/conn.c
++++ b/src/ngircd/conn.c
+@@ -2574,28 +2574,25 @@
+ 
+ 	serveridx = Conf_GetServer(idx);
+ 	assert(serveridx >= 0);
+-	if (serveridx < 0)
+-		goto err;
+-
+-	Log( LOG_INFO, "SSL connection %d with \"%s:%d\" established.", idx,
+-	    My_Connections[idx].host, Conf_Server[Conf_GetServer( idx )].port );
+ 
++	/* The SSL handshake is done, but validation results were ignored so
++	 * far, so let's see where we are: */
++	LogDebug("SSL handshake on socket %d done.", idx);
+ 	if (!Conn_OPTION_ISSET(&My_Connections[idx], CONN_SSL_PEERCERT_OK)) {
+ 		if (Conf_Server[serveridx].SSLVerify) {
+ 			Log(LOG_ERR,
+-				"SSLVerify enabled for %d, but peer certificate check failed",
+-				idx);
+-			goto err;
++				"Peer certificate check failed for \"%s\" on connection %d!",
++				My_Connections[idx].host, idx);
++			Conn_Close(idx, "Valid certificate required",
++				   NULL, false);
++			return;
+ 		}
+ 		Log(LOG_WARNING,
+-			"Peer certificate check failed for %d, but SSLVerify is disabled, continuing",
+-			idx);
++			"Peer certificate check failed for \"%s\" on connection %d, but \"SSLVerify\" is disabled. Continuing ...",
++			My_Connections[idx].host, idx);
+ 	}
++	LogDebug("Server certificate accepted, continuing server login ...");
+ 	server_login(idx);
+-	return;
+-      err:
+-	Log(LOG_ERR, "SSL connection on socket %d failed!", sock);
+-	Conn_Close(idx, "Can't connect!", NULL, false);
+ }
+ 
+ 
diff -Nru ngircd-26.1/debian/patches/0010-S2S-TLS-Fix-formatting-and-sort-new-SSL-options-in-n.patch ngircd-26.1/debian/patches/0010-S2S-TLS-Fix-formatting-and-sort-new-SSL-options-in-n.patch
--- ngircd-26.1/debian/patches/0010-S2S-TLS-Fix-formatting-and-sort-new-SSL-options-in-n.patch	1970-01-01 01:00:00.000000000 +0100
+++ ngircd-26.1/debian/patches/0010-S2S-TLS-Fix-formatting-and-sort-new-SSL-options-in-n.patch	2024-04-15 14:09:06.000000000 +0200
@@ -0,0 +1,38 @@
+From c9247d7031c4f92d583035ea29a182b3dd8b478d Mon Sep 17 00:00:00 2001
+From: Alexander Barton <alex@barton.de>
+Date: Wed, 3 Jan 2024 15:40:58 +0100
+Subject: [PATCH 10/20] S2S-TLS: Fix formatting and sort new SSL options in
+ ngircd.conf manual page
+
+(cherry picked from commit 58ee4df2ae2e4e59ae8909b69670825229158da8)
+---
+ man/ngircd.conf.5.tmpl | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/man/ngircd.conf.5.tmpl
++++ b/man/ngircd.conf.5.tmpl
+@@ -385,13 +385,10 @@
+ section. Please note that this whole section is only recognized by ngIRCd
+ when it is compiled with support for SSL using OpenSSL or GnuTLS!
+ .TP
+-\fBCAFile (string)\fR
++\fBCAFile\fR (string)
+ Filename pointing to the Trusted CA Certificates. This is required for
+ verifying peer certificates.
+ .TP
+-\fBCRLFile (string)\fR
+-Filename of Certificate Revocation List.
+-.TP
+ \fBCertFile\fR (string)
+ SSL Certificate file of the private server key.
+ .TP
+@@ -401,6 +398,9 @@
+ Please see 'man 1ssl ciphers' (OpenSSL) and 'man 3 gnutls_priority_init'
+ (GnuTLS) for details.
+ .TP
++\fBCRLFile\fR (string)
++Filename of Certificate Revocation List.
++.TP
+ \fBDHFile\fR (string)
+ Name of the Diffie-Hellman Parameter file. Can be created with GnuTLS
+ "certtool \-\-generate-dh-params" or "openssl dhparam". If this file is not
diff -Nru ngircd-26.1/debian/patches/0011-S2S-TLS-MAX_CERT_CHAIN_LENGTH-is-only-used-by-OpenSS.patch ngircd-26.1/debian/patches/0011-S2S-TLS-MAX_CERT_CHAIN_LENGTH-is-only-used-by-OpenSS.patch
--- ngircd-26.1/debian/patches/0011-S2S-TLS-MAX_CERT_CHAIN_LENGTH-is-only-used-by-OpenSS.patch	1970-01-01 01:00:00.000000000 +0100
+++ ngircd-26.1/debian/patches/0011-S2S-TLS-MAX_CERT_CHAIN_LENGTH-is-only-used-by-OpenSS.patch	2024-04-15 14:09:06.000000000 +0200
@@ -0,0 +1,30 @@
+From 9653e891d5aa9b9182f10eb5b737242de0ccada9 Mon Sep 17 00:00:00 2001
+From: Alexander Barton <alex@barton.de>
+Date: Fri, 5 Jan 2024 22:17:12 +0100
+Subject: [PATCH 11/20] S2S-TLS: MAX_CERT_CHAIN_LENGTH is only used by OpenSSL
+
+(cherry picked from commit c8589e9890742c377c78595131ef1cdc8d784c66)
+---
+ src/ngircd/conn-ssl.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/src/ngircd/conn-ssl.c
++++ b/src/ngircd/conn-ssl.c
+@@ -45,6 +45,8 @@
+ #include <openssl/dh.h>
+ #include <openssl/x509v3.h>
+ 
++#define MAX_CERT_CHAIN_LENGTH	10	/* XXX: do not hardcode */
++
+ static SSL_CTX * ssl_ctx;
+ static DH *dh_params;
+ 
+@@ -52,8 +54,6 @@
+ static bool ConnSSL_SetVerifyProperties_openssl PARAMS((SSL_CTX * c));
+ #endif
+ 
+-#define MAX_CERT_CHAIN_LENGTH	10	/* XXX: do not hardcode */
+-
+ #ifdef HAVE_LIBGNUTLS
+ #include <sys/types.h>
+ #include <sys/stat.h>
diff -Nru ngircd-26.1/debian/patches/0012-S2S-TLS-GnuTLS-Update-SSL-code-for-GnuTLS-certificat.patch ngircd-26.1/debian/patches/0012-S2S-TLS-GnuTLS-Update-SSL-code-for-GnuTLS-certificat.patch
--- ngircd-26.1/debian/patches/0012-S2S-TLS-GnuTLS-Update-SSL-code-for-GnuTLS-certificat.patch	1970-01-01 01:00:00.000000000 +0100
+++ ngircd-26.1/debian/patches/0012-S2S-TLS-GnuTLS-Update-SSL-code-for-GnuTLS-certificat.patch	2024-04-15 14:09:06.000000000 +0200
@@ -0,0 +1,27 @@
+From 8676c743246aaebe6d45f0978812c154ecfa25dd Mon Sep 17 00:00:00 2001
+From: Alexander Barton <alex@barton.de>
+Date: Fri, 5 Jan 2024 22:23:53 +0100
+Subject: [PATCH 12/20] S2S-TLS/GnuTLS: Update SSL code for GnuTLS certificate
+ reloading
+
+Without this, the S2S-TLS-Patch not even compiles with GnuTLS because
+of the "new" GnuTLS certificate reload support implemented in commit
+eead4a63 ("x509_cred_slot").
+
+(cherry picked from commit 0e176b557037b583f408229b518646804b33d745)
+---
+ src/ngircd/conn-ssl.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/src/ngircd/conn-ssl.c
++++ b/src/ngircd/conn-ssl.c
+@@ -468,6 +468,9 @@
+ 	if (!Conf_SSLOptions.CAFile)
+ 		return true;
+ 
++	x509_cred_slot *slot = array_get(&x509_creds, sizeof(x509_cred_slot), x509_cred_idx);
++	gnutls_certificate_credentials_t x509_cred = slot->x509_cred;
++
+ 	err = gnutls_certificate_set_x509_trust_file(x509_cred,
+ 						     Conf_SSLOptions.CAFile,
+ 						     GNUTLS_X509_FMT_PEM);
diff -Nru ngircd-26.1/debian/patches/0013-S2S-TLS-GnuTLS-Fix-handling-of-certificate-informati.patch ngircd-26.1/debian/patches/0013-S2S-TLS-GnuTLS-Fix-handling-of-certificate-informati.patch
--- ngircd-26.1/debian/patches/0013-S2S-TLS-GnuTLS-Fix-handling-of-certificate-informati.patch	1970-01-01 01:00:00.000000000 +0100
+++ ngircd-26.1/debian/patches/0013-S2S-TLS-GnuTLS-Fix-handling-of-certificate-informati.patch	2024-04-15 14:09:06.000000000 +0200
@@ -0,0 +1,118 @@
+From a1e391b1148b2e2cb406423473dc89ff28b7cdba Mon Sep 17 00:00:00 2001
+From: Alexander Barton <alex@barton.de>
+Date: Fri, 5 Jan 2024 22:29:40 +0100
+Subject: [PATCH 13/20] S2S-TLS/GnuTLS: Fix handling of certificate information
+ for incoming connections
+
+Show proper certificate information for incoming connections, too, and
+not "peer did not present a certificate", regardless if the client sent
+a certificate or not.
+
+This change is for GnuTLS and similar to what was implemented in commit
+for OpenSSL in "S2S-TLS/OpenSSL: Fix handling of certificate information
+for incoming connections".
+
+(cherry picked from commit 509ff6032686662328f4ecb0c5c287a34e929c53)
+---
+ src/ngircd/conn-ssl.c | 75 ++++++++++++++++++++++++-------------------
+ 1 file changed, 42 insertions(+), 33 deletions(-)
+
+--- a/src/ngircd/conn-ssl.c
++++ b/src/ngircd/conn-ssl.c
+@@ -747,6 +747,7 @@
+ #ifdef HAVE_LIBGNUTLS
+ 	int err;
+ 
++	(void)s;
+ 	err = gnutls_init(&c->ssl_state.gnutls_session, GNUTLS_CLIENT);
+ 	if (err) {
+ 		Log(LOG_ERR, "Failed to initialize new SSL session: %s",
+@@ -996,29 +997,8 @@
+ 	    gnutls_cipher_get_name(cipher),
+ 	    gnutls_mac_get_name(gnutls_mac_get(sess)));
+ 	cred = gnutls_auth_get_type(c->ssl_state.gnutls_session);
+-	if (cred == GNUTLS_CRD_CERTIFICATE && connect) {
++	if (cred == GNUTLS_CRD_CERTIFICATE) {
+ 		cert_seen = true;
+-		int verify =
+-		    gnutls_certificate_verify_peers2(c->
+-						     ssl_state.gnutls_session,
+-						     &status);
+-		if (verify < 0) {
+-			Log(LOG_ERR,
+-			    "gnutls_certificate_verify_peers2 failed: %s",
+-			    gnutls_strerror(verify));
+-			goto done_cn_validation;
+-		} else if (status) {
+-			gnutls_datum_t out;
+-
+-			if (gnutls_certificate_verification_status_print
+-			    (status, gnutls_certificate_type_get(sess), &out,
+-			     0) == GNUTLS_E_SUCCESS) {
+-				Log(LOG_ERR,
+-				    "Certificate validation failed: %s",
+-				    out.data);
+-				gnutls_free(out.data);
+-			}
+-		}
+ 
+ 		gnutls_x509_crt_t cert;
+ 		unsigned cert_list_size;
+@@ -1042,17 +1022,46 @@
+ 			    gnutls_strerror(err));
+ 			goto done_cn_validation;
+ 		}
+-		err = gnutls_x509_crt_check_hostname(cert, c->host);
+-		if (err == 0)
+-			Log(LOG_ERR,
+-			    "Failed to verify the hostname, expected \"%s\"",
+-			    c->host);
+-		else
+-			cert_ok = verify == 0 && status == 0;
+-
+-		snprintf(msg, sizeof(msg), "%svalid peer certificate",
+-			cert_ok ? "" : "in");
+-		LogGnuTLS_CertInfo(cert_ok ? LOG_DEBUG : LOG_ERR, cert, msg);
++
++		if (connect) {
++			int verify =
++			    gnutls_certificate_verify_peers2(c->
++							     ssl_state.gnutls_session,
++							     &status);
++			if (verify < 0) {
++				Log(LOG_ERR,
++				    "gnutls_certificate_verify_peers2 failed: %s",
++				    gnutls_strerror(verify));
++				goto done_cn_validation;
++			} else if (status) {
++				gnutls_datum_t out;
++
++				if (gnutls_certificate_verification_status_print
++				    (status, gnutls_certificate_type_get(sess), &out,
++				     0) == GNUTLS_E_SUCCESS) {
++					Log(LOG_ERR,
++					    "Certificate validation failed: %s",
++					    out.data);
++					gnutls_free(out.data);
++				}
++			}
++
++			err = gnutls_x509_crt_check_hostname(cert, c->host);
++			if (err == 0)
++				Log(LOG_ERR,
++				    "Failed to verify the hostname, expected \"%s\"",
++				    c->host);
++			else
++				cert_ok = verify == 0 && status == 0;
++
++			snprintf(msg, sizeof(msg), "Got %svalid server certificate",
++				cert_ok ? "" : "in");
++			LogGnuTLS_CertInfo(LOG_INFO, cert, msg);
++		} else {
++			/* Incoming connection. Please see comments for OpenSSL! */
++			LogGnuTLS_CertInfo(LOG_INFO, cert,
++					    "Got unchecked peer certificate");
++		}
+ 
+ 		gnutls_x509_crt_deinit(cert);
+ done_cn_validation:
diff -Nru ngircd-26.1/debian/patches/0014-S2S-TLS-GnuTLS-Streamline-logging.patch ngircd-26.1/debian/patches/0014-S2S-TLS-GnuTLS-Streamline-logging.patch
--- ngircd-26.1/debian/patches/0014-S2S-TLS-GnuTLS-Streamline-logging.patch	1970-01-01 01:00:00.000000000 +0100
+++ ngircd-26.1/debian/patches/0014-S2S-TLS-GnuTLS-Streamline-logging.patch	2024-04-15 14:09:06.000000000 +0200
@@ -0,0 +1,49 @@
+From e092877d9ad69f0cb4dea10bf546e561dd6a1abd Mon Sep 17 00:00:00 2001
+From: Alexander Barton <alex@barton.de>
+Date: Fri, 5 Jan 2024 22:31:32 +0100
+Subject: [PATCH 14/20] S2S-TLS/GnuTLS: Streamline logging
+
+(cherry picked from commit 663972c88d3ae3e3226fe6f95ca1113694ce0618)
+---
+ src/ngircd/conn-ssl.c | 12 +++++++-----
+ 1 file changed, 7 insertions(+), 5 deletions(-)
+
+--- a/src/ngircd/conn-ssl.c
++++ b/src/ngircd/conn-ssl.c
+@@ -869,8 +869,10 @@
+ 	default:
+ 		assert(code < 0);
+ 		if (gnutls_error_is_fatal(code)) {
+-			Log(LOG_ERR, "SSL error: %s [%s].",
+-			    gnutls_strerror(code), fname);
++			/* We don't need to log this here, the generic
++			 * connection layer will take care of it. */
++			LogDebug("SSL error: %s [%s].",
++				 gnutls_strerror(code), fname);
+ 			ConnSSL_Free(c);
+ 			return -1;
+ 		}
+@@ -914,12 +916,12 @@
+ 	assert(size);
+ 	issuer_dn = LogMalloc(size);
+ 	if (!issuer_dn) {
+-		Log(level, "%s: Distinguished Name: %s", msg, dn);
++		Log(level, "%s: Distinguished Name \"%s\".", msg, dn);
+ 		free(dn);
+ 		return;
+ 	}
+ 	gnutls_x509_crt_get_issuer_dn(cert, issuer_dn, &size);
+-	Log(level, "%s: Distinguished Name: \"%s\", Issuer \"%s\"", msg, dn,
++	Log(level, "%s: Distinguished Name \"%s\", Issuer \"%s\".", msg, dn,
+ 	    issuer_dn);
+ 	free(dn);
+ 	free(issuer_dn);
+@@ -979,7 +981,7 @@
+ 			 * hand we want client certificates, for example for
+ 			 * "CertFP" authentication with services ... */
+ 			LogOpenSSL_CertInfo(LOG_INFO, peer_cert,
+-					    "Got unchecked client certificate");
++					    "Got unchecked peer certificate");
+ 		}
+ 
+ 		X509_free(peer_cert);
diff -Nru ngircd-26.1/debian/patches/0015-S2S-TLS-Verify-the-TLS-certificates-by-default.patch ngircd-26.1/debian/patches/0015-S2S-TLS-Verify-the-TLS-certificates-by-default.patch
--- ngircd-26.1/debian/patches/0015-S2S-TLS-Verify-the-TLS-certificates-by-default.patch	1970-01-01 01:00:00.000000000 +0100
+++ ngircd-26.1/debian/patches/0015-S2S-TLS-Verify-the-TLS-certificates-by-default.patch	2024-04-15 14:09:06.000000000 +0200
@@ -0,0 +1,27 @@
+From 7086f4d15e240f5394b0b3e24d100f9c4fe4c792 Mon Sep 17 00:00:00 2001
+From: Alexander Barton <alex@barton.de>
+Date: Sat, 6 Jan 2024 15:55:54 +0100
+Subject: [PATCH 15/20] S2S-TLS: Verify the TLS certificates by default
+
+This is already mentioned as the default in the manual page and the
+sample configuration file, but was actually not enabled in the code!
+
+(cherry picked from commit 180e2ec1359378172135472148c99a2d14e873cc)
+---
+ src/ngircd/conf.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/src/ngircd/conf.c
++++ b/src/ngircd/conf.c
+@@ -2298,6 +2298,11 @@
+ 	Proc_InitStruct(&Server->res_stat);
+ 	Server->conn_id = NONE;
+ 	memset(&Server->bind_addr, 0, sizeof(Server->bind_addr));
++
++#ifdef SSL_SUPPORT
++	/* Verify SSL connections by default! */
++	Server->SSLVerify = true;
++#endif
+ }
+ 
+ /* -eof- */
diff -Nru ngircd-26.1/debian/patches/0016-S2S-TLS-GnuTLS-Fix-handling-of-connections-without-p.patch ngircd-26.1/debian/patches/0016-S2S-TLS-GnuTLS-Fix-handling-of-connections-without-p.patch
--- ngircd-26.1/debian/patches/0016-S2S-TLS-GnuTLS-Fix-handling-of-connections-without-p.patch	1970-01-01 01:00:00.000000000 +0100
+++ ngircd-26.1/debian/patches/0016-S2S-TLS-GnuTLS-Fix-handling-of-connections-without-p.patch	2024-04-15 14:09:06.000000000 +0200
@@ -0,0 +1,34 @@
+From 0f866fd27333c6d92fa514ba05b2a47d129357e2 Mon Sep 17 00:00:00 2001
+From: Alexander Barton <alex@barton.de>
+Date: Sat, 6 Jan 2024 19:57:50 +0100
+Subject: [PATCH 16/20] S2S-TLS/GnuTLS: Fix handling of connections without
+ peer certificates
+
+(cherry picked from commit 8cef3ce42cd645a3ffb0e1eded52b8b77bb8caff)
+---
+ src/ngircd/conn-ssl.c | 9 ++++-----
+ 1 file changed, 4 insertions(+), 5 deletions(-)
+
+--- a/src/ngircd/conn-ssl.c
++++ b/src/ngircd/conn-ssl.c
+@@ -1000,16 +1000,15 @@
+ 	    gnutls_mac_get_name(gnutls_mac_get(sess)));
+ 	cred = gnutls_auth_get_type(c->ssl_state.gnutls_session);
+ 	if (cred == GNUTLS_CRD_CERTIFICATE) {
+-		cert_seen = true;
+-
+ 		gnutls_x509_crt_t cert;
+ 		unsigned cert_list_size;
+ 		const gnutls_datum_t *cert_list =
+ 		    gnutls_certificate_get_peers(sess, &cert_list_size);
+-		if (!cert_list || cert_list_size == 0) {
+-			Log(LOG_ERR, "No certificates found");
++
++		if (!cert_list || cert_list_size == 0)
+ 			goto done_cn_validation;
+-		}
++
++		cert_seen = true;
+ 		int err = gnutls_x509_crt_init(&cert);
+ 		if (err < 0) {
+ 			Log(LOG_ERR,
diff -Nru ngircd-26.1/debian/patches/0017-S2S-TLS-Convert-SSL.txt-to-Markdown-and-update-infor.patch ngircd-26.1/debian/patches/0017-S2S-TLS-Convert-SSL.txt-to-Markdown-and-update-infor.patch
--- ngircd-26.1/debian/patches/0017-S2S-TLS-Convert-SSL.txt-to-Markdown-and-update-infor.patch	1970-01-01 01:00:00.000000000 +0100
+++ ngircd-26.1/debian/patches/0017-S2S-TLS-Convert-SSL.txt-to-Markdown-and-update-infor.patch	2024-04-15 14:09:06.000000000 +0200
@@ -0,0 +1,246 @@
+From b04ed224cf95c0f31849d3683412cb937cc00efc Mon Sep 17 00:00:00 2001
+From: Alexander Barton <alex@barton.de>
+Date: Mon, 8 Jan 2024 18:31:30 +0100
+Subject: [PATCH 17/20] S2S-TLS: Convert SSL.txt to Markdown and update
+ information given
+
+No longer describe creating self-signed certificates or using "stunnel",
+as both is not recommended.
+
+(cherry picked from commit b826fad15871f73435328b1d77fd364838389adb)
+---
+ INSTALL.md      |   2 +-
+ doc/Makefile.am |   2 +-
+ doc/SSL.md      |  80 +++++++++++++++++++++++++++++++++++
+ doc/SSL.txt     | 108 ------------------------------------------------
+ 4 files changed, 82 insertions(+), 110 deletions(-)
+ create mode 100644 doc/SSL.md
+ delete mode 100644 doc/SSL.txt
+
+--- a/INSTALL.md
++++ b/INSTALL.md
+@@ -347,7 +347,7 @@
+   - `--with-gnutls[=<path>]`
+ 
+   Enable support for SSL/TLS using OpenSSL or GnuTLS libraries.
+-  See `doc/SSL.txt` for details.
++  See `doc/SSL.md` for details.
+ 
+ - IPv6:
+ 
+--- a/doc/Makefile.am
++++ b/doc/Makefile.am
+@@ -33,7 +33,7 @@
+ 	README-Interix.txt \
+ 	RFC.txt \
+ 	Services.txt \
+-	SSL.txt
++	SSL.md
+ 
+ doc_templates = sample-ngircd.conf.tmpl
+ 
+--- /dev/null
++++ b/doc/SSL.md
+@@ -0,0 +1,80 @@
++# [ngIRCd](https://ngircd.barton.de) - SSL/TLS Encrypted Connections
++
++ngIRCd supports SSL/TLS encrypted connections using the *OpenSSL* or *GnuTLS*
++libraries. Both encrypted server-server links as well as client-server links
++are supported.
++
++SSL is a compile-time option which is disabled by default. Use one of these
++options of the ./configure script to enable it:
++
++- `--with-openssl`: enable SSL support using OpenSSL.
++- `--with-gnutls`: enable SSL support using GnuTLS.
++
++You can check the output of `ngircd --version` to validate if your executable
++includes support for SSL or not: "+SSL" must be listed in the feature flags.
++
++You also need a SSL key and certificate, for example using Let's Encrypt, which
++is out of the scope of this document.
++
++From a feature point of view, ngIRCds support for both libraries is
++comparable. The only major difference (at this time) is that ngIRCd with GnuTLS
++does not support password protected private keys.
++
++## Configuration
++
++SSL-encrypted connections and plain-text connects can't run on the same network
++port (which is a limitation of the IRC protocol); therefore you have to define
++separate port(s) in your `[SSL]` block in the configuration file.
++
++A minimal configuration for *accepting* SSL-encrypted client & server
++connections looks like this:
++
++``` ini
++[SSL]
++CertFile = /etc/ssl/certs/my-fullchain.pem
++KeyFile = /etc/ssl/certs/my-privkey.pem
++Ports = 6697, 6698
++```
++
++In this case, the server only deals with *incoming* connections and never has to
++validate SSL certificates itself, and therefore no "Certificate Authorities" are
++needed.
++
++If you want to use *outgoing* SSL-connections to other servers, you need to add:
++
++``` ini
++[SSL]
++...
++CAFile = /etc/ssl/certs/ca-certificates.crt
++DHFile = /etc/ngircd/dhparams.pem
++
++[SERVER]
++...
++SSLConnect = yes
++```
++
++The `CAFile` option configures a file listing all the certificates of the
++trusted Certificate Authorities.
++
++The Diffie-Hellman parameters file `dhparams.pem` can be created like this:
++
++- OpenSSL: `openssl dhparam -2 -out /etc/ngircd/dhparams.pem 4096`
++- GnuTLS: `certtool --generate-dh-params --bits 4096 --outfile /etc/ngircd/dhparams.pem`
++
++Note that enabling `SSLConnect` not only enforces SSL-encrypted links for
++*outgoing* connections to other servers, but for *incoming* connections as well:
++If a server configured with `SSLConnect = yes` tries to connect on a plain-text
++connection, it won't be accepted to prevent data leakage! Therefore you should
++set this for *all* servers you expect to use SSL-encrypted connections!
++
++## Accepting untrusted Remote Certificates
++
++If you are using self-signed certificates or otherwise invalid certificates,
++which ngIRCd would reject by default, you can force ngIRCd to skip certificate
++validation on a per-server basis and continue establishing outgoing connections
++to the respective peer by setting `SSLVerify = no` in the `[SERVER]` block of
++this remote server in your configuration.
++
++But please think twice before doing so: the established connection is still
++encrypted but the remote site is *not verified at all* and man-in-the-middle
++attacks are possible!
+--- a/doc/SSL.txt
++++ /dev/null
+@@ -1,108 +0,0 @@
+-
+-                     ngIRCd - Next Generation IRC Server
+-
+-                        (c)2001-2008 Alexander Barton,
+-                    alex@barton.de, http://www.barton.de/
+-
+-               ngIRCd is free software and published under the
+-                   terms of the GNU General Public License.
+-
+-                                 -- SSL.txt --
+-
+-
+-ngIRCd supports SSL/TLSv1 encrypted connections using the OpenSSL or GnuTLS
+-libraries. Both encrypted server-server links as well as client-server links
+-are supported.
+-
+-SSL is a compile-time option which is disabled by default. Use one of these
+-options of the ./configure script to enable it:
+-
+-  --with-openssl     enable SSL support using OpenSSL
+-  --with-gnutls      enable SSL support using GnuTLS
+-
+-You also need a key/certificate, see below for how to create a self-signed one.
+-
+-From a feature point of view, ngIRCds support for both libraries is
+-comparable. The only major difference (at this time) is that ngircd with gnutls
+-does not support password protected private keys.
+-
+-Configuration
+-~~~~~~~~~~~~~
+-
+-To enable SSL connections a separate port must be configured: it is NOT
+-possible to handle unencrypted and encrypted connections on the same port!
+-This is a limitation of the IRC protocol ...
+-
+-You have to set (at least) the following configuration variables in the
+-[SSL] section of ngircd.conf(5): Ports, KeyFile, and CertFile.
+-
+-Now IRC clients are able to connect using SSL on the configured port(s).
+-(Using port 6697 for encrypted connections is common.)
+-
+-To enable encrypted server-server links, you have to additionally set
+-SSLConnect to "yes" in the corresponding [SERVER] section.
+-
+-
+-Creating a self-signed certificate
+-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+-
+-OpenSSL:
+-
+-Creating a self-signed certificate and key:
+- $ openssl req -newkey rsa:2048 -x509 -keyout server-key.pem -out server-cert.pem -days 1461
+-Create DH parameters (optional):
+- $ openssl dhparam -2 -out dhparams.pem 4096
+-
+-GnuTLS:
+-
+-Creating a self-signed certificate and key:
+- $ certtool --generate-privkey --bits 2048 --outfile server-key.pem
+- $ certtool --generate-self-signed --load-privkey server-key.pem --outfile server-cert.pem
+-Create DH parameters (optional):
+- $ certtool  --generate-dh-params --bits 4096 --outfile dhparams.pem
+-
+-
+-Alternate approach using stunnel(1)
+-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+-
+-Alternatively (or if you are using ngIRCd compiled without support
+-for GnuTLS/OpenSSL), you can use external programs/tools like stunnel(1) to
+-get SSL encrypted connections:
+-
+-  <http://stunnel.mirt.net/>
+-  <http://www.stunnel.org/>
+-
+-Stefan Sperling (stefan at binarchy dot net) mailed the following text as a
+-short "how-to", thanks Stefan!
+-
+-=== snip ===
+-    ! This guide applies to stunnel 4.x !
+-
+-    Put this in your stunnel.conf:
+-
+-        [ircs]
+-        accept = 6667
+-        connect = 6668
+-
+-    This makes stunnel listen for incoming connections
+-    on port 6667 and forward decrypted data to port 6668.
+-    We call the connection 'ircs'. Stunnel will use this
+-    name when logging connection attempts via syslog.
+-    You can also use the name in /etc/hosts.{allow,deny}
+-    if you run tcp-wrappers.
+-
+-    To make sure ngircd is listening on the port where
+-    the decrypted data arrives, set
+-
+-        Ports = 6668
+-
+-    in your ngircd.conf.
+-
+-    Start stunnel and restart ngircd.
+-
+-    That's it.
+-    Don't forget to activate ssl support in your irc client ;)
+-    The main drawback of this approach compared to using builtin ssl
+-    is that from ngIRCds point of view, all ssl-enabled client connections will
+-    originate from the host running stunnel.
+-=== snip ===
+--- a/doc/Makefile.in
++++ b/doc/Makefile.in
+@@ -248,7 +248,7 @@
+ 	README-Interix.txt \
+ 	RFC.txt \
+ 	Services.txt \
+-	SSL.txt
++	SSL.md
+ 
+ doc_templates = sample-ngircd.conf.tmpl
+ generated_docs = sample-ngircd.conf
diff -Nru ngircd-26.1/debian/patches/0018-S2S-TLS-Add-notice-to-INSTALL.md.patch ngircd-26.1/debian/patches/0018-S2S-TLS-Add-notice-to-INSTALL.md.patch
--- ngircd-26.1/debian/patches/0018-S2S-TLS-Add-notice-to-INSTALL.md.patch	1970-01-01 01:00:00.000000000 +0100
+++ ngircd-26.1/debian/patches/0018-S2S-TLS-Add-notice-to-INSTALL.md.patch	2024-04-15 14:09:06.000000000 +0200
@@ -0,0 +1,33 @@
+From e8ffea49c26f298b3317fb765f7e6fb378db3923 Mon Sep 17 00:00:00 2001
+From: Alexander Barton <alex@barton.de>
+Date: Thu, 11 Jan 2024 14:24:22 +0100
+Subject: [PATCH 18/20] S2S-TLS: Add notice to INSTALL.md
+
+(cherry picked from commit 6b27eabf5bdbc6bf6f71d7b1e7d059dfeab6849b)
+---
+ INSTALL.md | 14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+--- a/INSTALL.md
++++ b/INSTALL.md
+@@ -12,6 +12,20 @@
+ 
+ ## Upgrade Information
+ 
++This section lists important updates and breaking changes that you should be
++aware of *before* starting the upgrade:
++
++- **Attention**:
++  Starting with release 27, ngIRCd validates SSL/TLS certificates on outgoing
++  server-server links by default and drops(!) connections when the remote
++  certificate is invalid (for example self-signed, expired, not matching the
++  host name, ...). Therefore you have to make sure that all relevant
++  *certificates are valid* (or to disable certificate validation on this
++  connection using the new `SSLVerify = false` setting in the affected
++  `[Server]` block, where the remote certificate is not valid and you can not
++  fix this issue).
++  And this change was backported to this ngIRCd release!
++
+ Differences to version 25
+ 
+ - **Attention**:
diff -Nru ngircd-26.1/debian/patches/0019-S2S-TLS-Fix-make-check-in-separate-build-directory.patch ngircd-26.1/debian/patches/0019-S2S-TLS-Fix-make-check-in-separate-build-directory.patch
--- ngircd-26.1/debian/patches/0019-S2S-TLS-Fix-make-check-in-separate-build-directory.patch	1970-01-01 01:00:00.000000000 +0100
+++ ngircd-26.1/debian/patches/0019-S2S-TLS-Fix-make-check-in-separate-build-directory.patch	2024-04-15 14:09:06.000000000 +0200
@@ -0,0 +1,35 @@
+From e4937e6ed3a13408f8e0f57124aa784de4299147 Mon Sep 17 00:00:00 2001
+From: Alexander Barton <alex@barton.de>
+Date: Sat, 10 Feb 2024 00:14:33 +0100
+Subject: [PATCH 19/20] S2S-TLS: Fix "make check" in separate build directory
+
+(cherry picked from commit b9d6a2f49c4b3607c69b298cc770c0c945f627f6)
+---
+ src/testsuite/prep-server3   | 9 +++++----
+ src/testsuite/switch-server3 | 9 ++++-----
+ 2 files changed, 9 insertions(+), 9 deletions(-)
+
+--- a/src/testsuite/prep-server3
++++ b/src/testsuite/prep-server3
+@@ -1,4 +1,5 @@
+-#!/bin/sh
+-cp ssl/cert-my-first-domain-tld.pem ssl/cert.pem
+-cp ssl/key-my-first-domain-tld.pem ssl/key.pem
+-cp ssl/dhparams-my-first-domain-tld.pem ssl/dhparams.pem
++#!/bin/sh -e
++mkdir -p ssl
++cp "${srcdir}"/ssl/cert-my-first-domain-tld.pem ssl/cert.pem
++cp "${srcdir}"/ssl/key-my-first-domain-tld.pem ssl/key.pem
++cp "${srcdir}"/ssl/dhparams-my-first-domain-tld.pem ssl/dhparams.pem
+--- a/src/testsuite/switch-server3
++++ b/src/testsuite/switch-server3
+@@ -1,5 +1,4 @@
+-#!/bin/sh
+-cp ssl/cert-my-second-domain-tld.pem ssl/cert.pem
+-cp ssl/key-my-second-domain-tld.pem ssl/key.pem
+-cp ssl/dhparams-my-second-domain-tld.pem ssl/dhparams.pem
+-# -eof-
++#!/bin/sh -e
++cp "${srcdir}"/ssl/cert-my-second-domain-tld.pem ssl/cert.pem
++cp "${srcdir}"/ssl/key-my-second-domain-tld.pem ssl/key.pem
++cp "${srcdir}"/ssl/dhparams-my-second-domain-tld.pem ssl/dhparams.pem
diff -Nru ngircd-26.1/debian/patches/0020-METADATA-Fix-unsetting-cloakhost.patch ngircd-26.1/debian/patches/0020-METADATA-Fix-unsetting-cloakhost.patch
--- ngircd-26.1/debian/patches/0020-METADATA-Fix-unsetting-cloakhost.patch	1970-01-01 01:00:00.000000000 +0100
+++ ngircd-26.1/debian/patches/0020-METADATA-Fix-unsetting-cloakhost.patch	2024-04-15 14:09:13.000000000 +0200
@@ -0,0 +1,28 @@
+From fe5f1666983f2ef7499b0454fc30ae36edc29f5e Mon Sep 17 00:00:00 2001
+From: Alexander Barton <alex@barton.de>
+Date: Sun, 17 Mar 2024 15:55:39 +0100
+Subject: [PATCH 20/20] METADATA: Fix unsetting "cloakhost"
+
+Correctly re-generate the "cloaked hostname" when removing the
+"cloakhost" using an empty string by passing down NULL instead of the
+empty string, which results in protocol violations (for example on
+WHOIS).
+
+(cherry picked from commit 1118b0e77ca961a7b082f90cb124210eca8fb6bd)
+---
+ src/ngircd/irc-metadata.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/src/ngircd/irc-metadata.c
++++ b/src/ngircd/irc-metadata.c
+@@ -72,7 +72,9 @@
+ 	}
+ 
+ 	if (strcasecmp(Req->argv[1], "cloakhost") == 0) {
+-		Client_UpdateCloakedHostname(target, prefix, Req->argv[2]);
++		/* Set or remove a "cloaked hostname". */
++		Client_UpdateCloakedHostname(target, prefix,
++					     *Req->argv[2] ? Req->argv[2] : NULL);
+ 		if (Client_Conn(target) > NONE && Client_HasMode(target, 'x'))
+ 			IRC_WriteStrClientPrefix(target, prefix,
+ 					RPL_HOSTHIDDEN_MSG, Client_ID(target),
diff -Nru ngircd-26.1/debian/patches/1713563399.rel-27-rc1-6-g3e3f6cbe.clarify-that-cafile-is-not-set-by-default.patch ngircd-26.1/debian/patches/1713563399.rel-27-rc1-6-g3e3f6cbe.clarify-that-cafile-is-not-set-by-default.patch
--- ngircd-26.1/debian/patches/1713563399.rel-27-rc1-6-g3e3f6cbe.clarify-that-cafile-is-not-set-by-default.patch	1970-01-01 01:00:00.000000000 +0100
+++ ngircd-26.1/debian/patches/1713563399.rel-27-rc1-6-g3e3f6cbe.clarify-that-cafile-is-not-set-by-default.patch	2024-05-01 11:00:00.000000000 +0200
@@ -0,0 +1,28 @@
+Subject: Clarify that "CAFile" is not set by default
+Origin: rel-27-rc1-6-g3e3f6cbe
+Upstream-Author: Alexander Barton <alex@barton.de>
+Date: Fri Apr 19 23:49:59 2024 +0200
+
+--- a/doc/sample-ngircd.conf.tmpl
++++ b/doc/sample-ngircd.conf.tmpl
+@@ -266,7 +266,8 @@
+ 	# is only available when ngIRCd is compiled with support for SSL!
+ 	# So don't forget to remove the ";" above if this is the case ...
+ 
+-	# SSL Trusted CA Certificates File (for verifying peer certificates)
++	# SSL Trusted CA Certificates File for verifying peer certificates.
++	# (Default: not set; so no certificates are trusted)
+ 	;CAFile = /etc/ssl/CA/cacert.pem
+ 
+ 	# Certificate Revocation File (for marking otherwise valid
+--- a/man/ngircd.conf.5.tmpl
++++ b/man/ngircd.conf.5.tmpl
+@@ -387,7 +387,7 @@
+ .TP
+ \fBCAFile\fR (string)
+ Filename pointing to the Trusted CA Certificates. This is required for
+-verifying peer certificates.
++verifying peer certificates. Default: not set, so no certificates are trusted.
+ .TP
+ \fBCertFile\fR (string)
+ SSL Certificate file of the private server key.
diff -Nru ngircd-26.1/debian/patches/series ngircd-26.1/debian/patches/series
--- ngircd-26.1/debian/patches/series	2021-01-02 21:48:41.000000000 +0100
+++ ngircd-26.1/debian/patches/series	2024-05-01 11:00:00.000000000 +0200
@@ -1,2 +1,26 @@
+# cherry-picked from upstream
+0001-Respect-SSLConnect-option-for-incoming-connections.patch
+0002-Support-for-server-certificate-validation-on-server-.patch
+0003-S2S-TLS-Add-missing-CAFile-and-CRLFile-options-to-co.patch
+0004-S2S-TLS-Remove-leftover-debug-messages.patch
+0005-S2S-TLS-OpenSSL-Always-setup-host-name-verification.patch
+0006-S2S-TLS-OpenSSL-Set-the-verification-flags-only-once.patch
+0007-S2S-TLS-OpenSSL-Fix-handling-of-certificate-informat.patch
+0008-S2S-TLS-OpenSSL-Postpone-verification-of-TLS-session.patch
+0009-S2S-TLS-OpenSSL-Streamline-logging.patch
+0010-S2S-TLS-Fix-formatting-and-sort-new-SSL-options-in-n.patch
+0011-S2S-TLS-MAX_CERT_CHAIN_LENGTH-is-only-used-by-OpenSS.patch
+0012-S2S-TLS-GnuTLS-Update-SSL-code-for-GnuTLS-certificat.patch
+0013-S2S-TLS-GnuTLS-Fix-handling-of-certificate-informati.patch
+0014-S2S-TLS-GnuTLS-Streamline-logging.patch
+0015-S2S-TLS-Verify-the-TLS-certificates-by-default.patch
+0016-S2S-TLS-GnuTLS-Fix-handling-of-connections-without-p.patch
+0017-S2S-TLS-Convert-SSL.txt-to-Markdown-and-update-infor.patch
+0018-S2S-TLS-Add-notice-to-INSTALL.md.patch
+0019-S2S-TLS-Fix-make-check-in-separate-build-directory.patch
+0020-METADATA-Fix-unsetting-cloakhost.patch
+0001-S2S-SSL-GnuTLS-Enable-CRL-verification_26.1.patch
+1713563399.rel-27-rc1-6-g3e3f6cbe.clarify-that-cafile-is-not-set-by-default.patch
+
 # patches that should go upstream
 fix-race-in-testsuite.patch

Attachment: signature.asc
Description: PGP signature


Reply to: