dovecot-1.2: DIGEST-MD5: Fixed authentication with user at domain u...

dovecot at dovecot.org dovecot at dovecot.org
Sun Feb 22 00:10:50 EET 2009


details:   http://hg.dovecot.org/dovecot-1.2/rev/888f57b1bf9c
changeset: 8766:888f57b1bf9c
user:      Timo Sirainen <tss at iki.fi>
date:      Sat Feb 21 17:10:43 2009 -0500
description:
DIGEST-MD5: Fixed authentication with user at domain usernames.

diffstat:

4 files changed, 39 insertions(+), 18 deletions(-)
src/auth/auth-request.h    |    3 +++
src/auth/mech-digest-md5.c |   17 +++++++++++------
src/auth/passdb.c          |   19 ++++++++++++-------
src/auth/password-scheme.c |   18 +++++++++++++-----

diffs (129 lines):

diff -r d69763bee853 -r 888f57b1bf9c src/auth/auth-request.h
--- a/src/auth/auth-request.h	Sat Feb 21 14:59:33 2009 -0500
+++ b/src/auth/auth-request.h	Sat Feb 21 17:10:43 2009 -0500
@@ -40,6 +40,8 @@ struct auth_request {
 	/* the username after doing all internal translations, but before
 	   being changed by a db lookup */
 	const char *translated_username;
+	/* realm for the request, may be specified by some auth mechanisms */
+	const char *realm;
 	char *mech_password; /* set if verify_plain() is called */
 	char *passdb_password; /* set after password lookup if successful */
         /* extra_fields are returned in authentication reply. Fields prefixed
@@ -84,6 +86,7 @@ struct auth_request {
 	unsigned int passdb_internal_failure:1;
 	unsigned int userdb_internal_failure:1;
 	unsigned int delayed_failure:1;
+	unsigned int domain_is_realm:1;
 	unsigned int accept_input:1;
 	unsigned int no_failure_delay:1;
 	unsigned int no_login:1;
diff -r d69763bee853 -r 888f57b1bf9c src/auth/mech-digest-md5.c
--- a/src/auth/mech-digest-md5.c	Sat Feb 21 14:59:33 2009 -0500
+++ b/src/auth/mech-digest-md5.c	Sat Feb 21 17:10:43 2009 -0500
@@ -41,7 +41,6 @@ struct digest_auth_request {
 	enum qop_option qop;
 
 	/* received: */
-	char *realm; /* may be NULL */
 	char *username;
 	char *cnonce;
 	char *nonce_count;
@@ -300,8 +299,9 @@ static bool auth_handle_response(struct 
 					str_sanitize(value, MAX_REALM_LEN));
 			return FALSE;
 		}
-		if (request->realm == NULL && *value != '\0')
-			request->realm = p_strdup(request->pool, value);
+		if (request->auth_request.realm == NULL && *value != '\0')
+			request->auth_request.realm =
+				p_strdup(request->pool, value);
 		return TRUE;
 	}
 
@@ -551,9 +551,14 @@ mech_digest_md5_auth_continue(struct aut
 	}
 
 	if (parse_digest_response(request, data, data_size, &error)) {
-		username = request->realm == NULL ? request->username :
-			t_strconcat(request->username, "@",
-				    request->realm, NULL);
+		if (auth_request->realm != NULL &&
+		    strchr(request->username, '@') == NULL) {
+			username = t_strconcat(request->username, "@",
+					       auth_request->realm, NULL);
+			auth_request->domain_is_realm = TRUE;
+		} else {
+			username = request->username;
+		}
 
 		if (auth_request_set_username(auth_request, username, &error)) {
 			auth_request_lookup_credentials(auth_request,
diff -r d69763bee853 -r 888f57b1bf9c src/auth/passdb.c
--- a/src/auth/passdb.c	Sat Feb 21 14:59:33 2009 -0500
+++ b/src/auth/passdb.c	Sat Feb 21 17:10:43 2009 -0500
@@ -52,7 +52,7 @@ bool passdb_get_credentials(struct auth_
 			    const unsigned char **credentials_r, size_t *size_r)
 {
 	const char *wanted_scheme = auth_request->credentials_scheme;
-	const char *plaintext;
+	const char *plaintext, *username;
 	int ret;
 
 	if (auth_request->prefer_plain_credentials &&
@@ -99,14 +99,19 @@ bool passdb_get_credentials(struct auth_
 
 		/* we can generate anything out of plaintext passwords */
 		plaintext = t_strndup(*credentials_r, *size_r);
+		username = auth_request->original_username;
+		if (!auth_request->domain_is_realm &&
+		    strchr(username, '@') != NULL) {
+			/* domain must not be used as realm. add the @realm. */
+			username = t_strconcat(username, "@",
+					       auth_request->realm, NULL);
+		}
 		if (auth_request->auth->verbose_debug_passwords) {
 			auth_request_log_info(auth_request, "password",
-				"Generating %s from user %s password %s",
-				wanted_scheme, auth_request->original_username,
-				plaintext);
-		}
-		if (!password_generate(plaintext,
-				       auth_request->original_username,
+				"Generating %s from user '%s', password '%s'",
+				wanted_scheme, username, plaintext);
+		}
+		if (!password_generate(plaintext, username,
 				       wanted_scheme, credentials_r, size_r)) {
 			auth_request_log_error(auth_request, "password",
 				"Requested unknown scheme %s", wanted_scheme);
diff -r d69763bee853 -r 888f57b1bf9c src/auth/password-scheme.c
--- a/src/auth/password-scheme.c	Sat Feb 21 14:59:33 2009 -0500
+++ b/src/auth/password-scheme.c	Sat Feb 21 17:10:43 2009 -0500
@@ -517,13 +517,21 @@ digest_md5_generate(const char *plaintex
 	if (user == NULL)
 		i_fatal("digest_md5_generate(): username not given");
 
+
+	/* assume user at realm format for username. If user at domain is wanted
+	   in the username, allow also user at domain@realm. */
+	realm = strrchr(user, '@');
+	if (realm != NULL) {
+		user = t_strdup_until(user, realm);
+		realm++;
+	} else {
+		user = realm;
+		realm = "";
+	}
+
 	/* user:realm:passwd */
-	realm = strchr(user, '@');
-	if (realm != NULL) realm++; else realm = "";
-
 	digest = t_malloc(MD5_RESULTLEN);
-	str = t_strdup_printf("%s:%s:%s", t_strcut(user, '@'),
-			      realm, plaintext);
+	str = t_strdup_printf("%s:%s:%s", user, realm, plaintext);
 	md5_get_digest(str, strlen(str), digest);
 
 	*raw_password_r = digest;


More information about the dovecot-cvs mailing list