Re: Password identifiers, protocol aging and SCRAM protocol
Michael Paquier <michael.paquier@gmail.com>
From: Michael Paquier <michael.paquier@gmail.com>
To: Heikki Linnakangas <hlinnaka@iki.fi>
Cc: Robert Haas <robertmhaas@gmail.com>, Andres Freund <andres@anarazel.de>, Peter Eisentraut <peter.eisentraut@2ndquadrant.com>,
David Steele <david@pgmasters.net>, Tom Lane <tgl@sss.pgh.pa.us>, David Fetter <david@fetter.org>, Alvaro Herrera <alvherre@2ndquadrant.com>,
Magnus Hagander <magnus@hagander.net>, Julian Markwort <julian.markwort@uni-muenster.de>,
Stephen Frost <sfrost@snowman.net>, PostgreSQL mailing lists <pgsql-hackers@postgresql.org>,
Valery Popov <v.popov@postgrespro.ru>
Date: 2016-12-08T13:05:27Z
Lists: pgsql-hackers
On Thu, Dec 8, 2016 at 5:55 PM, Heikki Linnakangas <hlinnaka@iki.fi> wrote: > On 12/08/2016 10:18 AM, Michael Paquier wrote: >> 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. Using directly an error message would map with MD5 and plain, but that's definitely a new protocol piece so I'd rather think that using e= once the client has sent its first message in the exchange should be answered with an appropriate SASL error... > 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.. A simple idea would be to use the system ID when generating this fake salt? That's generated by initdb, once per cluster. I am wondering if it would be risky to use it for the salt. For the number of iterations the default number could be used. > 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.. There is one catalog lookup when extracting the verifier from pg_authid, I'd guess that if we generate a fake verifier things should get pretty close. >> 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.) I'd think that the cases where the password is empty and the password has passed valid duration should be returned with e=other-error. If the caller sends a SCRAM request that would be impolite (?) to just throw up an error once the exchange has begun. > 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. Okay. -- Michael
Commits
-
Support SCRAM-SHA-256 authentication (RFC 5802 and 7677).
- 818fd4a67d61 10.0 landed
-
Refactor SHA2 functions and move them to src/common/.
- 273c458a2b3a 10.0 landed
-
Replace isMD5() with a more future-proof way to check if pw is encrypted.
- dbd69118c05d 10.0 landed
-
Remove bogus notice that older clients might not work with MD5 passwords.
- 7e3ae5455948 9.2.20 landed
- 470af1f41c8b 9.3.16 landed
- ada2cdb61015 9.4.11 landed
- 65a7f190b253 9.5.6 landed
- 7546c135dc30 9.6.2 landed
- 31c54096a18f 10.0 landed
-
Refactor the code for verifying user's password.
- e7f051b8f9a6 10.0 landed
-
Replace PostmasterRandom() with a stronger source, second attempt.
- fe0a0b5993df 10.0 landed
-
Remove support for (insecure) crypt authentication.
- 53a5026b5cb3 8.4.0 cited