diff --git a/README.md b/README.md index ecf765e..e70a95c 100644 --- a/README.md +++ b/README.md @@ -28,5 +28,4 @@ server.callback_enable(proxys::callback_udp, &udp_callback); ###### todo list: > *bind command support*
> *support ipv6*
-> *backward compatibility with socsk4*
-> *add more comments (or write small doc) to internal functional*
+> *add more comments (or write small doc) to internal functional*
\ No newline at end of file diff --git a/includes/proxy.hpp b/includes/proxy.hpp index faafaac..5baabbb 100644 --- a/includes/proxy.hpp +++ b/includes/proxy.hpp @@ -25,6 +25,12 @@ namespace proxys { callback_tcp = 2, }; + enum types { + socks4 = 0x01, + socks5 = 0x02, + http = 0x04, + }; + enum states { state_handshake = 0, state_connection_request = 1, @@ -162,10 +168,9 @@ class client { #define udp_callback_t bool, client*, unsigned int&, unsigned int&, unsigned short&, unsigned short&, proxys::data* #define tcp_callback_t bool, client*, std::string, std::string, proxys::data* -class proxy : virtual utils -{ +class proxy : virtual utils { public: - proxy(unsigned short port) { + proxy(unsigned short port, unsigned int proxy_type_ = proxys::socks5) : proxy_type((proxys::types)proxy_type_) { #ifdef _WIN32 WSADATA wsaData = { 0 }; WSAStartup(MAKEWORD(2, 2), &wsaData); @@ -178,8 +183,8 @@ class proxy : virtual utils sockaddr.sin_addr.s_addr = INADDR_ANY; sockaddr.sin_port = htons(port); - if (bind(socket_, (struct sockaddr*)&sockaddr, sockaddr_size) == -1) return; - if (listen(socket_, SOMAXCONN) == -1) return; + if(bind(socket_, (struct sockaddr*)&sockaddr, sockaddr_size) == -1) return; + if(listen(socket_, SOMAXCONN) == -1) return; std::thread([&]{accept_clients();}).detach(); }; @@ -301,7 +306,40 @@ class proxy : virtual utils case proxys::state_handshake: { if (buf->length < 3) return false; proxys::handshake* handshake = (proxys::handshake*)(buf->data); - if(handshake->protocol_version != 0x05) return false; + + if(handshake->protocol_version == 0x04 && (this->proxy_type & proxys::socks4)) { + switch(handshake->method_count) { + case 0x01: { + if(buf->length < 8) return false; + + person->set_dst_port(*(unsigned short*)&buf->data[2]); + person->set_dst_addr(*(unsigned int*)&buf->data[4]); + + if (!person->init_personal(0)) { + unsigned char error[8] = { 0x00, 0x5B }; + person->send_data(error, 8); + return false; + }; + + unsigned char packet[8] = { 0x00, 0x5A }; + *(unsigned short*)&packet[2] = htons(person->get_proxy_data().second); + *(unsigned int*)&packet[4] = local_ipv4; + + person->update_state(proxys::state_tcp_proxyfy); + std::thread([this, person] {personal_network(person); }).detach(); + + return person->send_data(packet, 8); + }; + + default: { // bind already not supported + return false; + }; + }; + + return true; + }; + + if(handshake->protocol_version != 0x05 || !(this->proxy_type & proxys::socks5)) return false; unsigned char packet[2] = { 0x05, 0xFF }; for (unsigned char i = 0; i < handshake->method_count; i++) { @@ -395,7 +433,7 @@ class proxy : virtual utils unsigned char packet[10] = { 0x05, 0x00, 0x00, 0x01 }; *(unsigned int*)&packet[4] = local_ipv4; *(unsigned short*)&packet[8] = htons(person->get_proxy_data().second); - + return person->send_data(packet, 10); }; @@ -438,6 +476,7 @@ class proxy : virtual utils long long socket_ = -1; unsigned int local_ipv4 = 0; + proxys::types proxy_type = proxys::socks5; std::pair auth_data; std::unordered_map clients; diff --git a/source/main.cpp b/source/main.cpp index 2b154a4..90c7005 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -1,7 +1,7 @@ #include "headers.hpp" #ifndef EPS_LIBRARY - proxy proxy_server = { 1337 }; + proxy proxy_server = { 1337, (proxys::socks4 | proxys::socks5) }; int main() { while(1) std::this_thread::sleep_for(std::chrono::milliseconds(45));