Bug 1740365 Part 2 - Add tests for named page styling r=dholbert
[gecko.git] / caps / BasePrincipal.cpp
blob67e9c14b95bfcfef4d149334a731af1b84ef45c6
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/ExtensionPolicyService.h"
22 #include "mozilla/NullPrincipal.h"
23 #include "mozilla/dom/BlobURLProtocolHandler.h"
24 #include "mozilla/dom/ChromeUtils.h"
25 #include "mozilla/dom/ReferrerInfo.h"
26 #include "mozilla/dom/ToJSValue.h"
27 #include "mozilla/dom/nsMixedContentBlocker.h"
28 #include "mozilla/Components.h"
29 #include "mozilla/dom/StorageUtils.h"
30 #include "mozilla/dom/StorageUtils.h"
31 #include "nsIURL.h"
32 #include "nsEffectiveTLDService.h"
33 #include "nsIURIMutator.h"
34 #include "mozilla/StaticPrefs_permissions.h"
35 #include "nsIURIMutator.h"
36 #include "nsMixedContentBlocker.h"
37 #include "prnetdb.h"
38 #include "nsIURIFixup.h"
39 #include "mozilla/dom/StorageUtils.h"
40 #include "mozilla/StorageAccess.h"
41 #include "nsPIDOMWindow.h"
42 #include "nsIURIMutator.h"
43 #include "mozilla/PermissionManager.h"
45 #include "json/json.h"
46 #include "nsSerializationHelper.h"
48 namespace mozilla {
50 BasePrincipal::BasePrincipal(PrincipalKind aKind,
51 const nsACString& aOriginNoSuffix,
52 const OriginAttributes& aOriginAttributes)
53 : mOriginNoSuffix(NS_Atomize(aOriginNoSuffix)),
54 mOriginSuffix(aOriginAttributes.CreateSuffixAtom()),
55 mOriginAttributes(aOriginAttributes),
56 mKind(aKind),
57 mHasExplicitDomain(false) {}
59 BasePrincipal::BasePrincipal(BasePrincipal* aOther,
60 const OriginAttributes& aOriginAttributes)
61 : mOriginNoSuffix(aOther->mOriginNoSuffix),
62 mOriginSuffix(aOriginAttributes.CreateSuffixAtom()),
63 mOriginAttributes(aOriginAttributes),
64 mKind(aOther->mKind),
65 mHasExplicitDomain(aOther->mHasExplicitDomain) {}
67 BasePrincipal::~BasePrincipal() = default;
69 NS_IMETHODIMP
70 BasePrincipal::GetOrigin(nsACString& aOrigin) {
71 nsresult rv = GetOriginNoSuffix(aOrigin);
72 NS_ENSURE_SUCCESS(rv, rv);
74 nsAutoCString suffix;
75 rv = GetOriginSuffix(suffix);
76 NS_ENSURE_SUCCESS(rv, rv);
77 aOrigin.Append(suffix);
78 return NS_OK;
81 NS_IMETHODIMP
82 BasePrincipal::GetAsciiOrigin(nsACString& aOrigin) {
83 aOrigin.Truncate();
84 nsCOMPtr<nsIURI> prinURI;
85 nsresult rv = GetURI(getter_AddRefs(prinURI));
86 if (NS_FAILED(rv) || !prinURI) {
87 return NS_ERROR_NOT_AVAILABLE;
89 return nsContentUtils::GetASCIIOrigin(prinURI, aOrigin);
92 NS_IMETHODIMP
93 BasePrincipal::GetHostPort(nsACString& aRes) {
94 aRes.Truncate();
95 nsCOMPtr<nsIURI> prinURI;
96 nsresult rv = GetURI(getter_AddRefs(prinURI));
97 if (NS_FAILED(rv) || !prinURI) {
98 return NS_OK;
100 return prinURI->GetHostPort(aRes);
103 NS_IMETHODIMP
104 BasePrincipal::GetHost(nsACString& aRes) {
105 aRes.Truncate();
106 nsCOMPtr<nsIURI> prinURI;
107 nsresult rv = GetURI(getter_AddRefs(prinURI));
108 if (NS_FAILED(rv) || !prinURI) {
109 return NS_OK;
111 return prinURI->GetHost(aRes);
114 NS_IMETHODIMP
115 BasePrincipal::GetOriginNoSuffix(nsACString& aOrigin) {
116 mOriginNoSuffix->ToUTF8String(aOrigin);
117 return NS_OK;
120 NS_IMETHODIMP
121 BasePrincipal::GetSiteOrigin(nsACString& aSiteOrigin) {
122 nsresult rv = GetSiteOriginNoSuffix(aSiteOrigin);
123 NS_ENSURE_SUCCESS(rv, rv);
125 nsAutoCString suffix;
126 rv = GetOriginSuffix(suffix);
127 NS_ENSURE_SUCCESS(rv, rv);
128 aSiteOrigin.Append(suffix);
129 return NS_OK;
132 NS_IMETHODIMP
133 BasePrincipal::GetSiteOriginNoSuffix(nsACString& aSiteOrigin) {
134 return GetOriginNoSuffix(aSiteOrigin);
137 // Returns the inner Json::value of the serialized principal
138 // Example input and return values:
139 // Null principal:
140 // {"0":{"0":"moz-nullprincipal:{56cac540-864d-47e7-8e25-1614eab5155e}"}} ->
141 // {"0":"moz-nullprincipal:{56cac540-864d-47e7-8e25-1614eab5155e}"}
143 // Content principal:
144 // {"1":{"0":"https://mozilla.com"}} -> {"0":"https://mozilla.com"}
146 // Expanded principal:
147 // {"2":{"0":"<base64principal1>,<base64principal2>"}} ->
148 // {"0":"<base64principal1>,<base64principal2>"}
150 // System principal:
151 // {"3":{}} -> {}
152 // The aKey passed in also returns the corresponding PrincipalKind enum
154 // Warning: The Json::Value* pointer is into the aRoot object
155 static const Json::Value* GetPrincipalObject(const Json::Value& aRoot,
156 int& aOutPrincipalKind) {
157 const Json::Value::Members members = aRoot.getMemberNames();
158 // We only support one top level key in the object
159 if (members.size() != 1) {
160 return nullptr;
162 // members[0] here is the "0", "1", "2", "3" principalKind
163 // that is the top level of the serialized JSON principal
164 const std::string stringPrincipalKind = members[0];
166 // Next we take the string value from the JSON
167 // and convert it into the int for the BasePrincipal::PrincipalKind enum
169 // Verify that the key is within the valid range
170 int principalKind = std::stoi(stringPrincipalKind);
171 MOZ_ASSERT(BasePrincipal::eNullPrincipal == 0,
172 "We need to rely on 0 being a bounds check for the first "
173 "principal kind.");
174 if (principalKind < 0 || principalKind > BasePrincipal::eKindMax) {
175 return nullptr;
177 MOZ_ASSERT(principalKind == BasePrincipal::eNullPrincipal ||
178 principalKind == BasePrincipal::eContentPrincipal ||
179 principalKind == BasePrincipal::eExpandedPrincipal ||
180 principalKind == BasePrincipal::eSystemPrincipal);
181 aOutPrincipalKind = principalKind;
183 if (!aRoot[stringPrincipalKind].isObject()) {
184 return nullptr;
187 // Return the inner value of the principal object
188 return &aRoot[stringPrincipalKind];
191 // Accepts the JSON inner object without the wrapping principalKind
192 // (See GetPrincipalObject for the inner object response examples)
193 // Creates an array of KeyVal objects that are all defined on the principal
194 // Each principal type (null, content, expanded) has a KeyVal that stores the
195 // fields of the JSON
197 // This simplifies deserializing elsewhere as we do the checking for presence
198 // and string values here for the complete set of serializable keys that the
199 // corresponding principal supports.
201 // The KeyVal object has the following fields:
202 // - valueWasSerialized: is true if the deserialized JSON contained a string
203 // value
204 // - value: The string that was serialized for this key
205 // - key: an SerializableKeys enum value specific to the principal.
206 // For example content principal is an enum of: eURI, eDomain,
207 // eSuffix, eCSP
210 // Given an inner content principal:
211 // {"0": "https://mozilla.com", "2": "^privateBrowsingId=1"}
212 // | | | |
213 // ----------------------------- |
214 // | | |
215 // Key ----------------------
216 // |
217 // Value
219 // They Key "0" corresponds to ContentPrincipal::eURI
220 // They Key "1" corresponds to ContentPrincipal::eSuffix
221 template <typename T>
222 static nsTArray<typename T::KeyVal> GetJSONKeys(const Json::Value* aInput) {
223 int size = T::eMax + 1;
224 nsTArray<typename T::KeyVal> fields;
225 for (int i = 0; i != size; i++) {
226 typename T::KeyVal* field = fields.AppendElement();
227 // field->valueWasSerialized returns if the field was found in the
228 // deserialized code. This simplifies the consumers from having to check
229 // length.
230 field->valueWasSerialized = false;
231 field->key = static_cast<typename T::SerializableKeys>(i);
232 const std::string key = std::to_string(field->key);
233 if (aInput->isMember(key)) {
234 const Json::Value& val = (*aInput)[key];
235 if (val.isString()) {
236 field->value.Append(nsDependentCString(val.asCString()));
237 field->valueWasSerialized = true;
241 return fields;
244 // Takes a JSON string and parses it turning it into a principal of the
245 // corresponding type
247 // Given a content principal:
249 // inner JSON object
250 // |
251 // ---------------------------------------------------------
252 // | |
253 // {"1": {"0": "https://mozilla.com", "2": "^privateBrowsingId=1"}}
254 // | | | | |
255 // | ----------------------------- |
256 // | | | |
257 // PrincipalKind | | |
258 // | ----------------------------
259 // SerializableKeys |
260 // Value
262 // The string is first deserialized with jsoncpp to get the Json::Value of the
263 // object. The inner JSON object is parsed with GetPrincipalObject which returns
264 // a KeyVal array of the inner object's fields. PrincipalKind is returned by
265 // GetPrincipalObject which is then used to decide which principal
266 // implementation of FromProperties to call. The corresponding FromProperties
267 // call takes the KeyVal fields and turns it into a principal.
268 already_AddRefed<BasePrincipal> BasePrincipal::FromJSON(
269 const nsACString& aJSON) {
270 Json::Value root;
271 Json::CharReaderBuilder builder;
272 std::unique_ptr<Json::CharReader> const reader(builder.newCharReader());
273 bool parseSuccess =
274 reader->parse(aJSON.BeginReading(), aJSON.EndReading(), &root, nullptr);
275 if (!parseSuccess) {
276 MOZ_ASSERT(false,
277 "Unable to parse string as JSON to deserialize as a principal");
278 return nullptr;
281 int principalKind = -1;
282 const Json::Value* value = GetPrincipalObject(root, principalKind);
283 if (!value) {
284 #ifdef DEBUG
285 fprintf(stderr, "Unexpected JSON principal %s\n",
286 root.toStyledString().c_str());
287 #endif
288 MOZ_ASSERT(false, "Unexpected JSON to deserialize as a principal");
290 return nullptr;
292 MOZ_ASSERT(principalKind != -1,
293 "PrincipalKind should always be >=0 by this point");
295 if (principalKind == eSystemPrincipal) {
296 RefPtr<BasePrincipal> principal =
297 BasePrincipal::Cast(nsContentUtils::GetSystemPrincipal());
298 return principal.forget();
301 if (principalKind == eNullPrincipal) {
302 nsTArray<NullPrincipal::KeyVal> res = GetJSONKeys<NullPrincipal>(value);
303 return NullPrincipal::FromProperties(res);
306 if (principalKind == eContentPrincipal) {
307 nsTArray<ContentPrincipal::KeyVal> res =
308 GetJSONKeys<ContentPrincipal>(value);
309 return ContentPrincipal::FromProperties(res);
312 if (principalKind == eExpandedPrincipal) {
313 nsTArray<ExpandedPrincipal::KeyVal> res =
314 GetJSONKeys<ExpandedPrincipal>(value);
315 return ExpandedPrincipal::FromProperties(res);
318 MOZ_RELEASE_ASSERT(false, "Unexpected enum to deserialize as a principal");
321 nsresult BasePrincipal::PopulateJSONObject(Json::Value& aObject) {
322 return NS_OK;
325 // Returns a JSON representation of the principal.
326 // Calling BasePrincipal::FromJSON will deserialize the JSON into
327 // the corresponding principal type.
328 nsresult BasePrincipal::ToJSON(nsACString& aResult) {
329 MOZ_ASSERT(aResult.IsEmpty(), "ToJSON only supports an empty result input");
330 aResult.Truncate();
332 Json::StreamWriterBuilder builder;
333 builder["indentation"] = "";
334 Json::Value innerJSONObject = Json::objectValue;
336 nsresult rv = PopulateJSONObject(innerJSONObject);
337 NS_ENSURE_SUCCESS(rv, rv);
339 Json::Value root = Json::objectValue;
340 std::string key = std::to_string(Kind());
341 root[key] = innerJSONObject;
342 std::string result = Json::writeString(builder, root);
343 aResult.Append(result);
344 if (aResult.Length() == 0) {
345 MOZ_ASSERT(false, "JSON writer failed to output a principal serialization");
346 return NS_ERROR_UNEXPECTED;
348 return NS_OK;
351 bool BasePrincipal::FastSubsumesIgnoringFPD(
352 nsIPrincipal* aOther, DocumentDomainConsideration aConsideration) {
353 MOZ_ASSERT(aOther);
355 if (Kind() == eContentPrincipal &&
356 !dom::ChromeUtils::IsOriginAttributesEqualIgnoringFPD(
357 mOriginAttributes, Cast(aOther)->mOriginAttributes)) {
358 return false;
361 return SubsumesInternal(aOther, aConsideration);
364 bool BasePrincipal::Subsumes(nsIPrincipal* aOther,
365 DocumentDomainConsideration aConsideration) {
366 MOZ_ASSERT(aOther);
367 MOZ_ASSERT_IF(Kind() == eContentPrincipal, mOriginSuffix);
369 // Expanded principals handle origin attributes for each of their
370 // sub-principals individually, null principals do only simple checks for
371 // pointer equality, and system principals are immune to origin attributes
372 // checks, so only do this check for content principals.
373 if (Kind() == eContentPrincipal &&
374 mOriginSuffix != Cast(aOther)->mOriginSuffix) {
375 return false;
378 return SubsumesInternal(aOther, aConsideration);
381 NS_IMETHODIMP
382 BasePrincipal::Equals(nsIPrincipal* aOther, bool* aResult) {
383 NS_ENSURE_ARG_POINTER(aOther);
385 *aResult = FastEquals(aOther);
387 return NS_OK;
390 NS_IMETHODIMP
391 BasePrincipal::EqualsForPermission(nsIPrincipal* aOther, bool aExactHost,
392 bool* aResult) {
393 *aResult = false;
394 NS_ENSURE_ARG_POINTER(aOther);
395 NS_ENSURE_ARG_POINTER(aResult);
397 auto* other = Cast(aOther);
398 if (Kind() != other->Kind()) {
399 // Principals of different kinds can't be equal.
400 return NS_OK;
403 if (Kind() == eSystemPrincipal) {
404 *aResult = this == other;
405 return NS_OK;
408 if (Kind() == eNullPrincipal) {
409 // We don't store permissions for NullPrincipals.
410 return NS_OK;
413 MOZ_ASSERT(Kind() == eExpandedPrincipal || Kind() == eContentPrincipal);
415 // Certain origin attributes should not be used to isolate permissions.
416 // Create a stripped copy of both OA sets to compare.
417 mozilla::OriginAttributes ourAttrs = mOriginAttributes;
418 PermissionManager::MaybeStripOriginAttributes(false, ourAttrs);
419 mozilla::OriginAttributes theirAttrs = aOther->OriginAttributesRef();
420 PermissionManager::MaybeStripOriginAttributes(false, theirAttrs);
422 if (ourAttrs != theirAttrs) {
423 return NS_OK;
426 if (mOriginNoSuffix == other->mOriginNoSuffix) {
427 *aResult = true;
428 return NS_OK;
431 // If we are matching with an exact host, we're done now - the permissions
432 // don't match otherwise, we need to start comparing subdomains!
433 if (aExactHost) {
434 return NS_OK;
437 nsCOMPtr<nsIURI> ourURI;
438 nsresult rv = GetURI(getter_AddRefs(ourURI));
439 NS_ENSURE_SUCCESS(rv, rv);
440 // Some principal types may indicate success, but still return nullptr for
441 // URI.
442 NS_ENSURE_TRUE(ourURI, NS_ERROR_FAILURE);
444 nsCOMPtr<nsIURI> otherURI;
445 rv = other->GetURI(getter_AddRefs(otherURI));
446 NS_ENSURE_SUCCESS(rv, rv);
447 NS_ENSURE_TRUE(otherURI, NS_ERROR_FAILURE);
449 // Compare schemes
450 nsAutoCString otherScheme;
451 rv = otherURI->GetScheme(otherScheme);
452 NS_ENSURE_SUCCESS(rv, rv);
454 nsAutoCString ourScheme;
455 rv = ourURI->GetScheme(ourScheme);
456 NS_ENSURE_SUCCESS(rv, rv);
458 if (otherScheme != ourScheme) {
459 return NS_OK;
462 // Compare ports
463 int32_t otherPort;
464 rv = otherURI->GetPort(&otherPort);
465 NS_ENSURE_SUCCESS(rv, rv);
467 int32_t ourPort;
468 rv = ourURI->GetPort(&ourPort);
469 NS_ENSURE_SUCCESS(rv, rv);
471 if (otherPort != ourPort) {
472 return NS_OK;
475 // Check if the host or any subdomain of their host matches.
476 nsAutoCString otherHost;
477 rv = otherURI->GetHost(otherHost);
478 if (NS_FAILED(rv) || otherHost.IsEmpty()) {
479 return NS_OK;
482 nsAutoCString ourHost;
483 rv = ourURI->GetHost(ourHost);
484 if (NS_FAILED(rv) || ourHost.IsEmpty()) {
485 return NS_OK;
488 nsCOMPtr<nsIEffectiveTLDService> tldService =
489 do_GetService(NS_EFFECTIVETLDSERVICE_CONTRACTID);
490 if (!tldService) {
491 NS_ERROR("Should have a tld service!");
492 return NS_ERROR_FAILURE;
495 // This loop will not loop forever, as GetNextSubDomain will eventually fail
496 // with NS_ERROR_INSUFFICIENT_DOMAIN_LEVELS.
497 while (otherHost != ourHost) {
498 rv = tldService->GetNextSubDomain(otherHost, otherHost);
499 if (NS_FAILED(rv)) {
500 if (rv == NS_ERROR_INSUFFICIENT_DOMAIN_LEVELS) {
501 return NS_OK;
503 return rv;
507 *aResult = true;
508 return NS_OK;
511 NS_IMETHODIMP
512 BasePrincipal::EqualsConsideringDomain(nsIPrincipal* aOther, bool* aResult) {
513 NS_ENSURE_ARG_POINTER(aOther);
515 *aResult = FastEqualsConsideringDomain(aOther);
517 return NS_OK;
520 NS_IMETHODIMP
521 BasePrincipal::EqualsURI(nsIURI* aOtherURI, bool* aResult) {
522 *aResult = false;
523 nsCOMPtr<nsIURI> prinURI;
524 nsresult rv = GetURI(getter_AddRefs(prinURI));
525 if (NS_FAILED(rv) || !prinURI) {
526 return NS_OK;
528 return prinURI->EqualsExceptRef(aOtherURI, aResult);
531 NS_IMETHODIMP
532 BasePrincipal::Subsumes(nsIPrincipal* aOther, bool* aResult) {
533 NS_ENSURE_ARG_POINTER(aOther);
535 *aResult = FastSubsumes(aOther);
537 return NS_OK;
540 NS_IMETHODIMP
541 BasePrincipal::SubsumesConsideringDomain(nsIPrincipal* aOther, bool* aResult) {
542 NS_ENSURE_ARG_POINTER(aOther);
544 *aResult = FastSubsumesConsideringDomain(aOther);
546 return NS_OK;
549 NS_IMETHODIMP
550 BasePrincipal::SubsumesConsideringDomainIgnoringFPD(nsIPrincipal* aOther,
551 bool* aResult) {
552 NS_ENSURE_ARG_POINTER(aOther);
554 *aResult = FastSubsumesConsideringDomainIgnoringFPD(aOther);
556 return NS_OK;
559 NS_IMETHODIMP
560 BasePrincipal::CheckMayLoad(nsIURI* aURI, bool aAllowIfInheritsPrincipal) {
561 return CheckMayLoadHelper(aURI, aAllowIfInheritsPrincipal, false, 0);
564 NS_IMETHODIMP
565 BasePrincipal::CheckMayLoadWithReporting(nsIURI* aURI,
566 bool aAllowIfInheritsPrincipal,
567 uint64_t aInnerWindowID) {
568 return CheckMayLoadHelper(aURI, aAllowIfInheritsPrincipal, true,
569 aInnerWindowID);
572 nsresult BasePrincipal::CheckMayLoadHelper(nsIURI* aURI,
573 bool aAllowIfInheritsPrincipal,
574 bool aReport,
575 uint64_t aInnerWindowID) {
576 NS_ENSURE_ARG_POINTER(aURI);
577 MOZ_ASSERT(
578 aReport || aInnerWindowID == 0,
579 "Why do we have an inner window id if we're not supposed to report?");
581 // Check the internal method first, which allows us to quickly approve loads
582 // for the System Principal.
583 if (MayLoadInternal(aURI)) {
584 return NS_OK;
587 nsresult rv;
588 if (aAllowIfInheritsPrincipal) {
589 // If the caller specified to allow loads of URIs that inherit
590 // our principal, allow the load if this URI inherits its principal.
591 bool doesInheritSecurityContext;
592 rv = NS_URIChainHasFlags(aURI,
593 nsIProtocolHandler::URI_INHERITS_SECURITY_CONTEXT,
594 &doesInheritSecurityContext);
595 if (NS_SUCCEEDED(rv) && doesInheritSecurityContext) {
596 return NS_OK;
600 // Web Accessible Resources in MV2 Extensions are marked with
601 // URI_FETCHABLE_BY_ANYONE
602 bool fetchableByAnyone;
603 rv = NS_URIChainHasFlags(aURI, nsIProtocolHandler::URI_FETCHABLE_BY_ANYONE,
604 &fetchableByAnyone);
605 if (NS_SUCCEEDED(rv) && fetchableByAnyone) {
606 return NS_OK;
609 // Get the principal uri for the last flag check or error.
610 nsCOMPtr<nsIURI> prinURI;
611 rv = GetURI(getter_AddRefs(prinURI));
612 if (!(NS_SUCCEEDED(rv) && prinURI)) {
613 return NS_ERROR_DOM_BAD_URI;
616 // If MV3 Extension uris are web accessible by this principal it is allowed to
617 // load.
618 bool maybeWebAccessible = false;
619 NS_URIChainHasFlags(aURI, nsIProtocolHandler::WEBEXT_URI_WEB_ACCESSIBLE,
620 &maybeWebAccessible);
621 NS_ENSURE_SUCCESS(rv, rv);
622 if (maybeWebAccessible) {
623 bool isWebAccessible = false;
624 rv = ExtensionPolicyService::GetSingleton().SourceMayLoadExtensionURI(
625 prinURI, aURI, &isWebAccessible);
626 if (NS_SUCCEEDED(rv) && isWebAccessible) {
627 return NS_OK;
631 if (aReport) {
632 nsScriptSecurityManager::ReportError(
633 "CheckSameOriginError", prinURI, aURI,
634 mOriginAttributes.mPrivateBrowsingId > 0, aInnerWindowID);
637 return NS_ERROR_DOM_BAD_URI;
640 NS_IMETHODIMP
641 BasePrincipal::IsThirdPartyURI(nsIURI* aURI, bool* aRes) {
642 if (IsSystemPrincipal() || (AddonPolicy() && AddonAllowsLoad(aURI))) {
643 *aRes = false;
644 return NS_OK;
647 *aRes = true;
648 // If we do not have a URI its always 3rd party.
649 nsCOMPtr<nsIURI> prinURI;
650 nsresult rv = GetURI(getter_AddRefs(prinURI));
651 if (NS_FAILED(rv) || !prinURI) {
652 return NS_OK;
654 ThirdPartyUtil* thirdPartyUtil = ThirdPartyUtil::GetInstance();
655 return thirdPartyUtil->IsThirdPartyURI(prinURI, aURI, aRes);
658 NS_IMETHODIMP
659 BasePrincipal::IsThirdPartyPrincipal(nsIPrincipal* aPrin, bool* aRes) {
660 *aRes = true;
661 nsCOMPtr<nsIURI> prinURI;
662 nsresult rv = GetURI(getter_AddRefs(prinURI));
663 if (NS_FAILED(rv) || !prinURI) {
664 return NS_OK;
666 return aPrin->IsThirdPartyURI(prinURI, aRes);
668 NS_IMETHODIMP
669 BasePrincipal::IsThirdPartyChannel(nsIChannel* aChan, bool* aRes) {
670 if (IsSystemPrincipal()) {
671 // Nothing is 3rd party to the system principal.
672 *aRes = false;
673 return NS_OK;
676 nsCOMPtr<nsIURI> prinURI;
677 GetURI(getter_AddRefs(prinURI));
678 ThirdPartyUtil* thirdPartyUtil = ThirdPartyUtil::GetInstance();
679 return thirdPartyUtil->IsThirdPartyChannel(aChan, prinURI, aRes);
682 NS_IMETHODIMP
683 BasePrincipal::IsSameOrigin(nsIURI* aURI, bool* aRes) {
684 *aRes = false;
685 nsCOMPtr<nsIURI> prinURI;
686 nsresult rv = GetURI(getter_AddRefs(prinURI));
687 if (NS_FAILED(rv) || !prinURI) {
688 // Note that expanded and system principals return here, because they have
689 // no URI.
690 return NS_OK;
692 nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
693 if (!ssm) {
694 return NS_OK;
696 bool reportError = false;
697 bool isPrivateWindow = false; // Only used for error reporting.
698 *aRes = NS_SUCCEEDED(
699 ssm->CheckSameOriginURI(prinURI, aURI, reportError, isPrivateWindow));
700 return NS_OK;
703 NS_IMETHODIMP
704 BasePrincipal::IsL10nAllowed(nsIURI* aURI, bool* aRes) {
705 *aRes = false;
707 if (nsContentUtils::IsErrorPage(aURI)) {
708 *aRes = true;
709 return NS_OK;
712 // The system principal is always allowed.
713 if (IsSystemPrincipal()) {
714 *aRes = true;
715 return NS_OK;
718 nsCOMPtr<nsIURI> uri;
719 nsresult rv = GetURI(getter_AddRefs(uri));
720 NS_ENSURE_SUCCESS(rv, NS_OK);
722 bool hasFlags;
724 // Allow access to uris that cannot be loaded by web content.
725 rv = NS_URIChainHasFlags(uri, nsIProtocolHandler::URI_DANGEROUS_TO_LOAD,
726 &hasFlags);
727 NS_ENSURE_SUCCESS(rv, NS_OK);
728 if (hasFlags) {
729 *aRes = true;
730 return NS_OK;
733 // UI resources also get access.
734 rv = NS_URIChainHasFlags(uri, nsIProtocolHandler::URI_IS_UI_RESOURCE,
735 &hasFlags);
736 NS_ENSURE_SUCCESS(rv, NS_OK);
737 if (hasFlags) {
738 *aRes = true;
739 return NS_OK;
742 auto policy = AddonPolicy();
743 *aRes = (policy && policy->IsPrivileged());
744 return NS_OK;
747 NS_IMETHODIMP
748 BasePrincipal::AllowsRelaxStrictFileOriginPolicy(nsIURI* aURI, bool* aRes) {
749 *aRes = false;
750 nsCOMPtr<nsIURI> prinURI;
751 nsresult rv = GetURI(getter_AddRefs(prinURI));
752 if (NS_FAILED(rv) || !prinURI) {
753 return NS_OK;
755 *aRes = NS_RelaxStrictFileOriginPolicy(aURI, prinURI);
756 return NS_OK;
759 NS_IMETHODIMP
760 BasePrincipal::GetPrefLightCacheKey(nsIURI* aURI, bool aWithCredentials,
761 const OriginAttributes& aOriginAttributes,
762 nsACString& _retval) {
763 _retval.Truncate();
764 constexpr auto space = " "_ns;
766 nsCOMPtr<nsIURI> uri;
767 nsresult rv = GetURI(getter_AddRefs(uri));
768 NS_ENSURE_SUCCESS(rv, rv);
770 nsAutoCString scheme, host, port;
771 if (uri) {
772 uri->GetScheme(scheme);
773 uri->GetHost(host);
774 port.AppendInt(NS_GetRealPort(uri));
777 if (aWithCredentials) {
778 _retval.AssignLiteral("cred");
779 } else {
780 _retval.AssignLiteral("nocred");
783 nsAutoCString spec;
784 rv = aURI->GetSpec(spec);
785 NS_ENSURE_SUCCESS(rv, rv);
787 nsAutoCString originAttributesSuffix;
788 aOriginAttributes.CreateSuffix(originAttributesSuffix);
790 _retval.Append(space + scheme + space + host + space + port + space + spec +
791 space + originAttributesSuffix);
793 return NS_OK;
796 NS_IMETHODIMP
797 BasePrincipal::HasFirstpartyStorageAccess(mozIDOMWindow* aCheckWindow,
798 uint32_t* aRejectedReason,
799 bool* aOutAllowed) {
800 *aRejectedReason = 0;
801 *aOutAllowed = false;
803 nsPIDOMWindowInner* win = nsPIDOMWindowInner::From(aCheckWindow);
804 nsCOMPtr<nsIURI> uri;
805 nsresult rv = GetURI(getter_AddRefs(uri));
806 if (NS_FAILED(rv)) {
807 return rv;
809 *aOutAllowed = ShouldAllowAccessFor(win, uri, aRejectedReason);
810 return NS_OK;
813 NS_IMETHODIMP
814 BasePrincipal::GetIsNullPrincipal(bool* aResult) {
815 *aResult = Kind() == eNullPrincipal;
816 return NS_OK;
819 NS_IMETHODIMP
820 BasePrincipal::GetIsContentPrincipal(bool* aResult) {
821 *aResult = Kind() == eContentPrincipal;
822 return NS_OK;
825 NS_IMETHODIMP
826 BasePrincipal::GetIsExpandedPrincipal(bool* aResult) {
827 *aResult = Kind() == eExpandedPrincipal;
828 return NS_OK;
831 NS_IMETHODIMP
832 BasePrincipal::GetAsciiSpec(nsACString& aSpec) {
833 aSpec.Truncate();
834 nsCOMPtr<nsIURI> prinURI;
835 nsresult rv = GetURI(getter_AddRefs(prinURI));
836 if (NS_FAILED(rv) || !prinURI) {
837 return NS_OK;
839 return prinURI->GetAsciiSpec(aSpec);
842 NS_IMETHODIMP
843 BasePrincipal::GetSpec(nsACString& aSpec) {
844 aSpec.Truncate();
845 nsCOMPtr<nsIURI> prinURI;
846 nsresult rv = GetURI(getter_AddRefs(prinURI));
847 if (NS_FAILED(rv) || !prinURI) {
848 return NS_OK;
850 return prinURI->GetSpec(aSpec);
853 NS_IMETHODIMP
854 BasePrincipal::GetAsciiHost(nsACString& aHost) {
855 aHost.Truncate();
856 nsCOMPtr<nsIURI> prinURI;
857 nsresult rv = GetURI(getter_AddRefs(prinURI));
858 if (NS_FAILED(rv) || !prinURI) {
859 return NS_OK;
861 return prinURI->GetAsciiHost(aHost);
864 NS_IMETHODIMP
865 BasePrincipal::GetExposablePrePath(nsACString& aPrepath) {
866 aPrepath.Truncate();
867 nsCOMPtr<nsIURI> prinURI;
868 nsresult rv = GetURI(getter_AddRefs(prinURI));
869 if (NS_FAILED(rv) || !prinURI) {
870 return NS_OK;
873 nsCOMPtr<nsIURI> exposableURI = net::nsIOService::CreateExposableURI(prinURI);
874 return exposableURI->GetDisplayPrePath(aPrepath);
877 NS_IMETHODIMP
878 BasePrincipal::GetExposableSpec(nsACString& aSpec) {
879 aSpec.Truncate();
880 nsCOMPtr<nsIURI> prinURI;
881 nsresult rv = GetURI(getter_AddRefs(prinURI));
882 if (NS_FAILED(rv) || !prinURI) {
883 return NS_OK;
885 nsCOMPtr<nsIURI> clone;
886 rv = NS_MutateURI(prinURI)
887 .SetQuery(""_ns)
888 .SetRef(""_ns)
889 .SetUserPass(""_ns)
890 .Finalize(clone);
891 NS_ENSURE_SUCCESS(rv, rv);
892 return clone->GetAsciiSpec(aSpec);
895 NS_IMETHODIMP
896 BasePrincipal::GetPrePath(nsACString& aPath) {
897 aPath.Truncate();
898 nsCOMPtr<nsIURI> prinURI;
899 nsresult rv = GetURI(getter_AddRefs(prinURI));
900 if (NS_FAILED(rv) || !prinURI) {
901 return NS_OK;
903 return prinURI->GetPrePath(aPath);
906 NS_IMETHODIMP
907 BasePrincipal::GetFilePath(nsACString& aPath) {
908 aPath.Truncate();
909 nsCOMPtr<nsIURI> prinURI;
910 nsresult rv = GetURI(getter_AddRefs(prinURI));
911 if (NS_FAILED(rv) || !prinURI) {
912 return NS_OK;
914 return prinURI->GetFilePath(aPath);
917 NS_IMETHODIMP
918 BasePrincipal::GetIsSystemPrincipal(bool* aResult) {
919 *aResult = IsSystemPrincipal();
920 return NS_OK;
923 NS_IMETHODIMP
924 BasePrincipal::GetIsAddonOrExpandedAddonPrincipal(bool* aResult) {
925 *aResult = AddonPolicy() || ContentScriptAddonPolicy();
926 return NS_OK;
929 NS_IMETHODIMP BasePrincipal::GetIsOnion(bool* aIsOnion) {
930 *aIsOnion = false;
931 nsCOMPtr<nsIURI> prinURI;
932 nsresult rv = GetURI(getter_AddRefs(prinURI));
933 if (NS_FAILED(rv) || !prinURI) {
934 return NS_OK;
937 nsAutoCString host;
938 rv = prinURI->GetHost(host);
939 if (NS_FAILED(rv)) {
940 return NS_OK;
942 *aIsOnion = StringEndsWith(host, ".onion"_ns);
943 return NS_OK;
946 NS_IMETHODIMP BasePrincipal::GetIsIpAddress(bool* aIsIpAddress) {
947 *aIsIpAddress = false;
949 nsCOMPtr<nsIURI> prinURI;
950 nsresult rv = GetURI(getter_AddRefs(prinURI));
951 if (NS_FAILED(rv) || !prinURI) {
952 return NS_OK;
955 nsAutoCString host;
956 rv = prinURI->GetHost(host);
957 if (NS_FAILED(rv)) {
958 return NS_OK;
961 PRNetAddr prAddr;
962 memset(&prAddr, 0, sizeof(prAddr));
964 if (PR_StringToNetAddr(host.get(), &prAddr) == PR_SUCCESS) {
965 *aIsIpAddress = true;
968 return NS_OK;
971 NS_IMETHODIMP BasePrincipal::GetIsLocalIpAddress(bool* aIsIpAddress) {
972 *aIsIpAddress = false;
974 nsCOMPtr<nsIURI> prinURI;
975 nsresult rv = GetURI(getter_AddRefs(prinURI));
976 if (NS_FAILED(rv) || !prinURI) {
977 return NS_OK;
980 nsCOMPtr<nsIIOService> ioService = do_GetIOService(&rv);
981 if (NS_FAILED(rv) || !ioService) {
982 return NS_OK;
984 rv = ioService->HostnameIsLocalIPAddress(prinURI, aIsIpAddress);
985 if (NS_FAILED(rv)) {
986 *aIsIpAddress = false;
988 return NS_OK;
991 NS_IMETHODIMP
992 BasePrincipal::GetScheme(nsACString& aScheme) {
993 aScheme.Truncate();
995 nsCOMPtr<nsIURI> prinURI;
996 nsresult rv = GetURI(getter_AddRefs(prinURI));
997 if (NS_FAILED(rv) || !prinURI) {
998 return NS_OK;
1001 return prinURI->GetScheme(aScheme);
1004 NS_IMETHODIMP
1005 BasePrincipal::SchemeIs(const char* aScheme, bool* aResult) {
1006 *aResult = false;
1007 nsCOMPtr<nsIURI> prinURI;
1008 nsresult rv = GetURI(getter_AddRefs(prinURI));
1009 if (NS_WARN_IF(NS_FAILED(rv)) || !prinURI) {
1010 return NS_OK;
1012 *aResult = prinURI->SchemeIs(aScheme);
1013 return NS_OK;
1016 NS_IMETHODIMP
1017 BasePrincipal::IsURIInPrefList(const char* aPref, bool* aResult) {
1018 *aResult = false;
1019 nsCOMPtr<nsIURI> prinURI;
1020 nsresult rv = GetURI(getter_AddRefs(prinURI));
1021 if (NS_FAILED(rv) || !prinURI) {
1022 return NS_OK;
1024 *aResult = nsContentUtils::IsURIInPrefList(prinURI, aPref);
1025 return NS_OK;
1028 NS_IMETHODIMP
1029 BasePrincipal::IsURIInList(const nsACString& aList, bool* aResult) {
1030 *aResult = false;
1031 nsCOMPtr<nsIURI> prinURI;
1033 nsresult rv = GetURI(getter_AddRefs(prinURI));
1034 if (NS_FAILED(rv) || !prinURI) {
1035 return NS_OK;
1038 *aResult = nsContentUtils::IsURIInList(prinURI, nsCString(aList));
1039 return NS_OK;
1042 NS_IMETHODIMP
1043 BasePrincipal::GetIsOriginPotentiallyTrustworthy(bool* aResult) {
1044 MOZ_ASSERT(NS_IsMainThread());
1045 *aResult = false;
1047 nsCOMPtr<nsIURI> uri;
1048 nsresult rv = GetURI(getter_AddRefs(uri));
1049 if (NS_FAILED(rv) || !uri) {
1050 return NS_OK;
1053 *aResult = nsMixedContentBlocker::IsPotentiallyTrustworthyOrigin(uri);
1054 return NS_OK;
1057 NS_IMETHODIMP
1058 BasePrincipal::GetIsLoopbackHost(bool* aRes) {
1059 *aRes = false;
1060 nsAutoCString host;
1061 nsresult rv = GetHost(host);
1062 // Swallow potential failure as this method is infallible.
1063 NS_ENSURE_SUCCESS(rv, NS_OK);
1065 *aRes = nsMixedContentBlocker::IsPotentiallyTrustworthyLoopbackHost(host);
1066 return NS_OK;
1069 NS_IMETHODIMP
1070 BasePrincipal::GetAboutModuleFlags(uint32_t* flags) {
1071 *flags = 0;
1072 nsCOMPtr<nsIURI> prinURI;
1073 nsresult rv = GetURI(getter_AddRefs(prinURI));
1074 if (NS_FAILED(rv) || !prinURI) {
1075 return NS_ERROR_NOT_AVAILABLE;
1077 if (!prinURI->SchemeIs("about")) {
1078 return NS_OK;
1081 nsCOMPtr<nsIAboutModule> aboutModule;
1082 rv = NS_GetAboutModule(prinURI, getter_AddRefs(aboutModule));
1083 if (NS_FAILED(rv) || !aboutModule) {
1084 return rv;
1086 return aboutModule->GetURIFlags(prinURI, flags);
1089 NS_IMETHODIMP
1090 BasePrincipal::GetOriginAttributes(JSContext* aCx,
1091 JS::MutableHandle<JS::Value> aVal) {
1092 if (NS_WARN_IF(!ToJSValue(aCx, mOriginAttributes, aVal))) {
1093 return NS_ERROR_FAILURE;
1095 return NS_OK;
1098 NS_IMETHODIMP
1099 BasePrincipal::GetOriginSuffix(nsACString& aOriginAttributes) {
1100 MOZ_ASSERT(mOriginSuffix);
1101 mOriginSuffix->ToUTF8String(aOriginAttributes);
1102 return NS_OK;
1105 NS_IMETHODIMP
1106 BasePrincipal::GetUserContextId(uint32_t* aUserContextId) {
1107 *aUserContextId = UserContextId();
1108 return NS_OK;
1111 NS_IMETHODIMP
1112 BasePrincipal::GetPrivateBrowsingId(uint32_t* aPrivateBrowsingId) {
1113 *aPrivateBrowsingId = PrivateBrowsingId();
1114 return NS_OK;
1117 NS_IMETHODIMP
1118 BasePrincipal::GetIsInIsolatedMozBrowserElement(
1119 bool* aIsInIsolatedMozBrowserElement) {
1120 *aIsInIsolatedMozBrowserElement = IsInIsolatedMozBrowserElement();
1121 return NS_OK;
1124 nsresult BasePrincipal::GetAddonPolicy(
1125 extensions::WebExtensionPolicy** aResult) {
1126 RefPtr<extensions::WebExtensionPolicy> policy(AddonPolicy());
1127 policy.forget(aResult);
1128 return NS_OK;
1131 extensions::WebExtensionPolicy* BasePrincipal::AddonPolicy() {
1132 if (Is<ContentPrincipal>()) {
1133 return As<ContentPrincipal>()->AddonPolicy();
1135 return nullptr;
1138 bool BasePrincipal::AddonHasPermission(const nsAtom* aPerm) {
1139 if (auto policy = AddonPolicy()) {
1140 return policy->HasPermission(aPerm);
1142 return false;
1145 nsIPrincipal* BasePrincipal::PrincipalToInherit(nsIURI* aRequestedURI) {
1146 if (Is<ExpandedPrincipal>()) {
1147 return As<ExpandedPrincipal>()->PrincipalToInherit(aRequestedURI);
1149 return this;
1152 already_AddRefed<BasePrincipal> BasePrincipal::CreateContentPrincipal(
1153 nsIURI* aURI, const OriginAttributes& aAttrs) {
1154 MOZ_ASSERT(aURI);
1156 nsAutoCString originNoSuffix;
1157 nsresult rv =
1158 ContentPrincipal::GenerateOriginNoSuffixFromURI(aURI, originNoSuffix);
1159 if (NS_FAILED(rv)) {
1160 // If the generation of the origin fails, we still want to have a valid
1161 // principal. Better to return a null principal here.
1162 return NullPrincipal::Create(aAttrs);
1165 return CreateContentPrincipal(aURI, aAttrs, originNoSuffix);
1168 already_AddRefed<BasePrincipal> BasePrincipal::CreateContentPrincipal(
1169 nsIURI* aURI, const OriginAttributes& aAttrs,
1170 const nsACString& aOriginNoSuffix) {
1171 MOZ_ASSERT(aURI);
1172 MOZ_ASSERT(!aOriginNoSuffix.IsEmpty());
1174 // If the URI is supposed to inherit the security context of whoever loads it,
1175 // we shouldn't make a content principal for it.
1176 bool inheritsPrincipal;
1177 nsresult rv = NS_URIChainHasFlags(
1178 aURI, nsIProtocolHandler::URI_INHERITS_SECURITY_CONTEXT,
1179 &inheritsPrincipal);
1180 if (NS_FAILED(rv) || inheritsPrincipal) {
1181 return NullPrincipal::Create(aAttrs);
1184 // Check whether the URI knows what its principal is supposed to be.
1185 #if defined(MOZ_THUNDERBIRD) || defined(MOZ_SUITE)
1186 nsCOMPtr<nsIURIWithSpecialOrigin> uriWithSpecialOrigin =
1187 do_QueryInterface(aURI);
1188 if (uriWithSpecialOrigin) {
1189 nsCOMPtr<nsIURI> origin;
1190 rv = uriWithSpecialOrigin->GetOrigin(getter_AddRefs(origin));
1191 if (NS_WARN_IF(NS_FAILED(rv))) {
1192 return nullptr;
1194 MOZ_ASSERT(origin);
1195 OriginAttributes attrs;
1196 RefPtr<BasePrincipal> principal = CreateContentPrincipal(origin, attrs);
1197 return principal.forget();
1199 #endif
1201 nsCOMPtr<nsIPrincipal> blobPrincipal;
1202 if (dom::BlobURLProtocolHandler::GetBlobURLPrincipal(
1203 aURI, getter_AddRefs(blobPrincipal))) {
1204 MOZ_ASSERT(blobPrincipal);
1205 RefPtr<BasePrincipal> principal = Cast(blobPrincipal);
1206 return principal.forget();
1209 // Mint a content principal.
1210 RefPtr<ContentPrincipal> principal =
1211 new ContentPrincipal(aURI, aAttrs, aOriginNoSuffix);
1212 return principal.forget();
1215 already_AddRefed<BasePrincipal> BasePrincipal::CreateContentPrincipal(
1216 const nsACString& aOrigin) {
1217 MOZ_ASSERT(!StringBeginsWith(aOrigin, "["_ns),
1218 "CreateContentPrincipal does not support System and Expanded "
1219 "principals");
1221 MOZ_ASSERT(
1222 !StringBeginsWith(aOrigin, nsLiteralCString(NS_NULLPRINCIPAL_SCHEME ":")),
1223 "CreateContentPrincipal does not support NullPrincipal");
1225 nsAutoCString originNoSuffix;
1226 OriginAttributes attrs;
1227 if (!attrs.PopulateFromOrigin(aOrigin, originNoSuffix)) {
1228 return nullptr;
1231 nsCOMPtr<nsIURI> uri;
1232 nsresult rv = NS_NewURI(getter_AddRefs(uri), originNoSuffix);
1233 NS_ENSURE_SUCCESS(rv, nullptr);
1235 return BasePrincipal::CreateContentPrincipal(uri, attrs);
1238 already_AddRefed<BasePrincipal> BasePrincipal::CloneForcingOriginAttributes(
1239 const OriginAttributes& aOriginAttributes) {
1240 if (NS_WARN_IF(!IsContentPrincipal())) {
1241 return nullptr;
1244 nsAutoCString originNoSuffix;
1245 nsresult rv = GetOriginNoSuffix(originNoSuffix);
1246 NS_ENSURE_SUCCESS(rv, nullptr);
1248 nsCOMPtr<nsIURI> uri;
1249 MOZ_ALWAYS_SUCCEEDS(GetURI(getter_AddRefs(uri)));
1251 RefPtr<ContentPrincipal> copy =
1252 new ContentPrincipal(uri, aOriginAttributes, originNoSuffix);
1253 return copy.forget();
1256 extensions::WebExtensionPolicy* BasePrincipal::ContentScriptAddonPolicy() {
1257 if (!Is<ExpandedPrincipal>()) {
1258 return nullptr;
1261 auto expanded = As<ExpandedPrincipal>();
1262 for (auto& prin : expanded->AllowList()) {
1263 if (auto policy = BasePrincipal::Cast(prin)->AddonPolicy()) {
1264 return policy;
1268 return nullptr;
1271 bool BasePrincipal::AddonAllowsLoad(nsIURI* aURI,
1272 bool aExplicit /* = false */) {
1273 if (Is<ExpandedPrincipal>()) {
1274 return As<ExpandedPrincipal>()->AddonAllowsLoad(aURI, aExplicit);
1276 if (auto policy = AddonPolicy()) {
1277 return policy->CanAccessURI(aURI, aExplicit);
1279 return false;
1282 NS_IMETHODIMP
1283 BasePrincipal::GetLocalStorageQuotaKey(nsACString& aKey) {
1284 aKey.Truncate();
1286 nsCOMPtr<nsIURI> uri;
1287 nsresult rv = GetURI(getter_AddRefs(uri));
1288 NS_ENSURE_SUCCESS(rv, rv);
1289 NS_ENSURE_TRUE(uri, NS_ERROR_UNEXPECTED);
1291 // The special handling of the file scheme should be consistent with
1292 // GetStorageOriginKey.
1294 nsAutoCString baseDomain;
1295 rv = uri->GetAsciiHost(baseDomain);
1296 NS_ENSURE_SUCCESS(rv, rv);
1298 if (baseDomain.IsEmpty() && uri->SchemeIs("file")) {
1299 nsCOMPtr<nsIURL> url = do_QueryInterface(uri, &rv);
1300 NS_ENSURE_SUCCESS(rv, rv);
1302 rv = url->GetDirectory(baseDomain);
1303 NS_ENSURE_SUCCESS(rv, rv);
1304 } else {
1305 nsCOMPtr<nsIEffectiveTLDService> eTLDService(
1306 do_GetService(NS_EFFECTIVETLDSERVICE_CONTRACTID, &rv));
1307 NS_ENSURE_SUCCESS(rv, rv);
1309 nsAutoCString eTLDplusOne;
1310 rv = eTLDService->GetBaseDomain(uri, 0, eTLDplusOne);
1311 if (NS_SUCCEEDED(rv)) {
1312 baseDomain = eTLDplusOne;
1313 } else if (rv == NS_ERROR_HOST_IS_IP_ADDRESS ||
1314 rv == NS_ERROR_INSUFFICIENT_DOMAIN_LEVELS) {
1315 rv = NS_OK;
1317 NS_ENSURE_SUCCESS(rv, rv);
1320 OriginAttributesRef().CreateSuffix(aKey);
1322 nsAutoCString subdomainsDBKey;
1323 rv = dom::StorageUtils::CreateReversedDomain(baseDomain, subdomainsDBKey);
1324 NS_ENSURE_SUCCESS(rv, rv);
1326 aKey.Append(':');
1327 aKey.Append(subdomainsDBKey);
1329 return NS_OK;
1332 NS_IMETHODIMP
1333 BasePrincipal::GetNextSubDomainPrincipal(
1334 nsIPrincipal** aNextSubDomainPrincipal) {
1335 nsCOMPtr<nsIURI> uri;
1336 nsresult rv = GetURI(getter_AddRefs(uri));
1337 if (NS_FAILED(rv) || !uri) {
1338 return NS_OK;
1341 nsAutoCString host;
1342 rv = uri->GetHost(host);
1343 if (NS_FAILED(rv) || host.IsEmpty()) {
1344 return NS_OK;
1347 nsCString subDomain;
1348 rv = nsEffectiveTLDService::GetInstance()->GetNextSubDomain(host, subDomain);
1350 if (NS_FAILED(rv) || subDomain.IsEmpty()) {
1351 return NS_OK;
1354 nsCOMPtr<nsIURI> subDomainURI;
1355 rv = NS_MutateURI(uri).SetHost(subDomain).Finalize(subDomainURI);
1356 if (NS_FAILED(rv) || !subDomainURI) {
1357 return NS_OK;
1359 // Copy the attributes over
1360 mozilla::OriginAttributes attrs = OriginAttributesRef();
1362 if (!StaticPrefs::permissions_isolateBy_userContext()) {
1363 // Disable userContext for permissions.
1364 attrs.StripAttributes(mozilla::OriginAttributes::STRIP_USER_CONTEXT_ID);
1366 RefPtr<nsIPrincipal> principal =
1367 mozilla::BasePrincipal::CreateContentPrincipal(subDomainURI, attrs);
1369 if (!principal) {
1370 return NS_OK;
1372 principal.forget(aNextSubDomainPrincipal);
1373 return NS_OK;
1376 NS_IMETHODIMP
1377 BasePrincipal::GetStorageOriginKey(nsACString& aOriginKey) {
1378 aOriginKey.Truncate();
1380 nsCOMPtr<nsIURI> uri;
1381 nsresult rv = GetURI(getter_AddRefs(uri));
1382 NS_ENSURE_SUCCESS(rv, rv);
1383 NS_ENSURE_TRUE(uri, NS_ERROR_UNEXPECTED);
1385 // The special handling of the file scheme should be consistent with
1386 // GetLocalStorageQuotaKey.
1388 nsAutoCString domainOrigin;
1389 rv = uri->GetAsciiHost(domainOrigin);
1390 NS_ENSURE_SUCCESS(rv, rv);
1392 if (domainOrigin.IsEmpty()) {
1393 // For the file:/// protocol use the exact directory as domain.
1394 if (uri->SchemeIs("file")) {
1395 nsCOMPtr<nsIURL> url = do_QueryInterface(uri, &rv);
1396 NS_ENSURE_SUCCESS(rv, rv);
1397 rv = url->GetDirectory(domainOrigin);
1398 NS_ENSURE_SUCCESS(rv, rv);
1402 // Append reversed domain
1403 nsAutoCString reverseDomain;
1404 rv = dom::StorageUtils::CreateReversedDomain(domainOrigin, reverseDomain);
1405 NS_ENSURE_SUCCESS(rv, rv);
1407 aOriginKey.Append(reverseDomain);
1409 // Append scheme
1410 nsAutoCString scheme;
1411 rv = uri->GetScheme(scheme);
1412 NS_ENSURE_SUCCESS(rv, rv);
1414 aOriginKey.Append(':');
1415 aOriginKey.Append(scheme);
1417 // Append port if any
1418 int32_t port = NS_GetRealPort(uri);
1419 if (port != -1) {
1420 aOriginKey.Append(nsPrintfCString(":%d", port));
1423 return NS_OK;
1426 NS_IMETHODIMP
1427 BasePrincipal::GetIsScriptAllowedByPolicy(bool* aIsScriptAllowedByPolicy) {
1428 *aIsScriptAllowedByPolicy = false;
1429 nsCOMPtr<nsIURI> prinURI;
1430 nsresult rv = GetURI(getter_AddRefs(prinURI));
1431 if (NS_FAILED(rv) || !prinURI) {
1432 return NS_OK;
1434 nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
1435 if (!ssm) {
1436 return NS_ERROR_UNEXPECTED;
1438 return ssm->PolicyAllowsScript(prinURI, aIsScriptAllowedByPolicy);
1441 bool SiteIdentifier::Equals(const SiteIdentifier& aOther) const {
1442 MOZ_ASSERT(IsInitialized());
1443 MOZ_ASSERT(aOther.IsInitialized());
1444 return mPrincipal->FastEquals(aOther.mPrincipal);
1447 NS_IMETHODIMP
1448 BasePrincipal::CreateReferrerInfo(mozilla::dom::ReferrerPolicy aReferrerPolicy,
1449 nsIReferrerInfo** _retval) {
1450 nsCOMPtr<nsIURI> prinURI;
1451 RefPtr<dom::ReferrerInfo> info;
1452 nsresult rv = GetURI(getter_AddRefs(prinURI));
1453 if (NS_FAILED(rv) || !prinURI) {
1454 info = new dom::ReferrerInfo(nullptr);
1455 info.forget(_retval);
1456 return NS_OK;
1458 info = new dom::ReferrerInfo(prinURI, aReferrerPolicy);
1459 info.forget(_retval);
1460 return NS_OK;
1463 NS_IMETHODIMP
1464 BasePrincipal::GetPrecursorPrincipal(nsIPrincipal** aPrecursor) {
1465 *aPrecursor = nullptr;
1466 return NS_OK;
1469 NS_IMPL_ADDREF(BasePrincipal::Deserializer)
1470 NS_IMPL_RELEASE(BasePrincipal::Deserializer)
1472 NS_INTERFACE_MAP_BEGIN(BasePrincipal::Deserializer)
1473 NS_INTERFACE_MAP_ENTRY(nsISupports)
1474 NS_INTERFACE_MAP_ENTRY(nsISerializable)
1475 if (mPrincipal) {
1476 return mPrincipal->QueryInterface(aIID, aInstancePtr);
1477 } else
1478 NS_INTERFACE_MAP_END
1480 NS_IMETHODIMP
1481 BasePrincipal::Deserializer::Write(nsIObjectOutputStream* aStream) {
1482 // Read is used still for legacy principals
1483 MOZ_RELEASE_ASSERT(false, "Old style serialization is removed");
1484 return NS_OK;
1487 } // namespace mozilla