fixes bug 150604 - digest authentication problem: Mozilla ignores the stale

flag from WWW-Authenticate Response Header.
patch=pach@cs.cmu.edu r=dougt sr=darin
This commit is contained in:
darin%netscape.com 2002-08-12 21:38:59 +00:00
parent 626d1cfe63
commit f4ffbe08da
4 changed files with 68 additions and 28 deletions

View File

@ -49,6 +49,13 @@ interface nsIHttpAuthenticator : nsISupports
*/
boolean areCredentialsReusable();
/**
* indicates if the challenge requires a new username/password (e.g.,
* if the response was invalid because the nonce has timed out, then
* the old username/password is still valid).
*/
boolean challengeRequiresUserPass(in string challenge);
/**
* allocate authenticator specific metadata implementation. implementations
* that don't need to store extra data in the auth cache can simply return NULL.

View File

@ -119,6 +119,14 @@ nsHttpBasicAuth::AreCredentialsReusable(PRBool *result)
return NS_OK;
}
NS_IMETHODIMP
nsHttpBasicAuth::ChallengeRequiresUserPass(const char *challenge,
PRBool *result)
{
*result = PR_TRUE;
return NS_OK;
}
NS_IMETHODIMP
nsHttpBasicAuth::AllocateMetaData(nsISupports **result)
{

View File

@ -1706,37 +1706,44 @@ nsHttpChannel::GetCredentials(const char *challenges,
//
nsHttpAuthEntry *entry = nsnull;
authCache->GetAuthEntryForDomain(host, port, realm.get(), &entry);
if (entry) {
if (user->Equals(entry->User()) && pass->Equals(entry->Pass())) {
LOG(("clearing bad credentials from the auth cache\n"));
// ok, we've already tried this user:pass combo, so clear the
// corresponding entry from the auth cache.
ClearPasswordManagerEntry(host, port, realm.get(), entry->User());
authCache->SetAuthEntry(host, port, nsnull, realm.get(),
nsnull, nsnull, nsnull, nsnull, nsnull);
entry = nsnull;
user->Adopt(0);
pass->Adopt(0);
}
else {
LOG(("taking user:pass from auth cache\n"));
user->Adopt(nsCRT::strdup(entry->User()));
pass->Adopt(nsCRT::strdup(entry->Pass()));
if (entry->Creds()) {
LOG(("using cached credentials!\n"));
creds.Assign(entry->Creds());
return NS_OK;
PRBool requireUserPass = PR_FALSE;
rv = auth->ChallengeRequiresUserPass(challenge.get(), &requireUserPass);
if (NS_FAILED(rv)) return rv;
if (requireUserPass) {
if (entry) {
if (user->Equals(entry->User()) && pass->Equals(entry->Pass())) {
LOG(("clearing bad credentials from the auth cache\n"));
// ok, we've already tried this user:pass combo, so clear the
// corresponding entry from the auth cache.
ClearPasswordManagerEntry(host, port, realm.get(), entry->User());
authCache->SetAuthEntry(host, port, nsnull, realm.get(),
nsnull, nsnull, nsnull, nsnull, nsnull);
entry = nsnull;
user->Adopt(0);
pass->Adopt(0);
}
else {
LOG(("taking user:pass from auth cache\n"));
user->Adopt(nsCRT::strdup(entry->User()));
pass->Adopt(nsCRT::strdup(entry->Pass()));
if (entry->Creds()) {
LOG(("using cached credentials!\n"));
creds.Assign(entry->Creds());
return NS_OK;
}
}
}
}
if (!entry && user->IsEmpty()) {
// at this point we are forced to interact with the user to get their
// username and password for this domain.
rv = PromptForUserPass(host, port, proxyAuth, realm.get(),
getter_Copies(*user),
getter_Copies(*pass));
if (NS_FAILED(rv)) return rv;
if (!entry && user->IsEmpty()) {
// at this point we are forced to interact with the user to get their
// username and password for this domain.
rv = PromptForUserPass(host, port, proxyAuth, realm.get(),
getter_Copies(*user),
getter_Copies(*pass));
if (NS_FAILED(rv)) return rv;
}
}
// ask the auth cache for a container for any meta data it might want to

View File

@ -272,6 +272,24 @@ nsHttpDigestAuth::AreCredentialsReusable(PRBool *result)
return NS_OK;
}
NS_IMETHODIMP
nsHttpDigestAuth::ChallengeRequiresUserPass(const char *challenge,
PRBool *result)
{
nsCAutoString realm, domain, nonce, opaque;
PRBool stale;
PRUint16 algorithm, qop;
nsresult rv = ParseChallenge(challenge, realm, domain, nonce, opaque,
&stale, &algorithm, &qop);
if (NS_FAILED(rv)) {
*result = PR_TRUE;
return rv;
}
*result = !stale;
return NS_OK;
}
NS_IMETHODIMP
nsHttpDigestAuth::AllocateMetaData(nsISupports **result)
{