Rename "scram" to "scram-sha-256" in pg_hba.conf and password_encryption.
authorHeikki Linnakangas
Tue, 18 Apr 2017 11:50:50 +0000 (14:50 +0300)
committerHeikki Linnakangas
Tue, 18 Apr 2017 11:50:50 +0000 (14:50 +0300)
Per discussion, plain "scram" is confusing because we actually implement
SCRAM-SHA-256 rather than the original SCRAM that uses SHA-1 as the hash
algorithm. If we add support for SCRAM-SHA-512 or some other mechanism in
the SCRAM family in the future, that would become even more confusing.

Most of the internal files and functions still use just "scram" as a
shorthand for SCRMA-SHA-256, but I did change PASSWORD_TYPE_SCRAM to
PASSWORD_TYPE_SCRAM_SHA_256, as that could potentially be used by 3rd
party extensions that hook into the password-check hook.

Michael Paquier did this in an earlier version of the SCRAM patch set
already, but I didn't include that in the version that was committed.

Discussion: https://www.postgresql.org/message-id/fde71ff1-5858-90c8-99a9-1c2427e7bafb@iki.fi

15 files changed:
doc/src/sgml/client-auth.sgml
doc/src/sgml/config.sgml
src/backend/commands/user.c
src/backend/libpq/auth-scram.c
src/backend/libpq/auth.c
src/backend/libpq/crypt.c
src/backend/libpq/hba.c
src/backend/libpq/pg_hba.conf.sample
src/backend/utils/misc/guc.c
src/bin/initdb/initdb.c
src/include/libpq/crypt.h
src/test/authentication/t/001_password.pl
src/test/authentication/t/002_saslprep.pl
src/test/regress/expected/password.out
src/test/regress/sql/password.sql

index d871c041ce5fe8389f74a2b40ae335b0c18c25d5..819db811b26a684d1b9d124842e56d783ce3af83 100644 (file)
@@ -412,7 +412,7 @@ hostnossl  database  user
        
 
        
-        scram
+        scram-sha-256
         
          
           Perform SCRAM-SHA-256 authentication to verify the user's
@@ -683,7 +683,7 @@ host    postgres        all             192.168.93.0/24         ident
 # "postgres" if the user's password is correctly supplied.
 #
 # TYPE  DATABASE        USER            ADDRESS                 METHOD
-host    postgres        all             192.168.12.10/32        scram
+host    postgres        all             192.168.12.10/32        scram-sha-256
 
 # Allow any user from hosts in the example.com domain to connect to
 # any database if the user's password is correctly supplied.
@@ -694,7 +694,7 @@ host    postgres        all             192.168.12.10/32        scram
 #
 # TYPE  DATABASE        USER            ADDRESS                 METHOD
 host    all             mike            .example.com            md5
-host    all             all             .example.com            scram
+host    all             all             .example.com            scram-sha-256
 
 # In the absence of preceding "host" lines, these two lines will
 # reject all connections from 192.168.54.1 (since that entry will be
@@ -922,7 +922,7 @@ omicron         bryanh                  guest1
    
 
    
-    The password-based authentication methods are scram,
+    The password-based authentication methods are scram-sha-256,
     md5, and password. These methods operate
     similarly except for the way that the password is sent across the
     connection.
@@ -939,8 +939,9 @@ omicron         bryanh                  guest1
 
 
    
-    scram performs SCRAM-SHA-256 authentication, as described
-    in RFC5802. It
+    scram-sha-256 performs SCRAM-SHA-256 authentication, as
+    described in
+    RFC5802. It
     is a challenge-response scheme, that prevents password sniffing on
     untrusted connections. It is more secure than the md5
     method, but might not be supported by older clients.
@@ -953,7 +954,7 @@ omicron         bryanh                  guest1
     protection if an attacker manages to steal the password hash from the
     server, and it cannot be used with the 
     linkend="guc-db-user-namespace"> feature. For all other users,
-    md5 works the same as scram.
+    md5 works the same as scram-sha-256.
    
 
    
index 744c5e8f37ac942d368c20353b97be62af2fee8d..e02b0c80df0e824f2e65e332ffde54d08a560538 100644 (file)
@@ -1194,8 +1194,8 @@ include_dir 'conf.d'
         stores the password as an MD5 hash. Setting this to plain stores
         it in plaintext. on and off are also accepted, as
         aliases for md5 and plain, respectively.  Setting
-        this parameter to scram will encrypt the password with
-        SCRAM-SHA-256.
+        this parameter to scram-sha-256 will encrypt the password
+        with SCRAM-SHA-256.
        
       
      
index de264974ae8af4c86056c8787463c0b6fabc21df..c719682274dff70079f6b6357ba1d5ee5155bc13 100644 (file)
@@ -140,8 +140,8 @@ CreateRole(ParseState *pstate, CreateRoleStmt *stmt)
            dpassword = defel;
            if (strcmp(defel->defname, "encryptedPassword") == 0)
            {
-               if (Password_encryption == PASSWORD_TYPE_SCRAM)
-                   password_type = PASSWORD_TYPE_SCRAM;
+               if (Password_encryption == PASSWORD_TYPE_SCRAM_SHA_256)
+                   password_type = PASSWORD_TYPE_SCRAM_SHA_256;
                else
                    password_type = PASSWORD_TYPE_MD5;
            }
@@ -548,8 +548,8 @@ AlterRole(AlterRoleStmt *stmt)
            dpassword = defel;
            if (strcmp(defel->defname, "encryptedPassword") == 0)
            {
-               if (Password_encryption == PASSWORD_TYPE_SCRAM)
-                   password_type = PASSWORD_TYPE_SCRAM;
+               if (Password_encryption == PASSWORD_TYPE_SCRAM_SHA_256)
+                   password_type = PASSWORD_TYPE_SCRAM_SHA_256;
                else
                    password_type = PASSWORD_TYPE_MD5;
            }
index 338afede9dec2a1813c31dc9f20beb51e60647e6..76c502d415da62d67c416a84312bcb1dc550b087 100644 (file)
@@ -183,7 +183,7 @@ pg_be_scram_init(const char *username, const char *shadow_pass)
    {
        int         password_type = get_password_type(shadow_pass);
 
-       if (password_type == PASSWORD_TYPE_SCRAM)
+       if (password_type == PASSWORD_TYPE_SCRAM_SHA_256)
        {
            if (parse_scram_verifier(shadow_pass, &state->salt, &state->iterations,
                                     state->StoredKey, state->ServerKey))
index 848561e188e7d8ef1c90f8df07fc7893c9778e4e..ab4be21943121eac599f99cd43343b586692382f 100644 (file)
@@ -50,7 +50,7 @@ static char *recv_password_packet(Port *port);
 
 
 /*----------------------------------------------------------------
- * Password-based authentication methods (password, md5, and scram)
+ * Password-based authentication methods (password, md5, and scram-sha-256)
  *----------------------------------------------------------------
  */
 static int CheckPasswordAuth(Port *port, char **logdetail);
@@ -757,10 +757,10 @@ CheckPWChallengeAuth(Port *port, char **logdetail)
     * If the user does not exist, or has no password, we still go through the
     * motions of authentication, to avoid revealing to the client that the
     * user didn't exist.  If 'md5' is allowed, we choose whether to use 'md5'
-    * or 'scram' authentication based on current password_encryption setting.
-    * The idea is that most genuine users probably have a password of that
-    * type, if we pretend that this user had a password of that type, too, it
-    * "blends in" best.
+    * or 'scram-sha-256' authentication based on current password_encryption
+    * setting.  The idea is that most genuine users probably have a password
+    * of that type, if we pretend that this user had a password of that type,
+    * too, it "blends in" best.
     *
     * If the user had a password, but it was expired, we'll use the details
     * of the expired password for the authentication, but report it as
@@ -773,9 +773,9 @@ CheckPWChallengeAuth(Port *port, char **logdetail)
 
    /*
     * If 'md5' authentication is allowed, decide whether to perform 'md5' or
-    * 'scram' authentication based on the type of password the user has.  If
-    * it's an MD5 hash, we must do MD5 authentication, and if it's a SCRAM
-    * verifier, we must do SCRAM authentication.  If it's stored in
+    * 'scram-sha-256' authentication based on the type of password the user
+    * has.  If it's an MD5 hash, we must do MD5 authentication, and if it's
+    * a SCRAM verifier, we must do SCRAM authentication.  If it's stored in
     * plaintext, we could do either one, so we opt for the more secure
     * mechanism, SCRAM.
     *
index 34beab53342036321883c9afc46fd556d65acb36..03ef3cc65228646c7b5d25b2f40ade1f971ead60 100644 (file)
@@ -101,7 +101,7 @@ get_password_type(const char *shadow_pass)
    if (strncmp(shadow_pass, "md5", 3) == 0 && strlen(shadow_pass) == MD5_PASSWD_LEN)
        return PASSWORD_TYPE_MD5;
    if (strncmp(shadow_pass, "scram-sha-256:", strlen("scram-sha-256:")) == 0)
-       return PASSWORD_TYPE_SCRAM;
+       return PASSWORD_TYPE_SCRAM_SHA_256;
    return PASSWORD_TYPE_PLAINTEXT;
 }
 
@@ -141,7 +141,7 @@ encrypt_password(PasswordType target_type, const char *role,
                        elog(ERROR, "password encryption failed");
                    return encrypted_password;
 
-               case PASSWORD_TYPE_SCRAM:
+               case PASSWORD_TYPE_SCRAM_SHA_256:
 
                    /*
                     * cannot convert a SCRAM verifier to an MD5 hash, so fall
@@ -152,7 +152,7 @@ encrypt_password(PasswordType target_type, const char *role,
            }
            break;
 
-       case PASSWORD_TYPE_SCRAM:
+       case PASSWORD_TYPE_SCRAM_SHA_256:
            switch (guessed_type)
            {
                case PASSWORD_TYPE_PLAINTEXT:
@@ -164,7 +164,7 @@ encrypt_password(PasswordType target_type, const char *role,
                     * cannot convert an MD5 hash to a SCRAM verifier, so fall
                     * through to save the MD5 hash instead.
                     */
-               case PASSWORD_TYPE_SCRAM:
+               case PASSWORD_TYPE_SCRAM_SHA_256:
                    return pstrdup(password);
            }
            break;
@@ -280,7 +280,7 @@ plain_crypt_verify(const char *role, const char *shadow_pass,
     */
    switch (get_password_type(shadow_pass))
    {
-       case PASSWORD_TYPE_SCRAM:
+       case PASSWORD_TYPE_SCRAM_SHA_256:
            if (scram_verify_plain_password(role,
                                            client_pass,
                                            shadow_pass))
index af89fe898a609759c0cc1247701cbc6376b71a54..5561c399da4643dc3ac7e5e21b1f366f882d602c 100644 (file)
@@ -126,7 +126,7 @@ static const char *const UserAuthName[] =
    "ident",
    "password",
    "md5",
-   "scram",
+   "scram-sha256",
    "gss",
    "sspi",
    "pam",
@@ -1327,7 +1327,7 @@ parse_hba_line(TokenizedLine *tok_line, int elevel)
        }
        parsedline->auth_method = uaMD5;
    }
-   else if (strcmp(token->string, "scram") == 0)
+   else if (strcmp(token->string, "scram-sha-256") == 0)
        parsedline->auth_method = uaSCRAM;
    else if (strcmp(token->string, "pam") == 0)
 #ifdef USE_PAM
index 6b1778a72136edf52cea56f2ab088b9449df9a48..c853e362329e41db0ef74ae0484891aa65b6ea51 100644 (file)
 # or "samenet" to match any address in any subnet that the server is
 # directly connected to.
 #
-# METHOD can be "trust", "reject", "md5", "password", "scram", "gss",
-# "sspi", "ident", "peer", "pam", "ldap", "radius" or "cert".  Note that
-# "password" sends passwords in clear text; "md5" or "scram" are preferred
-# since they send encrypted passwords.
+# METHOD can be "trust", "reject", "md5", "password", "scram-sha-256",
+# "gss", "sspi", "ident", "peer", "pam", "ldap", "radius" or "cert".
+# Note that "password" sends passwords in clear text; "md5" or
+# "scram-sha-256" are preferred since they send encrypted passwords.
 #
 # OPTIONS are a set of options for the authentication in the format
 # NAME=VALUE.  The available options depend on the different
index 9ad8361a9bd6a81bd2ea82c35992946b932528a1..a414fb2c767d98eb55aea3cf8e59712f77187419 100644 (file)
@@ -410,7 +410,7 @@ static const struct config_enum_entry force_parallel_mode_options[] = {
 static const struct config_enum_entry password_encryption_options[] = {
    {"plain", PASSWORD_TYPE_PLAINTEXT, false},
    {"md5", PASSWORD_TYPE_MD5, false},
-   {"scram", PASSWORD_TYPE_SCRAM, false},
+   {"scram-sha-256", PASSWORD_TYPE_SCRAM_SHA_256, false},
    {"off", PASSWORD_TYPE_PLAINTEXT, false},
    {"on", PASSWORD_TYPE_MD5, false},
    {"true", PASSWORD_TYPE_MD5, true},
index d40ed412fc7bb82f6c4caaf5ec08c10cfa2f5b9c..95da8b7722ce47e2348131feeddfa4330edc81d3 100644 (file)
@@ -77,7 +77,7 @@
 extern const char *select_default_timezone(const char *share_path);
 
 static const char *const auth_methods_host[] = {
-   "trust", "reject", "md5", "password", "scram", "ident", "radius",
+   "trust", "reject", "scram-sha-256", "md5", "password", "ident", "radius",
 #ifdef ENABLE_GSS
    "gss",
 #endif
@@ -99,7 +99,7 @@ static const char *const auth_methods_host[] = {
    NULL
 };
 static const char *const auth_methods_local[] = {
-   "trust", "reject", "md5", "scram", "password", "peer", "radius",
+   "trust", "reject", "scram-sha-256", "md5", "password", "peer", "radius",
 #ifdef USE_PAM
    "pam", "pam ",
 #endif
@@ -1130,12 +1130,12 @@ setup_config(void)
                              "#update_process_title = off");
 #endif
 
-   if (strcmp(authmethodlocal, "scram") == 0 ||
-       strcmp(authmethodhost, "scram") == 0)
+   if (strcmp(authmethodlocal, "scram-sha-256") == 0 ||
+       strcmp(authmethodhost, "scram-sha-256") == 0)
    {
        conflines = replace_token(conflines,
                                  "#password_encryption = md5",
-                                 "password_encryption = scram");
+                                 "password_encryption = scram-sha-256");
    }
 
    snprintf(path, sizeof(path), "%s/postgresql.conf", pg_data);
@@ -2329,16 +2329,16 @@ check_need_password(const char *authmethodlocal, const char *authmethodhost)
 {
    if ((strcmp(authmethodlocal, "md5") == 0 ||
         strcmp(authmethodlocal, "password") == 0 ||
-        strcmp(authmethodlocal, "scram") == 0) &&
+        strcmp(authmethodlocal, "scram-sha-256") == 0) &&
        (strcmp(authmethodhost, "md5") == 0 ||
         strcmp(authmethodhost, "password") == 0 ||
-        strcmp(authmethodhost, "scram") == 0) &&
+        strcmp(authmethodhost, "scram-sha-256") == 0) &&
        !(pwprompt || pwfilename))
    {
        fprintf(stderr, _("%s: must specify a password for the superuser to enable %s authentication\n"), progname,
                (strcmp(authmethodlocal, "md5") == 0 ||
                 strcmp(authmethodlocal, "password") == 0 ||
-                strcmp(authmethodlocal, "scram") == 0)
+                strcmp(authmethodlocal, "scram-sha-256") == 0)
                ? authmethodlocal
                : authmethodhost);
        exit(1);
index 3b5da69b08764713aff410703962b9c249f22105..63724f39ee2044f916f3ad6e81295c88ee59493a 100644 (file)
@@ -25,7 +25,7 @@ typedef enum PasswordType
 {
    PASSWORD_TYPE_PLAINTEXT = 0,
    PASSWORD_TYPE_MD5,
-   PASSWORD_TYPE_SCRAM
+   PASSWORD_TYPE_SCRAM_SHA_256
 } PasswordType;
 
 extern PasswordType get_password_type(const char *shadow_pass);
index d7bc13bd58e5cea6d048ce9f97deb966012c4934..216bdc031c81c9e46c246a60f8885fb9e6ef749a 100644 (file)
@@ -51,7 +51,7 @@ SKIP:
 
    # Create 3 roles with different password methods for each one. The same
    # password is used for all of them.
-   $node->safe_psql('postgres', "SET password_encryption='scram'; CREATE ROLE scram_role LOGIN PASSWORD 'pass';");
+   $node->safe_psql('postgres', "SET password_encryption='scram-sha-256'; CREATE ROLE scram_role LOGIN PASSWORD 'pass';");
    $node->safe_psql('postgres', "SET password_encryption='md5'; CREATE ROLE md5_role LOGIN PASSWORD 'pass';");
    $node->safe_psql('postgres', "SET password_encryption='plain'; CREATE ROLE plain_role LOGIN PASSWORD 'pass';");
    $ENV{"PGPASSWORD"} = 'pass';
@@ -68,12 +68,12 @@ SKIP:
    test_role($node, 'md5_role', 'password', 0);
    test_role($node, 'plain_role', 'password', 0);
 
-   # For "scram" method, user "plain_role" and "scram_role" should be able to
-   # connect.
-   reset_pg_hba($node, 'scram');
-   test_role($node, 'scram_role', 'scram', 0);
-   test_role($node, 'md5_role', 'scram', 2);
-   test_role($node, 'plain_role', 'scram', 0);
+   # For "scram-sha-256" method, user "plain_role" and "scram_role" should
+   # be able to connect.
+   reset_pg_hba($node, 'scram-sha-256');
+   test_role($node, 'scram_role', 'scram-sha-256', 0);
+   test_role($node, 'md5_role', 'scram-sha-256', 2);
+   test_role($node, 'plain_role', 'scram-sha-256', 0);
 
    # For "md5" method, all users should be able to connect (SCRAM
    # authentication will be performed for the user with a scram verifier.)
index 7e373ed7bf4ca0ad3f713bef9aa6178bfb49f3cf..67ba92cdd9b3e2bcef371fdb97ac8785fbb37af8 100644 (file)
@@ -63,7 +63,7 @@ SKIP:
 
    # Create test roles.
    $node->safe_psql('postgres',
-"SET password_encryption='scram';
+"SET password_encryption='scram-sha-256';
  SET client_encoding='utf8';
  CREATE ROLE saslpreptest1_role LOGIN PASSWORD 'IX';
  CREATE ROLE saslpreptest4a_role LOGIN PASSWORD 'a';
@@ -73,7 +73,7 @@ SKIP:
 ");
 
    # Require password from now on.
-   reset_pg_hba($node, 'scram');
+   reset_pg_hba($node, 'scram-sha-256');
 
    # Check that #1 and #5 are treated the same as just 'IX'
    test_login($node, 'saslpreptest1_role', "I\xc2\xadX", 0);
index c503e43abeb3d31523f5c6af7dba7423a5db39f5..676b3e6ff3f75b63ad4c51a19ec49a68fa895c49 100644 (file)
@@ -4,11 +4,11 @@
 -- Tests for GUC password_encryption
 SET password_encryption = 'novalue'; -- error
 ERROR:  invalid value for parameter "password_encryption": "novalue"
-HINT:  Available values: plain, md5, scram, off, on.
+HINT:  Available values: plain, md5, scram-sha-256, off, on.
 SET password_encryption = true; -- ok
 SET password_encryption = 'md5'; -- ok
 SET password_encryption = 'plain'; -- ok
-SET password_encryption = 'scram'; -- ok
+SET password_encryption = 'scram-sha-256'; -- ok
 -- consistency of password entries
 SET password_encryption = 'plain';
 CREATE ROLE regress_passwd1 PASSWORD 'role_pwd1';
@@ -16,7 +16,7 @@ SET password_encryption = 'md5';
 CREATE ROLE regress_passwd2 PASSWORD 'role_pwd2';
 SET password_encryption = 'on';
 CREATE ROLE regress_passwd3 PASSWORD 'role_pwd3';
-SET password_encryption = 'scram';
+SET password_encryption = 'scram-sha-256';
 CREATE ROLE regress_passwd4 PASSWORD 'role_pwd4';
 SET password_encryption = 'plain';
 CREATE ROLE regress_passwd5 PASSWORD NULL;
@@ -60,7 +60,7 @@ ALTER ROLE regress_passwd2 UNENCRYPTED PASSWORD 'md5dfa155cadd5f4ad57860162f3fab
 SET password_encryption = 'md5';
 ALTER ROLE regress_passwd3 ENCRYPTED PASSWORD 'foo'; -- encrypted with MD5
 ALTER ROLE regress_passwd4 ENCRYPTED PASSWORD 'scram-sha-256:VLK4RMaQLCvNtQ==:4096:3ded2376f7aafa93b1bdbd71bcc18b7d6ee50ed018029cc583d152ef3fc7d430:a6dd36dfc94c181956a6ae95f05e01b1864f0a22a2657d1de4ba84d2a24dc438'; -- client-supplied SCRAM verifier, use as it is
-SET password_encryption = 'scram';
+SET password_encryption = 'scram-sha-256';
 ALTER ROLE  regress_passwd5 ENCRYPTED PASSWORD 'foo'; -- create SCRAM verifier
 CREATE ROLE regress_passwd6 ENCRYPTED PASSWORD 'md53725413363ab045e20521bf36b8d8d7f'; -- encrypted with MD5, use as it is
 SELECT rolname, regexp_replace(rolpassword, '(scram-sha-256):([a-zA-Z0-9+/]+==):(\d+):(\w+):(\w+)', '\1::\3::') as rolpassword_masked
index f4b3a9ac3a1d6391e6483bd16e123a63fb185563..95557e45660eafb3de9d501ff87c297e68f7a65b 100644 (file)
@@ -7,7 +7,7 @@ SET password_encryption = 'novalue'; -- error
 SET password_encryption = true; -- ok
 SET password_encryption = 'md5'; -- ok
 SET password_encryption = 'plain'; -- ok
-SET password_encryption = 'scram'; -- ok
+SET password_encryption = 'scram-sha-256'; -- ok
 
 -- consistency of password entries
 SET password_encryption = 'plain';
@@ -16,7 +16,7 @@ SET password_encryption = 'md5';
 CREATE ROLE regress_passwd2 PASSWORD 'role_pwd2';
 SET password_encryption = 'on';
 CREATE ROLE regress_passwd3 PASSWORD 'role_pwd3';
-SET password_encryption = 'scram';
+SET password_encryption = 'scram-sha-256';
 CREATE ROLE regress_passwd4 PASSWORD 'role_pwd4';
 SET password_encryption = 'plain';
 CREATE ROLE regress_passwd5 PASSWORD NULL;
@@ -50,7 +50,7 @@ ALTER ROLE regress_passwd3 ENCRYPTED PASSWORD 'foo'; -- encrypted with MD5
 
 ALTER ROLE regress_passwd4 ENCRYPTED PASSWORD 'scram-sha-256:VLK4RMaQLCvNtQ==:4096:3ded2376f7aafa93b1bdbd71bcc18b7d6ee50ed018029cc583d152ef3fc7d430:a6dd36dfc94c181956a6ae95f05e01b1864f0a22a2657d1de4ba84d2a24dc438'; -- client-supplied SCRAM verifier, use as it is
 
-SET password_encryption = 'scram';
+SET password_encryption = 'scram-sha-256';
 ALTER ROLE  regress_passwd5 ENCRYPTED PASSWORD 'foo'; -- create SCRAM verifier
 CREATE ROLE regress_passwd6 ENCRYPTED PASSWORD 'md53725413363ab045e20521bf36b8d8d7f'; -- encrypted with MD5, use as it is