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