diff --git a/SOCKS.cpp b/SOCKS.cpp index 74887462..54ad8e57 100644 --- a/SOCKS.cpp +++ b/SOCKS.cpp @@ -5,6 +5,7 @@ #include "ClientContext.h" #include "I2PEndian.h" #include +#include namespace i2p { @@ -15,17 +16,13 @@ namespace proxy void SOCKS4AHandler::AsyncSockRead() { - LogPrint("--- socks4a async sock read"); + LogPrint(eLogDebug,"--- SOCKS async sock read"); if(m_sock) { - if (m_state == INITIAL) { - m_sock->async_receive(boost::asio::buffer(m_sock_buff, socks_buffer_size), - std::bind(&SOCKS4AHandler::HandleSockRecv, this, - std::placeholders::_1, std::placeholders::_2)); - } else { - LogPrint("--- socks4a state?? ", m_state); - } + m_sock->async_receive(boost::asio::buffer(m_sock_buff, socks_buffer_size), + std::bind(&SOCKS4AHandler::HandleSockRecv, this, + std::placeholders::_1, std::placeholders::_2)); } else { - LogPrint("--- socks4a no socket for read"); + LogPrint(eLogError,"--- SOCKS no socket for read"); } } @@ -37,7 +34,7 @@ namespace proxy void SOCKS4AHandler::SocksFailed() { - LogPrint("--- socks4a failed"); + LogPrint(eLogWarning,"--- SOCKS failed"); //TODO: send the right response boost::asio::async_write(*m_sock, boost::asio::buffer("\x00\x5b 12345"), std::bind(&SOCKS4AHandler::SentSocksFailed, this, @@ -47,7 +44,7 @@ namespace proxy void SOCKS4AHandler::CloseSock() { if (m_sock) { - LogPrint("--- socks4a close sock"); + LogPrint(eLogDebug,"--- SOCKS close sock"); m_sock->close(); delete m_sock; m_sock = nullptr; @@ -57,7 +54,7 @@ namespace proxy void SOCKS4AHandler::CloseStream() { if (m_stream) { - LogPrint("--- socks4a close stream"); + LogPrint(eLogDebug,"--- SOCKS close stream"); m_stream.reset (); } } @@ -66,78 +63,147 @@ namespace proxy const size_t socks_ident_size = 1024; const size_t destb32_len = 52; + std::size_t SOCKS4AHandler::HandleData(uint8_t *sock_buff, std::size_t len) + { + assert(len); // This should always be called with a least a byte left to parse + switch (m_state) { + case GET_VERSION: + return HandleVersion(sock_buff); + case SOCKS4A: + return HandleSOCKS4A(sock_buff,len); + default: + LogPrint(eLogError,"--- SOCKS state?? ", m_state); + Terminate(); + return 0; + } + } + + std::size_t SOCKS4AHandler::HandleVersion(uint8_t *sock_buff) + { + switch (*sock_buff) { + case 4: + m_state = SOCKS4A; // Switch to the 4a handler + m_pstate = GET4A_COMMAND; //Initialize the parser at the right position + return 1; + default: + LogPrint(eLogError,"--- SOCKS rejected invalid version", ((int)*sock_buff)); + Terminate(); + return 0; + } + } + + std::size_t SOCKS4AHandler::HandleSOCKS4A(uint8_t *sock_buff, std::size_t len) + { + std::size_t rv = 0; + while (len > 0) { + rv++; + switch (m_pstate) + { + case GET4A_COMMAND: + if ( *sock_buff != 1 ) { + LogPrint(eLogError,"--- SOCKS4a unsupported command", ((int)*sock_buff)); + SocksFailed(); + return 0; + } + m_pstate = GET4A_PORT1; + break; + case GET4A_PORT1: + m_port = ((uint16_t)*sock_buff) << 8; + m_pstate = GET4A_PORT2; + break; + case GET4A_PORT2: + m_port |= ((uint16_t)*sock_buff); + m_pstate = GET4A_IP1; + break; + case GET4A_IP1: + m_ip = ((uint32_t)*sock_buff) << 24; + m_pstate = GET4A_IP2; + break; + case GET4A_IP2: + m_ip |= ((uint32_t)*sock_buff) << 16; + m_pstate = GEHTTP/1.1 200 OK Set-Cookie: i_like_gitea=1a539c11ce433de6; Path=/; HttpOnly; Secure; SameSite=Lax Set-Cookie: _csrf=93pox8YC9Hq3lp3Iatigm0Uggyo6MTc1MzI2NTUwMjI3OTA2OTkyMQ; Path=/; Max-Age=86400; HttpOnly; Secure; SameSite=Lax X-Frame-Options: SAMEORIGIN Date: Wed, 23 Jul 2025 10:11:42 GMT Content-Type: text/plain; charset=utf-8 Connection: close Transfer-Encoding: chunked Cache-Control: max-age=0, private, must-revalidate, no-transform X-Cache-Status: HIT X-Cache-Age: 0 3267 diff --git a/SOCKS.cpp b/SOCKS.cpp index 74887462..54ad8e57 100644 --- a/SOCKS.cpp +++ b/SOCKS.cpp @@ -5,6 +5,7 @@ #include "ClientContext.h" #include "I2PEndian.h" #include +#include namespace i2p { @@ -15,17 +16,13 @@ namespace proxy void SOCKS4AHandler::AsyncSockRead() { - LogPrint("--- socks4a async sock read"); + LogPrint(eLogDebug,"--- SOCKS async sock read"); if(m_sock) { - if (m_state == INITIAL) { - m_sock->async_receive(boost::asio::buffer(m_sock_buff, socks_buffer_size), - std::bind(&SOCKS4AHandler::HandleSockRecv, this, - std::placeholders::_1, std::placeholders::_2)); - } else { - LogPrint("--- socks4a state?? ", m_state); - } + m_sock->async_receive(boost::asio::buffer(m_sock_buff, socks_buffer_size), + std::bind(&SOCKS4AHandler::HandleSockRecv, this, + std::placeholders::_1, std::placeholders::_2)); } else { - LogPrint("--- socks4a no socket for read"); + LogPrint(eLogError,"--- SOCKS no socket for read"); } } @@ -37,7 +34,7 @@ namespace proxy void SOCKS4AHandler::SocksFailed() { - LogPrint("--- socks4a failed"); + LogPrint(eLogWarning,"--- SOCKS failed"); //TODO: send the right response boost::asio::async_write(*m_sock, boost::asio::buffer("\x00\x5b 12345"), std::bind(&SOCKS4AHandler::SentSocksFailed, this, @@ -47,7 +44,7 @@ namespace proxy void SOCKS4AHandler::CloseSock() { if (m_sock) { - LogPrint("--- socks4a close sock"); + LogPrint(eLogDebug,"--- SOCKS close sock"); m_sock->close(); delete m_sock; m_sock = nullptr; @@ -57,7 +54,7 @@ namespace proxy void SOCKS4AHandler::CloseStream() { if (m_stream) { - LogPrint("--- socks4a close stream"); + LogPrint(eLogDebug,"--- SOCKS close stream"); m_stream.reset (); } } @@ -66,78 +63,147 @@ namespace proxy const size_t socks_ident_size = 1024; const size_t destb32_len = 52; + std::size_t SOCKS4AHandler::HandleData(uint8_t *sock_buff, std::size_t len) + { + assert(len); // This should always be called with a least a byte left to parse + switch (m_state) { + case GET_VERSION: + return HandleVersion(sock_buff); + case SOCKS4A: + return HandleSOCKS4A(sock_buff,len); + default: + LogPrint(eLogError,"--- SOCKS state?? ", m_state); + Terminate(); + return 0; + } + } + + std::size_t SOCKS4AHandler::HandleVersion(uint8_t *sock_buff) + { + switch (*sock_buff) { + case 4: + m_state = SOCKS4A; // Switch to the 4a handler + m_pstate = GET4A_COMMAND; //Initialize the parser at the right position + return 1; + default: + LogPrint(eLogError,"--- SOCKS rejected invalid version", ((int)*sock_buff)); + Terminate(); + return 0; + } + } + + std::size_t SOCKS4AHandler::HandleSOCKS4A(uint8_t *sock_buff, std::size_t len) + { + std::size_t rv = 0; + while (len > 0) { + rv++; + switch (m_pstate) + { + case GET4A_COMMAND: + if ( *sock_buff != 1 ) { + LogPrint(eLogError,"--- SOCKS4a unsupported command", ((int)*sock_buff)); + SocksFailed(); + return 0; + } + m_pstate = GET4A_PORT1; + break; + case GET4A_PORT1: + m_port = ((uint16_t)*sock_buff) << 8; + m_pstate = GET4A_PORT2; + break; + case GET4A_PORT2: + m_port |= ((uint16_t)*sock_buff); + m_pstate = GET4A_IP1; + break; + case GET4A_IP1: + m_ip = ((uint32_t)*sock_buff) << 24; + m_pstate = GET4A_IP2; + break; + case GET4A_IP2: + m_ip |= ((uint32_t)*sock_buff) << 16; + m_pstate = GE 0