1 /*-------------------------------------------------------------------------
4 * Look into the password file and check the encrypted password with
5 * the one passed in from the frontend.
7 * Original coding by Todd A. Brandys
9 * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
10 * Portions Copyright (c) 1994, Regents of the University of California
14 *-------------------------------------------------------------------------
23 #include "libpq/crypt.h"
24 #include "libpq/md5.h"
28 md5_crypt_verify(const Port
*port
, const char *role
, char *client_pass
)
30 char *shadow_pass
= NULL
,
33 int retval
= STATUS_ERROR
;
36 char *crypt_client_pass
= client_pass
;
38 if ((line
= get_role_line(role
)) == NULL
)
41 /* Skip over rolename */
42 token
= list_head(*line
);
47 shadow_pass
= (char *) lfirst(token
);
50 valuntil
= (char *) lfirst(token
);
53 if (shadow_pass
== NULL
|| *shadow_pass
== '\0')
57 * Compare with the encrypted or plain password depending on the
58 * authentication method being used for this connection.
60 switch (port
->hba
->auth_method
)
63 crypt_pwd
= palloc(MD5_PASSWD_LEN
+ 1);
64 if (isMD5(shadow_pass
))
66 /* stored password already encrypted, only do salt */
67 if (!pg_md5_encrypt(shadow_pass
+ strlen("md5"),
68 (char *) port
->md5Salt
,
69 sizeof(port
->md5Salt
), crypt_pwd
))
77 /* stored password is plain, double-encrypt */
78 char *crypt_pwd2
= palloc(MD5_PASSWD_LEN
+ 1);
80 if (!pg_md5_encrypt(shadow_pass
,
82 strlen(port
->user_name
),
89 if (!pg_md5_encrypt(crypt_pwd2
+ strlen("md5"),
91 sizeof(port
->md5Salt
),
102 if (isMD5(shadow_pass
))
104 /* Encrypt user-supplied password to match stored MD5 */
105 crypt_client_pass
= palloc(MD5_PASSWD_LEN
+ 1);
106 if (!pg_md5_encrypt(client_pass
,
108 strlen(port
->user_name
),
111 pfree(crypt_client_pass
);
115 crypt_pwd
= shadow_pass
;
119 if (strcmp(crypt_client_pass
, crypt_pwd
) == 0)
122 * Password OK, now check to be sure we are not past valuntil
124 if (valuntil
== NULL
|| *valuntil
== '\0')
130 vuntil
= DatumGetTimestampTz(DirectFunctionCall3(timestamptz_in
,
131 CStringGetDatum(valuntil
),
132 ObjectIdGetDatum(InvalidOid
),
135 if (vuntil
< GetCurrentTimestamp())
136 retval
= STATUS_ERROR
;
142 if (port
->hba
->auth_method
== uaMD5
)
144 if (crypt_client_pass
!= client_pass
)
145 pfree(crypt_client_pass
);