Bug 1264562 - Part 1: Add firstPartyDomain to socket transport (adapted from Tor Browser patch 13670) r=mayhemer
--- a/netwerk/base/nsISocketTransport.idl
+++ b/netwerk/base/nsISocketTransport.idl
@@ -40,16 +40,24 @@ 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.
+ */
+ attribute AUTF8String firstPartyDomain;
+
+ /**
* 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;
/**
* Returns the IP address of the socket connection peer. This
--- a/netwerk/base/nsSocketTransport2.cpp
+++ b/netwerk/base/nsSocketTransport2.cpp
@@ -1164,34 +1164,35 @@ 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,
+ proxyInfo, mFirstPartyDomain,
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,
- controlFlags, fd,
+ mFirstPartyDomain, 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
bool isSSL = (strcmp(mTypes[i], "ssl") == 0);
if (isSSL || (strcmp(mTypes[i], "starttls") == 0)) {
// remember security info and give notification callbacks to PSM...
@@ -2385,16 +2386,33 @@ 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)
+{
+ value = mFirstPartyDomain;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsSocketTransport::SetFirstPartyDomain(const nsACString &value)
+{
+ MutexAutoLock lock(mLock);
+ NS_ENSURE_FALSE(mFD.IsInitialized(), NS_ERROR_FAILURE);
+
+ mFirstPartyDomain = value;
+ 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
// we can freely access mNetAddr from any thread without being
// inside a critical section.
if (!mNetAddrIsSet) {
--- a/netwerk/base/nsSocketTransport2.h
+++ b/netwerk/base/nsSocketTransport2.h
@@ -297,16 +297,22 @@ private:
uint16_t mPort;
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;
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,17 +72,17 @@ 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,
+ provider->AddToSocket(PR_AF_INET, aTLSHost, aTLSPort, nullptr, EmptyCString(),
0, mFD, getter_AddRefs(mSecInfo));
}
if (mTransaction) {
nsCOMPtr<nsIInterfaceRequestor> callbacks;
mTransaction->GetSecurityCallbacks(getter_AddRefs(callbacks));
nsCOMPtr<nsISSLSocketControl> secCtrl(do_QueryInterface(mSecInfo));
if (secCtrl) {
@@ -1588,16 +1588,18 @@ 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&);
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,16 +3076,22 @@ 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);
+ }
+
socketTransport->SetQoSBits(gHttpHandler->GetQoSBits());
if (!ci->GetNetworkInterfaceId().IsEmpty()) {
socketTransport->SetNetworkInterfaceId(ci->GetNetworkInterfaceId());
}
rv = socketTransport->SetEventSink(this, nullptr);
NS_ENSURE_SUCCESS(rv, rv);
--- a/netwerk/socket/nsISocketProvider.idl
+++ b/netwerk/socket/nsISocketProvider.idl
@@ -35,16 +35,17 @@ interface nsISocketProvider : nsISupport
* 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);
/**
* addToSocket
*
* This function is called to allow the socket provider to layer a
@@ -54,16 +55,17 @@ interface nsISocketProvider : nsISupport
* 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);
/**
* PROXY_RESOLVES_HOST
*
* This flag is set if the proxy is to perform hostname resolution instead
--- a/netwerk/socket/nsSOCKSSocketProvider.cpp
+++ b/netwerk/socket/nsSOCKSSocketProvider.cpp
@@ -40,16 +40,17 @@ nsSOCKSSocketProvider::CreateV5(nsISuppo
return rv;
}
NS_IMETHODIMP
nsSOCKSSocketProvider::NewSocket(int32_t family,
const char *host,
int32_t port,
nsIProxyInfo *proxy,
+ const nsACString &firstPartyDomain,
uint32_t flags,
PRFileDesc **result,
nsISupports **socksInfo)
{
PRFileDesc *sock;
sock = PR_OpenTCPSocket(family);
if (!sock)
@@ -71,16 +72,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,
uint32_t flags,
PRFileDesc *sock,
nsISupports **socksInfo)
{
nsresult rv = nsSOCKSIOLayerAddToSocket(family,
host,
port,
proxy,
--- a/netwerk/socket/nsUDPSocketProvider.cpp
+++ b/netwerk/socket/nsUDPSocketProvider.cpp
@@ -12,16 +12,17 @@ nsUDPSocketProvider::~nsUDPSocketProvide
{
}
NS_IMETHODIMP
nsUDPSocketProvider::NewSocket(int32_t aFamily,
const char *aHost,
int32_t aPort,
nsIProxyInfo *aProxy,
+ const nsACString &firstPartyDomain,
uint32_t aFlags,
PRFileDesc * *aFileDesc,
nsISupports **aSecurityInfo)
{
NS_ENSURE_ARG_POINTER(aFileDesc);
PRFileDesc* udpFD = PR_OpenUDPSocket(aFamily);
if (!udpFD)
@@ -31,16 +32,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,
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;
}
--- a/security/manager/ssl/nsSSLSocketProvider.cpp
+++ b/security/manager/ssl/nsSSLSocketProvider.cpp
@@ -18,16 +18,17 @@ nsSSLSocketProvider::~nsSSLSocketProvide
NS_IMPL_ISUPPORTS(nsSSLSocketProvider, nsISocketProvider)
NS_IMETHODIMP
nsSSLSocketProvider::NewSocket(int32_t family,
const char *host,
int32_t port,
nsIProxyInfo *proxy,
+ const nsACString &firstPartyDomain,
uint32_t flags,
PRFileDesc **_result,
nsISupports **securityInfo)
{
nsresult rv = nsSSLIOLayerNewSocket(family,
host,
port,
proxy,
@@ -39,16 +40,17 @@ nsSSLSocketProvider::NewSocket(int32_t f
}
// Add the SSL IO layer to an existing socket
NS_IMETHODIMP
nsSSLSocketProvider::AddToSocket(int32_t family,
const char *host,
int32_t port,
nsIProxyInfo *proxy,
+ const nsACString &firstPartyDomain,
uint32_t flags,
PRFileDesc *aSocket,
nsISupports **securityInfo)
{
nsresult rv = nsSSLIOLayerAddToSocket(family,
host,
port,
proxy,
--- a/security/manager/ssl/nsTLSSocketProvider.cpp
+++ b/security/manager/ssl/nsTLSSocketProvider.cpp
@@ -18,16 +18,17 @@ nsTLSSocketProvider::~nsTLSSocketProvide
NS_IMPL_ISUPPORTS(nsTLSSocketProvider, nsISocketProvider)
NS_IMETHODIMP
nsTLSSocketProvider::NewSocket(int32_t family,
const char *host,
int32_t port,
nsIProxyInfo *proxy,
+ const nsACString &firstPartyDomain,
uint32_t flags,
PRFileDesc **_result,
nsISupports **securityInfo)
{
nsresult rv = nsSSLIOLayerNewSocket(family,
host,
port,
proxy,
@@ -40,16 +41,17 @@ nsTLSSocketProvider::NewSocket(int32_t f
}
// Add the SSL IO layer to an existing socket
NS_IMETHODIMP
nsTLSSocketProvider::AddToSocket(int32_t family,
const char *host,
int32_t port,
nsIProxyInfo *proxy,
+ const nsACString &firstPartyDomain,
uint32_t flags,
PRFileDesc *aSocket,
nsISupports **securityInfo)
{
nsresult rv = nsSSLIOLayerAddToSocket(family,
host,
port,
proxy,