19 #include "connectionsocks5proxy.h"
31 #if ( !defined( _WIN32 ) && !defined( _WIN32_WCE ) ) || defined( __SYMBIAN32__ )
32 # include <netinet/in.h>
35 #if defined( _WIN32 ) && !defined( __SYMBIAN32__ )
37 #elif defined( _WIN32_WCE )
38 # include <winsock2.h>
46 const std::string& server,
49 m_logInstance( logInstance ), m_s5state( S5StateDisconnected ), m_ip( ip )
62 const std::string& server,
65 m_logInstance( logInstance ), m_s5state( S5StateDisconnected ), m_ip( ip )
92 m_connection = connection;
101 m_s5state = S5StateConnected;
108 m_s5state = S5StateConnecting;
109 return m_connection->
connect();
125 return m_connection->
recv( timeout );
133 return m_connection->
receive();
150 return m_connection->
send( data );
158 m_s5state = S5StateDisconnected;
176 const std::string& data )
181 if( m_s5state != S5StateConnected )
182 m_proxyHandshakeBuffer += data;
188 case S5StateConnecting:
189 if( m_proxyHandshakeBuffer.length() < 2 )
192 if( m_proxyHandshakeBuffer.length() != 2 || m_proxyHandshakeBuffer[0] != 0x05 )
195 if( m_proxyHandshakeBuffer[1] == 0x00 )
199 else if( m_proxyHandshakeBuffer[1] == 0x02 && !m_proxyUser.empty() && !m_proxyPwd.empty() )
202 "authenticating to socks5 proxy as user " + m_proxyUser );
203 m_s5state = S5StateAuthenticating;
204 char* d =
new char[3 + m_proxyUser.length() + m_proxyPwd.length()];
207 d[pos++] =
static_cast<char>( m_proxyUser.length() );
208 strncpy( d + pos, m_proxyUser.c_str(), m_proxyUser.length() );
209 pos += m_proxyUser.length();
210 d[pos++] =
static_cast<char>( m_proxyPwd.length() );
211 strncpy( d + pos, m_proxyPwd.c_str(), m_proxyPwd.length() );
212 pos += m_proxyPwd.length();
214 if( !
send( std::string( d, pos ) ) )
223 if( m_proxyHandshakeBuffer[1] ==
static_cast<char>( 0xFF ) && !m_proxyUser.empty() && !m_proxyPwd.empty() )
229 m_proxyHandshakeBuffer =
"";
231 case S5StateNegotiating:
232 if( m_proxyHandshakeBuffer.length() < 6 )
235 if( m_proxyHandshakeBuffer.length() >= 6 && m_proxyHandshakeBuffer[0] == 0x05 )
237 if( m_proxyHandshakeBuffer[1] == 0x00 )
240 m_s5state = S5StateConnected;
249 m_proxyHandshakeBuffer =
"";
251 case S5StateAuthenticating:
252 if( m_proxyHandshakeBuffer.length() < 2 )
255 if( m_proxyHandshakeBuffer.length() == 2 && m_proxyHandshakeBuffer[0] == 0x01 && m_proxyHandshakeBuffer[1] == 0x00 )
260 m_proxyHandshakeBuffer =
"";
262 case S5StateConnected:
277 void ConnectionSOCKS5Proxy::negotiate()
279 m_s5state = S5StateNegotiating;
280 char* d =
new char[m_ip ? 10 : 6 +
m_server.length() + 1];
291 const size_t j =
server.length();
293 for(
size_t k = 0; k < j && l < 4; ++k )
298 if(
server[k] ==
'.' || k == j-1 )
300 d[pos++] =
static_cast<char>( atoi( s.c_str() ) & 0xFF );
313 const std::pair< std::string, int >& host = *servers.begin();
319 d[pos++] =
static_cast<char>(
m_server.length() );
323 int nport = htons(
port );
324 d[pos++] =
static_cast<char>( nport );
325 d[pos++] =
static_cast<char>( nport >> 8 );
327 std::string message =
"Requesting socks5 proxy connection to " +
server +
":"
328 + util::int2string(
port );
331 if( !
send( std::string( d, pos ) ) )
348 if( !servers.empty() )
350 const std::pair< std::string, int >& host = *servers.begin();
356 "Attempting to negotiate socks5 proxy connection" );
358 const bool auth = !m_proxyUser.empty() && !m_proxyPwd.empty();
361 static_cast<char>( auth ? 0x02
367 if( !
send( std::string( d, auth ? 4 : 3 ) ) )
An abstract base class for a connection.
const std::string & server() const
ConnectionState state() const
virtual ConnectionError recv(int timeout=-1)=0
virtual bool send(const std::string &data)=0
ConnectionDataHandler * m_handler
virtual ConnectionError connect()=0
virtual ConnectionError receive()=0
virtual void getStatistics(long int &totalIn, long int &totalOut)=0
virtual void disconnect()=0
virtual ConnectionBase * newInstance() const =0
void registerConnectionDataHandler(ConnectionDataHandler *cdh)
This is an abstract base class to receive events from a ConnectionBase-derived object.
virtual void handleReceivedData(const ConnectionBase *connection, const std::string &data)=0
virtual void handleDisconnect(const ConnectionBase *connection, ConnectionError reason)=0
virtual void handleConnect(const ConnectionBase *connection)=0
ConnectionSOCKS5Proxy(ConnectionBase *connection, const LogSink &logInstance, const std::string &server, int port=-1, bool ip=false)
virtual void handleDisconnect(const ConnectionBase *connection, ConnectionError reason)
virtual ConnectionError recv(int timeout=-1)
virtual void handleConnect(const ConnectionBase *connection)
virtual void handleReceivedData(const ConnectionBase *connection, const std::string &data)
virtual ~ConnectionSOCKS5Proxy()
virtual void disconnect()
virtual ConnectionBase * newInstance() const
virtual ConnectionError connect()
void setConnectionImpl(ConnectionBase *connection)
virtual bool send(const std::string &data)
virtual ConnectionError receive()
virtual void getStatistics(long int &totalIn, long int &totalOut)
static HostMap resolve(const std::string &service, const std::string &proto, const std::string &domain, const LogSink &logInstance)
std::map< std::string, int > HostMap
An implementation of log sink and source.
void dbg(LogArea area, const std::string &message) const
bool idna(const std::string &domain, std::string &out)
The namespace for the gloox library.
@ ConnProxyNoSupportedAuth
@ LogAreaClassConnectionSOCKS5Proxy
const std::string EmptyString