1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-27 12:41:57 +03:00

libpq: Add min/max_protocol_version connection options

All supported version of the PostgreSQL server send the
NegotiateProtocolVersion message when an unsupported minor protocol
version is requested by a client. But many other applications that
implement the PostgreSQL protocol (connection poolers, or other
databases) do not, and the same is true for PostgreSQL server versions
older than 9.3. Connecting to such other applications thus fails if a
client requests a protocol version different than 3.0.

This patch adds a max_protocol_version connection option to libpq that
specifies the protocol version that libpq should request from the
server. Currently only 3.0 is supported, but that will change in a
future commit that bumps the protocol version. Even after that version
bump the default will likely stay 3.0 for the time being. Once more of
the ecosystem supports the NegotiateProtocolVersion message we might
want to change the default to the latest minor version.

This also adds the similar min_protocol_version connection option, to
allow the client to specify that connecting should fail if a lower
protocol version is attempted by the server. This can be used to
ensure that certain protocol features are used, which can be
particularly useful if those features impact security.

Author: Jelte Fennema-Nio <postgres@jeltef.nl>
Reviewed-by: Robert Haas <robertmhaas@gmail.com> (earlier versions)
Discussion: https://www.postgresql.org/message-id/CAGECzQTfc_O%2BHXqAo5_-xG4r3EFVsTefUeQzSvhEyyLDba-O9w@mail.gmail.com
Discussion: https://www.postgresql.org/message-id/CAGECzQRbAGqJnnJJxTdKewTsNOovUt4bsx3NFfofz3m2j-t7tA@mail.gmail.com
This commit is contained in:
Heikki Linnakangas
2025-04-02 16:41:45 +03:00
parent 5070349102
commit 285613c60a
7 changed files with 315 additions and 12 deletions

View File

@ -2144,6 +2144,54 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname
</listitem>
</varlistentry>
<varlistentry id="libpq-connect-min-protocol-version" xreflabel="min_protocol_version">
<term><literal>min_protocol_version</literal></term>
<listitem>
<para>
Specifies the minimum protocol version to allow for the connection.
The default is to allow any version of the
<productname>PostgreSQL</productname> protocol supported by libpq,
which currently means <literal>3.0</literal>. If the server
does not support at least this protocol version the connection will be
closed.
</para>
<para>
The current supported values are
<literal>3.0</literal>, <literal>3.2</literal>,
and <literal>latest</literal>. The <literal>latest</literal> value is
equivalent to the latest protocol version supported by the libpq
version being used, which is currently <literal>3.2</literal>.
</para>
</listitem>
</varlistentry>
<varlistentry id="libpq-connect-max-protocol-version" xreflabel="max_protocol_version">
<term><literal>max_protocol_version</literal></term>
<listitem>
<para>
Specifies the protocol version to request from the server.
The default is to use version <literal>3.0</literal> of the
<productname>PostgreSQL</productname> protocol, unless the connection
string specifies a feature that relies on a higher protocol version,
in which case the latest version supported by libpq is used. If the
server does not support the protocol version requested by the client,
the connection is automatically downgraded to a lower minor protocol
version that the server supports. After the connection attempt has
completed you can use <xref linkend="libpq-PQprotocolVersion"/> to
find out which exact protocol version was negotiated.
</para>
<para>
The current supported values are
<literal>3.0</literal>, <literal>3.2</literal>,
and <literal>latest</literal>. The <literal>latest</literal> value is
equivalent to the latest protocol version supported by the libpq
version being used, which is currently <literal>3.2</literal>.
</para>
</listitem>
</varlistentry>
<varlistentry id="libpq-connect-ssl-max-protocol-version" xreflabel="ssl_max_protocol_version">
<term><literal>ssl_max_protocol_version</literal></term>
<listitem>
@ -9329,6 +9377,26 @@ myEventProc(PGEventId evtId, void *evtInfo, void *passThrough)
linkend="libpq-connect-load-balance-hosts"/> connection parameter.
</para>
</listitem>
<listitem>
<para>
<indexterm>
<primary><envar>PGMINPROTOCOLVERSION</envar></primary>
</indexterm>
<envar>PGMINPROTOCOLVERSION</envar> behaves the same as the <xref
linkend="libpq-connect-min-protocol-version"/> connection parameter.
</para>
</listitem>
<listitem>
<para>
<indexterm>
<primary><envar>PGMAXPROTOCOLVERSION</envar></primary>
</indexterm>
<envar>PGMAXPROTOCOLVERSION</envar> behaves the same as the <xref
linkend="libpq-connect-max-protocol-version"/> connection parameter.
</para>
</listitem>
</itemizedlist>
</para>

View File

@ -18,17 +18,23 @@
</para>
<para>
This document describes version 3.0 of the protocol, implemented in
<productname>PostgreSQL</productname> 7.4 and later. For descriptions
of the earlier protocol versions, see previous releases of the
<productname>PostgreSQL</productname> documentation. A single server
This document describes version 3.2 of the protocol, introduced in
<productname>PostgreSQL</productname> version 18. The server and the libpq
client library are backwards compatible with protocol version 3.0,
implemented in <productname>PostgreSQL</productname> 7.4 and later.
For descriptions of earlier protocol versions, see previous releases of the
<productname>PostgreSQL</productname> documentation.
</para>
<para>
A single server
can support multiple protocol versions. The initial startup-request
message tells the server which protocol version the client is attempting to
use. If the major version requested by the client is not supported by
the server, the connection will be rejected (for example, this would occur
if the client requested protocol version 4.0, which does not exist as of
this writing). If the minor version requested by the client is not
supported by the server (e.g., the client requests version 3.1, but the
supported by the server (e.g., the client requests version 3.2, but the
server supports only 3.0), the server may either reject the connection or
may respond with a NegotiateProtocolVersion message containing the highest
minor protocol version which it supports. The client may then choose either
@ -36,6 +42,13 @@
to abort the connection.
</para>
<para>
The protocol negotiation was introduced in
<productname>PostgreSQL</productname> version 9.3.21. Earlier versions would
reject the connection if the client requested a minor version that was not
supported by the server.
</para>
<para>
In order to serve multiple clients efficiently, the server launches
a new <quote>backend</quote> process for each client.
@ -413,8 +426,14 @@
this message indicates the highest supported minor version. This
message will also be sent if the client requested unsupported protocol
options (i.e., beginning with <literal>_pq_.</literal>) in the
startup packet. This message will be followed by an ErrorResponse or
a message indicating the success or failure of authentication.
startup packet.
</para>
<para>
After this message, the authentication will continue using the version
indicated by the server. If the client does not support the older
version, it should immediately close the connection. If the server
does not send this message, it supports the client's requested
protocol version and all the protocol options.
</para>
</listitem>
</varlistentry>