diff --git a/netwerk/base/nsIOService.cpp b/netwerk/base/nsIOService.cpp index 4ab04116d8c9..9861f3b515fb 100644 --- a/netwerk/base/nsIOService.cpp +++ b/netwerk/base/nsIOService.cpp @@ -52,6 +52,7 @@ #include "mozilla/net/DNS.h" #include "mozilla/ipc/URIUtils.h" #include "mozilla/net/NeckoChild.h" +#include "mozilla/dom/ContentParent.h" #include "CaptivePortalService.h" #include "ReferrerPolicy.h" #include "nsContentSecurityManager.h" @@ -1764,13 +1765,16 @@ IOServiceProxyCallback::OnProxyAvailable(nsICancelable *request, nsIChannel *cha nsresult nsIOService::SpeculativeConnectInternal(nsIURI *aURI, + nsIPrincipal *aPrincipal, nsIInterfaceRequestor *aCallbacks, bool aAnonymous) { if (IsNeckoChild()) { ipc::URIParams params; SerializeURI(aURI, params); - gNeckoChild->SendSpeculativeConnect(params, aAnonymous); + gNeckoChild->SendSpeculativeConnect(params, + IPC::Principal(aPrincipal), + aAnonymous); return NS_OK; } @@ -1782,12 +1786,17 @@ nsIOService::SpeculativeConnectInternal(nsIURI *aURI, do_GetService(NS_PROTOCOLPROXYSERVICE_CONTRACTID, &rv); NS_ENSURE_SUCCESS(rv, rv); - nsCOMPtr secMan( - do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv)); - NS_ENSURE_SUCCESS(rv, rv); - nsCOMPtr systemPrincipal; - rv = secMan->GetSystemPrincipal(getter_AddRefs(systemPrincipal)); - NS_ENSURE_SUCCESS(rv, rv); + nsCOMPtr loadingPrincipal = aPrincipal; + + // If the principal is given, we use this prinicpal directly. Otherwise, + // we fallback to use the system principal. + if (!aPrincipal) { + nsCOMPtr secMan( + do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv)); + NS_ENSURE_SUCCESS(rv, rv); + rv = secMan->GetSystemPrincipal(getter_AddRefs(loadingPrincipal)); + NS_ENSURE_SUCCESS(rv, rv); + } // dummy channel used to create a TCP connection. // we perform security checks on the *real* channel, responsible @@ -1798,7 +1807,7 @@ nsIOService::SpeculativeConnectInternal(nsIURI *aURI, nsCOMPtr channel; rv = NewChannelFromURI2(aURI, nullptr, // aLoadingNode, - systemPrincipal, + loadingPrincipal, nullptr, //aTriggeringPrincipal, nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL, nsIContentPolicy::TYPE_OTHER, @@ -1826,14 +1835,30 @@ NS_IMETHODIMP nsIOService::SpeculativeConnect(nsIURI *aURI, nsIInterfaceRequestor *aCallbacks) { - return SpeculativeConnectInternal(aURI, aCallbacks, false); + return SpeculativeConnectInternal(aURI, nullptr, aCallbacks, false); +} + +NS_IMETHODIMP +nsIOService::SpeculativeConnect2(nsIURI *aURI, + nsIPrincipal *aPrincipal, + nsIInterfaceRequestor *aCallbacks) +{ + return SpeculativeConnectInternal(aURI, aPrincipal, aCallbacks, false); } NS_IMETHODIMP nsIOService::SpeculativeAnonymousConnect(nsIURI *aURI, nsIInterfaceRequestor *aCallbacks) { - return SpeculativeConnectInternal(aURI, aCallbacks, true); + return SpeculativeConnectInternal(aURI, nullptr, aCallbacks, true); +} + +NS_IMETHODIMP +nsIOService::SpeculativeAnonymousConnect2(nsIURI *aURI, + nsIPrincipal *aPrincipal, + nsIInterfaceRequestor *aCallbacks) +{ + return SpeculativeConnectInternal(aURI, aPrincipal, aCallbacks, true); } } // namespace net diff --git a/netwerk/base/nsIOService.h b/netwerk/base/nsIOService.h index feb7e7b26b5c..7ac23b7910e3 100644 --- a/netwerk/base/nsIOService.h +++ b/netwerk/base/nsIOService.h @@ -136,6 +136,7 @@ private: nsIChannel** result); nsresult SpeculativeConnectInternal(nsIURI *aURI, + nsIPrincipal *aPrincipal, nsIInterfaceRequestor *aCallbacks, bool aAnonymous); diff --git a/netwerk/base/nsISpeculativeConnect.idl b/netwerk/base/nsISpeculativeConnect.idl index e9ca29fb13c8..067edd3f0880 100644 --- a/netwerk/base/nsISpeculativeConnect.idl +++ b/netwerk/base/nsISpeculativeConnect.idl @@ -5,6 +5,7 @@ #include "nsISupports.idl" +interface nsIPrincipal; interface nsIURI; interface nsIInterfaceRequestor; @@ -21,6 +22,8 @@ interface nsISpeculativeConnect : nsISupports * to actually open the new channel. * * @param aURI the URI of the hinted transaction + * @param aPrincipal the principal that will be used for opening the + * channel of the hinted transaction. * @param aCallbacks any security callbacks for use with SSL for interfaces * such as nsIBadCertListener. May be null. * @@ -28,8 +31,16 @@ interface nsISpeculativeConnect : nsISupports void speculativeConnect(in nsIURI aURI, in nsIInterfaceRequestor aCallbacks); + void speculativeConnect2(in nsIURI aURI, + in nsIPrincipal aPrincipal, + in nsIInterfaceRequestor aCallbacks); + void speculativeAnonymousConnect(in nsIURI aURI, in nsIInterfaceRequestor aCallbacks); + + void speculativeAnonymousConnect2(in nsIURI aURI, + in nsIPrincipal aPrincipal, + in nsIInterfaceRequestor aCallbacks); }; /** diff --git a/netwerk/ipc/NeckoParent.cpp b/netwerk/ipc/NeckoParent.cpp index 52eb9a8f5116..6c7e8b63c4fa 100644 --- a/netwerk/ipc/NeckoParent.cpp +++ b/netwerk/ipc/NeckoParent.cpp @@ -679,15 +679,18 @@ NeckoParent::DeallocPDNSRequestParent(PDNSRequestParent* aParent) } bool -NeckoParent::RecvSpeculativeConnect(const URIParams& aURI, const bool& aAnonymous) +NeckoParent::RecvSpeculativeConnect(const URIParams& aURI, + const Principal& aPrincipal, + const bool& aAnonymous) { nsCOMPtr speculator(gIOService); nsCOMPtr uri = DeserializeURI(aURI); + nsCOMPtr principal(aPrincipal); if (uri && speculator) { if (aAnonymous) { - speculator->SpeculativeAnonymousConnect(uri, nullptr); + speculator->SpeculativeAnonymousConnect2(uri, principal, nullptr); } else { - speculator->SpeculativeConnect(uri, nullptr); + speculator->SpeculativeConnect2(uri, principal, nullptr); } } diff --git a/netwerk/ipc/NeckoParent.h b/netwerk/ipc/NeckoParent.h index f0adf12f64a0..e18d585b1941 100644 --- a/netwerk/ipc/NeckoParent.h +++ b/netwerk/ipc/NeckoParent.h @@ -155,7 +155,9 @@ protected: const uint32_t& flags, const nsCString& aNetworkInterface) override; virtual bool DeallocPDNSRequestParent(PDNSRequestParent*) override; - virtual bool RecvSpeculativeConnect(const URIParams& aURI, const bool& aAnonymous) override; + virtual bool RecvSpeculativeConnect(const URIParams& aURI, + const Principal& aPrincipal, + const bool& aAnonymous) override; virtual bool RecvHTMLDNSPrefetch(const nsString& hostname, const uint16_t& flags) override; virtual bool RecvCancelHTMLDNSPrefetch(const nsString& hostname, diff --git a/netwerk/ipc/PNecko.ipdl b/netwerk/ipc/PNecko.ipdl index 685a4e5f35cb..d9d88352cc29 100644 --- a/netwerk/ipc/PNecko.ipdl +++ b/netwerk/ipc/PNecko.ipdl @@ -88,7 +88,7 @@ parent: uint32_t reason, SerializedLoadContext loadContext); async PredReset(); - async SpeculativeConnect(URIParams uri, bool anonymous); + async SpeculativeConnect(URIParams uri, Principal principal, bool anonymous); async HTMLDNSPrefetch(nsString hostname, uint16_t flags); async CancelHTMLDNSPrefetch(nsString hostname, uint16_t flags, nsresult reason); diff --git a/netwerk/protocol/http/nsHttpHandler.cpp b/netwerk/protocol/http/nsHttpHandler.cpp index 70c2a77d3330..1ddffabffc65 100644 --- a/netwerk/protocol/http/nsHttpHandler.cpp +++ b/netwerk/protocol/http/nsHttpHandler.cpp @@ -2208,13 +2208,16 @@ nsHttpHandler::Observe(nsISupports *subject, nsresult nsHttpHandler::SpeculativeConnectInternal(nsIURI *aURI, + nsIPrincipal *aPrincipal, nsIInterfaceRequestor *aCallbacks, bool anonymous) { if (IsNeckoChild()) { ipc::URIParams params; SerializeURI(aURI, params); - gNeckoChild->SendSpeculativeConnect(params, anonymous); + gNeckoChild->SendSpeculativeConnect(params, + IPC::Principal(aPrincipal), + anonymous); return NS_OK; } @@ -2297,10 +2300,16 @@ nsHttpHandler::SpeculativeConnectInternal(nsIURI *aURI, aURI->GetUsername(username); NeckoOriginAttributes neckoOriginAttributes; - if (loadContext) { - DocShellOriginAttributes docshellOriginAttributes; - loadContext->GetOriginAttributes(docshellOriginAttributes); - neckoOriginAttributes.InheritFromDocShellToNecko(docshellOriginAttributes); + // If the principal is given, we use the originAttributes from this + // principal. Otherwise, we use the originAttributes from the + // loadContext. + if (aPrincipal) { + neckoOriginAttributes.InheritFromDocToNecko( + BasePrincipal::Cast(aPrincipal)->OriginAttributesRef()); + } else if (loadContext) { + DocShellOriginAttributes docshellOriginAttributes; + loadContext->GetOriginAttributes(docshellOriginAttributes); + neckoOriginAttributes.InheritFromDocShellToNecko(docshellOriginAttributes); } auto *ci = @@ -2315,14 +2324,30 @@ NS_IMETHODIMP nsHttpHandler::SpeculativeConnect(nsIURI *aURI, nsIInterfaceRequestor *aCallbacks) { - return SpeculativeConnectInternal(aURI, aCallbacks, false); + return SpeculativeConnectInternal(aURI, nullptr, aCallbacks, false); +} + +NS_IMETHODIMP +nsHttpHandler::SpeculativeConnect2(nsIURI *aURI, + nsIPrincipal *aPrincipal, + nsIInterfaceRequestor *aCallbacks) +{ + return SpeculativeConnectInternal(aURI, aPrincipal, aCallbacks, false); } NS_IMETHODIMP nsHttpHandler::SpeculativeAnonymousConnect(nsIURI *aURI, nsIInterfaceRequestor *aCallbacks) { - return SpeculativeConnectInternal(aURI, aCallbacks, true); + return SpeculativeConnectInternal(aURI, nullptr, aCallbacks, true); +} + +NS_IMETHODIMP +nsHttpHandler::SpeculativeAnonymousConnect2(nsIURI *aURI, + nsIPrincipal *aPrincipal, + nsIInterfaceRequestor *aCallbacks) +{ + return SpeculativeConnectInternal(aURI, aPrincipal, aCallbacks, true); } void diff --git a/netwerk/protocol/http/nsHttpHandler.h b/netwerk/protocol/http/nsHttpHandler.h index 33af3e5adbd2..13cc72e8ef66 100644 --- a/netwerk/protocol/http/nsHttpHandler.h +++ b/netwerk/protocol/http/nsHttpHandler.h @@ -639,6 +639,7 @@ private: private: nsresult SpeculativeConnectInternal(nsIURI *aURI, + nsIPrincipal *aPrincipal, nsIInterfaceRequestor *aCallbacks, bool anonymous);