mirror of
https://github.com/postgres/postgres.git
synced 2025-08-19 23:22:23 +03:00
Improve the SASL authentication protocol.
This contains some protocol changes to SASL authentiation (which is new in v10): * For future-proofing, in the AuthenticationSASL message that begins SASL authentication, provide a list of SASL mechanisms that the server supports, for the client to choose from. Currently, it's always just SCRAM-SHA-256. * Add a separate authentication message type for the final server->client SASL message, which the client doesn't need to respond to. This makes it unambiguous whether the client is supposed to send a response or not. The SASL mechanism should know that anyway, but better to be explicit. Also, in the server, support clients that don't send an Initial Client response in the first SASLInitialResponse message. The server is supposed to first send an empty request in that case, to which the client will respond with the data that usually comes in the Initial Client Response. libpq uses the Initial Client Response field and doesn't need this, and I would assume any other sensible implementation to use Initial Client Response, too, but let's follow the SASL spec. Improve the documentation on SASL authentication in protocol. Add a section describing the SASL message flow, and some details on our SCRAM-SHA-256 implementation. Document the different kinds of PasswordMessages that the frontend sends in different phases of SASL authentication, as well as GSS/SSPI authentication as separate message formats. Even though they're all 'p' messages, and the exact format depends on the context, describing them as separate message formats makes the documentation more clear. Reviewed by Michael Paquier and Álvaro Hernández Tortosa. Discussion: https://www.postgresql.org/message-id/CAB7nPqS-aFg0iM3AQOJwKDv_0WkAedRjs1W2X8EixSz+sKBXCQ@mail.gmail.com
This commit is contained in:
@@ -254,8 +254,16 @@ pg_be_scram_init(const char *username, const char *shadow_pass)
|
||||
/*
|
||||
* Continue a SCRAM authentication exchange.
|
||||
*
|
||||
* The next message to send to client is saved in "output", for a length
|
||||
* of "outputlen". In the case of an error, optionally store a palloc'd
|
||||
* 'input' is the SCRAM payload sent by the client. On the first call,
|
||||
* 'input' contains the "Initial Client Response" that the client sent as
|
||||
* part of the SASLInitialResponse message, or NULL if no Initial Client
|
||||
* Response was given. (The SASL specification distinguishes between an
|
||||
* empty response and non-existing one.) On subsequent calls, 'input'
|
||||
* cannot be NULL. For convenience in this function, the caller must
|
||||
* ensure that there is a null terminator at input[inputlen].
|
||||
*
|
||||
* The next message to send to client is saved in 'output', for a length
|
||||
* of 'outputlen'. In the case of an error, optionally store a palloc'd
|
||||
* string at *logdetail that will be sent to the postmaster log (but not
|
||||
* the client).
|
||||
*/
|
||||
@@ -268,6 +276,21 @@ pg_be_scram_exchange(void *opaq, char *input, int inputlen,
|
||||
|
||||
*output = NULL;
|
||||
|
||||
/*
|
||||
* If the client didn't include an "Initial Client Response" in the
|
||||
* SASLInitialResponse message, send an empty challenge, to which the
|
||||
* client will respond with the same data that usually comes in the
|
||||
* Initial Client Response.
|
||||
*/
|
||||
if (input == NULL)
|
||||
{
|
||||
Assert(state->state == SCRAM_AUTH_INIT);
|
||||
|
||||
*output = pstrdup("");
|
||||
*outputlen = 0;
|
||||
return SASL_EXCHANGE_CONTINUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check that the input length agrees with the string length of the input.
|
||||
* We can ignore inputlen after this.
|
||||
|
Reference in New Issue
Block a user