mirror of
https://github.com/roytam1/UXP.git
synced 2026-05-26 14:54:25 +00:00
5ee2871524
Manual checking of the origins in SecFetch fails, so we add this capability to the base principal interface for sake of ease. We could use ScriptSecurityManager directly but it's more convenient this way and can be re-used elsewhere in the future.
787 lines
21 KiB
C++
787 lines
21 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 "mozilla/BasePrincipal.h"
|
|
|
|
#include "nsDocShell.h"
|
|
#include "nsIAddonPolicyService.h"
|
|
#include "nsIContentSecurityPolicy.h"
|
|
#include "nsIEffectiveTLDService.h"
|
|
#include "nsIObjectInputStream.h"
|
|
#include "nsIObjectOutputStream.h"
|
|
|
|
#include "nsPrincipal.h"
|
|
#include "nsNetUtil.h"
|
|
#include "nsIURIWithPrincipal.h"
|
|
#include "nsNullPrincipal.h"
|
|
#include "nsScriptSecurityManager.h"
|
|
#include "nsServiceManagerUtils.h"
|
|
|
|
#include "mozilla/dom/ChromeUtils.h"
|
|
#include "mozilla/dom/CSPDictionariesBinding.h"
|
|
#include "mozilla/dom/quota/QuotaManager.h"
|
|
#include "mozilla/dom/ToJSValue.h"
|
|
#include "mozilla/dom/URLSearchParams.h"
|
|
|
|
namespace mozilla {
|
|
|
|
using dom::URLParams;
|
|
|
|
void
|
|
PrincipalOriginAttributes::InheritFromDocShellToDoc(const DocShellOriginAttributes& aAttrs,
|
|
const nsIURI* aURI)
|
|
{
|
|
mAppId = aAttrs.mAppId;
|
|
mInIsolatedMozBrowser = aAttrs.mInIsolatedMozBrowser;
|
|
|
|
// addonId is computed from the principal URI and never propagated
|
|
mUserContextId = aAttrs.mUserContextId;
|
|
|
|
mPrivateBrowsingId = aAttrs.mPrivateBrowsingId;
|
|
mFirstPartyDomain = aAttrs.mFirstPartyDomain;
|
|
}
|
|
|
|
void
|
|
PrincipalOriginAttributes::InheritFromNecko(const NeckoOriginAttributes& aAttrs)
|
|
{
|
|
mAppId = aAttrs.mAppId;
|
|
mInIsolatedMozBrowser = aAttrs.mInIsolatedMozBrowser;
|
|
|
|
// addonId is computed from the principal URI and never propagated
|
|
mUserContextId = aAttrs.mUserContextId;
|
|
|
|
mPrivateBrowsingId = aAttrs.mPrivateBrowsingId;
|
|
mFirstPartyDomain = aAttrs.mFirstPartyDomain;
|
|
}
|
|
|
|
void
|
|
PrincipalOriginAttributes::StripUserContextIdAndFirstPartyDomain()
|
|
{
|
|
mUserContextId = nsIScriptSecurityManager::DEFAULT_USER_CONTEXT_ID;
|
|
mFirstPartyDomain.Truncate();
|
|
}
|
|
|
|
void
|
|
DocShellOriginAttributes::InheritFromDocToChildDocShell(const PrincipalOriginAttributes& aAttrs)
|
|
{
|
|
mAppId = aAttrs.mAppId;
|
|
mInIsolatedMozBrowser = aAttrs.mInIsolatedMozBrowser;
|
|
|
|
// addonId is computed from the principal URI and never propagated
|
|
mUserContextId = aAttrs.mUserContextId;
|
|
|
|
mPrivateBrowsingId = aAttrs.mPrivateBrowsingId;
|
|
mFirstPartyDomain = aAttrs.mFirstPartyDomain;
|
|
}
|
|
|
|
void
|
|
NeckoOriginAttributes::InheritFromDocToNecko(const PrincipalOriginAttributes& aAttrs)
|
|
{
|
|
mAppId = aAttrs.mAppId;
|
|
mInIsolatedMozBrowser = aAttrs.mInIsolatedMozBrowser;
|
|
|
|
// addonId is computed from the principal URI and never propagated
|
|
mUserContextId = aAttrs.mUserContextId;
|
|
|
|
mPrivateBrowsingId = aAttrs.mPrivateBrowsingId;
|
|
mFirstPartyDomain = aAttrs.mFirstPartyDomain;
|
|
}
|
|
|
|
void
|
|
NeckoOriginAttributes::InheritFromDocShellToNecko(const DocShellOriginAttributes& aAttrs,
|
|
const bool aIsTopLevelDocument,
|
|
nsIURI* aURI)
|
|
{
|
|
mAppId = aAttrs.mAppId;
|
|
mInIsolatedMozBrowser = aAttrs.mInIsolatedMozBrowser;
|
|
|
|
// addonId is computed from the principal URI and never propagated
|
|
mUserContextId = aAttrs.mUserContextId;
|
|
|
|
mPrivateBrowsingId = aAttrs.mPrivateBrowsingId;
|
|
|
|
bool isFirstPartyEnabled = IsFirstPartyEnabled();
|
|
|
|
// When the pref is on, we also compute the firstPartyDomain attribute
|
|
// if this is for top-level document.
|
|
if (isFirstPartyEnabled && aIsTopLevelDocument) {
|
|
nsCOMPtr<nsIEffectiveTLDService> tldService = do_GetService(NS_EFFECTIVETLDSERVICE_CONTRACTID);
|
|
MOZ_ASSERT(tldService);
|
|
if (!tldService) {
|
|
return;
|
|
}
|
|
|
|
nsAutoCString baseDomain;
|
|
tldService->GetBaseDomain(aURI, 0, baseDomain);
|
|
mFirstPartyDomain = NS_ConvertUTF8toUTF16(baseDomain);
|
|
} else {
|
|
mFirstPartyDomain = aAttrs.mFirstPartyDomain;
|
|
}
|
|
}
|
|
|
|
void
|
|
OriginAttributes::CreateSuffix(nsACString& aStr) const
|
|
{
|
|
UniquePtr<URLParams> params(new URLParams());
|
|
nsAutoString value;
|
|
|
|
//
|
|
// Important: While serializing any string-valued attributes, perform a
|
|
// release-mode assertion to make sure that they don't contain characters that
|
|
// will break the quota manager when it uses the serialization for file
|
|
// naming (see addonId below).
|
|
//
|
|
|
|
if (mAppId != nsIScriptSecurityManager::NO_APP_ID) {
|
|
value.AppendInt(mAppId);
|
|
params->Set(NS_LITERAL_STRING("appId"), value);
|
|
}
|
|
|
|
if (mInIsolatedMozBrowser) {
|
|
params->Set(NS_LITERAL_STRING("inBrowser"), NS_LITERAL_STRING("1"));
|
|
}
|
|
|
|
if (!mAddonId.IsEmpty()) {
|
|
if (mAddonId.FindCharInSet(dom::quota::QuotaManager::kReplaceChars) != kNotFound) {
|
|
MOZ_CRASH();
|
|
}
|
|
params->Set(NS_LITERAL_STRING("addonId"), mAddonId);
|
|
}
|
|
|
|
if (mUserContextId != nsIScriptSecurityManager::DEFAULT_USER_CONTEXT_ID) {
|
|
value.Truncate();
|
|
value.AppendInt(mUserContextId);
|
|
params->Set(NS_LITERAL_STRING("userContextId"), value);
|
|
}
|
|
|
|
|
|
if (mPrivateBrowsingId) {
|
|
value.Truncate();
|
|
value.AppendInt(mPrivateBrowsingId);
|
|
params->Set(NS_LITERAL_STRING("privateBrowsingId"), value);
|
|
}
|
|
|
|
if (!mFirstPartyDomain.IsEmpty()) {
|
|
MOZ_RELEASE_ASSERT(mFirstPartyDomain.FindCharInSet(dom::quota::QuotaManager::kReplaceChars) == kNotFound);
|
|
params->Set(NS_LITERAL_STRING("firstPartyDomain"), mFirstPartyDomain);
|
|
}
|
|
|
|
aStr.Truncate();
|
|
|
|
params->Serialize(value);
|
|
if (!value.IsEmpty()) {
|
|
aStr.AppendLiteral("^");
|
|
aStr.Append(NS_ConvertUTF16toUTF8(value));
|
|
}
|
|
|
|
// In debug builds, check the whole string for illegal characters too (just in case).
|
|
#ifdef DEBUG
|
|
nsAutoCString str;
|
|
str.Assign(aStr);
|
|
MOZ_ASSERT(str.FindCharInSet(dom::quota::QuotaManager::kReplaceChars) == kNotFound);
|
|
#endif
|
|
}
|
|
|
|
void
|
|
OriginAttributes::CreateAnonymizedSuffix(nsACString& aStr) const
|
|
{
|
|
OriginAttributes attrs = *this;
|
|
|
|
if (!attrs.mFirstPartyDomain.IsEmpty()) {
|
|
attrs.mFirstPartyDomain.AssignLiteral("_anonymizedFirstPartyDomain_");
|
|
}
|
|
|
|
attrs.CreateSuffix(aStr);
|
|
}
|
|
|
|
namespace {
|
|
|
|
class MOZ_STACK_CLASS PopulateFromSuffixIterator final
|
|
: public URLParams::ForEachIterator
|
|
{
|
|
public:
|
|
explicit PopulateFromSuffixIterator(OriginAttributes* aOriginAttributes)
|
|
: mOriginAttributes(aOriginAttributes)
|
|
{
|
|
MOZ_ASSERT(aOriginAttributes);
|
|
// If mPrivateBrowsingId is passed in as >0 and is not present in the suffix,
|
|
// then it will remain >0 when it should be 0 according to the suffix. Set to 0 before
|
|
// iterating to fix this.
|
|
mOriginAttributes->mPrivateBrowsingId = 0;
|
|
}
|
|
|
|
bool URLParamsIterator(const nsString& aName,
|
|
const nsString& aValue) override
|
|
{
|
|
if (aName.EqualsLiteral("appId")) {
|
|
nsresult rv;
|
|
int64_t val = aValue.ToInteger64(&rv);
|
|
NS_ENSURE_SUCCESS(rv, false);
|
|
NS_ENSURE_TRUE(val <= UINT32_MAX, false);
|
|
mOriginAttributes->mAppId = static_cast<uint32_t>(val);
|
|
|
|
return true;
|
|
}
|
|
|
|
if (aName.EqualsLiteral("inBrowser")) {
|
|
if (!aValue.EqualsLiteral("1")) {
|
|
return false;
|
|
}
|
|
|
|
mOriginAttributes->mInIsolatedMozBrowser = true;
|
|
return true;
|
|
}
|
|
|
|
if (aName.EqualsLiteral("addonId")) {
|
|
MOZ_RELEASE_ASSERT(mOriginAttributes->mAddonId.IsEmpty());
|
|
mOriginAttributes->mAddonId.Assign(aValue);
|
|
return true;
|
|
}
|
|
|
|
if (aName.EqualsLiteral("userContextId")) {
|
|
nsresult rv;
|
|
int64_t val = aValue.ToInteger64(&rv);
|
|
NS_ENSURE_SUCCESS(rv, false);
|
|
NS_ENSURE_TRUE(val <= UINT32_MAX, false);
|
|
mOriginAttributes->mUserContextId = static_cast<uint32_t>(val);
|
|
|
|
return true;
|
|
}
|
|
|
|
if (aName.EqualsLiteral("privateBrowsingId")) {
|
|
nsresult rv;
|
|
int64_t val = aValue.ToInteger64(&rv);
|
|
NS_ENSURE_SUCCESS(rv, false);
|
|
NS_ENSURE_TRUE(val >= 0 && val <= UINT32_MAX, false);
|
|
mOriginAttributes->mPrivateBrowsingId = static_cast<uint32_t>(val);
|
|
|
|
return true;
|
|
}
|
|
|
|
if (aName.EqualsLiteral("firstPartyDomain")) {
|
|
MOZ_RELEASE_ASSERT(mOriginAttributes->mFirstPartyDomain.IsEmpty());
|
|
mOriginAttributes->mFirstPartyDomain.Assign(aValue);
|
|
return true;
|
|
}
|
|
|
|
// No other attributes are supported.
|
|
return false;
|
|
}
|
|
|
|
private:
|
|
OriginAttributes* mOriginAttributes;
|
|
};
|
|
|
|
} // namespace
|
|
|
|
bool
|
|
OriginAttributes::PopulateFromSuffix(const nsACString& aStr)
|
|
{
|
|
if (aStr.IsEmpty()) {
|
|
return true;
|
|
}
|
|
|
|
if (aStr[0] != '^') {
|
|
return false;
|
|
}
|
|
|
|
UniquePtr<URLParams> params(new URLParams());
|
|
params->ParseInput(Substring(aStr, 1, aStr.Length() - 1));
|
|
|
|
PopulateFromSuffixIterator iterator(this);
|
|
return params->ForEach(iterator);
|
|
}
|
|
|
|
bool
|
|
OriginAttributes::PopulateFromOrigin(const nsACString& aOrigin,
|
|
nsACString& aOriginNoSuffix)
|
|
{
|
|
// RFindChar is only available on nsCString.
|
|
nsCString origin(aOrigin);
|
|
int32_t pos = origin.RFindChar('^');
|
|
|
|
if (pos == kNotFound) {
|
|
aOriginNoSuffix = origin;
|
|
return true;
|
|
}
|
|
|
|
aOriginNoSuffix = Substring(origin, 0, pos);
|
|
return PopulateFromSuffix(Substring(origin, pos));
|
|
}
|
|
|
|
void
|
|
OriginAttributes::SyncAttributesWithPrivateBrowsing(bool aInPrivateBrowsing)
|
|
{
|
|
mPrivateBrowsingId = aInPrivateBrowsing ? 1 : 0;
|
|
}
|
|
|
|
void
|
|
OriginAttributes::SetFromGenericAttributes(const GenericOriginAttributes& aAttrs)
|
|
{
|
|
mAppId = aAttrs.mAppId;
|
|
mInIsolatedMozBrowser = aAttrs.mInIsolatedMozBrowser;
|
|
mAddonId = aAttrs.mAddonId;
|
|
mUserContextId = aAttrs.mUserContextId;
|
|
mPrivateBrowsingId = aAttrs.mPrivateBrowsingId;
|
|
mFirstPartyDomain = aAttrs.mFirstPartyDomain;
|
|
}
|
|
|
|
/* static */
|
|
bool
|
|
OriginAttributes::IsFirstPartyEnabled()
|
|
{
|
|
// Cache the privacy.firstparty.isolate pref.
|
|
static bool sFirstPartyIsolation = false;
|
|
static bool sCachedFirstPartyPref = false;
|
|
if (!sCachedFirstPartyPref) {
|
|
sCachedFirstPartyPref = true;
|
|
Preferences::AddBoolVarCache(&sFirstPartyIsolation, "privacy.firstparty.isolate");
|
|
}
|
|
|
|
return sFirstPartyIsolation;
|
|
}
|
|
|
|
BasePrincipal::BasePrincipal()
|
|
{}
|
|
|
|
BasePrincipal::~BasePrincipal()
|
|
{}
|
|
|
|
NS_IMETHODIMP
|
|
BasePrincipal::GetOrigin(nsACString& aOrigin)
|
|
{
|
|
nsresult rv = GetOriginInternal(aOrigin);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
nsAutoCString suffix;
|
|
mOriginAttributes.CreateSuffix(suffix);
|
|
aOrigin.Append(suffix);
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
BasePrincipal::GetOriginNoSuffix(nsACString& aOrigin)
|
|
{
|
|
return GetOriginInternal(aOrigin);
|
|
}
|
|
|
|
bool
|
|
BasePrincipal::Subsumes(nsIPrincipal* aOther, DocumentDomainConsideration aConsideration)
|
|
{
|
|
MOZ_ASSERT(aOther);
|
|
|
|
// Expanded principals handle origin attributes for each of their
|
|
// sub-principals individually, null principals do only simple checks for
|
|
// pointer equality, and system principals are immune to origin attributes
|
|
// checks, so only do this check for codebase principals.
|
|
if (Kind() == eCodebasePrincipal &&
|
|
OriginAttributesRef() != Cast(aOther)->OriginAttributesRef()) {
|
|
return false;
|
|
}
|
|
|
|
return SubsumesInternal(aOther, aConsideration);
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
BasePrincipal::Equals(nsIPrincipal *aOther, bool *aResult)
|
|
{
|
|
NS_ENSURE_TRUE(aOther, NS_ERROR_INVALID_ARG);
|
|
*aResult = Subsumes(aOther, DontConsiderDocumentDomain) &&
|
|
Cast(aOther)->Subsumes(this, DontConsiderDocumentDomain);
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
BasePrincipal::EqualsConsideringDomain(nsIPrincipal *aOther, bool *aResult)
|
|
{
|
|
NS_ENSURE_TRUE(aOther, NS_ERROR_INVALID_ARG);
|
|
*aResult = Subsumes(aOther, ConsiderDocumentDomain) &&
|
|
Cast(aOther)->Subsumes(this, ConsiderDocumentDomain);
|
|
return NS_OK;
|
|
}
|
|
|
|
bool
|
|
BasePrincipal::EqualsIgnoringAddonId(nsIPrincipal *aOther)
|
|
{
|
|
MOZ_ASSERT(aOther);
|
|
|
|
// Note that this will not work for expanded principals, nor is it intended
|
|
// to.
|
|
if (!dom::ChromeUtils::IsOriginAttributesEqualIgnoringAddonId(
|
|
OriginAttributesRef(), Cast(aOther)->OriginAttributesRef())) {
|
|
return false;
|
|
}
|
|
|
|
return SubsumesInternal(aOther, DontConsiderDocumentDomain) &&
|
|
Cast(aOther)->SubsumesInternal(this, DontConsiderDocumentDomain);
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
BasePrincipal::Subsumes(nsIPrincipal *aOther, bool *aResult)
|
|
{
|
|
NS_ENSURE_TRUE(aOther, NS_ERROR_INVALID_ARG);
|
|
*aResult = Subsumes(aOther, DontConsiderDocumentDomain);
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
BasePrincipal::SubsumesConsideringDomain(nsIPrincipal *aOther, bool *aResult)
|
|
{
|
|
NS_ENSURE_TRUE(aOther, NS_ERROR_INVALID_ARG);
|
|
*aResult = Subsumes(aOther, ConsiderDocumentDomain);
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
BasePrincipal::CheckMayLoad(nsIURI* aURI, bool aReport, bool aAllowIfInheritsPrincipal)
|
|
{
|
|
// Check the internal method first, which allows us to quickly approve loads
|
|
// for the System Principal.
|
|
if (MayLoadInternal(aURI)) {
|
|
return NS_OK;
|
|
}
|
|
|
|
nsresult rv;
|
|
if (aAllowIfInheritsPrincipal) {
|
|
// If the caller specified to allow loads of URIs that inherit
|
|
// our principal, allow the load if this URI inherits its principal.
|
|
bool doesInheritSecurityContext;
|
|
rv = NS_URIChainHasFlags(aURI, nsIProtocolHandler::URI_INHERITS_SECURITY_CONTEXT,
|
|
&doesInheritSecurityContext);
|
|
if (NS_SUCCEEDED(rv) && doesInheritSecurityContext) {
|
|
return NS_OK;
|
|
}
|
|
}
|
|
|
|
bool fetchableByAnyone;
|
|
rv = NS_URIChainHasFlags(aURI, nsIProtocolHandler::URI_FETCHABLE_BY_ANYONE, &fetchableByAnyone);
|
|
if (NS_SUCCEEDED(rv) && fetchableByAnyone) {
|
|
return NS_OK;
|
|
}
|
|
|
|
if (aReport) {
|
|
nsCOMPtr<nsIURI> prinURI;
|
|
rv = GetURI(getter_AddRefs(prinURI));
|
|
if (NS_SUCCEEDED(rv) && prinURI) {
|
|
nsScriptSecurityManager::ReportError(nullptr, NS_LITERAL_STRING("CheckSameOriginError"), prinURI, aURI);
|
|
}
|
|
}
|
|
|
|
return NS_ERROR_DOM_BAD_URI;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
BasePrincipal::GetCsp(nsIContentSecurityPolicy** aCsp)
|
|
{
|
|
NS_IF_ADDREF(*aCsp = mCSP);
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
BasePrincipal::SetCsp(nsIContentSecurityPolicy* aCsp)
|
|
{
|
|
// Never destroy an existing CSP on the principal.
|
|
// This method should only be called in rare cases.
|
|
|
|
MOZ_ASSERT(!mCSP, "do not destroy an existing CSP");
|
|
if (mCSP) {
|
|
return NS_ERROR_ALREADY_INITIALIZED;
|
|
}
|
|
|
|
mCSP = aCsp;
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
BasePrincipal::EnsureCSP(nsIDOMDocument* aDocument,
|
|
nsIContentSecurityPolicy** aCSP)
|
|
{
|
|
if (mCSP) {
|
|
// if there is a CSP already associated with this principal
|
|
// then just return that - do not overwrite it!!!
|
|
NS_IF_ADDREF(*aCSP = mCSP);
|
|
return NS_OK;
|
|
}
|
|
|
|
nsresult rv = NS_OK;
|
|
mCSP = do_CreateInstance("@mozilla.org/cspcontext;1", &rv);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
// Store the request context for violation reports
|
|
rv = aDocument ? mCSP->SetRequestContext(aDocument, nullptr)
|
|
: mCSP->SetRequestContext(nullptr, this);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
NS_IF_ADDREF(*aCSP = mCSP);
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
BasePrincipal::GetPreloadCsp(nsIContentSecurityPolicy** aPreloadCSP)
|
|
{
|
|
NS_IF_ADDREF(*aPreloadCSP = mPreloadCSP);
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
BasePrincipal::EnsurePreloadCSP(nsIDOMDocument* aDocument,
|
|
nsIContentSecurityPolicy** aPreloadCSP)
|
|
{
|
|
if (mPreloadCSP) {
|
|
// if there is a speculative CSP already associated with this principal
|
|
// then just return that - do not overwrite it!!!
|
|
NS_IF_ADDREF(*aPreloadCSP = mPreloadCSP);
|
|
return NS_OK;
|
|
}
|
|
|
|
nsresult rv = NS_OK;
|
|
mPreloadCSP = do_CreateInstance("@mozilla.org/cspcontext;1", &rv);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
// Store the request context for violation reports
|
|
rv = aDocument ? mPreloadCSP->SetRequestContext(aDocument, nullptr)
|
|
: mPreloadCSP->SetRequestContext(nullptr, this);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
NS_IF_ADDREF(*aPreloadCSP = mPreloadCSP);
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
BasePrincipal::GetCspJSON(nsAString& outCSPinJSON)
|
|
{
|
|
outCSPinJSON.Truncate();
|
|
dom::CSPPolicies jsonPolicies;
|
|
|
|
if (!mCSP) {
|
|
jsonPolicies.ToJSON(outCSPinJSON);
|
|
return NS_OK;
|
|
}
|
|
return mCSP->ToJSON(outCSPinJSON);
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
BasePrincipal::IsSameOrigin(nsIURI* aURI, bool aIsPrivateWin, bool* aRes) {
|
|
*aRes = false;
|
|
nsCOMPtr<nsIURI> prinURI;
|
|
nsresult rv = GetURI(getter_AddRefs(prinURI));
|
|
if (NS_FAILED(rv) || !prinURI) {
|
|
return NS_OK;
|
|
}
|
|
nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
|
|
if (!ssm) {
|
|
return NS_ERROR_UNEXPECTED;
|
|
;
|
|
}
|
|
*aRes = NS_SUCCEEDED(ssm->CheckSameOriginURI(prinURI, aURI, aIsPrivateWin));
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
BasePrincipal::GetIsNullPrincipal(bool* aResult)
|
|
{
|
|
*aResult = Kind() == eNullPrincipal;
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
BasePrincipal::GetIsCodebasePrincipal(bool* aResult)
|
|
{
|
|
*aResult = Kind() == eCodebasePrincipal;
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
BasePrincipal::GetIsExpandedPrincipal(bool* aResult)
|
|
{
|
|
*aResult = Kind() == eExpandedPrincipal;
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
BasePrincipal::GetIsSystemPrincipal(bool* aResult)
|
|
{
|
|
*aResult = Kind() == eSystemPrincipal;
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
BasePrincipal::GetOriginAttributes(JSContext* aCx, JS::MutableHandle<JS::Value> aVal)
|
|
{
|
|
if (NS_WARN_IF(!ToJSValue(aCx, mOriginAttributes, aVal))) {
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
BasePrincipal::GetOriginSuffix(nsACString& aOriginAttributes)
|
|
{
|
|
mOriginAttributes.CreateSuffix(aOriginAttributes);
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
BasePrincipal::GetAppStatus(uint16_t* aAppStatus)
|
|
{
|
|
if (AppId() == nsIScriptSecurityManager::UNKNOWN_APP_ID) {
|
|
NS_WARNING("Asking for app status on a principal with an unknown app id");
|
|
*aAppStatus = nsIPrincipal::APP_STATUS_NOT_INSTALLED;
|
|
return NS_OK;
|
|
}
|
|
|
|
*aAppStatus = nsScriptSecurityManager::AppStatusForPrincipal(this);
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
BasePrincipal::GetAppId(uint32_t* aAppId)
|
|
{
|
|
if (AppId() == nsIScriptSecurityManager::UNKNOWN_APP_ID) {
|
|
MOZ_ASSERT(false);
|
|
*aAppId = nsIScriptSecurityManager::NO_APP_ID;
|
|
return NS_OK;
|
|
}
|
|
|
|
*aAppId = AppId();
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
BasePrincipal::GetAddonId(nsAString& aAddonId)
|
|
{
|
|
aAddonId.Assign(mOriginAttributes.mAddonId);
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
BasePrincipal::GetUserContextId(uint32_t* aUserContextId)
|
|
{
|
|
*aUserContextId = UserContextId();
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
BasePrincipal::GetPrivateBrowsingId(uint32_t* aPrivateBrowsingId)
|
|
{
|
|
*aPrivateBrowsingId = PrivateBrowsingId();
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
BasePrincipal::GetIsInIsolatedMozBrowserElement(bool* aIsInIsolatedMozBrowserElement)
|
|
{
|
|
*aIsInIsolatedMozBrowserElement = IsInIsolatedMozBrowserElement();
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
BasePrincipal::GetUnknownAppId(bool* aUnknownAppId)
|
|
{
|
|
*aUnknownAppId = AppId() == nsIScriptSecurityManager::UNKNOWN_APP_ID;
|
|
return NS_OK;
|
|
}
|
|
|
|
bool
|
|
BasePrincipal::AddonHasPermission(const nsAString& aPerm)
|
|
{
|
|
if (mOriginAttributes.mAddonId.IsEmpty()) {
|
|
return false;
|
|
}
|
|
nsCOMPtr<nsIAddonPolicyService> aps =
|
|
do_GetService("@mozilla.org/addons/policy-service;1");
|
|
NS_ENSURE_TRUE(aps, false);
|
|
|
|
bool retval = false;
|
|
nsresult rv = aps->AddonHasPermission(mOriginAttributes.mAddonId, aPerm, &retval);
|
|
NS_ENSURE_SUCCESS(rv, false);
|
|
return retval;
|
|
}
|
|
|
|
already_AddRefed<BasePrincipal>
|
|
BasePrincipal::CreateCodebasePrincipal(nsIURI* aURI, const PrincipalOriginAttributes& aAttrs)
|
|
{
|
|
// If the URI is supposed to inherit the security context of whoever loads it,
|
|
// we shouldn't make a codebase principal for it.
|
|
bool inheritsPrincipal;
|
|
nsresult rv = NS_URIChainHasFlags(aURI, nsIProtocolHandler::URI_INHERITS_SECURITY_CONTEXT,
|
|
&inheritsPrincipal);
|
|
if (NS_FAILED(rv) || inheritsPrincipal) {
|
|
return nsNullPrincipal::Create(aAttrs);
|
|
}
|
|
|
|
// Check whether the URI knows what its principal is supposed to be.
|
|
nsCOMPtr<nsIURIWithPrincipal> uriPrinc = do_QueryInterface(aURI);
|
|
if (uriPrinc) {
|
|
nsCOMPtr<nsIPrincipal> principal;
|
|
uriPrinc->GetPrincipal(getter_AddRefs(principal));
|
|
if (!principal) {
|
|
return nsNullPrincipal::Create(aAttrs);
|
|
}
|
|
RefPtr<BasePrincipal> concrete = Cast(principal);
|
|
return concrete.forget();
|
|
}
|
|
|
|
// Mint a codebase principal.
|
|
RefPtr<nsPrincipal> codebase = new nsPrincipal();
|
|
rv = codebase->Init(aURI, aAttrs);
|
|
NS_ENSURE_SUCCESS(rv, nullptr);
|
|
return codebase.forget();
|
|
}
|
|
|
|
already_AddRefed<BasePrincipal>
|
|
BasePrincipal::CreateCodebasePrincipal(const nsACString& aOrigin)
|
|
{
|
|
MOZ_ASSERT(!StringBeginsWith(aOrigin, NS_LITERAL_CSTRING("[")),
|
|
"CreateCodebasePrincipal does not support System and Expanded principals");
|
|
|
|
MOZ_ASSERT(!StringBeginsWith(aOrigin, NS_LITERAL_CSTRING(NS_NULLPRINCIPAL_SCHEME ":")),
|
|
"CreateCodebasePrincipal does not support nsNullPrincipal");
|
|
|
|
nsAutoCString originNoSuffix;
|
|
mozilla::PrincipalOriginAttributes attrs;
|
|
if (!attrs.PopulateFromOrigin(aOrigin, originNoSuffix)) {
|
|
return nullptr;
|
|
}
|
|
|
|
nsCOMPtr<nsIURI> uri;
|
|
nsresult rv = NS_NewURI(getter_AddRefs(uri), originNoSuffix);
|
|
NS_ENSURE_SUCCESS(rv, nullptr);
|
|
|
|
return BasePrincipal::CreateCodebasePrincipal(uri, attrs);
|
|
}
|
|
|
|
already_AddRefed<BasePrincipal>
|
|
BasePrincipal::CloneStrippingUserContextIdAndFirstPartyDomain()
|
|
{
|
|
PrincipalOriginAttributes attrs = OriginAttributesRef();
|
|
attrs.StripUserContextIdAndFirstPartyDomain();
|
|
|
|
nsAutoCString originNoSuffix;
|
|
nsresult rv = GetOriginNoSuffix(originNoSuffix);
|
|
NS_ENSURE_SUCCESS(rv, nullptr);
|
|
|
|
nsCOMPtr<nsIURI> uri;
|
|
rv = NS_NewURI(getter_AddRefs(uri), originNoSuffix);
|
|
NS_ENSURE_SUCCESS(rv, nullptr);
|
|
|
|
return BasePrincipal::CreateCodebasePrincipal(uri, attrs);
|
|
}
|
|
|
|
bool
|
|
BasePrincipal::AddonAllowsLoad(nsIURI* aURI)
|
|
{
|
|
if (mOriginAttributes.mAddonId.IsEmpty()) {
|
|
return false;
|
|
}
|
|
|
|
nsCOMPtr<nsIAddonPolicyService> aps = do_GetService("@mozilla.org/addons/policy-service;1");
|
|
NS_ENSURE_TRUE(aps, false);
|
|
|
|
bool allowed = false;
|
|
nsresult rv = aps->AddonMayLoadURI(mOriginAttributes.mAddonId, aURI, &allowed);
|
|
return NS_SUCCEEDED(rv) && allowed;
|
|
}
|
|
|
|
} // namespace mozilla
|