Don't rely on toString to build unique session keys

Fix IPv6 compatibility which contains brackets

Related #331
This commit is contained in:
games647
2020-04-25 17:02:52 +02:00
parent 6f99b6e9b4
commit 6091a228ab
10 changed files with 37 additions and 28 deletions

View File

@ -18,6 +18,7 @@ import com.github.games647.fastlogin.core.shared.PlatformPlugin;
import com.google.common.io.ByteArrayDataOutput;
import com.google.common.io.ByteStreams;
import java.net.InetSocketAddress;
import java.nio.file.Path;
import java.util.Map;
import java.util.UUID;
@ -145,6 +146,21 @@ public class FastLoginBukkit extends JavaPlugin implements PlatformPlugin<Comman
return loginSession;
}
public BukkitLoginSession getSession(InetSocketAddress addr) {
String id = addr.getAddress().getHostAddress() + ':' + addr.getPort();
return loginSession.get(id);
}
public void putSession(InetSocketAddress addr, BukkitLoginSession session) {
String id = addr.getAddress().getHostAddress() + ':' + addr.getPort();
loginSession.put(id, session);
}
public void removeSession(InetSocketAddress addr) {
String id = addr.getAddress().getHostAddress() + ':' + addr.getPort();
loginSession.remove(id);
}
public Map<UUID, PremiumStatus> getPremiumPlayers() {
return premiumPlayers;
}

View File

@ -33,8 +33,7 @@ public class AuthMeHook implements AuthPlugin<Player>, Listener {
public void onSessionRestore(RestoreSessionEvent restoreSessionEvent) {
Player player = restoreSessionEvent.getPlayer();
String id = '/' + player.getAddress().getAddress().getHostAddress() + ':' + player.getAddress().getPort();
BukkitLoginSession session = plugin.getLoginSessions().get(id);
BukkitLoginSession session = plugin.getSession(player.getAddress());
if (session != null && session.isVerified()) {
restoreSessionEvent.setCancelled(true);
}

View File

@ -78,11 +78,10 @@ public class BungeeListener implements PluginMessageListener {
Type type = message.getType();
InetSocketAddress address = player.getAddress();
String id = '/' + address.getAddress().getHostAddress() + ':' + address.getPort();
if (type == Type.LOGIN) {
BukkitLoginSession playerSession = new BukkitLoginSession(playerName, true);
playerSession.setVerified(true);
plugin.getLoginSessions().put(id, playerSession);
plugin.putSession(address, playerSession);
Bukkit.getScheduler().runTaskLaterAsynchronously(plugin, new ForceLoginTask(plugin.getCore(), player), 10L);
} else if (type == Type.REGISTER) {
@ -93,7 +92,7 @@ public class BungeeListener implements PluginMessageListener {
if (authPlugin == null || !authPlugin.isRegistered(playerName)) {
BukkitLoginSession playerSession = new BukkitLoginSession(playerName, false);
playerSession.setVerified(true);
plugin.getLoginSessions().put(id, playerSession);
plugin.putSession(address, playerSession);
new ForceLoginTask(plugin.getCore(), player).run();
}
} catch (Exception ex) {

View File

@ -7,11 +7,11 @@ import com.github.games647.fastlogin.bukkit.FastLoginBukkit;
import com.github.games647.fastlogin.bukkit.event.BukkitFastLoginPreLoginEvent;
import com.github.games647.fastlogin.core.StoredProfile;
import com.github.games647.fastlogin.core.shared.JoinManagement;
import com.github.games647.fastlogin.core.shared.event.FastLoginPreLoginEvent;
import java.security.PublicKey;
import java.util.Random;
import com.github.games647.fastlogin.core.shared.event.FastLoginPreLoginEvent;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
@ -74,7 +74,7 @@ public class NameCheckTask extends JoinManagement<Player, CommandSender, Protoco
byte[] verify = source.getVerifyToken();
BukkitLoginSession playerSession = new BukkitLoginSession(username, serverId, verify, registered, profile);
plugin.getLoginSessions().put(player.getAddress().toString(), playerSession);
plugin.putSession(player.getAddress(), playerSession);
//cancel only if the player has a paid account otherwise login as normal offline player
synchronized (packetEvent.getAsyncMarker().getProcessingLock()) {
packetEvent.setCancelled(true);
@ -84,6 +84,6 @@ public class NameCheckTask extends JoinManagement<Player, CommandSender, Protoco
@Override
public void startCrackedSession(ProtocolLibLoginSource source, StoredProfile profile, String username) {
BukkitLoginSession loginSession = new BukkitLoginSession(username, profile);
plugin.getLoginSessions().put(player.getAddress().toString(), loginSession);
plugin.putSession(player.getAddress(), loginSession);
}
}

View File

@ -74,7 +74,7 @@ public class ProtocolLibListener extends PacketAdapter {
String sessionKey = player.getAddress().toString();
//remove old data every time on a new login in order to keep the session only for one person
plugin.getLoginSessions().remove(sessionKey);
plugin.removeSession(player.getAddress());
//player.getName() won't work at this state
PacketContainer packet = packetEvent.getPacket();

View File

@ -40,7 +40,7 @@ public class SkinApplyListener implements Listener {
Player player = loginEvent.getPlayer();
if (plugin.getConfig().getBoolean("forwardSkin")) {
//go through every session, because player.getAddress is null
//go through every session, because player.getAddress is null
//loginEvent.getAddress is just a InetAddress not InetSocketAddress, so not unique enough
for (BukkitLoginSession session : plugin.getLoginSessions().values()) {
if (session.getUsername().equals(player.getName())) {

View File

@ -57,7 +57,7 @@ public class VerifyResponseTask implements Runnable {
@Override
public void run() {
try {
BukkitLoginSession session = plugin.getLoginSessions().get(player.getAddress().toString());
BukkitLoginSession session = plugin.getSession(player.getAddress());
if (session == null) {
disconnect("invalid-request", true
, "GameProfile {0} tried to send encryption response at invalid state", player.getAddress());

View File

@ -6,11 +6,11 @@ import com.github.games647.fastlogin.bukkit.FastLoginBukkit;
import com.github.games647.fastlogin.bukkit.event.BukkitFastLoginPreLoginEvent;
import com.github.games647.fastlogin.core.StoredProfile;
import com.github.games647.fastlogin.core.shared.JoinManagement;
import com.github.games647.fastlogin.core.shared.event.FastLoginPreLoginEvent;
import java.net.InetSocketAddress;
import java.util.Optional;
import com.github.games647.fastlogin.core.shared.event.FastLoginPreLoginEvent;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
@ -40,7 +40,7 @@ public class ProtocolSupportListener extends JoinManagement<Player, CommandSende
InetSocketAddress address = loginStartEvent.getAddress();
//remove old data every time on a new login in order to keep the session only for one person
plugin.getLoginSessions().remove(address.toString());
plugin.removeSession(address);
super.onLogin(username, new ProtocolLoginSource(loginStartEvent));
}
@ -48,13 +48,13 @@ public class ProtocolSupportListener extends JoinManagement<Player, CommandSende
@EventHandler
public void onConnectionClosed(ConnectionCloseEvent closeEvent) {
InetSocketAddress address = closeEvent.getConnection().getAddress();
plugin.getLoginSessions().remove(address.toString());
plugin.removeSession(address);
}
@EventHandler
public void onPropertiesResolve(PlayerProfileCompleteEvent profileCompleteEvent) {
InetSocketAddress address = profileCompleteEvent.getAddress();
BukkitLoginSession session = plugin.getLoginSessions().get(address.toString());
BukkitLoginSession session = plugin.getSession(address);
if (session != null && profileCompleteEvent.getConnection().getProfile().isOnlineMode()) {
session.setVerified(true);
@ -83,7 +83,7 @@ public class ProtocolSupportListener extends JoinManagement<Player, CommandSende
plugin.getCore().getPendingLogin().put(ip + username, new Object());
BukkitLoginSession playerSession = new BukkitLoginSession(username, registered, profile);
plugin.getLoginSessions().put(source.getAddress().toString(), playerSession);
plugin.putSession(source.getAddress(), playerSession);
if (plugin.getConfig().getBoolean("premiumUuid")) {
source.getLoginStartEvent().setOnlineMode(true);
}
@ -92,6 +92,6 @@ public class ProtocolSupportListener extends JoinManagement<Player, CommandSende
@Override
public void startCrackedSession(ProtocolLoginSource source, StoredProfile profile, String username) {
BukkitLoginSession loginSession = new BukkitLoginSession(username, profile);
plugin.getLoginSessions().put(source.getAddress().toString(), loginSession);
plugin.putSession(source.getAddress(), loginSession);
}
}

View File

@ -9,10 +9,10 @@ import com.github.games647.fastlogin.core.message.SuccessMessage;
import com.github.games647.fastlogin.core.shared.FastLoginCore;
import com.github.games647.fastlogin.core.shared.ForceLoginManagement;
import com.github.games647.fastlogin.core.shared.LoginSession;
import com.github.games647.fastlogin.core.shared.event.FastLoginAutoLoginEvent;
import java.util.concurrent.ExecutionException;
import com.github.games647.fastlogin.core.shared.event.FastLoginAutoLoginEvent;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
@ -21,13 +21,7 @@ import org.bukkit.metadata.FixedMetadataValue;
public class ForceLoginTask extends ForceLoginManagement<Player, CommandSender, BukkitLoginSession, FastLoginBukkit> {
public ForceLoginTask(FastLoginCore<Player, CommandSender, FastLoginBukkit> core, Player player) {
super(core, player, getSession(core.getPlugin(), player));
}
private static BukkitLoginSession getSession(FastLoginBukkit plugin, Player player) {
//remove the bungeecord identifier if there is ones
String id = '/' + player.getAddress().getAddress().getHostAddress() + ':' + player.getAddress().getPort();
return plugin.getLoginSessions().remove(id);
super(core, player, core.getPlugin().getSession(player.getAddress()));
}
@Override

View File

@ -74,8 +74,9 @@ public class ConnectListener implements Listener {
try {
UUID offlineUUID = UUIDAdapter.generateOfflineId(username);
//bungeecord doesn't support overriding the premium uuid
//so we have to do it with reflection
// BungeeCord only allows setting the UUID in PreLogin events and before requesting online mode
// However if online mode is requested, it will override previous values
// So we have to do it with reflection
Field idField = InitialHandler.class.getDeclaredField("uniqueId");
idField.setAccessible(true);
idField.set(connection, offlineUUID);
@ -85,7 +86,7 @@ public class ConnectListener implements Listener {
}
if (!plugin.getCore().getConfig().get("forwardSkin", true)) {
//this is null on offline mode
// this is null on offline mode
LoginResult loginProfile = initialHandler.getLoginProfile();
if (loginProfile != null) {
loginProfile.setProperties(emptyProperties);