Mercurial > dovecot > original-hg > dovecot-1.2
changeset 7984:399b81cc6189 HEAD
MD5 scheme can now autodetect between MD5-CRYPT and PLAIN-MD5.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Wed, 09 Jul 2008 17:50:29 +0530 |
parents | ba581bed8cc7 |
children | a6d187abaa5a |
files | src/auth/password-scheme.c |
diffstat | 1 files changed, 39 insertions(+), 12 deletions(-) [+] |
line wrap: on
line diff
--- a/src/auth/password-scheme.c Wed Jul 09 14:51:08 2008 +0530 +++ b/src/auth/password-scheme.c Wed Jul 09 17:50:29 2008 +0530 @@ -141,8 +141,10 @@ len = strlen(password); if (encoding != PW_ENCODING_NONE && s->raw_password_len != 0 && strchr(scheme, '.') == NULL) { - /* encoding not specified. we can autodetect between - base64 and hex encodings. */ + /* encoding not specified. we can guess quite well between + base64 and hex encodings. the only problem is distinguishing + 2 character strings, but there shouldn't be any that short + raw_password_lens. */ encoding = len == s->raw_password_len * 2 ? PW_ENCODING_HEX : PW_ENCODING_BASE64; } @@ -152,6 +154,17 @@ *raw_password_r = (const unsigned char *)password; *size_r = len; break; + case PW_ENCODING_HEX: + buf = buffer_create_static_hard(pool_datastack_create(), + len / 2 + 1); + if (hex_to_binary(password, buf) == 0) { + *raw_password_r = buf->data; + *size_r = buf->used; + break; + } + /* fall through, just in case it was base64-encoded after + all. some input lengths produce matching hex and base64 + encoded lengths. */ case PW_ENCODING_BASE64: buf = buffer_create_static_hard(pool_datastack_create(), MAX_BASE64_DECODED_SIZE(len)); @@ -161,15 +174,6 @@ *raw_password_r = buf->data; *size_r = buf->used; break; - case PW_ENCODING_HEX: - buf = buffer_create_static_hard(pool_datastack_create(), - len / 2 + 1); - if (hex_to_binary(password, buf) < 0) - return -1; - - *raw_password_r = buf->data; - *size_r = buf->used; - break; } if (s->raw_password_len != *size_r && s->raw_password_len != 0) { /* password has invalid length */ @@ -280,6 +284,29 @@ } static bool +md5_verify(const char *plaintext, const char *user, + const unsigned char *raw_password, size_t size) +{ + const char *password, *str; + const unsigned char *md5_password; + size_t md5_size; + + password = t_strndup(raw_password, size); + if (strncmp(password, "$1$", 3) == 0) { + /* MD5-CRYPT */ + str = password_generate_md5_crypt(plaintext, password); + return strcmp(str, password) == 0; + } else { + if (password_decode(password, "PLAIN-MD5", + &md5_password, &md5_size) < 0) + return FALSE; + + return password_verify(plaintext, user, "PLAIN-MD5", + md5_password, md5_size) > 0; + } +} + +static bool md5_crypt_verify(const char *plaintext, const char *user ATTR_UNUSED, const unsigned char *raw_password, size_t size) { @@ -560,7 +587,7 @@ static const struct password_scheme builtin_schemes[] = { { "CRYPT", PW_ENCODING_NONE, 0, crypt_verify, crypt_generate }, - { "MD5", PW_ENCODING_NONE, 0, md5_crypt_verify, md5_crypt_generate }, + { "MD5", PW_ENCODING_NONE, 0, md5_verify, md5_crypt_generate }, { "MD5-CRYPT", PW_ENCODING_NONE, 0, md5_crypt_verify, md5_crypt_generate }, { "SHA", PW_ENCODING_BASE64, SHA1_RESULTLEN, NULL, sha1_generate },