Skip to content

Commit 87d2801

Browse files
committed
libpq: Fix error messages when server rejects SSL or GSS
These messages were lost in commit 05fd30c. Put them back. This makes one change in the error message behavior compared to v16, in the case that the server responds to GSSRequest with an error instead of rejecting it with 'N'. Previously, libpq would hide the error that the server sent, assuming that you got the error because the server is an old pre-v12 version that doesn't understand the GSSRequest message. A v11 server sends a "FATAL: unsupported frontend protocol 1234.5680: server supports 2.0 to 3.0" error if you try to connect to it with GSS. That was a reasonable assumption when the feature was introduced, but v12 was released a long time ago and I don't think it's the most probable cause anymore. The attached patch changes things so that libpq prints the error message that the server sent in that case, making the "server responds with error to GSSRequest" case behave the same as the "server responds with error to SSLRequest" case. Reported-by: Peter Eisentraut Discussion: https://www.postgresql.org/message-id/[email protected]
1 parent 7e61e4c commit 87d2801

File tree

1 file changed

+35
-14
lines changed

1 file changed

+35
-14
lines changed

src/interfaces/libpq/fe-connect.c

+35-14
Original file line numberDiff line numberDiff line change
@@ -2861,12 +2861,17 @@ PQconnectPoll(PGconn *conn)
28612861
need_new_connection = false;
28622862
}
28632863

2864-
/* Decide what to do next, if SSL or GSS negotiation fails */
2865-
#define ENCRYPTION_NEGOTIATION_FAILED() \
2864+
/*
2865+
* Decide what to do next, if server rejects SSL or GSS negotiation, but
2866+
* the connection is still valid. If there are no options left, error out
2867+
* with 'msg'.
2868+
*/
2869+
#define ENCRYPTION_NEGOTIATION_FAILED(msg) \
28662870
do { \
28672871
switch (encryption_negotiation_failed(conn)) \
28682872
{ \
28692873
case 0: \
2874+
libpq_append_conn_error(conn, (msg)); \
28702875
goto error_return; \
28712876
case 1: \
28722877
conn->status = CONNECTION_MADE; \
@@ -2877,7 +2882,11 @@ PQconnectPoll(PGconn *conn)
28772882
} \
28782883
} while(0);
28792884

2880-
/* Decide what to do next, if connection fails */
2885+
/*
2886+
* Decide what to do next, if connection fails. If there are no options
2887+
* left, return with an error. The error message has already been written
2888+
* to the connection's error buffer.
2889+
*/
28812890
#define CONNECTION_FAILED() \
28822891
do { \
28832892
if (connection_failed(conn)) \
@@ -3483,9 +3492,13 @@ PQconnectPoll(PGconn *conn)
34833492
{
34843493
/* mark byte consumed */
34853494
conn->inStart = conn->inCursor;
3486-
/* OK to do without SSL? */
3487-
/* We can proceed using this connection */
3488-
ENCRYPTION_NEGOTIATION_FAILED();
3495+
3496+
/*
3497+
* The connection is still valid, so if it's OK to
3498+
* continue without SSL, we can proceed using this
3499+
* connection. Otherwise return with an error.
3500+
*/
3501+
ENCRYPTION_NEGOTIATION_FAILED("server does not support SSL, but SSL was required");
34893502
}
34903503
else if (SSLok == 'E')
34913504
{
@@ -3583,22 +3596,30 @@ PQconnectPoll(PGconn *conn)
35833596
if (gss_ok == 'E')
35843597
{
35853598
/*
3586-
* Server failure of some sort. Assume it's a
3587-
* protocol version support failure, and let's see if
3588-
* we can't recover (if it's not, we'll get a better
3589-
* error message on retry). Server gets fussy if we
3590-
* don't hang up the socket, though.
3599+
* Server failure of some sort, possibly protocol
3600+
* version support failure. We need to process and
3601+
* report the error message, which might be formatted
3602+
* according to either protocol 2 or protocol 3.
3603+
* Rather than duplicate the code for that, we flip
3604+
* into AWAITING_RESPONSE state and let the code there
3605+
* deal with it. Note we have *not* consumed the "E"
3606+
* byte here.
35913607
*/
3592-
CONNECTION_FAILED();
3608+
conn->status = CONNECTION_AWAITING_RESPONSE;
3609+
goto keep_going;
35933610
}
35943611

35953612
/* mark byte consumed */
35963613
conn->inStart = conn->inCursor;
35973614

35983615
if (gss_ok == 'N')
35993616
{
3600-
/* We can proceed using this connection */
3601-
ENCRYPTION_NEGOTIATION_FAILED();
3617+
/*
3618+
* The connection is still valid, so if it's OK to
3619+
* continue without GSS, we can proceed using this
3620+
* connection. Otherwise return with an error.
3621+
*/
3622+
ENCRYPTION_NEGOTIATION_FAILED("server doesn't support GSSAPI encryption, but it was required");
36023623
}
36033624
else if (gss_ok != 'G')
36043625
{

0 commit comments

Comments
 (0)