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

dovecot at dovecot.org dovecot at dovecot.org
Sun Feb 22 00:07:24 EET 2009


details:   http://hg.dovecot.org/dovecot-1.1/rev/2b0043ba89ae
changeset: 8170:2b0043ba89ae
user:      Timo Sirainen <tss at iki.fi>
date:      Sat Feb 21 17:07:11 2009 -0500
description:
DIGEST-MD5: Fixed authentication with user at domain usernames.

diffstat:

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

diffs (111 lines):

diff -r bb7ac37f78ee -r 2b0043ba89ae 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:07:11 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 bb7ac37f78ee -r 2b0043ba89ae 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:07:11 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 bb7ac37f78ee -r 2b0043ba89ae 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:07:11 2009 -0500
@@ -101,9 +101,15 @@ bool passdb_get_credentials(struct auth_
 		plaintext = t_strndup(*credentials_r, *size_r);
 		username = auth_request->original_username != NULL ?
 			auth_request->original_username : auth_request->user;
+		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",
+				"Generating %s from user '%s', password '%s'",
 				wanted_scheme, username, plaintext);
 		}
 		if (!password_generate(plaintext, username,
diff -r bb7ac37f78ee -r 2b0043ba89ae 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:07:11 2009 -0500
@@ -448,13 +448,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