diff --git a/proxy/src/main/java/net/md_5/bungee/connection/InitialHandler.java b/proxy/src/main/java/net/md_5/bungee/connection/InitialHandler.java index 08b311a6..ebdd57dc 100644 --- a/proxy/src/main/java/net/md_5/bungee/connection/InitialHandler.java +++ b/proxy/src/main/java/net/md_5/bungee/connection/InitialHandler.java @@ -29,9 +29,10 @@ import net.md_5.bungee.api.connection.ProxiedPlayer; import net.md_5.bungee.api.event.LoginEvent; import net.md_5.bungee.api.event.PostLoginEvent; import net.md_5.bungee.api.event.ProxyPingEvent; -import net.md_5.bungee.netty.CipherCodec; import net.md_5.bungee.netty.HandlerBoss; import net.md_5.bungee.netty.ChannelWrapper; +import net.md_5.bungee.netty.CipherDecoder; +import net.md_5.bungee.netty.CipherEncoder; import net.md_5.bungee.packet.Packet2Handshake; import net.md_5.bungee.packet.PacketCDClientStatus; import net.md_5.bungee.packet.PacketFAPluginMessage; @@ -126,6 +127,9 @@ public class InitialHandler extends PacketHandler implements PendingConnection Preconditions.checkState( thisState == State.ENCRYPT, "Not expecting ENCRYPT" ); sharedKey = EncryptionUtil.getSecret( encryptResponse, request ); + Cipher decrypt = EncryptionUtil.getCipher( Cipher.DECRYPT_MODE, sharedKey ); + ch.getHandle().pipeline().addBefore( "decoder", "decrypt", new CipherDecoder( decrypt ) ); + if ( BungeeCord.getInstance().config.isOnlineMode() ) { String encName = URLEncoder.encode( InitialHandler.this.getName(), "UTF-8" ); @@ -191,12 +195,11 @@ public class InitialHandler extends PacketHandler implements PendingConnection return; } + ch.write( new PacketFCEncryptionResponse() ); try { Cipher encrypt = EncryptionUtil.getCipher( Cipher.ENCRYPT_MODE, sharedKey ); - Cipher decrypt = EncryptionUtil.getCipher( Cipher.DECRYPT_MODE, sharedKey ); - ch.write( new PacketFCEncryptionResponse() ); - ch.getHandle().pipeline().addBefore( "decoder", "cipher", new CipherCodec( encrypt, decrypt ) ); + ch.getHandle().pipeline().addBefore( "decoder", "encrypt", new CipherEncoder( encrypt ) ); thisState = InitialHandler.State.LOGIN; } catch ( GeneralSecurityException ex ) { diff --git a/proxy/src/main/java/net/md_5/bungee/netty/CipherCodec.java b/proxy/src/main/java/net/md_5/bungee/netty/CipherBase.java similarity index 53% rename from proxy/src/main/java/net/md_5/bungee/netty/CipherCodec.java rename to proxy/src/main/java/net/md_5/bungee/netty/CipherBase.java index 18e25623..44936b95 100644 --- a/proxy/src/main/java/net/md_5/bungee/netty/CipherCodec.java +++ b/proxy/src/main/java/net/md_5/bungee/netty/CipherBase.java @@ -1,21 +1,22 @@ package net.md_5.bungee.netty; import io.netty.buffer.ByteBuf; -import io.netty.channel.ChannelHandlerContext; -import io.netty.handler.codec.ByteToByteCodec; import javax.crypto.Cipher; import javax.crypto.ShortBufferException; +import lombok.NonNull; +import lombok.RequiredArgsConstructor; /** - * This class is a complete solution for encrypting and decoding bytes in a - * Netty stream. It takes two {@link Cipher} instances, used for encryption and - * decryption respectively. + * Class to expose an + * {@link #cipher(io.netty.buffer.ByteBuf, io.netty.buffer.ByteBuf)} method to + * aid in the efficient passing of ByteBuffers through a cipher. */ -public class CipherCodec extends ByteToByteCodec +@RequiredArgsConstructor +public class CipherBase { - private Cipher encrypt; - private Cipher decrypt; + @NonNull + private final Cipher cipher; private ThreadLocal heapInLocal = new EmptyByteThreadLocal(); private ThreadLocal heapOutLocal = new EmptyByteThreadLocal(); @@ -29,25 +30,7 @@ public class CipherCodec extends ByteToByteCodec } } - public CipherCodec(Cipher encrypt, Cipher decrypt) - { - this.encrypt = encrypt; - this.decrypt = decrypt; - } - - @Override - public void encode(ChannelHandlerContext ctx, ByteBuf in, ByteBuf out) throws Exception - { - cipher( in, out, encrypt ); - } - - @Override - public void decode(ChannelHandlerContext ctx, ByteBuf in, ByteBuf out) throws Exception - { - cipher( in, out, decrypt ); - } - - private void cipher(ByteBuf in, ByteBuf out, Cipher cipher) throws ShortBufferException + protected void cipher(ByteBuf in, ByteBuf out) throws ShortBufferException { byte[] heapIn = heapInLocal.get(); int readableBytes = in.readableBytes(); diff --git a/proxy/src/main/java/net/md_5/bungee/netty/CipherDecoder.java b/proxy/src/main/java/net/md_5/bungee/netty/CipherDecoder.java new file mode 100644 index 00000000..cc4055b3 --- /dev/null +++ b/proxy/src/main/java/net/md_5/bungee/netty/CipherDecoder.java @@ -0,0 +1,23 @@ +package net.md_5.bungee.netty; + +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.ByteToByteDecoder; +import javax.crypto.Cipher; + +public class CipherDecoder extends ByteToByteDecoder +{ + + private final CipherBase cipher; + + public CipherDecoder(Cipher cipher) + { + this.cipher = new CipherBase( cipher ); + } + + @Override + protected void decode(ChannelHandlerContext ctx, ByteBuf in, ByteBuf out) throws Exception + { + cipher.cipher( in, out ); + } +} diff --git a/proxy/src/main/java/net/md_5/bungee/netty/CipherEncoder.java b/proxy/src/main/java/net/md_5/bungee/netty/CipherEncoder.java new file mode 100644 index 00000000..6d5232e3 --- /dev/null +++ b/proxy/src/main/java/net/md_5/bungee/netty/CipherEncoder.java @@ -0,0 +1,23 @@ +package net.md_5.bungee.netty; + +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.ByteToByteEncoder; +import javax.crypto.Cipher; + +public class CipherEncoder extends ByteToByteEncoder +{ + + private final CipherBase cipher; + + public CipherEncoder(Cipher cipher) + { + this.cipher = new CipherBase( cipher ); + } + + @Override + protected void encode(ChannelHandlerContext ctx, ByteBuf in, ByteBuf out) throws Exception + { + cipher.cipher( in, out ); + } +}