Bug 1728955: part 6) Log result of Windows' `OleSetClipboardResult`. r=masayuki
[gecko.git] / caps / BasePrincipal.cpp
blob3d7dd610e872917c57d63773726665abcf9d5a00
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=2 sw=2 et tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "mozilla/BasePrincipal.h"
9 #include "nsDocShell.h"
11 #include "ExpandedPrincipal.h"
12 #include "nsNetUtil.h"
13 #include "nsContentUtils.h"
14 #include "nsIOService.h"
15 #include "nsIURIWithSpecialOrigin.h"
16 #include "nsScriptSecurityManager.h"
17 #include "nsServiceManagerUtils.h"
18 #include "nsAboutProtocolUtils.h"
19 #include "ThirdPartyUtil.h"
20 #include "mozilla/ContentPrincipal.h"
21 #include "mozilla/NullPrincipal.h"
22 #include "mozilla/dom/BlobURLProtocolHandler.h"
23 #include "mozilla/dom/ChromeUtils.h"
24 #include "mozilla/dom/ReferrerInfo.h"
25 #include "mozilla/dom/ToJSValue.h"
26 #include "mozilla/dom/nsMixedContentBlocker.h"
27 #include "mozilla/Components.h"
28 #include "mozilla/dom/StorageUtils.h"
29 #include "mozilla/dom/StorageUtils.h"
30 #include "nsIURL.h"
31 #include "nsEffectiveTLDService.h"
32 #include "nsIURIMutator.h"
33 #include "mozilla/StaticPrefs_permissions.h"
34 #include "nsIURIMutator.h"
35 #include "prnetdb.h"
36 #include "nsIURIFixup.h"
37 #include "mozilla/dom/StorageUtils.h"
38 #include "mozilla/ContentBlocking.h"
39 #include "nsPIDOMWindow.h"
40 #include "nsIURIMutator.h"
41 #include "mozilla/PermissionManager.h"
43 #include "json/json.h"
44 #include "nsSerializationHelper.h"
46 namespace mozilla {
48 BasePrincipal::BasePrincipal(PrincipalKind aKind,
49 const nsACString& aOriginNoSuffix,
50 const OriginAttributes& aOriginAttributes)
51 : mOriginNoSuffix(NS_Atomize(aOriginNoSuffix)),
52 mOriginSuffix(aOriginAttributes.CreateSuffixAtom()),
53 mOriginAttributes(aOriginAttributes),
54 mKind(aKind),
55 mHasExplicitDomain(false) {}
57 BasePrincipal::BasePrincipal(BasePrincipal* aOther,
58 const OriginAttributes& aOriginAttributes)
59 : mOriginNoSuffix(aOther->mOriginNoSuffix),
60 mOriginSuffix(aOriginAttributes.CreateSuffixAtom()),
61 mOriginAttributes(aOriginAttributes),
62 mKind(aOther->mKind),
63 mHasExplicitDomain(aOther->mHasExplicitDomain) {}
65 BasePrincipal::~BasePrincipal() = default;
67 NS_IMETHODIMP
68 BasePrincipal::GetOrigin(nsACString& aOrigin) {
69 nsresult rv = GetOriginNoSuffix(aOrigin);
70 NS_ENSURE_SUCCESS(rv, rv);
72 nsAutoCString suffix;
73 rv = GetOriginSuffix(suffix);
74 NS_ENSURE_SUCCESS(rv, rv);
75 aOrigin.Append(suffix);
76 return NS_OK;
79 NS_IMETHODIMP
80 BasePrincipal::GetAsciiOrigin(nsACString& aOrigin) {
81 aOrigin.Truncate();
82 nsCOMPtr<nsIURI> prinURI;
83 nsresult rv = GetURI(getter_AddRefs(prinURI));
84 if (NS_FAILED(rv) || !prinURI) {
85 return NS_ERROR_NOT_AVAILABLE;
87 return nsContentUtils::GetASCIIOrigin(prinURI, aOrigin);
90 NS_IMETHODIMP
91 BasePrincipal::GetHostPort(nsACString& aRes) {
92 aRes.Truncate();
93 nsCOMPtr<nsIURI> prinURI;
94 nsresult rv = GetURI(getter_AddRefs(prinURI));
95 if (NS_FAILED(rv) || !prinURI) {
96 return NS_OK;
98 return prinURI->GetHostPort(aRes);
101 NS_IMETHODIMP
102 BasePrincipal::GetHost(nsACString& aRes) {
103 aRes.Truncate();
104 nsCOMPtr<nsIURI> prinURI;
105 nsresult rv = GetURI(getter_AddRefs(prinURI));
106 if (NS_FAILED(rv) || !prinURI) {
107 return NS_OK;
109 return prinURI->GetHost(aRes);
112 NS_IMETHODIMP
113 BasePrincipal::GetOriginNoSuffix(nsACString& aOrigin) {
114 mOriginNoSuffix->ToUTF8String(aOrigin);
115 return NS_OK;
118 NS_IMETHODIMP
119 BasePrincipal::GetSiteOrigin(nsACString& aSiteOrigin) {
120 nsresult rv = GetSiteOriginNoSuffix(aSiteOrigin);
121 NS_ENSURE_SUCCESS(rv, rv);
123 nsAutoCString suffix;
124 rv = GetOriginSuffix(suffix);
125 NS_ENSURE_SUCCESS(rv, rv);
126 aSiteOrigin.Append(suffix);
127 return NS_OK;
130 NS_IMETHODIMP
131 BasePrincipal::GetSiteOriginNoSuffix(nsACString& aSiteOrigin) {
132 return GetOriginNoSuffix(aSiteOrigin);
135 // Returns the inner Json::value of the serialized principal
136 // Example input and return values:
137 // Null principal:
138 // {"0":{"0":"moz-nullprincipal:{56cac540-864d-47e7-8e25-1614eab5155e}"}} ->
139 // {"0":"moz-nullprincipal:{56cac540-864d-47e7-8e25-1614eab5155e}"}
141 // Content principal:
142 // {"1":{"0":"https://mozilla.com"}} -> {"0":"https://mozilla.com"}
144 // Expanded principal:
145 // {"2":{"0":"<base64principal1>,<base64principal2>"}} ->
146 // {"0":"<base64principal1>,<base64principal2>"}
148 // System principal:
149 // {"3":{}} -> {}
150 // The aKey passed in also returns the corresponding PrincipalKind enum
152 // Warning: The Json::Value* pointer is into the aRoot object
153 static const Json::Value* GetPrincipalObject(const Json::Value& aRoot,
154 int& aOutPrincipalKind) {
155 const Json::Value::Members members = aRoot.getMemberNames();
156 // We only support one top level key in the object
157 if (members.size() != 1) {
158 return nullptr;
160 // members[0] here is the "0", "1", "2", "3" principalKind
161 // that is the top level of the serialized JSON principal
162 const std::string stringPrincipalKind = members[0];
164 // Next we take the string value from the JSON
165 // and convert it into the int for the BasePrincipal::PrincipalKind enum
167 // Verify that the key is within the valid range
168 int principalKind = std::stoi(stringPrincipalKind);
169 MOZ_ASSERT(BasePrincipal::eNullPrincipal == 0,
170 "We need to rely on 0 being a bounds check for the first "
171 "principal kind.");
172 if (principalKind < 0 || principalKind > BasePrincipal::eKindMax) {
173 return nullptr;
175 MOZ_ASSERT(principalKind == BasePrincipal::eNullPrincipal ||
176 principalKind == BasePrincipal::eContentPrincipal ||
177 principalKind == BasePrincipal::eExpandedPrincipal ||
178 principalKind == BasePrincipal::eSystemPrincipal);
179 aOutPrincipalKind = principalKind;
181 if (!aRoot[stringPrincipalKind].isObject()) {
182 return nullptr;
185 // Return the inner value of the principal object
186 return &aRoot[stringPrincipalKind];
189 // Accepts the JSON inner object without the wrapping principalKind
190 // (See GetPrincipalObject for the inner object response examples)
191 // Creates an array of KeyVal objects that are all defined on the principal
192 // Each principal type (null, content, expanded) has a KeyVal that stores the
193 // fields of the JSON
195 // This simplifies deserializing elsewhere as we do the checking for presence
196 // and string values here for the complete set of serializable keys that the
197 // corresponding principal supports.
199 // The KeyVal object has the following fields:
200 // - valueWasSerialized: is true if the deserialized JSON contained a string
201 // value
202 // - value: The string that was serialized for this key
203 // - key: an SerializableKeys enum value specific to the principal.
204 // For example content principal is an enum of: eURI, eDomain,
205 // eSuffix, eCSP
208 // Given an inner content principal:
209 // {"0": "https://mozilla.com", "2": "^privateBrowsingId=1"}
210 // | | | |
211 // ----------------------------- |
212 // | | |
213 // Key ----------------------
214 // |
215 // Value
217 // They Key "0" corresponds to ContentPrincipal::eURI
218 // They Key "1" corresponds to ContentPrincipal::eSuffix
219 template <typename T>
220 static nsTArray<typename T::KeyVal> GetJSONKeys(const Json::Value* aInput) {
221 int size = T::eMax + 1;
222 nsTArray<typename T::KeyVal> fields;
223 for (int i = 0; i != size; i++) {
224 typename T::KeyVal* field = fields.AppendElement();
225 // field->valueWasSerialized returns if the field was found in the
226 // deserialized code. This simplifies the consumers from having to check
227 // length.
228 field->valueWasSerialized = false;
229 field->key = static_cast<typename T::SerializableKeys>(i);
230 const std::string key = std::to_string(field->key);
231 if (aInput->isMember(key)) {
232 const Json::Value& val = (*aInput)[key];
233 if (val.isString()) {
234 field->value.Append(nsDependentCString(val.asCString()));
235 field->valueWasSerialized = true;
239 return fields;
242 // Takes a JSON string and parses it turning it into a principal of the
243 // corresponding type
245 // Given a content principal:
247 // inner JSON object
248 // |
249 // ---------------------------------------------------------
250 // | |
251 // {"1": {"0": "https://mozilla.com", "2": "^privateBrowsingId=1"}}
252 // | | | | |
253 // | ----------------------------- |
254 // | | | |
255 // PrincipalKind | | |
256 // | ----------------------------
257 // SerializableKeys |
258 // Value
260 // The string is first deserialized with jsoncpp to get the Json::Value of the
261 // object. The inner JSON object is parsed with GetPrincipalObject which returns
262 // a KeyVal array of the inner object's fields. PrincipalKind is returned by
263 // GetPrincipalObject which is then used to decide which principal
264 // implementation of FromProperties to call. The corresponding FromProperties
265 // call takes the KeyVal fields and turns it into a principal.
266 already_AddRefed<BasePrincipal> BasePrincipal::FromJSON(
267 const nsACString& aJSON) {
268 Json::Value root;
269 Json::CharReaderBuilder builder;
270 std::unique_ptr<Json::CharReader> const reader(builder.newCharReader());
271 bool parseSuccess =
272 reader->parse(aJSON.BeginReading(), aJSON.EndReading(), &root, nullptr);
273 if (!parseSuccess) {
274 MOZ_ASSERT(false,
275 "Unable to parse string as JSON to deserialize as a principal");
276 return nullptr;
279 int principalKind = -1;
280 const Json::Value* value = GetPrincipalObject(root, principalKind);
281 if (!value) {
282 #ifdef DEBUG
283 fprintf(stderr, "Unexpected JSON principal %s\n",
284 root.toStyledString().c_str());
285 #endif
286 MOZ_ASSERT(false, "Unexpected JSON to deserialize as a principal");
288 return nullptr;
290 MOZ_ASSERT(principalKind != -1,
291 "PrincipalKind should always be >=0 by this point");
293 if (principalKind == eSystemPrincipal) {
294 RefPtr<BasePrincipal> principal =
295 BasePrincipal::Cast(nsContentUtils::GetSystemPrincipal());
296 return principal.forget();
299 if (principalKind == eNullPrincipal) {
300 nsTArray<NullPrincipal::KeyVal> res = GetJSONKeys<NullPrincipal>(value);
301 return NullPrincipal::FromProperties(res);
304 if (principalKind == eContentPrincipal) {
305 nsTArray<ContentPrincipal::KeyVal> res =
306 GetJSONKeys<ContentPrincipal>(value);
307 return ContentPrincipal::FromProperties(res);
310 if (principalKind == eExpandedPrincipal) {
311 nsTArray<ExpandedPrincipal::KeyVal> res =
312 GetJSONKeys<ExpandedPrincipal>(value);
313 return ExpandedPrincipal::FromProperties(res);
316 MOZ_RELEASE_ASSERT(false, "Unexpected enum to deserialize as a principal");
319 nsresult BasePrincipal::PopulateJSONObject(Json::Value& aObject) {
320 return NS_OK;
323 // Returns a JSON representation of the principal.
324 // Calling BasePrincipal::FromJSON will deserialize the JSON into
325 // the corresponding principal type.
326 nsresult BasePrincipal::ToJSON(nsACString& aResult) {
327 MOZ_ASSERT(aResult.IsEmpty(), "ToJSON only supports an empty result input");
328 aResult.Truncate();
330 Json::StreamWriterBuilder builder;
331 builder["indentation"] = "";
332 Json::Value innerJSONObject = Json::objectValue;
334 nsresult rv = PopulateJSONObject(innerJSONObject);
335 NS_ENSURE_SUCCESS(rv, rv);
337 Json::Value root = Json::objectValue;
338 std::string key = std::to_string(Kind());
339 root[key] = innerJSONObject;
340 std::string result = Json::writeString(builder, root);
341 aResult.Append(result);
342 if (aResult.Length() == 0) {
343 MOZ_ASSERT(false, "JSON writer failed to output a principal serialization");
344 return NS_ERROR_UNEXPECTED;
346 return NS_OK;
349 bool BasePrincipal::FastSubsumesIgnoringFPD(
350 nsIPrincipal* aOther, DocumentDomainConsideration aConsideration) {
351 MOZ_ASSERT(aOther);
353 if (Kind() == eContentPrincipal &&
354 !dom::ChromeUtils::IsOriginAttributesEqualIgnoringFPD(
355 mOriginAttributes, Cast(aOther)->mOriginAttributes)) {
356 return false;
359 return SubsumesInternal(aOther, aConsideration);
362 bool BasePrincipal::Subsumes(nsIPrincipal* aOther,
363 DocumentDomainConsideration aConsideration) {
364 MOZ_ASSERT(aOther);
365 MOZ_ASSERT_IF(Kind() == eContentPrincipal, mOriginSuffix);
367 // Expanded principals handle origin attributes for each of their
368 // sub-principals individually, null principals do only simple checks for
369 // pointer equality, and system principals are immune to origin attributes
370 // checks, so only do this check for content principals.
371 if (Kind() == eContentPrincipal &&
372 mOriginSuffix != Cast(aOther)->mOriginSuffix) {
373 return false;
376 return SubsumesInternal(aOther, aConsideration);
379 NS_IMETHODIMP
380 BasePrincipal::Equals(nsIPrincipal* aOther, bool* aResult) {
381 NS_ENSURE_ARG_POINTER(aOther);
383 *aResult = FastEquals(aOther);
385 return NS_OK;
388 NS_IMETHODIMP
389 BasePrincipal::EqualsForPermission(nsIPrincipal* aOther, bool aExactHost,
390 bool* aResult) {
391 *aResult = false;
392 NS_ENSURE_ARG_POINTER(aOther);
393 NS_ENSURE_ARG_POINTER(aResult);
395 auto* other = Cast(aOther);
396 if (Kind() != other->Kind()) {
397 // Principals of different kinds can't be equal.
398 return NS_OK;
401 if (Kind() == eSystemPrincipal) {
402 *aResult = this == other;
403 return NS_OK;
406 if (Kind() == eNullPrincipal) {
407 // We don't store permissions for NullPrincipals.
408 return NS_OK;
411 MOZ_ASSERT(Kind() == eExpandedPrincipal || Kind() == eContentPrincipal);
413 // Certain origin attributes should not be used to isolate permissions.
414 // Create a stripped copy of both OA sets to compare.
415 mozilla::OriginAttributes ourAttrs = mOriginAttributes;
416 PermissionManager::MaybeStripOriginAttributes(false, ourAttrs);
417 mozilla::OriginAttributes theirAttrs = aOther->OriginAttributesRef();
418 PermissionManager::MaybeStripOriginAttributes(false, theirAttrs);
420 if (ourAttrs != theirAttrs) {
421 return NS_OK;
424 if (mOriginNoSuffix == other->mOriginNoSuffix) {
425 *aResult = true;
426 return NS_OK;
429 // If we are matching with an exact host, we're done now - the permissions
430 // don't match otherwise, we need to start comparing subdomains!
431 if (aExactHost) {
432 return NS_OK;
435 nsCOMPtr<nsIURI> ourURI;
436 nsresult rv = GetURI(getter_AddRefs(ourURI));
437 NS_ENSURE_SUCCESS(rv, rv);
438 // Some principal types may indicate success, but still return nullptr for
439 // URI.
440 NS_ENSURE_TRUE(ourURI, NS_ERROR_FAILURE);
442 nsCOMPtr<nsIURI> otherURI;
443 rv = other->GetURI(getter_AddRefs(otherURI));
444 NS_ENSURE_SUCCESS(rv, rv);
445 NS_ENSURE_TRUE(otherURI, NS_ERROR_FAILURE);
447 // Compare schemes
448 nsAutoCString otherScheme;
449 rv = otherURI->GetScheme(otherScheme);
450 NS_ENSURE_SUCCESS(rv, rv);
452 nsAutoCString ourScheme;
453 rv = ourURI->GetScheme(ourScheme);
454 NS_ENSURE_SUCCESS(rv, rv);
456 if (otherScheme != ourScheme) {
457 return NS_OK;
460 // Compare ports
461 int32_t otherPort;
462 rv = otherURI->GetPort(&otherPort);
463 NS_ENSURE_SUCCESS(rv, rv);
465 int32_t ourPort;
466 rv = ourURI->GetPort(&ourPort);
467 NS_ENSURE_SUCCESS(rv, rv);
469 if (otherPort != ourPort) {
470 return NS_OK;
473 // Check if the host or any subdomain of their host matches.
474 nsAutoCString otherHost;
475 rv = otherURI->GetHost(otherHost);
476 if (NS_FAILED(rv) || otherHost.IsEmpty()) {
477 return NS_OK;
480 nsAutoCString ourHost;
481 rv = ourURI->GetHost(ourHost);
482 if (NS_FAILED(rv) || ourHost.IsEmpty()) {
483 return NS_OK;
486 nsCOMPtr<nsIEffectiveTLDService> tldService =
487 do_GetService(NS_EFFECTIVETLDSERVICE_CONTRACTID);
488 if (!tldService) {
489 NS_ERROR("Should have a tld service!");
490 return NS_ERROR_FAILURE;
493 // This loop will not loop forever, as GetNextSubDomain will eventually fail
494 // with NS_ERROR_INSUFFICIENT_DOMAIN_LEVELS.
495 while (otherHost != ourHost) {
496 rv = tldService->GetNextSubDomain(otherHost, otherHost);
497 if (NS_FAILED(rv)) {
498 if (rv == NS_ERROR_INSUFFICIENT_DOMAIN_LEVELS) {
499 return NS_OK;
501 return rv;
505 *aResult = true;
506 return NS_OK;
509 NS_IMETHODIMP
510 BasePrincipal::EqualsConsideringDomain(nsIPrincipal* aOther, bool* aResult) {
511 NS_ENSURE_ARG_POINTER(aOther);
513 *aResult = FastEqualsConsideringDomain(aOther);
515 return NS_OK;
518 NS_IMETHODIMP
519 BasePrincipal::EqualsURI(nsIURI* aOtherURI, bool* aResult) {
520 *aResult = false;
521 nsCOMPtr<nsIURI> prinURI;
522 nsresult rv = GetURI(getter_AddRefs(prinURI));
523 if (NS_FAILED(rv) || !prinURI) {
524 return NS_OK;
526 return prinURI->EqualsExceptRef(aOtherURI, aResult);
529 NS_IMETHODIMP
530 BasePrincipal::Subsumes(nsIPrincipal* aOther, bool* aResult) {
531 NS_ENSURE_ARG_POINTER(aOther);
533 *aResult = FastSubsumes(aOther);
535 return NS_OK;
538 NS_IMETHODIMP
539 BasePrincipal::SubsumesConsideringDomain(nsIPrincipal* aOther, bool* aResult) {
540 NS_ENSURE_ARG_POINTER(aOther);
542 *aResult = FastSubsumesConsideringDomain(aOther);
544 return NS_OK;
547 NS_IMETHODIMP
548 BasePrincipal::SubsumesConsideringDomainIgnoringFPD(nsIPrincipal* aOther,
549 bool* aResult) {
550 NS_ENSURE_ARG_POINTER(aOther);
552 *aResult = FastSubsumesConsideringDomainIgnoringFPD(aOther);
554 return NS_OK;
557 NS_IMETHODIMP
558 BasePrincipal::CheckMayLoad(nsIURI* aURI, bool aAllowIfInheritsPrincipal) {
559 return CheckMayLoadHelper(aURI, aAllowIfInheritsPrincipal, false, 0);
562 NS_IMETHODIMP
563 BasePrincipal::CheckMayLoadWithReporting(nsIURI* aURI,
564 bool aAllowIfInheritsPrincipal,
565 uint64_t aInnerWindowID) {
566 return CheckMayLoadHelper(aURI, aAllowIfInheritsPrincipal, true,
567 aInnerWindowID);
570 nsresult BasePrincipal::CheckMayLoadHelper(nsIURI* aURI,
571 bool aAllowIfInheritsPrincipal,
572 bool aReport,
573 uint64_t aInnerWindowID) {
574 NS_ENSURE_ARG_POINTER(aURI);
575 MOZ_ASSERT(
576 aReport || aInnerWindowID == 0,
577 "Why do we have an inner window id if we're not supposed to report?");
579 // Check the internal method first, which allows us to quickly approve loads
580 // for the System Principal.
581 if (MayLoadInternal(aURI)) {
582 return NS_OK;
585 nsresult rv;
586 if (aAllowIfInheritsPrincipal) {
587 // If the caller specified to allow loads of URIs that inherit
588 // our principal, allow the load if this URI inherits its principal.
589 bool doesInheritSecurityContext;
590 rv = NS_URIChainHasFlags(aURI,
591 nsIProtocolHandler::URI_INHERITS_SECURITY_CONTEXT,
592 &doesInheritSecurityContext);
593 if (NS_SUCCEEDED(rv) && doesInheritSecurityContext) {
594 return NS_OK;
598 bool fetchableByAnyone;
599 rv = NS_URIChainHasFlags(aURI, nsIProtocolHandler::URI_FETCHABLE_BY_ANYONE,
600 &fetchableByAnyone);
601 if (NS_SUCCEEDED(rv) && fetchableByAnyone) {
602 return NS_OK;
605 if (aReport) {
606 nsCOMPtr<nsIURI> prinURI;
607 rv = GetURI(getter_AddRefs(prinURI));
608 if (NS_SUCCEEDED(rv) && prinURI) {
609 nsScriptSecurityManager::ReportError(
610 "CheckSameOriginError", prinURI, aURI,
611 mOriginAttributes.mPrivateBrowsingId > 0, aInnerWindowID);
615 return NS_ERROR_DOM_BAD_URI;
618 NS_IMETHODIMP
619 BasePrincipal::IsThirdPartyURI(nsIURI* aURI, bool* aRes) {
620 if (IsSystemPrincipal() || (AddonPolicy() && AddonAllowsLoad(aURI))) {
621 *aRes = false;
622 return NS_OK;
625 *aRes = true;
626 // If we do not have a URI its always 3rd party.
627 nsCOMPtr<nsIURI> prinURI;
628 nsresult rv = GetURI(getter_AddRefs(prinURI));
629 if (NS_FAILED(rv) || !prinURI) {
630 return NS_OK;
632 ThirdPartyUtil* thirdPartyUtil = ThirdPartyUtil::GetInstance();
633 return thirdPartyUtil->IsThirdPartyURI(prinURI, aURI, aRes);
636 NS_IMETHODIMP
637 BasePrincipal::IsThirdPartyPrincipal(nsIPrincipal* aPrin, bool* aRes) {
638 *aRes = true;
639 nsCOMPtr<nsIURI> prinURI;
640 nsresult rv = GetURI(getter_AddRefs(prinURI));
641 if (NS_FAILED(rv) || !prinURI) {
642 return NS_OK;
644 return aPrin->IsThirdPartyURI(prinURI, aRes);
646 NS_IMETHODIMP
647 BasePrincipal::IsThirdPartyChannel(nsIChannel* aChan, bool* aRes) {
648 if (IsSystemPrincipal()) {
649 // Nothing is 3rd party to the system principal.
650 *aRes = false;
651 return NS_OK;
654 nsCOMPtr<nsIURI> prinURI;
655 GetURI(getter_AddRefs(prinURI));
656 ThirdPartyUtil* thirdPartyUtil = ThirdPartyUtil::GetInstance();
657 return thirdPartyUtil->IsThirdPartyChannel(aChan, prinURI, aRes);
660 NS_IMETHODIMP
661 BasePrincipal::IsSameOrigin(nsIURI* aURI, bool aIsPrivateWin, bool* aRes) {
662 *aRes = false;
663 nsCOMPtr<nsIURI> prinURI;
664 nsresult rv = GetURI(getter_AddRefs(prinURI));
665 if (NS_FAILED(rv) || !prinURI) {
666 return NS_OK;
668 nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
669 if (!ssm) {
670 return NS_ERROR_UNEXPECTED;
672 *aRes = NS_SUCCEEDED(
673 ssm->CheckSameOriginURI(prinURI, aURI, false, aIsPrivateWin));
674 return NS_OK;
677 NS_IMETHODIMP
678 BasePrincipal::IsL10nAllowed(nsIURI* aURI, bool* aRes) {
679 *aRes = false;
681 if (nsContentUtils::IsErrorPage(aURI)) {
682 *aRes = true;
683 return NS_OK;
686 // The system principal is always allowed.
687 if (IsSystemPrincipal()) {
688 *aRes = true;
689 return NS_OK;
692 nsCOMPtr<nsIURI> uri;
693 nsresult rv = GetURI(getter_AddRefs(uri));
694 NS_ENSURE_SUCCESS(rv, NS_OK);
696 bool hasFlags;
698 // Allow access to uris that cannot be loaded by web content.
699 rv = NS_URIChainHasFlags(uri, nsIProtocolHandler::URI_DANGEROUS_TO_LOAD,
700 &hasFlags);
701 NS_ENSURE_SUCCESS(rv, NS_OK);
702 if (hasFlags) {
703 *aRes = true;
704 return NS_OK;
707 // UI resources also get access.
708 rv = NS_URIChainHasFlags(uri, nsIProtocolHandler::URI_IS_UI_RESOURCE,
709 &hasFlags);
710 NS_ENSURE_SUCCESS(rv, NS_OK);
711 if (hasFlags) {
712 *aRes = true;
713 return NS_OK;
716 auto policy = AddonPolicy();
717 *aRes = (policy && policy->IsPrivileged());
718 return NS_OK;
721 NS_IMETHODIMP
722 BasePrincipal::AllowsRelaxStrictFileOriginPolicy(nsIURI* aURI, bool* aRes) {
723 *aRes = false;
724 nsCOMPtr<nsIURI> prinURI;
725 nsresult rv = GetURI(getter_AddRefs(prinURI));
726 if (NS_FAILED(rv) || !prinURI) {
727 return NS_OK;
729 *aRes = NS_RelaxStrictFileOriginPolicy(aURI, prinURI);
730 return NS_OK;
733 NS_IMETHODIMP
734 BasePrincipal::GetPrefLightCacheKey(nsIURI* aURI, bool aWithCredentials,
735 const OriginAttributes& aOriginAttributes,
736 nsACString& _retval) {
737 _retval.Truncate();
738 constexpr auto space = " "_ns;
740 nsCOMPtr<nsIURI> uri;
741 nsresult rv = GetURI(getter_AddRefs(uri));
742 NS_ENSURE_SUCCESS(rv, rv);
744 nsAutoCString scheme, host, port;
745 if (uri) {
746 uri->GetScheme(scheme);
747 uri->GetHost(host);
748 port.AppendInt(NS_GetRealPort(uri));
751 if (aWithCredentials) {
752 _retval.AssignLiteral("cred");
753 } else {
754 _retval.AssignLiteral("nocred");
757 nsAutoCString spec;
758 rv = aURI->GetSpec(spec);
759 NS_ENSURE_SUCCESS(rv, rv);
761 nsAutoCString originAttributesSuffix;
762 aOriginAttributes.CreateSuffix(originAttributesSuffix);
764 _retval.Append(space + scheme + space + host + space + port + space + spec +
765 space + originAttributesSuffix);
767 return NS_OK;
770 NS_IMETHODIMP
771 BasePrincipal::HasFirstpartyStorageAccess(mozIDOMWindow* aCheckWindow,
772 uint32_t* aRejectedReason,
773 bool* aOutAllowed) {
774 *aRejectedReason = 0;
775 *aOutAllowed = false;
777 nsPIDOMWindowInner* win = nsPIDOMWindowInner::From(aCheckWindow);
778 nsCOMPtr<nsIURI> uri;
779 nsresult rv = GetURI(getter_AddRefs(uri));
780 if (NS_FAILED(rv)) {
781 return rv;
783 *aOutAllowed =
784 ContentBlocking::ShouldAllowAccessFor(win, uri, aRejectedReason);
785 return NS_OK;
788 NS_IMETHODIMP
789 BasePrincipal::GetIsNullPrincipal(bool* aResult) {
790 *aResult = Kind() == eNullPrincipal;
791 return NS_OK;
794 NS_IMETHODIMP
795 BasePrincipal::GetIsContentPrincipal(bool* aResult) {
796 *aResult = Kind() == eContentPrincipal;
797 return NS_OK;
800 NS_IMETHODIMP
801 BasePrincipal::GetIsExpandedPrincipal(bool* aResult) {
802 *aResult = Kind() == eExpandedPrincipal;
803 return NS_OK;
806 NS_IMETHODIMP
807 BasePrincipal::GetAsciiSpec(nsACString& aSpec) {
808 aSpec.Truncate();
809 nsCOMPtr<nsIURI> prinURI;
810 nsresult rv = GetURI(getter_AddRefs(prinURI));
811 if (NS_FAILED(rv) || !prinURI) {
812 return NS_OK;
814 return prinURI->GetAsciiSpec(aSpec);
817 NS_IMETHODIMP
818 BasePrincipal::GetSpec(nsACString& aSpec) {
819 aSpec.Truncate();
820 nsCOMPtr<nsIURI> prinURI;
821 nsresult rv = GetURI(getter_AddRefs(prinURI));
822 if (NS_FAILED(rv) || !prinURI) {
823 return NS_OK;
825 return prinURI->GetSpec(aSpec);
828 NS_IMETHODIMP
829 BasePrincipal::GetAsciiHost(nsACString& aHost) {
830 aHost.Truncate();
831 nsCOMPtr<nsIURI> prinURI;
832 nsresult rv = GetURI(getter_AddRefs(prinURI));
833 if (NS_FAILED(rv) || !prinURI) {
834 return NS_OK;
836 return prinURI->GetAsciiHost(aHost);
839 NS_IMETHODIMP
840 BasePrincipal::GetExposablePrePath(nsACString& aPrepath) {
841 aPrepath.Truncate();
842 nsCOMPtr<nsIURI> prinURI;
843 nsresult rv = GetURI(getter_AddRefs(prinURI));
844 if (NS_FAILED(rv) || !prinURI) {
845 return NS_OK;
848 nsCOMPtr<nsIURI> exposableURI = net::nsIOService::CreateExposableURI(prinURI);
849 return exposableURI->GetDisplayPrePath(aPrepath);
852 NS_IMETHODIMP
853 BasePrincipal::GetExposableSpec(nsACString& aSpec) {
854 aSpec.Truncate();
855 nsCOMPtr<nsIURI> prinURI;
856 nsresult rv = GetURI(getter_AddRefs(prinURI));
857 if (NS_FAILED(rv) || !prinURI) {
858 return NS_OK;
860 nsCOMPtr<nsIURI> clone;
861 rv = NS_MutateURI(prinURI)
862 .SetQuery(""_ns)
863 .SetRef(""_ns)
864 .SetUserPass(""_ns)
865 .Finalize(clone);
866 NS_ENSURE_SUCCESS(rv, rv);
867 return clone->GetAsciiSpec(aSpec);
870 NS_IMETHODIMP
871 BasePrincipal::GetPrePath(nsACString& aPath) {
872 aPath.Truncate();
873 nsCOMPtr<nsIURI> prinURI;
874 nsresult rv = GetURI(getter_AddRefs(prinURI));
875 if (NS_FAILED(rv) || !prinURI) {
876 return NS_OK;
878 return prinURI->GetPrePath(aPath);
881 NS_IMETHODIMP
882 BasePrincipal::GetFilePath(nsACString& aPath) {
883 aPath.Truncate();
884 nsCOMPtr<nsIURI> prinURI;
885 nsresult rv = GetURI(getter_AddRefs(prinURI));
886 if (NS_FAILED(rv) || !prinURI) {
887 return NS_OK;
889 return prinURI->GetFilePath(aPath);
892 NS_IMETHODIMP
893 BasePrincipal::GetIsSystemPrincipal(bool* aResult) {
894 *aResult = IsSystemPrincipal();
895 return NS_OK;
898 NS_IMETHODIMP
899 BasePrincipal::GetIsAddonOrExpandedAddonPrincipal(bool* aResult) {
900 *aResult = AddonPolicy() || ContentScriptAddonPolicy();
901 return NS_OK;
904 NS_IMETHODIMP BasePrincipal::GetIsOnion(bool* aIsOnion) {
905 *aIsOnion = false;
906 nsCOMPtr<nsIURI> prinURI;
907 nsresult rv = GetURI(getter_AddRefs(prinURI));
908 if (NS_FAILED(rv) || !prinURI) {
909 return NS_OK;
912 nsAutoCString host;
913 rv = prinURI->GetHost(host);
914 if (NS_FAILED(rv)) {
915 return NS_OK;
917 *aIsOnion = StringEndsWith(host, ".onion"_ns);
918 return NS_OK;
921 NS_IMETHODIMP BasePrincipal::GetIsIpAddress(bool* aIsIpAddress) {
922 *aIsIpAddress = false;
924 nsCOMPtr<nsIURI> prinURI;
925 nsresult rv = GetURI(getter_AddRefs(prinURI));
926 if (NS_FAILED(rv) || !prinURI) {
927 return NS_OK;
930 nsAutoCString host;
931 rv = prinURI->GetHost(host);
932 if (NS_FAILED(rv)) {
933 return NS_OK;
936 PRNetAddr prAddr;
937 memset(&prAddr, 0, sizeof(prAddr));
939 if (PR_StringToNetAddr(host.get(), &prAddr) == PR_SUCCESS) {
940 *aIsIpAddress = true;
943 return NS_OK;
946 NS_IMETHODIMP BasePrincipal::GetIsLocalIpAddress(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 nsCOMPtr<nsIIOService> ioService = do_GetIOService(&rv);
956 if (NS_FAILED(rv) || !ioService) {
957 return NS_OK;
959 rv = ioService->HostnameIsLocalIPAddress(prinURI, aIsIpAddress);
960 if (NS_FAILED(rv)) {
961 *aIsIpAddress = false;
963 return NS_OK;
966 NS_IMETHODIMP
967 BasePrincipal::GetScheme(nsACString& aScheme) {
968 aScheme.Truncate();
970 nsCOMPtr<nsIURI> prinURI;
971 nsresult rv = GetURI(getter_AddRefs(prinURI));
972 if (NS_FAILED(rv) || !prinURI) {
973 return NS_OK;
976 return prinURI->GetScheme(aScheme);
979 NS_IMETHODIMP
980 BasePrincipal::SchemeIs(const char* aScheme, bool* aResult) {
981 *aResult = false;
982 nsCOMPtr<nsIURI> prinURI;
983 nsresult rv = GetURI(getter_AddRefs(prinURI));
984 if (NS_FAILED(rv) || !prinURI) {
985 return NS_OK;
987 *aResult = prinURI->SchemeIs(aScheme);
988 return NS_OK;
991 NS_IMETHODIMP
992 BasePrincipal::IsURIInPrefList(const char* aPref, bool* aResult) {
993 *aResult = false;
994 nsCOMPtr<nsIURI> prinURI;
995 nsresult rv = GetURI(getter_AddRefs(prinURI));
996 if (NS_FAILED(rv) || !prinURI) {
997 return NS_OK;
999 *aResult = nsContentUtils::IsURIInPrefList(prinURI, aPref);
1000 return NS_OK;
1003 NS_IMETHODIMP
1004 BasePrincipal::GetIsOriginPotentiallyTrustworthy(bool* aResult) {
1005 MOZ_ASSERT(NS_IsMainThread());
1006 *aResult = false;
1008 nsCOMPtr<nsIURI> uri;
1009 nsresult rv = GetURI(getter_AddRefs(uri));
1010 if (NS_FAILED(rv) || !uri) {
1011 return NS_OK;
1014 *aResult = nsMixedContentBlocker::IsPotentiallyTrustworthyOrigin(uri);
1015 return NS_OK;
1018 NS_IMETHODIMP
1019 BasePrincipal::GetAboutModuleFlags(uint32_t* flags) {
1020 *flags = 0;
1021 nsCOMPtr<nsIURI> prinURI;
1022 nsresult rv = GetURI(getter_AddRefs(prinURI));
1023 if (NS_FAILED(rv) || !prinURI) {
1024 return NS_ERROR_NOT_AVAILABLE;
1026 if (!prinURI->SchemeIs("about")) {
1027 return NS_OK;
1030 nsCOMPtr<nsIAboutModule> aboutModule;
1031 rv = NS_GetAboutModule(prinURI, getter_AddRefs(aboutModule));
1032 if (NS_FAILED(rv) || !aboutModule) {
1033 return rv;
1035 return aboutModule->GetURIFlags(prinURI, flags);
1038 NS_IMETHODIMP
1039 BasePrincipal::GetOriginAttributes(JSContext* aCx,
1040 JS::MutableHandle<JS::Value> aVal) {
1041 if (NS_WARN_IF(!ToJSValue(aCx, mOriginAttributes, aVal))) {
1042 return NS_ERROR_FAILURE;
1044 return NS_OK;
1047 NS_IMETHODIMP
1048 BasePrincipal::GetOriginSuffix(nsACString& aOriginAttributes) {
1049 MOZ_ASSERT(mOriginSuffix);
1050 mOriginSuffix->ToUTF8String(aOriginAttributes);
1051 return NS_OK;
1054 NS_IMETHODIMP
1055 BasePrincipal::GetUserContextId(uint32_t* aUserContextId) {
1056 *aUserContextId = UserContextId();
1057 return NS_OK;
1060 NS_IMETHODIMP
1061 BasePrincipal::GetPrivateBrowsingId(uint32_t* aPrivateBrowsingId) {
1062 *aPrivateBrowsingId = PrivateBrowsingId();
1063 return NS_OK;
1066 NS_IMETHODIMP
1067 BasePrincipal::GetIsInIsolatedMozBrowserElement(
1068 bool* aIsInIsolatedMozBrowserElement) {
1069 *aIsInIsolatedMozBrowserElement = IsInIsolatedMozBrowserElement();
1070 return NS_OK;
1073 nsresult BasePrincipal::GetAddonPolicy(
1074 extensions::WebExtensionPolicy** aResult) {
1075 RefPtr<extensions::WebExtensionPolicy> policy(AddonPolicy());
1076 policy.forget(aResult);
1077 return NS_OK;
1080 extensions::WebExtensionPolicy* BasePrincipal::AddonPolicy() {
1081 if (Is<ContentPrincipal>()) {
1082 return As<ContentPrincipal>()->AddonPolicy();
1084 return nullptr;
1087 bool BasePrincipal::AddonHasPermission(const nsAtom* aPerm) {
1088 if (auto policy = AddonPolicy()) {
1089 return policy->HasPermission(aPerm);
1091 return false;
1094 nsIPrincipal* BasePrincipal::PrincipalToInherit(nsIURI* aRequestedURI) {
1095 if (Is<ExpandedPrincipal>()) {
1096 return As<ExpandedPrincipal>()->PrincipalToInherit(aRequestedURI);
1098 return this;
1101 already_AddRefed<BasePrincipal> BasePrincipal::CreateContentPrincipal(
1102 nsIURI* aURI, const OriginAttributes& aAttrs) {
1103 MOZ_ASSERT(aURI);
1105 nsAutoCString originNoSuffix;
1106 nsresult rv =
1107 ContentPrincipal::GenerateOriginNoSuffixFromURI(aURI, originNoSuffix);
1108 if (NS_FAILED(rv)) {
1109 // If the generation of the origin fails, we still want to have a valid
1110 // principal. Better to return a null principal here.
1111 return NullPrincipal::Create(aAttrs);
1114 return CreateContentPrincipal(aURI, aAttrs, originNoSuffix);
1117 already_AddRefed<BasePrincipal> BasePrincipal::CreateContentPrincipal(
1118 nsIURI* aURI, const OriginAttributes& aAttrs,
1119 const nsACString& aOriginNoSuffix) {
1120 MOZ_ASSERT(aURI);
1121 MOZ_ASSERT(!aOriginNoSuffix.IsEmpty());
1123 // If the URI is supposed to inherit the security context of whoever loads it,
1124 // we shouldn't make a content principal for it.
1125 bool inheritsPrincipal;
1126 nsresult rv = NS_URIChainHasFlags(
1127 aURI, nsIProtocolHandler::URI_INHERITS_SECURITY_CONTEXT,
1128 &inheritsPrincipal);
1129 if (NS_FAILED(rv) || inheritsPrincipal) {
1130 return NullPrincipal::Create(aAttrs);
1133 // Check whether the URI knows what its principal is supposed to be.
1134 #if defined(MOZ_THUNDERBIRD) || defined(MOZ_SUITE)
1135 nsCOMPtr<nsIURIWithSpecialOrigin> uriWithSpecialOrigin =
1136 do_QueryInterface(aURI);
1137 if (uriWithSpecialOrigin) {
1138 nsCOMPtr<nsIURI> origin;
1139 rv = uriWithSpecialOrigin->GetOrigin(getter_AddRefs(origin));
1140 if (NS_WARN_IF(NS_FAILED(rv))) {
1141 return nullptr;
1143 MOZ_ASSERT(origin);
1144 OriginAttributes attrs;
1145 RefPtr<BasePrincipal> principal = CreateContentPrincipal(origin, attrs);
1146 return principal.forget();
1148 #endif
1150 nsCOMPtr<nsIPrincipal> blobPrincipal;
1151 if (dom::BlobURLProtocolHandler::GetBlobURLPrincipal(
1152 aURI, getter_AddRefs(blobPrincipal))) {
1153 MOZ_ASSERT(blobPrincipal);
1154 RefPtr<BasePrincipal> principal = Cast(blobPrincipal);
1155 return principal.forget();
1158 // Mint a content principal.
1159 RefPtr<ContentPrincipal> principal =
1160 new ContentPrincipal(aURI, aAttrs, aOriginNoSuffix);
1161 return principal.forget();
1164 already_AddRefed<BasePrincipal> BasePrincipal::CreateContentPrincipal(
1165 const nsACString& aOrigin) {
1166 MOZ_ASSERT(!StringBeginsWith(aOrigin, "["_ns),
1167 "CreateContentPrincipal does not support System and Expanded "
1168 "principals");
1170 MOZ_ASSERT(
1171 !StringBeginsWith(aOrigin, nsLiteralCString(NS_NULLPRINCIPAL_SCHEME ":")),
1172 "CreateContentPrincipal does not support NullPrincipal");
1174 nsAutoCString originNoSuffix;
1175 OriginAttributes attrs;
1176 if (!attrs.PopulateFromOrigin(aOrigin, originNoSuffix)) {
1177 return nullptr;
1180 nsCOMPtr<nsIURI> uri;
1181 nsresult rv = NS_NewURI(getter_AddRefs(uri), originNoSuffix);
1182 NS_ENSURE_SUCCESS(rv, nullptr);
1184 return BasePrincipal::CreateContentPrincipal(uri, attrs);
1187 already_AddRefed<BasePrincipal> BasePrincipal::CloneForcingOriginAttributes(
1188 const OriginAttributes& aOriginAttributes) {
1189 if (NS_WARN_IF(!IsContentPrincipal())) {
1190 return nullptr;
1193 nsAutoCString originNoSuffix;
1194 nsresult rv = GetOriginNoSuffix(originNoSuffix);
1195 NS_ENSURE_SUCCESS(rv, nullptr);
1197 nsCOMPtr<nsIURI> uri;
1198 MOZ_ALWAYS_SUCCEEDS(GetURI(getter_AddRefs(uri)));
1200 RefPtr<ContentPrincipal> copy =
1201 new ContentPrincipal(uri, aOriginAttributes, originNoSuffix);
1202 return copy.forget();
1205 extensions::WebExtensionPolicy* BasePrincipal::ContentScriptAddonPolicy() {
1206 if (!Is<ExpandedPrincipal>()) {
1207 return nullptr;
1210 auto expanded = As<ExpandedPrincipal>();
1211 for (auto& prin : expanded->AllowList()) {
1212 if (auto policy = BasePrincipal::Cast(prin)->AddonPolicy()) {
1213 return policy;
1217 return nullptr;
1220 bool BasePrincipal::AddonAllowsLoad(nsIURI* aURI,
1221 bool aExplicit /* = false */) {
1222 if (Is<ExpandedPrincipal>()) {
1223 return As<ExpandedPrincipal>()->AddonAllowsLoad(aURI, aExplicit);
1225 if (auto policy = AddonPolicy()) {
1226 return policy->CanAccessURI(aURI, aExplicit);
1228 return false;
1231 NS_IMETHODIMP
1232 BasePrincipal::GetLocalStorageQuotaKey(nsACString& aKey) {
1233 aKey.Truncate();
1235 nsCOMPtr<nsIURI> uri;
1236 nsresult rv = GetURI(getter_AddRefs(uri));
1237 NS_ENSURE_SUCCESS(rv, rv);
1238 NS_ENSURE_TRUE(uri, NS_ERROR_UNEXPECTED);
1240 // The special handling of the file scheme should be consistent with
1241 // GetStorageOriginKey.
1243 nsAutoCString baseDomain;
1244 rv = uri->GetAsciiHost(baseDomain);
1245 NS_ENSURE_SUCCESS(rv, rv);
1247 if (baseDomain.IsEmpty() && uri->SchemeIs("file")) {
1248 nsCOMPtr<nsIURL> url = do_QueryInterface(uri, &rv);
1249 NS_ENSURE_SUCCESS(rv, rv);
1251 rv = url->GetDirectory(baseDomain);
1252 NS_ENSURE_SUCCESS(rv, rv);
1253 } else {
1254 nsCOMPtr<nsIEffectiveTLDService> eTLDService(
1255 do_GetService(NS_EFFECTIVETLDSERVICE_CONTRACTID, &rv));
1256 NS_ENSURE_SUCCESS(rv, rv);
1258 nsAutoCString eTLDplusOne;
1259 rv = eTLDService->GetBaseDomain(uri, 0, eTLDplusOne);
1260 if (NS_SUCCEEDED(rv)) {
1261 baseDomain = eTLDplusOne;
1262 } else if (rv == NS_ERROR_HOST_IS_IP_ADDRESS ||
1263 rv == NS_ERROR_INSUFFICIENT_DOMAIN_LEVELS) {
1264 rv = NS_OK;
1266 NS_ENSURE_SUCCESS(rv, rv);
1269 OriginAttributesRef().CreateSuffix(aKey);
1271 nsAutoCString subdomainsDBKey;
1272 rv = dom::StorageUtils::CreateReversedDomain(baseDomain, subdomainsDBKey);
1273 NS_ENSURE_SUCCESS(rv, rv);
1275 aKey.Append(':');
1276 aKey.Append(subdomainsDBKey);
1278 return NS_OK;
1281 NS_IMETHODIMP
1282 BasePrincipal::GetNextSubDomainPrincipal(
1283 nsIPrincipal** aNextSubDomainPrincipal) {
1284 nsCOMPtr<nsIURI> uri;
1285 nsresult rv = GetURI(getter_AddRefs(uri));
1286 if (NS_FAILED(rv) || !uri) {
1287 return NS_OK;
1290 nsAutoCString host;
1291 rv = uri->GetHost(host);
1292 if (NS_FAILED(rv) || host.IsEmpty()) {
1293 return NS_OK;
1296 nsCString subDomain;
1297 rv = nsEffectiveTLDService::GetInstance()->GetNextSubDomain(host, subDomain);
1299 if (NS_FAILED(rv) || subDomain.IsEmpty()) {
1300 return NS_OK;
1303 nsCOMPtr<nsIURI> subDomainURI;
1304 rv = NS_MutateURI(uri).SetHost(subDomain).Finalize(subDomainURI);
1305 if (NS_FAILED(rv) || !subDomainURI) {
1306 return NS_OK;
1308 // Copy the attributes over
1309 mozilla::OriginAttributes attrs = OriginAttributesRef();
1311 if (!StaticPrefs::permissions_isolateBy_userContext()) {
1312 // Disable userContext for permissions.
1313 attrs.StripAttributes(mozilla::OriginAttributes::STRIP_USER_CONTEXT_ID);
1315 RefPtr<nsIPrincipal> principal =
1316 mozilla::BasePrincipal::CreateContentPrincipal(subDomainURI, attrs);
1318 if (!principal) {
1319 return NS_OK;
1321 principal.forget(aNextSubDomainPrincipal);
1322 return NS_OK;
1325 NS_IMETHODIMP
1326 BasePrincipal::GetStorageOriginKey(nsACString& aOriginKey) {
1327 aOriginKey.Truncate();
1329 nsCOMPtr<nsIURI> uri;
1330 nsresult rv = GetURI(getter_AddRefs(uri));
1331 NS_ENSURE_SUCCESS(rv, rv);
1332 NS_ENSURE_TRUE(uri, NS_ERROR_UNEXPECTED);
1334 // The special handling of the file scheme should be consistent with
1335 // GetLocalStorageQuotaKey.
1337 nsAutoCString domainOrigin;
1338 rv = uri->GetAsciiHost(domainOrigin);
1339 NS_ENSURE_SUCCESS(rv, rv);
1341 if (domainOrigin.IsEmpty()) {
1342 // For the file:/// protocol use the exact directory as domain.
1343 if (uri->SchemeIs("file")) {
1344 nsCOMPtr<nsIURL> url = do_QueryInterface(uri, &rv);
1345 NS_ENSURE_SUCCESS(rv, rv);
1346 rv = url->GetDirectory(domainOrigin);
1347 NS_ENSURE_SUCCESS(rv, rv);
1351 // Append reversed domain
1352 nsAutoCString reverseDomain;
1353 rv = dom::StorageUtils::CreateReversedDomain(domainOrigin, reverseDomain);
1354 NS_ENSURE_SUCCESS(rv, rv);
1356 aOriginKey.Append(reverseDomain);
1358 // Append scheme
1359 nsAutoCString scheme;
1360 rv = uri->GetScheme(scheme);
1361 NS_ENSURE_SUCCESS(rv, rv);
1363 aOriginKey.Append(':');
1364 aOriginKey.Append(scheme);
1366 // Append port if any
1367 int32_t port = NS_GetRealPort(uri);
1368 if (port != -1) {
1369 aOriginKey.Append(nsPrintfCString(":%d", port));
1372 return NS_OK;
1375 NS_IMETHODIMP
1376 BasePrincipal::GetIsScriptAllowedByPolicy(bool* aIsScriptAllowedByPolicy) {
1377 *aIsScriptAllowedByPolicy = false;
1378 nsCOMPtr<nsIURI> prinURI;
1379 nsresult rv = GetURI(getter_AddRefs(prinURI));
1380 if (NS_FAILED(rv) || !prinURI) {
1381 return NS_OK;
1383 nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
1384 if (!ssm) {
1385 return NS_ERROR_UNEXPECTED;
1387 return ssm->PolicyAllowsScript(prinURI, aIsScriptAllowedByPolicy);
1390 bool SiteIdentifier::Equals(const SiteIdentifier& aOther) const {
1391 MOZ_ASSERT(IsInitialized());
1392 MOZ_ASSERT(aOther.IsInitialized());
1393 return mPrincipal->FastEquals(aOther.mPrincipal);
1396 NS_IMETHODIMP
1397 BasePrincipal::CreateReferrerInfo(mozilla::dom::ReferrerPolicy aReferrerPolicy,
1398 nsIReferrerInfo** _retval) {
1399 nsCOMPtr<nsIURI> prinURI;
1400 RefPtr<dom::ReferrerInfo> info;
1401 nsresult rv = GetURI(getter_AddRefs(prinURI));
1402 if (NS_FAILED(rv) || !prinURI) {
1403 info = new dom::ReferrerInfo(nullptr);
1404 info.forget(_retval);
1405 return NS_OK;
1407 info = new dom::ReferrerInfo(prinURI, aReferrerPolicy);
1408 info.forget(_retval);
1409 return NS_OK;
1412 NS_IMETHODIMP
1413 BasePrincipal::GetPrecursorPrincipal(nsIPrincipal** aPrecursor) {
1414 *aPrecursor = nullptr;
1415 return NS_OK;
1418 NS_IMPL_ADDREF(BasePrincipal::Deserializer)
1419 NS_IMPL_RELEASE(BasePrincipal::Deserializer)
1421 NS_INTERFACE_MAP_BEGIN(BasePrincipal::Deserializer)
1422 NS_INTERFACE_MAP_ENTRY(nsISupports)
1423 NS_INTERFACE_MAP_ENTRY(nsISerializable)
1424 if (mPrincipal) {
1425 return mPrincipal->QueryInterface(aIID, aInstancePtr);
1426 } else
1427 NS_INTERFACE_MAP_END
1429 NS_IMETHODIMP
1430 BasePrincipal::Deserializer::Write(nsIObjectOutputStream* aStream) {
1431 // Read is used still for legacy principals
1432 MOZ_RELEASE_ASSERT(false, "Old style serialization is removed");
1433 return NS_OK;
1436 } // namespace mozilla