aboutsummaryrefslogtreecommitdiff
path: root/src/backend/libpq/crypt.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/libpq/crypt.c')
-rw-r--r--src/backend/libpq/crypt.c108
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);