Bug 1758813 [wpt PR 33142] - Implement RP sign out, a=testonly
[gecko.git] / ipc / glue / BackgroundUtils.cpp
blobebeab035cea87743d0e35fed16572dd3c241f340
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 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 file,
5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "BackgroundUtils.h"
9 #include "MainThreadUtils.h"
10 #include "mozilla/Assertions.h"
11 #include "mozilla/BasePrincipal.h"
12 #include "mozilla/ContentPrincipal.h"
13 #include "mozilla/NullPrincipal.h"
14 #include "mozilla/ipc/PBackgroundSharedTypes.h"
15 #include "mozilla/ipc/URIUtils.h"
16 #include "mozilla/net/CookieJarSettings.h"
17 #include "mozilla/net/NeckoChannelParams.h"
18 #include "ExpandedPrincipal.h"
19 #include "nsIScriptSecurityManager.h"
20 #include "nsIURI.h"
21 #include "nsNetUtil.h"
22 #include "mozilla/LoadInfo.h"
23 #include "nsContentUtils.h"
24 #include "nsString.h"
25 #include "nsTArray.h"
26 #include "mozilla/nsRedirectHistoryEntry.h"
27 #include "mozilla/dom/nsCSPUtils.h"
28 #include "mozilla/dom/nsCSPContext.h"
29 #include "mozilla/dom/BrowsingContext.h"
30 #include "mozilla/dom/CanonicalBrowsingContext.h"
31 #include "mozilla/dom/Document.h"
32 #include "mozilla/dom/WindowGlobalParent.h"
33 #include "mozilla/LoadInfo.h"
35 using namespace mozilla::dom;
36 using namespace mozilla::net;
38 namespace mozilla {
40 namespace ipc {
42 Result<nsCOMPtr<nsIPrincipal>, nsresult> PrincipalInfoToPrincipal(
43 const PrincipalInfo& aPrincipalInfo) {
44 MOZ_ASSERT(NS_IsMainThread());
45 MOZ_ASSERT(aPrincipalInfo.type() != PrincipalInfo::T__None);
47 nsCOMPtr<nsIScriptSecurityManager> secMan =
48 nsContentUtils::GetSecurityManager();
49 if (!secMan) {
50 return Err(NS_ERROR_NULL_POINTER);
53 nsCOMPtr<nsIPrincipal> principal;
54 nsresult rv;
56 switch (aPrincipalInfo.type()) {
57 case PrincipalInfo::TSystemPrincipalInfo: {
58 rv = secMan->GetSystemPrincipal(getter_AddRefs(principal));
59 if (NS_WARN_IF(NS_FAILED(rv))) {
60 return Err(rv);
63 return principal;
66 case PrincipalInfo::TNullPrincipalInfo: {
67 const NullPrincipalInfo& info = aPrincipalInfo.get_NullPrincipalInfo();
69 nsCOMPtr<nsIURI> uri;
70 rv = NS_NewURI(getter_AddRefs(uri), info.spec());
71 if (NS_WARN_IF(NS_FAILED(rv))) {
72 return Err(rv);
75 if (!uri->SchemeIs(NS_NULLPRINCIPAL_SCHEME)) {
76 return Err(NS_ERROR_ILLEGAL_VALUE);
79 principal = NullPrincipal::Create(info.attrs(), uri);
80 return principal;
83 case PrincipalInfo::TContentPrincipalInfo: {
84 const ContentPrincipalInfo& info =
85 aPrincipalInfo.get_ContentPrincipalInfo();
87 nsCOMPtr<nsIURI> uri;
88 rv = NS_NewURI(getter_AddRefs(uri), info.spec());
89 if (NS_WARN_IF(NS_FAILED(rv))) {
90 return Err(rv);
93 principal = BasePrincipal::CreateContentPrincipal(uri, info.attrs());
94 if (NS_WARN_IF(!principal)) {
95 return Err(NS_ERROR_NULL_POINTER);
98 // Origin must match what the_new_principal.getOrigin returns.
99 nsAutoCString originNoSuffix;
100 rv = principal->GetOriginNoSuffix(originNoSuffix);
101 if (NS_WARN_IF(NS_FAILED(rv))) {
102 return Err(rv);
105 if (NS_WARN_IF(!info.originNoSuffix().Equals(originNoSuffix))) {
106 return Err(NS_ERROR_FAILURE);
109 if (info.domain()) {
110 nsCOMPtr<nsIURI> domain;
111 rv = NS_NewURI(getter_AddRefs(domain), *info.domain());
112 if (NS_WARN_IF(NS_FAILED(rv))) {
113 return Err(rv);
116 rv = principal->SetDomain(domain);
117 if (NS_WARN_IF(NS_FAILED(rv))) {
118 return Err(rv);
122 if (!info.baseDomain().IsVoid()) {
123 nsAutoCString baseDomain;
124 rv = principal->GetBaseDomain(baseDomain);
125 if (NS_WARN_IF(NS_FAILED(rv))) {
126 return Err(rv);
129 if (NS_WARN_IF(!info.baseDomain().Equals(baseDomain))) {
130 return Err(NS_ERROR_FAILURE);
133 return principal;
136 case PrincipalInfo::TExpandedPrincipalInfo: {
137 const ExpandedPrincipalInfo& info =
138 aPrincipalInfo.get_ExpandedPrincipalInfo();
140 nsTArray<nsCOMPtr<nsIPrincipal>> allowlist;
141 nsCOMPtr<nsIPrincipal> alPrincipal;
143 for (uint32_t i = 0; i < info.allowlist().Length(); i++) {
144 auto principalOrErr = PrincipalInfoToPrincipal(info.allowlist()[i]);
145 if (NS_WARN_IF(principalOrErr.isErr())) {
146 nsresult ret = principalOrErr.unwrapErr();
147 return Err(ret);
149 // append that principal to the allowlist
150 allowlist.AppendElement(principalOrErr.unwrap());
153 RefPtr<ExpandedPrincipal> expandedPrincipal =
154 ExpandedPrincipal::Create(allowlist, info.attrs());
155 if (!expandedPrincipal) {
156 return Err(NS_ERROR_FAILURE);
159 principal = expandedPrincipal;
160 return principal;
163 default:
164 return Err(NS_ERROR_FAILURE);
168 already_AddRefed<nsIContentSecurityPolicy> CSPInfoToCSP(
169 const CSPInfo& aCSPInfo, Document* aRequestingDoc,
170 nsresult* aOptionalResult) {
171 MOZ_ASSERT(NS_IsMainThread());
173 nsresult stackResult;
174 nsresult& rv = aOptionalResult ? *aOptionalResult : stackResult;
176 RefPtr<nsCSPContext> csp = new nsCSPContext();
178 if (aRequestingDoc) {
179 rv = csp->SetRequestContextWithDocument(aRequestingDoc);
180 if (NS_WARN_IF(NS_FAILED(rv))) {
181 return nullptr;
183 } else {
184 auto principalOrErr =
185 PrincipalInfoToPrincipal(aCSPInfo.requestPrincipalInfo());
186 if (NS_WARN_IF(principalOrErr.isErr())) {
187 return nullptr;
190 nsCOMPtr<nsIURI> selfURI;
191 if (!aCSPInfo.selfURISpec().IsEmpty()) {
192 rv = NS_NewURI(getter_AddRefs(selfURI), aCSPInfo.selfURISpec());
193 if (NS_WARN_IF(NS_FAILED(rv))) {
194 return nullptr;
198 nsCOMPtr<nsIPrincipal> principal = principalOrErr.unwrap();
200 rv = csp->SetRequestContextWithPrincipal(
201 principal, selfURI, aCSPInfo.referrer(), aCSPInfo.innerWindowID());
202 if (NS_WARN_IF(NS_FAILED(rv))) {
203 return nullptr;
206 csp->SetSkipAllowInlineStyleCheck(aCSPInfo.skipAllowInlineStyleCheck());
208 for (uint32_t i = 0; i < aCSPInfo.policyInfos().Length(); i++) {
209 csp->AddIPCPolicy(aCSPInfo.policyInfos()[i]);
211 return csp.forget();
214 nsresult CSPToCSPInfo(nsIContentSecurityPolicy* aCSP, CSPInfo* aCSPInfo) {
215 MOZ_ASSERT(NS_IsMainThread());
216 MOZ_ASSERT(aCSP);
217 MOZ_ASSERT(aCSPInfo);
219 if (!aCSP || !aCSPInfo) {
220 return NS_ERROR_FAILURE;
223 nsCOMPtr<nsIPrincipal> requestPrincipal = aCSP->GetRequestPrincipal();
225 PrincipalInfo requestingPrincipalInfo;
226 nsresult rv =
227 PrincipalToPrincipalInfo(requestPrincipal, &requestingPrincipalInfo);
228 if (NS_WARN_IF(NS_FAILED(rv))) {
229 return rv;
232 nsCOMPtr<nsIURI> selfURI = aCSP->GetSelfURI();
233 nsAutoCString selfURISpec;
234 if (selfURI) {
235 selfURI->GetSpec(selfURISpec);
238 nsAutoString referrer;
239 aCSP->GetReferrer(referrer);
241 uint64_t windowID = aCSP->GetInnerWindowID();
242 bool skipAllowInlineStyleCheck = aCSP->GetSkipAllowInlineStyleCheck();
244 nsTArray<ContentSecurityPolicy> policies;
245 static_cast<nsCSPContext*>(aCSP)->SerializePolicies(policies);
247 *aCSPInfo = CSPInfo(std::move(policies), requestingPrincipalInfo, selfURISpec,
248 referrer, windowID, skipAllowInlineStyleCheck);
249 return NS_OK;
252 nsresult PrincipalToPrincipalInfo(nsIPrincipal* aPrincipal,
253 PrincipalInfo* aPrincipalInfo,
254 bool aSkipBaseDomain) {
255 MOZ_ASSERT(NS_IsMainThread());
256 MOZ_ASSERT(aPrincipal);
257 MOZ_ASSERT(aPrincipalInfo);
259 nsresult rv;
260 if (aPrincipal->GetIsNullPrincipal()) {
261 nsAutoCString spec;
262 rv = aPrincipal->GetAsciiSpec(spec);
263 if (NS_WARN_IF(NS_FAILED(rv))) {
264 return rv;
267 *aPrincipalInfo =
268 NullPrincipalInfo(aPrincipal->OriginAttributesRef(), spec);
269 return NS_OK;
272 if (aPrincipal->IsSystemPrincipal()) {
273 *aPrincipalInfo = SystemPrincipalInfo();
274 return NS_OK;
277 // might be an expanded principal
278 auto* basePrin = BasePrincipal::Cast(aPrincipal);
279 if (basePrin->Is<ExpandedPrincipal>()) {
280 auto* expanded = basePrin->As<ExpandedPrincipal>();
282 nsTArray<PrincipalInfo> allowlistInfo;
283 PrincipalInfo info;
285 for (auto& prin : expanded->AllowList()) {
286 rv = PrincipalToPrincipalInfo(prin, &info, aSkipBaseDomain);
287 if (NS_WARN_IF(NS_FAILED(rv))) {
288 return rv;
290 // append that spec to the allowlist
291 allowlistInfo.AppendElement(info);
294 *aPrincipalInfo = ExpandedPrincipalInfo(aPrincipal->OriginAttributesRef(),
295 std::move(allowlistInfo));
296 return NS_OK;
299 nsAutoCString spec;
300 rv = aPrincipal->GetAsciiSpec(spec);
301 if (NS_WARN_IF(NS_FAILED(rv))) {
302 return rv;
305 nsCString originNoSuffix;
306 rv = aPrincipal->GetOriginNoSuffix(originNoSuffix);
307 if (NS_WARN_IF(NS_FAILED(rv))) {
308 return rv;
311 nsCOMPtr<nsIURI> domainUri;
312 rv = aPrincipal->GetDomain(getter_AddRefs(domainUri));
313 if (NS_WARN_IF(NS_FAILED(rv))) {
314 return rv;
317 Maybe<nsCString> domain;
318 if (domainUri) {
319 domain.emplace();
320 rv = domainUri->GetSpec(domain.ref());
321 if (NS_WARN_IF(NS_FAILED(rv))) {
322 return rv;
326 // This attribute is not crucial.
327 nsCString baseDomain;
328 if (aSkipBaseDomain) {
329 baseDomain.SetIsVoid(true);
330 } else {
331 if (NS_FAILED(aPrincipal->GetBaseDomain(baseDomain))) {
332 // No warning here. Some principal URLs do not have a base-domain.
333 baseDomain.SetIsVoid(true);
337 *aPrincipalInfo =
338 ContentPrincipalInfo(aPrincipal->OriginAttributesRef(), originNoSuffix,
339 spec, domain, baseDomain);
340 return NS_OK;
343 bool IsPrincipalInfoPrivate(const PrincipalInfo& aPrincipalInfo) {
344 if (aPrincipalInfo.type() != ipc::PrincipalInfo::TContentPrincipalInfo) {
345 return false;
348 const ContentPrincipalInfo& info = aPrincipalInfo.get_ContentPrincipalInfo();
349 return !!info.attrs().mPrivateBrowsingId;
352 already_AddRefed<nsIRedirectHistoryEntry> RHEntryInfoToRHEntry(
353 const RedirectHistoryEntryInfo& aRHEntryInfo) {
354 auto principalOrErr = PrincipalInfoToPrincipal(aRHEntryInfo.principalInfo());
355 if (NS_WARN_IF(principalOrErr.isErr())) {
356 return nullptr;
359 nsCOMPtr<nsIPrincipal> principal = principalOrErr.unwrap();
360 nsCOMPtr<nsIURI> referrerUri = DeserializeURI(aRHEntryInfo.referrerUri());
362 nsCOMPtr<nsIRedirectHistoryEntry> entry = new nsRedirectHistoryEntry(
363 principal, referrerUri, aRHEntryInfo.remoteAddress());
365 return entry.forget();
368 nsresult RHEntryToRHEntryInfo(nsIRedirectHistoryEntry* aRHEntry,
369 RedirectHistoryEntryInfo* aRHEntryInfo) {
370 MOZ_ASSERT(aRHEntry);
371 MOZ_ASSERT(aRHEntryInfo);
373 nsresult rv;
374 aRHEntry->GetRemoteAddress(aRHEntryInfo->remoteAddress());
376 nsCOMPtr<nsIURI> referrerUri;
377 rv = aRHEntry->GetReferrerURI(getter_AddRefs(referrerUri));
378 NS_ENSURE_SUCCESS(rv, rv);
379 SerializeURI(referrerUri, aRHEntryInfo->referrerUri());
381 nsCOMPtr<nsIPrincipal> principal;
382 rv = aRHEntry->GetPrincipal(getter_AddRefs(principal));
383 NS_ENSURE_SUCCESS(rv, rv);
385 return PrincipalToPrincipalInfo(principal, &aRHEntryInfo->principalInfo());
388 nsresult LoadInfoToLoadInfoArgs(nsILoadInfo* aLoadInfo,
389 Maybe<LoadInfoArgs>* aOptionalLoadInfoArgs) {
390 nsresult rv = NS_OK;
391 Maybe<PrincipalInfo> loadingPrincipalInfo;
392 if (nsIPrincipal* loadingPrin = aLoadInfo->GetLoadingPrincipal()) {
393 loadingPrincipalInfo.emplace();
394 rv = PrincipalToPrincipalInfo(loadingPrin, loadingPrincipalInfo.ptr());
395 NS_ENSURE_SUCCESS(rv, rv);
398 PrincipalInfo triggeringPrincipalInfo;
399 rv = PrincipalToPrincipalInfo(aLoadInfo->TriggeringPrincipal(),
400 &triggeringPrincipalInfo);
401 NS_ENSURE_SUCCESS(rv, rv);
403 Maybe<PrincipalInfo> principalToInheritInfo;
404 if (nsIPrincipal* principalToInherit = aLoadInfo->PrincipalToInherit()) {
405 principalToInheritInfo.emplace();
406 rv = PrincipalToPrincipalInfo(principalToInherit,
407 principalToInheritInfo.ptr());
408 NS_ENSURE_SUCCESS(rv, rv);
411 Maybe<PrincipalInfo> topLevelPrincipalInfo;
412 if (nsIPrincipal* topLevenPrin = aLoadInfo->GetTopLevelPrincipal()) {
413 topLevelPrincipalInfo.emplace();
414 rv = PrincipalToPrincipalInfo(topLevenPrin, topLevelPrincipalInfo.ptr());
415 NS_ENSURE_SUCCESS(rv, rv);
418 Maybe<URIParams> optionalResultPrincipalURI;
419 nsCOMPtr<nsIURI> resultPrincipalURI;
420 Unused << aLoadInfo->GetResultPrincipalURI(
421 getter_AddRefs(resultPrincipalURI));
422 if (resultPrincipalURI) {
423 SerializeURI(resultPrincipalURI, optionalResultPrincipalURI);
426 nsTArray<RedirectHistoryEntryInfo> redirectChainIncludingInternalRedirects;
427 for (const nsCOMPtr<nsIRedirectHistoryEntry>& redirectEntry :
428 aLoadInfo->RedirectChainIncludingInternalRedirects()) {
429 RedirectHistoryEntryInfo* entry =
430 redirectChainIncludingInternalRedirects.AppendElement();
431 rv = RHEntryToRHEntryInfo(redirectEntry, entry);
432 NS_ENSURE_SUCCESS(rv, rv);
435 nsTArray<RedirectHistoryEntryInfo> redirectChain;
436 for (const nsCOMPtr<nsIRedirectHistoryEntry>& redirectEntry :
437 aLoadInfo->RedirectChain()) {
438 RedirectHistoryEntryInfo* entry = redirectChain.AppendElement();
439 rv = RHEntryToRHEntryInfo(redirectEntry, entry);
440 NS_ENSURE_SUCCESS(rv, rv);
443 Maybe<IPCClientInfo> ipcClientInfo;
444 const Maybe<ClientInfo>& clientInfo = aLoadInfo->GetClientInfo();
445 if (clientInfo.isSome()) {
446 ipcClientInfo.emplace(clientInfo.ref().ToIPC());
449 Maybe<IPCClientInfo> ipcReservedClientInfo;
450 const Maybe<ClientInfo>& reservedClientInfo =
451 aLoadInfo->GetReservedClientInfo();
452 if (reservedClientInfo.isSome()) {
453 ipcReservedClientInfo.emplace(reservedClientInfo.ref().ToIPC());
456 Maybe<IPCClientInfo> ipcInitialClientInfo;
457 const Maybe<ClientInfo>& initialClientInfo =
458 aLoadInfo->GetInitialClientInfo();
459 if (initialClientInfo.isSome()) {
460 ipcInitialClientInfo.emplace(initialClientInfo.ref().ToIPC());
463 Maybe<IPCServiceWorkerDescriptor> ipcController;
464 const Maybe<ServiceWorkerDescriptor>& controller = aLoadInfo->GetController();
465 if (controller.isSome()) {
466 ipcController.emplace(controller.ref().ToIPC());
469 nsAutoString cspNonce;
470 Unused << NS_WARN_IF(NS_FAILED(aLoadInfo->GetCspNonce(cspNonce)));
472 nsCOMPtr<nsICookieJarSettings> cookieJarSettings;
473 rv = aLoadInfo->GetCookieJarSettings(getter_AddRefs(cookieJarSettings));
474 NS_ENSURE_SUCCESS(rv, rv);
476 CookieJarSettingsArgs cookieJarSettingsArgs;
477 static_cast<CookieJarSettings*>(cookieJarSettings.get())
478 ->Serialize(cookieJarSettingsArgs);
480 Maybe<CSPInfo> maybeCspToInheritInfo;
481 nsCOMPtr<nsIContentSecurityPolicy> cspToInherit =
482 aLoadInfo->GetCspToInherit();
483 if (cspToInherit) {
484 CSPInfo cspToInheritInfo;
485 Unused << NS_WARN_IF(
486 NS_FAILED(CSPToCSPInfo(cspToInherit, &cspToInheritInfo)));
487 maybeCspToInheritInfo.emplace(cspToInheritInfo);
490 nsCOMPtr<nsIURI> unstrippedURI;
491 Unused << aLoadInfo->GetUnstrippedURI(getter_AddRefs(unstrippedURI));
493 *aOptionalLoadInfoArgs = Some(LoadInfoArgs(
494 loadingPrincipalInfo, triggeringPrincipalInfo, principalToInheritInfo,
495 topLevelPrincipalInfo, optionalResultPrincipalURI,
496 aLoadInfo->GetSandboxedNullPrincipalID(), aLoadInfo->GetSecurityFlags(),
497 aLoadInfo->GetSandboxFlags(), aLoadInfo->GetTriggeringSandboxFlags(),
498 aLoadInfo->InternalContentPolicyType(),
499 static_cast<uint32_t>(aLoadInfo->GetTainting()),
500 aLoadInfo->GetBlockAllMixedContent(),
501 aLoadInfo->GetUpgradeInsecureRequests(),
502 aLoadInfo->GetBrowserUpgradeInsecureRequests(),
503 aLoadInfo->GetBrowserDidUpgradeInsecureRequests(),
504 aLoadInfo->GetBrowserWouldUpgradeInsecureRequests(),
505 aLoadInfo->GetForceAllowDataURI(),
506 aLoadInfo->GetAllowInsecureRedirectToDataURI(),
507 aLoadInfo->GetSkipContentPolicyCheckForWebRequest(),
508 aLoadInfo->GetOriginalFrameSrcLoad(),
509 aLoadInfo->GetForceInheritPrincipalDropped(),
510 aLoadInfo->GetInnerWindowID(), aLoadInfo->GetBrowsingContextID(),
511 aLoadInfo->GetFrameBrowsingContextID(),
512 aLoadInfo->GetInitialSecurityCheckDone(),
513 aLoadInfo->GetIsInThirdPartyContext(),
514 aLoadInfo->GetIsThirdPartyContextToTopWindow(),
515 aLoadInfo->GetIsFormSubmission(), aLoadInfo->GetSendCSPViolationEvents(),
516 aLoadInfo->GetOriginAttributes(), redirectChainIncludingInternalRedirects,
517 redirectChain, ipcClientInfo, ipcReservedClientInfo, ipcInitialClientInfo,
518 ipcController, aLoadInfo->CorsUnsafeHeaders(),
519 aLoadInfo->GetForcePreflight(), aLoadInfo->GetIsPreflight(),
520 aLoadInfo->GetLoadTriggeredFromExternal(),
521 aLoadInfo->GetServiceWorkerTaintingSynthesized(),
522 aLoadInfo->GetDocumentHasUserInteracted(),
523 aLoadInfo->GetAllowListFutureDocumentsCreatedFromThisRedirectChain(),
524 aLoadInfo->GetNeedForCheckingAntiTrackingHeuristic(), cspNonce,
525 aLoadInfo->GetSkipContentSniffing(), aLoadInfo->GetHttpsOnlyStatus(),
526 aLoadInfo->GetHasValidUserGestureActivation(),
527 aLoadInfo->GetAllowDeprecatedSystemRequests(),
528 aLoadInfo->GetIsInDevToolsContext(), aLoadInfo->GetParserCreatedScript(),
529 aLoadInfo->GetIsFromProcessingFrameAttributes(),
530 aLoadInfo->GetIsMediaRequest(), aLoadInfo->GetIsMediaInitialRequest(),
531 aLoadInfo->GetIsFromObjectOrEmbed(), cookieJarSettingsArgs,
532 aLoadInfo->GetRequestBlockingReason(), maybeCspToInheritInfo,
533 aLoadInfo->GetStoragePermission(), aLoadInfo->GetIsMetaRefresh(),
534 aLoadInfo->GetLoadingEmbedderPolicy(), unstrippedURI));
536 return NS_OK;
539 nsresult LoadInfoArgsToLoadInfo(
540 const Maybe<LoadInfoArgs>& aOptionalLoadInfoArgs,
541 nsILoadInfo** outLoadInfo) {
542 return LoadInfoArgsToLoadInfo(aOptionalLoadInfoArgs, nullptr, outLoadInfo);
544 nsresult LoadInfoArgsToLoadInfo(
545 const Maybe<LoadInfoArgs>& aOptionalLoadInfoArgs,
546 nsINode* aCspToInheritLoadingContext, nsILoadInfo** outLoadInfo) {
547 RefPtr<LoadInfo> loadInfo;
548 nsresult rv =
549 LoadInfoArgsToLoadInfo(aOptionalLoadInfoArgs, aCspToInheritLoadingContext,
550 getter_AddRefs(loadInfo));
551 NS_ENSURE_SUCCESS(rv, rv);
553 loadInfo.forget(outLoadInfo);
554 return NS_OK;
557 nsresult LoadInfoArgsToLoadInfo(
558 const Maybe<LoadInfoArgs>& aOptionalLoadInfoArgs, LoadInfo** outLoadInfo) {
559 return LoadInfoArgsToLoadInfo(aOptionalLoadInfoArgs, nullptr, outLoadInfo);
561 nsresult LoadInfoArgsToLoadInfo(
562 const Maybe<LoadInfoArgs>& aOptionalLoadInfoArgs,
563 nsINode* aCspToInheritLoadingContext, LoadInfo** outLoadInfo) {
564 if (aOptionalLoadInfoArgs.isNothing()) {
565 *outLoadInfo = nullptr;
566 return NS_OK;
569 const LoadInfoArgs& loadInfoArgs = aOptionalLoadInfoArgs.ref();
571 nsCOMPtr<nsIPrincipal> loadingPrincipal;
572 if (loadInfoArgs.requestingPrincipalInfo().isSome()) {
573 auto loadingPrincipalOrErr =
574 PrincipalInfoToPrincipal(loadInfoArgs.requestingPrincipalInfo().ref());
575 if (NS_WARN_IF(loadingPrincipalOrErr.isErr())) {
576 return loadingPrincipalOrErr.unwrapErr();
578 loadingPrincipal = loadingPrincipalOrErr.unwrap();
581 auto triggeringPrincipalOrErr =
582 PrincipalInfoToPrincipal(loadInfoArgs.triggeringPrincipalInfo());
583 if (NS_WARN_IF(triggeringPrincipalOrErr.isErr())) {
584 return triggeringPrincipalOrErr.unwrapErr();
586 nsCOMPtr<nsIPrincipal> triggeringPrincipal =
587 triggeringPrincipalOrErr.unwrap();
589 nsCOMPtr<nsIPrincipal> principalToInherit;
590 nsCOMPtr<nsIPrincipal> flattenedPrincipalToInherit;
591 if (loadInfoArgs.principalToInheritInfo().isSome()) {
592 auto principalToInheritOrErr =
593 PrincipalInfoToPrincipal(loadInfoArgs.principalToInheritInfo().ref());
594 if (NS_WARN_IF(principalToInheritOrErr.isErr())) {
595 return principalToInheritOrErr.unwrapErr();
597 flattenedPrincipalToInherit = principalToInheritOrErr.unwrap();
600 if (XRE_IsContentProcess()) {
601 auto targetBrowsingContextId = loadInfoArgs.frameBrowsingContextID()
602 ? loadInfoArgs.frameBrowsingContextID()
603 : loadInfoArgs.browsingContextID();
604 if (RefPtr<BrowsingContext> bc =
605 BrowsingContext::Get(targetBrowsingContextId)) {
606 nsCOMPtr<nsIPrincipal> originalTriggeringPrincipal;
607 nsCOMPtr<nsIPrincipal> originalPrincipalToInherit;
608 Tie(originalTriggeringPrincipal, originalPrincipalToInherit) =
609 bc->GetTriggeringAndInheritPrincipalsForCurrentLoad();
611 if (originalTriggeringPrincipal &&
612 originalTriggeringPrincipal->Equals(triggeringPrincipal)) {
613 triggeringPrincipal = originalTriggeringPrincipal;
615 if (originalPrincipalToInherit &&
616 (loadInfoArgs.securityFlags() &
617 nsILoadInfo::SEC_FORCE_INHERIT_PRINCIPAL) &&
618 originalPrincipalToInherit->Equals(flattenedPrincipalToInherit)) {
619 principalToInherit = originalPrincipalToInherit;
623 if (!principalToInherit && loadInfoArgs.principalToInheritInfo().isSome()) {
624 principalToInherit = flattenedPrincipalToInherit;
627 nsresult rv = NS_OK;
628 nsCOMPtr<nsIPrincipal> topLevelPrincipal;
629 if (loadInfoArgs.topLevelPrincipalInfo().isSome()) {
630 auto topLevelPrincipalOrErr =
631 PrincipalInfoToPrincipal(loadInfoArgs.topLevelPrincipalInfo().ref());
632 if (NS_WARN_IF(topLevelPrincipalOrErr.isErr())) {
633 return topLevelPrincipalOrErr.unwrapErr();
635 topLevelPrincipal = topLevelPrincipalOrErr.unwrap();
638 nsCOMPtr<nsIURI> resultPrincipalURI;
639 if (loadInfoArgs.resultPrincipalURI().isSome()) {
640 resultPrincipalURI = DeserializeURI(loadInfoArgs.resultPrincipalURI());
641 NS_ENSURE_TRUE(resultPrincipalURI, NS_ERROR_UNEXPECTED);
644 RedirectHistoryArray redirectChainIncludingInternalRedirects;
645 for (const RedirectHistoryEntryInfo& entryInfo :
646 loadInfoArgs.redirectChainIncludingInternalRedirects()) {
647 nsCOMPtr<nsIRedirectHistoryEntry> redirectHistoryEntry =
648 RHEntryInfoToRHEntry(entryInfo);
649 NS_ENSURE_SUCCESS(rv, rv);
650 redirectChainIncludingInternalRedirects.AppendElement(
651 redirectHistoryEntry.forget());
654 RedirectHistoryArray redirectChain;
655 for (const RedirectHistoryEntryInfo& entryInfo :
656 loadInfoArgs.redirectChain()) {
657 nsCOMPtr<nsIRedirectHistoryEntry> redirectHistoryEntry =
658 RHEntryInfoToRHEntry(entryInfo);
659 NS_ENSURE_SUCCESS(rv, rv);
660 redirectChain.AppendElement(redirectHistoryEntry.forget());
663 nsTArray<nsCOMPtr<nsIPrincipal>> ancestorPrincipals;
664 nsTArray<uint64_t> ancestorBrowsingContextIDs;
665 if (XRE_IsParentProcess() &&
666 (nsContentUtils::InternalContentPolicyTypeToExternal(
667 loadInfoArgs.contentPolicyType()) !=
668 ExtContentPolicy::TYPE_DOCUMENT)) {
669 // Only fill out ancestor principals and browsing context IDs when we
670 // are deserializing LoadInfoArgs to be LoadInfo for a subresource
671 RefPtr<BrowsingContext> parentBC =
672 BrowsingContext::Get(loadInfoArgs.browsingContextID());
673 if (parentBC) {
674 LoadInfo::ComputeAncestors(parentBC->Canonical(), ancestorPrincipals,
675 ancestorBrowsingContextIDs);
679 Maybe<ClientInfo> clientInfo;
680 if (loadInfoArgs.clientInfo().isSome()) {
681 clientInfo.emplace(ClientInfo(loadInfoArgs.clientInfo().ref()));
684 Maybe<ClientInfo> reservedClientInfo;
685 if (loadInfoArgs.reservedClientInfo().isSome()) {
686 reservedClientInfo.emplace(
687 ClientInfo(loadInfoArgs.reservedClientInfo().ref()));
690 Maybe<ClientInfo> initialClientInfo;
691 if (loadInfoArgs.initialClientInfo().isSome()) {
692 initialClientInfo.emplace(
693 ClientInfo(loadInfoArgs.initialClientInfo().ref()));
696 // We can have an initial client info or a reserved client info, but not both.
697 MOZ_DIAGNOSTIC_ASSERT(reservedClientInfo.isNothing() ||
698 initialClientInfo.isNothing());
699 NS_ENSURE_TRUE(
700 reservedClientInfo.isNothing() || initialClientInfo.isNothing(),
701 NS_ERROR_UNEXPECTED);
703 Maybe<ServiceWorkerDescriptor> controller;
704 if (loadInfoArgs.controller().isSome()) {
705 controller.emplace(
706 ServiceWorkerDescriptor(loadInfoArgs.controller().ref()));
709 nsCOMPtr<nsICookieJarSettings> cookieJarSettings;
710 CookieJarSettings::Deserialize(loadInfoArgs.cookieJarSettings(),
711 getter_AddRefs(cookieJarSettings));
713 nsCOMPtr<nsIContentSecurityPolicy> cspToInherit;
714 Maybe<mozilla::ipc::CSPInfo> cspToInheritInfo =
715 loadInfoArgs.cspToInheritInfo();
716 if (cspToInheritInfo.isSome()) {
717 nsCOMPtr<Document> doc = do_QueryInterface(aCspToInheritLoadingContext);
718 cspToInherit = CSPInfoToCSP(cspToInheritInfo.ref(), doc);
721 // Restore the loadingContext for frames using the BrowsingContext's
722 // embedder element. Note that this only works if the embedder is
723 // same-process, so won't be fission compatible.
724 nsCOMPtr<nsINode> loadingContext;
725 RefPtr<BrowsingContext> frameBrowsingContext =
726 BrowsingContext::Get(loadInfoArgs.frameBrowsingContextID());
727 if (frameBrowsingContext) {
728 loadingContext = frameBrowsingContext->GetEmbedderElement();
731 RefPtr<mozilla::net::LoadInfo> loadInfo = new mozilla::net::LoadInfo(
732 loadingPrincipal, triggeringPrincipal, principalToInherit,
733 topLevelPrincipal, resultPrincipalURI, cookieJarSettings, cspToInherit,
734 loadInfoArgs.sandboxedNullPrincipalID(), clientInfo, reservedClientInfo,
735 initialClientInfo, controller, loadInfoArgs.securityFlags(),
736 loadInfoArgs.sandboxFlags(), loadInfoArgs.triggeringSandboxFlags(),
737 loadInfoArgs.contentPolicyType(),
738 static_cast<LoadTainting>(loadInfoArgs.tainting()),
739 loadInfoArgs.blockAllMixedContent(),
740 loadInfoArgs.upgradeInsecureRequests(),
741 loadInfoArgs.browserUpgradeInsecureRequests(),
742 loadInfoArgs.browserDidUpgradeInsecureRequests(),
743 loadInfoArgs.browserWouldUpgradeInsecureRequests(),
744 loadInfoArgs.forceAllowDataURI(),
745 loadInfoArgs.allowInsecureRedirectToDataURI(),
746 loadInfoArgs.skipContentPolicyCheckForWebRequest(),
747 loadInfoArgs.originalFrameSrcLoad(),
748 loadInfoArgs.forceInheritPrincipalDropped(), loadInfoArgs.innerWindowID(),
749 loadInfoArgs.browsingContextID(), loadInfoArgs.frameBrowsingContextID(),
750 loadInfoArgs.initialSecurityCheckDone(),
751 loadInfoArgs.isInThirdPartyContext(),
752 loadInfoArgs.isThirdPartyContextToTopWindow(),
753 loadInfoArgs.isFormSubmission(), loadInfoArgs.sendCSPViolationEvents(),
754 loadInfoArgs.originAttributes(),
755 std::move(redirectChainIncludingInternalRedirects),
756 std::move(redirectChain), std::move(ancestorPrincipals),
757 ancestorBrowsingContextIDs, loadInfoArgs.corsUnsafeHeaders(),
758 loadInfoArgs.forcePreflight(), loadInfoArgs.isPreflight(),
759 loadInfoArgs.loadTriggeredFromExternal(),
760 loadInfoArgs.serviceWorkerTaintingSynthesized(),
761 loadInfoArgs.documentHasUserInteracted(),
762 loadInfoArgs.allowListFutureDocumentsCreatedFromThisRedirectChain(),
763 loadInfoArgs.needForCheckingAntiTrackingHeuristic(),
764 loadInfoArgs.cspNonce(), loadInfoArgs.skipContentSniffing(),
765 loadInfoArgs.httpsOnlyStatus(),
766 loadInfoArgs.hasValidUserGestureActivation(),
767 loadInfoArgs.allowDeprecatedSystemRequests(),
768 loadInfoArgs.isInDevToolsContext(), loadInfoArgs.parserCreatedScript(),
769 loadInfoArgs.storagePermission(), loadInfoArgs.isMetaRefresh(),
770 loadInfoArgs.requestBlockingReason(), loadingContext,
771 loadInfoArgs.loadingEmbedderPolicy(), loadInfoArgs.unstrippedURI());
773 if (loadInfoArgs.isFromProcessingFrameAttributes()) {
774 loadInfo->SetIsFromProcessingFrameAttributes();
777 if (loadInfoArgs.isMediaRequest()) {
778 loadInfo->SetIsMediaRequest(true);
780 if (loadInfoArgs.isMediaInitialRequest()) {
781 loadInfo->SetIsMediaInitialRequest(true);
785 if (loadInfoArgs.isFromObjectOrEmbed()) {
786 loadInfo->SetIsFromObjectOrEmbed(true);
789 loadInfo.forget(outLoadInfo);
790 return NS_OK;
793 void LoadInfoToParentLoadInfoForwarder(
794 nsILoadInfo* aLoadInfo, ParentLoadInfoForwarderArgs* aForwarderArgsOut) {
795 Maybe<IPCServiceWorkerDescriptor> ipcController;
796 Maybe<ServiceWorkerDescriptor> controller(aLoadInfo->GetController());
797 if (controller.isSome()) {
798 ipcController.emplace(controller.ref().ToIPC());
801 uint32_t tainting = nsILoadInfo::TAINTING_BASIC;
802 Unused << aLoadInfo->GetTainting(&tainting);
804 Maybe<CookieJarSettingsArgs> cookieJarSettingsArgs;
806 nsCOMPtr<nsICookieJarSettings> cookieJarSettings;
807 nsresult rv =
808 aLoadInfo->GetCookieJarSettings(getter_AddRefs(cookieJarSettings));
809 CookieJarSettings* cs =
810 static_cast<CookieJarSettings*>(cookieJarSettings.get());
811 if (NS_SUCCEEDED(rv) && cookieJarSettings && cs->HasBeenChanged()) {
812 CookieJarSettingsArgs args;
813 cs->Serialize(args);
814 cookieJarSettingsArgs = Some(args);
817 nsCOMPtr<nsIURI> unstrippedURI;
818 Unused << aLoadInfo->GetUnstrippedURI(getter_AddRefs(unstrippedURI));
820 *aForwarderArgsOut = ParentLoadInfoForwarderArgs(
821 aLoadInfo->GetAllowInsecureRedirectToDataURI(), ipcController, tainting,
822 aLoadInfo->GetSkipContentSniffing(), aLoadInfo->GetHttpsOnlyStatus(),
823 aLoadInfo->GetHasValidUserGestureActivation(),
824 aLoadInfo->GetAllowDeprecatedSystemRequests(),
825 aLoadInfo->GetIsInDevToolsContext(), aLoadInfo->GetParserCreatedScript(),
826 aLoadInfo->GetTriggeringSandboxFlags(),
827 aLoadInfo->GetServiceWorkerTaintingSynthesized(),
828 aLoadInfo->GetDocumentHasUserInteracted(),
829 aLoadInfo->GetAllowListFutureDocumentsCreatedFromThisRedirectChain(),
830 cookieJarSettingsArgs, aLoadInfo->GetRequestBlockingReason(),
831 aLoadInfo->GetStoragePermission(), aLoadInfo->GetIsMetaRefresh(),
832 aLoadInfo->GetIsThirdPartyContextToTopWindow(),
833 aLoadInfo->GetIsInThirdPartyContext(), unstrippedURI);
836 nsresult MergeParentLoadInfoForwarder(
837 ParentLoadInfoForwarderArgs const& aForwarderArgs, nsILoadInfo* aLoadInfo) {
838 nsresult rv;
840 rv = aLoadInfo->SetAllowInsecureRedirectToDataURI(
841 aForwarderArgs.allowInsecureRedirectToDataURI());
842 NS_ENSURE_SUCCESS(rv, rv);
844 aLoadInfo->ClearController();
845 auto& controller = aForwarderArgs.controller();
846 if (controller.isSome()) {
847 aLoadInfo->SetController(ServiceWorkerDescriptor(controller.ref()));
850 if (aForwarderArgs.serviceWorkerTaintingSynthesized()) {
851 aLoadInfo->SynthesizeServiceWorkerTainting(
852 static_cast<LoadTainting>(aForwarderArgs.tainting()));
853 } else {
854 aLoadInfo->MaybeIncreaseTainting(aForwarderArgs.tainting());
857 rv = aLoadInfo->SetSkipContentSniffing(aForwarderArgs.skipContentSniffing());
858 NS_ENSURE_SUCCESS(rv, rv);
860 rv = aLoadInfo->SetHttpsOnlyStatus(aForwarderArgs.httpsOnlyStatus());
861 NS_ENSURE_SUCCESS(rv, rv);
863 rv = aLoadInfo->SetTriggeringSandboxFlags(
864 aForwarderArgs.triggeringSandboxFlags());
865 NS_ENSURE_SUCCESS(rv, rv);
867 rv = aLoadInfo->SetHasValidUserGestureActivation(
868 aForwarderArgs.hasValidUserGestureActivation());
869 NS_ENSURE_SUCCESS(rv, rv);
871 rv = aLoadInfo->SetAllowDeprecatedSystemRequests(
872 aForwarderArgs.allowDeprecatedSystemRequests());
873 NS_ENSURE_SUCCESS(rv, rv);
875 rv = aLoadInfo->SetIsInDevToolsContext(aForwarderArgs.isInDevToolsContext());
876 NS_ENSURE_SUCCESS(rv, rv);
878 rv = aLoadInfo->SetParserCreatedScript(aForwarderArgs.parserCreatedScript());
879 NS_ENSURE_SUCCESS(rv, rv);
881 MOZ_ALWAYS_SUCCEEDS(aLoadInfo->SetDocumentHasUserInteracted(
882 aForwarderArgs.documentHasUserInteracted()));
883 MOZ_ALWAYS_SUCCEEDS(
884 aLoadInfo->SetAllowListFutureDocumentsCreatedFromThisRedirectChain(
885 aForwarderArgs
886 .allowListFutureDocumentsCreatedFromThisRedirectChain()));
887 MOZ_ALWAYS_SUCCEEDS(aLoadInfo->SetRequestBlockingReason(
888 aForwarderArgs.requestBlockingReason()));
890 const Maybe<CookieJarSettingsArgs>& cookieJarSettingsArgs =
891 aForwarderArgs.cookieJarSettings();
892 if (cookieJarSettingsArgs.isSome()) {
893 nsCOMPtr<nsICookieJarSettings> cookieJarSettings;
894 nsresult rv =
895 aLoadInfo->GetCookieJarSettings(getter_AddRefs(cookieJarSettings));
896 if (NS_SUCCEEDED(rv) && cookieJarSettings) {
897 static_cast<CookieJarSettings*>(cookieJarSettings.get())
898 ->Merge(cookieJarSettingsArgs.ref());
902 rv = aLoadInfo->SetStoragePermission(aForwarderArgs.storagePermission());
903 NS_ENSURE_SUCCESS(rv, rv);
905 rv = aLoadInfo->SetIsMetaRefresh(aForwarderArgs.isMetaRefresh());
906 NS_ENSURE_SUCCESS(rv, rv);
908 rv = aLoadInfo->SetIsThirdPartyContextToTopWindow(
909 aForwarderArgs.isThirdPartyContextToTopWindow());
910 NS_ENSURE_SUCCESS(rv, rv);
912 rv = aLoadInfo->SetIsInThirdPartyContext(
913 aForwarderArgs.isInThirdPartyContext());
914 NS_ENSURE_SUCCESS(rv, rv);
916 rv = aLoadInfo->SetUnstrippedURI(aForwarderArgs.unstrippedURI());
917 NS_ENSURE_SUCCESS(rv, rv);
919 return NS_OK;
922 void LoadInfoToChildLoadInfoForwarder(
923 nsILoadInfo* aLoadInfo, ChildLoadInfoForwarderArgs* aForwarderArgsOut) {
924 Maybe<IPCClientInfo> ipcReserved;
925 Maybe<ClientInfo> reserved(aLoadInfo->GetReservedClientInfo());
926 if (reserved.isSome()) {
927 ipcReserved.emplace(reserved.ref().ToIPC());
930 Maybe<IPCClientInfo> ipcInitial;
931 Maybe<ClientInfo> initial(aLoadInfo->GetInitialClientInfo());
932 if (initial.isSome()) {
933 ipcInitial.emplace(initial.ref().ToIPC());
936 Maybe<IPCServiceWorkerDescriptor> ipcController;
937 Maybe<ServiceWorkerDescriptor> controller(aLoadInfo->GetController());
938 if (controller.isSome()) {
939 ipcController.emplace(controller.ref().ToIPC());
942 *aForwarderArgsOut =
943 ChildLoadInfoForwarderArgs(ipcReserved, ipcInitial, ipcController,
944 aLoadInfo->GetRequestBlockingReason());
947 nsresult MergeChildLoadInfoForwarder(
948 const ChildLoadInfoForwarderArgs& aForwarderArgs, nsILoadInfo* aLoadInfo) {
949 Maybe<ClientInfo> reservedClientInfo;
950 auto& ipcReserved = aForwarderArgs.reservedClientInfo();
951 if (ipcReserved.isSome()) {
952 reservedClientInfo.emplace(ClientInfo(ipcReserved.ref()));
955 Maybe<ClientInfo> initialClientInfo;
956 auto& ipcInitial = aForwarderArgs.initialClientInfo();
957 if (ipcInitial.isSome()) {
958 initialClientInfo.emplace(ClientInfo(ipcInitial.ref()));
961 // There should only be at most one reserved or initial ClientInfo.
962 if (NS_WARN_IF(reservedClientInfo.isSome() && initialClientInfo.isSome())) {
963 return NS_ERROR_FAILURE;
966 // If we received no reserved or initial ClientInfo, then we must not
967 // already have one set. There are no use cases where this should
968 // happen and we don't have a way to clear the current value.
969 if (NS_WARN_IF(reservedClientInfo.isNothing() &&
970 initialClientInfo.isNothing() &&
971 (aLoadInfo->GetReservedClientInfo().isSome() ||
972 aLoadInfo->GetInitialClientInfo().isSome()))) {
973 return NS_ERROR_FAILURE;
976 if (reservedClientInfo.isSome()) {
977 // We need to override here instead of simply set the value. This
978 // allows us to change the reserved client. This is necessary when
979 // the ClientChannelHelper created a new reserved client in the
980 // child-side of the redirect.
981 aLoadInfo->OverrideReservedClientInfoInParent(reservedClientInfo.ref());
982 } else if (initialClientInfo.isSome()) {
983 aLoadInfo->SetInitialClientInfo(initialClientInfo.ref());
986 aLoadInfo->ClearController();
987 auto& controller = aForwarderArgs.controller();
988 if (controller.isSome()) {
989 aLoadInfo->SetController(ServiceWorkerDescriptor(controller.ref()));
992 uint32_t blockingReason = aForwarderArgs.requestBlockingReason();
993 if (blockingReason) {
994 // We only want to override when non-null, so that any earlier set non-null
995 // value is not reverted to 0.
996 aLoadInfo->SetRequestBlockingReason(blockingReason);
999 return NS_OK;
1002 } // namespace ipc
1003 } // namespace mozilla