From 400038265b0c3193a51a8490b41479b5aca54b2e Mon Sep 17 00:00:00 2001 From: Jerom van der Sar Date: Sun, 6 Sep 2015 17:02:06 +0200 Subject: [PATCH] Prevent command arguments from using long number strings. Resolves #782 Mass format --- buildnumber.properties | 4 +- .../TotalFreedomMod/TFM_CommandBlocker.java | 39 ++++-- .../TotalFreedomMod/TFM_PlayerList.java | 85 ++++++++---- .../TotalFreedomMod/TFM_ServerInterface.java | 7 +- .../TotalFreedomMod/TFM_UuidManager.java | 129 ++++++++++++------ 5 files changed, 179 insertions(+), 85 deletions(-) diff --git a/buildnumber.properties b/buildnumber.properties index c6578146..dd311f1c 100644 --- a/buildnumber.properties +++ b/buildnumber.properties @@ -1,3 +1,3 @@ #Build Number for ANT. Do not edit! -#Thu Jun 11 22:27:16 CEST 2015 -build.number=1054 +#Sun Sep 06 17:00:40 CEST 2015 +build.number=1055 diff --git a/src/me/StevenLawson/TotalFreedomMod/TFM_CommandBlocker.java b/src/me/StevenLawson/TotalFreedomMod/TFM_CommandBlocker.java index 7bc60d29..3f9f6845 100644 --- a/src/me/StevenLawson/TotalFreedomMod/TFM_CommandBlocker.java +++ b/src/me/StevenLawson/TotalFreedomMod/TFM_CommandBlocker.java @@ -3,6 +3,8 @@ package me.StevenLawson.TotalFreedomMod; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import me.StevenLawson.TotalFreedomMod.Commands.TFM_CommandLoader; import me.StevenLawson.TotalFreedomMod.Config.TFM_ConfigEntry; import org.apache.commons.lang3.StringUtils; @@ -14,12 +16,8 @@ import org.bukkit.entity.Player; public class TFM_CommandBlocker { - private static final Map BLOCKED_COMMANDS; - - static - { - BLOCKED_COMMANDS = new HashMap(); - } + public static Pattern NUMBER_FLAG_PATTERN = Pattern.compile("(:([0-9]){5,})"); + private static final Map BLOCKED_COMMANDS = new HashMap(); private TFM_CommandBlocker() { @@ -112,33 +110,50 @@ public class TFM_CommandBlocker return false; } + // Format command = command.toLowerCase().trim(); + command = command.startsWith("/") ? command.substring(1) : command; - if (command.split(" ")[0].contains(":")) + // Check for plugin specific commands + final String[] commandParts = command.split(" "); + if (commandParts[0].contains(":")) { - TFM_Util.playerMsg(sender, "Plugin-specific commands are disabled."); + if (doAction) + { + TFM_Util.playerMsg(sender, "Plugin specific commands are disabled."); + } return true; } - if (command.startsWith("/")) + for (String part : commandParts) { - command = command.substring(1); + Matcher matcher = NUMBER_FLAG_PATTERN.matcher(part); + if (!matcher.matches()) + { + continue; + } + if (doAction) + { + TFM_Util.playerMsg(sender, "That command contains an illegal number: " + matcher.group(1)); + } + return true; } - final String[] commandParts = command.split(" "); + // Obtain sub command, if it exists String subCommand = null; if (commandParts.length > 1) { subCommand = StringUtils.join(commandParts, " ", 1, commandParts.length).toLowerCase(); } + // Obtain entry final CommandBlockerEntry entry = BLOCKED_COMMANDS.get(commandParts[0]); - if (entry == null) { return false; } + // Validate sub command if (entry.getSubCommand() != null) { if (subCommand == null || !subCommand.startsWith(entry.getSubCommand())) diff --git a/src/me/StevenLawson/TotalFreedomMod/TFM_PlayerList.java b/src/me/StevenLawson/TotalFreedomMod/TFM_PlayerList.java index 418ee5f8..b579d8f5 100644 --- a/src/me/StevenLawson/TotalFreedomMod/TFM_PlayerList.java +++ b/src/me/StevenLawson/TotalFreedomMod/TFM_PlayerList.java @@ -11,53 +11,66 @@ import me.StevenLawson.TotalFreedomMod.Config.TFM_Config; import org.bukkit.Bukkit; import org.bukkit.entity.Player; -public class TFM_PlayerList { +public class TFM_PlayerList +{ private static final Map PLAYER_LIST = new HashMap(); - private TFM_PlayerList() { + private TFM_PlayerList() + { throw new AssertionError(); } - public static Set getAllPlayers() { + public static Set getAllPlayers() + { return Collections.unmodifiableSet(Sets.newHashSet(PLAYER_LIST.values())); } - public static void load() { + public static void load() + { PLAYER_LIST.clear(); // Load online players - for (Player player : Bukkit.getOnlinePlayers()) { + for (Player player : Bukkit.getOnlinePlayers()) + { getEntry(player); } TFM_Log.info("Loaded playerdata for " + PLAYER_LIST.size() + " players"); } - public static void saveAll() { - for (TFM_Player entry : PLAYER_LIST.values()) { + public static void saveAll() + { + for (TFM_Player entry : PLAYER_LIST.values()) + { save(entry); } } // May return null - public static TFM_Player getEntry(UUID uuid) { - if (PLAYER_LIST.containsKey(uuid)) { + public static TFM_Player getEntry(UUID uuid) + { + if (PLAYER_LIST.containsKey(uuid)) + { return PLAYER_LIST.get(uuid); } final File configFile = getConfigFile(uuid); - if (!configFile.exists()) { + if (!configFile.exists()) + { return null; } final TFM_Player entry = new TFM_Player(uuid, getConfig(uuid)); - if (entry.isComplete()) { + if (entry.isComplete()) + { PLAYER_LIST.put(uuid, entry); return entry; - } else { + } + else + { TFM_Log.warning("Could not load entry: Entry is not complete!"); configFile.delete(); } @@ -65,11 +78,13 @@ public class TFM_PlayerList { return null; } - public static TFM_Player getEntry(Player player) { + public static TFM_Player getEntry(Player player) + { final UUID uuid = TFM_UuidManager.getUniqueId(player); TFM_Player entry = getEntry(uuid); - if (entry != null) { + if (entry != null) + { return entry; } @@ -87,10 +102,12 @@ public class TFM_PlayerList { return entry; } - public static void removeEntry(Player player) { + public static void removeEntry(Player player) + { final UUID uuid = TFM_UuidManager.getUniqueId(player); - if (!PLAYER_LIST.containsKey(uuid)) { + if (!PLAYER_LIST.containsKey(uuid)) + { return; } @@ -99,16 +116,20 @@ public class TFM_PlayerList { PLAYER_LIST.remove(uuid); } - public static boolean existsEntry(Player player) { + public static boolean existsEntry(Player player) + { return existsEntry(TFM_UuidManager.getUniqueId(player)); } - public static boolean existsEntry(UUID uuid) { + public static boolean existsEntry(UUID uuid) + { return getConfigFile(uuid).exists(); } - public static void setUniqueId(TFM_Player entry, UUID newUuid) { - if (entry.getUniqueId().equals(newUuid)) { + public static void setUniqueId(TFM_Player entry, UUID newUuid) + { + if (entry.getUniqueId().equals(newUuid)) + { TFM_Log.warning("Not setting new UUID: UUIDs match!"); return; } @@ -127,13 +148,16 @@ public class TFM_PlayerList { // Remove old entry PLAYER_LIST.remove(entry.getUniqueId()); final File oldFile = getConfigFile(entry.getUniqueId()); - if (oldFile.exists() && !oldFile.delete()) { + if (oldFile.exists() && !oldFile.delete()) + { TFM_Log.warning("Could not delete config: " + getConfigFile(entry.getUniqueId()).getName()); } } - public static void purgeAll() { - for (File file : getConfigFolder().listFiles()) { + public static void purgeAll() + { + for (File file : getConfigFolder().listFiles()) + { file.delete(); } @@ -141,22 +165,27 @@ public class TFM_PlayerList { load(); } - public static File getConfigFolder() { + public static File getConfigFolder() + { return new File(TotalFreedomMod.plugin.getDataFolder(), "players"); } - public static File getConfigFile(UUID uuid) { + public static File getConfigFile(UUID uuid) + { return new File(getConfigFolder(), uuid + ".yml"); } - public static TFM_Config getConfig(UUID uuid) { + public static TFM_Config getConfig(UUID uuid) + { final TFM_Config config = new TFM_Config(TotalFreedomMod.plugin, getConfigFile(uuid), false); config.load(); return config; } - public static void save(TFM_Player entry) { - if (!entry.isComplete()) { + public static void save(TFM_Player entry) + { + if (!entry.isComplete()) + { throw new IllegalArgumentException("Entry is not complete!"); } diff --git a/src/me/StevenLawson/TotalFreedomMod/TFM_ServerInterface.java b/src/me/StevenLawson/TotalFreedomMod/TFM_ServerInterface.java index 6a0ddf92..33ed6331 100644 --- a/src/me/StevenLawson/TotalFreedomMod/TFM_ServerInterface.java +++ b/src/me/StevenLawson/TotalFreedomMod/TFM_ServerInterface.java @@ -77,9 +77,12 @@ public class TFM_ServerInterface continue; } - if (!isAdmin) { + if (!isAdmin) + { event.disallow(AsyncPlayerPreLoginEvent.Result.KICK_OTHER, "Your username is already logged into this server."); - } else { + } + else + { event.allow(); TFM_Sync.playerKick(onlinePlayer, "An admin just logged in with the username you are using."); } diff --git a/src/me/StevenLawson/TotalFreedomMod/TFM_UuidManager.java b/src/me/StevenLawson/TotalFreedomMod/TFM_UuidManager.java index 71fde308..a5df7c93 100644 --- a/src/me/StevenLawson/TotalFreedomMod/TFM_UuidManager.java +++ b/src/me/StevenLawson/TotalFreedomMod/TFM_UuidManager.java @@ -25,18 +25,21 @@ import org.json.simple.JSONArray; import org.json.simple.JSONObject; import org.json.simple.parser.JSONParser; -public class TFM_UuidManager { +public class TFM_UuidManager +{ public static final String TABLE_NAME = "uuids"; private static final TFM_SqliteDatabase SQL; private static final Statement FIND; private static final Statement UPDATE; - private TFM_UuidManager() { + private TFM_UuidManager() + { throw new AssertionError(); } - static { + static + { SQL = new TFM_SqliteDatabase( "uuids.db", TABLE_NAME, @@ -46,34 +49,40 @@ public class TFM_UuidManager { UPDATE = SQL.addPreparedStatement("REPLACE INTO " + TABLE_NAME + " (username, uuid) VALUES (?, ?);"); } - public static void load() { + public static void load() + { // Init DB SQL.connect(); } - public static void close() { + public static void close() + { SQL.close(); } - public static int purge() { + public static int purge() + { return SQL.purge(); } - public static UUID newPlayer(Player player, String ip) { + public static UUID newPlayer(Player player, String ip) + { TFM_Log.info("Obtaining UUID for new player: " + player.getName()); final String username = player.getName().toLowerCase(); // Look in DB final UUID dbUuid = find(username); - if (dbUuid != null) { + if (dbUuid != null) + { return dbUuid; } // Find UUID and update in DB if not found // Try API UUID uuid = TFM_UuidResolver.getUUIDOf(username); - if (uuid == null) { + if (uuid == null) + { // Spoof uuid = generateSpoofUuid(username); } @@ -82,9 +91,11 @@ public class TFM_UuidManager { return uuid; } - public static UUID getUniqueId(OfflinePlayer offlinePlayer) { + public static UUID getUniqueId(OfflinePlayer offlinePlayer) + { // Online check first - if (offlinePlayer.isOnline() && TFM_PlayerData.hasPlayerData(offlinePlayer.getPlayer())) { + if (offlinePlayer.isOnline() && TFM_PlayerData.hasPlayerData(offlinePlayer.getPlayer())) + { return TFM_PlayerData.getPlayerData(offlinePlayer.getPlayer()).getUniqueId(); } @@ -92,16 +103,19 @@ public class TFM_UuidManager { return getUniqueId(offlinePlayer.getName()); } - public static UUID getUniqueId(String username) { + public static UUID getUniqueId(String username) + { // Look in DB final UUID dbUuid = find(username); - if (dbUuid != null) { + if (dbUuid != null) + { return dbUuid; } // Try API final UUID apiUuid = TFM_UuidResolver.getUUIDOf(username); - if (apiUuid != null) { + if (apiUuid != null) + { return apiUuid; } @@ -109,8 +123,10 @@ public class TFM_UuidManager { return generateSpoofUuid(username); } - public static void rawSetUUID(String name, UUID uuid) { - if (name == null || uuid == null || name.isEmpty()) { + public static void rawSetUUID(String name, UUID uuid) + { + if (name == null || uuid == null || name.isEmpty()) + { TFM_Log.warning("Not setting raw UUID: name and uuid may not be null!"); return; } @@ -118,67 +134,86 @@ public class TFM_UuidManager { update(name.toLowerCase().trim(), uuid); } - private static UUID find(String searchName) { - if (!SQL.connect()) { + private static UUID find(String searchName) + { + if (!SQL.connect()) + { return null; } final ResultSet result; - try { + try + { final PreparedStatement statement = FIND.getStatement(); statement.clearParameters(); statement.setString(1, searchName.toLowerCase()); result = statement.executeQuery(); - } catch (Exception ex) { + } + catch (Exception ex) + { TFM_Log.severe("Could not execute find statement!"); TFM_Log.severe(ex); return null; } - if (!TFM_SqlUtil.hasData(result)) { + if (!TFM_SqlUtil.hasData(result)) + { TFM_SqlUtil.close(result); return null; } - try { + try + { final String uuidString = result.getString("uuid"); return UUID.fromString(uuidString); - } catch (Exception ex) { + } + catch (Exception ex) + { TFM_Log.severe(ex); return null; - } finally { + } + finally + { TFM_SqlUtil.close(result); } } - private static boolean update(String username, UUID uuid) { - if (!SQL.connect()) { + private static boolean update(String username, UUID uuid) + { + if (!SQL.connect()) + { return false; } - try { + try + { final PreparedStatement statement = UPDATE.getStatement(); statement.clearParameters(); statement.setString(1, username.toLowerCase()); statement.setString(2, uuid.toString()); statement.executeUpdate(); return true; - } catch (Exception ex) { + } + catch (Exception ex) + { TFM_Log.severe("Could not execute update statement!"); TFM_Log.severe(ex); return false; } } - private static UUID generateSpoofUuid(String name) { + private static UUID generateSpoofUuid(String name) + { name = name.toLowerCase(); TFM_Log.info("Generating spoof UUID for " + name); - try { + try + { final MessageDigest digest = MessageDigest.getInstance("SHA1"); final byte[] result = digest.digest(name.getBytes()); final StringBuilder builder = new StringBuilder(); - for (int i = 0; i < result.length; i++) { + for (int i = 0; i < result.length; i++) + { builder.append(Integer.toString((result[i] & 0xff) + 0x100, 16).substring(1)); } @@ -188,30 +223,37 @@ public class TFM_UuidManager { + "-" + builder.substring(12, 16) + "-" + builder.substring(16, 20) + "-" + builder.substring(20, 32)); - } catch (NoSuchAlgorithmException ex) { + } + catch (NoSuchAlgorithmException ex) + { TFM_Log.warning("Could not generate spoof UUID: SHA1 algorithm not found!"); } return UUID.randomUUID(); } - public static class TFM_UuidResolver implements Callable> { + public static class TFM_UuidResolver implements Callable> + { private static final double PROFILES_PER_REQUEST = 100; private static final String PROFILE_URL = "https://api.mojang.com/profiles/minecraft"; private final JSONParser jsonParser = new JSONParser(); private final List names; - public TFM_UuidResolver(List names) { + public TFM_UuidResolver(List names) + { this.names = ImmutableList.copyOf(names); } @Override - public Map call() { + public Map call() + { final Map uuidMap = new HashMap(); int requests = (int) Math.ceil(names.size() / PROFILES_PER_REQUEST); - for (int i = 0; i < requests; i++) { - try { + for (int i = 0; i < requests; i++) + { + try + { final URL url = new URL(PROFILE_URL); final HttpURLConnection connection = (HttpURLConnection) url.openConnection(); @@ -230,7 +272,8 @@ public class TFM_UuidManager { final JSONArray array = (JSONArray) jsonParser.parse(new InputStreamReader(connection.getInputStream())); - for (Object profile : array) { + for (Object profile : array) + { final JSONObject jsonProfile = (JSONObject) profile; final String id = (String) jsonProfile.get("id"); final String name = (String) jsonProfile.get("name"); @@ -243,10 +286,13 @@ public class TFM_UuidManager { uuidMap.put(name, uuid); } - if (i != requests - 1) { + if (i != requests - 1) + { Thread.sleep(100L); } - } catch (Exception ex) { + } + catch (Exception ex) + { TFM_Log.severe("Could not resolve UUID(s) of " + StringUtils.join(names.subList(i * 100, Math.min((i + 1) * 100, names.size())), ", ")); //TFM_Log.severe(ex); @@ -255,7 +301,8 @@ public class TFM_UuidManager { return uuidMap; } - public static UUID getUUIDOf(String name) { + public static UUID getUUIDOf(String name) + { return new TFM_UuidResolver(Arrays.asList(name)).call().get(name); } }