Accept SCRAM channel binding enabled clients

Add support to the SCRAM exchange for clients that support channel
binding, such as PostgreSQL version 11 and beyond.  If such a client
encounters a PostgreSQL 10 server that does not support channel binding,
it will send a channel binding flag 'y', meaning the client supports
channel binding but thinks the server does not.  But PostgreSQL 10
erroneously did not accept that flag.  This would cause connections to
fail if a version 11 client connects to a version 10 server with SCRAM
authentication over SSL.

Author: Michael Paquier <michael.paquier@gmail.com>
This commit is contained in:
Peter Eisentraut 2017-12-08 10:17:46 -05:00
parent ee5b595493
commit 218b024a7e

View File

@ -112,6 +112,8 @@ typedef struct
const char *username; /* username from startup packet */
char cbind_flag;
int iterations;
char *salt; /* base64-encoded */
uint8 StoredKey[SCRAM_KEY_LEN];
@ -774,6 +776,7 @@ read_client_first_message(scram_state *state, char *input)
*/
/* read gs2-cbind-flag */
state->cbind_flag = *input;
switch (*input)
{
case 'n':
@ -1033,10 +1036,13 @@ read_client_final_message(scram_state *state, char *input)
/*
* Read channel-binding. We don't support channel binding, so it's
* expected to always be "biws", which is "n,,", base64-encoded.
* expected to always be "biws", which is "n,,", base64-encoded, or
* "eSws", which is "y,,". We also have to check whether the flag is
* the same one that the client originally sent.
*/
channel_binding = read_attr_value(&p, 'c');
if (strcmp(channel_binding, "biws") != 0)
if (!(strcmp(channel_binding, "biws") == 0 && state->cbind_flag == 'n') &&
!(strcmp(channel_binding, "eSws") == 0 && state->cbind_flag == 'y'))
ereport(ERROR,
(errcode(ERRCODE_PROTOCOL_VIOLATION),
(errmsg("unexpected SCRAM channel-binding attribute in client-final-message"))));