Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/ipc/glue/BackgroundUtils.cpp
Line
Count
Source (jump to first uncovered line)
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/. */
6
7
#include "BackgroundUtils.h"
8
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/NeckoChannelParams.h"
17
#include "ExpandedPrincipal.h"
18
#include "nsIScriptSecurityManager.h"
19
#include "nsIURI.h"
20
#include "nsNetUtil.h"
21
#include "mozilla/LoadInfo.h"
22
#include "nsContentUtils.h"
23
#include "nsString.h"
24
#include "nsTArray.h"
25
#include "mozilla/nsRedirectHistoryEntry.h"
26
#include "URIUtils.h"
27
28
namespace mozilla {
29
namespace net {
30
class OptionalLoadInfoArgs;
31
}
32
33
using mozilla::BasePrincipal;
34
using mozilla::Maybe;
35
using mozilla::dom::ServiceWorkerDescriptor;
36
using namespace mozilla::net;
37
38
namespace ipc {
39
40
already_AddRefed<nsIPrincipal>
41
PrincipalInfoToPrincipal(const PrincipalInfo& aPrincipalInfo,
42
                         nsresult* aOptionalResult)
43
0
{
44
0
  MOZ_ASSERT(NS_IsMainThread());
45
0
  MOZ_ASSERT(aPrincipalInfo.type() != PrincipalInfo::T__None);
46
0
47
0
  nsresult stackResult;
48
0
  nsresult& rv = aOptionalResult ? *aOptionalResult : stackResult;
49
0
50
0
  nsCOMPtr<nsIScriptSecurityManager> secMan =
51
0
    nsContentUtils::GetSecurityManager();
52
0
  if (!secMan) {
53
0
    return nullptr;
54
0
  }
55
0
56
0
  nsCOMPtr<nsIPrincipal> principal;
57
0
58
0
  switch (aPrincipalInfo.type()) {
59
0
    case PrincipalInfo::TSystemPrincipalInfo: {
60
0
      rv = secMan->GetSystemPrincipal(getter_AddRefs(principal));
61
0
      if (NS_WARN_IF(NS_FAILED(rv))) {
62
0
        return nullptr;
63
0
      }
64
0
65
0
      return principal.forget();
66
0
    }
67
0
68
0
    case PrincipalInfo::TNullPrincipalInfo: {
69
0
      const NullPrincipalInfo& info =
70
0
        aPrincipalInfo.get_NullPrincipalInfo();
71
0
72
0
      nsCOMPtr<nsIURI> uri;
73
0
      rv = NS_NewURI(getter_AddRefs(uri), info.spec());
74
0
      if (NS_WARN_IF(NS_FAILED(rv))) {
75
0
        return nullptr;
76
0
      }
77
0
78
0
      principal = NullPrincipal::Create(info.attrs(), uri);
79
0
      return principal.forget();
80
0
    }
81
0
82
0
    case PrincipalInfo::TContentPrincipalInfo: {
83
0
      const ContentPrincipalInfo& info =
84
0
        aPrincipalInfo.get_ContentPrincipalInfo();
85
0
86
0
      nsCOMPtr<nsIURI> uri;
87
0
      rv = NS_NewURI(getter_AddRefs(uri), info.spec());
88
0
      if (NS_WARN_IF(NS_FAILED(rv))) {
89
0
        return nullptr;
90
0
      }
91
0
92
0
      OriginAttributes attrs;
93
0
      if (info.attrs().mAppId != nsIScriptSecurityManager::UNKNOWN_APP_ID) {
94
0
        attrs = info.attrs();
95
0
      }
96
0
      principal = BasePrincipal::CreateCodebasePrincipal(uri, attrs);
97
0
      if (NS_WARN_IF(!principal)) {
98
0
        return nullptr;
99
0
      }
100
0
101
0
      // Origin must match what the_new_principal.getOrigin returns.
102
0
      nsAutoCString originNoSuffix;
103
0
      rv = principal->GetOriginNoSuffix(originNoSuffix);
104
0
      if (NS_WARN_IF(NS_FAILED(rv)) ||
105
0
          !info.originNoSuffix().Equals(originNoSuffix)) {
106
0
        MOZ_CRASH("Origin must be available when deserialized");
107
0
      }
108
0
109
0
      return principal.forget();
110
0
    }
111
0
112
0
    case PrincipalInfo::TExpandedPrincipalInfo: {
113
0
      const ExpandedPrincipalInfo& info = aPrincipalInfo.get_ExpandedPrincipalInfo();
114
0
115
0
      nsTArray<nsCOMPtr<nsIPrincipal>> whitelist;
116
0
      nsCOMPtr<nsIPrincipal> wlPrincipal;
117
0
118
0
      for (uint32_t i = 0; i < info.whitelist().Length(); i++) {
119
0
        wlPrincipal = PrincipalInfoToPrincipal(info.whitelist()[i], &rv);
120
0
        if (NS_WARN_IF(NS_FAILED(rv))) {
121
0
          return nullptr;
122
0
        }
123
0
        // append that principal to the whitelist
124
0
        whitelist.AppendElement(wlPrincipal);
125
0
      }
126
0
127
0
      RefPtr<ExpandedPrincipal> expandedPrincipal =
128
0
        ExpandedPrincipal::Create(whitelist, info.attrs());
129
0
      if (!expandedPrincipal) {
130
0
        NS_WARNING("could not instantiate expanded principal");
131
0
        return nullptr;
132
0
      }
133
0
134
0
      principal = expandedPrincipal;
135
0
      return principal.forget();
136
0
    }
137
0
138
0
    default:
139
0
      MOZ_CRASH("Unknown PrincipalInfo type!");
140
0
  }
141
0
142
0
  MOZ_CRASH("Should never get here!");
143
0
}
144
145
nsresult
146
PrincipalToPrincipalInfo(nsIPrincipal* aPrincipal,
147
                         PrincipalInfo* aPrincipalInfo)
148
0
{
149
0
  MOZ_ASSERT(NS_IsMainThread());
150
0
  MOZ_ASSERT(aPrincipal);
151
0
  MOZ_ASSERT(aPrincipalInfo);
152
0
153
0
  if (aPrincipal->GetIsNullPrincipal()) {
154
0
    nsCOMPtr<nsIURI> uri;
155
0
    nsresult rv = aPrincipal->GetURI(getter_AddRefs(uri));
156
0
    if (NS_WARN_IF(NS_FAILED(rv))) {
157
0
      return rv;
158
0
    }
159
0
160
0
    if (NS_WARN_IF(!uri)) {
161
0
      return NS_ERROR_FAILURE;
162
0
    }
163
0
164
0
    nsAutoCString spec;
165
0
    rv = uri->GetSpec(spec);
166
0
    if (NS_WARN_IF(NS_FAILED(rv))) {
167
0
      return rv;
168
0
    }
169
0
170
0
    *aPrincipalInfo =
171
0
      NullPrincipalInfo(aPrincipal->OriginAttributesRef(), spec);
172
0
    return NS_OK;
173
0
  }
174
0
175
0
  nsCOMPtr<nsIScriptSecurityManager> secMan =
176
0
    nsContentUtils::GetSecurityManager();
177
0
  if (!secMan) {
178
0
    return NS_ERROR_FAILURE;
179
0
  }
180
0
181
0
  bool isSystemPrincipal;
182
0
  nsresult rv = secMan->IsSystemPrincipal(aPrincipal, &isSystemPrincipal);
183
0
  if (NS_WARN_IF(NS_FAILED(rv))) {
184
0
    return rv;
185
0
  }
186
0
187
0
  if (isSystemPrincipal) {
188
0
    *aPrincipalInfo = SystemPrincipalInfo();
189
0
    return NS_OK;
190
0
  }
191
0
192
0
  // might be an expanded principal
193
0
  auto* basePrin = BasePrincipal::Cast(aPrincipal);
194
0
  if (basePrin->Is<ExpandedPrincipal>()) {
195
0
    auto* expanded = basePrin->As<ExpandedPrincipal>();
196
0
197
0
    nsTArray<PrincipalInfo> whitelistInfo;
198
0
    PrincipalInfo info;
199
0
200
0
    for (auto& prin : expanded->WhiteList()) {
201
0
      rv = PrincipalToPrincipalInfo(prin, &info);
202
0
      if (NS_WARN_IF(NS_FAILED(rv))) {
203
0
        return rv;
204
0
      }
205
0
      // append that spec to the whitelist
206
0
      whitelistInfo.AppendElement(info);
207
0
    }
208
0
209
0
    *aPrincipalInfo =
210
0
      ExpandedPrincipalInfo(aPrincipal->OriginAttributesRef(),
211
0
                            std::move(whitelistInfo));
212
0
    return NS_OK;
213
0
  }
214
0
215
0
  // must be a content principal
216
0
217
0
  nsCOMPtr<nsIURI> uri;
218
0
  rv = aPrincipal->GetURI(getter_AddRefs(uri));
219
0
  if (NS_WARN_IF(NS_FAILED(rv))) {
220
0
    return rv;
221
0
  }
222
0
223
0
  if (NS_WARN_IF(!uri)) {
224
0
    return NS_ERROR_FAILURE;
225
0
  }
226
0
227
0
  nsAutoCString spec;
228
0
  rv = uri->GetSpec(spec);
229
0
  if (NS_WARN_IF(NS_FAILED(rv))) {
230
0
    return rv;
231
0
  }
232
0
233
0
  nsCString originNoSuffix;
234
0
  rv = aPrincipal->GetOriginNoSuffix(originNoSuffix);
235
0
  if (NS_WARN_IF(NS_FAILED(rv))) {
236
0
    return rv;
237
0
  }
238
0
239
0
  *aPrincipalInfo = ContentPrincipalInfo(aPrincipal->OriginAttributesRef(),
240
0
                                         originNoSuffix, spec);
241
0
  return NS_OK;
242
0
}
243
244
bool
245
IsPincipalInfoPrivate(const PrincipalInfo& aPrincipalInfo)
246
0
{
247
0
  if (aPrincipalInfo.type() != ipc::PrincipalInfo::TContentPrincipalInfo) {
248
0
    return false;
249
0
  }
250
0
251
0
  const ContentPrincipalInfo& info = aPrincipalInfo.get_ContentPrincipalInfo();
252
0
  return !!info.attrs().mPrivateBrowsingId;
253
0
}
254
255
already_AddRefed<nsIRedirectHistoryEntry>
256
RHEntryInfoToRHEntry(const RedirectHistoryEntryInfo& aRHEntryInfo)
257
0
{
258
0
  nsresult rv;
259
0
  nsCOMPtr<nsIPrincipal> principal =
260
0
    PrincipalInfoToPrincipal(aRHEntryInfo.principalInfo(), &rv);
261
0
  if (NS_WARN_IF(NS_FAILED(rv))) {
262
0
    return nullptr;
263
0
  }
264
0
265
0
  nsCOMPtr<nsIURI> referrerUri = DeserializeURI(aRHEntryInfo.referrerUri());
266
0
267
0
  nsCOMPtr<nsIRedirectHistoryEntry> entry =
268
0
    new nsRedirectHistoryEntry(principal, referrerUri, aRHEntryInfo.remoteAddress());
269
0
270
0
  return entry.forget();
271
0
}
272
273
nsresult
274
RHEntryToRHEntryInfo(nsIRedirectHistoryEntry* aRHEntry,
275
                     RedirectHistoryEntryInfo* aRHEntryInfo)
276
0
{
277
0
  MOZ_ASSERT(aRHEntry);
278
0
  MOZ_ASSERT(aRHEntryInfo);
279
0
280
0
  nsresult rv;
281
0
  aRHEntry->GetRemoteAddress(aRHEntryInfo->remoteAddress());
282
0
283
0
  nsCOMPtr<nsIURI> referrerUri;
284
0
  rv = aRHEntry->GetReferrerURI(getter_AddRefs(referrerUri));
285
0
  NS_ENSURE_SUCCESS(rv, rv);
286
0
  SerializeURI(referrerUri, aRHEntryInfo->referrerUri());
287
0
288
0
  nsCOMPtr<nsIPrincipal> principal;
289
0
  rv = aRHEntry->GetPrincipal(getter_AddRefs(principal));
290
0
  NS_ENSURE_SUCCESS(rv, rv);
291
0
292
0
  return PrincipalToPrincipalInfo(principal, &aRHEntryInfo->principalInfo());
293
0
}
294
295
nsresult
296
LoadInfoToLoadInfoArgs(nsILoadInfo *aLoadInfo,
297
                       OptionalLoadInfoArgs* aOptionalLoadInfoArgs)
298
0
{
299
0
  if (!aLoadInfo) {
300
0
    // if there is no loadInfo, then there is nothing to serialize
301
0
    *aOptionalLoadInfoArgs = void_t();
302
0
    return NS_OK;
303
0
  }
304
0
305
0
  nsresult rv = NS_OK;
306
0
  OptionalPrincipalInfo loadingPrincipalInfo = mozilla::void_t();
307
0
  if (aLoadInfo->LoadingPrincipal()) {
308
0
    PrincipalInfo loadingPrincipalInfoTemp;
309
0
    rv = PrincipalToPrincipalInfo(aLoadInfo->LoadingPrincipal(),
310
0
                                  &loadingPrincipalInfoTemp);
311
0
    NS_ENSURE_SUCCESS(rv, rv);
312
0
    loadingPrincipalInfo = loadingPrincipalInfoTemp;
313
0
  }
314
0
315
0
  PrincipalInfo triggeringPrincipalInfo;
316
0
  rv = PrincipalToPrincipalInfo(aLoadInfo->TriggeringPrincipal(),
317
0
                                &triggeringPrincipalInfo);
318
0
  NS_ENSURE_SUCCESS(rv, rv);
319
0
320
0
  OptionalPrincipalInfo principalToInheritInfo = mozilla::void_t();
321
0
  if (aLoadInfo->PrincipalToInherit()) {
322
0
    PrincipalInfo principalToInheritInfoTemp;
323
0
    rv = PrincipalToPrincipalInfo(aLoadInfo->PrincipalToInherit(),
324
0
                                  &principalToInheritInfoTemp);
325
0
    NS_ENSURE_SUCCESS(rv, rv);
326
0
    principalToInheritInfo = principalToInheritInfoTemp;
327
0
  }
328
0
329
0
  OptionalPrincipalInfo sandboxedLoadingPrincipalInfo = mozilla::void_t();
330
0
  if (aLoadInfo->GetLoadingSandboxed()) {
331
0
    PrincipalInfo sandboxedLoadingPrincipalInfoTemp;
332
0
    nsCOMPtr<nsIPrincipal> sandboxedLoadingPrincipal;
333
0
    rv = aLoadInfo->GetSandboxedLoadingPrincipal(
334
0
        getter_AddRefs(sandboxedLoadingPrincipal));
335
0
    NS_ENSURE_SUCCESS(rv, rv);
336
0
    rv = PrincipalToPrincipalInfo(sandboxedLoadingPrincipal,
337
0
                                  &sandboxedLoadingPrincipalInfoTemp);
338
0
    NS_ENSURE_SUCCESS(rv, rv);
339
0
    sandboxedLoadingPrincipalInfo = sandboxedLoadingPrincipalInfoTemp;
340
0
  }
341
0
342
0
  OptionalPrincipalInfo topLevelPrincipalInfo = mozilla::void_t();
343
0
  if (aLoadInfo->TopLevelPrincipal()) {
344
0
    PrincipalInfo topLevelPrincipalInfoTemp;
345
0
    rv = PrincipalToPrincipalInfo(aLoadInfo->TopLevelPrincipal(),
346
0
                                  &topLevelPrincipalInfoTemp);
347
0
    NS_ENSURE_SUCCESS(rv, rv);
348
0
    topLevelPrincipalInfo = topLevelPrincipalInfoTemp;
349
0
  }
350
0
351
0
  OptionalPrincipalInfo topLevelStorageAreaPrincipalInfo = mozilla::void_t();
352
0
  if (aLoadInfo->TopLevelStorageAreaPrincipal()) {
353
0
    PrincipalInfo topLevelStorageAreaPrincipalInfoTemp;
354
0
    rv = PrincipalToPrincipalInfo(aLoadInfo->TopLevelStorageAreaPrincipal(),
355
0
                                  &topLevelStorageAreaPrincipalInfoTemp);
356
0
    NS_ENSURE_SUCCESS(rv, rv);
357
0
    topLevelStorageAreaPrincipalInfo = topLevelStorageAreaPrincipalInfoTemp;
358
0
  }
359
0
360
0
  OptionalURIParams optionalResultPrincipalURI = mozilla::void_t();
361
0
  nsCOMPtr<nsIURI> resultPrincipalURI;
362
0
  Unused << aLoadInfo->GetResultPrincipalURI(getter_AddRefs(resultPrincipalURI));
363
0
  if (resultPrincipalURI) {
364
0
    SerializeURI(resultPrincipalURI, optionalResultPrincipalURI);
365
0
  }
366
0
367
0
  nsTArray<RedirectHistoryEntryInfo> redirectChainIncludingInternalRedirects;
368
0
  for (const nsCOMPtr<nsIRedirectHistoryEntry>& redirectEntry :
369
0
       aLoadInfo->RedirectChainIncludingInternalRedirects()) {
370
0
    RedirectHistoryEntryInfo* entry = redirectChainIncludingInternalRedirects.AppendElement();
371
0
    rv = RHEntryToRHEntryInfo(redirectEntry, entry);
372
0
    NS_ENSURE_SUCCESS(rv, rv);
373
0
  }
374
0
375
0
  nsTArray<RedirectHistoryEntryInfo> redirectChain;
376
0
  for (const nsCOMPtr<nsIRedirectHistoryEntry>& redirectEntry :
377
0
       aLoadInfo->RedirectChain()) {
378
0
    RedirectHistoryEntryInfo* entry = redirectChain.AppendElement();
379
0
    rv = RHEntryToRHEntryInfo(redirectEntry, entry);
380
0
    NS_ENSURE_SUCCESS(rv, rv);
381
0
  }
382
0
383
0
  nsTArray<PrincipalInfo> ancestorPrincipals;
384
0
  ancestorPrincipals.SetCapacity(aLoadInfo->AncestorPrincipals().Length());
385
0
  for (const auto& principal : aLoadInfo->AncestorPrincipals()) {
386
0
    rv = PrincipalToPrincipalInfo(principal, ancestorPrincipals.AppendElement());
387
0
    NS_ENSURE_SUCCESS(rv, rv);
388
0
  }
389
0
390
0
  OptionalIPCClientInfo ipcClientInfo = mozilla::void_t();
391
0
  const Maybe<ClientInfo>& clientInfo = aLoadInfo->GetClientInfo();
392
0
  if (clientInfo.isSome()) {
393
0
    ipcClientInfo = clientInfo.ref().ToIPC();
394
0
  }
395
0
396
0
  OptionalIPCClientInfo ipcReservedClientInfo = mozilla::void_t();
397
0
  const Maybe<ClientInfo>& reservedClientInfo = aLoadInfo->GetReservedClientInfo();
398
0
  if (reservedClientInfo.isSome()) {
399
0
    ipcReservedClientInfo = reservedClientInfo.ref().ToIPC();
400
0
  }
401
0
402
0
  OptionalIPCClientInfo ipcInitialClientInfo = mozilla::void_t();
403
0
  const Maybe<ClientInfo>& initialClientInfo = aLoadInfo->GetInitialClientInfo();
404
0
  if (initialClientInfo.isSome()) {
405
0
    ipcInitialClientInfo = initialClientInfo.ref().ToIPC();
406
0
  }
407
0
408
0
  OptionalIPCServiceWorkerDescriptor ipcController = mozilla::void_t();
409
0
  const Maybe<ServiceWorkerDescriptor>& controller = aLoadInfo->GetController();
410
0
  if (controller.isSome()) {
411
0
    ipcController = controller.ref().ToIPC();
412
0
  }
413
0
414
0
  *aOptionalLoadInfoArgs =
415
0
    LoadInfoArgs(
416
0
      loadingPrincipalInfo,
417
0
      triggeringPrincipalInfo,
418
0
      principalToInheritInfo,
419
0
      sandboxedLoadingPrincipalInfo,
420
0
      topLevelPrincipalInfo,
421
0
      topLevelStorageAreaPrincipalInfo,
422
0
      optionalResultPrincipalURI,
423
0
      aLoadInfo->GetSecurityFlags(),
424
0
      aLoadInfo->InternalContentPolicyType(),
425
0
      static_cast<uint32_t>(aLoadInfo->GetTainting()),
426
0
      aLoadInfo->GetUpgradeInsecureRequests(),
427
0
      aLoadInfo->GetBrowserUpgradeInsecureRequests(),
428
0
      aLoadInfo->GetBrowserWouldUpgradeInsecureRequests(),
429
0
      aLoadInfo->GetVerifySignedContent(),
430
0
      aLoadInfo->GetEnforceSRI(),
431
0
      aLoadInfo->GetForceAllowDataURI(),
432
0
      aLoadInfo->GetAllowInsecureRedirectToDataURI(),
433
0
      aLoadInfo->GetSkipContentPolicyCheckForWebRequest(),
434
0
      aLoadInfo->GetForceInheritPrincipalDropped(),
435
0
      aLoadInfo->GetInnerWindowID(),
436
0
      aLoadInfo->GetOuterWindowID(),
437
0
      aLoadInfo->GetParentOuterWindowID(),
438
0
      aLoadInfo->GetTopOuterWindowID(),
439
0
      aLoadInfo->GetFrameOuterWindowID(),
440
0
      aLoadInfo->GetEnforceSecurity(),
441
0
      aLoadInfo->GetInitialSecurityCheckDone(),
442
0
      aLoadInfo->GetIsInThirdPartyContext(),
443
0
      aLoadInfo->GetIsDocshellReload(),
444
0
      aLoadInfo->GetSendCSPViolationEvents(),
445
0
      aLoadInfo->GetOriginAttributes(),
446
0
      redirectChainIncludingInternalRedirects,
447
0
      redirectChain,
448
0
      ancestorPrincipals,
449
0
      aLoadInfo->AncestorOuterWindowIDs(),
450
0
      ipcClientInfo,
451
0
      ipcReservedClientInfo,
452
0
      ipcInitialClientInfo,
453
0
      ipcController,
454
0
      aLoadInfo->CorsUnsafeHeaders(),
455
0
      aLoadInfo->GetForcePreflight(),
456
0
      aLoadInfo->GetIsPreflight(),
457
0
      aLoadInfo->GetLoadTriggeredFromExternal(),
458
0
      aLoadInfo->GetServiceWorkerTaintingSynthesized(),
459
0
      aLoadInfo->GetDocumentHasUserInteracted()
460
0
      );
461
0
462
0
  return NS_OK;
463
0
}
464
465
nsresult
466
LoadInfoArgsToLoadInfo(const OptionalLoadInfoArgs& aOptionalLoadInfoArgs,
467
                       nsILoadInfo** outLoadInfo)
468
0
{
469
0
  if (aOptionalLoadInfoArgs.type() == OptionalLoadInfoArgs::Tvoid_t) {
470
0
    *outLoadInfo = nullptr;
471
0
    return NS_OK;
472
0
  }
473
0
474
0
  const LoadInfoArgs& loadInfoArgs =
475
0
    aOptionalLoadInfoArgs.get_LoadInfoArgs();
476
0
477
0
  nsresult rv = NS_OK;
478
0
  nsCOMPtr<nsIPrincipal> loadingPrincipal;
479
0
  if (loadInfoArgs.requestingPrincipalInfo().type() != OptionalPrincipalInfo::Tvoid_t) {
480
0
    loadingPrincipal = PrincipalInfoToPrincipal(loadInfoArgs.requestingPrincipalInfo(), &rv);
481
0
    NS_ENSURE_SUCCESS(rv, rv);
482
0
  }
483
0
484
0
  NS_ENSURE_SUCCESS(rv, rv);
485
0
  nsCOMPtr<nsIPrincipal> triggeringPrincipal =
486
0
    PrincipalInfoToPrincipal(loadInfoArgs.triggeringPrincipalInfo(), &rv);
487
0
  NS_ENSURE_SUCCESS(rv, rv);
488
0
489
0
  nsCOMPtr<nsIPrincipal> principalToInherit;
490
0
  if (loadInfoArgs.principalToInheritInfo().type() != OptionalPrincipalInfo::Tvoid_t) {
491
0
    principalToInherit = PrincipalInfoToPrincipal(loadInfoArgs.principalToInheritInfo(), &rv);
492
0
    NS_ENSURE_SUCCESS(rv, rv);
493
0
  }
494
0
495
0
  nsCOMPtr<nsIPrincipal> sandboxedLoadingPrincipal;
496
0
  if (loadInfoArgs.sandboxedLoadingPrincipalInfo().type() != OptionalPrincipalInfo::Tvoid_t) {
497
0
    sandboxedLoadingPrincipal =
498
0
      PrincipalInfoToPrincipal(loadInfoArgs.sandboxedLoadingPrincipalInfo(), &rv);
499
0
    NS_ENSURE_SUCCESS(rv, rv);
500
0
  }
501
0
502
0
  nsCOMPtr<nsIPrincipal> topLevelPrincipal;
503
0
  if (loadInfoArgs.topLevelPrincipalInfo().type() != OptionalPrincipalInfo::Tvoid_t) {
504
0
    topLevelPrincipal =
505
0
      PrincipalInfoToPrincipal(loadInfoArgs.topLevelPrincipalInfo(), &rv);
506
0
    NS_ENSURE_SUCCESS(rv, rv);
507
0
  }
508
0
509
0
  nsCOMPtr<nsIPrincipal> topLevelStorageAreaPrincipal;
510
0
  if (loadInfoArgs.topLevelStorageAreaPrincipalInfo().type() != OptionalPrincipalInfo::Tvoid_t) {
511
0
    topLevelStorageAreaPrincipal =
512
0
      PrincipalInfoToPrincipal(loadInfoArgs.topLevelStorageAreaPrincipalInfo(), &rv);
513
0
    NS_ENSURE_SUCCESS(rv, rv);
514
0
  }
515
0
516
0
  nsCOMPtr<nsIURI> resultPrincipalURI;
517
0
  if (loadInfoArgs.resultPrincipalURI().type() != OptionalURIParams::Tvoid_t) {
518
0
    resultPrincipalURI = DeserializeURI(loadInfoArgs.resultPrincipalURI());
519
0
    NS_ENSURE_TRUE(resultPrincipalURI, NS_ERROR_UNEXPECTED);
520
0
  }
521
0
522
0
  RedirectHistoryArray redirectChainIncludingInternalRedirects;
523
0
  for (const RedirectHistoryEntryInfo& entryInfo :
524
0
      loadInfoArgs.redirectChainIncludingInternalRedirects()) {
525
0
    nsCOMPtr<nsIRedirectHistoryEntry> redirectHistoryEntry =
526
0
      RHEntryInfoToRHEntry(entryInfo);
527
0
    NS_ENSURE_SUCCESS(rv, rv);
528
0
    redirectChainIncludingInternalRedirects.AppendElement(redirectHistoryEntry.forget());
529
0
  }
530
0
531
0
  RedirectHistoryArray redirectChain;
532
0
  for (const RedirectHistoryEntryInfo& entryInfo : loadInfoArgs.redirectChain()) {
533
0
    nsCOMPtr<nsIRedirectHistoryEntry> redirectHistoryEntry =
534
0
      RHEntryInfoToRHEntry(entryInfo);
535
0
    NS_ENSURE_SUCCESS(rv, rv);
536
0
    redirectChain.AppendElement(redirectHistoryEntry.forget());
537
0
  }
538
0
539
0
  nsTArray<nsCOMPtr<nsIPrincipal>> ancestorPrincipals;
540
0
  ancestorPrincipals.SetCapacity(loadInfoArgs.ancestorPrincipals().Length());
541
0
  for (const PrincipalInfo& principalInfo : loadInfoArgs.ancestorPrincipals()) {
542
0
    nsCOMPtr<nsIPrincipal> ancestorPrincipal =
543
0
      PrincipalInfoToPrincipal(principalInfo, &rv);
544
0
    NS_ENSURE_SUCCESS(rv, rv);
545
0
    ancestorPrincipals.AppendElement(ancestorPrincipal.forget());
546
0
  }
547
0
548
0
  Maybe<ClientInfo> clientInfo;
549
0
  if (loadInfoArgs.clientInfo().type() != OptionalIPCClientInfo::Tvoid_t) {
550
0
    clientInfo.emplace(ClientInfo(loadInfoArgs.clientInfo().get_IPCClientInfo()));
551
0
  }
552
0
553
0
  Maybe<ClientInfo> reservedClientInfo;
554
0
  if (loadInfoArgs.reservedClientInfo().type() != OptionalIPCClientInfo::Tvoid_t) {
555
0
    reservedClientInfo.emplace(
556
0
      ClientInfo(loadInfoArgs.reservedClientInfo().get_IPCClientInfo()));
557
0
  }
558
0
559
0
  Maybe<ClientInfo> initialClientInfo;
560
0
  if (loadInfoArgs.initialClientInfo().type() != OptionalIPCClientInfo::Tvoid_t) {
561
0
    initialClientInfo.emplace(
562
0
      ClientInfo(loadInfoArgs.initialClientInfo().get_IPCClientInfo()));
563
0
  }
564
0
565
0
  // We can have an initial client info or a reserved client info, but not both.
566
0
  MOZ_DIAGNOSTIC_ASSERT(reservedClientInfo.isNothing() ||
567
0
                        initialClientInfo.isNothing());
568
0
  NS_ENSURE_TRUE(reservedClientInfo.isNothing() ||
569
0
                 initialClientInfo.isNothing(), NS_ERROR_UNEXPECTED);
570
0
571
0
  Maybe<ServiceWorkerDescriptor> controller;
572
0
  if (loadInfoArgs.controller().type() != OptionalIPCServiceWorkerDescriptor::Tvoid_t) {
573
0
    controller.emplace(ServiceWorkerDescriptor(
574
0
      loadInfoArgs.controller().get_IPCServiceWorkerDescriptor()));
575
0
  }
576
0
577
0
  nsCOMPtr<nsILoadInfo> loadInfo =
578
0
    new mozilla::LoadInfo(loadingPrincipal,
579
0
                          triggeringPrincipal,
580
0
                          principalToInherit,
581
0
                          sandboxedLoadingPrincipal,
582
0
                          topLevelPrincipal,
583
0
                          topLevelStorageAreaPrincipal,
584
0
                          resultPrincipalURI,
585
0
                          clientInfo,
586
0
                          reservedClientInfo,
587
0
                          initialClientInfo,
588
0
                          controller,
589
0
                          loadInfoArgs.securityFlags(),
590
0
                          loadInfoArgs.contentPolicyType(),
591
0
                          static_cast<LoadTainting>(loadInfoArgs.tainting()),
592
0
                          loadInfoArgs.upgradeInsecureRequests(),
593
0
                          loadInfoArgs.browserUpgradeInsecureRequests(),
594
0
                          loadInfoArgs.browserWouldUpgradeInsecureRequests(),
595
0
                          loadInfoArgs.verifySignedContent(),
596
0
                          loadInfoArgs.enforceSRI(),
597
0
                          loadInfoArgs.forceAllowDataURI(),
598
0
                          loadInfoArgs.allowInsecureRedirectToDataURI(),
599
0
                          loadInfoArgs.skipContentPolicyCheckForWebRequest(),
600
0
                          loadInfoArgs.forceInheritPrincipalDropped(),
601
0
                          loadInfoArgs.innerWindowID(),
602
0
                          loadInfoArgs.outerWindowID(),
603
0
                          loadInfoArgs.parentOuterWindowID(),
604
0
                          loadInfoArgs.topOuterWindowID(),
605
0
                          loadInfoArgs.frameOuterWindowID(),
606
0
                          loadInfoArgs.enforceSecurity(),
607
0
                          loadInfoArgs.initialSecurityCheckDone(),
608
0
                          loadInfoArgs.isInThirdPartyContext(),
609
0
                          loadInfoArgs.isDocshellReload(),
610
0
                          loadInfoArgs.sendCSPViolationEvents(),
611
0
                          loadInfoArgs.originAttributes(),
612
0
                          redirectChainIncludingInternalRedirects,
613
0
                          redirectChain,
614
0
                          std::move(ancestorPrincipals),
615
0
                          loadInfoArgs.ancestorOuterWindowIDs(),
616
0
                          loadInfoArgs.corsUnsafeHeaders(),
617
0
                          loadInfoArgs.forcePreflight(),
618
0
                          loadInfoArgs.isPreflight(),
619
0
                          loadInfoArgs.loadTriggeredFromExternal(),
620
0
                          loadInfoArgs.serviceWorkerTaintingSynthesized(),
621
0
                          loadInfoArgs.documentHasUserInteracted()
622
0
                          );
623
0
624
0
   loadInfo.forget(outLoadInfo);
625
0
   return NS_OK;
626
0
}
627
628
void
629
LoadInfoToParentLoadInfoForwarder(nsILoadInfo* aLoadInfo,
630
                                  ParentLoadInfoForwarderArgs* aForwarderArgsOut)
631
0
{
632
0
  if (!aLoadInfo) {
633
0
    *aForwarderArgsOut = ParentLoadInfoForwarderArgs(false, void_t(),
634
0
                                                     nsILoadInfo::TAINTING_BASIC,
635
0
                                                     false, // serviceWorkerTaintingSynthesized
636
0
                                                     false, // isTracker
637
0
                                                     false, // isTrackerBlocked
638
0
                                                     mozilla::Telemetry::LABELS_DOCUMENT_ANALYTICS_TRACKER_FASTBLOCKED::all, // trackerBlockedReason
639
0
                                                     false  // documentHasUserInteracted
640
0
                                                    );
641
0
    return;
642
0
  }
643
0
644
0
  OptionalIPCServiceWorkerDescriptor ipcController = void_t();
645
0
  Maybe<ServiceWorkerDescriptor> controller(aLoadInfo->GetController());
646
0
  if (controller.isSome()) {
647
0
    ipcController = controller.ref().ToIPC();
648
0
  }
649
0
650
0
  uint32_t tainting = nsILoadInfo::TAINTING_BASIC;
651
0
  Unused << aLoadInfo->GetTainting(&tainting);
652
0
653
0
  mozilla::Telemetry::LABELS_DOCUMENT_ANALYTICS_TRACKER_FASTBLOCKED label =
654
0
    mozilla::Telemetry::LABELS_DOCUMENT_ANALYTICS_TRACKER_FASTBLOCKED::all;
655
0
  Unused << aLoadInfo->GetTrackerBlockedReason(&label);
656
0
657
0
  *aForwarderArgsOut = ParentLoadInfoForwarderArgs(
658
0
    aLoadInfo->GetAllowInsecureRedirectToDataURI(),
659
0
    ipcController,
660
0
    tainting,
661
0
    aLoadInfo->GetServiceWorkerTaintingSynthesized(),
662
0
    aLoadInfo->GetIsTracker(),
663
0
    aLoadInfo->GetIsTrackerBlocked(),
664
0
    label,
665
0
    aLoadInfo->GetDocumentHasUserInteracted()
666
0
  );
667
0
}
668
669
nsresult
670
MergeParentLoadInfoForwarder(ParentLoadInfoForwarderArgs const& aForwarderArgs,
671
                             nsILoadInfo* aLoadInfo)
672
0
{
673
0
  if (!aLoadInfo) {
674
0
    return NS_OK;
675
0
  }
676
0
677
0
  nsresult rv;
678
0
679
0
  rv = aLoadInfo->SetAllowInsecureRedirectToDataURI(
680
0
    aForwarderArgs.allowInsecureRedirectToDataURI());
681
0
  NS_ENSURE_SUCCESS(rv, rv);
682
0
683
0
  aLoadInfo->ClearController();
684
0
  auto& controller = aForwarderArgs.controller();
685
0
  if (controller.type() != OptionalIPCServiceWorkerDescriptor::Tvoid_t) {
686
0
    aLoadInfo->SetController(
687
0
      ServiceWorkerDescriptor(controller.get_IPCServiceWorkerDescriptor()));
688
0
  }
689
0
690
0
  if (aForwarderArgs.serviceWorkerTaintingSynthesized()) {
691
0
    aLoadInfo->SynthesizeServiceWorkerTainting(
692
0
      static_cast<LoadTainting>(aForwarderArgs.tainting()));
693
0
  } else {
694
0
    aLoadInfo->MaybeIncreaseTainting(aForwarderArgs.tainting());
695
0
  }
696
0
697
0
  MOZ_ALWAYS_SUCCEEDS(aLoadInfo->SetIsTracker(aForwarderArgs.isTracker()));
698
0
  MOZ_ALWAYS_SUCCEEDS(aLoadInfo->SetIsTrackerBlocked(aForwarderArgs.isTrackerBlocked()));
699
0
  MOZ_ALWAYS_SUCCEEDS(aLoadInfo->SetTrackerBlockedReason(aForwarderArgs.trackerBlockedReason()));
700
0
  MOZ_ALWAYS_SUCCEEDS(aLoadInfo->SetDocumentHasUserInteracted(aForwarderArgs.documentHasUserInteracted()));
701
0
702
0
  return NS_OK;
703
0
}
704
705
void
706
LoadInfoToChildLoadInfoForwarder(nsILoadInfo* aLoadInfo,
707
                                 ChildLoadInfoForwarderArgs* aForwarderArgsOut)
708
0
{
709
0
  if (!aLoadInfo) {
710
0
    *aForwarderArgsOut = ChildLoadInfoForwarderArgs(void_t(), void_t(),
711
0
                                                    void_t());
712
0
    return;
713
0
  }
714
0
715
0
  OptionalIPCClientInfo ipcReserved = void_t();
716
0
  Maybe<ClientInfo> reserved(aLoadInfo->GetReservedClientInfo());
717
0
  if (reserved.isSome()) {
718
0
    ipcReserved = reserved.ref().ToIPC();
719
0
  }
720
0
721
0
  OptionalIPCClientInfo ipcInitial = void_t();
722
0
  Maybe<ClientInfo> initial(aLoadInfo->GetInitialClientInfo());
723
0
  if (initial.isSome()) {
724
0
    ipcInitial = initial.ref().ToIPC();
725
0
  }
726
0
727
0
  OptionalIPCServiceWorkerDescriptor ipcController = void_t();
728
0
  Maybe<ServiceWorkerDescriptor> controller(aLoadInfo->GetController());
729
0
  if (controller.isSome()) {
730
0
    ipcController = controller.ref().ToIPC();
731
0
  }
732
0
733
0
  *aForwarderArgsOut = ChildLoadInfoForwarderArgs(
734
0
    ipcReserved,
735
0
    ipcInitial,
736
0
    ipcController
737
0
  );
738
0
}
739
740
nsresult
741
MergeChildLoadInfoForwarder(const ChildLoadInfoForwarderArgs& aForwarderArgs,
742
                            nsILoadInfo* aLoadInfo)
743
0
{
744
0
  if (!aLoadInfo) {
745
0
    return NS_OK;
746
0
  }
747
0
748
0
  Maybe<ClientInfo> reservedClientInfo;
749
0
  auto& ipcReserved = aForwarderArgs.reservedClientInfo();
750
0
  if (ipcReserved.type() != OptionalIPCClientInfo::Tvoid_t) {
751
0
    reservedClientInfo.emplace(ClientInfo(ipcReserved.get_IPCClientInfo()));
752
0
  }
753
0
754
0
  Maybe<ClientInfo> initialClientInfo;
755
0
  auto& ipcInitial = aForwarderArgs.initialClientInfo();
756
0
  if (ipcInitial.type() != OptionalIPCClientInfo::Tvoid_t) {
757
0
    initialClientInfo.emplace(ClientInfo(ipcInitial.get_IPCClientInfo()));
758
0
  }
759
0
760
0
  // There should only be at most one reserved or initial ClientInfo.
761
0
  if (NS_WARN_IF(reservedClientInfo.isSome() && initialClientInfo.isSome())) {
762
0
    return NS_ERROR_FAILURE;
763
0
  }
764
0
765
0
  // If we received no reserved or initial ClientInfo, then we must not
766
0
  // already have one set.  There are no use cases where this should
767
0
  // happen and we don't have a way to clear the current value.
768
0
  if (NS_WARN_IF(reservedClientInfo.isNothing() &&
769
0
                 initialClientInfo.isNothing() &&
770
0
                 (aLoadInfo->GetReservedClientInfo().isSome() ||
771
0
                  aLoadInfo->GetInitialClientInfo().isSome()))) {
772
0
    return NS_ERROR_FAILURE;
773
0
  }
774
0
775
0
  if (reservedClientInfo.isSome()) {
776
0
    // We need to override here instead of simply set the value.  This
777
0
    // allows us to change the reserved client.  This is necessary when
778
0
    // the ClientChannelHelper created a new reserved client in the
779
0
    // child-side of the redirect.
780
0
    aLoadInfo->OverrideReservedClientInfoInParent(reservedClientInfo.ref());
781
0
  } else if (initialClientInfo.isSome()) {
782
0
    aLoadInfo->SetInitialClientInfo(initialClientInfo.ref());
783
0
  }
784
0
785
0
  aLoadInfo->ClearController();
786
0
  auto& controller = aForwarderArgs.controller();
787
0
  if (controller.type() != OptionalIPCServiceWorkerDescriptor::Tvoid_t) {
788
0
    aLoadInfo->SetController(
789
0
      ServiceWorkerDescriptor(controller.get_IPCServiceWorkerDescriptor()));
790
0
  }
791
0
792
0
  return NS_OK;
793
0
}
794
795
} // namespace ipc
796
} // namespace mozilla