Hello,

As part of the NSS work it came up [1] that clients don't have a good
way to ask libpq what SSL library it was compiled with, unless they
already have a connection pointer so that they can call
PQsslAttribute(conn, "library"). This poses a chicken-and-egg problem:
with the NSS proposal, the client may have to know which library is in
use before it can construct a proper connection string. For example, I
have a test suite that needs to set up an NSS database with
certificates before telling libpq to connect using that database.

The simplest proposal was to just allow PQsslAttribute() to take NULL
as the connection parameter when querying the "library" attribute, and
that's what I've done in this patch. In current versions of libpq, the
"library" attribute will always be NULL if you pass NULL as the
connection; a client that needs to know whether this new behavior is
present can look at the LIBPQ_HAS_SSL_LIBRARY_DETECTION feature macro.

If this looks good, I'm not sure how best to test it in the regression
suite. I see that libpq has an installcheck recipe that compiles a test
executable for URI parsing; should I add a simple test alongside that?

Thanks,
--Jacob

[1] 
https://www.postgresql.org/message-id/a1798e46d6d801344ebc93672c6947ef5297c8a0.camel%40vmware.com
From a5e5549ccec9c70a510f031a678e9f0f32a35382 Mon Sep 17 00:00:00 2001
From: Jacob Champion <pchamp...@vmware.com>
Date: Mon, 29 Nov 2021 14:36:38 -0800
Subject: [PATCH 1/2] Enable SSL library detection via PQsslAttribute()

Currently, libpq client code must have a connection handle before it can
query the "library" SSL attribute. This poses problems if the client
needs to know what SSL library is in use before constructing a
connection string. (For example, with the NSS proposal, a client would
have to decide whether to use the "ssldatabase" connection setting
rather than "sslcert" et al.)

Allow PQsslAttribute(NULL, "library") to return the library in use --
currently, just "OpenSSL" or NULL. The new behavior is announced with
the LIBPQ_HAS_SSL_LIBRARY_DETECTION feature macro, allowing clients to
differentiate between a libpq that was compiled without SSL support and
a libpq that's just too old to tell.
---
 src/interfaces/libpq/fe-secure-openssl.c | 6 +++---
 src/interfaces/libpq/libpq-fe.h          | 2 ++
 2 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/src/interfaces/libpq/fe-secure-openssl.c b/src/interfaces/libpq/fe-secure-openssl.c
index f6e563a2e5..e095a0f538 100644
--- a/src/interfaces/libpq/fe-secure-openssl.c
+++ b/src/interfaces/libpq/fe-secure-openssl.c
@@ -1597,14 +1597,14 @@ PQsslAttributeNames(PGconn *conn)
 const char *
 PQsslAttribute(PGconn *conn, const char *attribute_name)
 {
+	if (strcmp(attribute_name, "library") == 0)
+		return "OpenSSL";
+
 	if (!conn)
 		return NULL;
 	if (conn->ssl == NULL)
 		return NULL;
 
-	if (strcmp(attribute_name, "library") == 0)
-		return "OpenSSL";
-
 	if (strcmp(attribute_name, "key_bits") == 0)
 	{
 		static char sslbits_str[12];
diff --git a/src/interfaces/libpq/libpq-fe.h b/src/interfaces/libpq/libpq-fe.h
index 20eb855abc..7986445f1a 100644
--- a/src/interfaces/libpq/libpq-fe.h
+++ b/src/interfaces/libpq/libpq-fe.h
@@ -36,6 +36,8 @@ extern "C"
 #define LIBPQ_HAS_PIPELINING 1
 /* Indicates presence of PQsetTraceFlags; also new PQtrace output format */
 #define LIBPQ_HAS_TRACE_FLAGS 1
+/* Indicates that PQsslAttribute(NULL, "library") is useful */
+#define LIBPQ_HAS_SSL_LIBRARY_DETECTION 1
 
 /*
  * Option flags for PQcopyResult
-- 
2.25.1

Reply via email to