[tor-commits] [tor-browser/tor-browser-31.2.0esr-4.5-1] Bug #3455.2. Allow RFC1929 authentication (username/password) to SOCKS servers.

mikeperry at torproject.org mikeperry at torproject.org
Thu Oct 30 20:48:36 UTC 2014


commit e0eaf6b471ae3bbc06066232a00f3b27c2bedeee
Author: Arthur Edelstein <arthuredelstein at gmail.com>
Date:   Tue Oct 21 02:17:55 2014 -0700

    Bug #3455.2. Allow RFC1929 authentication (username/password) to SOCKS servers.
---
 netwerk/base/public/nsIProtocolProxyService.idl  |   29 ++++
 netwerk/base/public/nsIProxyInfo.idl             |   12 +-
 netwerk/base/src/nsProtocolProxyService.cpp      |   39 ++++-
 netwerk/base/src/nsProtocolProxyService.h        |    8 +
 netwerk/base/src/nsProxyInfo.cpp                 |   14 ++
 netwerk/base/src/nsProxyInfo.h                   |    2 +
 netwerk/base/src/nsSocketTransport2.cpp          |   84 +++++++---
 netwerk/base/src/nsSocketTransport2.h            |   15 +-
 netwerk/socket/nsISocketProvider.idl             |    9 +-
 netwerk/socket/nsSOCKSIOLayer.cpp                |  196 +++++++++++++++++-----
 netwerk/socket/nsSOCKSIOLayer.h                  |    4 +-
 netwerk/socket/nsSOCKSSocketProvider.cpp         |   12 +-
 netwerk/socket/nsUDPSocketProvider.cpp           |    6 +-
 security/manager/ssl/src/nsNSSIOLayer.cpp        |   23 ++-
 security/manager/ssl/src/nsNSSIOLayer.h          |    7 +-
 security/manager/ssl/src/nsSSLSocketProvider.cpp |   12 +-
 security/manager/ssl/src/nsTLSSocketProvider.cpp |   12 +-
 17 files changed, 361 insertions(+), 123 deletions(-)

diff --git a/netwerk/base/public/nsIProtocolProxyService.idl b/netwerk/base/public/nsIProtocolProxyService.idl
index 9365658..f974f40 100644
--- a/netwerk/base/public/nsIProtocolProxyService.idl
+++ b/netwerk/base/public/nsIProtocolProxyService.idl
@@ -136,6 +136,35 @@ interface nsIProtocolProxyService : nsISupports
                               in nsIProxyInfo aFailoverProxy);
 
     /**
+     * This method may be called to construct a nsIProxyInfo instance for
+     * a SOCKS connection, with the specified username and password.
+     * @param aHost
+     *        The proxy hostname or IP address.
+     * @param aPort
+     *        The proxy port.
+     * @param aUsername
+     *        The SOCKS5 username
+     * @param aPassword
+     *        The SOCKS5 password
+     * @param aFlags
+     *        Flags associated with this connection.  See nsIProxyInfo.idl
+     *        for currently defined flags.
+     * @param aFailoverTimeout
+     *        Specifies the length of time (in seconds) to ignore this proxy if
+     *        this proxy fails.  Pass UINT32_MAX to specify the default
+     *        timeout value, causing nsIProxyInfo::failoverTimeout to be
+     *        assigned the default value.
+     * @param aFailoverProxy
+     *        Specifies the next proxy to try if this proxy fails.  This
+     *        parameter may be null.
+     */
+    nsIProxyInfo newSOCKSProxyInfo(in AUTF8String aHost, in long aPort,
+                                   in ACString aUsername, in ACString aPassword,
+                                   in unsigned long aFlags,
+                                   in unsigned long aFailoverTimeout,
+                                   in nsIProxyInfo aFailoverProxy);
+
+    /**
      * If the proxy identified by aProxyInfo is unavailable for some reason,
      * this method may be called to access an alternate proxy that may be used
      * instead.  As a side-effect, this method may affect future result values
diff --git a/netwerk/base/public/nsIProxyInfo.idl b/netwerk/base/public/nsIProxyInfo.idl
index f6f0bf3..56beb02 100644
--- a/netwerk/base/public/nsIProxyInfo.idl
+++ b/netwerk/base/public/nsIProxyInfo.idl
@@ -8,7 +8,7 @@
 /**
  * This interface identifies a proxy server.
  */
-[scriptable, uuid(9e557d99-7af0-4895-95b7-e6dba28c9ad9)]
+[scriptable, uuid(63fff172-2564-4138-96c6-3ae7d245fbed)]
 interface nsIProxyInfo : nsISupports
 {
   /**
@@ -50,6 +50,16 @@ interface nsIProxyInfo : nsISupports
   readonly attribute unsigned long resolveFlags;
 
   /**
+   * Specifies a SOCKS5 username.
+   */
+  readonly attribute ACString username;
+
+  /**
+   * Specifies a SOCKS5 password.
+   */
+  readonly attribute ACString password;
+
+  /**
    * This attribute specifies the failover timeout in seconds for this proxy.
    * If a nsIProxyInfo is reported as failed via nsIProtocolProxyService::
    * getFailoverForProxy, then the failed proxy will not be used again for this
diff --git a/netwerk/base/src/nsProtocolProxyService.cpp b/netwerk/base/src/nsProtocolProxyService.cpp
index 3878c58d..ed8b311 100644
--- a/netwerk/base/src/nsProtocolProxyService.cpp
+++ b/netwerk/base/src/nsProtocolProxyService.cpp
@@ -516,6 +516,12 @@ nsProtocolProxyService::PrefsChanged(nsIPrefBranch *prefBranch,
     if (!pref || !strcmp(pref, PROXY_PREF("socks_port")))
         proxy_GetIntPref(prefBranch, PROXY_PREF("socks_port"), mSOCKSProxyPort);
 
+    if (!pref || !strcmp(pref, PROXY_PREF("socks_username")))
+        proxy_GetStringPref(prefBranch, PROXY_PREF("socks_username"), mSOCKSProxyUsername);
+
+    if (!pref || !strcmp(pref, PROXY_PREF("socks_password")))
+        proxy_GetStringPref(prefBranch, PROXY_PREF("socks_password"), mSOCKSProxyPassword);
+
     if (!pref || !strcmp(pref, PROXY_PREF("socks_version"))) {
         int32_t version;
         proxy_GetIntPref(prefBranch, PROXY_PREF("socks_version"), version);
@@ -1188,10 +1194,25 @@ nsProtocolProxyService::NewProxyInfo(const nsACString &aType,
     }
     NS_ENSURE_TRUE(type, NS_ERROR_INVALID_ARG);
 
-    if (aPort <= 0)
-        aPort = -1;
+    return NewProxyInfo_Internal(type, aHost, aPort,
+                                 mSOCKSProxyUsername, mSOCKSProxyPassword,
+                                 aFlags, aFailoverTimeout,
+                                 aFailoverProxy, 0, aResult);
+}
 
-    return NewProxyInfo_Internal(type, aHost, aPort, aFlags, aFailoverTimeout,
+NS_IMETHODIMP
+nsProtocolProxyService::NewSOCKSProxyInfo(const nsACString &aHost,
+                                          int32_t aPort,
+                                          const nsACString &aUsername,
+                                          const nsACString &aPassword,
+                                          uint32_t aFlags,
+                                          uint32_t aFailoverTimeout,
+                                          nsIProxyInfo *aFailoverProxy,
+                                          nsIProxyInfo **aResult)
+{
+    return NewProxyInfo_Internal(kProxyType_SOCKS, aHost, aPort,
+                                 aUsername, aPassword,
+                                 aFlags, aFailoverTimeout,
                                  aFailoverProxy, 0, aResult);
 }
 
@@ -1496,12 +1517,17 @@ nsresult
 nsProtocolProxyService::NewProxyInfo_Internal(const char *aType,
                                               const nsACString &aHost,
                                               int32_t aPort,
+                                              const nsACString &aUsername,
+                                              const nsACString &aPassword,
                                               uint32_t aFlags,
                                               uint32_t aFailoverTimeout,
                                               nsIProxyInfo *aFailoverProxy,
                                               uint32_t aResolveFlags,
                                               nsIProxyInfo **aResult)
 {
+    if (aPort <= 0)
+        aPort = -1;
+
     nsCOMPtr<nsProxyInfo> failover;
     if (aFailoverProxy) {
         failover = do_QueryInterface(aFailoverProxy);
@@ -1515,6 +1541,8 @@ nsProtocolProxyService::NewProxyInfo_Internal(const char *aType,
     proxyInfo->mType = aType;
     proxyInfo->mHost = aHost;
     proxyInfo->mPort = aPort;
+    proxyInfo->mUsername = aUsername;
+    proxyInfo->mPassword = aPassword;
     proxyInfo->mFlags = aFlags;
     proxyInfo->mResolveFlags = aResolveFlags;
     proxyInfo->mTimeout = aFailoverTimeout == UINT32_MAX
@@ -1680,8 +1708,9 @@ nsProtocolProxyService::Resolve_Internal(nsIChannel *channel,
     }
 
     if (type) {
-        rv = NewProxyInfo_Internal(type, *host, port, proxyFlags,
-                                   UINT32_MAX, nullptr, flags,
+        rv = NewProxyInfo_Internal(type, *host, port,
+                                   mSOCKSProxyUsername, mSOCKSProxyPassword,
+                                   proxyFlags, UINT32_MAX, nullptr, flags,
                                    result);
         if (NS_FAILED(rv))
             return rv;
diff --git a/netwerk/base/src/nsProtocolProxyService.h b/netwerk/base/src/nsProtocolProxyService.h
index 9ef68b9..04c642f 100644
--- a/netwerk/base/src/nsProtocolProxyService.h
+++ b/netwerk/base/src/nsProtocolProxyService.h
@@ -177,6 +177,10 @@ protected:
      *        The proxy host name (UTF-8 ok).
      * @param port
      *        The proxy port number.
+     * @param username
+     *        The username for the proxy (ASCII). May be "", but not null.
+     * @param password
+     *        The password for the proxy (ASCII). May be "", but not null.
      * @param flags
      *        The proxy flags (nsIProxyInfo::flags).
      * @param timeout
@@ -191,6 +195,8 @@ protected:
     NS_HIDDEN_(nsresult) NewProxyInfo_Internal(const char *type,
                                                const nsACString &host,
                                                int32_t port,
+                                               const nsACString &username,
+                                               const nsACString &password,
                                                uint32_t flags,
                                                uint32_t timeout,
                                                nsIProxyInfo *next,
@@ -374,6 +380,8 @@ protected:
     int32_t                      mSOCKSProxyPort;
     int32_t                      mSOCKSProxyVersion;
     bool                         mSOCKSProxyRemoteDNS;
+    nsCString                    mSOCKSProxyUsername;
+    nsCString                    mSOCKSProxyPassword;
 
     nsRefPtr<nsPACMan>           mPACMan;  // non-null if we are using PAC
     nsCOMPtr<nsISystemProxySettings> mSystemProxySettings;
diff --git a/netwerk/base/src/nsProxyInfo.cpp b/netwerk/base/src/nsProxyInfo.cpp
index 4e727c4..66a78a4 100644
--- a/netwerk/base/src/nsProxyInfo.cpp
+++ b/netwerk/base/src/nsProxyInfo.cpp
@@ -48,6 +48,20 @@ nsProxyInfo::GetResolveFlags(uint32_t *result)
 }
 
 NS_IMETHODIMP
+nsProxyInfo::GetUsername(nsACString &result)
+{
+  result = mUsername;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsProxyInfo::GetPassword(nsACString &result)
+{
+  result = mPassword;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
 nsProxyInfo::GetFailoverTimeout(uint32_t *result)
 {
   *result = mTimeout;
diff --git a/netwerk/base/src/nsProxyInfo.h b/netwerk/base/src/nsProxyInfo.h
index 550bbf2..5432d95 100644
--- a/netwerk/base/src/nsProxyInfo.h
+++ b/netwerk/base/src/nsProxyInfo.h
@@ -59,6 +59,8 @@ private:
 
   const char  *mType;  // pointer to statically allocated value
   nsCString    mHost;
+  nsCString    mUsername;
+  nsCString    mPassword;
   int32_t      mPort;
   uint32_t     mFlags;
   uint32_t     mResolveFlags;
diff --git a/netwerk/base/src/nsSocketTransport2.cpp b/netwerk/base/src/nsSocketTransport2.cpp
index e202044..ea0dd68 100644
--- a/netwerk/base/src/nsSocketTransport2.cpp
+++ b/netwerk/base/src/nsSocketTransport2.cpp
@@ -751,7 +751,8 @@ nsSocketTransport::nsSocketTransport()
     : mTypes(nullptr)
     , mTypeCount(0)
     , mPort(0)
-    , mProxyPort(0)
+    , mHttpsProxy(false)
+    , mProxyUse(false)
     , mProxyTransparent(false)
     , mProxyTransparentResolvesHost(false)
     , mConnectionFlags(0)
@@ -813,18 +814,25 @@ nsSocketTransport::Init(const char **types, uint32_t typeCount,
 
     const char *proxyType = nullptr;
     if (proxyInfo) {
-        mProxyPort = proxyInfo->Port();
-        mProxyHost = proxyInfo->Host();
+        mProxyInfo = proxyInfo;
         // grab proxy type (looking for "socks" for example)
         proxyType = proxyInfo->Type();
         if (proxyType && (strcmp(proxyType, "http") == 0 ||
                           strcmp(proxyType, "direct") == 0 ||
                           strcmp(proxyType, "unknown") == 0))
             proxyType = nullptr;
+
+        mProxyUse = true;
+        // check that we don't have a proxyInfo without proxy
+        nsCString proxyHost;
+        proxyInfo->GetHost(proxyHost);
+        if (!proxyType || proxyHost.IsEmpty()) {
+            mProxyUse = false;
+        }
     }
 
-    SOCKET_LOG(("nsSocketTransport::Init [this=%p host=%s:%hu proxy=%s:%hu]\n",
-        this, mHost.get(), mPort, mProxyHost.get(), mProxyPort));
+    SOCKET_LOG(("nsSocketTransport::Init [this=%x host=%s:%hu proxy=%s]\n",
+        this, mHost.get(), mPort, mProxyUse ? "yes" : "no"));
 
     // include proxy type as a socket type if proxy type is not "http"
     mTypeCount = typeCount + (proxyType != nullptr);
@@ -997,7 +1005,7 @@ nsSocketTransport::ResolveHost()
 
     nsresult rv;
 
-    if (!mProxyHost.IsEmpty()) {
+    if (mProxyUse) {
         if (!mProxyTransparent || mProxyTransparentResolvesHost) {
 #if defined(XP_UNIX)
             NS_ABORT_IF_FALSE(!mNetAddrIsSet || mNetAddr.raw.family != AF_LOCAL,
@@ -1079,9 +1087,8 @@ nsSocketTransport::BuildSocket(PRFileDesc *&fd, bool &proxyTransparent, bool &us
 
         const char *host       = mHost.get();
         int32_t     port       = (int32_t) mPort;
-        const char *proxyHost  = mProxyHost.IsEmpty() ? nullptr : mProxyHost.get();
-        int32_t     proxyPort  = (int32_t) mProxyPort;
         uint32_t    proxyFlags = 0;
+        nsCOMPtr<nsIProxyInfo> proxy = mProxyInfo;
 
         uint32_t i;
         for (i=0; i<mTypeCount; ++i) {
@@ -1102,12 +1109,19 @@ nsSocketTransport::BuildSocket(PRFileDesc *&fd, bool &proxyTransparent, bool &us
             if (mConnectionFlags & nsISocketTransport::NO_PERMANENT_STORAGE)
                 proxyFlags |= nsISocketProvider::NO_PERMANENT_STORAGE;
 
+
             nsCOMPtr<nsISupports> secinfo;
             if (i == 0) {
                 // if this is the first type, we'll want the 
                 // service to allocate a new socket
+                nsCString proxyHost;
+                GetHost(proxyHost);
+                int32_t proxyPort;
+                GetPort(&proxyPort);
                 rv = provider->NewSocket(mNetAddr.raw.family,
-                                         host, port, proxyHost, proxyPort,
+                                         mHttpsProxy ? proxyHost.get() : host,
+                                         mHttpsProxy ? proxyPort : port,
+                                         proxy,
                                          proxyFlags, &fd,
                                          getter_AddRefs(secinfo));
 
@@ -1121,7 +1135,7 @@ nsSocketTransport::BuildSocket(PRFileDesc *&fd, bool &proxyTransparent, bool &us
                 // 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, proxyHost, proxyPort,
+                                           host, port, proxy,
                                            proxyFlags, fd,
                                            getter_AddRefs(secinfo));
             }
@@ -1151,8 +1165,7 @@ nsSocketTransport::BuildSocket(PRFileDesc *&fd, bool &proxyTransparent, bool &us
                      (strcmp(mTypes[i], "socks4") == 0)) {
                 // since socks is transparent, any layers above
                 // it do not have to worry about proxy stuff
-                proxyHost = nullptr;
-                proxyPort = -1;
+                proxy = nullptr;
                 proxyTransparent = true;
             }
         }
@@ -1211,10 +1224,14 @@ nsSocketTransport::InitiateSocket()
                                  netAddrCString.BeginWriting(),
                                  kIPv6CStrBufSize))
                 netAddrCString = NS_LITERAL_CSTRING("<IP-to-string failed>");
+            nsCString proxyHost;
+            GetHost(proxyHost);
+            int32_t proxyPort;
+            GetPort(&proxyPort);
             SOCKET_LOG(("nsSocketTransport::InitiateSocket skipping "
                         "speculative connection for host [%s:%d] proxy "
                         "[%s:%d] with Local IP address [%s]",
-                        mHost.get(), mPort, mProxyHost.get(), mProxyPort,
+                        mHost.get(), mPort, proxyHost.get(), proxyPort,
                         netAddrCString.get()));
         }
 #endif
@@ -1363,7 +1380,7 @@ nsSocketTransport::InitiateSocket()
             //
             OnSocketConnected();
 
-            if (mSecInfo && !mProxyHost.IsEmpty() && proxyTransparent && usingSSL) {
+            if (mSecInfo && mProxyUse && proxyTransparent && usingSSL) {
                 // if the connection phase is finished, and the ssl layer has
                 // been pushed, and we were proxying (transparently; ie. nothing
                 // has to happen in the protocol layer above us), it's time for
@@ -1387,8 +1404,7 @@ nsSocketTransport::InitiateSocket()
         // the OS error
         //
         else if (PR_UNKNOWN_ERROR == code &&
-                 mProxyTransparent &&
-                 !mProxyHost.IsEmpty()) {
+                 mProxyUse && mProxyTransparent) {
             code = PR_GetOSError();
             rv = ErrorAccordingToNSPR(code);
         }
@@ -1397,7 +1413,7 @@ nsSocketTransport::InitiateSocket()
         //
         else {
             rv = ErrorAccordingToNSPR(code);
-            if ((rv == NS_ERROR_CONNECTION_REFUSED) && !mProxyHost.IsEmpty())
+            if (rv == NS_ERROR_CONNECTION_REFUSED && mProxyUse)
                 rv = NS_ERROR_PROXY_CONNECTION_REFUSED;
         }
     }
@@ -1709,8 +1725,8 @@ nsSocketTransport::OnSocketEvent(uint32_t type, nsresult status, nsISupports *pa
             // For SOCKS proxies (mProxyTransparent == true), the socket 
             // transport resolves the real host here, so there's no fixup 
             // (see bug 226943).
-            if ((status == NS_ERROR_UNKNOWN_HOST) && !mProxyTransparent &&
-                !mProxyHost.IsEmpty())
+            if (status == NS_ERROR_UNKNOWN_HOST && !mProxyTransparent &&
+                mProxyUse)
                 mCondition = NS_ERROR_UNKNOWN_PROXY_HOST;
             else
                 mCondition = status;
@@ -1835,8 +1851,7 @@ nsSocketTransport::OnSocketReady(PRFileDesc *fd, int16_t outFlags)
             // The SOCKS proxy rejected our request. Find out why.
             //
             else if (PR_UNKNOWN_ERROR == code &&
-                     mProxyTransparent &&
-                     !mProxyHost.IsEmpty()) {
+                     mProxyUse && mProxyTransparent) {
                 code = PR_GetOSError();
                 mCondition = ErrorAccordingToNSPR(code);
             }
@@ -1845,7 +1860,7 @@ nsSocketTransport::OnSocketReady(PRFileDesc *fd, int16_t outFlags)
                 // else, the connection failed...
                 //
                 mCondition = ErrorAccordingToNSPR(code);
-                if ((mCondition == NS_ERROR_CONNECTION_REFUSED) && !mProxyHost.IsEmpty())
+                if (mCondition == NS_ERROR_CONNECTION_REFUSED && mProxyUse)
                     mCondition = NS_ERROR_PROXY_CONNECTION_REFUSED;
                 SOCKET_LOG(("  connection failed! [reason=%x]\n", mCondition));
             }
@@ -2168,6 +2183,31 @@ nsSocketTransport::GetPort(int32_t *port)
     return NS_OK;
 }
 
+const nsCString &
+nsSocketTransport::SocketHost()
+{
+  if (mProxyInfo && !mProxyTransparent) {
+    if (mProxyHostCache.IsEmpty()) {
+      mProxyInfo->GetHost(mProxyHostCache);
+    }
+    return mProxyHostCache;
+  }
+  else
+    return mHost;
+}
+
+uint16_t
+nsSocketTransport::SocketPort()
+{
+  if (mProxyInfo && !mProxyTransparent) {
+    int32_t result;
+    mProxyInfo->GetPort(&result);
+    return (uint16_t) result;
+  }
+  else
+    return mPort;
+}
+
 NS_IMETHODIMP
 nsSocketTransport::GetPeerAddr(NetAddr *addr)
 {
diff --git a/netwerk/base/src/nsSocketTransport2.h b/netwerk/base/src/nsSocketTransport2.h
index 8d822bf..73f750e 100644
--- a/netwerk/base/src/nsSocketTransport2.h
+++ b/netwerk/base/src/nsSocketTransport2.h
@@ -266,15 +266,18 @@ private:
     char       **mTypes;
     uint32_t     mTypeCount;
     nsCString    mHost;
-    nsCString    mProxyHost;
     uint16_t     mPort;
-    uint16_t     mProxyPort;
-    bool mProxyTransparent;
-    bool mProxyTransparentResolvesHost;
+    bool         mHttpsProxy;
+
+    nsCOMPtr<nsIProxyInfo> mProxyInfo;
+    bool         mProxyUse;
+    bool         mProxyTransparent;
+    bool         mProxyTransparentResolvesHost;
     uint32_t     mConnectionFlags;
     
-    uint16_t         SocketPort() { return (!mProxyHost.IsEmpty() && !mProxyTransparent) ? mProxyPort : mPort; }
-    const nsCString &SocketHost() { return (!mProxyHost.IsEmpty() && !mProxyTransparent) ? mProxyHost : mHost; }
+    uint16_t         SocketPort();
+    const nsCString &SocketHost();
+    nsCString        mProxyHostCache; // for SocketHost() only
 
     //-------------------------------------------------------------------------
     // members accessible only on the socket transport thread:
diff --git a/netwerk/socket/nsISocketProvider.idl b/netwerk/socket/nsISocketProvider.idl
index 57f6c4d..0dd316c 100644
--- a/netwerk/socket/nsISocketProvider.idl
+++ b/netwerk/socket/nsISocketProvider.idl
@@ -5,12 +5,13 @@
 
 #include "nsISupports.idl"
 
+interface nsIProxyInfo;
 [ptr] native PRFileDescStar(struct PRFileDesc);
 
 /**
  * nsISocketProvider
  */
-[scriptable, uuid(00b3df92-e830-11d8-d48e-0004e22243f8)]
+[scriptable, uuid(508d5469-9e1e-4a08-b5b0-7cfebba1e51a)]
 interface nsISocketProvider : nsISupports
 {
     /**
@@ -38,8 +39,7 @@ interface nsISocketProvider : nsISupports
     void newSocket(in long            aFamily,
                    in string          aHost, 
                    in long            aPort,
-                   in string          aProxyHost,
-                   in long            aProxyPort,
+                   in nsIProxyInfo    aProxy,
                    in unsigned long   aFlags,
                    out PRFileDescStar aFileDesc, 
                    out nsISupports    aSecurityInfo);
@@ -58,8 +58,7 @@ interface nsISocketProvider : nsISupports
     void addToSocket(in long           aFamily,
                      in string         aHost, 
                      in long           aPort,
-                     in string         aProxyHost,
-                     in long           aProxyPort,
+                     in nsIProxyInfo   aProxy,
                      in unsigned long  aFlags,
                      in PRFileDescStar aFileDesc, 
                      out nsISupports   aSecurityInfo);
diff --git a/netwerk/socket/nsSOCKSIOLayer.cpp b/netwerk/socket/nsSOCKSIOLayer.cpp
index e03b94c..f3250b9 100644
--- a/netwerk/socket/nsSOCKSIOLayer.cpp
+++ b/netwerk/socket/nsSOCKSIOLayer.cpp
@@ -50,6 +50,8 @@ class nsSOCKSSocketInfo : public nsISOCKSSocketInfo
         SOCKS4_READ_CONNECT_RESPONSE,
         SOCKS5_WRITE_AUTH_REQUEST,
         SOCKS5_READ_AUTH_RESPONSE,
+        SOCKS5_WRITE_USERNAME_REQUEST,
+        SOCKS5_READ_USERNAME_RESPONSE,
         SOCKS5_WRITE_CONNECT_REQUEST,
         SOCKS5_READ_CONNECT_RESPONSE_TOP,
         SOCKS5_READ_CONNECT_RESPONSE_BOTTOM,
@@ -57,10 +59,12 @@ class nsSOCKSSocketInfo : public nsISOCKSSocketInfo
         SOCKS_FAILED
     };
 
-    // A buffer of 262 bytes should be enough for any request and response
+    // A buffer of 520 bytes should be enough for any request and response
     // in case of SOCKS4 as well as SOCKS5
-    static const uint32_t BUFFER_SIZE = 262;
+    static const uint32_t BUFFER_SIZE = 520;
     static const uint32_t MAX_HOSTNAME_LEN = 255;
+    static const uint32_t MAX_USERNAME_LEN = 255;
+    static const uint32_t MAX_PASSWORD_LEN = 255;
 
 public:
     nsSOCKSSocketInfo();
@@ -72,8 +76,7 @@ public:
 
     void Init(int32_t version,
               int32_t family,
-              const char *proxyHost,
-              int32_t proxyPort,
+              nsIProxyInfo *proxy,
               const char *destinationHost,
               uint32_t flags);
 
@@ -95,6 +98,8 @@ private:
     PRStatus ReadV4ConnectResponse();
     PRStatus WriteV5AuthRequest();
     PRStatus ReadV5AuthResponse();
+    PRStatus WriteV5UsernameRequest();
+    PRStatus ReadV5UsernameResponse();
     PRStatus WriteV5ConnectRequest();
     PRStatus ReadV5AddrTypeAndLength(uint8_t *type, uint32_t *len);
     PRStatus ReadV5ConnectResponseTop();
@@ -130,8 +135,7 @@ private:
     PRFileDesc             *mFD;
 
     nsCString mDestinationHost;
-    nsCString mProxyHost;
-    int32_t   mProxyPort;
+    nsCOMPtr<nsIProxyInfo> mProxy;
     int32_t   mVersion;   // SOCKS version 4 or 5
     int32_t   mDestinationFamily;
     uint32_t  mFlags;
@@ -139,6 +143,7 @@ private:
     NetAddr   mExternalProxyAddr;
     NetAddr   mDestinationAddr;
     PRIntervalTime mTimeout;
+    nsCString mProxyUsername; // Cache, from mProxy
 };
 
 nsSOCKSSocketInfo::nsSOCKSSocketInfo()
@@ -147,7 +152,6 @@ nsSOCKSSocketInfo::nsSOCKSSocketInfo()
     , mDataLength(0)
     , mReadOffset(0)
     , mAmountToRead(0)
-    , mProxyPort(-1)
     , mVersion(-1)
     , mDestinationFamily(AF_INET)
     , mFlags(0)
@@ -169,14 +173,14 @@ nsSOCKSSocketInfo::nsSOCKSSocketInfo()
 }
 
 void
-nsSOCKSSocketInfo::Init(int32_t version, int32_t family, const char *proxyHost, int32_t proxyPort, const char *host, uint32_t flags)
+nsSOCKSSocketInfo::Init(int32_t version, int32_t family, nsIProxyInfo *proxy, const char *host, uint32_t flags)
 {
     mVersion         = version;
     mDestinationFamily = family;
-    mProxyHost       = proxyHost;
-    mProxyPort       = proxyPort;
+    mProxy           = proxy;
     mDestinationHost = host;
     mFlags           = flags;
+    mProxy->GetUsername(mProxyUsername); // cache
 }
 
 NS_IMPL_ISUPPORTS(nsSOCKSSocketInfo, nsISOCKSSocketInfo, nsIDNSListener)
@@ -263,14 +267,17 @@ nsSOCKSSocketInfo::StartDNS(PRFileDesc *fd)
     if (!dns)
         return PR_FAILURE;
 
+    nsCString proxyHost;
+    mProxy->GetHost(proxyHost);
+
     mFD  = fd;
-    nsresult rv = dns->AsyncResolve(mProxyHost, 0, this,
+    nsresult rv = dns->AsyncResolve(proxyHost, 0, this,
                                     NS_GetCurrentThread(),
                                     getter_AddRefs(mLookup));
 
     if (NS_FAILED(rv)) {
         LOGERROR(("socks: DNS lookup for SOCKS proxy %s failed",
-                  mProxyHost.get()));
+                  proxyHost.get()));
         return PR_FAILURE;
     }
     mState = SOCKS_DNS_IN_PROGRESS;
@@ -315,16 +322,21 @@ nsSOCKSSocketInfo::ConnectToProxy(PRFileDesc *fd)
         mVersion = 5;
     }
 
+    int32_t proxyPort;
+    mProxy->GetPort(&proxyPort);
+
     int32_t addresses = 0;
     do {
         if (addresses++)
-            mDnsRec->ReportUnusable(mProxyPort);
+            mDnsRec->ReportUnusable(proxyPort);
         
-        rv = mDnsRec->GetNextAddr(mProxyPort, &mInternalProxyAddr);
+        rv = mDnsRec->GetNextAddr(proxyPort, &mInternalProxyAddr);
         // No more addresses to try? If so, we'll need to bail
         if (NS_FAILED(rv)) {
+            nsCString proxyHost;
+            mProxy->GetHost(proxyHost);
             LOGERROR(("socks: unable to connect to SOCKS proxy, %s",
-                     mProxyHost.get()));
+                     proxyHost.get()));
             return PR_FAILURE;
         }
 
@@ -440,6 +452,12 @@ nsSOCKSSocketInfo::ContinueConnectingToProxy(PRFileDesc *fd, int16_t oflags)
 PRStatus
 nsSOCKSSocketInfo::WriteV4ConnectRequest()
 {
+    if (mProxyUsername.Length() > MAX_USERNAME_LEN) {
+        LOGERROR(("socks username is too long"));
+        HandshakeFinished(PR_UNKNOWN_ERROR);
+        return PR_FAILURE;
+    }
+
     NetAddr *addr = &mDestinationAddr;
     int32_t proxy_resolve;
 
@@ -465,7 +483,9 @@ nsSOCKSSocketInfo::WriteV4ConnectRequest()
         // than 0, is used to notify the proxy that this is a SOCKS 4a
         // request. This request type works for Tor and perhaps others.
         WriteUint32(htonl(0x00000001)); // Fake IP
-        WriteUint8(0x00); // Send an emtpy username
+        WriteString(mProxyUsername); // Send username. May be empty.
+        WriteUint8(0x00); // Null-terminate username
+        // Password not supported by V4.
         if (mDestinationHost.Length() > MAX_HOSTNAME_LEN) {
             LOGERROR(("socks4: destination host name is too long!"));
             HandshakeFinished(PR_BAD_ADDRESS_ERROR);
@@ -475,7 +495,9 @@ nsSOCKSSocketInfo::WriteV4ConnectRequest()
         WriteUint8(0x00);
     } else if (addr->raw.family == AF_INET) {
         WriteNetAddr(addr); // Add the IPv4 address
-        WriteUint8(0x00); // Send an emtpy username
+        WriteString(mProxyUsername); // Send username. May be empty.
+        WriteUint8(0x00); // Null-terminate username
+        // Password not supported by V4.
     } else if (addr->raw.family == AF_INET6) {
         LOGERROR(("socks: SOCKS 4 can't handle IPv6 addresses!"));
         HandshakeFinished(PR_BAD_ADDRESS_ERROR);
@@ -490,11 +512,15 @@ nsSOCKSSocketInfo::ReadV4ConnectResponse()
 {
     NS_ABORT_IF_FALSE(mState == SOCKS4_READ_CONNECT_RESPONSE,
                       "Handling SOCKS 4 connection reply in wrong state!");
-    NS_ABORT_IF_FALSE(mDataLength == 8,
-                      "SOCKS 4 connection reply must be 8 bytes!");
 
     LOGDEBUG(("socks4: checking connection reply"));
 
+    if (mDataLength != 8) {
+        LOGERROR(("SOCKS 4 connection reply must be 8 bytes!"));
+        HandshakeFinished(PR_CONNECT_REFUSED_ERROR);
+        return PR_FAILURE;
+    }
+
     if (ReadUint8() != 0x00) {
         LOGERROR(("socks4: wrong connection reply"));
         HandshakeFinished(PR_CONNECT_REFUSED_ERROR);
@@ -518,13 +544,18 @@ nsSOCKSSocketInfo::WriteV5AuthRequest()
 {
     NS_ABORT_IF_FALSE(mVersion == 5, "SOCKS version must be 5!");
 
+    mDataLength = 0;
     mState = SOCKS5_WRITE_AUTH_REQUEST;
 
     // Send an initial SOCKS 5 greeting
     LOGDEBUG(("socks5: sending auth methods"));
     WriteUint8(0x05); // version -- 5
-    WriteUint8(0x01); // # auth methods -- 1
-    WriteUint8(0x00); // we don't support authentication
+    WriteUint8(0x01); // # of auth methods -- 1
+    if (mProxyUsername.IsEmpty()) {
+      WriteUint8(0x00); // no authentication
+    } else {
+      WriteUint8(0x02); // username/password
+    }
 
     return PR_SUCCESS;
 }
@@ -534,10 +565,12 @@ nsSOCKSSocketInfo::ReadV5AuthResponse()
 {
     NS_ABORT_IF_FALSE(mState == SOCKS5_READ_AUTH_RESPONSE,
                       "Handling SOCKS 5 auth method reply in wrong state!");
-    NS_ABORT_IF_FALSE(mDataLength == 2,
-                      "SOCKS 5 auth method reply must be 2 bytes!");
 
-    LOGDEBUG(("socks5: checking auth method reply"));
+    if (mDataLength != 2) {
+        LOGERROR(("SOCKS 5 auth method reply must be 2 bytes"));
+        HandshakeFinished(PR_CONNECT_REFUSED_ERROR);
+        return PR_FAILURE;
+    }
 
     // Check version number
     if (ReadUint8() != 0x05) {
@@ -546,12 +579,82 @@ nsSOCKSSocketInfo::ReadV5AuthResponse()
         return PR_FAILURE;
     }
 
-    // Make sure our authentication choice was accepted
-    if (ReadUint8() != 0x00) {
+    // Make sure our authentication choice was accepted,
+    // and continue accordingly
+    uint8_t authMethod = ReadUint8();
+    if (mProxyUsername.IsEmpty() && authMethod == 0x00) { // no auth
+        LOGDEBUG(("socks5: server allows connection without authentication"));
+        return WriteV5ConnectRequest();
+    } else if (!mProxyUsername.IsEmpty() && authMethod == 0x02) { // username/pw
+        LOGDEBUG(("socks5: auth method accepted by server"));
+        return WriteV5UsernameRequest();
+    } else { // 0xFF signals error
         LOGERROR(("socks5: server did not accept our authentication method"));
         HandshakeFinished(PR_CONNECT_REFUSED_ERROR);
         return PR_FAILURE;
     }
+}
+
+PRStatus
+nsSOCKSSocketInfo::WriteV5UsernameRequest()
+{
+    NS_ABORT_IF_FALSE(mVersion == 5, "SOCKS version must be 5!");
+
+    if (mProxyUsername.Length() > MAX_USERNAME_LEN) {
+        LOGERROR(("socks username is too long"));
+        HandshakeFinished(PR_UNKNOWN_ERROR);
+        return PR_FAILURE;
+    }
+
+    nsCString password;
+    mProxy->GetPassword(password);
+    if (password.Length() > MAX_PASSWORD_LEN) {
+        LOGERROR(("socks password is too long"));
+        HandshakeFinished(PR_UNKNOWN_ERROR);
+        return PR_FAILURE;
+    }
+
+    mDataLength = 0;
+    mState = SOCKS5_WRITE_USERNAME_REQUEST;
+
+    LOGDEBUG(("socks5: sending username and password"));
+    // RFC 1929 Username/password auth for SOCKS 5
+    WriteUint8(0x01); // version 1 (not 5)
+    WriteUint8(mProxyUsername.Length()); // username length
+    WriteString(mProxyUsername); // username
+    WriteUint8(password.Length()); // password length
+    WriteString(password); // password. WARNING: Sent unencrypted!
+
+    return PR_SUCCESS;
+}
+
+PRStatus
+nsSOCKSSocketInfo::ReadV5UsernameResponse()
+{
+    NS_ABORT_IF_FALSE(mState == SOCKS5_READ_USERNAME_RESPONSE,
+                      "Handling SOCKS 5 username/password reply in wrong state!");
+
+    if (mDataLength != 2) {
+        LOGERROR(("SOCKS 5 username reply must be 2 bytes"));
+        HandshakeFinished(PR_CONNECT_REFUSED_ERROR);
+        return PR_FAILURE;
+    }
+
+    // Check version number, must be 1 (not 5)
+    if (ReadUint8() != 0x01) {
+        LOGERROR(("socks5: unexpected version in the reply"));
+        HandshakeFinished(PR_CONNECT_REFUSED_ERROR);
+        return PR_FAILURE;
+    }
+
+    // Check whether username/password were accepted
+    if (ReadUint8() != 0x00) { // 0 = success
+        LOGERROR(("socks5: username/password not accepted"));
+        HandshakeFinished(PR_CONNECT_REFUSED_ERROR);
+        return PR_FAILURE;
+    }
+
+    LOGDEBUG(("socks5: username/password accepted by server"));
 
     return WriteV5ConnectRequest();
 }
@@ -795,6 +898,16 @@ nsSOCKSSocketInfo::DoHandshake(PRFileDesc *fd, int16_t oflags)
             if (ReadFromSocket(fd) != PR_SUCCESS)
                 return PR_FAILURE;
             return ReadV5AuthResponse();
+        case SOCKS5_WRITE_USERNAME_REQUEST:
+            if (WriteToSocket(fd) != PR_SUCCESS)
+                return PR_FAILURE;
+            WantRead(2);
+            mState = SOCKS5_READ_USERNAME_RESPONSE;
+            return PR_SUCCESS;
+        case SOCKS5_READ_USERNAME_RESPONSE:
+            if (ReadFromSocket(fd) != PR_SUCCESS)
+                return PR_FAILURE;
+            return ReadV5UsernameResponse();
         case SOCKS5_WRITE_CONNECT_REQUEST:
             if (WriteToSocket(fd) != PR_SUCCESS)
                 return PR_FAILURE;
@@ -839,10 +952,12 @@ nsSOCKSSocketInfo::GetPollFlags() const
             return PR_POLL_EXCEPT | PR_POLL_WRITE;
         case SOCKS4_WRITE_CONNECT_REQUEST:
         case SOCKS5_WRITE_AUTH_REQUEST:
+        case SOCKS5_WRITE_USERNAME_REQUEST:
         case SOCKS5_WRITE_CONNECT_REQUEST:
             return PR_POLL_WRITE;
         case SOCKS4_READ_CONNECT_RESPONSE:
         case SOCKS5_READ_AUTH_RESPONSE:
+        case SOCKS5_READ_USERNAME_RESPONSE:
         case SOCKS5_READ_CONNECT_RESPONSE_TOP:
         case SOCKS5_READ_CONNECT_RESPONSE_BOTTOM:
             return PR_POLL_READ;
@@ -856,7 +971,7 @@ nsSOCKSSocketInfo::GetPollFlags() const
 inline void
 nsSOCKSSocketInfo::WriteUint8(uint8_t v)
 {
-    NS_ABORT_IF_FALSE(mDataLength + sizeof(v) <= BUFFER_SIZE,
+    MOZ_RELEASE_ASSERT(mDataLength + sizeof(v) <= BUFFER_SIZE,
                       "Can't write that much data!");
     mData[mDataLength] = v;
     mDataLength += sizeof(v);
@@ -865,7 +980,7 @@ nsSOCKSSocketInfo::WriteUint8(uint8_t v)
 inline void
 nsSOCKSSocketInfo::WriteUint16(uint16_t v)
 {
-    NS_ABORT_IF_FALSE(mDataLength + sizeof(v) <= BUFFER_SIZE,
+    MOZ_RELEASE_ASSERT(mDataLength + sizeof(v) <= BUFFER_SIZE,
                       "Can't write that much data!");
     memcpy(mData + mDataLength, &v, sizeof(v));
     mDataLength += sizeof(v);
@@ -874,7 +989,7 @@ nsSOCKSSocketInfo::WriteUint16(uint16_t v)
 inline void
 nsSOCKSSocketInfo::WriteUint32(uint32_t v)
 {
-    NS_ABORT_IF_FALSE(mDataLength + sizeof(v) <= BUFFER_SIZE,
+    MOZ_RELEASE_ASSERT(mDataLength + sizeof(v) <= BUFFER_SIZE,
                       "Can't write that much data!");
     memcpy(mData + mDataLength, &v, sizeof(v));
     mDataLength += sizeof(v);
@@ -894,8 +1009,8 @@ nsSOCKSSocketInfo::WriteNetAddr(const NetAddr *addr)
         len = sizeof(addr->inet6.ip.u8);
     }
 
-    NS_ABORT_IF_FALSE(ip != nullptr, "Unknown address");
-    NS_ABORT_IF_FALSE(mDataLength + len <= BUFFER_SIZE,
+    MOZ_RELEASE_ASSERT(ip != nullptr, "Unknown address");
+    MOZ_RELEASE_ASSERT(mDataLength + len <= BUFFER_SIZE,
                       "Can't write that much data!");
  
     memcpy(mData + mDataLength, ip, len);
@@ -911,7 +1026,7 @@ nsSOCKSSocketInfo::WriteNetPort(const NetAddr *addr)
 void
 nsSOCKSSocketInfo::WriteString(const nsACString &str)
 {
-    NS_ABORT_IF_FALSE(mDataLength + str.Length() <= BUFFER_SIZE,
+    MOZ_RELEASE_ASSERT(mDataLength + str.Length() <= BUFFER_SIZE,
                       "Can't write that much data!");
     memcpy(mData + mDataLength, str.Data(), str.Length());
     mDataLength += str.Length();
@@ -921,7 +1036,7 @@ inline uint8_t
 nsSOCKSSocketInfo::ReadUint8()
 {
     uint8_t rv;
-    NS_ABORT_IF_FALSE(mReadOffset + sizeof(rv) <= mDataLength,
+    MOZ_RELEASE_ASSERT(mReadOffset + sizeof(rv) <= mDataLength,
                       "Not enough space to pop a uint8_t!");
     rv = mData[mReadOffset];
     mReadOffset += sizeof(rv);
@@ -932,7 +1047,7 @@ inline uint16_t
 nsSOCKSSocketInfo::ReadUint16()
 {
     uint16_t rv;
-    NS_ABORT_IF_FALSE(mReadOffset + sizeof(rv) <= mDataLength,
+    MOZ_RELEASE_ASSERT(mReadOffset + sizeof(rv) <= mDataLength,
                       "Not enough space to pop a uint16_t!");
     memcpy(&rv, mData + mReadOffset, sizeof(rv));
     mReadOffset += sizeof(rv);
@@ -943,7 +1058,7 @@ inline uint32_t
 nsSOCKSSocketInfo::ReadUint32()
 {
     uint32_t rv;
-    NS_ABORT_IF_FALSE(mReadOffset + sizeof(rv) <= mDataLength,
+    MOZ_RELEASE_ASSERT(mReadOffset + sizeof(rv) <= mDataLength,
                       "Not enough space to pop a uint32_t!");
     memcpy(&rv, mData + mReadOffset, sizeof(rv));
     mReadOffset += sizeof(rv);
@@ -959,12 +1074,12 @@ nsSOCKSSocketInfo::ReadNetAddr(NetAddr *addr, uint16_t fam)
     addr->raw.family = fam;
     if (fam == AF_INET) {
         amt = sizeof(addr->inet.ip);
-        NS_ABORT_IF_FALSE(mReadOffset + amt <= mDataLength,
+        MOZ_RELEASE_ASSERT(mReadOffset + amt <= mDataLength,
                           "Not enough space to pop an ipv4 addr!");
         memcpy(&addr->inet.ip, ip, amt);
     } else if (fam == AF_INET6) {
         amt = sizeof(addr->inet6.ip.u8);
-        NS_ABORT_IF_FALSE(mReadOffset + amt <= mDataLength,
+        MOZ_RELEASE_ASSERT(mReadOffset + amt <= mDataLength,
                           "Not enough space to pop an ipv6 addr!");
         memcpy(addr->inet6.ip.u8, ip, amt);
     }
@@ -983,7 +1098,7 @@ nsSOCKSSocketInfo::WantRead(uint32_t sz)
 {
     NS_ABORT_IF_FALSE(mDataIoPtr == nullptr,
                       "WantRead() called while I/O already in progress!");
-    NS_ABORT_IF_FALSE(mDataLength + sz <= BUFFER_SIZE,
+    MOZ_RELEASE_ASSERT(mDataLength + sz <= BUFFER_SIZE,
                       "Can't read that much data!");
     mAmountToRead = sz;
 }
@@ -1221,8 +1336,7 @@ nsresult
 nsSOCKSIOLayerAddToSocket(int32_t family,
                           const char *host, 
                           int32_t port,
-                          const char *proxyHost,
-                          int32_t proxyPort,
+                          nsIProxyInfo *proxy,
                           int32_t socksVersion,
                           uint32_t flags,
                           PRFileDesc *fd, 
@@ -1289,7 +1403,7 @@ nsSOCKSIOLayerAddToSocket(int32_t family,
     }
 
     NS_ADDREF(infoObject);
-    infoObject->Init(socksVersion, family, proxyHost, proxyPort, host, flags);
+    infoObject->Init(socksVersion, family, proxy, host, flags);
     layer->secret = (PRFilePrivate*) infoObject;
     rv = PR_PushIOLayer(fd, PR_GetLayersIdentity(fd), layer);
 
diff --git a/netwerk/socket/nsSOCKSIOLayer.h b/netwerk/socket/nsSOCKSIOLayer.h
index dfe7c0c..54d936e 100644
--- a/netwerk/socket/nsSOCKSIOLayer.h
+++ b/netwerk/socket/nsSOCKSIOLayer.h
@@ -9,12 +9,12 @@
 
 #include "prio.h"
 #include "nscore.h"
+#include "nsIProxyInfo.h"
 
 nsresult nsSOCKSIOLayerAddToSocket(int32_t       family,
                                    const char   *host, 
                                    int32_t       port,
-                                   const char   *proxyHost,
-                                   int32_t       proxyPort,
+                                   nsIProxyInfo *proxyInfo,
                                    int32_t       socksVersion,
                                    uint32_t      flags,
                                    PRFileDesc   *fd, 
diff --git a/netwerk/socket/nsSOCKSSocketProvider.cpp b/netwerk/socket/nsSOCKSSocketProvider.cpp
index af7c9b5..c5a5655 100644
--- a/netwerk/socket/nsSOCKSSocketProvider.cpp
+++ b/netwerk/socket/nsSOCKSSocketProvider.cpp
@@ -44,8 +44,7 @@ NS_IMETHODIMP
 nsSOCKSSocketProvider::NewSocket(int32_t family,
                                  const char *host, 
                                  int32_t port,
-                                 const char *proxyHost,
-                                 int32_t proxyPort,
+                                 nsIProxyInfo *proxy,
                                  uint32_t flags,
                                  PRFileDesc **result,
                                  nsISupports **socksInfo)
@@ -59,8 +58,7 @@ nsSOCKSSocketProvider::NewSocket(int32_t family,
     nsresult rv = nsSOCKSIOLayerAddToSocket(family,
                                             host, 
                                             port,
-                                            proxyHost,
-                                            proxyPort,
+                                            proxy,
                                             mVersion,
                                             flags,
                                             sock, 
@@ -77,8 +75,7 @@ NS_IMETHODIMP
 nsSOCKSSocketProvider::AddToSocket(int32_t family,
                                    const char *host,
                                    int32_t port,
-                                   const char *proxyHost,
-                                   int32_t proxyPort,
+                                   nsIProxyInfo *proxy,
                                    uint32_t flags,
                                    PRFileDesc *sock,
                                    nsISupports **socksInfo)
@@ -86,8 +83,7 @@ nsSOCKSSocketProvider::AddToSocket(int32_t family,
     nsresult rv = nsSOCKSIOLayerAddToSocket(family,
                                             host, 
                                             port,
-                                            proxyHost,
-                                            proxyPort,
+                                            proxy,
                                             mVersion,
                                             flags,
                                             sock, 
diff --git a/netwerk/socket/nsUDPSocketProvider.cpp b/netwerk/socket/nsUDPSocketProvider.cpp
index 4ca7b29..f03b624 100644
--- a/netwerk/socket/nsUDPSocketProvider.cpp
+++ b/netwerk/socket/nsUDPSocketProvider.cpp
@@ -16,8 +16,7 @@ NS_IMETHODIMP
 nsUDPSocketProvider::NewSocket(int32_t aFamily,
                                const char *aHost, 
                                int32_t aPort, 
-                               const char *aProxyHost, 
-                               int32_t aProxyPort,
+                               nsIProxyInfo *aProxy,
                                uint32_t aFlags,
                                PRFileDesc * *aFileDesc, 
                                nsISupports **aSecurityInfo)
@@ -36,8 +35,7 @@ NS_IMETHODIMP
 nsUDPSocketProvider::AddToSocket(int32_t aFamily,
                                  const char *aHost,
                                  int32_t aPort,
-                                 const char *aProxyHost,
-                                 int32_t aProxyPort,
+                                 nsIProxyInfo *aProxy,
                                  uint32_t aFlags,
                                  struct PRFileDesc * aFileDesc,
                                  nsISupports **aSecurityInfo)
diff --git a/security/manager/ssl/src/nsNSSIOLayer.cpp b/security/manager/ssl/src/nsNSSIOLayer.cpp
index 43bb013..a71f265 100644
--- a/security/manager/ssl/src/nsNSSIOLayer.cpp
+++ b/security/manager/ssl/src/nsNSSIOLayer.cpp
@@ -1598,8 +1598,7 @@ nsresult
 nsSSLIOLayerNewSocket(int32_t family,
                       const char* host,
                       int32_t port,
-                      const char* proxyHost,
-                      int32_t proxyPort,
+                      nsIProxyInfo *proxy,
                       PRFileDesc** fd,
                       nsISupports** info,
                       bool forSTARTTLS,
@@ -1609,7 +1608,7 @@ nsSSLIOLayerNewSocket(int32_t family,
   PRFileDesc* sock = PR_OpenTCPSocket(family);
   if (!sock) return NS_ERROR_OUT_OF_MEMORY;
 
-  nsresult rv = nsSSLIOLayerAddToSocket(family, host, port, proxyHost, proxyPort,
+  nsresult rv = nsSSLIOLayerAddToSocket(family, host, port, proxy,
                                         sock, info, forSTARTTLS, flags);
   if (NS_FAILED(rv)) {
     PR_Close(sock);
@@ -2274,11 +2273,11 @@ loser:
 
 static nsresult
 nsSSLIOLayerSetOptions(PRFileDesc* fd, bool forSTARTTLS,
-                       const char* proxyHost, const char* host, int32_t port,
+                       bool haveProxy, const char* host, int32_t port,
                        nsNSSSocketInfo* infoObject)
 {
   nsNSSShutDownPreventionLock locker;
-  if (forSTARTTLS || proxyHost) {
+  if (forSTARTTLS || haveProxy) {
     if (SECSuccess != SSL_OptionSet(fd, SSL_SECURITY, false)) {
       return NS_ERROR_FAILURE;
     }
@@ -2350,8 +2349,7 @@ nsresult
 nsSSLIOLayerAddToSocket(int32_t family,
                         const char* host,
                         int32_t port,
-                        const char* proxyHost,
-                        int32_t proxyPort,
+                        nsIProxyInfo* proxy,
                         PRFileDesc* fd,
                         nsISupports** info,
                         bool forSTARTTLS,
@@ -2373,6 +2371,13 @@ nsSSLIOLayerAddToSocket(int32_t family,
   infoObject->SetHostName(host);
   infoObject->SetPort(port);
 
+  bool haveProxy = false;
+  if (proxy) {
+    nsCString proxyHost;
+    proxy->GetHost(proxyHost);
+    haveProxy = !proxyHost.IsEmpty();
+  }
+
   // A plaintext observer shim is inserted so we can observe some protocol
   // details without modifying nss
   plaintextLayer = PR_CreateIOLayerStub(nsSSLIOLayerHelpers::nsSSLPlaintextLayerIdentity,
@@ -2394,7 +2399,7 @@ nsSSLIOLayerAddToSocket(int32_t family,
 
   infoObject->SetFileDescPtr(sslSock);
 
-  rv = nsSSLIOLayerSetOptions(sslSock, forSTARTTLS, proxyHost, host, port,
+  rv = nsSSLIOLayerSetOptions(sslSock, forSTARTTLS, haveProxy, host, port,
                               infoObject);
 
   if (NS_FAILED(rv))
@@ -2419,7 +2424,7 @@ nsSSLIOLayerAddToSocket(int32_t family,
   infoObject->QueryInterface(NS_GET_IID(nsISupports), (void**) (info));
 
   // We are going use a clear connection first //
-  if (forSTARTTLS || proxyHost) {
+  if (forSTARTTLS || haveProxy) {
     infoObject->SetHandshakeNotPending();
   }
 
diff --git a/security/manager/ssl/src/nsNSSIOLayer.h b/security/manager/ssl/src/nsNSSIOLayer.h
index fca0ce8..6ba745d 100644
--- a/security/manager/ssl/src/nsNSSIOLayer.h
+++ b/security/manager/ssl/src/nsNSSIOLayer.h
@@ -10,6 +10,7 @@
 #include "TransportSecurityInfo.h"
 #include "nsISSLSocketControl.h"
 #include "nsIClientAuthDialogs.h"
+#include "nsIProxyInfo.h"
 #include "nsNSSCertificate.h"
 #include "nsDataHashtable.h"
 #include "nsTHashtable.h"
@@ -202,8 +203,7 @@ private:
 nsresult nsSSLIOLayerNewSocket(int32_t family,
                                const char* host,
                                int32_t port,
-                               const char* proxyHost,
-                               int32_t proxyPort,
+                               nsIProxyInfo *proxy,
                                PRFileDesc** fd,
                                nsISupports** securityInfo,
                                bool forSTARTTLS,
@@ -212,8 +212,7 @@ nsresult nsSSLIOLayerNewSocket(int32_t family,
 nsresult nsSSLIOLayerAddToSocket(int32_t family,
                                  const char* host,
                                  int32_t port,
-                                 const char* proxyHost,
-                                 int32_t proxyPort,
+                                 nsIProxyInfo *proxy,
                                  PRFileDesc* fd,
                                  nsISupports** securityInfo,
                                  bool forSTARTTLS,
diff --git a/security/manager/ssl/src/nsSSLSocketProvider.cpp b/security/manager/ssl/src/nsSSLSocketProvider.cpp
index fd37f4c..0666082 100644
--- a/security/manager/ssl/src/nsSSLSocketProvider.cpp
+++ b/security/manager/ssl/src/nsSSLSocketProvider.cpp
@@ -22,8 +22,7 @@ NS_IMETHODIMP
 nsSSLSocketProvider::NewSocket(int32_t family,
                                const char *host,
                                int32_t port,
-                               const char *proxyHost,
-                               int32_t proxyPort,
+                               nsIProxyInfo *proxy,
                                uint32_t flags,
                                PRFileDesc **_result,
                                nsISupports **securityInfo)
@@ -31,8 +30,7 @@ nsSSLSocketProvider::NewSocket(int32_t family,
   nsresult rv = nsSSLIOLayerNewSocket(family,
                                       host,
                                       port,
-                                      proxyHost,
-                                      proxyPort,
+                                      proxy,
                                       _result,
                                       securityInfo,
                                       false,
@@ -45,8 +43,7 @@ NS_IMETHODIMP
 nsSSLSocketProvider::AddToSocket(int32_t family,
                                  const char *host,
                                  int32_t port,
-                                 const char *proxyHost,
-                                 int32_t proxyPort,
+                                 nsIProxyInfo *proxy,
                                  uint32_t flags,
                                  PRFileDesc *aSocket,
                                  nsISupports **securityInfo)
@@ -54,8 +51,7 @@ nsSSLSocketProvider::AddToSocket(int32_t family,
   nsresult rv = nsSSLIOLayerAddToSocket(family,
                                         host,
                                         port,
-                                        proxyHost,
-                                        proxyPort,
+                                        proxy,
                                         aSocket,
                                         securityInfo,
                                         false,
diff --git a/security/manager/ssl/src/nsTLSSocketProvider.cpp b/security/manager/ssl/src/nsTLSSocketProvider.cpp
index 029b2c5..09dd2bd 100644
--- a/security/manager/ssl/src/nsTLSSocketProvider.cpp
+++ b/security/manager/ssl/src/nsTLSSocketProvider.cpp
@@ -22,8 +22,7 @@ NS_IMETHODIMP
 nsTLSSocketProvider::NewSocket(int32_t family,
                                const char *host,
                                int32_t port,
-                               const char *proxyHost,
-                               int32_t proxyPort,
+                               nsIProxyInfo *proxy,
                                uint32_t flags,
                                PRFileDesc **_result,
                                nsISupports **securityInfo)
@@ -31,8 +30,7 @@ nsTLSSocketProvider::NewSocket(int32_t family,
   nsresult rv = nsSSLIOLayerNewSocket(family,
                                       host,
                                       port,
-                                      proxyHost,
-                                      proxyPort,
+                                      proxy,
                                       _result,
                                       securityInfo,
                                       true,
@@ -46,8 +44,7 @@ NS_IMETHODIMP
 nsTLSSocketProvider::AddToSocket(int32_t family,
                                  const char *host,
                                  int32_t port,
-                                 const char *proxyHost,
-                                 int32_t proxyPort,
+                                 nsIProxyInfo *proxy,
                                  uint32_t flags,
                                  PRFileDesc *aSocket,
                                  nsISupports **securityInfo)
@@ -55,8 +52,7 @@ nsTLSSocketProvider::AddToSocket(int32_t family,
   nsresult rv = nsSSLIOLayerAddToSocket(family,
                                         host,
                                         port,
-                                        proxyHost,
-                                        proxyPort,
+                                        proxy,
                                         aSocket,
                                         securityInfo,
                                         true,





More information about the tor-commits mailing list