Fix fallback behavior when server sends an ERROR early at startup

With sslmode=prefer, the desired behavior is to completely fail the
connection attempt, *not* fall back to a plaintext connection, if the
server responds to the SSLRequest with an error ('E') response instead
of rejecting SSL with an 'N' response. This was broken in commit
05fd30c0e7.

Reported-by: Jacob Champion
Reviewed-by: Michael Paquier
Discussion: https://www.postgresql.org/message-id/CAOYmi%2Bnwvu21mJ4DYKUa98HdfM_KZJi7B1MhyXtnsyOO-PB6Ww%40mail.gmail.com
Backpatch-through: 17
This commit is contained in:
Heikki Linnakangas 2024-07-26 14:52:08 +03:00
parent 284c030a10
commit c95d2159c1

View File

@ -3521,6 +3521,12 @@ keep_going: /* We will come back to here until there is
* byte here.
*/
conn->status = CONNECTION_AWAITING_RESPONSE;
/*
* Don't fall back to a plaintext connection after
* reading the error.
*/
conn->failed_enc_methods |= conn->allowed_enc_methods & (~conn->current_enc_method);
goto keep_going;
}
else
@ -3612,6 +3618,13 @@ keep_going: /* We will come back to here until there is
* into AWAITING_RESPONSE state and let the code there
* deal with it. Note we have *not* consumed the "E"
* byte here.
*
* Note that unlike on an error response to
* SSLRequest, we allow falling back to SSL or
* plaintext connection here. GSS support was
* introduced in PostgreSQL version 12, so an error
* response might mean that we are connecting to a
* pre-v12 server.
*/
conn->status = CONNECTION_AWAITING_RESPONSE;
goto keep_going;
@ -3659,6 +3672,10 @@ keep_going: /* We will come back to here until there is
}
else if (pollres == PGRES_POLLING_FAILED)
{
/*
* GSS handshake failed. We will retry with an SSL or
* plaintext connection, if permitted by the options.
*/
CONNECTION_FAILED();
}
/* Else, return POLLING_READING or POLLING_WRITING status */