Click here to Skip to main content
15,881,248 members
Articles / Desktop Programming / MFC

Negotiating proxies in the form of a Whois client

Rate me:
Please Sign up or sign in to vote.
4.82/5 (6 votes)
19 May 20063 min read 43.9K   903   17  
An article on dealing with proxies.
// Whois.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "whois.h"
#include <stdlib.h>
#include <vector>
using namespace std;
#include "Base64Coder.h"
#include "HttpProxyClient.h"

bool GetIpAddress(char *hostname)
{
	HOSTENT *lpHost=NULL;
	struct sockaddr_in   dest;

	lpHost = gethostbyname(hostname);
	if (lpHost == NULL)
	{
		printf("gethostbyname failed: %d\n", WSAGetLastError());
	}
	else
	{
		for(int i=0; lpHost->h_addr_list[i] != NULL ;i++)
		{
			memcpy(&(dest.sin_addr), lpHost->h_addr_list[i],
				lpHost->h_length);
			printf("IP address is: '%s'\n",
				inet_ntoa(dest.sin_addr));
		}

	}
	return true;
} 

int _tmain(int argc, _TCHAR* argv[])
{
	if (argc == 1)
	{
		printf("Usage: whois [OPTION...]\n"
			"valid options:\n"
			"\tserver\n"
			"\t-h server  (server name)\n"
			"\t-p port    (server port)\n"
			"\t-ip ipaddress\n"
			"\t-host hostname\n"
			"\t-local\n"
			"\t (Cannot use -ip -host -local at the same time, only one can be used)\n"
			"\t-x (Use Proxy)\n"
			"\t-s (SOCKS proxy, default is HTTP)\n"
			"\t-v (One of either '4', 'A', or '5', without quotes)\n"
			"\t-r proxy\n"
			"\t-n proxyport\n"
			"\t-u username (Proxy user name)\n"
			"\t-w password (Proxy Password)\n"
			"*When using a proxy, only http proxies are supported.\n"
			"*Also note that the proxy only supports the following whois servers:\n"
			"\twhois.internic.net\n"
			"\twhois.register.com\n"
			"\twhois.apnic.net\n"
			"\twhois.ripe.net\n"
			"\twhois.arin.net\n");
	}
	else
	{
		WSADATA  wsadata;
		HOSTENT *lpHost=NULL;
		char    hostname[256];
		int      ret;

		WSAStartup(0x0202, &wsadata);
		if (_tcscmp(argv[1],_T("-host")) == 0)
		{
			GetIpAddress(argv[2]);
		}
		else if (_tcscmp(argv[1],_T("-local")) == 0)
		{
			if ((ret = gethostname(hostname, 256)) != 0)
			{
				printf("Error calling gethostname: %d\n", ret);
			}
			else
			{
				printf("Hostname is: %s\n", hostname);
			}

			// Print the local IP address.
			GetIpAddress (hostname);
			// Print the remote peer IP address.
			printf("Getting Remote Peer IP Address\n");
			GetIpAddress ("ppp_peer");
		}
		else if (_tcscmp(argv[1], _T("-ip")) == 0)
		{
			HOSTENT *lpHost=NULL;
			struct sockaddr_in   dest;
			unsigned int addr = inet_addr(argv[2]);
			

			lpHost = gethostbyaddr(reinterpret_cast<char *>(&addr), 4,AF_INET);
			if (lpHost == NULL)
			{
				printf("gethostbyaddr failed: %d\n", WSAGetLastError());
			}
			else
			{
				if (lpHost->h_name != NULL)
				{
					printf("Host name is: '%s'\n",lpHost->h_name);
				}
				for(int i=0; lpHost->h_addr_list[i] != NULL ;i++)
				{
					memcpy(&(dest.sin_addr), lpHost->h_addr_list[i],
						lpHost->h_length);
					printf("IP address is: '%s'\n",
						inet_ntoa(dest.sin_addr));
					if (lpHost->h_aliases[i] != NULL)
					{
						printf("Host alias is: '%s'\n",lpHost->h_aliases[i]);
					}
				}

			}
		}
		else
		{
			int    port   = 43;
			char * host   = "whois.internic.net";//"whois.register.com";
			char * domain = "";
			char* proxy = "";
			char* temp = "";
			SOCKS_VERSION sv = SOCKS_V4;
			char* username = NULL;
			char* password = NULL;
			int proxyport = 1080;
			bool bProxy = false, bProxySOCKS = false;
			for( int i = 1 ; i < argc ; i++ )
			{
				if( argv[i][0] == '-' ){

					if ( argv[i][1] == 'x' ){
						bProxy = true;
						continue;
					}
					else if ( argv[i][1] == 's' ){
						bProxySOCKS = true;
						continue;
					}
					else if( argv[i][1] == 'v' ){

						i++;
						temp = argv[i];
						
						if (stricmp(temp,"4")==0)
						{
							sv = SOCKS_V4;
						}
						else if (stricmp(temp,"A")==0)
						{
							sv = SOCKS_V4A;
						}
						else if (stricmp(temp,"5")==0)
						{
							sv = SOCKS_V5;
						}
						continue;
					}
					else if( argv[i][1] == 'h' ){

						if( strlen( argv[i] ) > 2 ){
							host = extract( argv[i] );
							continue;
						}
						else
						{
							i++;
							host = argv[i];
						}
						continue;
					}
					else if ( argv[i][1] == 'p' ){
						i++;
						port = atoi( argv[i] );
						continue;
					}
					else if( argv[i][1] == 'r' ){

						if( strlen( argv[i] ) > 2 ){
							proxy = extract( argv[i] );
							continue;
						}
						else
						{
							i++;
							proxy = argv[i];
						}
						continue;
					}
					else if ( argv[i][1] == 'n' ){
						i++;
						proxyport = atoi( argv[i] );
						continue;
					}
					else if( argv[i][1] == 'u' ){

						if( strlen( argv[i] ) > 2 ){
							username = extract( argv[i] );
							continue;
						}
						else
						{
							i++;
							username = argv[i];
						}
						continue;
					}
					else if( argv[i][1] == 'w' ){

						if( strlen( argv[i] ) > 2 ){
							password = extract( argv[i] );
							continue;
						}
						else
						{
							i++;
							password = argv[i];
						}
						continue;
					}
				}
				else
				{
					domain = argv[i];
				}
			}
			if (bProxy)
			{
				if (!bProxySOCKS)
				{
					proxy_whois(proxy,proxyport,username,password,host,domain,port);
				}
				else
					socks_proxy_whois(sv, proxy,proxyport,username,password,host,domain,port);
			}
			else
				do_whois( host, domain, port );
		}
		WSACleanup();
	}
	return 0;
}

void do_whois( char * host, char * domain, int port )
{

	SOCKET socket_descriptor;
	struct hostent *he;
	struct sockaddr_in host_address;


	if( !( he = gethostbyname( host ) ) ){
		fprintf( stderr, "Could not resolve host" );
		exit( 0 );
	}

	if( ( socket_descriptor = socket( AF_INET, SOCK_STREAM, 0 ) ) == -1 ){
		fprintf( stderr, "Could not establish socket connection." );
		exit( 0 );
	}

	host_address.sin_family = AF_INET;
	host_address.sin_port   = htons( port );
	host_address.sin_addr   = *( (struct in_addr *)he->h_addr );
	memset(& (host_address.sin_zero ), '\0', 8 );  //clear the struct

	if( connect( socket_descriptor, (struct sockaddr *)&host_address, sizeof( struct sockaddr ) ) == -1 ){
		fprintf( stderr, "Could not connect to host." );
		exit( 0 );
	}
	/*
	* Send the whois query
	*/
	char msg[80];
	sprintf( msg, "%s\n", domain );	 
	send( socket_descriptor, msg, (int)strlen( msg ), 0 );    

	/*
	* Check for socket forwarding with server addressing.
	*/
	char * text;
	int    linecounter = 0;
	char * nextserver  = NULL;

	while( true ){

		if( !(text = readLine( socket_descriptor ) ) )
			break;

		if( ++linecounter == SERVER_LINE )
			if( strstr( text, "Server" ) )
				nextserver = get_server( text );


		sprintf( "%s\n\r", text );		

	}

	if( nextserver )
		do_whois( nextserver, domain, port );

	return;
}

void proxy_whois(char* proxy, int proxyport, char* username, char* password, char * host, char * domain, int port)
{
	/*
	SOCKET socket_descriptor;
	struct hostent *he;
	struct sockaddr_in proxy_address;


	if( !( he = gethostbyname( proxy ) ) ){
		fprintf( stderr, "Could not resolve host" );
		exit( 0 );
	}

	if( ( socket_descriptor = socket( AF_INET, SOCK_STREAM, 0 ) ) == -1 ){
		fprintf( stderr, "Could not establish socket connection." );
		exit( 0 );
	}

	proxy_address.sin_family = AF_INET;
	proxy_address.sin_port   = htons( proxyport );
	proxy_address.sin_addr   = *( (struct in_addr *)he->h_addr );
	memset(& (proxy_address.sin_zero ), '\0', 8 );  //clear the struct

	// Code for proxy authentication if allowed by proxy server:
	if( connect( socket_descriptor, (struct sockaddr *)&proxy_address, sizeof( struct sockaddr ) ) == -1 ){
	fprintf( stderr, "Could not connect to proxy." );
	exit( 0 );
	}
	char msg[2048];
	Base64Coder coder;
	if ((username != NULL) && (password != NULL))
	{
		sprintf(msg,"%s:%s",username,password);
		coder.Encode(msg);
	}
	else if (username != NULL)
	{
		sprintf(msg,"%s:",username);
		coder.Encode(msg);
	}
	else if (password != NULL)
	{
		sprintf(msg,":%s",password);
		coder.Encode(msg);
	}
	host = strlwr(host);
	if (strcmp(host,"whois.internic.net")==0)
	{
		sprintf(msg,"GET %s%s%s HTTP/1.1\r\n","http://reports.internic.net/cgi/whois?whois_nic=",domain,"&type=domain");
	}
	else if (strcmp(host,"whois.register.com")==0)
	{
		sprintf(msg,"GET %s%s%s HTTP/1.1\r\n","http://whois.register.com/cgi/whois?whois_nic=",domain,"&type=domain");
	}
	else if (strcmp(host,"whois.ripe.net")==0)
	{
		sprintf(msg,"GET %s%s HTTP/1.1\r\n","http://www.ripe.net/perl/whois?form_type=simple&full_query_string=&searchtext=",domain);
	}
	else if (strcmp(host,"whois.arin.net")==0)
	{
		sprintf(msg,"GET %s%s HTTP/1.1\r\n","http://ws.arin.net/cgi-bin/whois.pl?queryinput=",domain);
	}
	else if (strcmp(host,"whois.apnic.net")==0)
	{
		sprintf(msg,"GET %s%s HTTP/1.1\r\n","http://www.apnic.net/apnic-bin/whois.pl?searchtext=",domain);
	}
	else
	{
		sprintf(msg,"GET http://%s HTTP/1.1\r\n",host);
		send( socket_descriptor, msg, (int)strlen( msg ), 0 );   
		sprintf( msg, "%s\n", domain );	  
	}
	//sprintf(msg,"CONNECT %s:%d HTTP/1.1\r\n","whois.register.com",43);
	if (send(socket_descriptor,msg,(int)strlen(msg),0) == SOCKET_ERROR)
	{
	return;
	}
	sprintf(msg,"host: %s:%d\r\n",host,port);
	send(socket_descriptor,msg,(int)strlen(msg),0);
	if (username != NULL)
	{
		sprintf(msg,"Proxy-Authorization: Basic %s\r\n",coder.EncodedMessage());
		send(socket_descriptor,msg,(int)strlen(msg),0);
	}
	sprintf(msg,"\r\n");
	send(socket_descriptor,msg,(int)strlen(msg),0);
	*/
	char msg[MAX_PATH];
	CHttpProxyClient httpProxy;
	httpProxy.SetHttpVersion(HTTP_11);
	bool bUseAuthorization = false;
	if (username != NULL)
	{
		httpProxy.SetUserName(username);
		bUseAuthorization = true;
	}
	if (password != NULL)
	{
		httpProxy.SetPassword(password);
		bUseAuthorization = true;
	}
	if (!httpProxy.SetProxy(proxy,proxyport))
		return;
	if(!httpProxy.Connect())
		return;
	host = strlwr(host);
	if (strcmp(host,"whois.internic.net")==0)
	{
		sprintf(msg,"%s%s%s","http://reports.internic.net/cgi/whois?whois_nic=",domain,"&type=domain");
	}
	else if (strcmp(host,"whois.register.com")==0)
	{
		sprintf(msg,"%s%s%s","http://whois.register.com/cgi/whois?whois_nic=",domain,"&type=domain");
	}
	else if (strcmp(host,"whois.ripe.net")==0)
	{
		sprintf(msg,"%s%s","http://www.ripe.net/perl/whois?form_type=simple&full_query_string=&searchtext=",domain);
	}
	else if (strcmp(host,"whois.arin.net")==0)
	{
		sprintf(msg,"%s%s","http://ws.arin.net/cgi-bin/whois.pl?queryinput=",domain);
	}
	else if (strcmp(host,"whois.apnic.net")==0)
	{
		sprintf(msg,"%s%s","http://www.apnic.net/apnic-bin/whois.pl?searchtext=",domain);
	}
	else
	{
		sprintf(msg,"http://%s",host);
	}
	if (!httpProxy.Request(HTTP_GET,msg,NULL,bUseAuthorization))
		return;
	/*
	* Check for socket forwarding with server addressing.
	*/
	char * text;
	int    linecounter = 0;
	char * nextserver  = NULL;

	while( true ){

		if(!(text = httpProxy.ReadLine()))
			break;

		//if( ++linecounter >= 106 & linecounter<= 158)
			printf("%s\n\r", text);

	}
	return;
}

void socks_proxy_whois(SOCKS_VERSION sv, char* proxy, int proxyport, char* username, char* password, char * host, char * domain, int port)
{

	/*SOCKET socket_descriptor;
	struct hostent *he;
	struct sockaddr_in proxy_address;


	if( !( he = gethostbyname( proxy ) ) ){
		fprintf( stderr, "Could not resolve host" );
		exit( 0 );
	}

	if( ( socket_descriptor = socket( AF_INET, SOCK_STREAM, 0 ) ) == -1 ){
		fprintf( stderr, "Could not establish socket connection." );
		exit( 0 );
	}

	proxy_address.sin_family = AF_INET;
	proxy_address.sin_port   = htons( proxyport );
	proxy_address.sin_addr   = *( (struct in_addr *)he->h_addr );
	memset(& (proxy_address.sin_zero ), '\0', 8 );  //clear the struct

	// Code for proxy authentication if allowed by proxy server:
	if( connect( socket_descriptor, (struct sockaddr *)&proxy_address, sizeof( struct sockaddr ) ) == -1 ){
		fprintf( stderr, "Could not connect to proxy." );
		exit( 0 );
	}
	byte msg[2048];
	host = strlwr(host);
	int nlen = 0;
	if (sv == SOCKS_V4)
	{
		msg[0] = 0x04;
		msg[1] = 0x01;
		SHORT dw = port;
		msg[2] = (dw>>8);
		msg[3] = (byte)dw;
		if( !( he = gethostbyname( host ) ) ){
			fprintf( stderr, "Could not resolve domain" );
			exit( 0 );
		}
		struct sockaddr_in   dest;

		memcpy(&(dest.sin_addr), he->h_addr_list[0],
			he->h_length);
		msg[4] = dest.sin_addr.S_un.S_un_b.s_b1;
		msg[5] = dest.sin_addr.S_un.S_un_b.s_b2;
		msg[6] = dest.sin_addr.S_un.S_un_b.s_b3;
		msg[7] = dest.sin_addr.S_un.S_un_b.s_b4;
		if (((username != NULL) || (password != NULL)) > 0)
		{
			//temp = &msg[8];
			//temp = (char*)coder.EncodedMessage();
			strcpy((char*)&msg[8],username);
			msg[8+strlen(username)] = 0x00;
			//msg[14] = 0x00;
		}
		else
			msg[8] = 0x00;
		nlen = 8+strlen(username)+1;
		//sprintf(msg,"CONNECT %s:%d HTTP/1.1\r\n","whois.register.com",43);
		if (send(socket_descriptor,(char*)msg,nlen,0) == SOCKET_ERROR)
		{
			return;
		}
		recv(socket_descriptor,(char*)msg,8,0);
		if (msg[1] == 0x5a)
		{
			//send request
			sprintf( (char*)msg, "%s\n", domain );	 
			send( socket_descriptor, (char*)msg, (int)strlen( (char*)msg ), 0 );
		}
	}
	else if (sv == SOCKS_V4A)
	{
		msg[0] = 0x04;
		msg[1] = 0x01;
		SHORT dw = port;
		msg[2] = (dw>>8);
		msg[3] = (byte)dw;
		if( !( he = gethostbyname( domain ) ) ){
			fprintf( stderr, "Could not resolve domain" );
			exit( 0 );
		}
		msg[4] = 0x00;
		msg[5] = 0x00;
		msg[6] = 0x00;
		msg[7] = 0xFF;
		if (((username != NULL) || (password != NULL)) > 0)
		{
			strcpy((char*)&msg[8],username);
			msg[8+strlen(username)] = 0x00;
			nlen = 9+strlen(username);
			if (send(socket_descriptor,(char*)msg,nlen,0) == SOCKET_ERROR)
			{
				return;
			}
			strcpy((char*)msg,host);
			msg[strlen(host)] = 0x00;
			nlen = strlen(host)+1;
		}
		else
		{
			msg[8] = 0x0;
			nlen = 9;
			if (send(socket_descriptor,(char*)msg,nlen,0) == SOCKET_ERROR)
			{
				return;
			}
			strcpy((char*)&msg[9],host);
			msg[9+strlen(host)] = 0x00;
			nlen = 9+strlen(host)+1;
		}

		if (send(socket_descriptor,(char*)msg,nlen,0) == SOCKET_ERROR)
		{
			return;
		}
		recv(socket_descriptor,(char*)msg,8,0);
		if (msg[1] == 0x5a)
		{
			//send request
			sprintf( (char*)msg, "%s\n", domain );	 
			send( socket_descriptor, (char*)msg, (int)strlen( (char*)msg ), 0 );
		}
	}
	else if (sv == SOCKS_V5)
	{
		msg[0] = 0x05;
		msg[1] = 0x02;
		msg[2] = 0x00;
		msg[3] = 0x02;
		if (send(socket_descriptor,(char*)msg,3,0) == SOCKET_ERROR)
		{
			return;
		}
		recv(socket_descriptor,(char*)msg,2,0);
		if (msg[1] == 0x00)//no authentication
		{
			msg[0] = 0x04;
			msg[1] = 0x01;
			msg[2] = 0x00;
			msg[3] = 0x03;
			msg[4] = strlen(host);
			strcpy((char*)&msg[5],host);
			nlen = strlen(host)+5;
			SHORT dw = port;
			msg[nlen++] = (dw>>8);
			msg[nlen++] = (byte)dw;
		}
		else if (msg[1] == 0x02)//username/password authentication
		{
			msg[0] = 0x01;
			msg[1] = strlen(username);
			strcpy((char*)&msg[2],username);
			nlen = 2+msg[1];
			msg[nlen++] = strlen(password);
			strcpy((char*)&msg[nlen],password);
			nlen += strlen(password);
			if (send(socket_descriptor,(char*)msg,nlen,0) == SOCKET_ERROR)
			{
				return;
			}
			recv(socket_descriptor,(char*)msg,8,0);
			if (msg[1] == 0x00)//status ok so send message
			{
				msg[0] = 0x04;
				msg[1] = 0x01;
				msg[2] = 0x00;
				msg[3] = 0x03;
				msg[4] = strlen(host);
				strcpy((char*)&msg[5],host);
				nlen = strlen(host)+5;
				SHORT dw = port;
				msg[nlen++] = (dw>>8);
				msg[nlen++] = (byte)dw;
			}
			else
				return;
		}
		else
			return;
		if (send(socket_descriptor,(char*)msg,nlen,0) == SOCKET_ERROR)
		{
			return;
		}
		recv(socket_descriptor,(char*)msg,8,0);
		if (msg[1] == 0x00)
		{
			//send request
			sprintf( (char*)msg, "%s\n", domain );	 
			send( socket_descriptor, (char*)msg, (int)strlen( (char*)msg ), 0 );
		}
		else
			return;
	}*/
	CSocksProxyClient socks;
	socks.SetSocksVersion(sv);
	if (username != NULL)
	{
		socks.SetUserName(username);
	}
	if (password != NULL)
	{
		socks.SetPassword(password);
	}
	socks.SetProxy(proxy,proxyport);
	if (socks.Connect(host,port))
	{
		char msg[2048];
		sprintf(msg, "%s\n", domain);	
		socks.Send(msg,(int)strlen(msg));
	}


	/*
	* Check for socket forwarding with server addressing.
	*/
	char * text;
	int    linecounter = 0;
	char * nextserver  = NULL;

	while( true ){

		if(!(text = socks.ReadLine()))
			break;

		//if( ++linecounter >= 106 & linecounter<= 158)
		printf("%s\n\r", text);

	}
	return;
}

char * readLine( SOCKET socketd ) {

	vector<char> collector;
	char         buffer[1];
	int          bytesReceived;

	while (true) {

		bytesReceived = recv( socketd, buffer, 1, 0 );

		if( bytesReceived <= 0 )
			return NULL;

		if( buffer[0] == '\n' ) {

			char *pChar = new char[ collector.size() + 1 ];
			memset( pChar, 0, collector.size() + 1 );

			for (int f = 0; f < (int)collector.size(); f++)
				pChar[f] = collector[f];

			return pChar;

		} 
		else 
		{
			collector.push_back( buffer[0] );
		}
	}
}

char * extract( char * aString ){

	char * test = new char[ strlen( aString ) - 2 ];

	int i = 0;

	fprintf( stdout, "EXTRACTING" );

	while( aString[i] != '\0' ){
		test[i] = aString[i+2];
		i++;
	}

	test[i] = '\0';

	return test;

}

char * get_server( char * text ){

	char * p;
	char * server;
	int    count;

	if( p = strchr( text, ':' ) )
	{
		p = p + 2;

		count  = (int)(strlen( text ) - ( strlen( text ) - strlen ( p ) ));
		server = new char[ count + 1 ];

		int i = 0;

		for( ; count > 0 ; i++, count-- )
			server[i] = *p++;

		server[i] = '\0';
	}
	else
	{
		return NULL;
	}

	return server;
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
United States United States
Programming using MFC and ATL for almost 12 years now. Currently studying Operating System implementation as well as Image processing. Previously worked on DSP and the use of FFT for audio application. Programmed using ADO, ODBC, ATL, COM, MFC for shell interfacing, databasing tasks, Internet items, and customization programs.

Comments and Discussions