dovecot-2.1: auth: If password data isn't valid for specified sc...

dovecot at dovecot.org dovecot at dovecot.org
Sat Oct 1 16:39:57 EEST 2011


details:   http://hg.dovecot.org/dovecot-2.1/rev/c9894346b1a3
changeset: 13566:c9894346b1a3
user:      Timo Sirainen <tss at iki.fi>
date:      Sat Oct 01 16:48:17 2011 +0300
description:
auth: If password data isn't valid for specified scheme, give a better error message.

diffstat:

 src/auth/auth-request.c    |   6 +++---
 src/auth/passdb.c          |   9 +++++----
 src/auth/password-scheme.c |  35 +++++++++++++++++++++++++++--------
 src/auth/password-scheme.h |   3 ++-
 4 files changed, 37 insertions(+), 16 deletions(-)

diffs (163 lines):

diff -r 1fd1321e55f4 -r c9894346b1a3 src/auth/auth-request.c
--- 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);
diff -r 1fd1321e55f4 -r c9894346b1a3 src/auth/passdb.c
--- 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);
diff -r 1fd1321e55f4 -r c9894346b1a3 src/auth/password-scheme.c
--- 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 {
diff -r 1fd1321e55f4 -r c9894346b1a3 src/auth/password-scheme.h
--- 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


More information about the dovecot-cvs mailing list