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

File socks-username-6733-proxyInfo-7.diff, 56.2 KB (added by ben, 7 years ago)

Same state, before Firefox update

  • netwerk/base/public/nsIProxiedChannel.idl

    diff --git a/netwerk/base/public/nsIProxiedChannel.idl b/netwerk/base/public/nsIProxiedChannel.idl
    a b interface nsIProxyInfo; 
    1414 */
    1515[scriptable, uuid(6238f134-8c3f-4354-958f-dfd9d54a4446)]
    1616interface nsIProxiedChannel : nsISupports
    1717{
    1818  /**
    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
    a b interface nsIProxyInfo : nsISupports 
    4545
    4646  /**
    4747   * This attribute specifies flags that were used by nsIProxyProtocolService when
    4848   * creating this ProxyInfo element.
    4949   */
    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
    5669   * many seconds.
    5770   */
    5871  readonly attribute unsigned long failoverTimeout;
    5972
    6073  /**
  • netwerk/base/src/nsProtocolProxyService.cpp

    diff --git a/netwerk/base/src/nsProtocolProxyService.cpp b/netwerk/base/src/nsProtocolProxyService.cpp
    a b nsProtocolProxyService::PrefsChanged(nsI 
    497497        proxy_GetIntPref(prefBranch, PROXY_PREF("ftp_port"), mFTPProxyPort);
    498498
    499499    if (!pref || !strcmp(pref, PROXY_PREF("socks")))
    500500        proxy_GetStringPref(prefBranch, PROXY_PREF("socks"), mSOCKSProxyHost);
    501501   
    502502    if (!pref || !strcmp(pref, PROXY_PREF("socks_port")))
    503503        proxy_GetIntPref(prefBranch, PROXY_PREF("socks_port"), mSOCKSProxyPort);
    504504
     505    if (!pref || !strcmp(pref, PROXY_PREF("socks_username")))
     506        proxy_GetStringPref(prefBranch, PROXY_PREF("socks_username"), mSOCKSProxyUsername);
     507
     508    if (!pref || !strcmp(pref, PROXY_PREF("socks_password")))
     509        proxy_GetStringPref(prefBranch, PROXY_PREF("socks_password"), mSOCKSProxyPassword);
     510
    505511    if (!pref || !strcmp(pref, PROXY_PREF("socks_version"))) {
    506512        int32_t version;
    507513        proxy_GetIntPref(prefBranch, PROXY_PREF("socks_version"), version);
    508514        // make sure this preference value remains sane
    509515        if (version == 5)
    510516            mSOCKSProxyVersion = 5;
    511517        else
    512518            mSOCKSProxyVersion = 4;
    nsProtocolProxyService::NewProxyInfo(con 
    11431149            break;
    11441150        }
    11451151    }
    11461152    NS_ENSURE_TRUE(type, NS_ERROR_INVALID_ARG);
    11471153
    11481154    if (aPort <= 0)
    11491155        aPort = -1;
    11501156
    1151     return NewProxyInfo_Internal(type, aHost, aPort, aFlags, aFailoverTimeout,
     1157    return NewProxyInfo_Internal(type, aHost, aPort,
     1158                                 EmptyCString(), EmptyCString(),
     1159                                 aFlags, aFailoverTimeout,
    11521160                                 aFailoverProxy, 0, aResult);
    11531161}
    11541162
    11551163NS_IMETHODIMP
    11561164nsProtocolProxyService::GetFailoverForProxy(nsIProxyInfo  *aProxy,
    11571165                                            nsIURI        *aURI,
    11581166                                            nsresult       aStatus,
    11591167                                            nsIProxyInfo **aResult)
    nsProtocolProxyService::GetProtocolInfo( 
    14201428    rv = handler->GetDefaultPort(&info->defaultPort);
    14211429    return rv;
    14221430}
    14231431
    14241432nsresult
    14251433nsProtocolProxyService::NewProxyInfo_Internal(const char *aType,
    14261434                                              const nsACString &aHost,
    14271435                                              int32_t aPort,
     1436                                              const nsACString &aUsername,
     1437                                              const nsACString &aPassword,
    14281438                                              uint32_t aFlags,
    14291439                                              uint32_t aFailoverTimeout,
    14301440                                              nsIProxyInfo *aFailoverProxy,
    14311441                                              uint32_t aResolveFlags,
    14321442                                              nsIProxyInfo **aResult)
    14331443{
    14341444    nsCOMPtr<nsProxyInfo> failover;
    14351445    if (aFailoverProxy) {
    nsProtocolProxyService::NewProxyInfo_Int 
    14391449
    14401450    nsProxyInfo *proxyInfo = new nsProxyInfo();
    14411451    if (!proxyInfo)
    14421452        return NS_ERROR_OUT_OF_MEMORY;
    14431453
    14441454    proxyInfo->mType = aType;
    14451455    proxyInfo->mHost = aHost;
    14461456    proxyInfo->mPort = aPort;
     1457    proxyInfo->mUsername = aUsername;
     1458    proxyInfo->mPassword = aPassword;
    14471459    proxyInfo->mFlags = aFlags;
    14481460    proxyInfo->mResolveFlags = aResolveFlags;
    14491461    proxyInfo->mTimeout = aFailoverTimeout == UINT32_MAX
    14501462        ? mFailedProxyTimeout : aFailoverTimeout;
    14511463    failover.swap(proxyInfo->mNext);
    14521464
    14531465    NS_ADDREF(*aResult = proxyInfo);
    14541466    return NS_OK;
    nsProtocolProxyService::Resolve_Internal 
    15961608        else
    15971609            type = kProxyType_SOCKS;
    15981610        port = mSOCKSProxyPort;
    15991611        if (mSOCKSProxyRemoteDNS)
    16001612            proxyFlags |= nsIProxyInfo::TRANSPARENT_PROXY_RESOLVES_HOST;
    16011613    }
    16021614
    16031615    if (type) {
    1604         rv = NewProxyInfo_Internal(type, *host, port, proxyFlags,
    1605                                    UINT32_MAX, nullptr, flags,
     1616        rv = NewProxyInfo_Internal(type, *host, port,
     1617                                   mSOCKSProxyUsername, mSOCKSProxyPassword,
     1618                                   proxyFlags, UINT32_MAX, nullptr, flags,
    16061619                                   result);
    16071620        if (NS_FAILED(rv))
    16081621            return rv;
    16091622    }
    16101623
    16111624    return NS_OK;
    16121625}
    16131626
  • netwerk/base/src/nsProtocolProxyService.h

    diff --git a/netwerk/base/src/nsProtocolProxyService.h b/netwerk/base/src/nsProtocolProxyService.h
    a b protected: 
    162162     * that expects a string literal for the type.
    163163     *
    164164     * @param type
    165165     *        The proxy type.
    166166     * @param host
    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
    173177     *        The failover timeout for this proxy.
    174178     * @param next
    175179     *        The next proxy to try if this one fails.
    176180     * @param aResolveFlags
    177181     *        The flags passed to resolve (from nsIProtocolProxyService).
    178182     * @param result
    179183     *        The resulting nsIProxyInfo object.
    180184     */
    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,
    187193                                               uint32_t aResolveFlags,
    188194                                               nsIProxyInfo **result);
    189195
    190196    /**
    191197     * This method is an internal version of Resolve that does not query PAC.
    protected: 
    351357
    352358    nsCString                    mHTTPSProxyHost;
    353359    int32_t                      mHTTPSProxyPort;
    354360   
    355361    nsCString                    mSOCKSProxyHost;
    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;
    362370
    363371    PRTime                       mSessionStart;
    364372    nsFailedProxyTable           mFailedProxies;
    365373    int32_t                      mFailedProxyTimeout;
    366374};
  • netwerk/base/src/nsProxyInfo.cpp

    diff --git a/netwerk/base/src/nsProxyInfo.cpp b/netwerk/base/src/nsProxyInfo.cpp
    a b nsProxyInfo::GetFlags(uint32_t *result) 
    4141NS_IMETHODIMP
    4242nsProxyInfo::GetResolveFlags(uint32_t *result)
    4343{
    4444  *result = mResolveFlags;
    4545  return NS_OK;
    4646}
    4747
    4848NS_IMETHODIMP
     49nsProxyInfo::GetUsername(nsACString &result)
     50{
     51  result = mUsername;
     52  return NS_OK;
     53}
     54
     55NS_IMETHODIMP
     56nsProxyInfo::GetPassword(nsACString &result)
     57{
     58  result = mPassword;
     59  return NS_OK;
     60}
     61
     62NS_IMETHODIMP
     63nsProxyInfo::SetUsername(const nsACString &newValue)
     64{
     65  mUsername = newValue;
     66  return NS_OK;
     67}
     68
     69NS_IMETHODIMP
     70nsProxyInfo::SetPassword(const nsACString &newValue)
     71{
     72  mPassword = newValue;
     73  return NS_OK;
     74}
     75
     76NS_IMETHODIMP
    4977nsProxyInfo::GetFailoverTimeout(uint32_t *result)
    5078{
    5179  *result = mTimeout;
    5280  return NS_OK;
    5381}
    5482
    5583NS_IMETHODIMP
    5684nsProxyInfo::GetFailoverProxy(nsIProxyInfo **result)
  • netwerk/base/src/nsProxyInfo.h

    diff --git a/netwerk/base/src/nsProxyInfo.h b/netwerk/base/src/nsProxyInfo.h
    a b private: 
    5050
    5151  ~nsProxyInfo()
    5252  {
    5353    NS_IF_RELEASE(mNext);
    5454  }
    5555
    5656  const char  *mType;  // pointer to statically allocated value
    5757  nsCString    mHost;
     58  nsCString    mUsername;
     59  nsCString    mPassword;
    5860  int32_t      mPort;
    5961  uint32_t     mFlags;
    6062  uint32_t     mResolveFlags;
    6163  uint32_t     mTimeout;
    6264  nsProxyInfo *mNext;
    6365};
    6466
    6567NS_DEFINE_STATIC_IID_ACCESSOR(nsProxyInfo, NS_PROXYINFO_IID)
  • netwerk/base/src/nsSocketTransport2.cpp

    diff --git a/netwerk/base/src/nsSocketTransport2.cpp b/netwerk/base/src/nsSocketTransport2.cpp
    a b nsSocketOutputStream::AsyncWait(nsIOutpu 
    676676//-----------------------------------------------------------------------------
    677677// socket transport impl
    678678//-----------------------------------------------------------------------------
    679679
    680680nsSocketTransport::nsSocketTransport()
    681681    : mTypes(nullptr)
    682682    , mTypeCount(0)
    683683    , mPort(0)
    684     , mProxyPort(0)
     684    , mProxyUse(false)
    685685    , mProxyTransparent(false)
    686686    , mProxyTransparentResolvesHost(false)
    687687    , mConnectionFlags(0)
    688688    , mState(STATE_CLOSED)
    689689    , mAttached(false)
    690690    , mInputClosed(true)
    691691    , mOutputClosed(true)
    692692    , mResolving(false)
    nsSocketTransport::Init(const char **typ 
    736736
    737737    // init socket type info
    738738
    739739    mPort = port;
    740740    mHost = host;
    741741
    742742    const char *proxyType = nullptr;
    743743    if (proxyInfo) {
    744         mProxyPort = proxyInfo->Port();
    745         mProxyHost = proxyInfo->Host();
     744        mProxyInfo = proxyInfo;
    746745        // grab proxy type (looking for "socks" for example)
    747746        proxyType = proxyInfo->Type();
    748747        if (proxyType && (strcmp(proxyType, "http") == 0 ||
    749748                          strcmp(proxyType, "direct") == 0 ||
    750749                          strcmp(proxyType, "unknown") == 0))
    751750            proxyType = nullptr;
     751
     752        mProxyUse = true;
     753        // check that we don't have a proxyInfo without proxy
     754        nsCString proxyHost;
     755        proxyInfo->GetHost(proxyHost);
     756        if (!proxyType || proxyHost.IsEmpty()) {
     757            mProxyUse = false;
     758        }
    752759    }
    753760
    754     SOCKET_LOG(("nsSocketTransport::Init [this=%x host=%s:%hu proxy=%s:%hu]\n",
    755         this, mHost.get(), mPort, mProxyHost.get(), mProxyPort));
     761    SOCKET_LOG(("nsSocketTransport::Init [this=%x host=%s:%hu proxy=%s]\n",
     762        this, mHost.get(), mPort, mProxyUse ? "yes" : "no"));
    756763
    757764    // include proxy type as a socket type if proxy type is not "http"
    758765    mTypeCount = typeCount + (proxyType != nullptr);
    759766    if (!mTypeCount)
    760767        return NS_OK;
    761768
    762769    // if we have socket types, then the socket provider service had
    763770    // better exist!
    nsSocketTransport::SendStatus(nsresult s 
    887894
    888895nsresult
    889896nsSocketTransport::ResolveHost()
    890897{
    891898    SOCKET_LOG(("nsSocketTransport::ResolveHost [this=%x]\n", this));
    892899
    893900    nsresult rv;
    894901
    895     if (!mProxyHost.IsEmpty()) {
     902    if (mProxyUse) {
    896903        if (!mProxyTransparent || mProxyTransparentResolvesHost) {
    897904            // When not resolving mHost locally, we still want to ensure that
    898905            // it only contains valid characters.  See bug 304904 for details.
    899906            if (!net_IsValidHostName(mHost))
    900907                return NS_ERROR_UNKNOWN_HOST;
    901908        }
    902909        if (mProxyTransparentResolvesHost) {
    903910            // Name resolution is done on the server side.  Just pretend
    nsSocketTransport::BuildSocket(PRFileDes 
    952959        fd = nullptr;
    953960
    954961        nsCOMPtr<nsISocketProviderService> spserv =
    955962            do_GetService(kSocketProviderServiceCID, &rv);
    956963        if (NS_FAILED(rv)) return rv;
    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) {
    966972            nsCOMPtr<nsISocketProvider> provider;
    967973
    968974            SOCKET_LOG(("  pushing io layer [%u:%s]\n", i, mTypes[i]));
    969975
    970976            rv = spserv->GetSocketProvider(mTypes[i], getter_AddRefs(provider));
    nsSocketTransport::BuildSocket(PRFileDes 
    977983            if (mConnectionFlags & nsISocketTransport::ANONYMOUS_CONNECT)
    978984                proxyFlags |= nsISocketProvider::ANONYMOUS_CONNECT;
    979985
    980986            nsCOMPtr<nsISupports> secinfo;
    981987            if (i == 0) {
    982988                // if this is the first type, we'll want the
    983989                // service to allocate a new socket
    984990                rv = provider->NewSocket(mNetAddr.raw.family,
    985                                          host, port, proxyHost, proxyPort,
     991                                         host, port, proxy,
    986992                                         proxyFlags, &fd,
    987993                                         getter_AddRefs(secinfo));
    988994
    989995                if (NS_SUCCEEDED(rv) && !fd) {
    990996                    NS_NOTREACHED("NewSocket succeeded but failed to create a PRFileDesc");
    991997                    rv = NS_ERROR_UNEXPECTED;
    992998                }
    993999            }
    9941000            else {
    9951001                // the socket has already been allocated,
    9961002                // so we just want the service to add itself
    9971003                // to the stack (such as pushing an io layer)
    9981004                rv = provider->AddToSocket(mNetAddr.raw.family,
    999                                            host, port, proxyHost, proxyPort,
     1005                                           host, port, proxy,
    10001006                                           proxyFlags, fd,
    10011007                                           getter_AddRefs(secinfo));
    10021008            }
    10031009            // proxyFlags = 0; not used below this point...
    10041010            if (NS_FAILED(rv))
    10051011                break;
    10061012
    10071013            // if the service was ssl or starttls, we want to hold onto the socket info
    nsSocketTransport::BuildSocket(PRFileDes 
    10211027                    secCtrl->SetNotificationCallbacks(callbacks);
    10221028                // remember if socket type is SSL so we can ProxyStartSSL if need be.
    10231029                usingSSL = isSSL;
    10241030            }
    10251031            else if ((strcmp(mTypes[i], "socks") == 0) ||
    10261032                     (strcmp(mTypes[i], "socks4") == 0)) {
    10271033                // since socks is transparent, any layers above
    10281034                // it do not have to worry about proxy stuff
    1029                 proxyHost = nullptr;
    1030                 proxyPort = -1;
     1035                proxy = nullptr;
    10311036                proxyTransparent = true;
    10321037            }
    10331038        }
    10341039
    10351040        if (NS_FAILED(rv)) {
    10361041            SOCKET_LOG(("  error pushing io layer [%u:%s rv=%x]\n", i, mTypes[i], rv));
    10371042            if (fd)
    10381043                PR_Close(fd);
    nsSocketTransport::InitiateSocket() 
    11861191        // If the socket is already connected, then return success...
    11871192        //
    11881193        else if (PR_IS_CONNECTED_ERROR == code) {
    11891194            //
    11901195            // we are connected!
    11911196            //
    11921197            OnSocketConnected();
    11931198
    1194             if (mSecInfo && !mProxyHost.IsEmpty() && proxyTransparent && usingSSL) {
     1199            if (mSecInfo && mProxyUse && proxyTransparent && usingSSL) {
    11951200                // if the connection phase is finished, and the ssl layer has
    11961201                // been pushed, and we were proxying (transparently; ie. nothing
    11971202                // has to happen in the protocol layer above us), it's time for
    11981203                // the ssl to start doing it's thing.
    11991204                nsCOMPtr<nsISSLSocketControl> secCtrl =
    12001205                    do_QueryInterface(mSecInfo);
    12011206                if (secCtrl) {
    12021207                    SOCKET_LOG(("  calling ProxyStartSSL()\n"));
    nsSocketTransport::InitiateSocket() 
    12101215                // isn't this broken?
    12111216            }
    12121217        }
    12131218        //
    12141219        // A SOCKS request was rejected; get the actual error code from
    12151220        // the OS error
    12161221        //
    12171222        else if (PR_UNKNOWN_ERROR == code &&
    1218                  mProxyTransparent &&
    1219                  !mProxyHost.IsEmpty()) {
     1223                 mProxyUse && mProxyTransparent) {
    12201224            code = PR_GetOSError();
    12211225            rv = ErrorAccordingToNSPR(code);
    12221226        }
    12231227        //
    12241228        // The connection was refused...
    12251229        //
    12261230        else {
    12271231            rv = ErrorAccordingToNSPR(code);
    1228             if ((rv == NS_ERROR_CONNECTION_REFUSED) && !mProxyHost.IsEmpty())
     1232            if (rv == NS_ERROR_CONNECTION_REFUSED && mProxyUse)
    12291233                rv = NS_ERROR_PROXY_CONNECTION_REFUSED;
    12301234        }
    12311235    }
    12321236    return rv;
    12331237}
    12341238
    12351239bool
    12361240nsSocketTransport::RecoverFromError()
    nsSocketTransport::OnSocketEvent(uint32_ 
    14621466        }
    14631467        // status contains DNS lookup status
    14641468        if (NS_FAILED(status)) {
    14651469            // When using a HTTP proxy, NS_ERROR_UNKNOWN_HOST means the HTTP
    14661470            // proxy host is not found, so we fixup the error code.
    14671471            // For SOCKS proxies (mProxyTransparent == true), the socket
    14681472            // transport resolves the real host here, so there's no fixup
    14691473            // (see bug 226943).
    1470             if ((status == NS_ERROR_UNKNOWN_HOST) && !mProxyTransparent &&
    1471                 !mProxyHost.IsEmpty())
     1474            if (status == NS_ERROR_UNKNOWN_HOST && !mProxyTransparent &&
     1475                mProxyUse)
    14721476                mCondition = NS_ERROR_UNKNOWN_PROXY_HOST;
    14731477            else
    14741478                mCondition = status;
    14751479        }
    14761480        else if (mState == STATE_RESOLVING)
    14771481            mCondition = InitiateSocket();
    14781482        break;
    14791483
    nsSocketTransport::OnSocketReady(PRFileD 
    15721576                mPollFlags = (PR_POLL_EXCEPT | PR_POLL_WRITE);
    15731577                // Update poll timeout in case it was changed
    15741578                mPollTimeout = mTimeouts[TIMEOUT_CONNECT];
    15751579            }
    15761580            //
    15771581            // The SOCKS proxy rejected our request. Find out why.
    15781582            //
    15791583            else if (PR_UNKNOWN_ERROR == code &&
    1580                      mProxyTransparent &&
    1581                      !mProxyHost.IsEmpty()) {
     1584                     mProxyUse && mProxyTransparent) {
    15821585                code = PR_GetOSError();
    15831586                mCondition = ErrorAccordingToNSPR(code);
    15841587            }
    15851588            else {
    15861589                //
    15871590                // else, the connection failed...
    15881591                //
    15891592                mCondition = ErrorAccordingToNSPR(code);
    1590                 if ((mCondition == NS_ERROR_CONNECTION_REFUSED) && !mProxyHost.IsEmpty())
     1593                if (mCondition == NS_ERROR_CONNECTION_REFUSED && mProxyUse)
    15911594                    mCondition = NS_ERROR_PROXY_CONNECTION_REFUSED;
    15921595                SOCKET_LOG(("  connection failed! [reason=%x]\n", mCondition));
    15931596            }
    15941597        }
    15951598    }
    15961599    else {
    15971600        NS_ERROR("unexpected socket state");
    15981601        mCondition = NS_ERROR_UNEXPECTED;
    nsSocketTransport::GetHost(nsACString &h 
    18921895
    18931896NS_IMETHODIMP
    18941897nsSocketTransport::GetPort(int32_t *port)
    18951898{
    18961899    *port = (int32_t) SocketPort();
    18971900    return NS_OK;
    18981901}
    18991902
     1903const nsCString &
     1904nsSocketTransport::SocketHost()
     1905{
     1906  if (mProxyInfo && !mProxyTransparent) {
     1907    if (mProxyHostCache.IsEmpty()) { // TODO cache necessary?
     1908      mProxyInfo->GetHost(mProxyHostCache);
     1909    }
     1910    return mProxyHostCache;
     1911  }
     1912  else
     1913    return mHost;
     1914}
     1915
     1916uint16_t
     1917nsSocketTransport::SocketPort()
     1918{
     1919  if (mProxyInfo && !mProxyTransparent) {
     1920    int32_t result;
     1921    mProxyInfo->GetPort(&result);
     1922    return (uint16_t) result; // TODO why doesn't SocketPort() return int32_t?
     1923  }
     1924  else
     1925    return mPort;
     1926}
     1927
    19001928NS_IMETHODIMP
    19011929nsSocketTransport::GetPeerAddr(PRNetAddr *addr)
    19021930{
    19031931    // once we are in the connected state, mNetAddr will not change.
    19041932    // so if we can verify that we are in the connected state, then
    19051933    // we can freely access mNetAddr from any thread without being
    19061934    // inside a critical section.
    19071935
  • netwerk/base/src/nsSocketTransport2.h

    diff --git a/netwerk/base/src/nsSocketTransport2.h b/netwerk/base/src/nsSocketTransport2.h
    a b private: 
    162162    // these members are "set" at initialization time and are never modified
    163163    // afterwards.  this allows them to be safely accessed from any thread.
    164164    //-------------------------------------------------------------------------
    165165
    166166    // socket type info:
    167167    char       **mTypes;
    168168    uint32_t     mTypeCount;
    169169    nsCString    mHost;
    170     nsCString    mProxyHost;
    171170    uint16_t     mPort;
    172     uint16_t     mProxyPort;
    173     bool mProxyTransparent;
    174     bool mProxyTransparentResolvesHost;
     171    nsCOMPtr<nsIProxyInfo> mProxyInfo;
     172    bool         mProxyUse;
     173    bool         mProxyTransparent;
     174    bool         mProxyTransparentResolvesHost;
    175175    uint32_t     mConnectionFlags;
    176176   
    177     uint16_t         SocketPort() { return (!mProxyHost.IsEmpty() && !mProxyTransparent) ? mProxyPort : mPort; }
    178     const nsCString &SocketHost() { return (!mProxyHost.IsEmpty() && !mProxyTransparent) ? mProxyHost : mHost; }
     177    uint16_t         SocketPort();
     178    const nsCString &SocketHost();
     179    nsCString        mProxyHostCache; // for SocketHost() only
    179180
    180181    //-------------------------------------------------------------------------
    181182    // members accessible only on the socket transport thread:
    182183    //  (the exception being initialization/shutdown time)
    183184    //-------------------------------------------------------------------------
    184185
    185186    // socket state vars:
    186187    uint32_t     mState;     // STATE_??? flags
  • netwerk/socket/nsISocketProvider.idl

    diff --git a/netwerk/socket/nsISocketProvider.idl b/netwerk/socket/nsISocketProvider.idl
    a b  
    11/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
    22/* This Source Code Form is subject to the terms of the Mozilla Public
    33 * License, v. 2.0. If a copy of the MPL was not distributed with this
    44 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
    55
    66#include "nsISupports.idl"
    77
     8interface nsIProxyInfo;
    89[ptr] native PRFileDescStar(struct PRFileDesc);
    910
    1011/**
    1112 * nsISocketProvider
    1213 */
    1314[scriptable, uuid(00b3df92-e830-11d8-d48e-0004e22243f8)]
    1415interface nsISocketProvider : nsISupports
    1516{
    interface nsISocketProvider : nsISupport 
    3334     * @param aSecurityInfo
    3435     *        Any security info that should be associated with aFileDesc.  This
    3536     *        object typically implements nsITransportSecurityInfo.
    3637     */
    3738    [noscript]
    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);
    4646
    4747    /**
    4848     * addToSocket
    4949     *
    5050     * This function is called to allow the socket provider to layer a
    interface nsISocketProvider : nsISupport 
    5353     *
    5454     * Parameters are the same as newSocket with the exception of aFileDesc,
    5555     * which is an in-param instead.
    5656     */
    5757    [noscript]
    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);
    6665
    6766    /**
    6867     * PROXY_RESOLVES_HOST
    6968     *
    7069     * This flag is set if the proxy is to perform hostname resolution instead
  • netwerk/socket/nsSOCKSIOLayer.cpp

    diff --git a/netwerk/socket/nsSOCKSIOLayer.cpp b/netwerk/socket/nsSOCKSIOLayer.cpp
    a b class nsSOCKSSocketInfo : public nsISOCK 
    4242        SOCKS_INITIAL,
    4343        SOCKS_DNS_IN_PROGRESS,
    4444        SOCKS_DNS_COMPLETE,
    4545        SOCKS_CONNECTING_TO_PROXY,
    4646        SOCKS4_WRITE_CONNECT_REQUEST,
    4747        SOCKS4_READ_CONNECT_RESPONSE,
    4848        SOCKS5_WRITE_AUTH_REQUEST,
    4949        SOCKS5_READ_AUTH_RESPONSE,
     50        SOCKS5_WRITE_USERNAME_REQUEST,
     51        SOCKS5_READ_USERNAME_RESPONSE,
    5052        SOCKS5_WRITE_CONNECT_REQUEST,
    5153        SOCKS5_READ_CONNECT_RESPONSE_TOP,
    5254        SOCKS5_READ_CONNECT_RESPONSE_BOTTOM,
    5355        SOCKS_CONNECTED,
    5456        SOCKS_FAILED
    5557    };
    5658
    5759    // A buffer of 262 bytes should be enough for any request and response
    public: 
    6466    virtual ~nsSOCKSSocketInfo() { HandshakeFinished(); }
    6567
    6668    NS_DECL_ISUPPORTS
    6769    NS_DECL_NSISOCKSSOCKETINFO
    6870    NS_DECL_NSIDNSLISTENER
    6971
    7072    void Init(int32_t version,
    7173              int32_t family,
    72               const char *proxyHost,
    73               int32_t proxyPort,
     74              nsIProxyInfo *proxy,
    7475              const char *destinationHost,
    7576              uint32_t flags);
    7677
    7778    void SetConnectTimeout(PRIntervalTime to);
    7879    PRStatus DoHandshake(PRFileDesc *fd, int16_t oflags = -1);
    7980    int16_t GetPollFlags() const;
    8081    bool IsConnected() const { return mState == SOCKS_CONNECTED; }
    8182
    private: 
    8485    PRStatus StartDNS(PRFileDesc *fd);
    8586    PRStatus ConnectToProxy(PRFileDesc *fd);
    8687    void FixupAddressFamily(PRFileDesc *fd, PRNetAddr *proxy);
    8788    PRStatus ContinueConnectingToProxy(PRFileDesc *fd, int16_t oflags);
    8889    PRStatus WriteV4ConnectRequest();
    8990    PRStatus ReadV4ConnectResponse();
    9091    PRStatus WriteV5AuthRequest();
    9192    PRStatus ReadV5AuthResponse();
     93    PRStatus WriteV5UsernameRequest();
     94    PRStatus ReadV5UsernameResponse();
    9295    PRStatus WriteV5ConnectRequest();
    9396    PRStatus ReadV5AddrTypeAndLength(uint8_t *type, uint32_t *len);
    9497    PRStatus ReadV5ConnectResponseTop();
    9598    PRStatus ReadV5ConnectResponseBottom();
    9699
    97100    void WriteUint8(uint8_t d);
    98101    void WriteUint16(uint16_t d);
    99102    void WriteUint32(uint32_t d);
    private: 
    119122    uint32_t  mReadOffset;
    120123    uint32_t  mAmountToRead;
    121124    nsCOMPtr<nsIDNSRecord>  mDnsRec;
    122125    nsCOMPtr<nsICancelable> mLookup;
    123126    nsresult                mLookupStatus;
    124127    PRFileDesc             *mFD;
    125128
    126129    nsCString mDestinationHost;
    127     nsCString mProxyHost;
    128     int32_t   mProxyPort;
     130    nsCOMPtr<nsIProxyInfo> mProxy;
    129131    int32_t   mVersion;   // SOCKS version 4 or 5
    130132    int32_t   mDestinationFamily;
    131133    uint32_t  mFlags;
    132134    PRNetAddr mInternalProxyAddr;
    133135    PRNetAddr mExternalProxyAddr;
    134136    PRNetAddr mDestinationAddr;
    135137    PRIntervalTime mTimeout;
     138    nsCString mProxyUsername; // Cache, from mProxy
    136139};
    137140
    138141nsSOCKSSocketInfo::nsSOCKSSocketInfo()
    139142    : mState(SOCKS_INITIAL)
    140143    , mDataIoPtr(nullptr)
    141144    , mDataLength(0)
    142145    , mReadOffset(0)
    143146    , mAmountToRead(0)
    144     , mProxyPort(-1)
    145147    , mVersion(-1)
    146148    , mDestinationFamily(PR_AF_INET)
    147149    , mFlags(0)
    148150    , mTimeout(PR_INTERVAL_NO_TIMEOUT)
    149151{
    150152    mData = new uint8_t[BUFFER_SIZE];
    151153    PR_InitializeNetAddr(PR_IpAddrAny, 0, &mInternalProxyAddr);
    152154    PR_InitializeNetAddr(PR_IpAddrAny, 0, &mExternalProxyAddr);
    153155    PR_InitializeNetAddr(PR_IpAddrAny, 0, &mDestinationAddr);
    154156}
    155157
    156158void
    157 nsSOCKSSocketInfo::Init(int32_t version, int32_t family, const char *proxyHost, int32_t proxyPort, const char *host, uint32_t flags)
     159nsSOCKSSocketInfo::Init(int32_t version, int32_t family, nsIProxyInfo *proxy, const char *host, uint32_t flags)
    158160{
    159161    mVersion         = version;
    160162    mDestinationFamily = family;
    161     mProxyHost       = proxyHost;
    162     mProxyPort       = proxyPort;
     163    mProxy           = proxy;
    163164    mDestinationHost = host;
    164165    mFlags           = flags;
     166    mProxy->GetUsername(mProxyUsername); // cache
    165167}
    166168
    167169NS_IMPL_THREADSAFE_ISUPPORTS2(nsSOCKSSocketInfo, nsISOCKSSocketInfo, nsIDNSListener)
    168170
    169171NS_IMETHODIMP
    170172nsSOCKSSocketInfo::GetExternalProxyAddr(PRNetAddr * *aExternalProxyAddr)
    171173{
    172174    memcpy(*aExternalProxyAddr, &mExternalProxyAddr, sizeof(PRNetAddr));
    nsSOCKSSocketInfo::StartDNS(PRFileDesc * 
    243245{
    244246    NS_ABORT_IF_FALSE(!mDnsRec && mState == SOCKS_INITIAL,
    245247                      "Must be in initial state to make DNS Lookup");
    246248
    247249    nsCOMPtr<nsIDNSService> dns = do_GetService(NS_DNSSERVICE_CONTRACTID);
    248250    if (!dns)
    249251        return PR_FAILURE;
    250252
     253    nsCString proxyHost;
     254    mProxy->GetHost(proxyHost);
     255
    251256    mFD  = fd;
    252     nsresult rv = dns->AsyncResolve(mProxyHost, 0, this,
     257    nsresult rv = dns->AsyncResolve(proxyHost, 0, this,
    253258                                    NS_GetCurrentThread(),
    254259                                    getter_AddRefs(mLookup));
    255260
    256261    if (NS_FAILED(rv)) {
    257262        LOGERROR(("socks: DNS lookup for SOCKS proxy %s failed",
    258                   mProxyHost.get()));
     263                  proxyHost.get()));
    259264        return PR_FAILURE;
    260265    }
    261266    mState = SOCKS_DNS_IN_PROGRESS;
    262267    PR_SetError(PR_IN_PROGRESS_ERROR, 0);
    263268    return PR_FAILURE;
    264269}
    265270
    266271NS_IMETHODIMP
    nsSOCKSSocketInfo::ConnectToProxy(PRFile 
    293298    }
    294299
    295300    // Try socks5 if the destination addrress is IPv6
    296301    if (mVersion == 4 &&
    297302        PR_NetAddrFamily(&mDestinationAddr) == PR_AF_INET6) {
    298303        mVersion = 5;
    299304    }
    300305
     306    int32_t proxyPort;
     307    mProxy->GetPort(&proxyPort);
     308
    301309    int32_t addresses = 0;
    302310    do {
    303311        if (addresses++)
    304             mDnsRec->ReportUnusable(mProxyPort);
     312            mDnsRec->ReportUnusable(proxyPort);
    305313       
    306         rv = mDnsRec->GetNextAddr(mProxyPort, &mInternalProxyAddr);
     314        rv = mDnsRec->GetNextAddr(proxyPort, &mInternalProxyAddr);
    307315        // No more addresses to try? If so, we'll need to bail
    308316        if (NS_FAILED(rv)) {
     317            nsCString proxyHost;
     318            mProxy->GetHost(proxyHost);
    309319            LOGERROR(("socks: unable to connect to SOCKS proxy, %s",
    310                      mProxyHost.get()));
     320                     proxyHost.get()));
    311321            return PR_FAILURE;
    312322        }
    313323
    314324#if defined(PR_LOGGING)
    315325        char buf[64];
    316326        PR_NetAddrToString(&mInternalProxyAddr, buf, sizeof(buf));
    317327        LOGDEBUG(("socks: trying proxy server, %s:%hu",
    318328                 buf, PR_ntohs(PR_NetAddrInetPort(&mInternalProxyAddr))));
    nsSOCKSSocketInfo::WriteV4ConnectRequest 
    441451    WriteNetPort(addr);
    442452    if (proxy_resolve) {
    443453        // Add the full name, null-terminated, to the request
    444454        // according to SOCKS 4a. A fake IP address, with the first
    445455        // four bytes set to 0 and the last byte set to something other
    446456        // than 0, is used to notify the proxy that this is a SOCKS 4a
    447457        // request. This request type works for Tor and perhaps others.
    448458        WriteUint32(PR_htonl(0x00000001)); // Fake IP
    449         WriteUint8(0x00); // Send an emtpy username
     459        WriteString(mProxyUsername); // Send username. May be empty.
     460        WriteUint8(0x00); // Null-terminate username
     461        // Password not supported by V4.
    450462        if (mDestinationHost.Length() > MAX_HOSTNAME_LEN) {
    451463            LOGERROR(("socks4: destination host name is too long!"));
    452464            HandshakeFinished(PR_BAD_ADDRESS_ERROR);
    453465            return PR_FAILURE;
    454466        }
    455467        WriteString(mDestinationHost); // Hostname
    456468        WriteUint8(0x00);
    457469    } else if (PR_NetAddrFamily(addr) == PR_AF_INET) {
    458470        WriteNetAddr(addr); // Add the IPv4 address
    459         WriteUint8(0x00); // Send an emtpy username
     471        WriteString(mProxyUsername); // Send username. May be empty.
     472        WriteUint8(0x00); // Null-terminate username
     473        // Password not supported by V4.
    460474    } else if (PR_NetAddrFamily(addr) == PR_AF_INET6) {
    461475        LOGERROR(("socks: SOCKS 4 can't handle IPv6 addresses!"));
    462476        HandshakeFinished(PR_BAD_ADDRESS_ERROR);
    463477        return PR_FAILURE;
    464478    }
    465479
    466480    return PR_SUCCESS;
    467481}
    nsSOCKSSocketInfo::ReadV4ConnectResponse 
    494508    return PR_FAILURE;
    495509}
    496510
    497511PRStatus
    498512nsSOCKSSocketInfo::WriteV5AuthRequest()
    499513{
    500514    NS_ABORT_IF_FALSE(mVersion == 5, "SOCKS version must be 5!");
    501515
     516    mDataLength = 0;
    502517    mState = SOCKS5_WRITE_AUTH_REQUEST;
    503518
    504519    // Send an initial SOCKS 5 greeting
    505520    LOGDEBUG(("socks5: sending auth methods"));
    506521    WriteUint8(0x05); // version -- 5
    507     WriteUint8(0x01); // # auth methods -- 1
    508     WriteUint8(0x00); // we don't support authentication
     522    WriteUint8(0x01); // # of auth methods -- 1
     523    if (mProxyUsername.IsEmpty()) {
     524      WriteUint8(0x00); // no authentication
     525    } else {
     526      WriteUint8(0x02); // username/password
     527    }
    509528
    510529    return PR_SUCCESS;
    511530}
    512531
    513532PRStatus
    514533nsSOCKSSocketInfo::ReadV5AuthResponse()
    515534{
    516535    NS_ABORT_IF_FALSE(mState == SOCKS5_READ_AUTH_RESPONSE,
    517536                      "Handling SOCKS 5 auth method reply in wrong state!");
    518537    NS_ABORT_IF_FALSE(mDataLength == 2,
    519538                      "SOCKS 5 auth method reply must be 2 bytes!");
    520539
    521     LOGDEBUG(("socks5: checking auth method reply"));
    522 
    523540    // Check version number
    524541    if (ReadUint8() != 0x05) {
    525542        LOGERROR(("socks5: unexpected version in the reply"));
    526543        HandshakeFinished(PR_CONNECT_REFUSED_ERROR);
    527544        return PR_FAILURE;
    528545    }
    529546
    530     // Make sure our authentication choice was accepted
    531     if (ReadUint8() != 0x00) {
     547    // Make sure our authentication choice was accepted,
     548    // and continue accordingly
     549    uint8_t authMethod = ReadUint8();
     550    if (mProxyUsername.IsEmpty() && authMethod == 0x00) { // no auth
     551        LOGDEBUG(("socks5: server allows connection without authentication"));
     552        return WriteV5ConnectRequest();
     553    } else if (!mProxyUsername.IsEmpty() && authMethod == 0x02) { // username/pw
     554        LOGDEBUG(("socks5: auth method accepted by server"));
     555        return WriteV5UsernameRequest();
     556    } else { // 0xFF signals error
    532557        LOGERROR(("socks5: server did not accept our authentication method"));
    533558        HandshakeFinished(PR_CONNECT_REFUSED_ERROR);
    534559        return PR_FAILURE;
    535560    }
     561}
    536562
    537     return WriteV5ConnectRequest();
     563PRStatus
     564nsSOCKSSocketInfo::WriteV5UsernameRequest()
     565{
     566    NS_ABORT_IF_FALSE(mVersion == 5, "SOCKS version must be 5!");
     567
     568    mDataLength = 0;
     569    mState = SOCKS5_WRITE_USERNAME_REQUEST;
     570
     571    LOGDEBUG(("socks5: sending username and password"));
     572    // RFC 1929 Username/password auth for SOCKS 5
     573    printf("%s\n", "socks5: sending username and password");
     574    printf("version %d\n", 0x01);
     575    WriteUint8(0x01); // version 1 (not 5)
     576    printf("username length %d\n", mProxyUsername.Length());
     577    WriteUint8(mProxyUsername.Length()); // username length
     578    printf("username %s\n", mProxyUsername.get());
     579    WriteString(mProxyUsername); // username
     580    nsCString password;
     581    mProxy->GetPassword(password);
     582    printf("password length %d\n", password.Length());
     583    WriteUint8(password.Length()); // password length
     584    printf("password %s\n", password.get());
     585    WriteString(password); // password. WARNING: Sent unencrypted!
     586
     587    return PR_SUCCESS;
     588}
     589
     590PRStatus
     591nsSOCKSSocketInfo::ReadV5UsernameResponse()
     592{
     593    printf("%s\n", "socks5: username response");
     594    NS_ABORT_IF_FALSE(mState == SOCKS5_READ_USERNAME_RESPONSE,
     595                      "Handling SOCKS 5 username/password reply in wrong state!");
     596    NS_ABORT_IF_FALSE(mDataLength == 2,
     597                      "SOCKS 5 username reply must be 2 bytes!");
     598
     599    // Check version number, must be 1 (not 5)
     600    if (ReadUint8() != 0x01) {
     601        printf("%s\n", "socks5: wrong version");
     602        LOGERROR(("socks5: unexpected version in the reply"));
     603        HandshakeFinished(PR_CONNECT_REFUSED_ERROR);
     604        return PR_FAILURE;
     605    }
     606
     607    // Check whether username/password were accepted
     608    if (ReadUint8() != 0x00) { // 0 = success
     609        printf("%s\n", "socks5: user rejected");
     610        LOGERROR(("socks5: username/password not accepted"));
     611        HandshakeFinished(PR_CONNECT_REFUSED_ERROR);
     612        return PR_FAILURE;
     613    }
     614    printf("%s\n", "socks5: user accepted rejected");
     615
     616    LOGDEBUG(("socks5: username/password accepted by server"));
     617
     618    return WriteV5UsernameRequest();
    538619}
    539620
    540621PRStatus
    541622nsSOCKSSocketInfo::WriteV5ConnectRequest()
    542623{
    543624    // Send SOCKS 5 connect request
    544625    PRNetAddr *addr = &mDestinationAddr;
    545626    int32_t proxy_resolve;
    nsSOCKSSocketInfo::DoHandshake(PRFileDes 
    771852                return PR_FAILURE;
    772853            WantRead(2);
    773854            mState = SOCKS5_READ_AUTH_RESPONSE;
    774855            return PR_SUCCESS;
    775856        case SOCKS5_READ_AUTH_RESPONSE:
    776857            if (ReadFromSocket(fd) != PR_SUCCESS)
    777858                return PR_FAILURE;
    778859            return ReadV5AuthResponse();
     860        case SOCKS5_WRITE_USERNAME_REQUEST:
     861            if (WriteToSocket(fd) != PR_SUCCESS)
     862                return PR_FAILURE;
     863            WantRead(2);
     864            mState = SOCKS5_READ_USERNAME_RESPONSE;
     865            return PR_SUCCESS;
     866        case SOCKS5_READ_USERNAME_RESPONSE:
     867            if (ReadFromSocket(fd) != PR_SUCCESS)
     868                return PR_FAILURE;
     869            return ReadV5UsernameResponse();
    779870        case SOCKS5_WRITE_CONNECT_REQUEST:
    780871            if (WriteToSocket(fd) != PR_SUCCESS)
    781872                return PR_FAILURE;
    782873
    783874            // The SOCKS 5 response to the connection request is variable
    784875            // length. First, we'll read enough to tell how long the response
    785876            // is, and will read the rest later.
    786877            WantRead(5);
    nsSOCKSIOLayerListen(PRFileDesc *fd, int 
    11861277    return fd->lower->methods->listen(fd->lower, backlog);
    11871278}
    11881279
    11891280// add SOCKS IO layer to an existing socket
    11901281nsresult
    11911282nsSOCKSIOLayerAddToSocket(int32_t family,
    11921283                          const char *host,
    11931284                          int32_t port,
    1194                           const char *proxyHost,
    1195                           int32_t proxyPort,
     1285                          nsIProxyInfo *proxy,
    11961286                          int32_t socksVersion,
    11971287                          uint32_t flags,
    11981288                          PRFileDesc *fd,
    11991289                          nsISupports** info)
    12001290{
    12011291    NS_ENSURE_TRUE((socksVersion == 4) || (socksVersion == 5), NS_ERROR_NOT_INITIALIZED);
    12021292
    12031293
    nsSOCKSIOLayerAddToSocket(int32_t family 
    12541344    {
    12551345        // clean up IOLayerStub
    12561346        LOGERROR(("Failed to create nsSOCKSSocketInfo()."));
    12571347        PR_DELETE(layer);
    12581348        return NS_ERROR_FAILURE;
    12591349    }
    12601350
    12611351    NS_ADDREF(infoObject);
    1262     infoObject->Init(socksVersion, family, proxyHost, proxyPort, host, flags);
     1352    infoObject->Init(socksVersion, family, proxy, host, flags);
    12631353    layer->secret = (PRFilePrivate*) infoObject;
    12641354    rv = PR_PushIOLayer(fd, PR_GetLayersIdentity(fd), layer);
    12651355
    12661356    if (rv == PR_FAILURE) {
    12671357        LOGERROR(("PR_PushIOLayer() failed. rv = %x.", rv));
    12681358        NS_RELEASE(infoObject);
    12691359        PR_DELETE(layer);
    12701360        return NS_ERROR_FAILURE;
  • netwerk/socket/nsSOCKSIOLayer.h

    diff --git a/netwerk/socket/nsSOCKSIOLayer.h b/netwerk/socket/nsSOCKSIOLayer.h
    a b  
    55 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
    66
    77#ifndef nsSOCKSIOLayer_h__
    88#define nsSOCKSIOLayer_h__
    99
    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,
    2222                                   nsISupports **info);
    2323
    2424#endif /* nsSOCKSIOLayer_h__ */
  • netwerk/socket/nsSOCKSSocketProvider.cpp

    diff --git a/netwerk/socket/nsSOCKSSocketProvider.cpp b/netwerk/socket/nsSOCKSSocketProvider.cpp
    a b nsSOCKSSocketProvider::CreateV5(nsISuppo 
    3939        rv = inst->QueryInterface(aIID, aResult);
    4040    return rv;
    4141}
    4242
    4343NS_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)
    5251{
    5352    PRFileDesc *sock;
    5453   
    5554    sock = PR_OpenTCPSocket(family);
    5655    if (!sock)
    5756        return NS_ERROR_OUT_OF_MEMORY;
    5857
    5958    nsresult rv = nsSOCKSIOLayerAddToSocket(family,
    6059                                            host,
    6160                                            port,
    62                                             proxyHost,
    63                                             proxyPort,
     61                                            proxy,
    6462                                            mVersion,
    6563                                            flags,
    6664                                            sock,
    6765                                            socksInfo);
    6866    if (NS_SUCCEEDED(rv)) {
    6967        *result = sock;
    7068        return NS_OK;
    7169    }
    7270
    7371    return NS_ERROR_SOCKET_CREATE_FAILED;
    7472}
    7573
    7674NS_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)
    8582{
    8683    nsresult rv = nsSOCKSIOLayerAddToSocket(family,
    8784                                            host,
    8885                                            port,
    89                                             proxyHost,
    90                                             proxyPort,
     86                                            proxy,
    9187                                            mVersion,
    9288                                            flags,
    9389                                            sock,
    9490                                            socksInfo);
    9591   
    9692    if (NS_FAILED(rv))
    9793        rv = NS_ERROR_SOCKET_CREATE_FAILED;
    9894    return rv;
  • netwerk/socket/nsUDPSocketProvider.cpp

    diff --git a/netwerk/socket/nsUDPSocketProvider.cpp b/netwerk/socket/nsUDPSocketProvider.cpp
    a b NS_IMPL_THREADSAFE_ISUPPORTS1(nsUDPSocke 
    1111nsUDPSocketProvider::~nsUDPSocketProvider()
    1212{
    1313}
    1414
    1515NS_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)
    2423{
    2524    NS_ENSURE_ARG_POINTER(aFileDesc);
    2625 
    2726    PRFileDesc* udpFD = PR_OpenUDPSocket(aFamily);
    2827    if (!udpFD)
    nsUDPSocketProvider::NewSocket(int32_t a 
    3130    *aFileDesc = udpFD;
    3231    return NS_OK;
    3332}
    3433
    3534NS_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)
    4442{
    4543    // does not make sense to strap a UDP socket onto an existing socket
    4644    NS_NOTREACHED("Cannot layer UDP socket on an existing socket");
    4745    return NS_ERROR_UNEXPECTED;
    4846}
  • security/manager/ssl/src/nsNSSIOLayer.cpp

    diff --git a/security/manager/ssl/src/nsNSSIOLayer.cpp b/security/manager/ssl/src/nsNSSIOLayer.cpp
    a b int32_t nsSSLIOLayerHelpers::getWarnLeve 
    13111311  MutexAutoLock lock(*mutex);
    13121312  return mWarnLevelMissingRFC5746;
    13131313}
    13141314
    13151315nsresult
    13161316nsSSLIOLayerNewSocket(int32_t family,
    13171317                      const char *host,
    13181318                      int32_t port,
    1319                       const char *proxyHost,
    1320                       int32_t proxyPort,
     1319                      nsIProxyInfo *proxy,
    13211320                      PRFileDesc **fd,
    13221321                      nsISupports** info,
    13231322                      bool forSTARTTLS,
    13241323                      bool anonymousLoad)
    13251324{
    13261325
    13271326  PRFileDesc* sock = PR_OpenTCPSocket(family);
    13281327  if (!sock) return NS_ERROR_OUT_OF_MEMORY;
    13291328
    1330   nsresult rv = nsSSLIOLayerAddToSocket(family, host, port, proxyHost, proxyPort,
     1329  nsresult rv = nsSSLIOLayerAddToSocket(family, host, port, proxy,
    13311330                                        sock, info, forSTARTTLS, anonymousLoad);
    13321331  if (NS_FAILED(rv)) {
    13331332    PR_Close(sock);
    13341333    return rv;
    13351334  }
    13361335
    13371336  *fd = sock;
    13381337  return NS_OK;
    loser: 
    23532352  if (sslSock) {
    23542353    PR_Close(sslSock);
    23552354  }
    23562355  return nullptr;
    23572356}
    23582357
    23592358static nsresult
    23602359nsSSLIOLayerSetOptions(PRFileDesc *fd, bool forSTARTTLS,
    2361                        const char *proxyHost, const char *host, int32_t port,
     2360                       bool haveProxy, const char *host, int32_t port,
    23622361                       bool anonymousLoad, nsNSSSocketInfo *infoObject)
    23632362{
    23642363  nsNSSShutDownPreventionLock locker;
    2365   if (forSTARTTLS || proxyHost) {
     2364  if (forSTARTTLS || haveProxy) {
    23662365    if (SECSuccess != SSL_OptionSet(fd, SSL_SECURITY, false)) {
    23672366      return NS_ERROR_FAILURE;
    23682367    }
    23692368    infoObject->SetHasCleartextPhase(true);
    23702369  }
    23712370
    23722371  // Let's see if we're trying to connect to a site we know is
    23732372  // TLS intolerant.
    nsSSLIOLayerSetOptions(PRFileDesc *fd, b 
    24272426  PR_smprintf_free(peerId);
    24282427  return NS_OK;
    24292428}
    24302429
    24312430nsresult
    24322431nsSSLIOLayerAddToSocket(int32_t family,
    24332432                        const char* host,
    24342433                        int32_t port,
    2435                         const char* proxyHost,
    2436                         int32_t proxyPort,
     2434                        nsIProxyInfo* proxy,
    24372435                        PRFileDesc* fd,
    24382436                        nsISupports** info,
    24392437                        bool forSTARTTLS,
    24402438                        bool anonymousLoad)
    24412439{
    24422440  nsNSSShutDownPreventionLock locker;
    24432441  PRFileDesc* layer = nullptr;
    24442442  nsresult rv;
    nsSSLIOLayerAddToSocket(int32_t family, 
    24472445  nsNSSSocketInfo* infoObject = new nsNSSSocketInfo();
    24482446  if (!infoObject) return NS_ERROR_FAILURE;
    24492447 
    24502448  NS_ADDREF(infoObject);
    24512449  infoObject->SetForSTARTTLS(forSTARTTLS);
    24522450  infoObject->SetHostName(host);
    24532451  infoObject->SetPort(port);
    24542452
     2453  bool haveProxy = false;
     2454  if (proxy) {
     2455    nsCString proxyHost;
     2456    proxy->GetHost(proxyHost);
     2457    haveProxy = !proxyHost.IsEmpty();
     2458  }
     2459
    24552460  PRFileDesc *sslSock = nsSSLIOLayerImportFD(fd, infoObject, host, anonymousLoad);
    24562461  if (!sslSock) {
    24572462    NS_ASSERTION(false, "NSS: Error importing socket");
    24582463    goto loser;
    24592464  }
    24602465
    24612466  infoObject->SetFileDescPtr(sslSock);
    24622467
    24632468  rv = nsSSLIOLayerSetOptions(sslSock,
    2464                               forSTARTTLS, proxyHost, host, port, anonymousLoad,
     2469                              forSTARTTLS, haveProxy, host, port, anonymousLoad,
    24652470                              infoObject);
    24662471
    24672472  if (NS_FAILED(rv))
    24682473    goto loser;
    24692474
    24702475  /* Now, layer ourselves on top of the SSL socket... */
    24712476  layer = PR_CreateIOLayerStub(nsSSLIOLayerHelpers::nsSSLIOLayerIdentity,
    24722477                               &nsSSLIOLayerHelpers::nsSSLIOLayerMethods);
    nsSSLIOLayerAddToSocket(int32_t family, 
    24802485    goto loser;
    24812486  }
    24822487 
    24832488  nsNSSShutDownList::trackSSLSocketCreate();
    24842489
    24852490  PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("[%p] Socket set up\n", (void*)sslSock));
    24862491  infoObject->QueryInterface(NS_GET_IID(nsISupports), (void**) (info));
    24872492
    2488   // We are going use a clear connection first //
    2489   if (forSTARTTLS || proxyHost) {
     2493  // We are going use a clear connection first
     2494  if (forSTARTTLS || haveProxy) {
    24902495    infoObject->SetHandshakePending(false);
    24912496  }
    24922497
    24932498  return NS_OK;
    24942499 loser:
    24952500  NS_IF_RELEASE(infoObject);
    24962501  if (layer) {
    24972502    layer->dtor(layer);
  • security/manager/ssl/src/nsNSSIOLayer.h

    diff --git a/security/manager/ssl/src/nsNSSIOLayer.h b/security/manager/ssl/src/nsNSSIOLayer.h
    a b public: 
    137137
    138138  static void setRenegoUnrestrictedSites(const nsCString &str);
    139139  static bool isRenegoUnrestrictedSite(const nsCString &str);
    140140};
    141141
    142142nsresult nsSSLIOLayerNewSocket(int32_t family,
    143143                               const char *host,
    144144                               int32_t port,
    145                                const char *proxyHost,
    146                                int32_t proxyPort,
     145                               nsIProxyInfo *proxy,
    147146                               PRFileDesc **fd,
    148147                               nsISupports **securityInfo,
    149148                               bool forSTARTTLS,
    150149                               bool anonymousLoad);
    151150
    152151nsresult nsSSLIOLayerAddToSocket(int32_t family,
    153152                                 const char *host,
    154153                                 int32_t port,
    155                                  const char *proxyHost,
    156                                  int32_t proxyPort,
     154                                 nsIProxyInfo *proxy,
    157155                                 PRFileDesc *fd,
    158156                                 nsISupports **securityInfo,
    159157                                 bool forSTARTTLS,
    160158                                 bool anonymousLoad);
    161159
    162160nsresult nsSSLIOLayerFreeTLSIntolerantSites();
    163161nsresult displayUnknownCertErrorAlert(nsNSSSocketInfo *infoObject, int error);
    164162
  • security/manager/ssl/src/nsSSLSocketProvider.cpp

    diff --git a/security/manager/ssl/src/nsSSLSocketProvider.cpp b/security/manager/ssl/src/nsSSLSocketProvider.cpp
    a b nsSSLSocketProvider::~nsSSLSocketProvide 
    1717}
    1818
    1919NS_IMPL_THREADSAFE_ISUPPORTS1(nsSSLSocketProvider, nsISocketProvider)
    2020
    2121NS_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)
    3029{
    3130  nsresult rv = nsSSLIOLayerNewSocket(family,
    3231                                      host,
    3332                                      port,
    34                                       proxyHost,
    35                                       proxyPort,
     33                                      proxy,
    3634                                      _result,
    3735                                      securityInfo,
    3836                                      false,
    3937                                      flags & ANONYMOUS_CONNECT);
    4038  return (NS_FAILED(rv)) ? NS_ERROR_SOCKET_CREATE_FAILED : NS_OK;
    4139}
    4240
    4341// Add the SSL IO layer to an existing socket
    4442NS_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)
    5350{
    5451  nsresult rv = nsSSLIOLayerAddToSocket(family,
    5552                                        host,
    5653                                        port,
    57                                         proxyHost,
    58                                         proxyPort,
     54                                        proxy,
    5955                                        aSocket,
    6056                                        securityInfo,
    6157                                        false,
    6258                                        flags & ANONYMOUS_CONNECT);
    6359 
    6460  return (NS_FAILED(rv)) ? NS_ERROR_SOCKET_CREATE_FAILED : NS_OK;
    6561}
  • security/manager/ssl/src/nsTLSSocketProvider.cpp

    diff --git a/security/manager/ssl/src/nsTLSSocketProvider.cpp b/security/manager/ssl/src/nsTLSSocketProvider.cpp
    a b nsTLSSocketProvider::~nsTLSSocketProvide 
    1717}
    1818
    1919NS_IMPL_THREADSAFE_ISUPPORTS1(nsTLSSocketProvider, nsISocketProvider)
    2020
    2121NS_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)
    3029{
    3130  nsresult rv = nsSSLIOLayerNewSocket(family,
    3231                                      host,
    3332                                      port,
    34                                       proxyHost,
    35                                       proxyPort,
     33                                      proxy,
    3634                                      _result,
    3735                                      securityInfo,
    3836                                      true,
    3937                                      flags & ANONYMOUS_CONNECT);
    4038 
    4139  return (NS_FAILED(rv)) ? NS_ERROR_SOCKET_CREATE_FAILED : NS_OK;
    4240}
    4341
    4442// Add the SSL IO layer to an existing socket
    4543NS_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)
    5451{
    5552  nsresult rv = nsSSLIOLayerAddToSocket(family,
    5653                                        host,
    5754                                        port,
    58                                         proxyHost,
    59                                         proxyPort,
     55                                        proxy,
    6056                                        aSocket,
    6157                                        securityInfo,
    6258                                        true,
    6359                                        flags & ANONYMOUS_CONNECT);
    6460 
    6561  return (NS_FAILED(rv)) ? NS_ERROR_SOCKET_CREATE_FAILED : NS_OK;
    6662}