mirror of
https://github.com/postgres/postgres.git
synced 2025-04-25 21:42:33 +03:00
Check channel binding flag at end of SCRAM exchange
We need to check whether the channel-binding flag encoded in the client-final-message is the same one sent in the client-first-message. Reviewed-by: Michael Paquier <michael.paquier@gmail.com>
This commit is contained in:
parent
143b54d21d
commit
86ab28fbd1
@ -110,6 +110,7 @@ typedef struct
|
|||||||
|
|
||||||
const char *username; /* username from startup packet */
|
const char *username; /* username from startup packet */
|
||||||
|
|
||||||
|
char cbind_flag;
|
||||||
bool ssl_in_use;
|
bool ssl_in_use;
|
||||||
const char *tls_finished_message;
|
const char *tls_finished_message;
|
||||||
size_t tls_finished_len;
|
size_t tls_finished_len;
|
||||||
@ -788,6 +789,7 @@ read_client_first_message(scram_state *state, char *input)
|
|||||||
* Read gs2-cbind-flag. (For details see also RFC 5802 Section 6 "Channel
|
* Read gs2-cbind-flag. (For details see also RFC 5802 Section 6 "Channel
|
||||||
* Binding".)
|
* Binding".)
|
||||||
*/
|
*/
|
||||||
|
state->cbind_flag = *input;
|
||||||
switch (*input)
|
switch (*input)
|
||||||
{
|
{
|
||||||
case 'n':
|
case 'n':
|
||||||
@ -1111,6 +1113,8 @@ read_client_final_message(scram_state *state, char *input)
|
|||||||
char *b64_message;
|
char *b64_message;
|
||||||
int b64_message_len;
|
int b64_message_len;
|
||||||
|
|
||||||
|
Assert(state->cbind_flag == 'p');
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Fetch data appropriate for channel binding type
|
* Fetch data appropriate for channel binding type
|
||||||
*/
|
*/
|
||||||
@ -1155,10 +1159,11 @@ read_client_final_message(scram_state *state, char *input)
|
|||||||
/*
|
/*
|
||||||
* If we are not using channel binding, the binding data is expected
|
* If we are not using channel binding, the binding data is expected
|
||||||
* to always be "biws", which is "n,," base64-encoded, or "eSws",
|
* to always be "biws", which is "n,," base64-encoded, or "eSws",
|
||||||
* which is "y,,".
|
* which is "y,,". We also have to check whether the flag is the same
|
||||||
|
* one that the client originally sent.
|
||||||
*/
|
*/
|
||||||
if (strcmp(channel_binding, "biws") != 0 &&
|
if (!(strcmp(channel_binding, "biws") == 0 && state->cbind_flag == 'n') &&
|
||||||
strcmp(channel_binding, "eSws") != 0)
|
!(strcmp(channel_binding, "eSws") == 0 && state->cbind_flag == 'y'))
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_PROTOCOL_VIOLATION),
|
(errcode(ERRCODE_PROTOCOL_VIOLATION),
|
||||||
(errmsg("unexpected SCRAM channel-binding attribute in client-final-message"))));
|
(errmsg("unexpected SCRAM channel-binding attribute in client-final-message"))));
|
||||||
|
@ -437,6 +437,10 @@ build_client_final_message(fe_scram_state *state, PQExpBuffer errormessage)
|
|||||||
/*
|
/*
|
||||||
* Construct client-final-message-without-proof. We need to remember it
|
* Construct client-final-message-without-proof. We need to remember it
|
||||||
* for verifying the server proof in the final step of authentication.
|
* for verifying the server proof in the final step of authentication.
|
||||||
|
*
|
||||||
|
* The channel binding flag handling (p/y/n) must be consistent with
|
||||||
|
* build_client_first_message(), because the server will check that it's
|
||||||
|
* the same flag both times.
|
||||||
*/
|
*/
|
||||||
if (strcmp(state->sasl_mechanism, SCRAM_SHA256_PLUS_NAME) == 0)
|
if (strcmp(state->sasl_mechanism, SCRAM_SHA256_PLUS_NAME) == 0)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user