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

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

API change, v2. Slightly polished.

  • 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/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 public: 
    6464    virtual ~nsSOCKSSocketInfo() { HandshakeFinished(); }
    6565
    6666    NS_DECL_ISUPPORTS
    6767    NS_DECL_NSISOCKSSOCKETINFO
    6868    NS_DECL_NSIDNSLISTENER
    6969
    7070    void Init(int32_t version,
    7171              int32_t family,
    72               const char *proxyHost,
    73               int32_t proxyPort,
     72              nsIProxyInfo *proxy,
    7473              const char *destinationHost,
    7574              uint32_t flags);
    7675
    7776    void SetConnectTimeout(PRIntervalTime to);
    7877    PRStatus DoHandshake(PRFileDesc *fd, int16_t oflags = -1);
    7978    int16_t GetPollFlags() const;
    8079    bool IsConnected() const { return mState == SOCKS_CONNECTED; }
    8180
    private: 
    119118    uint32_t  mReadOffset;
    120119    uint32_t  mAmountToRead;
    121120    nsCOMPtr<nsIDNSRecord>  mDnsRec;
    122121    nsCOMPtr<nsICancelable> mLookup;
    123122    nsresult                mLookupStatus;
    124123    PRFileDesc             *mFD;
    125124
    126125    nsCString mDestinationHost;
    127     nsCString mProxyHost;
    128     int32_t   mProxyPort;
     126    nsCOMPtr<nsIProxyInfo> mProxy;
    129127    int32_t   mVersion;   // SOCKS version 4 or 5
    130128    int32_t   mDestinationFamily;
    131129    uint32_t  mFlags;
    132130    PRNetAddr mInternalProxyAddr;
    133131    PRNetAddr mExternalProxyAddr;
    134132    PRNetAddr mDestinationAddr;
    135133    PRIntervalTime mTimeout;
    136134};
    137135
    138136nsSOCKSSocketInfo::nsSOCKSSocketInfo()
    139137    : mState(SOCKS_INITIAL)
    140138    , mDataIoPtr(nullptr)
    141139    , mDataLength(0)
    142140    , mReadOffset(0)
    143141    , mAmountToRead(0)
    144     , mProxyPort(-1)
    145142    , mVersion(-1)
    146143    , mDestinationFamily(PR_AF_INET)
    147144    , mFlags(0)
    148145    , mTimeout(PR_INTERVAL_NO_TIMEOUT)
    149146{
    150147    mData = new uint8_t[BUFFER_SIZE];
    151148    PR_InitializeNetAddr(PR_IpAddrAny, 0, &mInternalProxyAddr);
    152149    PR_InitializeNetAddr(PR_IpAddrAny, 0, &mExternalProxyAddr);
    153150    PR_InitializeNetAddr(PR_IpAddrAny, 0, &mDestinationAddr);
    154151}
    155152
    156153void
    157 nsSOCKSSocketInfo::Init(int32_t version, int32_t family, const char *proxyHost, int32_t proxyPort, const char *host, uint32_t flags)
     154nsSOCKSSocketInfo::Init(int32_t version, int32_t family, nsIProxyInfo *proxy, const char *host, uint32_t flags)
    158155{
    159156    mVersion         = version;
    160157    mDestinationFamily = family;
    161     mProxyHost       = proxyHost;
    162     mProxyPort       = proxyPort;
     158    mProxy           = proxy;
    163159    mDestinationHost = host;
    164160    mFlags           = flags;
    165161}
    166162
    167163NS_IMPL_THREADSAFE_ISUPPORTS2(nsSOCKSSocketInfo, nsISOCKSSocketInfo, nsIDNSListener)
    168164
    169165NS_IMETHODIMP
    170166nsSOCKSSocketInfo::GetExternalProxyAddr(PRNetAddr * *aExternalProxyAddr)
    nsSOCKSSocketInfo::StartDNS(PRFileDesc * 
    243239{
    244240    NS_ABORT_IF_FALSE(!mDnsRec && mState == SOCKS_INITIAL,
    245241                      "Must be in initial state to make DNS Lookup");
    246242
    247243    nsCOMPtr<nsIDNSService> dns = do_GetService(NS_DNSSERVICE_CONTRACTID);
    248244    if (!dns)
    249245        return PR_FAILURE;
    250246
     247    nsCString proxyHost;
     248    mProxy->GetHost(proxyHost);
     249
    251250    mFD  = fd;
    252     nsresult rv = dns->AsyncResolve(mProxyHost, 0, this,
     251    nsresult rv = dns->AsyncResolve(proxyHost, 0, this,
    253252                                    NS_GetCurrentThread(),
    254253                                    getter_AddRefs(mLookup));
    255254
    256255    if (NS_FAILED(rv)) {
    257256        LOGERROR(("socks: DNS lookup for SOCKS proxy %s failed",
    258                   mProxyHost.get()));
     257                  proxyHost.get()));
    259258        return PR_FAILURE;
    260259    }
    261260    mState = SOCKS_DNS_IN_PROGRESS;
    262261    PR_SetError(PR_IN_PROGRESS_ERROR, 0);
    263262    return PR_FAILURE;
    264263}
    265264
    266265NS_IMETHODIMP
    nsSOCKSSocketInfo::ConnectToProxy(PRFile 
    293292    }
    294293
    295294    // Try socks5 if the destination addrress is IPv6
    296295    if (mVersion == 4 &&
    297296        PR_NetAddrFamily(&mDestinationAddr) == PR_AF_INET6) {
    298297        mVersion = 5;
    299298    }
    300299
     300    int32_t proxyPort;
     301    mProxy->GetPort(&proxyPort);
     302
    301303    int32_t addresses = 0;
    302304    do {
    303305        if (addresses++)
    304             mDnsRec->ReportUnusable(mProxyPort);
     306            mDnsRec->ReportUnusable(proxyPort);
    305307       
    306         rv = mDnsRec->GetNextAddr(mProxyPort, &mInternalProxyAddr);
     308        rv = mDnsRec->GetNextAddr(proxyPort, &mInternalProxyAddr);
    307309        // No more addresses to try? If so, we'll need to bail
    308310        if (NS_FAILED(rv)) {
     311            nsCString proxyHost;
     312            mProxy->GetHost(proxyHost);
    309313            LOGERROR(("socks: unable to connect to SOCKS proxy, %s",
    310                      mProxyHost.get()));
     314                     proxyHost.get()));
    311315            return PR_FAILURE;
    312316        }
    313317
    314318#if defined(PR_LOGGING)
    315319        char buf[64];
    316320        PR_NetAddrToString(&mInternalProxyAddr, buf, sizeof(buf));
    317321        LOGDEBUG(("socks: trying proxy server, %s:%hu",
    318322                 buf, PR_ntohs(PR_NetAddrInetPort(&mInternalProxyAddr))));
    nsSOCKSIOLayerListen(PRFileDesc *fd, int 
    11861190    return fd->lower->methods->listen(fd->lower, backlog);
    11871191}
    11881192
    11891193// add SOCKS IO layer to an existing socket
    11901194nsresult
    11911195nsSOCKSIOLayerAddToSocket(int32_t family,
    11921196                          const char *host,
    11931197                          int32_t port,
    1194                           const char *proxyHost,
    1195                           int32_t proxyPort,
     1198                          nsIProxyInfo *proxy,
    11961199                          int32_t socksVersion,
    11971200                          uint32_t flags,
    11981201                          PRFileDesc *fd,
    11991202                          nsISupports** info)
    12001203{
    12011204    NS_ENSURE_TRUE((socksVersion == 4) || (socksVersion == 5), NS_ERROR_NOT_INITIALIZED);
    12021205
    12031206
    nsSOCKSIOLayerAddToSocket(int32_t family 
    12541257    {
    12551258        // clean up IOLayerStub
    12561259        LOGERROR(("Failed to create nsSOCKSSocketInfo()."));
    12571260        PR_DELETE(layer);
    12581261        return NS_ERROR_FAILURE;
    12591262    }
    12601263
    12611264    NS_ADDREF(infoObject);
    1262     infoObject->Init(socksVersion, family, proxyHost, proxyPort, host, flags);
     1265    infoObject->Init(socksVersion, family, proxy, host, flags);
    12631266    layer->secret = (PRFilePrivate*) infoObject;
    12641267    rv = PR_PushIOLayer(fd, PR_GetLayersIdentity(fd), layer);
    12651268
    12661269    if (rv == PR_FAILURE) {
    12671270        LOGERROR(("PR_PushIOLayer() failed. rv = %x.", rv));
    12681271        NS_RELEASE(infoObject);
    12691272        PR_DELETE(layer);
    12701273        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}