Mercurial > dovecot > original-hg > dovecot-1.2
changeset 8766:888f57b1bf9c HEAD
DIGEST-MD5: Fixed authentication with user@domain usernames.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sat, 21 Feb 2009 17:10:43 -0500 |
parents | d69763bee853 |
children | e82e0a6b9399 |
files | src/auth/auth-request.h src/auth/mech-digest-md5.c src/auth/passdb.c src/auth/password-scheme.c |
diffstat | 4 files changed, 38 insertions(+), 17 deletions(-) [+] |
line wrap: on
line diff
--- 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 @@ /* 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 @@ 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;
--- 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 @@ enum qop_option qop; /* received: */ - char *realm; /* may be NULL */ char *username; char *cnonce; char *nonce_count; @@ -300,8 +299,9 @@ 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 @@ } 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,
--- 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 @@ 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 @@ /* 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); + "Generating %s from user '%s', password '%s'", + wanted_scheme, username, plaintext); } - if (!password_generate(plaintext, - auth_request->original_username, + if (!password_generate(plaintext, username, wanted_scheme, credentials_r, size_r)) { auth_request_log_error(auth_request, "password", "Requested unknown scheme %s", wanted_scheme);
--- 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 @@ if (user == NULL) i_fatal("digest_md5_generate(): username not given"); - /* user:realm:passwd */ - realm = strchr(user, '@'); - if (realm != NULL) realm++; else realm = ""; + /* assume user@realm format for username. If user@domain is wanted + in the username, allow also user@domain@realm. */ + realm = strrchr(user, '@'); + if (realm != NULL) { + user = t_strdup_until(user, realm); + realm++; + } else { + user = realm; + realm = ""; + } + + /* user:realm:passwd */ 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;