1 /*
2  *  Copyright 2004 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 #ifndef RTC_BASE_SOCKET_ADAPTERS_H_
12 #define RTC_BASE_SOCKET_ADAPTERS_H_
13 
14 #include <string>
15 
16 #include "api/array_view.h"
17 #include "rtc_base/async_socket.h"
18 #include "rtc_base/constructor_magic.h"
19 #include "rtc_base/crypt_string.h"
20 
21 namespace rtc {
22 
23 struct HttpAuthContext;
24 class ByteBufferReader;
25 class ByteBufferWriter;
26 
27 ///////////////////////////////////////////////////////////////////////////////
28 
29 // Implements a socket adapter that can buffer and process data internally,
30 // as in the case of connecting to a proxy, where you must speak the proxy
31 // protocol before commencing normal socket behavior.
32 class BufferedReadAdapter : public AsyncSocketAdapter {
33  public:
34   BufferedReadAdapter(AsyncSocket* socket, size_t buffer_size);
35   ~BufferedReadAdapter() override;
36 
37   int Send(const void* pv, size_t cb) override;
38   int Recv(void* pv, size_t cb, int64_t* timestamp) override;
39 
40  protected:
DirectSend(const void * pv,size_t cb)41   int DirectSend(const void* pv, size_t cb) {
42     return AsyncSocketAdapter::Send(pv, cb);
43   }
44 
45   void BufferInput(bool on = true);
46   virtual void ProcessInput(char* data, size_t* len) = 0;
47 
48   void OnReadEvent(AsyncSocket* socket) override;
49 
50  private:
51   char* buffer_;
52   size_t buffer_size_, data_len_;
53   bool buffering_;
54   RTC_DISALLOW_COPY_AND_ASSIGN(BufferedReadAdapter);
55 };
56 
57 ///////////////////////////////////////////////////////////////////////////////
58 
59 // Implements a socket adapter that performs the client side of a
60 // fake SSL handshake. Used for "ssltcp" P2P functionality.
61 class AsyncSSLSocket : public BufferedReadAdapter {
62  public:
63   static ArrayView<const uint8_t> SslClientHello();
64   static ArrayView<const uint8_t> SslServerHello();
65 
66   explicit AsyncSSLSocket(AsyncSocket* socket);
67 
68   int Connect(const SocketAddress& addr) override;
69 
70  protected:
71   void OnConnectEvent(AsyncSocket* socket) override;
72   void ProcessInput(char* data, size_t* len) override;
73   RTC_DISALLOW_COPY_AND_ASSIGN(AsyncSSLSocket);
74 };
75 
76 ///////////////////////////////////////////////////////////////////////////////
77 
78 // Implements a socket adapter that speaks the HTTP/S proxy protocol.
79 class AsyncHttpsProxySocket : public BufferedReadAdapter {
80  public:
81   AsyncHttpsProxySocket(AsyncSocket* socket,
82                         const std::string& user_agent,
83                         const SocketAddress& proxy,
84                         const std::string& username,
85                         const CryptString& password);
86   ~AsyncHttpsProxySocket() override;
87 
88   // If connect is forced, the adapter will always issue an HTTP CONNECT to the
89   // target address.  Otherwise, it will connect only if the destination port
90   // is not port 80.
SetForceConnect(bool force)91   void SetForceConnect(bool force) { force_connect_ = force; }
92 
93   int Connect(const SocketAddress& addr) override;
94   SocketAddress GetRemoteAddress() const override;
95   int Close() override;
96   ConnState GetState() const override;
97 
98  protected:
99   void OnConnectEvent(AsyncSocket* socket) override;
100   void OnCloseEvent(AsyncSocket* socket, int err) override;
101   void ProcessInput(char* data, size_t* len) override;
102 
103   bool ShouldIssueConnect() const;
104   void SendRequest();
105   void ProcessLine(char* data, size_t len);
106   void EndResponse();
107   void Error(int error);
108 
109  private:
110   SocketAddress proxy_, dest_;
111   std::string agent_, user_, headers_;
112   CryptString pass_;
113   bool force_connect_;
114   size_t content_length_;
115   int defer_error_;
116   bool expect_close_;
117   enum ProxyState {
118     PS_INIT,
119     PS_LEADER,
120     PS_AUTHENTICATE,
121     PS_SKIP_HEADERS,
122     PS_ERROR_HEADERS,
123     PS_TUNNEL_HEADERS,
124     PS_SKIP_BODY,
125     PS_TUNNEL,
126     PS_WAIT_CLOSE,
127     PS_ERROR
128   } state_;
129   HttpAuthContext* context_;
130   std::string unknown_mechanisms_;
131   RTC_DISALLOW_COPY_AND_ASSIGN(AsyncHttpsProxySocket);
132 };
133 
134 ///////////////////////////////////////////////////////////////////////////////
135 
136 // Implements a socket adapter that speaks the SOCKS proxy protocol.
137 class AsyncSocksProxySocket : public BufferedReadAdapter {
138  public:
139   AsyncSocksProxySocket(AsyncSocket* socket,
140                         const SocketAddress& proxy,
141                         const std::string& username,
142                         const CryptString& password);
143   ~AsyncSocksProxySocket() override;
144 
145   int Connect(const SocketAddress& addr) override;
146   SocketAddress GetRemoteAddress() const override;
147   int Close() override;
148   ConnState GetState() const override;
149 
150  protected:
151   void OnConnectEvent(AsyncSocket* socket) override;
152   void ProcessInput(char* data, size_t* len) override;
153 
154   void SendHello();
155   void SendConnect();
156   void SendAuth();
157   void Error(int error);
158 
159  private:
160   enum State { SS_INIT, SS_HELLO, SS_AUTH, SS_CONNECT, SS_TUNNEL, SS_ERROR };
161   State state_;
162   SocketAddress proxy_, dest_;
163   std::string user_;
164   CryptString pass_;
165   RTC_DISALLOW_COPY_AND_ASSIGN(AsyncSocksProxySocket);
166 };
167 
168 }  // namespace rtc
169 
170 #endif  // RTC_BASE_SOCKET_ADAPTERS_H_
171