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

dovecot at dovecot.org dovecot at dovecot.org
Sat Oct 1 16:41:11 EEST 2011


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

diffstat:

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

diffs (176 lines):

diff -r 9007d5de0e87 -r dfb38f346e8c src/auth/auth-request.c
--- a/src/auth/auth-request.c	Fri Sep 30 19:03:49 2011 +0300
+++ b/src/auth/auth-request.c	Sat Oct 01 16:49:30 2011 +0300
@@ -1468,6 +1468,7 @@
 {
 	const unsigned char *raw_password;
 	size_t raw_password_size;
+	const char *error;
 	int ret;
 
 	if (request->skip_password_check) {
@@ -1488,12 +1489,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 9007d5de0e87 -r dfb38f346e8c src/auth/passdb.c
--- a/src/auth/passdb.c	Fri Sep 30 19:03:49 2011 +0300
+++ b/src/auth/passdb.c	Sat Oct 01 16:49:30 2011 +0300
@@ -63,7 +63,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 &&
@@ -73,12 +73,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 9007d5de0e87 -r dfb38f346e8c src/auth/password-scheme.c
--- a/src/auth/password-scheme.c	Fri Sep 30 19:03:49 2011 +0300
+++ b/src/auth/password-scheme.c	Sat Oct 01 16:49:30 2011 +0300
@@ -127,16 +127,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 &&
@@ -145,8 +151,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) {
@@ -162,14 +171,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;
@@ -177,6 +192,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;
@@ -272,11 +290,13 @@
 	unsigned int i, count;
 	const unsigned char *raw_password;
 	size_t raw_password_size;
+	const char *error;
 
 	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,
@@ -324,7 +344,7 @@
 md5_verify(const char *plaintext, const char *user,
 	   const unsigned char *raw_password, size_t size)
 {
-	const char *password, *str;
+	const char *password, *str, *error;
 	const unsigned char *md5_password;
 	size_t md5_size;
 
@@ -334,7 +354,7 @@
 		str = password_generate_md5_crypt(plaintext, password);
 		return strcmp(str, password) == 0;
 	} else if (password_decode(password, "PLAIN-MD5",
-				   &md5_password, &md5_size) < 0) {
+				   &md5_password, &md5_size, &error) < 0) {
 		i_error("md5_verify(%s): Not a valid MD5-CRYPT or "
 			"PLAIN-MD5 password", user);
 		return FALSE;
diff -r 9007d5de0e87 -r dfb38f346e8c src/auth/password-scheme.h
--- a/src/auth/password-scheme.h	Fri Sep 30 19:03:49 2011 +0300
+++ b/src/auth/password-scheme.h	Sat Oct 01 16:49:30 2011 +0300
@@ -36,7 +36,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