Bug 1782261 [wpt PR 35272] - Create toggles on elements when specified by the 'toggle...
[gecko.git] / caps / BasePrincipal.cpp
blob982b5509d30e42a46fdfeeb5fd8beaf9f52548d7
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::GetAboutModuleFlags(uint32_t* flags) {
1059 *flags = 0;
1060 nsCOMPtr<nsIURI> prinURI;
1061 nsresult rv = GetURI(getter_AddRefs(prinURI));
1062 if (NS_FAILED(rv) || !prinURI) {
1063 return NS_ERROR_NOT_AVAILABLE;
1065 if (!prinURI->SchemeIs("about")) {
1066 return NS_OK;
1069 nsCOMPtr<nsIAboutModule> aboutModule;
1070 rv = NS_GetAboutModule(prinURI, getter_AddRefs(aboutModule));
1071 if (NS_FAILED(rv) || !aboutModule) {
1072 return rv;
1074 return aboutModule->GetURIFlags(prinURI, flags);
1077 NS_IMETHODIMP
1078 BasePrincipal::GetOriginAttributes(JSContext* aCx,
1079 JS::MutableHandle<JS::Value> aVal) {
1080 if (NS_WARN_IF(!ToJSValue(aCx, mOriginAttributes, aVal))) {
1081 return NS_ERROR_FAILURE;
1083 return NS_OK;
1086 NS_IMETHODIMP
1087 BasePrincipal::GetOriginSuffix(nsACString& aOriginAttributes) {
1088 MOZ_ASSERT(mOriginSuffix);
1089 mOriginSuffix->ToUTF8String(aOriginAttributes);
1090 return NS_OK;
1093 NS_IMETHODIMP
1094 BasePrincipal::GetUserContextId(uint32_t* aUserContextId) {
1095 *aUserContextId = UserContextId();
1096 return NS_OK;
1099 NS_IMETHODIMP
1100 BasePrincipal::GetPrivateBrowsingId(uint32_t* aPrivateBrowsingId) {
1101 *aPrivateBrowsingId = PrivateBrowsingId();
1102 return NS_OK;
1105 NS_IMETHODIMP
1106 BasePrincipal::GetIsInIsolatedMozBrowserElement(
1107 bool* aIsInIsolatedMozBrowserElement) {
1108 *aIsInIsolatedMozBrowserElement = IsInIsolatedMozBrowserElement();
1109 return NS_OK;
1112 nsresult BasePrincipal::GetAddonPolicy(
1113 extensions::WebExtensionPolicy** aResult) {
1114 RefPtr<extensions::WebExtensionPolicy> policy(AddonPolicy());
1115 policy.forget(aResult);
1116 return NS_OK;
1119 extensions::WebExtensionPolicy* BasePrincipal::AddonPolicy() {
1120 if (Is<ContentPrincipal>()) {
1121 return As<ContentPrincipal>()->AddonPolicy();
1123 return nullptr;
1126 bool BasePrincipal::AddonHasPermission(const nsAtom* aPerm) {
1127 if (auto policy = AddonPolicy()) {
1128 return policy->HasPermission(aPerm);
1130 return false;
1133 nsIPrincipal* BasePrincipal::PrincipalToInherit(nsIURI* aRequestedURI) {
1134 if (Is<ExpandedPrincipal>()) {
1135 return As<ExpandedPrincipal>()->PrincipalToInherit(aRequestedURI);
1137 return this;
1140 bool BasePrincipal::IsLoopbackHost() {
1141 nsAutoCString host;
1142 nsresult rv = GetHost(host);
1143 NS_ENSURE_SUCCESS(rv, false);
1144 return nsMixedContentBlocker::IsPotentiallyTrustworthyLoopbackHost(host);
1147 already_AddRefed<BasePrincipal> BasePrincipal::CreateContentPrincipal(
1148 nsIURI* aURI, const OriginAttributes& aAttrs) {
1149 MOZ_ASSERT(aURI);
1151 nsAutoCString originNoSuffix;
1152 nsresult rv =
1153 ContentPrincipal::GenerateOriginNoSuffixFromURI(aURI, originNoSuffix);
1154 if (NS_FAILED(rv)) {
1155 // If the generation of the origin fails, we still want to have a valid
1156 // principal. Better to return a null principal here.
1157 return NullPrincipal::Create(aAttrs);
1160 return CreateContentPrincipal(aURI, aAttrs, originNoSuffix);
1163 already_AddRefed<BasePrincipal> BasePrincipal::CreateContentPrincipal(
1164 nsIURI* aURI, const OriginAttributes& aAttrs,
1165 const nsACString& aOriginNoSuffix) {
1166 MOZ_ASSERT(aURI);
1167 MOZ_ASSERT(!aOriginNoSuffix.IsEmpty());
1169 // If the URI is supposed to inherit the security context of whoever loads it,
1170 // we shouldn't make a content principal for it.
1171 bool inheritsPrincipal;
1172 nsresult rv = NS_URIChainHasFlags(
1173 aURI, nsIProtocolHandler::URI_INHERITS_SECURITY_CONTEXT,
1174 &inheritsPrincipal);
1175 if (NS_FAILED(rv) || inheritsPrincipal) {
1176 return NullPrincipal::Create(aAttrs);
1179 // Check whether the URI knows what its principal is supposed to be.
1180 #if defined(MOZ_THUNDERBIRD) || defined(MOZ_SUITE)
1181 nsCOMPtr<nsIURIWithSpecialOrigin> uriWithSpecialOrigin =
1182 do_QueryInterface(aURI);
1183 if (uriWithSpecialOrigin) {
1184 nsCOMPtr<nsIURI> origin;
1185 rv = uriWithSpecialOrigin->GetOrigin(getter_AddRefs(origin));
1186 if (NS_WARN_IF(NS_FAILED(rv))) {
1187 return nullptr;
1189 MOZ_ASSERT(origin);
1190 OriginAttributes attrs;
1191 RefPtr<BasePrincipal> principal = CreateContentPrincipal(origin, attrs);
1192 return principal.forget();
1194 #endif
1196 nsCOMPtr<nsIPrincipal> blobPrincipal;
1197 if (dom::BlobURLProtocolHandler::GetBlobURLPrincipal(
1198 aURI, getter_AddRefs(blobPrincipal))) {
1199 MOZ_ASSERT(blobPrincipal);
1200 RefPtr<BasePrincipal> principal = Cast(blobPrincipal);
1201 return principal.forget();
1204 // Mint a content principal.
1205 RefPtr<ContentPrincipal> principal =
1206 new ContentPrincipal(aURI, aAttrs, aOriginNoSuffix);
1207 return principal.forget();
1210 already_AddRefed<BasePrincipal> BasePrincipal::CreateContentPrincipal(
1211 const nsACString& aOrigin) {
1212 MOZ_ASSERT(!StringBeginsWith(aOrigin, "["_ns),
1213 "CreateContentPrincipal does not support System and Expanded "
1214 "principals");
1216 MOZ_ASSERT(
1217 !StringBeginsWith(aOrigin, nsLiteralCString(NS_NULLPRINCIPAL_SCHEME ":")),
1218 "CreateContentPrincipal does not support NullPrincipal");
1220 nsAutoCString originNoSuffix;
1221 OriginAttributes attrs;
1222 if (!attrs.PopulateFromOrigin(aOrigin, originNoSuffix)) {
1223 return nullptr;
1226 nsCOMPtr<nsIURI> uri;
1227 nsresult rv = NS_NewURI(getter_AddRefs(uri), originNoSuffix);
1228 NS_ENSURE_SUCCESS(rv, nullptr);
1230 return BasePrincipal::CreateContentPrincipal(uri, attrs);
1233 already_AddRefed<BasePrincipal> BasePrincipal::CloneForcingOriginAttributes(
1234 const OriginAttributes& aOriginAttributes) {
1235 if (NS_WARN_IF(!IsContentPrincipal())) {
1236 return nullptr;
1239 nsAutoCString originNoSuffix;
1240 nsresult rv = GetOriginNoSuffix(originNoSuffix);
1241 NS_ENSURE_SUCCESS(rv, nullptr);
1243 nsCOMPtr<nsIURI> uri;
1244 MOZ_ALWAYS_SUCCEEDS(GetURI(getter_AddRefs(uri)));
1246 RefPtr<ContentPrincipal> copy =
1247 new ContentPrincipal(uri, aOriginAttributes, originNoSuffix);
1248 return copy.forget();
1251 extensions::WebExtensionPolicy* BasePrincipal::ContentScriptAddonPolicy() {
1252 if (!Is<ExpandedPrincipal>()) {
1253 return nullptr;
1256 auto expanded = As<ExpandedPrincipal>();
1257 for (auto& prin : expanded->AllowList()) {
1258 if (auto policy = BasePrincipal::Cast(prin)->AddonPolicy()) {
1259 return policy;
1263 return nullptr;
1266 bool BasePrincipal::AddonAllowsLoad(nsIURI* aURI,
1267 bool aExplicit /* = false */) {
1268 if (Is<ExpandedPrincipal>()) {
1269 return As<ExpandedPrincipal>()->AddonAllowsLoad(aURI, aExplicit);
1271 if (auto policy = AddonPolicy()) {
1272 return policy->CanAccessURI(aURI, aExplicit);
1274 return false;
1277 NS_IMETHODIMP
1278 BasePrincipal::GetLocalStorageQuotaKey(nsACString& aKey) {
1279 aKey.Truncate();
1281 nsCOMPtr<nsIURI> uri;
1282 nsresult rv = GetURI(getter_AddRefs(uri));
1283 NS_ENSURE_SUCCESS(rv, rv);
1284 NS_ENSURE_TRUE(uri, NS_ERROR_UNEXPECTED);
1286 // The special handling of the file scheme should be consistent with
1287 // GetStorageOriginKey.
1289 nsAutoCString baseDomain;
1290 rv = uri->GetAsciiHost(baseDomain);
1291 NS_ENSURE_SUCCESS(rv, rv);
1293 if (baseDomain.IsEmpty() && uri->SchemeIs("file")) {
1294 nsCOMPtr<nsIURL> url = do_QueryInterface(uri, &rv);
1295 NS_ENSURE_SUCCESS(rv, rv);
1297 rv = url->GetDirectory(baseDomain);
1298 NS_ENSURE_SUCCESS(rv, rv);
1299 } else {
1300 nsCOMPtr<nsIEffectiveTLDService> eTLDService(
1301 do_GetService(NS_EFFECTIVETLDSERVICE_CONTRACTID, &rv));
1302 NS_ENSURE_SUCCESS(rv, rv);
1304 nsAutoCString eTLDplusOne;
1305 rv = eTLDService->GetBaseDomain(uri, 0, eTLDplusOne);
1306 if (NS_SUCCEEDED(rv)) {
1307 baseDomain = eTLDplusOne;
1308 } else if (rv == NS_ERROR_HOST_IS_IP_ADDRESS ||
1309 rv == NS_ERROR_INSUFFICIENT_DOMAIN_LEVELS) {
1310 rv = NS_OK;
1312 NS_ENSURE_SUCCESS(rv, rv);
1315 OriginAttributesRef().CreateSuffix(aKey);
1317 nsAutoCString subdomainsDBKey;
1318 rv = dom::StorageUtils::CreateReversedDomain(baseDomain, subdomainsDBKey);
1319 NS_ENSURE_SUCCESS(rv, rv);
1321 aKey.Append(':');
1322 aKey.Append(subdomainsDBKey);
1324 return NS_OK;
1327 NS_IMETHODIMP
1328 BasePrincipal::GetNextSubDomainPrincipal(
1329 nsIPrincipal** aNextSubDomainPrincipal) {
1330 nsCOMPtr<nsIURI> uri;
1331 nsresult rv = GetURI(getter_AddRefs(uri));
1332 if (NS_FAILED(rv) || !uri) {
1333 return NS_OK;
1336 nsAutoCString host;
1337 rv = uri->GetHost(host);
1338 if (NS_FAILED(rv) || host.IsEmpty()) {
1339 return NS_OK;
1342 nsCString subDomain;
1343 rv = nsEffectiveTLDService::GetInstance()->GetNextSubDomain(host, subDomain);
1345 if (NS_FAILED(rv) || subDomain.IsEmpty()) {
1346 return NS_OK;
1349 nsCOMPtr<nsIURI> subDomainURI;
1350 rv = NS_MutateURI(uri).SetHost(subDomain).Finalize(subDomainURI);
1351 if (NS_FAILED(rv) || !subDomainURI) {
1352 return NS_OK;
1354 // Copy the attributes over
1355 mozilla::OriginAttributes attrs = OriginAttributesRef();
1357 if (!StaticPrefs::permissions_isolateBy_userContext()) {
1358 // Disable userContext for permissions.
1359 attrs.StripAttributes(mozilla::OriginAttributes::STRIP_USER_CONTEXT_ID);
1361 RefPtr<nsIPrincipal> principal =
1362 mozilla::BasePrincipal::CreateContentPrincipal(subDomainURI, attrs);
1364 if (!principal) {
1365 return NS_OK;
1367 principal.forget(aNextSubDomainPrincipal);
1368 return NS_OK;
1371 NS_IMETHODIMP
1372 BasePrincipal::GetStorageOriginKey(nsACString& aOriginKey) {
1373 aOriginKey.Truncate();
1375 nsCOMPtr<nsIURI> uri;
1376 nsresult rv = GetURI(getter_AddRefs(uri));
1377 NS_ENSURE_SUCCESS(rv, rv);
1378 NS_ENSURE_TRUE(uri, NS_ERROR_UNEXPECTED);
1380 // The special handling of the file scheme should be consistent with
1381 // GetLocalStorageQuotaKey.
1383 nsAutoCString domainOrigin;
1384 rv = uri->GetAsciiHost(domainOrigin);
1385 NS_ENSURE_SUCCESS(rv, rv);
1387 if (domainOrigin.IsEmpty()) {
1388 // For the file:/// protocol use the exact directory as domain.
1389 if (uri->SchemeIs("file")) {
1390 nsCOMPtr<nsIURL> url = do_QueryInterface(uri, &rv);
1391 NS_ENSURE_SUCCESS(rv, rv);
1392 rv = url->GetDirectory(domainOrigin);
1393 NS_ENSURE_SUCCESS(rv, rv);
1397 // Append reversed domain
1398 nsAutoCString reverseDomain;
1399 rv = dom::StorageUtils::CreateReversedDomain(domainOrigin, reverseDomain);
1400 NS_ENSURE_SUCCESS(rv, rv);
1402 aOriginKey.Append(reverseDomain);
1404 // Append scheme
1405 nsAutoCString scheme;
1406 rv = uri->GetScheme(scheme);
1407 NS_ENSURE_SUCCESS(rv, rv);
1409 aOriginKey.Append(':');
1410 aOriginKey.Append(scheme);
1412 // Append port if any
1413 int32_t port = NS_GetRealPort(uri);
1414 if (port != -1) {
1415 aOriginKey.Append(nsPrintfCString(":%d", port));
1418 return NS_OK;
1421 NS_IMETHODIMP
1422 BasePrincipal::GetIsScriptAllowedByPolicy(bool* aIsScriptAllowedByPolicy) {
1423 *aIsScriptAllowedByPolicy = false;
1424 nsCOMPtr<nsIURI> prinURI;
1425 nsresult rv = GetURI(getter_AddRefs(prinURI));
1426 if (NS_FAILED(rv) || !prinURI) {
1427 return NS_OK;
1429 nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
1430 if (!ssm) {
1431 return NS_ERROR_UNEXPECTED;
1433 return ssm->PolicyAllowsScript(prinURI, aIsScriptAllowedByPolicy);
1436 bool SiteIdentifier::Equals(const SiteIdentifier& aOther) const {
1437 MOZ_ASSERT(IsInitialized());
1438 MOZ_ASSERT(aOther.IsInitialized());
1439 return mPrincipal->FastEquals(aOther.mPrincipal);
1442 NS_IMETHODIMP
1443 BasePrincipal::CreateReferrerInfo(mozilla::dom::ReferrerPolicy aReferrerPolicy,
1444 nsIReferrerInfo** _retval) {
1445 nsCOMPtr<nsIURI> prinURI;
1446 RefPtr<dom::ReferrerInfo> info;
1447 nsresult rv = GetURI(getter_AddRefs(prinURI));
1448 if (NS_FAILED(rv) || !prinURI) {
1449 info = new dom::ReferrerInfo(nullptr);
1450 info.forget(_retval);
1451 return NS_OK;
1453 info = new dom::ReferrerInfo(prinURI, aReferrerPolicy);
1454 info.forget(_retval);
1455 return NS_OK;
1458 NS_IMETHODIMP
1459 BasePrincipal::GetPrecursorPrincipal(nsIPrincipal** aPrecursor) {
1460 *aPrecursor = nullptr;
1461 return NS_OK;
1464 NS_IMPL_ADDREF(BasePrincipal::Deserializer)
1465 NS_IMPL_RELEASE(BasePrincipal::Deserializer)
1467 NS_INTERFACE_MAP_BEGIN(BasePrincipal::Deserializer)
1468 NS_INTERFACE_MAP_ENTRY(nsISupports)
1469 NS_INTERFACE_MAP_ENTRY(nsISerializable)
1470 if (mPrincipal) {
1471 return mPrincipal->QueryInterface(aIID, aInstancePtr);
1472 } else
1473 NS_INTERFACE_MAP_END
1475 NS_IMETHODIMP
1476 BasePrincipal::Deserializer::Write(nsIObjectOutputStream* aStream) {
1477 // Read is used still for legacy principals
1478 MOZ_RELEASE_ASSERT(false, "Old style serialization is removed");
1479 return NS_OK;
1482 } // namespace mozilla