Minor cleanup using inspections + Https
* Use https for maven repositories if possible * Fix typos * Merge ProtocolLib listeners into one class * Upgrade maven plugins and dependencies
This commit is contained in:
27 files changed
+93
-199
No files matched your search
+1
-1
@@ -37,7 +37,7 @@
|
||||
<!--Authme Reloaded-->
|
||||
<repository>
|
||||
<id>xephi-repo</id>
|
||||
<url>http://ci.xephi.fr/plugin/repository/everything/</url>
|
||||
<url>https://ci.xephi.fr/plugin/repository/everything/</url>
|
||||
</repository>
|
||||
|
||||
<!--xAuth-->
|
||||
|
||||
@@ -28,7 +28,7 @@ public class BukkitLoginSession extends LoginSession {
|
||||
this.verifyToken = ArrayUtils.clone(verifyToken);
|
||||
}
|
||||
|
||||
//available for bungeecord
|
||||
//available for BungeeCord
|
||||
public BukkitLoginSession(String username, boolean registered) {
|
||||
this(username, "", ArrayUtils.EMPTY_BYTE_ARRAY, registered, null);
|
||||
}
|
||||
@@ -41,7 +41,7 @@ public class BukkitLoginSession extends LoginSession {
|
||||
/**
|
||||
* Gets the random generated server id. This makes sure the request sent from the client is just for this server.
|
||||
*
|
||||
* See this for details http://www.sk89q.com/2011/09/minecraft-name-spoofing-exploit/
|
||||
* See this for details http://www.sk89q.com/2011/09/Minecraft-name-spoofing-exploit/
|
||||
*
|
||||
* Empty if it's a BungeeCord connection
|
||||
*
|
||||
|
||||
@@ -8,8 +8,6 @@ import java.security.KeyPair;
|
||||
import java.security.KeyPairGenerator;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.PublicKey;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import javax.crypto.BadPaddingException;
|
||||
@@ -41,7 +39,7 @@ public class EncryptionUtil {
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] getServerIdHash(String serverId, PublicKey publicKey, SecretKey secretKey) {
|
||||
public static byte[] getServerIdHash(String serverId, Key publicKey, Key secretKey) {
|
||||
return digestOperation("SHA-1"
|
||||
, new byte[][]{serverId.getBytes(Charsets.ISO_8859_1), secretKey.getEncoded(), publicKey.getEncoded()});
|
||||
}
|
||||
@@ -72,7 +70,7 @@ public class EncryptionUtil {
|
||||
// return null;
|
||||
// }
|
||||
|
||||
public static SecretKey decryptSharedKey(PrivateKey privateKey, byte[] encryptedSharedKey) {
|
||||
public static SecretKey decryptSharedKey(Key privateKey, byte[] encryptedSharedKey) {
|
||||
return new SecretKeySpec(decryptData(privateKey, encryptedSharedKey), "AES");
|
||||
}
|
||||
|
||||
|
||||
@@ -5,9 +5,8 @@ import com.github.games647.fastlogin.bukkit.commands.ImportCommand;
|
||||
import com.github.games647.fastlogin.bukkit.commands.PremiumCommand;
|
||||
import com.github.games647.fastlogin.bukkit.listener.BukkitJoinListener;
|
||||
import com.github.games647.fastlogin.bukkit.listener.BungeeCordListener;
|
||||
import com.github.games647.fastlogin.bukkit.listener.protocollib.EncryptionPacketListener;
|
||||
import com.github.games647.fastlogin.bukkit.listener.protocollib.LoginSkinApplyListener;
|
||||
import com.github.games647.fastlogin.bukkit.listener.protocollib.StartPacketListener;
|
||||
import com.github.games647.fastlogin.bukkit.listener.protocollib.ProtocolLibListener;
|
||||
import com.github.games647.fastlogin.bukkit.listener.protocolsupport.ProtocolSupportListener;
|
||||
import com.github.games647.fastlogin.bukkit.tasks.DelayedAuthHook;
|
||||
import com.github.games647.fastlogin.core.shared.FastLoginCore;
|
||||
@@ -32,14 +31,13 @@ import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.bukkit.plugin.messaging.PluginMessageRecipient;
|
||||
|
||||
/**
|
||||
* This plugin checks if a player has a paid account and if so tries to skip offline mode authentication.
|
||||
*/
|
||||
public class FastLoginBukkit extends JavaPlugin implements PlatformPlugin<CommandSender> {
|
||||
|
||||
private static final int WORKER_THREADS = 3;
|
||||
|
||||
//provide a immutable key pair to be thread safe | used for encrypting and decrypting traffic
|
||||
private final KeyPair keyPair = EncryptionUtil.generateKeyPair();
|
||||
|
||||
@@ -90,8 +88,7 @@ public class FastLoginBukkit extends JavaPlugin implements PlatformPlugin<Comman
|
||||
//they will be created with a static builder, because otherwise it will throw a
|
||||
//java.lang.NoClassDefFoundError: com/comphenix/protocol/events/PacketListener if ProtocolSupport was
|
||||
//only found
|
||||
StartPacketListener.register(this, WORKER_THREADS);
|
||||
EncryptionPacketListener.register(this, WORKER_THREADS);
|
||||
ProtocolLibListener.register(this);
|
||||
|
||||
getServer().getPluginManager().registerEvents(new LoginSkinApplyListener(this), this);
|
||||
} else {
|
||||
@@ -185,7 +182,7 @@ public class FastLoginBukkit extends JavaPlugin implements PlatformPlugin<Comman
|
||||
}
|
||||
}
|
||||
|
||||
private void notifiyBungeeCord(Player sender, String target, boolean activate, boolean isPlayer) {
|
||||
private void notifiyBungeeCord(PluginMessageRecipient sender, String target, boolean activate, boolean isPlayer) {
|
||||
ByteArrayDataOutput dataOutput = ByteStreams.newDataOutput();
|
||||
if (activate) {
|
||||
dataOutput.writeUTF("ON");
|
||||
|
||||
@@ -33,7 +33,7 @@ public class MojangApiBukkit extends MojangApiConnector {
|
||||
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
|
||||
String line = reader.readLine();
|
||||
if (line != null && !line.equals("null")) {
|
||||
if (line != null && !"null".equals(line)) {
|
||||
//validate parsing
|
||||
//http://wiki.vg/Protocol_Encryption#Server
|
||||
JSONObject userData = (JSONObject) JSONValue.parseWithException(line);
|
||||
@@ -44,7 +44,7 @@ public class MojangApiBukkit extends MojangApiConnector {
|
||||
JSONObject skinProperty = (JSONObject) properties.get(0);
|
||||
|
||||
String propertyName = (String) skinProperty.get("name");
|
||||
if (propertyName.equals("textures")) {
|
||||
if ("textures".equals(propertyName)) {
|
||||
String skinValue = (String) skinProperty.get("value");
|
||||
String signature = (String) skinProperty.get("signature");
|
||||
playerSession.setSkin(skinValue, signature);
|
||||
|
||||
@@ -24,7 +24,7 @@ public class PremiumPlaceholder extends PlaceholderHook {
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
if (metadata.size() > 0) {
|
||||
if (!metadata.isEmpty()) {
|
||||
return "premium";
|
||||
} else {
|
||||
return "cracked";
|
||||
|
||||
@@ -8,6 +8,7 @@ import java.util.logging.Level;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.royaldev.royalauth.AuthPlayer;
|
||||
import org.royaldev.royalauth.Config;
|
||||
import org.royaldev.royalauth.RoyalAuth;
|
||||
@@ -21,7 +22,7 @@ import org.royaldev.royalauth.RoyalAuth;
|
||||
*/
|
||||
public class RoyalAuthHook implements AuthPlugin<Player> {
|
||||
|
||||
private final RoyalAuth royalAuthPlugin = (RoyalAuth) Bukkit.getPluginManager().getPlugin("RoyalAuth");
|
||||
private final Plugin royalAuthPlugin = (RoyalAuth) Bukkit.getPluginManager().getPlugin("RoyalAuth");
|
||||
|
||||
@Override
|
||||
public boolean forceLogin(Player player) {
|
||||
|
||||
@@ -53,7 +53,7 @@ public class UltraAuthHook implements AuthPlugin<Player> {
|
||||
public boolean forceRegister(Player player, String password) {
|
||||
UltraAuthAPI.setPlayerPasswordOnline(player, password);
|
||||
if (PlayerManager.getInstance().checkPlayerPassword(player, password)) {
|
||||
//the register method silents any excpetion so check if our entry was saved
|
||||
//the register method silents any exception so check if our entry was saved
|
||||
return forceLogin(player);
|
||||
}
|
||||
|
||||
|
||||
@@ -66,10 +66,9 @@ public class xAuthHook implements AuthPlugin<Player> {
|
||||
if (xAuthPlayer != null) {
|
||||
//this should run async because the plugin executes a sql query, but the method
|
||||
//accesses non thread-safe collections :(
|
||||
boolean registerSuccess = xAuthPlugin.getAuthClass(xAuthPlayer)
|
||||
.adminRegister(player.getName(), password, null);
|
||||
|
||||
return registerSuccess;
|
||||
return xAuthPlugin.getAuthClass(xAuthPlayer)
|
||||
.adminRegister(player.getName(), password, null);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
+1
-1
@@ -40,7 +40,7 @@ public class BukkitJoinListener implements Listener {
|
||||
|
||||
if (!plugin.isBungeeCord()) {
|
||||
//Wait before auth plugin and we received a message from BungeeCord initializes the player
|
||||
ForceLoginTask forceLoginTask = new ForceLoginTask(plugin.getCore(), player);
|
||||
Runnable forceLoginTask = new ForceLoginTask(plugin.getCore(), player);
|
||||
Bukkit.getScheduler().runTaskLaterAsynchronously(plugin, forceLoginTask, DELAY_LOGIN);
|
||||
}
|
||||
}
|
||||
|
||||
-72
@@ -1,72 +0,0 @@
|
||||
package com.github.games647.fastlogin.bukkit.listener.protocollib;
|
||||
|
||||
import com.comphenix.protocol.PacketType;
|
||||
import com.comphenix.protocol.ProtocolLibrary;
|
||||
import com.comphenix.protocol.events.PacketAdapter;
|
||||
import com.comphenix.protocol.events.PacketEvent;
|
||||
import com.github.games647.fastlogin.bukkit.FastLoginBukkit;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
|
||||
/**
|
||||
* Handles incoming encryption responses from connecting clients.
|
||||
* It prevents them from reaching the server because that cannot handle
|
||||
* it in offline mode.
|
||||
*
|
||||
* Moreover this manages a started premium check from
|
||||
* this plugin. So check if all data is correct and we can prove him as a
|
||||
* owner of a paid minecraft account.
|
||||
*
|
||||
* Receiving packet information:
|
||||
* http://wiki.vg/Protocol#Encryption_Response
|
||||
*
|
||||
* sharedSecret=encrypted byte array
|
||||
* verify token=encrypted byte array
|
||||
*/
|
||||
public class EncryptionPacketListener extends PacketAdapter {
|
||||
|
||||
//hides the inherit Plugin plugin field, but we need this type
|
||||
private final FastLoginBukkit plugin;
|
||||
|
||||
public EncryptionPacketListener(FastLoginBukkit plugin) {
|
||||
//run async in order to not block the server, because we make api calls to Mojang
|
||||
super(params(plugin, PacketType.Login.Client.ENCRYPTION_BEGIN).optionAsync());
|
||||
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
public static void register(FastLoginBukkit plugin, int workerThreads) {
|
||||
ProtocolLibrary.getProtocolManager().getAsynchronousManager()
|
||||
.registerAsyncHandler(new EncryptionPacketListener(plugin)).start(workerThreads);
|
||||
}
|
||||
|
||||
/**
|
||||
* C->S : Handshake State=2
|
||||
* C->S : Login Start
|
||||
* S->C : Encryption Key Request
|
||||
* (Client Auth)
|
||||
* C->S : Encryption Key Response
|
||||
* (Server Auth, Both enable encryption)
|
||||
* S->C : Login Success (*)
|
||||
*
|
||||
* On offline logins is Login Start followed by Login Success
|
||||
*
|
||||
* Minecraft Server implementation
|
||||
* https://github.com/bergerkiller/CraftSource/blob/master/net.minecraft.server/LoginListener.java#L180
|
||||
*/
|
||||
@Override
|
||||
public void onPacketReceiving(PacketEvent packetEvent) {
|
||||
if (packetEvent.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Player sender = packetEvent.getPlayer();
|
||||
byte[] sharedSecret = packetEvent.getPacket().getByteArrays().read(0);
|
||||
|
||||
packetEvent.getAsyncMarker().incrementProcessingDelay();
|
||||
VerifyResponseTask verifyTask = new VerifyResponseTask(plugin, packetEvent, sender, sharedSecret);
|
||||
Bukkit.getScheduler().runTaskAsynchronously(plugin, verifyTask);
|
||||
}
|
||||
}
|
||||
+32
-32
@@ -1,6 +1,7 @@
|
||||
package com.github.games647.fastlogin.bukkit.listener.protocollib;
|
||||
|
||||
import com.comphenix.protocol.PacketType;
|
||||
import com.comphenix.protocol.PacketType.Login.Client;
|
||||
import com.comphenix.protocol.ProtocolLibrary;
|
||||
import com.comphenix.protocol.events.PacketAdapter;
|
||||
import com.comphenix.protocol.events.PacketContainer;
|
||||
@@ -13,57 +14,56 @@ import java.util.logging.Level;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
/**
|
||||
* Handles incoming start packets from connecting clients. It
|
||||
* checks if we can start checking if the player is premium and
|
||||
* start a request to the client that it should start online mode
|
||||
* login.
|
||||
*
|
||||
* Receiving packet information:
|
||||
* http://wiki.vg/Protocol#Login_Start
|
||||
*
|
||||
* String=Username
|
||||
*/
|
||||
public class StartPacketListener extends PacketAdapter {
|
||||
public class ProtocolLibListener extends PacketAdapter {
|
||||
|
||||
private static final int WORKER_THREADS = 3;
|
||||
|
||||
//hides the inherit Plugin plugin field, but we need a more detailed type than just Plugin
|
||||
private final FastLoginBukkit plugin;
|
||||
|
||||
//just create a new once on plugin enable. This used for verify token generation
|
||||
private final Random random = new Random();
|
||||
|
||||
public StartPacketListener(FastLoginBukkit plugin) {
|
||||
public ProtocolLibListener(FastLoginBukkit plugin) {
|
||||
//run async in order to not block the server, because we are making api calls to Mojang
|
||||
super(params(plugin, PacketType.Login.Client.START).optionAsync());
|
||||
super(params().plugin(plugin)
|
||||
.types(PacketType.Login.Client.START)
|
||||
.types(PacketType.Login.Client.ENCRYPTION_BEGIN)
|
||||
.optionAsync());
|
||||
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
public static void register(FastLoginBukkit plugin, int workerThreads) {
|
||||
public static void register(FastLoginBukkit plugin) {
|
||||
ProtocolLibrary.getProtocolManager().getAsynchronousManager()
|
||||
.registerAsyncHandler(new StartPacketListener(plugin)).start(workerThreads);
|
||||
.registerAsyncHandler(new ProtocolLibListener(plugin))
|
||||
.start(WORKER_THREADS);
|
||||
}
|
||||
|
||||
/**
|
||||
* C->S : Handshake State=2
|
||||
* C->S : Login Start
|
||||
* S->C : Encryption Key Request
|
||||
* (Client Auth)
|
||||
* C->S : Encryption Key Response
|
||||
* (Server Auth, Both enable encryption)
|
||||
* S->C : Login Success (*)
|
||||
*
|
||||
* On offline logins is Login Start followed by Login Success
|
||||
*/
|
||||
@Override
|
||||
public void onPacketReceiving(PacketEvent packetEvent) {
|
||||
if (packetEvent.isCancelled()
|
||||
|| plugin.getCore().getAuthPluginHook()== null || !plugin.isServerFullyStarted()) {
|
||||
|| plugin.getCore().getAuthPluginHook()== null
|
||||
|| !plugin.isServerFullyStarted()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Player player = packetEvent.getPlayer();
|
||||
Player sender = packetEvent.getPlayer();
|
||||
PacketType packetType = packetEvent.getPacketType();
|
||||
if (packetType == Client.START) {
|
||||
onLogin(packetEvent, sender);
|
||||
} else {
|
||||
onEncryptionBegin(packetEvent, sender);
|
||||
}
|
||||
}
|
||||
|
||||
private void onEncryptionBegin(PacketEvent packetEvent, Player sender) {
|
||||
byte[] sharedSecret = packetEvent.getPacket().getByteArrays().read(0);
|
||||
|
||||
packetEvent.getAsyncMarker().incrementProcessingDelay();
|
||||
Runnable verifyTask = new VerifyResponseTask(plugin, packetEvent, sender, sharedSecret);
|
||||
Bukkit.getScheduler().runTaskAsynchronously(plugin, verifyTask);
|
||||
}
|
||||
|
||||
private void onLogin(PacketEvent packetEvent, Player player) {
|
||||
//this includes ip:port. Should be unique for an incoming login request with a timeout of 2 minutes
|
||||
String sessionKey = player.getAddress().toString();
|
||||
|
||||
@@ -77,7 +77,7 @@ public class StartPacketListener extends PacketAdapter {
|
||||
plugin.getLogger().log(Level.FINER, "Player {0} with {1} connecting", new Object[]{sessionKey, username});
|
||||
|
||||
packetEvent.getAsyncMarker().incrementProcessingDelay();
|
||||
NameCheckTask nameCheckTask = new NameCheckTask(plugin, packetEvent, random, player, username);
|
||||
Runnable nameCheckTask = new NameCheckTask(plugin, packetEvent, random, player, username);
|
||||
Bukkit.getScheduler().runTaskAsynchronously(plugin, nameCheckTask);
|
||||
}
|
||||
}
|
||||
+3
-2
@@ -17,6 +17,7 @@ import com.github.games647.fastlogin.bukkit.FastLoginBukkit;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.math.BigInteger;
|
||||
import java.security.Key;
|
||||
import java.security.PrivateKey;
|
||||
import java.util.Arrays;
|
||||
import java.util.UUID;
|
||||
@@ -47,7 +48,7 @@ public class VerifyResponseTask implements Runnable {
|
||||
try {
|
||||
BukkitLoginSession session = plugin.getLoginSessions().get(fromPlayer.getAddress().toString());
|
||||
if (session == null) {
|
||||
disconnect(plugin.getCore().getMessage("invalid-requst"), true
|
||||
disconnect(plugin.getCore().getMessage("invalid-request"), true
|
||||
, "Player {0} tried to send encryption response at invalid state", fromPlayer.getAddress());
|
||||
} else {
|
||||
verifyResponse(session);
|
||||
@@ -106,7 +107,7 @@ public class VerifyResponseTask implements Runnable {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean checkVerifyToken(BukkitLoginSession session, PrivateKey privateKey) {
|
||||
private boolean checkVerifyToken(BukkitLoginSession session, Key privateKey) {
|
||||
byte[] requestVerify = session.getVerifyToken();
|
||||
//encrypted verify token
|
||||
byte[] responseVerify = packetEvent.getPacket().getByteArrays().read(1);
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
# project informations for Bukkit in order to register our plugin with all it components
|
||||
# project data for Bukkit in order to register our plugin with all it components
|
||||
# ${-} are variables from Maven (pom.xml) which will be replaced after the build
|
||||
name: ${project.parent.name}
|
||||
version: ${project.version}-git${git.commit.id}
|
||||
main: ${project.groupId}.${project.artifactId}.${project.name}
|
||||
|
||||
# meta informations for plugin managers
|
||||
# meta data for plugin managers
|
||||
authors: [games647, 'https://github.com/games647/FastLogin/graphs/contributors']
|
||||
description: |
|
||||
${project.description}
|
||||
@@ -55,4 +55,4 @@ permissions:
|
||||
${project.artifactId}.command.cracked.other:
|
||||
description: 'Label others as cracked'
|
||||
children:
|
||||
${project.artifactId}.command.cracked: true
|
||||
${project.artifactId}.command.cracked: true
|
||||
Reference in new issue
Block a user