#include "postgres.h"#include <ctype.h>#include "commands/user.h"#include "fmgr.h"#include "libpq/md5.h"
Go to the source code of this file.
Defines | |
| #define | MIN_PWD_LENGTH 8 |
Functions | |
| void | _PG_init (void) |
| static void | check_password (const char *username, const char *password, int password_type, Datum validuntil_time, bool validuntil_null) |
Variables | |
| PG_MODULE_MAGIC | |
| #define MIN_PWD_LENGTH 8 |
Definition at line 31 of file passwordcheck.c.
Referenced by check_password().
| void _PG_init | ( | void | ) |
Definition at line 144 of file passwordcheck.c.
References check_password_hook.
{
/* activate password checks when the module is loaded */
check_password_hook = check_password;
}
| static void check_password | ( | const char * | username, | |
| const char * | password, | |||
| int | password_type, | |||
| Datum | validuntil_time, | |||
| bool | validuntil_null | |||
| ) | [static] |
Definition at line 53 of file passwordcheck.c.
References elog, ereport, errcode(), errmsg(), ERROR, i, MD5_PASSWD_LEN, MIN_PWD_LENGTH, PASSWORD_TYPE_MD5, PASSWORD_TYPE_PLAINTEXT, and pg_md5_encrypt().
{
int namelen = strlen(username);
int pwdlen = strlen(password);
char encrypted[MD5_PASSWD_LEN + 1];
int i;
bool pwd_has_letter,
pwd_has_nonletter;
switch (password_type)
{
case PASSWORD_TYPE_MD5:
/*
* Unfortunately we cannot perform exhaustive checks on encrypted
* passwords - we are restricted to guessing. (Alternatively, we
* could insist on the password being presented non-encrypted, but
* that has its own security disadvantages.)
*
* We only check for username = password.
*/
if (!pg_md5_encrypt(username, username, namelen, encrypted))
elog(ERROR, "password encryption failed");
if (strcmp(password, encrypted) == 0)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("password must not contain user name")));
break;
case PASSWORD_TYPE_PLAINTEXT:
/*
* For unencrypted passwords we can perform better checks
*/
/* enforce minimum length */
if (pwdlen < MIN_PWD_LENGTH)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("password is too short")));
/* check if the password contains the username */
if (strstr(password, username))
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("password must not contain user name")));
/* check if the password contains both letters and non-letters */
pwd_has_letter = false;
pwd_has_nonletter = false;
for (i = 0; i < pwdlen; i++)
{
/*
* isalpha() does not work for multibyte encodings but let's
* consider non-ASCII characters non-letters
*/
if (isalpha((unsigned char) password[i]))
pwd_has_letter = true;
else
pwd_has_nonletter = true;
}
if (!pwd_has_letter || !pwd_has_nonletter)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("password must contain both letters and nonletters")));
#ifdef USE_CRACKLIB
/* call cracklib to check password */
if (FascistCheck(password, CRACKLIB_DICTPATH))
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("password is easily cracked")));
#endif
break;
default:
elog(ERROR, "unrecognized password type: %d", password_type);
break;
}
/* all checks passed, password is ok */
}
Definition at line 28 of file passwordcheck.c.
1.7.1