1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-28 23:42:10 +03:00

Allow SCRAM authentication, when pg_hba.conf says 'md5'.

If a user has a SCRAM verifier in pg_authid.rolpassword, there's no reason
we cannot attempt to perform SCRAM authentication instead of MD5. The worst
that can happen is that the client doesn't support SCRAM, and the
authentication will fail. But previously, it would fail for sure, because
we would not even try. SCRAM is strictly more secure than MD5, so there's
no harm in trying it. This allows for a more graceful transition from MD5
passwords to SCRAM, as user passwords can be changed to SCRAM verifiers
incrementally, without changing pg_hba.conf.

Refactor the code in auth.c to support that better. Notably, we now have to
look up the user's pg_authid entry before sending the password challenge,
also when performing MD5 authentication. Also simplify the concept of a
"doomed" authentication. Previously, if a user had a password, but it had
expired, we still performed SCRAM authentication (but always returned error
at the end) using the salt and iteration count from the expired password.
Now we construct a fake salt, like we do when the user doesn't have a
password or doesn't exist at all. That simplifies get_role_password(), and
we can don't need to distinguish the  "user has expired password", and
"user does not exist" cases in auth.c.

On second thoughts, also rename uaSASL to uaSCRAM. It refers to the
mechanism specified in pg_hba.conf, and while we use SASL for SCRAM
authentication at the protocol level, the mechanism should be called SCRAM,
not SASL. As a comparison, we have uaLDAP, even though it looks like the
plain 'password' authentication at the protocol level.

Discussion: https://www.postgresql.org/message-id/6425.1489506016@sss.pgh.pa.us
Reviewed-by: Michael Paquier
This commit is contained in:
Heikki Linnakangas
2017-03-24 13:32:21 +02:00
parent 78874531ba
commit 7ac955b347
9 changed files with 221 additions and 172 deletions

View File

@ -412,23 +412,22 @@ hostnossl <replaceable>database</replaceable> <replaceable>user</replaceable>
</varlistentry>
<varlistentry>
<term><literal>md5</></term>
<term><literal>scram</></term>
<listitem>
<para>
Require the client to supply a double-MD5-hashed password for
authentication.
See <xref linkend="auth-password"> for details.
Perform SCRAM-SHA-256 authentication to verify the user's
password. See <xref linkend="auth-password"> for details.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>scram</></term>
<term><literal>md5</></term>
<listitem>
<para>
Perform SCRAM-SHA-256 authentication to verify the user's
password.
See <xref linkend="auth-password"> for details.
Perform SCRAM-SHA-256 or MD5 authentication to verify the
user's password. See <xref linkend="auth-password">
for details.
</para>
</listitem>
</varlistentry>
@ -689,13 +688,12 @@ host postgres all 192.168.12.10/32 scram
# 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.
# Require SCRAM authentication for most users, but make an exception
# for user 'mike', who uses an older client that doesn't support SCRAM
# authentication.
#
# TYPE DATABASE USER ADDRESS METHOD
host all @md5users .example.com md5
host all mike .example.com md5
host all all .example.com scram
# In the absence of preceding "host" lines, these two lines will
@ -949,12 +947,13 @@ omicron bryanh guest1
</para>
<para>
In <literal>md5</>, the client sends a hash of a random challenge,
generated by the server, and the password. It prevents password sniffing,
but is less secure than <literal>scram</>, and provides no protection
if an attacker manages to steal the password hash from the server.
<literal>md5</> cannot be used with the <xref
linkend="guc-db-user-namespace"> feature.
<literal>md5</> allows falling back to a less secure challenge-response
mechanism for those users with an MD5 hashed password.
The fallback mechanism also prevents password sniffing, but provides no
protection if an attacker manages to steal the password hash from the
server, and it cannot be used with the <xref
linkend="guc-db-user-namespace"> feature. For all other users,
<literal>md5</> works the same as <literal>scram</>.
</para>
<para>