Ejemplo n.º 1
0
int main(int argc, char **argv)
{

	atexit(exit_handle);

	if(initConfig(argc, argv))
		exit(EXIT_FAILURE);
	signal(SIGALRM, sig_handle);	/* 定时器 */
	signal(SIGHUP, sig_handle);	 /* 注销时 */
	signal(SIGINT, sig_handle);	 /* Ctrl+C */
	signal(SIGQUIT, sig_handle);	/* Ctrl+\ */
	signal(SIGTSTP, sig_handle);	/* Ctrl+Z */
	signal(SIGTERM, sig_handle);	/* 被结束时 */
	signal(SIGKILL, sig_handle);


	if (dhcpMode == 3)	  /* 认证前DHCP */
		switchState(ID_DHCP);
	else
		switchState(ID_START);	/* 开始认证 */
	if (-1 == pcap_loop(hPcap, -1, pcap_handle, NULL)) { /* 开始捕获数据包 */
		printf("!! 捕获数据包失败,请检查网络连接!\n");
#ifndef NO_NOTIFY
		if (showNotify)
			show_notify("MentoHUST - 错误提示", "捕获数据包失败,请检查网络连接!");
#endif
	}
	exit(EXIT_FAILURE);
}
Ejemplo n.º 2
0
static void* lan_thread()
{
	if (-1 == pcap_loop(hPcapLan, -1, pcap_handle_lan, NULL)) { /* 开始捕获数据包 */
		print_log(_("!! 从LAN捕获数据包失败,请检查网络连接!\n"));
#ifndef NO_NOTIFY
		if (showNotify && show_notify(_("MentoHUST - 错误提示"),
			_("!! 从LAN捕获数据包失败,请检查网络连接!\n"), 1000*showNotify) < 0)
			showNotify = 0;
#endif
	}
	return 0;
}
Ejemplo n.º 3
0
static void showRuijieMsg(const u_char *buf, unsigned bufLen)
{
	char *serverMsg;
	int length = buf[0x1b];
	if (length > 0) {
		for (serverMsg=(char *)(buf+0x1c); *serverMsg=='\r'||*serverMsg=='\n'; serverMsg++,length--);	/* 跳过开头的换行符 */
		if (strlen(serverMsg) < length)
			length = strlen(serverMsg);
		if (length>0 && (serverMsg=gbk2utf(serverMsg, length))!=NULL) {
			if (strlen(serverMsg)) {
				print_log(_("$$ 系统提示:\n%s\n"), serverMsg);
#ifndef NO_NOTIFY
				if (showNotify && show_notify(_("MentoHUST - 系统提示"),
					serverMsg, 1000*showNotify) < 0)
					showNotify = 0;
#endif
			}
			free(serverMsg);
		}
	}
	if ((length=0x1c+buf[0x1b]+0x69+39) < bufLen) {
		serverMsg=(char *)(buf+length);
		if (buf[length-1]-2 > bufLen-length)
			length = bufLen - length;
		else
			length = buf[length-1]-2;
		for (; *serverMsg=='\r'||*serverMsg=='\n'; serverMsg++,length--);
		if (length>0 && (serverMsg=gbk2utf(serverMsg, length))!=NULL) {
			if (strlen(serverMsg)) {
				print_log(_("$$ 计费提示:\n%s\n"), serverMsg);
#ifndef NO_NOTIFY
				if (showNotify && show_notify(_("MentoHUST - 计费提示"),
					serverMsg, 1000*showNotify) < 0)
					showNotify = 0;
#endif
			}
			free(serverMsg);
		}
	}
}
Ejemplo n.º 4
0
static void* wan_thread()
{
	char* err_base[2] = { _("!! 捕获数据包失败,请检查网络连接!\n"),
						  _("!! 从WAN捕获数据包失败,请检查网络连接!\n") };
	if (-1 == pcap_loop(hPcap, -1, pcap_handle, NULL)) { /* 开始捕获数据包 */
		print_log("%s", err_base[proxyMode == 1]);
#ifndef NO_NOTIFY
		if (showNotify && show_notify(_("MentoHUST - 错误提示"),
			err_base[proxyMode == 1], 1000*showNotify) < 0)
			showNotify = 0;
#endif
	}
	return 0;
}
Ejemplo n.º 5
0
static void showCernetMsg(const u_char *buf)
{
	char *serverMsg = (char *)(buf+0x17);
	int length = ntohs(*(u_int16_t *)(buf+0x14)) - 5;
	if (strlen(serverMsg) < length)
		length = strlen(serverMsg);
	if (length>0 && (serverMsg=gbk2utf(serverMsg, length))!=NULL)
	{
		printf("$$ 系统提示:\t%s\n", serverMsg);
#ifndef NO_NOTIFY
			if (showNotify)
				show_notify("MentoHUST - 系统提示", serverMsg);
#endif
		free(serverMsg);
	}
	fflush(stdout);
}
Ejemplo n.º 6
0
static void sig_handle(int sig)
{
	if (sig == SIGALRM)	 /* 定时器 */
	{
		if (-1 == switchState(state))
		{
			pcap_breakloop(hPcap);
			printf("!! 发送数据包失败, 请检查网络连接!\n");
			fflush(stdout);
#ifndef NO_NOTIFY
			if (showNotify)
				show_notify("MentoHUST - 错误提示", "发送数据包失败, 请检查网络连接!");
#endif
			exit(EXIT_FAILURE);
		}
	}
	else	/* 退出 */
	{
		pcap_breakloop(hPcap);
		exit(EXIT_SUCCESS);
	}
}
Ejemplo n.º 7
0
static void sig_handle(int sig)
{
	if (sig == SIGALRM)	 /* 定时器 */
	{
		if (-1 == switchState(state))
		{
			pcap_breakloop(hPcap);
			print_log(_("!! 发送数据包失败, 请检查网络连接!\n"));
#ifndef NO_NOTIFY
			if (showNotify && show_notify(_("MentoHUST - 错误提示"),
				_("发送数据包失败, 请检查网络连接!"), 1000*showNotify) < 0)
				showNotify = 0;
#endif
			exit(EXIT_FAILURE);
		}
	}
	else	/* 退出 */
	{
		print_log(_("!! 收到信号:%s (%d)\n"), strsignal(sig), sig);
		pcap_breakloop(hPcap);
		if (hPcapLan != NULL) pcap_breakloop(hPcapLan);
		exit(EXIT_SUCCESS);
	}
}
Ejemplo n.º 8
0
static void pcap_handle(u_char *user, const struct pcap_pkthdr *h, const u_char *buf)
{
	static unsigned failCount = 0;
#ifndef NO_ARP
	if (buf[0x0c]==0x88 && buf[0x0d]==0x8e) {
#endif
		if (memcmp(destMAC, buf+6, 6)!=0 && startMode>2)	/* 服务器MAC地址不符 */
			return;
		capBuf = buf;
		if (buf[0x0F]==0x00 && buf[0x12]==0x01 && buf[0x16]==0x01) {	/* 验证用户名 */
			if (startMode < 3) {
				memcpy(destMAC, buf+6, 6);
				printf("** 认证MAC:\t%s\n", formatHex(destMAC, 6));
				startMode += 3;	/* 标记为已获取 */
			}
			if (startMode==3 && memcmp(buf+0x17, "User name", 9)==0)	/* 塞尔 */
				startMode = 5;
			switchState(ID_IDENTITY);
		}
		else if (buf[0x0F]==0x00 && buf[0x12]==0x01 && buf[0x16]==0x04)	/* 验证密码 */
			switchState(ID_CHALLENGE);
		else if (buf[0x0F]==0x00 && buf[0x12]==0x03) {	/* 认证成功 */
			printf(">> 认证成功!\n");
			fflush(stdout);
			failCount = 0;
			if (!(startMode%3 == 2)) {
				getEchoKey(buf);
				showRuijieMsg(buf, h->caplen);
			}
			if (dhcpMode==1 || dhcpMode==2)	/* 二次认证第一次或者认证后 */
				switchState(ID_DHCP);
			else if (startMode%3 == 2)
				switchState(ID_WAITECHO);
			else
				switchState(ID_ECHO);
		}
		else if (buf[0x0F]==0x00 && buf[0x12]==0x01 && buf[0x16]==0x02)	/* 显示赛尔提示信息 */
			showCernetMsg(buf);
		else if (buf[0x0F] == 0x05)	/* (赛尔)响应在线 */
			switchState(ID_ECHO);
		else if (buf[0x0F]==0x00 && buf[0x12]==0x04) {  /* 认证失败或被踢下线 */
			if (state==ID_WAITECHO || state==ID_ECHO) {
				printf(">! 认证掉线,开始重连!\n");
				fflush(stdout);
				switchState(ID_START);
			}
			else if (buf[0x1b]!=0 || startMode%3==2) {
				printf("!! 认证失败!\n");
				fflush(stdout);
				if (startMode%3 != 2)
					showRuijieMsg(buf, h->caplen);
				if (maxFail && ++failCount>=maxFail) {
					printf(">! 连续认证失败%u次,退出认证。\n", maxFail);
					fflush(stdout);
					exit(EXIT_SUCCESS);
				}
				restart();
			}
			else
				switchState(ID_START);
		}
#ifndef NO_ARP
	} else if (gateMAC[0]!=0xFE && buf[0x0c]==0x08 && buf[0x0d]==0x06) {
		if (*(u_int32_t *)(buf+0x1c) == gateway) {
			char str[50];
			if (gateMAC[0] == 0xFF) {
				memcpy(gateMAC, buf+0x16, 6);
				printf("** 网关MAC:\t%s\n", formatHex(gateMAC, 6));
				fflush(stdout);
				sprintf(str, "arp -s %s %s", formatIP(gateway), formatHex(gateMAC, 6));
				system(str);
			} else if (buf[0x15]==0x02 && *(u_int32_t *)(buf+0x26)==rip
				&& memcmp(gateMAC, buf+0x16, 6)!=0) {
				printf("** ARP欺骗:\t%s\n", formatHex(buf+0x16, 6));
				fflush(stdout);
#ifndef NO_NOTIFY
				if (showNotify) {
					sprintf(str, "欺骗源: %s", formatHex(buf+0x16, 6));
					show_notify("MentoHUST - ARP提示", str);
				}
#endif
			}
		}
	}
#endif
}
Ejemplo n.º 9
0
static void pcap_handle(u_char *user, const struct pcap_pkthdr *h, const u_char *buf)
{
	static unsigned failCount = 0;
	pthread_t thread_lan;

#ifndef NO_ARP
	if (buf[0x0c]==0x88 && buf[0x0d]==0x8e) {
#endif
		if (memcmp(destMAC, buf+6, 6)!=0 && startMode>2)	/* 服务器MAC地址不符 */
			return;
		capBuf = buf;
		if (buf[0x0F]==0x00 && buf[0x12]==0x01 && buf[0x16]==0x01) {	/* 验证用户名 */
			if (startMode < 3) {
				memcpy(destMAC, buf+6, 6);
				print_log(_("** 认证服务器MAC: %s\n"), formatHex(destMAC, 6));
				startMode += 3;	/* 标记认证服务器MAC为已获取,可以锁定 */
			}
			if (proxyMode == 0) {
				if (startMode==3 && memcmp(buf+0x17, "User name", 9)==0)	/* 塞尔 */
					startMode = 5;
				switchState(ID_IDENTITY);
			} else {
				if (proxyClientRequested == 1) {
					print_log(_(">> 服务器已请求用户名\n"));
					proxy_send_to_lan(buf, h->len);
				} else {
					print_log(_("!! 在代理认证完成后收到用户名请求,将重启认证!\n"));
					switchState(ID_WAITCLIENT);
				}
			}
		}
		else if (buf[0x0F]==0x00 && buf[0x12]==0x01 && buf[0x16]==0x04)	{ /* 验证密码 */
			if (proxyMode == 0) {
				switchState(ID_CHALLENGE);
			} else {
				if (proxyClientRequested == 1) {
					print_log(_(">> 服务器已请求密码\n"));
					proxy_send_to_lan(buf, h->len);
				} else {
					print_log(_("!! 在代理认证完成后收到密码请求,将重启认证!\n"));
					switchState(ID_WAITCLIENT);
				}
			}
		}
		else if (buf[0x0F]==0x00 && buf[0x12]==0x03) {	/* 认证成功 */
			print_log(_(">> 认证成功!\n"));
			failCount = 0;
			proxySuccessCount++;
			if (proxyMode != 0) {
				proxy_send_to_lan(buf, h->len);
				if (proxySuccessCount >= proxyRequireSuccessCount) {
					pcap_breakloop(hPcapLan);
					proxyClientRequested = 0;
					proxySuccessCount = 0;
					memcpy(lastSuccessClientMAC, clientMAC, 6); // 备份本次认证成功的客户端MAC,用于通知掉线
					proxy_clear_client_mac(); // 重设MAC地址,以备下次使用不同客户端认证用
					print_log(_(">> 已关闭LAN监听线程\n"));
				}
			}
			if (!(startMode%3 == 2)) {
				getEchoKey(buf);
			}
			showRuijieMsg(buf, h->caplen);
			if (dhcpMode==1 || dhcpMode==2)	/* 二次认证第一次或者认证后 */
				switchState(ID_DHCP);
			else if (startMode%3 == 2)
				switchState(ID_WAITECHO);
			else
				switchState(ID_ECHO);
		}
		else if (buf[0x0F]==0x00 && buf[0x12]==0x01 && buf[0x16]==0x02)	/* 显示赛尔提示信息 */
			showCernetMsg(buf);
		else if (buf[0x0F] == 0x05)	/* (赛尔)响应在线 */
			switchState(ID_ECHO);
		else if (buf[0x0F]==0x00 && buf[0x12]==0x04) {  /* 认证失败或被踢下线 */
			if (state==ID_WAITECHO || state==ID_ECHO) {
				if (proxyMode == 0) {
					print_log(_(">> 认证掉线!\n"));
					showRuijieMsg(buf, h->caplen);
					if (restartOnLogOff) {
						print_log(_(">> 正在重新认证...\n"));
						switchState(ID_START);					
					} else {
						exit(1);
					}
				} else {
					pthread_create(&thread_lan, NULL, lan_thread, 0);
					print_log(_(">> 认证掉线,已发回客户端并重新启用对LAN的监听\n"));
					showRuijieMsg(buf, h->caplen);
					// clientMAC已经在成功时被清除了,所以使用lastSuccessClientMAC发送,发完清除
					memmove(clientMAC, lastSuccessClientMAC, 6);
					proxy_send_to_lan(buf, h->len);
					proxy_clear_client_mac();
					switchState(ID_WAITCLIENT);
				}
			}
			else if (buf[0x1b]!=0 || startMode%3==2) {
				print_log(_(">> 认证失败!\n"));
				showRuijieMsg(buf, h->caplen);
				if (maxFail && ++failCount>=maxFail) {
					print_log(_(">> 连续认证失败%u次,退出认证。\n"), maxFail);
					exit(EXIT_SUCCESS);
				}
				restart();
			} else {
				if (proxyMode == 0)
					switchState(ID_START);
				else
					switchState(ID_WAITCLIENT);
			}
		}
#ifndef NO_ARP
	} else if (gateMAC[0]!=0xFE && buf[0x0c]==0x08 && buf[0x0d]==0x06) {
		if (*(u_int32_t *)(buf+0x1c) == gateway) {
			char str[50];
			if (gateMAC[0] == 0xFF) {
				memcpy(gateMAC, buf+0x16, 6);
				print_log(_("** 网关MAC:\t%s\n"), formatHex(gateMAC, 6));
				sprintf(str, "arp -s %s %s", formatIP(gateway), formatHex(gateMAC, 6));
				system(str);
			} else if (buf[0x15]==0x02 && memcmp(&rip, buf+0x26, 4)==0
				&& memcmp(gateMAC, buf+0x16, 6)!=0) {
				print_log(_("** ARP欺骗:\t%s\n"), formatHex(buf+0x16, 6));
#ifndef NO_NOTIFY
				if (showNotify) {
					sprintf(str, _("欺骗源: %s"), formatHex(buf+0x16, 6));
					if (show_notify(_("MentoHUST - ARP提示"), str, 1000*showNotify) < 0)
						showNotify = 0;
				}
#endif
			}
		}
	}
#endif
}
Ejemplo n.º 10
0
int WINAPI WinMain(HINSTANCE hInstance,
                   HINSTANCE hPrevInstance,
                   LPTSTR    lpCmdLine,
                   int       nCmdShow)
{
	HINTERNET inet = InternetOpen( "ChewingUpdate", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
	if( !inet )
		return -1;
	_tcscpy( url_file_name, "version-info" );
	HINTERNET ifile = InternetOpenUrl( inet, url, NULL, 0, INTERNET_FLAG_NO_CACHE_WRITE, 0 );
	if( ifile )
	{
		char buf[4096];
		memset( buf, 0, sizeof(buf) );

		char* pbuf = buf;
		char* end = buf + sizeof(buf);
		DWORD len = 0;

		while( InternetReadFile( ifile, pbuf, int(end - pbuf), &len) && len )
		{
			pbuf += len;
		}
		InternetCloseHandle(ifile);

		// version-info should in following simple format:
		// 1st line: Version string (required)
		// 2nd line: Release date (required)
		// 3rd line: URL of relating web page (required)
		// 4th line to end of file: Change log (optional)

		if ( strncmp(buf, CSig, strlen(CSig))!=0 ) {
			return	-1;
		}
		version = strtok(buf, "\r\n ");
		if( ! version )
			return -1;

		version += strlen(CSig);

		// Check if we are using the latest version
		HKEY hk = NULL;
		char cur_ver[32] = "";
		if( ERROR_SUCCESS == RegOpenKey( HKEY_LOCAL_MACHINE, 
			_T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\New Chewing IM"), &hk) )
		{
			DWORD size = sizeof(cur_ver);
			DWORD type = REG_SZ;
			RegQueryValueEx( hk, "DisplayVersion", 0, &type, (LPBYTE)cur_ver, &size );
			RegCloseKey( hk );
		}

		has_new_version = strcmp( cur_ver, version ) ? true : false;

		// No new version and in silent mode
		if( ! has_new_version && strstr(lpCmdLine, "/silent") )
			return 0;
		released_time = strtok( NULL, "\r\n" );
		news_url = strtok( NULL, "\r\n" );
		change_log = strtok( NULL, "" );

		hinst = hInstance;
		show_notify();
		return 0;
	}
	InternetCloseHandle(inet);
	return (ifile ? 0 : -1);
}