aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2022-09-29 17:28:09 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2022-09-29 17:28:09 -0400
commitcae4688ce81b8449aa6e1e7bfa384d53520a81fb (patch)
tree93748024b0d30bf6796b101390bb09f75a987c77
parentd460faf00285fd99d3c80e890c8f6fe798233b48 (diff)
downloadpostgresql-cae4688ce81b8449aa6e1e7bfa384d53520a81fb.tar.gz
postgresql-cae4688ce81b8449aa6e1e7bfa384d53520a81fb.zip
Fix bogus behavior of PQsslAttribute(conn, "library").
Commit ebc8b7d44 intended to change the behavior of PQsslAttribute(NULL, "library"), but accidentally also changed what happens with a non-NULL conn pointer. Undo that so that only the intended behavior change happens. Clarify some associated documentation. Per bug #17625 from Heath Lord. Back-patch to v15. Discussion: https://postgr.es/m/17625-fc47c78b7d71b534@postgresql.org
-rw-r--r--doc/src/sgml/libpq.sgml36
-rw-r--r--src/interfaces/libpq/fe-secure-openssl.c13
2 files changed, 32 insertions, 17 deletions
diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index 54068c25cbd..1f8e7875cfa 100644
--- a/doc/src/sgml/libpq.sgml
+++ b/doc/src/sgml/libpq.sgml
@@ -2515,8 +2515,9 @@ const char *PQsslAttribute(const PGconn *conn, const char *attribute_name);
<para>
The list of available attributes varies depending on the SSL library
- being used, and the type of connection. If an attribute is not
- available, returns NULL.
+ being used and the type of connection. Returns NULL if the connection
+ does not use SSL or the specified attribute name is not defined for the
+ library in use.
</para>
<para>
@@ -2575,12 +2576,15 @@ const char *PQsslAttribute(const PGconn *conn, const char *attribute_name);
<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.
+ queried without a connection by passing NULL as
+ the <literal>conn</literal> argument. The result will be the default
+ SSL library name, or NULL if <application>libpq</application> was
+ compiled without any SSL support. (Prior
+ to <productname>PostgreSQL</productname> version 15, passing NULL as
+ the <literal>conn</literal> argument always resulted in NULL.
+ Client programs needing to differentiate between the newer and older
+ implementations of this case may check the
+ <literal>LIBPQ_HAS_SSL_LIBRARY_DETECTION</literal> feature macro.)
</para>
</listitem>
</varlistentry>
@@ -2589,7 +2593,8 @@ const char *PQsslAttribute(const PGconn *conn, const char *attribute_name);
<term><function>PQsslAttributeNames</function><indexterm><primary>PQsslAttributeNames</primary></indexterm></term>
<listitem>
<para>
- Return an array of SSL attribute names available. The array is terminated by a NULL pointer.
+ Returns an array of SSL attribute names available.
+ The array is terminated by a NULL pointer.
<synopsis>
const char * const * PQsslAttributeNames(const PGconn *conn);
</synopsis>
@@ -2601,8 +2606,10 @@ const char * const * PQsslAttributeNames(const PGconn *conn);
<term><function>PQsslStruct</function><indexterm><primary>PQsslStruct</primary></indexterm></term>
<listitem>
<para>
- Return a pointer to an SSL-implementation-specific object describing
- the connection.
+ Returns a pointer to an SSL-implementation-specific object describing
+ the connection. Returns NULL if the connection is not encrypted
+ or the requested type of object is not available from the connection's
+ SSL implementation.
<synopsis>
void *PQsslStruct(const PGconn *conn, const char *struct_name);
</synopsis>
@@ -2610,8 +2617,9 @@ void *PQsslStruct(const PGconn *conn, const char *struct_name);
<para>
The struct(s) available depend on the SSL implementation in use.
For <productname>OpenSSL</productname>, there is one struct,
- available under the name "OpenSSL", and it returns a pointer to the
- <productname>OpenSSL</productname> <literal>SSL</literal> struct.
+ available under the name <literal>OpenSSL</literal>,
+ and it returns a pointer to
+ <productname>OpenSSL</productname>'s <literal>SSL</literal> struct.
To use this function, code along the following lines could be used:
<programlisting><![CDATA[
#include <libpq-fe.h>
@@ -2644,7 +2652,7 @@ void *PQsslStruct(const PGconn *conn, const char *struct_name);
<listitem>
<para>
<indexterm><primary>SSL</primary><secondary sortas="libpq">in libpq</secondary></indexterm>
- Returns the SSL structure used in the connection, or null
+ Returns the SSL structure used in the connection, or NULL
if SSL is not in use.
<synopsis>
diff --git a/src/interfaces/libpq/fe-secure-openssl.c b/src/interfaces/libpq/fe-secure-openssl.c
index 3cc75380e02..fe1e98a3b0d 100644
--- a/src/interfaces/libpq/fe-secure-openssl.c
+++ b/src/interfaces/libpq/fe-secure-openssl.c
@@ -1747,14 +1747,21 @@ PQsslAttributeNames(PGconn *conn)
const char *
PQsslAttribute(PGconn *conn, const char *attribute_name)
{
- if (strcmp(attribute_name, "library") == 0)
- return "OpenSSL";
-
if (!conn)
+ {
+ /* PQsslAttribute(NULL, "library") reports the default SSL library */
+ if (strcmp(attribute_name, "library") == 0)
+ return "OpenSSL";
return NULL;
+ }
+
+ /* All attributes read as NULL for a non-encrypted connection */
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];