Ticket #6733: socks-username-6733-proxyInfo-9.diff

File socks-username-6733-proxyInfo-9.diff, 41.3 KB (added by ben, 6 years ago)

Updated to Firefox 24; 1 bug fixed

  • netwerk/base/public/nsIProxiedChannel.idl

    diff --git a/netwerk/base/public/nsIProxiedChannel.idl b/netwerk/base/public/nsIProxiedChannel.idl
    index 69fc346..762836c 100644
    a b interface nsIProxiedChannel : nsISupports 
    1919   * Gets the proxy info the channel was constructed with. null or a
    2020   * proxyInfo with type "direct" mean no proxy.
    2121   *
    22    * The returned proxy info must not be modified.
     22   * SOCKS username and password may be modified
     23   * before the connection is established.
    2324   */
    2425  readonly attribute nsIProxyInfo proxyInfo;
    2526};
    26 
    27 
  • netwerk/base/public/nsIProxyInfo.idl

    diff --git a/netwerk/base/public/nsIProxyInfo.idl b/netwerk/base/public/nsIProxyInfo.idl
    index f6f0bf3..6be7224 100644
    a b interface nsIProxyInfo : nsISupports 
    5050  readonly attribute unsigned long resolveFlags;
    5151
    5252  /**
     53   * In case of SOCKS proxy, allows to specify a username and password
     54   * to pass to the proxy.
     55   * They can, for some special usecases like Tor, vary per connection.
     56   * This must be specified before the connection is established.
     57   */
     58  attribute ACString username;
     59
     60  /**
     61   * @see username
     62   */
     63  attribute ACString password;
     64
     65  /**
    5366   * This attribute specifies the failover timeout in seconds for this proxy.
    5467   * If a nsIProxyInfo is reported as failed via nsIProtocolProxyService::
    5568   * getFailoverForProxy, then the failed proxy will not be used again for this
  • netwerk/base/src/nsProtocolProxyService.cpp

    diff --git a/netwerk/base/src/nsProtocolProxyService.cpp b/netwerk/base/src/nsProtocolProxyService.cpp
    index b7f240c..959bd6d 100644
    a b nsProtocolProxyService::PrefsChanged(nsIPrefBranch *prefBranch, 
    517517    if (!pref || !strcmp(pref, PROXY_PREF("socks_port")))
    518518        proxy_GetIntPref(prefBranch, PROXY_PREF("socks_port"), mSOCKSProxyPort);
    519519
     520    if (!pref || !strcmp(pref, PROXY_PREF("socks_username")))
     521        proxy_GetStringPref(prefBranch, PROXY_PREF("socks_username"), mSOCKSProxyUsername);
     522
     523    if (!pref || !strcmp(pref, PROXY_PREF("socks_password")))
     524        proxy_GetStringPref(prefBranch, PROXY_PREF("socks_password"), mSOCKSProxyPassword);
     525
    520526    if (!pref || !strcmp(pref, PROXY_PREF("socks_version"))) {
    521527        int32_t version;
    522528        proxy_GetIntPref(prefBranch, PROXY_PREF("socks_version"), version);
    nsProtocolProxyService::NewProxyInfo(const nsACString &aType, 
    11621168    if (aPort <= 0)
    11631169        aPort = -1;
    11641170
    1165     return NewProxyInfo_Internal(type, aHost, aPort, aFlags, aFailoverTimeout,
     1171    return NewProxyInfo_Internal(type, aHost, aPort,
     1172                                 EmptyCString(), EmptyCString(),
     1173                                 aFlags, aFailoverTimeout,
    11661174                                 aFailoverProxy, 0, aResult);
    11671175}
    11681176
    nsresult 
    14391447nsProtocolProxyService::NewProxyInfo_Internal(const char *aType,
    14401448                                              const nsACString &aHost,
    14411449                                              int32_t aPort,
     1450                                              const nsACString &aUsername,
     1451                                              const nsACString &aPassword,
    14421452                                              uint32_t aFlags,
    14431453                                              uint32_t aFailoverTimeout,
    14441454                                              nsIProxyInfo *aFailoverProxy,
    nsProtocolProxyService::NewProxyInfo_Internal(const char *aType, 
    14581468    proxyInfo->mType = aType;
    14591469    proxyInfo->mHost = aHost;
    14601470    proxyInfo->mPort = aPort;
     1471    proxyInfo->mUsername = aUsername;
     1472    proxyInfo->mPassword = aPassword;
    14611473    proxyInfo->mFlags = aFlags;
    14621474    proxyInfo->mResolveFlags = aResolveFlags;
    14631475    proxyInfo->mTimeout = aFailoverTimeout == UINT32_MAX
    nsProtocolProxyService::Resolve_Internal(nsIURI *uri, 
    16201632    }
    16211633
    16221634    if (type) {
    1623         rv = NewProxyInfo_Internal(type, *host, port, proxyFlags,
    1624                                    UINT32_MAX, nullptr, flags,
     1635        rv = NewProxyInfo_Internal(type, *host, port,
     1636                                   mSOCKSProxyUsername, mSOCKSProxyPassword,
     1637                                   proxyFlags, UINT32_MAX, nullptr, flags,
    16251638                                   result);
    16261639        if (NS_FAILED(rv))
    16271640            return rv;
  • netwerk/base/src/nsProtocolProxyService.h

    diff --git a/netwerk/base/src/nsProtocolProxyService.h b/netwerk/base/src/nsProtocolProxyService.h
    index 35ec5c2..f9afde0 100644
    a b protected: 
    167167     *        The proxy host name (UTF-8 ok).
    168168     * @param port
    169169     *        The proxy port number.
     170     * @param username
     171     *        The username for the proxy (ASCII). May be "", but not null.
     172     * @param password
     173     *        The password for the proxy (ASCII). May be "", but not null.
    170174     * @param flags
    171175     *        The proxy flags (nsIProxyInfo::flags).
    172176     * @param timeout
    protected: 
    181185    NS_HIDDEN_(nsresult) NewProxyInfo_Internal(const char *type,
    182186                                               const nsACString &host,
    183187                                               int32_t port,
     188                                               const nsACString &username,
     189                                               const nsACString &password,
    184190                                               uint32_t flags,
    185191                                               uint32_t timeout,
    186192                                               nsIProxyInfo *next,
    protected: 
    356362    int32_t                      mSOCKSProxyPort;
    357363    int32_t                      mSOCKSProxyVersion;
    358364    bool                         mSOCKSProxyRemoteDNS;
     365    nsCString                    mSOCKSProxyUsername;
     366    nsCString                    mSOCKSProxyPassword;
    359367
    360368    nsRefPtr<nsPACMan>           mPACMan;  // non-null if we are using PAC
    361369    nsCOMPtr<nsISystemProxySettings> mSystemProxySettings;
  • netwerk/base/src/nsProxyInfo.cpp

    diff --git a/netwerk/base/src/nsProxyInfo.cpp b/netwerk/base/src/nsProxyInfo.cpp
    index d21e579..e36e85b 100644
    a b nsProxyInfo::GetResolveFlags(uint32_t *result) 
    4848}
    4949
    5050NS_IMETHODIMP
     51nsProxyInfo::GetUsername(nsACString &result)
     52{
     53  result = mUsername;
     54  return NS_OK;
     55}
     56
     57NS_IMETHODIMP
     58nsProxyInfo::GetPassword(nsACString &result)
     59{
     60  result = mPassword;
     61  return NS_OK;
     62}
     63
     64NS_IMETHODIMP
     65nsProxyInfo::SetUsername(const nsACString &newValue)
     66{
     67  mUsername = newValue;
     68  return NS_OK;
     69}
     70
     71NS_IMETHODIMP
     72nsProxyInfo::SetPassword(const nsACString &newValue)
     73{
     74  mPassword = newValue;
     75  return NS_OK;
     76}
     77
     78NS_IMETHODIMP
    5179nsProxyInfo::GetFailoverTimeout(uint32_t *result)
    5280{
    5381  *result = mTimeout;
  • netwerk/base/src/nsProxyInfo.h

    diff --git a/netwerk/base/src/nsProxyInfo.h b/netwerk/base/src/nsProxyInfo.h
    index 9f11f04..a458b24 100644
    a b private: 
    5959
    6060  const char  *mType;  // pointer to statically allocated value
    6161  nsCString    mHost;
     62  nsCString    mUsername;
     63  nsCString    mPassword;
    6264  int32_t      mPort;
    6365  uint32_t     mFlags;
    6466  uint32_t     mResolveFlags;
  • netwerk/base/src/nsSocketTransport2.cpp

    diff --git a/netwerk/base/src/nsSocketTransport2.cpp b/netwerk/base/src/nsSocketTransport2.cpp
    index 30d270b..02a91a2 100644
    a b nsSocketTransport::nsSocketTransport() 
    671671    : mTypes(nullptr)
    672672    , mTypeCount(0)
    673673    , mPort(0)
    674     , mProxyPort(0)
     674    , mProxyUse(false)
    675675    , mProxyTransparent(false)
    676676    , mProxyTransparentResolvesHost(false)
    677677    , mConnectionFlags(0)
    nsSocketTransport::Init(const char **types, uint32_t typeCount, 
    733733
    734734    const char *proxyType = nullptr;
    735735    if (proxyInfo) {
    736         mProxyPort = proxyInfo->Port();
    737         mProxyHost = proxyInfo->Host();
     736        mProxyInfo = proxyInfo;
    738737        // grab proxy type (looking for "socks" for example)
    739738        proxyType = proxyInfo->Type();
    740739        if (proxyType && (strcmp(proxyType, "http") == 0 ||
    741740                          strcmp(proxyType, "direct") == 0 ||
    742741                          strcmp(proxyType, "unknown") == 0))
    743742            proxyType = nullptr;
     743
     744        mProxyUse = true;
     745        // check that we don't have a proxyInfo without proxy
     746        nsCString proxyHost;
     747        proxyInfo->GetHost(proxyHost);
     748        if (!proxyType || proxyHost.IsEmpty()) {
     749            mProxyUse = false;
     750        }
    744751    }
    745752
    746     SOCKET_LOG(("nsSocketTransport::Init [this=%p host=%s:%hu proxy=%s:%hu]\n",
    747         this, mHost.get(), mPort, mProxyHost.get(), mProxyPort));
     753    SOCKET_LOG(("nsSocketTransport::Init [this=%x host=%s:%hu proxy=%s]\n",
     754        this, mHost.get(), mPort, mProxyUse ? "yes" : "no"));
    748755
    749756    // include proxy type as a socket type if proxy type is not "http"
    750757    mTypeCount = typeCount + (proxyType != nullptr);
    nsSocketTransport::ResolveHost() 
    884891
    885892    nsresult rv;
    886893
    887     if (!mProxyHost.IsEmpty()) {
     894    if (mProxyUse) {
    888895        if (!mProxyTransparent || mProxyTransparentResolvesHost) {
    889896            // When not resolving mHost locally, we still want to ensure that
    890897            // it only contains valid characters.  See bug 304904 for details.
    nsSocketTransport::BuildSocket(PRFileDesc *&fd, bool &proxyTransparent, bool &us 
    957964
    958965        const char *host       = mHost.get();
    959966        int32_t     port       = (int32_t) mPort;
    960         const char *proxyHost  = mProxyHost.IsEmpty() ? nullptr : mProxyHost.get();
    961         int32_t     proxyPort  = (int32_t) mProxyPort;
    962967        uint32_t    proxyFlags = 0;
     968        nsCOMPtr<nsIProxyInfo> proxy = mProxyInfo;
    963969
    964970        uint32_t i;
    965971        for (i=0; i<mTypeCount; ++i) {
    nsSocketTransport::BuildSocket(PRFileDesc *&fd, bool &proxyTransparent, bool &us 
    985991                // if this is the first type, we'll want the
    986992                // service to allocate a new socket
    987993                rv = provider->NewSocket(mNetAddr.raw.family,
    988                                          host, port, proxyHost, proxyPort,
     994                                         host, port, proxy,
    989995                                         proxyFlags, &fd,
    990996                                         getter_AddRefs(secinfo));
    991997
    nsSocketTransport::BuildSocket(PRFileDesc *&fd, bool &proxyTransparent, bool &us 
    9991005                // so we just want the service to add itself
    10001006                // to the stack (such as pushing an io layer)
    10011007                rv = provider->AddToSocket(mNetAddr.raw.family,
    1002                                            host, port, proxyHost, proxyPort,
     1008                                           host, port, proxy,
    10031009                                           proxyFlags, fd,
    10041010                                           getter_AddRefs(secinfo));
    10051011            }
    nsSocketTransport::BuildSocket(PRFileDesc *&fd, bool &proxyTransparent, bool &us 
    10291035                     (strcmp(mTypes[i], "socks4") == 0)) {
    10301036                // since socks is transparent, any layers above
    10311037                // it do not have to worry about proxy stuff
    1032                 proxyHost = nullptr;
    1033                 proxyPort = -1;
     1038                proxy = nullptr;
    10341039                proxyTransparent = true;
    10351040            }
    10361041        }
    nsSocketTransport::InitiateSocket() 
    11981203            //
    11991204            OnSocketConnected();
    12001205
    1201             if (mSecInfo && !mProxyHost.IsEmpty() && proxyTransparent && usingSSL) {
     1206            if (mSecInfo && mProxyUse && proxyTransparent && usingSSL) {
    12021207                // if the connection phase is finished, and the ssl layer has
    12031208                // been pushed, and we were proxying (transparently; ie. nothing
    12041209                // has to happen in the protocol layer above us), it's time for
    nsSocketTransport::InitiateSocket() 
    12221227        // the OS error
    12231228        //
    12241229        else if (PR_UNKNOWN_ERROR == code &&
    1225                  mProxyTransparent &&
    1226                  !mProxyHost.IsEmpty()) {
     1230                 mProxyUse && mProxyTransparent) {
    12271231            code = PR_GetOSError();
    12281232            rv = ErrorAccordingToNSPR(code);
    12291233        }
    nsSocketTransport::InitiateSocket() 
    12321236        //
    12331237        else {
    12341238            rv = ErrorAccordingToNSPR(code);
    1235             if ((rv == NS_ERROR_CONNECTION_REFUSED) && !mProxyHost.IsEmpty())
     1239            if (rv == NS_ERROR_CONNECTION_REFUSED && mProxyUse)
    12361240                rv = NS_ERROR_PROXY_CONNECTION_REFUSED;
    12371241        }
    12381242    }
    nsSocketTransport::OnSocketEvent(uint32_t type, nsresult status, nsISupports *pa 
    15101514            // For SOCKS proxies (mProxyTransparent == true), the socket
    15111515            // transport resolves the real host here, so there's no fixup
    15121516            // (see bug 226943).
    1513             if ((status == NS_ERROR_UNKNOWN_HOST) && !mProxyTransparent &&
    1514                 !mProxyHost.IsEmpty())
     1517            if (status == NS_ERROR_UNKNOWN_HOST && !mProxyTransparent &&
     1518                mProxyUse)
    15151519                mCondition = NS_ERROR_UNKNOWN_PROXY_HOST;
    15161520            else
    15171521                mCondition = status;
    nsSocketTransport::OnSocketReady(PRFileDesc *fd, int16_t outFlags) 
    16361640            // The SOCKS proxy rejected our request. Find out why.
    16371641            //
    16381642            else if (PR_UNKNOWN_ERROR == code &&
    1639                      mProxyTransparent &&
    1640                      !mProxyHost.IsEmpty()) {
     1643                     mProxyUse && mProxyTransparent) {
    16411644                code = PR_GetOSError();
    16421645                mCondition = ErrorAccordingToNSPR(code);
    16431646            }
    nsSocketTransport::OnSocketReady(PRFileDesc *fd, int16_t outFlags) 
    16461649                // else, the connection failed...
    16471650                //
    16481651                mCondition = ErrorAccordingToNSPR(code);
    1649                 if ((mCondition == NS_ERROR_CONNECTION_REFUSED) && !mProxyHost.IsEmpty())
     1652                if (mCondition == NS_ERROR_CONNECTION_REFUSED && mProxyUse)
    16501653                    mCondition = NS_ERROR_PROXY_CONNECTION_REFUSED;
    16511654                SOCKET_LOG(("  connection failed! [reason=%x]\n", mCondition));
    16521655            }
    nsSocketTransport::GetPort(int32_t *port) 
    19611964    return NS_OK;
    19621965}
    19631966
     1967const nsCString &
     1968nsSocketTransport::SocketHost()
     1969{
     1970  if (mProxyInfo && !mProxyTransparent) {
     1971    if (mProxyHostCache.IsEmpty()) { // TODO cache necessary?
     1972      mProxyInfo->GetHost(mProxyHostCache);
     1973    }
     1974    return mProxyHostCache;
     1975  }
     1976  else
     1977    return mHost;
     1978}
     1979
     1980uint16_t
     1981nsSocketTransport::SocketPort()
     1982{
     1983  if (mProxyInfo && !mProxyTransparent) {
     1984    int32_t result;
     1985    mProxyInfo->GetPort(&result);
     1986    return (uint16_t) result; // TODO why doesn't SocketPort() return int32_t?
     1987  }
     1988  else
     1989    return mPort;
     1990}
     1991
    19641992NS_IMETHODIMP
    19651993nsSocketTransport::GetPeerAddr(NetAddr *addr)
    19661994{
  • netwerk/base/src/nsSocketTransport2.h

    diff --git a/netwerk/base/src/nsSocketTransport2.h b/netwerk/base/src/nsSocketTransport2.h
    index 8008ff6..1d5852f 100644
    a b private: 
    177177    char       **mTypes;
    178178    uint32_t     mTypeCount;
    179179    nsCString    mHost;
    180     nsCString    mProxyHost;
    181180    uint16_t     mPort;
    182     uint16_t     mProxyPort;
    183     bool mProxyTransparent;
    184     bool mProxyTransparentResolvesHost;
     181    nsCOMPtr<nsIProxyInfo> mProxyInfo;
     182    bool         mProxyUse;
     183    bool         mProxyTransparent;
     184    bool         mProxyTransparentResolvesHost;
    185185    uint32_t     mConnectionFlags;
    186186   
    187     uint16_t         SocketPort() { return (!mProxyHost.IsEmpty() && !mProxyTransparent) ? mProxyPort : mPort; }
    188     const nsCString &SocketHost() { return (!mProxyHost.IsEmpty() && !mProxyTransparent) ? mProxyHost : mHost; }
     187    uint16_t         SocketPort();
     188    const nsCString &SocketHost();
     189    nsCString        mProxyHostCache; // for SocketHost() only
    189190
    190191    //-------------------------------------------------------------------------
    191192    // members accessible only on the socket transport thread:
  • netwerk/socket/nsISocketProvider.idl

    diff --git a/netwerk/socket/nsISocketProvider.idl b/netwerk/socket/nsISocketProvider.idl
    index 57f6c4d..ea7fcd1 100644
    a b  
    55
    66#include "nsISupports.idl"
    77
     8interface nsIProxyInfo;
    89[ptr] native PRFileDescStar(struct PRFileDesc);
    910
    1011/**
    interface nsISocketProvider : nsISupports 
    3839    void newSocket(in long            aFamily,
    3940                   in string          aHost,
    4041                   in long            aPort,
    41                    in string          aProxyHost,
    42                    in long            aProxyPort,
     42                   in nsIProxyInfo    aProxy,
    4343                   in unsigned long   aFlags,
    4444                   out PRFileDescStar aFileDesc,
    4545                   out nsISupports    aSecurityInfo);
    interface nsISocketProvider : nsISupports 
    5858    void addToSocket(in long           aFamily,
    5959                     in string         aHost,
    6060                     in long           aPort,
    61                      in string         aProxyHost,
    62                      in long           aProxyPort,
     61                     in nsIProxyInfo   aProxy,
    6362                     in unsigned long  aFlags,
    6463                     in PRFileDescStar aFileDesc,
    6564                     out nsISupports   aSecurityInfo);
  • netwerk/socket/nsSOCKSIOLayer.cpp

    diff --git a/netwerk/socket/nsSOCKSIOLayer.cpp b/netwerk/socket/nsSOCKSIOLayer.cpp
    index 7be6538..9422959 100644
    a b class nsSOCKSSocketInfo : public nsISOCKSSocketInfo 
    5050        SOCKS4_READ_CONNECT_RESPONSE,
    5151        SOCKS5_WRITE_AUTH_REQUEST,
    5252        SOCKS5_READ_AUTH_RESPONSE,
     53        SOCKS5_WRITE_USERNAME_REQUEST,
     54        SOCKS5_READ_USERNAME_RESPONSE,
    5355        SOCKS5_WRITE_CONNECT_REQUEST,
    5456        SOCKS5_READ_CONNECT_RESPONSE_TOP,
    5557        SOCKS5_READ_CONNECT_RESPONSE_BOTTOM,
    public: 
    7274
    7375    void Init(int32_t version,
    7476              int32_t family,
    75               const char *proxyHost,
    76               int32_t proxyPort,
     77              nsIProxyInfo *proxy,
    7778              const char *destinationHost,
    7879              uint32_t flags);
    7980
    private: 
    9596    PRStatus ReadV4ConnectResponse();
    9697    PRStatus WriteV5AuthRequest();
    9798    PRStatus ReadV5AuthResponse();
     99    PRStatus WriteV5UsernameRequest();
     100    PRStatus ReadV5UsernameResponse();
    98101    PRStatus WriteV5ConnectRequest();
    99102    PRStatus ReadV5AddrTypeAndLength(uint8_t *type, uint32_t *len);
    100103    PRStatus ReadV5ConnectResponseTop();
    private: 
    130133    PRFileDesc             *mFD;
    131134
    132135    nsCString mDestinationHost;
    133     nsCString mProxyHost;
    134     int32_t   mProxyPort;
     136    nsCOMPtr<nsIProxyInfo> mProxy;
    135137    int32_t   mVersion;   // SOCKS version 4 or 5
    136138    int32_t   mDestinationFamily;
    137139    uint32_t  mFlags;
    private: 
    139141    NetAddr   mExternalProxyAddr;
    140142    NetAddr   mDestinationAddr;
    141143    PRIntervalTime mTimeout;
     144    nsCString mProxyUsername; // Cache, from mProxy
    142145};
    143146
    144147nsSOCKSSocketInfo::nsSOCKSSocketInfo()
    nsSOCKSSocketInfo::nsSOCKSSocketInfo() 
    147150    , mDataLength(0)
    148151    , mReadOffset(0)
    149152    , mAmountToRead(0)
    150     , mProxyPort(-1)
    151153    , mVersion(-1)
    152154    , mDestinationFamily(AF_INET)
    153155    , mFlags(0)
    nsSOCKSSocketInfo::nsSOCKSSocketInfo() 
    169171}
    170172
    171173void
    172 nsSOCKSSocketInfo::Init(int32_t version, int32_t family, const char *proxyHost, int32_t proxyPort, const char *host, uint32_t flags)
     174nsSOCKSSocketInfo::Init(int32_t version, int32_t family, nsIProxyInfo *proxy, const char *host, uint32_t flags)
    173175{
    174176    mVersion         = version;
    175177    mDestinationFamily = family;
    176     mProxyHost       = proxyHost;
    177     mProxyPort       = proxyPort;
     178    mProxy           = proxy;
    178179    mDestinationHost = host;
    179180    mFlags           = flags;
     181    mProxy->GetUsername(mProxyUsername); // cache
    180182}
    181183
    182184NS_IMPL_THREADSAFE_ISUPPORTS2(nsSOCKSSocketInfo, nsISOCKSSocketInfo, nsIDNSListener)
    nsSOCKSSocketInfo::StartDNS(PRFileDesc *fd) 
    263265    if (!dns)
    264266        return PR_FAILURE;
    265267
     268    nsCString proxyHost;
     269    mProxy->GetHost(proxyHost);
     270
    266271    mFD  = fd;
    267     nsresult rv = dns->AsyncResolve(mProxyHost, 0, this,
     272    nsresult rv = dns->AsyncResolve(proxyHost, 0, this,
    268273                                    NS_GetCurrentThread(),
    269274                                    getter_AddRefs(mLookup));
    270275
    271276    if (NS_FAILED(rv)) {
    272277        LOGERROR(("socks: DNS lookup for SOCKS proxy %s failed",
    273                   mProxyHost.get()));
     278                  proxyHost.get()));
    274279        return PR_FAILURE;
    275280    }
    276281    mState = SOCKS_DNS_IN_PROGRESS;
    nsSOCKSSocketInfo::ConnectToProxy(PRFileDesc *fd) 
    315320        mVersion = 5;
    316321    }
    317322
     323    int32_t proxyPort;
     324    mProxy->GetPort(&proxyPort);
     325
    318326    int32_t addresses = 0;
    319327    do {
    320328        if (addresses++)
    321             mDnsRec->ReportUnusable(mProxyPort);
     329            mDnsRec->ReportUnusable(proxyPort);
    322330       
    323         rv = mDnsRec->GetNextAddr(mProxyPort, &mInternalProxyAddr);
     331        rv = mDnsRec->GetNextAddr(proxyPort, &mInternalProxyAddr);
    324332        // No more addresses to try? If so, we'll need to bail
    325333        if (NS_FAILED(rv)) {
     334            nsCString proxyHost;
     335            mProxy->GetHost(proxyHost);
    326336            LOGERROR(("socks: unable to connect to SOCKS proxy, %s",
    327                      mProxyHost.get()));
     337                     proxyHost.get()));
    328338            return PR_FAILURE;
    329339        }
    330340
    nsSOCKSSocketInfo::WriteV4ConnectRequest() 
    465475        // than 0, is used to notify the proxy that this is a SOCKS 4a
    466476        // request. This request type works for Tor and perhaps others.
    467477        WriteUint32(htonl(0x00000001)); // Fake IP
    468         WriteUint8(0x00); // Send an emtpy username
     478        WriteString(mProxyUsername); // Send username. May be empty.
     479        WriteUint8(0x00); // Null-terminate username
     480        // Password not supported by V4.
    469481        if (mDestinationHost.Length() > MAX_HOSTNAME_LEN) {
    470482            LOGERROR(("socks4: destination host name is too long!"));
    471483            HandshakeFinished(PR_BAD_ADDRESS_ERROR);
    nsSOCKSSocketInfo::WriteV4ConnectRequest() 
    475487        WriteUint8(0x00);
    476488    } else if (addr->raw.family == AF_INET) {
    477489        WriteNetAddr(addr); // Add the IPv4 address
    478         WriteUint8(0x00); // Send an emtpy username
     490        WriteString(mProxyUsername); // Send username. May be empty.
     491        WriteUint8(0x00); // Null-terminate username
     492        // Password not supported by V4.
    479493    } else if (addr->raw.family == AF_INET6) {
    480494        LOGERROR(("socks: SOCKS 4 can't handle IPv6 addresses!"));
    481495        HandshakeFinished(PR_BAD_ADDRESS_ERROR);
    nsSOCKSSocketInfo::WriteV5AuthRequest() 
    518532{
    519533    NS_ABORT_IF_FALSE(mVersion == 5, "SOCKS version must be 5!");
    520534
     535    mDataLength = 0;
    521536    mState = SOCKS5_WRITE_AUTH_REQUEST;
    522537
    523538    // Send an initial SOCKS 5 greeting
    524539    LOGDEBUG(("socks5: sending auth methods"));
    525540    WriteUint8(0x05); // version -- 5
    526     WriteUint8(0x01); // # auth methods -- 1
    527     WriteUint8(0x00); // we don't support authentication
     541    WriteUint8(0x01); // # of auth methods -- 1
     542    if (mProxyUsername.IsEmpty()) {
     543      WriteUint8(0x00); // no authentication
     544    } else {
     545      WriteUint8(0x02); // username/password
     546    }
    528547
    529548    return PR_SUCCESS;
    530549}
    nsSOCKSSocketInfo::ReadV5AuthResponse() 
    537556    NS_ABORT_IF_FALSE(mDataLength == 2,
    538557                      "SOCKS 5 auth method reply must be 2 bytes!");
    539558
    540     LOGDEBUG(("socks5: checking auth method reply"));
    541 
    542559    // Check version number
    543560    if (ReadUint8() != 0x05) {
    544561        LOGERROR(("socks5: unexpected version in the reply"));
    nsSOCKSSocketInfo::ReadV5AuthResponse() 
    546563        return PR_FAILURE;
    547564    }
    548565
    549     // Make sure our authentication choice was accepted
    550     if (ReadUint8() != 0x00) {
     566    // Make sure our authentication choice was accepted,
     567    // and continue accordingly
     568    uint8_t authMethod = ReadUint8();
     569    if (mProxyUsername.IsEmpty() && authMethod == 0x00) { // no auth
     570        LOGDEBUG(("socks5: server allows connection without authentication"));
     571        return WriteV5ConnectRequest();
     572    } else if (!mProxyUsername.IsEmpty() && authMethod == 0x02) { // username/pw
     573        LOGDEBUG(("socks5: auth method accepted by server"));
     574        return WriteV5UsernameRequest();
     575    } else { // 0xFF signals error
    551576        LOGERROR(("socks5: server did not accept our authentication method"));
    552577        HandshakeFinished(PR_CONNECT_REFUSED_ERROR);
    553578        return PR_FAILURE;
    554579    }
     580}
     581
     582PRStatus
     583nsSOCKSSocketInfo::WriteV5UsernameRequest()
     584{
     585    NS_ABORT_IF_FALSE(mVersion == 5, "SOCKS version must be 5!");
     586
     587    mDataLength = 0;
     588    mState = SOCKS5_WRITE_USERNAME_REQUEST;
     589
     590    LOGDEBUG(("socks5: sending username and password"));
     591    // RFC 1929 Username/password auth for SOCKS 5
     592    printf("%s\n", "socks5: sending username and password");
     593    printf("version %d\n", 0x01);
     594    WriteUint8(0x01); // version 1 (not 5)
     595    printf("username length %d\n", mProxyUsername.Length());
     596    WriteUint8(mProxyUsername.Length()); // username length
     597    printf("username %s\n", mProxyUsername.get());
     598    WriteString(mProxyUsername); // username
     599    nsCString password;
     600    mProxy->GetPassword(password);
     601    printf("password length %d\n", password.Length());
     602    WriteUint8(password.Length()); // password length
     603    printf("password %s\n", password.get());
     604    WriteString(password); // password. WARNING: Sent unencrypted!
     605
     606    return PR_SUCCESS;
     607}
     608
     609PRStatus
     610nsSOCKSSocketInfo::ReadV5UsernameResponse()
     611{
     612    printf("%s\n", "socks5: username response");
     613    NS_ABORT_IF_FALSE(mState == SOCKS5_READ_USERNAME_RESPONSE,
     614                      "Handling SOCKS 5 username/password reply in wrong state!");
     615    NS_ABORT_IF_FALSE(mDataLength == 2,
     616                      "SOCKS 5 username reply must be 2 bytes!");
     617
     618    // Check version number, must be 1 (not 5)
     619    if (ReadUint8() != 0x01) {
     620        printf("%s\n", "socks5: wrong version");
     621        LOGERROR(("socks5: unexpected version in the reply"));
     622        HandshakeFinished(PR_CONNECT_REFUSED_ERROR);
     623        return PR_FAILURE;
     624    }
     625
     626    // Check whether username/password were accepted
     627    if (ReadUint8() != 0x00) { // 0 = success
     628        printf("%s\n", "socks5: user rejected");
     629        LOGERROR(("socks5: username/password not accepted"));
     630        HandshakeFinished(PR_CONNECT_REFUSED_ERROR);
     631        return PR_FAILURE;
     632    }
     633    printf("%s\n", "socks5: user accepted rejected");
     634
     635    LOGDEBUG(("socks5: username/password accepted by server"));
    555636
    556637    return WriteV5ConnectRequest();
    557638}
    nsSOCKSSocketInfo::DoHandshake(PRFileDesc *fd, int16_t oflags) 
    795876            if (ReadFromSocket(fd) != PR_SUCCESS)
    796877                return PR_FAILURE;
    797878            return ReadV5AuthResponse();
     879        case SOCKS5_WRITE_USERNAME_REQUEST:
     880            if (WriteToSocket(fd) != PR_SUCCESS)
     881                return PR_FAILURE;
     882            WantRead(2);
     883            mState = SOCKS5_READ_USERNAME_RESPONSE;
     884            return PR_SUCCESS;
     885        case SOCKS5_READ_USERNAME_RESPONSE:
     886            if (ReadFromSocket(fd) != PR_SUCCESS)
     887                return PR_FAILURE;
     888            return ReadV5UsernameResponse();
    798889        case SOCKS5_WRITE_CONNECT_REQUEST:
    799890            if (WriteToSocket(fd) != PR_SUCCESS)
    800891                return PR_FAILURE;
    nsresult 
    12211312nsSOCKSIOLayerAddToSocket(int32_t family,
    12221313                          const char *host,
    12231314                          int32_t port,
    1224                           const char *proxyHost,
    1225                           int32_t proxyPort,
     1315                          nsIProxyInfo *proxy,
    12261316                          int32_t socksVersion,
    12271317                          uint32_t flags,
    12281318                          PRFileDesc *fd,
    nsSOCKSIOLayerAddToSocket(int32_t family, 
    12891379    }
    12901380
    12911381    NS_ADDREF(infoObject);
    1292     infoObject->Init(socksVersion, family, proxyHost, proxyPort, host, flags);
     1382    infoObject->Init(socksVersion, family, proxy, host, flags);
    12931383    layer->secret = (PRFilePrivate*) infoObject;
    12941384    rv = PR_PushIOLayer(fd, PR_GetLayersIdentity(fd), layer);
    12951385
  • netwerk/socket/nsSOCKSIOLayer.h

    diff --git a/netwerk/socket/nsSOCKSIOLayer.h b/netwerk/socket/nsSOCKSIOLayer.h
    index e30f547..909259d 100644
    a b  
    1010#include "prtypes.h"
    1111#include "prio.h"
    1212#include "nscore.h"
     13#include "nsIProxyInfo.h"
    1314
    1415nsresult nsSOCKSIOLayerAddToSocket(int32_t       family,
    1516                                   const char   *host,
    1617                                   int32_t       port,
    17                                    const char   *proxyHost,
    18                                    int32_t       proxyPort,
     18                                   nsIProxyInfo *proxy,
    1919                                   int32_t       socksVersion,
    2020                                   uint32_t      flags,
    2121                                   PRFileDesc   *fd,
  • netwerk/socket/nsSOCKSSocketProvider.cpp

    diff --git a/netwerk/socket/nsSOCKSSocketProvider.cpp b/netwerk/socket/nsSOCKSSocketProvider.cpp
    index 63ed38c..c49075e 100644
    a b NS_IMETHODIMP 
    4444nsSOCKSSocketProvider::NewSocket(int32_t family,
    4545                                 const char *host,
    4646                                 int32_t port,
    47                                  const char *proxyHost,
    48                                  int32_t proxyPort,
     47                                 nsIProxyInfo *proxy,
    4948                                 uint32_t flags,
    5049                                 PRFileDesc **result,
    5150                                 nsISupports **socksInfo)
    nsSOCKSSocketProvider::NewSocket(int32_t family, 
    5958    nsresult rv = nsSOCKSIOLayerAddToSocket(family,
    6059                                            host,
    6160                                            port,
    62                                             proxyHost,
    63                                             proxyPort,
     61                                            proxy,
    6462                                            mVersion,
    6563                                            flags,
    6664                                            sock,
    NS_IMETHODIMP 
    7775nsSOCKSSocketProvider::AddToSocket(int32_t family,
    7876                                   const char *host,
    7977                                   int32_t port,
    80                                    const char *proxyHost,
    81                                    int32_t proxyPort,
     78                                   nsIProxyInfo *proxy,
    8279                                   uint32_t flags,
    8380                                   PRFileDesc *sock,
    8481                                   nsISupports **socksInfo)
    nsSOCKSSocketProvider::AddToSocket(int32_t family, 
    8683    nsresult rv = nsSOCKSIOLayerAddToSocket(family,
    8784                                            host,
    8885                                            port,
    89                                             proxyHost,
    90                                             proxyPort,
     86                                            proxy,
    9187                                            mVersion,
    9288                                            flags,
    9389                                            sock,
  • netwerk/socket/nsUDPSocketProvider.cpp

    diff --git a/netwerk/socket/nsUDPSocketProvider.cpp b/netwerk/socket/nsUDPSocketProvider.cpp
    index 17e19ab..2059747 100644
    a b NS_IMETHODIMP 
    1616nsUDPSocketProvider::NewSocket(int32_t aFamily,
    1717                               const char *aHost,
    1818                               int32_t aPort,
    19                                const char *aProxyHost,
    20                                int32_t aProxyPort,
     19                               nsIProxyInfo *aProxy,
    2120                               uint32_t aFlags,
    2221                               PRFileDesc * *aFileDesc,
    2322                               nsISupports **aSecurityInfo)
    NS_IMETHODIMP 
    3635nsUDPSocketProvider::AddToSocket(int32_t aFamily,
    3736                                 const char *aHost,
    3837                                 int32_t aPort,
    39                                  const char *aProxyHost,
    40                                  int32_t aProxyPort,
     38                                 nsIProxyInfo *aProxy,
    4139                                 uint32_t aFlags,
    4240                                 struct PRFileDesc * aFileDesc,
    4341                                 nsISupports **aSecurityInfo)
  • security/manager/ssl/src/nsNSSIOLayer.cpp

    diff --git a/security/manager/ssl/src/nsNSSIOLayer.cpp b/security/manager/ssl/src/nsNSSIOLayer.cpp
    index 3d88596..b5b2f77 100644
    a b nsresult 
    14811481nsSSLIOLayerNewSocket(int32_t family,
    14821482                      const char *host,
    14831483                      int32_t port,
    1484                       const char *proxyHost,
    1485                       int32_t proxyPort,
     1484                      nsIProxyInfo *proxy,
    14861485                      PRFileDesc **fd,
    14871486                      nsISupports** info,
    14881487                      bool forSTARTTLS,
    nsSSLIOLayerNewSocket(int32_t family, 
    14921491  PRFileDesc* sock = PR_OpenTCPSocket(family);
    14931492  if (!sock) return NS_ERROR_OUT_OF_MEMORY;
    14941493
    1495   nsresult rv = nsSSLIOLayerAddToSocket(family, host, port, proxyHost, proxyPort,
     1494  nsresult rv = nsSSLIOLayerAddToSocket(family, host, port, proxy,
    14961495                                        sock, info, forSTARTTLS, flags);
    14971496  if (NS_FAILED(rv)) {
    14981497    PR_Close(sock);
    loser: 
    25132512
    25142513static nsresult
    25152514nsSSLIOLayerSetOptions(PRFileDesc *fd, bool forSTARTTLS,
    2516                        const char *proxyHost, const char *host, int32_t port,
     2515                       bool haveProxy, const char *host, int32_t port,
    25172516                       nsNSSSocketInfo *infoObject)
    25182517{
    25192518  nsNSSShutDownPreventionLock locker;
    2520   if (forSTARTTLS || proxyHost) {
     2519  if (forSTARTTLS || haveProxy) {
    25212520    if (SECSuccess != SSL_OptionSet(fd, SSL_SECURITY, false)) {
    25222521      return NS_ERROR_FAILURE;
    25232522    }
    nsresult 
    25912590nsSSLIOLayerAddToSocket(int32_t family,
    25922591                        const char* host,
    25932592                        int32_t port,
    2594                         const char* proxyHost,
    2595                         int32_t proxyPort,
     2593                        nsIProxyInfo* proxy,
    25962594                        PRFileDesc* fd,
    25972595                        nsISupports** info,
    25982596                        bool forSTARTTLS,
    nsSSLIOLayerAddToSocket(int32_t family, 
    26142612  infoObject->SetHostName(host);
    26152613  infoObject->SetPort(port);
    26162614
     2615  bool haveProxy = false;
     2616  if (proxy) {
     2617    nsCString proxyHost;
     2618    proxy->GetHost(proxyHost);
     2619    haveProxy = !proxyHost.IsEmpty();
     2620  }
     2621
    26172622  // A plaintext observer shim is inserted so we can observe some protocol
    26182623  // details without modifying nss
    26192624  plaintextLayer = PR_CreateIOLayerStub(nsSSLIOLayerHelpers::nsSSLPlaintextLayerIdentity,
    nsSSLIOLayerAddToSocket(int32_t family, 
    26352640
    26362641  infoObject->SetFileDescPtr(sslSock);
    26372642
    2638   rv = nsSSLIOLayerSetOptions(sslSock, forSTARTTLS, proxyHost, host, port,
     2643  rv = nsSSLIOLayerSetOptions(sslSock, forSTARTTLS, haveProxy, host, port,
    26392644                              infoObject);
    26402645
    26412646  if (NS_FAILED(rv))
    nsSSLIOLayerAddToSocket(int32_t family, 
    26592664  PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("[%p] Socket set up\n", (void*)sslSock));
    26602665  infoObject->QueryInterface(NS_GET_IID(nsISupports), (void**) (info));
    26612666
    2662   // We are going use a clear connection first //
    2663   if (forSTARTTLS || proxyHost) {
     2667  // We are going use a clear connection first
     2668  if (forSTARTTLS || haveProxy) {
    26642669    infoObject->SetHandshakePending(false);
    26652670  }
    26662671
  • security/manager/ssl/src/nsNSSIOLayer.h

    diff --git a/security/manager/ssl/src/nsNSSIOLayer.h b/security/manager/ssl/src/nsNSSIOLayer.h
    index 2714367..1c07813 100644
    a b  
    1414#include "nsDataHashtable.h"
    1515#include "nsTHashtable.h"
    1616#include "mozilla/TimeStamp.h"
     17#include "nsIProxyInfo.h"
    1718
    1819namespace mozilla {
    1920namespace psm {
    private: 
    171172nsresult nsSSLIOLayerNewSocket(int32_t family,
    172173                               const char *host,
    173174                               int32_t port,
    174                                const char *proxyHost,
    175                                int32_t proxyPort,
     175                               nsIProxyInfo *proxy,
    176176                               PRFileDesc **fd,
    177177                               nsISupports **securityInfo,
    178178                               bool forSTARTTLS,
    nsresult nsSSLIOLayerNewSocket(int32_t family, 
    181181nsresult nsSSLIOLayerAddToSocket(int32_t family,
    182182                                 const char *host,
    183183                                 int32_t port,
    184                                  const char *proxyHost,
    185                                  int32_t proxyPort,
     184                                 nsIProxyInfo *proxy,
    186185                                 PRFileDesc *fd,
    187186                                 nsISupports **securityInfo,
    188187                                 bool forSTARTTLS,
  • security/manager/ssl/src/nsSSLSocketProvider.cpp

    diff --git a/security/manager/ssl/src/nsSSLSocketProvider.cpp b/security/manager/ssl/src/nsSSLSocketProvider.cpp
    index ce04027..a100c57 100644
    a b NS_IMETHODIMP 
    2222nsSSLSocketProvider::NewSocket(int32_t family,
    2323                               const char *host,
    2424                               int32_t port,
    25                                const char *proxyHost,
    26                                int32_t proxyPort,
     25                               nsIProxyInfo *proxy,
    2726                               uint32_t flags,
    2827                               PRFileDesc **_result,
    2928                               nsISupports **securityInfo)
    nsSSLSocketProvider::NewSocket(int32_t family, 
    3130  nsresult rv = nsSSLIOLayerNewSocket(family,
    3231                                      host,
    3332                                      port,
    34                                       proxyHost,
    35                                       proxyPort,
     33                                      proxy,
    3634                                      _result,
    3735                                      securityInfo,
    3836                                      false,
    NS_IMETHODIMP 
    4543nsSSLSocketProvider::AddToSocket(int32_t family,
    4644                                 const char *host,
    4745                                 int32_t port,
    48                                  const char *proxyHost,
    49                                  int32_t proxyPort,
     46                                 nsIProxyInfo *proxy,
    5047                                 uint32_t flags,
    5148                                 PRFileDesc *aSocket,
    5249                                 nsISupports **securityInfo)
    nsSSLSocketProvider::AddToSocket(int32_t family, 
    5451  nsresult rv = nsSSLIOLayerAddToSocket(family,
    5552                                        host,
    5653                                        port,
    57                                         proxyHost,
    58                                         proxyPort,
     54                                        proxy,
    5955                                        aSocket,
    6056                                        securityInfo,
    6157                                        false,
  • security/manager/ssl/src/nsTLSSocketProvider.cpp

    diff --git a/security/manager/ssl/src/nsTLSSocketProvider.cpp b/security/manager/ssl/src/nsTLSSocketProvider.cpp
    index 9963480..08e2aa2 100644
    a b NS_IMETHODIMP 
    2222nsTLSSocketProvider::NewSocket(int32_t family,
    2323                               const char *host,
    2424                               int32_t port,
    25                                const char *proxyHost,
    26                                int32_t proxyPort,
     25                               nsIProxyInfo *proxy,
    2726                               uint32_t flags,
    2827                               PRFileDesc **_result,
    2928                               nsISupports **securityInfo)
    nsTLSSocketProvider::NewSocket(int32_t family, 
    3130  nsresult rv = nsSSLIOLayerNewSocket(family,
    3231                                      host,
    3332                                      port,
    34                                       proxyHost,
    35                                       proxyPort,
     33                                      proxy,
    3634                                      _result,
    3735                                      securityInfo,
    3836                                      true,
    NS_IMETHODIMP 
    4644nsTLSSocketProvider::AddToSocket(int32_t family,
    4745                                 const char *host,
    4846                                 int32_t port,
    49                                  const char *proxyHost,
    50                                  int32_t proxyPort,
     47                                 nsIProxyInfo *proxy,
    5148                                 uint32_t flags,
    5249                                 PRFileDesc *aSocket,
    5350                                 nsISupports **securityInfo)
    nsTLSSocketProvider::AddToSocket(int32_t family, 
    5552  nsresult rv = nsSSLIOLayerAddToSocket(family,
    5653                                        host,
    5754                                        port,
    58                                         proxyHost,
    59                                         proxyPort,
     55                                        proxy,
    6056                                        aSocket,
    6157                                        securityInfo,
    6258                                        true,