• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * libjingle
3  * Copyright 2004--2005, Google Inc.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  *  1. Redistributions of source code must retain the above copyright notice,
9  *     this list of conditions and the following disclaimer.
10  *  2. Redistributions in binary form must reproduce the above copyright notice,
11  *     this list of conditions and the following disclaimer in the documentation
12  *     and/or other materials provided with the distribution.
13  *  3. The name of the author may not be used to endorse or promote products
14  *     derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19  * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 #ifndef TALK_BASE_SOCKETADAPTERS_H_
29 #define TALK_BASE_SOCKETADAPTERS_H_
30 
31 #include <map>
32 #include <string>
33 
34 #include "talk/base/asyncsocket.h"
35 #include "talk/base/cryptstring.h"
36 #include "talk/base/logging.h"
37 
38 namespace talk_base {
39 
40 struct HttpAuthContext;
41 class ByteBuffer;
42 
43 ///////////////////////////////////////////////////////////////////////////////
44 
45 // Implements a socket adapter that can buffer and process data internally,
46 // as in the case of connecting to a proxy, where you must speak the proxy
47 // protocol before commencing normal socket behavior.
48 class BufferedReadAdapter : public AsyncSocketAdapter {
49  public:
50   BufferedReadAdapter(AsyncSocket* socket, size_t buffer_size);
51   virtual ~BufferedReadAdapter();
52 
53   virtual int Send(const void* pv, size_t cb);
54   virtual int Recv(void* pv, size_t cb);
55 
56  protected:
DirectSend(const void * pv,size_t cb)57   int DirectSend(const void* pv, size_t cb) {
58     return AsyncSocketAdapter::Send(pv, cb);
59   }
60 
61   void BufferInput(bool on = true);
62   virtual void ProcessInput(char* data, size_t* len) = 0;
63 
64   virtual void OnReadEvent(AsyncSocket * socket);
65 
66  private:
67   char * buffer_;
68   size_t buffer_size_, data_len_;
69   bool buffering_;
70   DISALLOW_EVIL_CONSTRUCTORS(BufferedReadAdapter);
71 };
72 
73 ///////////////////////////////////////////////////////////////////////////////
74 
75 // Interface for implementing proxy server sockets.
76 class AsyncProxyServerSocket : public BufferedReadAdapter {
77  public:
AsyncProxyServerSocket(AsyncSocket * socket,size_t buffer_size)78   AsyncProxyServerSocket(AsyncSocket* socket, size_t buffer_size)
79       : BufferedReadAdapter(socket, buffer_size) {}
80   sigslot::signal2<AsyncProxyServerSocket*,
81                    const SocketAddress&>  SignalConnectRequest;
82   virtual void SendConnectResult(int err, const SocketAddress& addr) = 0;
83 };
84 
85 ///////////////////////////////////////////////////////////////////////////////
86 
87 // Implements a socket adapter that performs the client side of a
88 // fake SSL handshake. Used for "ssltcp" P2P functionality.
89 class AsyncSSLSocket : public BufferedReadAdapter {
90  public:
91   explicit AsyncSSLSocket(AsyncSocket* socket);
92 
93   virtual int Connect(const SocketAddress& addr);
94 
95  protected:
96   virtual void OnConnectEvent(AsyncSocket* socket);
97   virtual void ProcessInput(char* data, size_t* len);
98   DISALLOW_EVIL_CONSTRUCTORS(AsyncSSLSocket);
99 };
100 
101 // Implements a socket adapter that performs the server side of a
102 // fake SSL handshake. Used when implementing a relay server that does "ssltcp".
103 class AsyncSSLServerSocket : public BufferedReadAdapter {
104  public:
105   explicit AsyncSSLServerSocket(AsyncSocket* socket);
106 
107  protected:
108   virtual void ProcessInput(char* data, size_t* len);
109   DISALLOW_EVIL_CONSTRUCTORS(AsyncSSLServerSocket);
110 };
111 
112 ///////////////////////////////////////////////////////////////////////////////
113 
114 // Implements a socket adapter that speaks the HTTP/S proxy protocol.
115 class AsyncHttpsProxySocket : public BufferedReadAdapter {
116  public:
117   AsyncHttpsProxySocket(AsyncSocket* socket, const std::string& user_agent,
118     const SocketAddress& proxy,
119     const std::string& username, const CryptString& password);
120   virtual ~AsyncHttpsProxySocket();
121 
122   // If connect is forced, the adapter will always issue an HTTP CONNECT to the
123   // target address.  Otherwise, it will connect only if the destination port
124   // is not port 80.
SetForceConnect(bool force)125   void SetForceConnect(bool force) { force_connect_ = force; }
126 
127   virtual int Connect(const SocketAddress& addr);
128   virtual SocketAddress GetRemoteAddress() const;
129   virtual int Close();
130   virtual ConnState GetState() const;
131 
132  protected:
133   virtual void OnConnectEvent(AsyncSocket* socket);
134   virtual void OnCloseEvent(AsyncSocket* socket, int err);
135   virtual void ProcessInput(char* data, size_t* len);
136 
137   bool ShouldIssueConnect() const;
138   void SendRequest();
139   void ProcessLine(char* data, size_t len);
140   void EndResponse();
141   void Error(int error);
142 
143  private:
144   SocketAddress proxy_, dest_;
145   std::string agent_, user_, headers_;
146   CryptString pass_;
147   bool force_connect_;
148   size_t content_length_;
149   int defer_error_;
150   bool expect_close_;
151   enum ProxyState {
152     PS_INIT, PS_LEADER, PS_AUTHENTICATE, PS_SKIP_HEADERS, PS_ERROR_HEADERS,
153     PS_TUNNEL_HEADERS, PS_SKIP_BODY, PS_TUNNEL, PS_WAIT_CLOSE, PS_ERROR
154   } state_;
155   HttpAuthContext * context_;
156   std::string unknown_mechanisms_;
157   DISALLOW_EVIL_CONSTRUCTORS(AsyncHttpsProxySocket);
158 };
159 
160 /* TODO: Implement this.
161 class AsyncHttpsProxyServerSocket : public AsyncProxyServerSocket {
162  public:
163   explicit AsyncHttpsProxyServerSocket(AsyncSocket* socket);
164 
165  private:
166   virtual void ProcessInput(char * data, size_t& len);
167   void Error(int error);
168   DISALLOW_EVIL_CONSTRUCTORS(AsyncHttpsProxyServerSocket);
169 };
170 */
171 
172 ///////////////////////////////////////////////////////////////////////////////
173 
174 // Implements a socket adapter that speaks the SOCKS proxy protocol.
175 class AsyncSocksProxySocket : public BufferedReadAdapter {
176  public:
177   AsyncSocksProxySocket(AsyncSocket* socket, const SocketAddress& proxy,
178     const std::string& username, const CryptString& password);
179 
180   virtual int Connect(const SocketAddress& addr);
181   virtual SocketAddress GetRemoteAddress() const;
182   virtual int Close();
183   virtual ConnState GetState() const;
184 
185  protected:
186   virtual void OnConnectEvent(AsyncSocket* socket);
187   virtual void ProcessInput(char* data, size_t* len);
188 
189   void SendHello();
190   void SendConnect();
191   void SendAuth();
192   void Error(int error);
193 
194  private:
195   enum State {
196     SS_INIT, SS_HELLO, SS_AUTH, SS_CONNECT, SS_TUNNEL, SS_ERROR
197   };
198   State state_;
199   SocketAddress proxy_, dest_;
200   std::string user_;
201   CryptString pass_;
202   DISALLOW_EVIL_CONSTRUCTORS(AsyncSocksProxySocket);
203 };
204 
205 // Implements a proxy server socket for the SOCKS protocol.
206 class AsyncSocksProxyServerSocket : public AsyncProxyServerSocket {
207  public:
208   explicit AsyncSocksProxyServerSocket(AsyncSocket* socket);
209 
210  private:
211   virtual void ProcessInput(char* data, size_t* len);
212   void DirectSend(const ByteBuffer& buf);
213 
214   void HandleHello(ByteBuffer* request);
215   void SendHelloReply(int method);
216   void HandleAuth(ByteBuffer* request);
217   void SendAuthReply(int result);
218   void HandleConnect(ByteBuffer* request);
219   virtual void SendConnectResult(int result, const SocketAddress& addr);
220 
221   void Error(int error);
222 
223   static const int kBufferSize = 1024;
224   enum State {
225     SS_HELLO, SS_AUTH, SS_CONNECT, SS_CONNECT_PENDING, SS_TUNNEL, SS_ERROR
226   };
227   State state_;
228   DISALLOW_EVIL_CONSTRUCTORS(AsyncSocksProxyServerSocket);
229 };
230 
231 ///////////////////////////////////////////////////////////////////////////////
232 
233 // Implements a socket adapter that logs everything that it sends and receives.
234 class LoggingSocketAdapter : public AsyncSocketAdapter {
235  public:
236   LoggingSocketAdapter(AsyncSocket* socket, LoggingSeverity level,
237                  const char * label, bool hex_mode = false);
238 
239   virtual int Send(const void *pv, size_t cb);
240   virtual int SendTo(const void *pv, size_t cb, const SocketAddress& addr);
241   virtual int Recv(void *pv, size_t cb);
242   virtual int RecvFrom(void *pv, size_t cb, SocketAddress *paddr);
243   virtual int Close();
244 
245  protected:
246   virtual void OnConnectEvent(AsyncSocket * socket);
247   virtual void OnCloseEvent(AsyncSocket * socket, int err);
248 
249  private:
250   LoggingSeverity level_;
251   std::string label_;
252   bool hex_mode_;
253   LogMultilineState lms_;
254   DISALLOW_EVIL_CONSTRUCTORS(LoggingSocketAdapter);
255 };
256 
257 ///////////////////////////////////////////////////////////////////////////////
258 
259 }  // namespace talk_base
260 
261 #endif  // TALK_BASE_SOCKETADAPTERS_H_
262