Merge remote-tracking branch 'itsRevela/main'
# Conflicts: # .github/workflows/nightly.yml # .gitignore # Minecraft.Client/ChatScreen.cpp # Minecraft.Client/ClientConnection.cpp # Minecraft.Client/Common/Audio/SoundEngine.cpp # Minecraft.Client/Common/Audio/SoundEngine.h # Minecraft.Client/Common/Media/MediaWindows64.arc # Minecraft.Client/Common/UI/IUIScene_HUD.cpp # Minecraft.Client/Common/UI/UIControl_Base.cpp # Minecraft.Client/Common/UI/UIScene_DeathMenu.cpp # Minecraft.Client/Common/UI/UIScene_JoinMenu.cpp # Minecraft.Client/Common/XUI/XUI_Chat.cpp # Minecraft.Client/Common/XUI/XUI_Death.cpp # Minecraft.Client/Font.cpp # Minecraft.Client/Gui.cpp # Minecraft.Client/PendingConnection.cpp # Minecraft.Client/PlayerConnection.cpp # Minecraft.Client/PlayerConnection.h # Minecraft.Client/PlayerList.cpp # Minecraft.Client/Windows64/Network/WinsockNetLayer.cpp # Minecraft.Client/Windows64/Network/WinsockNetLayer.h # Minecraft.Client/Windows64Media/strings.h # Minecraft.Client/cmake/sources/Common.cmake # Minecraft.Server/Console/ServerCliEngine.cpp # Minecraft.Server/Console/commands/whitelist/CliCommandWhitelist.cpp # Minecraft.Server/Windows64/ServerMain.cpp # Minecraft.World/WitherBoss.h # Minecraft.World/cmake/sources/Common.cmake # README.md
This commit is contained in:
@@ -17,7 +17,8 @@
|
||||
#if defined(_WINDOWS64) && defined(MINECRAFT_SERVER_BUILD)
|
||||
#include "../Minecraft.Server/ServerLogManager.h"
|
||||
#include "../Minecraft.Server/Access/Access.h"
|
||||
#include "../Minecraft.World/Socket.h"
|
||||
#include "..\Minecraft.Server/Security/SecurityConfig.h"
|
||||
#include "..\Minecraft.World\Socket.h"
|
||||
#endif
|
||||
// #ifdef __PS3__
|
||||
// #include "PS3/Network/NetworkPlayerSony.h"
|
||||
@@ -150,6 +151,20 @@ void PendingConnection::sendPreLoginResponse()
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(_WINDOWS64) && defined(MINECRAFT_SERVER_BUILD)
|
||||
// Security: strip real XUIDs from pre-login response to prevent unauthenticated enumeration.
|
||||
// The client receives the correct player count but cannot identify who is connected.
|
||||
// Real XUID data is sent post-login via PlayerInfoPacket broadcasts.
|
||||
if (ServerRuntime::Security::GetSettings().hidePlayerListPreLogin)
|
||||
{
|
||||
for (DWORD i = 0; i < ugcXuidCount; ++i)
|
||||
{
|
||||
ugcXuids[i] = INVALID_XUID;
|
||||
}
|
||||
ugcFriendsOnlyBits = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
if (false)// server->onlineMode) // 4J - removed
|
||||
{
|
||||
@@ -203,6 +218,56 @@ void PendingConnection::handleLogin(shared_ptr<LoginPacket> packet)
|
||||
duplicateXuid = true;
|
||||
}
|
||||
|
||||
#if defined(_WINDOWS64) && defined(MINECRAFT_SERVER_BUILD)
|
||||
// Cross-reference: if someone claims the same XUID as an existing player from a different IP,
|
||||
// log and reject as a potential spoofing attempt.
|
||||
// Note: this runs on the main tick thread (via PendingConnection::tick -> Connection::tick ->
|
||||
// handleLogin), same thread that mutates the player list, so no lock is needed.
|
||||
if (!duplicateXuid && loginXuid != INVALID_XUID)
|
||||
{
|
||||
std::string newIp;
|
||||
unsigned char newSmallId = GetPendingConnectionSmallId(connection);
|
||||
bool hasNewIp = ServerRuntime::ServerLogManager::TryGetConnectionRemoteIp(newSmallId, &newIp);
|
||||
|
||||
for (auto &existingPlayer : server->getPlayers()->players)
|
||||
{
|
||||
if (existingPlayer == nullptr) continue;
|
||||
PlayerUID existingXuid = existingPlayer->connection->m_offlineXUID;
|
||||
if (existingXuid == INVALID_XUID) existingXuid = existingPlayer->connection->m_onlineXUID;
|
||||
if (existingXuid == loginXuid)
|
||||
{
|
||||
if (hasNewIp)
|
||||
{
|
||||
std::string existingIp;
|
||||
INetworkPlayer *np = existingPlayer->connection->getNetworkPlayer();
|
||||
if (np != nullptr)
|
||||
{
|
||||
unsigned char existingSmallId = np->GetSmallId();
|
||||
if (ServerRuntime::ServerLogManager::TryGetConnectionRemoteIp(existingSmallId, &existingIp))
|
||||
{
|
||||
if (existingIp != newIp)
|
||||
{
|
||||
app.DebugPrintf("SECURITY: XUID spoofing suspected - XUID 0x%016llx claimed from IP %s while already connected from IP %s\n",
|
||||
(unsigned long long)loginXuid, newIp.c_str(), existingIp.c_str());
|
||||
ServerRuntime::ServerLogManager::OnXuidSpoofDetected(newSmallId, name, newIp.c_str(), existingIp.c_str());
|
||||
duplicateXuid = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Cannot verify IP -- treat same-XUID connection as suspicious
|
||||
app.DebugPrintf("SECURITY: XUID 0x%016llx claimed but could not verify source IP\n",
|
||||
(unsigned long long)loginXuid);
|
||||
duplicateXuid = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
bool bannedXuid = false;
|
||||
if (loginXuid != INVALID_XUID)
|
||||
{
|
||||
@@ -243,7 +308,11 @@ void PendingConnection::handleLogin(shared_ptr<LoginPacket> packet)
|
||||
else if (!whitelistSatisfied)
|
||||
{
|
||||
#if defined(_WINDOWS64) && defined(MINECRAFT_SERVER_BUILD)
|
||||
// Cache name->XUID so `whitelist add <name>` can resolve the XUID
|
||||
ServerRuntime::ServerLogManager::CachePlayerXuid(name, loginXuid);
|
||||
ServerRuntime::ServerLogManager::OnRejectedPlayerLogin(GetPendingConnectionSmallId(connection), name, ServerRuntime::ServerLogManager::eLoginRejectReason_NotWhitelisted);
|
||||
app.DebugPrintf("WHITELIST: Rejected %ls (XUID: 0x%016llx) - use 'whitelist add %ls' to allow\n",
|
||||
name.c_str(), (unsigned long long)loginXuid, name.c_str());
|
||||
#endif
|
||||
disconnect(DisconnectPacket::eDisconnect_Banned);
|
||||
}
|
||||
@@ -330,11 +399,17 @@ void PendingConnection::handleAcceptedLogin(shared_ptr<LoginPacket> packet)
|
||||
PlayerUID playerXuid = packet->m_offlineXuid;
|
||||
if(playerXuid == INVALID_XUID) playerXuid = packet->m_onlineXuid;
|
||||
|
||||
#if defined(_WINDOWS64) && defined(MINECRAFT_SERVER_BUILD)
|
||||
// Cache name->XUID for console commands (whitelist add, revoketoken, etc.)
|
||||
ServerRuntime::ServerLogManager::CachePlayerXuid(name, playerXuid);
|
||||
#endif
|
||||
|
||||
shared_ptr<ServerPlayer> playerEntity = server->getPlayers()->getPlayerForLogin(this, name, playerXuid,packet->m_onlineXuid);
|
||||
if (playerEntity != nullptr)
|
||||
{
|
||||
#if defined(_WINDOWS64) && defined(MINECRAFT_SERVER_BUILD)
|
||||
ServerRuntime::ServerLogManager::OnAcceptedPlayerLogin(GetPendingConnectionSmallId(connection), name);
|
||||
ServerRuntime::ServerLogManager::OnAcceptedPlayerLogin(GetPendingConnectionSmallId(connection), name,
|
||||
packet->m_offlineXuid, packet->m_onlineXuid, packet->m_isGuest);
|
||||
#endif
|
||||
server->getPlayers()->placeNewPlayer(connection, playerEntity, packet);
|
||||
connection = nullptr; // We've moved responsibility for this over to the new PlayerConnection, nullptr so we don't delete our reference to it here in our dtor
|
||||
|
||||
Reference in New Issue
Block a user