Bug 1615297 - Move Localstorage Keygen into Principal r=ckerschb,baku
authorSebastian Streich <sstreich@mozilla.com>
Sun, 29 Mar 2020 15:31:24 +0000
changeset 520995 dc6091aecfecfccc4dc8a1c95498b9e564238a8a
parent 520994 7a4dc7c9fd1b2873713efe940066a8e71d948612
child 520996 84dce89016b8b1ff80da7bf122a910a0775f2414
push id111405
push userarchaeopteryx@coole-files.de
push dateSun, 29 Mar 2020 15:45:51 +0000
treeherderautoland@dc6091aecfec [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersckerschb, baku
bugs1615297
milestone76.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1615297 - Move Localstorage Keygen into Principal r=ckerschb,baku Differential Revision: https://phabricator.services.mozilla.com/D62757
caps/BasePrincipal.cpp
caps/BasePrincipal.h
caps/nsIPrincipal.idl
dom/localstorage/LSObject.cpp
dom/localstorage/LocalStorageManager2.cpp
dom/localstorage/test/gtest/TestLocalStorage.cpp
dom/storage/LocalStorageManager.cpp
dom/storage/SessionStorageManager.cpp
dom/storage/StorageUtils.cpp
dom/storage/StorageUtils.h
--- a/caps/BasePrincipal.cpp
+++ b/caps/BasePrincipal.cpp
@@ -20,17 +20,18 @@
 #include "mozilla/ContentPrincipal.h"
 #include "mozilla/NullPrincipal.h"
 #include "mozilla/dom/BlobURLProtocolHandler.h"
 #include "mozilla/dom/ChromeUtils.h"
 #include "mozilla/dom/ToJSValue.h"
 #include "mozilla/dom/nsMixedContentBlocker.h"
 #include "mozilla/Components.h"
 #include "mozilla/dom/StorageUtils.h"
-
+#include "mozilla/dom/StorageUtils.h"
+#include "nsIURL.h"
 #include "nsIURIMutator.h"
 #include "prnetdb.h"
 
 #include "json/json.h"
 #include "nsSerializationHelper.h"
 
 namespace mozilla {
 
@@ -1021,16 +1022,65 @@ BasePrincipal::GetLocalStorageQuotaKey(n
 
   aKey.Append(':');
   aKey.Append(subdomainsDBKey);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
+BasePrincipal::GetStorageOriginKey(nsACString& aOriginKey) {
+  aOriginKey.Truncate();
+  nsCOMPtr<nsIURI> uri;
+  nsresult rv = GetURI(getter_AddRefs(uri));
+  NS_ENSURE_SUCCESS(rv, rv);
+  if (!uri) {
+    return NS_ERROR_UNEXPECTED;
+  }
+
+  nsAutoCString domainOrigin;
+  rv = uri->GetAsciiHost(domainOrigin);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  if (domainOrigin.IsEmpty()) {
+    // For the file:/// protocol use the exact directory as domain.
+    if (uri->SchemeIs("file")) {
+      nsCOMPtr<nsIURL> url = do_QueryInterface(uri, &rv);
+      NS_ENSURE_SUCCESS(rv, rv);
+      rv = url->GetDirectory(domainOrigin);
+      NS_ENSURE_SUCCESS(rv, rv);
+    }
+  }
+
+  // Append reversed domain
+  nsAutoCString reverseDomain;
+  rv = dom::StorageUtils::CreateReversedDomain(domainOrigin, reverseDomain);
+  if (NS_FAILED(rv)) {
+    return rv;
+  }
+
+  aOriginKey.Append(reverseDomain);
+
+  // Append scheme
+  nsAutoCString scheme;
+  rv = uri->GetScheme(scheme);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  aOriginKey.Append(':');
+  aOriginKey.Append(scheme);
+
+  // Append port if any
+  int32_t port = NS_GetRealPort(uri);
+  if (port != -1) {
+    aOriginKey.Append(nsPrintfCString(":%d", port));
+  }
+  return NS_OK;
+}
+
+NS_IMETHODIMP
 BasePrincipal::GetIsScriptAllowedByPolicy(bool* aIsScriptAllowedByPolicy) {
   *aIsScriptAllowedByPolicy = false;
   nsCOMPtr<nsIURI> prinURI;
   nsresult rv = GetURI(getter_AddRefs(prinURI));
   if (NS_FAILED(rv) || !prinURI) {
     return NS_OK;
   }
   nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
--- a/caps/BasePrincipal.h
+++ b/caps/BasePrincipal.h
@@ -151,16 +151,17 @@ class BasePrincipal : public nsJSPrincip
   NS_IMETHOD GetAsciiHost(nsACString& aAsciiHost) override;
   NS_IMETHOD GetLocalStorageQuotaKey(nsACString& aRes) override;
   NS_IMETHOD AllowsRelaxStrictFileOriginPolicy(nsIURI* aURI,
                                                bool* aRes) override;
   NS_IMETHOD CreateReferrerInfo(mozilla::dom::ReferrerPolicy aReferrerPolicy,
                                 nsIReferrerInfo** _retval) override;
   NS_IMETHOD GetIsScriptAllowedByPolicy(
       bool* aIsScriptAllowedByPolicy) override;
+  NS_IMETHOD GetStorageOriginKey(nsACString& aOriginKey) override;
   nsresult ToJSON(nsACString& aJSON);
   static already_AddRefed<BasePrincipal> FromJSON(const nsACString& aJSON);
   // Method populates a passed Json::Value with serializable fields
   // which represent all of the fields to deserialize the principal
   virtual nsresult PopulateJSONObject(Json::Value& aObject);
 
   virtual bool AddonHasPermission(const nsAtom* aPerm);
 
--- a/caps/nsIPrincipal.idl
+++ b/caps/nsIPrincipal.idl
@@ -325,16 +325,22 @@ interface nsIPrincipal : nsISerializable
     readonly attribute bool isOriginPotentiallyTrustworthy;
 
     /**
      * Returns the Flags of the Principals 
      * associated AboutModule, in case there is one.
      */
     uint32_t getAboutModuleFlags();
 
+    /*
+    * Returns the Key to access the Principals 
+    * Origin Local/Session Storage
+    */
+    readonly attribute ACString storageOriginKey;
+
     /**
      * Creates and Returns a new ReferrerInfo with the 
      * Principals URI
      */
     nsIReferrerInfo createReferrerInfo(in ReferrerPolicy aReferrerPolicy);
 
     /**
      * The base part of |origin| without the concatenation with |originSuffix|.
--- a/dom/localstorage/LSObject.cpp
+++ b/dom/localstorage/LSObject.cpp
@@ -266,18 +266,19 @@ nsresult LSObject::CreateForWindow(nsPID
     return NS_ERROR_NOT_AVAILABLE;
   }
 
   // localStorage is not available on some pages on purpose, for example
   // about:home. Match the old implementation by using GenerateOriginKey
   // for the check.
   nsCString originAttrSuffix;
   nsCString originKey;
-  nsresult rv =
-      GenerateOriginKey(storagePrincipal, originAttrSuffix, originKey);
+  nsresult rv = storagePrincipal->GetStorageOriginKey(originKey);
+  storagePrincipal->OriginAttributesRef().CreateSuffix(originAttrSuffix);
+
   if (NS_FAILED(rv)) {
     return NS_ERROR_NOT_AVAILABLE;
   }
 
   auto principalInfo = MakeUnique<PrincipalInfo>();
   rv = PrincipalToPrincipalInfo(principal, principalInfo.get());
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
@@ -350,18 +351,18 @@ nsresult LSObject::CreateForPrincipal(ns
                                       bool aPrivate, LSObject** aObject) {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(aPrincipal);
   MOZ_ASSERT(aStoragePrincipal);
   MOZ_ASSERT(aObject);
 
   nsCString originAttrSuffix;
   nsCString originKey;
-  nsresult rv =
-      GenerateOriginKey(aStoragePrincipal, originAttrSuffix, originKey);
+  nsresult rv = aStoragePrincipal->GetStorageOriginKey(originKey);
+  aStoragePrincipal->OriginAttributesRef().CreateSuffix(originAttrSuffix);
   if (NS_FAILED(rv)) {
     return NS_ERROR_NOT_AVAILABLE;
   }
 
   auto principalInfo = MakeUnique<PrincipalInfo>();
   rv = PrincipalToPrincipalInfo(aPrincipal, principalInfo.get());
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
--- a/dom/localstorage/LocalStorageManager2.cpp
+++ b/dom/localstorage/LocalStorageManager2.cpp
@@ -264,17 +264,18 @@ NS_IMETHODIMP
 LocalStorageManager2::Preload(nsIPrincipal* aPrincipal, JSContext* aContext,
                               nsISupports** _retval) {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(aPrincipal);
   MOZ_ASSERT(_retval);
 
   nsCString originAttrSuffix;
   nsCString originKey;
-  nsresult rv = GenerateOriginKey(aPrincipal, originAttrSuffix, originKey);
+  nsresult rv = aPrincipal->GetStorageOriginKey(originKey);
+  aPrincipal->OriginAttributesRef().CreateSuffix(originAttrSuffix);
   if (NS_FAILED(rv)) {
     return NS_ERROR_NOT_AVAILABLE;
   }
 
   PrincipalInfo principalInfo;
   rv = CheckedPrincipalToPrincipalInfo(aPrincipal, principalInfo);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
--- a/dom/localstorage/test/gtest/TestLocalStorage.cpp
+++ b/dom/localstorage/test/gtest/TestLocalStorage.cpp
@@ -40,17 +40,18 @@ already_AddRefed<nsIPrincipal> GetConten
       BasePrincipal::CreateContentPrincipal(uri, attrs);
 
   return principal.forget();
 }
 
 void CheckGeneratedOriginKey(nsIPrincipal* aPrincipal, const char* aOriginKey) {
   nsCString originAttrSuffix;
   nsCString originKey;
-  nsresult rv = GenerateOriginKey(aPrincipal, originAttrSuffix, originKey);
+  nsresult rv = aPrincipal->GetStorageOriginKey(originKey);
+  aPrincipal->OriginAttributesRef().CreateSuffix(originAttrSuffix);
   if (aOriginKey) {
     ASSERT_EQ(rv, NS_OK) << "GenerateOriginKey should not fail";
     EXPECT_TRUE(originKey == nsDependentCString(aOriginKey));
   } else {
     ASSERT_NE(rv, NS_OK) << "GenerateOriginKey should fail";
   }
 
   PrincipalInfo principalInfo;
--- a/dom/storage/LocalStorageManager.cpp
+++ b/dom/storage/LocalStorageManager.cpp
@@ -142,18 +142,18 @@ void LocalStorageManager::DropCache(Loca
 
 nsresult LocalStorageManager::GetStorageInternal(
     CreateMode aCreateMode, mozIDOMWindow* aWindow, nsIPrincipal* aPrincipal,
     nsIPrincipal* aStoragePrincipal, const nsAString& aDocumentURI,
     bool aPrivate, Storage** aRetval) {
   nsAutoCString originAttrSuffix;
   nsAutoCString originKey;
 
-  nsresult rv =
-      GenerateOriginKey(aStoragePrincipal, originAttrSuffix, originKey);
+  nsresult rv = aStoragePrincipal->GetStorageOriginKey(originKey);
+  aStoragePrincipal->OriginAttributesRef().CreateSuffix(originAttrSuffix);
   if (NS_FAILED(rv)) {
     return NS_ERROR_NOT_AVAILABLE;
   }
 
   RefPtr<LocalStorageCache> cache = GetCache(originAttrSuffix, originKey);
 
   // Get or create a cache for the given scope
   if (!cache) {
--- a/dom/storage/SessionStorageManager.cpp
+++ b/dom/storage/SessionStorageManager.cpp
@@ -97,17 +97,18 @@ SessionStorageManager::GetSessionStorage
                                       aRetVal);
 }
 
 nsresult SessionStorageManager::GetSessionStorageCacheHelper(
     nsIPrincipal* aPrincipal, bool aMakeIfNeeded,
     SessionStorageCache* aCloneFrom, RefPtr<SessionStorageCache>* aRetVal) {
   nsAutoCString originKey;
   nsAutoCString originAttributes;
-  nsresult rv = GenerateOriginKey(aPrincipal, originAttributes, originKey);
+  nsresult rv = aPrincipal->GetStorageOriginKey(originKey);
+  aPrincipal->OriginAttributesRef().CreateSuffix(originAttributes);
   if (NS_FAILED(rv)) {
     return NS_ERROR_NOT_AVAILABLE;
   }
 
   return GetSessionStorageCacheHelper(originAttributes, originKey,
                                       aMakeIfNeeded, aCloneFrom, aRetVal);
 }
 
@@ -296,17 +297,18 @@ void SessionStorageManager::SendSessionS
     }
   }
 }
 
 void SessionStorageManager::SendSessionStorageDataToContentProcess(
     ContentParent* const aActor, nsIPrincipal* const aPrincipal) {
   nsAutoCString originAttrs;
   nsAutoCString originKey;
-  auto rv = GenerateOriginKey(aPrincipal, originAttrs, originKey);
+  nsresult rv = aPrincipal->GetStorageOriginKey(originKey);
+  aPrincipal->OriginAttributesRef().CreateSuffix(originAttrs);
   if (NS_FAILED(rv)) {
     return;
   }
 
   const auto originRecord =
       GetOriginRecord(originAttrs, originKey, false, nullptr);
   if (!originRecord) {
     return;
--- a/dom/storage/StorageUtils.cpp
+++ b/dom/storage/StorageUtils.cpp
@@ -14,72 +14,16 @@
 #include "nsIURL.h"
 #include "nsNetUtil.h"
 #include "nsPrintfCString.h"
 
 namespace mozilla {
 namespace dom {
 namespace StorageUtils {
 
-nsresult GenerateOriginKey(nsIPrincipal* aPrincipal,
-                           nsACString& aOriginAttrSuffix,
-                           nsACString& aOriginKey) {
-  if (NS_WARN_IF(!aPrincipal)) {
-    return NS_ERROR_UNEXPECTED;
-  }
-
-  aPrincipal->OriginAttributesRef().CreateSuffix(aOriginAttrSuffix);
-
-  nsCOMPtr<nsIURI> uri;
-  nsresult rv = aPrincipal->GetURI(getter_AddRefs(uri));
-  NS_ENSURE_SUCCESS(rv, rv);
-  if (!uri) {
-    return NS_ERROR_UNEXPECTED;
-  }
-
-  nsAutoCString domainOrigin;
-  rv = uri->GetAsciiHost(domainOrigin);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  if (domainOrigin.IsEmpty()) {
-    // For the file:/// protocol use the exact directory as domain.
-    if (uri->SchemeIs("file")) {
-      nsCOMPtr<nsIURL> url = do_QueryInterface(uri, &rv);
-      NS_ENSURE_SUCCESS(rv, rv);
-      rv = url->GetDirectory(domainOrigin);
-      NS_ENSURE_SUCCESS(rv, rv);
-    }
-  }
-
-  // Append reversed domain
-  nsAutoCString reverseDomain;
-  rv = CreateReversedDomain(domainOrigin, reverseDomain);
-  if (NS_FAILED(rv)) {
-    return rv;
-  }
-
-  aOriginKey.Append(reverseDomain);
-
-  // Append scheme
-  nsAutoCString scheme;
-  rv = uri->GetScheme(scheme);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  aOriginKey.Append(':');
-  aOriginKey.Append(scheme);
-
-  // Append port if any
-  int32_t port = NS_GetRealPort(uri);
-  if (port != -1) {
-    aOriginKey.Append(nsPrintfCString(":%d", port));
-  }
-
-  return NS_OK;
-}
-
 bool PrincipalsEqual(nsIPrincipal* aObjectPrincipal,
                      nsIPrincipal* aSubjectPrincipal) {
   if (!aSubjectPrincipal) {
     return true;
   }
 
   if (!aObjectPrincipal) {
     return false;
--- a/dom/storage/StorageUtils.h
+++ b/dom/storage/StorageUtils.h
@@ -10,20 +10,16 @@
 #include "nsStringFwd.h"
 
 class nsIPrincipal;
 
 namespace mozilla {
 namespace dom {
 namespace StorageUtils {
 
-nsresult GenerateOriginKey(nsIPrincipal* aPrincipal,
-                           nsACString& aOriginAttrSuffix,
-                           nsACString& aOriginKey);
-
 bool PrincipalsEqual(nsIPrincipal* aObjectPrincipal,
                      nsIPrincipal* aSubjectPrincipal);
 
 void ReverseString(const nsACString& aSource, nsACString& aResult);
 
 nsresult CreateReversedDomain(const nsACString& aAsciiDomain, nsACString& aKey);
 
 nsCString Scheme0Scope(const nsACString& aOriginSuffix,