password-scheme.c revision 69293bd0b4ceb47c7f12c4a01254f4cddf700470
02c335c23bf5fa225a467c19f2c063fb0dc7b8c3Timo Sirainen/* Copyright (C) 2003-2007 Timo Sirainen */
8f0503ea115c4bb1eb1857023cc5051cf4bed807Baofeng Wangstatic const char salt_chars[] =
1ae5d61ec366fdb2f3c5b150ca378d6141b0f4bdTimo Sirainen "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
1ae5d61ec366fdb2f3c5b150ca378d6141b0f4bdTimo SirainenARRAY_TYPE(password_scheme_p) password_schemes;
8f0503ea115c4bb1eb1857023cc5051cf4bed807Baofeng Wangstatic const struct password_scheme *
8f0503ea115c4bb1eb1857023cc5051cf4bed807Baofeng Wang unsigned int i, count;
1ae5d61ec366fdb2f3c5b150ca378d6141b0f4bdTimo Sirainen schemes = array_get(&password_schemes, &count);
8f0503ea115c4bb1eb1857023cc5051cf4bed807Baofeng Wang for (i = 0; i < count; i++) {
8f0503ea115c4bb1eb1857023cc5051cf4bed807Baofeng Wang/* Lookup scheme and encoding by given name. The encoding is taken from
8f0503ea115c4bb1eb1857023cc5051cf4bed807Baofeng Wang ".base64", ".b64" or ".hex" suffix if it exists, otherwise the default
1ae5d61ec366fdb2f3c5b150ca378d6141b0f4bdTimo Sirainen encoding is used. */
1ae5d61ec366fdb2f3c5b150ca378d6141b0f4bdTimo Sirainenstatic const struct password_scheme *
1ae5d61ec366fdb2f3c5b150ca378d6141b0f4bdTimo Sirainenpassword_scheme_lookup(const char *name, enum password_encoding *encoding_r)
1ae5d61ec366fdb2f3c5b150ca378d6141b0f4bdTimo Sirainen for (scheme_len = 0; name[scheme_len] != '\0'; scheme_len++) {
1ae5d61ec366fdb2f3c5b150ca378d6141b0f4bdTimo Sirainen /* unknown encoding. treat as invalid scheme. */
1ae5d61ec366fdb2f3c5b150ca378d6141b0f4bdTimo Sirainenint password_verify(const char *plaintext, const char *user, const char *scheme,
1ae5d61ec366fdb2f3c5b150ca378d6141b0f4bdTimo Sirainen const unsigned char *raw_password, size_t size)
1ae5d61ec366fdb2f3c5b150ca378d6141b0f4bdTimo Sirainen const struct password_scheme *s;
1ae5d61ec366fdb2f3c5b150ca378d6141b0f4bdTimo Sirainen const unsigned char *generated;
1ae5d61ec366fdb2f3c5b150ca378d6141b0f4bdTimo Sirainen s = password_scheme_lookup(scheme, &encoding);
1ae5d61ec366fdb2f3c5b150ca378d6141b0f4bdTimo Sirainen return s->password_verify(plaintext, user, raw_password, size);
25866546f1e8aabce4118c0690d76de49223e6a8Timo Sirainen /* generic verification handler: generate the password and compare it
25866546f1e8aabce4118c0690d76de49223e6a8Timo Sirainen to the one in database */
25866546f1e8aabce4118c0690d76de49223e6a8Timo Sirainen s->password_generate(plaintext, user, &generated, &generated_size);
25866546f1e8aabce4118c0690d76de49223e6a8Timo Sirainenconst char *password_get_scheme(const char **password)
25866546f1e8aabce4118c0690d76de49223e6a8Timo Sirainen const char *p, *scheme;
25866546f1e8aabce4118c0690d76de49223e6a8Timo Sirainen /* $1$<salt>$<password>[$<ignored>] */
25866546f1e8aabce4118c0690d76de49223e6a8Timo Sirainen /* stop at next '$' after password */
25866546f1e8aabce4118c0690d76de49223e6a8Timo Sirainen return "MD5-CRYPT";
76e5f0fe5e9e8bdee24d0e047378a665e01b808dTimo Sirainenint password_decode(const char *password, const char *scheme,
1ae5d61ec366fdb2f3c5b150ca378d6141b0f4bdTimo Sirainen const unsigned char **raw_password_r, size_t *size_r)
1ae5d61ec366fdb2f3c5b150ca378d6141b0f4bdTimo Sirainen const struct password_scheme *s;
8f0503ea115c4bb1eb1857023cc5051cf4bed807Baofeng Wang unsigned int len;
1ae5d61ec366fdb2f3c5b150ca378d6141b0f4bdTimo Sirainen s = password_scheme_lookup(scheme, &encoding);
25866546f1e8aabce4118c0690d76de49223e6a8Timo Sirainen if (encoding != PW_ENCODING_NONE && s->raw_password_len != 0 &&
25866546f1e8aabce4118c0690d76de49223e6a8Timo Sirainen /* encoding not specified. we can autodetect between
25866546f1e8aabce4118c0690d76de49223e6a8Timo Sirainen base64 and hex encodings. */
25866546f1e8aabce4118c0690d76de49223e6a8Timo Sirainen encoding = len == s->raw_password_len * 2 ? PW_ENCODING_HEX :
1ae5d61ec366fdb2f3c5b150ca378d6141b0f4bdTimo Sirainen *raw_password_r = (const unsigned char *)password;
1ae5d61ec366fdb2f3c5b150ca378d6141b0f4bdTimo Sirainen buf = buffer_create_static_hard(pool_datastack_create(),
1ae5d61ec366fdb2f3c5b150ca378d6141b0f4bdTimo Sirainen if (base64_decode(password, len, NULL, buf) < 0)
case PW_ENCODING_HEX:
const char *scheme,
const struct password_scheme *s;
if (s == NULL)
return FALSE;
return TRUE;
const struct password_scheme *s;
const unsigned char *raw_password;
if (s == NULL)
return FALSE;
switch (encoding) {
case PW_ENCODING_NONE:
case PW_ENCODING_BASE64:
case PW_ENCODING_HEX:
return TRUE;
unsigned int i, count;
return TRUE;
for (i = 0; i < count; i++) {
const char *password;
if (size == 0) {
return FALSE;
const char *password;
const char *password;
unsigned char *digest;
unsigned char *digest;
return FALSE;
return FALSE;
unsigned char *context_digest;
unsigned char *digest;
unsigned char *digest;
unsigned char *digest;
unsigned char *digest;
unsigned char *digest;
const char *password;
const char *password;
const char *password;
unsigned char *digest;
unsigned int i, count;
for (i = 0; i < count; i++) {
void password_schemes_init(void)
void password_schemes_deinit(void)