Re: Password identifiers, protocol aging and SCRAM protocol
От | Heikki Linnakangas |
---|---|
Тема | Re: Password identifiers, protocol aging and SCRAM protocol |
Дата | |
Msg-id | 21eecdb8-365b-8347-1ae2-5278d1fe798c@iki.fi обсуждение исходный текст |
Ответ на | Re: Password identifiers, protocol aging and SCRAM protocol (Michael Paquier <michael.paquier@gmail.com>) |
Ответы |
Re: Password identifiers, protocol aging and SCRAM protocol
(Michael Paquier <michael.paquier@gmail.com>)
|
Список | pgsql-hackers |
On 12/08/2016 10:18 AM, Michael Paquier wrote: > On Thu, Dec 8, 2016 at 5:54 AM, Heikki Linnakangas <hlinnaka@iki.fi> wrote: >> Attached those here, as add-on patches to your latest patch set. > > Thanks for looking at it! > >> I'll continue reviewing, but a couple of things caught my eye that you may want >> to jump on, in the meanwhile: >> >> On error messages, the spec says: >> >>> o e: This attribute specifies an error that occurred during >>> authentication exchange. It is sent by the server in its final >>> message and can help diagnose the reason for the authentication >>> exchange failure. On failed authentication, the entire server- >>> final-message is OPTIONAL; specifically, a server implementation >>> MAY conclude the SASL exchange with a failure without sending the >>> server-final-message. This results in an application-level error >>> response without an extra round-trip. If the server-final-message >>> is sent on authentication failure, then the "e" attribute MUST be >>> included. >> >> >> Note that it says that the server can send the error message with the e= >> attribute, in the *final message*. It's not a valid response in the earlier >> state, before sending server-first-message. I think we need to change the >> INIT state handling in pg_be_scram_exchange() to not send e= messages to the >> client. On an error at that state, it needs to just bail out without a >> message. The spec allows that. We can always log the detailed reason in the >> server log, anyway. > > Hmmm. How do we handle the case where the user name does not match > then? The spec gives an error message e= specifically for this case. Hmm, interesting. I wonder how/when they imagine that error message to be used. I suppose you could send a dummy server-first message, with a made-up salt and iteration count, if the user is not found, so that you can report that in the server-final message. But that seems unnecessarily complicated, compared to just sending the error immediately. I could imagine using a dummy server-first messaage to hide whether the user exists, but that argument doesn't hold water if you're going to report an "unknown-user" error, anyway. Actually, we don't give away that information currently. If you try to log in with password or MD5 authentication, and the user doesn't exist, you get the same error as with an incorrect password. So, I think we do need to give the client a made-up salt and iteration count in that case, to hide the fact that the user doesn't exist. Furthermore, you can't just generate random salt and iteration count, because then you could simply try connecting twice, and see if you get the same salt and iteration count. We need to deterministically derive the salt from the username, so that you get the same salt/iteration count every time you try connecting with that username. But it needs indistinguishable from a random salt, to the client. Perhaps a SHA hash of the username and some per-cluster secret value, created by initdb. There must be research papers out there on how to do this.. To be really pedantic about that, we should also ward off timing attacks, by making sure that the dummy authentication is no faster/slower than a real one.. > If this is taken into account we need to perform sanity checks at > initialization phase I am afraid as the number of iterations and the > salt are part of the verifier. So you mean that just sending out a > normal ERROR message is fine at an earlier step (with *logdetails > filled for the backend)? I just want to be sure I understand what you > mean here. That's right, we can send a normal ERROR message. (But not for the "user-not-found" case, as discussed above.) >> As Peter E pointed out earlier, the documentation is lacking, on how to >> configure MD5 and/or SCRAM. If you put "scram" as the authentication method >> in pg_hba.conf, what does it mean? If you have a line for both "scram" and >> "md5" in pg_hba.conf, with the same database/user/hostname combo, what does >> that mean? Answer: The first one takes effect, the second one has no effect. >> Yet the example in the docs now has that, which is nonsense :-). Hopefully >> we'll have some kind of a "both" option, before the release, but in the >> meanwhile, we need describe how this works now in the docs. > > OK, it would be better to add a paragraph in client-auth.sgml > regarding the mapping of the two settings. For the example of file in > postgresql.conf, I would have really thought that adding directly a > line with "scram" listed was enough though. Perhaps a comment to say > that if md5 and scram are specified the first one wins where a user > and database name map? So, I think this makes no sense: > # Allow any user from host 192.168.12.10 to connect to database > -# "postgres" if the user's password is correctly supplied. > +# "postgres" if the user's password is correctly supplied and is > +# using the correct password method. > # > # TYPE DATABASE USER ADDRESS METHOD > host postgres all 192.168.12.10/32 md5 > +host postgres all 192.168.12.10/32 scram But this is OK: > +# Same as previous entry, except that the supplied password must be > +# encrypted with SCRAM-SHA-256. > +host all all .example.com scram > + Although, currently, the whole pg_hba.conf file in that example is a valid file that someone might have on a real server. With the above addition, it would not be. You would never have the two lines with the same host/database/user combination in pg_hba.conf. Overall, I think something like this would make sense in the example: # Allow any user from hosts in the example.com domain to connect to # any database, if the user's password is correctly supplied. # # Most users use SCRAM authentication, but some users use older clients # that don't support SCRAM authentication, and need to be able to log # in using MD5 authentication. Such users are put in the @md5users # group, everyone else must use SCRAM. # # TYPE DATABASE USER ADDRESS METHOD host all @md5users .example.com md5 host all all .example.com scram - Heikki
В списке pgsql-hackers по дате отправления: