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