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 "mozilla/BasePrincipal.h"
9 #include "nsDocShell.h"
11 #include "ExpandedPrincipal.h"
12 #include "nsNetUtil.h"
13 #include "nsContentUtils.h"
14 #include "nsIURIWithSpecialOrigin.h"
15 #include "nsScriptSecurityManager.h"
16 #include "nsServiceManagerUtils.h"
17 #include "nsAboutProtocolUtils.h"
18 #include "ThirdPartyUtil.h"
19 #include "mozilla/ContentPrincipal.h"
20 #include "mozilla/NullPrincipal.h"
21 #include "mozilla/dom/BlobURLProtocolHandler.h"
22 #include "mozilla/dom/ChromeUtils.h"
23 #include "mozilla/dom/ToJSValue.h"
24 #include "mozilla/dom/nsMixedContentBlocker.h"
25 #include "mozilla/Components.h"
26 #include "nsIURIFixup.h"
28 #include "json/json.h"
29 #include "nsSerializationHelper.h"
33 BasePrincipal::BasePrincipal(PrincipalKind aKind
)
34 : mKind(aKind
), mHasExplicitDomain(false), mInitialized(false) {}
36 BasePrincipal::~BasePrincipal() {}
39 BasePrincipal::GetOrigin(nsACString
& aOrigin
) {
40 MOZ_ASSERT(mInitialized
);
42 nsresult rv
= GetOriginNoSuffix(aOrigin
);
43 NS_ENSURE_SUCCESS(rv
, rv
);
46 rv
= GetOriginSuffix(suffix
);
47 NS_ENSURE_SUCCESS(rv
, rv
);
48 aOrigin
.Append(suffix
);
53 BasePrincipal::GetAsciiOrigin(nsACString
& aOrigin
) {
55 nsCOMPtr
<nsIURI
> prinURI
;
56 nsresult rv
= GetURI(getter_AddRefs(prinURI
));
57 if (NS_FAILED(rv
) || !prinURI
) {
58 return NS_ERROR_NOT_AVAILABLE
;
60 return nsContentUtils::GetASCIIOrigin(prinURI
, aOrigin
);
64 BasePrincipal::GetHostPort(nsACString
& aRes
) {
66 nsCOMPtr
<nsIURI
> prinURI
;
67 nsresult rv
= GetURI(getter_AddRefs(prinURI
));
68 if (NS_FAILED(rv
) || !prinURI
) {
71 return prinURI
->GetHostPort(aRes
);
75 BasePrincipal::GetOriginNoSuffix(nsACString
& aOrigin
) {
76 MOZ_ASSERT(mInitialized
);
77 mOriginNoSuffix
->ToUTF8String(aOrigin
);
82 BasePrincipal::GetSiteOrigin(nsACString
& aSiteOrigin
) {
83 MOZ_ASSERT(mInitialized
);
84 return GetOrigin(aSiteOrigin
);
87 // Returns the inner Json::value of the serialized principal
88 // Example input and return values:
90 // {"0":{"0":"moz-nullprincipal:{56cac540-864d-47e7-8e25-1614eab5155e}"}} ->
91 // {"0":"moz-nullprincipal:{56cac540-864d-47e7-8e25-1614eab5155e}"}
94 // {"1":{"0":"https://mozilla.com"}} -> {"0":"https://mozilla.com"}
96 // Expanded principal:
97 // {"2":{"0":"<base64principal1>,<base64principal2>"}} ->
98 // {"0":"<base64principal1>,<base64principal2>"}
102 // The aKey passed in also returns the corresponding PrincipalKind enum
104 // Warning: The Json::Value* pointer is into the aRoot object
105 static const Json::Value
* GetPrincipalObject(const Json::Value
& aRoot
,
106 int& aOutPrincipalKind
) {
107 const Json::Value::Members members
= aRoot
.getMemberNames();
108 // We only support one top level key in the object
109 if (members
.size() != 1) {
112 // members[0] here is the "0", "1", "2", "3" principalKind
113 // that is the top level of the serialized JSON principal
114 const std::string stringPrincipalKind
= members
[0];
116 // Next we take the string value from the JSON
117 // and convert it into the int for the BasePrincipal::PrincipalKind enum
119 // Verify that the key is within the valid range
120 int principalKind
= std::stoi(stringPrincipalKind
);
121 MOZ_ASSERT(BasePrincipal::eNullPrincipal
== 0,
122 "We need to rely on 0 being a bounds check for the first "
124 if (principalKind
< 0 || principalKind
> BasePrincipal::eKindMax
) {
127 MOZ_ASSERT(principalKind
== BasePrincipal::eNullPrincipal
||
128 principalKind
== BasePrincipal::eContentPrincipal
||
129 principalKind
== BasePrincipal::eExpandedPrincipal
||
130 principalKind
== BasePrincipal::eSystemPrincipal
);
131 aOutPrincipalKind
= principalKind
;
133 if (!aRoot
[stringPrincipalKind
].isObject()) {
137 // Return the inner value of the principal object
138 return &aRoot
[stringPrincipalKind
];
141 // Accepts the JSON inner object without the wrapping principalKind
142 // (See GetPrincipalObject for the inner object response examples)
143 // Creates an array of KeyVal objects that are all defined on the principal
144 // Each principal type (null, content, expanded) has a KeyVal that stores the
145 // fields of the JSON
147 // This simplifies deserializing elsewhere as we do the checking for presence
148 // and string values here for the complete set of serializable keys that the
149 // corresponding principal supports.
151 // The KeyVal object has the following fields:
152 // - valueWasSerialized: is true if the deserialized JSON contained a string
154 // - value: The string that was serialized for this key
155 // - key: an SerializableKeys enum value specific to the principal.
156 // For example content principal is an enum of: eURI, eDomain,
160 // Given an inner content principal:
161 // {"0": "https://mozilla.com", "2": "^privateBrowsingId=1"}
163 // ----------------------------- |
165 // Key ----------------------
169 // They Key "0" corresponds to ContentPrincipal::eURI
170 // They Key "1" corresponds to ContentPrincipal::eSuffix
171 template <typename T
>
172 static nsTArray
<typename
T::KeyVal
> GetJSONKeys(const Json::Value
* aInput
) {
173 int size
= T::eMax
+ 1;
174 nsTArray
<typename
T::KeyVal
> fields
;
175 for (int i
= 0; i
!= size
; i
++) {
176 typename
T::KeyVal
* field
= fields
.AppendElement();
177 // field->valueWasSerialized returns if the field was found in the
178 // deserialized code. This simplifies the consumers from having to check
180 field
->valueWasSerialized
= false;
181 field
->key
= static_cast<typename
T::SerializableKeys
>(i
);
182 const std::string key
= std::to_string(field
->key
);
183 if (aInput
->isMember(key
)) {
184 const Json::Value
& val
= (*aInput
)[key
];
185 if (val
.isString()) {
186 field
->value
.Append(nsDependentCString(val
.asCString()));
187 field
->valueWasSerialized
= true;
194 // Takes a JSON string and parses it turning it into a principal of the
195 // corresponding type
197 // Given a content principal:
201 // ---------------------------------------------------------
203 // {"1": {"0": "https://mozilla.com", "2": "^privateBrowsingId=1"}}
205 // | ----------------------------- |
207 // PrincipalKind | | |
208 // | ----------------------------
209 // SerializableKeys |
212 // The string is first deserialized with jsoncpp to get the Json::Value of the
213 // object. The inner JSON object is parsed with GetPrincipalObject which returns
214 // a KeyVal array of the inner object's fields. PrincipalKind is returned by
215 // GetPrincipalObject which is then used to decide which principal
216 // implementation of FromProperties to call. The corresponding FromProperties
217 // call takes the KeyVal fields and turns it into a principal.
218 already_AddRefed
<BasePrincipal
> BasePrincipal::FromJSON(
219 const nsACString
& aJSON
) {
221 Json::CharReaderBuilder builder
;
222 std::unique_ptr
<Json::CharReader
> const reader(builder
.newCharReader());
224 reader
->parse(aJSON
.BeginReading(), aJSON
.EndReading(), &root
, nullptr);
227 "Unable to parse string as JSON to deserialize as a principal");
231 int principalKind
= -1;
232 const Json::Value
* value
= GetPrincipalObject(root
, principalKind
);
235 fprintf(stderr
, "Unexpected JSON principal %s\n",
236 root
.toStyledString().c_str());
238 MOZ_ASSERT(false, "Unexpected JSON to deserialize as a principal");
242 MOZ_ASSERT(principalKind
!= -1,
243 "PrincipalKind should always be >=0 by this point");
245 if (principalKind
== eSystemPrincipal
) {
246 RefPtr
<BasePrincipal
> principal
=
247 BasePrincipal::Cast(nsContentUtils::GetSystemPrincipal());
248 return principal
.forget();
251 if (principalKind
== eNullPrincipal
) {
252 nsTArray
<NullPrincipal::KeyVal
> res
= GetJSONKeys
<NullPrincipal
>(value
);
253 return NullPrincipal::FromProperties(res
);
256 if (principalKind
== eContentPrincipal
) {
257 nsTArray
<ContentPrincipal::KeyVal
> res
=
258 GetJSONKeys
<ContentPrincipal
>(value
);
259 return ContentPrincipal::FromProperties(res
);
262 if (principalKind
== eExpandedPrincipal
) {
263 nsTArray
<ExpandedPrincipal::KeyVal
> res
=
264 GetJSONKeys
<ExpandedPrincipal
>(value
);
265 return ExpandedPrincipal::FromProperties(res
);
268 MOZ_RELEASE_ASSERT(false, "Unexpected enum to deserialize as a principal");
271 nsresult
BasePrincipal::PopulateJSONObject(Json::Value
& aObject
) {
275 // Returns a JSON representation of the principal.
276 // Calling BasePrincipal::FromJSON will deserialize the JSON into
277 // the corresponding principal type.
278 nsresult
BasePrincipal::ToJSON(nsACString
& aResult
) {
279 MOZ_ASSERT(aResult
.IsEmpty(), "ToJSON only supports an empty result input");
282 Json::StreamWriterBuilder builder
;
283 builder
["indentation"] = "";
284 Json::Value innerJSONObject
= Json::objectValue
;
286 nsresult rv
= PopulateJSONObject(innerJSONObject
);
287 NS_ENSURE_SUCCESS(rv
, rv
);
289 Json::Value root
= Json::objectValue
;
290 std::string key
= std::to_string(Kind());
291 root
[key
] = innerJSONObject
;
292 std::string result
= Json::writeString(builder
, root
);
293 aResult
.Append(result
);
294 if (aResult
.Length() == 0) {
295 MOZ_ASSERT(false, "JSON writer failed to output a principal serialization");
296 return NS_ERROR_UNEXPECTED
;
301 bool BasePrincipal::Subsumes(nsIPrincipal
* aOther
,
302 DocumentDomainConsideration aConsideration
) {
304 MOZ_ASSERT_IF(Kind() == eContentPrincipal
, mOriginSuffix
);
306 // Expanded principals handle origin attributes for each of their
307 // sub-principals individually, null principals do only simple checks for
308 // pointer equality, and system principals are immune to origin attributes
309 // checks, so only do this check for content principals.
310 if (Kind() == eContentPrincipal
&&
311 mOriginSuffix
!= Cast(aOther
)->mOriginSuffix
) {
315 return SubsumesInternal(aOther
, aConsideration
);
319 BasePrincipal::Equals(nsIPrincipal
* aOther
, bool* aResult
) {
320 NS_ENSURE_ARG_POINTER(aOther
);
322 *aResult
= FastEquals(aOther
);
328 BasePrincipal::EqualsConsideringDomain(nsIPrincipal
* aOther
, bool* aResult
) {
329 NS_ENSURE_ARG_POINTER(aOther
);
331 *aResult
= FastEqualsConsideringDomain(aOther
);
337 BasePrincipal::EqualsURI(nsIURI
* aOtherURI
, bool* aResult
) {
339 nsCOMPtr
<nsIURI
> prinURI
;
340 nsresult rv
= GetURI(getter_AddRefs(prinURI
));
341 if (NS_FAILED(rv
) || !prinURI
) {
344 return prinURI
->EqualsExceptRef(aOtherURI
, aResult
);
348 BasePrincipal::Subsumes(nsIPrincipal
* aOther
, bool* aResult
) {
349 NS_ENSURE_ARG_POINTER(aOther
);
351 *aResult
= FastSubsumes(aOther
);
357 BasePrincipal::SubsumesConsideringDomain(nsIPrincipal
* aOther
, bool* aResult
) {
358 NS_ENSURE_ARG_POINTER(aOther
);
360 *aResult
= FastSubsumesConsideringDomain(aOther
);
366 BasePrincipal::SubsumesConsideringDomainIgnoringFPD(nsIPrincipal
* aOther
,
368 NS_ENSURE_ARG_POINTER(aOther
);
370 *aResult
= FastSubsumesConsideringDomainIgnoringFPD(aOther
);
376 BasePrincipal::CheckMayLoad(nsIURI
* aURI
, bool aAllowIfInheritsPrincipal
) {
377 return CheckMayLoadHelper(aURI
, aAllowIfInheritsPrincipal
, false, 0);
381 BasePrincipal::CheckMayLoadWithReporting(nsIURI
* aURI
,
382 bool aAllowIfInheritsPrincipal
,
383 uint64_t aInnerWindowID
) {
384 return CheckMayLoadHelper(aURI
, aAllowIfInheritsPrincipal
, true,
388 nsresult
BasePrincipal::CheckMayLoadHelper(nsIURI
* aURI
,
389 bool aAllowIfInheritsPrincipal
,
391 uint64_t aInnerWindowID
) {
392 NS_ENSURE_ARG_POINTER(aURI
);
394 aReport
|| aInnerWindowID
== 0,
395 "Why do we have an inner window id if we're not supposed to report?");
397 // Check the internal method first, which allows us to quickly approve loads
398 // for the System Principal.
399 if (MayLoadInternal(aURI
)) {
404 if (aAllowIfInheritsPrincipal
) {
405 // If the caller specified to allow loads of URIs that inherit
406 // our principal, allow the load if this URI inherits its principal.
407 bool doesInheritSecurityContext
;
408 rv
= NS_URIChainHasFlags(aURI
,
409 nsIProtocolHandler::URI_INHERITS_SECURITY_CONTEXT
,
410 &doesInheritSecurityContext
);
411 if (NS_SUCCEEDED(rv
) && doesInheritSecurityContext
) {
416 bool fetchableByAnyone
;
417 rv
= NS_URIChainHasFlags(aURI
, nsIProtocolHandler::URI_FETCHABLE_BY_ANYONE
,
419 if (NS_SUCCEEDED(rv
) && fetchableByAnyone
) {
424 nsCOMPtr
<nsIURI
> prinURI
;
425 rv
= GetURI(getter_AddRefs(prinURI
));
426 if (NS_SUCCEEDED(rv
) && prinURI
) {
427 nsScriptSecurityManager::ReportError(
428 "CheckSameOriginError", prinURI
, aURI
,
429 mOriginAttributes
.mPrivateBrowsingId
> 0, aInnerWindowID
);
433 return NS_ERROR_DOM_BAD_URI
;
437 BasePrincipal::IsThirdPartyURI(nsIURI
* aURI
, bool* aRes
) {
439 // If we do not have a URI its always 3rd party.
440 nsCOMPtr
<nsIURI
> prinURI
;
441 nsresult rv
= GetURI(getter_AddRefs(prinURI
));
442 if (NS_FAILED(rv
) || !prinURI
) {
445 ThirdPartyUtil
* thirdPartyUtil
= ThirdPartyUtil::GetInstance();
446 return thirdPartyUtil
->IsThirdPartyURI(prinURI
, aURI
, aRes
);
450 BasePrincipal::IsThirdPartyPrincipal(nsIPrincipal
* aPrin
, bool* aRes
) {
452 nsCOMPtr
<nsIURI
> prinURI
;
453 nsresult rv
= GetURI(getter_AddRefs(prinURI
));
454 if (NS_FAILED(rv
) || !prinURI
) {
457 return aPrin
->IsThirdPartyURI(prinURI
, aRes
);
461 BasePrincipal::IsSameOrigin(nsIURI
* aURI
, bool aIsPrivateWin
, bool* aRes
) {
463 nsCOMPtr
<nsIURI
> prinURI
;
464 nsresult rv
= GetURI(getter_AddRefs(prinURI
));
465 if (NS_FAILED(rv
) || !prinURI
) {
468 nsIScriptSecurityManager
* ssm
= nsContentUtils::GetSecurityManager();
470 return NS_ERROR_UNEXPECTED
;
473 *aRes
= NS_SUCCEEDED(
474 ssm
->CheckSameOriginURI(prinURI
, aURI
, false, aIsPrivateWin
));
479 BasePrincipal::GetIsNullPrincipal(bool* aResult
) {
480 *aResult
= Kind() == eNullPrincipal
;
485 BasePrincipal::GetIsContentPrincipal(bool* aResult
) {
486 *aResult
= Kind() == eContentPrincipal
;
491 BasePrincipal::GetIsExpandedPrincipal(bool* aResult
) {
492 *aResult
= Kind() == eExpandedPrincipal
;
497 BasePrincipal::GetAsciiSpec(nsACString
& aSpec
) {
499 nsCOMPtr
<nsIURI
> prinURI
;
500 nsresult rv
= GetURI(getter_AddRefs(prinURI
));
501 if (NS_FAILED(rv
) || !prinURI
) {
504 return prinURI
->GetAsciiSpec(aSpec
);
508 BasePrincipal::GetExposablePrePath(nsACString
& aPrepath
) {
510 nsCOMPtr
<nsIURI
> prinURI
;
511 nsresult rv
= GetURI(getter_AddRefs(prinURI
));
512 if (NS_FAILED(rv
) || !prinURI
) {
516 nsCOMPtr
<nsIURIFixup
> fixup(components::URIFixup::Service());
517 nsCOMPtr
<nsIURIFixup
> urifixup
= services::GetURIFixup();
518 if (NS_WARN_IF(!urifixup
)) {
522 nsCOMPtr
<nsIURI
> fixedURI
;
523 rv
= fixup
->CreateExposableURI(prinURI
, getter_AddRefs(fixedURI
));
525 if (NS_FAILED(rv
) || NS_WARN_IF(!fixedURI
)) {
528 return fixedURI
->GetDisplayPrePath(aPrepath
);
531 BasePrincipal::GetPrepath(nsACString
& aPath
) {
533 nsCOMPtr
<nsIURI
> prinURI
;
534 nsresult rv
= GetURI(getter_AddRefs(prinURI
));
535 if (NS_FAILED(rv
) || !prinURI
) {
538 return prinURI
->GetPrePath(aPath
);
542 BasePrincipal::GetIsSystemPrincipal(bool* aResult
) {
543 *aResult
= IsSystemPrincipal();
548 BasePrincipal::GetIsAddonOrExpandedAddonPrincipal(bool* aResult
) {
549 *aResult
= AddonPolicy() || ContentScriptAddonPolicy();
553 NS_IMETHODIMP
BasePrincipal::GetIsOnion(bool* aIsOnion
) {
555 nsCOMPtr
<nsIURI
> prinURI
;
556 nsresult rv
= GetURI(getter_AddRefs(prinURI
));
557 if (NS_FAILED(rv
) || !prinURI
) {
562 rv
= prinURI
->GetHost(host
);
566 *aIsOnion
= StringEndsWith(host
, NS_LITERAL_CSTRING(".onion"));
571 BasePrincipal::SchemeIs(const char* aScheme
, bool* aResult
) {
573 nsCOMPtr
<nsIURI
> prinURI
;
574 nsresult rv
= GetURI(getter_AddRefs(prinURI
));
575 if (NS_FAILED(rv
) || !prinURI
) {
578 *aResult
= prinURI
->SchemeIs(aScheme
);
583 BasePrincipal::IsURIInPrefList(const char* aPref
, bool* aResult
) {
585 nsCOMPtr
<nsIURI
> prinURI
;
586 nsresult rv
= GetURI(getter_AddRefs(prinURI
));
587 if (NS_FAILED(rv
) || !prinURI
) {
590 *aResult
= nsContentUtils::IsURIInPrefList(prinURI
, aPref
);
595 BasePrincipal::GetIsOriginPotentiallyTrustworthy(bool* aResult
) {
596 MOZ_ASSERT(NS_IsMainThread());
599 nsCOMPtr
<nsIURI
> uri
;
600 nsresult rv
= GetURI(getter_AddRefs(uri
));
601 if (NS_FAILED(rv
) || !uri
) {
605 *aResult
= nsMixedContentBlocker::IsPotentiallyTrustworthyOrigin(uri
);
610 BasePrincipal::GetAboutModuleFlags(uint32_t* flags
) {
612 nsCOMPtr
<nsIURI
> prinURI
;
613 nsresult rv
= GetURI(getter_AddRefs(prinURI
));
614 if (NS_FAILED(rv
) || !prinURI
) {
615 return NS_ERROR_NOT_AVAILABLE
;
617 if (!prinURI
->SchemeIs("about")) {
621 nsCOMPtr
<nsIAboutModule
> aboutModule
;
622 rv
= NS_GetAboutModule(prinURI
, getter_AddRefs(aboutModule
));
623 if (NS_FAILED(rv
) || !aboutModule
) {
626 return aboutModule
->GetURIFlags(prinURI
, flags
);
630 BasePrincipal::GetOriginAttributes(JSContext
* aCx
,
631 JS::MutableHandle
<JS::Value
> aVal
) {
632 if (NS_WARN_IF(!ToJSValue(aCx
, mOriginAttributes
, aVal
))) {
633 return NS_ERROR_FAILURE
;
639 BasePrincipal::GetOriginSuffix(nsACString
& aOriginAttributes
) {
640 MOZ_ASSERT(mOriginSuffix
);
641 mOriginSuffix
->ToUTF8String(aOriginAttributes
);
646 BasePrincipal::GetUserContextId(uint32_t* aUserContextId
) {
647 *aUserContextId
= UserContextId();
652 BasePrincipal::GetPrivateBrowsingId(uint32_t* aPrivateBrowsingId
) {
653 *aPrivateBrowsingId
= PrivateBrowsingId();
658 BasePrincipal::GetIsInIsolatedMozBrowserElement(
659 bool* aIsInIsolatedMozBrowserElement
) {
660 *aIsInIsolatedMozBrowserElement
= IsInIsolatedMozBrowserElement();
664 nsresult
BasePrincipal::GetAddonPolicy(nsISupports
** aResult
) {
665 RefPtr
<extensions::WebExtensionPolicy
> policy(AddonPolicy());
666 policy
.forget(aResult
);
670 extensions::WebExtensionPolicy
* BasePrincipal::AddonPolicy() {
671 if (Is
<ContentPrincipal
>()) {
672 return As
<ContentPrincipal
>()->AddonPolicy();
677 bool BasePrincipal::AddonHasPermission(const nsAtom
* aPerm
) {
678 if (auto policy
= AddonPolicy()) {
679 return policy
->HasPermission(aPerm
);
684 nsIPrincipal
* BasePrincipal::PrincipalToInherit(nsIURI
* aRequestedURI
) {
685 if (Is
<ExpandedPrincipal
>()) {
686 return As
<ExpandedPrincipal
>()->PrincipalToInherit(aRequestedURI
);
691 already_AddRefed
<BasePrincipal
> BasePrincipal::CreateContentPrincipal(
692 nsIURI
* aURI
, const OriginAttributes
& aAttrs
) {
695 nsAutoCString originNoSuffix
;
697 ContentPrincipal::GenerateOriginNoSuffixFromURI(aURI
, originNoSuffix
);
699 // If the generation of the origin fails, we still want to have a valid
700 // principal. Better to return a null principal here.
701 return NullPrincipal::Create(aAttrs
);
704 return CreateContentPrincipal(aURI
, aAttrs
, originNoSuffix
);
707 already_AddRefed
<BasePrincipal
> BasePrincipal::CreateContentPrincipal(
708 nsIURI
* aURI
, const OriginAttributes
& aAttrs
,
709 const nsACString
& aOriginNoSuffix
) {
711 MOZ_ASSERT(!aOriginNoSuffix
.IsEmpty());
713 // If the URI is supposed to inherit the security context of whoever loads it,
714 // we shouldn't make a content principal for it.
715 bool inheritsPrincipal
;
716 nsresult rv
= NS_URIChainHasFlags(
717 aURI
, nsIProtocolHandler::URI_INHERITS_SECURITY_CONTEXT
,
719 if (NS_FAILED(rv
) || inheritsPrincipal
) {
720 return NullPrincipal::Create(aAttrs
);
723 // Check whether the URI knows what its principal is supposed to be.
724 #if defined(MOZ_THUNDERBIRD) || defined(MOZ_SUITE)
725 nsCOMPtr
<nsIURIWithSpecialOrigin
> uriWithSpecialOrigin
=
726 do_QueryInterface(aURI
);
727 if (uriWithSpecialOrigin
) {
728 nsCOMPtr
<nsIURI
> origin
;
729 rv
= uriWithSpecialOrigin
->GetOrigin(getter_AddRefs(origin
));
730 if (NS_WARN_IF(NS_FAILED(rv
))) {
734 OriginAttributes attrs
;
735 RefPtr
<BasePrincipal
> principal
= CreateContentPrincipal(origin
, attrs
);
736 return principal
.forget();
740 nsCOMPtr
<nsIPrincipal
> blobPrincipal
;
741 if (dom::BlobURLProtocolHandler::GetBlobURLPrincipal(
742 aURI
, getter_AddRefs(blobPrincipal
))) {
743 MOZ_ASSERT(blobPrincipal
);
744 RefPtr
<BasePrincipal
> principal
= Cast(blobPrincipal
);
745 return principal
.forget();
748 // Mint a content principal.
749 RefPtr
<ContentPrincipal
> principal
= new ContentPrincipal();
750 rv
= principal
->Init(aURI
, aAttrs
, aOriginNoSuffix
);
751 NS_ENSURE_SUCCESS(rv
, nullptr);
752 return principal
.forget();
755 already_AddRefed
<BasePrincipal
> BasePrincipal::CreateContentPrincipal(
756 const nsACString
& aOrigin
) {
757 MOZ_ASSERT(!StringBeginsWith(aOrigin
, NS_LITERAL_CSTRING("[")),
758 "CreateContentPrincipal does not support System and Expanded "
761 MOZ_ASSERT(!StringBeginsWith(aOrigin
,
762 NS_LITERAL_CSTRING(NS_NULLPRINCIPAL_SCHEME
":")),
763 "CreateContentPrincipal does not support NullPrincipal");
765 nsAutoCString originNoSuffix
;
766 OriginAttributes attrs
;
767 if (!attrs
.PopulateFromOrigin(aOrigin
, originNoSuffix
)) {
771 nsCOMPtr
<nsIURI
> uri
;
772 nsresult rv
= NS_NewURI(getter_AddRefs(uri
), originNoSuffix
);
773 NS_ENSURE_SUCCESS(rv
, nullptr);
775 return BasePrincipal::CreateContentPrincipal(uri
, attrs
);
778 already_AddRefed
<BasePrincipal
> BasePrincipal::CloneForcingOriginAttributes(
779 const OriginAttributes
& aOriginAttributes
) {
780 if (NS_WARN_IF(!IsContentPrincipal())) {
784 nsAutoCString originNoSuffix
;
785 nsresult rv
= GetOriginNoSuffix(originNoSuffix
);
786 NS_ENSURE_SUCCESS(rv
, nullptr);
788 nsIURI
* uri
= static_cast<ContentPrincipal
*>(this)->mURI
;
789 RefPtr
<ContentPrincipal
> copy
= new ContentPrincipal();
790 rv
= copy
->Init(uri
, aOriginAttributes
, originNoSuffix
);
791 NS_ENSURE_SUCCESS(rv
, nullptr);
793 return copy
.forget();
796 extensions::WebExtensionPolicy
* BasePrincipal::ContentScriptAddonPolicy() {
797 if (!Is
<ExpandedPrincipal
>()) {
801 auto expanded
= As
<ExpandedPrincipal
>();
802 for (auto& prin
: expanded
->AllowList()) {
803 if (auto policy
= BasePrincipal::Cast(prin
)->AddonPolicy()) {
811 bool BasePrincipal::AddonAllowsLoad(nsIURI
* aURI
,
812 bool aExplicit
/* = false */) {
813 if (Is
<ExpandedPrincipal
>()) {
814 return As
<ExpandedPrincipal
>()->AddonAllowsLoad(aURI
, aExplicit
);
816 if (auto policy
= AddonPolicy()) {
817 return policy
->CanAccessURI(aURI
, aExplicit
);
822 void BasePrincipal::FinishInit(const nsACString
& aOriginNoSuffix
,
823 const OriginAttributes
& aOriginAttributes
) {
825 mOriginAttributes
= aOriginAttributes
;
827 // First compute the origin suffix since it's infallible.
828 nsAutoCString originSuffix
;
829 mOriginAttributes
.CreateSuffix(originSuffix
);
830 mOriginSuffix
= NS_Atomize(originSuffix
);
832 MOZ_ASSERT(!aOriginNoSuffix
.IsEmpty());
833 mOriginNoSuffix
= NS_Atomize(aOriginNoSuffix
);
836 void BasePrincipal::FinishInit(BasePrincipal
* aOther
,
837 const OriginAttributes
& aOriginAttributes
) {
839 mOriginAttributes
= aOriginAttributes
;
841 // First compute the origin suffix since it's infallible.
842 nsAutoCString originSuffix
;
843 mOriginAttributes
.CreateSuffix(originSuffix
);
844 mOriginSuffix
= NS_Atomize(originSuffix
);
846 mOriginNoSuffix
= aOther
->mOriginNoSuffix
;
847 mHasExplicitDomain
= aOther
->mHasExplicitDomain
;
850 bool SiteIdentifier::Equals(const SiteIdentifier
& aOther
) const {
851 MOZ_ASSERT(IsInitialized());
852 MOZ_ASSERT(aOther
.IsInitialized());
853 return mPrincipal
->FastEquals(aOther
.mPrincipal
);
856 } // namespace mozilla