1-- 2-- Tests for password verifiers 3-- 4-- Tests for GUC password_encryption 5SET password_encryption = 'novalue'; -- error 6ERROR: invalid value for parameter "password_encryption": "novalue" 7HINT: Available values: md5, scram-sha-256. 8SET password_encryption = true; -- ok 9SET password_encryption = 'md5'; -- ok 10SET password_encryption = 'scram-sha-256'; -- ok 11-- consistency of password entries 12SET password_encryption = 'md5'; 13CREATE ROLE regress_passwd1 PASSWORD 'role_pwd1'; 14SET password_encryption = 'on'; 15CREATE ROLE regress_passwd2 PASSWORD 'role_pwd2'; 16SET password_encryption = 'scram-sha-256'; 17CREATE ROLE regress_passwd3 PASSWORD 'role_pwd3'; 18CREATE ROLE regress_passwd4 PASSWORD NULL; 19-- check list of created entries 20-- 21-- The scram verifier will look something like: 22-- SCRAM-SHA-256$4096:E4HxLGtnRzsYwg==$6YtlR4t69SguDiwFvbVgVZtuz6gpJQQqUMZ7IQJK5yI=:ps75jrHeYU4lXCcXI4O8oIdJ3eO8o2jirjruw9phBTo= 23-- 24-- Since the salt is random, the exact value stored will be different on every test 25-- run. Use a regular expression to mask the changing parts. 26SELECT rolname, regexp_replace(rolpassword, '(SCRAM-SHA-256)\$(\d+):([a-zA-Z0-9+/=]+)\$([a-zA-Z0-9+=/]+):([a-zA-Z0-9+/=]+)', '\1$\2:<salt>$<storedkey>:<serverkey>') as rolpassword_masked 27 FROM pg_authid 28 WHERE rolname LIKE 'regress_passwd%' 29 ORDER BY rolname, rolpassword; 30 rolname | rolpassword_masked 31-----------------+--------------------------------------------------- 32 regress_passwd1 | md5783277baca28003b33453252be4dbb34 33 regress_passwd2 | md54044304ba511dd062133eb5b4b84a2a3 34 regress_passwd3 | SCRAM-SHA-256$4096:<salt>$<storedkey>:<serverkey> 35 regress_passwd4 | 36(4 rows) 37 38-- Rename a role 39ALTER ROLE regress_passwd2 RENAME TO regress_passwd2_new; 40NOTICE: MD5 password cleared because of role rename 41-- md5 entry should have been removed 42SELECT rolname, rolpassword 43 FROM pg_authid 44 WHERE rolname LIKE 'regress_passwd2_new' 45 ORDER BY rolname, rolpassword; 46 rolname | rolpassword 47---------------------+------------- 48 regress_passwd2_new | 49(1 row) 50 51ALTER ROLE regress_passwd2_new RENAME TO regress_passwd2; 52-- Change passwords with ALTER USER. With plaintext or already-encrypted 53-- passwords. 54SET password_encryption = 'md5'; 55-- encrypt with MD5 56ALTER ROLE regress_passwd2 PASSWORD 'foo'; 57-- already encrypted, use as they are 58ALTER ROLE regress_passwd1 PASSWORD 'md5cd3578025fe2c3d7ed1b9a9b26238b70'; 59ALTER ROLE regress_passwd3 PASSWORD 'SCRAM-SHA-256$4096:VLK4RMaQLCvNtQ==$6YtlR4t69SguDiwFvbVgVZtuz6gpJQQqUMZ7IQJK5yI=:ps75jrHeYU4lXCcXI4O8oIdJ3eO8o2jirjruw9phBTo='; 60SET password_encryption = 'scram-sha-256'; 61-- create SCRAM verifier 62ALTER ROLE regress_passwd4 PASSWORD 'foo'; 63-- already encrypted with MD5, use as it is 64CREATE ROLE regress_passwd5 PASSWORD 'md5e73a4b11df52a6068f8b39f90be36023'; 65-- This looks like a valid SCRAM-SHA-256 verifier, but it is not 66-- so it should be hashed with SCRAM-SHA-256. 67CREATE ROLE regress_passwd6 PASSWORD 'SCRAM-SHA-256$1234'; 68-- These may look like valid MD5 verifiers, but they are not, so they 69-- should be hashed with SCRAM-SHA-256. 70-- trailing garbage at the end 71CREATE ROLE regress_passwd7 PASSWORD 'md5012345678901234567890123456789zz'; 72-- invalid length 73CREATE ROLE regress_passwd8 PASSWORD 'md501234567890123456789012345678901zz'; 74SELECT rolname, regexp_replace(rolpassword, '(SCRAM-SHA-256)\$(\d+):([a-zA-Z0-9+/=]+)\$([a-zA-Z0-9+=/]+):([a-zA-Z0-9+/=]+)', '\1$\2:<salt>$<storedkey>:<serverkey>') as rolpassword_masked 75 FROM pg_authid 76 WHERE rolname LIKE 'regress_passwd%' 77 ORDER BY rolname, rolpassword; 78 rolname | rolpassword_masked 79-----------------+--------------------------------------------------- 80 regress_passwd1 | md5cd3578025fe2c3d7ed1b9a9b26238b70 81 regress_passwd2 | md5dfa155cadd5f4ad57860162f3fab9cdb 82 regress_passwd3 | SCRAM-SHA-256$4096:<salt>$<storedkey>:<serverkey> 83 regress_passwd4 | SCRAM-SHA-256$4096:<salt>$<storedkey>:<serverkey> 84 regress_passwd5 | md5e73a4b11df52a6068f8b39f90be36023 85 regress_passwd6 | SCRAM-SHA-256$4096:<salt>$<storedkey>:<serverkey> 86 regress_passwd7 | SCRAM-SHA-256$4096:<salt>$<storedkey>:<serverkey> 87 regress_passwd8 | SCRAM-SHA-256$4096:<salt>$<storedkey>:<serverkey> 88(8 rows) 89 90-- An empty password is not allowed, in any form 91CREATE ROLE regress_passwd_empty PASSWORD ''; 92NOTICE: empty string is not a valid password, clearing password 93ALTER ROLE regress_passwd_empty PASSWORD 'md585939a5ce845f1a1b620742e3c659e0a'; 94NOTICE: empty string is not a valid password, clearing password 95ALTER ROLE regress_passwd_empty PASSWORD 'SCRAM-SHA-256$4096:hpFyHTUsSWcR7O9P$LgZFIt6Oqdo27ZFKbZ2nV+vtnYM995pDh9ca6WSi120=:qVV5NeluNfUPkwm7Vqat25RjSPLkGeoZBQs6wVv+um4='; 96NOTICE: empty string is not a valid password, clearing password 97SELECT rolpassword FROM pg_authid WHERE rolname='regress_passwd_empty'; 98 rolpassword 99------------- 100 101(1 row) 102 103-- Test with invalid stored and server keys. 104-- 105-- The first is valid, to act as a control. The others have too long 106-- stored/server keys. They will be re-hashed. 107CREATE ROLE regress_passwd_sha_len0 PASSWORD 'SCRAM-SHA-256$4096:A6xHKoH/494E941doaPOYg==$Ky+A30sewHIH3VHQLRN9vYsuzlgNyGNKCh37dy96Rqw=:COPdlNiIkrsacU5QoxydEuOH6e/KfiipeETb/bPw8ZI='; 108CREATE ROLE regress_passwd_sha_len1 PASSWORD 'SCRAM-SHA-256$4096:A6xHKoH/494E941doaPOYg==$Ky+A30sewHIH3VHQLRN9vYsuzlgNyGNKCh37dy96RqwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=:COPdlNiIkrsacU5QoxydEuOH6e/KfiipeETb/bPw8ZI='; 109CREATE ROLE regress_passwd_sha_len2 PASSWORD 'SCRAM-SHA-256$4096:A6xHKoH/494E941doaPOYg==$Ky+A30sewHIH3VHQLRN9vYsuzlgNyGNKCh37dy96Rqw=:COPdlNiIkrsacU5QoxydEuOH6e/KfiipeETb/bPw8ZIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA='; 110-- Check that the invalid verifiers were re-hashed. A re-hashed verifier 111-- should not contain the original salt. 112SELECT rolname, rolpassword not like '%A6xHKoH/494E941doaPOYg==%' as is_rolpassword_rehashed 113 FROM pg_authid 114 WHERE rolname LIKE 'regress_passwd_sha_len%' 115 ORDER BY rolname; 116 rolname | is_rolpassword_rehashed 117-------------------------+------------------------- 118 regress_passwd_sha_len0 | f 119 regress_passwd_sha_len1 | t 120 regress_passwd_sha_len2 | t 121(3 rows) 122 123DROP ROLE regress_passwd1; 124DROP ROLE regress_passwd2; 125DROP ROLE regress_passwd3; 126DROP ROLE regress_passwd4; 127DROP ROLE regress_passwd5; 128DROP ROLE regress_passwd6; 129DROP ROLE regress_passwd7; 130DROP ROLE regress_passwd8; 131DROP ROLE regress_passwd_empty; 132DROP ROLE regress_passwd_sha_len0; 133DROP ROLE regress_passwd_sha_len1; 134DROP ROLE regress_passwd_sha_len2; 135-- all entries should have been removed 136SELECT rolname, rolpassword 137 FROM pg_authid 138 WHERE rolname LIKE 'regress_passwd%' 139 ORDER BY rolname, rolpassword; 140 rolname | rolpassword 141---------+------------- 142(0 rows) 143 144