⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 handle_bnet.c

📁 打魔兽战网的都知道他是什么
💻 C
📖 第 1 页 / 共 5 页
字号:
    {	char const *username;	t_account *account;	if (!(username = packet_get_str_const(packet, sizeof(t_client_changepassreq), UNCHECKED_NAME_STR))) {	    eventlog(eventlog_level_error, __FUNCTION__, "[%d] got bad CHANGEPASSREQ (missing or too long username)", conn_get_socket(c));	    return -1;	}	eventlog(eventlog_level_info, __FUNCTION__, "[%d] password change requested for \"%s\"", conn_get_socket(c), username);	if (!(rpacket = packet_create(packet_class_bnet)))	    return -1;	packet_set_size(rpacket, sizeof(t_server_changepassack));	packet_set_type(rpacket, SERVER_CHANGEPASSACK);	/* fail if logged in or no account */	if (connlist_find_connection_by_accountname(username) || !(account = accountlist_find_account(username))) {	    eventlog(eventlog_level_info, __FUNCTION__, "[%d] password change for \"%s\" refused (no such account)", conn_get_socket(c), username);	    bn_int_set(&rpacket->u.server_changepassack.message, SERVER_CHANGEPASSACK_MESSAGE_FAIL);	} else if (account_get_auth_changepass(account) == 0) {	/* default to true */	    eventlog(eventlog_level_info, __FUNCTION__, "[%d] password change for \"%s\" refused (no change access)", conn_get_socket(c), username);	    bn_int_set(&rpacket->u.server_changepassack.message, SERVER_CHANGEPASSACK_MESSAGE_FAIL);	} else if (conn_get_sessionkey(c) != bn_int_get(packet->u.client_changepassreq.sessionkey)) {	    eventlog(eventlog_level_error, __FUNCTION__, "[%d] password change for \"%s\" refused (expected session key 0x%08x, got 0x%08x)", conn_get_socket(c), username, conn_get_sessionkey(c), bn_int_get(packet->u.client_changepassreq.sessionkey));	    bn_int_set(&rpacket->u.server_changepassack.message, SERVER_CHANGEPASSACK_MESSAGE_FAIL);	} else {	    struct {		bn_int ticks;		bn_int sessionkey;		bn_int passhash1[5];	    } temp;	    char const *oldstrhash1;	    t_hash oldpasshash1;	    t_hash oldpasshash2;	    t_hash trypasshash2;	    t_hash newpasshash1;	    if ((oldstrhash1 = account_get_pass(account))) {		bn_int_set(&temp.ticks, bn_int_get(packet->u.client_changepassreq.ticks));		bn_int_set(&temp.sessionkey, bn_int_get(packet->u.client_changepassreq.sessionkey));		if (hash_set_str(&oldpasshash1, oldstrhash1) < 0) {		    bnhash_to_hash(packet->u.client_changepassreq.newpassword_hash1, &newpasshash1);		    account_set_pass(account, hash_get_str(newpasshash1));		    eventlog(eventlog_level_info, __FUNCTION__, "[%d] password change for \"%s\" successful (bad previous password)", conn_get_socket(c), account_get_name(account));		    bn_int_set(&rpacket->u.server_changepassack.message, SERVER_CHANGEPASSACK_MESSAGE_SUCCESS);		} else {		    hash_to_bnhash((t_hash const *) &oldpasshash1, temp.passhash1);	/* avoid warning */		    bnet_hash(&oldpasshash2, sizeof(temp), &temp);	/* do the double hash */		    bnhash_to_hash(packet->u.client_changepassreq.oldpassword_hash2, &trypasshash2);		    if (hash_eq(trypasshash2, oldpasshash2) == 1) {			bnhash_to_hash(packet->u.client_changepassreq.newpassword_hash1, &newpasshash1);			account_set_pass(account, hash_get_str(newpasshash1));			eventlog(eventlog_level_info, __FUNCTION__, "[%d] password change for \"%s\" successful (previous password)", conn_get_socket(c), account_get_name(account));			bn_int_set(&rpacket->u.server_changepassack.message, SERVER_CHANGEPASSACK_MESSAGE_SUCCESS);		    } else {			eventlog(eventlog_level_info, __FUNCTION__, "[%d] password change for \"%s\" refused (wrong password)", conn_get_socket(c), account_get_name(account));			conn_increment_passfail_count(c);			bn_int_set(&rpacket->u.server_changepassack.message, SERVER_CHANGEPASSACK_MESSAGE_FAIL);		    }		}	    } else {		bnhash_to_hash(packet->u.client_changepassreq.newpassword_hash1, &newpasshash1);		account_set_pass(account, hash_get_str(newpasshash1));		eventlog(eventlog_level_info, __FUNCTION__, "[%d] password change for \"%s\" successful (no previous password)", conn_get_socket(c), account_get_name(account));		bn_int_set(&rpacket->u.server_changepassack.message, SERVER_CHANGEPASSACK_MESSAGE_SUCCESS);	    }	}	conn_push_outqueue(c, rpacket);	packet_del_ref(rpacket);    }    return 0;}static int _client_echoreply(t_connection * c, t_packet const *const packet){    if (packet_get_size(packet) < sizeof(t_client_echoreply)) {	eventlog(eventlog_level_error, __FUNCTION__, "[%d] got bad ECHOREPLY packet (expected %u bytes, got %u)", conn_get_socket(c), sizeof(t_client_echoreply), packet_get_size(packet));	return -1;    }    {	unsigned int now;	unsigned int then;	now = get_ticks();	then = bn_int_get(packet->u.client_echoreply.ticks);	if (!now || !then || now < then)	    eventlog(eventlog_level_warn, __FUNCTION__, "[%d] bad timing in echo reply: now=%u then=%u", conn_get_socket(c), now, then);	else	    conn_set_latency(c, now - then);    }    return 0;}static int _client_authreq1(t_connection * c, t_packet const *const packet){    t_packet *rpacket;    if (packet_get_size(packet) < sizeof(t_client_authreq1)) {	eventlog(eventlog_level_error, __FUNCTION__, "[%d] got bad AUTHREQ1 packet (expected %u bytes, got %u)", conn_get_socket(c), sizeof(t_client_authreq1), packet_get_size(packet));	return -1;    }    {	char verstr[16];	char const *exeinfo;	char const *versiontag;	int failed;	failed = 0;	if (bn_int_get(packet->u.client_authreq1.archtag) != conn_get_archtag(c))	    failed = 1;	if (bn_int_get(packet->u.client_authreq1.clienttag) != conn_get_clienttag(c))	    failed = 1;	if (!(exeinfo = packet_get_str_const(packet, sizeof(t_client_authreq1), MAX_EXEINFO_STR))) {	    eventlog(eventlog_level_error, __FUNCTION__, "[%d] got bad AUTHREQ1 (missing or too long exeinfo)", conn_get_socket(c));	    exeinfo = "badexe";	    failed = 1;	}	conn_set_versionid(c, bn_int_get(packet->u.client_authreq1.versionid));	conn_set_checksum(c, bn_int_get(packet->u.client_authreq1.checksum));	conn_set_gameversion(c, bn_int_get(packet->u.client_authreq1.gameversion));	strcpy(verstr, vernum_to_verstr(bn_int_get(packet->u.client_authreq1.gameversion)));	conn_set_clientver(c, verstr);	conn_set_clientexe(c, exeinfo);	eventlog(eventlog_level_info, __FUNCTION__, "[%d] CLIENT_AUTHREQ1 archtag=0x%08x clienttag=0x%08x verstr=%s exeinfo=\"%s\" versionid=0x%08lx gameversion=0x%08lx checksum=0x%08lx", conn_get_socket(c), bn_int_get(packet->u.client_authreq1.archtag), bn_int_get(packet->u.client_authreq1.clienttag), verstr, exeinfo, conn_get_versionid(c), conn_get_gameversion(c), conn_get_checksum(c));	if ((rpacket = packet_create(packet_class_bnet))) {	    packet_set_size(rpacket, sizeof(t_server_authreply1));	    packet_set_type(rpacket, SERVER_AUTHREPLY1);	    if (!conn_get_versioncheck(c) && prefs_get_skip_versioncheck())		eventlog(eventlog_level_info, __FUNCTION__, "[%d] skip versioncheck enabled and client did not request validation", conn_get_socket(c));	    else		switch (versioncheck_validate(conn_get_versioncheck(c), conn_get_archtag(c), conn_get_clienttag(c), exeinfo, conn_get_versionid(c), conn_get_gameversion(c), conn_get_checksum(c))) {		    case -1:	/* failed test... client has been modified */			if (!prefs_get_allow_bad_version()) {			    eventlog(eventlog_level_info, __FUNCTION__, "[%d] client failed test (marking untrusted)", conn_get_socket(c));			    failed = 1;			} else			    eventlog(eventlog_level_info, __FUNCTION__, "[%d] client failed test, allowing anyway", conn_get_socket(c));			break;		    case 0:	/* not listed in table... can't tell if client has been modified */			if (!prefs_get_allow_unknown_version()) {			    eventlog(eventlog_level_info, __FUNCTION__, "[%d] unable to test client (marking untrusted)", conn_get_socket(c));			    failed = 1;			} else			    eventlog(eventlog_level_info, __FUNCTION__, "[%d] unable to test client, allowing anyway", conn_get_socket(c));			break;			/* 1 == test passed... client seems to be ok */		}	    versiontag = versioncheck_get_versiontag(conn_get_versioncheck(c));	    eventlog(eventlog_level_info, __FUNCTION__, "[%d] client matches versiontag \"%s\"", conn_get_socket(c), versiontag);	    if (failed) {		conn_set_state(c, conn_state_untrusted);		if (bn_int_get(packet->u.client_progident.clienttag) == CLIENTTAG_DIABLO2XP_UINT)		    bn_int_set(&rpacket->u.server_authreply1.message, SERVER_AUTHREPLY1_D2XP_MESSAGE_BADVERSION);		else		    bn_int_set(&rpacket->u.server_authreply1.message, SERVER_AUTHREPLY1_MESSAGE_BADVERSION);		packet_append_string(rpacket, "");	    } else {		char *mpqfilename;		mpqfilename = autoupdate_check(conn_get_archtag(c), conn_get_clienttag(c), conn_get_gamelang(c), versiontag);		/* Only handle updates when there is an update file available. */		if (mpqfilename != NULL) {		    eventlog(eventlog_level_info, __FUNCTION__, "[%d] an upgrade for version %s is available \"%s\"", conn_get_socket(c), versioncheck_get_versiontag(conn_get_versioncheck(c)), mpqfilename);		    if (bn_int_get(packet->u.client_progident.clienttag) == CLIENTTAG_DIABLO2XP_UINT)			bn_int_set(&rpacket->u.server_authreply1.message, SERVER_AUTHREPLY1_D2XP_MESSAGE_UPDATE);		    else			bn_int_set(&rpacket->u.server_authreply1.message, SERVER_AUTHREPLY1_MESSAGE_UPDATE);		    packet_append_string(rpacket, mpqfilename);		} else {		    eventlog(eventlog_level_info, __FUNCTION__, "[%d] no upgrade for %s is available", conn_get_socket(c), versioncheck_get_versiontag(conn_get_versioncheck(c)));		    if (bn_int_get(packet->u.client_progident.clienttag) == CLIENTTAG_DIABLO2XP_UINT)			bn_int_set(&rpacket->u.server_authreply1.message, SERVER_AUTHREPLY1_D2XP_MESSAGE_OK);		    else			bn_int_set(&rpacket->u.server_authreply1.message, SERVER_AUTHREPLY1_MESSAGE_OK);		    packet_append_string(rpacket, "");		}		if (mpqfilename)		    xfree((void *) mpqfilename);	    }	    packet_append_string(rpacket, "");	/* FIXME: what's the second string for? */	    conn_push_outqueue(c, rpacket);	    packet_del_ref(rpacket);	}    }    return 0;}static int _client_authreq109(t_connection * c, t_packet const *const packet){    t_packet *rpacket;    if (packet_get_size(packet) < sizeof(t_client_authreq_109)) {	eventlog(eventlog_level_error, __FUNCTION__, "[%d] got bad AUTHREQ_109 packet (expected %u bytes, got %u)", conn_get_socket(c), sizeof(t_client_authreq_109), packet_get_size(packet));	return 0;    }    {	char verstr[16];	char const *exeinfo;	char const *versiontag;	int failed;	char const *owner;	unsigned int count;	unsigned int pos;	failed = 0;	count = bn_int_get(packet->u.client_authreq_109.cdkey_number);	pos = sizeof(t_client_authreq_109) + (count * sizeof(t_cdkey_info));	if (!(exeinfo = packet_get_str_const(packet, pos, MAX_EXEINFO_STR))) {	    eventlog(eventlog_level_error, __FUNCTION__, "[%d] got bad AUTHREQ_109 (missing or too long exeinfo)", conn_get_socket(c));	    exeinfo = "badexe";	    failed = 1;	}	conn_set_clientexe(c, exeinfo);	pos += strlen(exeinfo) + 1;	if (!(owner = packet_get_str_const(packet, pos, MAX_OWNER_STR))) {	    eventlog(eventlog_level_error, __FUNCTION__, "[%d] got bad AUTHREQ_109 (missing or too long owner)", conn_get_socket(c));	    owner = "";		/* maybe owner was missing, use empty string */	}	conn_set_owner(c, owner);	conn_set_checksum(c, bn_int_get(packet->u.client_authreq_109.checksum));	conn_set_gameversion(c, bn_int_get(packet->u.client_authreq_109.gameversion));	strcpy(verstr, vernum_to_verstr(bn_int_get(packet->u.client_authreq_109.gameversion)));	conn_set_clientver(c, verstr);	conn_set_clientexe(c, exeinfo);	eventlog(eventlog_level_info, __FUNCTION__, "[%d] CLIENT_AUTHREQ_109 ticks=0x%08x, verstr=%s exeinfo=\"%s\" versionid=0x%08lx gameversion=0x%08lx checksum=0x%08lx", conn_get_socket(c), bn_int_get(packet->u.client_authreq_109.ticks), verstr, exeinfo, conn_get_versionid(c), conn_get_gameversion(c), conn_get_checksum(c));	if ((rpacket = packet_create(packet_class_bnet))) {	    packet_set_size(rpacket, sizeof(t_server_authreply_109));	    packet_set_type(rpacket, SERVER_AUTHREPLY_109);	    if (!conn_get_versioncheck(c) && prefs_get_skip_versioncheck())		eventlog(eventlog_level_info, __FUNCTION__, "[%d] skip versioncheck enabled and client did not request validation", conn_get_socket(c));	    else		switch (versioncheck_validate(conn_get_versioncheck(c), conn_get_archtag(c), conn_get_clienttag(c), exeinfo, conn_get_versionid(c), conn_get_gameversion(c), conn_get_checksum(c))) {		    case -1:	/* failed test... client has been modified */			if (!prefs_get_allow_bad_version()) {			    eventlog(eventlog_level_info, __FUNCTION__, "[%d] client failed test (closing connection)", conn_get_socket(c));			    failed = 1;			} else			    eventlog(eventlog_level_info, __FUNCTION__, "[%d] client failed test, allowing anyway", conn_get_socket(c));			break;		    case 0:	/* not listed in table... can't tell if client has been modified */			if (!prefs_get_allow_unknown_version()) {			    eventlog(eventlog_level_info, __FUNCTION__, "[%d] unable to test client (closing connection)", conn_get_socket(c));			    failed = 1;			} else			    eventlog(eventlog_level_info, __FUNCTION__, "[%d] unable to test client, allowing anyway", conn_get_socket(c));			break;			/* 1 == test passed... client seems to be ok */		}	    versiontag = versioncheck_get_versiontag(conn_get_versioncheck(c));	    eventlog(eventlog_level_info, __FUNCTION__, "[%d] client matches versiontag \"%s\"", conn_get_socket(c), versiontag);	    if (failed) {		conn_set_state(c, conn_state_untrusted);		bn_int_set(&rpacket->u.server_authreply_109.message, SERVER_AUTHREPLY_109_MESSAGE_BADVERSION);		packet_append_string(rpacket, "");	    } else {		char *mpqfilename;		mpqfilename = autoupdate_check(conn_get_archtag(c), conn_get_clienttag(c), conn_get_gamelang(c), versiontag);		/* Only handle updates when there is an update file available. */		if (mpqfilename != NULL) {		    eventlog(eventlog_level_info, __FUNCTION__, "[%d] an upgrade for %s is available \"%s\"", conn_get_socket(c), versiontag, mpqfilename);		    bn_int_set(&rpacket->u.server_authreply_109.message, SERVER_AUTHREPLY_109_MESSAGE_UPDATE);		    packet_append_string(rpacket, mpqfilename);		} else {		    eventlog(eventlog_level_info, __FUNCTION__, "[%d] no upgrade for %s is available", conn_get_socket(c), versiontag);		    bn_int_set(&rpacket->u.server_authreply_109.message, SERVER_AUTHREPLY_109_MESSAGE_OK);		    packet_append_string(rpacket, "");		}		if (mpqfilename)		    xfree((void *) mpqfilename);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -