/* 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
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;
enum qop_option qop;
/* received: */
- char *realm; /* may be NULL */
char *username;
char *cnonce;
char *nonce_count;
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;
}
}
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,
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 &&
/* 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);
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;