with
<acronym>GSSAPI</acronym>, see <xref linkend="gssapi-enc"/>.
</para>
<para>
To initiate a <acronym>GSSAPI</acronym>-encrypted connection, the
frontend initially sends a GSSENCRequest message rather than a
StartupMessage. The server then responds with a single byte
containing <literal>G</literal> or <literal>N</literal>, indicating that it
is willing or unwilling to perform <acronym>GSSAPI</acronym> encryption,
respectively. The frontend might close the connection at this point
if it is dissatisfied with the response. To continue after
<literal>G</literal>, using the GSSAPI C bindings as discussed in
<ulink url="https://datatracker.ietf.org/doc/html/rfc2744">RFC 2744</ulink>
or equivalent, perform a <acronym>GSSAPI</acronym> initialization by
calling <function>gss_init_sec_context()</function> in a loop and sending
the result to the server, starting with an empty input and then with each
result from the server, until it returns no output. When sending the
results of <function>gss_init_sec_context()</function> to the server,
prepend the length of the message as a four byte integer in network byte
order.
To continue after
<literal>N</literal>, send the usual StartupMessage and proceed without
encryption.
(Alternatively, it is permissible to issue an SSLRequest message
after an <literal>N</literal> response to try to
use <acronym>SSL</acronym> encryption instead
of <acronym>GSSAPI</acronym>.)
</para>
<para>
The frontend should also be prepared to handle an ErrorMessage
response to GSSENCRequest from the server. The frontend should not display
this error message to the user/application, since the server has not been
authenticated
(<ulink url="https://www.postgresql.org/support/security/CVE-2024-10977/">CVE-2024-10977</ulink>).
In this case the connection must be closed, but the frontend might choose
to open a fresh connection and proceed without requesting
<acronym>GSSAPI</acronym> encryption.
</para>
<para>
When <acronym>GSSAPI</acronym> encryption can be performed, the server
is expected to send only the single <literal>G</literal> byte and then
wait for the frontend to initiate a <acronym>GSSAPI</acronym> handshake.
If additional bytes are available to read at this point, it likely
means that a man-in-the-middle is attempting to perform a
buffer-stuffing attack
(<ulink url="https://www.postgresql.org/support/security/CVE-2021-23222/">CVE-2021-23222</ulink>).
Frontends should be coded either to read exactly one byte from the
socket before turning the socket over to their GSSAPI library, or to
treat it as a protocol violation if they find they have read additional
bytes.
</para>
<para>
An initial GSSENCRequest can also be used in a connection that is being
opened to send a CancelRequest message.
</para>
<para>
Once <acronym>GSSAPI</acronym> encryption has been successfully
established, use <function>gss_wrap()</function> to
encrypt the usual StartupMessage and all subsequent data, prepending the
length of the result from <function>gss_wrap()</function> as a four byte
integer in network byte order to the actual encrypted payload. Note that
the server will only accept encrypted packets from the client which are less
than 16kB; <function>gss_wrap_size_limit()</function> should be used by the
client to determine the size of the unencrypted message which will fit
within this limit and larger messages should be broken up into multiple
<function>gss_wrap()</function> calls. Typical segments are 8kB of
unencrypted data, resulting in encrypted packets of slightly larger than 8kB
but well within the 16kB maximum. The server can be expected to not send
encrypted packets of larger than 16kB to the client.
</para>
<para>
While the protocol itself does not provide