Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/netwerk/ipc/NeckoParent.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 sw=2 ts=8 et tw=80 : */
3
4
/* This Source Code Form is subject to the terms of the Mozilla Public
5
 * License, v. 2.0. If a copy of the MPL was not distributed with this
6
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7
8
#include "necko-config.h"
9
#include "nsHttp.h"
10
#include "mozilla/BasePrincipal.h"
11
#include "mozilla/ContentPrincipal.h"
12
#include "mozilla/ipc/IPCStreamUtils.h"
13
#include "mozilla/net/ExtensionProtocolHandler.h"
14
#include "mozilla/net/NeckoParent.h"
15
#include "mozilla/net/HttpChannelParent.h"
16
#include "mozilla/net/CookieServiceParent.h"
17
#include "mozilla/net/WyciwygChannelParent.h"
18
#include "mozilla/net/FTPChannelParent.h"
19
#include "mozilla/net/WebSocketChannelParent.h"
20
#include "mozilla/net/WebSocketEventListenerParent.h"
21
#include "mozilla/net/DataChannelParent.h"
22
#include "mozilla/net/SimpleChannelParent.h"
23
#include "mozilla/net/AltDataOutputStreamParent.h"
24
#include "mozilla/Unused.h"
25
#include "mozilla/net/FileChannelParent.h"
26
#include "mozilla/net/DNSRequestParent.h"
27
#include "mozilla/net/ChannelDiverterParent.h"
28
#include "mozilla/net/IPCTransportProvider.h"
29
#ifdef MOZ_WEBRTC
30
#include "mozilla/net/StunAddrsRequestParent.h"
31
#endif
32
#include "mozilla/dom/ChromeUtils.h"
33
#include "mozilla/dom/ContentParent.h"
34
#include "mozilla/dom/TabContext.h"
35
#include "mozilla/dom/TabParent.h"
36
#include "mozilla/dom/network/TCPSocketParent.h"
37
#include "mozilla/dom/network/TCPServerSocketParent.h"
38
#include "mozilla/dom/network/UDPSocketParent.h"
39
#include "mozilla/dom/ServiceWorkerManager.h"
40
#include "mozilla/LoadContext.h"
41
#include "mozilla/MozPromise.h"
42
#include "nsPrintfCString.h"
43
#include "nsHTMLDNSPrefetch.h"
44
#include "nsEscape.h"
45
#include "SerializedLoadContext.h"
46
#include "nsAuthInformationHolder.h"
47
#include "nsIAuthPromptCallback.h"
48
#include "nsINetworkPredictor.h"
49
#include "nsINetworkPredictorVerifier.h"
50
#include "nsISpeculativeConnect.h"
51
#include "nsNetUtil.h"
52
53
using mozilla::OriginAttributes;
54
using mozilla::dom::ChromeUtils;
55
using mozilla::dom::ContentParent;
56
using mozilla::dom::ServiceWorkerManager;
57
using mozilla::dom::TabContext;
58
using mozilla::dom::TabParent;
59
using mozilla::net::PTCPSocketParent;
60
using mozilla::dom::TCPSocketParent;
61
using mozilla::net::PTCPServerSocketParent;
62
using mozilla::dom::TCPServerSocketParent;
63
using mozilla::net::PUDPSocketParent;
64
using mozilla::dom::UDPSocketParent;
65
using mozilla::ipc::OptionalPrincipalInfo;
66
using mozilla::ipc::PrincipalInfo;
67
using mozilla::ipc::LoadInfoArgsToLoadInfo;
68
using IPC::SerializedLoadContext;
69
70
namespace mozilla {
71
namespace net {
72
73
// C++ file contents
74
NeckoParent::NeckoParent()
75
0
{
76
0
  // Init HTTP protocol handler now since we need atomTable up and running very
77
0
  // early (IPDL argument handling for PHttpChannel constructor needs it) so
78
0
  // normal init (during 1st Http channel request) isn't early enough.
79
0
  nsCOMPtr<nsIProtocolHandler> proto =
80
0
    do_GetService("@mozilla.org/network/protocol;1?name=http");
81
0
82
0
  // only register once--we will have multiple NeckoParents if there are
83
0
  // multiple child processes.
84
0
  static bool registeredBool = false;
85
0
  if (!registeredBool) {
86
0
    Preferences::AddBoolVarCache(&NeckoCommonInternal::gSecurityDisabled,
87
0
                                 "network.disable.ipc.security");
88
0
    registeredBool = true;
89
0
  }
90
0
}
91
92
static PBOverrideStatus
93
PBOverrideStatusFromLoadContext(const SerializedLoadContext& aSerialized)
94
0
{
95
0
  if (!aSerialized.IsNotNull() && aSerialized.IsPrivateBitValid()) {
96
0
    return (aSerialized.mOriginAttributes.mPrivateBrowsingId > 0) ?
97
0
      kPBOverride_Private :
98
0
      kPBOverride_NotPrivate;
99
0
  }
100
0
  return kPBOverride_Unset;
101
0
}
102
103
static already_AddRefed<nsIPrincipal>
104
GetRequestingPrincipal(const OptionalLoadInfoArgs& aOptionalLoadInfoArgs)
105
0
{
106
0
  if (aOptionalLoadInfoArgs.type() != OptionalLoadInfoArgs::TLoadInfoArgs) {
107
0
    return nullptr;
108
0
  }
109
0
110
0
  const LoadInfoArgs& loadInfoArgs = aOptionalLoadInfoArgs.get_LoadInfoArgs();
111
0
  const OptionalPrincipalInfo& optionalPrincipalInfo =
112
0
    loadInfoArgs.requestingPrincipalInfo();
113
0
114
0
  if (optionalPrincipalInfo.type() != OptionalPrincipalInfo::TPrincipalInfo) {
115
0
    return nullptr;
116
0
  }
117
0
118
0
  const PrincipalInfo& principalInfo =
119
0
    optionalPrincipalInfo.get_PrincipalInfo();
120
0
121
0
  return PrincipalInfoToPrincipal(principalInfo);
122
0
}
123
124
static already_AddRefed<nsIPrincipal>
125
GetRequestingPrincipal(const HttpChannelCreationArgs& aArgs)
126
0
{
127
0
  if (aArgs.type() != HttpChannelCreationArgs::THttpChannelOpenArgs) {
128
0
    return nullptr;
129
0
  }
130
0
131
0
  const HttpChannelOpenArgs& args = aArgs.get_HttpChannelOpenArgs();
132
0
  return GetRequestingPrincipal(args.loadInfo());
133
0
}
134
135
static already_AddRefed<nsIPrincipal>
136
GetRequestingPrincipal(const FTPChannelCreationArgs& aArgs)
137
0
{
138
0
  if (aArgs.type() != FTPChannelCreationArgs::TFTPChannelOpenArgs) {
139
0
    return nullptr;
140
0
  }
141
0
142
0
  const FTPChannelOpenArgs& args = aArgs.get_FTPChannelOpenArgs();
143
0
  return GetRequestingPrincipal(args.loadInfo());
144
0
}
145
146
// Bug 1289001 - If GetValidatedOriginAttributes returns an error string, that
147
// usually leads to a content crash with very little info about the cause.
148
// We prefer to crash on the parent, so we get the reason in the crash report.
149
static MOZ_COLD
150
void CrashWithReason(const char * reason)
151
0
{
152
0
#ifndef RELEASE_OR_BETA
153
0
  MOZ_CRASH_UNSAFE_OOL(reason);
154
0
#endif
155
0
}
156
157
const char*
158
NeckoParent::GetValidatedOriginAttributes(const SerializedLoadContext& aSerialized,
159
                                          PContentParent* aContent,
160
                                          nsIPrincipal* aRequestingPrincipal,
161
                                          OriginAttributes& aAttrs)
162
0
{
163
0
  if (!UsingNeckoIPCSecurity()) {
164
0
    if (!aSerialized.IsNotNull()) {
165
0
      // If serialized is null, we cannot validate anything. We have to assume
166
0
      // that this requests comes from a SystemPrincipal.
167
0
      aAttrs = OriginAttributes(NECKO_NO_APP_ID, false);
168
0
    } else {
169
0
      aAttrs = aSerialized.mOriginAttributes;
170
0
    }
171
0
    return nullptr;
172
0
  }
173
0
174
0
  if (!aSerialized.IsNotNull()) {
175
0
    CrashWithReason("GetValidatedOriginAttributes | SerializedLoadContext from child is null");
176
0
    return "SerializedLoadContext from child is null";
177
0
  }
178
0
179
0
  nsTArray<TabContext> contextArray =
180
0
    static_cast<ContentParent*>(aContent)->GetManagedTabContext();
181
0
182
0
  nsAutoCString serializedSuffix;
183
0
  aSerialized.mOriginAttributes.CreateAnonymizedSuffix(serializedSuffix);
184
0
185
0
  nsAutoCString debugString;
186
0
  for (uint32_t i = 0; i < contextArray.Length(); i++) {
187
0
    const TabContext& tabContext = contextArray[i];
188
0
189
0
    if (!ChromeUtils::IsOriginAttributesEqual(aSerialized.mOriginAttributes,
190
0
                                              tabContext.OriginAttributesRef())) {
191
0
      debugString.AppendLiteral("(");
192
0
      debugString.Append(serializedSuffix);
193
0
      debugString.AppendLiteral(",");
194
0
195
0
      nsAutoCString tabSuffix;
196
0
      tabContext.OriginAttributesRef().CreateAnonymizedSuffix(tabSuffix);
197
0
      debugString.Append(tabSuffix);
198
0
199
0
      debugString.AppendLiteral(")");
200
0
      continue;
201
0
    }
202
0
203
0
    aAttrs = aSerialized.mOriginAttributes;
204
0
    return nullptr;
205
0
  }
206
0
207
0
  // This may be a ServiceWorker: when a push notification is received, FF wakes
208
0
  // up the corrisponding service worker so that it can manage the PushEvent. At
209
0
  // that time we probably don't have any valid tabcontext, but still, we want
210
0
  // to support http channel requests coming from that ServiceWorker.
211
0
  if (aRequestingPrincipal) {
212
0
    RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
213
0
    if (swm &&
214
0
        swm->MayHaveActiveServiceWorkerInstance(static_cast<ContentParent*>(aContent),
215
0
                                                aRequestingPrincipal)) {
216
0
      aAttrs = aSerialized.mOriginAttributes;
217
0
      return nullptr;
218
0
    }
219
0
  }
220
0
221
0
  nsAutoCString errorString;
222
0
  errorString.AppendLiteral("GetValidatedOriginAttributes | App does not have permission -");
223
0
  errorString.Append(debugString);
224
0
225
0
  // Leak the buffer on the heap to make sure that it lives long enough, as
226
0
  // MOZ_CRASH_ANNOTATE expects the pointer passed to it to live to the end of
227
0
  // the program.
228
0
  char * error = strdup(errorString.BeginReading());
229
0
  CrashWithReason(error);
230
0
  return "App does not have permission";
231
0
}
232
233
const char *
234
NeckoParent::CreateChannelLoadContext(const PBrowserOrId& aBrowser,
235
                                      PContentParent* aContent,
236
                                      const SerializedLoadContext& aSerialized,
237
                                      nsIPrincipal* aRequestingPrincipal,
238
                                      nsCOMPtr<nsILoadContext> &aResult)
239
0
{
240
0
  OriginAttributes attrs;
241
0
  const char* error = GetValidatedOriginAttributes(aSerialized, aContent,
242
0
                                                   aRequestingPrincipal, attrs);
243
0
  if (error) {
244
0
    return error;
245
0
  }
246
0
247
0
  // if !UsingNeckoIPCSecurity(), we may not have a LoadContext to set. This is
248
0
  // the common case for most xpcshell tests.
249
0
  if (aSerialized.IsNotNull()) {
250
0
    attrs.SyncAttributesWithPrivateBrowsing(aSerialized.mOriginAttributes.mPrivateBrowsingId > 0);
251
0
    switch (aBrowser.type()) {
252
0
      case PBrowserOrId::TPBrowserParent:
253
0
      {
254
0
        RefPtr<TabParent> tabParent =
255
0
          TabParent::GetFrom(aBrowser.get_PBrowserParent());
256
0
        dom::Element* topFrameElement = nullptr;
257
0
        if (tabParent) {
258
0
          topFrameElement = tabParent->GetOwnerElement();
259
0
        }
260
0
        aResult = new LoadContext(aSerialized, topFrameElement, attrs);
261
0
        break;
262
0
      }
263
0
      case PBrowserOrId::TTabId:
264
0
      {
265
0
        aResult = new LoadContext(aSerialized, aBrowser.get_TabId(), attrs);
266
0
        break;
267
0
      }
268
0
      default:
269
0
        MOZ_CRASH();
270
0
    }
271
0
  }
272
0
273
0
  return nullptr;
274
0
}
275
276
void
277
NeckoParent::ActorDestroy(ActorDestroyReason aWhy)
278
0
{
279
0
  // Nothing needed here. Called right before destructor since this is a
280
0
  // non-refcounted class.
281
0
}
282
283
PHttpChannelParent*
284
NeckoParent::AllocPHttpChannelParent(const PBrowserOrId& aBrowser,
285
                                     const SerializedLoadContext& aSerialized,
286
                                     const HttpChannelCreationArgs& aOpenArgs)
287
0
{
288
0
  nsCOMPtr<nsIPrincipal> requestingPrincipal =
289
0
    GetRequestingPrincipal(aOpenArgs);
290
0
291
0
  nsCOMPtr<nsILoadContext> loadContext;
292
0
  const char *error = CreateChannelLoadContext(aBrowser, Manager(),
293
0
                                               aSerialized, requestingPrincipal,
294
0
                                               loadContext);
295
0
  if (error) {
296
0
    printf_stderr("NeckoParent::AllocPHttpChannelParent: "
297
0
                  "FATAL error: %s: KILLING CHILD PROCESS\n",
298
0
                  error);
299
0
    return nullptr;
300
0
  }
301
0
  PBOverrideStatus overrideStatus = PBOverrideStatusFromLoadContext(aSerialized);
302
0
  HttpChannelParent *p = new HttpChannelParent(aBrowser, loadContext, overrideStatus);
303
0
  p->AddRef();
304
0
  return p;
305
0
}
306
307
bool
308
NeckoParent::DeallocPHttpChannelParent(PHttpChannelParent* channel)
309
0
{
310
0
  HttpChannelParent *p = static_cast<HttpChannelParent *>(channel);
311
0
  p->Release();
312
0
  return true;
313
0
}
314
315
mozilla::ipc::IPCResult
316
NeckoParent::RecvPHttpChannelConstructor(
317
                      PHttpChannelParent* aActor,
318
                      const PBrowserOrId& aBrowser,
319
                      const SerializedLoadContext& aSerialized,
320
                      const HttpChannelCreationArgs& aOpenArgs)
321
0
{
322
0
  HttpChannelParent* p = static_cast<HttpChannelParent*>(aActor);
323
0
  if (!p->Init(aOpenArgs)) {
324
0
    return IPC_FAIL_NO_REASON(this);
325
0
  }
326
0
  return IPC_OK();
327
0
}
328
329
PStunAddrsRequestParent*
330
NeckoParent::AllocPStunAddrsRequestParent()
331
0
{
332
0
#ifdef MOZ_WEBRTC
333
0
  StunAddrsRequestParent* p = new StunAddrsRequestParent();
334
0
  p->AddRef();
335
0
  return p;
336
#else
337
  return nullptr;
338
#endif
339
}
340
341
bool
342
NeckoParent::DeallocPStunAddrsRequestParent(PStunAddrsRequestParent* aActor)
343
0
{
344
0
#ifdef MOZ_WEBRTC
345
0
  StunAddrsRequestParent* p = static_cast<StunAddrsRequestParent*>(aActor);
346
0
  p->Release();
347
0
#endif
348
0
  return true;
349
0
}
350
351
PAltDataOutputStreamParent*
352
NeckoParent::AllocPAltDataOutputStreamParent(
353
        const nsCString& type,
354
        const int64_t& predictedSize,
355
        PHttpChannelParent* channel)
356
0
{
357
0
  HttpChannelParent* chan = static_cast<HttpChannelParent*>(channel);
358
0
  nsCOMPtr<nsIOutputStream> stream;
359
0
  nsresult rv = chan->OpenAlternativeOutputStream(type, predictedSize, getter_AddRefs(stream));
360
0
  AltDataOutputStreamParent* parent = new AltDataOutputStreamParent(stream);
361
0
  parent->AddRef();
362
0
  // If the return value was not NS_OK, the error code will be sent
363
0
  // asynchronously to the child, after receiving the first message.
364
0
  parent->SetError(rv);
365
0
  return parent;
366
0
}
367
368
bool
369
NeckoParent::DeallocPAltDataOutputStreamParent(PAltDataOutputStreamParent* aActor)
370
0
{
371
0
  AltDataOutputStreamParent* parent = static_cast<AltDataOutputStreamParent*>(aActor);
372
0
  parent->Release();
373
0
  return true;
374
0
}
375
376
PFTPChannelParent*
377
NeckoParent::AllocPFTPChannelParent(const PBrowserOrId& aBrowser,
378
                                    const SerializedLoadContext& aSerialized,
379
                                    const FTPChannelCreationArgs& aOpenArgs)
380
0
{
381
0
  nsCOMPtr<nsIPrincipal> requestingPrincipal =
382
0
    GetRequestingPrincipal(aOpenArgs);
383
0
384
0
  nsCOMPtr<nsILoadContext> loadContext;
385
0
  const char *error = CreateChannelLoadContext(aBrowser, Manager(),
386
0
                                               aSerialized, requestingPrincipal,
387
0
                                               loadContext);
388
0
  if (error) {
389
0
    printf_stderr("NeckoParent::AllocPFTPChannelParent: "
390
0
                  "FATAL error: %s: KILLING CHILD PROCESS\n",
391
0
                  error);
392
0
    return nullptr;
393
0
  }
394
0
  PBOverrideStatus overrideStatus = PBOverrideStatusFromLoadContext(aSerialized);
395
0
  FTPChannelParent *p = new FTPChannelParent(aBrowser, loadContext, overrideStatus);
396
0
  p->AddRef();
397
0
  return p;
398
0
}
399
400
bool
401
NeckoParent::DeallocPFTPChannelParent(PFTPChannelParent* channel)
402
0
{
403
0
  FTPChannelParent *p = static_cast<FTPChannelParent *>(channel);
404
0
  p->Release();
405
0
  return true;
406
0
}
407
408
mozilla::ipc::IPCResult
409
NeckoParent::RecvPFTPChannelConstructor(
410
                      PFTPChannelParent* aActor,
411
                      const PBrowserOrId& aBrowser,
412
                      const SerializedLoadContext& aSerialized,
413
                      const FTPChannelCreationArgs& aOpenArgs)
414
0
{
415
0
  FTPChannelParent* p = static_cast<FTPChannelParent*>(aActor);
416
0
  if (!p->Init(aOpenArgs)) {
417
0
    return IPC_FAIL_NO_REASON(this);
418
0
  }
419
0
  return IPC_OK();
420
0
}
421
422
PCookieServiceParent*
423
NeckoParent::AllocPCookieServiceParent()
424
0
{
425
0
  return new CookieServiceParent();
426
0
}
427
428
bool
429
NeckoParent::DeallocPCookieServiceParent(PCookieServiceParent* cs)
430
0
{
431
0
  delete cs;
432
0
  return true;
433
0
}
434
435
PWyciwygChannelParent*
436
NeckoParent::AllocPWyciwygChannelParent()
437
0
{
438
0
  WyciwygChannelParent *p = new WyciwygChannelParent();
439
0
  p->AddRef();
440
0
  return p;
441
0
}
442
443
bool
444
NeckoParent::DeallocPWyciwygChannelParent(PWyciwygChannelParent* channel)
445
0
{
446
0
  WyciwygChannelParent *p = static_cast<WyciwygChannelParent *>(channel);
447
0
  p->Release();
448
0
  return true;
449
0
}
450
451
PWebSocketParent*
452
NeckoParent::AllocPWebSocketParent(const PBrowserOrId& browser,
453
                                   const SerializedLoadContext& serialized,
454
                                   const uint32_t& aSerial)
455
0
{
456
0
  nsCOMPtr<nsILoadContext> loadContext;
457
0
  const char *error = CreateChannelLoadContext(browser, Manager(),
458
0
                                               serialized,
459
0
                                               nullptr,
460
0
                                               loadContext);
461
0
  if (error) {
462
0
    printf_stderr("NeckoParent::AllocPWebSocketParent: "
463
0
                  "FATAL error: %s: KILLING CHILD PROCESS\n",
464
0
                  error);
465
0
    return nullptr;
466
0
  }
467
0
468
0
  RefPtr<TabParent> tabParent = TabParent::GetFrom(browser.get_PBrowserParent());
469
0
  PBOverrideStatus overrideStatus = PBOverrideStatusFromLoadContext(serialized);
470
0
  WebSocketChannelParent* p = new WebSocketChannelParent(tabParent, loadContext,
471
0
                                                         overrideStatus,
472
0
                                                         aSerial);
473
0
  p->AddRef();
474
0
  return p;
475
0
}
476
477
bool
478
NeckoParent::DeallocPWebSocketParent(PWebSocketParent* actor)
479
0
{
480
0
  WebSocketChannelParent* p = static_cast<WebSocketChannelParent*>(actor);
481
0
  p->Release();
482
0
  return true;
483
0
}
484
485
PWebSocketEventListenerParent*
486
NeckoParent::AllocPWebSocketEventListenerParent(const uint64_t& aInnerWindowID)
487
0
{
488
0
  RefPtr<WebSocketEventListenerParent> c =
489
0
    new WebSocketEventListenerParent(aInnerWindowID);
490
0
  return c.forget().take();
491
0
}
492
493
bool
494
NeckoParent::DeallocPWebSocketEventListenerParent(PWebSocketEventListenerParent* aActor)
495
0
{
496
0
  RefPtr<WebSocketEventListenerParent> c =
497
0
    dont_AddRef(static_cast<WebSocketEventListenerParent*>(aActor));
498
0
  MOZ_ASSERT(c);
499
0
  return true;
500
0
}
501
502
PDataChannelParent*
503
NeckoParent::AllocPDataChannelParent(const uint32_t &channelId)
504
0
{
505
0
  RefPtr<DataChannelParent> p = new DataChannelParent();
506
0
  return p.forget().take();
507
0
}
508
509
bool
510
NeckoParent::DeallocPDataChannelParent(PDataChannelParent* actor)
511
0
{
512
0
  RefPtr<DataChannelParent> p = dont_AddRef(static_cast<DataChannelParent*>(actor));
513
0
  return true;
514
0
}
515
516
mozilla::ipc::IPCResult
517
NeckoParent::RecvPDataChannelConstructor(PDataChannelParent* actor,
518
                                         const uint32_t& channelId)
519
0
{
520
0
  DataChannelParent* p = static_cast<DataChannelParent*>(actor);
521
0
  DebugOnly<bool> rv = p->Init(channelId);
522
0
  MOZ_ASSERT(rv);
523
0
  return IPC_OK();
524
0
}
525
526
PSimpleChannelParent*
527
NeckoParent::AllocPSimpleChannelParent(const uint32_t &channelId)
528
0
{
529
0
  RefPtr<SimpleChannelParent> p = new SimpleChannelParent();
530
0
  return p.forget().take();
531
0
}
532
533
bool
534
NeckoParent::DeallocPSimpleChannelParent(PSimpleChannelParent* actor)
535
0
{
536
0
  RefPtr<SimpleChannelParent> p = dont_AddRef(actor).downcast<SimpleChannelParent>();
537
0
  return true;
538
0
}
539
540
mozilla::ipc::IPCResult
541
NeckoParent::RecvPSimpleChannelConstructor(PSimpleChannelParent* actor,
542
                                           const uint32_t& channelId)
543
0
{
544
0
  SimpleChannelParent* p = static_cast<SimpleChannelParent*>(actor);
545
0
  MOZ_ALWAYS_TRUE(p->Init(channelId));
546
0
  return IPC_OK();
547
0
}
548
549
PFileChannelParent*
550
NeckoParent::AllocPFileChannelParent(const uint32_t &channelId)
551
0
{
552
0
  RefPtr<FileChannelParent> p = new FileChannelParent();
553
0
  return p.forget().take();
554
0
}
555
556
bool
557
NeckoParent::DeallocPFileChannelParent(PFileChannelParent* actor)
558
0
{
559
0
  RefPtr<FileChannelParent> p = dont_AddRef(static_cast<FileChannelParent*>(actor));
560
0
  return true;
561
0
}
562
563
mozilla::ipc::IPCResult
564
NeckoParent::RecvPFileChannelConstructor(PFileChannelParent* actor,
565
                                         const uint32_t& channelId)
566
0
{
567
0
  FileChannelParent* p = static_cast<FileChannelParent*>(actor);
568
0
  DebugOnly<bool> rv = p->Init(channelId);
569
0
  MOZ_ASSERT(rv);
570
0
  return IPC_OK();
571
0
}
572
573
PTCPSocketParent*
574
NeckoParent::AllocPTCPSocketParent(const nsString& /* host */,
575
                                   const uint16_t& /* port */)
576
0
{
577
0
  // We actually don't need host/port to construct a TCPSocketParent since
578
0
  // TCPSocketParent will maintain an internal nsIDOMTCPSocket instance which
579
0
  // can be delegated to get the host/port.
580
0
  TCPSocketParent* p = new TCPSocketParent();
581
0
  p->AddIPDLReference();
582
0
  return p;
583
0
}
584
585
bool
586
NeckoParent::DeallocPTCPSocketParent(PTCPSocketParent* actor)
587
0
{
588
0
  TCPSocketParent* p = static_cast<TCPSocketParent*>(actor);
589
0
  p->ReleaseIPDLReference();
590
0
  return true;
591
0
}
592
593
PTCPServerSocketParent*
594
NeckoParent::AllocPTCPServerSocketParent(const uint16_t& aLocalPort,
595
                                         const uint16_t& aBacklog,
596
                                         const bool& aUseArrayBuffers)
597
0
{
598
0
  TCPServerSocketParent* p = new TCPServerSocketParent(this, aLocalPort, aBacklog, aUseArrayBuffers);
599
0
  p->AddIPDLReference();
600
0
  return p;
601
0
}
602
603
mozilla::ipc::IPCResult
604
NeckoParent::RecvPTCPServerSocketConstructor(PTCPServerSocketParent* aActor,
605
                                             const uint16_t& aLocalPort,
606
                                             const uint16_t& aBacklog,
607
                                             const bool& aUseArrayBuffers)
608
0
{
609
0
  static_cast<TCPServerSocketParent*>(aActor)->Init();
610
0
  return IPC_OK();
611
0
}
612
613
bool
614
NeckoParent::DeallocPTCPServerSocketParent(PTCPServerSocketParent* actor)
615
0
{
616
0
  TCPServerSocketParent* p = static_cast<TCPServerSocketParent*>(actor);
617
0
   p->ReleaseIPDLReference();
618
0
  return true;
619
0
}
620
621
PUDPSocketParent*
622
NeckoParent::AllocPUDPSocketParent(const Principal& /* unused */,
623
                                   const nsCString& /* unused */)
624
0
{
625
0
  RefPtr<UDPSocketParent> p = new UDPSocketParent(this);
626
0
627
0
  return p.forget().take();
628
0
}
629
630
mozilla::ipc::IPCResult
631
NeckoParent::RecvPUDPSocketConstructor(PUDPSocketParent* aActor,
632
                                       const Principal& aPrincipal,
633
                                       const nsCString& aFilter)
634
0
{
635
0
  if (!static_cast<UDPSocketParent*>(aActor)->Init(aPrincipal, aFilter)) {
636
0
    return IPC_FAIL_NO_REASON(this);
637
0
  }
638
0
  return IPC_OK();
639
0
}
640
641
bool
642
NeckoParent::DeallocPUDPSocketParent(PUDPSocketParent* actor)
643
0
{
644
0
  UDPSocketParent* p = static_cast<UDPSocketParent*>(actor);
645
0
  p->Release();
646
0
  return true;
647
0
}
648
649
PDNSRequestParent*
650
NeckoParent::AllocPDNSRequestParent(const nsCString& aHost,
651
                                    const OriginAttributes& aOriginAttributes,
652
                                    const uint32_t& aFlags)
653
0
{
654
0
  DNSRequestParent *p = new DNSRequestParent();
655
0
  p->AddRef();
656
0
  return p;
657
0
}
658
659
mozilla::ipc::IPCResult
660
NeckoParent::RecvPDNSRequestConstructor(PDNSRequestParent* aActor,
661
                                        const nsCString& aHost,
662
                                        const OriginAttributes& aOriginAttributes,
663
                                        const uint32_t& aFlags)
664
0
{
665
0
  static_cast<DNSRequestParent*>(aActor)->DoAsyncResolve(aHost,
666
0
                                                         aOriginAttributes,
667
0
                                                         aFlags);
668
0
  return IPC_OK();
669
0
}
670
671
bool
672
NeckoParent::DeallocPDNSRequestParent(PDNSRequestParent* aParent)
673
0
{
674
0
  DNSRequestParent *p = static_cast<DNSRequestParent*>(aParent);
675
0
  p->Release();
676
0
  return true;
677
0
}
678
679
mozilla::ipc::IPCResult
680
NeckoParent::RecvSpeculativeConnect(const URIParams& aURI,
681
                                    const Principal& aPrincipal,
682
                                    const bool& aAnonymous)
683
0
{
684
0
  nsCOMPtr<nsISpeculativeConnect> speculator(gIOService);
685
0
  nsCOMPtr<nsIURI> uri = DeserializeURI(aURI);
686
0
  nsCOMPtr<nsIPrincipal> principal(aPrincipal);
687
0
  if (uri && speculator) {
688
0
    if (aAnonymous) {
689
0
      speculator->SpeculativeAnonymousConnect2(uri, principal, nullptr);
690
0
    } else {
691
0
      speculator->SpeculativeConnect2(uri, principal, nullptr);
692
0
    }
693
0
694
0
  }
695
0
  return IPC_OK();
696
0
}
697
698
mozilla::ipc::IPCResult
699
NeckoParent::RecvHTMLDNSPrefetch(const nsString& hostname, const bool& isHttps,
700
                                 const OriginAttributes& aOriginAttributes,
701
                                 const uint16_t& flags)
702
0
{
703
0
  nsHTMLDNSPrefetch::Prefetch(hostname, isHttps, aOriginAttributes, flags);
704
0
  return IPC_OK();
705
0
}
706
707
mozilla::ipc::IPCResult
708
NeckoParent::RecvCancelHTMLDNSPrefetch(const nsString& hostname,
709
                                       const bool& isHttps,
710
                                       const OriginAttributes& aOriginAttributes,
711
                                       const uint16_t& flags,
712
                                       const nsresult& reason)
713
0
{
714
0
  nsHTMLDNSPrefetch::CancelPrefetch(hostname, isHttps, aOriginAttributes,
715
0
                                    flags, reason);
716
0
  return IPC_OK();
717
0
}
718
719
PChannelDiverterParent*
720
NeckoParent::AllocPChannelDiverterParent(const ChannelDiverterArgs& channel)
721
0
{
722
0
  return new ChannelDiverterParent();
723
0
}
724
725
mozilla::ipc::IPCResult
726
NeckoParent::RecvPChannelDiverterConstructor(PChannelDiverterParent* actor,
727
                                             const ChannelDiverterArgs& channel)
728
0
{
729
0
  auto parent = static_cast<ChannelDiverterParent*>(actor);
730
0
  parent->Init(channel);
731
0
  return IPC_OK();
732
0
}
733
734
bool
735
NeckoParent::DeallocPChannelDiverterParent(PChannelDiverterParent* parent)
736
0
{
737
0
  delete static_cast<ChannelDiverterParent*>(parent);
738
0
  return true;
739
0
}
740
741
PTransportProviderParent*
742
NeckoParent::AllocPTransportProviderParent()
743
0
{
744
0
  RefPtr<TransportProviderParent> res = new TransportProviderParent();
745
0
  return res.forget().take();
746
0
}
747
748
bool
749
NeckoParent::DeallocPTransportProviderParent(PTransportProviderParent* aActor)
750
0
{
751
0
  RefPtr<TransportProviderParent> provider =
752
0
    dont_AddRef(static_cast<TransportProviderParent*>(aActor));
753
0
  return true;
754
0
}
755
756
namespace {
757
std::map<uint64_t, nsCOMPtr<nsIAuthPromptCallback> >&
758
CallbackMap()
759
0
{
760
0
  MOZ_ASSERT(NS_IsMainThread());
761
0
  static std::map<uint64_t, nsCOMPtr<nsIAuthPromptCallback> > sCallbackMap;
762
0
  return sCallbackMap;
763
0
}
764
} // namespace
765
766
NS_IMPL_ISUPPORTS(NeckoParent::NestedFrameAuthPrompt, nsIAuthPrompt2)
767
768
NeckoParent::NestedFrameAuthPrompt::NestedFrameAuthPrompt(PNeckoParent* aParent,
769
                                                          TabId aNestedFrameId)
770
  : mNeckoParent(aParent)
771
  , mNestedFrameId(aNestedFrameId)
772
0
{}
773
774
NS_IMETHODIMP
775
NeckoParent::NestedFrameAuthPrompt::AsyncPromptAuth(
776
  nsIChannel* aChannel, nsIAuthPromptCallback* callback,
777
  nsISupports*, uint32_t,
778
  nsIAuthInformation* aInfo, nsICancelable**)
779
0
{
780
0
  static uint64_t callbackId = 0;
781
0
  MOZ_ASSERT(XRE_IsParentProcess());
782
0
  nsCOMPtr<nsIURI> uri;
783
0
  nsresult rv = aChannel->GetURI(getter_AddRefs(uri));
784
0
  NS_ENSURE_SUCCESS(rv, rv);
785
0
  nsAutoCString spec;
786
0
  if (uri) {
787
0
    rv = uri->GetSpec(spec);
788
0
    NS_ENSURE_SUCCESS(rv, rv);
789
0
  }
790
0
  nsString realm;
791
0
  rv = aInfo->GetRealm(realm);
792
0
  NS_ENSURE_SUCCESS(rv, rv);
793
0
  callbackId++;
794
0
  if (mNeckoParent->SendAsyncAuthPromptForNestedFrame(mNestedFrameId,
795
0
                                                      spec,
796
0
                                                      realm,
797
0
                                                      callbackId)) {
798
0
    CallbackMap()[callbackId] = callback;
799
0
    return NS_OK;
800
0
  }
801
0
  return NS_ERROR_FAILURE;
802
0
}
803
804
mozilla::ipc::IPCResult
805
NeckoParent::RecvOnAuthAvailable(const uint64_t& aCallbackId,
806
                                 const nsString& aUser,
807
                                 const nsString& aPassword,
808
                                 const nsString& aDomain)
809
0
{
810
0
  nsCOMPtr<nsIAuthPromptCallback> callback = CallbackMap()[aCallbackId];
811
0
  if (!callback) {
812
0
    return IPC_OK();
813
0
  }
814
0
  CallbackMap().erase(aCallbackId);
815
0
816
0
  RefPtr<nsAuthInformationHolder> holder =
817
0
    new nsAuthInformationHolder(0, EmptyString(), EmptyCString());
818
0
  holder->SetUsername(aUser);
819
0
  holder->SetPassword(aPassword);
820
0
  holder->SetDomain(aDomain);
821
0
822
0
  callback->OnAuthAvailable(nullptr, holder);
823
0
  return IPC_OK();
824
0
}
825
826
mozilla::ipc::IPCResult
827
NeckoParent::RecvOnAuthCancelled(const uint64_t& aCallbackId,
828
                                 const bool& aUserCancel)
829
0
{
830
0
  nsCOMPtr<nsIAuthPromptCallback> callback = CallbackMap()[aCallbackId];
831
0
  if (!callback) {
832
0
    return IPC_OK();
833
0
  }
834
0
  CallbackMap().erase(aCallbackId);
835
0
  callback->OnAuthCancelled(nullptr, aUserCancel);
836
0
  return IPC_OK();
837
0
}
838
839
/* Predictor Messages */
840
mozilla::ipc::IPCResult
841
NeckoParent::RecvPredPredict(const ipc::OptionalURIParams& aTargetURI,
842
                             const ipc::OptionalURIParams& aSourceURI,
843
                             const uint32_t& aReason,
844
                             const OriginAttributes& aOriginAttributes,
845
                             const bool& hasVerifier)
846
0
{
847
0
  nsCOMPtr<nsIURI> targetURI = DeserializeURI(aTargetURI);
848
0
  nsCOMPtr<nsIURI> sourceURI = DeserializeURI(aSourceURI);
849
0
850
0
  // Get the current predictor
851
0
  nsresult rv = NS_OK;
852
0
  nsCOMPtr<nsINetworkPredictor> predictor =
853
0
    do_GetService("@mozilla.org/network/predictor;1", &rv);
854
0
  NS_ENSURE_SUCCESS(rv, IPC_FAIL_NO_REASON(this));
855
0
856
0
  nsCOMPtr<nsINetworkPredictorVerifier> verifier;
857
0
  if (hasVerifier) {
858
0
    verifier = do_QueryInterface(predictor);
859
0
  }
860
0
  predictor->PredictNative(targetURI, sourceURI, aReason, aOriginAttributes, verifier);
861
0
  return IPC_OK();
862
0
}
863
864
mozilla::ipc::IPCResult
865
NeckoParent::RecvPredLearn(const ipc::URIParams& aTargetURI,
866
                           const ipc::OptionalURIParams& aSourceURI,
867
                           const uint32_t& aReason,
868
                           const OriginAttributes& aOriginAttributes)
869
0
{
870
0
  nsCOMPtr<nsIURI> targetURI = DeserializeURI(aTargetURI);
871
0
  nsCOMPtr<nsIURI> sourceURI = DeserializeURI(aSourceURI);
872
0
873
0
  // Get the current predictor
874
0
  nsresult rv = NS_OK;
875
0
  nsCOMPtr<nsINetworkPredictor> predictor =
876
0
    do_GetService("@mozilla.org/network/predictor;1", &rv);
877
0
  NS_ENSURE_SUCCESS(rv, IPC_FAIL_NO_REASON(this));
878
0
879
0
  predictor->LearnNative(targetURI, sourceURI, aReason, aOriginAttributes);
880
0
  return IPC_OK();
881
0
}
882
883
mozilla::ipc::IPCResult
884
NeckoParent::RecvPredReset()
885
0
{
886
0
  // Get the current predictor
887
0
  nsresult rv = NS_OK;
888
0
  nsCOMPtr<nsINetworkPredictor> predictor =
889
0
    do_GetService("@mozilla.org/network/predictor;1", &rv);
890
0
  NS_ENSURE_SUCCESS(rv, IPC_FAIL_NO_REASON(this));
891
0
892
0
  predictor->Reset();
893
0
  return IPC_OK();
894
0
}
895
896
mozilla::ipc::IPCResult
897
NeckoParent::RecvRequestContextLoadBegin(const uint64_t& rcid)
898
0
{
899
0
  nsCOMPtr<nsIRequestContextService> rcsvc =
900
0
    do_GetService("@mozilla.org/network/request-context-service;1");
901
0
  if (!rcsvc) {
902
0
    return IPC_OK();
903
0
  }
904
0
  nsCOMPtr<nsIRequestContext> rc;
905
0
  rcsvc->GetRequestContext(rcid, getter_AddRefs(rc));
906
0
  if (rc) {
907
0
    rc->BeginLoad();
908
0
  }
909
0
910
0
  return IPC_OK();
911
0
}
912
913
mozilla::ipc::IPCResult
914
NeckoParent::RecvRequestContextAfterDOMContentLoaded(const uint64_t& rcid)
915
0
{
916
0
  nsCOMPtr<nsIRequestContextService> rcsvc =
917
0
    do_GetService("@mozilla.org/network/request-context-service;1");
918
0
  if (!rcsvc) {
919
0
    return IPC_OK();
920
0
  }
921
0
  nsCOMPtr<nsIRequestContext> rc;
922
0
  rcsvc->GetRequestContext(rcid, getter_AddRefs(rc));
923
0
  if (rc) {
924
0
    rc->DOMContentLoaded();
925
0
  }
926
0
927
0
  return IPC_OK();
928
0
}
929
930
mozilla::ipc::IPCResult
931
NeckoParent::RecvRemoveRequestContext(const uint64_t& rcid)
932
0
{
933
0
  nsCOMPtr<nsIRequestContextService> rcsvc =
934
0
    do_GetService("@mozilla.org/network/request-context-service;1");
935
0
  if (!rcsvc) {
936
0
    return IPC_OK();
937
0
  }
938
0
939
0
  rcsvc->RemoveRequestContext(rcid);
940
0
941
0
  return IPC_OK();
942
0
}
943
944
mozilla::ipc::IPCResult
945
NeckoParent::RecvGetExtensionStream(const URIParams& aURI,
946
                                    GetExtensionStreamResolver&& aResolve)
947
0
{
948
0
  nsCOMPtr<nsIURI> deserializedURI = DeserializeURI(aURI);
949
0
  if (!deserializedURI) {
950
0
    return IPC_FAIL_NO_REASON(this);
951
0
  }
952
0
953
0
  RefPtr<ExtensionProtocolHandler> ph(ExtensionProtocolHandler::GetSingleton());
954
0
  MOZ_ASSERT(ph);
955
0
956
0
  // Ask the ExtensionProtocolHandler to give us a new input stream for
957
0
  // this URI. The request comes from an ExtensionProtocolHandler in the
958
0
  // child process, but is not guaranteed to be a valid moz-extension URI,
959
0
  // and not guaranteed to represent a resource that the child should be
960
0
  // allowed to access. The ExtensionProtocolHandler is responsible for
961
0
  // validating the request. Specifically, only URI's for local files that
962
0
  // an extension is allowed to access via moz-extension URI's should be
963
0
  // accepted.
964
0
  nsCOMPtr<nsIInputStream> inputStream;
965
0
  bool terminateSender = true;
966
0
  auto inputStreamOrReason = ph->NewStream(deserializedURI, &terminateSender);
967
0
  if (inputStreamOrReason.isOk()) {
968
0
    inputStream = inputStreamOrReason.unwrap();
969
0
  }
970
0
971
0
  // If NewStream failed, we send back an invalid stream to the child so
972
0
  // it can handle the error. MozPromise rejection is reserved for channel
973
0
  // errors/disconnects.
974
0
  aResolve(inputStream);
975
0
976
0
  if (terminateSender) {
977
0
    return IPC_FAIL_NO_REASON(this);
978
0
  }
979
0
  return IPC_OK();
980
0
}
981
982
mozilla::ipc::IPCResult
983
NeckoParent::RecvGetExtensionFD(const URIParams& aURI,
984
                                GetExtensionFDResolver&& aResolve)
985
0
{
986
0
  nsCOMPtr<nsIURI> deserializedURI = DeserializeURI(aURI);
987
0
  if (!deserializedURI) {
988
0
    return IPC_FAIL_NO_REASON(this);
989
0
  }
990
0
991
0
  RefPtr<ExtensionProtocolHandler> ph(ExtensionProtocolHandler::GetSingleton());
992
0
  MOZ_ASSERT(ph);
993
0
994
0
  // Ask the ExtensionProtocolHandler to give us a new input stream for
995
0
  // this URI. The request comes from an ExtensionProtocolHandler in the
996
0
  // child process, but is not guaranteed to be a valid moz-extension URI,
997
0
  // and not guaranteed to represent a resource that the child should be
998
0
  // allowed to access. The ExtensionProtocolHandler is responsible for
999
0
  // validating the request. Specifically, only URI's for local files that
1000
0
  // an extension is allowed to access via moz-extension URI's should be
1001
0
  // accepted.
1002
0
  bool terminateSender = true;
1003
0
  auto result = ph->NewFD(deserializedURI, &terminateSender, aResolve);
1004
0
1005
0
  if (result.isErr() && terminateSender) {
1006
0
    return IPC_FAIL_NO_REASON(this);
1007
0
  }
1008
0
1009
0
  if (result.isErr()) {
1010
0
    FileDescriptor invalidFD;
1011
0
    aResolve(invalidFD);
1012
0
  }
1013
0
1014
0
  return IPC_OK();
1015
0
}
1016
1017
} // namespace net
1018
} // namespace mozilla