Use username from Mojang for offline IDs

Affected systems: BungeeCord after name change
Effects: Carry on items, permissions, etc. from the old user account without access to the new one

After a name change it could happen that the client still only
knows the old username and will send it to the server. Mojang will provide us with an up-to-date username that we should use instead.

The username is also sent to Mojang, so that they could verify the use. Therefore exploiting this behavior extensively for arbitrary usernames is not possible.

Related #344
This commit is contained in:
games647 committed 2020-05-25 13:41:41 +02:00
1 parent 286b755ee3
commit 2bd339b0bf
5 files changed
+51 -34

No files matched your search

@@ -94,30 +94,36 @@ public class VerifyResponseTask implements Runnable {
String serverId = EncryptionUtil.getServerIdHashString("", loginKey, serverKey.getPublic());
String username = session.getUsername();
String requestedUsername = session.getRequestUsername();
InetSocketAddress socketAddress = player.getAddress();
try {
MojangResolver resolver = plugin.getCore().getResolver();
InetAddress address = socketAddress.getAddress();
Optional<Verification> response = resolver.hasJoined(username, serverId, address);
Optional<Verification> response = resolver.hasJoined(requestedUsername, serverId, address);
if (response.isPresent()) {
plugin.getLog().info("GameProfile {} has a verified premium account", username);
plugin.getLog().info("GameProfile {} has a verified premium account", requestedUsername);
String realUsername = response.get().getName();
if (realUsername == null) {
disconnect("invalid-session", true, "Username field null for {}", requestedUsername);
return;
}
SkinProperty[] properties = response.get().getProperties();
if (properties.length > 0) {
session.setSkinProperty(properties[0]);
}
session.setVerifiedUsername(realUsername);
session.setUuid(response.get().getId());
session.setVerified(true);
setPremiumUUID(session.getUuid());
receiveFakeStartPacket(username);
receiveFakeStartPacket(realUsername);
} else {
//user tried to fake a authentication
disconnect("invalid-session", true
, "GameProfile {0} ({1}) tried to log in with an invalid session ServerId: {2}"
, session.getUsername(), socketAddress, serverId);
, session.getRequestUsername(), socketAddress, serverId);
}
} catch (IOException ioEx) {
disconnect("error-kick", false, "Failed to connect to session server", ioEx);
@@ -146,7 +152,7 @@ public class VerifyResponseTask implements Runnable {
//check if the verify token are equal to the server sent one
disconnect("invalid-verify-token", true
, "GameProfile {0} ({1}) tried to login with an invalid verify token. Server: {2} Client: {3}"
, session.getUsername(), packetEvent.getPlayer().getAddress(), requestVerify, responseVerify);
, session.getRequestUsername(), packetEvent.getPlayer().getAddress(), requestVerify, responseVerify);
return false;
}
@@ -92,9 +92,6 @@ public class ProtocolSupportListener extends JoinManagement<Player, CommandSende
BukkitLoginSession playerSession = new BukkitLoginSession(username, registered, profile);
plugin.putSession(source.getAddress(), playerSession);
if (plugin.getConfig().getBoolean("premiumUuid")) {
source.getLoginStartEvent().setOnlineMode(true);
}
}
@Override
@@ -31,6 +31,12 @@ public class ForceLoginTask extends ForceLoginManagement<Player, CommandSender,
FastLoginBukkit plugin = core.getPlugin();
player.setMetadata(core.getPlugin().getName(), new FixedMetadataValue(plugin, true));
if (session != null && !session.getUsername().equals(player.getName())) {
String playerName = player.getName();
plugin.getLog().warn("Player username {} is not matching session {}", playerName, session.getUsername());
return;
}
super.run();
PremiumStatus status = PremiumStatus.CRACKED;
@@ -73,10 +79,6 @@ public class ForceLoginTask extends ForceLoginManagement<Player, CommandSender,
@Override
public boolean isOnlineMode() {
if (session == null) {
return false;
}
return session.isVerified() && player.getName().equals(session.getUsername());
return session.isVerified();
}
}