Bug 1693315 - Insert "Page Source" before "Extensions for Developers" in the DevTools...
[gecko.git] / caps / BasePrincipal.cpp
blobf32d628d0838d8f543e314787e6e34e5d61be6af
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 "nsIOService.h"
15 #include "nsIURIWithSpecialOrigin.h"
16 #include "nsScriptSecurityManager.h"
17 #include "nsServiceManagerUtils.h"
18 #include "nsAboutProtocolUtils.h"
19 #include "ThirdPartyUtil.h"
20 #include "mozilla/ContentPrincipal.h"
21 #include "mozilla/NullPrincipal.h"
22 #include "mozilla/dom/BlobURLProtocolHandler.h"
23 #include "mozilla/dom/ChromeUtils.h"
24 #include "mozilla/dom/ReferrerInfo.h"
25 #include "mozilla/dom/ToJSValue.h"
26 #include "mozilla/dom/nsMixedContentBlocker.h"
27 #include "mozilla/Components.h"
28 #include "mozilla/dom/StorageUtils.h"
29 #include "mozilla/dom/StorageUtils.h"
30 #include "nsIURL.h"
31 #include "nsEffectiveTLDService.h"
32 #include "nsIURIMutator.h"
33 #include "mozilla/StaticPrefs_permissions.h"
34 #include "nsIURIMutator.h"
35 #include "prnetdb.h"
36 #include "nsIURIFixup.h"
37 #include "mozilla/dom/StorageUtils.h"
38 #include "mozilla/ContentBlocking.h"
39 #include "nsPIDOMWindow.h"
40 #include "nsIURIMutator.h"
42 #include "json/json.h"
43 #include "nsSerializationHelper.h"
45 namespace mozilla {
47 BasePrincipal::BasePrincipal(PrincipalKind aKind)
48 : mKind(aKind), mHasExplicitDomain(false), mInitialized(false) {}
50 BasePrincipal::~BasePrincipal() {}
52 NS_IMETHODIMP
53 BasePrincipal::GetOrigin(nsACString& aOrigin) {
54 MOZ_ASSERT(mInitialized);
56 nsresult rv = GetOriginNoSuffix(aOrigin);
57 NS_ENSURE_SUCCESS(rv, rv);
59 nsAutoCString suffix;
60 rv = GetOriginSuffix(suffix);
61 NS_ENSURE_SUCCESS(rv, rv);
62 aOrigin.Append(suffix);
63 return NS_OK;
66 NS_IMETHODIMP
67 BasePrincipal::GetAsciiOrigin(nsACString& aOrigin) {
68 aOrigin.Truncate();
69 nsCOMPtr<nsIURI> prinURI;
70 nsresult rv = GetURI(getter_AddRefs(prinURI));
71 if (NS_FAILED(rv) || !prinURI) {
72 return NS_ERROR_NOT_AVAILABLE;
74 return nsContentUtils::GetASCIIOrigin(prinURI, aOrigin);
77 NS_IMETHODIMP
78 BasePrincipal::GetHostPort(nsACString& aRes) {
79 aRes.Truncate();
80 nsCOMPtr<nsIURI> prinURI;
81 nsresult rv = GetURI(getter_AddRefs(prinURI));
82 if (NS_FAILED(rv) || !prinURI) {
83 return NS_OK;
85 return prinURI->GetHostPort(aRes);
88 NS_IMETHODIMP
89 BasePrincipal::GetHost(nsACString& aRes) {
90 aRes.Truncate();
91 nsCOMPtr<nsIURI> prinURI;
92 nsresult rv = GetURI(getter_AddRefs(prinURI));
93 if (NS_FAILED(rv) || !prinURI) {
94 return NS_OK;
96 return prinURI->GetHost(aRes);
99 NS_IMETHODIMP
100 BasePrincipal::GetOriginNoSuffix(nsACString& aOrigin) {
101 MOZ_ASSERT(mInitialized);
102 mOriginNoSuffix->ToUTF8String(aOrigin);
103 return NS_OK;
106 NS_IMETHODIMP
107 BasePrincipal::GetSiteOrigin(nsACString& aSiteOrigin) {
108 MOZ_ASSERT(mInitialized);
110 nsresult rv = GetSiteOriginNoSuffix(aSiteOrigin);
111 NS_ENSURE_SUCCESS(rv, rv);
113 nsAutoCString suffix;
114 rv = GetOriginSuffix(suffix);
115 NS_ENSURE_SUCCESS(rv, rv);
116 aSiteOrigin.Append(suffix);
117 return NS_OK;
120 NS_IMETHODIMP
121 BasePrincipal::GetSiteOriginNoSuffix(nsACString& aSiteOrigin) {
122 MOZ_ASSERT(mInitialized);
123 return GetOriginNoSuffix(aSiteOrigin);
126 // Returns the inner Json::value of the serialized principal
127 // Example input and return values:
128 // Null principal:
129 // {"0":{"0":"moz-nullprincipal:{56cac540-864d-47e7-8e25-1614eab5155e}"}} ->
130 // {"0":"moz-nullprincipal:{56cac540-864d-47e7-8e25-1614eab5155e}"}
132 // Content principal:
133 // {"1":{"0":"https://mozilla.com"}} -> {"0":"https://mozilla.com"}
135 // Expanded principal:
136 // {"2":{"0":"<base64principal1>,<base64principal2>"}} ->
137 // {"0":"<base64principal1>,<base64principal2>"}
139 // System principal:
140 // {"3":{}} -> {}
141 // The aKey passed in also returns the corresponding PrincipalKind enum
143 // Warning: The Json::Value* pointer is into the aRoot object
144 static const Json::Value* GetPrincipalObject(const Json::Value& aRoot,
145 int& aOutPrincipalKind) {
146 const Json::Value::Members members = aRoot.getMemberNames();
147 // We only support one top level key in the object
148 if (members.size() != 1) {
149 return nullptr;
151 // members[0] here is the "0", "1", "2", "3" principalKind
152 // that is the top level of the serialized JSON principal
153 const std::string stringPrincipalKind = members[0];
155 // Next we take the string value from the JSON
156 // and convert it into the int for the BasePrincipal::PrincipalKind enum
158 // Verify that the key is within the valid range
159 int principalKind = std::stoi(stringPrincipalKind);
160 MOZ_ASSERT(BasePrincipal::eNullPrincipal == 0,
161 "We need to rely on 0 being a bounds check for the first "
162 "principal kind.");
163 if (principalKind < 0 || principalKind > BasePrincipal::eKindMax) {
164 return nullptr;
166 MOZ_ASSERT(principalKind == BasePrincipal::eNullPrincipal ||
167 principalKind == BasePrincipal::eContentPrincipal ||
168 principalKind == BasePrincipal::eExpandedPrincipal ||
169 principalKind == BasePrincipal::eSystemPrincipal);
170 aOutPrincipalKind = principalKind;
172 if (!aRoot[stringPrincipalKind].isObject()) {
173 return nullptr;
176 // Return the inner value of the principal object
177 return &aRoot[stringPrincipalKind];
180 // Accepts the JSON inner object without the wrapping principalKind
181 // (See GetPrincipalObject for the inner object response examples)
182 // Creates an array of KeyVal objects that are all defined on the principal
183 // Each principal type (null, content, expanded) has a KeyVal that stores the
184 // fields of the JSON
186 // This simplifies deserializing elsewhere as we do the checking for presence
187 // and string values here for the complete set of serializable keys that the
188 // corresponding principal supports.
190 // The KeyVal object has the following fields:
191 // - valueWasSerialized: is true if the deserialized JSON contained a string
192 // value
193 // - value: The string that was serialized for this key
194 // - key: an SerializableKeys enum value specific to the principal.
195 // For example content principal is an enum of: eURI, eDomain,
196 // eSuffix, eCSP
199 // Given an inner content principal:
200 // {"0": "https://mozilla.com", "2": "^privateBrowsingId=1"}
201 // | | | |
202 // ----------------------------- |
203 // | | |
204 // Key ----------------------
205 // |
206 // Value
208 // They Key "0" corresponds to ContentPrincipal::eURI
209 // They Key "1" corresponds to ContentPrincipal::eSuffix
210 template <typename T>
211 static nsTArray<typename T::KeyVal> GetJSONKeys(const Json::Value* aInput) {
212 int size = T::eMax + 1;
213 nsTArray<typename T::KeyVal> fields;
214 for (int i = 0; i != size; i++) {
215 typename T::KeyVal* field = fields.AppendElement();
216 // field->valueWasSerialized returns if the field was found in the
217 // deserialized code. This simplifies the consumers from having to check
218 // length.
219 field->valueWasSerialized = false;
220 field->key = static_cast<typename T::SerializableKeys>(i);
221 const std::string key = std::to_string(field->key);
222 if (aInput->isMember(key)) {
223 const Json::Value& val = (*aInput)[key];
224 if (val.isString()) {
225 field->value.Append(nsDependentCString(val.asCString()));
226 field->valueWasSerialized = true;
230 return fields;
233 // Takes a JSON string and parses it turning it into a principal of the
234 // corresponding type
236 // Given a content principal:
238 // inner JSON object
239 // |
240 // ---------------------------------------------------------
241 // | |
242 // {"1": {"0": "https://mozilla.com", "2": "^privateBrowsingId=1"}}
243 // | | | | |
244 // | ----------------------------- |
245 // | | | |
246 // PrincipalKind | | |
247 // | ----------------------------
248 // SerializableKeys |
249 // Value
251 // The string is first deserialized with jsoncpp to get the Json::Value of the
252 // object. The inner JSON object is parsed with GetPrincipalObject which returns
253 // a KeyVal array of the inner object's fields. PrincipalKind is returned by
254 // GetPrincipalObject which is then used to decide which principal
255 // implementation of FromProperties to call. The corresponding FromProperties
256 // call takes the KeyVal fields and turns it into a principal.
257 already_AddRefed<BasePrincipal> BasePrincipal::FromJSON(
258 const nsACString& aJSON) {
259 Json::Value root;
260 Json::CharReaderBuilder builder;
261 std::unique_ptr<Json::CharReader> const reader(builder.newCharReader());
262 bool parseSuccess =
263 reader->parse(aJSON.BeginReading(), aJSON.EndReading(), &root, nullptr);
264 if (!parseSuccess) {
265 MOZ_ASSERT(false,
266 "Unable to parse string as JSON to deserialize as a principal");
267 return nullptr;
270 int principalKind = -1;
271 const Json::Value* value = GetPrincipalObject(root, principalKind);
272 if (!value) {
273 #ifdef DEBUG
274 fprintf(stderr, "Unexpected JSON principal %s\n",
275 root.toStyledString().c_str());
276 #endif
277 MOZ_ASSERT(false, "Unexpected JSON to deserialize as a principal");
279 return nullptr;
281 MOZ_ASSERT(principalKind != -1,
282 "PrincipalKind should always be >=0 by this point");
284 if (principalKind == eSystemPrincipal) {
285 RefPtr<BasePrincipal> principal =
286 BasePrincipal::Cast(nsContentUtils::GetSystemPrincipal());
287 return principal.forget();
290 if (principalKind == eNullPrincipal) {
291 nsTArray<NullPrincipal::KeyVal> res = GetJSONKeys<NullPrincipal>(value);
292 return NullPrincipal::FromProperties(res);
295 if (principalKind == eContentPrincipal) {
296 nsTArray<ContentPrincipal::KeyVal> res =
297 GetJSONKeys<ContentPrincipal>(value);
298 return ContentPrincipal::FromProperties(res);
301 if (principalKind == eExpandedPrincipal) {
302 nsTArray<ExpandedPrincipal::KeyVal> res =
303 GetJSONKeys<ExpandedPrincipal>(value);
304 return ExpandedPrincipal::FromProperties(res);
307 MOZ_RELEASE_ASSERT(false, "Unexpected enum to deserialize as a principal");
310 nsresult BasePrincipal::PopulateJSONObject(Json::Value& aObject) {
311 return NS_OK;
314 // Returns a JSON representation of the principal.
315 // Calling BasePrincipal::FromJSON will deserialize the JSON into
316 // the corresponding principal type.
317 nsresult BasePrincipal::ToJSON(nsACString& aResult) {
318 MOZ_ASSERT(aResult.IsEmpty(), "ToJSON only supports an empty result input");
319 aResult.Truncate();
321 Json::StreamWriterBuilder builder;
322 builder["indentation"] = "";
323 Json::Value innerJSONObject = Json::objectValue;
325 nsresult rv = PopulateJSONObject(innerJSONObject);
326 NS_ENSURE_SUCCESS(rv, rv);
328 Json::Value root = Json::objectValue;
329 std::string key = std::to_string(Kind());
330 root[key] = innerJSONObject;
331 std::string result = Json::writeString(builder, root);
332 aResult.Append(result);
333 if (aResult.Length() == 0) {
334 MOZ_ASSERT(false, "JSON writer failed to output a principal serialization");
335 return NS_ERROR_UNEXPECTED;
337 return NS_OK;
340 bool BasePrincipal::FastSubsumesIgnoringFPD(
341 nsIPrincipal* aOther, DocumentDomainConsideration aConsideration) {
342 MOZ_ASSERT(aOther);
344 if (Kind() == eContentPrincipal &&
345 !dom::ChromeUtils::IsOriginAttributesEqualIgnoringFPD(
346 mOriginAttributes, Cast(aOther)->mOriginAttributes)) {
347 return false;
350 return SubsumesInternal(aOther, aConsideration);
353 bool BasePrincipal::Subsumes(nsIPrincipal* aOther,
354 DocumentDomainConsideration aConsideration) {
355 MOZ_ASSERT(aOther);
356 MOZ_ASSERT_IF(Kind() == eContentPrincipal, mOriginSuffix);
358 // Expanded principals handle origin attributes for each of their
359 // sub-principals individually, null principals do only simple checks for
360 // pointer equality, and system principals are immune to origin attributes
361 // checks, so only do this check for content principals.
362 if (Kind() == eContentPrincipal &&
363 mOriginSuffix != Cast(aOther)->mOriginSuffix) {
364 return false;
367 return SubsumesInternal(aOther, aConsideration);
370 NS_IMETHODIMP
371 BasePrincipal::Equals(nsIPrincipal* aOther, bool* aResult) {
372 NS_ENSURE_ARG_POINTER(aOther);
374 *aResult = FastEquals(aOther);
376 return NS_OK;
379 NS_IMETHODIMP
380 BasePrincipal::EqualsForPermission(nsIPrincipal* aOther, bool aExactHost,
381 bool* aResult) {
382 *aResult = false;
383 NS_ENSURE_ARG_POINTER(aOther);
384 NS_ENSURE_ARG_POINTER(aResult);
386 // If the principals are equal, then they match.
387 if (FastEquals(aOther)) {
388 *aResult = true;
389 return NS_OK;
392 // If we are matching with an exact host, we're done now - the permissions
393 // don't match otherwise, we need to start comparing subdomains!
394 if (aExactHost) {
395 return NS_OK;
398 // Compare their OriginAttributes
399 const mozilla::OriginAttributes& theirAttrs = aOther->OriginAttributesRef();
400 const mozilla::OriginAttributes& ourAttrs = OriginAttributesRef();
402 if (theirAttrs != ourAttrs) {
403 return NS_OK;
406 nsCOMPtr<nsIURI> ourURI;
407 nsresult rv = GetURI(getter_AddRefs(ourURI));
408 NS_ENSURE_SUCCESS(rv, rv);
409 auto* basePrin = BasePrincipal::Cast(aOther);
411 nsCOMPtr<nsIURI> otherURI;
412 rv = basePrin->GetURI(getter_AddRefs(otherURI));
413 NS_ENSURE_SUCCESS(rv, rv);
414 // Compare schemes
415 nsAutoCString otherScheme;
416 rv = otherURI->GetScheme(otherScheme);
417 NS_ENSURE_SUCCESS(rv, rv);
419 nsAutoCString ourScheme;
420 rv = ourURI->GetScheme(ourScheme);
421 NS_ENSURE_SUCCESS(rv, rv);
423 if (otherScheme != ourScheme) {
424 return NS_OK;
427 // Compare ports
428 int32_t otherPort;
429 rv = otherURI->GetPort(&otherPort);
430 NS_ENSURE_SUCCESS(rv, rv);
432 int32_t ourPort;
433 rv = ourURI->GetPort(&ourPort);
434 NS_ENSURE_SUCCESS(rv, rv);
436 if (otherPort != ourPort) {
437 return NS_OK;
440 // Check if the host or any subdomain of their host matches.
441 nsAutoCString otherHost;
442 rv = otherURI->GetHost(otherHost);
443 if (NS_FAILED(rv) || otherHost.IsEmpty()) {
444 return NS_OK;
447 nsAutoCString ourHost;
448 rv = ourURI->GetHost(ourHost);
449 if (NS_FAILED(rv) || ourHost.IsEmpty()) {
450 return NS_OK;
453 nsCOMPtr<nsIEffectiveTLDService> tldService =
454 do_GetService(NS_EFFECTIVETLDSERVICE_CONTRACTID);
455 if (!tldService) {
456 NS_ERROR("Should have a tld service!");
457 return NS_ERROR_FAILURE;
460 // This loop will not loop forever, as GetNextSubDomain will eventually fail
461 // with NS_ERROR_INSUFFICIENT_DOMAIN_LEVELS.
462 while (otherHost != ourHost) {
463 rv = tldService->GetNextSubDomain(otherHost, otherHost);
464 if (NS_FAILED(rv)) {
465 if (rv == NS_ERROR_INSUFFICIENT_DOMAIN_LEVELS) {
466 return NS_OK;
468 return rv;
472 *aResult = true;
473 return NS_OK;
476 NS_IMETHODIMP
477 BasePrincipal::EqualsConsideringDomain(nsIPrincipal* aOther, bool* aResult) {
478 NS_ENSURE_ARG_POINTER(aOther);
480 *aResult = FastEqualsConsideringDomain(aOther);
482 return NS_OK;
485 NS_IMETHODIMP
486 BasePrincipal::EqualsURI(nsIURI* aOtherURI, bool* aResult) {
487 *aResult = false;
488 nsCOMPtr<nsIURI> prinURI;
489 nsresult rv = GetURI(getter_AddRefs(prinURI));
490 if (NS_FAILED(rv) || !prinURI) {
491 return NS_OK;
493 return prinURI->EqualsExceptRef(aOtherURI, aResult);
496 NS_IMETHODIMP
497 BasePrincipal::Subsumes(nsIPrincipal* aOther, bool* aResult) {
498 NS_ENSURE_ARG_POINTER(aOther);
500 *aResult = FastSubsumes(aOther);
502 return NS_OK;
505 NS_IMETHODIMP
506 BasePrincipal::SubsumesConsideringDomain(nsIPrincipal* aOther, bool* aResult) {
507 NS_ENSURE_ARG_POINTER(aOther);
509 *aResult = FastSubsumesConsideringDomain(aOther);
511 return NS_OK;
514 NS_IMETHODIMP
515 BasePrincipal::SubsumesConsideringDomainIgnoringFPD(nsIPrincipal* aOther,
516 bool* aResult) {
517 NS_ENSURE_ARG_POINTER(aOther);
519 *aResult = FastSubsumesConsideringDomainIgnoringFPD(aOther);
521 return NS_OK;
524 NS_IMETHODIMP
525 BasePrincipal::CheckMayLoad(nsIURI* aURI, bool aAllowIfInheritsPrincipal) {
526 return CheckMayLoadHelper(aURI, aAllowIfInheritsPrincipal, false, 0);
529 NS_IMETHODIMP
530 BasePrincipal::CheckMayLoadWithReporting(nsIURI* aURI,
531 bool aAllowIfInheritsPrincipal,
532 uint64_t aInnerWindowID) {
533 return CheckMayLoadHelper(aURI, aAllowIfInheritsPrincipal, true,
534 aInnerWindowID);
537 nsresult BasePrincipal::CheckMayLoadHelper(nsIURI* aURI,
538 bool aAllowIfInheritsPrincipal,
539 bool aReport,
540 uint64_t aInnerWindowID) {
541 NS_ENSURE_ARG_POINTER(aURI);
542 MOZ_ASSERT(
543 aReport || aInnerWindowID == 0,
544 "Why do we have an inner window id if we're not supposed to report?");
546 // Check the internal method first, which allows us to quickly approve loads
547 // for the System Principal.
548 if (MayLoadInternal(aURI)) {
549 return NS_OK;
552 nsresult rv;
553 if (aAllowIfInheritsPrincipal) {
554 // If the caller specified to allow loads of URIs that inherit
555 // our principal, allow the load if this URI inherits its principal.
556 bool doesInheritSecurityContext;
557 rv = NS_URIChainHasFlags(aURI,
558 nsIProtocolHandler::URI_INHERITS_SECURITY_CONTEXT,
559 &doesInheritSecurityContext);
560 if (NS_SUCCEEDED(rv) && doesInheritSecurityContext) {
561 return NS_OK;
565 bool fetchableByAnyone;
566 rv = NS_URIChainHasFlags(aURI, nsIProtocolHandler::URI_FETCHABLE_BY_ANYONE,
567 &fetchableByAnyone);
568 if (NS_SUCCEEDED(rv) && fetchableByAnyone) {
569 return NS_OK;
572 if (aReport) {
573 nsCOMPtr<nsIURI> prinURI;
574 rv = GetURI(getter_AddRefs(prinURI));
575 if (NS_SUCCEEDED(rv) && prinURI) {
576 nsScriptSecurityManager::ReportError(
577 "CheckSameOriginError", prinURI, aURI,
578 mOriginAttributes.mPrivateBrowsingId > 0, aInnerWindowID);
582 return NS_ERROR_DOM_BAD_URI;
585 NS_IMETHODIMP
586 BasePrincipal::IsThirdPartyURI(nsIURI* aURI, bool* aRes) {
587 if (IsSystemPrincipal() || (AddonPolicy() && AddonAllowsLoad(aURI))) {
588 *aRes = false;
589 return NS_OK;
592 *aRes = true;
593 // If we do not have a URI its always 3rd party.
594 nsCOMPtr<nsIURI> prinURI;
595 nsresult rv = GetURI(getter_AddRefs(prinURI));
596 if (NS_FAILED(rv) || !prinURI) {
597 return NS_OK;
599 ThirdPartyUtil* thirdPartyUtil = ThirdPartyUtil::GetInstance();
600 return thirdPartyUtil->IsThirdPartyURI(prinURI, aURI, aRes);
603 NS_IMETHODIMP
604 BasePrincipal::IsThirdPartyPrincipal(nsIPrincipal* aPrin, bool* aRes) {
605 *aRes = true;
606 nsCOMPtr<nsIURI> prinURI;
607 nsresult rv = GetURI(getter_AddRefs(prinURI));
608 if (NS_FAILED(rv) || !prinURI) {
609 return NS_OK;
611 return aPrin->IsThirdPartyURI(prinURI, aRes);
613 NS_IMETHODIMP
614 BasePrincipal::IsThirdPartyChannel(nsIChannel* aChan, bool* aRes) {
615 if (IsSystemPrincipal()) {
616 // Nothing is 3rd party to the system principal.
617 *aRes = false;
618 return NS_OK;
621 nsCOMPtr<nsIURI> prinURI;
622 GetURI(getter_AddRefs(prinURI));
623 ThirdPartyUtil* thirdPartyUtil = ThirdPartyUtil::GetInstance();
624 return thirdPartyUtil->IsThirdPartyChannel(aChan, prinURI, aRes);
627 NS_IMETHODIMP
628 BasePrincipal::IsSameOrigin(nsIURI* aURI, bool aIsPrivateWin, bool* aRes) {
629 *aRes = false;
630 nsCOMPtr<nsIURI> prinURI;
631 nsresult rv = GetURI(getter_AddRefs(prinURI));
632 if (NS_FAILED(rv) || !prinURI) {
633 return NS_OK;
635 nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
636 if (!ssm) {
637 return NS_ERROR_UNEXPECTED;
639 *aRes = NS_SUCCEEDED(
640 ssm->CheckSameOriginURI(prinURI, aURI, false, aIsPrivateWin));
641 return NS_OK;
644 NS_IMETHODIMP
645 BasePrincipal::IsL10nAllowed(nsIURI* aURI, bool* aRes) {
646 *aRes = false;
648 if (nsContentUtils::IsErrorPage(aURI)) {
649 *aRes = true;
650 return NS_OK;
653 // The system principal is always allowed.
654 if (IsSystemPrincipal()) {
655 *aRes = true;
656 return NS_OK;
659 nsCOMPtr<nsIURI> uri;
660 nsresult rv = GetURI(getter_AddRefs(uri));
661 NS_ENSURE_SUCCESS(rv, NS_OK);
663 bool hasFlags;
665 // Allow access to uris that cannot be loaded by web content.
666 rv = NS_URIChainHasFlags(uri, nsIProtocolHandler::URI_DANGEROUS_TO_LOAD,
667 &hasFlags);
668 NS_ENSURE_SUCCESS(rv, NS_OK);
669 if (hasFlags) {
670 *aRes = true;
671 return NS_OK;
674 // UI resources also get access.
675 rv = NS_URIChainHasFlags(uri, nsIProtocolHandler::URI_IS_UI_RESOURCE,
676 &hasFlags);
677 NS_ENSURE_SUCCESS(rv, NS_OK);
678 if (hasFlags) {
679 *aRes = true;
680 return NS_OK;
683 auto policy = AddonPolicy();
684 *aRes = (policy && policy->IsPrivileged());
685 return NS_OK;
688 NS_IMETHODIMP
689 BasePrincipal::AllowsRelaxStrictFileOriginPolicy(nsIURI* aURI, bool* aRes) {
690 *aRes = false;
691 nsCOMPtr<nsIURI> prinURI;
692 nsresult rv = GetURI(getter_AddRefs(prinURI));
693 if (NS_FAILED(rv) || !prinURI) {
694 return NS_OK;
696 *aRes = NS_RelaxStrictFileOriginPolicy(aURI, prinURI);
697 return NS_OK;
700 NS_IMETHODIMP
701 BasePrincipal::GetPrefLightCacheKey(nsIURI* aURI, bool aWithCredentials,
702 const OriginAttributes& aOriginAttributes,
703 nsACString& _retval) {
704 _retval.Truncate();
705 constexpr auto space = " "_ns;
707 nsCOMPtr<nsIURI> uri;
708 nsresult rv = GetURI(getter_AddRefs(uri));
709 NS_ENSURE_SUCCESS(rv, rv);
711 nsAutoCString scheme, host, port;
712 if (uri) {
713 uri->GetScheme(scheme);
714 uri->GetHost(host);
715 port.AppendInt(NS_GetRealPort(uri));
718 if (aWithCredentials) {
719 _retval.AssignLiteral("cred");
720 } else {
721 _retval.AssignLiteral("nocred");
724 nsAutoCString spec;
725 rv = aURI->GetSpec(spec);
726 NS_ENSURE_SUCCESS(rv, rv);
728 nsAutoCString originAttributesSuffix;
729 aOriginAttributes.CreateSuffix(originAttributesSuffix);
731 _retval.Append(space + scheme + space + host + space + port + space + spec +
732 space + originAttributesSuffix);
734 return NS_OK;
737 NS_IMETHODIMP
738 BasePrincipal::HasFirstpartyStorageAccess(mozIDOMWindow* aCheckWindow,
739 uint32_t* aRejectedReason,
740 bool* aOutAllowed) {
741 *aRejectedReason = 0;
742 *aOutAllowed = false;
744 nsPIDOMWindowInner* win = nsPIDOMWindowInner::From(aCheckWindow);
745 nsCOMPtr<nsIURI> uri;
746 nsresult rv = GetURI(getter_AddRefs(uri));
747 if (NS_FAILED(rv)) {
748 return rv;
750 *aOutAllowed =
751 ContentBlocking::ShouldAllowAccessFor(win, uri, aRejectedReason);
752 return NS_OK;
755 NS_IMETHODIMP
756 BasePrincipal::GetIsNullPrincipal(bool* aResult) {
757 *aResult = Kind() == eNullPrincipal;
758 return NS_OK;
761 NS_IMETHODIMP
762 BasePrincipal::GetIsContentPrincipal(bool* aResult) {
763 *aResult = Kind() == eContentPrincipal;
764 return NS_OK;
767 NS_IMETHODIMP
768 BasePrincipal::GetIsExpandedPrincipal(bool* aResult) {
769 *aResult = Kind() == eExpandedPrincipal;
770 return NS_OK;
773 NS_IMETHODIMP
774 BasePrincipal::GetAsciiSpec(nsACString& aSpec) {
775 aSpec.Truncate();
776 nsCOMPtr<nsIURI> prinURI;
777 nsresult rv = GetURI(getter_AddRefs(prinURI));
778 if (NS_FAILED(rv) || !prinURI) {
779 return NS_OK;
781 return prinURI->GetAsciiSpec(aSpec);
784 NS_IMETHODIMP
785 BasePrincipal::GetSpec(nsACString& aSpec) {
786 aSpec.Truncate();
787 nsCOMPtr<nsIURI> prinURI;
788 nsresult rv = GetURI(getter_AddRefs(prinURI));
789 if (NS_FAILED(rv) || !prinURI) {
790 return NS_OK;
792 return prinURI->GetSpec(aSpec);
795 NS_IMETHODIMP
796 BasePrincipal::GetAsciiHost(nsACString& aHost) {
797 aHost.Truncate();
798 nsCOMPtr<nsIURI> prinURI;
799 nsresult rv = GetURI(getter_AddRefs(prinURI));
800 if (NS_FAILED(rv) || !prinURI) {
801 return NS_OK;
803 return prinURI->GetAsciiHost(aHost);
806 NS_IMETHODIMP
807 BasePrincipal::GetExposablePrePath(nsACString& aPrepath) {
808 aPrepath.Truncate();
809 nsCOMPtr<nsIURI> prinURI;
810 nsresult rv = GetURI(getter_AddRefs(prinURI));
811 if (NS_FAILED(rv) || !prinURI) {
812 return NS_OK;
815 nsCOMPtr<nsIURI> exposableURI = net::nsIOService::CreateExposableURI(prinURI);
816 return exposableURI->GetDisplayPrePath(aPrepath);
819 NS_IMETHODIMP
820 BasePrincipal::GetExposableSpec(nsACString& aSpec) {
821 aSpec.Truncate();
822 nsCOMPtr<nsIURI> prinURI;
823 nsresult rv = GetURI(getter_AddRefs(prinURI));
824 if (NS_FAILED(rv) || !prinURI) {
825 return NS_OK;
827 nsCOMPtr<nsIURI> clone;
828 rv = NS_MutateURI(prinURI)
829 .SetQuery(""_ns)
830 .SetRef(""_ns)
831 .SetUserPass(""_ns)
832 .Finalize(clone);
833 NS_ENSURE_SUCCESS(rv, rv);
834 return clone->GetAsciiSpec(aSpec);
837 NS_IMETHODIMP
838 BasePrincipal::GetPrepath(nsACString& aPath) {
839 aPath.Truncate();
840 nsCOMPtr<nsIURI> prinURI;
841 nsresult rv = GetURI(getter_AddRefs(prinURI));
842 if (NS_FAILED(rv) || !prinURI) {
843 return NS_OK;
845 return prinURI->GetPrePath(aPath);
848 NS_IMETHODIMP
849 BasePrincipal::GetFilePath(nsACString& aPath) {
850 aPath.Truncate();
851 nsCOMPtr<nsIURI> prinURI;
852 nsresult rv = GetURI(getter_AddRefs(prinURI));
853 if (NS_FAILED(rv) || !prinURI) {
854 return NS_OK;
856 return prinURI->GetFilePath(aPath);
859 NS_IMETHODIMP
860 BasePrincipal::GetIsSystemPrincipal(bool* aResult) {
861 *aResult = IsSystemPrincipal();
862 return NS_OK;
865 NS_IMETHODIMP
866 BasePrincipal::GetIsAddonOrExpandedAddonPrincipal(bool* aResult) {
867 *aResult = AddonPolicy() || ContentScriptAddonPolicy();
868 return NS_OK;
871 NS_IMETHODIMP BasePrincipal::GetIsOnion(bool* aIsOnion) {
872 *aIsOnion = false;
873 nsCOMPtr<nsIURI> prinURI;
874 nsresult rv = GetURI(getter_AddRefs(prinURI));
875 if (NS_FAILED(rv) || !prinURI) {
876 return NS_OK;
879 nsAutoCString host;
880 rv = prinURI->GetHost(host);
881 if (NS_FAILED(rv)) {
882 return NS_OK;
884 *aIsOnion = StringEndsWith(host, ".onion"_ns);
885 return NS_OK;
888 NS_IMETHODIMP BasePrincipal::GetIsIpAddress(bool* aIsIpAddress) {
889 *aIsIpAddress = false;
891 nsCOMPtr<nsIURI> prinURI;
892 nsresult rv = GetURI(getter_AddRefs(prinURI));
893 if (NS_FAILED(rv) || !prinURI) {
894 return NS_OK;
897 nsAutoCString host;
898 rv = prinURI->GetHost(host);
899 if (NS_FAILED(rv)) {
900 return NS_OK;
903 PRNetAddr prAddr;
904 memset(&prAddr, 0, sizeof(prAddr));
906 if (PR_StringToNetAddr(host.get(), &prAddr) == PR_SUCCESS) {
907 *aIsIpAddress = true;
910 return NS_OK;
913 NS_IMETHODIMP BasePrincipal::GetIsLocalIpAddress(bool* aIsIpAddress) {
914 *aIsIpAddress = false;
916 nsCOMPtr<nsIURI> prinURI;
917 nsresult rv = GetURI(getter_AddRefs(prinURI));
918 if (NS_FAILED(rv) || !prinURI) {
919 return NS_OK;
922 nsCOMPtr<nsIIOService> ioService = do_GetIOService(&rv);
923 if (NS_FAILED(rv) || !ioService) {
924 return NS_OK;
926 rv = ioService->HostnameIsLocalIPAddress(prinURI, aIsIpAddress);
927 if (NS_FAILED(rv)) {
928 *aIsIpAddress = false;
930 return NS_OK;
933 NS_IMETHODIMP
934 BasePrincipal::GetScheme(nsACString& aScheme) {
935 aScheme.Truncate();
937 nsCOMPtr<nsIURI> prinURI;
938 nsresult rv = GetURI(getter_AddRefs(prinURI));
939 if (NS_FAILED(rv) || !prinURI) {
940 return NS_OK;
943 return prinURI->GetScheme(aScheme);
946 NS_IMETHODIMP
947 BasePrincipal::SchemeIs(const char* aScheme, bool* aResult) {
948 *aResult = false;
949 nsCOMPtr<nsIURI> prinURI;
950 nsresult rv = GetURI(getter_AddRefs(prinURI));
951 if (NS_FAILED(rv) || !prinURI) {
952 return NS_OK;
954 *aResult = prinURI->SchemeIs(aScheme);
955 return NS_OK;
958 NS_IMETHODIMP
959 BasePrincipal::IsURIInPrefList(const char* aPref, bool* aResult) {
960 *aResult = false;
961 nsCOMPtr<nsIURI> prinURI;
962 nsresult rv = GetURI(getter_AddRefs(prinURI));
963 if (NS_FAILED(rv) || !prinURI) {
964 return NS_OK;
966 *aResult = nsContentUtils::IsURIInPrefList(prinURI, aPref);
967 return NS_OK;
970 NS_IMETHODIMP
971 BasePrincipal::GetIsOriginPotentiallyTrustworthy(bool* aResult) {
972 MOZ_ASSERT(NS_IsMainThread());
973 *aResult = false;
975 nsCOMPtr<nsIURI> uri;
976 nsresult rv = GetURI(getter_AddRefs(uri));
977 if (NS_FAILED(rv) || !uri) {
978 return NS_OK;
981 *aResult = nsMixedContentBlocker::IsPotentiallyTrustworthyOrigin(uri);
982 return NS_OK;
985 NS_IMETHODIMP
986 BasePrincipal::GetAboutModuleFlags(uint32_t* flags) {
987 *flags = 0;
988 nsCOMPtr<nsIURI> prinURI;
989 nsresult rv = GetURI(getter_AddRefs(prinURI));
990 if (NS_FAILED(rv) || !prinURI) {
991 return NS_ERROR_NOT_AVAILABLE;
993 if (!prinURI->SchemeIs("about")) {
994 return NS_OK;
997 nsCOMPtr<nsIAboutModule> aboutModule;
998 rv = NS_GetAboutModule(prinURI, getter_AddRefs(aboutModule));
999 if (NS_FAILED(rv) || !aboutModule) {
1000 return rv;
1002 return aboutModule->GetURIFlags(prinURI, flags);
1005 NS_IMETHODIMP
1006 BasePrincipal::GetOriginAttributes(JSContext* aCx,
1007 JS::MutableHandle<JS::Value> aVal) {
1008 if (NS_WARN_IF(!ToJSValue(aCx, mOriginAttributes, aVal))) {
1009 return NS_ERROR_FAILURE;
1011 return NS_OK;
1014 NS_IMETHODIMP
1015 BasePrincipal::GetOriginSuffix(nsACString& aOriginAttributes) {
1016 MOZ_ASSERT(mOriginSuffix);
1017 mOriginSuffix->ToUTF8String(aOriginAttributes);
1018 return NS_OK;
1021 NS_IMETHODIMP
1022 BasePrincipal::GetUserContextId(uint32_t* aUserContextId) {
1023 *aUserContextId = UserContextId();
1024 return NS_OK;
1027 NS_IMETHODIMP
1028 BasePrincipal::GetPrivateBrowsingId(uint32_t* aPrivateBrowsingId) {
1029 *aPrivateBrowsingId = PrivateBrowsingId();
1030 return NS_OK;
1033 NS_IMETHODIMP
1034 BasePrincipal::GetIsInIsolatedMozBrowserElement(
1035 bool* aIsInIsolatedMozBrowserElement) {
1036 *aIsInIsolatedMozBrowserElement = IsInIsolatedMozBrowserElement();
1037 return NS_OK;
1040 nsresult BasePrincipal::GetAddonPolicy(nsISupports** aResult) {
1041 RefPtr<extensions::WebExtensionPolicy> policy(AddonPolicy());
1042 policy.forget(aResult);
1043 return NS_OK;
1046 extensions::WebExtensionPolicy* BasePrincipal::AddonPolicy() {
1047 if (Is<ContentPrincipal>()) {
1048 return As<ContentPrincipal>()->AddonPolicy();
1050 return nullptr;
1053 bool BasePrincipal::AddonHasPermission(const nsAtom* aPerm) {
1054 if (auto policy = AddonPolicy()) {
1055 return policy->HasPermission(aPerm);
1057 return false;
1060 nsIPrincipal* BasePrincipal::PrincipalToInherit(nsIURI* aRequestedURI) {
1061 if (Is<ExpandedPrincipal>()) {
1062 return As<ExpandedPrincipal>()->PrincipalToInherit(aRequestedURI);
1064 return this;
1067 already_AddRefed<BasePrincipal> BasePrincipal::CreateContentPrincipal(
1068 nsIURI* aURI, const OriginAttributes& aAttrs) {
1069 MOZ_ASSERT(aURI);
1071 nsAutoCString originNoSuffix;
1072 nsresult rv =
1073 ContentPrincipal::GenerateOriginNoSuffixFromURI(aURI, originNoSuffix);
1074 if (NS_FAILED(rv)) {
1075 // If the generation of the origin fails, we still want to have a valid
1076 // principal. Better to return a null principal here.
1077 return NullPrincipal::Create(aAttrs);
1080 return CreateContentPrincipal(aURI, aAttrs, originNoSuffix);
1083 already_AddRefed<BasePrincipal> BasePrincipal::CreateContentPrincipal(
1084 nsIURI* aURI, const OriginAttributes& aAttrs,
1085 const nsACString& aOriginNoSuffix) {
1086 MOZ_ASSERT(aURI);
1087 MOZ_ASSERT(!aOriginNoSuffix.IsEmpty());
1089 // If the URI is supposed to inherit the security context of whoever loads it,
1090 // we shouldn't make a content principal for it.
1091 bool inheritsPrincipal;
1092 nsresult rv = NS_URIChainHasFlags(
1093 aURI, nsIProtocolHandler::URI_INHERITS_SECURITY_CONTEXT,
1094 &inheritsPrincipal);
1095 if (NS_FAILED(rv) || inheritsPrincipal) {
1096 return NullPrincipal::Create(aAttrs);
1099 // Check whether the URI knows what its principal is supposed to be.
1100 #if defined(MOZ_THUNDERBIRD) || defined(MOZ_SUITE)
1101 nsCOMPtr<nsIURIWithSpecialOrigin> uriWithSpecialOrigin =
1102 do_QueryInterface(aURI);
1103 if (uriWithSpecialOrigin) {
1104 nsCOMPtr<nsIURI> origin;
1105 rv = uriWithSpecialOrigin->GetOrigin(getter_AddRefs(origin));
1106 if (NS_WARN_IF(NS_FAILED(rv))) {
1107 return nullptr;
1109 MOZ_ASSERT(origin);
1110 OriginAttributes attrs;
1111 RefPtr<BasePrincipal> principal = CreateContentPrincipal(origin, attrs);
1112 return principal.forget();
1114 #endif
1116 nsCOMPtr<nsIPrincipal> blobPrincipal;
1117 if (dom::BlobURLProtocolHandler::GetBlobURLPrincipal(
1118 aURI, getter_AddRefs(blobPrincipal))) {
1119 MOZ_ASSERT(blobPrincipal);
1120 RefPtr<BasePrincipal> principal = Cast(blobPrincipal);
1121 return principal.forget();
1124 // Mint a content principal.
1125 RefPtr<ContentPrincipal> principal = new ContentPrincipal();
1126 rv = principal->Init(aURI, aAttrs, aOriginNoSuffix);
1127 NS_ENSURE_SUCCESS(rv, nullptr);
1128 return principal.forget();
1131 already_AddRefed<BasePrincipal> BasePrincipal::CreateContentPrincipal(
1132 const nsACString& aOrigin) {
1133 MOZ_ASSERT(!StringBeginsWith(aOrigin, "["_ns),
1134 "CreateContentPrincipal does not support System and Expanded "
1135 "principals");
1137 MOZ_ASSERT(
1138 !StringBeginsWith(aOrigin, nsLiteralCString(NS_NULLPRINCIPAL_SCHEME ":")),
1139 "CreateContentPrincipal does not support NullPrincipal");
1141 nsAutoCString originNoSuffix;
1142 OriginAttributes attrs;
1143 if (!attrs.PopulateFromOrigin(aOrigin, originNoSuffix)) {
1144 return nullptr;
1147 nsCOMPtr<nsIURI> uri;
1148 nsresult rv = NS_NewURI(getter_AddRefs(uri), originNoSuffix);
1149 NS_ENSURE_SUCCESS(rv, nullptr);
1151 return BasePrincipal::CreateContentPrincipal(uri, attrs);
1154 already_AddRefed<BasePrincipal> BasePrincipal::CloneForcingOriginAttributes(
1155 const OriginAttributes& aOriginAttributes) {
1156 if (NS_WARN_IF(!IsContentPrincipal())) {
1157 return nullptr;
1160 nsAutoCString originNoSuffix;
1161 nsresult rv = GetOriginNoSuffix(originNoSuffix);
1162 NS_ENSURE_SUCCESS(rv, nullptr);
1164 nsIURI* uri = static_cast<ContentPrincipal*>(this)->mURI;
1165 RefPtr<ContentPrincipal> copy = new ContentPrincipal();
1166 rv = copy->Init(uri, aOriginAttributes, originNoSuffix);
1167 NS_ENSURE_SUCCESS(rv, nullptr);
1169 return copy.forget();
1172 extensions::WebExtensionPolicy* BasePrincipal::ContentScriptAddonPolicy() {
1173 if (!Is<ExpandedPrincipal>()) {
1174 return nullptr;
1177 auto expanded = As<ExpandedPrincipal>();
1178 for (auto& prin : expanded->AllowList()) {
1179 if (auto policy = BasePrincipal::Cast(prin)->AddonPolicy()) {
1180 return policy;
1184 return nullptr;
1187 bool BasePrincipal::AddonAllowsLoad(nsIURI* aURI,
1188 bool aExplicit /* = false */) {
1189 if (Is<ExpandedPrincipal>()) {
1190 return As<ExpandedPrincipal>()->AddonAllowsLoad(aURI, aExplicit);
1192 if (auto policy = AddonPolicy()) {
1193 return policy->CanAccessURI(aURI, aExplicit);
1195 return false;
1198 void BasePrincipal::FinishInit(const nsACString& aOriginNoSuffix,
1199 const OriginAttributes& aOriginAttributes) {
1200 mInitialized = true;
1201 mOriginAttributes = aOriginAttributes;
1203 // First compute the origin suffix since it's infallible.
1204 nsAutoCString originSuffix;
1205 mOriginAttributes.CreateSuffix(originSuffix);
1206 mOriginSuffix = NS_Atomize(originSuffix);
1208 MOZ_ASSERT(!aOriginNoSuffix.IsEmpty());
1209 mOriginNoSuffix = NS_Atomize(aOriginNoSuffix);
1212 void BasePrincipal::FinishInit(BasePrincipal* aOther,
1213 const OriginAttributes& aOriginAttributes) {
1214 mInitialized = true;
1215 mOriginAttributes = aOriginAttributes;
1217 // First compute the origin suffix since it's infallible.
1218 nsAutoCString originSuffix;
1219 mOriginAttributes.CreateSuffix(originSuffix);
1220 mOriginSuffix = NS_Atomize(originSuffix);
1222 mOriginNoSuffix = aOther->mOriginNoSuffix;
1223 mHasExplicitDomain = aOther->mHasExplicitDomain;
1226 NS_IMETHODIMP
1227 BasePrincipal::GetLocalStorageQuotaKey(nsACString& aKey) {
1228 aKey.Truncate();
1230 nsCOMPtr<nsIURI> uri;
1231 nsresult rv = GetURI(getter_AddRefs(uri));
1232 NS_ENSURE_SUCCESS(rv, rv);
1233 NS_ENSURE_TRUE(uri, NS_ERROR_UNEXPECTED);
1235 // The special handling of the file scheme should be consistent with
1236 // GetStorageOriginKey.
1238 nsAutoCString baseDomain;
1239 rv = uri->GetAsciiHost(baseDomain);
1240 NS_ENSURE_SUCCESS(rv, rv);
1242 if (baseDomain.IsEmpty() && uri->SchemeIs("file")) {
1243 nsCOMPtr<nsIURL> url = do_QueryInterface(uri, &rv);
1244 NS_ENSURE_SUCCESS(rv, rv);
1246 rv = url->GetDirectory(baseDomain);
1247 NS_ENSURE_SUCCESS(rv, rv);
1248 } else {
1249 nsCOMPtr<nsIEffectiveTLDService> eTLDService(
1250 do_GetService(NS_EFFECTIVETLDSERVICE_CONTRACTID, &rv));
1251 NS_ENSURE_SUCCESS(rv, rv);
1253 nsAutoCString eTLDplusOne;
1254 rv = eTLDService->GetBaseDomain(uri, 0, eTLDplusOne);
1255 if (NS_SUCCEEDED(rv)) {
1256 baseDomain = eTLDplusOne;
1257 } else if (rv == NS_ERROR_HOST_IS_IP_ADDRESS ||
1258 rv == NS_ERROR_INSUFFICIENT_DOMAIN_LEVELS) {
1259 rv = NS_OK;
1261 NS_ENSURE_SUCCESS(rv, rv);
1264 OriginAttributesRef().CreateSuffix(aKey);
1266 nsAutoCString subdomainsDBKey;
1267 rv = dom::StorageUtils::CreateReversedDomain(baseDomain, subdomainsDBKey);
1268 NS_ENSURE_SUCCESS(rv, rv);
1270 aKey.Append(':');
1271 aKey.Append(subdomainsDBKey);
1273 return NS_OK;
1276 NS_IMETHODIMP
1277 BasePrincipal::GetNextSubDomainPrincipal(
1278 nsIPrincipal** aNextSubDomainPrincipal) {
1279 nsCOMPtr<nsIURI> uri;
1280 nsresult rv = GetURI(getter_AddRefs(uri));
1281 if (NS_FAILED(rv) || !uri) {
1282 return NS_OK;
1285 nsAutoCString host;
1286 rv = uri->GetHost(host);
1287 if (NS_FAILED(rv) || host.IsEmpty()) {
1288 return NS_OK;
1291 nsCString subDomain;
1292 rv = nsEffectiveTLDService::GetInstance()->GetNextSubDomain(host, subDomain);
1294 if (NS_FAILED(rv) || subDomain.IsEmpty()) {
1295 return NS_OK;
1298 nsCOMPtr<nsIURI> subDomainURI;
1299 rv = NS_MutateURI(uri).SetHost(subDomain).Finalize(subDomainURI);
1300 if (NS_FAILED(rv) || !subDomainURI) {
1301 return NS_OK;
1303 // Copy the attributes over
1304 mozilla::OriginAttributes attrs = OriginAttributesRef();
1306 if (!StaticPrefs::permissions_isolateBy_userContext()) {
1307 // Disable userContext for permissions.
1308 attrs.StripAttributes(mozilla::OriginAttributes::STRIP_USER_CONTEXT_ID);
1310 RefPtr<nsIPrincipal> principal =
1311 mozilla::BasePrincipal::CreateContentPrincipal(subDomainURI, attrs);
1313 if (!principal) {
1314 return NS_OK;
1316 principal.forget(aNextSubDomainPrincipal);
1317 return NS_OK;
1320 NS_IMETHODIMP
1321 BasePrincipal::GetStorageOriginKey(nsACString& aOriginKey) {
1322 aOriginKey.Truncate();
1324 nsCOMPtr<nsIURI> uri;
1325 nsresult rv = GetURI(getter_AddRefs(uri));
1326 NS_ENSURE_SUCCESS(rv, rv);
1327 NS_ENSURE_TRUE(uri, NS_ERROR_UNEXPECTED);
1329 // The special handling of the file scheme should be consistent with
1330 // GetLocalStorageQuotaKey.
1332 nsAutoCString domainOrigin;
1333 rv = uri->GetAsciiHost(domainOrigin);
1334 NS_ENSURE_SUCCESS(rv, rv);
1336 if (domainOrigin.IsEmpty()) {
1337 // For the file:/// protocol use the exact directory as domain.
1338 if (uri->SchemeIs("file")) {
1339 nsCOMPtr<nsIURL> url = do_QueryInterface(uri, &rv);
1340 NS_ENSURE_SUCCESS(rv, rv);
1341 rv = url->GetDirectory(domainOrigin);
1342 NS_ENSURE_SUCCESS(rv, rv);
1346 // Append reversed domain
1347 nsAutoCString reverseDomain;
1348 rv = dom::StorageUtils::CreateReversedDomain(domainOrigin, reverseDomain);
1349 NS_ENSURE_SUCCESS(rv, rv);
1351 aOriginKey.Append(reverseDomain);
1353 // Append scheme
1354 nsAutoCString scheme;
1355 rv = uri->GetScheme(scheme);
1356 NS_ENSURE_SUCCESS(rv, rv);
1358 aOriginKey.Append(':');
1359 aOriginKey.Append(scheme);
1361 // Append port if any
1362 int32_t port = NS_GetRealPort(uri);
1363 if (port != -1) {
1364 aOriginKey.Append(nsPrintfCString(":%d", port));
1367 return NS_OK;
1370 NS_IMETHODIMP
1371 BasePrincipal::GetIsScriptAllowedByPolicy(bool* aIsScriptAllowedByPolicy) {
1372 *aIsScriptAllowedByPolicy = false;
1373 nsCOMPtr<nsIURI> prinURI;
1374 nsresult rv = GetURI(getter_AddRefs(prinURI));
1375 if (NS_FAILED(rv) || !prinURI) {
1376 return NS_OK;
1378 nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
1379 if (!ssm) {
1380 return NS_ERROR_UNEXPECTED;
1382 return ssm->PolicyAllowsScript(prinURI, aIsScriptAllowedByPolicy);
1385 bool SiteIdentifier::Equals(const SiteIdentifier& aOther) const {
1386 MOZ_ASSERT(IsInitialized());
1387 MOZ_ASSERT(aOther.IsInitialized());
1388 return mPrincipal->FastEquals(aOther.mPrincipal);
1391 NS_IMETHODIMP
1392 BasePrincipal::CreateReferrerInfo(mozilla::dom::ReferrerPolicy aReferrerPolicy,
1393 nsIReferrerInfo** _retval) {
1394 nsCOMPtr<nsIURI> prinURI;
1395 RefPtr<dom::ReferrerInfo> info;
1396 nsresult rv = GetURI(getter_AddRefs(prinURI));
1397 if (NS_FAILED(rv) || !prinURI) {
1398 info = new dom::ReferrerInfo(nullptr);
1399 info.forget(_retval);
1400 return NS_OK;
1402 info = new dom::ReferrerInfo(prinURI, aReferrerPolicy);
1403 info.forget(_retval);
1404 return NS_OK;
1407 } // namespace mozilla