diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2022-09-29 17:28:09 -0400 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2022-09-29 17:28:09 -0400 |
commit | cae4688ce81b8449aa6e1e7bfa384d53520a81fb (patch) | |
tree | 93748024b0d30bf6796b101390bb09f75a987c77 | |
parent | d460faf00285fd99d3c80e890c8f6fe798233b48 (diff) | |
download | postgresql-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.sgml | 36 | ||||
-rw-r--r-- | src/interfaces/libpq/fe-secure-openssl.c | 13 |
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]; |