Files
palemoon27/caps/BasePrincipal.cpp
T
roytam1 f7d677cddd import changes from `dev' branch of rmottola/Arctic-Fox:
- Bug 1168263 - Exclude perspective transforms from the transform used to convert from screen coordinates to an APZC's coordinate space. r=kats (dab02eb359)
- Bug 1225950 - Remove unnecessary parameter from SetNeedsComposite. r=mchang (0fb6099bd5)
- Bug 1225950 - Make mNeedsComposite a counter rather than a boolean. r=mchang (4d46dba314)
- Bug 1225950 - Force a composite if we have requested one but haven't gotten a vsync in a while. r=mchang (06f0d4553e)
- Bug 1221697 - Add a telemetry probe for time-to-composite. r=kats (c333e2ea87)
- Bug 1213120 - Ensure we don't try to use an uninitialized map. r=BenWa (99069b78fe)
- Bug 1228133 - Guard against a race condition that could result in an illegal pointer access. r=BenWa (65e1393908)
- update, mostly shadow warnings (5ca9c8ec0c)
- Bug 1119106 - Increase the radio button rendering bottom margin on 10.10 so that the button hits its frame more accurately. r=smichaud (2b55533095)
- Bug 1221451: Don't pass nil when an argument is required. r=spohl (7adfcf2543)
- Bug 1153579 - Fix -Wpointer-bool-conversion warning by removing null check of an array address. r=mstange (8c7ad82e8f)
- Bug 1204620 - Don't prepend 'image.' to CUIDraw image names on 10.11. r=stefanh (9a4794ecd4)
- Bug 1181289 - Specify size: small when drawing small scrollbars with CoreUI. r=smichaud (e75bff6036)
- Bug 1138359 - Make the margins of native-themed Cocoa buttons aware of writing mode. r=smontagu (49afef0f00)
- Bug 1220358 - Fix -Wunreachable-code warnings in widget/cocoa. r=spohl (720c720afc)
- fixup widget/ios from EventMessage change (no bug, NPOTB) (ab33d61f95)
- Bug 1217818 - Add support for the mHandledByAPZ flag on touch events as well. r=botond (d4658c671a)
- Bug 1209772 - 'mozregression was installed. please re-run your command.' when running ./mach mozregression. r=ahal (5febef290b)
- Bug 1204787 - Add |mach power|. r=glandium. (5a0d84f480)
- Bug 1214924 - Add "WindowServer" and "kernel" processes to |mach power|'s output. r=BenWa. (89c3a515f7)
- Bug 1197694 - fflush() rapl output so it always appears immediately.  r=erahm. (052568f395)
- Bug 1194560 (follow-up) - Only build rapl on Linux if the arch is x86 or x86-64. r=glandium. (0101937ffa)
- Bug 1198137 - Add some summary stats to tool/power/rapl's output. r=erahm. (53052f366b)
- Bug 1198137 (follow-up) - Add a missing #include to unbreak Mac OS builds on a CLOSED TREE. r=me (27862d34ff)
- Bug 1203834 - Fix's rapl's handling of unsupported power domains. r=glandium. (facb022467)
- Bug 1203811 - Clarify two error messages in tools/power/rapl. r=heycam. (07a6bb847e)
- Bug 1201811 (part 1) - Don't use integer arithmetic when summing totals in rapl. r=erahm. (57a1de1376)
- Bug 1201811 (part 2) - Don't print distribution stats if there was only 1 sample. r=erahm. (e5c085a4df)
- Bug 1222887 - Suppress -Wunreachable-code warning in tools/power. r=njn (4fbbbe81e1)
- Bug 1222352 - Resource Timing - nextHopProtocol does not work in e10s r=nwgh (57029cf33d)
- Bug 1211636 - use ToInteger64 in PopulateFromSuffix. r=bholley (d67e5fe9d1)
- Bug 961049 - Part 2: Remove Utilities.h; r=baku (3c09679a40)
- Bug 961049 - Part 3: Move PersistenceType serializer from indexedDB to quota module; r=baku (021478905a)
- Bug 1186809 (part 1) - Replace nsBaseHashtable::EnumerateRead() calls in dom/quota/ with iterators. r=janv. (8933726851)
- Bug 1186809 (part 2) - Replace nsBaseHashtable::EnumerateRead() calls in dom/quota/ with iterators. r=janv. (cb7c6f27dc)
- Bug 1186809 (part 3) - Replace nsBaseHashtable::EnumerateRead() calls in dom/quota/ with iterators. r=janv. (1ded98347c)
- Bug 1187151 (part 1) - Replace nsBaseHashtable::Enumerate() calls in dom/base/ with iterators. r=khuey. (a409e8590e)
- Bug 1187151 (part 2) - Replace nsBaseHashtable::Enumerate() calls in dom/base/ with iterators. r=janv. (bd4fe93dfc)
- Bug 1187151 (part 3) - Replace nsBaseHashtable::Enumerate() calls in dom/ with iterators. r=khuey. (de0f2dda26)
- Bug 1187151 (part 4) - Replace nsBaseHashtable::Enumerate() calls in dom/ with iterators. r=khuey. (e72d744118)
- Bug 1187151 (part 5) - Replace nsBaseHashtable::Enumerate() calls in dom/ with iterators. r=khuey. (18eddd5225)
- Bug 1187151 (part 6) - Replace nsBaseHashtable::Enumerate() calls in dom/ with iterators. r=khuey. (36fb6272e1)
- Bug 1187151 (part 7) - Replace nsBaseHashtable::Enumerate() calls in dom/ with iterators. r=khuey. (594438d35f)
- Bug 1187151 (part 8) - Replace nsBaseHashtable::Enumerate() calls in dom/ with iterators. r=khuey. (d8de2742d8)
- Bug 1187151 (part 9) - Replace nsBaseHashtable::Enumerate() calls in dom/ with iterators. r=khuey. (d2b4a29111)
- missing namespace (0b0453cc40)
- Bug 1187701 - add_task function for mochitest chrome and plain; r=jmaher (1c31a40c7c)
- Bug 1223831 - SpecialPowers API to create files in an e10s-compatible way. r=jmaher,baku (a04646cb50)
- Bug 1178526 - Create docshell with packageId from TabContext. r=sicking. (c89edfc7ab)
- Bug 1217694 - Signed package should come from the moz-package-origin specified in its manifest. r=valentin (705aeae07a)
- Bug 1225422 - Update the PrivilegedPackageRoot certificate. r=keeler (2a90eed63c)
- Bug 1204301 - HttpChannelParent needs to be able to GetInterface to an nsIPrompt. r=billm. (4937a2fbbe)
2023-03-13 17:37:42 +08:00

492 lines
12 KiB
C++

/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 sw=2 et tw=80: */
/* 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 "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/CSPDictionariesBinding.h"
#include "mozilla/dom/quota/QuotaManager.h"
#include "mozilla/dom/ToJSValue.h"
#include "mozilla/dom/URLSearchParams.h"
namespace mozilla {
using dom::URLParams;
void OriginAttributes::InheritFromDocShellParent(const OriginAttributes& aParent)
{
mAppId = aParent.mAppId;
mInBrowser = aParent.mInBrowser;
mUserContextId = aParent.mUserContextId;
mSignedPkg = aParent.mSignedPkg;
}
bool OriginAttributes::CopyFromLoadContext(nsILoadContext* aLoadContext)
{
OriginAttributes attrs;
bool result = aLoadContext->GetOriginAttributes(attrs);
NS_ENSURE_TRUE(result, false);
mAppId = attrs.mAppId;
mInBrowser = attrs.mInBrowser;
mAddonId = attrs.mAddonId;
mUserContextId = attrs.mUserContextId;
mSignedPkg = attrs.mSignedPkg;
return true;
}
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 (mInBrowser) {
params->Set(NS_LITERAL_STRING("inBrowser"), NS_LITERAL_STRING("1"));
}
if (!mAddonId.IsEmpty()) {
MOZ_RELEASE_ASSERT(mAddonId.FindCharInSet(dom::quota::QuotaManager::kReplaceChars) == kNotFound);
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 (!mSignedPkg.IsEmpty()) {
params->Set(NS_LITERAL_STRING("signedPkg"), mSignedPkg);
}
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
}
namespace {
class MOZ_STACK_CLASS PopulateFromSuffixIterator final
: public URLParams::ForEachIterator
{
public:
explicit PopulateFromSuffixIterator(OriginAttributes* aOriginAttributes)
: mOriginAttributes(aOriginAttributes)
{
MOZ_ASSERT(aOriginAttributes);
}
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->mInBrowser = 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("signedPkg")) {
MOZ_RELEASE_ASSERT(mOriginAttributes->mSignedPkg.IsEmpty());
mOriginAttributes->mSignedPkg.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));
}
BasePrincipal::BasePrincipal()
{}
BasePrincipal::~BasePrincipal()
{}
NS_IMETHODIMP
BasePrincipal::GetOrigin(nsACString& aOrigin)
{
return GetOriginInternal(aOrigin);
}
bool
BasePrincipal::Subsumes(nsIPrincipal* aOther, DocumentDomainConsideration aConsideration)
{
MOZ_ASSERT(aOther);
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;
}
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)
{
if (mCSP) {
return NS_ERROR_ALREADY_INITIALIZED;
}
mCSP = aCsp;
return NS_OK;
}
NS_IMETHODIMP
BasePrincipal::GetPreloadCsp(nsIContentSecurityPolicy** aPreloadCSP)
{
NS_IF_ADDREF(*aPreloadCSP = mPreloadCSP);
return NS_OK;
}
NS_IMETHODIMP
BasePrincipal::SetPreloadCsp(nsIContentSecurityPolicy* aPreloadCSP)
{
if (mPreloadCSP) {
return NS_ERROR_ALREADY_INITIALIZED;
}
mPreloadCSP = aPreloadCSP;
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::GetJarPrefix(nsACString& aJarPrefix)
{
mozilla::GetJarPrefix(mOriginAttributes.mAppId, mOriginAttributes.mInBrowser, aJarPrefix);
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::GetUserContextId(uint32_t* aUserContextId)
{
*aUserContextId = UserContextId();
return NS_OK;
}
NS_IMETHODIMP
BasePrincipal::GetIsInBrowserElement(bool* aIsInBrowserElement)
{
*aIsInBrowserElement = IsInBrowserElement();
return NS_OK;
}
NS_IMETHODIMP
BasePrincipal::GetUnknownAppId(bool* aUnknownAppId)
{
*aUnknownAppId = AppId() == nsIScriptSecurityManager::UNKNOWN_APP_ID;
return NS_OK;
}
already_AddRefed<BasePrincipal>
BasePrincipal::CreateCodebasePrincipal(nsIURI* aURI, const OriginAttributes& 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);
nsCOMPtr<nsIPrincipal> principal;
if (NS_FAILED(rv) || inheritsPrincipal) {
return nsNullPrincipal::Create();
}
// 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();
}
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();
}
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