caps/src/nsPrincipal.cpp

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

     1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* vim: set ts=2 sw=2 et tw=80: */
     3 /* This Source Code Form is subject to the terms of the Mozilla Public
     4  * License, v. 2.0. If a copy of the MPL was not distributed with this
     5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     7 #include "nsPrincipal.h"
     9 #include "mozIThirdPartyUtil.h"
    10 #include "nscore.h"
    11 #include "nsScriptSecurityManager.h"
    12 #include "nsString.h"
    13 #include "nsReadableUtils.h"
    14 #include "pratom.h"
    15 #include "nsIURI.h"
    16 #include "nsJSPrincipals.h"
    17 #include "nsIObjectInputStream.h"
    18 #include "nsIObjectOutputStream.h"
    19 #include "nsIClassInfoImpl.h"
    20 #include "nsError.h"
    21 #include "nsIContentSecurityPolicy.h"
    22 #include "nsCxPusher.h"
    23 #include "jswrapper.h"
    25 #include "mozilla/Preferences.h"
    26 #include "mozilla/HashFunctions.h"
    28 #include "nsIAppsService.h"
    29 #include "mozIApplication.h"
    31 using namespace mozilla;
    33 static bool gCodeBasePrincipalSupport = false;
    34 static bool gIsObservingCodeBasePrincipalSupport = false;
    36 static bool URIIsImmutable(nsIURI* aURI)
    37 {
    38   nsCOMPtr<nsIMutable> mutableObj(do_QueryInterface(aURI));
    39   bool isMutable;
    40   return
    41     mutableObj &&
    42     NS_SUCCEEDED(mutableObj->GetMutable(&isMutable)) &&
    43     !isMutable;
    44 }
    46 // Static member variables
    47 const char nsBasePrincipal::sInvalid[] = "Invalid";
    49 NS_IMETHODIMP_(MozExternalRefCountType)
    50 nsBasePrincipal::AddRef()
    51 {
    52   NS_PRECONDITION(int32_t(refcount) >= 0, "illegal refcnt");
    53   // XXXcaa does this need to be threadsafe?  See bug 143559.
    54   nsrefcnt count = ++refcount;
    55   NS_LOG_ADDREF(this, count, "nsBasePrincipal", sizeof(*this));
    56   return count;
    57 }
    59 NS_IMETHODIMP_(MozExternalRefCountType)
    60 nsBasePrincipal::Release()
    61 {
    62   NS_PRECONDITION(0 != refcount, "dup release");
    63   nsrefcnt count = --refcount;
    64   NS_LOG_RELEASE(this, count, "nsBasePrincipal");
    65   if (count == 0) {
    66     delete this;
    67   }
    69   return count;
    70 }
    72 nsBasePrincipal::nsBasePrincipal()
    73 {
    74   if (!gIsObservingCodeBasePrincipalSupport) {
    75     nsresult rv =
    76       Preferences::AddBoolVarCache(&gCodeBasePrincipalSupport,
    77                                    "signed.applets.codebase_principal_support",
    78                                    false);
    79     gIsObservingCodeBasePrincipalSupport = NS_SUCCEEDED(rv);
    80     NS_WARN_IF_FALSE(gIsObservingCodeBasePrincipalSupport,
    81                      "Installing gCodeBasePrincipalSupport failed!");
    82   }
    83 }
    85 nsBasePrincipal::~nsBasePrincipal(void)
    86 {
    87 }
    89 NS_IMETHODIMP
    90 nsBasePrincipal::GetCsp(nsIContentSecurityPolicy** aCsp)
    91 {
    92   NS_IF_ADDREF(*aCsp = mCSP);
    93   return NS_OK;
    94 }
    96 NS_IMETHODIMP
    97 nsBasePrincipal::SetCsp(nsIContentSecurityPolicy* aCsp)
    98 {
    99   // If CSP was already set, it should not be destroyed!  Instead, it should
   100   // get set anew when a new principal is created.
   101   if (mCSP)
   102     return NS_ERROR_ALREADY_INITIALIZED;
   104   mCSP = aCsp;
   105   return NS_OK;
   106 }
   108 #ifdef DEBUG
   109 void nsPrincipal::dumpImpl()
   110 {
   111   nsAutoCString str;
   112   GetScriptLocation(str);
   113   fprintf(stderr, "nsPrincipal (%p) = %s\n", static_cast<void*>(this), str.get());
   114 }
   115 #endif 
   117 NS_IMPL_CLASSINFO(nsPrincipal, nullptr, nsIClassInfo::MAIN_THREAD_ONLY,
   118                   NS_PRINCIPAL_CID)
   119 NS_IMPL_QUERY_INTERFACE_CI(nsPrincipal,
   120                            nsIPrincipal,
   121                            nsISerializable)
   122 NS_IMPL_CI_INTERFACE_GETTER(nsPrincipal,
   123                             nsIPrincipal,
   124                             nsISerializable)
   125 NS_IMPL_ADDREF_INHERITED(nsPrincipal, nsBasePrincipal)
   126 NS_IMPL_RELEASE_INHERITED(nsPrincipal, nsBasePrincipal)
   128 nsPrincipal::nsPrincipal()
   129   : mAppId(nsIScriptSecurityManager::UNKNOWN_APP_ID)
   130   , mInMozBrowser(false)
   131   , mCodebaseImmutable(false)
   132   , mDomainImmutable(false)
   133   , mInitialized(false)
   134 { }
   136 nsPrincipal::~nsPrincipal()
   137 { }
   139 nsresult
   140 nsPrincipal::Init(nsIURI *aCodebase,
   141                   uint32_t aAppId,
   142                   bool aInMozBrowser)
   143 {
   144   NS_ENSURE_STATE(!mInitialized);
   145   NS_ENSURE_ARG(aCodebase);
   147   mInitialized = true;
   149   mCodebase = NS_TryToMakeImmutable(aCodebase);
   150   mCodebaseImmutable = URIIsImmutable(mCodebase);
   152   mAppId = aAppId;
   153   mInMozBrowser = aInMozBrowser;
   155   return NS_OK;
   156 }
   158 void
   159 nsPrincipal::GetScriptLocation(nsACString &aStr)
   160 {
   161   mCodebase->GetSpec(aStr);
   162 }
   164 /* static */ nsresult
   165 nsPrincipal::GetOriginForURI(nsIURI* aURI, char **aOrigin)
   166 {
   167   if (!aURI) {
   168     return NS_ERROR_FAILURE;
   169   }
   171   *aOrigin = nullptr;
   173   nsCOMPtr<nsIURI> origin = NS_GetInnermostURI(aURI);
   174   if (!origin) {
   175     return NS_ERROR_FAILURE;
   176   }
   178   nsAutoCString hostPort;
   180   // chrome: URLs don't have a meaningful origin, so make
   181   // sure we just get the full spec for them.
   182   // XXX this should be removed in favor of the solution in
   183   // bug 160042.
   184   bool isChrome;
   185   nsresult rv = origin->SchemeIs("chrome", &isChrome);
   186   if (NS_SUCCEEDED(rv) && !isChrome) {
   187     rv = origin->GetAsciiHost(hostPort);
   188     // Some implementations return an empty string, treat it as no support
   189     // for asciiHost by that implementation.
   190     if (hostPort.IsEmpty()) {
   191       rv = NS_ERROR_FAILURE;
   192     }
   193   }
   195   int32_t port;
   196   if (NS_SUCCEEDED(rv) && !isChrome) {
   197     rv = origin->GetPort(&port);
   198   }
   200   if (NS_SUCCEEDED(rv) && !isChrome) {
   201     if (port != -1) {
   202       hostPort.AppendLiteral(":");
   203       hostPort.AppendInt(port, 10);
   204     }
   206     nsAutoCString scheme;
   207     rv = origin->GetScheme(scheme);
   208     NS_ENSURE_SUCCESS(rv, rv);
   210     *aOrigin = ToNewCString(scheme + NS_LITERAL_CSTRING("://") + hostPort);
   211   }
   212   else {
   213     // Some URIs (e.g., nsSimpleURI) don't support asciiHost. Just
   214     // get the full spec.
   215     nsAutoCString spec;
   216     // XXX nsMozIconURI and nsJARURI don't implement this correctly, they
   217     // both fall back to GetSpec.  That needs to be fixed.
   218     rv = origin->GetAsciiSpec(spec);
   219     NS_ENSURE_SUCCESS(rv, rv);
   221     *aOrigin = ToNewCString(spec);
   222   }
   224   return *aOrigin ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
   225 }
   227 NS_IMETHODIMP
   228 nsPrincipal::GetOrigin(char **aOrigin)
   229 {
   230   return GetOriginForURI(mCodebase, aOrigin);
   231 }
   233 NS_IMETHODIMP
   234 nsPrincipal::EqualsConsideringDomain(nsIPrincipal *aOther, bool *aResult)
   235 {
   236   *aResult = false;
   238   if (!aOther) {
   239     NS_WARNING("Need a principal to compare this to!");
   240     return NS_OK;
   241   }
   243   if (aOther == this) {
   244     *aResult = true;
   245     return NS_OK;
   246   }
   248   if (!nsScriptSecurityManager::AppAttributesEqual(this, aOther)) {
   249       return NS_OK;
   250   }
   252   // If either the subject or the object has changed its principal by
   253   // explicitly setting document.domain then the other must also have
   254   // done so in order to be considered the same origin. This prevents
   255   // DNS spoofing based on document.domain (154930)
   257   nsCOMPtr<nsIURI> thisURI;
   258   this->GetDomain(getter_AddRefs(thisURI));
   259   bool thisSetDomain = !!thisURI;
   260   if (!thisURI) {
   261       this->GetURI(getter_AddRefs(thisURI));
   262   }
   264   nsCOMPtr<nsIURI> otherURI;
   265   aOther->GetDomain(getter_AddRefs(otherURI));
   266   bool otherSetDomain = !!otherURI;
   267   if (!otherURI) {
   268       aOther->GetURI(getter_AddRefs(otherURI));
   269   }
   271   *aResult = thisSetDomain == otherSetDomain &&
   272              nsScriptSecurityManager::SecurityCompareURIs(thisURI, otherURI);
   273   return NS_OK;
   274 }
   276 NS_IMETHODIMP
   277 nsPrincipal::Equals(nsIPrincipal *aOther, bool *aResult)
   278 {
   279   *aResult = false;
   281   if (!aOther) {
   282     NS_WARNING("Need a principal to compare this to!");
   283     return NS_OK;
   284   }
   286   if (aOther == this) {
   287     *aResult = true;
   288     return NS_OK;
   289   }
   291   if (!nsScriptSecurityManager::AppAttributesEqual(this, aOther)) {
   292     return NS_OK;
   293   }
   295   nsCOMPtr<nsIURI> otherURI;
   296   nsresult rv = aOther->GetURI(getter_AddRefs(otherURI));
   297   if (NS_FAILED(rv)) {
   298     return rv;
   299   }
   301   NS_ASSERTION(mCodebase,
   302                "shouldn't be calling this on principals from preferences");
   304   // Compare codebases.
   305   *aResult = nsScriptSecurityManager::SecurityCompareURIs(mCodebase,
   306                                                           otherURI);
   307   return NS_OK;
   308 }
   310 NS_IMETHODIMP
   311 nsPrincipal::Subsumes(nsIPrincipal *aOther, bool *aResult)
   312 {
   313   return Equals(aOther, aResult);
   314 }
   316 NS_IMETHODIMP
   317 nsPrincipal::SubsumesConsideringDomain(nsIPrincipal *aOther, bool *aResult)
   318 {
   319   return EqualsConsideringDomain(aOther, aResult);
   320 }
   322 NS_IMETHODIMP
   323 nsPrincipal::GetURI(nsIURI** aURI)
   324 {
   325   if (mCodebaseImmutable) {
   326     NS_ADDREF(*aURI = mCodebase);
   327     return NS_OK;
   328   }
   330   if (!mCodebase) {
   331     *aURI = nullptr;
   332     return NS_OK;
   333   }
   335   return NS_EnsureSafeToReturn(mCodebase, aURI);
   336 }
   338 NS_IMETHODIMP
   339 nsPrincipal::CheckMayLoad(nsIURI* aURI, bool aReport, bool aAllowIfInheritsPrincipal)
   340 {
   341    if (aAllowIfInheritsPrincipal) {
   342     // If the caller specified to allow loads of URIs that inherit
   343     // our principal, allow the load if this URI inherits its principal
   344     if (nsPrincipal::IsPrincipalInherited(aURI)) {
   345       return NS_OK;
   346     }
   347   }
   349   if (nsScriptSecurityManager::SecurityCompareURIs(mCodebase, aURI)) {
   350     return NS_OK;
   351   }
   353   // If strict file origin policy is in effect, local files will always fail
   354   // SecurityCompareURIs unless they are identical. Explicitly check file origin
   355   // policy, in that case.
   356   if (nsScriptSecurityManager::GetStrictFileOriginPolicy() &&
   357       NS_URIIsLocalFile(aURI) &&
   358       NS_RelaxStrictFileOriginPolicy(aURI, mCodebase)) {
   359     return NS_OK;
   360   }
   362   if (aReport) {
   363     nsScriptSecurityManager::ReportError(nullptr, NS_LITERAL_STRING("CheckSameOriginError"), mCodebase, aURI);
   364   }
   365   return NS_ERROR_DOM_BAD_URI;
   366 }
   368 void
   369 nsPrincipal::SetURI(nsIURI* aURI)
   370 {
   371   mCodebase = NS_TryToMakeImmutable(aURI);
   372   mCodebaseImmutable = URIIsImmutable(mCodebase);
   373 }
   375 NS_IMETHODIMP
   376 nsPrincipal::GetHashValue(uint32_t* aValue)
   377 {
   378   NS_PRECONDITION(mCodebase, "Need a codebase");
   380   *aValue = nsScriptSecurityManager::HashPrincipalByOrigin(this);
   381   return NS_OK;
   382 }
   384 NS_IMETHODIMP
   385 nsPrincipal::GetDomain(nsIURI** aDomain)
   386 {
   387   if (!mDomain) {
   388     *aDomain = nullptr;
   389     return NS_OK;
   390   }
   392   if (mDomainImmutable) {
   393     NS_ADDREF(*aDomain = mDomain);
   394     return NS_OK;
   395   }
   397   return NS_EnsureSafeToReturn(mDomain, aDomain);
   398 }
   400 NS_IMETHODIMP
   401 nsPrincipal::SetDomain(nsIURI* aDomain)
   402 {
   403   mDomain = NS_TryToMakeImmutable(aDomain);
   404   mDomainImmutable = URIIsImmutable(mDomain);
   406   // Recompute all wrappers between compartments using this principal and other
   407   // non-chrome compartments.
   408   AutoSafeJSContext cx;
   409   JSPrincipals *principals = nsJSPrincipals::get(static_cast<nsIPrincipal*>(this));
   410   bool success = js::RecomputeWrappers(cx, js::ContentCompartmentsOnly(),
   411                                        js::CompartmentsWithPrincipals(principals));
   412   NS_ENSURE_TRUE(success, NS_ERROR_FAILURE);
   413   success = js::RecomputeWrappers(cx, js::CompartmentsWithPrincipals(principals),
   414                                   js::ContentCompartmentsOnly());
   415   NS_ENSURE_TRUE(success, NS_ERROR_FAILURE);
   417   return NS_OK;
   418 }
   420 NS_IMETHODIMP
   421 nsPrincipal::GetJarPrefix(nsACString& aJarPrefix)
   422 {
   423   MOZ_ASSERT(mAppId != nsIScriptSecurityManager::UNKNOWN_APP_ID);
   425   mozilla::GetJarPrefix(mAppId, mInMozBrowser, aJarPrefix);
   426   return NS_OK;
   427 }
   429 NS_IMETHODIMP
   430 nsPrincipal::GetAppStatus(uint16_t* aAppStatus)
   431 {
   432   *aAppStatus = GetAppStatus();
   433   return NS_OK;
   434 }
   436 NS_IMETHODIMP
   437 nsPrincipal::GetAppId(uint32_t* aAppId)
   438 {
   439   if (mAppId == nsIScriptSecurityManager::UNKNOWN_APP_ID) {
   440     MOZ_ASSERT(false);
   441     *aAppId = nsIScriptSecurityManager::NO_APP_ID;
   442     return NS_OK;
   443   }
   445   *aAppId = mAppId;
   446   return NS_OK;
   447 }
   449 NS_IMETHODIMP
   450 nsPrincipal::GetIsInBrowserElement(bool* aIsInBrowserElement)
   451 {
   452   *aIsInBrowserElement = mInMozBrowser;
   453   return NS_OK;
   454 }
   456 NS_IMETHODIMP
   457 nsPrincipal::GetUnknownAppId(bool* aUnknownAppId)
   458 {
   459   *aUnknownAppId = mAppId == nsIScriptSecurityManager::UNKNOWN_APP_ID;
   460   return NS_OK;
   461 }
   463 NS_IMETHODIMP
   464 nsPrincipal::GetIsNullPrincipal(bool* aIsNullPrincipal)
   465 {
   466   *aIsNullPrincipal = false;
   467   return NS_OK;
   468 }
   470 NS_IMETHODIMP
   471 nsPrincipal::GetBaseDomain(nsACString& aBaseDomain)
   472 {
   473   // For a file URI, we return the file path.
   474   if (NS_URIIsLocalFile(mCodebase)) {
   475     nsCOMPtr<nsIURL> url = do_QueryInterface(mCodebase);
   477     if (url) {
   478       return url->GetFilePath(aBaseDomain);
   479     }
   480   }
   482   // For everything else, we ask the TLD service via
   483   // the ThirdPartyUtil.
   484   nsCOMPtr<mozIThirdPartyUtil> thirdPartyUtil =
   485     do_GetService(THIRDPARTYUTIL_CONTRACTID);
   486   if (thirdPartyUtil) {
   487     return thirdPartyUtil->GetBaseDomain(mCodebase, aBaseDomain);
   488   }
   490   return NS_OK;
   491 }
   493 NS_IMETHODIMP
   494 nsPrincipal::Read(nsIObjectInputStream* aStream)
   495 {
   496   nsCOMPtr<nsISupports> supports;
   497   nsCOMPtr<nsIURI> codebase;
   498   nsresult rv = NS_ReadOptionalObject(aStream, true, getter_AddRefs(supports));
   499   if (NS_FAILED(rv)) {
   500     return rv;
   501   }
   503   codebase = do_QueryInterface(supports);
   505   nsCOMPtr<nsIURI> domain;
   506   rv = NS_ReadOptionalObject(aStream, true, getter_AddRefs(supports));
   507   if (NS_FAILED(rv)) {
   508     return rv;
   509   }
   511   domain = do_QueryInterface(supports);
   513   uint32_t appId;
   514   rv = aStream->Read32(&appId);
   515   NS_ENSURE_SUCCESS(rv, rv);
   517   bool inMozBrowser;
   518   rv = aStream->ReadBoolean(&inMozBrowser);
   519   NS_ENSURE_SUCCESS(rv, rv);
   521   rv = NS_ReadOptionalObject(aStream, true, getter_AddRefs(supports));
   522   NS_ENSURE_SUCCESS(rv, rv);
   524   // This may be null.
   525   nsCOMPtr<nsIContentSecurityPolicy> csp = do_QueryInterface(supports, &rv);
   527   rv = Init(codebase, appId, inMozBrowser);
   528   NS_ENSURE_SUCCESS(rv, rv);
   530   rv = SetCsp(csp);
   531   NS_ENSURE_SUCCESS(rv, rv);
   533   // need to link in the CSP context here (link in a reference to this
   534   // nsIPrincipal and to the URI of the protected resource).
   535   if (csp) {
   536     csp->SetRequestContext(codebase, nullptr, this, nullptr);
   537   }
   539   SetDomain(domain);
   541   return NS_OK;
   542 }
   544 NS_IMETHODIMP
   545 nsPrincipal::Write(nsIObjectOutputStream* aStream)
   546 {
   547   NS_ENSURE_STATE(mCodebase);
   549   nsresult rv = NS_WriteOptionalCompoundObject(aStream, mCodebase, NS_GET_IID(nsIURI),
   550                                                true);
   551   if (NS_FAILED(rv)) {
   552     return rv;
   553   }
   555   rv = NS_WriteOptionalCompoundObject(aStream, mDomain, NS_GET_IID(nsIURI),
   556                                       true);
   557   if (NS_FAILED(rv)) {
   558     return rv;
   559   }
   561   aStream->Write32(mAppId);
   562   aStream->WriteBoolean(mInMozBrowser);
   564   rv = NS_WriteOptionalCompoundObject(aStream, mCSP,
   565                                       NS_GET_IID(nsIContentSecurityPolicy),
   566                                       true);
   567   if (NS_FAILED(rv)) {
   568     return rv;
   569   }
   571   // mCodebaseImmutable and mDomainImmutable will be recomputed based
   572   // on the deserialized URIs in Read().
   574   return NS_OK;
   575 }
   577 uint16_t
   578 nsPrincipal::GetAppStatus()
   579 {
   580   NS_WARN_IF_FALSE(mAppId != nsIScriptSecurityManager::UNKNOWN_APP_ID,
   581                    "Asking for app status on a principal with an unknown app id");
   582   // Installed apps have a valid app id (not NO_APP_ID or UNKNOWN_APP_ID)
   583   // and they are not inside a mozbrowser.
   584   if (mAppId == nsIScriptSecurityManager::NO_APP_ID ||
   585       mAppId == nsIScriptSecurityManager::UNKNOWN_APP_ID || mInMozBrowser) {
   586     return nsIPrincipal::APP_STATUS_NOT_INSTALLED;
   587   }
   589   nsCOMPtr<nsIAppsService> appsService = do_GetService(APPS_SERVICE_CONTRACTID);
   590   NS_ENSURE_TRUE(appsService, nsIPrincipal::APP_STATUS_NOT_INSTALLED);
   592   nsCOMPtr<mozIApplication> app;
   593   appsService->GetAppByLocalId(mAppId, getter_AddRefs(app));
   594   NS_ENSURE_TRUE(app, nsIPrincipal::APP_STATUS_NOT_INSTALLED);
   596   uint16_t status = nsIPrincipal::APP_STATUS_INSTALLED;
   597   NS_ENSURE_SUCCESS(app->GetAppStatus(&status),
   598                     nsIPrincipal::APP_STATUS_NOT_INSTALLED);
   600   nsAutoCString origin;
   601   NS_ENSURE_SUCCESS(GetOrigin(getter_Copies(origin)),
   602                     nsIPrincipal::APP_STATUS_NOT_INSTALLED);
   603   nsString appOrigin;
   604   NS_ENSURE_SUCCESS(app->GetOrigin(appOrigin),
   605                     nsIPrincipal::APP_STATUS_NOT_INSTALLED);
   607   // We go from string -> nsIURI -> origin to be sure we
   608   // compare two punny-encoded origins.
   609   nsCOMPtr<nsIURI> appURI;
   610   NS_ENSURE_SUCCESS(NS_NewURI(getter_AddRefs(appURI), appOrigin),
   611                     nsIPrincipal::APP_STATUS_NOT_INSTALLED);
   613   nsAutoCString appOriginPunned;
   614   NS_ENSURE_SUCCESS(GetOriginForURI(appURI, getter_Copies(appOriginPunned)),
   615                     nsIPrincipal::APP_STATUS_NOT_INSTALLED);
   617   if (!appOriginPunned.Equals(origin)) {
   618     return nsIPrincipal::APP_STATUS_NOT_INSTALLED;
   619   }
   621   return status;
   622 }
   624 /************************************************************************************************************************/
   626 static const char EXPANDED_PRINCIPAL_SPEC[] = "[Expanded Principal]";
   628 NS_IMPL_CLASSINFO(nsExpandedPrincipal, nullptr, nsIClassInfo::MAIN_THREAD_ONLY,
   629                   NS_EXPANDEDPRINCIPAL_CID)
   630 NS_IMPL_QUERY_INTERFACE_CI(nsExpandedPrincipal,
   631                            nsIPrincipal,
   632                            nsIExpandedPrincipal)
   633 NS_IMPL_CI_INTERFACE_GETTER(nsExpandedPrincipal,
   634                              nsIPrincipal,
   635                              nsIExpandedPrincipal)
   636 NS_IMPL_ADDREF_INHERITED(nsExpandedPrincipal, nsBasePrincipal)
   637 NS_IMPL_RELEASE_INHERITED(nsExpandedPrincipal, nsBasePrincipal)
   639 nsExpandedPrincipal::nsExpandedPrincipal(nsTArray<nsCOMPtr <nsIPrincipal> > &aWhiteList)
   640 {
   641   mPrincipals.AppendElements(aWhiteList);
   642 }
   644 nsExpandedPrincipal::~nsExpandedPrincipal()
   645 { }
   647 NS_IMETHODIMP
   648 nsExpandedPrincipal::GetDomain(nsIURI** aDomain)
   649 {
   650   *aDomain = nullptr;
   651   return NS_OK;
   652 }
   654 NS_IMETHODIMP
   655 nsExpandedPrincipal::SetDomain(nsIURI* aDomain)
   656 {
   657   return NS_OK;
   658 }
   660 NS_IMETHODIMP
   661 nsExpandedPrincipal::GetOrigin(char** aOrigin)
   662 {
   663   *aOrigin = ToNewCString(NS_LITERAL_CSTRING(EXPANDED_PRINCIPAL_SPEC));
   664   return *aOrigin ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
   665 }
   667 typedef nsresult (NS_STDCALL nsIPrincipal::*nsIPrincipalMemFn)(nsIPrincipal* aOther,
   668                                                                bool* aResult);
   669 #define CALL_MEMBER_FUNCTION(THIS,MEM_FN)  ((THIS)->*(MEM_FN))
   671 // nsExpandedPrincipal::Equals and nsExpandedPrincipal::EqualsConsideringDomain
   672 // shares the same logic. The difference only that Equals requires 'this'
   673 // and 'aOther' to Subsume each other while EqualsConsideringDomain requires
   674 // bidirectional SubsumesConsideringDomain.
   675 static nsresult
   676 Equals(nsExpandedPrincipal* aThis, nsIPrincipalMemFn aFn, nsIPrincipal* aOther,
   677        bool* aResult)
   678 {
   679   // If (and only if) 'aThis' and 'aOther' both Subsume/SubsumesConsideringDomain
   680   // each other, then they are Equal.
   681   *aResult = false;
   682   // Calling the corresponding subsume function on this (aFn).
   683   nsresult rv = CALL_MEMBER_FUNCTION(aThis, aFn)(aOther, aResult);
   684   NS_ENSURE_SUCCESS(rv, rv);
   685   if (!*aResult)
   686     return NS_OK;
   688   // Calling the corresponding subsume function on aOther (aFn).
   689   rv = CALL_MEMBER_FUNCTION(aOther, aFn)(aThis, aResult);
   690   NS_ENSURE_SUCCESS(rv, rv);
   691   return NS_OK;
   692 }
   694 NS_IMETHODIMP
   695 nsExpandedPrincipal::Equals(nsIPrincipal* aOther, bool* aResult)
   696 {
   697   return ::Equals(this, &nsIPrincipal::Subsumes, aOther, aResult);
   698 }
   700 NS_IMETHODIMP
   701 nsExpandedPrincipal::EqualsConsideringDomain(nsIPrincipal* aOther, bool* aResult)
   702 {
   703   return ::Equals(this, &nsIPrincipal::SubsumesConsideringDomain, aOther, aResult);
   704 }
   706 // nsExpandedPrincipal::Subsumes and nsExpandedPrincipal::SubsumesConsideringDomain
   707 // shares the same logic. The difference only that Subsumes calls are replaced
   708 //with SubsumesConsideringDomain calls in the second case.
   709 static nsresult
   710 Subsumes(nsExpandedPrincipal* aThis, nsIPrincipalMemFn aFn, nsIPrincipal* aOther,
   711          bool* aResult)
   712 {
   713   nsresult rv;
   714   nsCOMPtr<nsIExpandedPrincipal> expanded = do_QueryInterface(aOther);
   715   if (expanded) {
   716     // If aOther is an ExpandedPrincipal too, check if all of its
   717     // principals are subsumed.
   718     nsTArray< nsCOMPtr<nsIPrincipal> >* otherList;
   719     expanded->GetWhiteList(&otherList);
   720     for (uint32_t i = 0; i < otherList->Length(); ++i){
   721       rv = CALL_MEMBER_FUNCTION(aThis, aFn)((*otherList)[i], aResult);
   722       NS_ENSURE_SUCCESS(rv, rv);
   723       if (!*aResult) {
   724         // If we don't subsume at least one principal of aOther, return false.
   725         return NS_OK;
   726       }
   727     }
   728   } else {
   729     // For a regular aOther, one of our principals must subsume it.
   730     nsTArray< nsCOMPtr<nsIPrincipal> >* list;
   731     aThis->GetWhiteList(&list);
   732     for (uint32_t i = 0; i < list->Length(); ++i){
   733       rv = CALL_MEMBER_FUNCTION((*list)[i], aFn)(aOther, aResult);
   734       NS_ENSURE_SUCCESS(rv, rv);
   735       if (*aResult) {
   736         // If one of our principal subsumes it, return true.
   737         return NS_OK;
   738       }
   739     }
   740   }
   741   return NS_OK;
   742 }
   744 #undef CALL_MEMBER_FUNCTION
   746 NS_IMETHODIMP
   747 nsExpandedPrincipal::Subsumes(nsIPrincipal* aOther, bool* aResult)
   748 {
   749   return ::Subsumes(this, &nsIPrincipal::Subsumes, aOther, aResult);
   750 }
   752 NS_IMETHODIMP
   753 nsExpandedPrincipal::SubsumesConsideringDomain(nsIPrincipal* aOther, bool* aResult)
   754 {
   755   return ::Subsumes(this, &nsIPrincipal::SubsumesConsideringDomain, aOther, aResult);
   756 }
   758 NS_IMETHODIMP
   759 nsExpandedPrincipal::CheckMayLoad(nsIURI* uri, bool aReport, bool aAllowIfInheritsPrincipal)
   760 {
   761   nsresult rv;
   762   for (uint32_t i = 0; i < mPrincipals.Length(); ++i){
   763     rv = mPrincipals[i]->CheckMayLoad(uri, aReport, aAllowIfInheritsPrincipal);
   764     if (NS_SUCCEEDED(rv))
   765       return rv;
   766   }
   768   return NS_ERROR_DOM_BAD_URI;
   769 }
   771 NS_IMETHODIMP
   772 nsExpandedPrincipal::GetHashValue(uint32_t* result)
   773 {
   774   MOZ_CRASH("extended principal should never be used as key in a hash map");
   775 }
   777 NS_IMETHODIMP
   778 nsExpandedPrincipal::GetURI(nsIURI** aURI)
   779 {
   780   *aURI = nullptr;
   781   return NS_OK;
   782 }
   784 NS_IMETHODIMP
   785 nsExpandedPrincipal::GetWhiteList(nsTArray<nsCOMPtr<nsIPrincipal> >** aWhiteList)
   786 {
   787   *aWhiteList = &mPrincipals;
   788   return NS_OK;
   789 }
   791 NS_IMETHODIMP
   792 nsExpandedPrincipal::GetJarPrefix(nsACString& aJarPrefix)
   793 {
   794   aJarPrefix.Truncate();
   795   return NS_OK;
   796 }
   798 NS_IMETHODIMP
   799 nsExpandedPrincipal::GetAppStatus(uint16_t* aAppStatus)
   800 {
   801   *aAppStatus = nsIPrincipal::APP_STATUS_NOT_INSTALLED;
   802   return NS_OK;
   803 }
   805 NS_IMETHODIMP
   806 nsExpandedPrincipal::GetAppId(uint32_t* aAppId)
   807 {
   808   *aAppId = nsIScriptSecurityManager::NO_APP_ID;
   809   return NS_OK;
   810 }
   812 NS_IMETHODIMP
   813 nsExpandedPrincipal::GetIsInBrowserElement(bool* aIsInBrowserElement)
   814 {
   815   *aIsInBrowserElement = false;
   816   return NS_OK;
   817 }
   819 NS_IMETHODIMP
   820 nsExpandedPrincipal::GetUnknownAppId(bool* aUnknownAppId)
   821 {
   822   *aUnknownAppId = false;
   823   return NS_OK;
   824 }
   826 NS_IMETHODIMP
   827 nsExpandedPrincipal::GetIsNullPrincipal(bool* aIsNullPrincipal)
   828 {
   829   *aIsNullPrincipal = false;
   830   return NS_OK;
   831 }
   833 NS_IMETHODIMP
   834 nsExpandedPrincipal::GetBaseDomain(nsACString& aBaseDomain)
   835 {
   836   return NS_ERROR_NOT_AVAILABLE;
   837 }
   839 void
   840 nsExpandedPrincipal::GetScriptLocation(nsACString& aStr)
   841 {
   842   // Is that a good idea to list it's principals?
   843   aStr.Assign(EXPANDED_PRINCIPAL_SPEC);
   844 }
   846 #ifdef DEBUG
   847 void nsExpandedPrincipal::dumpImpl()
   848 {
   849   fprintf(stderr, "nsExpandedPrincipal (%p)\n", static_cast<void*>(this));
   850 }
   851 #endif 
   853 //////////////////////////////////////////
   854 // Methods implementing nsISerializable //
   855 //////////////////////////////////////////
   857 NS_IMETHODIMP
   858 nsExpandedPrincipal::Read(nsIObjectInputStream* aStream)
   859 {
   860   return NS_ERROR_NOT_IMPLEMENTED;
   861 }
   863 NS_IMETHODIMP
   864 nsExpandedPrincipal::Write(nsIObjectOutputStream* aStream)
   865 {
   866   return NS_ERROR_NOT_IMPLEMENTED;
   867 }

mercurial