Merge pull request #149 from Minestom/authlib-removal

Stop using authlib
This commit is contained in:
TheMode 2021-05-15 07:53:35 +02:00 committed by GitHub
commit 3bd389fb57
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 50 additions and 37 deletions

View File

@ -160,7 +160,6 @@ dependencies {
// Guava 21.0+ required for Mixin, but Authlib imports 17.0 // Guava 21.0+ required for Mixin, but Authlib imports 17.0
api 'com.google.guava:guava:30.1-jre' api 'com.google.guava:guava:30.1-jre'
api 'com.mojang:authlib:1.5.21'
// Code modification // Code modification
api "org.ow2.asm:asm:${asmVersion}" api "org.ow2.asm:asm:${asmVersion}"

View File

@ -3,8 +3,8 @@ package net.minestom.server.entity.metadata.animal;
import net.minestom.server.entity.Entity; import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Metadata; import net.minestom.server.entity.Metadata;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.annotation.Nullable;
import java.util.UUID; import java.util.UUID;
public class FoxMeta extends AnimalMeta { public class FoxMeta extends AnimalMeta {

View File

@ -1,14 +1,10 @@
package net.minestom.server.extras; package net.minestom.server.extras;
import com.mojang.authlib.AuthenticationService;
import com.mojang.authlib.minecraft.MinecraftSessionService;
import com.mojang.authlib.yggdrasil.YggdrasilAuthenticationService;
import net.minestom.server.MinecraftServer; import net.minestom.server.MinecraftServer;
import net.minestom.server.extras.mojangAuth.MojangCrypt; import net.minestom.server.extras.mojangAuth.MojangCrypt;
import net.minestom.server.utils.validate.Check; import net.minestom.server.utils.validate.Check;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.net.Proxy;
import java.security.KeyPair; import java.security.KeyPair;
public final class MojangAuth { public final class MojangAuth {
@ -16,8 +12,6 @@ public final class MojangAuth {
private static volatile boolean enabled = false; private static volatile boolean enabled = false;
private static KeyPair keyPair; private static KeyPair keyPair;
private static AuthenticationService authService;
private static MinecraftSessionService sessionService;
/** /**
* Enables mojang authentication on the server. * Enables mojang authentication on the server.
@ -32,8 +26,6 @@ public final class MojangAuth {
// Generate necessary fields... // Generate necessary fields...
keyPair = MojangCrypt.generateKeyPair(); keyPair = MojangCrypt.generateKeyPair();
authService = new YggdrasilAuthenticationService(Proxy.NO_PROXY, "");
sessionService = authService.createMinecraftSessionService();
} }
public static boolean isEnabled() { public static boolean isEnabled() {
@ -44,14 +36,4 @@ public final class MojangAuth {
public static KeyPair getKeyPair() { public static KeyPair getKeyPair() {
return keyPair; return keyPair;
} }
@Nullable
public static AuthenticationService getAuthService() {
return authService;
}
@Nullable
public static MinecraftSessionService getSessionService() {
return sessionService;
}
} }

View File

@ -1,7 +1,7 @@
package net.minestom.server.network.packet.client.login; package net.minestom.server.network.packet.client.login;
import com.mojang.authlib.GameProfile; import com.google.gson.Gson;
import com.mojang.authlib.exceptions.AuthenticationUnavailableException; import com.google.gson.JsonObject;
import net.minestom.server.MinecraftServer; import net.minestom.server.MinecraftServer;
import net.minestom.server.data.type.array.ByteArrayData; import net.minestom.server.data.type.array.ByteArrayData;
import net.minestom.server.extras.MojangAuth; import net.minestom.server.extras.MojangAuth;
@ -15,11 +15,16 @@ import net.minestom.server.utils.binary.BinaryWriter;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import javax.crypto.SecretKey; import javax.crypto.SecretKey;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.math.BigInteger; import java.math.BigInteger;
import java.net.URL;
import java.util.Arrays; import java.util.Arrays;
import java.util.UUID;
public class EncryptionResponsePacket implements ClientPreplayPacket { public class EncryptionResponsePacket implements ClientPreplayPacket {
private static final Gson GSON = new Gson();
private byte[] sharedSecret; private byte[] sharedSecret;
private byte[] verifyToken; private byte[] verifyToken;
@ -44,7 +49,7 @@ public class EncryptionResponsePacket implements ClientPreplayPacket {
MinecraftServer.LOGGER.error("{} tried to login with an invalid nonce!", loginUsername); MinecraftServer.LOGGER.error("{} tried to login with an invalid nonce!", loginUsername);
return; return;
} }
if (!loginUsername.isEmpty()) { if (loginUsername != null && !loginUsername.isEmpty()) {
final byte[] digestedData = MojangCrypt.digestData("", MojangAuth.getKeyPair().getPublic(), getSecretKey()); final byte[] digestedData = MojangCrypt.digestData("", MojangAuth.getKeyPair().getPublic(), getSecretKey());
@ -55,14 +60,24 @@ public class EncryptionResponsePacket implements ClientPreplayPacket {
return; return;
} }
final String string3 = new BigInteger(digestedData).toString(16); // Query Mojang's sessionserver.
final GameProfile gameProfile = MojangAuth.getSessionService().hasJoinedServer(new GameProfile(null, loginUsername), string3); final String serverId = new BigInteger(digestedData).toString(16);
nettyConnection.setEncryptionKey(getSecretKey()); InputStream gameProfileStream = new URL(
"https://sessionserver.mojang.com/session/minecraft/hasJoined?"
+ "username=" + loginUsername + "&"
+ "serverId=" + serverId
// TODO: Add ability to add ip query tag. See: https://wiki.vg/Protocol_Encryption#Authentication
).openStream();
MinecraftServer.LOGGER.info("UUID of player {} is {}", loginUsername, gameProfile.getId()); final JsonObject gameProfile = GSON.fromJson(new InputStreamReader(gameProfileStream), JsonObject.class);
CONNECTION_MANAGER.startPlayState(connection, gameProfile.getId(), gameProfile.getName(), true); nettyConnection.setEncryptionKey(getSecretKey());
UUID profileUUID = UUID.fromString(gameProfile.get("id").getAsString().replaceFirst("(\\w{8})(\\w{4})(\\w{4})(\\w{4})(\\w{12})", "$1-$2-$3-$4-$5"));
String profileName = gameProfile.get("name").getAsString();
MinecraftServer.LOGGER.info("UUID of player {} is {}", loginUsername, profileUUID);
CONNECTION_MANAGER.startPlayState(connection, profileUUID, profileName, true);
} }
} catch (AuthenticationUnavailableException e) { } catch (IOException e) {
MinecraftServer.getExceptionManager().handleException(e); MinecraftServer.getExceptionManager().handleException(e);
} }
}); });

View File

@ -5,16 +5,27 @@ import com.google.gson.JsonArray;
import com.google.gson.JsonElement; import com.google.gson.JsonElement;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import it.unimi.dsi.fastutil.io.FastBufferedInputStream; import it.unimi.dsi.fastutil.io.FastBufferedInputStream;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.io.*; import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.math.BigInteger;
import java.net.URL; import java.net.URL;
import java.nio.file.*; import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.StandardCopyOption;
import java.nio.file.attribute.BasicFileAttributes; import java.nio.file.attribute.BasicFileAttributes;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
/** /**
* Responsible for making sure Minestom has the necessary files to run (notably registry files) * Responsible for making sure Minestom has the necessary files to run (notably registry files)
@ -177,13 +188,19 @@ public class ResourceGatherer {
} }
// Verify checksum // Verify checksum
try (FileInputStream fis = new FileInputStream(target)) { try (FileInputStream fis = new FileInputStream(target)) {
String sha1Target = DigestUtils.sha1Hex(fis); MessageDigest messageDigest = MessageDigest.getInstance("SHA-1");
messageDigest.reset();
// This just converts the sha1 back into a readable string.
String sha1Target = new BigInteger(1, messageDigest.digest(fis.readAllBytes())).toString(16);
if (!sha1Target.equals(sha1Source)) { if (!sha1Target.equals(sha1Source)) {
LOGGER.debug("The checksum test failed after downloading the Minecraft server jar."); LOGGER.error("The checksum test failed after downloading the Minecraft server jar.");
LOGGER.debug("The expected checksum was: {}.", sha1Source); LOGGER.error("The expected checksum was: {}.", sha1Source);
LOGGER.debug("The calculated checksum was: {}.", sha1Target); LOGGER.error("The calculated checksum was: {}.", sha1Target);
throw new IOException("Failed to download Minecraft server jar."); throw new IOException("Failed to download Minecraft server jar.");
} }
} catch (NoSuchAlgorithmException e) {
LOGGER.error("Failed to find SHA-1 hashing algorithm in Java Environment.");
throw new IOException("Failed to download Minecraft server jar.");
} }
return target; return target;
} }