#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.