Bug 773373 part 2: Use principals instead of URIs when calculating scopes. r=honzab

This commit is contained in:
Jonas Sicking 2012-09-25 16:06:27 -07:00
Родитель 716644d33d
Коммит 0318213b63
9 изменённых файлов: 62 добавлений и 176 удалений

Просмотреть файл

@ -36,8 +36,7 @@ parent:
__delete__();
Init(bool useDB, bool sessionOnly, bool isPrivate,
nsCString domain, nsCString scopeDBKey,
nsCString quotaDBKey, uint32_t storageType);
nsCString scopeDBKey, nsCString quotaDBKey, uint32_t storageType);
sync GetKeys(bool callerSecure)
returns (nsString[] keys);

Просмотреть файл

@ -83,21 +83,21 @@ StorageChild::InitRemote()
ContentChild* child = ContentChild::GetSingleton();
AddIPDLReference();
child->SendPStorageConstructor(this, null_t());
SendInit(mUseDB, mSessionOnly, mInPrivateBrowsing, mDomain, mScopeDBKey,
SendInit(mUseDB, mSessionOnly, mInPrivateBrowsing, mScopeDBKey,
mQuotaDBKey, mStorageType);
}
void
StorageChild::InitAsSessionStorage(nsIURI* aDomainURI, bool aPrivate)
StorageChild::InitAsSessionStorage(nsIPrincipal* aPrincipal, bool aPrivate)
{
DOMStorageBase::InitAsSessionStorage(aDomainURI, aPrivate);
DOMStorageBase::InitAsSessionStorage(aPrincipal, aPrivate);
InitRemote();
}
void
StorageChild::InitAsLocalStorage(nsIURI* aDomainURI, bool aPrivate)
StorageChild::InitAsLocalStorage(nsIPrincipal* aPrincipal, bool aPrivate)
{
DOMStorageBase::InitAsLocalStorage(aDomainURI, aPrivate);
DOMStorageBase::InitAsLocalStorage(aPrincipal, aPrivate);
InitRemote();
}
@ -233,7 +233,7 @@ StorageChild::CloneFrom(bool aCallerSecure, DOMStorageBase* aThat)
StorageClone clone(nullptr, other, aCallerSecure);
AddIPDLReference();
child->SendPStorageConstructor(this, clone);
SendInit(mUseDB, mSessionOnly, mInPrivateBrowsing, mDomain,
SendInit(mUseDB, mSessionOnly, mInPrivateBrowsing,
mScopeDBKey, mQuotaDBKey, mStorageType);
return NS_OK;
}

Просмотреть файл

@ -26,8 +26,8 @@ public:
StorageChild(nsDOMStorage* aOwner);
StorageChild(nsDOMStorage* aOwner, StorageChild& aOther);
virtual void InitAsSessionStorage(nsIURI* aDomainURI, bool aPrivate);
virtual void InitAsLocalStorage(nsIURI* aDomainURI, bool aPrivate);
virtual void InitAsSessionStorage(nsIPrincipal* aPrincipal, bool aPrivate);
virtual void InitAsLocalStorage(nsIPrincipal* aPrincipal, bool aPrivate);
virtual bool CacheStoragePermissions();

Просмотреть файл

@ -30,12 +30,11 @@ bool
StorageParent::RecvInit(const bool& aUseDB,
const bool& aSessionOnly,
const bool& aPrivate,
const nsCString& aDomain,
const nsCString& aScopeDBKey,
const nsCString& aQuotaDBKey,
const uint32_t& aStorageType)
{
mStorage->InitFromChild(aUseDB, aSessionOnly, aPrivate, aDomain,
mStorage->InitFromChild(aUseDB, aSessionOnly, aPrivate,
aScopeDBKey, aQuotaDBKey,
aStorageType);
return true;

Просмотреть файл

@ -45,7 +45,6 @@ private:
bool RecvInit(const bool& aUseDB,
const bool& aSessionOnly,
const bool& aPrivate,
const nsCString& aDomain,
const nsCString& aScopeDBKey,
const nsCString& aQuotaDBKey,
const uint32_t& aStorageType);

Просмотреть файл

@ -59,38 +59,6 @@ static const char kStorageEnabled[] = "dom.storage.enabled";
static const char kCookiesBehavior[] = "network.cookie.cookieBehavior";
static const char kCookiesLifetimePolicy[] = "network.cookie.lifetimePolicy";
// The URI returned is the innermost URI that should be used for
// security-check-like stuff. aHost is its hostname, correctly canonicalized.
static nsresult
GetPrincipalURIAndHost(nsIPrincipal* aPrincipal, nsIURI** aURI, nsCString& aHost)
{
nsresult rv = aPrincipal->GetDomain(aURI);
NS_ENSURE_SUCCESS(rv, rv);
if (!*aURI) {
rv = aPrincipal->GetURI(aURI);
NS_ENSURE_SUCCESS(rv, rv);
}
if (!*aURI) {
return NS_OK;
}
nsCOMPtr<nsIURI> innerURI = NS_GetInnermostURI(*aURI);
if (!innerURI) {
return NS_ERROR_UNEXPECTED;
}
rv = innerURI->GetAsciiHost(aHost);
if (NS_FAILED(rv)) {
return NS_ERROR_DOM_SECURITY_ERR;
}
innerURI.swap(*aURI);
return NS_OK;
}
//
// Helper that tells us whether the caller is secure or not.
//
@ -459,7 +427,6 @@ DOMStorageBase::DOMStorageBase(DOMStorageBase& aThat)
: mStorageType(aThat.mStorageType)
, mUseDB(false) // Clones don't use the DB
, mSessionOnly(true)
, mDomain(aThat.mDomain)
, mScopeDBKey(aThat.mScopeDBKey)
, mQuotaDBKey(aThat.mQuotaDBKey)
, mInPrivateBrowsing(aThat.mInPrivateBrowsing)
@ -467,15 +434,9 @@ DOMStorageBase::DOMStorageBase(DOMStorageBase& aThat)
}
void
DOMStorageBase::InitAsSessionStorage(nsIURI* aDomainURI, bool aPrivate)
DOMStorageBase::InitAsSessionStorage(nsIPrincipal* aPrincipal, bool aPrivate)
{
// No need to check for a return value. If this would fail we would not get
// here as we call GetPrincipalURIAndHost (nsDOMStorage.cpp:88) from
// nsDOMStorage::CanUseStorage before we query the storage manager for a new
// sessionStorage. It calls GetAsciiHost on innermost URI. If it fails, we
// won't get to InitAsSessionStorage.
aDomainURI->GetAsciiHost(mDomain);
MOZ_ASSERT(mQuotaDBKey.IsEmpty());
mUseDB = false;
mScopeDBKey.Truncate();
mStorageType = nsPIDOMStorage::SessionStorage;
@ -483,18 +444,9 @@ DOMStorageBase::InitAsSessionStorage(nsIURI* aDomainURI, bool aPrivate)
}
void
DOMStorageBase::InitAsLocalStorage(nsIURI* aDomainURI,
bool aPrivate)
DOMStorageBase::InitAsLocalStorage(nsIPrincipal* aPrincipal, bool aPrivate)
{
// No need to check for a return value. If this would fail we would not get
// here as we call GetPrincipalURIAndHost (nsDOMStorage.cpp:88) from
// nsDOMStorage::CanUseStorage before we query the storage manager for a new
// localStorage. It calls GetAsciiHost on innermost URI. If it fails, we won't
// get to InitAsLocalStorage. Actually, mDomain will get replaced with
// mPrincipal in bug 455070. It is not even used for localStorage.
aDomainURI->GetAsciiHost(mDomain);
nsDOMStorageDBWrapper::CreateScopeDBKey(aDomainURI, mScopeDBKey);
nsDOMStorageDBWrapper::CreateScopeDBKey(aPrincipal, mScopeDBKey);
// XXX Bug 357323, we have to solve the issue how to define
// origin for file URLs. In that case CreateOriginScopeDBKey
@ -502,7 +454,7 @@ DOMStorageBase::InitAsLocalStorage(nsIURI* aDomainURI,
// in that case because it produces broken entries w/o owner.
mUseDB = !mScopeDBKey.IsEmpty();
nsDOMStorageDBWrapper::CreateQuotaDBKey(mDomain, mQuotaDBKey);
nsDOMStorageDBWrapper::CreateQuotaDBKey(aPrincipal, mQuotaDBKey);
mStorageType = nsPIDOMStorage::LocalStorage;
mInPrivateBrowsing = aPrivate;
}
@ -589,7 +541,6 @@ DOMStorageImpl::InitDB()
void
DOMStorageImpl::InitFromChild(bool aUseDB,
bool aSessionOnly, bool aPrivate,
const nsACString& aDomain,
const nsACString& aScopeDBKey,
const nsACString& aQuotaDBKey,
uint32_t aStorageType)
@ -597,7 +548,6 @@ DOMStorageImpl::InitFromChild(bool aUseDB,
mUseDB = aUseDB;
mSessionOnly = aSessionOnly;
mInPrivateBrowsing = aPrivate;
mDomain = aDomain;
mScopeDBKey = aScopeDBKey;
mQuotaDBKey = aQuotaDBKey;
mStorageType = static_cast<nsPIDOMStorage::nsDOMStorageType>(aStorageType);
@ -609,19 +559,6 @@ DOMStorageImpl::SetSessionOnly(bool aSessionOnly)
mSessionOnly = aSessionOnly;
}
void
DOMStorageImpl::InitAsSessionStorage(nsIURI* aDomainURI, bool aPrivate)
{
DOMStorageBase::InitAsSessionStorage(aDomainURI, aPrivate);
}
void
DOMStorageImpl::InitAsLocalStorage(nsIURI* aDomainURI,
bool aPrivate)
{
DOMStorageBase::InitAsLocalStorage(aDomainURI, aPrivate);
}
bool
DOMStorageImpl::CacheStoragePermissions()
{
@ -1122,49 +1059,16 @@ nsDOMStorage::~nsDOMStorage()
{
}
static
nsresult
GetDomainURI(nsIPrincipal *aPrincipal, bool aIncludeDomain, nsIURI **_domain)
{
nsCOMPtr<nsIURI> uri;
if (aIncludeDomain) {
nsresult rv = aPrincipal->GetDomain(getter_AddRefs(uri));
NS_ENSURE_SUCCESS(rv, rv);
}
if (!uri) {
nsresult rv = aPrincipal->GetURI(getter_AddRefs(uri));
NS_ENSURE_SUCCESS(rv, rv);
}
// Check if we really got any URI. System principal doesn't return a URI
// instance and we would crash in NS_GetInnermostURI below.
if (!uri)
return NS_ERROR_NOT_AVAILABLE;
nsCOMPtr<nsIURI> innerURI = NS_GetInnermostURI(uri);
if (!innerURI)
return NS_ERROR_UNEXPECTED;
innerURI.forget(_domain);
return NS_OK;
}
nsresult
nsDOMStorage::InitAsSessionStorage(nsIPrincipal *aPrincipal, const nsSubstring &aDocumentURI,
bool aPrivate)
{
nsCOMPtr<nsIURI> domainURI;
nsresult rv = GetDomainURI(aPrincipal, true, getter_AddRefs(domainURI));
NS_ENSURE_SUCCESS(rv, rv);
mDocumentURI = aDocumentURI;
mPrincipal = aPrincipal;
mStorageType = SessionStorage;
mStorageImpl->InitAsSessionStorage(domainURI, aPrivate);
mStorageImpl->InitAsSessionStorage(mPrincipal, aPrivate);
return NS_OK;
}
@ -1172,16 +1076,12 @@ nsresult
nsDOMStorage::InitAsLocalStorage(nsIPrincipal *aPrincipal, const nsSubstring &aDocumentURI,
bool aPrivate)
{
nsCOMPtr<nsIURI> domainURI;
nsresult rv = GetDomainURI(aPrincipal, false, getter_AddRefs(domainURI));
NS_ENSURE_SUCCESS(rv, rv);
mDocumentURI = aDocumentURI;
mPrincipal = aPrincipal;
mStorageType = LocalStorage;
mStorageImpl->InitAsLocalStorage(domainURI, aPrivate);
mStorageImpl->InitAsLocalStorage(aPrincipal, aPrivate);
return NS_OK;
}
@ -1217,21 +1117,14 @@ nsDOMStorage::CanUseStorage(DOMStorageBase* aStorage /* = NULL */)
// if subjectPrincipal were null we'd have returned after
// IsCallerChrome().
nsCOMPtr<nsIURI> subjectURI;
nsAutoCString unused;
if (NS_FAILED(GetPrincipalURIAndHost(subjectPrincipal,
getter_AddRefs(subjectURI),
unused))) {
return false;
}
nsCOMPtr<nsIPermissionManager> permissionManager =
do_GetService(NS_PERMISSIONMANAGER_CONTRACTID);
if (!permissionManager)
return false;
uint32_t perm;
permissionManager->TestPermission(subjectURI, kPermissionType, &perm);
permissionManager->TestPermissionFromPrincipal(subjectPrincipal,
kPermissionType, &perm);
if (perm == nsIPermissionManager::DENY_ACTION)
return false;

Просмотреть файл

@ -109,8 +109,8 @@ public:
DOMStorageBase();
DOMStorageBase(DOMStorageBase&);
virtual void InitAsSessionStorage(nsIURI* aDomainURI, bool aPrivate);
virtual void InitAsLocalStorage(nsIURI* aDomainURI, bool aPrivate);
virtual void InitAsSessionStorage(nsIPrincipal* aPrincipal, bool aPrivate);
virtual void InitAsLocalStorage(nsIPrincipal* aPrincipal, bool aPrivate);
virtual nsTArray<nsString>* GetKeys(bool aCallerSecure) = 0;
virtual nsresult GetLength(bool aCallerSecure, uint32_t* aLength) = 0;
@ -190,9 +190,6 @@ protected:
// make sure this stays up to date.
bool mSessionOnly;
// domain this store is associated with
nsCString mDomain;
// keys are used for database queries.
// see comments of the getters bellow.
nsCString mScopeDBKey;
@ -213,9 +210,6 @@ public:
DOMStorageImpl(nsDOMStorage*, DOMStorageImpl&);
~DOMStorageImpl();
virtual void InitAsSessionStorage(nsIURI* aDomainURI, bool aPrivate);
virtual void InitAsLocalStorage(nsIURI* aDomainURI, bool aPrivate);
bool SessionOnly() {
return mSessionOnly;
}
@ -281,7 +275,7 @@ private:
// Cross-process storage implementations never have InitAs(Session|Local|Global)Storage
// called, so the appropriate initialization needs to happen from the child.
void InitFromChild(bool aUseDB, bool aSessionOnly,
bool aPrivate, const nsACString& aDomain,
bool aPrivate,
const nsACString& aScopeDBKey,
const nsACString& aQuotaDBKey,
uint32_t aStorageType);

Просмотреть файл

@ -19,6 +19,7 @@
#include "mozIStorageFunction.h"
#include "nsPrintfCString.h"
#include "nsNetUtil.h"
#include "nsIPrincipal.h"
void ReverseString(const nsCSubstring& source, nsCSubstring& result)
{
@ -226,37 +227,16 @@ nsDOMStorageDBWrapper::GetUsage(const nsACString& aDomain,
}
nsresult
nsDOMStorageDBWrapper::CreateScopeDBKey(nsIURI* aUri, nsACString& aKey)
nsDOMStorageDBWrapper::CreateScopeDBKey(nsIPrincipal* aPrincipal,
nsACString& aKey)
{
nsresult rv;
rv = CreateReversedDomain(aUri, aKey);
if (NS_FAILED(rv))
return rv;
nsAutoCString scheme;
rv = aUri->GetScheme(scheme);
nsCOMPtr<nsIURI> uri;
nsresult rv = aPrincipal->GetURI(getter_AddRefs(uri));
NS_ENSURE_SUCCESS(rv, rv);
aKey.AppendLiteral(":");
aKey.Append(scheme);
int32_t port = NS_GetRealPort(aUri);
if (port != -1) {
aKey.AppendLiteral(":");
aKey.Append(nsPrintfCString("%d", port));
}
return NS_OK;
}
nsresult
nsDOMStorageDBWrapper::CreateReversedDomain(nsIURI* aUri, nsACString& aKey)
{
nsresult rv;
NS_ENSURE_TRUE(uri, NS_ERROR_UNEXPECTED);
nsAutoCString domainScope;
rv = aUri->GetAsciiHost(domainScope);
rv = uri->GetAsciiHost(domainScope);
NS_ENSURE_SUCCESS(rv, rv);
if (domainScope.IsEmpty()) {
@ -264,16 +244,16 @@ nsDOMStorageDBWrapper::CreateReversedDomain(nsIURI* aUri, nsACString& aKey)
// internally by our own redirector, we can trust them and use path as key.
// if file:/// protocol, let's make the exact directory the domain
bool isScheme = false;
if ((NS_SUCCEEDED(aUri->SchemeIs("about", &isScheme)) && isScheme) ||
(NS_SUCCEEDED(aUri->SchemeIs("moz-safe-about", &isScheme)) && isScheme)) {
rv = aUri->GetPath(domainScope);
if ((NS_SUCCEEDED(uri->SchemeIs("about", &isScheme)) && isScheme) ||
(NS_SUCCEEDED(uri->SchemeIs("moz-safe-about", &isScheme)) && isScheme)) {
rv = uri->GetPath(domainScope);
NS_ENSURE_SUCCESS(rv, rv);
// While the host is always canonicalized to lowercase, the path is not,
// thus need to force the casing.
ToLowerCase(domainScope);
}
else if (NS_SUCCEEDED(aUri->SchemeIs("file", &isScheme)) && isScheme) {
nsCOMPtr<nsIURL> url = do_QueryInterface(aUri, &rv);
else if (NS_SUCCEEDED(uri->SchemeIs("file", &isScheme)) && isScheme) {
nsCOMPtr<nsIURL> url = do_QueryInterface(uri, &rv);
NS_ENSURE_SUCCESS(rv, rv);
rv = url->GetDirectory(domainScope);
NS_ENSURE_SUCCESS(rv, rv);
@ -283,6 +263,17 @@ nsDOMStorageDBWrapper::CreateReversedDomain(nsIURI* aUri, nsACString& aKey)
rv = CreateReversedDomain(domainScope, aKey);
NS_ENSURE_SUCCESS(rv, rv);
nsAutoCString scheme;
rv = uri->GetScheme(scheme);
NS_ENSURE_SUCCESS(rv, rv);
aKey.Append(NS_LITERAL_CSTRING(":") + scheme);
int32_t port = NS_GetRealPort(uri);
if (port != -1) {
aKey.Append(nsPrintfCString(":%d", port));
}
return NS_OK;
}
@ -300,7 +291,7 @@ nsDOMStorageDBWrapper::CreateReversedDomain(const nsACString& aAsciiDomain,
}
nsresult
nsDOMStorageDBWrapper::CreateQuotaDBKey(const nsACString& aAsciiDomain,
nsDOMStorageDBWrapper::CreateQuotaDBKey(nsIPrincipal* aPrincipal,
nsACString& aKey)
{
nsresult rv;
@ -311,15 +302,15 @@ nsDOMStorageDBWrapper::CreateQuotaDBKey(const nsACString& aAsciiDomain,
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIURI> uri;
rv = NS_NewURI(getter_AddRefs(uri), NS_LITERAL_CSTRING("http://") + aAsciiDomain);
rv = aPrincipal->GetURI(getter_AddRefs(uri));
NS_ENSURE_SUCCESS(rv, rv);
NS_ENSURE_TRUE(uri, NS_ERROR_UNEXPECTED);
nsAutoCString eTLDplusOne;
rv = eTLDService->GetBaseDomain(uri, 0, eTLDplusOne);
if (NS_ERROR_INSUFFICIENT_DOMAIN_LEVELS == rv) {
// XXX bug 357323 - what to do for localhost/file exactly?
eTLDplusOne = aAsciiDomain;
rv = NS_OK;
rv = uri->GetAsciiHost(eTLDplusOne);
}
NS_ENSURE_SUCCESS(rv, rv);

Просмотреть файл

@ -173,7 +173,7 @@ public:
* i.e. reverses the host, appends a dot, appends the schema
* and a port number.
*/
static nsresult CreateScopeDBKey(nsIURI* aUri, nsACString& aKey);
static nsresult CreateScopeDBKey(nsIPrincipal* aPrincipal, nsACString& aKey);
/**
* Turns "http://foo.bar.com" to "moc.rab.oof.",
@ -187,9 +187,20 @@ public:
* i.e. extracts eTLD+1 from the host, reverses the result
* and appends a dot.
*/
static nsresult CreateQuotaDBKey(const nsACString& aAsciiDomain,
static nsresult CreateQuotaDBKey(nsIPrincipal* aPrincipal,
nsACString& aKey);
/**
* Turns "foo.bar.com" to "moc.rab.",
* i.e. extracts eTLD+1 from the host, reverses the result
* and appends a dot.
*/
static nsresult CreateQuotaDBKey(const nsACString& aDomain,
nsACString& aKey)
{
return CreateReversedDomain(aDomain, aKey);
}
/**
* Ensures the temp table flush timer is running. This is called when we add
* data that will need to be flushed.