[Loginserver] Worldserver Name Sanitization (#1739)

* Sanitize bad words in server names

* Add config options and enforcement for dev/test servers and servers starting with a special character

* Refine bad word logic

* Add installer to dev/test servers

* Change server prefixes

* Special char prefix

* Formatting

* Remove multi words

* Add server types enum

* Add error constants

* Remove sanitize from world level

* Use strn0cpy
This commit is contained in:
Chris Miles
2021-11-12 23:02:05 -06:00
committed by GitHub
parent 8b83a13560
commit a9d1034298
12 changed files with 726 additions and 243 deletions
+70 -30
View File
@@ -1,6 +1,6 @@
#include "world_server.h"
#include "login_server.h"
#include "login_structures.h"
#include "login_types.h"
#include "../common/ip_util.h"
#include "../common/string_util.h"
@@ -198,15 +198,15 @@ void WorldServer::ProcessUserToWorldResponseLegacy(uint16_t opcode, const EQ::Ne
LogDebug("User-To-World Response received");
}
auto *user_to_world_response = (UsertoWorldResponseLegacy_Struct *) packet.Data();
auto *r = (UsertoWorldResponseLegacy_Struct *) packet.Data();
LogDebug("Trying to find client with user id of [{0}]", user_to_world_response->lsaccountid);
Client *client = server.client_manager->GetClient(user_to_world_response->lsaccountid, "eqemu");
LogDebug("Trying to find client with user id of [{0}]", r->lsaccountid);
Client *client = server.client_manager->GetClient(r->lsaccountid, "eqemu");
if (client) {
LogDebug(
"Found client with user id of [{0}] and account name of [{1}]",
user_to_world_response->lsaccountid,
r->lsaccountid,
client->GetAccountName()
);
@@ -217,9 +217,9 @@ void WorldServer::ProcessUserToWorldResponseLegacy(uint16_t opcode, const EQ::Ne
auto *per = (PlayEverquestResponse_Struct *) outapp->pBuffer;
per->base_header.sequence = client->GetPlaySequence();
per->server_number = client->GetPlayServerID();
per->server_number = client->GetPlayServerID();
if (user_to_world_response->response > 0) {
if (r->response > 0) {
per->base_reply.success = true;
SendClientAuth(
client->GetConnection()->GetRemoteAddr(),
@@ -230,27 +230,27 @@ void WorldServer::ProcessUserToWorldResponseLegacy(uint16_t opcode, const EQ::Ne
);
}
switch (user_to_world_response->response) {
switch (r->response) {
case UserToWorldStatusSuccess:
per->base_reply.error_str_id = 101;
per->base_reply.error_str_id = LS::ErrStr::NO_ERROR;
break;
case UserToWorldStatusWorldUnavail:
per->base_reply.error_str_id = 326;
per->base_reply.error_str_id = LS::ErrStr::SERVER_UNAVAILABLE;
break;
case UserToWorldStatusSuspended:
per->base_reply.error_str_id = 337;
per->base_reply.error_str_id = LS::ErrStr::ACCOUNT_SUSPENDED;
break;
case UserToWorldStatusBanned:
per->base_reply.error_str_id = 338;
per->base_reply.error_str_id = LS::ErrStr::ACCOUNT_BANNED;
break;
case UserToWorldStatusWorldAtCapacity:
per->base_reply.error_str_id = 339;
per->base_reply.error_str_id = LS::ErrStr::WORLD_MAX_CAPACITY;
break;
case UserToWorldStatusAlreadyOnline:
per->base_reply.error_str_id = 111;
per->base_reply.error_str_id = LS::ErrStr::ERROR_1018_ACTIVE_CHARACTER;
break;
default:
per->base_reply.error_str_id = 102;
per->base_reply.error_str_id = LS::ErrStr::UNKNOWN_ERROR;
}
if (server.options.IsWorldTraceOn()) {
@@ -275,7 +275,7 @@ void WorldServer::ProcessUserToWorldResponseLegacy(uint16_t opcode, const EQ::Ne
else {
LogError(
"Received User-To-World Response for [{0}] but could not find the client referenced!",
user_to_world_response->lsaccountid
r->lsaccountid
);
}
}
@@ -335,7 +335,7 @@ void WorldServer::ProcessUserToWorldResponse(uint16_t opcode, const EQ::Net::Pac
auto *per = (PlayEverquestResponse_Struct *) outapp->pBuffer;
per->base_header.sequence = client->GetPlaySequence();
per->server_number = client->GetPlayServerID();
per->server_number = client->GetPlayServerID();
LogDebug(
"Found sequence and play of [{0}] [{1}]",
@@ -358,25 +358,25 @@ void WorldServer::ProcessUserToWorldResponse(uint16_t opcode, const EQ::Net::Pac
switch (user_to_world_response->response) {
case UserToWorldStatusSuccess:
per->base_reply.error_str_id = 101;
per->base_reply.error_str_id = LS::ErrStr::NO_ERROR;
break;
case UserToWorldStatusWorldUnavail:
per->base_reply.error_str_id = 326;
per->base_reply.error_str_id = LS::ErrStr::SERVER_UNAVAILABLE;
break;
case UserToWorldStatusSuspended:
per->base_reply.error_str_id = 337;
per->base_reply.error_str_id = LS::ErrStr::ACCOUNT_SUSPENDED;
break;
case UserToWorldStatusBanned:
per->base_reply.error_str_id = 338;
per->base_reply.error_str_id = LS::ErrStr::ACCOUNT_BANNED;
break;
case UserToWorldStatusWorldAtCapacity:
per->base_reply.error_str_id = 339;
per->base_reply.error_str_id = LS::ErrStr::WORLD_MAX_CAPACITY;
break;
case UserToWorldStatusAlreadyOnline:
per->base_reply.error_str_id = 111;
per->base_reply.error_str_id = LS::ErrStr::ERROR_1018_ACTIVE_CHARACTER;
break;
default:
per->base_reply.error_str_id = 102;
per->base_reply.error_str_id = LS::ErrStr::UNKNOWN_ERROR;
}
if (server.options.IsTraceOn()) {
@@ -571,6 +571,12 @@ void WorldServer::Handle_NewLSInfo(ServerNewLSInfo_Struct *new_world_server_info
GetServerLongName(),
GetRemoteIp()
);
WorldServer::FormatWorldServerName(
new_world_server_info_packet->server_long_name,
world_registration.server_list_type
);
SetLongName(new_world_server_info_packet->server_long_name);
}
/**
@@ -1025,21 +1031,21 @@ bool WorldServer::ValidateWorldServerAdminLogin(
return false;
}
void WorldServer::SerializeForClientServerList(SerializeBuffer& out, bool use_local_ip) const
void WorldServer::SerializeForClientServerList(SerializeBuffer &out, bool use_local_ip) const
{
// see LoginClientServerData_Struct
if (use_local_ip) {
out.WriteString(GetLocalIP());
} else {
}
else {
out.WriteString(GetRemoteIP());
}
switch (GetServerListID())
{
case 1:
switch (GetServerListID()) {
case LS::ServerType::Legends:
out.WriteInt32(LS::ServerTypeFlags::Legends);
break;
case 2:
case LS::ServerType::Preferred:
out.WriteInt32(LS::ServerTypeFlags::Preferred);
break;
default:
@@ -1348,3 +1354,37 @@ void WorldServer::OnKeepAlive(EQ::Timer *t)
ServerPacket pack(ServerOP_KeepAlive, 0);
m_connection->SendPacket(&pack);
}
void WorldServer::FormatWorldServerName(char *name, int8 server_list_type)
{
std::string server_long_name = name;
server_long_name = trim(server_long_name);
bool name_set_to_bottom = false;
if (server_list_type == LS::ServerType::Standard) {
if (server.options.IsWorldDevTestServersListBottom()) {
std::string s = str_tolower(server_long_name);
if (s.find("dev") != std::string::npos) {
server_long_name = fmt::format("|D| {}", server_long_name);
name_set_to_bottom = true;
}
else if (s.find("test") != std::string::npos) {
server_long_name = fmt::format("|T| {}", server_long_name);
name_set_to_bottom = true;
}
else if (s.find("installer") != std::string::npos) {
server_long_name = fmt::format("|I| {}", server_long_name);
name_set_to_bottom = true;
}
}
if (server.options.IsWorldSpecialCharacterStartListBottom() && !name_set_to_bottom) {
auto first_char = server_long_name.c_str()[0];
if (IsAllowedWorldServerCharacterList(first_char) && first_char != '|') {
server_long_name = fmt::format("|*| {}", server_long_name);
name_set_to_bottom = true;
}
}
}
strn0cpy(name, server_long_name.c_str(), 201);
}