From 7c326e7b0ae7a4e614d4f21703e0987d235d42aa Mon Sep 17 00:00:00 2001 From: Vaishnavi Prabakaran Date: Wed, 10 May 2017 11:39:50 +1000 Subject: [PATCH] Removal of plaintext password reference --- src/backend/commands/user.c | 6 +++--- src/backend/libpq/auth-scram.c | 2 +- src/backend/libpq/auth.c | 2 +- src/backend/libpq/crypt.c | 35 +++++++++++++++++++---------------- src/include/commands/user.h | 2 +- src/include/libpq/crypt.h | 9 +++++++-- 6 files changed, 32 insertions(+), 24 deletions(-) diff --git a/src/backend/commands/user.c b/src/backend/commands/user.c index 36d5f40..841fc98 100644 --- a/src/backend/commands/user.c +++ b/src/backend/commands/user.c @@ -362,7 +362,7 @@ CreateRole(ParseState *pstate, CreateRoleStmt *stmt) if (check_password_hook && password) (*check_password_hook) (stmt->role, password, - get_password_type(password), + isPasswordEncrypted(password), validUntil_datum, validUntil_null); @@ -724,7 +724,7 @@ AlterRole(AlterRoleStmt *stmt) if (check_password_hook && password) (*check_password_hook) (rolename, password, - get_password_type(password), + isPasswordEncrypted(password), validUntil_datum, validUntil_null); @@ -1204,7 +1204,7 @@ RenameRole(const char *oldname, const char *newname) datum = heap_getattr(oldtuple, Anum_pg_authid_rolpassword, dsc, &isnull); - if (!isnull && get_password_type(TextDatumGetCString(datum)) == PASSWORD_TYPE_MD5) + if (!isnull && get_password_encryption_type(TextDatumGetCString(datum)) == PASSWORD_TYPE_MD5) { /* MD5 uses the username as salt, so just clear it on a rename */ repl_repl[Anum_pg_authid_rolpassword - 1] = true; diff --git a/src/backend/libpq/auth-scram.c b/src/backend/libpq/auth-scram.c index 99feb0c..8aebaeb 100644 --- a/src/backend/libpq/auth-scram.c +++ b/src/backend/libpq/auth-scram.c @@ -182,7 +182,7 @@ pg_be_scram_init(const char *username, const char *shadow_pass) */ if (shadow_pass) { - int password_type = get_password_type(shadow_pass); + int password_type = get_password_encryption_type(shadow_pass); if (password_type == PASSWORD_TYPE_SCRAM_SHA_256) { diff --git a/src/backend/libpq/auth.c b/src/backend/libpq/auth.c index 6d3ff68..dadfdd4 100644 --- a/src/backend/libpq/auth.c +++ b/src/backend/libpq/auth.c @@ -765,7 +765,7 @@ CheckPWChallengeAuth(Port *port, char **logdetail) if (!shadow_pass) pwtype = Password_encryption; else - pwtype = get_password_type(shadow_pass); + pwtype = get_password_encryption_type(shadow_pass); /* * If 'md5' authentication is allowed, decide whether to perform 'md5' or diff --git a/src/backend/libpq/crypt.c b/src/backend/libpq/crypt.c index e7a6b04..1d7c73f 100644 --- a/src/backend/libpq/crypt.c +++ b/src/backend/libpq/crypt.c @@ -96,13 +96,24 @@ get_role_password(const char *role, char **logdetail) * What kind of a password verifier is 'shadow_pass'? */ PasswordType -get_password_type(const char *shadow_pass) +get_password_encryption_type(const char *shadow_pass) { - if (strncmp(shadow_pass, "md5", 3) == 0 && strlen(shadow_pass) == MD5_PASSWD_LEN) + /* Currently only 2 encryption mechanism are supported, so we can skip verifying password against SCRAM */ + if(isMD5(shadow_pass)) return PASSWORD_TYPE_MD5; - if (strncmp(shadow_pass, "SCRAM-SHA-256$", strlen("SCRAM-SHA-256$")) == 0) + else return PASSWORD_TYPE_SCRAM_SHA_256; - return PASSWORD_TYPE_PLAINTEXT; +} + +/* + * Verify whether the given password is already encrypted or not + */ +bool +isPasswordEncrypted(const char *password) +{ + if(isMD5(password) || isSCRAM(password)) + return true; + return false; } /* @@ -116,10 +127,10 @@ char * encrypt_password(PasswordType target_type, const char *role, const char *password) { - PasswordType guessed_type = get_password_type(password); + bool password_encrypted = isPasswordEncrypted(password); char *encrypted_password; - if (guessed_type != PASSWORD_TYPE_PLAINTEXT) + if (password_encrypted) { /* * Cannot convert an already-encrypted password from one @@ -141,8 +152,6 @@ encrypt_password(PasswordType target_type, const char *role, case PASSWORD_TYPE_SCRAM_SHA_256: return pg_be_scram_build_verifier(password); - case PASSWORD_TYPE_PLAINTEXT: - elog(ERROR, "cannot encrypt password with 'plaintext'"); } /* @@ -175,7 +184,7 @@ md5_crypt_verify(const char *role, const char *shadow_pass, Assert(md5_salt_len > 0); - if (get_password_type(shadow_pass) != PASSWORD_TYPE_MD5) + if (get_password_encryption_type(shadow_pass) != PASSWORD_TYPE_MD5) { /* incompatible password hash format. */ *logdetail = psprintf(_("User \"%s\" has a password that cannot be used with MD5 authentication."), @@ -232,7 +241,7 @@ plain_crypt_verify(const char *role, const char *shadow_pass, * the password the client sent, and compare the hashes. Otherwise * compare the plaintext passwords directly. */ - switch (get_password_type(shadow_pass)) + switch (get_password_encryption_type(shadow_pass)) { case PASSWORD_TYPE_SCRAM_SHA_256: if (scram_verify_plain_password(role, @@ -273,12 +282,6 @@ plain_crypt_verify(const char *role, const char *shadow_pass, } break; - case PASSWORD_TYPE_PLAINTEXT: - /* - * We never store passwords in plaintext, so this shouldn't - * happen. - */ - break; } /* diff --git a/src/include/commands/user.h b/src/include/commands/user.h index 08037e0..4984faa 100644 --- a/src/include/commands/user.h +++ b/src/include/commands/user.h @@ -20,7 +20,7 @@ extern int Password_encryption; /* Hook to check passwords in CreateRole() and AlterRole() */ -typedef void (*check_password_hook_type) (const char *username, const char *shadow_pass, PasswordType password_type, Datum validuntil_time, bool validuntil_null); +typedef void (*check_password_hook_type) (const char *username, const char *shadow_pass, bool password_encrypted, Datum validuntil_time, bool validuntil_null); extern PGDLLIMPORT check_password_hook_type check_password_hook; diff --git a/src/include/libpq/crypt.h b/src/include/libpq/crypt.h index 9bad67c..5516dba 100644 --- a/src/include/libpq/crypt.h +++ b/src/include/libpq/crypt.h @@ -26,12 +26,17 @@ */ typedef enum PasswordType { - PASSWORD_TYPE_PLAINTEXT = 0, PASSWORD_TYPE_MD5, PASSWORD_TYPE_SCRAM_SHA_256 } PasswordType; -extern PasswordType get_password_type(const char *shadow_pass); +#define isMD5(password) \ + ((strncmp(password, "md5", 3) == 0 && strlen(password) == MD5_PASSWD_LEN)? 1:0) + +#define isSCRAM(password) \ + ( (strncmp(password, "SCRAM-SHA-256$", 14) == 0)? 1 :0) + +extern PasswordType get_password_encryption_type(const char *shadow_pass); extern char *encrypt_password(PasswordType target_type, const char *role, const char *password); -- 2.7.4.windows.1