Bug 1315143 - Make OCSP use Origin Attribute framework (Necko). r=mayhemer
authorJonathan Hao <jhao@mozilla.com>
Mon, 21 Nov 2016 11:43:06 +0800
changeset 368930 498b09513061f6567afc307aba099c4bbe9d550b
parent 368929 80a39e170b4106eae2d15d56ff10d1d0a5feb84b
child 368931 d7dd10403797f53ca13b86bb751013f5b45aefc9
push id6996
push userjlorenzo@mozilla.com
push dateMon, 06 Mar 2017 20:48:21 +0000
treeherdermozilla-beta@d89512dab048 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmayhemer
bugs1315143
milestone53.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1315143 - Make OCSP use Origin Attribute framework (Necko). r=mayhemer
netwerk/base/nsISocketTransport.idl
netwerk/base/nsSocketTransport2.cpp
netwerk/base/nsSocketTransport2.h
netwerk/protocol/http/TunnelUtils.cpp
netwerk/protocol/http/nsHttpConnectionMgr.cpp
netwerk/socket/nsISocketProvider.idl
netwerk/socket/nsSOCKSSocketProvider.cpp
netwerk/socket/nsUDPSocketProvider.cpp
--- a/netwerk/base/nsISocketTransport.idl
+++ b/netwerk/base/nsISocketTransport.idl
@@ -4,24 +4,27 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsITransport.idl"
 
 interface nsIInterfaceRequestor;
 interface nsINetAddr;
 
 %{ C++
+#include "mozilla/BasePrincipal.h"
 namespace mozilla {
 namespace net {
 union NetAddr;
 }
 }
 %}
 native NetAddr(mozilla::net::NetAddr);
 [ptr] native NetAddrPtr(mozilla::net::NetAddr);
+native NeckoOriginAttributes(mozilla::NeckoOriginAttributes);
+[ref] native const_OriginAttributesRef(const mozilla::NeckoOriginAttributes);
 
 /**
  * nsISocketTransport
  *
  * NOTE: Connection setup is triggered by opening an input or output stream,
  * it does not start on its own. Completion of the connection setup is
  * indicated by a STATUS_CONNECTED_TO notification to the event sink (if set).
  *
@@ -40,22 +43,30 @@ interface nsISocketTransport : nsITransp
 
     /**
      * Get the port for the underlying socket connection.
      * For Unix domain sockets, this is zero.
      */
     readonly attribute long port;
 
     /**
-     * This is only non-empty when "privacy.firstparty.isolate" is enabled.
-     * It is used to create sockets, and will eventually be used to isolate
-     * OCSP cache. It's the only way to carry it down to NSPR layers which are
-     * final consumers.  It must be set before the socket transport is built.
+     * The origin attributes are used to create sockets.  The first party domain
+     * will eventually be used to isolate OCSP cache and is only non-empty when
+     * "privacy.firstparty.isolate" is enabled.  Setting this is the only way to
+     * carry origin attributes down to NSPR layers which are final consumers.
+     * It must be set before the socket transport is built.
      */
-    attribute AUTF8String firstPartyDomain;
+    [implicit_jscontext, binaryname(ScriptableOriginAttributes)]
+    attribute jsval originAttributes;
+
+    [noscript, nostdcall, binaryname(GetOriginAttributes)]
+    NeckoOriginAttributes binaryGetOriginAttributes();
+
+    [noscript, nostdcall, binaryname(SetOriginAttributes)]
+    void binarySetOriginAttributes(in const_OriginAttributesRef aOriginAttrs);
 
     /**
      * The platform-specific network interface id that this socket
      * associated with. Note that this attribute can be only accessed
      * in the socket thread.
      */
     attribute ACString networkInterfaceId;
 
--- a/netwerk/base/nsSocketTransport2.cpp
+++ b/netwerk/base/nsSocketTransport2.cpp
@@ -17,16 +17,17 @@
 #include "nsNetCID.h"
 #include "nsNetUtil.h"
 #include "nsAutoPtr.h"
 #include "nsCOMPtr.h"
 #include "plstr.h"
 #include "prerr.h"
 #include "NetworkActivityMonitor.h"
 #include "NSSErrorsService.h"
+#include "mozilla/dom/ToJSValue.h"
 #include "mozilla/net/NeckoChild.h"
 #include "nsThreadUtils.h"
 #include "nsISocketProviderService.h"
 #include "nsISocketProvider.h"
 #include "nsISSLSocketControl.h"
 #include "nsIPipe.h"
 #include "nsIClassInfoImpl.h"
 #include "nsURLHelper.h"
@@ -1164,32 +1165,32 @@ nsSocketTransport::BuildSocket(PRFileDes
                 // service to allocate a new socket
 
                 // when https proxying we want to just connect to the proxy as if
                 // it were the end host (i.e. expect the proxy's cert)
 
                 rv = provider->NewSocket(mNetAddr.raw.family,
                                          mHttpsProxy ? mProxyHost.get() : host,
                                          mHttpsProxy ? mProxyPort : port,
-                                         proxyInfo, mFirstPartyDomain,
+                                         proxyInfo, mOriginAttributes,
                                          controlFlags, &fd,
                                          getter_AddRefs(secinfo));
 
                 if (NS_SUCCEEDED(rv) && !fd) {
                     NS_NOTREACHED("NewSocket succeeded but failed to create a PRFileDesc");
                     rv = NS_ERROR_UNEXPECTED;
                 }
             }
             else {
                 // the socket has already been allocated, 
                 // so we just want the service to add itself
                 // to the stack (such as pushing an io layer)
                 rv = provider->AddToSocket(mNetAddr.raw.family,
                                            host, port, proxyInfo,
-                                           mFirstPartyDomain, controlFlags, fd,
+                                           mOriginAttributes, controlFlags, fd,
                                            getter_AddRefs(secinfo));
             }
 
             // controlFlags = 0; not used below this point...
             if (NS_FAILED(rv))
                 break;
 
             // if the service was ssl or starttls, we want to hold onto the socket info
@@ -2386,29 +2387,56 @@ NS_IMETHODIMP
 nsSocketTransport::SetNetworkInterfaceId(const nsACString_internal &aNetworkInterfaceId)
 {
     MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread, "wrong thread");
     mNetworkInterfaceId = aNetworkInterfaceId;
     return NS_OK;
 }
 
 NS_IMETHODIMP
-nsSocketTransport::GetFirstPartyDomain(nsACString &value)
+nsSocketTransport::GetScriptableOriginAttributes(JSContext* aCx,
+    JS::MutableHandle<JS::Value> aOriginAttributes)
 {
-    value = mFirstPartyDomain;
+    if (NS_WARN_IF(!ToJSValue(aCx, mOriginAttributes, aOriginAttributes))) {
+        return NS_ERROR_FAILURE;
+    }
     return NS_OK;
 }
 
 NS_IMETHODIMP
-nsSocketTransport::SetFirstPartyDomain(const nsACString &value)
+nsSocketTransport::SetScriptableOriginAttributes(JSContext* aCx,
+    JS::Handle<JS::Value> aOriginAttributes)
 {
     MutexAutoLock lock(mLock);
     NS_ENSURE_FALSE(mFD.IsInitialized(), NS_ERROR_FAILURE);
 
-    mFirstPartyDomain = value;
+    NeckoOriginAttributes attrs;
+    if (!aOriginAttributes.isObject() || !attrs.Init(aCx, aOriginAttributes)) {
+        return NS_ERROR_INVALID_ARG;
+    }
+
+    mOriginAttributes = attrs;
+    return NS_OK;
+}
+
+nsresult
+nsSocketTransport::GetOriginAttributes(NeckoOriginAttributes* aOriginAttributes)
+{
+    NS_ENSURE_ARG(aOriginAttributes);
+    *aOriginAttributes = mOriginAttributes;
+    return NS_OK;
+}
+
+nsresult
+nsSocketTransport::SetOriginAttributes(const NeckoOriginAttributes& aOriginAttributes)
+{
+    MutexAutoLock lock(mLock);
+    NS_ENSURE_FALSE(mFD.IsInitialized(), NS_ERROR_FAILURE);
+
+    mOriginAttributes = aOriginAttributes;
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsSocketTransport::GetPeerAddr(NetAddr *addr)
 {
     // once we are in the connected state, mNetAddr will not change.
     // so if we can verify that we are in the connected state, then
--- a/netwerk/base/nsSocketTransport2.h
+++ b/netwerk/base/nsSocketTransport2.h
@@ -298,21 +298,22 @@ private:
     nsCOMPtr<nsIProxyInfo> mProxyInfo;
     uint16_t     mProxyPort;
     uint16_t     mOriginPort;
     bool mProxyTransparent;
     bool mProxyTransparentResolvesHost;
     bool mHttpsProxy;
     uint32_t     mConnectionFlags;
 
-    // This is only non-empty when "privacy.firstparty.isolate" is enabled.
-    // It is used to create sockets. It's the only way to carry it down to NSPR
-    // layers which are final consumers.  It must be set before the socket
-    // transport is built.
-    nsCString    mFirstPartyDomain;
+    // The origin attributes are used to create sockets.  The first party domain
+    // will eventually be used to isolate OCSP cache and is only non-empty when
+    // "privacy.firstparty.isolate" is enabled.  Setting this is the only way to
+    // carry origin attributes down to NSPR layers which are final consumers.
+    // It must be set before the socket transport is built.
+    NeckoOriginAttributes mOriginAttributes;
     
     uint16_t         SocketPort() { return (!mProxyHost.IsEmpty() && !mProxyTransparent) ? mProxyPort : mPort; }
     const nsCString &SocketHost() { return (!mProxyHost.IsEmpty() && !mProxyTransparent) ? mProxyHost : mHost; }
 
     //-------------------------------------------------------------------------
     // members accessible only on the socket transport thread:
     //  (the exception being initialization/shutdown time)
     //-------------------------------------------------------------------------
--- a/netwerk/protocol/http/TunnelUtils.cpp
+++ b/netwerk/protocol/http/TunnelUtils.cpp
@@ -72,18 +72,19 @@ TLSFilterTransaction::TLSFilterTransacti
     sLayerMethods.close = FilterClose;
     sLayerMethodsPtr = &sLayerMethods;
   }
 
   mFD = PR_CreateIOLayerStub(sLayerIdentity, &sLayerMethods);
 
   if (provider && mFD) {
     mFD->secret = reinterpret_cast<PRFilePrivate *>(this);
-    provider->AddToSocket(PR_AF_INET, aTLSHost, aTLSPort, nullptr, EmptyCString(),
-                          0, mFD, getter_AddRefs(mSecInfo));
+    provider->AddToSocket(PR_AF_INET, aTLSHost, aTLSPort, nullptr,
+                          NeckoOriginAttributes(), 0, mFD,
+                          getter_AddRefs(mSecInfo));
   }
 
   if (mTransaction) {
     nsCOMPtr<nsIInterfaceRequestor> callbacks;
     mTransaction->GetSecurityCallbacks(getter_AddRefs(callbacks));
     nsCOMPtr<nsISSLSocketControl> secCtrl(do_QueryInterface(mSecInfo));
     if (secCtrl) {
       secCtrl->SetNotificationCallbacks(callbacks);
@@ -1588,18 +1589,42 @@ FWD_TS_ADDREF(GetScriptablePeerAddr, nsI
 FWD_TS_ADDREF(GetScriptableSelfAddr, nsINetAddr);
 FWD_TS_ADDREF(GetSecurityInfo, nsISupports);
 FWD_TS_ADDREF(GetSecurityCallbacks, nsIInterfaceRequestor);
 FWD_TS_PTR(IsAlive, bool);
 FWD_TS_PTR(GetConnectionFlags, uint32_t);
 FWD_TS(SetConnectionFlags, uint32_t);
 FWD_TS_PTR(GetRecvBufferSize, uint32_t);
 FWD_TS(SetRecvBufferSize, uint32_t);
-FWD_TS(SetFirstPartyDomain, const nsACString&);
-FWD_TS(GetFirstPartyDomain, nsACString&);
+
+nsresult
+SocketTransportShim::GetOriginAttributes(mozilla::NeckoOriginAttributes* aOriginAttributes)
+{
+  return mWrapped->GetOriginAttributes(aOriginAttributes);
+}
+
+nsresult
+SocketTransportShim::SetOriginAttributes(const mozilla::NeckoOriginAttributes& aOriginAttributes)
+{
+  return mWrapped->SetOriginAttributes(aOriginAttributes);
+}
+
+NS_IMETHODIMP
+SocketTransportShim::GetScriptableOriginAttributes(JSContext* aCx,
+  JS::MutableHandle<JS::Value> aOriginAttributes)
+{
+  return mWrapped->GetScriptableOriginAttributes(aCx, aOriginAttributes);
+}
+
+NS_IMETHODIMP
+SocketTransportShim::SetScriptableOriginAttributes(JSContext* aCx,
+  JS::Handle<JS::Value> aOriginAttributes)
+{
+  return mWrapped->SetScriptableOriginAttributes(aCx, aOriginAttributes);
+}
 
 NS_IMETHODIMP
 SocketTransportShim::GetHost(nsACString & aHost)
 {
   return mWrapped->GetHost(aHost);
 }
 
 NS_IMETHODIMP
--- a/netwerk/protocol/http/nsHttpConnectionMgr.cpp
+++ b/netwerk/protocol/http/nsHttpConnectionMgr.cpp
@@ -3076,20 +3076,20 @@ nsHalfOpenSocket::SetupStreams(nsISocket
     }
 
     if (!Allow1918()) {
         tmpFlags |= nsISocketTransport::DISABLE_RFC1918;
     }
 
     socketTransport->SetConnectionFlags(tmpFlags);
 
-    nsAutoCString firstPartyDomain =
-      NS_ConvertUTF16toUTF8(mEnt->mConnInfo->GetOriginAttributes().mFirstPartyDomain);
-    if (!firstPartyDomain.IsEmpty()) {
-        socketTransport->SetFirstPartyDomain(firstPartyDomain);
+    NeckoOriginAttributes originAttributes =
+        mEnt->mConnInfo->GetOriginAttributes();
+    if (originAttributes != NeckoOriginAttributes()) {
+        socketTransport->SetOriginAttributes(originAttributes);
     }
 
     socketTransport->SetQoSBits(gHttpHandler->GetQoSBits());
 
     if (!ci->GetNetworkInterfaceId().IsEmpty()) {
         socketTransport->SetNetworkInterfaceId(ci->GetNetworkInterfaceId());
     }
 
--- a/netwerk/socket/nsISocketProvider.idl
+++ b/netwerk/socket/nsISocketProvider.idl
@@ -2,16 +2,22 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsISupports.idl"
 
 interface nsIProxyInfo;
 [ptr] native PRFileDescStar(struct PRFileDesc);
+native NeckoOriginAttributes(mozilla::NeckoOriginAttributes);
+[ref] native const_OriginAttributesRef(const mozilla::NeckoOriginAttributes);
+
+%{ C++
+#include "mozilla/BasePrincipal.h"
+%}
 
 /**
  * nsISocketProvider
  */
 [scriptable, uuid(508d5469-9e1e-4a08-b5b0-7cfebba1e51a)]
 interface nsISocketProvider : nsISupports
 {
     /**
@@ -31,44 +37,44 @@ interface nsISocketProvider : nsISupport
      *        Control flags that govern this connection (see below.)
      * @param aFileDesc
      *        The resulting PRFileDesc.
      * @param aSecurityInfo
      *        Any security info that should be associated with aFileDesc.  This
      *        object typically implements nsITransportSecurityInfo.
      */
     [noscript]
-    void newSocket(in long            aFamily,
-                   in string          aHost, 
-                   in long            aPort,
-                   in nsIProxyInfo    aProxy,
-                   in ACString        aFirstPartyDomain,
-                   in unsigned long   aFlags,
-                   out PRFileDescStar aFileDesc, 
-                   out nsISupports    aSecurityInfo);
+    void newSocket(in long                      aFamily,
+                   in string                    aHost, 
+                   in long                      aPort,
+                   in nsIProxyInfo              aProxy,
+                   in const_OriginAttributesRef aOriginAttributes,
+                   in unsigned long             aFlags,
+                   out PRFileDescStar           aFileDesc, 
+                   out nsISupports              aSecurityInfo);
 
     /**
      * addToSocket
      *
      * This function is called to allow the socket provider to layer a
      * PRFileDesc on top of another PRFileDesc.  For example, SSL via a SOCKS
      * proxy.
      *
      * Parameters are the same as newSocket with the exception of aFileDesc,
      * which is an in-param instead.
      */
     [noscript]
-    void addToSocket(in long           aFamily,
-                     in string         aHost, 
-                     in long           aPort,
-                     in nsIProxyInfo   aProxy,
-                     in ACString       aFirstPartyDomain,
-                     in unsigned long  aFlags,
-                     in PRFileDescStar aFileDesc, 
-                     out nsISupports   aSecurityInfo);
+    void addToSocket(in long                      aFamily,
+                     in string                    aHost, 
+                     in long                      aPort,
+                     in nsIProxyInfo              aProxy,
+                     in const_OriginAttributesRef aOriginAttributes,
+                     in unsigned long             aFlags,
+                     in PRFileDescStar            aFileDesc, 
+                     out nsISupports              aSecurityInfo);
 
     /**
      * PROXY_RESOLVES_HOST
      *
      * This flag is set if the proxy is to perform hostname resolution instead
      * of the client.  When set, the hostname parameter passed when in this
      * interface will be used instead of the address structure passed for a
      * later connect et al. request.
--- a/netwerk/socket/nsSOCKSSocketProvider.cpp
+++ b/netwerk/socket/nsSOCKSSocketProvider.cpp
@@ -6,16 +6,18 @@
 
 #include "nsIServiceManager.h"
 #include "nsNamedPipeIOLayer.h"
 #include "nsSOCKSSocketProvider.h"
 #include "nsSOCKSIOLayer.h"
 #include "nsCOMPtr.h"
 #include "nsError.h"
 
+using mozilla::NeckoOriginAttributes;
+
 //////////////////////////////////////////////////////////////////////////
 
 NS_IMPL_ISUPPORTS(nsSOCKSSocketProvider, nsISocketProvider)
 
 nsresult
 nsSOCKSSocketProvider::CreateV4(nsISupports *aOuter, REFNSIID aIID, void **aResult)
 {
     nsresult rv;
@@ -41,17 +43,17 @@ nsSOCKSSocketProvider::CreateV5(nsISuppo
     return rv;
 }
 
 NS_IMETHODIMP
 nsSOCKSSocketProvider::NewSocket(int32_t family,
                                  const char *host, 
                                  int32_t port,
                                  nsIProxyInfo *proxy,
-                                 const nsACString &firstPartyDomain,
+                                 const NeckoOriginAttributes &originAttributes,
                                  uint32_t flags,
                                  PRFileDesc **result,
                                  nsISupports **socksInfo)
 {
     PRFileDesc *sock;
 
 #if defined(XP_WIN)
     nsAutoCString proxyHost;
@@ -83,17 +85,17 @@ nsSOCKSSocketProvider::NewSocket(int32_t
     return NS_ERROR_SOCKET_CREATE_FAILED;
 }
 
 NS_IMETHODIMP
 nsSOCKSSocketProvider::AddToSocket(int32_t family,
                                    const char *host,
                                    int32_t port,
                                    nsIProxyInfo *proxy,
-                                   const nsACString &firstPartyDomain,
+                                   const NeckoOriginAttributes &originAttributes,
                                    uint32_t flags,
                                    PRFileDesc *sock,
                                    nsISupports **socksInfo)
 {
     nsresult rv = nsSOCKSIOLayerAddToSocket(family,
                                             host, 
                                             port,
                                             proxy,
--- a/netwerk/socket/nsUDPSocketProvider.cpp
+++ b/netwerk/socket/nsUDPSocketProvider.cpp
@@ -1,28 +1,30 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsUDPSocketProvider.h"
 
 #include "nspr.h"
 
+using mozilla::NeckoOriginAttributes;
+
 NS_IMPL_ISUPPORTS(nsUDPSocketProvider, nsISocketProvider)
 
 nsUDPSocketProvider::~nsUDPSocketProvider()
 {
 }
 
 NS_IMETHODIMP 
 nsUDPSocketProvider::NewSocket(int32_t aFamily,
                                const char *aHost, 
                                int32_t aPort, 
                                nsIProxyInfo *aProxy,
-                               const nsACString &firstPartyDomain,
+                               const NeckoOriginAttributes &originAttributes,
                                uint32_t aFlags,
                                PRFileDesc * *aFileDesc, 
                                nsISupports **aSecurityInfo)
 {
     NS_ENSURE_ARG_POINTER(aFileDesc);
   
     PRFileDesc* udpFD = PR_OpenUDPSocket(aFamily);
     if (!udpFD)
@@ -32,17 +34,17 @@ nsUDPSocketProvider::NewSocket(int32_t a
     return NS_OK;
 }
 
 NS_IMETHODIMP 
 nsUDPSocketProvider::AddToSocket(int32_t aFamily,
                                  const char *aHost,
                                  int32_t aPort,
                                  nsIProxyInfo *aProxy,
-                                 const nsACString &firstPartyDomain,
+                                 const NeckoOriginAttributes &originAttributes,
                                  uint32_t aFlags,
                                  struct PRFileDesc * aFileDesc,
                                  nsISupports **aSecurityInfo)
 {
     // does not make sense to strap a UDP socket onto an existing socket
     NS_NOTREACHED("Cannot layer UDP socket on an existing socket");
     return NS_ERROR_UNEXPECTED;
 }