Home | History | Annotate | Download | only in base
      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 #if defined(_MSC_VER) && _MSC_VER < 1300
     12 #pragma warning(disable:4786)
     13 #endif
     14 
     15 #include <time.h>
     16 #include <errno.h>
     17 
     18 #if defined(WEBRTC_WIN)
     19 #define WIN32_LEAN_AND_MEAN
     20 #include <windows.h>
     21 #include <winsock2.h>
     22 #include <ws2tcpip.h>
     23 #define SECURITY_WIN32
     24 #include <security.h>
     25 #endif
     26 
     27 #include <algorithm>
     28 
     29 #include "webrtc/base/bytebuffer.h"
     30 #include "webrtc/base/common.h"
     31 #include "webrtc/base/httpcommon.h"
     32 #include "webrtc/base/logging.h"
     33 #include "webrtc/base/socketadapters.h"
     34 #include "webrtc/base/stringencode.h"
     35 #include "webrtc/base/stringutils.h"
     36 
     37 #if defined(WEBRTC_WIN)
     38 #include "webrtc/base/sec_buffer.h"
     39 #endif  // WEBRTC_WIN
     40 
     41 namespace rtc {
     42 
     43 BufferedReadAdapter::BufferedReadAdapter(AsyncSocket* socket, size_t size)
     44     : AsyncSocketAdapter(socket), buffer_size_(size),
     45       data_len_(0), buffering_(false) {
     46   buffer_ = new char[buffer_size_];
     47 }
     48 
     49 BufferedReadAdapter::~BufferedReadAdapter() {
     50   delete [] buffer_;
     51 }
     52 
     53 int BufferedReadAdapter::Send(const void *pv, size_t cb) {
     54   if (buffering_) {
     55     // TODO: Spoof error better; Signal Writeable
     56     socket_->SetError(EWOULDBLOCK);
     57     return -1;
     58   }
     59   return AsyncSocketAdapter::Send(pv, cb);
     60 }
     61 
     62 int BufferedReadAdapter::Recv(void *pv, size_t cb) {
     63   if (buffering_) {
     64     socket_->SetError(EWOULDBLOCK);
     65     return -1;
     66   }
     67 
     68   size_t read = 0;
     69 
     70   if (data_len_) {
     71     read = std::min(cb, data_len_);
     72     memcpy(pv, buffer_, read);
     73     data_len_ -= read;
     74     if (data_len_ > 0) {
     75       memmove(buffer_, buffer_ + read, data_len_);
     76     }
     77     pv = static_cast<char *>(pv) + read;
     78     cb -= read;
     79   }
     80 
     81   // FIX: If cb == 0, we won't generate another read event
     82 
     83   int res = AsyncSocketAdapter::Recv(pv, cb);
     84   if (res >= 0) {
     85     // Read from socket and possibly buffer; return combined length
     86     return res + static_cast<int>(read);
     87   }
     88 
     89   if (read > 0) {
     90     // Failed to read from socket, but still read something from buffer
     91     return static_cast<int>(read);
     92   }
     93 
     94   // Didn't read anything; return error from socket
     95   return res;
     96 }
     97 
     98 void BufferedReadAdapter::BufferInput(bool on) {
     99   buffering_ = on;
    100 }
    101 
    102 void BufferedReadAdapter::OnReadEvent(AsyncSocket * socket) {
    103   ASSERT(socket == socket_);
    104 
    105   if (!buffering_) {
    106     AsyncSocketAdapter::OnReadEvent(socket);
    107     return;
    108   }
    109 
    110   if (data_len_ >= buffer_size_) {
    111     LOG(INFO) << "Input buffer overflow";
    112     ASSERT(false);
    113     data_len_ = 0;
    114   }
    115 
    116   int len = socket_->Recv(buffer_ + data_len_, buffer_size_ - data_len_);
    117   if (len < 0) {
    118     // TODO: Do something better like forwarding the error to the user.
    119     LOG_ERR(INFO) << "Recv";
    120     return;
    121   }
    122 
    123   data_len_ += len;
    124 
    125   ProcessInput(buffer_, &data_len_);
    126 }
    127 
    128 AsyncProxyServerSocket::AsyncProxyServerSocket(AsyncSocket* socket,
    129                                                size_t buffer_size)
    130     : BufferedReadAdapter(socket, buffer_size) {
    131 }
    132 
    133 AsyncProxyServerSocket::~AsyncProxyServerSocket() = default;
    134 
    135 ///////////////////////////////////////////////////////////////////////////////
    136 
    137 // This is a SSL v2 CLIENT_HELLO message.
    138 // TODO: Should this have a session id? The response doesn't have a
    139 // certificate, so the hello should have a session id.
    140 static const uint8_t kSslClientHello[] = {
    141     0x80, 0x46,                                            // msg len
    142     0x01,                                                  // CLIENT_HELLO
    143     0x03, 0x01,                                            // SSL 3.1
    144     0x00, 0x2d,                                            // ciphersuite len
    145     0x00, 0x00,                                            // session id len
    146     0x00, 0x10,                                            // challenge len
    147     0x01, 0x00, 0x80, 0x03, 0x00, 0x80, 0x07, 0x00, 0xc0,  // ciphersuites
    148     0x06, 0x00, 0x40, 0x02, 0x00, 0x80, 0x04, 0x00, 0x80,  //
    149     0x00, 0x00, 0x04, 0x00, 0xfe, 0xff, 0x00, 0x00, 0x0a,  //
    150     0x00, 0xfe, 0xfe, 0x00, 0x00, 0x09, 0x00, 0x00, 0x64,  //
    151     0x00, 0x00, 0x62, 0x00, 0x00, 0x03, 0x00, 0x00, 0x06,  //
    152     0x1f, 0x17, 0x0c, 0xa6, 0x2f, 0x00, 0x78, 0xfc,        // challenge
    153     0x46, 0x55, 0x2e, 0xb1, 0x83, 0x39, 0xf1, 0xea         //
    154 };
    155 
    156 // This is a TLSv1 SERVER_HELLO message.
    157 static const uint8_t kSslServerHello[] = {
    158     0x16,                                            // handshake message
    159     0x03, 0x01,                                      // SSL 3.1
    160     0x00, 0x4a,                                      // message len
    161     0x02,                                            // SERVER_HELLO
    162     0x00, 0x00, 0x46,                                // handshake len
    163     0x03, 0x01,                                      // SSL 3.1
    164     0x42, 0x85, 0x45, 0xa7, 0x27, 0xa9, 0x5d, 0xa0,  // server random
    165     0xb3, 0xc5, 0xe7, 0x53, 0xda, 0x48, 0x2b, 0x3f,  //
    166     0xc6, 0x5a, 0xca, 0x89, 0xc1, 0x58, 0x52, 0xa1,  //
    167     0x78, 0x3c, 0x5b, 0x17, 0x46, 0x00, 0x85, 0x3f,  //
    168     0x20,                                            // session id len
    169     0x0e, 0xd3, 0x06, 0x72, 0x5b, 0x5b, 0x1b, 0x5f,  // session id
    170     0x15, 0xac, 0x13, 0xf9, 0x88, 0x53, 0x9d, 0x9b,  //
    171     0xe8, 0x3d, 0x7b, 0x0c, 0x30, 0x32, 0x6e, 0x38,  //
    172     0x4d, 0xa2, 0x75, 0x57, 0x41, 0x6c, 0x34, 0x5c,  //
    173     0x00, 0x04,                                      // RSA/RC4-128/MD5
    174     0x00                                             // null compression
    175 };
    176 
    177 AsyncSSLSocket::AsyncSSLSocket(AsyncSocket* socket)
    178     : BufferedReadAdapter(socket, 1024) {
    179 }
    180 
    181 int AsyncSSLSocket::Connect(const SocketAddress& addr) {
    182   // Begin buffering before we connect, so that there isn't a race condition
    183   // between potential senders and receiving the OnConnectEvent signal
    184   BufferInput(true);
    185   return BufferedReadAdapter::Connect(addr);
    186 }
    187 
    188 void AsyncSSLSocket::OnConnectEvent(AsyncSocket * socket) {
    189   ASSERT(socket == socket_);
    190   // TODO: we could buffer output too...
    191   VERIFY(sizeof(kSslClientHello) ==
    192       DirectSend(kSslClientHello, sizeof(kSslClientHello)));
    193 }
    194 
    195 void AsyncSSLSocket::ProcessInput(char* data, size_t* len) {
    196   if (*len < sizeof(kSslServerHello))
    197     return;
    198 
    199   if (memcmp(kSslServerHello, data, sizeof(kSslServerHello)) != 0) {
    200     Close();
    201     SignalCloseEvent(this, 0);  // TODO: error code?
    202     return;
    203   }
    204 
    205   *len -= sizeof(kSslServerHello);
    206   if (*len > 0) {
    207     memmove(data, data + sizeof(kSslServerHello), *len);
    208   }
    209 
    210   bool remainder = (*len > 0);
    211   BufferInput(false);
    212   SignalConnectEvent(this);
    213 
    214   // FIX: if SignalConnect causes the socket to be destroyed, we are in trouble
    215   if (remainder)
    216     SignalReadEvent(this);
    217 }
    218 
    219 AsyncSSLServerSocket::AsyncSSLServerSocket(AsyncSocket* socket)
    220      : BufferedReadAdapter(socket, 1024) {
    221   BufferInput(true);
    222 }
    223 
    224 void AsyncSSLServerSocket::ProcessInput(char* data, size_t* len) {
    225   // We only accept client hello messages.
    226   if (*len < sizeof(kSslClientHello)) {
    227     return;
    228   }
    229 
    230   if (memcmp(kSslClientHello, data, sizeof(kSslClientHello)) != 0) {
    231     Close();
    232     SignalCloseEvent(this, 0);
    233     return;
    234   }
    235 
    236   *len -= sizeof(kSslClientHello);
    237 
    238   // Clients should not send more data until the handshake is completed.
    239   ASSERT(*len == 0);
    240 
    241   // Send a server hello back to the client.
    242   DirectSend(kSslServerHello, sizeof(kSslServerHello));
    243 
    244   // Handshake completed for us, redirect input to our parent.
    245   BufferInput(false);
    246 }
    247 
    248 ///////////////////////////////////////////////////////////////////////////////
    249 
    250 AsyncHttpsProxySocket::AsyncHttpsProxySocket(AsyncSocket* socket,
    251                                              const std::string& user_agent,
    252                                              const SocketAddress& proxy,
    253                                              const std::string& username,
    254                                              const CryptString& password)
    255   : BufferedReadAdapter(socket, 1024), proxy_(proxy), agent_(user_agent),
    256     user_(username), pass_(password), force_connect_(false), state_(PS_ERROR),
    257     context_(0) {
    258 }
    259 
    260 AsyncHttpsProxySocket::~AsyncHttpsProxySocket() {
    261   delete context_;
    262 }
    263 
    264 int AsyncHttpsProxySocket::Connect(const SocketAddress& addr) {
    265   int ret;
    266   LOG(LS_VERBOSE) << "AsyncHttpsProxySocket::Connect("
    267                   << proxy_.ToSensitiveString() << ")";
    268   dest_ = addr;
    269   state_ = PS_INIT;
    270   if (ShouldIssueConnect()) {
    271     BufferInput(true);
    272   }
    273   ret = BufferedReadAdapter::Connect(proxy_);
    274   // TODO: Set state_ appropriately if Connect fails.
    275   return ret;
    276 }
    277 
    278 SocketAddress AsyncHttpsProxySocket::GetRemoteAddress() const {
    279   return dest_;
    280 }
    281 
    282 int AsyncHttpsProxySocket::Close() {
    283   headers_.clear();
    284   state_ = PS_ERROR;
    285   dest_.Clear();
    286   delete context_;
    287   context_ = NULL;
    288   return BufferedReadAdapter::Close();
    289 }
    290 
    291 Socket::ConnState AsyncHttpsProxySocket::GetState() const {
    292   if (state_ < PS_TUNNEL) {
    293     return CS_CONNECTING;
    294   } else if (state_ == PS_TUNNEL) {
    295     return CS_CONNECTED;
    296   } else {
    297     return CS_CLOSED;
    298   }
    299 }
    300 
    301 void AsyncHttpsProxySocket::OnConnectEvent(AsyncSocket * socket) {
    302   LOG(LS_VERBOSE) << "AsyncHttpsProxySocket::OnConnectEvent";
    303   if (!ShouldIssueConnect()) {
    304     state_ = PS_TUNNEL;
    305     BufferedReadAdapter::OnConnectEvent(socket);
    306     return;
    307   }
    308   SendRequest();
    309 }
    310 
    311 void AsyncHttpsProxySocket::OnCloseEvent(AsyncSocket * socket, int err) {
    312   LOG(LS_VERBOSE) << "AsyncHttpsProxySocket::OnCloseEvent(" << err << ")";
    313   if ((state_ == PS_WAIT_CLOSE) && (err == 0)) {
    314     state_ = PS_ERROR;
    315     Connect(dest_);
    316   } else {
    317     BufferedReadAdapter::OnCloseEvent(socket, err);
    318   }
    319 }
    320 
    321 void AsyncHttpsProxySocket::ProcessInput(char* data, size_t* len) {
    322   size_t start = 0;
    323   for (size_t pos = start; state_ < PS_TUNNEL && pos < *len;) {
    324     if (state_ == PS_SKIP_BODY) {
    325       size_t consume = std::min(*len - pos, content_length_);
    326       pos += consume;
    327       start = pos;
    328       content_length_ -= consume;
    329       if (content_length_ == 0) {
    330         EndResponse();
    331       }
    332       continue;
    333     }
    334 
    335     if (data[pos++] != '\n')
    336       continue;
    337 
    338     size_t len = pos - start - 1;
    339     if ((len > 0) && (data[start + len - 1] == '\r'))
    340       --len;
    341 
    342     data[start + len] = 0;
    343     ProcessLine(data + start, len);
    344     start = pos;
    345   }
    346 
    347   *len -= start;
    348   if (*len > 0) {
    349     memmove(data, data + start, *len);
    350   }
    351 
    352   if (state_ != PS_TUNNEL)
    353     return;
    354 
    355   bool remainder = (*len > 0);
    356   BufferInput(false);
    357   SignalConnectEvent(this);
    358 
    359   // FIX: if SignalConnect causes the socket to be destroyed, we are in trouble
    360   if (remainder)
    361     SignalReadEvent(this);  // TODO: signal this??
    362 }
    363 
    364 bool AsyncHttpsProxySocket::ShouldIssueConnect() const {
    365   // TODO: Think about whether a more sophisticated test
    366   // than dest port == 80 is needed.
    367   return force_connect_ || (dest_.port() != 80);
    368 }
    369 
    370 void AsyncHttpsProxySocket::SendRequest() {
    371   std::stringstream ss;
    372   ss << "CONNECT " << dest_.ToString() << " HTTP/1.0\r\n";
    373   ss << "User-Agent: " << agent_ << "\r\n";
    374   ss << "Host: " << dest_.HostAsURIString() << "\r\n";
    375   ss << "Content-Length: 0\r\n";
    376   ss << "Proxy-Connection: Keep-Alive\r\n";
    377   ss << headers_;
    378   ss << "\r\n";
    379   std::string str = ss.str();
    380   DirectSend(str.c_str(), str.size());
    381   state_ = PS_LEADER;
    382   expect_close_ = true;
    383   content_length_ = 0;
    384   headers_.clear();
    385 
    386   LOG(LS_VERBOSE) << "AsyncHttpsProxySocket >> " << str;
    387 }
    388 
    389 void AsyncHttpsProxySocket::ProcessLine(char * data, size_t len) {
    390   LOG(LS_VERBOSE) << "AsyncHttpsProxySocket << " << data;
    391 
    392   if (len == 0) {
    393     if (state_ == PS_TUNNEL_HEADERS) {
    394       state_ = PS_TUNNEL;
    395     } else if (state_ == PS_ERROR_HEADERS) {
    396       Error(defer_error_);
    397       return;
    398     } else if (state_ == PS_SKIP_HEADERS) {
    399       if (content_length_) {
    400         state_ = PS_SKIP_BODY;
    401       } else {
    402         EndResponse();
    403         return;
    404       }
    405     } else {
    406       static bool report = false;
    407       if (!unknown_mechanisms_.empty() && !report) {
    408         report = true;
    409         std::string msg(
    410           "Unable to connect to the Google Talk service due to an incompatibility "
    411           "with your proxy.\r\nPlease help us resolve this issue by submitting the "
    412           "following information to us using our technical issue submission form "
    413           "at:\r\n\r\n"
    414           "http://www.google.com/support/talk/bin/request.py\r\n\r\n"
    415           "We apologize for the inconvenience.\r\n\r\n"
    416           "Information to submit to Google: "
    417           );
    418         //std::string msg("Please report the following information to foo (at) bar.com:\r\nUnknown methods: ");
    419         msg.append(unknown_mechanisms_);
    420 #if defined(WEBRTC_WIN)
    421         MessageBoxA(0, msg.c_str(), "Oops!", MB_OK);
    422 #endif
    423 #if defined(WEBRTC_POSIX)
    424         // TODO: Raise a signal so the UI can be separated.
    425         LOG(LS_ERROR) << "Oops!\n\n" << msg;
    426 #endif
    427       }
    428       // Unexpected end of headers
    429       Error(0);
    430       return;
    431     }
    432   } else if (state_ == PS_LEADER) {
    433     unsigned int code;
    434     if (sscanf(data, "HTTP/%*u.%*u %u", &code) != 1) {
    435       Error(0);
    436       return;
    437     }
    438     switch (code) {
    439     case 200:
    440       // connection good!
    441       state_ = PS_TUNNEL_HEADERS;
    442       return;
    443 #if defined(HTTP_STATUS_PROXY_AUTH_REQ) && (HTTP_STATUS_PROXY_AUTH_REQ != 407)
    444 #error Wrong code for HTTP_STATUS_PROXY_AUTH_REQ
    445 #endif
    446     case 407:  // HTTP_STATUS_PROXY_AUTH_REQ
    447       state_ = PS_AUTHENTICATE;
    448       return;
    449     default:
    450       defer_error_ = 0;
    451       state_ = PS_ERROR_HEADERS;
    452       return;
    453     }
    454   } else if ((state_ == PS_AUTHENTICATE)
    455              && (_strnicmp(data, "Proxy-Authenticate:", 19) == 0)) {
    456     std::string response, auth_method;
    457     switch (HttpAuthenticate(data + 19, len - 19,
    458                              proxy_, "CONNECT", "/",
    459                              user_, pass_, context_, response, auth_method)) {
    460     case HAR_IGNORE:
    461       LOG(LS_VERBOSE) << "Ignoring Proxy-Authenticate: " << auth_method;
    462       if (!unknown_mechanisms_.empty())
    463         unknown_mechanisms_.append(", ");
    464       unknown_mechanisms_.append(auth_method);
    465       break;
    466     case HAR_RESPONSE:
    467       headers_ = "Proxy-Authorization: ";
    468       headers_.append(response);
    469       headers_.append("\r\n");
    470       state_ = PS_SKIP_HEADERS;
    471       unknown_mechanisms_.clear();
    472       break;
    473     case HAR_CREDENTIALS:
    474       defer_error_ = SOCKET_EACCES;
    475       state_ = PS_ERROR_HEADERS;
    476       unknown_mechanisms_.clear();
    477       break;
    478     case HAR_ERROR:
    479       defer_error_ = 0;
    480       state_ = PS_ERROR_HEADERS;
    481       unknown_mechanisms_.clear();
    482       break;
    483     }
    484   } else if (_strnicmp(data, "Content-Length:", 15) == 0) {
    485     content_length_ = strtoul(data + 15, 0, 0);
    486   } else if (_strnicmp(data, "Proxy-Connection: Keep-Alive", 28) == 0) {
    487     expect_close_ = false;
    488     /*
    489   } else if (_strnicmp(data, "Connection: close", 17) == 0) {
    490     expect_close_ = true;
    491     */
    492   }
    493 }
    494 
    495 void AsyncHttpsProxySocket::EndResponse() {
    496   if (!expect_close_) {
    497     SendRequest();
    498     return;
    499   }
    500 
    501   // No point in waiting for the server to close... let's close now
    502   // TODO: Refactor out PS_WAIT_CLOSE
    503   state_ = PS_WAIT_CLOSE;
    504   BufferedReadAdapter::Close();
    505   OnCloseEvent(this, 0);
    506 }
    507 
    508 void AsyncHttpsProxySocket::Error(int error) {
    509   BufferInput(false);
    510   Close();
    511   SetError(error);
    512   SignalCloseEvent(this, error);
    513 }
    514 
    515 ///////////////////////////////////////////////////////////////////////////////
    516 
    517 AsyncSocksProxySocket::AsyncSocksProxySocket(AsyncSocket* socket,
    518                                              const SocketAddress& proxy,
    519                                              const std::string& username,
    520                                              const CryptString& password)
    521     : BufferedReadAdapter(socket, 1024), state_(SS_ERROR), proxy_(proxy),
    522       user_(username), pass_(password) {
    523 }
    524 
    525 AsyncSocksProxySocket::~AsyncSocksProxySocket() = default;
    526 
    527 int AsyncSocksProxySocket::Connect(const SocketAddress& addr) {
    528   int ret;
    529   dest_ = addr;
    530   state_ = SS_INIT;
    531   BufferInput(true);
    532   ret = BufferedReadAdapter::Connect(proxy_);
    533   // TODO: Set state_ appropriately if Connect fails.
    534   return ret;
    535 }
    536 
    537 SocketAddress AsyncSocksProxySocket::GetRemoteAddress() const {
    538   return dest_;
    539 }
    540 
    541 int AsyncSocksProxySocket::Close() {
    542   state_ = SS_ERROR;
    543   dest_.Clear();
    544   return BufferedReadAdapter::Close();
    545 }
    546 
    547 Socket::ConnState AsyncSocksProxySocket::GetState() const {
    548   if (state_ < SS_TUNNEL) {
    549     return CS_CONNECTING;
    550   } else if (state_ == SS_TUNNEL) {
    551     return CS_CONNECTED;
    552   } else {
    553     return CS_CLOSED;
    554   }
    555 }
    556 
    557 void AsyncSocksProxySocket::OnConnectEvent(AsyncSocket* socket) {
    558   SendHello();
    559 }
    560 
    561 void AsyncSocksProxySocket::ProcessInput(char* data, size_t* len) {
    562   ASSERT(state_ < SS_TUNNEL);
    563 
    564   ByteBuffer response(data, *len);
    565 
    566   if (state_ == SS_HELLO) {
    567     uint8_t ver, method;
    568     if (!response.ReadUInt8(&ver) ||
    569         !response.ReadUInt8(&method))
    570       return;
    571 
    572     if (ver != 5) {
    573       Error(0);
    574       return;
    575     }
    576 
    577     if (method == 0) {
    578       SendConnect();
    579     } else if (method == 2) {
    580       SendAuth();
    581     } else {
    582       Error(0);
    583       return;
    584     }
    585   } else if (state_ == SS_AUTH) {
    586     uint8_t ver, status;
    587     if (!response.ReadUInt8(&ver) ||
    588         !response.ReadUInt8(&status))
    589       return;
    590 
    591     if ((ver != 1) || (status != 0)) {
    592       Error(SOCKET_EACCES);
    593       return;
    594     }
    595 
    596     SendConnect();
    597   } else if (state_ == SS_CONNECT) {
    598     uint8_t ver, rep, rsv, atyp;
    599     if (!response.ReadUInt8(&ver) ||
    600         !response.ReadUInt8(&rep) ||
    601         !response.ReadUInt8(&rsv) ||
    602         !response.ReadUInt8(&atyp))
    603       return;
    604 
    605     if ((ver != 5) || (rep != 0)) {
    606       Error(0);
    607       return;
    608     }
    609 
    610     uint16_t port;
    611     if (atyp == 1) {
    612       uint32_t addr;
    613       if (!response.ReadUInt32(&addr) ||
    614           !response.ReadUInt16(&port))
    615         return;
    616       LOG(LS_VERBOSE) << "Bound on " << addr << ":" << port;
    617     } else if (atyp == 3) {
    618       uint8_t len;
    619       std::string addr;
    620       if (!response.ReadUInt8(&len) ||
    621           !response.ReadString(&addr, len) ||
    622           !response.ReadUInt16(&port))
    623         return;
    624       LOG(LS_VERBOSE) << "Bound on " << addr << ":" << port;
    625     } else if (atyp == 4) {
    626       std::string addr;
    627       if (!response.ReadString(&addr, 16) ||
    628           !response.ReadUInt16(&port))
    629         return;
    630       LOG(LS_VERBOSE) << "Bound on <IPV6>:" << port;
    631     } else {
    632       Error(0);
    633       return;
    634     }
    635 
    636     state_ = SS_TUNNEL;
    637   }
    638 
    639   // Consume parsed data
    640   *len = response.Length();
    641   memcpy(data, response.Data(), *len);
    642 
    643   if (state_ != SS_TUNNEL)
    644     return;
    645 
    646   bool remainder = (*len > 0);
    647   BufferInput(false);
    648   SignalConnectEvent(this);
    649 
    650   // FIX: if SignalConnect causes the socket to be destroyed, we are in trouble
    651   if (remainder)
    652     SignalReadEvent(this);  // TODO: signal this??
    653 }
    654 
    655 void AsyncSocksProxySocket::SendHello() {
    656   ByteBuffer request;
    657   request.WriteUInt8(5);    // Socks Version
    658   if (user_.empty()) {
    659     request.WriteUInt8(1);  // Authentication Mechanisms
    660     request.WriteUInt8(0);  // No authentication
    661   } else {
    662     request.WriteUInt8(2);  // Authentication Mechanisms
    663     request.WriteUInt8(0);  // No authentication
    664     request.WriteUInt8(2);  // Username/Password
    665   }
    666   DirectSend(request.Data(), request.Length());
    667   state_ = SS_HELLO;
    668 }
    669 
    670 void AsyncSocksProxySocket::SendAuth() {
    671   ByteBuffer request;
    672   request.WriteUInt8(1);           // Negotiation Version
    673   request.WriteUInt8(static_cast<uint8_t>(user_.size()));
    674   request.WriteString(user_);      // Username
    675   request.WriteUInt8(static_cast<uint8_t>(pass_.GetLength()));
    676   size_t len = pass_.GetLength() + 1;
    677   char * sensitive = new char[len];
    678   pass_.CopyTo(sensitive, true);
    679   request.WriteString(sensitive);  // Password
    680   memset(sensitive, 0, len);
    681   delete [] sensitive;
    682   DirectSend(request.Data(), request.Length());
    683   state_ = SS_AUTH;
    684 }
    685 
    686 void AsyncSocksProxySocket::SendConnect() {
    687   ByteBuffer request;
    688   request.WriteUInt8(5);              // Socks Version
    689   request.WriteUInt8(1);              // CONNECT
    690   request.WriteUInt8(0);              // Reserved
    691   if (dest_.IsUnresolvedIP()) {
    692     std::string hostname = dest_.hostname();
    693     request.WriteUInt8(3);            // DOMAINNAME
    694     request.WriteUInt8(static_cast<uint8_t>(hostname.size()));
    695     request.WriteString(hostname);    // Destination Hostname
    696   } else {
    697     request.WriteUInt8(1);            // IPV4
    698     request.WriteUInt32(dest_.ip());  // Destination IP
    699   }
    700   request.WriteUInt16(dest_.port());  // Destination Port
    701   DirectSend(request.Data(), request.Length());
    702   state_ = SS_CONNECT;
    703 }
    704 
    705 void AsyncSocksProxySocket::Error(int error) {
    706   state_ = SS_ERROR;
    707   BufferInput(false);
    708   Close();
    709   SetError(SOCKET_EACCES);
    710   SignalCloseEvent(this, error);
    711 }
    712 
    713 AsyncSocksProxyServerSocket::AsyncSocksProxyServerSocket(AsyncSocket* socket)
    714     : AsyncProxyServerSocket(socket, kBufferSize), state_(SS_HELLO) {
    715   BufferInput(true);
    716 }
    717 
    718 void AsyncSocksProxyServerSocket::ProcessInput(char* data, size_t* len) {
    719   // TODO: See if the whole message has arrived
    720   ASSERT(state_ < SS_CONNECT_PENDING);
    721 
    722   ByteBuffer response(data, *len);
    723   if (state_ == SS_HELLO) {
    724     HandleHello(&response);
    725   } else if (state_ == SS_AUTH) {
    726     HandleAuth(&response);
    727   } else if (state_ == SS_CONNECT) {
    728     HandleConnect(&response);
    729   }
    730 
    731   // Consume parsed data
    732   *len = response.Length();
    733   memcpy(data, response.Data(), *len);
    734 }
    735 
    736 void AsyncSocksProxyServerSocket::DirectSend(const ByteBuffer& buf) {
    737   BufferedReadAdapter::DirectSend(buf.Data(), buf.Length());
    738 }
    739 
    740 void AsyncSocksProxyServerSocket::HandleHello(ByteBuffer* request) {
    741   uint8_t ver, num_methods;
    742   if (!request->ReadUInt8(&ver) ||
    743       !request->ReadUInt8(&num_methods)) {
    744     Error(0);
    745     return;
    746   }
    747 
    748   if (ver != 5) {
    749     Error(0);
    750     return;
    751   }
    752 
    753   // Handle either no-auth (0) or user/pass auth (2)
    754   uint8_t method = 0xFF;
    755   if (num_methods > 0 && !request->ReadUInt8(&method)) {
    756     Error(0);
    757     return;
    758   }
    759 
    760   // TODO: Ask the server which method to use.
    761   SendHelloReply(method);
    762   if (method == 0) {
    763     state_ = SS_CONNECT;
    764   } else if (method == 2) {
    765     state_ = SS_AUTH;
    766   } else {
    767     state_ = SS_ERROR;
    768   }
    769 }
    770 
    771 void AsyncSocksProxyServerSocket::SendHelloReply(uint8_t method) {
    772   ByteBuffer response;
    773   response.WriteUInt8(5);  // Socks Version
    774   response.WriteUInt8(method);  // Auth method
    775   DirectSend(response);
    776 }
    777 
    778 void AsyncSocksProxyServerSocket::HandleAuth(ByteBuffer* request) {
    779   uint8_t ver, user_len, pass_len;
    780   std::string user, pass;
    781   if (!request->ReadUInt8(&ver) ||
    782       !request->ReadUInt8(&user_len) ||
    783       !request->ReadString(&user, user_len) ||
    784       !request->ReadUInt8(&pass_len) ||
    785       !request->ReadString(&pass, pass_len)) {
    786     Error(0);
    787     return;
    788   }
    789 
    790   // TODO: Allow for checking of credentials.
    791   SendAuthReply(0);
    792   state_ = SS_CONNECT;
    793 }
    794 
    795 void AsyncSocksProxyServerSocket::SendAuthReply(uint8_t result) {
    796   ByteBuffer response;
    797   response.WriteUInt8(1);  // Negotiation Version
    798   response.WriteUInt8(result);
    799   DirectSend(response);
    800 }
    801 
    802 void AsyncSocksProxyServerSocket::HandleConnect(ByteBuffer* request) {
    803   uint8_t ver, command, reserved, addr_type;
    804   uint32_t ip;
    805   uint16_t port;
    806   if (!request->ReadUInt8(&ver) ||
    807       !request->ReadUInt8(&command) ||
    808       !request->ReadUInt8(&reserved) ||
    809       !request->ReadUInt8(&addr_type) ||
    810       !request->ReadUInt32(&ip) ||
    811       !request->ReadUInt16(&port)) {
    812       Error(0);
    813       return;
    814   }
    815 
    816   if (ver != 5 || command != 1 ||
    817       reserved != 0 || addr_type != 1) {
    818       Error(0);
    819       return;
    820   }
    821 
    822   SignalConnectRequest(this, SocketAddress(ip, port));
    823   state_ = SS_CONNECT_PENDING;
    824 }
    825 
    826 void AsyncSocksProxyServerSocket::SendConnectResult(int result,
    827                                                     const SocketAddress& addr) {
    828   if (state_ != SS_CONNECT_PENDING)
    829     return;
    830 
    831   ByteBuffer response;
    832   response.WriteUInt8(5);  // Socks version
    833   response.WriteUInt8((result != 0));  // 0x01 is generic error
    834   response.WriteUInt8(0);  // reserved
    835   response.WriteUInt8(1);  // IPv4 address
    836   response.WriteUInt32(addr.ip());
    837   response.WriteUInt16(addr.port());
    838   DirectSend(response);
    839   BufferInput(false);
    840   state_ = SS_TUNNEL;
    841 }
    842 
    843 void AsyncSocksProxyServerSocket::Error(int error) {
    844   state_ = SS_ERROR;
    845   BufferInput(false);
    846   Close();
    847   SetError(SOCKET_EACCES);
    848   SignalCloseEvent(this, error);
    849 }
    850 
    851 ///////////////////////////////////////////////////////////////////////////////
    852 
    853 LoggingSocketAdapter::LoggingSocketAdapter(AsyncSocket* socket,
    854                                            LoggingSeverity level,
    855                                            const char * label, bool hex_mode)
    856     : AsyncSocketAdapter(socket), level_(level), hex_mode_(hex_mode) {
    857   label_.append("[");
    858   label_.append(label);
    859   label_.append("]");
    860 }
    861 
    862 int LoggingSocketAdapter::Send(const void *pv, size_t cb) {
    863   int res = AsyncSocketAdapter::Send(pv, cb);
    864   if (res > 0)
    865     LogMultiline(level_, label_.c_str(), false, pv, res, hex_mode_, &lms_);
    866   return res;
    867 }
    868 
    869 int LoggingSocketAdapter::SendTo(const void *pv, size_t cb,
    870                              const SocketAddress& addr) {
    871   int res = AsyncSocketAdapter::SendTo(pv, cb, addr);
    872   if (res > 0)
    873     LogMultiline(level_, label_.c_str(), false, pv, res, hex_mode_, &lms_);
    874   return res;
    875 }
    876 
    877 int LoggingSocketAdapter::Recv(void *pv, size_t cb) {
    878   int res = AsyncSocketAdapter::Recv(pv, cb);
    879   if (res > 0)
    880     LogMultiline(level_, label_.c_str(), true, pv, res, hex_mode_, &lms_);
    881   return res;
    882 }
    883 
    884 int LoggingSocketAdapter::RecvFrom(void *pv, size_t cb, SocketAddress *paddr) {
    885   int res = AsyncSocketAdapter::RecvFrom(pv, cb, paddr);
    886   if (res > 0)
    887     LogMultiline(level_, label_.c_str(), true, pv, res, hex_mode_, &lms_);
    888   return res;
    889 }
    890 
    891 int LoggingSocketAdapter::Close() {
    892   LogMultiline(level_, label_.c_str(), false, NULL, 0, hex_mode_, &lms_);
    893   LogMultiline(level_, label_.c_str(), true, NULL, 0, hex_mode_, &lms_);
    894   LOG_V(level_) << label_ << " Closed locally";
    895   return socket_->Close();
    896 }
    897 
    898 void LoggingSocketAdapter::OnConnectEvent(AsyncSocket * socket) {
    899   LOG_V(level_) << label_ << " Connected";
    900   AsyncSocketAdapter::OnConnectEvent(socket);
    901 }
    902 
    903 void LoggingSocketAdapter::OnCloseEvent(AsyncSocket * socket, int err) {
    904   LogMultiline(level_, label_.c_str(), false, NULL, 0, hex_mode_, &lms_);
    905   LogMultiline(level_, label_.c_str(), true, NULL, 0, hex_mode_, &lms_);
    906   LOG_V(level_) << label_ << " Closed with error: " << err;
    907   AsyncSocketAdapter::OnCloseEvent(socket, err);
    908 }
    909 
    910 ///////////////////////////////////////////////////////////////////////////////
    911 
    912 }  // namespace rtc
    913