mirror of https://github.com/roytam1/UXP
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
769 lines
21 KiB
769 lines
21 KiB
/* -*- 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::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
|
|
|