From eec7a7f575f3eec4d7428274ecf67a23ed1b7be4 Mon Sep 17 00:00:00 2001 From: Xephi59 Date: Thu, 27 Aug 2015 23:28:12 +0200 Subject: [PATCH 1/3] Add SALTEDSHA512 Encryption --- .../xephi/authme/security/HashAlgorithm.java | 1 + .../authme/security/PasswordSecurity.java | 9 ++++-- .../authme/security/crypts/SALTEDSHA512.java | 32 +++++++++++++++++++ 3 files changed, 40 insertions(+), 2 deletions(-) create mode 100644 src/main/java/fr/xephi/authme/security/crypts/SALTEDSHA512.java diff --git a/src/main/java/fr/xephi/authme/security/HashAlgorithm.java b/src/main/java/fr/xephi/authme/security/HashAlgorithm.java index a9fd19e53..312b6df01 100644 --- a/src/main/java/fr/xephi/authme/security/HashAlgorithm.java +++ b/src/main/java/fr/xephi/authme/security/HashAlgorithm.java @@ -29,6 +29,7 @@ public enum HashAlgorithm { ROYALAUTH(fr.xephi.authme.security.crypts.ROYALAUTH.class), CRAZYCRYPT1(fr.xephi.authme.security.crypts.CRAZYCRYPT1.class), BCRYPT2Y(fr.xephi.authme.security.crypts.BCRYPT2Y.class), + SALTEDSHA512(fr.xephi.authme.security.crypts.SALTEDSHA512.class), CUSTOM(Null.class); Class classe; diff --git a/src/main/java/fr/xephi/authme/security/PasswordSecurity.java b/src/main/java/fr/xephi/authme/security/PasswordSecurity.java index bfc2fb2d6..305b89b63 100644 --- a/src/main/java/fr/xephi/authme/security/PasswordSecurity.java +++ b/src/main/java/fr/xephi/authme/security/PasswordSecurity.java @@ -96,7 +96,12 @@ public class PasswordSecurity { userSalt.put(playerName, salt); break; case BCRYPT2Y: - salt = createSalt(22); + salt = createSalt(16); + userSalt.put(playerName, salt); + break; + case SALTEDSHA512: + salt = createSalt(32); + userSalt.put(playerName, salt); break; case MD5: case SHA1: @@ -165,7 +170,7 @@ public class PasswordSecurity { PlayerAuth nAuth = AuthMe.getInstance().database.getAuth(playerName); if (nAuth != null) { nAuth.setHash(getHash(Settings.getPasswordHash, password, playerName)); - nAuth.setSalt(userSalt.get(playerName)); + nAuth.setSalt(userSalt.containsKey(playerName) ? userSalt.get(playerName) : ""); AuthMe.getInstance().database.updatePassword(nAuth); AuthMe.getInstance().database.updateSalt(nAuth); } diff --git a/src/main/java/fr/xephi/authme/security/crypts/SALTEDSHA512.java b/src/main/java/fr/xephi/authme/security/crypts/SALTEDSHA512.java new file mode 100644 index 000000000..0050dd73d --- /dev/null +++ b/src/main/java/fr/xephi/authme/security/crypts/SALTEDSHA512.java @@ -0,0 +1,32 @@ +package fr.xephi.authme.security.crypts; + +import java.math.BigInteger; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +import fr.xephi.authme.AuthMe; + +public class SALTEDSHA512 implements EncryptionMethod { + + @Override + public String getHash(String password, String salt, String name) + throws NoSuchAlgorithmException { + return getSHA512(password + salt); + } + + @Override + public boolean comparePassword(String hash, String password, + String playerName) throws NoSuchAlgorithmException { + String salt = AuthMe.getInstance().database.getAuth(playerName).getSalt(); + return hash.equals(getHash(password, salt, "")); + } + + private static String getSHA512(String message) + throws NoSuchAlgorithmException { + MessageDigest sha512 = MessageDigest.getInstance("SHA-512"); + sha512.reset(); + sha512.update(message.getBytes()); + byte[] digest = sha512.digest(); + return String.format("%0" + (digest.length << 1) + "x", new BigInteger(1, digest)); + } +} From e33ebb7379011d449dcf79237e33b2d591ad06a0 Mon Sep 17 00:00:00 2001 From: Xephi59 Date: Fri, 28 Aug 2015 00:16:26 +0200 Subject: [PATCH 2/3] Change some custom event to let them be async --- .../xephi/authme/commands/AdminCommand.java | 67 +++++++++++-------- .../fr/xephi/authme/events/CustomEvent.java | 8 +++ .../events/FirstSpawnTeleportEvent.java | 1 + .../events/PasswordEncryptionEvent.java | 1 + .../authme/events/ProtectInventoryEvent.java | 1 + .../authme/events/ResetInventoryEvent.java | 1 + .../authme/events/RestoreInventoryEvent.java | 8 +++ .../authme/events/StoreInventoryEvent.java | 3 +- .../authme/process/join/AsyncronousJoin.java | 59 ++++++++-------- .../logout/ProcessSyncronousPlayerLogout.java | 8 +-- .../authme/process/quit/AsyncronousQuit.java | 10 +++ .../quit/ProcessSyncronousPlayerQuit.java | 10 +-- 12 files changed, 103 insertions(+), 74 deletions(-) diff --git a/src/main/java/fr/xephi/authme/commands/AdminCommand.java b/src/main/java/fr/xephi/authme/commands/AdminCommand.java index 28f4519b9..cdcbf9975 100644 --- a/src/main/java/fr/xephi/authme/commands/AdminCommand.java +++ b/src/main/java/fr/xephi/authme/commands/AdminCommand.java @@ -47,8 +47,8 @@ public class AdminCommand implements CommandExecutor { } @Override - public boolean onCommand(CommandSender sender, Command cmnd, String label, - String[] args) { + public boolean onCommand(final CommandSender sender, Command cmnd, + String label, String[] args) { if (args.length == 0) { sender.sendMessage("Usage:"); sender.sendMessage("/authme reload - Reload the config"); @@ -434,34 +434,43 @@ public class AdminCommand implements CommandExecutor { return true; } } - try { - String name = args[1].toLowerCase(); - String hash = PasswordSecurity.getHash(Settings.getPasswordHash, args[2], name); - PlayerAuth auth = null; - if (PlayerCache.getInstance().isAuthenticated(name)) { - auth = PlayerCache.getInstance().getAuth(name); - } else if (plugin.database.isAuthAvailable(name)) { - auth = plugin.database.getAuth(name); + final String name = args[1].toLowerCase(); + final String raw = args[2]; + Bukkit.getScheduler().runTaskAsynchronously(plugin, new Runnable() { + + @Override + public void run() { + String hash; + try { + hash = PasswordSecurity.getHash(Settings.getPasswordHash, raw, name); + } catch (NoSuchAlgorithmException e) { + m.send(sender, "error"); + return; + } + PlayerAuth auth = null; + if (PlayerCache.getInstance().isAuthenticated(name)) { + auth = PlayerCache.getInstance().getAuth(name); + } else if (plugin.database.isAuthAvailable(name)) { + auth = plugin.database.getAuth(name); + } + if (auth == null) { + m.send(sender, "unknown_user"); + return; + } + auth.setHash(hash); + if (PasswordSecurity.userSalt.containsKey(name)) { + auth.setSalt(PasswordSecurity.userSalt.get(name)); + plugin.database.updateSalt(auth); + } + if (!plugin.database.updatePassword(auth)) { + m.send(sender, "error"); + return; + } + sender.sendMessage("pwd_changed"); + ConsoleLogger.info(name + "'s password changed"); } - if (auth == null) { - m.send(sender, "unknown_user"); - return true; - } - auth.setHash(hash); - if (PasswordSecurity.userSalt.containsKey(name)) { - auth.setSalt(PasswordSecurity.userSalt.get(name)); - plugin.database.updateSalt(auth); - } - if (!plugin.database.updatePassword(auth)) { - m.send(sender, "error"); - return true; - } - sender.sendMessage("pwd_changed"); - ConsoleLogger.info(args[1] + "'s password changed"); - } catch (NoSuchAlgorithmException ex) { - ConsoleLogger.showError(ex.getMessage()); - m.send(sender, "error"); - } + + }); return true; } else if (args[0].equalsIgnoreCase("unregister") || args[0].equalsIgnoreCase("unreg") || args[0].equalsIgnoreCase("del")) { if (args.length != 2) { diff --git a/src/main/java/fr/xephi/authme/events/CustomEvent.java b/src/main/java/fr/xephi/authme/events/CustomEvent.java index 227429961..5be14710e 100644 --- a/src/main/java/fr/xephi/authme/events/CustomEvent.java +++ b/src/main/java/fr/xephi/authme/events/CustomEvent.java @@ -13,6 +13,14 @@ public class CustomEvent extends Event implements Cancellable { private boolean isCancelled; private static final HandlerList handlers = new HandlerList(); + public CustomEvent() { + super(false); + } + + public CustomEvent(boolean b) { + super(b); + } + public HandlerList getHandlers() { return handlers; } diff --git a/src/main/java/fr/xephi/authme/events/FirstSpawnTeleportEvent.java b/src/main/java/fr/xephi/authme/events/FirstSpawnTeleportEvent.java index 079a4614d..e40614602 100644 --- a/src/main/java/fr/xephi/authme/events/FirstSpawnTeleportEvent.java +++ b/src/main/java/fr/xephi/authme/events/FirstSpawnTeleportEvent.java @@ -16,6 +16,7 @@ public class FirstSpawnTeleportEvent extends CustomEvent { private Location from; public FirstSpawnTeleportEvent(Player player, Location from, Location to) { + super(true); this.player = player; this.from = from; this.to = to; diff --git a/src/main/java/fr/xephi/authme/events/PasswordEncryptionEvent.java b/src/main/java/fr/xephi/authme/events/PasswordEncryptionEvent.java index 9f6ea0078..4e5a0f5cd 100644 --- a/src/main/java/fr/xephi/authme/events/PasswordEncryptionEvent.java +++ b/src/main/java/fr/xephi/authme/events/PasswordEncryptionEvent.java @@ -22,6 +22,7 @@ public class PasswordEncryptionEvent extends Event { private String playerName = ""; public PasswordEncryptionEvent(EncryptionMethod method, String playerName) { + super(true); this.method = method; this.playerName = playerName; } diff --git a/src/main/java/fr/xephi/authme/events/ProtectInventoryEvent.java b/src/main/java/fr/xephi/authme/events/ProtectInventoryEvent.java index eebf6f4a1..10d5636b5 100644 --- a/src/main/java/fr/xephi/authme/events/ProtectInventoryEvent.java +++ b/src/main/java/fr/xephi/authme/events/ProtectInventoryEvent.java @@ -20,6 +20,7 @@ public class ProtectInventoryEvent extends CustomEvent { public ProtectInventoryEvent(Player player, ItemStack[] storedinventory, ItemStack[] storedarmor) { + super(true); this.player = player; this.storedinventory = storedinventory; this.storedarmor = storedarmor; diff --git a/src/main/java/fr/xephi/authme/events/ResetInventoryEvent.java b/src/main/java/fr/xephi/authme/events/ResetInventoryEvent.java index 84fbe206e..5c7b622e8 100644 --- a/src/main/java/fr/xephi/authme/events/ResetInventoryEvent.java +++ b/src/main/java/fr/xephi/authme/events/ResetInventoryEvent.java @@ -13,6 +13,7 @@ public class ResetInventoryEvent extends CustomEvent { private Player player; public ResetInventoryEvent(Player player) { + super(true); this.player = player; } diff --git a/src/main/java/fr/xephi/authme/events/RestoreInventoryEvent.java b/src/main/java/fr/xephi/authme/events/RestoreInventoryEvent.java index f51499a9e..c2c36ba42 100644 --- a/src/main/java/fr/xephi/authme/events/RestoreInventoryEvent.java +++ b/src/main/java/fr/xephi/authme/events/RestoreInventoryEvent.java @@ -22,6 +22,14 @@ public class RestoreInventoryEvent extends CustomEvent { this.armor = armor; } + public RestoreInventoryEvent(Player player, ItemStack[] inventory, + ItemStack[] armor, boolean b) { + super(b); + this.player = player; + this.inventory = inventory; + this.armor = armor; + } + public ItemStack[] getInventory() { return this.inventory; } diff --git a/src/main/java/fr/xephi/authme/events/StoreInventoryEvent.java b/src/main/java/fr/xephi/authme/events/StoreInventoryEvent.java index 785075245..c91523d87 100644 --- a/src/main/java/fr/xephi/authme/events/StoreInventoryEvent.java +++ b/src/main/java/fr/xephi/authme/events/StoreInventoryEvent.java @@ -28,8 +28,7 @@ public class StoreInventoryEvent extends CustomEvent { try { this.inventory = fileCache.readCache(player).getInventory(); this.armor = fileCache.readCache(player).getArmour(); - } catch (Exception e) - { + } catch (Exception e) { this.inventory = player.getInventory().getContents(); this.armor = player.getInventory().getArmorContents(); } diff --git a/src/main/java/fr/xephi/authme/process/join/AsyncronousJoin.java b/src/main/java/fr/xephi/authme/process/join/AsyncronousJoin.java index d1ef309d0..3a3e8e1f3 100644 --- a/src/main/java/fr/xephi/authme/process/join/AsyncronousJoin.java +++ b/src/main/java/fr/xephi/authme/process/join/AsyncronousJoin.java @@ -6,6 +6,7 @@ import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffectType; import org.bukkit.scheduler.BukkitScheduler; @@ -176,25 +177,27 @@ public class AsyncronousJoin { } if (Settings.protectInventoryBeforeLogInEnabled) { - sched.scheduleSyncDelayedTask(plugin, new Runnable() { + try { + LimboPlayer limbo = LimboCache.getInstance().getLimboPlayer(player.getName().toLowerCase()); + ProtectInventoryEvent ev = new ProtectInventoryEvent(player, limbo.getInventory(), limbo.getArmour()); + plugin.getServer().getPluginManager().callEvent(ev); + if (ev.isCancelled()) { + if (!Settings.noConsoleSpam) + ConsoleLogger.info("ProtectInventoryEvent has been cancelled for " + player.getName() + " ..."); + } else { + final ItemStack[] inv = ev.getEmptyArmor(); + final ItemStack[] armor = ev.getEmptyArmor(); + sched.scheduleSyncDelayedTask(plugin, new Runnable() { - @Override - public void run() { - try { - LimboPlayer limbo = LimboCache.getInstance().getLimboPlayer(player.getName().toLowerCase()); - ProtectInventoryEvent ev = new ProtectInventoryEvent(player, limbo.getInventory(), limbo.getArmour()); - plugin.getServer().getPluginManager().callEvent(ev); - if (ev.isCancelled()) { - if (!Settings.noConsoleSpam) - ConsoleLogger.info("ProtectInventoryEvent has been cancelled for " + player.getName() + " ..."); - } else { - plugin.api.setPlayerInventory(player, ev.getEmptyInventory(), ev.getEmptyArmor()); + @Override + public void run() { + plugin.api.setPlayerInventory(player, inv, armor); } - } catch (NullPointerException ex) { - } - } - }); + }); + } + } catch (NullPointerException ex) { + } } String[] msg; if (Settings.emailRegistration) { @@ -262,21 +265,21 @@ public class AsyncronousJoin { else { if (Spawn.getInstance().getFirstSpawn() == null || Spawn.getInstance().getFirstSpawn().getWorld() == null) return false; - final Location loc = Spawn.getInstance().getFirstSpawn(); - Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() { + FirstSpawnTeleportEvent tpEvent = new FirstSpawnTeleportEvent(player, player.getLocation(), Spawn.getInstance().getFirstSpawn()); + plugin.getServer().getPluginManager().callEvent(tpEvent); + if (!tpEvent.isCancelled()) { + if (player.isOnline() && tpEvent.getTo() != null && tpEvent.getTo().getWorld() != null) { + final Location fLoc = tpEvent.getTo(); + Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() { - @Override - public void run() { - FirstSpawnTeleportEvent tpEvent = new FirstSpawnTeleportEvent(player, player.getLocation(), loc); - plugin.getServer().getPluginManager().callEvent(tpEvent); - if (!tpEvent.isCancelled()) { - if (player.isOnline() && tpEvent.getTo() != null && tpEvent.getTo().getWorld() != null) { - player.teleport(tpEvent.getTo()); + @Override + public void run() { + player.teleport(fLoc); } - } - } - }); + }); + } + } return true; } } diff --git a/src/main/java/fr/xephi/authme/process/logout/ProcessSyncronousPlayerLogout.java b/src/main/java/fr/xephi/authme/process/logout/ProcessSyncronousPlayerLogout.java index f926c6949..4cac3864a 100644 --- a/src/main/java/fr/xephi/authme/process/logout/ProcessSyncronousPlayerLogout.java +++ b/src/main/java/fr/xephi/authme/process/logout/ProcessSyncronousPlayerLogout.java @@ -56,13 +56,7 @@ public class ProcessSyncronousPlayerLogout implements Runnable { player.setFlying(true); } // Player is now logout... Time to fire event ! - sched.scheduleSyncDelayedTask(plugin, new Runnable() { - - @Override - public void run() { - Bukkit.getServer().getPluginManager().callEvent(new LogoutEvent(player)); - } - }); + Bukkit.getServer().getPluginManager().callEvent(new LogoutEvent(player)); m.send(player, "logout"); ConsoleLogger.info(player.getDisplayName() + " logged out"); } diff --git a/src/main/java/fr/xephi/authme/process/quit/AsyncronousQuit.java b/src/main/java/fr/xephi/authme/process/quit/AsyncronousQuit.java index 40a71247d..dd84fdc85 100644 --- a/src/main/java/fr/xephi/authme/process/quit/AsyncronousQuit.java +++ b/src/main/java/fr/xephi/authme/process/quit/AsyncronousQuit.java @@ -13,6 +13,7 @@ import fr.xephi.authme.cache.auth.PlayerCache; import fr.xephi.authme.cache.limbo.LimboCache; import fr.xephi.authme.cache.limbo.LimboPlayer; import fr.xephi.authme.datasource.DataSource; +import fr.xephi.authme.events.RestoreInventoryEvent; import fr.xephi.authme.listener.AuthMePlayerListener; import fr.xephi.authme.plugin.manager.CombatTagComunicator; import fr.xephi.authme.settings.Settings; @@ -97,6 +98,15 @@ public class AsyncronousQuit { } AuthMePlayerListener.gameMode.remove(name); final Player p = player; + RestoreInventoryEvent ev = new RestoreInventoryEvent(player, inv, armor, true); + Bukkit.getPluginManager().callEvent(ev); + if (ev.isCancelled()) { + inv = null; + armor = null; + } else { + inv = ev.getInventory(); + armor = ev.getArmor(); + } Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new ProcessSyncronousPlayerQuit(plugin, p, inv, armor, isOp, isFlying, needToChange)); } } diff --git a/src/main/java/fr/xephi/authme/process/quit/ProcessSyncronousPlayerQuit.java b/src/main/java/fr/xephi/authme/process/quit/ProcessSyncronousPlayerQuit.java index b21a78bfe..488134099 100644 --- a/src/main/java/fr/xephi/authme/process/quit/ProcessSyncronousPlayerQuit.java +++ b/src/main/java/fr/xephi/authme/process/quit/ProcessSyncronousPlayerQuit.java @@ -5,7 +5,6 @@ import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import fr.xephi.authme.AuthMe; -import fr.xephi.authme.events.RestoreInventoryEvent; import fr.xephi.authme.settings.Settings; public class ProcessSyncronousPlayerQuit implements Runnable { @@ -32,13 +31,8 @@ public class ProcessSyncronousPlayerQuit implements Runnable { @Override public void run() { - if (inv != null && armor != null) { - RestoreInventoryEvent ev = new RestoreInventoryEvent(player, inv, armor); - player.getServer().getPluginManager().callEvent(ev); - if (!ev.isCancelled()) { - plugin.api.setPlayerInventory(player, ev.getInventory(), ev.getArmor()); - } - } + if (inv != null && armor != null) + plugin.api.setPlayerInventory(player, inv, armor); if (needToChange) { player.setOp(isOp); if (player.getGameMode() != GameMode.CREATIVE && !Settings.isMovementAllowed) { From 3bcaa3f12b34102718a00e92b12654b5538963cb Mon Sep 17 00:00:00 2001 From: Xephi59 Date: Fri, 28 Aug 2015 00:16:49 +0200 Subject: [PATCH 3/3] Change to minimum lifeTime --- src/main/java/fr/xephi/authme/datasource/MySQL.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/fr/xephi/authme/datasource/MySQL.java b/src/main/java/fr/xephi/authme/datasource/MySQL.java index 89d9fd85e..1588ac6b8 100644 --- a/src/main/java/fr/xephi/authme/datasource/MySQL.java +++ b/src/main/java/fr/xephi/authme/datasource/MySQL.java @@ -122,7 +122,7 @@ public class MySQL implements DataSource { config.addDataSourceProperty("prepStmtCacheSize", "250"); config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048"); config.addDataSourceProperty("autoReconnect", true); - config.setMaxLifetime(12000); + config.setMaxLifetime(30000); config.setInitializationFailFast(false); ds = new HikariDataSource(config); ConsoleLogger.info("Connection pool ready");