Re: pg_authid.rolpassword format (was Re: Password identifiers, protocol aging and SCRAM protocol)
Heikki Linnakangas <hlinnaka@iki.fi>
From: Heikki Linnakangas <hlinnaka@iki.fi>
To: Michael Paquier <michael.paquier@gmail.com>
Cc: Magnus Hagander <magnus@hagander.net>, 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>,
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-20T12:23:51Z
Lists: pgsql-hackers
Attachments
- 0001-Use-plain-prefix-for-plaintext-passwords-stored-in-p-2.patch (invalid/octet-stream)
On 12/16/2016 03:31 AM, Michael Paquier wrote:
> On Thu, Dec 15, 2016 at 9:48 PM, Heikki Linnakangas <hlinnaka@iki.fi> wrote:
>> The only way to distinguish, is to know about every verifier kind there is,
>> and check whether rolpassword looks valid as anything else than a plaintext
>> password. And we already got tripped by a bug-of-omission on that once. If
>> we add more verifier formats in the future, it's bound to happen again.
>> Let's nip that source of bugs in the bud. Attached is a patch to implement
>> what I have in mind.
>
> OK, I had a look at the patch proposed.
>
> - if (!pg_md5_encrypt(username, username, namelen, encrypted))
> - elog(ERROR, "password encryption failed");
> - if (strcmp(password, encrypted) == 0)
> - ereport(ERROR,
> - (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
> - errmsg("password must not contain user name")));
>
> This patch removes the only possible check for MD5 hashes that it has
> never been done in passwordcheck. It may be fine to remove it, but I would
> think that it is a good source of example regarding what could be done with
> MD5 hashes, though limited. So it seems to me that this check should involve
> as well pg_md5_encrypt on the username and compare if with the MD5 hash
> given by the caller.
Actually, it does still perform that check. There's a new function,
plain_crypt_verify, that passwordcheck uses now. plain_crypt_verify() is
intended to work with any future hash formats we might introduce in the
future (including SCRAM), so that passwordcheck doesn't need to know
about all the hash formats.
> A simple ALTER USER role PASSWORD 'foo' causes a crash:
Ah, fixed.
> + case PASSWORD_TYPE_PLAINTEXT:
> + shadow_pass = &shadow_pass[strlen("plain:")];
> + break;
> It would be a good idea to have a generic routine able to get the plain
> password value. In short I think that we should reduce the amount of
> locations where "plain:" prefix is hardcoded.
There is such a function included in the patch, get_plain_password(char
*shadow_pass), actually. Contrib/passwordcheck uses it. I figured that
in crypt.c itself, it's OK to do the above directly, but
get_plain_password() is intended to be used elsewhere.
Thanks for having a look! Attached is a new version, with that bug fixed.
- Heikki
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