mirror of
https://github.com/roytam1/UXP.git
synced 2026-05-26 13:58:49 +00:00
9847e9f759
Per the CSP specification, content injected by extensions is meant to be exempt from page CSP. This patch takes care of the most common case of content injected by extension content scripts, which always have expanded principals which inherit from the page principal. To make this easier, de-virtualize BasePrincipal::Kind(), using CTOR initializers instead.
680 lines
18 KiB
C++
680 lines
18 KiB
C++
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
#include "nsPrincipal.h"
|
|
|
|
#include "mozIThirdPartyUtil.h"
|
|
#include "nscore.h"
|
|
#include "nsScriptSecurityManager.h"
|
|
#include "nsString.h"
|
|
#include "nsReadableUtils.h"
|
|
#include "pratom.h"
|
|
#include "nsIURI.h"
|
|
#include "nsIURL.h"
|
|
#include "nsIStandardURL.h"
|
|
#include "nsIURIWithPrincipal.h"
|
|
#include "nsJSPrincipals.h"
|
|
#include "nsIEffectiveTLDService.h"
|
|
#include "nsIClassInfoImpl.h"
|
|
#include "nsIObjectInputStream.h"
|
|
#include "nsIObjectOutputStream.h"
|
|
#include "nsIProtocolHandler.h"
|
|
#include "nsError.h"
|
|
#include "nsIContentSecurityPolicy.h"
|
|
#include "nsNetCID.h"
|
|
#include "jswrapper.h"
|
|
|
|
#include "mozilla/dom/nsCSPContext.h"
|
|
#include "mozilla/dom/ScriptSettings.h"
|
|
#include "mozilla/Preferences.h"
|
|
#include "mozilla/HashFunctions.h"
|
|
|
|
using namespace mozilla;
|
|
|
|
static bool gCodeBasePrincipalSupport = false;
|
|
|
|
static bool URIIsImmutable(nsIURI* aURI)
|
|
{
|
|
nsCOMPtr<nsIMutable> mutableObj(do_QueryInterface(aURI));
|
|
bool isMutable;
|
|
return
|
|
mutableObj &&
|
|
NS_SUCCEEDED(mutableObj->GetMutable(&isMutable)) &&
|
|
!isMutable;
|
|
}
|
|
|
|
NS_IMPL_CLASSINFO(nsPrincipal, nullptr, nsIClassInfo::MAIN_THREAD_ONLY,
|
|
NS_PRINCIPAL_CID)
|
|
NS_IMPL_QUERY_INTERFACE_CI(nsPrincipal,
|
|
nsIPrincipal,
|
|
nsISerializable)
|
|
NS_IMPL_CI_INTERFACE_GETTER(nsPrincipal,
|
|
nsIPrincipal,
|
|
nsISerializable)
|
|
|
|
// Called at startup:
|
|
/* static */ void
|
|
nsPrincipal::InitializeStatics()
|
|
{
|
|
Preferences::AddBoolVarCache(&gCodeBasePrincipalSupport,
|
|
"signed.applets.codebase_principal_support",
|
|
false);
|
|
}
|
|
|
|
nsPrincipal::nsPrincipal()
|
|
: BasePrincipal(eCodebasePrincipal)
|
|
, mCodebaseImmutable(false)
|
|
, mDomainImmutable(false)
|
|
, mInitialized(false)
|
|
{}
|
|
|
|
nsPrincipal::~nsPrincipal()
|
|
{
|
|
// let's clear the principal within the csp to avoid a tangling pointer
|
|
if (mCSP) {
|
|
static_cast<nsCSPContext*>(mCSP.get())->clearLoadingPrincipal();
|
|
}
|
|
}
|
|
|
|
nsresult
|
|
nsPrincipal::Init(nsIURI *aCodebase, const PrincipalOriginAttributes& aOriginAttributes)
|
|
{
|
|
NS_ENSURE_STATE(!mInitialized);
|
|
NS_ENSURE_ARG(aCodebase);
|
|
|
|
mInitialized = true;
|
|
|
|
mCodebase = NS_TryToMakeImmutable(aCodebase);
|
|
mCodebaseImmutable = URIIsImmutable(mCodebase);
|
|
mOriginAttributes = aOriginAttributes;
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
nsresult
|
|
nsPrincipal::GetScriptLocation(nsACString &aStr)
|
|
{
|
|
return mCodebase->GetSpec(aStr);
|
|
}
|
|
|
|
/* static */ nsresult
|
|
nsPrincipal::GetOriginForURI(nsIURI* aURI, nsACString& aOrigin)
|
|
{
|
|
if (!aURI) {
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
nsCOMPtr<nsIURI> origin = NS_GetInnermostURI(aURI);
|
|
if (!origin) {
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
nsresult rv;
|
|
// NB: This is only compiled for Thunderbird/Suite.
|
|
#if IS_ORIGIN_IS_FULL_SPEC_DEFINED
|
|
bool fullSpec = false;
|
|
rv = NS_URIChainHasFlags(origin, nsIProtocolHandler::ORIGIN_IS_FULL_SPEC, &fullSpec);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
if (fullSpec) {
|
|
return origin->GetAsciiSpec(aOrigin);
|
|
}
|
|
#endif
|
|
|
|
nsAutoCString hostPort;
|
|
|
|
// chrome: URLs don't have a meaningful origin, so make
|
|
// sure we just get the full spec for them.
|
|
// XXX this should be removed in favor of the solution in
|
|
// bug 160042.
|
|
bool isChrome;
|
|
rv = origin->SchemeIs("chrome", &isChrome);
|
|
if (NS_SUCCEEDED(rv) && !isChrome) {
|
|
rv = origin->GetAsciiHostPort(hostPort);
|
|
// Some implementations return an empty string, treat it as no support
|
|
// for asciiHost by that implementation.
|
|
if (hostPort.IsEmpty()) {
|
|
rv = NS_ERROR_FAILURE;
|
|
}
|
|
}
|
|
|
|
// We want the invariant that prinA.origin == prinB.origin i.f.f.
|
|
// prinA.equals(prinB). However, this requires that we impose certain constraints
|
|
// on the behavior and origin semantics of principals, and in particular, forbid
|
|
// creating origin strings for principals whose equality constraints are not
|
|
// expressible as strings (i.e. object equality). Moreover, we want to forbid URIs
|
|
// containing the magic "^" we use as a separating character for origin
|
|
// attributes.
|
|
//
|
|
// These constraints can generally be achieved by restricting .origin to
|
|
// nsIStandardURL-based URIs, but there are a few other URI schemes that we need
|
|
// to handle.
|
|
bool isBehaved;
|
|
if ((NS_SUCCEEDED(origin->SchemeIs("about", &isBehaved)) && isBehaved) ||
|
|
(NS_SUCCEEDED(origin->SchemeIs("moz-safe-about", &isBehaved)) && isBehaved) ||
|
|
(NS_SUCCEEDED(origin->SchemeIs("indexeddb", &isBehaved)) && isBehaved)) {
|
|
rv = origin->GetAsciiSpec(aOrigin);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
// Remove query or ref part from about: origin
|
|
int32_t pos = aOrigin.FindChar('?');
|
|
int32_t hashPos = aOrigin.FindChar('#');
|
|
|
|
if (hashPos != kNotFound && (pos == kNotFound || hashPos < pos)) {
|
|
pos = hashPos;
|
|
}
|
|
|
|
if (pos != kNotFound) {
|
|
aOrigin.Truncate(pos);
|
|
}
|
|
|
|
// These URIs could technically contain a '^', but they never should.
|
|
if (NS_WARN_IF(aOrigin.FindChar('^', 0) != -1)) {
|
|
aOrigin.Truncate();
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
return NS_OK;
|
|
}
|
|
|
|
if (NS_SUCCEEDED(rv) && !isChrome) {
|
|
rv = origin->GetScheme(aOrigin);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
aOrigin.AppendLiteral("://");
|
|
aOrigin.Append(hostPort);
|
|
}
|
|
else {
|
|
// If we reached this branch, we can only create an origin if we have a nsIStandardURL.
|
|
// So, we query to a nsIStandardURL, and fail if we aren't an instance of an nsIStandardURL
|
|
// nsIStandardURLs have the good property of escaping the '^' character in their specs,
|
|
// which means that we can be sure that the caret character (which is reserved for delimiting
|
|
// the end of the spec, and the beginning of the origin attributes) is not present in the
|
|
// origin string
|
|
nsCOMPtr<nsIStandardURL> standardURL = do_QueryInterface(origin);
|
|
NS_ENSURE_TRUE(standardURL, NS_ERROR_FAILURE);
|
|
|
|
rv = origin->GetAsciiSpec(aOrigin);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
// The origin, when taken from the spec, should not contain the ref part of
|
|
// the URL.
|
|
|
|
int32_t pos = aOrigin.FindChar('?');
|
|
int32_t hashPos = aOrigin.FindChar('#');
|
|
|
|
if (hashPos != kNotFound && (pos == kNotFound || hashPos < pos)) {
|
|
pos = hashPos;
|
|
}
|
|
|
|
if (pos != kNotFound) {
|
|
aOrigin.Truncate(pos);
|
|
}
|
|
}
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
nsresult
|
|
nsPrincipal::GetOriginInternal(nsACString& aOrigin)
|
|
{
|
|
return GetOriginForURI(mCodebase, aOrigin);
|
|
}
|
|
|
|
bool
|
|
nsPrincipal::SubsumesInternal(nsIPrincipal* aOther,
|
|
BasePrincipal::DocumentDomainConsideration aConsideration)
|
|
{
|
|
MOZ_ASSERT(aOther);
|
|
|
|
// For nsPrincipal, Subsumes is equivalent to Equals.
|
|
if (aOther == this) {
|
|
return true;
|
|
}
|
|
|
|
// If either the subject or the object has changed its principal by
|
|
// explicitly setting document.domain then the other must also have
|
|
// done so in order to be considered the same origin. This prevents
|
|
// DNS spoofing based on document.domain (154930)
|
|
nsresult rv;
|
|
if (aConsideration == ConsiderDocumentDomain) {
|
|
// Get .domain on each principal.
|
|
nsCOMPtr<nsIURI> thisDomain, otherDomain;
|
|
GetDomain(getter_AddRefs(thisDomain));
|
|
aOther->GetDomain(getter_AddRefs(otherDomain));
|
|
|
|
// If either has .domain set, we have equality i.f.f. the domains match.
|
|
// Otherwise, we fall through to the non-document-domain-considering case.
|
|
if (thisDomain || otherDomain) {
|
|
return nsScriptSecurityManager::SecurityCompareURIs(thisDomain, otherDomain);
|
|
}
|
|
}
|
|
|
|
nsCOMPtr<nsIURI> otherURI;
|
|
rv = aOther->GetURI(getter_AddRefs(otherURI));
|
|
NS_ENSURE_SUCCESS(rv, false);
|
|
|
|
// Compare codebases.
|
|
return nsScriptSecurityManager::SecurityCompareURIs(mCodebase, otherURI);
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsPrincipal::GetURI(nsIURI** aURI)
|
|
{
|
|
if (mCodebaseImmutable) {
|
|
NS_ADDREF(*aURI = mCodebase);
|
|
return NS_OK;
|
|
}
|
|
|
|
if (!mCodebase) {
|
|
*aURI = nullptr;
|
|
return NS_OK;
|
|
}
|
|
|
|
return NS_EnsureSafeToReturn(mCodebase, aURI);
|
|
}
|
|
|
|
bool
|
|
nsPrincipal::MayLoadInternal(nsIURI* aURI)
|
|
{
|
|
// See if aURI is something like a Blob URI that is actually associated with
|
|
// a principal.
|
|
nsCOMPtr<nsIURIWithPrincipal> uriWithPrin = do_QueryInterface(aURI);
|
|
nsCOMPtr<nsIPrincipal> uriPrin;
|
|
if (uriWithPrin) {
|
|
uriWithPrin->GetPrincipal(getter_AddRefs(uriPrin));
|
|
}
|
|
if (uriPrin) {
|
|
return nsIPrincipal::Subsumes(uriPrin);
|
|
}
|
|
|
|
// If this principal is associated with an addon, check whether that addon
|
|
// has been given permission to load from this domain.
|
|
if (AddonAllowsLoad(aURI)) {
|
|
return true;
|
|
}
|
|
|
|
if (nsScriptSecurityManager::SecurityCompareURIs(mCodebase, aURI)) {
|
|
return true;
|
|
}
|
|
|
|
// If strict file origin policy is in effect, local files will always fail
|
|
// SecurityCompareURIs unless they are identical. Explicitly check file origin
|
|
// policy, in that case.
|
|
if (nsScriptSecurityManager::GetStrictFileOriginPolicy() &&
|
|
NS_URIIsLocalFile(aURI) &&
|
|
NS_RelaxStrictFileOriginPolicy(aURI, mCodebase)) {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void
|
|
nsPrincipal::SetURI(nsIURI* aURI)
|
|
{
|
|
mCodebase = NS_TryToMakeImmutable(aURI);
|
|
mCodebaseImmutable = URIIsImmutable(mCodebase);
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsPrincipal::GetHashValue(uint32_t* aValue)
|
|
{
|
|
NS_PRECONDITION(mCodebase, "Need a codebase");
|
|
|
|
*aValue = nsScriptSecurityManager::HashPrincipalByOrigin(this);
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsPrincipal::GetDomain(nsIURI** aDomain)
|
|
{
|
|
if (!mDomain) {
|
|
*aDomain = nullptr;
|
|
return NS_OK;
|
|
}
|
|
|
|
if (mDomainImmutable) {
|
|
NS_ADDREF(*aDomain = mDomain);
|
|
return NS_OK;
|
|
}
|
|
|
|
return NS_EnsureSafeToReturn(mDomain, aDomain);
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsPrincipal::SetDomain(nsIURI* aDomain)
|
|
{
|
|
mDomain = NS_TryToMakeImmutable(aDomain);
|
|
mDomainImmutable = URIIsImmutable(mDomain);
|
|
|
|
// Recompute all wrappers between compartments using this principal and other
|
|
// non-chrome compartments.
|
|
AutoSafeJSContext cx;
|
|
JSPrincipals *principals = nsJSPrincipals::get(static_cast<nsIPrincipal*>(this));
|
|
bool success = js::RecomputeWrappers(cx, js::ContentCompartmentsOnly(),
|
|
js::CompartmentsWithPrincipals(principals));
|
|
NS_ENSURE_TRUE(success, NS_ERROR_FAILURE);
|
|
success = js::RecomputeWrappers(cx, js::CompartmentsWithPrincipals(principals),
|
|
js::ContentCompartmentsOnly());
|
|
NS_ENSURE_TRUE(success, NS_ERROR_FAILURE);
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsPrincipal::GetBaseDomain(nsACString& aBaseDomain)
|
|
{
|
|
// For a file URI, we return the file path.
|
|
if (NS_URIIsLocalFile(mCodebase)) {
|
|
nsCOMPtr<nsIURL> url = do_QueryInterface(mCodebase);
|
|
|
|
if (url) {
|
|
return url->GetFilePath(aBaseDomain);
|
|
}
|
|
}
|
|
|
|
bool hasNoRelativeFlag;
|
|
nsresult rv = NS_URIChainHasFlags(mCodebase,
|
|
nsIProtocolHandler::URI_NORELATIVE,
|
|
&hasNoRelativeFlag);
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
return rv;
|
|
}
|
|
|
|
if (hasNoRelativeFlag) {
|
|
return mCodebase->GetSpec(aBaseDomain);
|
|
}
|
|
|
|
// For everything else, we ask the TLD service via
|
|
// the ThirdPartyUtil.
|
|
nsCOMPtr<mozIThirdPartyUtil> thirdPartyUtil =
|
|
do_GetService(THIRDPARTYUTIL_CONTRACTID);
|
|
if (thirdPartyUtil) {
|
|
return thirdPartyUtil->GetBaseDomain(mCodebase, aBaseDomain);
|
|
}
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsPrincipal::Read(nsIObjectInputStream* aStream)
|
|
{
|
|
nsCOMPtr<nsISupports> supports;
|
|
nsCOMPtr<nsIURI> codebase;
|
|
nsresult rv = NS_ReadOptionalObject(aStream, true, getter_AddRefs(supports));
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
|
|
codebase = do_QueryInterface(supports);
|
|
|
|
nsCOMPtr<nsIURI> domain;
|
|
rv = NS_ReadOptionalObject(aStream, true, getter_AddRefs(supports));
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
|
|
domain = do_QueryInterface(supports);
|
|
|
|
nsAutoCString suffix;
|
|
rv = aStream->ReadCString(suffix);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
PrincipalOriginAttributes attrs;
|
|
bool ok = attrs.PopulateFromSuffix(suffix);
|
|
NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE);
|
|
|
|
rv = NS_ReadOptionalObject(aStream, true, getter_AddRefs(supports));
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
rv = Init(codebase, attrs);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
mCSP = do_QueryInterface(supports, &rv);
|
|
// make sure setRequestContext is called after Init(),
|
|
// to make sure the principals URI been initalized.
|
|
if (mCSP) {
|
|
mCSP->SetRequestContext(nullptr, this);
|
|
}
|
|
|
|
SetDomain(domain);
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsPrincipal::Write(nsIObjectOutputStream* aStream)
|
|
{
|
|
NS_ENSURE_STATE(mCodebase);
|
|
nsresult rv = NS_WriteOptionalCompoundObject(aStream, mCodebase, NS_GET_IID(nsIURI),
|
|
true);
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
|
|
rv = NS_WriteOptionalCompoundObject(aStream, mDomain, NS_GET_IID(nsIURI),
|
|
true);
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
|
|
nsAutoCString suffix;
|
|
OriginAttributesRef().CreateSuffix(suffix);
|
|
|
|
rv = aStream->WriteStringZ(suffix.get());
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
rv = NS_WriteOptionalCompoundObject(aStream, mCSP,
|
|
NS_GET_IID(nsIContentSecurityPolicy),
|
|
true);
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
|
|
// mCodebaseImmutable and mDomainImmutable will be recomputed based
|
|
// on the deserialized URIs in Read().
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
/************************************************************************************************************************/
|
|
|
|
NS_IMPL_CLASSINFO(nsExpandedPrincipal, nullptr, nsIClassInfo::MAIN_THREAD_ONLY,
|
|
NS_EXPANDEDPRINCIPAL_CID)
|
|
NS_IMPL_QUERY_INTERFACE_CI(nsExpandedPrincipal,
|
|
nsIPrincipal,
|
|
nsIExpandedPrincipal)
|
|
NS_IMPL_CI_INTERFACE_GETTER(nsExpandedPrincipal,
|
|
nsIPrincipal,
|
|
nsIExpandedPrincipal)
|
|
|
|
struct OriginComparator
|
|
{
|
|
bool LessThan(nsIPrincipal* a, nsIPrincipal* b) const
|
|
{
|
|
nsAutoCString originA;
|
|
nsresult rv = a->GetOrigin(originA);
|
|
NS_ENSURE_SUCCESS(rv, false);
|
|
nsAutoCString originB;
|
|
rv = b->GetOrigin(originB);
|
|
NS_ENSURE_SUCCESS(rv, false);
|
|
return originA < originB;
|
|
}
|
|
|
|
bool Equals(nsIPrincipal* a, nsIPrincipal* b) const
|
|
{
|
|
nsAutoCString originA;
|
|
nsresult rv = a->GetOrigin(originA);
|
|
NS_ENSURE_SUCCESS(rv, false);
|
|
nsAutoCString originB;
|
|
rv = b->GetOrigin(originB);
|
|
NS_ENSURE_SUCCESS(rv, false);
|
|
return a == b;
|
|
}
|
|
};
|
|
|
|
nsExpandedPrincipal::nsExpandedPrincipal(nsTArray<nsCOMPtr<nsIPrincipal>> &aWhiteList,
|
|
const PrincipalOriginAttributes& aAttrs)
|
|
: BasePrincipal(eExpandedPrincipal)
|
|
{
|
|
// We force the principals to be sorted by origin so that nsExpandedPrincipal
|
|
// origins can have a canonical form.
|
|
OriginComparator c;
|
|
for (size_t i = 0; i < aWhiteList.Length(); ++i) {
|
|
mPrincipals.InsertElementSorted(aWhiteList[i], c);
|
|
}
|
|
mOriginAttributes = aAttrs;
|
|
}
|
|
|
|
nsExpandedPrincipal::~nsExpandedPrincipal()
|
|
{ }
|
|
|
|
NS_IMETHODIMP
|
|
nsExpandedPrincipal::GetDomain(nsIURI** aDomain)
|
|
{
|
|
*aDomain = nullptr;
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsExpandedPrincipal::SetDomain(nsIURI* aDomain)
|
|
{
|
|
return NS_OK;
|
|
}
|
|
|
|
nsresult
|
|
nsExpandedPrincipal::GetOriginInternal(nsACString& aOrigin)
|
|
{
|
|
aOrigin.AssignLiteral("[Expanded Principal [");
|
|
for (size_t i = 0; i < mPrincipals.Length(); ++i) {
|
|
if (i != 0) {
|
|
aOrigin.AppendLiteral(", ");
|
|
}
|
|
|
|
nsAutoCString subOrigin;
|
|
nsresult rv = mPrincipals.ElementAt(i)->GetOrigin(subOrigin);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
aOrigin.Append(subOrigin);
|
|
}
|
|
|
|
aOrigin.Append("]]");
|
|
return NS_OK;
|
|
}
|
|
|
|
bool
|
|
nsExpandedPrincipal::SubsumesInternal(nsIPrincipal* aOther,
|
|
BasePrincipal::DocumentDomainConsideration aConsideration)
|
|
{
|
|
// If aOther is an ExpandedPrincipal too, we break it down into its component
|
|
// nsIPrincipals, and check subsumes on each one.
|
|
nsCOMPtr<nsIExpandedPrincipal> expanded = do_QueryInterface(aOther);
|
|
if (expanded) {
|
|
nsTArray< nsCOMPtr<nsIPrincipal> >* otherList;
|
|
expanded->GetWhiteList(&otherList);
|
|
for (uint32_t i = 0; i < otherList->Length(); ++i){
|
|
// Use SubsumesInternal rather than Subsumes here, since OriginAttribute
|
|
// checks are only done between non-expanded sub-principals, and we don't
|
|
// need to incur the extra virtual call overhead.
|
|
if (!SubsumesInternal((*otherList)[i], aConsideration)) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
// We're dealing with a regular principal. One of our principals must subsume
|
|
// it.
|
|
for (uint32_t i = 0; i < mPrincipals.Length(); ++i) {
|
|
if (Cast(mPrincipals[i])->Subsumes(aOther, aConsideration)) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool
|
|
nsExpandedPrincipal::MayLoadInternal(nsIURI* uri)
|
|
{
|
|
for (uint32_t i = 0; i < mPrincipals.Length(); ++i){
|
|
if (BasePrincipal::Cast(mPrincipals[i])->MayLoadInternal(uri)) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsExpandedPrincipal::GetHashValue(uint32_t* result)
|
|
{
|
|
MOZ_CRASH("extended principal should never be used as key in a hash map");
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsExpandedPrincipal::GetURI(nsIURI** aURI)
|
|
{
|
|
*aURI = nullptr;
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsExpandedPrincipal::GetWhiteList(nsTArray<nsCOMPtr<nsIPrincipal> >** aWhiteList)
|
|
{
|
|
*aWhiteList = &mPrincipals;
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsExpandedPrincipal::GetBaseDomain(nsACString& aBaseDomain)
|
|
{
|
|
return NS_ERROR_NOT_AVAILABLE;
|
|
}
|
|
|
|
bool
|
|
nsExpandedPrincipal::AddonHasPermission(const nsAString& aPerm)
|
|
{
|
|
for (size_t i = 0; i < mPrincipals.Length(); ++i) {
|
|
if (BasePrincipal::Cast(mPrincipals[i])->AddonHasPermission(aPerm)) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
nsresult
|
|
nsExpandedPrincipal::GetScriptLocation(nsACString& aStr)
|
|
{
|
|
aStr.Assign("[Expanded Principal [");
|
|
for (size_t i = 0; i < mPrincipals.Length(); ++i) {
|
|
if (i != 0) {
|
|
aStr.AppendLiteral(", ");
|
|
}
|
|
|
|
nsAutoCString spec;
|
|
nsresult rv =
|
|
nsJSPrincipals::get(mPrincipals.ElementAt(i))->GetScriptLocation(spec);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
aStr.Append(spec);
|
|
}
|
|
aStr.Append("]]");
|
|
return NS_OK;
|
|
}
|
|
|
|
//////////////////////////////////////////
|
|
// Methods implementing nsISerializable //
|
|
//////////////////////////////////////////
|
|
|
|
NS_IMETHODIMP
|
|
nsExpandedPrincipal::Read(nsIObjectInputStream* aStream)
|
|
{
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsExpandedPrincipal::Write(nsIObjectOutputStream* aStream)
|
|
{
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
}
|