📄 handle_bnet.c
字号:
conn_set_country(c, langstr); /* FIXME: This isn't right. We want USA not ENU (English-US) */ conn_set_tzbias(c, uint32_to_int(tzbias)); conn_set_versionid(c, bn_int_get(packet->u.client_countryinfo_109.versionid)); conn_set_archtag(c, bn_int_get(packet->u.client_countryinfo_109.archtag)); conn_set_clienttag(c, bn_int_get(packet->u.client_countryinfo_109.clienttag)); conn_set_gamelang(c, bn_int_get(packet->u.client_countryinfo_109.gamelang)); /* First, send an ECHO_REQ */ if ((rpacket = packet_create(packet_class_bnet))) { packet_set_size(rpacket, sizeof(t_server_echoreq)); packet_set_type(rpacket, SERVER_ECHOREQ); bn_int_set(&rpacket->u.server_echoreq.ticks, get_ticks()); conn_push_outqueue(c, rpacket); packet_del_ref(rpacket); } if ((rpacket = packet_create(packet_class_bnet))) { t_versioncheck *vc; eventlog(eventlog_level_debug, __FUNCTION__, "[%d] selecting version check", conn_get_socket(c)); vc = versioncheck_create(conn_get_archtag(c), conn_get_clienttag(c)); conn_set_versioncheck(c, vc); packet_set_size(rpacket, sizeof(t_server_authreq_109)); packet_set_type(rpacket, SERVER_AUTHREQ_109); if ((conn_get_clienttag(c) == CLIENTTAG_WARCRAFT3_UINT)) bn_int_set(&rpacket->u.server_authreq_109.logontype, SERVER_AUTHREQ_109_LOGONTYPE_W3); else if ((conn_get_clienttag(c) == CLIENTTAG_WAR3XP_UINT)) bn_int_set(&rpacket->u.server_authreq_109.logontype, SERVER_AUTHREQ_109_LOGONTYPE_W3XP); else bn_int_set(&rpacket->u.server_authreq_109.logontype, SERVER_AUTHREQ_109_LOGONTYPE); bn_int_set(&rpacket->u.server_authreq_109.sessionkey, conn_get_sessionkey(c)); bn_int_set(&rpacket->u.server_authreq_109.sessionnum, conn_get_sessionnum(c)); file_to_mod_time(versioncheck_get_mpqfile(vc), &rpacket->u.server_authreq_109.timestamp); packet_append_string(rpacket, versioncheck_get_mpqfile(vc)); packet_append_string(rpacket, versioncheck_get_eqn(vc)); eventlog(eventlog_level_debug, __FUNCTION__, "[%d] selected \"%s\" \"%s\"", conn_get_socket(c), versioncheck_get_mpqfile(vc), versioncheck_get_eqn(vc)); if ((conn_get_clienttag(c) == CLIENTTAG_WARCRAFT3_UINT) || (conn_get_clienttag(c) == CLIENTTAG_WAR3XP_UINT)) { char padding[128]; memset(padding, 0, 128); packet_append_data(rpacket, padding, 128); } conn_push_outqueue(c, rpacket); packet_del_ref(rpacket); } } return 0;}static int _client_unknown2b(t_connection * c, t_packet const *const packet){ if (packet_get_size(packet) < sizeof(t_client_unknown_2b)) { eventlog(eventlog_level_error, __FUNCTION__, "[%d] got bad UNKNOWN_2B packet (expected %u bytes, got %u)", conn_get_socket(c), sizeof(t_client_unknown_2b), packet_get_size(packet)); return -1; } return 0;}static int _client_progident(t_connection * c, t_packet const *const packet){ t_packet *rpacket; if (packet_get_size(packet) < sizeof(t_client_progident)) { eventlog(eventlog_level_error, __FUNCTION__, "[%d] got bad PROGIDENT packet (expected %u bytes, got %u)", conn_get_socket(c), sizeof(t_client_progident), packet_get_size(packet)); return -1; } if (_check_allowed_client(bn_int_get(packet->u.client_progident.clienttag))) { conn_set_state(c, conn_state_destroy); return 0; } eventlog(eventlog_level_debug, __FUNCTION__, "[%d] CLIENT_PROGIDENT archtag=0x%08x clienttag=0x%08x versionid=0x%08x unknown1=0x%08x", conn_get_socket(c), bn_int_get(packet->u.client_progident.archtag), bn_int_get(packet->u.client_progident.clienttag), bn_int_get(packet->u.client_progident.versionid), bn_int_get(packet->u.client_progident.unknown1)); conn_set_archtag(c, bn_int_get(packet->u.client_progident.archtag)); conn_set_clienttag(c, bn_int_get(packet->u.client_progident.clienttag)); if (prefs_get_skip_versioncheck()) { eventlog(eventlog_level_debug, __FUNCTION__, "[%d] attempting to skip version check by sending early authreply", conn_get_socket(c)); /* skip over SERVER_AUTHREQ1 and CLIENT_AUTHREQ1 */ if ((rpacket = packet_create(packet_class_bnet))) { packet_set_size(rpacket, sizeof(t_server_authreply1)); packet_set_type(rpacket, SERVER_AUTHREPLY1); 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, ""); packet_append_string(rpacket, ""); /* FIXME: what's the second string for? */ conn_push_outqueue(c, rpacket); packet_del_ref(rpacket); } } else { t_versioncheck *vc; eventlog(eventlog_level_debug, __FUNCTION__, "[%d] selecting version check", conn_get_socket(c)); vc = versioncheck_create(conn_get_archtag(c), conn_get_clienttag(c)); conn_set_versioncheck(c, vc); if ((rpacket = packet_create(packet_class_bnet))) { packet_set_size(rpacket, sizeof(t_server_authreq1)); packet_set_type(rpacket, SERVER_AUTHREQ1); file_to_mod_time(versioncheck_get_mpqfile(vc), &rpacket->u.server_authreq1.timestamp); packet_append_string(rpacket, versioncheck_get_mpqfile(vc)); packet_append_string(rpacket, versioncheck_get_eqn(vc)); eventlog(eventlog_level_debug, __FUNCTION__, "[%d] selected \"%s\" \"%s\"", conn_get_socket(c), versioncheck_get_mpqfile(vc), versioncheck_get_eqn(vc)); conn_push_outqueue(c, rpacket); packet_del_ref(rpacket); } } return 0;}static int _client_createaccountw3(t_connection * c, t_packet const *const packet){ t_packet *rpacket; char const *username; char const *plainpass; char upass[20]; char lpass[20]; t_hash sc_hash; unsigned int i; if (packet_get_size(packet) < sizeof(t_client_createaccount_w3)) { eventlog(eventlog_level_error, __FUNCTION__, "[%d] got bad CREATEACCOUNT_W3 packet (expected %u bytes, got %u)", conn_get_socket(c), sizeof(t_client_createaccount_w3), packet_get_size(packet)); return -1; } username = packet_get_str_const(packet, sizeof(t_client_createaccount_w3), UNCHECKED_NAME_STR); if (!username) { eventlog(eventlog_level_error, __FUNCTION__, "[%d] got bad CREATEACCOUNT_W3 (missing or too long username)", conn_get_socket(c)); return -1; } plainpass = packet_get_str_const(packet, 4 + 8 * 4, 16); if (!plainpass) { eventlog(eventlog_level_error, __FUNCTION__, "[%d] got bad CREATEACCOUNT_W3 (missing password)", conn_get_socket(c)); return -1; } rpacket = packet_create(packet_class_bnet); if (!rpacket) return -1; packet_set_size(rpacket, sizeof(t_server_createaccount_w3)); packet_set_type(rpacket, SERVER_CREATEACCOUNT_W3); eventlog(eventlog_level_debug, __FUNCTION__, "[%d] new account requested for \"%s\"", conn_get_socket(c), username); if (prefs_get_allow_new_accounts() == 0) { eventlog(eventlog_level_debug, __FUNCTION__, "[%d] account not created (disabled)", conn_get_socket(c)); bn_int_set(&rpacket->u.server_createaccount_w3.result, SERVER_CREATEACCOUNT_W3_RESULT_EXIST); goto out; } if (account_check_name(username) < 0) { eventlog(eventlog_level_debug, __FUNCTION__, "[%d] account not created (invalid symbols)", conn_get_socket(c)); bn_int_set(&rpacket->u.server_createaccount_w3.result, SERVER_CREATEACCOUNT_W3_RESULT_INVALID); goto out; } /* convert plaintext password to uppercase */ strncpy(upass, plainpass, 16); upass[16] = 0; for (i = 0; i < strlen(upass); i++) if (isascii((int) upass[i]) && islower((int) upass[i])) upass[i] = toupper((int) upass[i]); /* convert plaintext password to lowercase for sc etc. */ strncpy(lpass, plainpass, 16); lpass[16] = 0; for (i = 0; i < strlen(lpass); i++) if (isascii((int) lpass[i]) && isupper((int) lpass[i])) lpass[i] = tolower((int) lpass[i]); //set password hash for sc etc. bnet_hash(&sc_hash, strlen(lpass), lpass); if (!accountlist_create_account(username, hash_get_str(sc_hash))) bn_int_set(&rpacket->u.server_createaccount_w3.result, SERVER_CREATEACCOUNT_W3_RESULT_EXIST); else { eventlog(eventlog_level_debug, __FUNCTION__, "[%d] account created", conn_get_socket(c)); bn_int_set(&rpacket->u.server_createaccount_w3.result, SERVER_CREATEACCOUNT_W3_RESULT_OK); } out: conn_push_outqueue(c, rpacket); packet_del_ref(rpacket); return 0;}static int _client_createacctreq1(t_connection * c, t_packet const *const packet){ t_packet *rpacket; char const *username; t_hash newpasshash1; if (packet_get_size(packet) < sizeof(t_client_createacctreq1)) { eventlog(eventlog_level_error, __FUNCTION__, "[%d] got bad CREATEACCTREQ1 packet (expected %u bytes, got %u)", conn_get_socket(c), sizeof(t_client_createacctreq1), packet_get_size(packet)); return -1; } if (!(username = packet_get_str_const(packet, sizeof(t_client_createacctreq1), UNCHECKED_NAME_STR))) { eventlog(eventlog_level_error, __FUNCTION__, "[%d] got bad CREATEACCTREQ1 (missing or too long username)", conn_get_socket(c)); return -1; } eventlog(eventlog_level_debug, __FUNCTION__, "[%d] new account requested for \"%s\"", conn_get_socket(c), username); rpacket = packet_create(packet_class_bnet); if (!rpacket) return -1; packet_set_size(rpacket, sizeof(t_server_createacctreply1)); packet_set_type(rpacket, SERVER_CREATEACCTREPLY1); if (prefs_get_allow_new_accounts() == 0) { eventlog(eventlog_level_debug, __FUNCTION__, "[%d] account not created (disabled)", conn_get_socket(c)); bn_int_set(&rpacket->u.server_createacctreply1.result, SERVER_CREATEACCTREPLY1_RESULT_NO); goto out; } bnhash_to_hash(packet->u.client_createacctreq1.password_hash1, &newpasshash1); if (!accountlist_create_account(username, hash_get_str(newpasshash1))) { eventlog(eventlog_level_debug, __FUNCTION__, "[%d] account not created (failed)", conn_get_socket(c)); bn_int_set(&rpacket->u.server_createacctreply1.result, SERVER_CREATEACCTREPLY1_RESULT_NO); goto out; } eventlog(eventlog_level_debug, __FUNCTION__, "[%d] account created", conn_get_socket(c)); bn_int_set(&rpacket->u.server_createacctreply1.result, SERVER_CREATEACCTREPLY1_RESULT_OK); out: conn_push_outqueue(c, rpacket); packet_del_ref(rpacket); return 0;}static int _client_createacctreq2(t_connection * c, t_packet const *const packet){ t_packet *rpacket; char const *username; t_hash newpasshash1; if (packet_get_size(packet) < sizeof(t_client_createacctreq2)) { eventlog(eventlog_level_error, __FUNCTION__, "[%d] got bad CLIENT_CREATEACCTREQ2 packet (expected %u bytes, got %u)", conn_get_socket(c), sizeof(t_client_createacctreq2), packet_get_size(packet)); return -1; } username = packet_get_str_const(packet, sizeof(t_client_createacctreq2), UNCHECKED_NAME_STR); if (!username) { eventlog(eventlog_level_error, __FUNCTION__, "[%d] got bad CREATEACCTREQ2 (missing or too long username)", conn_get_socket(c)); return -1; } eventlog(eventlog_level_debug, __FUNCTION__, "[%d] new account requested for \"%s\"", conn_get_socket(c), username); rpacket = packet_create(packet_class_bnet); if (!rpacket) return -1; packet_set_size(rpacket, sizeof(t_server_createacctreply2)); packet_set_type(rpacket, SERVER_CREATEACCTREPLY2); if (prefs_get_allow_new_accounts() == 0) { eventlog(eventlog_level_debug, __FUNCTION__, "[%d] account not created (disabled)", conn_get_socket(c)); bn_int_set(&rpacket->u.server_createacctreply2.result, SERVER_CREATEACCTREPLY2_RESULT_EXIST); goto out; } if (account_check_name(username) < 0) { eventlog(eventlog_level_debug, __FUNCTION__, "[%d] account not created (invalid symbols)", conn_get_socket(c)); bn_int_set(&rpacket->u.server_createaccount_w3.result, SERVER_CREATEACCTREPLY2_RESULT_INVALID); goto out; } bnhash_to_hash(packet->u.client_createacctreq2.password_hash1, &newpasshash1); if (!accountlist_create_account(username, hash_get_str(newpasshash1))) { eventlog(eventlog_level_debug, __FUNCTION__, "[%d] account not created (failed)", conn_get_socket(c)); bn_int_set(&rpacket->u.server_createacctreply2.result, SERVER_CREATEACCTREPLY2_RESULT_EXIST); /* FIXME: return reason for failure */ goto out; } eventlog(eventlog_level_debug, __FUNCTION__, "[%d] account created", conn_get_socket(c)); bn_int_set(&rpacket->u.server_createacctreply2.result, SERVER_CREATEACCTREPLY2_RESULT_OK); out: conn_push_outqueue(c, rpacket); packet_del_ref(rpacket); return 0;}static int _client_changepassreq(t_connection * c, t_packet const *const packet){ t_packet *rpacket; if (packet_get_size(packet) < sizeof(t_client_changepassreq)) { eventlog(eventlog_level_error, __FUNCTION__, "[%d] got bad CHANGEPASSREQ packet (expected %u bytes, got %u)", conn_get_socket(c), sizeof(t_client_changepassreq), packet_get_size(packet)); return -1; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -