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

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

Implement SOCKS username and password, with pref

  • 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   * This can, for some special usecases like Tor, vary per connection.
     56   */
     57  attribute AUTF8String username;
     58
     59  /**
     60   * @see username
     61   */
     62  attribute AUTF8String password;
     63
     64  /**
    5365   * This attribute specifies the failover timeout in seconds for this proxy.
    5466   * If a nsIProxyInfo is reported as failed via nsIProtocolProxyService::
    5567   * getFailoverForProxy, then the failed proxy will not be used again for this
    5668   * many seconds.
    5769   */
    5870  readonly attribute unsigned long failoverTimeout;
    5971
    6072  /**
  • 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;
     1463
    14511464    failover.swap(proxyInfo->mNext);
    14521465
    14531466    NS_ADDREF(*aResult = proxyInfo);
    14541467    return NS_OK;
    14551468}
    14561469
    14571470nsresult
    14581471nsProtocolProxyService::Resolve_Internal(nsIURI *uri,
    nsProtocolProxyService::Resolve_Internal 
    15961609        else
    15971610            type = kProxyType_SOCKS;
    15981611        port = mSOCKSProxyPort;
    15991612        if (mSOCKSProxyRemoteDNS)
    16001613            proxyFlags |= nsIProxyInfo::TRANSPARENT_PROXY_RESOLVES_HOST;
    16011614    }
    16021615
    16031616    if (type) {
    1604         rv = NewProxyInfo_Internal(type, *host, port, proxyFlags,
    1605                                    UINT32_MAX, nullptr, flags,
     1617        rv = NewProxyInfo_Internal(type, *host, port,
     1618                                   mSOCKSProxyUsername, mSOCKSProxyPassword,
     1619                                   proxyFlags, UINT32_MAX, nullptr, flags,
    16061620                                   result);
    16071621        if (NS_FAILED(rv))
    16081622            return rv;
    16091623    }
    16101624
    16111625    return NS_OK;
    16121626}
    16131627
    nsProtocolProxyService::ApplyFilters(nsI 
    16431657        return;
    16441658
    16451659    // We prune the proxy list prior to invoking each filter.  This may be
    16461660    // somewhat inefficient, but it seems like a good idea since we want each
    16471661    // filter to "see" a valid proxy list.
    16481662
    16491663    nsresult rv;
    16501664    nsCOMPtr<nsIProxyInfo> result;
    1651 
    16521665    for (FilterLink *iter = mFilters; iter; iter = iter->next) {
    16531666        PruneProxyInfo(info, list);
    16541667
    16551668        rv = iter->filter->ApplyFilter(this, uri, *list,
    16561669                                       getter_AddRefs(result));
    16571670        if (NS_FAILED(rv))
    16581671            continue;
    16591672        result.swap(*list);
  • 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;
     131    nsCString mProxyUsername; // Cache, from mProxy
    129132    int32_t   mVersion;   // SOCKS version 4 or 5
    130133    int32_t   mDestinationFamily;
    131134    uint32_t  mFlags;
    132135    PRNetAddr mInternalProxyAddr;
    133136    PRNetAddr mExternalProxyAddr;
    134137    PRNetAddr mDestinationAddr;
    135138    PRIntervalTime mTimeout;
    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::WriteV5AuthRequest() 
    499513{
    500514    NS_ABORT_IF_FALSE(mVersion == 5, "SOCKS version must be 5!");
    501515
    502516    mState = SOCKS5_WRITE_AUTH_REQUEST;
    503517
    504518    // Send an initial SOCKS 5 greeting
    505519    LOGDEBUG(("socks5: sending auth methods"));
    506520    WriteUint8(0x05); // version -- 5
    507     WriteUint8(0x01); // # auth methods -- 1
    508     WriteUint8(0x00); // we don't support authentication
     521    WriteUint8(0x01); // # of auth methods -- 1
     522    if (mProxyUsername.IsEmpty()) {
     523      WriteUint8(0x00); // no authentication
     524    } else {
     525      WriteUint8(0x02); // username/password
     526    }
    509527
    510528    return PR_SUCCESS;
    511529}
    512530
    513531PRStatus
    514532nsSOCKSSocketInfo::ReadV5AuthResponse()
    515533{
    516534    NS_ABORT_IF_FALSE(mState == SOCKS5_READ_AUTH_RESPONSE,
    517535                      "Handling SOCKS 5 auth method reply in wrong state!");
    518536    NS_ABORT_IF_FALSE(mDataLength == 2,
    519537                      "SOCKS 5 auth method reply must be 2 bytes!");
    520538
    521     LOGDEBUG(("socks5: checking auth method reply"));
    522 
    523539    // Check version number
    524540    if (ReadUint8() != 0x05) {
    525541        LOGERROR(("socks5: unexpected version in the reply"));
    526542        HandshakeFinished(PR_CONNECT_REFUSED_ERROR);
    527543        return PR_FAILURE;
    528544    }
    529545
    530     // Make sure our authentication choice was accepted
    531     if (ReadUint8() != 0x00) {
     546    // Make sure our authentication choice was accepted,
     547    // and continue accordingly
     548    uint8_t authMethod = ReadUint8(); // don't call Read() twice
     549    if (mProxyUsername.IsEmpty() && authMethod == 0x00) { // no auth
     550        LOGDEBUG(("socks5: auth-less connect accepted by server"));
     551        return WriteV5ConnectRequest();
     552    } else if (!mProxyUsername.IsEmpty() && authMethod == 0x02) { // username/pw
     553        LOGDEBUG(("socks5: auth method accepted by server"));
     554        return WriteV5UsernameRequest();
     555    } else { // 0xFF signals error
    532556        LOGERROR(("socks5: server did not accept our authentication method"));
    533557        HandshakeFinished(PR_CONNECT_REFUSED_ERROR);
    534558        return PR_FAILURE;
    535559    }
     560}
    536561
    537     return WriteV5ConnectRequest();
     562PRStatus
     563nsSOCKSSocketInfo::WriteV5UsernameRequest()
     564{
     565    NS_ABORT_IF_FALSE(mVersion == 5, "SOCKS version must be 5!");
     566
     567    mState = SOCKS5_WRITE_USERNAME_REQUEST;
     568
     569    LOGDEBUG(("socks5: sending username and password"));
     570    // RFC 1929 Username/password auth for SOCKS 5
     571    WriteUint8(0x01); // version 1 (not 5)
     572    WriteUint8(mProxyUsername.Length()); // username length
     573    WriteString(mProxyUsername); // username
     574    nsCString password;
     575    mProxy->GetPassword(password);
     576    WriteUint8(password.Length()); // password length
     577    WriteString(password); // password. WARNING: Sent unencrypted!
     578
     579    return PR_SUCCESS;
     580}
     581
     582PRStatus
     583nsSOCKSSocketInfo::ReadV5UsernameResponse()
     584{
     585    NS_ABORT_IF_FALSE(mState == SOCKS5_READ_USERNAME_RESPONSE,
     586                      "Handling SOCKS 5 username/password reply in wrong state!");
     587    NS_ABORT_IF_FALSE(mDataLength == 2,
     588                      "SOCKS 5 username reply must be 2 bytes!");
     589
     590    ReadUint8(); // version, ignore
     591
     592    // Check whether username/password were accepted
     593    if (ReadUint8() != 0x00) { // 0 = success
     594        LOGERROR(("socks5: username/password not accepted"));
     595        HandshakeFinished(PR_CONNECT_REFUSED_ERROR);
     596        return PR_FAILURE;
     597    }
     598
     599    LOGDEBUG(("socks5: username/password accepted by server"));
     600
     601    return WriteV5UsernameRequest();
    538602}
    539603
    540604PRStatus
    541605nsSOCKSSocketInfo::WriteV5ConnectRequest()
    542606{
    543607    // Send SOCKS 5 connect request
    544608    PRNetAddr *addr = &mDestinationAddr;
    545609    int32_t proxy_resolve;
    nsSOCKSSocketInfo::DoHandshake(PRFileDes 
    771835                return PR_FAILURE;
    772836            WantRead(2);
    773837            mState = SOCKS5_READ_AUTH_RESPONSE;
    774838            return PR_SUCCESS;
    775839        case SOCKS5_READ_AUTH_RESPONSE:
    776840            if (ReadFromSocket(fd) != PR_SUCCESS)
    777841                return PR_FAILURE;
    778842            return ReadV5AuthResponse();
     843        case SOCKS5_WRITE_USERNAME_REQUEST:
     844            if (WriteToSocket(fd) != PR_SUCCESS)
     845                return PR_FAILURE;
     846            WantRead(2);
     847            mState = SOCKS5_READ_USERNAME_RESPONSE;
     848            return PR_SUCCESS;
     849        case SOCKS5_READ_USERNAME_RESPONSE:
     850            if (ReadFromSocket(fd) != PR_SUCCESS)
     851                return PR_FAILURE;
     852            return ReadV5UsernameResponse();
    779853        case SOCKS5_WRITE_CONNECT_REQUEST:
    780854            if (WriteToSocket(fd) != PR_SUCCESS)
    781855                return PR_FAILURE;
    782856
    783857            // The SOCKS 5 response to the connection request is variable
    784858            // length. First, we'll read enough to tell how long the response
    785859            // is, and will read the rest later.
    786860            WantRead(5);
    nsSOCKSIOLayerListen(PRFileDesc *fd, int 
    11861260    return fd->lower->methods->listen(fd->lower, backlog);
    11871261}
    11881262
    11891263// add SOCKS IO layer to an existing socket
    11901264nsresult
    11911265nsSOCKSIOLayerAddToSocket(int32_t family,
    11921266                          const char *host,
    11931267                          int32_t port,
    1194                           const char *proxyHost,
    1195                           int32_t proxyPort,
     1268                          nsIProxyInfo *proxy,
    11961269                          int32_t socksVersion,
    11971270                          uint32_t flags,
    11981271                          PRFileDesc *fd,
    11991272                          nsISupports** info)
    12001273{
    12011274    NS_ENSURE_TRUE((socksVersion == 4) || (socksVersion == 5), NS_ERROR_NOT_INITIALIZED);
    12021275
    12031276
    nsSOCKSIOLayerAddToSocket(int32_t family 
    12541327    {
    12551328        // clean up IOLayerStub
    12561329        LOGERROR(("Failed to create nsSOCKSSocketInfo()."));
    12571330        PR_DELETE(layer);
    12581331        return NS_ERROR_FAILURE;
    12591332    }
    12601333
    12611334    NS_ADDREF(infoObject);
    1262     infoObject->Init(socksVersion, family, proxyHost, proxyPort, host, flags);
     1335    infoObject->Init(socksVersion, family, proxy, host, flags);
    12631336    layer->secret = (PRFilePrivate*) infoObject;
    12641337    rv = PR_PushIOLayer(fd, PR_GetLayersIdentity(fd), layer);
    12651338
    12661339    if (rv == PR_FAILURE) {
    12671340        LOGERROR(("PR_PushIOLayer() failed. rv = %x.", rv));
    12681341        NS_RELEASE(infoObject);
    12691342        PR_DELETE(layer);
    12701343        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}