mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-03-22 00:59:08 +01:00
[SOCKS] wrap DNS type requests response as IPv4 (fixes netcat usage, closes #1336)
Signed-off-by: R4SAS <r4sas@i2pmail.org>
This commit is contained in:
parent
627d8cfe69
commit
7133a07f38
1 changed files with 34 additions and 35 deletions
|
@ -219,8 +219,8 @@ namespace proxy
|
||||||
assert(error >= SOCKS4_OK);
|
assert(error >= SOCKS4_OK);
|
||||||
m_response[0] = '\x00'; //Version
|
m_response[0] = '\x00'; //Version
|
||||||
m_response[1] = error; //Response code
|
m_response[1] = error; //Response code
|
||||||
htobe16buf(m_response+2,port); //Port
|
htobe16buf(m_response + 2, port); //Port
|
||||||
htobe32buf(m_response+4,ip); //IP
|
htobe32buf(m_response + 4, ip); //IP
|
||||||
return boost::asio::const_buffers_1(m_response,8);
|
return boost::asio::const_buffers_1(m_response,8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -236,20 +236,23 @@ namespace proxy
|
||||||
{
|
{
|
||||||
case ADDR_IPV4:
|
case ADDR_IPV4:
|
||||||
size = 10;
|
size = 10;
|
||||||
htobe32buf(m_response+4,addr.ip);
|
htobe32buf(m_response + 4, addr.ip);
|
||||||
break;
|
break;
|
||||||
case ADDR_IPV6:
|
case ADDR_IPV6:
|
||||||
size = 22;
|
size = 22;
|
||||||
memcpy(m_response+4,addr.ipv6, 16);
|
memcpy(m_response + 4, addr.ipv6, 16);
|
||||||
break;
|
break;
|
||||||
case ADDR_DNS:
|
case ADDR_DNS:
|
||||||
size = 7+addr.dns.size;
|
size = 7 + addr.dns.size;
|
||||||
m_response[4] = addr.dns.size;
|
m_response[4] = addr.dns.size;
|
||||||
memcpy(m_response+5,addr.dns.value, addr.dns.size);
|
memcpy(m_response + 5, addr.dns.value, addr.dns.size);
|
||||||
|
// replace type to IPv4 for support socks5 clients
|
||||||
|
// without domain name resolving support (like netcat)
|
||||||
|
m_response[3] = ADDR_IPV4;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
htobe16buf(m_response+size-2,port); //Port
|
htobe16buf(m_response + size - 2, port); //Port
|
||||||
return boost::asio::const_buffers_1(m_response,size);
|
return boost::asio::const_buffers_1(m_response, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::asio::const_buffers_1 SOCKSHandler::GenerateUpstreamRequest()
|
boost::asio::const_buffers_1 SOCKSHandler::GenerateUpstreamRequest()
|
||||||
|
@ -259,7 +262,7 @@ namespace proxy
|
||||||
// SOCKS 4a
|
// SOCKS 4a
|
||||||
m_upstream_request[0] = '\x04'; //version
|
m_upstream_request[0] = '\x04'; //version
|
||||||
m_upstream_request[1] = m_cmd;
|
m_upstream_request[1] = m_cmd;
|
||||||
htobe16buf(m_upstream_request+2, m_port);
|
htobe16buf(m_upstream_request + 2, m_port);
|
||||||
m_upstream_request[4] = 0;
|
m_upstream_request[4] = 0;
|
||||||
m_upstream_request[5] = 0;
|
m_upstream_request[5] = 0;
|
||||||
m_upstream_request[6] = 0;
|
m_upstream_request[6] = 0;
|
||||||
|
@ -285,21 +288,19 @@ namespace proxy
|
||||||
|
|
||||||
bool SOCKSHandler::Socks5ChooseAuth()
|
bool SOCKSHandler::Socks5ChooseAuth()
|
||||||
{
|
{
|
||||||
m_response[0] = '\x05'; //Version
|
m_response[0] = '\x05'; // Version
|
||||||
m_response[1] = m_authchosen; //Response code
|
m_response[1] = m_authchosen; // Response code
|
||||||
boost::asio::const_buffers_1 response(m_response,2);
|
boost::asio::const_buffers_1 response(m_response, 2);
|
||||||
if (m_authchosen == AUTH_UNACCEPTABLE)
|
if (m_authchosen == AUTH_UNACCEPTABLE)
|
||||||
{
|
{
|
||||||
LogPrint(eLogWarning, "SOCKS: v5 authentication negotiation failed");
|
LogPrint(eLogWarning, "SOCKS: v5 authentication negotiation failed");
|
||||||
boost::asio::async_write(*m_sock, response, std::bind(&SOCKSHandler::SentSocksFailed,
|
boost::asio::async_write(*m_sock, response, std::bind(&SOCKSHandler::SentSocksFailed, shared_from_this(), std::placeholders::_1));
|
||||||
shared_from_this(), std::placeholders::_1));
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LogPrint(eLogDebug, "SOCKS: v5 choosing authentication method: ", m_authchosen);
|
LogPrint(eLogDebug, "SOCKS: v5 choosing authentication method: ", m_authchosen);
|
||||||
boost::asio::async_write(*m_sock, response, std::bind(&SOCKSHandler::SentSocksResponse,
|
boost::asio::async_write(*m_sock, response, std::bind(&SOCKSHandler::SentSocksResponse, shared_from_this(), std::placeholders::_1));
|
||||||
shared_from_this(), std::placeholders::_1));
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -313,7 +314,7 @@ namespace proxy
|
||||||
{
|
{
|
||||||
case SOCKS4:
|
case SOCKS4:
|
||||||
LogPrint(eLogWarning, "SOCKS: v4 request failed: ", error);
|
LogPrint(eLogWarning, "SOCKS: v4 request failed: ", error);
|
||||||
if (error < SOCKS4_OK) error = SOCKS4_FAIL; //Transparently map SOCKS5 errors
|
if (error < SOCKS4_OK) error = SOCKS4_FAIL; // Transparently map SOCKS5 errors
|
||||||
response = GenerateSOCKS4Response(error, m_4aip, m_port);
|
response = GenerateSOCKS4Response(error, m_4aip, m_port);
|
||||||
break;
|
break;
|
||||||
case SOCKS5:
|
case SOCKS5:
|
||||||
|
@ -328,7 +329,7 @@ namespace proxy
|
||||||
void SOCKSHandler::SocksRequestSuccess()
|
void SOCKSHandler::SocksRequestSuccess()
|
||||||
{
|
{
|
||||||
boost::asio::const_buffers_1 response(nullptr,0);
|
boost::asio::const_buffers_1 response(nullptr,0);
|
||||||
//TODO: this should depend on things like the command type and callbacks may change
|
// TODO: this should depend on things like the command type and callbacks may change
|
||||||
switch (m_socksv)
|
switch (m_socksv)
|
||||||
{
|
{
|
||||||
case SOCKS4:
|
case SOCKS4:
|
||||||
|
@ -339,12 +340,11 @@ namespace proxy
|
||||||
LogPrint(eLogInfo, "SOCKS: v5 connection success");
|
LogPrint(eLogInfo, "SOCKS: v5 connection success");
|
||||||
auto s = i2p::client::context.GetAddressBook().ToAddress(GetOwner()->GetLocalDestination()->GetIdentHash());
|
auto s = i2p::client::context.GetAddressBook().ToAddress(GetOwner()->GetLocalDestination()->GetIdentHash());
|
||||||
address ad; ad.dns.FromString(s);
|
address ad; ad.dns.FromString(s);
|
||||||
//HACK only 16 bits passed in port as SOCKS5 doesn't allow for more
|
// HACK only 16 bits passed in port as SOCKS5 doesn't allow for more
|
||||||
response = GenerateSOCKS5Response(SOCKS5_OK, ADDR_DNS, ad, m_stream->GetRecvStreamID());
|
response = GenerateSOCKS5Response(SOCKS5_OK, ADDR_DNS, ad, m_stream->GetRecvStreamID());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
boost::asio::async_write(*m_sock, response, std::bind(&SOCKSHandler::SentSocksDone,
|
boost::asio::async_write(*m_sock, response, std::bind(&SOCKSHandler::SentSocksDone, shared_from_this(), std::placeholders::_1));
|
||||||
shared_from_this(), std::placeholders::_1));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SOCKSHandler::EnterState(SOCKSHandler::state nstate, uint8_t parseleft) {
|
void SOCKSHandler::EnterState(SOCKSHandler::state nstate, uint8_t parseleft) {
|
||||||
|
@ -366,12 +366,12 @@ namespace proxy
|
||||||
{
|
{
|
||||||
if ( m_cmd != CMD_CONNECT )
|
if ( m_cmd != CMD_CONNECT )
|
||||||
{
|
{
|
||||||
//TODO: we need to support binds and other shit!
|
// TODO: we need to support binds and other shit!
|
||||||
LogPrint(eLogError, "SOCKS: unsupported command: ", m_cmd);
|
LogPrint(eLogError, "SOCKS: unsupported command: ", m_cmd);
|
||||||
SocksRequestFailed(SOCKS5_CMD_UNSUP);
|
SocksRequestFailed(SOCKS5_CMD_UNSUP);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
//TODO: we may want to support other address types!
|
// TODO: we may want to support other address types!
|
||||||
if ( m_addrtype != ADDR_DNS )
|
if ( m_addrtype != ADDR_DNS )
|
||||||
{
|
{
|
||||||
switch (m_socksv)
|
switch (m_socksv)
|
||||||
|
@ -735,8 +735,7 @@ namespace proxy
|
||||||
LogPrint(eLogInfo, "SOCKS: negotiating with upstream proxy");
|
LogPrint(eLogInfo, "SOCKS: negotiating with upstream proxy");
|
||||||
EnterState(UPSTREAM_HANDSHAKE);
|
EnterState(UPSTREAM_HANDSHAKE);
|
||||||
if (m_upstreamSock) {
|
if (m_upstreamSock) {
|
||||||
boost::asio::write(*m_upstreamSock,
|
boost::asio::write(*m_upstreamSock, GenerateUpstreamRequest());
|
||||||
GenerateUpstreamRequest());
|
|
||||||
AsyncUpstreamSockRead();
|
AsyncUpstreamSockRead();
|
||||||
} else {
|
} else {
|
||||||
LogPrint(eLogError, "SOCKS: no upstream socket to send handshake to");
|
LogPrint(eLogError, "SOCKS: no upstream socket to send handshake to");
|
||||||
|
|
Loading…
Add table
Reference in a new issue