mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-28 15:23:51 +00:00
Bug 814247 - Add auth cache jars for separate apps. r=mayhemer
This commit is contained in:
parent
68a13d6a9f
commit
fbf5889d74
@ -40,7 +40,7 @@ function testHttpAuthCancel(e) {
|
||||
iframe.addEventListener("mozbrowsertitlechange", function onTitleChange(e) {
|
||||
iframe.removeEventListener("mozbrowsertitlechange", onTitleChange);
|
||||
iframe.removeEventListener("mozbrowserusernameandpasswordrequired", testFail);
|
||||
is(e.detail, 'http auth failed');
|
||||
is(e.detail, 'http auth failed', 'expected authentication to fail');
|
||||
iframe.addEventListener('mozbrowserusernameandpasswordrequired', testHttpAuth);
|
||||
SimpleTest.executeSoon(function() {
|
||||
// Use absolute path because we need to specify host.
|
||||
@ -48,8 +48,8 @@ function testHttpAuthCancel(e) {
|
||||
});
|
||||
});
|
||||
|
||||
is(e.detail.realm, 'http_realm');
|
||||
is(e.detail.host, 'http://test');
|
||||
is(e.detail.realm, 'http_realm', 'expected realm matches');
|
||||
is(e.detail.host, 'http://test', 'expected host matches');
|
||||
e.preventDefault();
|
||||
|
||||
SimpleTest.executeSoon(function() {
|
||||
@ -66,12 +66,12 @@ function testHttpAuth(e) {
|
||||
iframe.addEventListener("mozbrowsertitlechange", function onTitleChange(e) {
|
||||
iframe.removeEventListener("mozbrowsertitlechange", onTitleChange);
|
||||
iframe.removeEventListener("mozbrowserusernameandpasswordrequired", testFail);
|
||||
is(e.detail, 'http auth success');
|
||||
SimpleTest.executeSoon(testFinish);
|
||||
is(e.detail, 'http auth success', 'expect authentication to succeed');
|
||||
SimpleTest.executeSoon(testAuthJarNoInterfere);
|
||||
});
|
||||
|
||||
is(e.detail.realm, 'http_realm');
|
||||
is(e.detail.host, 'http://test');
|
||||
is(e.detail.realm, 'http_realm', 'expected realm matches');
|
||||
is(e.detail.host, 'http://test', 'expected host matches');
|
||||
e.preventDefault();
|
||||
|
||||
SimpleTest.executeSoon(function() {
|
||||
@ -79,7 +79,77 @@ function testHttpAuth(e) {
|
||||
});
|
||||
}
|
||||
|
||||
function testAuthJarNoInterfere(e) {
|
||||
var authMgr = SpecialPowers.Cc['@mozilla.org/network/http-auth-manager;1']
|
||||
.getService(SpecialPowers.Ci.nsIHttpAuthManager);
|
||||
var secMan = SpecialPowers.Cc["@mozilla.org/scriptsecuritymanager;1"]
|
||||
.getService(SpecialPowers.Ci.nsIScriptSecurityManager);
|
||||
var ioService = SpecialPowers.Cc["@mozilla.org/network/io-service;1"]
|
||||
.getService(SpecialPowers.Ci.nsIIOService);
|
||||
var uri = ioService.newURI("http://test/tests/dom/browser-element/mochitest/file_http_401_response.sjs", null, null);
|
||||
|
||||
// Set a bunch of auth data that should not conflict with the correct auth data already
|
||||
// stored in the cache.
|
||||
var principal = secMan.getAppCodebasePrincipal(uri, 1, false);
|
||||
authMgr.setAuthIdentity('http', 'test', -1, 'basic', 'http_realm',
|
||||
'tests/dom/browser-element/mochitest/file_http_401_response.sjs',
|
||||
'', 'httpuser', 'wrongpass', false, principal);
|
||||
principal = secMan.getAppCodebasePrincipal(uri, 1, true);
|
||||
authMgr.setAuthIdentity('http', 'test', -1, 'basic', 'http_realm',
|
||||
'tests/dom/browser-element/mochitest/file_http_401_response.sjs',
|
||||
'', 'httpuser', 'wrongpass', false, principal);
|
||||
principal = secMan.getAppCodebasePrincipal(uri, secMan.NO_APP_ID, false);
|
||||
authMgr.setAuthIdentity('http', 'test', -1, 'basic', 'http_realm',
|
||||
'tests/dom/browser-element/mochitest/file_http_401_response.sjs',
|
||||
'', 'httpuser', 'wrongpass', false, principal);
|
||||
|
||||
// Will authenticate with correct password, prompt should not be
|
||||
// called again.
|
||||
iframe.addEventListener("mozbrowserusernameandpasswordrequired", testFail);
|
||||
iframe.addEventListener("mozbrowsertitlechange", function onTitleChange(e) {
|
||||
iframe.removeEventListener("mozbrowsertitlechange", onTitleChange);
|
||||
iframe.removeEventListener("mozbrowserusernameandpasswordrequired", testFail);
|
||||
is(e.detail, 'http auth success', 'expected authentication success');
|
||||
SimpleTest.executeSoon(testAuthJarInterfere);
|
||||
});
|
||||
|
||||
// Once more with feeling. Ensure that our new auth data doesn't interfere with this mozbrowser's
|
||||
// auth data.
|
||||
iframe.src = 'http://test/tests/dom/browser-element/mochitest/file_http_401_response.sjs';
|
||||
}
|
||||
|
||||
function testAuthJarInterfere(e) {
|
||||
var authMgr = SpecialPowers.Cc['@mozilla.org/network/http-auth-manager;1']
|
||||
.getService(SpecialPowers.Ci.nsIHttpAuthManager);
|
||||
var secMan = SpecialPowers.Cc["@mozilla.org/scriptsecuritymanager;1"]
|
||||
.getService(SpecialPowers.Ci.nsIScriptSecurityManager);
|
||||
var ioService = SpecialPowers.Cc["@mozilla.org/network/io-service;1"]
|
||||
.getService(SpecialPowers.Ci.nsIIOService);
|
||||
var uri = ioService.newURI("http://test/tests/dom/browser-element/mochitest/file_http_401_response.sjs", null, null);
|
||||
|
||||
// Set some auth data that should overwrite the successful stored details.
|
||||
var principal = secMan.getAppCodebasePrincipal(uri, secMan.NO_APP_ID, true);
|
||||
authMgr.setAuthIdentity('http', 'test', -1, 'basic', 'http_realm',
|
||||
'tests/dom/browser-element/mochitest/file_http_401_response.sjs',
|
||||
'', 'httpuser', 'wrongpass', false, principal);
|
||||
|
||||
// Will authenticate with correct password, prompt should not be
|
||||
// called again.
|
||||
iframe.addEventListener("mozbrowserusernameandpasswordrequired", testFinish);
|
||||
iframe.addEventListener("mozbrowsertitlechange", function onTitleChange(e) {
|
||||
iframe.removeEventListener("mozbrowsertitlechange", onTitleChange);
|
||||
iframe.removeEventListener("mozbrowserusernameandpasswordrequired", testFinish);
|
||||
SimpleTest.execute(testFail);
|
||||
});
|
||||
|
||||
// Once more with feeling. Ensure that our new auth data interferes with this mozbrowser's
|
||||
// auth data.
|
||||
iframe.src = 'http://test/tests/dom/browser-element/mochitest/file_http_401_response.sjs';
|
||||
}
|
||||
|
||||
function testFinish() {
|
||||
iframe.removeEventListener("mozbrowserusernameandpasswordrequired", testFinish);
|
||||
|
||||
// Clear login information stored in password manager.
|
||||
var authMgr = SpecialPowers.Cc['@mozilla.org/network/http-auth-manager;1']
|
||||
.getService(SpecialPowers.Ci.nsIHttpAuthManager);
|
||||
|
@ -2771,12 +2771,16 @@ _getauthenticationinfo(NPP instance, const char *protocol, const char *host,
|
||||
bool authPrivate = false;
|
||||
GetPrivacyFromNPP(instance, &authPrivate);
|
||||
|
||||
nsIDocument *doc = GetDocumentFromNPP(instance);
|
||||
NS_ENSURE_TRUE(doc, NPERR_GENERIC_ERROR);
|
||||
nsIPrincipal *principal = doc->NodePrincipal();
|
||||
|
||||
nsAutoString unused, uname16, pwd16;
|
||||
if (NS_FAILED(authManager->GetAuthIdentity(proto, nsDependentCString(host),
|
||||
port, nsDependentCString(scheme),
|
||||
nsDependentCString(realm),
|
||||
EmptyCString(), unused, uname16,
|
||||
pwd16, authPrivate))) {
|
||||
pwd16, authPrivate, principal))) {
|
||||
return NPERR_GENERIC_ERROR;
|
||||
}
|
||||
|
||||
|
@ -9,11 +9,20 @@
|
||||
#include "nsString.h"
|
||||
#include "nsCRT.h"
|
||||
#include "prprf.h"
|
||||
#include "mozIApplicationClearPrivateDataParams.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "mozilla/Services.h"
|
||||
#include "nsNetUtil.h"
|
||||
|
||||
static inline void
|
||||
GetAuthKey(const char *scheme, const char *host, int32_t port, nsCString &key)
|
||||
GetAuthKey(const char *scheme, const char *host, int32_t port, uint32_t appId, bool inBrowserElement, nsCString &key)
|
||||
{
|
||||
key.Assign(scheme);
|
||||
key.Truncate();
|
||||
key.AppendInt(appId);
|
||||
key.Append(':');
|
||||
key.AppendInt(inBrowserElement);
|
||||
key.Append(':');
|
||||
key.Append(scheme);
|
||||
key.AppendLiteral("://");
|
||||
key.Append(host);
|
||||
key.Append(':');
|
||||
@ -41,13 +50,23 @@ StrEquivalent(const PRUnichar *a, const PRUnichar *b)
|
||||
|
||||
nsHttpAuthCache::nsHttpAuthCache()
|
||||
: mDB(nullptr)
|
||||
, mObserver(new AppDataClearObserver(this))
|
||||
{
|
||||
nsCOMPtr<nsIObserverService> obsSvc = mozilla::services::GetObserverService();
|
||||
if (obsSvc) {
|
||||
obsSvc->AddObserver(mObserver, "webapps-clear-data", false);
|
||||
}
|
||||
}
|
||||
|
||||
nsHttpAuthCache::~nsHttpAuthCache()
|
||||
{
|
||||
if (mDB)
|
||||
ClearAll();
|
||||
nsCOMPtr<nsIObserverService> obsSvc = mozilla::services::GetObserverService();
|
||||
if (obsSvc) {
|
||||
obsSvc->RemoveObserver(mObserver, "webapps-clear-data");
|
||||
mObserver->mOwner = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
@ -71,13 +90,15 @@ nsHttpAuthCache::GetAuthEntryForPath(const char *scheme,
|
||||
const char *host,
|
||||
int32_t port,
|
||||
const char *path,
|
||||
uint32_t appId,
|
||||
bool inBrowserElement,
|
||||
nsHttpAuthEntry **entry)
|
||||
{
|
||||
LOG(("nsHttpAuthCache::GetAuthEntryForPath [key=%s://%s:%d path=%s]\n",
|
||||
scheme, host, port, path));
|
||||
|
||||
nsAutoCString key;
|
||||
nsHttpAuthNode *node = LookupAuthNode(scheme, host, port, key);
|
||||
nsHttpAuthNode *node = LookupAuthNode(scheme, host, port, appId, inBrowserElement, key);
|
||||
if (!node)
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
@ -90,6 +111,8 @@ nsHttpAuthCache::GetAuthEntryForDomain(const char *scheme,
|
||||
const char *host,
|
||||
int32_t port,
|
||||
const char *realm,
|
||||
uint32_t appId,
|
||||
bool inBrowserElement,
|
||||
nsHttpAuthEntry **entry)
|
||||
|
||||
{
|
||||
@ -97,7 +120,7 @@ nsHttpAuthCache::GetAuthEntryForDomain(const char *scheme,
|
||||
scheme, host, port, realm));
|
||||
|
||||
nsAutoCString key;
|
||||
nsHttpAuthNode *node = LookupAuthNode(scheme, host, port, key);
|
||||
nsHttpAuthNode *node = LookupAuthNode(scheme, host, port, appId, inBrowserElement, key);
|
||||
if (!node)
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
@ -113,6 +136,8 @@ nsHttpAuthCache::SetAuthEntry(const char *scheme,
|
||||
const char *realm,
|
||||
const char *creds,
|
||||
const char *challenge,
|
||||
uint32_t appId,
|
||||
bool inBrowserElement,
|
||||
const nsHttpAuthIdentity *ident,
|
||||
nsISupports *metadata)
|
||||
{
|
||||
@ -127,7 +152,7 @@ nsHttpAuthCache::SetAuthEntry(const char *scheme,
|
||||
}
|
||||
|
||||
nsAutoCString key;
|
||||
nsHttpAuthNode *node = LookupAuthNode(scheme, host, port, key);
|
||||
nsHttpAuthNode *node = LookupAuthNode(scheme, host, port, appId, inBrowserElement, key);
|
||||
|
||||
if (!node) {
|
||||
// create a new entry node and set the given entry
|
||||
@ -149,13 +174,15 @@ void
|
||||
nsHttpAuthCache::ClearAuthEntry(const char *scheme,
|
||||
const char *host,
|
||||
int32_t port,
|
||||
const char *realm)
|
||||
const char *realm,
|
||||
uint32_t appId,
|
||||
bool inBrowserElement)
|
||||
{
|
||||
if (!mDB)
|
||||
return;
|
||||
|
||||
nsAutoCString key;
|
||||
GetAuthKey(scheme, host, port, key);
|
||||
GetAuthKey(scheme, host, port, appId, inBrowserElement, key);
|
||||
PL_HashTableRemove(mDB, key.get());
|
||||
}
|
||||
|
||||
@ -179,12 +206,14 @@ nsHttpAuthNode *
|
||||
nsHttpAuthCache::LookupAuthNode(const char *scheme,
|
||||
const char *host,
|
||||
int32_t port,
|
||||
uint32_t appId,
|
||||
bool inBrowserElement,
|
||||
nsCString &key)
|
||||
{
|
||||
if (!mDB)
|
||||
return nullptr;
|
||||
|
||||
GetAuthKey(scheme, host, port, key);
|
||||
GetAuthKey(scheme, host, port, appId, inBrowserElement, key);
|
||||
|
||||
return (nsHttpAuthNode *) PL_HashTableLookup(mDB, key.get());
|
||||
}
|
||||
@ -232,6 +261,62 @@ PLHashAllocOps nsHttpAuthCache::gHashAllocOps =
|
||||
nsHttpAuthCache::FreeEntry
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsHttpAuthCache::AppDataClearObserver, nsIObserver)
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHttpAuthCache::AppDataClearObserver::Observe(nsISupports *subject,
|
||||
const char * topic,
|
||||
const PRUnichar * data_unicode)
|
||||
{
|
||||
NS_ENSURE_TRUE(mOwner, NS_ERROR_NOT_AVAILABLE);
|
||||
|
||||
nsCOMPtr<mozIApplicationClearPrivateDataParams> params =
|
||||
do_QueryInterface(subject);
|
||||
if (!params) {
|
||||
NS_ERROR("'webapps-clear-data' notification's subject should be a mozIApplicationClearPrivateDataParams");
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
uint32_t appId;
|
||||
bool browserOnly;
|
||||
|
||||
nsresult rv = params->GetAppId(&appId);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = params->GetBrowserOnly(&browserOnly);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
MOZ_ASSERT(appId != NECKO_UNKNOWN_APP_ID);
|
||||
mOwner->ClearAppData(appId, browserOnly);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static int
|
||||
RemoveEntriesForApp(PLHashEntry *entry, int32_t number, void *arg)
|
||||
{
|
||||
nsDependentCString key(static_cast<const char*>(entry->key));
|
||||
nsAutoCString* prefix = static_cast<nsAutoCString*>(arg);
|
||||
if (StringBeginsWith(key, *prefix)) {
|
||||
return HT_ENUMERATE_NEXT | HT_ENUMERATE_REMOVE;
|
||||
}
|
||||
return HT_ENUMERATE_NEXT;
|
||||
}
|
||||
|
||||
void
|
||||
nsHttpAuthCache::ClearAppData(uint32_t appId, bool browserOnly)
|
||||
{
|
||||
if (!mDB) {
|
||||
return;
|
||||
}
|
||||
nsAutoCString keyPrefix;
|
||||
keyPrefix.AppendInt(appId);
|
||||
keyPrefix.Append(':');
|
||||
if (browserOnly) {
|
||||
keyPrefix.AppendInt(browserOnly);
|
||||
keyPrefix.Append(':');
|
||||
}
|
||||
PL_HashTableEnumerateEntries(mDB, RemoveEntriesForApp, &keyPrefix);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// nsHttpAuthIdentity
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -15,6 +15,8 @@
|
||||
#include "nsCOMPtr.h"
|
||||
#include "plhash.h"
|
||||
#include "nsCRT.h"
|
||||
#include "nsIObserver.h"
|
||||
|
||||
|
||||
|
||||
struct nsHttpAuthPath {
|
||||
@ -180,6 +182,8 @@ public:
|
||||
const char *host,
|
||||
int32_t port,
|
||||
const char *path,
|
||||
uint32_t appId,
|
||||
bool inBrowserElement,
|
||||
nsHttpAuthEntry **entry);
|
||||
|
||||
// |scheme|, |host|, and |port| are required
|
||||
@ -189,6 +193,8 @@ public:
|
||||
const char *host,
|
||||
int32_t port,
|
||||
const char *realm,
|
||||
uint32_t appId,
|
||||
bool inBrowserElement,
|
||||
nsHttpAuthEntry **entry);
|
||||
|
||||
// |scheme|, |host|, and |port| are required
|
||||
@ -203,13 +209,17 @@ public:
|
||||
const char *realm,
|
||||
const char *credentials,
|
||||
const char *challenge,
|
||||
uint32_t appId,
|
||||
bool inBrowserElement,
|
||||
const nsHttpAuthIdentity *ident,
|
||||
nsISupports *metadata);
|
||||
|
||||
void ClearAuthEntry(const char *scheme,
|
||||
const char *host,
|
||||
int32_t port,
|
||||
const char *realm);
|
||||
const char *realm,
|
||||
uint32_t appId,
|
||||
bool inBrowserElement);
|
||||
|
||||
// expire all existing auth list entries including proxy auths.
|
||||
nsresult ClearAll();
|
||||
@ -218,6 +228,8 @@ private:
|
||||
nsHttpAuthNode *LookupAuthNode(const char *scheme,
|
||||
const char *host,
|
||||
int32_t port,
|
||||
uint32_t appId,
|
||||
bool inBrowserElement,
|
||||
nsCString &key);
|
||||
|
||||
// hash table allocation functions
|
||||
@ -227,9 +239,21 @@ private:
|
||||
static void FreeEntry(void *, PLHashEntry *he, unsigned flag);
|
||||
|
||||
static PLHashAllocOps gHashAllocOps;
|
||||
|
||||
class AppDataClearObserver : public nsIObserver {
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIOBSERVER
|
||||
AppDataClearObserver(nsHttpAuthCache* aOwner) : mOwner(aOwner) {}
|
||||
virtual ~AppDataClearObserver() {}
|
||||
nsHttpAuthCache* mOwner;
|
||||
};
|
||||
|
||||
void ClearAppData(uint32_t appId, bool browserOnly);
|
||||
|
||||
private:
|
||||
PLHashTable *mDB; // "host:port" --> nsHttpAuthNode
|
||||
nsRefPtr<AppDataClearObserver> mObserver;
|
||||
};
|
||||
|
||||
#endif // nsHttpAuthCache_h__
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "nsHttpAuthManager.h"
|
||||
#include "nsReadableUtils.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsIPrincipal.h"
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsHttpAuthManager, nsIHttpAuthManager)
|
||||
|
||||
@ -56,22 +57,32 @@ nsHttpAuthManager::GetAuthIdentity(const nsACString & aScheme,
|
||||
nsAString & aUserDomain,
|
||||
nsAString & aUserName,
|
||||
nsAString & aUserPassword,
|
||||
bool aIsPrivate)
|
||||
bool aIsPrivate,
|
||||
nsIPrincipal* aPrincipal)
|
||||
{
|
||||
nsHttpAuthCache* auth_cache = aIsPrivate ? mPrivateAuthCache : mAuthCache;
|
||||
nsHttpAuthEntry * entry = nullptr;
|
||||
nsresult rv;
|
||||
uint32_t appId = NECKO_NO_APP_ID;
|
||||
bool inBrowserElement = false;
|
||||
if (aPrincipal) {
|
||||
appId = aPrincipal->GetAppId();
|
||||
inBrowserElement = aPrincipal->GetIsInBrowserElement();
|
||||
}
|
||||
|
||||
if (!aPath.IsEmpty())
|
||||
rv = auth_cache->GetAuthEntryForPath(PromiseFlatCString(aScheme).get(),
|
||||
PromiseFlatCString(aHost).get(),
|
||||
aPort,
|
||||
PromiseFlatCString(aPath).get(),
|
||||
appId, inBrowserElement,
|
||||
&entry);
|
||||
else
|
||||
rv = auth_cache->GetAuthEntryForDomain(PromiseFlatCString(aScheme).get(),
|
||||
PromiseFlatCString(aHost).get(),
|
||||
aPort,
|
||||
PromiseFlatCString(aRealm).get(),
|
||||
appId, inBrowserElement,
|
||||
&entry);
|
||||
|
||||
if (NS_FAILED(rv))
|
||||
@ -95,12 +106,20 @@ nsHttpAuthManager::SetAuthIdentity(const nsACString & aScheme,
|
||||
const nsAString & aUserDomain,
|
||||
const nsAString & aUserName,
|
||||
const nsAString & aUserPassword,
|
||||
bool aIsPrivate)
|
||||
bool aIsPrivate,
|
||||
nsIPrincipal* aPrincipal)
|
||||
{
|
||||
nsHttpAuthIdentity ident(PromiseFlatString(aUserDomain).get(),
|
||||
PromiseFlatString(aUserName).get(),
|
||||
PromiseFlatString(aUserPassword).get());
|
||||
|
||||
uint32_t appId = NECKO_NO_APP_ID;
|
||||
bool inBrowserElement = false;
|
||||
if (aPrincipal) {
|
||||
appId = aPrincipal->GetAppId();
|
||||
inBrowserElement = aPrincipal->GetIsInBrowserElement();
|
||||
}
|
||||
|
||||
nsHttpAuthCache* auth_cache = aIsPrivate ? mPrivateAuthCache : mAuthCache;
|
||||
return auth_cache->SetAuthEntry(PromiseFlatCString(aScheme).get(),
|
||||
PromiseFlatCString(aHost).get(),
|
||||
@ -109,6 +128,7 @@ nsHttpAuthManager::SetAuthIdentity(const nsACString & aScheme,
|
||||
PromiseFlatCString(aRealm).get(),
|
||||
nullptr, // credentials
|
||||
nullptr, // challenge
|
||||
appId, inBrowserElement,
|
||||
&ident,
|
||||
nullptr); // metadata
|
||||
}
|
||||
|
@ -20,6 +20,23 @@
|
||||
#include "nsIDNSService.h"
|
||||
#include "nsNetCID.h"
|
||||
#include "nsIDNSRecord.h"
|
||||
#include "nsNetUtil.h"
|
||||
|
||||
static void
|
||||
GetAppIdAndBrowserStatus(nsIChannel* aChan, uint32_t* aAppId, bool* aInBrowserElem)
|
||||
{
|
||||
nsCOMPtr<nsILoadContext> loadContext;
|
||||
if (aChan) {
|
||||
NS_QueryNotificationCallbacks(aChan, loadContext);
|
||||
}
|
||||
if (!loadContext) {
|
||||
*aAppId = NECKO_NO_APP_ID;
|
||||
*aInBrowserElem = false;
|
||||
} else {
|
||||
loadContext->GetAppId(aAppId);
|
||||
loadContext->GetIsInBrowserElement(aInBrowserElem);
|
||||
}
|
||||
}
|
||||
|
||||
nsHttpChannelAuthProvider::nsHttpChannelAuthProvider()
|
||||
: mAuthChannel(nullptr)
|
||||
@ -372,6 +389,11 @@ nsHttpChannelAuthProvider::GenCredsAndSetEntry(nsIHttpAuthenticator *auth,
|
||||
// this getter never fails
|
||||
nsHttpAuthCache *authCache = gHttpHandler->AuthCache(mIsPrivate);
|
||||
|
||||
nsCOMPtr<nsIChannel> chan = do_QueryInterface(mAuthChannel);
|
||||
uint32_t appId;
|
||||
bool isInBrowserElement;
|
||||
GetAppIdAndBrowserStatus(chan, &appId, &isInBrowserElement);
|
||||
|
||||
// create a cache entry. we do this even though we don't yet know that
|
||||
// these credentials are valid b/c we need to avoid prompting the user
|
||||
// more than once in case the credentials are valid.
|
||||
@ -381,6 +403,7 @@ nsHttpChannelAuthProvider::GenCredsAndSetEntry(nsIHttpAuthenticator *auth,
|
||||
rv = authCache->SetAuthEntry(scheme, host, port, directory, realm,
|
||||
saveCreds ? *result : nullptr,
|
||||
saveChallenge ? challenge : nullptr,
|
||||
appId, isInBrowserElement,
|
||||
saveIdentity ? &ident : nullptr,
|
||||
sessionState);
|
||||
return rv;
|
||||
@ -694,6 +717,11 @@ nsHttpChannelAuthProvider::GetCredentialsForChallenge(const char *challenge,
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIChannel> chan = do_QueryInterface(mAuthChannel);
|
||||
uint32_t appId;
|
||||
bool isInBrowserElement;
|
||||
GetAppIdAndBrowserStatus(chan, &appId, &isInBrowserElement);
|
||||
|
||||
//
|
||||
// if we already tried some credentials for this transaction, then
|
||||
// we need to possibly clear them from the cache, unless the credentials
|
||||
@ -702,7 +730,8 @@ nsHttpChannelAuthProvider::GetCredentialsForChallenge(const char *challenge,
|
||||
//
|
||||
nsHttpAuthEntry *entry = nullptr;
|
||||
authCache->GetAuthEntryForDomain(scheme.get(), host, port,
|
||||
realm.get(), &entry);
|
||||
realm.get(), appId,
|
||||
isInBrowserElement, &entry);
|
||||
|
||||
// hold reference to the auth session state (in case we clear our
|
||||
// reference to the entry).
|
||||
@ -732,7 +761,8 @@ nsHttpChannelAuthProvider::GetCredentialsForChallenge(const char *challenge,
|
||||
// ok, we've already tried this user identity, so clear the
|
||||
// corresponding entry from the auth cache.
|
||||
authCache->ClearAuthEntry(scheme.get(), host,
|
||||
port, realm.get());
|
||||
port, realm.get(),
|
||||
appId, isInBrowserElement);
|
||||
entry = nullptr;
|
||||
ident->Clear();
|
||||
}
|
||||
@ -1057,10 +1087,17 @@ NS_IMETHODIMP nsHttpChannelAuthProvider::OnAuthAvailable(nsISupports *aContext,
|
||||
nsAutoCString realm;
|
||||
ParseRealm(mCurrentChallenge.get(), realm);
|
||||
|
||||
nsCOMPtr<nsIChannel> chan = do_QueryInterface(mAuthChannel);
|
||||
uint32_t appId;
|
||||
bool isInBrowserElement;
|
||||
GetAppIdAndBrowserStatus(chan, &appId, &isInBrowserElement);
|
||||
|
||||
nsHttpAuthCache *authCache = gHttpHandler->AuthCache(mIsPrivate);
|
||||
nsHttpAuthEntry *entry = nullptr;
|
||||
authCache->GetAuthEntryForDomain(scheme.get(), host, port,
|
||||
realm.get(), &entry);
|
||||
realm.get(), appId,
|
||||
isInBrowserElement,
|
||||
&entry);
|
||||
|
||||
nsCOMPtr<nsISupports> sessionStateGrip;
|
||||
if (entry)
|
||||
@ -1292,7 +1329,13 @@ nsHttpChannelAuthProvider::SetAuthorizationHeader(nsHttpAuthCache *authCache,
|
||||
continuationState = &mAuthContinuationState;
|
||||
}
|
||||
|
||||
rv = authCache->GetAuthEntryForPath(scheme, host, port, path, &entry);
|
||||
nsCOMPtr<nsIChannel> chan = do_QueryInterface(mAuthChannel);
|
||||
uint32_t appId;
|
||||
bool isInBrowserElement;
|
||||
GetAppIdAndBrowserStatus(chan, &appId, &isInBrowserElement);
|
||||
|
||||
rv = authCache->GetAuthEntryForPath(scheme, host, port, path,
|
||||
appId, isInBrowserElement, &entry);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
// if we are trying to add a header for origin server auth and if the
|
||||
// URL contains an explicit username, then try the given username first.
|
||||
|
@ -5,6 +5,8 @@
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
interface nsIPrincipal;
|
||||
|
||||
/**
|
||||
* nsIHttpAuthManager
|
||||
*
|
||||
@ -19,7 +21,7 @@
|
||||
* Java client fetches content from a HTTP site that the user
|
||||
* has already logged into.
|
||||
*/
|
||||
[scriptable, uuid(1301b517-ac72-48f6-a781-70c196eaaf3d)]
|
||||
[scriptable, uuid(54f90444-c52b-4d2d-8916-c59a2bb25938)]
|
||||
interface nsIHttpAuthManager : nsISupports
|
||||
{
|
||||
/**
|
||||
@ -45,6 +47,12 @@ interface nsIHttpAuthManager : nsISupports
|
||||
* return value containing user name.
|
||||
* @param aUserPassword
|
||||
* return value containing user password.
|
||||
* @param aIsPrivate
|
||||
* whether to look up a private or public identity (they are
|
||||
* stored separately, for use by private browsing)
|
||||
* @param aPrincipal
|
||||
* the principal from which to derive information about which
|
||||
* app/mozbrowser is in use for this request
|
||||
*/
|
||||
void getAuthIdentity(in ACString aScheme,
|
||||
in ACString aHost,
|
||||
@ -55,7 +63,8 @@ interface nsIHttpAuthManager : nsISupports
|
||||
out AString aUserDomain,
|
||||
out AString aUserName,
|
||||
out AString aUserPassword,
|
||||
[optional] in bool aIsPrivate);
|
||||
[optional] in bool aIsPrivate,
|
||||
[optional] in nsIPrincipal aPrincipal);
|
||||
|
||||
/**
|
||||
* Store auth identity.
|
||||
@ -80,6 +89,12 @@ interface nsIHttpAuthManager : nsISupports
|
||||
* optional string containing user name.
|
||||
* @param aUserPassword
|
||||
* optional string containing user password.
|
||||
* @param aIsPrivate
|
||||
* whether to store a private or public identity (they are
|
||||
* stored separately, for use by private browsing)
|
||||
* @param aPrincipal
|
||||
* the principal from which to derive information about which
|
||||
* app/mozbrowser is in use for this request
|
||||
*/
|
||||
void setAuthIdentity(in ACString aScheme,
|
||||
in ACString aHost,
|
||||
@ -90,7 +105,8 @@ interface nsIHttpAuthManager : nsISupports
|
||||
in AString aUserDomain,
|
||||
in AString aUserName,
|
||||
in AString aUserPassword,
|
||||
[optional] in boolean aIsPrivate);
|
||||
[optional] in boolean aIsPrivate,
|
||||
[optional] in nsIPrincipal aPrincipal);
|
||||
|
||||
/**
|
||||
* Clear all auth cache.
|
||||
|
52
netwerk/test/unit/test_auth_jar.js
Normal file
52
netwerk/test/unit/test_auth_jar.js
Normal file
@ -0,0 +1,52 @@
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
Components.utils.import("resource://gre/modules/Services.jsm");
|
||||
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
function createURI(s) {
|
||||
let service = Components.classes["@mozilla.org/network/io-service;1"]
|
||||
.getService(Components.interfaces.nsIIOService);
|
||||
return service.newURI(s, null, null);
|
||||
}
|
||||
|
||||
function run_test() {
|
||||
var secMan = Cc["@mozilla.org/scriptsecuritymanager;1"].getService(Ci.nsIScriptSecurityManager);
|
||||
const kURI1 = "http://example.com";
|
||||
var app1 = secMan.getAppCodebasePrincipal(createURI(kURI1), 1, false);
|
||||
var app10 = secMan.getAppCodebasePrincipal(createURI(kURI1), 10, false);
|
||||
var app1browser = secMan.getAppCodebasePrincipal(createURI(kURI1), 1, true);
|
||||
|
||||
var am = Cc["@mozilla.org/network/http-auth-manager;1"].
|
||||
getService(Ci.nsIHttpAuthManager);
|
||||
am.setAuthIdentity("http", "a.example.com", -1, "basic", "realm", "", "example.com", "user", "pass", false, app1);
|
||||
am.setAuthIdentity("http", "a.example.com", -1, "basic", "realm", "", "example.com", "user3", "pass3", false, app1browser);
|
||||
am.setAuthIdentity("http", "a.example.com", -1, "basic", "realm", "", "example.com", "user2", "pass2", false, app10);
|
||||
|
||||
let subject = {
|
||||
appId: 1,
|
||||
browserOnly: true,
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.mozIApplicationClearPrivateDataParams])
|
||||
};
|
||||
Services.obs.notifyObservers(subject, "webapps-clear-data", null);
|
||||
|
||||
var domain = {value: ""}, user = {value: ""}, pass = {value: ""};
|
||||
try {
|
||||
am.getAuthIdentity("http", "a.example.com", -1, "basic", "realm", "", domain, user, pass, false, app1browser);
|
||||
do_check_false(true); // no identity should be present
|
||||
} catch (x) {
|
||||
do_check_eq(domain.value, "");
|
||||
do_check_eq(user.value, "");
|
||||
do_check_eq(pass.value, "");
|
||||
}
|
||||
|
||||
am.getAuthIdentity("http", "a.example.com", -1, "basic", "realm", "", domain, user, pass, false, app1);
|
||||
do_check_eq(domain.value, "example.com");
|
||||
do_check_eq(user.value, "user");
|
||||
do_check_eq(pass.value, "pass");
|
||||
|
||||
|
||||
am.getAuthIdentity("http", "a.example.com", -1, "basic", "realm", "", domain, user, pass, false, app10);
|
||||
do_check_eq(domain.value, "example.com");
|
||||
do_check_eq(user.value, "user2");
|
||||
do_check_eq(pass.value, "pass2");
|
||||
}
|
@ -9,6 +9,7 @@ tail =
|
||||
[test_URIs.js]
|
||||
[test_aboutblank.js]
|
||||
[test_assoc.js]
|
||||
[test_auth_jar.js]
|
||||
[test_auth_proxy.js]
|
||||
[test_authentication.js]
|
||||
# Bug 675039: test hangs consistently on Android
|
||||
|
Loading…
Reference in New Issue
Block a user