Using new command error system

This commit is contained in:
WolverinDEV
2020-01-25 23:42:37 +01:00
parent 10092cfab0
commit bb2e7699dc
18 changed files with 1223 additions and 1190 deletions
+34 -23
View File
@@ -343,22 +343,24 @@ HWID_REGEX(unix, "^[a-z0-9]{32}$");
HWID_REGEX(android, "^[a-z0-9]{16}$");
HWID_REGEX(ios, "^[A-Z0-9]{8}-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{12}$");
CommandResult SpeakingClient::handleCommandClientInit(Command& cmd) {
command_result SpeakingClient::handleCommandClientInit(Command& cmd) {
TIMING_START(timings);
{
lock_guard<threads::Mutex> lock(this->server->join_attempts_lock);
auto inetAddr = this->getPeerIp();
if(config::voice::clientConnectLimit > 0 && this->server->join_attempts[inetAddr] + 1 > config::voice::clientConnectLimit)
return {findError("client_is_flooding"), "To many joins per second per ip"};
return command_result{error::client_join_rate_limit_reached};
if(config::voice::connectLimit > 0 && this->server->join_attempts["_"] + 1 > config::voice::connectLimit)
return {findError("client_is_flooding"), "To many joins per second"};
return command_result{error::server_join_rate_limit_reached};
this->server->join_attempts[inetAddr]++;
this->server->join_attempts["_"]++;
}
TIMING_STEP(timings, "join atmp c");
if(!DatabaseHelper::assignDatabaseId(this->server->getSql(), this->server->getServerId(), _this.lock())) return {findError("vs_critical"), "Could not assign database id!"};
if(!DatabaseHelper::assignDatabaseId(this->server->getSql(), this->server->getServerId(), _this.lock()))
return command_result{error::vs_critical, "Could not assign database id!"};
TIMING_STEP(timings, "db assign ");
this->server->getGroupManager()->enableCache(this->getClientDatabaseId());
TIMING_STEP(timings, "gr cache ");
@@ -423,8 +425,10 @@ CommandResult SpeakingClient::handleCommandClientInit(Command& cmd) {
else if(key == "pubSignCert") continue;
else if(key == "client_version" || key == "client_platform") {
for(auto& character : cmd[key].string())
if(!isascii(character))
return {findError("parameter_invalid"), "invalid version or platform"};
if(!isascii(character)) {
logWarning(this->getServerId(), "{} Tried to join within an invalid supplied '{}' ({})", CLIENT_STR_LOG_PREFIX, key,cmd[key].string());
return command_result{error::client_hacked};
}
}
const auto &info = property::info<property::ClientProperties>(key);
@@ -433,7 +437,8 @@ CommandResult SpeakingClient::handleCommandClientInit(Command& cmd) {
continue;
//return {findError("parameter_invalid"), "Unknown property " + key};
}
if(!info->validate_input(cmd[key].as<string>())) return {findError("parameter_invalid"), "Unknown value type for " + key};
if(!info->validate_input(cmd[key].as<string>()))
return command_result{error::parameter_invalid};
this->properties()[info] = cmd[key].as<std::string>();
}
@@ -459,7 +464,7 @@ CommandResult SpeakingClient::handleCommandClientInit(Command& cmd) {
if(geoloc::provider_vpn && permissions[permission::b_client_ignore_vpn] == permNotGranted) {
auto provider = this->isAddressV4() ? geoloc::provider_vpn->resolveInfoV4(this->getPeerIp(), true) : geoloc::provider_vpn->resolveInfoV6(this->getPeerIp(), true);
if(provider)
return {findError(0xD01), strvar::transform(ts::config::messages::kick_vpn, strvar::StringValue{"provider.name", provider->name}, strvar::StringValue{"provider.website", provider->side})};
return command_result{error::server_connect_banned, strvar::transform(ts::config::messages::kick_vpn, strvar::StringValue{"provider.name", provider->name}, strvar::StringValue{"provider.website", provider->side})};
}
if(this->getType() == ClientType::CLIENT_TEAMSPEAK && (permissions[permission::b_client_enforce_valid_hwid] == permNotGranted && permissions[permission::b_client_enforce_valid_hwid] == 0)) {
@@ -470,14 +475,15 @@ CommandResult SpeakingClient::handleCommandClientInit(Command& cmd) {
!std::regex_match(hwid, regex_hwid_android) &&
!std::regex_match(hwid, regex_hwid_ios)
) {
return {findError("parameter_invalid"), config::messages::kick_invalid_hardware_id};
return command_result{error::parameter_invalid, config::messages::kick_invalid_hardware_id};
}
}
TIMING_STEP(timings, "valid hw ip");
auto ignorePassword = permissions[permission::b_virtualserver_join_ignore_password] > 0 && permissions[permission::b_virtualserver_join_ignore_password] != permNotGranted;
if(!ignorePassword)
if(!this->server->verifyServerPassword(cmd["client_server_password"].string(), true)) return {findError("server_invalid_password"), "invalid server password"};
if(!this->server->verifyServerPassword(cmd["client_server_password"].string(), true))
return command_result{error::server_invalid_password};
size_t clones_uid = 0;
size_t clones_ip = 0;
@@ -496,17 +502,17 @@ CommandResult SpeakingClient::handleCommandClientInit(Command& cmd) {
if(permissions[permission::i_client_max_clones_uid] > 0 && clones_uid >= permissions[permission::i_client_max_clones_uid]) {
logMessage(this->getServerId(), "{} Disconnecting because there are already {} uid clones connected. (Allowed: {})", CLIENT_STR_LOG_PREFIX, clones_uid, permissions[permission::i_client_max_clones_uid]);
return {findError("client_too_many_clones_connected"), "too many clones connected (uid)"};
return command_result{error:: client_too_many_clones_connected, "too many clones connected (uid)"};
}
if(permissions[permission::i_client_max_clones_ip] > 0 && clones_ip >= permissions[permission::i_client_max_clones_ip]) {
logMessage(this->getServerId(), "{} Disconnecting because there are already {} ip clones connected. (Allowed: {})", CLIENT_STR_LOG_PREFIX, clones_ip, permissions[permission::i_client_max_clones_ip]);
return {findError("client_too_many_clones_connected"), "too many clones connected (ip)"};
return command_result{error:: client_too_many_clones_connected, "too many clones connected (ip)"};
}
if(permissions[permission::i_client_max_clones_hwid] > 0 && clones_hwid >= permissions[permission::i_client_max_clones_hwid] && !_own_hwid.empty()) {
logMessage(this->getServerId(), "{} Disconnecting because there are already {} hwid clones connected. (Allowed: {})", CLIENT_STR_LOG_PREFIX, clones_hwid, permissions[permission::i_client_max_clones_hwid]);
return {findError("client_too_many_clones_connected"), "too many clones connected (hwid)"};
return command_result{error:: client_too_many_clones_connected, "too many clones connected (hwid)"};
}
TIMING_STEP(timings, "max clones ");
@@ -560,7 +566,7 @@ CommandResult SpeakingClient::handleCommandClientInit(Command& cmd) {
} else time = "never";
fullReason += time + "!";
return {findError(0xD01), fullReason};
return command_result{error::server_connect_banned, fullReason};
}
TIMING_STEP(timings, "ban resolve");
@@ -577,9 +583,10 @@ CommandResult SpeakingClient::handleCommandClientInit(Command& cmd) {
bool allowReserved = permissions[permission::b_client_use_reserved_slot] != permNotGranted && permissions[permission::b_client_use_reserved_slot] != 0;
if(reserved > maxClients){
if(!allowReserved) return {findError("server_maxclients_reached"), "server max clients reached"};
if(!allowReserved)
return command_result{error::server_maxclients_reached};
} else if(maxClients - (allowReserved ? 0 : reserved) <= count)
return {findError("server_maxclients_reached"), "server max clients reached"};
return command_result{error::server_maxclients_reached};
TIMING_STEP(timings, "max clients");
@@ -613,7 +620,7 @@ CommandResult SpeakingClient::handleCommandClientInit(Command& cmd) {
});
debugMessage(this->getServerId(), "{} Client init timings: {}", CLIENT_STR_LOG_PREFIX, TIMING_FINISH(timings));
return CommandResult::Success;
return command_result{error::ok};
}
/* must be triggered while helding an execute lock */
@@ -666,7 +673,9 @@ void SpeakingClient::processJoin() {
TIMING_STEP(timings, "notify sini");
if(!ref_server->assignDefaultChannel(this->ref(), false)) {
this->notifyError({findError("vs_critical"), "Could not assign default channel!"});
auto result = command_result{error::vs_critical, "Could not assign default channel!"};
this->notifyError(result);
result.release_details();
this->closeConnection(system_clock::now() + seconds(1));
return;
}
@@ -776,19 +785,21 @@ void SpeakingClient::updateChannelClientProperties(bool channel_lock, bool notif
this->max_idle_time = this->permissionValueFlagged(permission::i_client_max_idletime, this->currentChannel);
}
CommandResult SpeakingClient::handleCommand(Command &command) {
command_result SpeakingClient::handleCommand(Command &command) {
if(this->connectionState() == ConnectionState::INIT_HIGH) {
if(this->handshake.state == HandshakeState::BEGIN || this->handshake.state == HandshakeState::IDENTITY_PROOF) {
CommandResult result;
command_result result;
if(command.command() == "handshakebegin")
result = this->handleCommandHandshakeBegin(command);
else if(command.command() == "handshakeindentityproof")
result = this->handleCommandHandshakeIdentityProof(command);
else
result = {findError("client_not_logged_in")};
result = command_result{error::client_not_logged_in};
if(!result)
this->closeConnection(system_clock::now() + seconds(1));
if(result.error_code())
this->postCommandHandler.push_back([&]{
this->closeConnection(system_clock::now() + seconds(1));
});
return result;
}
}