On Fri, 2022-03-25 at 15:32 -0400, Robert Haas wrote: > On Mon, Feb 28, 2022 at 3:21 PM Jacob Champion <pchamp...@vmware.com> wrote: > > v3 rebases over Andres' changes and actually adds the Perl driver that > > I missed the git-add for. > > This seems totally reasonable. However, I think it should update the > documentation somehow.
Done in v4. Do I need to merge my tiny test program into the libpq_pipeline tests? I'm not sure what the roadmap is for those. Thanks! --Jacob
commit 53fca988682c80a99bbb19eeb3d7959533fc3b83 Author: Jacob Champion <pchamp...@vmware.com> Date: Fri Mar 25 14:16:47 2022 -0700 squash! Enable SSL library detection via PQsslAttribute() Add docs. diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml index 3998b1781b..82f3092715 100644 --- a/doc/src/sgml/libpq.sgml +++ b/doc/src/sgml/libpq.sgml @@ -2538,6 +2538,17 @@ const char *PQsslAttribute(const PGconn *conn, const char *attribute_name); Name of the SSL implementation in use. (Currently, only <literal>"OpenSSL"</literal> is implemented) </para> + <note> + <para> + As a special case, the <literal>library</literal> attribute may be + queried without an existing connection by passing NULL as the + <literal>conn</literal> argument. The historical behavior was to + return NULL for any attribute when a NULL <literal>conn</literal> + was provided; client programs needing to differentiate between the + newer and older implementations may check the + <literal>LIBPQ_HAS_SSL_LIBRARY_DETECTION</literal> feature macro. + </para> + </note> </listitem> </varlistentry> <varlistentry>
From 1ec54121dc0eeae7e48b9e38b829980e6a11e31c Mon Sep 17 00:00:00 2001 From: Jacob Champion <pchamp...@vmware.com> Date: Mon, 29 Nov 2021 14:36:38 -0800 Subject: [PATCH v4] 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. --- doc/src/sgml/libpq.sgml | 11 +++++++ src/interfaces/libpq/Makefile | 1 + src/interfaces/libpq/fe-secure-openssl.c | 6 ++-- src/interfaces/libpq/libpq-fe.h | 2 ++ src/interfaces/libpq/t/002_api.pl | 23 +++++++++++++++ src/interfaces/libpq/test/.gitignore | 1 + src/interfaces/libpq/test/Makefile | 2 +- src/interfaces/libpq/test/testclient.c | 37 ++++++++++++++++++++++++ 8 files changed, 79 insertions(+), 4 deletions(-) create mode 100644 src/interfaces/libpq/t/002_api.pl create mode 100644 src/interfaces/libpq/test/testclient.c diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml index 3998b1781b..82f3092715 100644 --- a/doc/src/sgml/libpq.sgml +++ b/doc/src/sgml/libpq.sgml @@ -2538,6 +2538,17 @@ const char *PQsslAttribute(const PGconn *conn, const char *attribute_name); Name of the SSL implementation in use. (Currently, only <literal>"OpenSSL"</literal> is implemented) </para> + <note> + <para> + As a special case, the <literal>library</literal> attribute may be + queried without an existing connection by passing NULL as the + <literal>conn</literal> argument. The historical behavior was to + return NULL for any attribute when a NULL <literal>conn</literal> + was provided; client programs needing to differentiate between the + newer and older implementations may check the + <literal>LIBPQ_HAS_SSL_LIBRARY_DETECTION</literal> feature macro. + </para> + </note> </listitem> </varlistentry> <varlistentry> diff --git a/src/interfaces/libpq/Makefile b/src/interfaces/libpq/Makefile index 3c53393fa4..89bf5e0126 100644 --- a/src/interfaces/libpq/Makefile +++ b/src/interfaces/libpq/Makefile @@ -13,6 +13,7 @@ subdir = src/interfaces/libpq top_builddir = ../../.. include $(top_builddir)/src/Makefile.global +export with_ssl PGFILEDESC = "PostgreSQL Access Library" diff --git a/src/interfaces/libpq/fe-secure-openssl.c b/src/interfaces/libpq/fe-secure-openssl.c index d81218a4cc..d3bf57b850 100644 --- a/src/interfaces/libpq/fe-secure-openssl.c +++ b/src/interfaces/libpq/fe-secure-openssl.c @@ -1631,14 +1631,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 diff --git a/src/interfaces/libpq/t/002_api.pl b/src/interfaces/libpq/t/002_api.pl new file mode 100644 index 0000000000..bcf91bc558 --- /dev/null +++ b/src/interfaces/libpq/t/002_api.pl @@ -0,0 +1,23 @@ +#!/usr/bin/perl + +# Copyright (c) 2022, PostgreSQL Global Development Group + +use strict; +use warnings; + +use PostgreSQL::Test::Utils; +use Test::More; + +# Test PQsslAttribute(NULL, "library") +my ($out, $err) = run_command(['testclient', '--ssl']); + +if ($ENV{with_ssl} eq 'openssl') +{ + is($out, 'OpenSSL', 'PQsslAttribute(NULL, "library") returns "OpenSSL"'); +} +else +{ + is($err, 'SSL is not enabled', 'PQsslAttribute(NULL, "library") returns NULL'); +} + +done_testing(); diff --git a/src/interfaces/libpq/test/.gitignore b/src/interfaces/libpq/test/.gitignore index 5e803d8816..4b17210483 100644 --- a/src/interfaces/libpq/test/.gitignore +++ b/src/interfaces/libpq/test/.gitignore @@ -1 +1,2 @@ +/testclient /uri-regress diff --git a/src/interfaces/libpq/test/Makefile b/src/interfaces/libpq/test/Makefile index 5421215906..1d45be0c37 100644 --- a/src/interfaces/libpq/test/Makefile +++ b/src/interfaces/libpq/test/Makefile @@ -11,7 +11,7 @@ endif override CPPFLAGS := -I$(libpq_srcdir) $(CPPFLAGS) LDFLAGS_INTERNAL += $(libpq_pgport) -PROGS = uri-regress +PROGS = testclient uri-regress all: $(PROGS) diff --git a/src/interfaces/libpq/test/testclient.c b/src/interfaces/libpq/test/testclient.c new file mode 100644 index 0000000000..2c730d83fa --- /dev/null +++ b/src/interfaces/libpq/test/testclient.c @@ -0,0 +1,37 @@ +/* + * testclient.c + * A test program for the libpq public API + * + * Copyright (c) 2022, PostgreSQL Global Development Group + * + * IDENTIFICATION + * src/interfaces/libpq/test/testclient.c + */ + +#include "postgres_fe.h" + +#include "libpq-fe.h" + +static void +print_ssl_library() +{ + const char *lib = PQsslAttribute(NULL, "library"); + + if (!lib) + fprintf(stderr, "SSL is not enabled\n"); + else + printf("%s\n", lib); +} + +int +main(int argc, char *argv[]) +{ + if ((argc > 1) && !strcmp(argv[1], "--ssl")) + { + print_ssl_library(); + return 0; + } + + printf("currently only --ssl is supported\n"); + return 1; +} -- 2.25.1