diff --git a/directory/xpcom/base/src/nsLDAPSecurityGlue.cpp b/directory/xpcom/base/src/nsLDAPSecurityGlue.cpp index ec7b0c2fbe6d..92d7a595cdff 100644 --- a/directory/xpcom/base/src/nsLDAPSecurityGlue.cpp +++ b/directory/xpcom/base/src/nsLDAPSecurityGlue.cpp @@ -210,8 +210,8 @@ nsLDAPSSLConnect(const char *hostlist, int defport, int timeout, // the certificate. Need to investigate. // rv = tlsSocketProvider->AddToSocket(PR_AF_INET, - sessionClosure->hostname, defport, - nsnull, 0, socketInfo.soinfo_prfd, + sessionClosure->hostname, defport, + nsnull, 0, 0, socketInfo.soinfo_prfd, getter_AddRefs(securityInfo)); if (NS_FAILED(rv)) { NS_ERROR("nsLDAPSSLConnect(): unable to add SSL layer to socket"); diff --git a/modules/libpref/src/init/all.js b/modules/libpref/src/init/all.js index 90052ed43335..94a5d2909e16 100644 --- a/modules/libpref/src/init/all.js +++ b/modules/libpref/src/init/all.js @@ -622,6 +622,7 @@ pref("network.proxy.ssl_port", 0); pref("network.proxy.socks", ""); pref("network.proxy.socks_port", 0); pref("network.proxy.socks_version", 5); +pref("network.proxy.socks_remote_dns", false); pref("network.proxy.no_proxies_on", "localhost, 127.0.0.1"); pref("network.proxy.failover_timeout", 1800); // 30 minutes pref("network.online", true); //online/offline diff --git a/netwerk/base/public/nsIProtocolProxyService.idl b/netwerk/base/public/nsIProtocolProxyService.idl index bba0b0046c5a..1b03de9aa0e7 100644 --- a/netwerk/base/public/nsIProtocolProxyService.idl +++ b/netwerk/base/public/nsIProtocolProxyService.idl @@ -47,7 +47,7 @@ interface nsIURI; * nsIProtocolProxyService provides methods to access information about * various network proxies. */ -[scriptable, uuid(6b40d918-c01a-42a2-ab4d-4ea0b707f91f)] +[scriptable, uuid(ec2da5ae-eb2e-11d8-9782-0004e22243f8)] interface nsIProtocolProxyService : nsISupports { /** @@ -97,8 +97,12 @@ interface nsIProtocolProxyService : nsISupports * The proxy hostname or IP address. * @param aPort * The proxy port. + * @param aFlags + * Flags associated with this connection. See nsIProxyInfo.idl + * for currently defined flags. */ - nsIProxyInfo newProxyInfo(in ACString aType, in AUTF8String aHost, in long aPort); + nsIProxyInfo newProxyInfo(in ACString aType, in AUTF8String aHost, + in long aPort, in unsigned long aFlags); /** * This method may be called to re-configure proxy settings given a URI diff --git a/netwerk/base/public/nsIProxyInfo.idl b/netwerk/base/public/nsIProxyInfo.idl index d7ca47634941..672dc2ce4e25 100644 --- a/netwerk/base/public/nsIProxyInfo.idl +++ b/netwerk/base/public/nsIProxyInfo.idl @@ -21,6 +21,7 @@ * * Contributor(s): * Bradley Baetz (Original Developer) + * Malcolm Smith * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or @@ -52,10 +53,17 @@ */ native constCharPtr(const char*); -[scriptable, uuid(d49f429c-7c8e-4f7a-90a3-ea6122bd3887)] +[scriptable, uuid(cefb3b30-e82f-11d8-329c-0004e22243f8)] interface nsIProxyInfo : nsISupports { [noscript, notxpcom] constCharPtr Host(); [noscript, notxpcom] PRInt32 Port(); [noscript, notxpcom] constCharPtr Type(); + [noscript, notxpcom] PRUint32 Flags(); + + /* This flag is set if the proxy is to perform name resolution + * itself. If this is the case, the hostname is used in some + * fashion, and we shouldn't do any form of DNS lookup ourselves. + */ + const unsigned short TRANSPARENT_PROXY_RESOLVES_HOST = 1 << 0; }; diff --git a/netwerk/base/public/nsNetUtil.h b/netwerk/base/public/nsNetUtil.h index 01dace806b26..b3a81ba9a226 100644 --- a/netwerk/base/public/nsNetUtil.h +++ b/netwerk/base/public/nsNetUtil.h @@ -22,6 +22,7 @@ * * Contributor(s): * Bradley Baetz + * Malcolm Smith * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or @@ -588,13 +589,14 @@ inline nsresult NS_NewProxyInfo(const nsACString &type, const nsACString &host, PRInt32 port, + PRUint32 flags, nsIProxyInfo **result) { nsresult rv; static NS_DEFINE_CID(kPPSServiceCID, NS_PROTOCOLPROXYSERVICE_CID); nsCOMPtr pps = do_GetService(kPPSServiceCID, &rv); if (NS_SUCCEEDED(rv)) - rv = pps->NewProxyInfo(type, host, port, result); + rv = pps->NewProxyInfo(type, host, port, flags, result); return rv; } diff --git a/netwerk/base/src/nsProtocolProxyService.cpp b/netwerk/base/src/nsProtocolProxyService.cpp index 857903119e26..17a921d8d692 100644 --- a/netwerk/base/src/nsProtocolProxyService.cpp +++ b/netwerk/base/src/nsProtocolProxyService.cpp @@ -21,6 +21,7 @@ * the Initial Developer. All Rights Reserved. * * Contributor(s): + * Malcolm Smith * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or @@ -131,6 +132,19 @@ proxy_GetIntPref(nsIPrefBranch *aPrefBranch, aResult = temp; } +static void +proxy_GetBoolPref(nsIPrefBranch *aPrefBranch, + const char *aPref, + PRBool &aResult) +{ + PRBool temp; + nsresult rv = aPrefBranch->GetBoolPref(aPref, &temp); + if (NS_FAILED(rv)) + aResult = PR_FALSE; + else + aResult = temp; +} + //---------------------------------------------------------------------------- class nsProxyInfo : public nsIProxyInfo @@ -153,6 +167,10 @@ public: return mType; } + NS_IMETHOD_(PRUint32) Flags() { + return mFlags; + } + ~nsProxyInfo() { NS_IF_RELEASE(mNext); @@ -161,12 +179,14 @@ public: nsProxyInfo(const char *type = nsnull) : mType(type) , mPort(-1) + , mFlags(0) , mNext(nsnull) {} const char *mType; // pointer to static kProxyType_XYZ value nsCString mHost; PRInt32 mPort; + PRUint32 mFlags; nsProxyInfo *mNext; }; @@ -207,6 +227,7 @@ nsProtocolProxyService::nsProtocolProxyService() , mHTTPSProxyPort(-1) , mSOCKSProxyPort(-1) , mSOCKSProxyVersion(4) + , mSOCKSProxyRemoteDNS(PR_FALSE) , mSessionStart(PR_Now()) , mFailedProxyTimeout(30 * 60) // 30 minute default { @@ -320,6 +341,9 @@ nsProtocolProxyService::PrefsChanged(nsIPrefBranch *prefBranch, mSOCKSProxyVersion = 4; } + if (!pref || !strcmp(pref, "network.proxy.socks_remote_dns")) + proxy_GetBoolPref(prefBranch, "network.proxy.socks_remote_dns", mSOCKSProxyRemoteDNS); + if (!pref || !strcmp(pref, "network.proxy.failover_timeout")) proxy_GetIntPref(prefBranch, "network.proxy.failover_timeout", mFailedProxyTimeout); @@ -484,6 +508,7 @@ const char * nsProtocolProxyService::ExtractProxyInfo(const char *start, PRBool permitHttp, nsProxyInfo **result) { *result = nsnull; + PRUint32 flags = 0; // see BNF in nsIProxyAutoConfig.idl @@ -518,6 +543,13 @@ nsProtocolProxyService::ExtractProxyInfo(const char *start, PRBool permitHttp, n if (type) { const char *host = nsnull, *hostEnd = nsnull; PRInt32 port = -1; + + // If it's a SOCKS5 proxy, do name resolution on the server side. + // We could use this with SOCKS4a servers too, but they might not + // support it. + if (type == kProxyType_SOCKS) + flags |= nsIProxyInfo::TRANSPARENT_PROXY_RESOLVES_HOST; + // extract host:port start = sp; while ((*start == ' ' || *start == '\t') && start < end) @@ -539,6 +571,7 @@ nsProtocolProxyService::ExtractProxyInfo(const char *start, PRBool permitHttp, n nsProxyInfo *pi = new nsProxyInfo; if (pi) { pi->mType = type; + pi->mFlags = flags; // YES, it is ok to specify a null proxy host. if (host) { pi->mHost.Assign(host, hostEnd - host); @@ -762,6 +795,8 @@ nsProtocolProxyService::ExamineForProxy(nsIURI *aURI, nsIProxyInfo **aResult) const nsACString *host = nsnull; PRInt32 port = -1; + PRUint32 proxyFlags = 0; + if (!mHTTPProxyHost.IsEmpty() && mHTTPProxyPort > 0 && scheme.EqualsLiteral("http")) { host = &mHTTPProxyHost; @@ -793,10 +828,12 @@ nsProtocolProxyService::ExamineForProxy(nsIURI *aURI, nsIProxyInfo **aResult) else type = kProxyType_SOCKS; port = mSOCKSProxyPort; + if (mSOCKSProxyRemoteDNS) + proxyFlags |= nsIProxyInfo::TRANSPARENT_PROXY_RESOLVES_HOST; } if (type) - return NewProxyInfo_Internal(type, *host, port, aResult); + return NewProxyInfo_Internal(type, *host, port, proxyFlags, aResult); return NS_OK; } @@ -805,6 +842,7 @@ NS_IMETHODIMP nsProtocolProxyService::NewProxyInfo(const nsACString &aType, const nsACString &aHost, PRInt32 aPort, + PRUint32 aFlags, nsIProxyInfo **aResult) { static const char *types[] = { @@ -827,7 +865,7 @@ nsProtocolProxyService::NewProxyInfo(const nsACString &aType, if (aPort <= 0) aPort = -1; - return NewProxyInfo_Internal(type, aHost, aPort, aResult); + return NewProxyInfo_Internal(type, aHost, aPort, aFlags, aResult); } NS_IMETHODIMP @@ -1075,6 +1113,7 @@ nsresult nsProtocolProxyService::NewProxyInfo_Internal(const char *aType, const nsACString &aHost, PRInt32 aPort, + PRUint32 aFlags, nsIProxyInfo **aResult) { nsProxyInfo *proxyInfo = new nsProxyInfo(); @@ -1084,6 +1123,7 @@ nsProtocolProxyService::NewProxyInfo_Internal(const char *aType, proxyInfo->mType = aType; proxyInfo->mHost = aHost; proxyInfo->mPort = aPort; + proxyInfo->mFlags = aFlags; NS_ADDREF(*aResult = proxyInfo); return NS_OK; diff --git a/netwerk/base/src/nsProtocolProxyService.h b/netwerk/base/src/nsProtocolProxyService.h index 637f784cb7ac..efd75871812d 100644 --- a/netwerk/base/src/nsProtocolProxyService.h +++ b/netwerk/base/src/nsProtocolProxyService.h @@ -20,6 +20,7 @@ * the Initial Developer. All Rights Reserved. * * Contributor(s): + * Malcolm Smith * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or @@ -87,7 +88,7 @@ protected: NS_HIDDEN_(PRBool) IsProxyDisabled(nsProxyInfo *); NS_HIDDEN_(nsresult) ExaminePACForProxy(nsIURI *aURI, PRUint32 protoFlags, nsIProxyInfo **aResult); NS_HIDDEN_(nsresult) GetProtocolInfo(const char *scheme, PRUint32 &flags, PRInt32 &defaultPort); - NS_HIDDEN_(nsresult) NewProxyInfo_Internal(const char *type, const nsACString &host, PRInt32 port, nsIProxyInfo **); + NS_HIDDEN_(nsresult) NewProxyInfo_Internal(const char *type, const nsACString &host, PRInt32 port, PRUint32 flags, nsIProxyInfo **); NS_HIDDEN_(void) LoadFilters(const char *filters); NS_HIDDEN_(PRBool) CanUseProxy(nsIURI *aURI, PRInt32 defaultPort); NS_HIDDEN_(void) ConfigureFromWPAD(); @@ -150,6 +151,7 @@ protected: nsCString mSOCKSProxyHost; PRInt32 mSOCKSProxyPort; PRInt32 mSOCKSProxyVersion; + PRBool mSOCKSProxyRemoteDNS; nsCOMPtr mPAC; nsCString mPACURI; diff --git a/netwerk/base/src/nsSocketTransport2.cpp b/netwerk/base/src/nsSocketTransport2.cpp index bd7d8384ee15..de485917f0dd 100644 --- a/netwerk/base/src/nsSocketTransport2.cpp +++ b/netwerk/base/src/nsSocketTransport2.cpp @@ -21,6 +21,7 @@ * * Contributor(s): * Darin Fisher + * Malcolm Smith * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or @@ -677,6 +678,7 @@ nsSocketTransport::nsSocketTransport() , mPort(0) , mProxyPort(0) , mProxyTransparent(PR_FALSE) + , mProxyTransparentResolvesHost(PR_FALSE) , mState(STATE_CLOSED) , mAttached(PR_FALSE) , mInputClosed(PR_TRUE) @@ -769,8 +771,15 @@ nsSocketTransport::Init(const char **types, PRUint32 typeCount, // note if socket type corresponds to a transparent proxy if ((strcmp(mTypes[i], "socks") == 0) || - (strcmp(mTypes[i], "socks4") == 0)) + (strcmp(mTypes[i], "socks4") == 0)) { mProxyTransparent = PR_TRUE; + + if (proxyInfo->Flags() & nsIProxyInfo::TRANSPARENT_PROXY_RESOLVES_HOST) { + // we want the SOCKS layer to send the hostname + // and port to the proxy and let it do the DNS. + mProxyTransparentResolvesHost = PR_TRUE; + } + } } } @@ -865,6 +874,20 @@ nsSocketTransport::ResolveHost() nsresult rv; + if (!mProxyHost.IsEmpty() && mProxyTransparentResolvesHost) { + // Name resolution is done on the server side. Just pretend + // client resolution is complete, this will get picked up later. + // since we don't need to do DNS now, we bypass the resolving + // step by initializing mNetAddr to an empty address, but we + // must keep the port. The SOCKS IO layer will use the hostname + // we send it when it's created, rather than the empty address + // we send with the connect call. + mState = STATE_RESOLVING; + PR_SetNetAddr(PR_IpAddrAny, PR_AF_INET, SocketPort(), &mNetAddr); + return PostEvent(MSG_DNS_LOOKUP_COMPLETE, NS_OK, nsnull); + } + + nsCOMPtr dns = do_GetService(kDNSServiceCID, &rv); if (NS_FAILED(rv)) return rv; @@ -903,11 +926,12 @@ nsSocketTransport::BuildSocket(PRFileDesc *&fd, PRBool &proxyTransparent, PRBool do_GetService(kSocketProviderServiceCID, &rv); if (NS_FAILED(rv)) return rv; - const char *host = mHost.get(); - PRInt32 port = (PRInt32) mPort; - const char *proxyHost = mProxyHost.IsEmpty() ? nsnull : mProxyHost.get(); - PRInt32 proxyPort = (PRInt32) mProxyPort; - + const char *host = mHost.get(); + PRInt32 port = (PRInt32) mPort; + const char *proxyHost = mProxyHost.IsEmpty() ? nsnull : mProxyHost.get(); + PRInt32 proxyPort = (PRInt32) mProxyPort; + PRUint32 proxyFlags = 0; + PRUint32 i; for (i=0; i provider; @@ -918,13 +942,17 @@ nsSocketTransport::BuildSocket(PRFileDesc *&fd, PRBool &proxyTransparent, PRBool if (NS_FAILED(rv)) break; + if (mProxyTransparentResolvesHost) + proxyFlags |= nsISocketProvider::PROXY_RESOLVES_HOST; + nsCOMPtr secinfo; if (i == 0) { // if this is the first type, we'll want the // service to allocate a new socket rv = provider->NewSocket(mNetAddr.raw.family, host, port, proxyHost, proxyPort, - &fd, getter_AddRefs(secinfo)); + proxyFlags, &fd, + getter_AddRefs(secinfo)); if (NS_SUCCEEDED(rv) && !fd) { NS_NOTREACHED("NewSocket succeeded but failed to create a PRFileDesc"); @@ -937,8 +965,10 @@ nsSocketTransport::BuildSocket(PRFileDesc *&fd, PRBool &proxyTransparent, PRBool // to the stack (such as pushing an io layer) rv = provider->AddToSocket(mNetAddr.raw.family, host, port, proxyHost, proxyPort, - fd, getter_AddRefs(secinfo)); + proxyFlags, fd, + getter_AddRefs(secinfo)); } + proxyFlags = 0; if (NS_FAILED(rv)) break; diff --git a/netwerk/base/src/nsSocketTransport2.h b/netwerk/base/src/nsSocketTransport2.h index 01757af3df13..e939dc6ea924 100644 --- a/netwerk/base/src/nsSocketTransport2.h +++ b/netwerk/base/src/nsSocketTransport2.h @@ -187,13 +187,14 @@ private: //------------------------------------------------------------------------- // socket type info: - char **mTypes; - PRUint32 mTypeCount; - nsCString mHost; - nsCString mProxyHost; - PRUint16 mPort; - PRUint16 mProxyPort; - PRBool mProxyTransparent; + char **mTypes; + PRUint32 mTypeCount; + nsCString mHost; + nsCString mProxyHost; + PRUint16 mPort; + PRUint16 mProxyPort; + PRPackedBool mProxyTransparent; + PRPackedBool mProxyTransparentResolvesHost; PRUint16 SocketPort() { return (!mProxyHost.IsEmpty() && !mProxyTransparent) ? mProxyPort : mPort; } const nsCString &SocketHost() { return (!mProxyHost.IsEmpty() && !mProxyTransparent) ? mProxyHost : mHost; } diff --git a/netwerk/socket/base/nsISocketProvider.idl b/netwerk/socket/base/nsISocketProvider.idl index ca7fb0e1cc15..8e489e5243af 100644 --- a/netwerk/socket/base/nsISocketProvider.idl +++ b/netwerk/socket/base/nsISocketProvider.idl @@ -20,6 +20,7 @@ * the Initial Developer. All Rights Reserved. * * Contributor(s): + * Malcolm Smith * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or @@ -42,7 +43,7 @@ /** * nsISocketProvider */ -[noscript, uuid(4c29772e-cf73-414a-98d9-661761a4511a)] +[noscript, uuid(00b3df92-e830-11d8-d48e-0004e22243f8)] interface nsISocketProvider : nsISupports { /** @@ -58,6 +59,8 @@ interface nsISocketProvider : nsISupports * If non-null, the proxy hostname for this connection. * @param aProxyPort * The proxy port for this connection. + * @param aFlags + * Control flags that govern this connection (see below.) * @param aFileDesc * The resulting PRFileDesc. * @param aSecurityInfo @@ -69,25 +72,38 @@ interface nsISocketProvider : nsISupports in long aPort, in string aProxyHost, in long aProxyPort, + in unsigned long aFlags, out nsFileDescStar 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. + * 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. + * Parameters are the same as newSocket with the exception of aFileDesc, + * which is an in-param instead. */ void addToSocket(in long aFamily, in string aHost, in long aPort, in string aProxyHost, in long aProxyPort, + in unsigned long aFlags, in nsFileDescStar 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. + */ + const long PROXY_RESOLVES_HOST = 1 << 0; }; %{C++ diff --git a/netwerk/socket/base/nsSOCKSIOLayer.cpp b/netwerk/socket/base/nsSOCKSIOLayer.cpp index 31e67020024b..8e74089ce04b 100644 --- a/netwerk/socket/base/nsSOCKSIOLayer.cpp +++ b/netwerk/socket/base/nsSOCKSIOLayer.cpp @@ -24,6 +24,7 @@ * Justin Bradford * Bradley Baetz * Darin Fisher + * Malcolm Smith * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or @@ -46,6 +47,7 @@ #include "nsIServiceManager.h" #include "nsIDNSService.h" #include "nsISOCKSSocketInfo.h" +#include "nsISocketProvider.h" #include "nsSOCKSIOLayer.h" #include "nsNetCID.h" @@ -68,20 +70,28 @@ class nsSOCKSSocketInfo : public nsISOCKSSocketInfo public: nsSOCKSSocketInfo(); virtual ~nsSOCKSSocketInfo() {} - + NS_DECL_ISUPPORTS NS_DECL_NSISOCKSSOCKETINFO - void Init(PRInt32 version, const char *proxyHost, PRInt32 proxyPort); - - const nsCString &ProxyHost() { return mProxyHost; } - PRInt32 ProxyPort() { return mProxyPort; } - PRInt32 Version() { return mVersion; } + void Init(PRInt32 version, + const char *proxyHost, + PRInt32 proxyPort, + const char *destinationHost, + PRUint32 flags); + + const nsCString &DestinationHost() { return mDestinationHost; } + const nsCString &ProxyHost() { return mProxyHost; } + PRInt32 ProxyPort() { return mProxyPort; } + PRInt32 Version() { return mVersion; } + PRUint32 Flags() { return mFlags; } private: + nsCString mDestinationHost; nsCString mProxyHost; - PRInt32 mProxyPort; + PRInt32 mProxyPort; PRInt32 mVersion; // SOCKS version 4 or 5 + PRUint32 mFlags; PRNetAddr mInternalProxyAddr; PRNetAddr mExternalProxyAddr; PRNetAddr mDestinationAddr; @@ -90,6 +100,7 @@ private: nsSOCKSSocketInfo::nsSOCKSSocketInfo() : mProxyPort(-1) , mVersion(-1) + , mFlags(0) { PR_InitializeNetAddr(PR_IpAddrAny, 0, &mInternalProxyAddr); PR_InitializeNetAddr(PR_IpAddrAny, 0, &mExternalProxyAddr); @@ -97,11 +108,13 @@ nsSOCKSSocketInfo::nsSOCKSSocketInfo() } void -nsSOCKSSocketInfo::Init(PRInt32 version, const char *proxyHost, PRInt32 proxyPort) +nsSOCKSSocketInfo::Init(PRInt32 version, const char *proxyHost, PRInt32 proxyPort, const char *host, PRUint32 flags) { - mVersion = version; - mProxyHost = proxyHost; - mProxyPort = proxyPort; + mVersion = version; + mProxyHost = proxyHost; + mProxyPort = proxyPort; + mDestinationHost = host; + mFlags = flags; } NS_IMPL_THREADSAFE_ISUPPORTS1(nsSOCKSSocketInfo, nsISOCKSSocketInfo) @@ -182,17 +195,17 @@ ConnectSOCKS5(PRFileDesc *fd, const PRNetAddr *addr, PRNetAddr *extAddr, PRInter LOGERROR(("PR_Send() failed. Wrote: %d bytes; Expected: %d.", write_len, request_len)); return NS_ERROR_FAILURE; } - + // get the server's response. Use PR_Recv() instead of response_len = 2; response_len = PR_Recv(fd, response, response_len, 0, timeout); - + if (response_len <= 0) { LOGERROR(("PR_Recv() failed. response_len = %d.", response_len)); return NS_ERROR_FAILURE; } - + if (response[0] != 0x05) { // it's a either not SOCKS or not our version LOGERROR(("Not a SOCKS 5 reply. Expected: 5; received: %x", response[0])); @@ -222,67 +235,119 @@ ConnectSOCKS5(PRFileDesc *fd, const PRNetAddr *addr, PRNetAddr *extAddr, PRInter LOGERROR(("Uncrecognized authentication method received: %x", response[1])); return NS_ERROR_FAILURE; } - + // we are now authenticated, so lets tell // the server where to connect to - - request_len = 6; - + + request_len = 0; + request[0] = 0x05; // SOCKS version 5 request[1] = 0x01; // CONNECT command request[2] = 0x00; // obligatory reserved field (perfect for MS tampering!) - - if (PR_NetAddrFamily(addr) == PR_AF_INET) { - + + // get destination port + PRInt32 destPort = PR_ntohs(PR_NetAddrInetPort(addr)); + nsSOCKSSocketInfo * info = (nsSOCKSSocketInfo*) fd->secret; + + if (info->Flags() & nsISocketProvider::PROXY_RESOLVES_HOST) { + + LOGDEBUG(("using server to resolve hostnames rather than resolving it first\n")); + + // if the PROXY_RESOLVES_HOST flag is set, we assume + // that the transport wants us to pass the SOCKS server the + // hostname and port and let it do the name resolution. + + // the real destination hostname and port was stored + // in our info object earlier when this layer was created. + + const nsCString& destHost = info->DestinationHost(); + + LOGDEBUG(("host:port -> %s:%li", destHost.get(), destPort)); + + request[3] = 0x03; // encoding of destination address (3 == hostname) + + int host_len = destHost.Length(); + if (host_len > 255) { + // SOCKS5 transmits the length of the hostname in a single char. + // This gives us an absolute limit of 255 chars in a hostname, and + // there's nothing we can do to extend it. I don't think many + // hostnames will ever be bigger than this, so hopefully it's an + // uneventful abort condition. + LOGERROR (("Hostname too big for SOCKS5.")); + return NS_ERROR_INVALID_ARG; + } + request[4] = (char) host_len; + request_len = 5; + + // Send the initial header first... + write_len = PR_Send(fd, request, request_len, 0, timeout); + if (write_len != request_len) { + // bad write + LOGERROR(("PR_Send() failed sending connect command. Wrote: %d bytes; Expected: %d.", write_len, request_len)); + return NS_ERROR_FAILURE; + } + + // Now send the hostname... + write_len = PR_Send(fd, destHost.get(), host_len, 0, timeout); + if (write_len != host_len) { + // bad write + LOGERROR(("PR_Send() failed sending connect command. Wrote: %d bytes; Expected: %d.", write_len, host_len)); + return NS_ERROR_FAILURE; + } + + // There's no data left because we just sent it. + request_len = 0; + + } else if (PR_NetAddrFamily(addr) == PR_AF_INET) { + request[3] = 0x01; // encoding of destination address (1 == IPv4) - request_len += 4; - + request_len = 8; // 4 for address, 4 SOCKS headers + char * ip = (char*)(&addr->inet.ip); request[4] = *ip++; request[5] = *ip++; request[6] = *ip++; request[7] = *ip++; - + } else if (PR_NetAddrFamily(addr) == PR_AF_INET6) { - + request[3] = 0x04; // encoding of destination address (4 == IPv6) - request_len += 16; - + request_len = 20; // 16 for address, 4 SOCKS headers + char * ip = (char*)(&addr->ipv6.ip.pr_s6_addr); - request[4] = *ip++; request[5] = *ip++; request[6] = *ip++; request[7] = *ip++; - request[8] = *ip++; request[9] = *ip++; request[10] = *ip++; request[11] = *ip++; - request[12] = *ip++; request[13] = *ip++; request[14] = *ip++; request[15] = *ip++; - request[16] = *ip++; request[17] = *ip++; request[18] = *ip++; request[19] = *ip++; - + request[4] = *ip++; request[5] = *ip++; + request[6] = *ip++; request[7] = *ip++; + request[8] = *ip++; request[9] = *ip++; + request[10] = *ip++; request[11] = *ip++; + request[12] = *ip++; request[13] = *ip++; + request[14] = *ip++; request[15] = *ip++; + request[16] = *ip++; request[17] = *ip++; + request[18] = *ip++; request[19] = *ip++; + // we're going to test to see if this address can // be mapped back into IPv4 without loss. if so, // we'll use IPv4 instead, as reliable SOCKS server // support for IPv6 is probably questionable. - + if (PR_IsNetAddrType(addr, PR_IpAddrV4Mapped)) { - request[3] = 0x01; // ipv4 encoding request[4] = request[16]; request[5] = request[17]; request[6] = request[18]; request[7] = request[19]; request_len -= 12; - } - } else { - // Unknown address type LOGERROR(("Don't know what kind of IP address this is.")); return NS_ERROR_FAILURE; } - - // destination port - PRUint16 destPort = PR_htons(PR_NetAddrInetPort(addr)); - - request[request_len-2] = (unsigned char)(destPort >> 8); - request[request_len-1] = (unsigned char)destPort; - + + // add the destination port to the request + request[request_len] = (unsigned char)(destPort >> 8); + request[request_len+1] = (unsigned char)destPort; + request_len += 2; + write_len = PR_Send(fd, request, request_len, 0, timeout); if (write_len != request_len) { @@ -290,7 +355,7 @@ ConnectSOCKS5(PRFileDesc *fd, const PRNetAddr *addr, PRNetAddr *extAddr, PRInter LOGERROR(("PR_Send() failed sending connect command. Wrote: %d bytes; Expected: %d.", write_len, request_len)); return NS_ERROR_FAILURE; } - + response_len = 22; response_len = PR_Recv(fd, response, response_len, 0, timeout); if (response_len <= 0) { @@ -299,14 +364,14 @@ ConnectSOCKS5(PRFileDesc *fd, const PRNetAddr *addr, PRNetAddr *extAddr, PRInter LOGERROR(("PR_Recv() failed getting connect command reply. response_len = %d.", response_len)); return NS_ERROR_FAILURE; } - + if (response[0] != 0x05) { // bad response LOGERROR(("Not a SOCKS 5 reply. Expected: 5; received: %x", response[0])); return NS_ERROR_FAILURE; } - + switch(response[1]) { case 0x00: break; // success case 0x01: LOGERROR(("SOCKS 5 server rejected connect request: 01, General SOCKS server failure.")); @@ -328,10 +393,10 @@ ConnectSOCKS5(PRFileDesc *fd, const PRNetAddr *addr, PRNetAddr *extAddr, PRInter default: LOGERROR(("SOCKS 5 server rejected connect request: %x.", response[1])); return NS_ERROR_FAILURE; - + } - - + + // get external bound address (this is what // the outside world sees as "us") char *ip = nsnull; @@ -339,30 +404,34 @@ ConnectSOCKS5(PRFileDesc *fd, const PRNetAddr *addr, PRNetAddr *extAddr, PRInter switch (response[3]) { case 0x01: // IPv4 - + extPort = (response[8] << 8) | response[9]; - + PR_SetNetAddr(PR_IpAddrAny, PR_AF_INET, extPort, extAddr); - + ip = (char*)(&extAddr->inet.ip); *ip++ = response[4]; *ip++ = response[5]; *ip++ = response[6]; *ip++ = response[7]; - + break; case 0x04: // IPv6 - + extPort = (response[20] << 8) | response[21]; - + PR_SetNetAddr(PR_IpAddrAny, PR_AF_INET6, extPort, extAddr); - + ip = (char*)(&extAddr->ipv6.ip.pr_s6_addr); - *ip++ = response[4]; *ip++ = response[5]; *ip++ = response[6]; *ip++ = response[7]; - *ip++ = response[8]; *ip++ = response[9]; *ip++ = response[10]; *ip++ = response[11]; - *ip++ = response[12]; *ip++ = response[13]; *ip++ = response[14]; *ip++ = response[15]; - *ip++ = response[16]; *ip++ = response[17]; *ip++ = response[18]; *ip++ = response[19]; - + *ip++ = response[4]; *ip++ = response[5]; + *ip++ = response[6]; *ip++ = response[7]; + *ip++ = response[8]; *ip++ = response[9]; + *ip++ = response[10]; *ip++ = response[11]; + *ip++ = response[12]; *ip++ = response[13]; + *ip++ = response[14]; *ip++ = response[15]; + *ip++ = response[16]; *ip++ = response[17]; + *ip++ = response[18]; *ip++ = response[19]; + break; case 0x03: // FQDN (should not get this back) default: // unknown format @@ -387,48 +456,21 @@ ConnectSOCKS4(PRFileDesc *fd, const PRNetAddr *addr, PRIntervalTime timeout) unsigned char request[12]; int request_len = 0; + int write_len; unsigned char response[10]; int response_len = 0; + char *ip = nsnull; request[0] = 0x04; // SOCKS version 4 request[1] = 0x01; // CD command code -- 1 for connect // destination port - PRUint16 destPort = PR_htons(PR_NetAddrInetPort(addr)); + PRInt32 destPort = PR_ntohs(PR_NetAddrInetPort(addr)); + // store the port request[2] = (unsigned char)(destPort >> 8); request[3] = (unsigned char)destPort; - // destination IP - char * ip = nsnull; - - // IPv4 - if (PR_NetAddrFamily(addr) == PR_AF_INET) - ip = (char*)(&addr->inet.ip); - - // IPv6 - else if (PR_NetAddrFamily(addr) == PR_AF_INET6) { - - // IPv4 address encoded in an IPv6 address - if (PR_IsNetAddrType(addr, PR_IpAddrV4Mapped)) - ip = (char*)(&addr->ipv6.ip.pr_s6_addr[12]); - else { - LOGERROR(("IPv6 not supported in SOCK 4.")); - return NS_ERROR_FAILURE; // SOCKS 4 can't do IPv6 - } - } - - else { - - LOGERROR(("Don't know what kind of IP address this is.")); - return NS_ERROR_FAILURE; // don't recognize this type - } - - request[4] = *ip++; - request[5] = *ip++; - request[6] = *ip++; - request[7] = *ip++; - // username request[8] = 'M'; request[9] = 'O'; @@ -437,13 +479,89 @@ ConnectSOCKS4(PRFileDesc *fd, const PRNetAddr *addr, PRIntervalTime timeout) request[11] = 0x00; request_len = 12; - int write_len = PR_Send(fd, request, request_len, 0, timeout); - if (write_len != request_len) { - LOGERROR(("PR_Send() failed. Wrote: %d bytes; Expected: %d.", write_len, request_len)); - return NS_ERROR_FAILURE; + nsSOCKSSocketInfo * info = (nsSOCKSSocketInfo*) fd->secret; + + if (info->Flags() & nsISocketProvider::PROXY_RESOLVES_HOST) { + + LOGDEBUG(("using server to resolve hostnames rather than resolving it first\n")); + + // if the PROXY_RESOLVES_HOST flag is set, we assume that the + // transport wants us to pass the SOCKS server the hostname + // and port and let it do the name resolution. + + // an extension to SOCKS 4, called 4a, specifies a way + // to do this, so we'll try that and hope the + // server supports it. + + // the real destination hostname and port was stored + // in our info object earlier when this layer was created. + + const nsCString& destHost = info->DestinationHost(); + + LOGDEBUG(("host:port -> %s:%li\n", destHost.get(), destPort)); + + // the IP portion of the query is set to this special address. + request[4] = 0; + request[5] = 0; + request[6] = 0; + request[7] = 1; + + write_len = PR_Send(fd, request, request_len, 0, timeout); + if (write_len != request_len) { + LOGERROR(("PR_Send() failed. Wrote: %d bytes; Expected: %d.", write_len, request_len)); + return NS_ERROR_FAILURE; + } + + // Remember the NULL. + int host_len = destHost.Length() + 1; + + write_len = PR_Send(fd, destHost.get(), host_len, 0, timeout); + if (write_len != host_len) { + LOGERROR(("PR_Send() failed. Wrote: %d bytes; Expected: %d.", write_len, host_len)); + return NS_ERROR_FAILURE; + } + + // No data to send, just sent it. + request_len = 0; + + } else if (PR_NetAddrFamily(addr) == PR_AF_INET) { // IPv4 + + // store the ip + ip = (char*)(&addr->inet.ip); + request[4] = *ip++; + request[5] = *ip++; + request[6] = *ip++; + request[7] = *ip++; + + } else if (PR_NetAddrFamily(addr) == PR_AF_INET6) { // IPv6 + + // IPv4 address encoded in an IPv6 address + if (PR_IsNetAddrType(addr, PR_IpAddrV4Mapped)) { + // store the ip + ip = (char*)(&addr->ipv6.ip.pr_s6_addr[12]); + request[4] = *ip++; + request[5] = *ip++; + request[6] = *ip++; + request[7] = *ip++; + } else { + LOGERROR(("IPv6 is not supported in SOCKS 4.")); + return NS_ERROR_FAILURE; // SOCKS 4 can't do IPv6 + } + + } else { + LOGERROR(("Don't know what kind of IP address this is.")); + return NS_ERROR_FAILURE; // don't recognize this type } - + + if (request_len > 0) { + write_len = PR_Send(fd, request, request_len, 0, timeout); + if (write_len != request_len) { + LOGERROR(("PR_Send() failed. Wrote: %d bytes; Expected: %d.", write_len, request_len)); + return NS_ERROR_FAILURE; + } + } + // get the server's response response_len = 8; // size of the response response_len = PR_Recv(fd, response, response_len, 0, timeout); @@ -452,7 +570,7 @@ ConnectSOCKS4(PRFileDesc *fd, const PRNetAddr *addr, PRIntervalTime timeout) LOGERROR(("PR_Recv() failed. response_len = %d.", response_len)); return NS_ERROR_FAILURE; } - + if ((response[0] != 0x00) && (response[0] != 0x04)) { // Novell BorderManager sends a response of type 4, should be zero // According to the spec. Cope with this brokenness. @@ -477,10 +595,10 @@ nsSOCKSIOLayerConnect(PRFileDesc *fd, const PRNetAddr *addr, PRIntervalTime /*ti { PRStatus status; - + nsSOCKSSocketInfo * info = (nsSOCKSSocketInfo*) fd->secret; if (info == NULL) return PR_FAILURE; - + // First, we need to look up our proxy... const nsCString &proxyHost = info->ProxyHost(); @@ -497,7 +615,7 @@ nsSOCKSIOLayerConnect(PRFileDesc *fd, const PRNetAddr *addr, PRIntervalTime /*ti nsCOMPtr dns; nsCOMPtr rec; nsresult rv; - + dns = do_GetService(NS_DNSSERVICE_CONTRACTID, &rv); if (NS_FAILED(rv)) return PR_FAILURE; @@ -512,38 +630,38 @@ nsSOCKSIOLayerConnect(PRFileDesc *fd, const PRNetAddr *addr, PRIntervalTime /*ti } info->SetInternalProxyAddr(&proxyAddr); - + // For now, we'll do this as a blocking connect, // but with nspr 4.1, the necessary functions to // do a non-blocking connect will be available - + // Preserve the non-blocking state of the socket PRBool nonblocking; PRSocketOptionData sockopt; sockopt.option = PR_SockOpt_Nonblocking; status = PR_GetSocketOption(fd, &sockopt); - + if (PR_SUCCESS != status) { LOGERROR(("PR_GetSocketOption() failed. status = %x.", status)); return status; } - + // Store blocking option nonblocking = sockopt.value.non_blocking; - + sockopt.option = PR_SockOpt_Nonblocking; sockopt.value.non_blocking = PR_FALSE; status = PR_SetSocketOption(fd, &sockopt); - + if (PR_SUCCESS != status) { LOGERROR(("PR_SetSocketOption() failed. status = %x.", status)); return status; } - + // Now setup sockopts, so we can restore the value later. sockopt.option = PR_SockOpt_Nonblocking; sockopt.value.non_blocking = nonblocking; - + // This connectWait should be long enough to connect to local proxy // servers, but not much longer. Since this protocol negotiation @@ -556,17 +674,17 @@ nsSOCKSIOLayerConnect(PRFileDesc *fd, const PRNetAddr *addr, PRIntervalTime /*ti // Connect to the proxy server. status = fd->lower->methods->connect(fd->lower, &proxyAddr, connectWait); - + if (PR_SUCCESS != status) { LOGERROR(("Failed to TCP connect to the proxy server (%s): timeout = %d, status = %x.",proxyHost.get(), connectWait, status)); PR_SetSocketOption(fd, &sockopt); return status; } - - + + // We are now connected to the SOCKS proxy server. // Now we will negotiate a connection to the desired server. - + // External IP address returned from ConnectSOCKS5(). Not supported in SOCKS4. PRNetAddr extAddr; PR_InitializeNetAddr(PR_IpAddrNull, 0, &extAddr); @@ -599,16 +717,16 @@ nsSOCKSIOLayerConnect(PRFileDesc *fd, const PRNetAddr *addr, PRIntervalTime /*ti } - + info->SetDestinationAddr((PRNetAddr*)addr); info->SetExternalProxyAddr(&extAddr); - + // restore non-blocking option PR_SetSocketOption(fd, &sockopt); - + // we're set-up and connected. // this socket can be used as normal now. - + return PR_SUCCESS; } @@ -617,13 +735,13 @@ nsSOCKSIOLayerClose(PRFileDesc *fd) { nsSOCKSSocketInfo * info = (nsSOCKSSocketInfo*) fd->secret; PRDescIdentity id = PR_GetLayersIdentity(fd); - + if (info && id == nsSOCKSIOLayerIdentity) { NS_RELEASE(info); fd->identity = PR_INVALID_IO_LAYER; } - + return fd->lower->methods->close(fd->lower); } @@ -657,7 +775,7 @@ nsSOCKSIOLayerGetName(PRFileDesc *fd, PRNetAddr *addr) if (info->GetExternalProxyAddr(&addr) == NS_OK) return PR_SUCCESS; } - + return PR_FAILURE; } @@ -665,12 +783,12 @@ static PRStatus PR_CALLBACK nsSOCKSIOLayerGetPeerName(PRFileDesc *fd, PRNetAddr *addr) { nsSOCKSSocketInfo * info = (nsSOCKSSocketInfo*) fd->secret; - + if (info != NULL && addr != NULL) { if (info->GetDestinationAddr(&addr) == NS_OK) return PR_SUCCESS; } - + return PR_FAILURE; } @@ -689,6 +807,7 @@ nsSOCKSIOLayerAddToSocket(PRInt32 family, const char *proxyHost, PRInt32 proxyPort, PRInt32 socksVersion, + PRUint32 flags, PRFileDesc *fd, nsISupports** info) { @@ -699,7 +818,7 @@ nsSOCKSIOLayerAddToSocket(PRInt32 family, { nsSOCKSIOLayerIdentity = PR_GetUniqueIdentity("SOCKS layer"); nsSOCKSIOLayerMethods = *PR_GetDefaultIOMethods(); - + nsSOCKSIOLayerMethods.connect = nsSOCKSIOLayerConnect; nsSOCKSIOLayerMethods.bind = nsSOCKSIOLayerBind; nsSOCKSIOLayerMethods.acceptread = nsSOCKSIOLayerAcceptRead; @@ -708,7 +827,7 @@ nsSOCKSIOLayerAddToSocket(PRInt32 family, nsSOCKSIOLayerMethods.accept = nsSOCKSIOLayerAccept; nsSOCKSIOLayerMethods.listen = nsSOCKSIOLayerListen; nsSOCKSIOLayerMethods.close = nsSOCKSIOLayerClose; - + firstTime = PR_FALSE; #if defined(PR_LOGGING) @@ -716,19 +835,19 @@ nsSOCKSIOLayerAddToSocket(PRInt32 family, #endif } - + LOGDEBUG(("Entering nsSOCKSIOLayerAddToSocket().")); - + PRFileDesc * layer; PRStatus rv; - + layer = PR_CreateIOLayerStub(nsSOCKSIOLayerIdentity, &nsSOCKSIOLayerMethods); if (! layer) { LOGERROR(("PR_CreateIOLayerStub() failed.")); return NS_ERROR_FAILURE; } - + nsSOCKSSocketInfo * infoObject = new nsSOCKSSocketInfo(); if (!infoObject) { @@ -737,12 +856,12 @@ nsSOCKSIOLayerAddToSocket(PRInt32 family, PR_DELETE(layer); return NS_ERROR_FAILURE; } - + NS_ADDREF(infoObject); - infoObject->Init(socksVersion, proxyHost, proxyPort); + infoObject->Init(socksVersion, proxyHost, proxyPort, host, flags); layer->secret = (PRFilePrivate*) infoObject; rv = PR_PushIOLayer(fd, PR_GetLayersIdentity(fd), layer); - + if (NS_FAILED(rv)) { LOGERROR(("PR_PushIOLayer() failed. rv = %x.", rv)); @@ -750,7 +869,7 @@ nsSOCKSIOLayerAddToSocket(PRInt32 family, PR_DELETE(layer); return NS_ERROR_FAILURE; } - + *info = infoObject; NS_ADDREF(*info); return NS_OK; diff --git a/netwerk/socket/base/nsSOCKSIOLayer.h b/netwerk/socket/base/nsSOCKSIOLayer.h index b4e625c08660..4de0263c0386 100644 --- a/netwerk/socket/base/nsSOCKSIOLayer.h +++ b/netwerk/socket/base/nsSOCKSIOLayer.h @@ -22,6 +22,7 @@ * * Contributor(s): * Justin Bradford + * Malcolm Smith * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or @@ -44,13 +45,14 @@ #include "prio.h" #include "nscore.h" -nsresult nsSOCKSIOLayerAddToSocket(PRInt32 family, - const char *host, - PRInt32 port, - const char *proxyHost, - PRInt32 proxyPort, - PRInt32 socksVersion, - PRFileDesc *fd, +nsresult nsSOCKSIOLayerAddToSocket(PRInt32 family, + const char *host, + PRInt32 port, + const char *proxyHost, + PRInt32 proxyPort, + PRInt32 socksVersion, + PRUint32 flags, + PRFileDesc *fd, nsISupports **info); #endif /* nsSOCKSIOLayer_h__ */ diff --git a/netwerk/socket/base/nsSOCKSSocketProvider.cpp b/netwerk/socket/base/nsSOCKSSocketProvider.cpp index 83d4634d6e6f..cd72c70449dc 100644 --- a/netwerk/socket/base/nsSOCKSSocketProvider.cpp +++ b/netwerk/socket/base/nsSOCKSSocketProvider.cpp @@ -23,6 +23,7 @@ * Contributor(s): * Justin Bradford * Darin Fisher + * Malcolm Smith * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or @@ -80,6 +81,7 @@ nsSOCKSSocketProvider::NewSocket(PRInt32 family, PRInt32 port, const char *proxyHost, PRInt32 proxyPort, + PRUint32 flags, PRFileDesc **result, nsISupports **socksInfo) { @@ -95,6 +97,7 @@ nsSOCKSSocketProvider::NewSocket(PRInt32 family, proxyHost, proxyPort, mVersion, + flags, sock, socksInfo); if (NS_SUCCEEDED(rv)) { @@ -111,6 +114,7 @@ nsSOCKSSocketProvider::AddToSocket(PRInt32 family, PRInt32 port, const char *proxyHost, PRInt32 proxyPort, + PRUint32 flags, PRFileDesc *sock, nsISupports **socksInfo) { @@ -120,6 +124,7 @@ nsSOCKSSocketProvider::AddToSocket(PRInt32 family, proxyHost, proxyPort, mVersion, + flags, sock, socksInfo); diff --git a/security/manager/ssl/src/nsSSLSocketProvider.cpp b/security/manager/ssl/src/nsSSLSocketProvider.cpp index ccb2904372ec..d3d9838b237c 100644 --- a/security/manager/ssl/src/nsSSLSocketProvider.cpp +++ b/security/manager/ssl/src/nsSSLSocketProvider.cpp @@ -58,6 +58,7 @@ nsSSLSocketProvider::NewSocket(PRInt32 family, PRInt32 port, const char *proxyHost, PRInt32 proxyPort, + PRUint32 flags, PRFileDesc **_result, nsISupports **securityInfo) { @@ -79,6 +80,7 @@ nsSSLSocketProvider::AddToSocket(PRInt32 family, PRInt32 port, const char *proxyHost, PRInt32 proxyPort, + PRUint32 flags, PRFileDesc *aSocket, nsISupports **securityInfo) { diff --git a/security/manager/ssl/src/nsTLSSocketProvider.cpp b/security/manager/ssl/src/nsTLSSocketProvider.cpp index c56889d6f72f..69aa92729f50 100644 --- a/security/manager/ssl/src/nsTLSSocketProvider.cpp +++ b/security/manager/ssl/src/nsTLSSocketProvider.cpp @@ -58,6 +58,7 @@ nsTLSSocketProvider::NewSocket(PRInt32 family, PRInt32 port, const char *proxyHost, PRInt32 proxyPort, + PRUint32 flags, PRFileDesc **_result, nsISupports **securityInfo) { @@ -80,6 +81,7 @@ nsTLSSocketProvider::AddToSocket(PRInt32 family, PRInt32 port, const char *proxyHost, PRInt32 proxyPort, + PRUint32 flags, PRFileDesc *aSocket, nsISupports **securityInfo) {