From 8013619a1ee2187fce289054a846e17a5414801d Mon Sep 17 00:00:00 2001
From: Jim Jones <jim.jones@uni-muenster.de>
Date: Mon, 21 Nov 2022 15:05:33 +0100
Subject: [PATCH v1] add sslmode no-clientcert

---
 doc/src/sgml/libpq.sgml                  | 11 +++++++++
 src/interfaces/libpq/fe-connect.c        |  1 +
 src/interfaces/libpq/fe-secure-openssl.c | 29 +++++++++++++++++++++++-
 3 files changed, 40 insertions(+), 1 deletion(-)

diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index f9558dec3b..aa14253f7e 100644
--- a/doc/src/sgml/libpq.sgml
+++ b/doc/src/sgml/libpq.sgml
@@ -8638,6 +8638,17 @@ ldap://ldap.acme.com/cn=dbserver,cn=hosts?pgconnectinfo?base?(objectclass=*)
       </entry>
      </row>
 
+     <row>
+      <entry><literal>no-clientcert</literal></entry>
+      <entry>Yes</entry>
+      <entry>Depends on CA policy</entry>
+      <entry>I want my data encrypted, and I accept the overhead. I want to be
+       sure that I connect to a server that I trust, but I do not wish to 
+       authenticate the client using ssl certificates.
+      </entry>
+     </row>
+     
+     
      <row>
       <entry><literal>verify-ca</literal></entry>
       <entry>Yes</entry>
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index f88d672c6c..08c7f21ec1 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -1268,6 +1268,7 @@ connectOptions2(PGconn *conn)
 			&& strcmp(conn->sslmode, "allow") != 0
 			&& strcmp(conn->sslmode, "prefer") != 0
 			&& strcmp(conn->sslmode, "require") != 0
+			&& strcmp(conn->sslmode, "no-clientcert") != 0
 			&& strcmp(conn->sslmode, "verify-ca") != 0
 			&& strcmp(conn->sslmode, "verify-full") != 0)
 		{
diff --git a/src/interfaces/libpq/fe-secure-openssl.c b/src/interfaces/libpq/fe-secure-openssl.c
index bad85359b6..c092020c5e 100644
--- a/src/interfaces/libpq/fe-secure-openssl.c
+++ b/src/interfaces/libpq/fe-secure-openssl.c
@@ -1098,7 +1098,34 @@ initialize_SSL(PGconn *conn)
 	if (conn->sslcert && strlen(conn->sslcert) > 0)
 		strlcpy(fnbuf, conn->sslcert, sizeof(fnbuf));
 	else if (have_homedir)
-		snprintf(fnbuf, sizeof(fnbuf), "%s/%s", homedir, USER_CERT_FILE);
+	{
+
+		/* sslmode no-clientcert */
+		if (conn->sslmode[0] == 'n')
+		{
+
+			/*
+			 * The option "no-clientcert" ignores the client certificate in case they are
+			 * stored in ~/.postgresql/postgresql.crt and ~/.postgresql/postgresql.key,
+			 * and therefore automatically sent to the server. This is useful for
+			 * pg_hba.conf entries of type "hostssl" without "cert" as authentication
+			 * method - e.g. using "md5" or "scram-sha-256" - as they will fail if
+			 * the client certificate is sent to the server in the background and it
+			 * does not exist in the server's 'ssl_ca_file'.
+			 */
+
+			fnbuf[0] = '\0';
+
+		}
+		else
+		{
+
+			snprintf(fnbuf, sizeof(fnbuf), "%s/%s", homedir, USER_CERT_FILE);
+
+		}
+
+
+	}
 	else
 		fnbuf[0] = '\0';
 
-- 
2.25.1

