A lot of updates

This commit is contained in:
WolverinDEV 2019-08-20 13:42:22 +02:00
commit 7c490d2180

View File

@ -125,180 +125,180 @@ CommandResult QueryClient::handleCommandExit(Command &) {
//login client_login_name=andreas client_login_password=meinPW //login client_login_name=andreas client_login_password=meinPW
CommandResult QueryClient::handleCommandLogin(Command& cmd) { CommandResult QueryClient::handleCommandLogin(Command& cmd) {
CMD_RESET_IDLE; CMD_RESET_IDLE;
std::string username, password; std::string username, password;
if(cmd[0].has("client_login_name") && cmd[0].has("client_login_password")){ if(cmd[0].has("client_login_name") && cmd[0].has("client_login_password")){
username = cmd["client_login_name"].string(); username = cmd["client_login_name"].string();
password = cmd["client_login_password"].string(); password = cmd["client_login_password"].string();
} else { } else {
username = cmd[0][0].key(); username = cmd[0][0].key();
password = cmd[0][1].key(); password = cmd[0][1].key();
} }
debugMessage("Attempted query login with " + username + " - " + password); debugMessage("Attempted query login with " + username + " - " + password);
auto _account = serverInstance->getQueryServer()->find_query_account_by_name(username); auto _account = serverInstance->getQueryServer()->find_query_account_by_name(username);
auto account = _account ? serverInstance->getQueryServer()->load_password(_account) : nullptr; auto account = _account ? serverInstance->getQueryServer()->load_password(_account) : nullptr;
{ {
threads::MutexLock lock(this->handle->loginLock); threads::MutexLock lock(this->handle->loginLock);
if(!account) if(!account)
return {findError("client_invalid_password"), "username or password dose not match"}; return {findError("client_invalid_password"), "username or password dose not match"};
if (account->password != password) { if (account->password != password) {
if(!this->whitelisted) { if(!this->whitelisted) {
this->handle->loginAttempts[this->getPeerIp()]++; this->handle->loginAttempts[this->getPeerIp()]++;
if(this->handle->loginAttempts[this->getPeerIp()] > 3) { if(this->handle->loginAttempts[this->getPeerIp()] > 3) {
this->handle->queryBann[this->getPeerIp()] = system_clock::now() + seconds(serverInstance->properties()[property::SERVERINSTANCE_SERVERQUERY_BAN_TIME].as<uint64_t>()); //TODO configurable | Disconnect all others? this->handle->queryBann[this->getPeerIp()] = system_clock::now() + seconds(serverInstance->properties()[property::SERVERINSTANCE_SERVERQUERY_BAN_TIME].as<uint64_t>()); //TODO configurable | Disconnect all others?
this->postCommandHandler.emplace_back([&](){ this->postCommandHandler.emplace_back([&](){
this->closeConnection(system_clock::now() + seconds(1)); this->closeConnection(system_clock::now() + seconds(1));
}); });
return {findError("ban_flooding"), ""}; return {findError("ban_flooding"), ""};
} }
} }
return {findError("client_invalid_password"), "username or password dose not match"}; return {findError("client_invalid_password"), "username or password dose not match"};
} }
} }
if(!this->properties()[property::CLIENT_LOGIN_NAME].as<string>().empty()) { if(!this->properties()[property::CLIENT_LOGIN_NAME].as<string>().empty()) {
Command log("logout"); Command log("logout");
if(!this->handleCommandLogout(log)) return {ErrorType::VSError, "Failed to logout!"}; if(!this->handleCommandLogout(log)) return {ErrorType::VSError, "Failed to logout!"};
} }
this->query_account = account; this->query_account = account;
auto joined_channel = this->currentChannel; auto joined_channel = this->currentChannel;
if(this->server) { if(this->server) {
{ {
unique_lock tree_lock(this->server->channel_tree_lock); unique_lock tree_lock(this->server->channel_tree_lock);
if(joined_channel) if(joined_channel)
this->server->client_move(this->ref(), nullptr, nullptr, "", ViewReasonId::VREASON_USER_ACTION, false, tree_lock); this->server->client_move(this->ref(), nullptr, nullptr, "", ViewReasonId::VREASON_USER_ACTION, false, tree_lock);
this->server->unregisterClient(_this.lock(), "login", tree_lock); this->server->unregisterClient(_this.lock(), "login", tree_lock);
} }
this->server->groups->disableCache(_this.lock()); this->server->groups->disableCache(_this.lock());
} else serverInstance->getGroupManager()->disableCache(_this.lock()); } else serverInstance->getGroupManager()->disableCache(_this.lock());
logMessage(LOG_QUERY, "Got new authenticated client. Username: {}, Unique-ID: {}, Bounded Server: {}", account->username, account->unique_id, account->bound_server); logMessage(LOG_QUERY, "Got new authenticated client. Username: {}, Unique-ID: {}, Bounded Server: {}", account->username, account->unique_id, account->bound_server);
this->properties()[property::CLIENT_LOGIN_NAME] = username; this->properties()[property::CLIENT_LOGIN_NAME] = username;
this->properties()[property::CLIENT_UNIQUE_IDENTIFIER] = account->unique_id; //TODO load from table this->properties()[property::CLIENT_UNIQUE_IDENTIFIER] = account->unique_id; //TODO load from table
this->properties()[property::CLIENT_NICKNAME] = username; this->properties()[property::CLIENT_NICKNAME] = username;
auto target_server = this->server; /* keep the server alive 'ill we've joined the server */ auto target_server = this->server; /* keep the server alive 'ill we've joined the server */
if(account->bound_server) { if(account->bound_server) {
target_server = serverInstance->getVoiceServerManager()->findServerById(account->bound_server); target_server = serverInstance->getVoiceServerManager()->findServerById(account->bound_server);
if(target_server != this->server) if(target_server != this->server)
joined_channel = nullptr; joined_channel = nullptr;
if(!target_server) if(!target_server)
return {findError("server_invalid_id"), "server does not exists anymore"}; return {findError("server_invalid_id"), "server does not exists anymore"};
} }
this->server = target_server; this->server = target_server;
DatabaseHelper::assignDatabaseId(this->sql, static_cast<ServerId>(target_server ? target_server->getServerId() : 0), _this.lock()); DatabaseHelper::assignDatabaseId(this->sql, static_cast<ServerId>(target_server ? target_server->getServerId() : 0), _this.lock());
if(target_server) { if(target_server) {
target_server->groups->enableCache(_this.lock()); target_server->groups->enableCache(_this.lock());
target_server->registerClient(_this.lock()); target_server->registerClient(_this.lock());
{ {
shared_lock server_tree_lock(target_server->channel_tree_lock); shared_lock server_tree_lock(target_server->channel_tree_lock);
if(joined_channel) /* needs only notify if we were already on that server within a channel */ if(joined_channel) /* needs only notify if we were already on that server within a channel */
target_server->notifyClientPropertyUpdates(_this.lock(), deque<property::ClientProperties>{property::CLIENT_NICKNAME, property::CLIENT_UNIQUE_IDENTIFIER}); target_server->notifyClientPropertyUpdates(_this.lock(), deque<property::ClientProperties>{property::CLIENT_NICKNAME, property::CLIENT_UNIQUE_IDENTIFIER});
unique_lock client_tree_lock(this->channel_lock); unique_lock client_tree_lock(this->channel_lock);
this->channels->reset(); this->channels->reset();
this->channels->insert_channels(target_server->channelTree->tree_head(), true, false); this->channels->insert_channels(target_server->channelTree->tree_head(), true, false);
this->subscribeChannel(this->server->channelTree->channels(), false, false); this->subscribeChannel(this->server->channelTree->channels(), false, false);
} }
if(joined_channel) { if(joined_channel) {
unique_lock tree_lock(this->server->channel_tree_lock); unique_lock tree_lock(this->server->channel_tree_lock);
if(joined_channel) if(joined_channel)
this->server->client_move(this->ref(), joined_channel, nullptr, "", ViewReasonId::VREASON_USER_ACTION, false, tree_lock); this->server->client_move(this->ref(), joined_channel, nullptr, "", ViewReasonId::VREASON_USER_ACTION, false, tree_lock);
} else if(!this->permissionGranted(permission::PERMTEST_ORDERED, permission::b_virtualserver_select_godmode, 1)) } else if(!this->permissionGranted(permission::PERMTEST_ORDERED, permission::b_virtualserver_select_godmode, 1))
this->server->assignDefaultChannel(this->ref(), true); this->server->assignDefaultChannel(this->ref(), true);
else else
this->update_cached_permissions(); this->update_cached_permissions();
} else { } else {
serverInstance->getGroupManager()->enableCache(_this.lock()); serverInstance->getGroupManager()->enableCache(_this.lock());
this->update_cached_permissions(); this->update_cached_permissions();
} }
this->properties()[property::CLIENT_TOTALCONNECTIONS]++; this->properties()[property::CLIENT_TOTALCONNECTIONS]++;
this->updateChannelClientProperties(true, true); this->updateChannelClientProperties(true, true);
return CommandResult::Success; return CommandResult::Success;
} }
CommandResult QueryClient::handleCommandLogout(Command &) { CommandResult QueryClient::handleCommandLogout(Command &) {
CMD_RESET_IDLE; CMD_RESET_IDLE;
if(this->properties()[property::CLIENT_LOGIN_NAME].as<string>().empty()) return {findError("client_not_logged_in"), "not logged in"}; if(this->properties()[property::CLIENT_LOGIN_NAME].as<string>().empty()) return {findError("client_not_logged_in"), "not logged in"};
this->properties()[property::CLIENT_LOGIN_NAME] = ""; this->properties()[property::CLIENT_LOGIN_NAME] = "";
this->query_account = nullptr; this->query_account = nullptr;
auto joined = this->currentChannel; auto joined = this->currentChannel;
if(this->server){ if(this->server){
{ {
unique_lock tree_lock(this->server->channel_tree_lock); unique_lock tree_lock(this->server->channel_tree_lock);
if(joined) if(joined)
this->server->client_move(this->ref(), nullptr, nullptr, "", ViewReasonId::VREASON_USER_ACTION, false, tree_lock); this->server->client_move(this->ref(), nullptr, nullptr, "", ViewReasonId::VREASON_USER_ACTION, false, tree_lock);
this->server->unregisterClient(_this.lock(), "logout", tree_lock); this->server->unregisterClient(_this.lock(), "logout", tree_lock);
} }
this->server->groups->disableCache(_this.lock()); this->server->groups->disableCache(_this.lock());
} else serverInstance->getGroupManager()->disableCache(_this.lock()); } else serverInstance->getGroupManager()->disableCache(_this.lock());
this->properties()[property::CLIENT_UNIQUE_IDENTIFIER] = "UnknownQuery"; //TODO load from table this->properties()[property::CLIENT_UNIQUE_IDENTIFIER] = "UnknownQuery"; //TODO load from table
this->properties()[property::CLIENT_NICKNAME] = string() + "ServerQuery#" + this->getLoggingPeerIp() + "/" + to_string(ntohs(this->getPeerPort())); this->properties()[property::CLIENT_NICKNAME] = string() + "ServerQuery#" + this->getLoggingPeerIp() + "/" + to_string(ntohs(this->getPeerPort()));
DatabaseHelper::assignDatabaseId(this->sql, static_cast<ServerId>(this->server ? this->server->getServerId() : 0), _this.lock()); DatabaseHelper::assignDatabaseId(this->sql, static_cast<ServerId>(this->server ? this->server->getServerId() : 0), _this.lock());
if(this->server){ if(this->server){
this->server->groups->enableCache(_this.lock()); this->server->groups->enableCache(_this.lock());
this->server->registerClient(this->ref()); this->server->registerClient(this->ref());
{ {
shared_lock server_channel_r_lock(this->server->channel_tree_lock); shared_lock server_channel_r_lock(this->server->channel_tree_lock);
unique_lock client_channel_lock(this->channel_lock); unique_lock client_channel_lock(this->channel_lock);
this->channels->reset(); this->channels->reset();
this->channels->insert_channels(this->server->channelTree->tree_head(), true, false); this->channels->insert_channels(this->server->channelTree->tree_head(), true, false);
this->subscribeChannel(this->server->channelTree->channels(), false, false); this->subscribeChannel(this->server->channelTree->channels(), false, false);
} }
if(joined) { if(joined) {
unique_lock server_channel_w_lock(this->server->channel_tree_lock, defer_lock); unique_lock server_channel_w_lock(this->server->channel_tree_lock, defer_lock);
this->server->client_move(this->ref(), joined, nullptr, "", ViewReasonId::VREASON_USER_ACTION, false, server_channel_w_lock); this->server->client_move(this->ref(), joined, nullptr, "", ViewReasonId::VREASON_USER_ACTION, false, server_channel_w_lock);
} else if(!this->permissionGranted(permission::PERMTEST_ORDERED, permission::b_virtualserver_select_godmode, 1)) { } else if(!this->permissionGranted(permission::PERMTEST_ORDERED, permission::b_virtualserver_select_godmode, 1)) {
this->server->assignDefaultChannel(this->ref(), true); this->server->assignDefaultChannel(this->ref(), true);
} else { } else {
this->update_cached_permissions(); this->update_cached_permissions();
} }
} else { } else {
serverInstance->getGroupManager()->enableCache(_this.lock()); serverInstance->getGroupManager()->enableCache(_this.lock());
this->update_cached_permissions(); this->update_cached_permissions();
} }
this->updateChannelClientProperties(true, true); this->updateChannelClientProperties(true, true);
return CommandResult::Success; return CommandResult::Success;
} }
CommandResult QueryClient::handleCommandServerSelect(Command &cmd) { CommandResult QueryClient::handleCommandServerSelect(Command &cmd) {
CMD_RESET_IDLE; CMD_RESET_IDLE;
shared_ptr<TSServer> target; shared_ptr<TSServer> target;
if(cmd[0].has("port")){ if(cmd[0].has("port")){
target = serverInstance->getVoiceServerManager()->findServerByPort(cmd["port"].as<uint16_t>()); target = serverInstance->getVoiceServerManager()->findServerByPort(cmd["port"].as<uint16_t>());
} else if(cmd[0].has("sid")) { } else if(cmd[0].has("sid")) {
target = serverInstance->getVoiceServerManager()->findServerById(cmd["sid"].as<ServerId>()); target = serverInstance->getVoiceServerManager()->findServerById(cmd["sid"].as<ServerId>());
} }
for(auto& parm : cmd[0].keys()) for(auto& parm : cmd[0].keys())
if(parm.find_first_not_of("0123456789") == string::npos) if(parm.find_first_not_of("0123456789") == string::npos)
target = serverInstance->getVoiceServerManager()->findServerById(static_cast<ServerId>(stol(parm))); target = serverInstance->getVoiceServerManager()->findServerById(static_cast<ServerId>(stol(parm)));
if(!target && (!cmd[0].has("0") && (!cmd[0].has("sid") || !cmd["sid"] == 0))) return {findError("server_invalid_id"), "Invalid server id"}; if(!target && (!cmd[0].has("0") && (!cmd[0].has("sid") || !cmd["sid"] == 0))) return {findError("server_invalid_id"), "Invalid server id"};
if(target == this->server) return CommandResult::Success; if(target == this->server) return CommandResult::Success;
if(target) { if(target) {
if(this->query_account && this->query_account->bound_server > 0) { if(this->query_account && this->query_account->bound_server > 0) {
@ -325,9 +325,9 @@ CommandResult QueryClient::handleCommandServerSelect(Command &cmd) {
} else } else
serverInstance->getGroupManager()->disableCache(_this.lock()); serverInstance->getGroupManager()->disableCache(_this.lock());
} }
this->resetEventMask(); this->resetEventMask();
//register at current server //register at current server
{ {
//unique_lock server_lock(this->server_lock); //unique_lock server_lock(this->server_lock);
/* We dont need to lock the server because only one command can be executed at the time. Everything else should copy the server once and test the copy and use that ref then */ /* We dont need to lock the server because only one command can be executed at the time. Everything else should copy the server once and test the copy and use that ref then */
@ -337,32 +337,32 @@ CommandResult QueryClient::handleCommandServerSelect(Command &cmd) {
if(cmd[0].has("client_nickname")) if(cmd[0].has("client_nickname"))
this->properties()[property::CLIENT_NICKNAME] = cmd["client_nickname"].string(); this->properties()[property::CLIENT_NICKNAME] = cmd["client_nickname"].string();
DatabaseHelper::assignDatabaseId(this->sql, static_cast<ServerId>(this->server ? this->server->getServerId() : 0), _this.lock()); DatabaseHelper::assignDatabaseId(this->sql, static_cast<ServerId>(this->server ? this->server->getServerId() : 0), _this.lock());
if(this->server) { if(this->server) {
this->server->groups->enableCache(_this.lock()); this->server->groups->enableCache(_this.lock());
this->server->registerClient(_this.lock()); this->server->registerClient(_this.lock());
{ {
shared_lock server_channel_lock(target->channel_tree_lock); shared_lock server_channel_lock(target->channel_tree_lock);
unique_lock client_channel_lock(this->channel_lock); unique_lock client_channel_lock(this->channel_lock);
this->subscribeToAll = true; this->subscribeToAll = true;
this->channels->insert_channels(this->server->channelTree->tree_head(), true, false); this->channels->insert_channels(this->server->channelTree->tree_head(), true, false);
this->subscribeChannel(this->server->channelTree->channels(), false, false); this->subscribeChannel(this->server->channelTree->channels(), false, false);
} }
auto negated_enforce_join = this->permissionGranted(permission::PERMTEST_ORDERED, permission::b_virtualserver_select_godmode, 1); auto negated_enforce_join = this->permissionGranted(permission::PERMTEST_ORDERED, permission::b_virtualserver_select_godmode, 1);
if(!negated_enforce_join) if(!negated_enforce_join)
this->server->assignDefaultChannel(this->ref(), true); this->server->assignDefaultChannel(this->ref(), true);
else else
this->update_cached_permissions(); this->update_cached_permissions();
} else { } else {
serverInstance->getGroupManager()->enableCache(_this.lock()); serverInstance->getGroupManager()->enableCache(_this.lock());
this->update_cached_permissions(); this->update_cached_permissions();
} }
this->updateChannelClientProperties(true, true); this->updateChannelClientProperties(true, true);
return CommandResult::Success; return CommandResult::Success;
} }
CommandResult QueryClient::handleCommandJoin(Command &) { CommandResult QueryClient::handleCommandJoin(Command &) {