Mercurial > dovecot > core-2.2
changeset 13566:c9894346b1a3
auth: If password data isn't valid for specified scheme, give a better error message.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sat, 01 Oct 2011 16:48:17 +0300 |
parents | 1fd1321e55f4 |
children | c126a88546f8 |
files | src/auth/auth-request.c src/auth/passdb.c src/auth/password-scheme.c src/auth/password-scheme.h |
diffstat | 4 files changed, 37 insertions(+), 16 deletions(-) [+] |
line wrap: on
line diff
--- a/src/auth/auth-request.c Fri Sep 30 19:02:31 2011 +0300 +++ b/src/auth/auth-request.c Sat Oct 01 16:48:17 2011 +0300 @@ -1509,12 +1509,12 @@ } ret = password_decode(crypted_password, scheme, - &raw_password, &raw_password_size); + &raw_password, &raw_password_size, &error); if (ret <= 0) { if (ret < 0) { auth_request_log_error(request, subsystem, - "Password in passdb is not in expected scheme %s", - scheme); + "Password data is not valid for scheme %s: %s", + scheme, error); } else { auth_request_log_error(request, subsystem, "Unknown scheme %s", scheme);
--- a/src/auth/passdb.c Fri Sep 30 19:02:31 2011 +0300 +++ b/src/auth/passdb.c Sat Oct 01 16:48:17 2011 +0300 @@ -64,7 +64,7 @@ const unsigned char **credentials_r, size_t *size_r) { const char *wanted_scheme = auth_request->credentials_scheme; - const char *plaintext, *username; + const char *plaintext, *username, *error; int ret; if (auth_request->prefer_plain_credentials && @@ -74,12 +74,13 @@ wanted_scheme = ""; } - ret = password_decode(input, input_scheme, credentials_r, size_r); + ret = password_decode(input, input_scheme, + credentials_r, size_r, &error); if (ret <= 0) { if (ret < 0) { auth_request_log_error(auth_request, "password", - "Password in passdb is not in expected scheme %s", - input_scheme); + "Password data is not valid for scheme %s: %s", + input_scheme, error); } else { auth_request_log_error(auth_request, "password", "Unknown scheme %s", input_scheme);
--- a/src/auth/password-scheme.c Fri Sep 30 19:02:31 2011 +0300 +++ b/src/auth/password-scheme.c Sat Oct 01 16:48:17 2011 +0300 @@ -132,16 +132,22 @@ } int password_decode(const char *password, const char *scheme, - const unsigned char **raw_password_r, size_t *size_r) + const unsigned char **raw_password_r, size_t *size_r, + const char **error_r) { const struct password_scheme *s; enum password_encoding encoding; buffer_t *buf; unsigned int len; + bool guessed_encoding; + + *error_r = NULL; s = password_scheme_lookup(scheme, &encoding); - if (s == NULL) + if (s == NULL) { + *error_r = "Unknown scheme"; return 0; + } len = strlen(password); if (encoding != PW_ENCODING_NONE && s->raw_password_len != 0 && @@ -150,8 +156,11 @@ 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; + encoding = len == s->raw_password_len * 2 ? + PW_ENCODING_HEX : PW_ENCODING_BASE64; + guessed_encoding = TRUE; + } else { + guessed_encoding = FALSE; } switch (encoding) { @@ -167,14 +176,20 @@ *size_r = buf->used; break; } + if (!guessed_encoding) { + *error_r = "Input isn't valid HEX encoded data"; + return -1; + } /* 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_dynamic(pool_datastack_create(), MAX_BASE64_DECODED_SIZE(len)); - if (base64_decode(password, len, NULL, buf) < 0) + if (base64_decode(password, len, NULL, buf) < 0) { + *error_r = "Input isn't valid base64 encoded data"; return -1; + } *raw_password_r = buf->data; *size_r = buf->used; @@ -182,6 +197,9 @@ } if (s->raw_password_len != *size_r && s->raw_password_len != 0) { /* password has invalid length */ + *error_r = t_strdup_printf( + "Input length isn't valid (%u instead of %u)", + (unsigned int)*size_r, s->raw_password_len); return -1; } return 1; @@ -282,7 +300,8 @@ schemes = array_get(&password_schemes, &count); for (i = 0; i < count; i++) { if (password_decode(crypted_password, schemes[i]->name, - &raw_password, &raw_password_size) <= 0) + &raw_password, &raw_password_size, + &error) <= 0) continue; if (password_verify(plain_password, user, schemes[i]->name, @@ -332,7 +351,7 @@ md5_verify(const char *plaintext, const char *user, const unsigned char *raw_password, size_t size, const char **error_r) { - const char *password, *str; + const char *password, *str, *error; const unsigned char *md5_password; size_t md5_size; @@ -342,7 +361,7 @@ str = password_generate_md5_crypt(plaintext, password); return strcmp(str, password) == 0 ? 1 : 0; } else if (password_decode(password, "PLAIN-MD5", - &md5_password, &md5_size) < 0) { + &md5_password, &md5_size, &error) < 0) { *error_r = "Not a valid MD5-CRYPT or PLAIN-MD5 password"; return -1; } else {
--- a/src/auth/password-scheme.h Fri Sep 30 19:02:31 2011 +0300 +++ b/src/auth/password-scheme.h Sat Oct 01 16:48:17 2011 +0300 @@ -39,7 +39,8 @@ /* Decode encoded (base64/hex) password to raw form. Returns 1 if ok, 0 if scheme is unknown, -1 if password is invalid. */ int password_decode(const char *password, const char *scheme, - const unsigned char **raw_password_r, size_t *size_r); + const unsigned char **raw_password_r, size_t *size_r, + const char **error_r); /* Create password with wanted scheme out of plaintext password and username. Potential base64/hex directives are ignored in scheme. Returns FALSE if