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

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

Updated to current Firefox trunk

  • 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 
    504504        proxy_GetIntPref(prefBranch, PROXY_PREF("ftp_port"), mFTPProxyPort);
    505505
    506506    if (!pref || !strcmp(pref, PROXY_PREF("socks")))
    507507        proxy_GetStringPref(prefBranch, PROXY_PREF("socks"), mSOCKSProxyHost);
    508508   
    509509    if (!pref || !strcmp(pref, PROXY_PREF("socks_port")))
    510510        proxy_GetIntPref(prefBranch, PROXY_PREF("socks_port"), mSOCKSProxyPort);
    511511
     512    if (!pref || !strcmp(pref, PROXY_PREF("socks_username")))
     513        proxy_GetStringPref(prefBranch, PROXY_PREF("socks_username"), mSOCKSProxyUsername);
     514
     515    if (!pref || !strcmp(pref, PROXY_PREF("socks_password")))
     516        proxy_GetStringPref(prefBranch, PROXY_PREF("socks_password"), mSOCKSProxyPassword);
     517
    512518    if (!pref || !strcmp(pref, PROXY_PREF("socks_version"))) {
    513519        int32_t version;
    514520        proxy_GetIntPref(prefBranch, PROXY_PREF("socks_version"), version);
    515521        // make sure this preference value remains sane
    516522        if (version == 5)
    517523            mSOCKSProxyVersion = 5;
    518524        else
    519525            mSOCKSProxyVersion = 4;
    nsProtocolProxyService::NewProxyInfo(con 
    11491155            break;
    11501156        }
    11511157    }
    11521158    NS_ENSURE_TRUE(type, NS_ERROR_INVALID_ARG);
    11531159
    11541160    if (aPort <= 0)
    11551161        aPort = -1;
    11561162
    1157     return NewProxyInfo_Internal(type, aHost, aPort, aFlags, aFailoverTimeout,
     1163    return NewProxyInfo_Internal(type, aHost, aPort,
     1164                                 EmptyCString(), EmptyCString(),
     1165                                 aFlags, aFailoverTimeout,
    11581166                                 aFailoverProxy, 0, aResult);
    11591167}
    11601168
    11611169NS_IMETHODIMP
    11621170nsProtocolProxyService::GetFailoverForProxy(nsIProxyInfo  *aProxy,
    11631171                                            nsIURI        *aURI,
    11641172                                            nsresult       aStatus,
    11651173                                            nsIProxyInfo **aResult)
    nsProtocolProxyService::GetProtocolInfo( 
    14261434    rv = handler->GetDefaultPort(&info->defaultPort);
    14271435    return rv;
    14281436}
    14291437
    14301438nsresult
    14311439nsProtocolProxyService::NewProxyInfo_Internal(const char *aType,
    14321440                                              const nsACString &aHost,
    14331441                                              int32_t aPort,
     1442                                              const nsACString &aUsername,
     1443                                              const nsACString &aPassword,
    14341444                                              uint32_t aFlags,
    14351445                                              uint32_t aFailoverTimeout,
    14361446                                              nsIProxyInfo *aFailoverProxy,
    14371447                                              uint32_t aResolveFlags,
    14381448                                              nsIProxyInfo **aResult)
    14391449{
    14401450    nsCOMPtr<nsProxyInfo> failover;
    14411451    if (aFailoverProxy) {
    nsProtocolProxyService::NewProxyInfo_Int 
    14451455
    14461456    nsProxyInfo *proxyInfo = new nsProxyInfo();
    14471457    if (!proxyInfo)
    14481458        return NS_ERROR_OUT_OF_MEMORY;
    14491459
    14501460    proxyInfo->mType = aType;
    14511461    proxyInfo->mHost = aHost;
    14521462    proxyInfo->mPort = aPort;
     1463    proxyInfo->mUsername = aUsername;
     1464    proxyInfo->mPassword = aPassword;
    14531465    proxyInfo->mFlags = aFlags;
    14541466    proxyInfo->mResolveFlags = aResolveFlags;
    14551467    proxyInfo->mTimeout = aFailoverTimeout == UINT32_MAX
    14561468        ? mFailedProxyTimeout : aFailoverTimeout;
    14571469    failover.swap(proxyInfo->mNext);
    14581470
    14591471    NS_ADDREF(*aResult = proxyInfo);
    14601472    return NS_OK;
    nsProtocolProxyService::Resolve_Internal 
    16021614        else
    16031615            type = kProxyType_SOCKS;
    16041616        port = mSOCKSProxyPort;
    16051617        if (mSOCKSProxyRemoteDNS)
    16061618            proxyFlags |= nsIProxyInfo::TRANSPARENT_PROXY_RESOLVES_HOST;
    16071619    }
    16081620
    16091621    if (type) {
    1610         rv = NewProxyInfo_Internal(type, *host, port, proxyFlags,
    1611                                    UINT32_MAX, nullptr, flags,
     1622        rv = NewProxyInfo_Internal(type, *host, port,
     1623                                   mSOCKSProxyUsername, mSOCKSProxyPassword,
     1624                                   proxyFlags, UINT32_MAX, nullptr, flags,
    16121625                                   result);
    16131626        if (NS_FAILED(rv))
    16141627            return rv;
    16151628    }
    16161629
    16171630    return NS_OK;
    16181631}
    16191632
  • 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) 
    4343NS_IMETHODIMP
    4444nsProxyInfo::GetResolveFlags(uint32_t *result)
    4545{
    4646  *result = mResolveFlags;
    4747  return NS_OK;
    4848}
    4949
    5050NS_IMETHODIMP
     51nsProxyInfo::GetUsername(nsACString &result)
     52{
     53  result = mUsername;
     54  return NS_OK;
     55}
     56
     57NS_IMETHODIMP
     58nsProxyInfo::GetPassword(nsACString &result)
     59{
     60  result = mPassword;
     61  return NS_OK;
     62}
     63
     64NS_IMETHODIMP
     65nsProxyInfo::SetUsername(const nsACString &newValue)
     66{
     67  mUsername = newValue;
     68  return NS_OK;
     69}
     70
     71NS_IMETHODIMP
     72nsProxyInfo::SetPassword(const nsACString &newValue)
     73{
     74  mPassword = newValue;
     75  return NS_OK;
     76}
     77
     78NS_IMETHODIMP
    5179nsProxyInfo::GetFailoverTimeout(uint32_t *result)
    5280{
    5381  *result = mTimeout;
    5482  return NS_OK;
    5583}
    5684
    5785NS_IMETHODIMP
    5886nsProxyInfo::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: 
    5454
    5555  ~nsProxyInfo()
    5656  {
    5757    NS_IF_RELEASE(mNext);
    5858  }
    5959
    6060  const char  *mType;  // pointer to statically allocated value
    6161  nsCString    mHost;
     62  nsCString    mUsername;
     63  nsCString    mPassword;
    6264  int32_t      mPort;
    6365  uint32_t     mFlags;
    6466  uint32_t     mResolveFlags;
    6567  uint32_t     mTimeout;
    6668  nsProxyInfo *mNext;
    6769};
    6870
    6971NS_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 
    960967        fd = nullptr;
    961968
    962969        nsCOMPtr<nsISocketProviderService> spserv =
    963970            do_GetService(kSocketProviderServiceCID, &rv);
    964971        if (NS_FAILED(rv)) return rv;
    965972
    966973        const char *host       = mHost.get();
    967974        int32_t     port       = (int32_t) mPort;
    968         const char *proxyHost  = mProxyHost.IsEmpty() ? nullptr : mProxyHost.get();
    969         int32_t     proxyPort  = (int32_t) mProxyPort;
    970975        uint32_t    proxyFlags = 0;
     976        nsCOMPtr<nsIProxyInfo> proxy = mProxyInfo;
    971977
    972978        uint32_t i;
    973979        for (i=0; i<mTypeCount; ++i) {
    974980            nsCOMPtr<nsISocketProvider> provider;
    975981
    976982            SOCKET_LOG(("  pushing io layer [%u:%s]\n", i, mTypes[i]));
    977983
    978984            rv = spserv->GetSocketProvider(mTypes[i], getter_AddRefs(provider));
    nsSocketTransport::BuildSocket(PRFileDes 
    988994            if (mConnectionFlags & nsISocketTransport::NO_PERMANENT_STORAGE)
    989995                proxyFlags |= nsISocketProvider::NO_PERMANENT_STORAGE;
    990996
    991997            nsCOMPtr<nsISupports> secinfo;
    992998            if (i == 0) {
    993999                // if this is the first type, we'll want the
    9941000                // service to allocate a new socket
    9951001                rv = provider->NewSocket(mNetAddr.raw.family,
    996                                          host, port, proxyHost, proxyPort,
     1002                                         host, port, proxy,
    9971003                                         proxyFlags, &fd,
    9981004                                         getter_AddRefs(secinfo));
    9991005
    10001006                if (NS_SUCCEEDED(rv) && !fd) {
    10011007                    NS_NOTREACHED("NewSocket succeeded but failed to create a PRFileDesc");
    10021008                    rv = NS_ERROR_UNEXPECTED;
    10031009                }
    10041010            }
    10051011            else {
    10061012                // the socket has already been allocated,
    10071013                // so we just want the service to add itself
    10081014                // to the stack (such as pushing an io layer)
    10091015                rv = provider->AddToSocket(mNetAddr.raw.family,
    1010                                            host, port, proxyHost, proxyPort,
     1016                                           host, port, proxy,
    10111017                                           proxyFlags, fd,
    10121018                                           getter_AddRefs(secinfo));
    10131019            }
    10141020            // proxyFlags = 0; not used below this point...
    10151021            if (NS_FAILED(rv))
    10161022                break;
    10171023
    10181024            // if the service was ssl or starttls, we want to hold onto the socket info
    nsSocketTransport::BuildSocket(PRFileDes 
    10321038                    secCtrl->SetNotificationCallbacks(callbacks);
    10331039                // remember if socket type is SSL so we can ProxyStartSSL if need be.
    10341040                usingSSL = isSSL;
    10351041            }
    10361042            else if ((strcmp(mTypes[i], "socks") == 0) ||
    10371043                     (strcmp(mTypes[i], "socks4") == 0)) {
    10381044                // since socks is transparent, any layers above
    10391045                // it do not have to worry about proxy stuff
    1040                 proxyHost = nullptr;
    1041                 proxyPort = -1;
     1046                proxy = nullptr;
    10421047                proxyTransparent = true;
    10431048            }
    10441049        }
    10451050
    10461051        if (NS_FAILED(rv)) {
    10471052            SOCKET_LOG(("  error pushing io layer [%u:%s rv=%x]\n", i, mTypes[i], rv));
    10481053            if (fd)
    10491054                PR_Close(fd);
    nsSocketTransport::InitiateSocket() 
    11991204        // If the socket is already connected, then return success...
    12001205        //
    12011206        else if (PR_IS_CONNECTED_ERROR == code) {
    12021207            //
    12031208            // we are connected!
    12041209            //
    12051210            OnSocketConnected();
    12061211
    1207             if (mSecInfo && !mProxyHost.IsEmpty() && proxyTransparent && usingSSL) {
     1212            if (mSecInfo && mProxyUse && proxyTransparent && usingSSL) {
    12081213                // if the connection phase is finished, and the ssl layer has
    12091214                // been pushed, and we were proxying (transparently; ie. nothing
    12101215                // has to happen in the protocol layer above us), it's time for
    12111216                // the ssl to start doing it's thing.
    12121217                nsCOMPtr<nsISSLSocketControl> secCtrl =
    12131218                    do_QueryInterface(mSecInfo);
    12141219                if (secCtrl) {
    12151220                    SOCKET_LOG(("  calling ProxyStartSSL()\n"));
    nsSocketTransport::InitiateSocket() 
    12231228                // isn't this broken?
    12241229            }
    12251230        }
    12261231        //
    12271232        // A SOCKS request was rejected; get the actual error code from
    12281233        // the OS error
    12291234        //
    12301235        else if (PR_UNKNOWN_ERROR == code &&
    1231                  mProxyTransparent &&
    1232                  !mProxyHost.IsEmpty()) {
     1236                 mProxyUse && mProxyTransparent) {
    12331237            code = PR_GetOSError();
    12341238            rv = ErrorAccordingToNSPR(code);
    12351239        }
    12361240        //
    12371241        // The connection was refused...
    12381242        //
    12391243        else {
    12401244            rv = ErrorAccordingToNSPR(code);
    1241             if ((rv == NS_ERROR_CONNECTION_REFUSED) && !mProxyHost.IsEmpty())
     1245            if (rv == NS_ERROR_CONNECTION_REFUSED && mProxyUse)
    12421246                rv = NS_ERROR_PROXY_CONNECTION_REFUSED;
    12431247        }
    12441248    }
    12451249    return rv;
    12461250}
    12471251
    12481252bool
    12491253nsSocketTransport::RecoverFromError()
    nsSocketTransport::OnSocketEvent(uint32_ 
    14761480        }
    14771481        // status contains DNS lookup status
    14781482        if (NS_FAILED(status)) {
    14791483            // When using a HTTP proxy, NS_ERROR_UNKNOWN_HOST means the HTTP
    14801484            // proxy host is not found, so we fixup the error code.
    14811485            // For SOCKS proxies (mProxyTransparent == true), the socket
    14821486            // transport resolves the real host here, so there's no fixup
    14831487            // (see bug 226943).
    1484             if ((status == NS_ERROR_UNKNOWN_HOST) && !mProxyTransparent &&
    1485                 !mProxyHost.IsEmpty())
     1488            if (status == NS_ERROR_UNKNOWN_HOST && !mProxyTransparent &&
     1489                mProxyUse)
    14861490                mCondition = NS_ERROR_UNKNOWN_PROXY_HOST;
    14871491            else
    14881492                mCondition = status;
    14891493        }
    14901494        else if (mState == STATE_RESOLVING)
    14911495            mCondition = InitiateSocket();
    14921496        break;
    14931497
    nsSocketTransport::OnSocketReady(PRFileD 
    15861590                mPollFlags = (PR_POLL_EXCEPT | PR_POLL_WRITE);
    15871591                // Update poll timeout in case it was changed
    15881592                mPollTimeout = mTimeouts[TIMEOUT_CONNECT];
    15891593            }
    15901594            //
    15911595            // The SOCKS proxy rejected our request. Find out why.
    15921596            //
    15931597            else if (PR_UNKNOWN_ERROR == code &&
    1594                      mProxyTransparent &&
    1595                      !mProxyHost.IsEmpty()) {
     1598                     mProxyUse && mProxyTransparent) {
    15961599                code = PR_GetOSError();
    15971600                mCondition = ErrorAccordingToNSPR(code);
    15981601            }
    15991602            else {
    16001603                //
    16011604                // else, the connection failed...
    16021605                //
    16031606                mCondition = ErrorAccordingToNSPR(code);
    1604                 if ((mCondition == NS_ERROR_CONNECTION_REFUSED) && !mProxyHost.IsEmpty())
     1607                if (mCondition == NS_ERROR_CONNECTION_REFUSED && mProxyUse)
    16051608                    mCondition = NS_ERROR_PROXY_CONNECTION_REFUSED;
    16061609                SOCKET_LOG(("  connection failed! [reason=%x]\n", mCondition));
    16071610            }
    16081611        }
    16091612    }
    16101613    else {
    16111614        NS_ERROR("unexpected socket state");
    16121615        mCondition = NS_ERROR_UNEXPECTED;
    nsSocketTransport::GetHost(nsACString &h 
    19061909
    19071910NS_IMETHODIMP
    19081911nsSocketTransport::GetPort(int32_t *port)
    19091912{
    19101913    *port = (int32_t) SocketPort();
    19111914    return NS_OK;
    19121915}
    19131916
     1917const nsCString &
     1918nsSocketTransport::SocketHost()
     1919{
     1920  if (mProxyInfo && !mProxyTransparent) {
     1921    if (mProxyHostCache.IsEmpty()) { // TODO cache necessary?
     1922      mProxyInfo->GetHost(mProxyHostCache);
     1923    }
     1924    return mProxyHostCache;
     1925  }
     1926  else
     1927    return mHost;
     1928}
     1929
     1930uint16_t
     1931nsSocketTransport::SocketPort()
     1932{
     1933  if (mProxyInfo && !mProxyTransparent) {
     1934    int32_t result;
     1935    mProxyInfo->GetPort(&result);
     1936    return (uint16_t) result; // TODO why doesn't SocketPort() return int32_t?
     1937  }
     1938  else
     1939    return mPort;
     1940}
     1941
    19141942NS_IMETHODIMP
    19151943nsSocketTransport::GetPeerAddr(NetAddr *addr)
    19161944{
    19171945    // once we are in the connected state, mNetAddr will not change.
    19181946    // so if we can verify that we are in the connected state, then
    19191947    // we can freely access mNetAddr from any thread without being
    19201948    // inside a critical section.
    19211949
  • netwerk/base/src/nsSocketTransport2.h

    diff --git a/netwerk/base/src/nsSocketTransport2.h b/netwerk/base/src/nsSocketTransport2.h
    a b private: 
    165165    // these members are "set" at initialization time and are never modified
    166166    // afterwards.  this allows them to be safely accessed from any thread.
    167167    //-------------------------------------------------------------------------
    168168
    169169    // socket type info:
    170170    char       **mTypes;
    171171    uint32_t     mTypeCount;
    172172    nsCString    mHost;
    173     nsCString    mProxyHost;
    174173    uint16_t     mPort;
    175     uint16_t     mProxyPort;
    176     bool mProxyTransparent;
    177     bool mProxyTransparentResolvesHost;
     174    nsCOMPtr<nsIProxyInfo> mProxyInfo;
     175    bool         mProxyUse;
     176    bool         mProxyTransparent;
     177    bool         mProxyTransparentResolvesHost;
    178178    uint32_t     mConnectionFlags;
    179179   
    180     uint16_t         SocketPort() { return (!mProxyHost.IsEmpty() && !mProxyTransparent) ? mProxyPort : mPort; }
    181     const nsCString &SocketHost() { return (!mProxyHost.IsEmpty() && !mProxyTransparent) ? mProxyHost : mHost; }
     180    uint16_t         SocketPort();
     181    const nsCString &SocketHost();
     182    nsCString        mProxyHostCache; // for SocketHost() only
    182183
    183184    //-------------------------------------------------------------------------
    184185    // members accessible only on the socket transport thread:
    185186    //  (the exception being initialization/shutdown time)
    186187    //-------------------------------------------------------------------------
    187188
    188189    // socket state vars:
    189190    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 
    4545        SOCKS_INITIAL,
    4646        SOCKS_DNS_IN_PROGRESS,
    4747        SOCKS_DNS_COMPLETE,
    4848        SOCKS_CONNECTING_TO_PROXY,
    4949        SOCKS4_WRITE_CONNECT_REQUEST,
    5050        SOCKS4_READ_CONNECT_RESPONSE,
    5151        SOCKS5_WRITE_AUTH_REQUEST,
    5252        SOCKS5_READ_AUTH_RESPONSE,
     53        SOCKS5_WRITE_USERNAME_REQUEST,
     54        SOCKS5_READ_USERNAME_RESPONSE,
    5355        SOCKS5_WRITE_CONNECT_REQUEST,
    5456        SOCKS5_READ_CONNECT_RESPONSE_TOP,
    5557        SOCKS5_READ_CONNECT_RESPONSE_BOTTOM,
    5658        SOCKS_CONNECTED,
    5759        SOCKS_FAILED
    5860    };
    5961
    6062    // A buffer of 262 bytes should be enough for any request and response
    public: 
    6769    virtual ~nsSOCKSSocketInfo() { HandshakeFinished(); }
    6870
    6971    NS_DECL_ISUPPORTS
    7072    NS_DECL_NSISOCKSSOCKETINFO
    7173    NS_DECL_NSIDNSLISTENER
    7274
    7375    void Init(int32_t version,
    7476              int32_t family,
    75               const char *proxyHost,
    76               int32_t proxyPort,
     77              nsIProxyInfo *proxy,
    7778              const char *destinationHost,
    7879              uint32_t flags);
    7980
    8081    void SetConnectTimeout(PRIntervalTime to);
    8182    PRStatus DoHandshake(PRFileDesc *fd, int16_t oflags = -1);
    8283    int16_t GetPollFlags() const;
    8384    bool IsConnected() const { return mState == SOCKS_CONNECTED; }
    8485    void ForgetFD() { mFD = nullptr; }
    private: 
    8889    PRStatus StartDNS(PRFileDesc *fd);
    8990    PRStatus ConnectToProxy(PRFileDesc *fd);
    9091    void FixupAddressFamily(PRFileDesc *fd, NetAddr *proxy);
    9192    PRStatus ContinueConnectingToProxy(PRFileDesc *fd, int16_t oflags);
    9293    PRStatus WriteV4ConnectRequest();
    9394    PRStatus ReadV4ConnectResponse();
    9495    PRStatus WriteV5AuthRequest();
    9596    PRStatus ReadV5AuthResponse();
     97    PRStatus WriteV5UsernameRequest();
     98    PRStatus ReadV5UsernameResponse();
    9699    PRStatus WriteV5ConnectRequest();
    97100    PRStatus ReadV5AddrTypeAndLength(uint8_t *type, uint32_t *len);
    98101    PRStatus ReadV5ConnectResponseTop();
    99102    PRStatus ReadV5ConnectResponseBottom();
    100103
    101104    void WriteUint8(uint8_t d);
    102105    void WriteUint16(uint16_t d);
    103106    void WriteUint32(uint32_t d);
    private: 
    123126    uint32_t  mReadOffset;
    124127    uint32_t  mAmountToRead;
    125128    nsCOMPtr<nsIDNSRecord>  mDnsRec;
    126129    nsCOMPtr<nsICancelable> mLookup;
    127130    nsresult                mLookupStatus;
    128131    PRFileDesc             *mFD;
    129132
    130133    nsCString mDestinationHost;
    131     nsCString mProxyHost;
    132     int32_t   mProxyPort;
     134    nsCOMPtr<nsIProxyInfo> mProxy;
    133135    int32_t   mVersion;   // SOCKS version 4 or 5
    134136    int32_t   mDestinationFamily;
    135137    uint32_t  mFlags;
    136138    NetAddr   mInternalProxyAddr;
    137139    NetAddr   mExternalProxyAddr;
    138140    NetAddr   mDestinationAddr;
    139141    PRIntervalTime mTimeout;
     142    nsCString mProxyUsername; // Cache, from mProxy
    140143};
    141144
    142145nsSOCKSSocketInfo::nsSOCKSSocketInfo()
    143146    : mState(SOCKS_INITIAL)
    144147    , mDataIoPtr(nullptr)
    145148    , mDataLength(0)
    146149    , mReadOffset(0)
    147150    , mAmountToRead(0)
    148     , mProxyPort(-1)
    149151    , mVersion(-1)
    150152    , mDestinationFamily(AF_INET)
    151153    , mFlags(0)
    152154    , mTimeout(PR_INTERVAL_NO_TIMEOUT)
    153155{
    154156    mData = new uint8_t[BUFFER_SIZE];
    155157
    156158    mInternalProxyAddr.raw.family = AF_INET;
    nsSOCKSSocketInfo::nsSOCKSSocketInfo() 
    162164    mExternalProxyAddr.inet.port = htons(0);
    163165
    164166    mDestinationAddr.raw.family = AF_INET;
    165167    mDestinationAddr.inet.ip = htonl(INADDR_ANY);
    166168    mDestinationAddr.inet.port = htons(0);
    167169}
    168170
    169171void
    170 nsSOCKSSocketInfo::Init(int32_t version, int32_t family, const char *proxyHost, int32_t proxyPort, const char *host, uint32_t flags)
     172nsSOCKSSocketInfo::Init(int32_t version, int32_t family, nsIProxyInfo *proxy, const char *host, uint32_t flags)
    171173{
    172174    mVersion         = version;
    173175    mDestinationFamily = family;
    174     mProxyHost       = proxyHost;
    175     mProxyPort       = proxyPort;
     176    mProxy           = proxy;
    176177    mDestinationHost = host;
    177178    mFlags           = flags;
     179    mProxy->GetUsername(mProxyUsername); // cache
    178180}
    179181
    180182NS_IMPL_THREADSAFE_ISUPPORTS2(nsSOCKSSocketInfo, nsISOCKSSocketInfo, nsIDNSListener)
    181183
    182184NS_IMETHODIMP
    183185nsSOCKSSocketInfo::GetExternalProxyAddr(NetAddr * *aExternalProxyAddr)
    184186{
    185187    memcpy(*aExternalProxyAddr, &mExternalProxyAddr, sizeof(NetAddr));
    nsSOCKSSocketInfo::StartDNS(PRFileDesc * 
    256258{
    257259    NS_ABORT_IF_FALSE(!mDnsRec && mState == SOCKS_INITIAL,
    258260                      "Must be in initial state to make DNS Lookup");
    259261
    260262    nsCOMPtr<nsIDNSService> dns = do_GetService(NS_DNSSERVICE_CONTRACTID);
    261263    if (!dns)
    262264        return PR_FAILURE;
    263265
     266    nsCString proxyHost;
     267    mProxy->GetHost(proxyHost);
     268
    264269    mFD  = fd;
    265     nsresult rv = dns->AsyncResolve(mProxyHost, 0, this,
     270    nsresult rv = dns->AsyncResolve(proxyHost, 0, this,
    266271                                    NS_GetCurrentThread(),
    267272                                    getter_AddRefs(mLookup));
    268273
    269274    if (NS_FAILED(rv)) {
    270275        LOGERROR(("socks: DNS lookup for SOCKS proxy %s failed",
    271                   mProxyHost.get()));
     276                  proxyHost.get()));
    272277        return PR_FAILURE;
    273278    }
    274279    mState = SOCKS_DNS_IN_PROGRESS;
    275280    PR_SetError(PR_IN_PROGRESS_ERROR, 0);
    276281    return PR_FAILURE;
    277282}
    278283
    279284NS_IMETHODIMP
    nsSOCKSSocketInfo::ConnectToProxy(PRFile 
    308313    }
    309314
    310315    // Try socks5 if the destination addrress is IPv6
    311316    if (mVersion == 4 &&
    312317        mDestinationAddr.raw.family == AF_INET6) {
    313318        mVersion = 5;
    314319    }
    315320
     321    int32_t proxyPort;
     322    mProxy->GetPort(&proxyPort);
     323
    316324    int32_t addresses = 0;
    317325    do {
    318326        if (addresses++)
    319             mDnsRec->ReportUnusable(mProxyPort);
     327            mDnsRec->ReportUnusable(proxyPort);
    320328       
    321         rv = mDnsRec->GetNextAddr(mProxyPort, &mInternalProxyAddr);
     329        rv = mDnsRec->GetNextAddr(proxyPort, &mInternalProxyAddr);
    322330        // No more addresses to try? If so, we'll need to bail
    323331        if (NS_FAILED(rv)) {
     332            nsCString proxyHost;
     333            mProxy->GetHost(proxyHost);
    324334            LOGERROR(("socks: unable to connect to SOCKS proxy, %s",
    325                      mProxyHost.get()));
     335                     proxyHost.get()));
    326336            return PR_FAILURE;
    327337        }
    328338
    329339#if defined(PR_LOGGING)
    330340        char buf[kIPv6CStrBufSize];
    331341        NetAddrToString(&mInternalProxyAddr, buf, sizeof(buf));
    332342        LOGDEBUG(("socks: trying proxy server, %s:%hu",
    333343                 buf, ntohs(mInternalProxyAddr.inet.port)));
    nsSOCKSSocketInfo::WriteV4ConnectRequest 
    458468    WriteNetPort(addr);
    459469    if (proxy_resolve) {
    460470        // Add the full name, null-terminated, to the request
    461471        // according to SOCKS 4a. A fake IP address, with the first
    462472        // four bytes set to 0 and the last byte set to something other
    463473        // than 0, is used to notify the proxy that this is a SOCKS 4a
    464474        // request. This request type works for Tor and perhaps others.
    465475        WriteUint32(htonl(0x00000001)); // Fake IP
    466         WriteUint8(0x00); // Send an emtpy username
     476        WriteString(mProxyUsername); // Send username. May be empty.
     477        WriteUint8(0x00); // Null-terminate username
     478        // Password not supported by V4.
    467479        if (mDestinationHost.Length() > MAX_HOSTNAME_LEN) {
    468480            LOGERROR(("socks4: destination host name is too long!"));
    469481            HandshakeFinished(PR_BAD_ADDRESS_ERROR);
    470482            return PR_FAILURE;
    471483        }
    472484        WriteString(mDestinationHost); // Hostname
    473485        WriteUint8(0x00);
    474486    } else if (addr->raw.family == AF_INET) {
    475487        WriteNetAddr(addr); // Add the IPv4 address
    476         WriteUint8(0x00); // Send an emtpy username
     488        WriteString(mProxyUsername); // Send username. May be empty.
     489        WriteUint8(0x00); // Null-terminate username
     490        // Password not supported by V4.
    477491    } else if (addr->raw.family == AF_INET6) {
    478492        LOGERROR(("socks: SOCKS 4 can't handle IPv6 addresses!"));
    479493        HandshakeFinished(PR_BAD_ADDRESS_ERROR);
    480494        return PR_FAILURE;
    481495    }
    482496
    483497    return PR_SUCCESS;
    484498}
    nsSOCKSSocketInfo::ReadV4ConnectResponse 
    511525    return PR_FAILURE;
    512526}
    513527
    514528PRStatus
    515529nsSOCKSSocketInfo::WriteV5AuthRequest()
    516530{
    517531    NS_ABORT_IF_FALSE(mVersion == 5, "SOCKS version must be 5!");
    518532
     533    mDataLength = 0;
    519534    mState = SOCKS5_WRITE_AUTH_REQUEST;
    520535
    521536    // Send an initial SOCKS 5 greeting
    522537    LOGDEBUG(("socks5: sending auth methods"));
    523538    WriteUint8(0x05); // version -- 5
    524     WriteUint8(0x01); // # auth methods -- 1
    525     WriteUint8(0x00); // we don't support authentication
     539    WriteUint8(0x01); // # of auth methods -- 1
     540    if (mProxyUsername.IsEmpty()) {
     541      WriteUint8(0x00); // no authentication
     542    } else {
     543      WriteUint8(0x02); // username/password
     544    }
    526545
    527546    return PR_SUCCESS;
    528547}
    529548
    530549PRStatus
    531550nsSOCKSSocketInfo::ReadV5AuthResponse()
    532551{
    533552    NS_ABORT_IF_FALSE(mState == SOCKS5_READ_AUTH_RESPONSE,
    534553                      "Handling SOCKS 5 auth method reply in wrong state!");
    535554    NS_ABORT_IF_FALSE(mDataLength == 2,
    536555                      "SOCKS 5 auth method reply must be 2 bytes!");
    537556
    538     LOGDEBUG(("socks5: checking auth method reply"));
    539 
    540557    // Check version number
    541558    if (ReadUint8() != 0x05) {
    542559        LOGERROR(("socks5: unexpected version in the reply"));
    543560        HandshakeFinished(PR_CONNECT_REFUSED_ERROR);
    544561        return PR_FAILURE;
    545562    }
    546563
    547     // Make sure our authentication choice was accepted
    548     if (ReadUint8() != 0x00) {
     564    // Make sure our authentication choice was accepted,
     565    // and continue accordingly
     566    uint8_t authMethod = ReadUint8();
     567    if (mProxyUsername.IsEmpty() && authMethod == 0x00) { // no auth
     568        LOGDEBUG(("socks5: server allows connection without authentication"));
     569        return WriteV5ConnectRequest();
     570    } else if (!mProxyUsername.IsEmpty() && authMethod == 0x02) { // username/pw
     571        LOGDEBUG(("socks5: auth method accepted by server"));
     572        return WriteV5UsernameRequest();
     573    } else { // 0xFF signals error
    549574        LOGERROR(("socks5: server did not accept our authentication method"));
    550575        HandshakeFinished(PR_CONNECT_REFUSED_ERROR);
    551576        return PR_FAILURE;
    552577    }
     578}
    553579
    554     return WriteV5ConnectRequest();
     580PRStatus
     581nsSOCKSSocketInfo::WriteV5UsernameRequest()
     582{
     583    NS_ABORT_IF_FALSE(mVersion == 5, "SOCKS version must be 5!");
     584
     585    mDataLength = 0;
     586    mState = SOCKS5_WRITE_USERNAME_REQUEST;
     587
     588    LOGDEBUG(("socks5: sending username and password"));
     589    // RFC 1929 Username/password auth for SOCKS 5
     590    printf("%s\n", "socks5: sending username and password");
     591    printf("version %d\n", 0x01);
     592    WriteUint8(0x01); // version 1 (not 5)
     593    printf("username length %d\n", mProxyUsername.Length());
     594    WriteUint8(mProxyUsername.Length()); // username length
     595    printf("username %s\n", mProxyUsername.get());
     596    WriteString(mProxyUsername); // username
     597    nsCString password;
     598    mProxy->GetPassword(password);
     599    printf("password length %d\n", password.Length());
     600    WriteUint8(password.Length()); // password length
     601    printf("password %s\n", password.get());
     602    WriteString(password); // password. WARNING: Sent unencrypted!
     603
     604    return PR_SUCCESS;
     605}
     606
     607PRStatus
     608nsSOCKSSocketInfo::ReadV5UsernameResponse()
     609{
     610    printf("%s\n", "socks5: username response");
     611    NS_ABORT_IF_FALSE(mState == SOCKS5_READ_USERNAME_RESPONSE,
     612                      "Handling SOCKS 5 username/password reply in wrong state!");
     613    NS_ABORT_IF_FALSE(mDataLength == 2,
     614                      "SOCKS 5 username reply must be 2 bytes!");
     615
     616    // Check version number, must be 1 (not 5)
     617    if (ReadUint8() != 0x01) {
     618        printf("%s\n", "socks5: wrong version");
     619        LOGERROR(("socks5: unexpected version in the reply"));
     620        HandshakeFinished(PR_CONNECT_REFUSED_ERROR);
     621        return PR_FAILURE;
     622    }
     623
     624    // Check whether username/password were accepted
     625    if (ReadUint8() != 0x00) { // 0 = success
     626        printf("%s\n", "socks5: user rejected");
     627        LOGERROR(("socks5: username/password not accepted"));
     628        HandshakeFinished(PR_CONNECT_REFUSED_ERROR);
     629        return PR_FAILURE;
     630    }
     631    printf("%s\n", "socks5: user accepted rejected");
     632
     633    LOGDEBUG(("socks5: username/password accepted by server"));
     634
     635    return WriteV5UsernameRequest();
    555636}
    556637
    557638PRStatus
    558639nsSOCKSSocketInfo::WriteV5ConnectRequest()
    559640{
    560641    // Send SOCKS 5 connect request
    561642    NetAddr *addr = &mDestinationAddr;
    562643    int32_t proxy_resolve;
    nsSOCKSSocketInfo::DoHandshake(PRFileDes 
    788869                return PR_FAILURE;
    789870            WantRead(2);
    790871            mState = SOCKS5_READ_AUTH_RESPONSE;
    791872            return PR_SUCCESS;
    792873        case SOCKS5_READ_AUTH_RESPONSE:
    793874            if (ReadFromSocket(fd) != PR_SUCCESS)
    794875                return PR_FAILURE;
    795876            return ReadV5AuthResponse();
     877        case SOCKS5_WRITE_USERNAME_REQUEST:
     878            if (WriteToSocket(fd) != PR_SUCCESS)
     879                return PR_FAILURE;
     880            WantRead(2);
     881            mState = SOCKS5_READ_USERNAME_RESPONSE;
     882            return PR_SUCCESS;
     883        case SOCKS5_READ_USERNAME_RESPONSE:
     884            if (ReadFromSocket(fd) != PR_SUCCESS)
     885                return PR_FAILURE;
     886            return ReadV5UsernameResponse();
    796887        case SOCKS5_WRITE_CONNECT_REQUEST:
    797888            if (WriteToSocket(fd) != PR_SUCCESS)
    798889                return PR_FAILURE;
    799890
    800891            // The SOCKS 5 response to the connection request is variable
    801892            // length. First, we'll read enough to tell how long the response
    802893            // is, and will read the rest later.
    803894            WantRead(5);
    nsSOCKSIOLayerListen(PRFileDesc *fd, int 
    12141305    return fd->lower->methods->listen(fd->lower, backlog);
    12151306}
    12161307
    12171308// add SOCKS IO layer to an existing socket
    12181309nsresult
    12191310nsSOCKSIOLayerAddToSocket(int32_t family,
    12201311                          const char *host,
    12211312                          int32_t port,
    1222                           const char *proxyHost,
    1223                           int32_t proxyPort,
     1313                          nsIProxyInfo *proxy,
    12241314                          int32_t socksVersion,
    12251315                          uint32_t flags,
    12261316                          PRFileDesc *fd,
    12271317                          nsISupports** info)
    12281318{
    12291319    NS_ENSURE_TRUE((socksVersion == 4) || (socksVersion == 5), NS_ERROR_NOT_INITIALIZED);
    12301320
    12311321
    nsSOCKSIOLayerAddToSocket(int32_t family 
    12821372    {
    12831373        // clean up IOLayerStub
    12841374        LOGERROR(("Failed to create nsSOCKSSocketInfo()."));
    12851375        PR_DELETE(layer);
    12861376        return NS_ERROR_FAILURE;
    12871377    }
    12881378
    12891379    NS_ADDREF(infoObject);
    1290     infoObject->Init(socksVersion, family, proxyHost, proxyPort, host, flags);
     1380    infoObject->Init(socksVersion, family, proxy, host, flags);
    12911381    layer->secret = (PRFilePrivate*) infoObject;
    12921382    rv = PR_PushIOLayer(fd, PR_GetLayersIdentity(fd), layer);
    12931383
    12941384    if (rv == PR_FAILURE) {
    12951385        LOGERROR(("PR_PushIOLayer() failed. rv = %x.", rv));
    12961386        NS_RELEASE(infoObject);
    12971387        PR_DELETE(layer);
    12981388        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 
    14101410  MutexAutoLock lock(*mutex);
    14111411  return mWarnLevelMissingRFC5746;
    14121412}
    14131413
    14141414nsresult
    14151415nsSSLIOLayerNewSocket(int32_t family,
    14161416                      const char *host,
    14171417                      int32_t port,
    1418                       const char *proxyHost,
    1419                       int32_t proxyPort,
     1418                      nsIProxyInfo *proxy,
    14201419                      PRFileDesc **fd,
    14211420                      nsISupports** info,
    14221421                      bool forSTARTTLS,
    14231422                      uint32_t flags)
    14241423{
    14251424
    14261425  PRFileDesc* sock = PR_OpenTCPSocket(family);
    14271426  if (!sock) return NS_ERROR_OUT_OF_MEMORY;
    14281427
    1429   nsresult rv = nsSSLIOLayerAddToSocket(family, host, port, proxyHost, proxyPort,
     1428  nsresult rv = nsSSLIOLayerAddToSocket(family, host, port, proxy,
    14301429                                        sock, info, forSTARTTLS, flags);
    14311430  if (NS_FAILED(rv)) {
    14321431    PR_Close(sock);
    14331432    return rv;
    14341433  }
    14351434
    14361435  *fd = sock;
    14371436  return NS_OK;
    loser: 
    24422441  if (sslSock) {
    24432442    PR_Close(sslSock);
    24442443  }
    24452444  return nullptr;
    24462445}
    24472446
    24482447static nsresult
    24492448nsSSLIOLayerSetOptions(PRFileDesc *fd, bool forSTARTTLS,
    2450                        const char *proxyHost, const char *host, int32_t port,
     2449                       bool haveProxy, const char *host, int32_t port,
    24512450                       nsNSSSocketInfo *infoObject)
    24522451{
    24532452  nsNSSShutDownPreventionLock locker;
    2454   if (forSTARTTLS || proxyHost) {
     2453  if (forSTARTTLS || haveProxy) {
    24552454    if (SECSuccess != SSL_OptionSet(fd, SSL_SECURITY, false)) {
    24562455      return NS_ERROR_FAILURE;
    24572456    }
    24582457    infoObject->SetHasCleartextPhase(true);
    24592458  }
    24602459
    24612460  // Let's see if we're trying to connect to a site we know is
    24622461  // TLS intolerant.
    nsSSLIOLayerSetOptions(PRFileDesc *fd, b 
    25202519
    25212520  return NS_OK;
    25222521}
    25232522
    25242523nsresult
    25252524nsSSLIOLayerAddToSocket(int32_t family,
    25262525                        const char* host,
    25272526                        int32_t port,
    2528                         const char* proxyHost,
    2529                         int32_t proxyPort,
     2527                        nsIProxyInfo* proxy,
    25302528                        PRFileDesc* fd,
    25312529                        nsISupports** info,
    25322530                        bool forSTARTTLS,
    25332531                        uint32_t providerFlags)
    25342532{
    25352533  nsNSSShutDownPreventionLock locker;
    25362534  PRFileDesc* layer = nullptr;
    25372535  nsresult rv;
    nsSSLIOLayerAddToSocket(int32_t family, 
    25422540  nsNSSSocketInfo* infoObject = new nsNSSSocketInfo(*sharedState, providerFlags);
    25432541  if (!infoObject) return NS_ERROR_FAILURE;
    25442542 
    25452543  NS_ADDREF(infoObject);
    25462544  infoObject->SetForSTARTTLS(forSTARTTLS);
    25472545  infoObject->SetHostName(host);
    25482546  infoObject->SetPort(port);
    25492547
     2548  bool haveProxy = false;
     2549  if (proxy) {
     2550    nsCString proxyHost;
     2551    proxy->GetHost(proxyHost);
     2552    haveProxy = !proxyHost.IsEmpty();
     2553  }
     2554
    25502555  PRFileDesc *sslSock = nsSSLIOLayerImportFD(fd, infoObject, host);
    25512556  if (!sslSock) {
    25522557    NS_ASSERTION(false, "NSS: Error importing socket");
    25532558    goto loser;
    25542559  }
    25552560
    25562561  infoObject->SetFileDescPtr(sslSock);
    25572562
    2558   rv = nsSSLIOLayerSetOptions(sslSock, forSTARTTLS, proxyHost, host, port,
     2563  rv = nsSSLIOLayerSetOptions(sslSock, forSTARTTLS, haveProxy, host, port,
    25592564                              infoObject);
    25602565
    25612566  if (NS_FAILED(rv))
    25622567    goto loser;
    25632568
    25642569  /* Now, layer ourselves on top of the SSL socket... */
    25652570  layer = PR_CreateIOLayerStub(nsSSLIOLayerHelpers::nsSSLIOLayerIdentity,
    25662571                               &nsSSLIOLayerHelpers::nsSSLIOLayerMethods);
    nsSSLIOLayerAddToSocket(int32_t family, 
    25742579    goto loser;
    25752580  }
    25762581 
    25772582  nsNSSShutDownList::trackSSLSocketCreate();
    25782583
    25792584  PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("[%p] Socket set up\n", (void*)sslSock));
    25802585  infoObject->QueryInterface(NS_GET_IID(nsISupports), (void**) (info));
    25812586
    2582   // We are going use a clear connection first //
    2583   if (forSTARTTLS || proxyHost) {
     2587  // We are going use a clear connection first
     2588  if (forSTARTTLS || haveProxy) {
    25842589    infoObject->SetHandshakePending(false);
    25852590  }
    25862591
    25872592  infoObject->SharedState().NoteSocketCreated();
    25882593
    25892594  return NS_OK;
    25902595 loser:
    25912596  NS_IF_RELEASE(infoObject);
  • security/manager/ssl/src/nsNSSIOLayer.h

    diff --git a/security/manager/ssl/src/nsNSSIOLayer.h b/security/manager/ssl/src/nsNSSIOLayer.h
    a b  
    99
    1010#include "TransportSecurityInfo.h"
    1111#include "nsISSLSocketControl.h"
    1212#include "nsIClientAuthDialogs.h"
    1313#include "nsNSSCertificate.h"
    1414#include "nsDataHashtable.h"
    1515#include "nsTHashtable.h"
    1616#include "mozilla/TimeStamp.h"
     17#include "nsIProxyInfo.h"
    1718
    1819namespace mozilla {
    1920namespace psm {
    2021class SharedSSLState;
    2122}
    2223}
    2324
    2425class nsIObserver;
    public: 
    160161  void clearStoredData();
    161162private:
    162163  nsCOMPtr<nsIObserver> mPrefObserver;
    163164};
    164165
    165166nsresult nsSSLIOLayerNewSocket(int32_t family,
    166167                               const char *host,
    167168                               int32_t port,
    168                                const char *proxyHost,
    169                                int32_t proxyPort,
     169                               nsIProxyInfo *proxy,
    170170                               PRFileDesc **fd,
    171171                               nsISupports **securityInfo,
    172172                               bool forSTARTTLS,
    173173                               uint32_t flags);
    174174
    175175nsresult nsSSLIOLayerAddToSocket(int32_t family,
    176176                                 const char *host,
    177177                                 int32_t port,
    178                                  const char *proxyHost,
    179                                  int32_t proxyPort,
     178                                 nsIProxyInfo *proxy,
    180179                                 PRFileDesc *fd,
    181180                                 nsISupports **securityInfo,
    182181                                 bool forSTARTTLS,
    183182                                 uint32_t flags);
    184183
    185184nsresult nsSSLIOLayerFreeTLSIntolerantSites();
    186185nsresult displayUnknownCertErrorAlert(nsNSSSocketInfo *infoObject, int error);
    187186
  • 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);
    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);
    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);
    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);
    6460 
    6561  return (NS_FAILED(rv)) ? NS_ERROR_SOCKET_CREATE_FAILED : NS_OK;
    6662}