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