diff options
author | Heikki Linnakangas <heikki.linnakangas@iki.fi> | 2016-12-08 13:44:47 +0200 |
---|---|---|
committer | Heikki Linnakangas <heikki.linnakangas@iki.fi> | 2016-12-08 13:44:47 +0200 |
commit | fe7bdf0bf67d8ac360d67fa9740074a2c70e88a4 (patch) | |
tree | b0463aaf3839ff828407632d31c87aadd826461c /src/backend/libpq/crypt.c | |
parent | f7d54f4f7ddf72bf4db1783890b058e758b4b894 (diff) | |
download | postgresql-fe7bdf0bf67d8ac360d67fa9740074a2c70e88a4.tar.gz postgresql-fe7bdf0bf67d8ac360d67fa9740074a2c70e88a4.zip |
Clean up password authentication code a bit.
Commit fe0a0b59, which moved code to do MD5 authentication to a separate
CheckMD5Auth() function, left behind a comment that really belongs inside
the function, too. Also move the check for db_user_namespace inside the
function, seems clearer that way.
Now that the md5 salt is passed as argument to md5_crypt_verify, it's a bit
silly that it peeks into the Port struct to see if MD5 authentication was
used. Seems more straightforward to treat it as an MD5 authentication, if
the md5 salt argument is given. And after that, md5_crypt_verify only used
the Port argument to look at port->user_name, but that is redundant,
because it is also passed as a separate 'role' argument. So remove the Port
argument altogether.
Diffstat (limited to 'src/backend/libpq/crypt.c')
-rw-r--r-- | src/backend/libpq/crypt.c | 108 |
1 files changed, 57 insertions, 51 deletions
diff --git a/src/backend/libpq/crypt.c b/src/backend/libpq/crypt.c index 35b657adbbe..b4ca17431a2 100644 --- a/src/backend/libpq/crypt.c +++ b/src/backend/libpq/crypt.c @@ -31,11 +31,16 @@ /* * Check given password for given user, and return STATUS_OK or STATUS_ERROR. + * + * 'client_pass' is the password response given by the remote user. If + * 'md5_salt' is not NULL, it is a response to an MD5 authentication + * challenge, with the given salt. Otherwise, it is a plaintext password. + * * In the error case, optionally store a palloc'd string at *logdetail * that will be sent to the postmaster log (but not the client). */ int -md5_crypt_verify(const Port *port, const char *role, char *client_pass, +md5_crypt_verify(const char *role, char *client_pass, char *md5_salt, int md5_salt_len, char **logdetail) { int retval = STATUS_ERROR; @@ -88,63 +93,64 @@ md5_crypt_verify(const Port *port, const char *role, char *client_pass, * error is out-of-memory, which is unlikely, and if it did happen adding * a psprintf call would only make things worse.) */ - switch (port->hba->auth_method) + if (md5_salt) { - case uaMD5: - Assert(md5_salt != NULL && md5_salt_len > 0); - crypt_pwd = palloc(MD5_PASSWD_LEN + 1); - if (isMD5(shadow_pass)) + /* MD5 authentication */ + Assert(md5_salt_len > 0); + crypt_pwd = palloc(MD5_PASSWD_LEN + 1); + if (isMD5(shadow_pass)) + { + /* stored password already encrypted, only do salt */ + if (!pg_md5_encrypt(shadow_pass + strlen("md5"), + md5_salt, md5_salt_len, + crypt_pwd)) { - /* stored password already encrypted, only do salt */ - if (!pg_md5_encrypt(shadow_pass + strlen("md5"), - md5_salt, md5_salt_len, - crypt_pwd)) - { - pfree(crypt_pwd); - return STATUS_ERROR; - } + pfree(crypt_pwd); + return STATUS_ERROR; } - else - { - /* stored password is plain, double-encrypt */ - char *crypt_pwd2 = palloc(MD5_PASSWD_LEN + 1); + } + else + { + /* stored password is plain, double-encrypt */ + char *crypt_pwd2 = palloc(MD5_PASSWD_LEN + 1); - if (!pg_md5_encrypt(shadow_pass, - port->user_name, - strlen(port->user_name), - crypt_pwd2)) - { - pfree(crypt_pwd); - pfree(crypt_pwd2); - return STATUS_ERROR; - } - if (!pg_md5_encrypt(crypt_pwd2 + strlen("md5"), - md5_salt, md5_salt_len, - crypt_pwd)) - { - pfree(crypt_pwd); - pfree(crypt_pwd2); - return STATUS_ERROR; - } + if (!pg_md5_encrypt(shadow_pass, + role, + strlen(role), + crypt_pwd2)) + { + pfree(crypt_pwd); pfree(crypt_pwd2); + return STATUS_ERROR; } - break; - default: - if (isMD5(shadow_pass)) + if (!pg_md5_encrypt(crypt_pwd2 + strlen("md5"), + md5_salt, md5_salt_len, + crypt_pwd)) { - /* Encrypt user-supplied password to match stored MD5 */ - crypt_client_pass = palloc(MD5_PASSWD_LEN + 1); - if (!pg_md5_encrypt(client_pass, - port->user_name, - strlen(port->user_name), - crypt_client_pass)) - { - pfree(crypt_client_pass); - return STATUS_ERROR; - } + pfree(crypt_pwd); + pfree(crypt_pwd2); + return STATUS_ERROR; } - crypt_pwd = shadow_pass; - break; + pfree(crypt_pwd2); + } + } + else + { + /* Client sent password in plaintext */ + if (isMD5(shadow_pass)) + { + /* Encrypt user-supplied password to match stored MD5 */ + crypt_client_pass = palloc(MD5_PASSWD_LEN + 1); + if (!pg_md5_encrypt(client_pass, + role, + strlen(role), + crypt_client_pass)) + { + pfree(crypt_client_pass); + return STATUS_ERROR; + } + } + crypt_pwd = shadow_pass; } if (strcmp(crypt_client_pass, crypt_pwd) == 0) @@ -167,7 +173,7 @@ md5_crypt_verify(const Port *port, const char *role, char *client_pass, *logdetail = psprintf(_("Password does not match for user \"%s\"."), role); - if (port->hba->auth_method == uaMD5) + if (crypt_pwd != shadow_pass) pfree(crypt_pwd); if (crypt_client_pass != client_pass) pfree(crypt_client_pass); |