• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
ProxySocketAdapter(SslSocketFactory * factory,int family,int type)30   ProxySocketAdapter(SslSocketFactory* factory, int family, int type)
31       : AsyncSocketAdapter(NULL), factory_(factory), family_(family),
32         type_(type), detect_(NULL) {
33   }
~ProxySocketAdapter()34   ~ProxySocketAdapter() override {
35     Close();
36   }
37 
Connect(const SocketAddress & addr)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   }
GetError() const54   int GetError() const override {
55     if (socket_) {
56       return socket_->GetError();
57     }
58     return detect_ ? EWOULDBLOCK : EADDRNOTAVAIL;
59   }
Close()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   }
GetState() const70   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
OnProxyDetectionComplete(SignalThread * thread)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 
SslSocketFactory(SocketFactory * factory,const std::string & user_agent)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 
CreateSocket(int type)115 Socket* SslSocketFactory::CreateSocket(int type) {
116   return CreateSocket(AF_INET, type);
117 }
118 
CreateSocket(int family,int type)119 Socket* SslSocketFactory::CreateSocket(int family, int type) {
120   return factory_->CreateSocket(family, type);
121 }
122 
CreateAsyncSocket(int type)123 AsyncSocket* SslSocketFactory::CreateAsyncSocket(int type) {
124   return CreateAsyncSocket(AF_INET, type);
125 }
126 
CreateAsyncSocket(int family,int type)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 
CreateProxySocket(const ProxyInfo & proxy,int family,int type)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