From 78c9d261c5ea611dd19c97053201e2fea0c54cb5 Mon Sep 17 00:00:00 2001 From: Michael Paquier Date: Sat, 25 Mar 2017 14:07:16 +0900 Subject: [PATCH 5/5] Extend psql's \password and createuser to handle SCRAM verifier creation Depending on the version of PostgreSQL those utilities are connected to, generate MD5 verifiers when connecting to a server older than 10, and MD5 otherwise. --- doc/src/sgml/ref/createuser.sgml | 6 ++++-- doc/src/sgml/ref/psql-ref.sgml | 4 +++- src/bin/psql/command.c | 9 ++++++++- src/bin/scripts/createuser.c | 16 +++++++++++++--- 4 files changed, 28 insertions(+), 7 deletions(-) diff --git a/doc/src/sgml/ref/createuser.sgml b/doc/src/sgml/ref/createuser.sgml index 4332008c68..4454591d79 100644 --- a/doc/src/sgml/ref/createuser.sgml +++ b/doc/src/sgml/ref/createuser.sgml @@ -125,7 +125,9 @@ PostgreSQL documentation Encrypts the user's password stored in the database. If not - specified, the default password behavior is used. + specified, the default password behavior is used. The password + is hashed using SCRAM-SHA-256 when connecting to a version of + PostgreSQL newer than 10, and MD5 otherwise. @@ -477,7 +479,7 @@ PostgreSQL documentation $ createuser -P -s -e joe Enter password for new role: xyzzy Enter it again: xyzzy -CREATE ROLE joe PASSWORD 'md5b5f5ba1a423792b526f799ae4eb3d59e' SUPERUSER CREATEDB CREATEROLE INHERIT LOGIN; +CREATE ROLE joe PASSWORD 'scram-sha-256:aPheg4yCAFhStg==:4096:TOHLPF8w+NzqtcxD2oz9w5wPISutHLOXWMKoe4HCvuo=:lTG0OiB/ZH5/hsfUqnndRwfMziY5j5C6FS8IAIwL2nA=' SUPERUSER CREATEDB CREATEROLE INHERIT LOGIN; In the above example, the new password isn't actually echoed when typed, but we show what was typed for clarity. As you see, the password is diff --git a/doc/src/sgml/ref/psql-ref.sgml b/doc/src/sgml/ref/psql-ref.sgml index 3b86612862..749221aa76 100644 --- a/doc/src/sgml/ref/psql-ref.sgml +++ b/doc/src/sgml/ref/psql-ref.sgml @@ -2380,7 +2380,9 @@ lo_import 152801 user). This command prompts for the new password, encrypts it, and sends it to the server as an ALTER ROLE command. This makes sure that the new password does not appear in cleartext in the - command history, the server log, or elsewhere. + command history, the server log, or elsewhere. The password is hashed + with SCRAM-SHA-256 when connecting to PostgreSQL 10 + and newer versions, and with MD5 otherwise. diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c index 9716c98fc2..4e9b526e43 100644 --- a/src/bin/psql/command.c +++ b/src/bin/psql/command.c @@ -1882,7 +1882,14 @@ exec_command_password(PsqlScanState scan_state, bool active_branch) else user = PQuser(pset.db); - encrypted_password = PQencryptPassword(pw1, user, "md5"); + /* + * Hash password using SCRAM-SHA-256 when connecting to servers + * newer than Postgres 10, and hash with MD5 otherwise. + */ + if (pset.sversion < 100000) + encrypted_password = PQencryptPassword(pw1, user, "md5"); + else + encrypted_password = PQencryptPassword(pw1, user, "scram"); if (!encrypted_password) { diff --git a/src/bin/scripts/createuser.c b/src/bin/scripts/createuser.c index 5af263e34a..0107497e23 100644 --- a/src/bin/scripts/createuser.c +++ b/src/bin/scripts/createuser.c @@ -274,9 +274,19 @@ main(int argc, char *argv[]) { char *encrypted_password; - encrypted_password = PQencryptPassword(newpassword, - newuser, - "md5"); + /* + * Hash password using SCRAM-SHA-256 when connecting to servers + * newer than Postgres 10, and hash with MD5 otherwise. + */ + if (PQserverVersion(conn) < 100000) + encrypted_password = PQencryptPassword(newpassword, + newuser, + "md5"); + else + encrypted_password = PQencryptPassword(newpassword, + newuser, + "scram"); + if (!encrypted_password) { fprintf(stderr, _("Password encryption failed.\n")); -- 2.12.2