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