diff --git a/code/components/voip-server-mumble/src/messagehandler.cpp b/code/components/voip-server-mumble/src/messagehandler.cpp index 2c36e886f6..6981d4f67c 100644 --- a/code/components/voip-server-mumble/src/messagehandler.cpp +++ b/code/components/voip-server-mumble/src/messagehandler.cpp @@ -721,6 +721,11 @@ void Mh_handle_message(client_t *client, message_t *msg) sendPermissionDenied(client, "Channel name too long"); break; } + /* Check description length */ + if (strlen(msg->payload.channelState->description().c_str()) > MAX_TEXT) { + sendPermissionDenied(client, "Description too long"); + break; + } parent = Chan_fromId(msg->payload.channelState->parent()); if (parent == NULL) diff --git a/code/components/voip-server-mumble/src/server.cpp b/code/components/voip-server-mumble/src/server.cpp index 8b8884bb04..b4826b75c2 100644 --- a/code/components/voip-server-mumble/src/server.cpp +++ b/code/components/voip-server-mumble/src/server.cpp @@ -296,6 +296,8 @@ static std::map mumblePairs; static std::mutex retryPairsMutex; static std::map retryPairs; +static std::map clientsPerIP; + extern std::recursive_mutex g_mumbleClientMutex; void Server_onFree(client_t* client) @@ -327,14 +329,34 @@ void CleanupMumblePairs() } } +static bool mumbleServerInitialized; + +static void EnsureServerInitialized() +{ + if (!mumbleServerInitialized) + { + Chan_init(); + Client_init(); + // Ban_init(); + mumbleServerInitialized = true; + } +} + +std::shared_ptr> mumble_disableServer; +std::shared_ptr> mumble_maxClientsPerIP; + static InitFunction initFunction([]() { - Chan_init(); - Client_init(); -// Ban_init(); + mumble_disableServer = std::make_shared>("mumble_disableServer", ConVar_None, false); + mumble_maxClientsPerIP = std::make_shared>("mumble_maxClientsPerIP", ConVar_None, 32); OnCreateTlsMultiplex.Connect([=](fwRefContainer multiplex) { + if (mumble_disableServer->GetValue()) + return; + + EnsureServerInitialized(); + auto server = multiplex->CreateServer([](const std::vector& bytes) { if (bytes.size() > 6) @@ -366,6 +388,24 @@ static InitFunction initFunction([]() { std::unique_lock lock(g_mumbleClientMutex); + auto hostIP = stream->GetPeerAddress().GetHost(); + auto mapEntry = clientsPerIP.find(hostIP); + if (mapEntry != clientsPerIP.end()) + { + auto maxClientCount = mumble_maxClientsPerIP->GetValue(); + if (mapEntry->second >= maxClientCount) + { + trace("IP %s already has %d Mumble connections active, rejecting client. This limit can be changed using the mumble_maxClientsPerIP ConVar.\n", + hostIP.c_str(), maxClientCount); + return; + } + mapEntry->second++; + } + else + { + clientsPerIP.insert({ hostIP, 1 }); + } + Client_add(stream, &client); } @@ -472,6 +512,11 @@ static InitFunction initFunction([]() stream->SetCloseCallback([=]() { std::unique_lock lock(g_mumbleClientMutex); + auto mapEntry = clientsPerIP.find(client->remote_tcp.GetHost()); + if (mapEntry->second == 1) + clientsPerIP.erase(mapEntry); + else + mapEntry->second--; Client_free(client); }); }); @@ -503,6 +548,11 @@ static InitFunction initFunction([]() fx::ServerInstanceBase::OnServerCreate.Connect([](fx::ServerInstanceBase* instance) { + if (mumble_disableServer->GetValue()) + return; + + EnsureServerInitialized(); + auto interceptor = instance->GetComponent(); interceptor->OnIntercept.Connect([interceptor](const net::PeerAddress& address, const uint8_t* data, size_t len, bool* intercepted)