diff options
author | Nassim Jahnke <[email protected]> | 2024-12-21 13:45:04 +0100 |
---|---|---|
committer | Nassim Jahnke <[email protected]> | 2024-12-21 13:45:04 +0100 |
commit | 3b0b3a0aef5863b37f252bfffef7ff5b9b266445 (patch) | |
tree | d6088aef454eff0d163847ebdcc5eb349fcac9bb /paper-server/patches/features/0005-Use-Velocity-compression-and-cipher-natives.patch | |
parent | 82216a59fef17863c86192c2754417480baa71c1 (diff) | |
download | Paper-3b0b3a0aef5863b37f252bfffef7ff5b9b266445.tar.gz Paper-3b0b3a0aef5863b37f252bfffef7ff5b9b266445.zip |
and some more
Diffstat (limited to 'paper-server/patches/features/0005-Use-Velocity-compression-and-cipher-natives.patch')
-rw-r--r-- | paper-server/patches/features/0005-Use-Velocity-compression-and-cipher-natives.patch | 354 |
1 files changed, 354 insertions, 0 deletions
diff --git a/paper-server/patches/features/0005-Use-Velocity-compression-and-cipher-natives.patch b/paper-server/patches/features/0005-Use-Velocity-compression-and-cipher-natives.patch new file mode 100644 index 0000000000..9011d342f0 --- /dev/null +++ b/paper-server/patches/features/0005-Use-Velocity-compression-and-cipher-natives.patch @@ -0,0 +1,354 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Andrew Steinborn <[email protected]> +Date: Mon, 26 Jul 2021 02:15:17 -0400 +Subject: [PATCH] Use Velocity compression and cipher natives + + +diff --git a/net/minecraft/network/CipherDecoder.java b/net/minecraft/network/CipherDecoder.java +index 429325ffb7db2b85ed271ddf3da64c6fdc593673..d764552aea825af7bbf0f47c9d88af527d9dbe62 100644 +--- a/net/minecraft/network/CipherDecoder.java ++++ b/net/minecraft/network/CipherDecoder.java +@@ -7,14 +7,30 @@ import java.util.List; + import javax.crypto.Cipher; + + public class CipherDecoder extends MessageToMessageDecoder<ByteBuf> { +- private final CipherBase cipher; ++ private final com.velocitypowered.natives.encryption.VelocityCipher cipher; // Paper - Use Velocity cipher + +- public CipherDecoder(Cipher cipher) { +- this.cipher = new CipherBase(cipher); ++ public CipherDecoder(com.velocitypowered.natives.encryption.VelocityCipher cipher) { // Paper - Use Velocity cipher ++ this.cipher = cipher; // Paper - Use Velocity cipher + } + + @Override + protected void decode(ChannelHandlerContext context, ByteBuf in, List<Object> out) throws Exception { +- out.add(this.cipher.decipher(context, in)); ++ // Paper start - Use Velocity cipher ++ ByteBuf compatible = com.velocitypowered.natives.util.MoreByteBufUtils.ensureCompatible(context.alloc(), this.cipher, in); ++ try { ++ this.cipher.process(compatible); ++ out.add(compatible); ++ } catch (Exception e) { ++ compatible.release(); // compatible will never be used if we throw an exception ++ throw e; ++ } ++ // Paper end - Use Velocity cipher + } ++ ++ // Paper start - Use Velocity cipher ++ @Override ++ public void handlerRemoved(ChannelHandlerContext ctx) { ++ this.cipher.close(); ++ } ++ // Paper end - Use Velocity cipher + } +diff --git a/net/minecraft/network/CipherEncoder.java b/net/minecraft/network/CipherEncoder.java +index 992b9c7aed57ce29cdd2b4f66737d39db214f0cf..b927c85923147d2b346e892a3e4deee48b3d073e 100644 +--- a/net/minecraft/network/CipherEncoder.java ++++ b/net/minecraft/network/CipherEncoder.java +@@ -5,15 +5,31 @@ import io.netty.channel.ChannelHandlerContext; + import io.netty.handler.codec.MessageToByteEncoder; + import javax.crypto.Cipher; + +-public class CipherEncoder extends MessageToByteEncoder<ByteBuf> { +- private final CipherBase cipher; ++public class CipherEncoder extends io.netty.handler.codec.MessageToMessageEncoder<ByteBuf> { // Paper - Use Velocity cipher; change superclass ++ private final com.velocitypowered.natives.encryption.VelocityCipher cipher; // Paper - Use Velocity cipher + +- public CipherEncoder(Cipher cipher) { +- this.cipher = new CipherBase(cipher); ++ public CipherEncoder(com.velocitypowered.natives.encryption.VelocityCipher cipher) { // Paper - Use Velocity cipher ++ this.cipher = cipher; // Paper - Use Velocity cipher + } + ++ // Paper start - Use Velocity cipher + @Override +- protected void encode(ChannelHandlerContext context, ByteBuf message, ByteBuf out) throws Exception { +- this.cipher.encipher(message, out); ++ protected void encode(ChannelHandlerContext context, ByteBuf message, java.util.List<Object> list) throws Exception { ++ ByteBuf compatible = com.velocitypowered.natives.util.MoreByteBufUtils.ensureCompatible(context.alloc(), this.cipher, message); ++ try { ++ this.cipher.process(compatible); ++ list.add(compatible); ++ } catch (Exception e) { ++ compatible.release(); // compatible will never be used if we throw an exception ++ throw e; ++ } ++ // Paper end - Use Velocity cipher + } ++ ++ // Paper start - Use Velocity cipher ++ @Override ++ public void handlerRemoved(ChannelHandlerContext ctx) { ++ this.cipher.close(); ++ } ++ // Paper end - Use Velocity cipher + } +diff --git a/net/minecraft/network/CompressionDecoder.java b/net/minecraft/network/CompressionDecoder.java +index fcf0e557fbcbd5f306625096d859578fe8511734..2c7f935fcecb24a4394fdde523219a5b5984a673 100644 +--- a/net/minecraft/network/CompressionDecoder.java ++++ b/net/minecraft/network/CompressionDecoder.java +@@ -12,14 +12,22 @@ import java.util.zip.Inflater; + public class CompressionDecoder extends ByteToMessageDecoder { + public static final int MAXIMUM_COMPRESSED_LENGTH = 2097152; + public static final int MAXIMUM_UNCOMPRESSED_LENGTH = 8388608; ++ private com.velocitypowered.natives.compression.VelocityCompressor compressor; // Paper - Use Velocity cipher + private Inflater inflater; + private int threshold; + private boolean validateDecompressed; + ++ // Paper start - Use Velocity cipher ++ @io.papermc.paper.annotation.DoNotUse + public CompressionDecoder(int threshold, boolean validateDecompressed) { ++ this(null, threshold, validateDecompressed); ++ } ++ public CompressionDecoder(com.velocitypowered.natives.compression.VelocityCompressor compressor, int threshold, boolean validateDecompressed) { + this.threshold = threshold; + this.validateDecompressed = validateDecompressed; +- this.inflater = new Inflater(); ++ this.inflater = compressor == null ? new Inflater() : null; ++ this.compressor = compressor; ++ // Paper end - Use Velocity cipher + } + + @Override +@@ -39,14 +47,42 @@ public class CompressionDecoder extends ByteToMessageDecoder { + } + } + ++ if (inflater != null) { // Paper - Use Velocity cipher; fallback to vanilla inflater + this.setupInflaterInput(in); + ByteBuf byteBuf = this.inflate(context, i); + this.inflater.reset(); + out.add(byteBuf); ++ return; // Paper - Use Velocity cipher ++ } // Paper - use velocity compression ++ ++ // Paper start - Use Velocity cipher ++ int claimedUncompressedSize = i; // OBFHELPER ++ ByteBuf compatibleIn = com.velocitypowered.natives.util.MoreByteBufUtils.ensureCompatible(context.alloc(), this.compressor, in); ++ ByteBuf uncompressed = com.velocitypowered.natives.util.MoreByteBufUtils.preferredBuffer(context.alloc(), this.compressor, claimedUncompressedSize); ++ try { ++ this.compressor.inflate(compatibleIn, uncompressed, claimedUncompressedSize); ++ out.add(uncompressed); ++ in.clear(); ++ } catch (Exception e) { ++ uncompressed.release(); ++ throw e; ++ } finally { ++ compatibleIn.release(); ++ } ++ // Paper end - Use Velocity cipher + } + } + } + ++ // Paper start - Use Velocity cipher ++ @Override ++ public void handlerRemoved0(ChannelHandlerContext ctx) { ++ if (this.compressor != null) { ++ this.compressor.close(); ++ } ++ } ++ // Paper end - Use Velocity cipher ++ + private void setupInflaterInput(ByteBuf buffer) { + ByteBuffer byteBuffer; + if (buffer.nioBufferCount() > 0) { +@@ -81,7 +117,13 @@ public class CompressionDecoder extends ByteToMessageDecoder { + } + } + +- public void setThreshold(int threshold, boolean validateDecompressed) { ++ // Paper start - Use Velocity cipher ++ public void setThreshold(com.velocitypowered.natives.compression.VelocityCompressor compressor, int threshold, boolean validateDecompressed) { ++ if (this.compressor == null && compressor != null) { // Only re-configure once. Re-reconfiguring would require closing the native compressor. ++ this.compressor = compressor; ++ this.inflater = null; ++ } ++ // Paper end - Use Velocity cipher + this.threshold = threshold; + this.validateDecompressed = validateDecompressed; + } +diff --git a/net/minecraft/network/CompressionEncoder.java b/net/minecraft/network/CompressionEncoder.java +index bc674b08a41d5529fe06c6d3f077051cf4138f73..ea8a894158c44c2e7943dea43ecd8e1f0075b18f 100644 +--- a/net/minecraft/network/CompressionEncoder.java ++++ b/net/minecraft/network/CompressionEncoder.java +@@ -6,17 +6,31 @@ import io.netty.handler.codec.MessageToByteEncoder; + import java.util.zip.Deflater; + + public class CompressionEncoder extends MessageToByteEncoder<ByteBuf> { +- private final byte[] encodeBuf = new byte[8192]; ++ @javax.annotation.Nullable private final byte[] encodeBuf; // Paper - Use Velocity cipher ++ @javax.annotation.Nullable // Paper - Use Velocity cipher + private final Deflater deflater; ++ @javax.annotation.Nullable private final com.velocitypowered.natives.compression.VelocityCompressor compressor; // Paper - Use Velocity cipher + private int threshold; + ++ // Paper start - Use Velocity cipher + public CompressionEncoder(int threshold) { ++ this(null, threshold); ++ } ++ public CompressionEncoder(@javax.annotation.Nullable com.velocitypowered.natives.compression.VelocityCompressor compressor, int threshold) { + this.threshold = threshold; +- this.deflater = new Deflater(); ++ if (compressor == null) { ++ this.encodeBuf = new byte[8192]; ++ this.deflater = new Deflater(); ++ } else { ++ this.encodeBuf = null; ++ this.deflater = null; ++ } ++ this.compressor = compressor; ++ // Paper end - Use Velocity cipher + } + + @Override +- protected void encode(ChannelHandlerContext context, ByteBuf encodingByteBuf, ByteBuf byteBuf) { ++ protected void encode(ChannelHandlerContext context, ByteBuf encodingByteBuf, ByteBuf byteBuf) throws Exception { // Paper - Use Velocity cipher + int i = encodingByteBuf.readableBytes(); + if (i > 8388608) { + throw new IllegalArgumentException("Packet too big (is " + i + ", should be less than 8388608)"); +@@ -25,6 +39,7 @@ public class CompressionEncoder extends MessageToByteEncoder<ByteBuf> { + VarInt.write(byteBuf, 0); + byteBuf.writeBytes(encodingByteBuf); + } else { ++ if (this.deflater != null) { // Paper - Use Velocity cipher + byte[] bytes = new byte[i]; + encodingByteBuf.readBytes(bytes); + VarInt.write(byteBuf, bytes.length); +@@ -37,6 +52,17 @@ public class CompressionEncoder extends MessageToByteEncoder<ByteBuf> { + } + + this.deflater.reset(); ++ // Paper start - Use Velocity cipher ++ return; ++ } ++ ++ VarInt.write(byteBuf, i); ++ final ByteBuf compatibleIn = com.velocitypowered.natives.util.MoreByteBufUtils.ensureCompatible(context.alloc(), this.compressor, encodingByteBuf); ++ try { ++ this.compressor.deflate(compatibleIn, byteBuf); ++ } finally { ++ compatibleIn.release(); ++ } + } + } + } +@@ -48,4 +74,31 @@ public class CompressionEncoder extends MessageToByteEncoder<ByteBuf> { + public void setThreshold(int threshold) { + this.threshold = threshold; + } ++ ++ // Paper start - Use Velocity cipher ++ @Override ++ protected ByteBuf allocateBuffer(ChannelHandlerContext ctx, ByteBuf msg, boolean preferDirect) throws Exception { ++ if (this.compressor != null) { ++ // We allocate bytes to be compressed plus 1 byte. This covers two cases: ++ // ++ // - Compression ++ // According to https://github.com/ebiggers/libdeflate/blob/master/libdeflate.h#L103, ++ // if the data compresses well (and we do not have some pathological case) then the maximum ++ // size the compressed size will ever be is the input size minus one. ++ // - Uncompressed ++ // This is fairly obvious - we will then have one more than the uncompressed size. ++ final int initialBufferSize = msg.readableBytes() + 1; ++ return com.velocitypowered.natives.util.MoreByteBufUtils.preferredBuffer(ctx.alloc(), this.compressor, initialBufferSize); ++ } ++ ++ return super.allocateBuffer(ctx, msg, preferDirect); ++ } ++ ++ @Override ++ public void handlerRemoved(ChannelHandlerContext ctx) { ++ if (this.compressor != null) { ++ this.compressor.close(); ++ } ++ } ++ // Paper end - Use Velocity cipher + } +diff --git a/net/minecraft/network/Connection.java b/net/minecraft/network/Connection.java +index ad8f8428b75e37097487cdfbd0db2421ee4cbe37..208efae06c7c44f220d4192219a86ec55c98a2fe 100644 +--- a/net/minecraft/network/Connection.java ++++ b/net/minecraft/network/Connection.java +@@ -772,11 +772,22 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> { + return connection; + } + +- public void setEncryptionKey(Cipher decryptingCipher, Cipher encryptingCipher) { +- this.encrypted = true; +- this.channel.pipeline().addBefore("splitter", "decrypt", new CipherDecoder(decryptingCipher)); +- this.channel.pipeline().addBefore("prepender", "encrypt", new CipherEncoder(encryptingCipher)); ++ // Paper start - Use Velocity cipher ++ public void setEncryptionKey(javax.crypto.SecretKey key) throws net.minecraft.util.CryptException { ++ if (!this.encrypted) { ++ try { ++ com.velocitypowered.natives.encryption.VelocityCipher decryptionCipher = com.velocitypowered.natives.util.Natives.cipher.get().forDecryption(key); ++ com.velocitypowered.natives.encryption.VelocityCipher encryptionCipher = com.velocitypowered.natives.util.Natives.cipher.get().forEncryption(key); ++ ++ this.encrypted = true; ++ this.channel.pipeline().addBefore("splitter", "decrypt", new CipherDecoder(decryptionCipher)); ++ this.channel.pipeline().addBefore("prepender", "encrypt", new CipherEncoder(encryptionCipher)); ++ } catch (java.security.GeneralSecurityException e) { ++ throw new net.minecraft.util.CryptException(e); ++ } ++ } + } ++ // Paper end - Use Velocity cipher + + public boolean isEncrypted() { + return this.encrypted; +@@ -815,16 +826,17 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> { + // Paper end - add proper async disconnect + public void setupCompression(int threshold, boolean validateDecompressed) { + if (threshold >= 0) { ++ com.velocitypowered.natives.compression.VelocityCompressor compressor = com.velocitypowered.natives.util.Natives.compress.get().create(io.papermc.paper.configuration.GlobalConfiguration.get().misc.compressionLevel.or(-1)); // Paper - Use Velocity cipher + if (this.channel.pipeline().get("decompress") instanceof CompressionDecoder compressionDecoder) { +- compressionDecoder.setThreshold(threshold, validateDecompressed); ++ compressionDecoder.setThreshold(compressor, threshold, validateDecompressed); // Paper - Use Velocity cipher + } else { +- this.channel.pipeline().addAfter("splitter", "decompress", new CompressionDecoder(threshold, validateDecompressed)); ++ this.channel.pipeline().addAfter("splitter", "decompress", new CompressionDecoder(compressor, threshold, validateDecompressed)); // Paper - Use Velocity cipher + } + + if (this.channel.pipeline().get("compress") instanceof CompressionEncoder compressionEncoder) { + compressionEncoder.setThreshold(threshold); + } else { +- this.channel.pipeline().addAfter("prepender", "compress", new CompressionEncoder(threshold)); ++ this.channel.pipeline().addAfter("prepender", "compress", new CompressionEncoder(compressor, threshold)); // Paper - Use Velocity cipher + } + this.channel.pipeline().fireUserEventTriggered(io.papermc.paper.network.ConnectionEvent.COMPRESSION_THRESHOLD_SET); // Paper - Add Channel initialization listeners + } else { +diff --git a/net/minecraft/server/network/ServerConnectionListener.java b/net/minecraft/server/network/ServerConnectionListener.java +index 7de11ba404f0b60e7f7b7c16954811a343688219..bd07e6a5aa1883786d789ea71711a0c0c0a95c26 100644 +--- a/net/minecraft/server/network/ServerConnectionListener.java ++++ b/net/minecraft/server/network/ServerConnectionListener.java +@@ -108,6 +108,10 @@ public class ServerConnectionListener { + LOGGER.warn("Using HAProxy, please ensure the server port is adequately firewalled."); + } + // Paper end - Warn people with console access that HAProxy is in use. ++ // Paper start - Use Velocity cipher ++ ServerConnectionListener.LOGGER.info("Paper: Using " + com.velocitypowered.natives.util.Natives.compress.getLoadedVariant() + " compression from Velocity."); ++ ServerConnectionListener.LOGGER.info("Paper: Using " + com.velocitypowered.natives.util.Natives.cipher.getLoadedVariant() + " cipher from Velocity."); ++ // Paper end - Use Velocity cipher + + this.channels + .add( +diff --git a/net/minecraft/server/network/ServerLoginPacketListenerImpl.java b/net/minecraft/server/network/ServerLoginPacketListenerImpl.java +index bb28453d230921d662ed69c8dd48021f428ef060..6689aeacf50d1498e8d23cce696fb4fecbd1cf39 100644 +--- a/net/minecraft/server/network/ServerLoginPacketListenerImpl.java ++++ b/net/minecraft/server/network/ServerLoginPacketListenerImpl.java +@@ -276,11 +276,9 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener, + } + + SecretKey secretKey = packet.getSecretKey(_private); +- Cipher cipher = Crypt.getCipher(2, secretKey); +- Cipher cipher1 = Crypt.getCipher(1, secretKey); + string = new BigInteger(Crypt.digestData("", this.server.getKeyPair().getPublic(), secretKey)).toString(16); + this.state = ServerLoginPacketListenerImpl.State.AUTHENTICATING; +- this.connection.setEncryptionKey(cipher, cipher1); ++ this.connection.setEncryptionKey(secretKey); // Paper - Use Velocity cipher + } catch (CryptException var7) { + throw new IllegalStateException("Protocol error", var7); + } |