Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit7f56d43

Browse files
committed
Fix detection of passwords hashed with MD5 or SCRAM-SHA-256
This commit fixes a couple of issues related to the way passwordverifiers hashed with MD5 or SCRAM-SHA-256 are detected, leading tobeing able to store in catalogs passwords which do not follow thesupported hash formats:- A MD5-hashed entry was checked based on if its header uses "md5" andif the string length matches what is expected. Unfortunately the codenever checked if the hash only used hexadecimal characters, as reportedby Tom Lane.- A SCRAM-hashed entry was checked based on only its header, whichshould be "SCRAM-SHA-256$", but it never checked for any fieldsafterwards, as reported by Jonathan Katz.Backpatch down to v10, which is where SCRAM has been introduced, andwhere password verifiers in plain format have been removed.Author: Jonathan KatzReviewed-by: Tom Lane, Michael PaquierDiscussion:https://postgr.es/m/016deb6b-1f0a-8e9f-1833-a8675b170aa9@postgresql.orgBackpatch-through: 10
1 parentcee3cfd commit7f56d43

File tree

6 files changed

+44
-6
lines changed

6 files changed

+44
-6
lines changed

‎src/backend/libpq/auth-scram.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -162,8 +162,6 @@ static char *build_server_first_message(scram_state *state);
162162
staticchar*build_server_final_message(scram_state*state);
163163
staticboolverify_client_proof(scram_state*state);
164164
staticboolverify_final_nonce(scram_state*state);
165-
staticboolparse_scram_verifier(constchar*verifier,int*iterations,
166-
char**salt,uint8*stored_key,uint8*server_key);
167165
staticvoidmock_scram_verifier(constchar*username,int*iterations,
168166
char**salt,uint8*stored_key,uint8*server_key);
169167
staticboolis_scram_printable(char*p);
@@ -547,7 +545,7 @@ scram_verify_plain_password(const char *username, const char *password,
547545
*
548546
* Returns true if the SCRAM verifier has been parsed, and false otherwise.
549547
*/
550-
staticbool
548+
bool
551549
parse_scram_verifier(constchar*verifier,int*iterations,char**salt,
552550
uint8*stored_key,uint8*server_key)
553551
{

‎src/backend/libpq/crypt.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
#include"catalog/pg_authid.h"
2222
#include"common/md5.h"
23+
#include"common/scram-common.h"
2324
#include"libpq/crypt.h"
2425
#include"libpq/scram.h"
2526
#include"miscadmin.h"
@@ -90,9 +91,17 @@ get_role_password(const char *role, char **logdetail)
9091
PasswordType
9192
get_password_type(constchar*shadow_pass)
9293
{
93-
if (strncmp(shadow_pass,"md5",3)==0&&strlen(shadow_pass)==MD5_PASSWD_LEN)
94+
char*encoded_salt;
95+
intiterations;
96+
uint8stored_key[SCRAM_KEY_LEN];
97+
uint8server_key[SCRAM_KEY_LEN];
98+
99+
if (strncmp(shadow_pass,"md5",3)==0&&
100+
strlen(shadow_pass)==MD5_PASSWD_LEN&&
101+
strspn(shadow_pass+3,MD5_PASSWD_CHARSET)==MD5_PASSWD_LEN-3)
94102
returnPASSWORD_TYPE_MD5;
95-
if (strncmp(shadow_pass,"SCRAM-SHA-256$",strlen("SCRAM-SHA-256$"))==0)
103+
if (parse_scram_verifier(shadow_pass,&iterations,&encoded_salt,
104+
stored_key,server_key))
96105
returnPASSWORD_TYPE_SCRAM_SHA_256;
97106
returnPASSWORD_TYPE_PLAINTEXT;
98107
}

‎src/include/common/md5.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#ifndefPG_MD5_H
1717
#definePG_MD5_H
1818

19+
#defineMD5_PASSWD_CHARSET"0123456789abcdef"
1920
#defineMD5_PASSWD_LEN35
2021

2122
externboolpg_md5_hash(constvoid*buff,size_tlen,char*hexsum);

‎src/include/libpq/scram.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ extern int pg_be_scram_exchange(void *opaq, char *input, int inputlen,
2929

3030
/* Routines to handle and check SCRAM-SHA-256 verifier */
3131
externchar*pg_be_scram_build_verifier(constchar*password);
32+
externboolparse_scram_verifier(constchar*verifier,int*iterations,char**salt,
33+
uint8*stored_key,uint8*server_key);
3234
externboolscram_verify_plain_password(constchar*username,
3335
constchar*password,constchar*verifier);
3436

‎src/test/regress/expected/password.out

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,15 @@ SET password_encryption = 'scram-sha-256';
6262
ALTER ROLE regress_passwd4 PASSWORD 'foo';
6363
-- already encrypted with MD5, use as it is
6464
CREATE 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.
67+
CREATE 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
71+
CREATE ROLE regress_passwd7 PASSWORD 'md5012345678901234567890123456789zz';
72+
-- invalid length
73+
CREATE ROLE regress_passwd8 PASSWORD 'md501234567890123456789012345678901zz';
6574
SELECT 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
6675
FROM pg_authid
6776
WHERE rolname LIKE 'regress_passwd%'
@@ -73,7 +82,10 @@ SELECT rolname, regexp_replace(rolpassword, '(SCRAM-SHA-256)\$(\d+):([a-zA-Z0-9+
7382
regress_passwd3 | SCRAM-SHA-256$4096:<salt>$<storedkey>:<serverkey>
7483
regress_passwd4 | SCRAM-SHA-256$4096:<salt>$<storedkey>:<serverkey>
7584
regress_passwd5 | md5e73a4b11df52a6068f8b39f90be36023
76-
(5 rows)
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)
7789

7890
-- An empty password is not allowed, in any form
7991
CREATE ROLE regress_passwd_empty PASSWORD '';
@@ -93,6 +105,9 @@ DROP ROLE regress_passwd2;
93105
DROP ROLE regress_passwd3;
94106
DROP ROLE regress_passwd4;
95107
DROP ROLE regress_passwd5;
108+
DROP ROLE regress_passwd6;
109+
DROP ROLE regress_passwd7;
110+
DROP ROLE regress_passwd8;
96111
DROP ROLE regress_passwd_empty;
97112
-- all entries should have been removed
98113
SELECT rolname, rolpassword

‎src/test/regress/sql/password.sql

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,16 @@ ALTER ROLE regress_passwd4 PASSWORD 'foo';
5454
-- already encrypted with MD5, use as it is
5555
CREATE ROLE regress_passwd5 PASSWORD'md5e73a4b11df52a6068f8b39f90be36023';
5656

57+
-- This looks like a valid SCRAM-SHA-256 verifier, but it is not
58+
-- so it should be hashed with SCRAM-SHA-256.
59+
CREATE ROLE regress_passwd6 PASSWORD'SCRAM-SHA-256$1234';
60+
-- These may look like valid MD5 verifiers, but they are not, so they
61+
-- should be hashed with SCRAM-SHA-256.
62+
-- trailing garbage at the end
63+
CREATE ROLE regress_passwd7 PASSWORD'md5012345678901234567890123456789zz';
64+
-- invalid length
65+
CREATE ROLE regress_passwd8 PASSWORD'md501234567890123456789012345678901zz';
66+
5767
SELECT 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
5868
FROM pg_authid
5969
WHERE rolnameLIKE'regress_passwd%'
@@ -70,6 +80,9 @@ DROP ROLE regress_passwd2;
7080
DROP ROLE regress_passwd3;
7181
DROP ROLE regress_passwd4;
7282
DROP ROLE regress_passwd5;
83+
DROP ROLE regress_passwd6;
84+
DROP ROLE regress_passwd7;
85+
DROP ROLE regress_passwd8;
7386
DROP ROLE regress_passwd_empty;
7487

7588
-- all entries should have been removed

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp