geforkt von Mirrors/Velocity
Add some needed utilities for encryption
Dieser Commit ist enthalten in:
Ursprung
ab965108d6
Commit
b26a17e587
@ -4,6 +4,7 @@ import com.velocitypowered.proxy.connection.MinecraftConnection;
|
|||||||
import com.velocitypowered.proxy.protocol.StateRegistry;
|
import com.velocitypowered.proxy.protocol.StateRegistry;
|
||||||
import com.velocitypowered.proxy.protocol.netty.MinecraftPipelineUtils;
|
import com.velocitypowered.proxy.protocol.netty.MinecraftPipelineUtils;
|
||||||
import com.velocitypowered.proxy.connection.client.HandshakeSessionHandler;
|
import com.velocitypowered.proxy.connection.client.HandshakeSessionHandler;
|
||||||
|
import com.velocitypowered.proxy.protocol.packets.EncryptionRequest;
|
||||||
import io.netty.bootstrap.Bootstrap;
|
import io.netty.bootstrap.Bootstrap;
|
||||||
import io.netty.bootstrap.ServerBootstrap;
|
import io.netty.bootstrap.ServerBootstrap;
|
||||||
import io.netty.channel.*;
|
import io.netty.channel.*;
|
||||||
@ -30,6 +31,10 @@ public class VelocityServer {
|
|||||||
return server;
|
return server;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public KeyPair getServerKeyPair() {
|
||||||
|
return serverKeyPair;
|
||||||
|
}
|
||||||
|
|
||||||
public void initialize() {
|
public void initialize() {
|
||||||
// Create a key pair
|
// Create a key pair
|
||||||
try {
|
try {
|
||||||
|
@ -3,6 +3,7 @@ package com.velocitypowered.proxy.connection.client;
|
|||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Preconditions;
|
||||||
import com.velocitypowered.proxy.protocol.MinecraftPacket;
|
import com.velocitypowered.proxy.protocol.MinecraftPacket;
|
||||||
import com.velocitypowered.proxy.protocol.StateRegistry;
|
import com.velocitypowered.proxy.protocol.StateRegistry;
|
||||||
|
import com.velocitypowered.proxy.protocol.packets.EncryptionRequest;
|
||||||
import com.velocitypowered.proxy.protocol.packets.ServerLogin;
|
import com.velocitypowered.proxy.protocol.packets.ServerLogin;
|
||||||
import com.velocitypowered.proxy.protocol.packets.ServerLoginSuccess;
|
import com.velocitypowered.proxy.protocol.packets.ServerLoginSuccess;
|
||||||
import com.velocitypowered.proxy.connection.MinecraftConnection;
|
import com.velocitypowered.proxy.connection.MinecraftConnection;
|
||||||
@ -13,9 +14,11 @@ import com.velocitypowered.proxy.data.ServerInfo;
|
|||||||
import com.velocitypowered.proxy.util.UuidUtils;
|
import com.velocitypowered.proxy.util.UuidUtils;
|
||||||
|
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
|
import java.util.concurrent.ThreadLocalRandom;
|
||||||
|
|
||||||
public class LoginSessionHandler implements MinecraftSessionHandler {
|
public class LoginSessionHandler implements MinecraftSessionHandler {
|
||||||
private final MinecraftConnection inbound;
|
private final MinecraftConnection inbound;
|
||||||
|
private ServerLogin login;
|
||||||
|
|
||||||
public LoginSessionHandler(MinecraftConnection inbound) {
|
public LoginSessionHandler(MinecraftConnection inbound) {
|
||||||
this.inbound = Preconditions.checkNotNull(inbound, "inbound");
|
this.inbound = Preconditions.checkNotNull(inbound, "inbound");
|
||||||
@ -23,12 +26,27 @@ public class LoginSessionHandler implements MinecraftSessionHandler {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handle(MinecraftPacket packet) {
|
public void handle(MinecraftPacket packet) {
|
||||||
Preconditions.checkArgument(packet instanceof ServerLogin, "Expected a ServerLogin packet, not " + packet.getClass().getName());
|
if (packet instanceof ServerLogin) {
|
||||||
|
this.login = (ServerLogin) packet;
|
||||||
|
// TODO: Online-mode checks
|
||||||
|
handleSuccessfulLogin();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Encryption
|
private EncryptionRequest generateRequest() {
|
||||||
|
byte[] verify = new byte[4];
|
||||||
|
ThreadLocalRandom.current().nextBytes(verify);
|
||||||
|
|
||||||
|
EncryptionRequest request = new EncryptionRequest();
|
||||||
|
request.setPublicKey(VelocityServer.getServer().getServerKeyPair().getPublic().getEncoded());
|
||||||
|
request.setVerifyToken(verify);
|
||||||
|
return request;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleSuccessfulLogin() {
|
||||||
inbound.setCompressionThreshold(256);
|
inbound.setCompressionThreshold(256);
|
||||||
|
|
||||||
String username = ((ServerLogin) packet).getUsername();
|
String username = login.getUsername();
|
||||||
ServerLoginSuccess success = new ServerLoginSuccess();
|
ServerLoginSuccess success = new ServerLoginSuccess();
|
||||||
success.setUsername(username);
|
success.setUsername(username);
|
||||||
success.setUuid(UuidUtils.generateOfflinePlayerUuid(username));
|
success.setUuid(UuidUtils.generateOfflinePlayerUuid(username));
|
||||||
@ -43,5 +61,4 @@ public class LoginSessionHandler implements MinecraftSessionHandler {
|
|||||||
inbound.setSessionHandler(new InitialConnectSessionHandler(player));
|
inbound.setSessionHandler(new InitialConnectSessionHandler(player));
|
||||||
connection.connect();
|
connection.connect();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -34,6 +34,7 @@ public enum StateRegistry {
|
|||||||
LOGIN {
|
LOGIN {
|
||||||
{
|
{
|
||||||
TO_SERVER.register(0x00, ServerLogin.class, ServerLogin::new);
|
TO_SERVER.register(0x00, ServerLogin.class, ServerLogin::new);
|
||||||
|
TO_SERVER.register(0x01, EncryptionResponse.class, EncryptionResponse::new);
|
||||||
|
|
||||||
TO_CLIENT.register(0x00, Disconnect.class, Disconnect::new);
|
TO_CLIENT.register(0x00, Disconnect.class, Disconnect::new);
|
||||||
TO_CLIENT.register(0x01, EncryptionRequest.class, EncryptionRequest::new);
|
TO_CLIENT.register(0x01, EncryptionRequest.class, EncryptionRequest::new);
|
||||||
|
@ -1,13 +1,12 @@
|
|||||||
package com.velocitypowered.proxy.protocol.compression;
|
package com.velocitypowered.proxy.protocol.compression;
|
||||||
|
|
||||||
|
import com.velocitypowered.proxy.util.Disposable;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
|
|
||||||
import java.util.zip.DataFormatException;
|
import java.util.zip.DataFormatException;
|
||||||
|
|
||||||
public interface VelocityCompressor {
|
public interface VelocityCompressor extends Disposable {
|
||||||
void inflate(ByteBuf source, ByteBuf destination) throws DataFormatException;
|
void inflate(ByteBuf source, ByteBuf destination) throws DataFormatException;
|
||||||
|
|
||||||
void deflate(ByteBuf source, ByteBuf destination) throws DataFormatException;
|
void deflate(ByteBuf source, ByteBuf destination) throws DataFormatException;
|
||||||
|
|
||||||
void dispose();
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,8 @@
|
|||||||
|
package com.velocitypowered.proxy.protocol.encryption;
|
||||||
|
|
||||||
|
import com.velocitypowered.proxy.util.Disposable;
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
|
||||||
|
public interface VelocityEncryptor extends Disposable {
|
||||||
|
void process(ByteBuf source, ByteBuf destination);
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
package com.velocitypowered.proxy.protocol.packets;
|
||||||
|
|
||||||
|
import com.velocitypowered.proxy.protocol.MinecraftPacket;
|
||||||
|
import com.velocitypowered.proxy.protocol.ProtocolConstants;
|
||||||
|
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
|
||||||
|
public class EncryptionResponse implements MinecraftPacket {
|
||||||
|
private byte[] sharedSecret;
|
||||||
|
private byte[] verifyToken;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void decode(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) {
|
||||||
|
this.sharedSecret = ProtocolUtils.readByteArray(buf, 256);
|
||||||
|
this.verifyToken = ProtocolUtils.readByteArray(buf, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void encode(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) {
|
||||||
|
ProtocolUtils.writeByteArray(buf, sharedSecret);
|
||||||
|
ProtocolUtils.writeByteArray(buf, verifyToken);
|
||||||
|
}
|
||||||
|
}
|
9
src/main/java/com/velocitypowered/proxy/util/Disposable.java
Normale Datei
9
src/main/java/com/velocitypowered/proxy/util/Disposable.java
Normale Datei
@ -0,0 +1,9 @@
|
|||||||
|
package com.velocitypowered.proxy.util;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This marker interface indicates that this object should be explicitly disposed before the object can no longer be used.
|
||||||
|
* Not disposing these objects will likely leak native resources and eventually lead to resource exhaustion.
|
||||||
|
*/
|
||||||
|
public interface Disposable {
|
||||||
|
void dispose();
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
package com.velocitypowered.proxy.util;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
|
||||||
|
public enum EncryptionUtils { ;
|
||||||
|
public static String twoComplementsSha1Digest(byte[] digest) {
|
||||||
|
return new BigInteger(digest).toString(16);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
package com.velocitypowered.proxy.util;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.security.MessageDigest;
|
||||||
|
|
||||||
|
public class EncryptionUtilsTest {
|
||||||
|
@Test
|
||||||
|
public void twoComplementsSha1Digest() throws Exception {
|
||||||
|
String notchHash = hexDigest("Notch");
|
||||||
|
Assert.assertEquals("4ed1f46bbe04bc756bcb17c0c7ce3e4632f06a48", notchHash);
|
||||||
|
|
||||||
|
String jebHash = hexDigest("jeb_");
|
||||||
|
Assert.assertEquals("-7c9d5b0044c130109a5d7b5fb5c317c02b4e28c1", jebHash);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String hexDigest(String str) throws Exception {
|
||||||
|
MessageDigest digest = MessageDigest.getInstance("SHA-1");
|
||||||
|
digest.update(str.getBytes(StandardCharsets.UTF_8));
|
||||||
|
byte[] digested = digest.digest();
|
||||||
|
return EncryptionUtils.twoComplementsSha1Digest(digested);
|
||||||
|
}
|
||||||
|
}
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren