Bug 1755924 [wpt PR 32876] - Handle resumed blocks that get sliced by floats correctl...
[gecko.git] / caps / BasePrincipal.cpp
blob6a03b541ece3a9eb1fed5fdfd8b20807e1c2dc9e
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 "nsMixedContentBlocker.h"
36 #include "prnetdb.h"
37 #include "nsIURIFixup.h"
38 #include "mozilla/dom/StorageUtils.h"
39 #include "mozilla/ContentBlocking.h"
40 #include "nsPIDOMWindow.h"
41 #include "nsIURIMutator.h"
42 #include "mozilla/PermissionManager.h"
44 #include "json/json.h"
45 #include "nsSerializationHelper.h"
47 namespace mozilla {
49 BasePrincipal::BasePrincipal(PrincipalKind aKind,
50 const nsACString& aOriginNoSuffix,
51 const OriginAttributes& aOriginAttributes)
52 : mOriginNoSuffix(NS_Atomize(aOriginNoSuffix)),
53 mOriginSuffix(aOriginAttributes.CreateSuffixAtom()),
54 mOriginAttributes(aOriginAttributes),
55 mKind(aKind),
56 mHasExplicitDomain(false) {}
58 BasePrincipal::BasePrincipal(BasePrincipal* aOther,
59 const OriginAttributes& aOriginAttributes)
60 : mOriginNoSuffix(aOther->mOriginNoSuffix),
61 mOriginSuffix(aOriginAttributes.CreateSuffixAtom()),
62 mOriginAttributes(aOriginAttributes),
63 mKind(aOther->mKind),
64 mHasExplicitDomain(aOther->mHasExplicitDomain) {}
66 BasePrincipal::~BasePrincipal() = default;
68 NS_IMETHODIMP
69 BasePrincipal::GetOrigin(nsACString& aOrigin) {
70 nsresult rv = GetOriginNoSuffix(aOrigin);
71 NS_ENSURE_SUCCESS(rv, rv);
73 nsAutoCString suffix;
74 rv = GetOriginSuffix(suffix);
75 NS_ENSURE_SUCCESS(rv, rv);
76 aOrigin.Append(suffix);
77 return NS_OK;
80 NS_IMETHODIMP
81 BasePrincipal::GetAsciiOrigin(nsACString& aOrigin) {
82 aOrigin.Truncate();
83 nsCOMPtr<nsIURI> prinURI;
84 nsresult rv = GetURI(getter_AddRefs(prinURI));
85 if (NS_FAILED(rv) || !prinURI) {
86 return NS_ERROR_NOT_AVAILABLE;
88 return nsContentUtils::GetASCIIOrigin(prinURI, aOrigin);
91 NS_IMETHODIMP
92 BasePrincipal::GetHostPort(nsACString& aRes) {
93 aRes.Truncate();
94 nsCOMPtr<nsIURI> prinURI;
95 nsresult rv = GetURI(getter_AddRefs(prinURI));
96 if (NS_FAILED(rv) || !prinURI) {
97 return NS_OK;
99 return prinURI->GetHostPort(aRes);
102 NS_IMETHODIMP
103 BasePrincipal::GetHost(nsACString& aRes) {
104 aRes.Truncate();
105 nsCOMPtr<nsIURI> prinURI;
106 nsresult rv = GetURI(getter_AddRefs(prinURI));
107 if (NS_FAILED(rv) || !prinURI) {
108 return NS_OK;
110 return prinURI->GetHost(aRes);
113 NS_IMETHODIMP
114 BasePrincipal::GetOriginNoSuffix(nsACString& aOrigin) {
115 mOriginNoSuffix->ToUTF8String(aOrigin);
116 return NS_OK;
119 NS_IMETHODIMP
120 BasePrincipal::GetSiteOrigin(nsACString& aSiteOrigin) {
121 nsresult rv = GetSiteOriginNoSuffix(aSiteOrigin);
122 NS_ENSURE_SUCCESS(rv, rv);
124 nsAutoCString suffix;
125 rv = GetOriginSuffix(suffix);
126 NS_ENSURE_SUCCESS(rv, rv);
127 aSiteOrigin.Append(suffix);
128 return NS_OK;
131 NS_IMETHODIMP
132 BasePrincipal::GetSiteOriginNoSuffix(nsACString& aSiteOrigin) {
133 return GetOriginNoSuffix(aSiteOrigin);
136 // Returns the inner Json::value of the serialized principal
137 // Example input and return values:
138 // Null principal:
139 // {"0":{"0":"moz-nullprincipal:{56cac540-864d-47e7-8e25-1614eab5155e}"}} ->
140 // {"0":"moz-nullprincipal:{56cac540-864d-47e7-8e25-1614eab5155e}"}
142 // Content principal:
143 // {"1":{"0":"https://mozilla.com"}} -> {"0":"https://mozilla.com"}
145 // Expanded principal:
146 // {"2":{"0":"<base64principal1>,<base64principal2>"}} ->
147 // {"0":"<base64principal1>,<base64principal2>"}
149 // System principal:
150 // {"3":{}} -> {}
151 // The aKey passed in also returns the corresponding PrincipalKind enum
153 // Warning: The Json::Value* pointer is into the aRoot object
154 static const Json::Value* GetPrincipalObject(const Json::Value& aRoot,
155 int& aOutPrincipalKind) {
156 const Json::Value::Members members = aRoot.getMemberNames();
157 // We only support one top level key in the object
158 if (members.size() != 1) {
159 return nullptr;
161 // members[0] here is the "0", "1", "2", "3" principalKind
162 // that is the top level of the serialized JSON principal
163 const std::string stringPrincipalKind = members[0];
165 // Next we take the string value from the JSON
166 // and convert it into the int for the BasePrincipal::PrincipalKind enum
168 // Verify that the key is within the valid range
169 int principalKind = std::stoi(stringPrincipalKind);
170 MOZ_ASSERT(BasePrincipal::eNullPrincipal == 0,
171 "We need to rely on 0 being a bounds check for the first "
172 "principal kind.");
173 if (principalKind < 0 || principalKind > BasePrincipal::eKindMax) {
174 return nullptr;
176 MOZ_ASSERT(principalKind == BasePrincipal::eNullPrincipal ||
177 principalKind == BasePrincipal::eContentPrincipal ||
178 principalKind == BasePrincipal::eExpandedPrincipal ||
179 principalKind == BasePrincipal::eSystemPrincipal);
180 aOutPrincipalKind = principalKind;
182 if (!aRoot[stringPrincipalKind].isObject()) {
183 return nullptr;
186 // Return the inner value of the principal object
187 return &aRoot[stringPrincipalKind];
190 // Accepts the JSON inner object without the wrapping principalKind
191 // (See GetPrincipalObject for the inner object response examples)
192 // Creates an array of KeyVal objects that are all defined on the principal
193 // Each principal type (null, content, expanded) has a KeyVal that stores the
194 // fields of the JSON
196 // This simplifies deserializing elsewhere as we do the checking for presence
197 // and string values here for the complete set of serializable keys that the
198 // corresponding principal supports.
200 // The KeyVal object has the following fields:
201 // - valueWasSerialized: is true if the deserialized JSON contained a string
202 // value
203 // - value: The string that was serialized for this key
204 // - key: an SerializableKeys enum value specific to the principal.
205 // For example content principal is an enum of: eURI, eDomain,
206 // eSuffix, eCSP
209 // Given an inner content principal:
210 // {"0": "https://mozilla.com", "2": "^privateBrowsingId=1"}
211 // | | | |
212 // ----------------------------- |
213 // | | |
214 // Key ----------------------
215 // |
216 // Value
218 // They Key "0" corresponds to ContentPrincipal::eURI
219 // They Key "1" corresponds to ContentPrincipal::eSuffix
220 template <typename T>
221 static nsTArray<typename T::KeyVal> GetJSONKeys(const Json::Value* aInput) {
222 int size = T::eMax + 1;
223 nsTArray<typename T::KeyVal> fields;
224 for (int i = 0; i != size; i++) {
225 typename T::KeyVal* field = fields.AppendElement();
226 // field->valueWasSerialized returns if the field was found in the
227 // deserialized code. This simplifies the consumers from having to check
228 // length.
229 field->valueWasSerialized = false;
230 field->key = static_cast<typename T::SerializableKeys>(i);
231 const std::string key = std::to_string(field->key);
232 if (aInput->isMember(key)) {
233 const Json::Value& val = (*aInput)[key];
234 if (val.isString()) {
235 field->value.Append(nsDependentCString(val.asCString()));
236 field->valueWasSerialized = true;
240 return fields;
243 // Takes a JSON string and parses it turning it into a principal of the
244 // corresponding type
246 // Given a content principal:
248 // inner JSON object
249 // |
250 // ---------------------------------------------------------
251 // | |
252 // {"1": {"0": "https://mozilla.com", "2": "^privateBrowsingId=1"}}
253 // | | | | |
254 // | ----------------------------- |
255 // | | | |
256 // PrincipalKind | | |
257 // | ----------------------------
258 // SerializableKeys |
259 // Value
261 // The string is first deserialized with jsoncpp to get the Json::Value of the
262 // object. The inner JSON object is parsed with GetPrincipalObject which returns
263 // a KeyVal array of the inner object's fields. PrincipalKind is returned by
264 // GetPrincipalObject which is then used to decide which principal
265 // implementation of FromProperties to call. The corresponding FromProperties
266 // call takes the KeyVal fields and turns it into a principal.
267 already_AddRefed<BasePrincipal> BasePrincipal::FromJSON(
268 const nsACString& aJSON) {
269 Json::Value root;
270 Json::CharReaderBuilder builder;
271 std::unique_ptr<Json::CharReader> const reader(builder.newCharReader());
272 bool parseSuccess =
273 reader->parse(aJSON.BeginReading(), aJSON.EndReading(), &root, nullptr);
274 if (!parseSuccess) {
275 MOZ_ASSERT(false,
276 "Unable to parse string as JSON to deserialize as a principal");
277 return nullptr;
280 int principalKind = -1;
281 const Json::Value* value = GetPrincipalObject(root, principalKind);
282 if (!value) {
283 #ifdef DEBUG
284 fprintf(stderr, "Unexpected JSON principal %s\n",
285 root.toStyledString().c_str());
286 #endif
287 MOZ_ASSERT(false, "Unexpected JSON to deserialize as a principal");
289 return nullptr;
291 MOZ_ASSERT(principalKind != -1,
292 "PrincipalKind should always be >=0 by this point");
294 if (principalKind == eSystemPrincipal) {
295 RefPtr<BasePrincipal> principal =
296 BasePrincipal::Cast(nsContentUtils::GetSystemPrincipal());
297 return principal.forget();
300 if (principalKind == eNullPrincipal) {
301 nsTArray<NullPrincipal::KeyVal> res = GetJSONKeys<NullPrincipal>(value);
302 return NullPrincipal::FromProperties(res);
305 if (principalKind == eContentPrincipal) {
306 nsTArray<ContentPrincipal::KeyVal> res =
307 GetJSONKeys<ContentPrincipal>(value);
308 return ContentPrincipal::FromProperties(res);
311 if (principalKind == eExpandedPrincipal) {
312 nsTArray<ExpandedPrincipal::KeyVal> res =
313 GetJSONKeys<ExpandedPrincipal>(value);
314 return ExpandedPrincipal::FromProperties(res);
317 MOZ_RELEASE_ASSERT(false, "Unexpected enum to deserialize as a principal");
320 nsresult BasePrincipal::PopulateJSONObject(Json::Value& aObject) {
321 return NS_OK;
324 // Returns a JSON representation of the principal.
325 // Calling BasePrincipal::FromJSON will deserialize the JSON into
326 // the corresponding principal type.
327 nsresult BasePrincipal::ToJSON(nsACString& aResult) {
328 MOZ_ASSERT(aResult.IsEmpty(), "ToJSON only supports an empty result input");
329 aResult.Truncate();
331 Json::StreamWriterBuilder builder;
332 builder["indentation"] = "";
333 Json::Value innerJSONObject = Json::objectValue;
335 nsresult rv = PopulateJSONObject(innerJSONObject);
336 NS_ENSURE_SUCCESS(rv, rv);
338 Json::Value root = Json::objectValue;
339 std::string key = std::to_string(Kind());
340 root[key] = innerJSONObject;
341 std::string result = Json::writeString(builder, root);
342 aResult.Append(result);
343 if (aResult.Length() == 0) {
344 MOZ_ASSERT(false, "JSON writer failed to output a principal serialization");
345 return NS_ERROR_UNEXPECTED;
347 return NS_OK;
350 bool BasePrincipal::FastSubsumesIgnoringFPD(
351 nsIPrincipal* aOther, DocumentDomainConsideration aConsideration) {
352 MOZ_ASSERT(aOther);
354 if (Kind() == eContentPrincipal &&
355 !dom::ChromeUtils::IsOriginAttributesEqualIgnoringFPD(
356 mOriginAttributes, Cast(aOther)->mOriginAttributes)) {
357 return false;
360 return SubsumesInternal(aOther, aConsideration);
363 bool BasePrincipal::Subsumes(nsIPrincipal* aOther,
364 DocumentDomainConsideration aConsideration) {
365 MOZ_ASSERT(aOther);
366 MOZ_ASSERT_IF(Kind() == eContentPrincipal, mOriginSuffix);
368 // Expanded principals handle origin attributes for each of their
369 // sub-principals individually, null principals do only simple checks for
370 // pointer equality, and system principals are immune to origin attributes
371 // checks, so only do this check for content principals.
372 if (Kind() == eContentPrincipal &&
373 mOriginSuffix != Cast(aOther)->mOriginSuffix) {
374 return false;
377 return SubsumesInternal(aOther, aConsideration);
380 NS_IMETHODIMP
381 BasePrincipal::Equals(nsIPrincipal* aOther, bool* aResult) {
382 NS_ENSURE_ARG_POINTER(aOther);
384 *aResult = FastEquals(aOther);
386 return NS_OK;
389 NS_IMETHODIMP
390 BasePrincipal::EqualsForPermission(nsIPrincipal* aOther, bool aExactHost,
391 bool* aResult) {
392 *aResult = false;
393 NS_ENSURE_ARG_POINTER(aOther);
394 NS_ENSURE_ARG_POINTER(aResult);
396 auto* other = Cast(aOther);
397 if (Kind() != other->Kind()) {
398 // Principals of different kinds can't be equal.
399 return NS_OK;
402 if (Kind() == eSystemPrincipal) {
403 *aResult = this == other;
404 return NS_OK;
407 if (Kind() == eNullPrincipal) {
408 // We don't store permissions for NullPrincipals.
409 return NS_OK;
412 MOZ_ASSERT(Kind() == eExpandedPrincipal || Kind() == eContentPrincipal);
414 // Certain origin attributes should not be used to isolate permissions.
415 // Create a stripped copy of both OA sets to compare.
416 mozilla::OriginAttributes ourAttrs = mOriginAttributes;
417 PermissionManager::MaybeStripOriginAttributes(false, ourAttrs);
418 mozilla::OriginAttributes theirAttrs = aOther->OriginAttributesRef();
419 PermissionManager::MaybeStripOriginAttributes(false, theirAttrs);
421 if (ourAttrs != theirAttrs) {
422 return NS_OK;
425 if (mOriginNoSuffix == other->mOriginNoSuffix) {
426 *aResult = true;
427 return NS_OK;
430 // If we are matching with an exact host, we're done now - the permissions
431 // don't match otherwise, we need to start comparing subdomains!
432 if (aExactHost) {
433 return NS_OK;
436 nsCOMPtr<nsIURI> ourURI;
437 nsresult rv = GetURI(getter_AddRefs(ourURI));
438 NS_ENSURE_SUCCESS(rv, rv);
439 // Some principal types may indicate success, but still return nullptr for
440 // URI.
441 NS_ENSURE_TRUE(ourURI, NS_ERROR_FAILURE);
443 nsCOMPtr<nsIURI> otherURI;
444 rv = other->GetURI(getter_AddRefs(otherURI));
445 NS_ENSURE_SUCCESS(rv, rv);
446 NS_ENSURE_TRUE(otherURI, NS_ERROR_FAILURE);
448 // Compare schemes
449 nsAutoCString otherScheme;
450 rv = otherURI->GetScheme(otherScheme);
451 NS_ENSURE_SUCCESS(rv, rv);
453 nsAutoCString ourScheme;
454 rv = ourURI->GetScheme(ourScheme);
455 NS_ENSURE_SUCCESS(rv, rv);
457 if (otherScheme != ourScheme) {
458 return NS_OK;
461 // Compare ports
462 int32_t otherPort;
463 rv = otherURI->GetPort(&otherPort);
464 NS_ENSURE_SUCCESS(rv, rv);
466 int32_t ourPort;
467 rv = ourURI->GetPort(&ourPort);
468 NS_ENSURE_SUCCESS(rv, rv);
470 if (otherPort != ourPort) {
471 return NS_OK;
474 // Check if the host or any subdomain of their host matches.
475 nsAutoCString otherHost;
476 rv = otherURI->GetHost(otherHost);
477 if (NS_FAILED(rv) || otherHost.IsEmpty()) {
478 return NS_OK;
481 nsAutoCString ourHost;
482 rv = ourURI->GetHost(ourHost);
483 if (NS_FAILED(rv) || ourHost.IsEmpty()) {
484 return NS_OK;
487 nsCOMPtr<nsIEffectiveTLDService> tldService =
488 do_GetService(NS_EFFECTIVETLDSERVICE_CONTRACTID);
489 if (!tldService) {
490 NS_ERROR("Should have a tld service!");
491 return NS_ERROR_FAILURE;
494 // This loop will not loop forever, as GetNextSubDomain will eventually fail
495 // with NS_ERROR_INSUFFICIENT_DOMAIN_LEVELS.
496 while (otherHost != ourHost) {
497 rv = tldService->GetNextSubDomain(otherHost, otherHost);
498 if (NS_FAILED(rv)) {
499 if (rv == NS_ERROR_INSUFFICIENT_DOMAIN_LEVELS) {
500 return NS_OK;
502 return rv;
506 *aResult = true;
507 return NS_OK;
510 NS_IMETHODIMP
511 BasePrincipal::EqualsConsideringDomain(nsIPrincipal* aOther, bool* aResult) {
512 NS_ENSURE_ARG_POINTER(aOther);
514 *aResult = FastEqualsConsideringDomain(aOther);
516 return NS_OK;
519 NS_IMETHODIMP
520 BasePrincipal::EqualsURI(nsIURI* aOtherURI, bool* aResult) {
521 *aResult = false;
522 nsCOMPtr<nsIURI> prinURI;
523 nsresult rv = GetURI(getter_AddRefs(prinURI));
524 if (NS_FAILED(rv) || !prinURI) {
525 return NS_OK;
527 return prinURI->EqualsExceptRef(aOtherURI, aResult);
530 NS_IMETHODIMP
531 BasePrincipal::Subsumes(nsIPrincipal* aOther, bool* aResult) {
532 NS_ENSURE_ARG_POINTER(aOther);
534 *aResult = FastSubsumes(aOther);
536 return NS_OK;
539 NS_IMETHODIMP
540 BasePrincipal::SubsumesConsideringDomain(nsIPrincipal* aOther, bool* aResult) {
541 NS_ENSURE_ARG_POINTER(aOther);
543 *aResult = FastSubsumesConsideringDomain(aOther);
545 return NS_OK;
548 NS_IMETHODIMP
549 BasePrincipal::SubsumesConsideringDomainIgnoringFPD(nsIPrincipal* aOther,
550 bool* aResult) {
551 NS_ENSURE_ARG_POINTER(aOther);
553 *aResult = FastSubsumesConsideringDomainIgnoringFPD(aOther);
555 return NS_OK;
558 NS_IMETHODIMP
559 BasePrincipal::CheckMayLoad(nsIURI* aURI, bool aAllowIfInheritsPrincipal) {
560 return CheckMayLoadHelper(aURI, aAllowIfInheritsPrincipal, false, 0);
563 NS_IMETHODIMP
564 BasePrincipal::CheckMayLoadWithReporting(nsIURI* aURI,
565 bool aAllowIfInheritsPrincipal,
566 uint64_t aInnerWindowID) {
567 return CheckMayLoadHelper(aURI, aAllowIfInheritsPrincipal, true,
568 aInnerWindowID);
571 nsresult BasePrincipal::CheckMayLoadHelper(nsIURI* aURI,
572 bool aAllowIfInheritsPrincipal,
573 bool aReport,
574 uint64_t aInnerWindowID) {
575 NS_ENSURE_ARG_POINTER(aURI);
576 MOZ_ASSERT(
577 aReport || aInnerWindowID == 0,
578 "Why do we have an inner window id if we're not supposed to report?");
580 // Check the internal method first, which allows us to quickly approve loads
581 // for the System Principal.
582 if (MayLoadInternal(aURI)) {
583 return NS_OK;
586 nsresult rv;
587 if (aAllowIfInheritsPrincipal) {
588 // If the caller specified to allow loads of URIs that inherit
589 // our principal, allow the load if this URI inherits its principal.
590 bool doesInheritSecurityContext;
591 rv = NS_URIChainHasFlags(aURI,
592 nsIProtocolHandler::URI_INHERITS_SECURITY_CONTEXT,
593 &doesInheritSecurityContext);
594 if (NS_SUCCEEDED(rv) && doesInheritSecurityContext) {
595 return NS_OK;
599 bool fetchableByAnyone;
600 rv = NS_URIChainHasFlags(aURI, nsIProtocolHandler::URI_FETCHABLE_BY_ANYONE,
601 &fetchableByAnyone);
602 if (NS_SUCCEEDED(rv) && fetchableByAnyone) {
603 return NS_OK;
606 if (aReport) {
607 nsCOMPtr<nsIURI> prinURI;
608 rv = GetURI(getter_AddRefs(prinURI));
609 if (NS_SUCCEEDED(rv) && prinURI) {
610 nsScriptSecurityManager::ReportError(
611 "CheckSameOriginError", prinURI, aURI,
612 mOriginAttributes.mPrivateBrowsingId > 0, aInnerWindowID);
616 return NS_ERROR_DOM_BAD_URI;
619 NS_IMETHODIMP
620 BasePrincipal::IsThirdPartyURI(nsIURI* aURI, bool* aRes) {
621 if (IsSystemPrincipal() || (AddonPolicy() && AddonAllowsLoad(aURI))) {
622 *aRes = false;
623 return NS_OK;
626 *aRes = true;
627 // If we do not have a URI its always 3rd party.
628 nsCOMPtr<nsIURI> prinURI;
629 nsresult rv = GetURI(getter_AddRefs(prinURI));
630 if (NS_FAILED(rv) || !prinURI) {
631 return NS_OK;
633 ThirdPartyUtil* thirdPartyUtil = ThirdPartyUtil::GetInstance();
634 return thirdPartyUtil->IsThirdPartyURI(prinURI, aURI, aRes);
637 NS_IMETHODIMP
638 BasePrincipal::IsThirdPartyPrincipal(nsIPrincipal* aPrin, bool* aRes) {
639 *aRes = true;
640 nsCOMPtr<nsIURI> prinURI;
641 nsresult rv = GetURI(getter_AddRefs(prinURI));
642 if (NS_FAILED(rv) || !prinURI) {
643 return NS_OK;
645 return aPrin->IsThirdPartyURI(prinURI, aRes);
647 NS_IMETHODIMP
648 BasePrincipal::IsThirdPartyChannel(nsIChannel* aChan, bool* aRes) {
649 if (IsSystemPrincipal()) {
650 // Nothing is 3rd party to the system principal.
651 *aRes = false;
652 return NS_OK;
655 nsCOMPtr<nsIURI> prinURI;
656 GetURI(getter_AddRefs(prinURI));
657 ThirdPartyUtil* thirdPartyUtil = ThirdPartyUtil::GetInstance();
658 return thirdPartyUtil->IsThirdPartyChannel(aChan, prinURI, aRes);
661 NS_IMETHODIMP
662 BasePrincipal::IsSameOrigin(nsIURI* aURI, bool* aRes) {
663 *aRes = false;
664 nsCOMPtr<nsIURI> prinURI;
665 nsresult rv = GetURI(getter_AddRefs(prinURI));
666 if (NS_FAILED(rv) || !prinURI) {
667 // Note that expanded and system principals return here, because they have
668 // no URI.
669 return NS_OK;
671 nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
672 if (!ssm) {
673 return NS_OK;
675 bool reportError = false;
676 bool isPrivateWindow = false; // Only used for error reporting.
677 *aRes = NS_SUCCEEDED(
678 ssm->CheckSameOriginURI(prinURI, aURI, reportError, isPrivateWindow));
679 return NS_OK;
682 NS_IMETHODIMP
683 BasePrincipal::IsL10nAllowed(nsIURI* aURI, bool* aRes) {
684 *aRes = false;
686 if (nsContentUtils::IsErrorPage(aURI)) {
687 *aRes = true;
688 return NS_OK;
691 // The system principal is always allowed.
692 if (IsSystemPrincipal()) {
693 *aRes = true;
694 return NS_OK;
697 nsCOMPtr<nsIURI> uri;
698 nsresult rv = GetURI(getter_AddRefs(uri));
699 NS_ENSURE_SUCCESS(rv, NS_OK);
701 bool hasFlags;
703 // Allow access to uris that cannot be loaded by web content.
704 rv = NS_URIChainHasFlags(uri, nsIProtocolHandler::URI_DANGEROUS_TO_LOAD,
705 &hasFlags);
706 NS_ENSURE_SUCCESS(rv, NS_OK);
707 if (hasFlags) {
708 *aRes = true;
709 return NS_OK;
712 // UI resources also get access.
713 rv = NS_URIChainHasFlags(uri, nsIProtocolHandler::URI_IS_UI_RESOURCE,
714 &hasFlags);
715 NS_ENSURE_SUCCESS(rv, NS_OK);
716 if (hasFlags) {
717 *aRes = true;
718 return NS_OK;
721 auto policy = AddonPolicy();
722 *aRes = (policy && policy->IsPrivileged());
723 return NS_OK;
726 NS_IMETHODIMP
727 BasePrincipal::AllowsRelaxStrictFileOriginPolicy(nsIURI* aURI, bool* aRes) {
728 *aRes = false;
729 nsCOMPtr<nsIURI> prinURI;
730 nsresult rv = GetURI(getter_AddRefs(prinURI));
731 if (NS_FAILED(rv) || !prinURI) {
732 return NS_OK;
734 *aRes = NS_RelaxStrictFileOriginPolicy(aURI, prinURI);
735 return NS_OK;
738 NS_IMETHODIMP
739 BasePrincipal::GetPrefLightCacheKey(nsIURI* aURI, bool aWithCredentials,
740 const OriginAttributes& aOriginAttributes,
741 nsACString& _retval) {
742 _retval.Truncate();
743 constexpr auto space = " "_ns;
745 nsCOMPtr<nsIURI> uri;
746 nsresult rv = GetURI(getter_AddRefs(uri));
747 NS_ENSURE_SUCCESS(rv, rv);
749 nsAutoCString scheme, host, port;
750 if (uri) {
751 uri->GetScheme(scheme);
752 uri->GetHost(host);
753 port.AppendInt(NS_GetRealPort(uri));
756 if (aWithCredentials) {
757 _retval.AssignLiteral("cred");
758 } else {
759 _retval.AssignLiteral("nocred");
762 nsAutoCString spec;
763 rv = aURI->GetSpec(spec);
764 NS_ENSURE_SUCCESS(rv, rv);
766 nsAutoCString originAttributesSuffix;
767 aOriginAttributes.CreateSuffix(originAttributesSuffix);
769 _retval.Append(space + scheme + space + host + space + port + space + spec +
770 space + originAttributesSuffix);
772 return NS_OK;
775 NS_IMETHODIMP
776 BasePrincipal::HasFirstpartyStorageAccess(mozIDOMWindow* aCheckWindow,
777 uint32_t* aRejectedReason,
778 bool* aOutAllowed) {
779 *aRejectedReason = 0;
780 *aOutAllowed = false;
782 nsPIDOMWindowInner* win = nsPIDOMWindowInner::From(aCheckWindow);
783 nsCOMPtr<nsIURI> uri;
784 nsresult rv = GetURI(getter_AddRefs(uri));
785 if (NS_FAILED(rv)) {
786 return rv;
788 *aOutAllowed =
789 ContentBlocking::ShouldAllowAccessFor(win, uri, aRejectedReason);
790 return NS_OK;
793 NS_IMETHODIMP
794 BasePrincipal::GetIsNullPrincipal(bool* aResult) {
795 *aResult = Kind() == eNullPrincipal;
796 return NS_OK;
799 NS_IMETHODIMP
800 BasePrincipal::GetIsContentPrincipal(bool* aResult) {
801 *aResult = Kind() == eContentPrincipal;
802 return NS_OK;
805 NS_IMETHODIMP
806 BasePrincipal::GetIsExpandedPrincipal(bool* aResult) {
807 *aResult = Kind() == eExpandedPrincipal;
808 return NS_OK;
811 NS_IMETHODIMP
812 BasePrincipal::GetAsciiSpec(nsACString& aSpec) {
813 aSpec.Truncate();
814 nsCOMPtr<nsIURI> prinURI;
815 nsresult rv = GetURI(getter_AddRefs(prinURI));
816 if (NS_FAILED(rv) || !prinURI) {
817 return NS_OK;
819 return prinURI->GetAsciiSpec(aSpec);
822 NS_IMETHODIMP
823 BasePrincipal::GetSpec(nsACString& aSpec) {
824 aSpec.Truncate();
825 nsCOMPtr<nsIURI> prinURI;
826 nsresult rv = GetURI(getter_AddRefs(prinURI));
827 if (NS_FAILED(rv) || !prinURI) {
828 return NS_OK;
830 return prinURI->GetSpec(aSpec);
833 NS_IMETHODIMP
834 BasePrincipal::GetAsciiHost(nsACString& aHost) {
835 aHost.Truncate();
836 nsCOMPtr<nsIURI> prinURI;
837 nsresult rv = GetURI(getter_AddRefs(prinURI));
838 if (NS_FAILED(rv) || !prinURI) {
839 return NS_OK;
841 return prinURI->GetAsciiHost(aHost);
844 NS_IMETHODIMP
845 BasePrincipal::GetExposablePrePath(nsACString& aPrepath) {
846 aPrepath.Truncate();
847 nsCOMPtr<nsIURI> prinURI;
848 nsresult rv = GetURI(getter_AddRefs(prinURI));
849 if (NS_FAILED(rv) || !prinURI) {
850 return NS_OK;
853 nsCOMPtr<nsIURI> exposableURI = net::nsIOService::CreateExposableURI(prinURI);
854 return exposableURI->GetDisplayPrePath(aPrepath);
857 NS_IMETHODIMP
858 BasePrincipal::GetExposableSpec(nsACString& aSpec) {
859 aSpec.Truncate();
860 nsCOMPtr<nsIURI> prinURI;
861 nsresult rv = GetURI(getter_AddRefs(prinURI));
862 if (NS_FAILED(rv) || !prinURI) {
863 return NS_OK;
865 nsCOMPtr<nsIURI> clone;
866 rv = NS_MutateURI(prinURI)
867 .SetQuery(""_ns)
868 .SetRef(""_ns)
869 .SetUserPass(""_ns)
870 .Finalize(clone);
871 NS_ENSURE_SUCCESS(rv, rv);
872 return clone->GetAsciiSpec(aSpec);
875 NS_IMETHODIMP
876 BasePrincipal::GetPrePath(nsACString& aPath) {
877 aPath.Truncate();
878 nsCOMPtr<nsIURI> prinURI;
879 nsresult rv = GetURI(getter_AddRefs(prinURI));
880 if (NS_FAILED(rv) || !prinURI) {
881 return NS_OK;
883 return prinURI->GetPrePath(aPath);
886 NS_IMETHODIMP
887 BasePrincipal::GetFilePath(nsACString& aPath) {
888 aPath.Truncate();
889 nsCOMPtr<nsIURI> prinURI;
890 nsresult rv = GetURI(getter_AddRefs(prinURI));
891 if (NS_FAILED(rv) || !prinURI) {
892 return NS_OK;
894 return prinURI->GetFilePath(aPath);
897 NS_IMETHODIMP
898 BasePrincipal::GetIsSystemPrincipal(bool* aResult) {
899 *aResult = IsSystemPrincipal();
900 return NS_OK;
903 NS_IMETHODIMP
904 BasePrincipal::GetIsAddonOrExpandedAddonPrincipal(bool* aResult) {
905 *aResult = AddonPolicy() || ContentScriptAddonPolicy();
906 return NS_OK;
909 NS_IMETHODIMP BasePrincipal::GetIsOnion(bool* aIsOnion) {
910 *aIsOnion = false;
911 nsCOMPtr<nsIURI> prinURI;
912 nsresult rv = GetURI(getter_AddRefs(prinURI));
913 if (NS_FAILED(rv) || !prinURI) {
914 return NS_OK;
917 nsAutoCString host;
918 rv = prinURI->GetHost(host);
919 if (NS_FAILED(rv)) {
920 return NS_OK;
922 *aIsOnion = StringEndsWith(host, ".onion"_ns);
923 return NS_OK;
926 NS_IMETHODIMP BasePrincipal::GetIsIpAddress(bool* aIsIpAddress) {
927 *aIsIpAddress = false;
929 nsCOMPtr<nsIURI> prinURI;
930 nsresult rv = GetURI(getter_AddRefs(prinURI));
931 if (NS_FAILED(rv) || !prinURI) {
932 return NS_OK;
935 nsAutoCString host;
936 rv = prinURI->GetHost(host);
937 if (NS_FAILED(rv)) {
938 return NS_OK;
941 PRNetAddr prAddr;
942 memset(&prAddr, 0, sizeof(prAddr));
944 if (PR_StringToNetAddr(host.get(), &prAddr) == PR_SUCCESS) {
945 *aIsIpAddress = true;
948 return NS_OK;
951 NS_IMETHODIMP BasePrincipal::GetIsLocalIpAddress(bool* aIsIpAddress) {
952 *aIsIpAddress = false;
954 nsCOMPtr<nsIURI> prinURI;
955 nsresult rv = GetURI(getter_AddRefs(prinURI));
956 if (NS_FAILED(rv) || !prinURI) {
957 return NS_OK;
960 nsCOMPtr<nsIIOService> ioService = do_GetIOService(&rv);
961 if (NS_FAILED(rv) || !ioService) {
962 return NS_OK;
964 rv = ioService->HostnameIsLocalIPAddress(prinURI, aIsIpAddress);
965 if (NS_FAILED(rv)) {
966 *aIsIpAddress = false;
968 return NS_OK;
971 NS_IMETHODIMP
972 BasePrincipal::GetScheme(nsACString& aScheme) {
973 aScheme.Truncate();
975 nsCOMPtr<nsIURI> prinURI;
976 nsresult rv = GetURI(getter_AddRefs(prinURI));
977 if (NS_FAILED(rv) || !prinURI) {
978 return NS_OK;
981 return prinURI->GetScheme(aScheme);
984 NS_IMETHODIMP
985 BasePrincipal::SchemeIs(const char* aScheme, bool* aResult) {
986 *aResult = false;
987 nsCOMPtr<nsIURI> prinURI;
988 nsresult rv = GetURI(getter_AddRefs(prinURI));
989 if (NS_WARN_IF(NS_FAILED(rv)) || !prinURI) {
990 return NS_OK;
992 *aResult = prinURI->SchemeIs(aScheme);
993 return NS_OK;
996 NS_IMETHODIMP
997 BasePrincipal::IsURIInPrefList(const char* aPref, bool* aResult) {
998 *aResult = false;
999 nsCOMPtr<nsIURI> prinURI;
1000 nsresult rv = GetURI(getter_AddRefs(prinURI));
1001 if (NS_FAILED(rv) || !prinURI) {
1002 return NS_OK;
1004 *aResult = nsContentUtils::IsURIInPrefList(prinURI, aPref);
1005 return NS_OK;
1008 NS_IMETHODIMP
1009 BasePrincipal::IsURIInList(const nsACString& aList, bool* aResult) {
1010 *aResult = false;
1011 nsCOMPtr<nsIURI> prinURI;
1013 nsresult rv = GetURI(getter_AddRefs(prinURI));
1014 if (NS_FAILED(rv) || !prinURI) {
1015 return NS_OK;
1018 *aResult = nsContentUtils::IsURIInList(prinURI, nsCString(aList));
1019 return NS_OK;
1022 NS_IMETHODIMP
1023 BasePrincipal::GetIsOriginPotentiallyTrustworthy(bool* aResult) {
1024 MOZ_ASSERT(NS_IsMainThread());
1025 *aResult = false;
1027 nsCOMPtr<nsIURI> uri;
1028 nsresult rv = GetURI(getter_AddRefs(uri));
1029 if (NS_FAILED(rv) || !uri) {
1030 return NS_OK;
1033 *aResult = nsMixedContentBlocker::IsPotentiallyTrustworthyOrigin(uri);
1034 return NS_OK;
1037 NS_IMETHODIMP
1038 BasePrincipal::GetAboutModuleFlags(uint32_t* flags) {
1039 *flags = 0;
1040 nsCOMPtr<nsIURI> prinURI;
1041 nsresult rv = GetURI(getter_AddRefs(prinURI));
1042 if (NS_FAILED(rv) || !prinURI) {
1043 return NS_ERROR_NOT_AVAILABLE;
1045 if (!prinURI->SchemeIs("about")) {
1046 return NS_OK;
1049 nsCOMPtr<nsIAboutModule> aboutModule;
1050 rv = NS_GetAboutModule(prinURI, getter_AddRefs(aboutModule));
1051 if (NS_FAILED(rv) || !aboutModule) {
1052 return rv;
1054 return aboutModule->GetURIFlags(prinURI, flags);
1057 NS_IMETHODIMP
1058 BasePrincipal::GetOriginAttributes(JSContext* aCx,
1059 JS::MutableHandle<JS::Value> aVal) {
1060 if (NS_WARN_IF(!ToJSValue(aCx, mOriginAttributes, aVal))) {
1061 return NS_ERROR_FAILURE;
1063 return NS_OK;
1066 NS_IMETHODIMP
1067 BasePrincipal::GetOriginSuffix(nsACString& aOriginAttributes) {
1068 MOZ_ASSERT(mOriginSuffix);
1069 mOriginSuffix->ToUTF8String(aOriginAttributes);
1070 return NS_OK;
1073 NS_IMETHODIMP
1074 BasePrincipal::GetUserContextId(uint32_t* aUserContextId) {
1075 *aUserContextId = UserContextId();
1076 return NS_OK;
1079 NS_IMETHODIMP
1080 BasePrincipal::GetPrivateBrowsingId(uint32_t* aPrivateBrowsingId) {
1081 *aPrivateBrowsingId = PrivateBrowsingId();
1082 return NS_OK;
1085 NS_IMETHODIMP
1086 BasePrincipal::GetIsInIsolatedMozBrowserElement(
1087 bool* aIsInIsolatedMozBrowserElement) {
1088 *aIsInIsolatedMozBrowserElement = IsInIsolatedMozBrowserElement();
1089 return NS_OK;
1092 nsresult BasePrincipal::GetAddonPolicy(
1093 extensions::WebExtensionPolicy** aResult) {
1094 RefPtr<extensions::WebExtensionPolicy> policy(AddonPolicy());
1095 policy.forget(aResult);
1096 return NS_OK;
1099 extensions::WebExtensionPolicy* BasePrincipal::AddonPolicy() {
1100 if (Is<ContentPrincipal>()) {
1101 return As<ContentPrincipal>()->AddonPolicy();
1103 return nullptr;
1106 bool BasePrincipal::AddonHasPermission(const nsAtom* aPerm) {
1107 if (auto policy = AddonPolicy()) {
1108 return policy->HasPermission(aPerm);
1110 return false;
1113 nsIPrincipal* BasePrincipal::PrincipalToInherit(nsIURI* aRequestedURI) {
1114 if (Is<ExpandedPrincipal>()) {
1115 return As<ExpandedPrincipal>()->PrincipalToInherit(aRequestedURI);
1117 return this;
1120 bool BasePrincipal::IsLoopbackHost() {
1121 nsAutoCString host;
1122 nsresult rv = GetHost(host);
1123 NS_ENSURE_SUCCESS(rv, false);
1124 return nsMixedContentBlocker::IsPotentiallyTrustworthyLoopbackHost(host);
1127 already_AddRefed<BasePrincipal> BasePrincipal::CreateContentPrincipal(
1128 nsIURI* aURI, const OriginAttributes& aAttrs) {
1129 MOZ_ASSERT(aURI);
1131 nsAutoCString originNoSuffix;
1132 nsresult rv =
1133 ContentPrincipal::GenerateOriginNoSuffixFromURI(aURI, originNoSuffix);
1134 if (NS_FAILED(rv)) {
1135 // If the generation of the origin fails, we still want to have a valid
1136 // principal. Better to return a null principal here.
1137 return NullPrincipal::Create(aAttrs);
1140 return CreateContentPrincipal(aURI, aAttrs, originNoSuffix);
1143 already_AddRefed<BasePrincipal> BasePrincipal::CreateContentPrincipal(
1144 nsIURI* aURI, const OriginAttributes& aAttrs,
1145 const nsACString& aOriginNoSuffix) {
1146 MOZ_ASSERT(aURI);
1147 MOZ_ASSERT(!aOriginNoSuffix.IsEmpty());
1149 // If the URI is supposed to inherit the security context of whoever loads it,
1150 // we shouldn't make a content principal for it.
1151 bool inheritsPrincipal;
1152 nsresult rv = NS_URIChainHasFlags(
1153 aURI, nsIProtocolHandler::URI_INHERITS_SECURITY_CONTEXT,
1154 &inheritsPrincipal);
1155 if (NS_FAILED(rv) || inheritsPrincipal) {
1156 return NullPrincipal::Create(aAttrs);
1159 // Check whether the URI knows what its principal is supposed to be.
1160 #if defined(MOZ_THUNDERBIRD) || defined(MOZ_SUITE)
1161 nsCOMPtr<nsIURIWithSpecialOrigin> uriWithSpecialOrigin =
1162 do_QueryInterface(aURI);
1163 if (uriWithSpecialOrigin) {
1164 nsCOMPtr<nsIURI> origin;
1165 rv = uriWithSpecialOrigin->GetOrigin(getter_AddRefs(origin));
1166 if (NS_WARN_IF(NS_FAILED(rv))) {
1167 return nullptr;
1169 MOZ_ASSERT(origin);
1170 OriginAttributes attrs;
1171 RefPtr<BasePrincipal> principal = CreateContentPrincipal(origin, attrs);
1172 return principal.forget();
1174 #endif
1176 nsCOMPtr<nsIPrincipal> blobPrincipal;
1177 if (dom::BlobURLProtocolHandler::GetBlobURLPrincipal(
1178 aURI, getter_AddRefs(blobPrincipal))) {
1179 MOZ_ASSERT(blobPrincipal);
1180 RefPtr<BasePrincipal> principal = Cast(blobPrincipal);
1181 return principal.forget();
1184 // Mint a content principal.
1185 RefPtr<ContentPrincipal> principal =
1186 new ContentPrincipal(aURI, aAttrs, aOriginNoSuffix);
1187 return principal.forget();
1190 already_AddRefed<BasePrincipal> BasePrincipal::CreateContentPrincipal(
1191 const nsACString& aOrigin) {
1192 MOZ_ASSERT(!StringBeginsWith(aOrigin, "["_ns),
1193 "CreateContentPrincipal does not support System and Expanded "
1194 "principals");
1196 MOZ_ASSERT(
1197 !StringBeginsWith(aOrigin, nsLiteralCString(NS_NULLPRINCIPAL_SCHEME ":")),
1198 "CreateContentPrincipal does not support NullPrincipal");
1200 nsAutoCString originNoSuffix;
1201 OriginAttributes attrs;
1202 if (!attrs.PopulateFromOrigin(aOrigin, originNoSuffix)) {
1203 return nullptr;
1206 nsCOMPtr<nsIURI> uri;
1207 nsresult rv = NS_NewURI(getter_AddRefs(uri), originNoSuffix);
1208 NS_ENSURE_SUCCESS(rv, nullptr);
1210 return BasePrincipal::CreateContentPrincipal(uri, attrs);
1213 already_AddRefed<BasePrincipal> BasePrincipal::CloneForcingOriginAttributes(
1214 const OriginAttributes& aOriginAttributes) {
1215 if (NS_WARN_IF(!IsContentPrincipal())) {
1216 return nullptr;
1219 nsAutoCString originNoSuffix;
1220 nsresult rv = GetOriginNoSuffix(originNoSuffix);
1221 NS_ENSURE_SUCCESS(rv, nullptr);
1223 nsCOMPtr<nsIURI> uri;
1224 MOZ_ALWAYS_SUCCEEDS(GetURI(getter_AddRefs(uri)));
1226 RefPtr<ContentPrincipal> copy =
1227 new ContentPrincipal(uri, aOriginAttributes, originNoSuffix);
1228 return copy.forget();
1231 extensions::WebExtensionPolicy* BasePrincipal::ContentScriptAddonPolicy() {
1232 if (!Is<ExpandedPrincipal>()) {
1233 return nullptr;
1236 auto expanded = As<ExpandedPrincipal>();
1237 for (auto& prin : expanded->AllowList()) {
1238 if (auto policy = BasePrincipal::Cast(prin)->AddonPolicy()) {
1239 return policy;
1243 return nullptr;
1246 bool BasePrincipal::AddonAllowsLoad(nsIURI* aURI,
1247 bool aExplicit /* = false */) {
1248 if (Is<ExpandedPrincipal>()) {
1249 return As<ExpandedPrincipal>()->AddonAllowsLoad(aURI, aExplicit);
1251 if (auto policy = AddonPolicy()) {
1252 return policy->CanAccessURI(aURI, aExplicit);
1254 return false;
1257 NS_IMETHODIMP
1258 BasePrincipal::GetLocalStorageQuotaKey(nsACString& aKey) {
1259 aKey.Truncate();
1261 nsCOMPtr<nsIURI> uri;
1262 nsresult rv = GetURI(getter_AddRefs(uri));
1263 NS_ENSURE_SUCCESS(rv, rv);
1264 NS_ENSURE_TRUE(uri, NS_ERROR_UNEXPECTED);
1266 // The special handling of the file scheme should be consistent with
1267 // GetStorageOriginKey.
1269 nsAutoCString baseDomain;
1270 rv = uri->GetAsciiHost(baseDomain);
1271 NS_ENSURE_SUCCESS(rv, rv);
1273 if (baseDomain.IsEmpty() && uri->SchemeIs("file")) {
1274 nsCOMPtr<nsIURL> url = do_QueryInterface(uri, &rv);
1275 NS_ENSURE_SUCCESS(rv, rv);
1277 rv = url->GetDirectory(baseDomain);
1278 NS_ENSURE_SUCCESS(rv, rv);
1279 } else {
1280 nsCOMPtr<nsIEffectiveTLDService> eTLDService(
1281 do_GetService(NS_EFFECTIVETLDSERVICE_CONTRACTID, &rv));
1282 NS_ENSURE_SUCCESS(rv, rv);
1284 nsAutoCString eTLDplusOne;
1285 rv = eTLDService->GetBaseDomain(uri, 0, eTLDplusOne);
1286 if (NS_SUCCEEDED(rv)) {
1287 baseDomain = eTLDplusOne;
1288 } else if (rv == NS_ERROR_HOST_IS_IP_ADDRESS ||
1289 rv == NS_ERROR_INSUFFICIENT_DOMAIN_LEVELS) {
1290 rv = NS_OK;
1292 NS_ENSURE_SUCCESS(rv, rv);
1295 OriginAttributesRef().CreateSuffix(aKey);
1297 nsAutoCString subdomainsDBKey;
1298 rv = dom::StorageUtils::CreateReversedDomain(baseDomain, subdomainsDBKey);
1299 NS_ENSURE_SUCCESS(rv, rv);
1301 aKey.Append(':');
1302 aKey.Append(subdomainsDBKey);
1304 return NS_OK;
1307 NS_IMETHODIMP
1308 BasePrincipal::GetNextSubDomainPrincipal(
1309 nsIPrincipal** aNextSubDomainPrincipal) {
1310 nsCOMPtr<nsIURI> uri;
1311 nsresult rv = GetURI(getter_AddRefs(uri));
1312 if (NS_FAILED(rv) || !uri) {
1313 return NS_OK;
1316 nsAutoCString host;
1317 rv = uri->GetHost(host);
1318 if (NS_FAILED(rv) || host.IsEmpty()) {
1319 return NS_OK;
1322 nsCString subDomain;
1323 rv = nsEffectiveTLDService::GetInstance()->GetNextSubDomain(host, subDomain);
1325 if (NS_FAILED(rv) || subDomain.IsEmpty()) {
1326 return NS_OK;
1329 nsCOMPtr<nsIURI> subDomainURI;
1330 rv = NS_MutateURI(uri).SetHost(subDomain).Finalize(subDomainURI);
1331 if (NS_FAILED(rv) || !subDomainURI) {
1332 return NS_OK;
1334 // Copy the attributes over
1335 mozilla::OriginAttributes attrs = OriginAttributesRef();
1337 if (!StaticPrefs::permissions_isolateBy_userContext()) {
1338 // Disable userContext for permissions.
1339 attrs.StripAttributes(mozilla::OriginAttributes::STRIP_USER_CONTEXT_ID);
1341 RefPtr<nsIPrincipal> principal =
1342 mozilla::BasePrincipal::CreateContentPrincipal(subDomainURI, attrs);
1344 if (!principal) {
1345 return NS_OK;
1347 principal.forget(aNextSubDomainPrincipal);
1348 return NS_OK;
1351 NS_IMETHODIMP
1352 BasePrincipal::GetStorageOriginKey(nsACString& aOriginKey) {
1353 aOriginKey.Truncate();
1355 nsCOMPtr<nsIURI> uri;
1356 nsresult rv = GetURI(getter_AddRefs(uri));
1357 NS_ENSURE_SUCCESS(rv, rv);
1358 NS_ENSURE_TRUE(uri, NS_ERROR_UNEXPECTED);
1360 // The special handling of the file scheme should be consistent with
1361 // GetLocalStorageQuotaKey.
1363 nsAutoCString domainOrigin;
1364 rv = uri->GetAsciiHost(domainOrigin);
1365 NS_ENSURE_SUCCESS(rv, rv);
1367 if (domainOrigin.IsEmpty()) {
1368 // For the file:/// protocol use the exact directory as domain.
1369 if (uri->SchemeIs("file")) {
1370 nsCOMPtr<nsIURL> url = do_QueryInterface(uri, &rv);
1371 NS_ENSURE_SUCCESS(rv, rv);
1372 rv = url->GetDirectory(domainOrigin);
1373 NS_ENSURE_SUCCESS(rv, rv);
1377 // Append reversed domain
1378 nsAutoCString reverseDomain;
1379 rv = dom::StorageUtils::CreateReversedDomain(domainOrigin, reverseDomain);
1380 NS_ENSURE_SUCCESS(rv, rv);
1382 aOriginKey.Append(reverseDomain);
1384 // Append scheme
1385 nsAutoCString scheme;
1386 rv = uri->GetScheme(scheme);
1387 NS_ENSURE_SUCCESS(rv, rv);
1389 aOriginKey.Append(':');
1390 aOriginKey.Append(scheme);
1392 // Append port if any
1393 int32_t port = NS_GetRealPort(uri);
1394 if (port != -1) {
1395 aOriginKey.Append(nsPrintfCString(":%d", port));
1398 return NS_OK;
1401 NS_IMETHODIMP
1402 BasePrincipal::GetIsScriptAllowedByPolicy(bool* aIsScriptAllowedByPolicy) {
1403 *aIsScriptAllowedByPolicy = false;
1404 nsCOMPtr<nsIURI> prinURI;
1405 nsresult rv = GetURI(getter_AddRefs(prinURI));
1406 if (NS_FAILED(rv) || !prinURI) {
1407 return NS_OK;
1409 nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
1410 if (!ssm) {
1411 return NS_ERROR_UNEXPECTED;
1413 return ssm->PolicyAllowsScript(prinURI, aIsScriptAllowedByPolicy);
1416 bool SiteIdentifier::Equals(const SiteIdentifier& aOther) const {
1417 MOZ_ASSERT(IsInitialized());
1418 MOZ_ASSERT(aOther.IsInitialized());
1419 return mPrincipal->FastEquals(aOther.mPrincipal);
1422 NS_IMETHODIMP
1423 BasePrincipal::CreateReferrerInfo(mozilla::dom::ReferrerPolicy aReferrerPolicy,
1424 nsIReferrerInfo** _retval) {
1425 nsCOMPtr<nsIURI> prinURI;
1426 RefPtr<dom::ReferrerInfo> info;
1427 nsresult rv = GetURI(getter_AddRefs(prinURI));
1428 if (NS_FAILED(rv) || !prinURI) {
1429 info = new dom::ReferrerInfo(nullptr);
1430 info.forget(_retval);
1431 return NS_OK;
1433 info = new dom::ReferrerInfo(prinURI, aReferrerPolicy);
1434 info.forget(_retval);
1435 return NS_OK;
1438 NS_IMETHODIMP
1439 BasePrincipal::GetPrecursorPrincipal(nsIPrincipal** aPrecursor) {
1440 *aPrecursor = nullptr;
1441 return NS_OK;
1444 NS_IMPL_ADDREF(BasePrincipal::Deserializer)
1445 NS_IMPL_RELEASE(BasePrincipal::Deserializer)
1447 NS_INTERFACE_MAP_BEGIN(BasePrincipal::Deserializer)
1448 NS_INTERFACE_MAP_ENTRY(nsISupports)
1449 NS_INTERFACE_MAP_ENTRY(nsISerializable)
1450 if (mPrincipal) {
1451 return mPrincipal->QueryInterface(aIID, aInstancePtr);
1452 } else
1453 NS_INTERFACE_MAP_END
1455 NS_IMETHODIMP
1456 BasePrincipal::Deserializer::Write(nsIObjectOutputStream* aStream) {
1457 // Read is used still for legacy principals
1458 MOZ_RELEASE_ASSERT(false, "Old style serialization is removed");
1459 return NS_OK;
1462 } // namespace mozilla