Home | History | Annotate | Download | only in base
      1 /*
      2  *  Copyright 2007 The WebRTC Project Authors. All rights reserved.
      3  *
      4  *  Use of this source code is governed by a BSD-style license
      5  *  that can be found in the LICENSE file in the root of the source
      6  *  tree. An additional intellectual property rights grant can be found
      7  *  in the file PATENTS.  All contributing project authors may
      8  *  be found in the AUTHORS file in the root of the source tree.
      9  */
     10 
     11 #include "webrtc/base/autodetectproxy.h"
     12 #include "webrtc/base/httpcommon.h"
     13 #include "webrtc/base/httpcommon-inl.h"
     14 #include "webrtc/base/scoped_ptr.h"
     15 #include "webrtc/base/socketadapters.h"
     16 #include "webrtc/base/ssladapter.h"
     17 #include "webrtc/base/sslsocketfactory.h"
     18 
     19 namespace rtc {
     20 
     21 ///////////////////////////////////////////////////////////////////////////////
     22 // ProxySocketAdapter
     23 // TODO: Consider combining AutoDetectProxy and ProxySocketAdapter.  I think
     24 // the socket adapter is the more appropriate idiom for automatic proxy
     25 // detection.  We may or may not want to combine proxydetect.* as well.
     26 ///////////////////////////////////////////////////////////////////////////////
     27 
     28 class ProxySocketAdapter : public AsyncSocketAdapter {
     29  public:
     30   ProxySocketAdapter(SslSocketFactory* factory, int family, int type)
     31       : AsyncSocketAdapter(NULL), factory_(factory), family_(family),
     32         type_(type), detect_(NULL) {
     33   }
     34   ~ProxySocketAdapter() override {
     35     Close();
     36   }
     37 
     38   int Connect(const SocketAddress& addr) override {
     39     ASSERT(NULL == detect_);
     40     ASSERT(NULL == socket_);
     41     remote_ = addr;
     42     if (remote_.IsAnyIP() && remote_.hostname().empty()) {
     43       LOG_F(LS_ERROR) << "Empty address";
     44       return SOCKET_ERROR;
     45     }
     46     Url<char> url("/", remote_.HostAsURIString(), remote_.port());
     47     detect_ = new AutoDetectProxy(factory_->agent_);
     48     detect_->set_server_url(url.url());
     49     detect_->SignalWorkDone.connect(this,
     50         &ProxySocketAdapter::OnProxyDetectionComplete);
     51     detect_->Start();
     52     return SOCKET_ERROR;
     53   }
     54   int GetError() const override {
     55     if (socket_) {
     56       return socket_->GetError();
     57     }
     58     return detect_ ? EWOULDBLOCK : EADDRNOTAVAIL;
     59   }
     60   int Close() override {
     61     if (socket_) {
     62       return socket_->Close();
     63     }
     64     if (detect_) {
     65       detect_->Destroy(false);
     66       detect_ = NULL;
     67     }
     68     return 0;
     69   }
     70   ConnState GetState() const override {
     71     if (socket_) {
     72       return socket_->GetState();
     73     }
     74     return detect_ ? CS_CONNECTING : CS_CLOSED;
     75   }
     76 
     77 private:
     78   // AutoDetectProxy Slots
     79   void OnProxyDetectionComplete(SignalThread* thread) {
     80     ASSERT(detect_ == thread);
     81     Attach(factory_->CreateProxySocket(detect_->proxy(), family_, type_));
     82     detect_->Release();
     83     detect_ = NULL;
     84     if (0 == AsyncSocketAdapter::Connect(remote_)) {
     85       SignalConnectEvent(this);
     86     } else if (!IsBlockingError(socket_->GetError())) {
     87       SignalCloseEvent(this, socket_->GetError());
     88     }
     89   }
     90 
     91   SslSocketFactory* factory_;
     92   int family_;
     93   int type_;
     94   SocketAddress remote_;
     95   AutoDetectProxy* detect_;
     96 };
     97 
     98 ///////////////////////////////////////////////////////////////////////////////
     99 // SslSocketFactory
    100 ///////////////////////////////////////////////////////////////////////////////
    101 
    102 SslSocketFactory::SslSocketFactory(SocketFactory* factory,
    103                                    const std::string& user_agent)
    104     : factory_(factory),
    105       agent_(user_agent),
    106       autodetect_proxy_(true),
    107       force_connect_(false),
    108       logging_level_(LS_VERBOSE),
    109       binary_mode_(false),
    110       ignore_bad_cert_(false) {
    111 }
    112 
    113 SslSocketFactory::~SslSocketFactory() = default;
    114 
    115 Socket* SslSocketFactory::CreateSocket(int type) {
    116   return CreateSocket(AF_INET, type);
    117 }
    118 
    119 Socket* SslSocketFactory::CreateSocket(int family, int type) {
    120   return factory_->CreateSocket(family, type);
    121 }
    122 
    123 AsyncSocket* SslSocketFactory::CreateAsyncSocket(int type) {
    124   return CreateAsyncSocket(AF_INET, type);
    125 }
    126 
    127 AsyncSocket* SslSocketFactory::CreateAsyncSocket(int family, int type) {
    128   if (autodetect_proxy_) {
    129     return new ProxySocketAdapter(this, family, type);
    130   } else {
    131     return CreateProxySocket(proxy_, family, type);
    132   }
    133 }
    134 
    135 
    136 AsyncSocket* SslSocketFactory::CreateProxySocket(const ProxyInfo& proxy,
    137                                                  int family,
    138                                                  int type) {
    139   AsyncSocket* socket = factory_->CreateAsyncSocket(family, type);
    140   if (!socket)
    141     return NULL;
    142 
    143   // Binary logging happens at the lowest level
    144   if (!logging_label_.empty() && binary_mode_) {
    145     socket = new LoggingSocketAdapter(socket, logging_level_,
    146                                       logging_label_.c_str(), binary_mode_);
    147   }
    148 
    149   if (proxy.type) {
    150     AsyncSocket* proxy_socket = 0;
    151     if (proxy_.type == PROXY_SOCKS5) {
    152       proxy_socket = new AsyncSocksProxySocket(socket, proxy.address,
    153                                                proxy.username, proxy.password);
    154     } else {
    155       // Note: we are trying unknown proxies as HTTPS currently
    156       AsyncHttpsProxySocket* http_proxy =
    157           new AsyncHttpsProxySocket(socket, agent_, proxy.address,
    158                                     proxy.username, proxy.password);
    159       http_proxy->SetForceConnect(force_connect_ || !hostname_.empty());
    160       proxy_socket = http_proxy;
    161     }
    162     if (!proxy_socket) {
    163       delete socket;
    164       return NULL;
    165     }
    166     socket = proxy_socket;  // for our purposes the proxy is now the socket
    167   }
    168 
    169   if (!hostname_.empty()) {
    170     rtc::scoped_ptr<SSLAdapter> ssl_adapter(SSLAdapter::Create(socket));
    171     if (!ssl_adapter) {
    172       LOG_F(LS_ERROR) << "SSL unavailable";
    173       delete socket;
    174       return NULL;
    175     }
    176 
    177     ssl_adapter->set_ignore_bad_cert(ignore_bad_cert_);
    178     if (ssl_adapter->StartSSL(hostname_.c_str(), true) != 0) {
    179       LOG_F(LS_ERROR) << "SSL failed to start.";
    180       return NULL;
    181     }
    182     socket = ssl_adapter.release();
    183   }
    184 
    185   // Regular logging occurs at the highest level
    186   if (!logging_label_.empty() && !binary_mode_) {
    187     socket = new LoggingSocketAdapter(socket, logging_level_,
    188                                       logging_label_.c_str(), binary_mode_);
    189   }
    190   return socket;
    191 }
    192 
    193 ///////////////////////////////////////////////////////////////////////////////
    194 
    195 }  // namespace rtc
    196