Re: [HACKERS] Letting the client choose the protocol to use during a SASL exchange
On Fri, Apr 14, 2017 at 8:28 PM, Craig Ringerwrote: > There's no point advertising scram-512 if only -256 can work for 'bob' > because that's what we have in pg_authid. The possibility to have multiple verifiers has other benefits than that, password rolling being one. We may want to revisit that once there is a need to have a pg_auth_verifiers, my intuition on the matter is that we are years away from it, but we'll very likely need it for more reasons than the one you are raising here. > Yes, filtering the advertised mechs exposes info. But not being able to log > in if you're the legitimate user without configuring the client with your > password hash format would suck too. Yup. -- Michael -- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers
Re: [HACKERS] Letting the client choose the protocol to use during a SASL exchange
On 14 Apr. 2017 10:44, "Michael Paquier"wrote: On Fri, Apr 14, 2017 at 1:37 AM, Heikki Linnakangas wrote: > On 04/13/2017 05:53 AM, Michael Paquier wrote: >> +* Parse the list of SASL authentication mechanisms in the >> +* AuthenticationSASL message, and select the best mechanism that we >> +* support. (Only SCRAM-SHA-256 is supported at the moment.) >> */ >> - if (strcmp(auth_mechanism, SCRAM_SHA256_NAME) == 0) >> + for (;;) >> Just an idea here: being able to enforce the selection with an >> environment variable (useful for testing as well in the future). > > Hmm. It wouldn't do much, as long as SCRAM-SHA-256 is the only supported > mechanism. In general, there is no way to tell libpq to e.g. not do plain > password authentication, which is more pressing than choosing a particular > SASL mechanism. So I think we should have libpq options to control that, but > it's a bigger feature than just adding a debug environment variable here. Of course, my last sentence implied that this may be useful once more than 1 mechanism is added. This definitely cannot be a connection parameter. Your last sentence makes me guess that we agree on that. But those are thoughts for later.. Are we going to have issues with with mech negotiation re the ability to store auth data for >1 mech and access it early enough? Presumably we'll need multiple digests for a user. For example if we want to allow the choice of mechs scram-256 and scram-512 we need different stored hashes for the same user in pg_authid. And we'll possibly need to be able to tell at the time we advertise mechs which users have creds for which mechs otherwise we'll advertise mechs they can never succeed. The client has no way to make a sensible choice of mech if some arbitrary subset (maybe just 1) will work for a given user. There's no point advertising scram-512 if only -256 can work for 'bob' because that's what we have in pg_authid. Yes, filtering the advertised mechs exposes info. But not being able to log in if you're the legitimate user without configuring the client with your password hash format would suck too. > Thanks for the review! I've pushed these patches, after a bunch of little > cleanups here and there, and fixing a few garden-variety bugs in the > GSS/SSPI changes. Committed patches look good to me after a second lookup. Thanks! -- Michael -- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers
Re: [HACKERS] Letting the client choose the protocol to use during a SASL exchange
On Fri, Apr 14, 2017 at 1:37 AM, Heikki Linnakangaswrote: > On 04/13/2017 05:53 AM, Michael Paquier wrote: >> +* Parse the list of SASL authentication mechanisms in the >> +* AuthenticationSASL message, and select the best mechanism that we >> +* support. (Only SCRAM-SHA-256 is supported at the moment.) >> */ >> - if (strcmp(auth_mechanism, SCRAM_SHA256_NAME) == 0) >> + for (;;) >> Just an idea here: being able to enforce the selection with an >> environment variable (useful for testing as well in the future). > > Hmm. It wouldn't do much, as long as SCRAM-SHA-256 is the only supported > mechanism. In general, there is no way to tell libpq to e.g. not do plain > password authentication, which is more pressing than choosing a particular > SASL mechanism. So I think we should have libpq options to control that, but > it's a bigger feature than just adding a debug environment variable here. Of course, my last sentence implied that this may be useful once more than 1 mechanism is added. This definitely cannot be a connection parameter. Your last sentence makes me guess that we agree on that. But those are thoughts for later.. > Thanks for the review! I've pushed these patches, after a bunch of little > cleanups here and there, and fixing a few garden-variety bugs in the > GSS/SSPI changes. Committed patches look good to me after a second lookup. Thanks! -- Michael -- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers
Re: [HACKERS] Letting the client choose the protocol to use during a SASL exchange
On 04/13/2017 05:53 AM, Michael Paquier wrote: Thanks for the updated patches! I had a close look at them. Let's begin with 0001... /* * Negotiation generated data to be sent to the client. */ - elog(DEBUG4, "sending SASL response token of length %u", outputlen); + elog(DEBUG4, "sending SASL challenge of length %u", outputlen); sendAuthRequest(port, AUTH_REQ_SASL_CONT, output, outputlen); + + pfree(output); } This will leak one byte if output is of length 0. I think that the pfree call should be moved out of this if condition and only called if output is not NULL. That's a nit, and in the code this scenario cannot happen, but I would recommend to be correct. Fixed. +static int +pg_SASL_init(PGconn *conn, int payloadLen) { + charauth_mechanism[21]; So this assumes that any SASL mechanism name will never be longer than 20 characters. Looking at the link of IANA that Alvaro is providing upthread this is true, could you add a comment that this relies on such an assumption? I picked 20 characters for the buffer, because that's what the SASL spec says is the maximum, but note that the code doesn't actually rely on that. It checks the length of the incoming string, and throws a "SASL mechanism not supported" error if it doesn't fit in the buffer. 20 is enough to hold "SCRAM-SHA-256", which is the only supported mechanism. Also note that the second patch replaces this code, anyway.. + if (initialresponselen != 0) + { + res = pqPacketSend(conn, 'p', initialresponse, initialresponselen); + free(initialresponse); + + if (res != STATUS_OK) + return STATUS_ERROR; + } Here also initialresponse could be free'd only if it is not NULL. Fixed. And now for 0002... No much changes in the docs I like the split done for GSS and SSPI messages. + /* +* The StringInfo guarantees that there's a \0 byte after the +* response. +*/ + Assert(input[inputlen] == '\0'); + pq_getmsgend(); Shouldn't this also check input == NULL? This could crash the assertion and pg_be_scram_exchange is able to handle a NULL input message. Yep, fixed! +* Parse the list of SASL authentication mechanisms in the +* AuthenticationSASL message, and select the best mechanism that we +* support. (Only SCRAM-SHA-256 is supported at the moment.) */ - if (strcmp(auth_mechanism, SCRAM_SHA256_NAME) == 0) + for (;;) Just an idea here: being able to enforce the selection with an environment variable (useful for testing as well in the future). Hmm. It wouldn't do much, as long as SCRAM-SHA-256 is the only supported mechanism. In general, there is no way to tell libpq to e.g. not do plain password authentication, which is more pressing than choosing a particular SASL mechanism. So I think we should have libpq options to control that, but it's a bigger feature than just adding a debug environment variable here. Thanks for the review! I've pushed these patches, after a bunch of little cleanups here and there, and fixing a few garden-variety bugs in the GSS/SSPI changes. Álvaro, you're good to go and implement the JDBC support based on this. Thanks! Please keep me informed on how it goes, and let me know if you run into any trouble, or if there's any discrepancies or ambiguity in the docs that we should fix. - Heikki -- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers
Re: [HACKERS] Letting the client choose the protocol to use during a SASL exchange
My only desire would be to have a final spec and implement the full parser now, not have to change it in the future. We already know today all the requirements, so please pick one and I will follow it :) On Apr 13, 2017 13:47, "Heikki Linnakangas"wrote: > On 04/13/2017 02:35 PM, Álvaro Hernández Tortosa wrote: > >> On 13/04/17 13:24, Heikki Linnakangas wrote: >> >>> Right, when we get channel binding, the server will list >>> "SCRAM-SHA-256" and "SCRAM-SHA-256-PLUS" as the list of mechanisms. >>> And if we get channel binding using something else than tls-unique, >>> then those will be added as extra mechanisms, too, e.g. >>> "SCRAM-SHA-256-PLUS tls-awesome". >>> >> >> And how about supporting different SCRAM mechanisms with different >> possible channel bindings? Separate by space too? So given a field, is >> the first item the SCRAM mechanism, and all the remaning the channel >> binding methods? I.e.: >> >> SCRAM-SHA-256-PLUS tls-awesome tls-awesome2 tls-awesome3\0... >> > > I think we're going in circles.. Yeah, we could do that. Or they could be > listed as separate mechanisms: > > SCRAM-SHA-256-PLUS\0 > SCRAM-SHA-256-PLUS tls-awesome\0 > SCRAM-SHA-256-PLUS tls-awesome2\0 > SCRAM-SHA-256-PLUS tls-awesome3\0 > \0 > > One alternative is that you could list extra channel bindings that are > supported by all the mechanisms, as separate entries. So the list could be: > > binding tls-unique\0 > binding tls-awesome\0 > binding tls-awesome2\0 > binding tls-awesome3\0 > SCRAM-SHA-256-PLUS\0 > SCRAM-SHA-512-PLUS\0 > \0 > > which would mean that those bindings are supported by all the mechanisms > that follow. I think this would achieve the same thing as your proposed > separate field, with the current proposed protocol. > > But again, I'm 99% sure we won't need it, and we don't need to decide the > exact syntax for channel bindings yet. We have the flexibility now, so we > can cross the bridge when we get there. > > - Heikki > >
Re: [HACKERS] Letting the client choose the protocol to use during a SASL exchange
On 04/13/2017 02:35 PM, Álvaro Hernández Tortosa wrote: On 13/04/17 13:24, Heikki Linnakangas wrote: Right, when we get channel binding, the server will list "SCRAM-SHA-256" and "SCRAM-SHA-256-PLUS" as the list of mechanisms. And if we get channel binding using something else than tls-unique, then those will be added as extra mechanisms, too, e.g. "SCRAM-SHA-256-PLUS tls-awesome". And how about supporting different SCRAM mechanisms with different possible channel bindings? Separate by space too? So given a field, is the first item the SCRAM mechanism, and all the remaning the channel binding methods? I.e.: SCRAM-SHA-256-PLUS tls-awesome tls-awesome2 tls-awesome3\0... I think we're going in circles.. Yeah, we could do that. Or they could be listed as separate mechanisms: SCRAM-SHA-256-PLUS\0 SCRAM-SHA-256-PLUS tls-awesome\0 SCRAM-SHA-256-PLUS tls-awesome2\0 SCRAM-SHA-256-PLUS tls-awesome3\0 \0 One alternative is that you could list extra channel bindings that are supported by all the mechanisms, as separate entries. So the list could be: binding tls-unique\0 binding tls-awesome\0 binding tls-awesome2\0 binding tls-awesome3\0 SCRAM-SHA-256-PLUS\0 SCRAM-SHA-512-PLUS\0 \0 which would mean that those bindings are supported by all the mechanisms that follow. I think this would achieve the same thing as your proposed separate field, with the current proposed protocol. But again, I'm 99% sure we won't need it, and we don't need to decide the exact syntax for channel bindings yet. We have the flexibility now, so we can cross the bridge when we get there. - Heikki -- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers
Re: [HACKERS] Letting the client choose the protocol to use during a SASL exchange
On 13/04/17 04:54, Michael Paquier wrote: On Thu, Apr 13, 2017 at 6:37 AM, Álvaro Hernández Tortosawrote: By looking at the them, and unless I'm missing something, I don't see how the extra information for the future implementation of channel binding would be added (without changing the protocol). Relevant part is: The message body is a list of SASL authentication mechanisms, in the server's order of preference. A zero byte is required as terminator after the last authentication mechanism name. For each mechanism, there is the following: String Name of a SASL authentication mechanism. How do you plan to implement it, in future versions, without modifying the AuthenticationSASL message? Or is it OK to add new fields to a message in future PostgreSQL versions, without considering that a protocol change? I don't quite understand the complain here, it is perfectly fine to add as many null-terminated names as you want with this model. The patches would make the server just send one mechanism name now, but nothing prevents the addition of more. I think I explained in my previous reply, but just in case: there are two lists here: SCRAM mechanism and channel binding mechanisms. They are orthogonal, you could pick them separately (only with the -PLUS variants, of course). All two (both SCRAM and channel binding mechanisms) have to be advertised by the server. Álvaro -- Álvaro Hernández Tortosa --- <8K>data -- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers
Re: [HACKERS] Letting the client choose the protocol to use during a SASL exchange
On 13/04/17 13:24, Heikki Linnakangas wrote: On 04/13/2017 05:54 AM, Michael Paquier wrote: On Thu, Apr 13, 2017 at 6:37 AM, Álvaro Hernández Tortosawrote: By looking at the them, and unless I'm missing something, I don't see how the extra information for the future implementation of channel binding would be added (without changing the protocol). Relevant part is: The message body is a list of SASL authentication mechanisms, in the server's order of preference. A zero byte is required as terminator after the last authentication mechanism name. For each mechanism, there is the following: String Name of a SASL authentication mechanism. How do you plan to implement it, in future versions, without modifying the AuthenticationSASL message? Or is it OK to add new fields to a message in future PostgreSQL versions, without considering that a protocol change? I don't quite understand the complain here, it is perfectly fine to add as many null-terminated names as you want with this model. The patches would make the server just send one mechanism name now, but nothing prevents the addition of more. Right, when we get channel binding, the server will list "SCRAM-SHA-256" and "SCRAM-SHA-256-PLUS" as the list of mechanisms. And if we get channel binding using something else than tls-unique, then those will be added as extra mechanisms, too, e.g. "SCRAM-SHA-256-PLUS tls-awesome". And how about supporting different SCRAM mechanisms with different possible channel bindings? Separate by space too? So given a field, is the first item the SCRAM mechanism, and all the remaning the channel binding methods? I.e.: SCRAM-SHA-256-PLUS tls-awesome tls-awesome2 tls-awesome3\0... Please note that if this is the solution chosen: - A lot of parsing and convention is required (first arg is the SCRAM mechanism, succesive are channel binding; tls-unique is always "implied", etc) - Channel binding names will be repeated for every SCRAM mechanism with "-PLUS". This is not needed, SCRAM mechanisms and channel binding are separate things. - Channel binding names will not be present on others, making the parser even more complex. All this vs, again, stating SCRAM mechanisms on one list and channel binding on another list, which is to my much more KISS. But... anyway, if this is the decision made, at least I think this should be documented now, because client parsers need to be designed one way or another. Thanks, Álvaro -- Álvaro Hernández Tortosa --- <8K>data -- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers
Re: [HACKERS] Letting the client choose the protocol to use during a SASL exchange
On 04/13/2017 05:54 AM, Michael Paquier wrote: On Thu, Apr 13, 2017 at 6:37 AM, Álvaro Hernández Tortosawrote: By looking at the them, and unless I'm missing something, I don't see how the extra information for the future implementation of channel binding would be added (without changing the protocol). Relevant part is: The message body is a list of SASL authentication mechanisms, in the server's order of preference. A zero byte is required as terminator after the last authentication mechanism name. For each mechanism, there is the following: String Name of a SASL authentication mechanism. How do you plan to implement it, in future versions, without modifying the AuthenticationSASL message? Or is it OK to add new fields to a message in future PostgreSQL versions, without considering that a protocol change? I don't quite understand the complain here, it is perfectly fine to add as many null-terminated names as you want with this model. The patches would make the server just send one mechanism name now, but nothing prevents the addition of more. Right, when we get channel binding, the server will list "SCRAM-SHA-256" and "SCRAM-SHA-256-PLUS" as the list of mechanisms. And if we get channel binding using something else than tls-unique, then those will be added as extra mechanisms, too, e.g. "SCRAM-SHA-256-PLUS tls-awesome". I don't think that needs to be discussed in the docs yet, because a client will simply ignore any mechanisms it doesn't understand. Although perhaps it would be good to mention explicitly that even though SASL defines that mechanism names have a particular format - all ASCII upper-case, max 20 chars - the client should accept and ignore arbitrary strings, not limited to that format. - Heikki -- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers
Re: [HACKERS] Letting the client choose the protocol to use during a SASL exchange
On Thu, Apr 13, 2017 at 6:37 AM, Álvaro Hernández Tortosawrote: > By looking at the them, and unless I'm missing something, I don't see > how the extra information for the future implementation of channel binding > would be added (without changing the protocol). Relevant part is: > > The message body is a list of SASL authentication mechanisms, in the > server's order of preference. A zero byte is required as terminator after > the last authentication mechanism name. For each mechanism, there is the > following: > > > > String > > > > Name of a SASL authentication mechanism. > > > > > How do you plan to implement it, in future versions, without modifying > the AuthenticationSASL message? Or is it OK to add new fields to a message > in future PostgreSQL versions, without considering that a protocol change? I don't quite understand the complain here, it is perfectly fine to add as many null-terminated names as you want with this model. The patches would make the server just send one mechanism name now, but nothing prevents the addition of more. -- Michael -- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers
Re: [HACKERS] Letting the client choose the protocol to use during a SASL exchange
On Thu, Apr 13, 2017 at 2:34 AM, Heikki Linnakangaswrote: > On 04/11/2017 02:32 PM, Álvaro Hernández Tortosa wrote: >> >> So I still see your proposal more awkward and less clear, mixing >> things that are separate. But again, your choice :) > > > So, here's my more full-fledged proposal. > > The first patch refactors libpq code, by moving the responsibility of > reading the GSS/SSPI/SASL/MD5 specific data from the authentication request > packet, from the enormous switch-case construct in PQConnectPoll(), into > pg_fe_sendauth(). This isn't strictly necessary, but I think it's useful > cleanup anyway, and now that there's a bit more structure in the > AuthenticationSASL message, the old way was getting awkward. > > The second patch contains the protocol changes, and adds the documentation > for it. Thanks for the updated patches! I had a close look at them. Let's begin with 0001... /* * Negotiation generated data to be sent to the client. */ - elog(DEBUG4, "sending SASL response token of length %u", outputlen); + elog(DEBUG4, "sending SASL challenge of length %u", outputlen); sendAuthRequest(port, AUTH_REQ_SASL_CONT, output, outputlen); + + pfree(output); } This will leak one byte if output is of length 0. I think that the pfree call should be moved out of this if condition and only called if output is not NULL. That's a nit, and in the code this scenario cannot happen, but I would recommend to be correct. +static int +pg_SASL_init(PGconn *conn, int payloadLen) { + charauth_mechanism[21]; So this assumes that any SASL mechanism name will never be longer than 20 characters. Looking at the link of IANA that Alvaro is providing upthread this is true, could you add a comment that this relies on such an assumption? + if (initialresponselen != 0) + { + res = pqPacketSend(conn, 'p', initialresponse, initialresponselen); + free(initialresponse); + + if (res != STATUS_OK) + return STATUS_ERROR; + } Here also initialresponse could be free'd only if it is not NULL. And now for 0002... No much changes in the docs I like the split done for GSS and SSPI messages. + /* +* The StringInfo guarantees that there's a \0 byte after the +* response. +*/ + Assert(input[inputlen] == '\0'); + pq_getmsgend(); Shouldn't this also check input == NULL? This could crash the assertion and pg_be_scram_exchange is able to handle a NULL input message. +* Parse the list of SASL authentication mechanisms in the +* AuthenticationSASL message, and select the best mechanism that we +* support. (Only SCRAM-SHA-256 is supported at the moment.) */ - if (strcmp(auth_mechanism, SCRAM_SHA256_NAME) == 0) + for (;;) Just an idea here: being able to enforce the selection with an environment variable (useful for testing as well in the future). -- Michael -- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers
Re: [HACKERS] Letting the client choose the protocol to use during a SASL exchange
On 12/04/17 19:34, Heikki Linnakangas wrote: On 04/11/2017 02:32 PM, Álvaro Hernández Tortosa wrote: So I still see your proposal more awkward and less clear, mixing things that are separate. But again, your choice :) So, here's my more full-fledged proposal. The first patch refactors libpq code, by moving the responsibility of reading the GSS/SSPI/SASL/MD5 specific data from the authentication request packet, from the enormous switch-case construct in PQConnectPoll(), into pg_fe_sendauth(). This isn't strictly necessary, but I think it's useful cleanup anyway, and now that there's a bit more structure in the AuthenticationSASL message, the old way was getting awkward. The second patch contains the protocol changes, and adds the documentation for it. - Heikki Hi Heikki. Thanks for the patches :) By looking at the them, and unless I'm missing something, I don't see how the extra information for the future implementation of channel binding would be added (without changing the protocol). Relevant part is: The message body is a list of SASL authentication mechanisms, in the server's order of preference. A zero byte is required as terminator after the last authentication mechanism name. For each mechanism, there is the following: String Name of a SASL authentication mechanism. How do you plan to implement it, in future versions, without modifying the AuthenticationSASL message? Or is it OK to add new fields to a message in future PostgreSQL versions, without considering that a protocol change? On a side note, I'd mention that the list of SASL authentication mechanisms contains valid IANA Registry SCRAM names (https://www.iana.org/assignments/sasl-mechanisms/sasl-mechanisms.xhtml#scram)for SCRAM authentication messages (making it more clear what values would be expected there from the client). I hope to start testing this from Java the coming weekend. I will keep you posted. Álvaro -- Álvaro Hernández Tortosa --- <8K>data -- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers
Re: [HACKERS] Letting the client choose the protocol to use during a SASL exchange
On 04/11/2017 02:32 PM, Álvaro Hernández Tortosa wrote: So I still see your proposal more awkward and less clear, mixing things that are separate. But again, your choice :) So, here's my more full-fledged proposal. The first patch refactors libpq code, by moving the responsibility of reading the GSS/SSPI/SASL/MD5 specific data from the authentication request packet, from the enormous switch-case construct in PQConnectPoll(), into pg_fe_sendauth(). This isn't strictly necessary, but I think it's useful cleanup anyway, and now that there's a bit more structure in the AuthenticationSASL message, the old way was getting awkward. The second patch contains the protocol changes, and adds the documentation for it. - Heikki >From 29c958dab9f8ece5d855b335c09cc9125606774a Mon Sep 17 00:00:00 2001 From: Heikki LinnakangasDate: Wed, 12 Apr 2017 16:01:18 +0300 Subject: [PATCH 1/2] Refactor libpq authentication request processing. Move the responsibility of reading the data from the authentication request message from PQconnectPoll() to pg_fe_sendauth(). This way, PQconnectPoll() doesn't need to know about the different authentication request types, and we don't need the extra fields in the pg_conn struct to pass the data from PQconnectPoll() to pg_fe_sendauth() anymore. In the backend, free each SASL message after sending it. It's not a lot of wasted memory, but a leak nevertheless. Adding the pfree() revealed a little bug in build_server_first_message(): It attempts to keeps a copy of the sent message, but it was missing a pstrdup(), so the pointer started to dangle, after adding the pfree() into CheckSCRAMAuth(). --- src/backend/libpq/auth-scram.c| 10 +- src/backend/libpq/auth.c | 10 +- src/interfaces/libpq/fe-auth.c| 214 +- src/interfaces/libpq/fe-auth.h| 2 +- src/interfaces/libpq/fe-connect.c | 113 +++- src/interfaces/libpq/fe-misc.c| 13 +++ src/interfaces/libpq/libpq-int.h | 11 +- 7 files changed, 204 insertions(+), 169 deletions(-) diff --git a/src/backend/libpq/auth-scram.c b/src/backend/libpq/auth-scram.c index 5077ff33b1..a47c48d980 100644 --- a/src/backend/libpq/auth-scram.c +++ b/src/backend/libpq/auth-scram.c @@ -161,10 +161,10 @@ static char *scram_MockSalt(const char *username); * needs to be called before doing any exchange. It will be filled later * after the beginning of the exchange with verifier data. * - * 'username' is the provided by the client. 'shadow_pass' is the role's - * password verifier, from pg_authid.rolpassword. If 'shadow_pass' is NULL, we - * still perform an authentication exchange, but it will fail, as if an - * incorrect password was given. + * 'username' is the username provided by the client in the startup message. + * 'shadow_pass' is the role's password verifier, from pg_authid.rolpassword. + * If 'shadow_pass' is NULL, we still perform an authentication exchange, but + * it will fail, as if an incorrect password was given. */ void * pg_be_scram_init(const char *username, const char *shadow_pass) @@ -984,7 +984,7 @@ build_server_first_message(scram_state *state) state->client_nonce, state->server_nonce, state->salt, state->iterations); - return state->server_first_message; + return pstrdup(state->server_first_message); } diff --git a/src/backend/libpq/auth.c b/src/backend/libpq/auth.c index 66ead9381d..681b93855f 100644 --- a/src/backend/libpq/auth.c +++ b/src/backend/libpq/auth.c @@ -872,6 +872,8 @@ CheckSCRAMAuth(Port *port, char *shadow_pass, char **logdetail) strlen(SCRAM_SHA256_NAME) + 1); /* + * Initialize the status tracker for message exchanges. + * * If the user doesn't exist, or doesn't have a valid password, or it's * expired, we still go through the motions of SASL authentication, but * tell the authentication method that the authentication is "doomed". @@ -880,8 +882,6 @@ CheckSCRAMAuth(Port *port, char *shadow_pass, char **logdetail) * This is because we don't want to reveal to an attacker what usernames * are valid, nor which users have a valid password. */ - - /* Initialize the status tracker for message exchanges */ scram_opaq = pg_be_scram_init(port->user_name, shadow_pass); /* @@ -918,7 +918,7 @@ CheckSCRAMAuth(Port *port, char *shadow_pass, char **logdetail) return STATUS_ERROR; } - elog(DEBUG4, "Processing received SASL token of length %d", buf.len); + elog(DEBUG4, "Processing received SASL response of length %d", buf.len); /* * we pass 'logdetail' as NULL when doing a mock authentication, @@ -936,9 +936,11 @@ CheckSCRAMAuth(Port *port, char *shadow_pass, char **logdetail) /* * Negotiation generated data to be sent to the client. */ - elog(DEBUG4, "sending SASL response token of length %u", outputlen); + elog(DEBUG4, "sending SASL challenge of length %u", outputlen); sendAuthRequest(port,
Re: [HACKERS] Letting the client choose the protocol to use during a SASL exchange
On 11/04/17 13:21, Heikki Linnakangas wrote: On 04/11/2017 01:39 PM, Álvaro Hernández Tortosa wrote: The fact that you null terminate them (fine with me) doesn't change my reasoning. How do you separate multiple channel binding methods? And do you realize that you will be repeating the channel binding methods without reason? A contrived but legal, possible example: Field1: SCRAM-SHA-256\0 SCRAM-SHA-512\0 SCRAM-SHA-999\0 SCRAM-SHA-256-PLUS tls-unique tls-awesome yet-another-tls\0 SCRAM-SHA-512-PLUS tls-unique tls-awesome yet-another-tls\0 SCRAM-SHA-999-PLUS tls-unique tls-awesome yet-another-tls\0 I was actually thinking of: SCRAM-SHA-256\0 SCRAM-SHA-512\0 SCRAM-SHA-999\0 SCRAM-SHA-256-PLUS\0 SCRAM-SHA-256-PLUS tls-awesome\0 SCRAM-SHA-256-PLUS yet-another-tls\0 SCRAM-SHA-512-PLUS\0 SCRAM-SHA-512-PLUS tls-awesome\0 SCRAM-SHA-512-PLUS yet-another-tls\0 SCRAM-SHA-999-PLUS\0 SCRAM-SHA-999-PLUS tls-awesome\0 SCRAM-SHA-999-PLUS yet-another-tls\0 In practice, I don't foresee us having this many options, so the verbosity won't be an issue. Parsing this is very straightforward. That's maybe slightly better, since -I agree- verbosity is not an issue. But parsing (parsers, and validators) are still more complex (you need to check that if suffix is -PLUS you need to split by space and find another field with another format based on another lookup table of IANA registry names and so forth). Vs: this field is for SCRAM names, this field is for channel binding names. Done. Let me exemplify. In Java-ish syntax, your type would be something like: List> from where you need to extract individually ScramMechanisms and unique(ChannelBindingType) My proposal would have two lists: List List which is exactly what you need. So I still see your proposal more awkward and less clear, mixing things that are separate. But again, your choice :) vs Field 1: SCRAM-SHA-256,SCRAM-SHA-256-PLUS,SCRAM-SHA-1-PLUS,SCRAM-SHA-512-PLUS (simple CSV) Field 2: tls-unique (String) What if tls-unique is only supported with SCRAM-SHA-256-PLUS, while SCRAM-SHA-512-PLUS requires tls-awesome? It can't happen. The RFC clearly states that they are orthogonal. It is left to the implementations support one or the other, but no reason to limit applicability of a given binding method to a given SCRAM mechanisms (or viceversa). Well, if tls-unique is found to be insecure, a future SCRAM-SHA-512-PLUS spec might well define that the default for that mechanism is tls-unique-new-and-secure rather than tls-unique. Maybe even forbid using tls-unique altogether. I don't think that's likely, but this is all about future-proofing, so I'd rather keep it flexible. If it would be insecure, I'd immediately stop it from being advertised, and problem solved. Nothing would change (under my proposal). -- Álvaro Hernández Tortosa --- <8K>data -- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers
Re: [HACKERS] Letting the client choose the protocol to use during a SASL exchange
On 04/11/2017 01:39 PM, Álvaro Hernández Tortosa wrote: The fact that you null terminate them (fine with me) doesn't change my reasoning. How do you separate multiple channel binding methods? And do you realize that you will be repeating the channel binding methods without reason? A contrived but legal, possible example: Field1: SCRAM-SHA-256\0 SCRAM-SHA-512\0 SCRAM-SHA-999\0 SCRAM-SHA-256-PLUS tls-unique tls-awesome yet-another-tls\0 SCRAM-SHA-512-PLUS tls-unique tls-awesome yet-another-tls\0 SCRAM-SHA-999-PLUS tls-unique tls-awesome yet-another-tls\0 I was actually thinking of: SCRAM-SHA-256\0 SCRAM-SHA-512\0 SCRAM-SHA-999\0 SCRAM-SHA-256-PLUS\0 SCRAM-SHA-256-PLUS tls-awesome\0 SCRAM-SHA-256-PLUS yet-another-tls\0 SCRAM-SHA-512-PLUS\0 SCRAM-SHA-512-PLUS tls-awesome\0 SCRAM-SHA-512-PLUS yet-another-tls\0 SCRAM-SHA-999-PLUS\0 SCRAM-SHA-999-PLUS tls-awesome\0 SCRAM-SHA-999-PLUS yet-another-tls\0 In practice, I don't foresee us having this many options, so the verbosity won't be an issue. Parsing this is very straightforward. vs Field 1: SCRAM-SHA-256,SCRAM-SHA-256-PLUS,SCRAM-SHA-1-PLUS,SCRAM-SHA-512-PLUS (simple CSV) Field 2: tls-unique (String) What if tls-unique is only supported with SCRAM-SHA-256-PLUS, while SCRAM-SHA-512-PLUS requires tls-awesome? It can't happen. The RFC clearly states that they are orthogonal. It is left to the implementations support one or the other, but no reason to limit applicability of a given binding method to a given SCRAM mechanisms (or viceversa). Well, if tls-unique is found to be insecure, a future SCRAM-SHA-512-PLUS spec might well define that the default for that mechanism is tls-unique-new-and-secure rather than tls-unique. Maybe even forbid using tls-unique altogether. I don't think that's likely, but this is all about future-proofing, so I'd rather keep it flexible. - Heikki -- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers
Re: [HACKERS] Letting the client choose the protocol to use during a SASL exchange
On 11/04/17 12:23, Heikki Linnakangas wrote: On 04/11/2017 11:55 AM, Álvaro Hernández Tortosa wrote: On 11/04/17 08:50, Heikki Linnakangas wrote: Oh, I see. According to the SCRAM RFC, "tls-unique" is used by default. I don't see us implementing anything else any time soon. PostgreSQL doesn't support any other "channel type" than TLS, and tls-unique is the only one that makes sense for TLS. If we do need it after all, the server could advertise the additional channel binding types as additional SASL mechanisms in the AuthenticationSASL message, maybe something like: "SCRAM-SHA-256" "SCRAM-SHA-256-PLUS" (for tls-unique) "SCRAM-SHA-256-PLUS ssh-unique" (for hypothetical ssh channel binding) The same trick can be used to advertise any other SASL mechanism specific options, if needed in the future. Why not add an extra field to the message? This scheme has in my opinion some disadvantages: - You assume no extensibility. Maybe Postgres will implement other mechanisms for channel binding. Maybe not. But why limit ourselves? - Apart from tls-unique there are others today, like tls-server-end-point and who knows if in the future TLS 1.x comes with something like 'tls-unique-1.x' - Why have to parse the string (separated by spaces) when you could use different fields and have no parsing at all? I don't think an option separated by space is any more difficult to parse than a separate field. I'm envisioning that the "parsing" would be simply: if (strcmp(sasl_mechanism, "SCRAM-SHA-256") == 0) { ... } else if (strcmp(sasl_mechanism, "SCRAM-SHA-256-PLUS") == 0) { ... } else if (strcmp(sasl_mechanism, "SCRAM-SHA-256-PLUS tls-awesome") == 0) { ... } This can be extended for more complicated options, if necessary. Although if we find that we need a dozen different options, I think we've done something wrong. - How do you advertise different SCRAM mechanisms with different channel binding types? And a mix of SCRAM mechanisms with and without channel binding? If I got it right, with your proposal it would be something like: Field 1: SCRAM-SHA-256,SCRAM-SHA-256-PLUS tls-unique,SCRAM-SHA-1-PLUS tls-unique,SCRAM-SHA-512-PLUS tls-unique (which is basically a CSV of pairs where the right part of the pair might be empty; too much IMHO for a single field) Yes, except that in my proposal, the list is not a comma-separated string, but a list of null-terminated strings, similar to how some other lists of options in the FE/BE protocol are transmitted. The fact that you null terminate them (fine with me) doesn't change my reasoning. How do you separate multiple channel binding methods? And do you realize that you will be repeating the channel binding methods without reason? A contrived but legal, possible example: Field1: SCRAM-SHA-256\0 SCRAM-SHA-512\0 SCRAM-SHA-999\0 SCRAM-SHA-256-PLUS tls-unique tls-awesome yet-another-tls\0 SCRAM-SHA-512-PLUS tls-unique tls-awesome yet-another-tls\0 SCRAM-SHA-999-PLUS tls-unique tls-awesome yet-another-tls\0 vs Field 1: SCRAM-SHA-256 SCRAM-SHA-512 SCRAM-SHA-999 SCRAM-SHA-256-PLUS SCRAM-SHA-512-PLUS SCRAM-SHA-999-PLUS\0 Field 2: tls-unique tls-awesome yet-another-tls\0 Parsing and validation of the first option is significantly more complex than the second option. vs Field 1: SCRAM-SHA-256,SCRAM-SHA-256-PLUS,SCRAM-SHA-1-PLUS,SCRAM-SHA-512-PLUS (simple CSV) Field 2: tls-unique (String) What if tls-unique is only supported with SCRAM-SHA-256-PLUS, while SCRAM-SHA-512-PLUS requires tls-awesome? It can't happen. The RFC clearly states that they are orthogonal. It is left to the implementations support one or the other, but no reason to limit applicability of a given binding method to a given SCRAM mechanisms (or viceversa). What about possible other options you might need to tack on to mechanisms? This seems less flexible. I'm not saying that either of those cases is very likely, but I don't think it's very likely we'll need extra options or different channel binding types any time soon, anyway. As I said, channel binding and SCRAM mechanisms are orthogonal. On the flip side, a contrived parsing mechanism with optional fields and many that would be repeated all the time seems far from ideal. And far less clear. Is there any reason not to use two fields? AuthenticationSASL is a new message, I guess we can freely choose its format, right? Yes, we can choose the format freely. Cool. In summary, I think the simple list of mechanism names is best, because: * It's simple, and doesn't have any extra fields or options that are not needed right now. I think it is too complicated and mixing things that are orthogonal. Since protocol is hard to extend, adding an extra field for the channel binding mechanisms -even if unused as of PG 10- is a good thing. If you need to change the protocol later, that's a very bad thing (realistically, we all know it won't be changed and some hack would
Re: [HACKERS] Letting the client choose the protocol to use during a SASL exchange
On 04/11/2017 11:55 AM, Álvaro Hernández Tortosa wrote: On 11/04/17 08:50, Heikki Linnakangas wrote: Oh, I see. According to the SCRAM RFC, "tls-unique" is used by default. I don't see us implementing anything else any time soon. PostgreSQL doesn't support any other "channel type" than TLS, and tls-unique is the only one that makes sense for TLS. If we do need it after all, the server could advertise the additional channel binding types as additional SASL mechanisms in the AuthenticationSASL message, maybe something like: "SCRAM-SHA-256" "SCRAM-SHA-256-PLUS" (for tls-unique) "SCRAM-SHA-256-PLUS ssh-unique" (for hypothetical ssh channel binding) The same trick can be used to advertise any other SASL mechanism specific options, if needed in the future. Why not add an extra field to the message? This scheme has in my opinion some disadvantages: - You assume no extensibility. Maybe Postgres will implement other mechanisms for channel binding. Maybe not. But why limit ourselves? - Apart from tls-unique there are others today, like tls-server-end-point and who knows if in the future TLS 1.x comes with something like 'tls-unique-1.x' - Why have to parse the string (separated by spaces) when you could use different fields and have no parsing at all? I don't think an option separated by space is any more difficult to parse than a separate field. I'm envisioning that the "parsing" would be simply: if (strcmp(sasl_mechanism, "SCRAM-SHA-256") == 0) { ... } else if (strcmp(sasl_mechanism, "SCRAM-SHA-256-PLUS") == 0) { ... } else if (strcmp(sasl_mechanism, "SCRAM-SHA-256-PLUS tls-awesome") == 0) { ... } This can be extended for more complicated options, if necessary. Although if we find that we need a dozen different options, I think we've done something wrong. - How do you advertise different SCRAM mechanisms with different channel binding types? And a mix of SCRAM mechanisms with and without channel binding? If I got it right, with your proposal it would be something like: Field 1: SCRAM-SHA-256,SCRAM-SHA-256-PLUS tls-unique,SCRAM-SHA-1-PLUS tls-unique,SCRAM-SHA-512-PLUS tls-unique (which is basically a CSV of pairs where the right part of the pair might be empty; too much IMHO for a single field) Yes, except that in my proposal, the list is not a comma-separated string, but a list of null-terminated strings, similar to how some other lists of options in the FE/BE protocol are transmitted. vs Field 1: SCRAM-SHA-256,SCRAM-SHA-256-PLUS,SCRAM-SHA-1-PLUS,SCRAM-SHA-512-PLUS (simple CSV) Field 2: tls-unique (String) What if tls-unique is only supported with SCRAM-SHA-256-PLUS, while SCRAM-SHA-512-PLUS requires tls-awesome? What about possible other options you might need to tack on to mechanisms? This seems less flexible. I'm not saying that either of those cases is very likely, but I don't think it's very likely we'll need extra options or different channel binding types any time soon, anyway. Is there any reason not to use two fields? AuthenticationSASL is a new message, I guess we can freely choose its format, right? Yes, we can choose the format freely. In summary, I think the simple list of mechanism names is best, because: * It's simple, and doesn't have any extra fields or options that are not needed right now. * It's flexible, for future extension. We can add new mechanism entries with extra options, not just new channel binding types, if needed, and existing clients (i.e. v10 clients) will ignore them. Perhaps we should reserve a magic user name to mean "same as startup message", in addition or instead of the empty string. We actually discussed that already at [1], but we forgot about it since. That works. Please let me know what is the "magic constant" chosen ;P I was hoping you'd have some good suggestions :-). Unfortunately there is no reserved username prefix or anything like that, so whatever we choose might also be a real username. That's OK, but it could be confusing, if we ever tried to do something different with the SASL username. How about "pg_same_as_startup_message"? - Heikki -- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers
Re: [HACKERS] Letting the client choose the protocol to use during a SASL exchange
On 11/04/17 08:50, Heikki Linnakangas wrote: On 04/10/2017 11:03 PM, Álvaro Hernández Tortosa wrote: Channel binding needs to specify actually three things: - The mechanism, which is indeed suffixed "-PLUS". - The channel binding name, which is described here: https://tools.ietf.org/html/rfc5056. Types are also IANA-registered (see https://www.iana.org/assignments/channel-binding-types/channel-binding-types.xhtml). SCRAM mandates to implement 'tls-unique', but other channel binding types could be supported (like 'tls-server-end-point' for example). - The channel binding data, which is channel binding mechanism dependent, and is sent as part of the client last message. What I'm talking about here is the second one, the channel binding type (name). Oh, I see. According to the SCRAM RFC, "tls-unique" is used by default. I don't see us implementing anything else any time soon. PostgreSQL doesn't support any other "channel type" than TLS, and tls-unique is the only one that makes sense for TLS. If we do need it after all, the server could advertise the additional channel binding types as additional SASL mechanisms in the AuthenticationSASL message, maybe something like: "SCRAM-SHA-256" "SCRAM-SHA-256-PLUS" (for tls-unique) "SCRAM-SHA-256-PLUS ssh-unique" (for hypothetical ssh channel binding) The same trick can be used to advertise any other SASL mechanism specific options, if needed in the future. Why not add an extra field to the message? This scheme has in my opinion some disadvantages: - You assume no extensibility. Maybe Postgres will implement other mechanisms for channel binding. Maybe not. But why limit ourselves? - Apart from tls-unique there are others today, like tls-server-end-point and who knows if in the future TLS 1.x comes with something like 'tls-unique-1.x' - Why have to parse the string (separated by spaces) when you could use different fields and have no parsing at all? - How do you advertise different SCRAM mechanisms with different channel binding types? And a mix of SCRAM mechanisms with and without channel binding? If I got it right, with your proposal it would be something like: Field 1: SCRAM-SHA-256,SCRAM-SHA-256-PLUS tls-unique,SCRAM-SHA-1-PLUS tls-unique,SCRAM-SHA-512-PLUS tls-unique (which is basically a CSV of pairs where the right part of the pair might be empty; too much IMHO for a single field) vs Field 1: SCRAM-SHA-256,SCRAM-SHA-256-PLUS,SCRAM-SHA-1-PLUS,SCRAM-SHA-512-PLUS (simple CSV) Field 2: tls-unique (String) Is there any reason not to use two fields? AuthenticationSASL is a new message, I guess we can freely choose its format, right? I'm not sure I follow. The username is sent from client to server, and currently, the server will ignore it. If you're writing a client library, it can send whatever it wants. (Although again I would recommend an empty string, to avoid confusion. Sending the same username as in the startup packet, as long as it's in UTF-8, seems reasonable too.) OK, understood. I will not let then the SCRAM implementation I'm writing to allow for empty string as the user name, but in the pgjdbc glue code send "ignore" as the user name or something like that ;P Hmm, so the SASL library you're using doesn't like sending an empty string as the username? Now that I look at RFC5802 more closely, it says: If the preparation of the username fails or results in an empty string, the server SHOULD abort the authentication exchange. Perhaps we should reserve a magic user name to mean "same as startup message", in addition or instead of the empty string. We actually discussed that already at [1], but we forgot about it since. That works. Please let me know what is the "magic constant" chosen ;P Thanks, Álvaro -- Álvaro Hernández Tortosa --- <8K>data -- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers
Re: [HACKERS] Letting the client choose the protocol to use during a SASL exchange
On 04/10/2017 11:03 PM, Álvaro Hernández Tortosa wrote: Channel binding needs to specify actually three things: - The mechanism, which is indeed suffixed "-PLUS". - The channel binding name, which is described here: https://tools.ietf.org/html/rfc5056. Types are also IANA-registered (see https://www.iana.org/assignments/channel-binding-types/channel-binding-types.xhtml). SCRAM mandates to implement 'tls-unique', but other channel binding types could be supported (like 'tls-server-end-point' for example). - The channel binding data, which is channel binding mechanism dependent, and is sent as part of the client last message. What I'm talking about here is the second one, the channel binding type (name). Oh, I see. According to the SCRAM RFC, "tls-unique" is used by default. I don't see us implementing anything else any time soon. PostgreSQL doesn't support any other "channel type" than TLS, and tls-unique is the only one that makes sense for TLS. If we do need it after all, the server could advertise the additional channel binding types as additional SASL mechanisms in the AuthenticationSASL message, maybe something like: "SCRAM-SHA-256" "SCRAM-SHA-256-PLUS" (for tls-unique) "SCRAM-SHA-256-PLUS ssh-unique" (for hypothetical ssh channel binding) The same trick can be used to advertise any other SASL mechanism specific options, if needed in the future. I'm not sure I follow. The username is sent from client to server, and currently, the server will ignore it. If you're writing a client library, it can send whatever it wants. (Although again I would recommend an empty string, to avoid confusion. Sending the same username as in the startup packet, as long as it's in UTF-8, seems reasonable too.) OK, understood. I will not let then the SCRAM implementation I'm writing to allow for empty string as the user name, but in the pgjdbc glue code send "ignore" as the user name or something like that ;P Hmm, so the SASL library you're using doesn't like sending an empty string as the username? Now that I look at RFC5802 more closely, it says: If the preparation of the username fails or results in an empty string, the server SHOULD abort the authentication exchange. Perhaps we should reserve a magic user name to mean "same as startup message", in addition or instead of the empty string. We actually discussed that already at [1], but we forgot about it since. [1] https://www.postgresql.org/message-id/551A8C2F.7050409%40iki.fi - Heikki -- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers
Re: [HACKERS] Letting the client choose the protocol to use during a SASL exchange
On Tue, Apr 11, 2017 at 4:41 AM, Heikki Linnakangaswrote: > On 04/10/2017 09:33 PM, Álvaro Hernández Tortosa wrote: >> - If the username used is the one sent in the startup message, rather >> than leaving it empty in the client-first-message, I would force it to >> be the same as the used in the startuo message. > > The problem with that is that the SCRAM spec dictates that the username must > be encoded in UTF-8, but PostgreSQL supports non-UTF-8 usernames. > > Or did you mean that, if the username is sent, it must match the one in the > startup packet, but an empty string would always be allowed? That would be > reasonable. That sounds sensible from here. >> Otherwise we may confuse >> some client implementations which would probably consider that as an >> error; for one, my implementation would currently throw an error if >> username is empty, and I think that's correct. > > I'm not sure I follow. The username is sent from client to server, and > currently, the server will ignore it. If you're writing a client library, it > can send whatever it wants. (Although again I would recommend an empty > string, to avoid confusion. Sending the same username as in the startup > packet, as long as it's in UTF-8, seems reasonable too.) > > Thanks for reviewing this! I'll start hacking on code changes to go with > these docs. Sounds good to me, thanks! I looked at the doc patch for now, and here are some nits. + +SCRAM-SHA-256 is the only implemented SASL mechanism, at the moment. It is +described in detail in [RFC7677] and [RFC5741]. (called just SCRAM from now on) + Perhaps those should be links to the RFCs. + + Client sends a SASLResponse messsage, with SCRAM + client-final-message as the content. + Typo. Message needs two 's'. + server-final-message in the "additional data" field. + + + + I think that you are missing a markup here. + + +Authentication method specific "additional data". If this +message contains no additional data, this field is omitted. + + So that's for the first message generated by the client in the exchange. Better than my previous idea. Shouldn't double quotes be replaced by proper markups? -- Michael -- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers
Re: [HACKERS] Letting the client choose the protocol to use during a SASL exchange
On 10/04/17 21:41, Heikki Linnakangas wrote: On 04/10/2017 09:33 PM, Álvaro Hernández Tortosa wrote: Thanks for posting the patched HTML. In my opinion, all looks good except that: - I will add an extra String (a CSV) to AuthenticationSASL message for channel binding names, so that message format can remain without changes when channel binding is implemented. It can be empty. Note that SCRAM-SHA-256 with channel binding has a different SASL mechanism name, SRAM-SHA-256-PLUS. No need for a separate flag or string for channel binding. When support for channel binding is added to the server, it will advertise two SASL mechanisms in the AuthenticationSASL message, SCRAM-SHA-256 and SCRAM-SHA-256-PLUS. (Or just SCRAM-SHA-256-PLUS, if channel-binding is required). Channel binding needs to specify actually three things: - The mechanism, which is indeed suffixed "-PLUS". - The channel binding name, which is described here: https://tools.ietf.org/html/rfc5056. Types are also IANA-registered (see https://www.iana.org/assignments/channel-binding-types/channel-binding-types.xhtml). SCRAM mandates to implement 'tls-unique', but other channel binding types could be supported (like 'tls-server-end-point' for example). - The channel binding data, which is channel binding mechanism dependent, and is sent as part of the client last message. What I'm talking about here is the second one, the channel binding type (name). - If the username used is the one sent in the startup message, rather than leaving it empty in the client-first-message, I would force it to be the same as the used in the startuo message. The problem with that is that the SCRAM spec dictates that the username must be encoded in UTF-8, but PostgreSQL supports non-UTF-8 usernames. Or did you mean that, if the username is sent, it must match the one in the startup packet, but an empty string would always be allowed? That would be reasonable. Otherwise we may confuse some client implementations which would probably consider that as an error; for one, my implementation would currently throw an error if username is empty, and I think that's correct. I'm not sure I follow. The username is sent from client to server, and currently, the server will ignore it. If you're writing a client library, it can send whatever it wants. (Although again I would recommend an empty string, to avoid confusion. Sending the same username as in the startup packet, as long as it's in UTF-8, seems reasonable too.) OK, understood. I will not let then the SCRAM implementation I'm writing to allow for empty string as the user name, but in the pgjdbc glue code send "ignore" as the user name or something like that ;P Thanks for reviewing this! I'll start hacking on code changes to go with these docs. Thanks for writing the code :) Álvaro -- Álvaro Hernández Tortosa --- <8K>data -- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers
Re: [HACKERS] Letting the client choose the protocol to use during a SASL exchange
On 04/10/2017 09:33 PM, Álvaro Hernández Tortosa wrote: Thanks for posting the patched HTML. In my opinion, all looks good except that: - I will add an extra String (a CSV) to AuthenticationSASL message for channel binding names, so that message format can remain without changes when channel binding is implemented. It can be empty. Note that SCRAM-SHA-256 with channel binding has a different SASL mechanism name, SRAM-SHA-256-PLUS. No need for a separate flag or string for channel binding. When support for channel binding is added to the server, it will advertise two SASL mechanisms in the AuthenticationSASL message, SCRAM-SHA-256 and SCRAM-SHA-256-PLUS. (Or just SCRAM-SHA-256-PLUS, if channel-binding is required). - If the username used is the one sent in the startup message, rather than leaving it empty in the client-first-message, I would force it to be the same as the used in the startuo message. The problem with that is that the SCRAM spec dictates that the username must be encoded in UTF-8, but PostgreSQL supports non-UTF-8 usernames. Or did you mean that, if the username is sent, it must match the one in the startup packet, but an empty string would always be allowed? That would be reasonable. Otherwise we may confuse some client implementations which would probably consider that as an error; for one, my implementation would currently throw an error if username is empty, and I think that's correct. I'm not sure I follow. The username is sent from client to server, and currently, the server will ignore it. If you're writing a client library, it can send whatever it wants. (Although again I would recommend an empty string, to avoid confusion. Sending the same username as in the startup packet, as long as it's in UTF-8, seems reasonable too.) Thanks for reviewing this! I'll start hacking on code changes to go with these docs. - Heikki -- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers
Re: [HACKERS] Letting the client choose the protocol to use during a SASL exchange
On 10/04/17 14:57, Heikki Linnakangas wrote: On 04/07/2017 01:13 AM, Michael Paquier wrote: On Fri, Apr 7, 2017 at 5:15 AM, Álvaro Hernández Tortosawrote: I don't see it. The message AuthenticationSASL.String could contain a CSV of the SCRAM protocols supported. This is specially important to support channel binding (which is just another protocol name for this matter), which is the really enhanced security mechanism of SCRAM. Since this message is sent regardless, and the client replies with PasswordMessage, no extra round trip is required. However, PasswordMessage needs to also include a field with the name of the selected protocol (it is the client who picks). Or a different message would need to be created, but no extra round-trips more than those required by SCRAM itself (4 messages for SCRAM + 1 extra for the server to tell the client it needs to use SCRAM). Yes, it seems to me that the list of protocols to send should be done by sendAuthRequest(). Then the client parses the received string, and sends an extra 'p' message with its choice before sending the first SCRAM message. So there is no need for any extra round trips. I started writing down the protocol docs, based on the above idea. See attached. The AuthenticationSASL message now contains a list of mechanisms. Does that seem clear to you? If so, I'll change the code to match the attached docs. I added two new message formats to the docs, SASLResponse and SASLInitialResponse. Those use the same type byte as PasswordMessage, 'p', but I decided to describe them as separate messages for documentation purposes, since the content is completely different depending on whether the message is sent as part of SASL, GSS, md5, or password authentication. IOW, this is not a change in the implementation, only in the way it's documented. While working on this, and reading the RFCs more carefully, I noticed one detail we should change, to be spec-complicant. The SASL spec specifies that a SASL authentication exchange consists of challenge-response pairs. There must be a response to each challenge. If the last message in the authentication mechanism (SCRAM in this case) goes in the server->client direction, then that message must sent as "additional data" in the server->client message that tells the client that the authentication was successful. That's AuthenticationOK in the PostgreSQL protocol. In the current implementation, the server-final-message is sent as an AuthenticationSASLContinue message, and the client doesn't respond to that. We should change that, so that the server-final-message is sent as "additional data" in the AuthenticationOK message. The attached docs patch describes that, rather than what the current implementation does. (For your convenience, I built the HTML docs with this patch, and put them up at http://hlinnaka.iki.fi/temp/scram-wip-docs/protocol.html for viewing) - Heikki Thanks for posting the patched HTML. In my opinion, all looks good except that: - I will add an extra String (a CSV) to AuthenticationSASL message for channel binding names, so that message format can remain without changes when channel binding is implemented. It can be empty. - If the username used is the one sent in the startup message, rather than leaving it empty in the client-first-message, I would force it to be the same as the used in the startuo message. Otherwise we may confuse some client implementations which would probably consider that as an error; for one, my implementation would currently throw an error if username is empty, and I think that's correct. Álvaro -- Álvaro Hernández Tortosa --- <8K>data
Re: [HACKERS] Letting the client choose the protocol to use during a SASL exchange
On 04/07/2017 01:13 AM, Michael Paquier wrote: On Fri, Apr 7, 2017 at 5:15 AM, Álvaro Hernández Tortosawrote: I don't see it. The message AuthenticationSASL.String could contain a CSV of the SCRAM protocols supported. This is specially important to support channel binding (which is just another protocol name for this matter), which is the really enhanced security mechanism of SCRAM. Since this message is sent regardless, and the client replies with PasswordMessage, no extra round trip is required. However, PasswordMessage needs to also include a field with the name of the selected protocol (it is the client who picks). Or a different message would need to be created, but no extra round-trips more than those required by SCRAM itself (4 messages for SCRAM + 1 extra for the server to tell the client it needs to use SCRAM). Yes, it seems to me that the list of protocols to send should be done by sendAuthRequest(). Then the client parses the received string, and sends an extra 'p' message with its choice before sending the first SCRAM message. So there is no need for any extra round trips. I started writing down the protocol docs, based on the above idea. See attached. The AuthenticationSASL message now contains a list of mechanisms. Does that seem clear to you? If so, I'll change the code to match the attached docs. I added two new message formats to the docs, SASLResponse and SASLInitialResponse. Those use the same type byte as PasswordMessage, 'p', but I decided to describe them as separate messages for documentation purposes, since the content is completely different depending on whether the message is sent as part of SASL, GSS, md5, or password authentication. IOW, this is not a change in the implementation, only in the way it's documented. While working on this, and reading the RFCs more carefully, I noticed one detail we should change, to be spec-complicant. The SASL spec specifies that a SASL authentication exchange consists of challenge-response pairs. There must be a response to each challenge. If the last message in the authentication mechanism (SCRAM in this case) goes in the server->client direction, then that message must sent as "additional data" in the server->client message that tells the client that the authentication was successful. That's AuthenticationOK in the PostgreSQL protocol. In the current implementation, the server-final-message is sent as an AuthenticationSASLContinue message, and the client doesn't respond to that. We should change that, so that the server-final-message is sent as "additional data" in the AuthenticationOK message. The attached docs patch describes that, rather than what the current implementation does. (For your convenience, I built the HTML docs with this patch, and put them up at http://hlinnaka.iki.fi/temp/scram-wip-docs/protocol.html for viewing) - Heikki 0001-Add-docs-for-SASL-authentication-in-protocol.patch Description: invalid/octet-stream -- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers
Re: [HACKERS] Letting the client choose the protocol to use during a SASL exchange
On 04/07/2017 11:57 AM, Craig Ringer wrote: On 7 April 2017 at 16:33, Heikki Linnakangaswrote: That list of supported authentication methods would need to be included in the startup message. Unfortunately, there is no way to add options to the startup message, without breaking compatibility with old servers. If there is an option in the startup message that the server doesn't understand, it will treat it as a GUC, and you get an "unrecognized configuration parameter" after authentication. sasl.mechanisms = 'SCRAM_SHA256' :p No, I'm not seriously suggesting we abuse that. Hmm, that's not such a bad idea, actually. It only goes back to 9.2, though. Before that, the prefix needed to be listed in custom_variable_classes, or you got an error. 9.2 is the oldest supported version, but libpq should still be able to connect to older versions. - Heikki -- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers
Re: [HACKERS] Letting the client choose the protocol to use during a SASL exchange
On 7 April 2017 at 16:33, Heikki Linnakangaswrote: > That list of supported authentication methods would need to be included in > the startup message. Unfortunately, there is no way to add options to the > startup message, without breaking compatibility with old servers. If there > is an option in the startup message that the server doesn't understand, it > will treat it as a GUC, and you get an "unrecognized configuration > parameter" after authentication. sasl.mechanisms = 'SCRAM_SHA256' :p No, I'm not seriously suggesting we abuse that. Personally I think it's reasonable enough to let the server send a 'B' message with supported auth modes. I'm not overly concerned about the small information leak that provides. We're unlikely to be able to convincingly fake execution of any and all SASL auth methods the client may request, and since they may require any arbitrary number of message exchanges we'd basically land up blackholeing clients that try an unsupported auth-method. No thanks. It's one area I'd rather honestly say "nope, we don't support that". In which case the client can easily enough probe for all known methods, and we might as well just tell it up front. This is hardly new. Most servers with neotiable auth, like SMTP, IMAP, etc, have the server supply a list of auth mechs. -- Craig Ringer http://www.2ndQuadrant.com/ PostgreSQL Development, 24x7 Support, Training & Services -- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers
Re: [HACKERS] Letting the client choose the protocol to use during a SASL exchange
On 04/06/2017 11:05 PM, Tom Lane wrote: Perhaps we could turn this around: have the client send (in the connection request packet) a list of auth protocols it thinks it is able to handle. (I'm envisioning this as being more or less fixed for any one version of any one client, since it would basically mean "I have code to do X, Y, or Z".) Then the server can pick one that is allowed by pg_hba.conf, or it can just ignore the list and send what it wants anyway, probably leading to client disconnect. That list of supported authentication methods would need to be included in the startup message. Unfortunately, there is no way to add options to the startup message, without breaking compatibility with old servers. If there is an option in the startup message that the server doesn't understand, it will treat it as a GUC, and you get an "unrecognized configuration parameter" after authentication. It would be nice to change that, so that the server would ignore parameters that it doesn't understand that begin with "optional_" prefix, for example. But it won't help us right now. - Heikki -- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers
Re: [HACKERS] Letting the client choose the protocol to use during a SASL exchange
On 04/06/2017 11:16 PM, Simon Riggs wrote: or it can just ignore the list and send what it wants anyway, probably leading to client disconnect. It would need to follow one of the requested protocols, but mark the request as doomed. Otherwise we'd be revealing information. That's what SCRAM does now. It's not a secret today, what authentication method the server requires. You can't really hide it, anyway, as the client could probe with different lists of supported methods, and see which method the server picks in each case. - Heikki -- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers
Re: [HACKERS] Letting the client choose the protocol to use during a SASL exchange
On Fri, Apr 7, 2017 at 7:29 AM, Simon Riggswrote: > On 6 April 2017 at 16:15, Álvaro Hernández Tortosa wrote: > >> Per the SCRAM RFC, it is the server who advertises and the client who >> picks. > > Yes, but what does the RFC say about how to handle servers with an > pg_hba.conf? > > How and what will we advertise? Did you read the first email of this thread? The RFC says that the protocol implementers are free to do what they want as this is protocol-specific. At least that's what I understand. -- Michael -- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers
Re: [HACKERS] Letting the client choose the protocol to use during a SASL exchange
On 6 April 2017 at 16:15, Álvaro Hernández Tortosawrote: > Per the SCRAM RFC, it is the server who advertises and the client who > picks. Yes, but what does the RFC say about how to handle servers with an pg_hba.conf? How and what will we advertise? -- Simon Riggshttp://www.2ndQuadrant.com/ PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services -- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers
Re: [HACKERS] Letting the client choose the protocol to use during a SASL exchange
On Fri, Apr 7, 2017 at 5:15 AM, Álvaro Hernández Tortosawrote: > I don't see it. The message AuthenticationSASL.String could contain a > CSV of the SCRAM protocols supported. This is specially important to support > channel binding (which is just another protocol name for this matter), which > is the really enhanced security mechanism of SCRAM. Since this message is > sent regardless, and the client replies with PasswordMessage, no extra round > trip is required. However, PasswordMessage needs to also include a field > with the name of the selected protocol (it is the client who picks). Or a > different message would need to be created, but no extra round-trips more > than those required by SCRAM itself (4 messages for SCRAM + 1 extra for the > server to tell the client it needs to use SCRAM). Yes, it seems to me that the list of protocols to send should be done by sendAuthRequest(). Then the client parses the received string, and sends an extra 'p' message with its choice before sending the first SCRAM message. So there is no need for any extra round trips. -- Michael -- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers
Re: [HACKERS] Letting the client choose the protocol to use during a SASL exchange
On 6 April 2017 at 16:05, Tom Lanewrote: > Perhaps we could turn this around: have the client send (in the connection > request packet) a list of auth protocols it thinks it is able to handle. > (I'm envisioning this as being more or less fixed for any one version of > any one client, since it would basically mean "I have code to do X, Y, or > Z".) Then the server can pick one that is allowed by pg_hba.conf, +1 Much better plan. > or it > can just ignore the list and send what it wants anyway, probably leading > to client disconnect. It would need to follow one of the requested protocols, but mark the request as doomed. Otherwise we'd be revealing information. That's what SCRAM does now. Since the list is currently length one, we can add more later when we get a list potentially > 1. > We could avoid this being a protocol break by having the server's default > assumption being that the client can handle all pre-SCRAM auth protocols. +1 -- Simon Riggshttp://www.2ndQuadrant.com/ PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services -- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers
Re: [HACKERS] Letting the client choose the protocol to use during a SASL exchange
On 06/04/17 22:05, Tom Lane wrote: Simon Riggswrites: How would we provide the list of protocols? Surely the protocol is defined by pg_hba.conf, which makes it dependent upon username, database and ip range. If the list were accurate, it would allow an attacker to discover how best to attack. If the list were inaccurate it would just be an annoyance. At minimum, providing the list of protocols means an extra round trip to the server. Yeah, that's a problem. I don't see it. The message AuthenticationSASL.String could contain a CSV of the SCRAM protocols supported. This is specially important to support channel binding (which is just another protocol name for this matter), which is the really enhanced security mechanism of SCRAM. Since this message is sent regardless, and the client replies with PasswordMessage, no extra round trip is required. However, PasswordMessage needs to also include a field with the name of the selected protocol (it is the client who picks). Or a different message would need to be created, but no extra round-trips more than those required by SCRAM itself (4 messages for SCRAM + 1 extra for the server to tell the client it needs to use SCRAM). ISTM that if you have a valid role to connect to then you'll also know what authentication mechanism to use so you should be able to specify the mechanism in your connection message and save the extra trip. I do not buy that in the least. It has never been the case before now that clients know in advance what the auth challenge method will be. If we put that requirement on them for SCRAM, we're just going to be exporting a lot of pain and end-user-visible inconsistency. Perhaps we could turn this around: have the client send (in the connection request packet) a list of auth protocols it thinks it is able to handle. Per the SCRAM RFC, it is the server who advertises and the client who picks. Regards, Álvaro -- Álvaro Hernández Tortosa --- <8K>data -- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers
Re: [HACKERS] Letting the client choose the protocol to use during a SASL exchange
Simon Riggswrites: > How would we provide the list of protocols? Surely the protocol is > defined by pg_hba.conf, which makes it dependent upon username, > database and ip range. If the list were accurate, it would allow an > attacker to discover how best to attack. If the list were inaccurate > it would just be an annoyance. > At minimum, providing the list of protocols means an extra round trip > to the server. Yeah, that's a problem. > ISTM that if you have a valid role to connect to then you'll also know > what authentication mechanism to use so you should be able to specify > the mechanism in your connection message and save the extra trip. I do not buy that in the least. It has never been the case before now that clients know in advance what the auth challenge method will be. If we put that requirement on them for SCRAM, we're just going to be exporting a lot of pain and end-user-visible inconsistency. Perhaps we could turn this around: have the client send (in the connection request packet) a list of auth protocols it thinks it is able to handle. (I'm envisioning this as being more or less fixed for any one version of any one client, since it would basically mean "I have code to do X, Y, or Z".) Then the server can pick one that is allowed by pg_hba.conf, or it can just ignore the list and send what it wants anyway, probably leading to client disconnect. We could avoid this being a protocol break by having the server's default assumption being that the client can handle all pre-SCRAM auth protocols. regards, tom lane -- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers
Re: [HACKERS] Letting the client choose the protocol to use during a SASL exchange
On 4 April 2017 at 02:02, Michael Paquierwrote: > Hi all, > > There is still one open item pending for SCRAM that has not been > treated which is mentioned here: > https://www.postgresql.org/message-id/b081887e-1712-3aa4-7dbe-e012333d5...@iki.fi > > When doing an authentication with SASL, the server decides what is the > mechanism that the client has to use. As SCRAM-SHA-256 is only one of > such mechanisms, it would be nice to have something more generic and > have the server return to the client a list of protocols that the > client can choose from. And also the server achnowledge which protocol > is going to be used. > > Note that RFC4422 has some content on the matter > https://tools.ietf.org/html/rfc4422#section-3.1: >Mechanism negotiation is protocol specific. > >Commonly, a protocol will specify that the server advertises >supported and available mechanisms to the client via some facility >provided by the protocol, and the client will then select the "best" >mechanism from this list that it supports and finds suitable. > > So once the server sends back the list of mechanisms that are > supported, the client is free to use what it wants. > > On HEAD, a 'R' message with AUTH_REQ_SASL followed by > SCRAM_SHA256_NAME is sent to let the client know what is the mechanism > to use for the SASL exchange. In the future, this should be extended > so as a list of names is sent, for example a comma-separated list, but > we are free to choose the format we want here. With this list at hand, > the client can then choose the protocol it thinks is the best. Still, > there is a gap with our current implementation because the server > expects the first message from the client to have a SCRAM format, but > that's true only if SCRAM-SHA-256 is used as mechanism. How would we provide the list of protocols? Surely the protocol is defined by pg_hba.conf, which makes it dependent upon username, database and ip range. If the list were accurate, it would allow an attacker to discover how best to attack. If the list were inaccurate it would just be an annoyance. At minimum, providing the list of protocols means an extra round trip to the server. So while RFC4422 might say what "commonly" happens, I don't think it applies sensibly to PostgreSQL, especially when we only have one method. ISTM that if you have a valid role to connect to then you'll also know what authentication mechanism to use so you should be able to specify the mechanism in your connection message and save the extra trip. > In order to cover this gap, it seems to me that we need to have an > intermediate state before the server is switched to FE_SCRAM_INIT so > as the mechanism used is negotiated between the two parties. Once the > protocol negotiation is done, the server can then move on with the > mechanism to use. This would be important in the future to allow more > SASL mechanisms to work. I am adding an open item for that. So I don't see a gap or an open item on that point. I see a potential future feature. > For extensibility, we may also want to revisit the choice of defining > 'scram' in pg_hba.conf instead of 'sasl'... I'd like to see us replace "scram" with "sasl=scram-sha-256". So when we extend it in future, we already have the syntax in place to support "sasl=newmethod", rather than introduce syntax that we already know will become outdated in future. -- Simon Riggshttp://www.2ndQuadrant.com/ PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services -- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers
[HACKERS] Letting the client choose the protocol to use during a SASL exchange
Hi all, There is still one open item pending for SCRAM that has not been treated which is mentioned here: https://www.postgresql.org/message-id/b081887e-1712-3aa4-7dbe-e012333d5...@iki.fi When doing an authentication with SASL, the server decides what is the mechanism that the client has to use. As SCRAM-SHA-256 is only one of such mechanisms, it would be nice to have something more generic and have the server return to the client a list of protocols that the client can choose from. And also the server achnowledge which protocol is going to be used. Note that RFC4422 has some content on the matter https://tools.ietf.org/html/rfc4422#section-3.1: Mechanism negotiation is protocol specific. Commonly, a protocol will specify that the server advertises supported and available mechanisms to the client via some facility provided by the protocol, and the client will then select the "best" mechanism from this list that it supports and finds suitable. So once the server sends back the list of mechanisms that are supported, the client is free to use what it wants. On HEAD, a 'R' message with AUTH_REQ_SASL followed by SCRAM_SHA256_NAME is sent to let the client know what is the mechanism to use for the SASL exchange. In the future, this should be extended so as a list of names is sent, for example a comma-separated list, but we are free to choose the format we want here. With this list at hand, the client can then choose the protocol it thinks is the best. Still, there is a gap with our current implementation because the server expects the first message from the client to have a SCRAM format, but that's true only if SCRAM-SHA-256 is used as mechanism. In order to cover this gap, it seems to me that we need to have an intermediate state before the server is switched to FE_SCRAM_INIT so as the mechanism used is negotiated between the two parties. Once the protocol negotiation is done, the server can then move on with the mechanism to use. This would be important in the future to allow more SASL mechanisms to work. I am adding an open item for that. For extensibility, we may also want to revisit the choice of defining 'scram' in pg_hba.conf instead of 'sasl'... Thoughts? -- Michael -- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers