From b5f2b17fd8a44b9a4e6b47f10b405f070814041a Mon Sep 17 00:00:00 2001 From: Harald Alvestrand Date: Thu, 4 Jan 2024 12:02:08 +0000 Subject: [PATCH] Remove SOCKS5 support Bug: webrtc:15726 Change-Id: Icd3aca433966f76e1b200b0f4790013cce12095a Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/331820 Reviewed-by: Tomas Gunnarsson Commit-Queue: Harald Alvestrand Cr-Commit-Position: refs/heads/main@{#41655} --- p2p/base/basic_packet_socket_factory.cc | 6 +- p2p/base/p2p_transport_channel_unittest.cc | 61 ++----- rtc_base/BUILD.gn | 1 - rtc_base/proxy_server.cc | 4 - rtc_base/proxy_server.h | 16 -- rtc_base/proxy_unittest.cc | 68 -------- rtc_base/server_socket_adapters.cc | 131 -------------- rtc_base/server_socket_adapters.h | 34 ---- rtc_base/socket_adapters.cc | 194 --------------------- rtc_base/socket_adapters.h | 36 ---- 10 files changed, 14 insertions(+), 537 deletions(-) delete mode 100644 rtc_base/proxy_unittest.cc diff --git a/p2p/base/basic_packet_socket_factory.cc b/p2p/base/basic_packet_socket_factory.cc index 6a811af71a..816d964360 100644 --- a/p2p/base/basic_packet_socket_factory.cc +++ b/p2p/base/basic_packet_socket_factory.cc @@ -119,11 +119,7 @@ AsyncPacketSocket* BasicPacketSocketFactory::CreateClientTcpSocket( << socket->GetError(); } - // If using a proxy, wrap the socket in a proxy socket. - if (proxy_info.type == PROXY_SOCKS5) { - socket = new AsyncSocksProxySocket( - socket, proxy_info.address, proxy_info.username, proxy_info.password); - } else if (proxy_info.type == PROXY_HTTPS) { + if (proxy_info.type == PROXY_HTTPS) { socket = new AsyncHttpsProxySocket(socket, user_agent, proxy_info.address, proxy_info.username, proxy_info.password); diff --git a/p2p/base/p2p_transport_channel_unittest.cc b/p2p/base/p2p_transport_channel_unittest.cc index e701998e27..5bcfee0473 100644 --- a/p2p/base/p2p_transport_channel_unittest.cc +++ b/p2p/base/p2p_transport_channel_unittest.cc @@ -286,14 +286,6 @@ class P2PTransportChannelTestBase : public ::testing::Test, main_(ss_.get()), stun_server_(TestStunServer::Create(ss_.get(), kStunAddr, main_)), turn_server_(&main_, ss_.get(), kTurnUdpIntAddr, kTurnUdpExtAddr), - socks_server1_(ss_.get(), - kSocksProxyAddrs[0], - ss_.get(), - kSocksProxyAddrs[0]), - socks_server2_(ss_.get(), - kSocksProxyAddrs[1], - ss_.get(), - kSocksProxyAddrs[1]), force_relay_(false) { ep1_.role_ = ICEROLE_CONTROLLING; ep2_.role_ = ICEROLE_CONTROLLED; @@ -330,7 +322,6 @@ class P2PTransportChannelTestBase : public ::testing::Test, BLOCK_UDP_AND_INCOMING_TCP, // Firewall, UDP in/out and TCP in blocked BLOCK_ALL_BUT_OUTGOING_HTTP, // Firewall, only TCP out on 80/443 PROXY_HTTPS, // All traffic through HTTPS proxy - PROXY_SOCKS, // All traffic through SOCKS proxy NUM_CONFIGS }; @@ -1028,8 +1019,6 @@ class P2PTransportChannelTestBase : public ::testing::Test, PendingTaskSafetyFlag::Create(); TestStunServer::StunServerPtr stun_server_; TestTurnServer turn_server_; - rtc::SocksProxyServer socks_server1_; - rtc::SocksProxyServer socks_server2_; Endpoint ep1_; Endpoint ep2_; RemoteIceParameterSource remote_ice_parameter_source_ = FROM_CANDIDATE; @@ -1179,7 +1168,6 @@ class P2PTransportChannelTest : public P2PTransportChannelTestBase { case BLOCK_UDP_AND_INCOMING_TCP: case BLOCK_ALL_BUT_OUTGOING_HTTP: case PROXY_HTTPS: - case PROXY_SOCKS: AddAddress(endpoint, kPublicAddrs[endpoint]); // Block all UDP fw()->AddRule(false, rtc::FP_UDP, rtc::FD_ANY, kPublicAddrs[endpoint]); @@ -1202,13 +1190,6 @@ class P2PTransportChannelTest : public P2PTransportChannelTestBase { fw()->AddRule(false, rtc::FP_TCP, rtc::FD_ANY, kPublicAddrs[endpoint]); SetProxy(endpoint, rtc::PROXY_HTTPS); - } else if (config == PROXY_SOCKS) { - // Block all TCP to/from the endpoint except to the proxy server - fw()->AddRule(true, rtc::FP_TCP, kPublicAddrs[endpoint], - kSocksProxyAddrs[endpoint]); - fw()->AddRule(false, rtc::FP_TCP, rtc::FD_ANY, - kPublicAddrs[endpoint]); - SetProxy(endpoint, rtc::PROXY_SOCKS5); } break; default: @@ -1253,42 +1234,28 @@ class P2PTransportChannelMatrixTest : public P2PTransportChannelTest, const P2PTransportChannelMatrixTest::Result* P2PTransportChannelMatrixTest::kMatrix[NUM_CONFIGS][NUM_CONFIGS] = { // OPEN CONE ADDR PORT SYMM 2CON SCON !UDP !TCP HTTP PRXH - // PRXS - /*OP*/ {LULU, LUSU, LUSU, LUSU, LUPU, LUSU, LUPU, LTPT, LTPT, LSRS, - NULL, LTPT}, + /*OP*/ + {LULU, LUSU, LUSU, LUSU, LUPU, LUSU, LUPU, LTPT, LTPT, LSRS, NULL}, /*CO*/ - {SULU, SUSU, SUSU, SUSU, SUPU, SUSU, SUPU, NULL, NULL, LSRS, NULL, - LTRT}, + {SULU, SUSU, SUSU, SUSU, SUPU, SUSU, SUPU, NULL, NULL, LSRS, NULL}, /*AD*/ - {SULU, SUSU, SUSU, SUSU, SUPU, SUSU, SUPU, NULL, NULL, LSRS, NULL, - LTRT}, + {SULU, SUSU, SUSU, SUSU, SUPU, SUSU, SUPU, NULL, NULL, LSRS, NULL}, /*PO*/ - {SULU, SUSU, SUSU, SUSU, RUPU, SUSU, RUPU, NULL, NULL, LSRS, NULL, - LTRT}, + {SULU, SUSU, SUSU, SUSU, RUPU, SUSU, RUPU, NULL, NULL, LSRS, NULL}, /*SY*/ - {PULU, PUSU, PUSU, PURU, PURU, PUSU, PURU, NULL, NULL, LSRS, NULL, - LTRT}, + {PULU, PUSU, PUSU, PURU, PURU, PUSU, PURU, NULL, NULL, LSRS, NULL}, /*2C*/ - {SULU, SUSU, SUSU, SUSU, SUPU, SUSU, SUPU, NULL, NULL, LSRS, NULL, - LTRT}, + {SULU, SUSU, SUSU, SUSU, SUPU, SUSU, SUPU, NULL, NULL, LSRS, NULL}, /*SC*/ - {PULU, PUSU, PUSU, PURU, PURU, PUSU, PURU, NULL, NULL, LSRS, NULL, - LTRT}, + {PULU, PUSU, PUSU, PURU, PURU, PUSU, PURU, NULL, NULL, LSRS, NULL}, /*!U*/ - {LTPT, NULL, NULL, NULL, NULL, NULL, NULL, LTPT, LTPT, LSRS, NULL, - LTRT}, + {LTPT, NULL, NULL, NULL, NULL, NULL, NULL, LTPT, LTPT, LSRS, NULL}, /*!T*/ - {PTLT, NULL, NULL, NULL, NULL, NULL, NULL, PTLT, LTRT, LSRS, NULL, - LTRT}, + {PTLT, NULL, NULL, NULL, NULL, NULL, NULL, PTLT, LTRT, LSRS, NULL}, /*HT*/ - {LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, NULL, - LSRS}, + {LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, NULL}, /*PR*/ - {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL}, - /*PR*/ - {LTRT, LTRT, LTRT, LTRT, LTRT, LTRT, LTRT, LTRT, LTRT, LSRS, NULL, - LTRT}, + {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, }; // The actual tests that exercise all the various configurations. @@ -1316,8 +1283,7 @@ const P2PTransportChannelMatrixTest::Result* P2P_TEST(x, BLOCK_UDP) \ P2P_TEST(x, BLOCK_UDP_AND_INCOMING_TCP) \ P2P_TEST(x, BLOCK_ALL_BUT_OUTGOING_HTTP) \ - P2P_TEST(x, PROXY_HTTPS) \ - P2P_TEST(x, PROXY_SOCKS) + P2P_TEST(x, PROXY_HTTPS) P2P_TEST_SET(OPEN) P2P_TEST_SET(NAT_FULL_CONE) @@ -1330,7 +1296,6 @@ P2P_TEST_SET(BLOCK_UDP) P2P_TEST_SET(BLOCK_UDP_AND_INCOMING_TCP) P2P_TEST_SET(BLOCK_ALL_BUT_OUTGOING_HTTP) P2P_TEST_SET(PROXY_HTTPS) -P2P_TEST_SET(PROXY_SOCKS) INSTANTIATE_TEST_SUITE_P( All, diff --git a/rtc_base/BUILD.gn b/rtc_base/BUILD.gn index 8d108bbdec..2cf9c11316 100644 --- a/rtc_base/BUILD.gn +++ b/rtc_base/BUILD.gn @@ -2088,7 +2088,6 @@ if (rtc_include_tests) { "nat_unittest.cc", "network_route_unittest.cc", "network_unittest.cc", - "proxy_unittest.cc", "rolling_accumulator_unittest.cc", "rtc_certificate_generator_unittest.cc", "rtc_certificate_unittest.cc", diff --git a/rtc_base/proxy_server.cc b/rtc_base/proxy_server.cc index 84c96213c3..f8fe23da2a 100644 --- a/rtc_base/proxy_server.cc +++ b/rtc_base/proxy_server.cc @@ -149,8 +149,4 @@ void ProxyBinding::Destroy() { SignalDestroyed(this); } -AsyncProxyServerSocket* SocksProxyServer::WrapSocket(Socket* socket) { - return new AsyncSocksProxyServerSocket(socket); -} - } // namespace rtc diff --git a/rtc_base/proxy_server.h b/rtc_base/proxy_server.h index 0b9b655a5e..033dd82118 100644 --- a/rtc_base/proxy_server.h +++ b/rtc_base/proxy_server.h @@ -89,22 +89,6 @@ class ProxyServer : public sigslot::has_slots<> { std::vector> bindings_; }; -// SocksProxyServer is a simple extension of ProxyServer to implement SOCKS. -class SocksProxyServer : public ProxyServer { - public: - SocksProxyServer(SocketFactory* int_factory, - const SocketAddress& int_addr, - SocketFactory* ext_factory, - const SocketAddress& ext_ip) - : ProxyServer(int_factory, int_addr, ext_factory, ext_ip) {} - - SocksProxyServer(const SocksProxyServer&) = delete; - SocksProxyServer& operator=(const SocksProxyServer&) = delete; - - protected: - AsyncProxyServerSocket* WrapSocket(Socket* socket) override; -}; - } // namespace rtc #endif // RTC_BASE_PROXY_SERVER_H_ diff --git a/rtc_base/proxy_unittest.cc b/rtc_base/proxy_unittest.cc deleted file mode 100644 index 9e3898e430..0000000000 --- a/rtc_base/proxy_unittest.cc +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2009 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include "rtc_base/gunit.h" -#include "rtc_base/proxy_server.h" -#include "rtc_base/socket_adapters.h" -#include "rtc_base/test_client.h" -#include "rtc_base/test_echo_server.h" -#include "rtc_base/virtual_socket_server.h" - -using rtc::Socket; -using rtc::SocketAddress; - -static const SocketAddress kSocksProxyIntAddr("1.2.3.4", 1080); -static const SocketAddress kSocksProxyExtAddr("1.2.3.5", 0); -static const SocketAddress kBogusProxyIntAddr("1.2.3.4", 999); - -// Sets up a virtual socket server and a SOCKS5 proxy server. -class ProxyTest : public ::testing::Test { - public: - ProxyTest() : ss_(new rtc::VirtualSocketServer()), thread_(ss_.get()) { - socks_.reset(new rtc::SocksProxyServer(ss_.get(), kSocksProxyIntAddr, - ss_.get(), kSocksProxyExtAddr)); - } - - rtc::SocketServer* ss() { return ss_.get(); } - - private: - std::unique_ptr ss_; - rtc::AutoSocketServerThread thread_; - std::unique_ptr socks_; -}; - -// Tests whether we can use a SOCKS5 proxy to connect to a server. -TEST_F(ProxyTest, TestSocks5Connect) { - rtc::Socket* socket = - ss()->CreateSocket(kSocksProxyIntAddr.family(), SOCK_STREAM); - rtc::AsyncSocksProxySocket* proxy_socket = new rtc::AsyncSocksProxySocket( - socket, kSocksProxyIntAddr, "", rtc::CryptString()); - // TODO: IPv6-ize these tests when proxy supports IPv6. - - rtc::TestEchoServer server(rtc::Thread::Current(), - SocketAddress(INADDR_ANY, 0)); - - std::unique_ptr packet_socket( - rtc::AsyncTCPSocket::Create(proxy_socket, SocketAddress(INADDR_ANY, 0), - server.address())); - EXPECT_TRUE(packet_socket != nullptr); - rtc::TestClient client(std::move(packet_socket)); - - EXPECT_EQ(Socket::CS_CONNECTING, proxy_socket->GetState()); - EXPECT_TRUE(client.CheckConnected()); - EXPECT_EQ(Socket::CS_CONNECTED, proxy_socket->GetState()); - EXPECT_EQ(server.address(), client.remote_address()); - client.Send("foo", 3); - EXPECT_TRUE(client.CheckNextPacket("foo", 3, nullptr)); - EXPECT_TRUE(client.CheckNoPacket()); -} diff --git a/rtc_base/server_socket_adapters.cc b/rtc_base/server_socket_adapters.cc index 0bef752f1e..5a4db26dd2 100644 --- a/rtc_base/server_socket_adapters.cc +++ b/rtc_base/server_socket_adapters.cc @@ -55,135 +55,4 @@ void AsyncSSLServerSocket::ProcessInput(char* data, size_t* len) { BufferInput(false); } -AsyncSocksProxyServerSocket::AsyncSocksProxyServerSocket(Socket* socket) - : AsyncProxyServerSocket(socket, kBufferSize), state_(SS_HELLO) { - BufferInput(true); -} - -void AsyncSocksProxyServerSocket::ProcessInput(char* data, size_t* len) { - RTC_DCHECK(state_ < SS_CONNECT_PENDING); - - ByteBufferReader response( - rtc::MakeArrayView(reinterpret_cast(data), *len)); - if (state_ == SS_HELLO) { - HandleHello(&response); - } else if (state_ == SS_AUTH) { - HandleAuth(&response); - } else if (state_ == SS_CONNECT) { - HandleConnect(&response); - } - - // Consume parsed data - *len = response.Length(); - if (response.Length() > 0) { - memmove(data, response.DataView().data(), *len); - } -} - -void AsyncSocksProxyServerSocket::DirectSend(const ByteBufferWriter& buf) { - BufferedReadAdapter::DirectSend(buf.Data(), buf.Length()); -} - -void AsyncSocksProxyServerSocket::HandleHello(ByteBufferReader* request) { - uint8_t ver, num_methods; - if (!request->ReadUInt8(&ver) || !request->ReadUInt8(&num_methods)) { - Error(0); - return; - } - - if (ver != 5) { - Error(0); - return; - } - - // Handle either no-auth (0) or user/pass auth (2) - uint8_t method = 0xFF; - if (num_methods > 0 && !request->ReadUInt8(&method)) { - Error(0); - return; - } - - SendHelloReply(method); - if (method == 0) { - state_ = SS_CONNECT; - } else if (method == 2) { - state_ = SS_AUTH; - } else { - state_ = SS_ERROR; - } -} - -void AsyncSocksProxyServerSocket::SendHelloReply(uint8_t method) { - ByteBufferWriter response; - response.WriteUInt8(5); // Socks Version - response.WriteUInt8(method); // Auth method - DirectSend(response); -} - -void AsyncSocksProxyServerSocket::HandleAuth(ByteBufferReader* request) { - uint8_t ver, user_len, pass_len; - std::string user, pass; - if (!request->ReadUInt8(&ver) || !request->ReadUInt8(&user_len) || - !request->ReadString(&user, user_len) || !request->ReadUInt8(&pass_len) || - !request->ReadString(&pass, pass_len)) { - Error(0); - return; - } - - SendAuthReply(0); - state_ = SS_CONNECT; -} - -void AsyncSocksProxyServerSocket::SendAuthReply(uint8_t result) { - ByteBufferWriter response; - response.WriteUInt8(1); // Negotiation Version - response.WriteUInt8(result); - DirectSend(response); -} - -void AsyncSocksProxyServerSocket::HandleConnect(ByteBufferReader* request) { - uint8_t ver, command, reserved, addr_type; - uint32_t ip; - uint16_t port; - if (!request->ReadUInt8(&ver) || !request->ReadUInt8(&command) || - !request->ReadUInt8(&reserved) || !request->ReadUInt8(&addr_type) || - !request->ReadUInt32(&ip) || !request->ReadUInt16(&port)) { - Error(0); - return; - } - - if (ver != 5 || command != 1 || reserved != 0 || addr_type != 1) { - Error(0); - return; - } - - SignalConnectRequest(this, SocketAddress(ip, port)); - state_ = SS_CONNECT_PENDING; -} - -void AsyncSocksProxyServerSocket::SendConnectResult(int result, - const SocketAddress& addr) { - if (state_ != SS_CONNECT_PENDING) - return; - - ByteBufferWriter response; - response.WriteUInt8(5); // Socks version - response.WriteUInt8((result != 0)); // 0x01 is generic error - response.WriteUInt8(0); // reserved - response.WriteUInt8(1); // IPv4 address - response.WriteUInt32(addr.ip()); - response.WriteUInt16(addr.port()); - DirectSend(response); - BufferInput(false); - state_ = SS_TUNNEL; -} - -void AsyncSocksProxyServerSocket::Error(int error) { - state_ = SS_ERROR; - BufferInput(false); - Close(); - SetError(SOCKET_EACCES); - SignalCloseEvent(this, error); -} - } // namespace rtc diff --git a/rtc_base/server_socket_adapters.h b/rtc_base/server_socket_adapters.h index b18c7a6a65..05dcd292f8 100644 --- a/rtc_base/server_socket_adapters.h +++ b/rtc_base/server_socket_adapters.h @@ -38,40 +38,6 @@ class AsyncSSLServerSocket : public BufferedReadAdapter { void ProcessInput(char* data, size_t* len) override; }; -// Implements a proxy server socket for the SOCKS protocol. -class AsyncSocksProxyServerSocket : public AsyncProxyServerSocket { - public: - explicit AsyncSocksProxyServerSocket(Socket* socket); - - AsyncSocksProxyServerSocket(const AsyncSocksProxyServerSocket&) = delete; - AsyncSocksProxyServerSocket& operator=(const AsyncSocksProxyServerSocket&) = - delete; - - private: - void ProcessInput(char* data, size_t* len) override; - void DirectSend(const ByteBufferWriter& buf); - - void HandleHello(ByteBufferReader* request); - void SendHelloReply(uint8_t method); - void HandleAuth(ByteBufferReader* request); - void SendAuthReply(uint8_t result); - void HandleConnect(ByteBufferReader* request); - void SendConnectResult(int result, const SocketAddress& addr) override; - - void Error(int error); - - static const int kBufferSize = 1024; - enum State { - SS_HELLO, - SS_AUTH, - SS_CONNECT, - SS_CONNECT_PENDING, - SS_TUNNEL, - SS_ERROR - }; - State state_; -}; - } // namespace rtc #endif // RTC_BASE_SERVER_SOCKET_ADAPTERS_H_ diff --git a/rtc_base/socket_adapters.cc b/rtc_base/socket_adapters.cc index a1eee5bd67..f6fa182f5d 100644 --- a/rtc_base/socket_adapters.cc +++ b/rtc_base/socket_adapters.cc @@ -469,198 +469,4 @@ void AsyncHttpsProxySocket::Error(int error) { SignalCloseEvent(this, error); } -/////////////////////////////////////////////////////////////////////////////// - -AsyncSocksProxySocket::AsyncSocksProxySocket(Socket* socket, - const SocketAddress& proxy, - absl::string_view username, - const CryptString& password) - : BufferedReadAdapter(socket, 1024), - state_(SS_ERROR), - proxy_(proxy), - user_(username), - pass_(password) {} - -AsyncSocksProxySocket::~AsyncSocksProxySocket() = default; - -int AsyncSocksProxySocket::Connect(const SocketAddress& addr) { - int ret; - dest_ = addr; - state_ = SS_INIT; - BufferInput(true); - ret = BufferedReadAdapter::Connect(proxy_); - // TODO: Set state_ appropriately if Connect fails. - return ret; -} - -SocketAddress AsyncSocksProxySocket::GetRemoteAddress() const { - return dest_; -} - -int AsyncSocksProxySocket::Close() { - state_ = SS_ERROR; - dest_.Clear(); - return BufferedReadAdapter::Close(); -} - -Socket::ConnState AsyncSocksProxySocket::GetState() const { - if (state_ < SS_TUNNEL) { - return CS_CONNECTING; - } else if (state_ == SS_TUNNEL) { - return CS_CONNECTED; - } else { - return CS_CLOSED; - } -} - -void AsyncSocksProxySocket::OnConnectEvent(Socket* socket) { - SendHello(); -} - -void AsyncSocksProxySocket::ProcessInput(char* data, size_t* len) { - RTC_DCHECK(state_ < SS_TUNNEL); - - ByteBufferReader response( - rtc::MakeArrayView(reinterpret_cast(data), *len)); - - if (state_ == SS_HELLO) { - uint8_t ver, method; - if (!response.ReadUInt8(&ver) || !response.ReadUInt8(&method)) - return; - - if (ver != 5) { - Error(0); - return; - } - - if (method == 0) { - SendConnect(); - } else if (method == 2) { - SendAuth(); - } else { - Error(0); - return; - } - } else if (state_ == SS_AUTH) { - uint8_t ver, status; - if (!response.ReadUInt8(&ver) || !response.ReadUInt8(&status)) - return; - - if ((ver != 1) || (status != 0)) { - Error(SOCKET_EACCES); - return; - } - - SendConnect(); - } else if (state_ == SS_CONNECT) { - uint8_t ver, rep, rsv, atyp; - if (!response.ReadUInt8(&ver) || !response.ReadUInt8(&rep) || - !response.ReadUInt8(&rsv) || !response.ReadUInt8(&atyp)) - return; - - if ((ver != 5) || (rep != 0)) { - Error(0); - return; - } - - uint16_t port; - if (atyp == 1) { - uint32_t addr; - if (!response.ReadUInt32(&addr) || !response.ReadUInt16(&port)) - return; - RTC_LOG(LS_VERBOSE) << "Bound on " << addr << ":" << port; - } else if (atyp == 3) { - uint8_t length; - std::string addr; - if (!response.ReadUInt8(&length) || !response.ReadString(&addr, length) || - !response.ReadUInt16(&port)) - return; - RTC_LOG(LS_VERBOSE) << "Bound on " << addr << ":" << port; - } else if (atyp == 4) { - std::string addr; - if (!response.ReadString(&addr, 16) || !response.ReadUInt16(&port)) - return; - RTC_LOG(LS_VERBOSE) << "Bound on :" << port; - } else { - Error(0); - return; - } - - state_ = SS_TUNNEL; - } - - // Consume parsed data - *len = response.Length(); - memmove(data, response.Data(), *len); - - if (state_ != SS_TUNNEL) - return; - - bool remainder = (*len > 0); - BufferInput(false); - SignalConnectEvent(this); - - // FIX: if SignalConnect causes the socket to be destroyed, we are in trouble - if (remainder) - SignalReadEvent(this); // TODO: signal this?? -} - -void AsyncSocksProxySocket::SendHello() { - ByteBufferWriter request; - request.WriteUInt8(5); // Socks Version - if (user_.empty()) { - request.WriteUInt8(1); // Authentication Mechanisms - request.WriteUInt8(0); // No authentication - } else { - request.WriteUInt8(2); // Authentication Mechanisms - request.WriteUInt8(0); // No authentication - request.WriteUInt8(2); // Username/Password - } - DirectSend(request.Data(), request.Length()); - state_ = SS_HELLO; -} - -void AsyncSocksProxySocket::SendAuth() { - ByteBufferWriterT> request; - request.WriteUInt8(1); // Negotiation Version - request.WriteUInt8(static_cast(user_.size())); - request.WriteString(user_); // Username - request.WriteUInt8(static_cast(pass_.GetLength())); - size_t len = pass_.GetLength() + 1; - char* sensitive = new char[len]; - pass_.CopyTo(sensitive, true); - request.WriteString(std::string(sensitive, pass_.GetLength())); // Password - ExplicitZeroMemory(sensitive, len); - delete[] sensitive; - DirectSend(request.Data(), request.Length()); - state_ = SS_AUTH; -} - -void AsyncSocksProxySocket::SendConnect() { - ByteBufferWriter request; - request.WriteUInt8(5); // Socks Version - request.WriteUInt8(1); // CONNECT - request.WriteUInt8(0); // Reserved - if (dest_.IsUnresolvedIP()) { - std::string hostname = dest_.hostname(); - request.WriteUInt8(3); // DOMAINNAME - request.WriteUInt8(static_cast(hostname.size())); - request.WriteString(hostname); // Destination Hostname - } else { - request.WriteUInt8(1); // IPV4 - request.WriteUInt32(dest_.ip()); // Destination IP - } - request.WriteUInt16(dest_.port()); // Destination Port - DirectSend(request.Data(), request.Length()); - state_ = SS_CONNECT; -} - -void AsyncSocksProxySocket::Error(int error) { - state_ = SS_ERROR; - BufferInput(false); - Close(); - SetError(SOCKET_EACCES); - SignalCloseEvent(this, error); -} - } // namespace rtc diff --git a/rtc_base/socket_adapters.h b/rtc_base/socket_adapters.h index e78ee18a27..e67c8d4db9 100644 --- a/rtc_base/socket_adapters.h +++ b/rtc_base/socket_adapters.h @@ -137,42 +137,6 @@ class AsyncHttpsProxySocket : public BufferedReadAdapter { std::string unknown_mechanisms_; }; -/////////////////////////////////////////////////////////////////////////////// - -// Implements a socket adapter that speaks the SOCKS proxy protocol. -class AsyncSocksProxySocket : public BufferedReadAdapter { - public: - AsyncSocksProxySocket(Socket* socket, - const SocketAddress& proxy, - absl::string_view username, - const CryptString& password); - ~AsyncSocksProxySocket() override; - - AsyncSocksProxySocket(const AsyncSocksProxySocket&) = delete; - AsyncSocksProxySocket& operator=(const AsyncSocksProxySocket&) = delete; - - int Connect(const SocketAddress& addr) override; - SocketAddress GetRemoteAddress() const override; - int Close() override; - ConnState GetState() const override; - - protected: - void OnConnectEvent(Socket* socket) override; - void ProcessInput(char* data, size_t* len) override; - - void SendHello(); - void SendConnect(); - void SendAuth(); - void Error(int error); - - private: - enum State { SS_INIT, SS_HELLO, SS_AUTH, SS_CONNECT, SS_TUNNEL, SS_ERROR }; - State state_; - SocketAddress proxy_, dest_; - std::string user_; - CryptString pass_; -}; - } // namespace rtc #endif // RTC_BASE_SOCKET_ADAPTERS_H_