Fix race condition in BungeeCord

This commit is contained in:
games647
2016-05-13 18:54:08 +02:00
parent bfaf390463
commit 59703bac4e
6 changed files with 28 additions and 15 deletions

View File

@@ -2,7 +2,7 @@
* Make the configuration options also work under BungeeCord (premiumUUID, forwardSkin) * Make the configuration options also work under BungeeCord (premiumUUID, forwardSkin)
* Catch configuration loading exception if it's not spigot build * Catch configuration loading exception if it's not spigot build
* Fix config loading for older PaperSpigot builds * Fix config loading for older Spigot builds
######1.0 ######1.0

View File

@@ -12,7 +12,6 @@ import java.util.logging.Level;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.metadata.FixedMetadataValue;
public class ForceLoginTask implements Runnable { public class ForceLoginTask implements Runnable {
@@ -34,9 +33,6 @@ public class ForceLoginTask implements Runnable {
String id = '/' + player.getAddress().getAddress().getHostAddress() + ':' + player.getAddress().getPort(); String id = '/' + player.getAddress().getAddress().getHostAddress() + ':' + player.getAddress().getPort();
PlayerSession session = plugin.getSessions().get(id); PlayerSession session = plugin.getSessions().get(id);
//blacklist this target player for BungeeCord Id brute force attacks
player.setMetadata(plugin.getName(), new FixedMetadataValue(plugin, true));
BukkitAuthPlugin authPlugin = plugin.getAuthPlugin(); BukkitAuthPlugin authPlugin = plugin.getAuthPlugin();
Storage storage = plugin.getStorage(); Storage storage = plugin.getStorage();

View File

@@ -41,9 +41,11 @@ public class BukkitJoinListener implements Listener {
} }
} }
if (!plugin.isBungeeCord()) {
//Wait before auth plugin and we received a message from BungeeCord initializes the player //Wait before auth plugin and we received a message from BungeeCord initializes the player
Bukkit.getScheduler().runTaskLaterAsynchronously(plugin, new ForceLoginTask(plugin, player), DELAY_LOGIN); Bukkit.getScheduler().runTaskLaterAsynchronously(plugin, new ForceLoginTask(plugin, player), DELAY_LOGIN);
} }
}
@EventHandler @EventHandler
public void onPlayerQuit(PlayerQuitEvent quitEvent) { public void onPlayerQuit(PlayerQuitEvent quitEvent) {

View File

@@ -1,6 +1,7 @@
package com.github.games647.fastlogin.bukkit.listener; package com.github.games647.fastlogin.bukkit.listener;
import com.github.games647.fastlogin.bukkit.FastLoginBukkit; import com.github.games647.fastlogin.bukkit.FastLoginBukkit;
import com.github.games647.fastlogin.bukkit.ForceLoginTask;
import com.github.games647.fastlogin.bukkit.PlayerSession; import com.github.games647.fastlogin.bukkit.PlayerSession;
import com.github.games647.fastlogin.bukkit.hooks.BukkitAuthPlugin; import com.github.games647.fastlogin.bukkit.hooks.BukkitAuthPlugin;
import com.google.common.base.Charsets; import com.google.common.base.Charsets;
@@ -54,17 +55,24 @@ public class BungeeCordListener implements PluginMessageListener {
final Player checkedPlayer = plugin.getServer().getPlayerExact(playerName); final Player checkedPlayer = plugin.getServer().getPlayerExact(playerName);
//fail if target player is blacklisted because already authed or wrong bungeecord id //fail if target player is blacklisted because already authed or wrong bungeecord id
if (checkedPlayer != null && !checkedPlayer.hasMetadata(plugin.getName())) { if (checkedPlayer != null && !checkedPlayer.hasMetadata(plugin.getName())) {
//blacklist this target player for BungeeCord Id brute force attacks
player.setMetadata(plugin.getName(), new FixedMetadataValue(plugin, true));
//bungeecord UUID //bungeecord UUID
long mostSignificantBits = dataInput.readLong(); long mostSignificantBits = dataInput.readLong();
long leastSignificantBits = dataInput.readLong(); long leastSignificantBits = dataInput.readLong();
UUID sourceId = new UUID(mostSignificantBits, leastSignificantBits); UUID sourceId = new UUID(mostSignificantBits, leastSignificantBits);
plugin.getLogger().log(Level.FINEST, "Received proxy id {0} from {1}", new Object[]{sourceId, player});
//fail if BungeeCord support is disabled (id = null) //fail if BungeeCord support is disabled (id = null)
if (sourceId.equals(proxyId)) { if (sourceId.equals(proxyId)) {
final PlayerSession playerSession = new PlayerSession(playerName); final PlayerSession playerSession = new PlayerSession(playerName);
final String id = '/' + checkedPlayer.getAddress().getAddress().getHostAddress() + ':'
+ checkedPlayer.getAddress().getPort();
if ("AUTO_LOGIN".equalsIgnoreCase(subchannel)) { if ("AUTO_LOGIN".equalsIgnoreCase(subchannel)) {
playerSession.setVerified(true); playerSession.setVerified(true);
playerSession.setRegistered(true); playerSession.setRegistered(true);
plugin.getSessions().put(checkedPlayer.getAddress().toString(), playerSession); plugin.getSessions().put(id, playerSession);
} else if ("AUTO_REGISTER".equalsIgnoreCase(subchannel)) { } else if ("AUTO_REGISTER".equalsIgnoreCase(subchannel)) {
playerSession.setVerified(true); playerSession.setVerified(true);
@@ -75,7 +83,7 @@ public class BungeeCordListener implements PluginMessageListener {
try { try {
//we need to check if the player is registered on Bukkit too //we need to check if the player is registered on Bukkit too
if (authPlugin != null && !authPlugin.isRegistered(playerName)) { if (authPlugin != null && !authPlugin.isRegistered(playerName)) {
plugin.getSessions().put(checkedPlayer.getAddress().toString(), playerSession); plugin.getSessions().put(id, playerSession);
} }
} catch (Exception ex) { } catch (Exception ex) {
plugin.getLogger().log(Level.SEVERE, "Failed to query isRegistered", ex); plugin.getLogger().log(Level.SEVERE, "Failed to query isRegistered", ex);
@@ -83,9 +91,8 @@ public class BungeeCordListener implements PluginMessageListener {
} }
}); });
} }
} else {
//blacklist target for the current login Bukkit.getScheduler().runTaskAsynchronously(plugin, new ForceLoginTask(plugin, player));
checkedPlayer.setMetadata(plugin.getName(), new FixedMetadataValue(plugin, true));
} }
} }
} }

View File

@@ -13,10 +13,12 @@ public class ForceLoginTask implements Runnable {
private final FastLoginBungee plugin; private final FastLoginBungee plugin;
private final ProxiedPlayer player; private final ProxiedPlayer player;
private final Server server;
public ForceLoginTask(FastLoginBungee plugin, ProxiedPlayer player) { public ForceLoginTask(FastLoginBungee plugin, ProxiedPlayer player, Server server) {
this.plugin = plugin; this.plugin = plugin;
this.player = player; this.player = player;
this.server = server;
} }
@Override @Override
@@ -65,7 +67,6 @@ public class ForceLoginTask implements Runnable {
dataOutput.writeLong(proxyId.getMostSignificantBits()); dataOutput.writeLong(proxyId.getMostSignificantBits());
dataOutput.writeLong(proxyId.getLeastSignificantBits()); dataOutput.writeLong(proxyId.getLeastSignificantBits());
Server server = player.getServer();
if (server != null) { if (server != null) {
server.sendData(plugin.getDescription().getName(), dataOutput.toByteArray()); server.sendData(plugin.getDescription().getName(), dataOutput.toByteArray());
} }

View File

@@ -119,7 +119,8 @@ public class PlayerConnectionListener implements Listener {
@EventHandler @EventHandler
public void onServerConnected(ServerConnectedEvent serverConnectedEvent) { public void onServerConnected(ServerConnectedEvent serverConnectedEvent) {
ProxiedPlayer player = serverConnectedEvent.getPlayer(); ProxiedPlayer player = serverConnectedEvent.getPlayer();
ProxyServer.getInstance().getScheduler().runAsync(plugin, new ForceLoginTask(plugin, player)); ForceLoginTask loginTask = new ForceLoginTask(plugin, player, serverConnectedEvent.getServer());
ProxyServer.getInstance().getScheduler().runAsync(plugin, loginTask);
} }
@EventHandler @EventHandler
@@ -179,6 +180,9 @@ public class PlayerConnectionListener implements Listener {
playerProfile.setUuid(null); playerProfile.setUuid(null);
//todo: set uuid //todo: set uuid
plugin.getStorage().save(playerProfile); plugin.getStorage().save(playerProfile);
TextComponent textComponent = new TextComponent("Added to the list of premium players");
textComponent.setColor(ChatColor.DARK_GREEN);
forPlayer.sendMessage(textComponent);
} }
}); });
} else if ("SUCCESS".equals(subchannel)) { } else if ("SUCCESS".equals(subchannel)) {
@@ -190,6 +194,9 @@ public class PlayerConnectionListener implements Listener {
//we override this in the loginevent //we override this in the loginevent
// playerProfile.setUuid(forPlayer.getUniqueId()); // playerProfile.setUuid(forPlayer.getUniqueId());
plugin.getStorage().save(playerProfile); plugin.getStorage().save(playerProfile);
TextComponent textComponent = new TextComponent("Removed to the list of premium players");
textComponent.setColor(ChatColor.DARK_GREEN);
forPlayer.sendMessage(textComponent);
} }
} }
} }