diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000000..c950c4c5d9 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,6 @@ +[submodule "native/mbedtls"] + path = native/mbedtls + url = https://github.com/ARMmbed/mbedtls.git +[submodule "native/zlib"] + path = native/zlib + url = https://github.com/cloudflare/zlib.git diff --git a/log/src/main/java/net/md_5/bungee/log/BungeeLogger.java b/log/src/main/java/net/md_5/bungee/log/BungeeLogger.java index 68481e8200..8e2f1bf3d9 100644 --- a/log/src/main/java/net/md_5/bungee/log/BungeeLogger.java +++ b/log/src/main/java/net/md_5/bungee/log/BungeeLogger.java @@ -13,10 +13,12 @@ public class BungeeLogger extends Logger private final LogDispatcher dispatcher = new LogDispatcher( this ); + // CHECKSTYLE:OFF @SuppressWarnings( { "CallToPrintStackTrace", "CallToThreadStartDuringObjectConstruction" }) + // CHECKSTYLE:ON @SuppressFBWarnings("SC_START_IN_CTOR") public BungeeLogger(String loggerName, String filePattern, ConsoleReader reader) { diff --git a/native/compile-native.sh b/native/compile-native.sh index 98baf0e239..f37c9fddb6 100644 --- a/native/compile-native.sh +++ b/native/compile-native.sh @@ -1,6 +1,14 @@ #!/bin/sh -CXX="g++ -shared -fPIC -O3 -Wall -Werror -I$JAVA_HOME/include/ -I$JAVA_HOME/include/linux/" +set -eu -$CXX src/main/c/NativeCipherImpl.cpp -o src/main/resources/native-cipher.so -lcrypto -$CXX src/main/c/NativeCompressImpl.cpp -o src/main/resources/native-compress.so -lz +echo "Compiling mbedtls" +(cd mbedtls && make no_test) + +echo "Compiling zlib" +(cd zlib && CFLAGS=-fPIC ./configure --static && make) + +CXX="g++ -shared -fPIC -Wl,--wrap=memcpy -O3 -Wall -Werror -I$JAVA_HOME/include/ -I$JAVA_HOME/include/linux/" + +$CXX -Imbedtls/include src/main/c/NativeCipherImpl.cpp -o src/main/resources/native-cipher.so mbedtls/library/libmbedcrypto.a +$CXX -Izlib src/main/c/NativeCompressImpl.cpp -o src/main/resources/native-compress.so zlib/libz.a diff --git a/native/mbedtls b/native/mbedtls new file mode 160000 index 0000000000..e483a77c85 --- /dev/null +++ b/native/mbedtls @@ -0,0 +1 @@ +Subproject commit e483a77c85e1f9c1dd2eb1c5a8f552d2617fe400 diff --git a/native/src/main/c/NativeCipherImpl.cpp b/native/src/main/c/NativeCipherImpl.cpp index aa7a12b4a4..9de328ea2b 100644 --- a/native/src/main/c/NativeCipherImpl.cpp +++ b/native/src/main/c/NativeCipherImpl.cpp @@ -1,12 +1,15 @@ -// Support for CentOS 6 -__asm__(".symver memcpy,memcpy@GLIBC_2.2.5"); - #include #include #include #include "net_md_5_bungee_jni_cipher_NativeCipherImpl.h" +// Support for CentOS 6 +__asm__(".symver memcpy,memcpy@GLIBC_2.2.5"); +extern "C" void *__wrap_memcpy(void *dest, const void *src, size_t n) { + return memcpy(dest, src, n); +} + typedef unsigned char byte; struct crypto_context { diff --git a/native/src/main/c/NativeCompressImpl.cpp b/native/src/main/c/NativeCompressImpl.cpp index 9bda6300ca..b490ede587 100644 --- a/native/src/main/c/NativeCompressImpl.cpp +++ b/native/src/main/c/NativeCompressImpl.cpp @@ -1,7 +1,15 @@ #include +#include + #include #include "net_md_5_bungee_jni_zlib_NativeCompressImpl.h" +// Support for CentOS 6 +__asm__(".symver memcpy,memcpy@GLIBC_2.2.5"); +extern "C" void *__wrap_memcpy(void *dest, const void *src, size_t n) { + return memcpy(dest, src, n); +} + typedef unsigned char byte; static jfieldID consumedID; diff --git a/native/src/main/java/net/md_5/bungee/jni/NativeCode.java b/native/src/main/java/net/md_5/bungee/jni/NativeCode.java index 4e4130bc60..62bdaa0e8c 100644 --- a/native/src/main/java/net/md_5/bungee/jni/NativeCode.java +++ b/native/src/main/java/net/md_5/bungee/jni/NativeCode.java @@ -6,18 +6,19 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.util.function.Supplier; import net.md_5.bungee.jni.cipher.BungeeCipher; public final class NativeCode { private final String name; - private final Class javaImpl; - private final Class nativeImpl; + private final Supplier javaImpl; + private final Supplier nativeImpl; // private boolean loaded; - public NativeCode(String name, Class javaImpl, Class nativeImpl) + public NativeCode(String name, Supplier javaImpl, Supplier nativeImpl) { this.name = name; this.javaImpl = javaImpl; @@ -26,13 +27,7 @@ public NativeCode(String name, Class javaImpl, Class n public T newInstance() { - try - { - return ( loaded ) ? nativeImpl.getDeclaredConstructor().newInstance() : javaImpl.getDeclaredConstructor().newInstance(); - } catch ( ReflectiveOperationException ex ) - { - throw new RuntimeException( "Error getting instance", ex ); - } + return ( loaded ) ? nativeImpl.get() : javaImpl.get(); } public boolean load() diff --git a/native/src/main/java/net/md_5/bungee/jni/cipher/JavaCipher.java b/native/src/main/java/net/md_5/bungee/jni/cipher/JavaCipher.java index d211cef6d5..0e27c2d7e5 100644 --- a/native/src/main/java/net/md_5/bungee/jni/cipher/JavaCipher.java +++ b/native/src/main/java/net/md_5/bungee/jni/cipher/JavaCipher.java @@ -25,9 +25,15 @@ protected byte[] initialValue() } } - public JavaCipher() throws GeneralSecurityException + public JavaCipher() { - this.cipher = Cipher.getInstance( "AES/CFB8/NoPadding" ); + try + { + this.cipher = Cipher.getInstance( "AES/CFB8/NoPadding" ); + } catch ( GeneralSecurityException ex ) + { + throw new RuntimeException( ex ); + } } @Override diff --git a/native/src/main/resources/native-cipher.so b/native/src/main/resources/native-cipher.so index 8f1717b93e..8ac128df6f 100644 Binary files a/native/src/main/resources/native-cipher.so and b/native/src/main/resources/native-cipher.so differ diff --git a/native/src/main/resources/native-compress.so b/native/src/main/resources/native-compress.so index e83e4d2d96..8fc5fef1ba 100644 Binary files a/native/src/main/resources/native-compress.so and b/native/src/main/resources/native-compress.so differ diff --git a/native/src/test/java/net/md_5/bungee/NativeCipherTest.java b/native/src/test/java/net/md_5/bungee/NativeCipherTest.java index 72b81ab87a..b67862ea33 100644 --- a/native/src/test/java/net/md_5/bungee/NativeCipherTest.java +++ b/native/src/test/java/net/md_5/bungee/NativeCipherTest.java @@ -26,7 +26,7 @@ public class NativeCipherTest private final SecretKey secret = new SecretKeySpec( new byte[ 16 ], "AES" ); private static final int BENCHMARK_COUNT = 4096; // - private static final NativeCode factory = new NativeCode<>( "native-cipher", JavaCipher.class, NativeCipher.class ); + private static final NativeCode factory = new NativeCode<>( "native-cipher", JavaCipher::new, NativeCipher::new ); @Test public void testNative() throws Exception diff --git a/native/src/test/java/net/md_5/bungee/NativeZlibTest.java b/native/src/test/java/net/md_5/bungee/NativeZlibTest.java index fde626b1ac..60b71a13e1 100644 --- a/native/src/test/java/net/md_5/bungee/NativeZlibTest.java +++ b/native/src/test/java/net/md_5/bungee/NativeZlibTest.java @@ -15,7 +15,7 @@ public class NativeZlibTest { - private final NativeCode factory = new NativeCode<>( "native-compress", JavaZlib.class, NativeZlib.class ); + private final NativeCode factory = new NativeCode<>( "native-compress", JavaZlib::new, NativeZlib::new ); @Test public void doTest() throws DataFormatException diff --git a/native/zlib b/native/zlib new file mode 160000 index 0000000000..959b4ea305 --- /dev/null +++ b/native/zlib @@ -0,0 +1 @@ +Subproject commit 959b4ea305821e753385e873ec4edfaa9a5d49b7 diff --git a/pom.xml b/pom.xml index fdd049bed1..f44f6c2b40 100644 --- a/pom.xml +++ b/pom.xml @@ -138,7 +138,7 @@ org.apache.maven.plugins maven-checkstyle-plugin - 3.1.1 + 3.1.2 process-classes @@ -156,14 +156,14 @@ com.puppycrawl.tools checkstyle - 8.36.2 + 8.44 org.codehaus.mojo animal-sniffer-maven-plugin - 1.19 + 1.20 process-classes diff --git a/protocol/src/main/java/net/md_5/bungee/protocol/ProtocolConstants.java b/protocol/src/main/java/net/md_5/bungee/protocol/ProtocolConstants.java index 8757ed1000..ed70052719 100644 --- a/protocol/src/main/java/net/md_5/bungee/protocol/ProtocolConstants.java +++ b/protocol/src/main/java/net/md_5/bungee/protocol/ProtocolConstants.java @@ -37,6 +37,7 @@ public class ProtocolConstants public static final int MINECRAFT_1_16_3 = 753; public static final int MINECRAFT_1_16_4 = 754; public static final int MINECRAFT_1_17 = 755; + public static final int MINECRAFT_1_17_1 = 756; public static final List SUPPORTED_VERSIONS; public static final List SUPPORTED_VERSION_IDS; @@ -85,7 +86,8 @@ public class ProtocolConstants ProtocolConstants.MINECRAFT_1_16_2, ProtocolConstants.MINECRAFT_1_16_3, ProtocolConstants.MINECRAFT_1_16_4, - ProtocolConstants.MINECRAFT_1_17 + ProtocolConstants.MINECRAFT_1_17, + ProtocolConstants.MINECRAFT_1_17_1 ); if ( SNAPSHOT_SUPPORT ) diff --git a/protocol/src/main/java/net/md_5/bungee/protocol/packet/Chat.java b/protocol/src/main/java/net/md_5/bungee/protocol/packet/Chat.java index 8907bdb38a..0dbff4f057 100644 --- a/protocol/src/main/java/net/md_5/bungee/protocol/packet/Chat.java +++ b/protocol/src/main/java/net/md_5/bungee/protocol/packet/Chat.java @@ -40,7 +40,7 @@ public Chat(String message, byte position, UUID sender) @Override public void read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) { - message = readString( buf, ( direction == ProtocolConstants.Direction.TO_CLIENT ) ? 262144 : 256 ); + message = readString( buf, ( direction == ProtocolConstants.Direction.TO_CLIENT ) ? 262144 : ( protocolVersion >= ProtocolConstants.MINECRAFT_1_11 ? 256 : 100 ) ); if ( direction == ProtocolConstants.Direction.TO_CLIENT && protocolVersion >= ProtocolConstants.MINECRAFT_1_8 ) { position = buf.readByte(); diff --git a/protocol/src/main/java/net/md_5/bungee/protocol/packet/TabCompleteRequest.java b/protocol/src/main/java/net/md_5/bungee/protocol/packet/TabCompleteRequest.java index 9927cb37a0..71f23d7579 100644 --- a/protocol/src/main/java/net/md_5/bungee/protocol/packet/TabCompleteRequest.java +++ b/protocol/src/main/java/net/md_5/bungee/protocol/packet/TabCompleteRequest.java @@ -41,7 +41,7 @@ public void read(ByteBuf buf, ProtocolConstants.Direction direction, int protoco { transactionId = readVarInt( buf ); } - cursor = readString( buf, 32500 ); + cursor = readString( buf, ( protocolVersion > ProtocolConstants.MINECRAFT_1_13 ? 32500 : ( protocolVersion == ProtocolConstants.MINECRAFT_1_13 ? 256 : 32767 ) ) ); if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_8 && protocolVersion < ProtocolConstants.MINECRAFT_1_13 ) { diff --git a/proxy/src/main/java/net/md_5/bungee/BungeeCord.java b/proxy/src/main/java/net/md_5/bungee/BungeeCord.java index 8413eebef1..95e1534033 100644 --- a/proxy/src/main/java/net/md_5/bungee/BungeeCord.java +++ b/proxy/src/main/java/net/md_5/bungee/BungeeCord.java @@ -265,7 +265,7 @@ public BungeeCord() throws IOException public void start() throws Exception { System.setProperty( "io.netty.selectorAutoRebuildThreshold", "0" ); // Seems to cause Bungee to stop accepting connections - if ( System.getProperty( "io.netty.leakDetectionLevel" ) == null ) + if ( System.getProperty( "io.netty.leakDetectionLevel" ) == null && System.getProperty( "io.netty.leakDetection.level" ) == null ) { ResourceLeakDetector.setLevel( ResourceLeakDetector.Level.DISABLED ); // Eats performance } diff --git a/proxy/src/main/java/net/md_5/bungee/EncryptionUtil.java b/proxy/src/main/java/net/md_5/bungee/EncryptionUtil.java index ff6bb8c16d..f76c395ab8 100644 --- a/proxy/src/main/java/net/md_5/bungee/EncryptionUtil.java +++ b/proxy/src/main/java/net/md_5/bungee/EncryptionUtil.java @@ -31,7 +31,7 @@ public class EncryptionUtil public static final KeyPair keys; @Getter private static final SecretKey secret = new SecretKeySpec( new byte[ 16 ], "AES" ); - public static final NativeCode nativeFactory = new NativeCode<>( "native-cipher", JavaCipher.class, NativeCipher.class ); + public static final NativeCode nativeFactory = new NativeCode<>( "native-cipher", JavaCipher::new, NativeCipher::new ); static { diff --git a/proxy/src/main/java/net/md_5/bungee/UserConnection.java b/proxy/src/main/java/net/md_5/bungee/UserConnection.java index 5a254eb3a9..b62f2c61db 100644 --- a/proxy/src/main/java/net/md_5/bungee/UserConnection.java +++ b/proxy/src/main/java/net/md_5/bungee/UserConnection.java @@ -8,6 +8,7 @@ import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelOption; +import io.netty.channel.ConnectTimeoutException; import io.netty.util.internal.PlatformDependent; import java.net.InetSocketAddress; import java.net.SocketAddress; @@ -359,10 +360,10 @@ public void operationComplete(ChannelFuture future) throws Exception connect( def, null, true, ServerConnectEvent.Reason.LOBBY_FALLBACK ); } else if ( dimensionChange ) { - disconnect( bungee.getTranslation( "fallback_kick", future.cause().getClass().getName() ) ); + disconnect( bungee.getTranslation( "fallback_kick", connectionFailMessage( future.cause() ) ) ); } else { - sendMessage( bungee.getTranslation( "fallback_kick", future.cause().getClass().getName() ) ); + sendMessage( bungee.getTranslation( "fallback_kick", connectionFailMessage( future.cause() ) ) ); } } } @@ -381,6 +382,17 @@ public void operationComplete(ChannelFuture future) throws Exception b.connect().addListener( listener ); } + private String connectionFailMessage(Throwable cause) + { + if ( cause instanceof ConnectTimeoutException ) + { + return bungee.getTranslation( "timeout" ); + } else + { + return cause.getClass().getName(); + } + } + @Override public void disconnect(String reason) { diff --git a/proxy/src/main/java/net/md_5/bungee/compress/CompressFactory.java b/proxy/src/main/java/net/md_5/bungee/compress/CompressFactory.java index 1f2d5a70aa..2e0c63d1f0 100644 --- a/proxy/src/main/java/net/md_5/bungee/compress/CompressFactory.java +++ b/proxy/src/main/java/net/md_5/bungee/compress/CompressFactory.java @@ -8,5 +8,5 @@ public class CompressFactory { - public static final NativeCode zlib = new NativeCode<>( "native-compress", JavaZlib.class, NativeZlib.class ); + public static final NativeCode zlib = new NativeCode<>( "native-compress", JavaZlib::new, NativeZlib::new ); } 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 3cc4558eb1..8b0417e5cb 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 @@ -360,12 +360,6 @@ public void handle(LoginRequest loginRequest) throws Exception return; } - if ( getName().length() > 16 ) - { - disconnect( bungee.getTranslation( "name_too_long" ) ); - return; - } - int limit = BungeeCord.getInstance().config.getPlayerLimit(); if ( limit > 0 && bungee.getOnlineCount() >= limit ) { diff --git a/proxy/src/main/java/net/md_5/bungee/connection/UpstreamBridge.java b/proxy/src/main/java/net/md_5/bungee/connection/UpstreamBridge.java index 94e3369c23..ead2024b5e 100644 --- a/proxy/src/main/java/net/md_5/bungee/connection/UpstreamBridge.java +++ b/proxy/src/main/java/net/md_5/bungee/connection/UpstreamBridge.java @@ -147,8 +147,16 @@ public void handle(KeepAlive alive) throws Exception @Override public void handle(Chat chat) throws Exception { - int maxLength = ( con.getPendingConnection().getVersion() >= ProtocolConstants.MINECRAFT_1_11 ) ? 256 : 100; - Preconditions.checkArgument( chat.getMessage().length() <= maxLength, "Chat message too long" ); // Mojang limit, check on updates + for ( int index = 0, length = chat.getMessage().length(); index < length; index++ ) + { + char c = chat.getMessage().charAt( index ); + // Section symbol, control sequences, and delete + if ( c == '\u00A7' || c < ' ' || c == 127 ) + { + con.disconnect( bungee.getTranslation( "illegal_chat_characters", String.format( "\\u%04x", (int) c ) ) ); + throw CancelSendSignal.INSTANCE; + } + } ChatEvent chatEvent = new ChatEvent( con, con.getServer(), chat.getMessage() ); if ( !bungee.getPluginManager().callEvent( chatEvent ).isCancelled() ) diff --git a/proxy/src/main/java/net/md_5/bungee/entitymap/EntityMap.java b/proxy/src/main/java/net/md_5/bungee/entitymap/EntityMap.java index 12798f29fa..aae6ae5f50 100644 --- a/proxy/src/main/java/net/md_5/bungee/entitymap/EntityMap.java +++ b/proxy/src/main/java/net/md_5/bungee/entitymap/EntityMap.java @@ -73,6 +73,7 @@ public static EntityMap getEntityMap(int version) case ProtocolConstants.MINECRAFT_1_16_4: return EntityMap_1_16_2.INSTANCE_1_16_2; case ProtocolConstants.MINECRAFT_1_17: + case ProtocolConstants.MINECRAFT_1_17_1: return EntityMap_1_16_2.INSTANCE_1_17; } throw new RuntimeException( "Version " + version + " has no entity map" ); diff --git a/proxy/src/main/java/net/md_5/bungee/module/ModuleManager.java b/proxy/src/main/java/net/md_5/bungee/module/ModuleManager.java index 1ac9d376ee..ecfb9f68c3 100644 --- a/proxy/src/main/java/net/md_5/bungee/module/ModuleManager.java +++ b/proxy/src/main/java/net/md_5/bungee/module/ModuleManager.java @@ -32,10 +32,12 @@ public ModuleManager() knownSources.put( "travis-ci", new TravisCiModuleSource() ); } + // CHECKSTYLE:OFF @SuppressFBWarnings( { "SF_SWITCH_FALLTHROUGH", "SF_SWITCH_NO_DEFAULT" }) + // CHECKSTYLE:ON public void load(ProxyServer proxy, File moduleDirectory) throws Exception { moduleDirectory.mkdir(); diff --git a/proxy/src/main/resources/messages.properties b/proxy/src/main/resources/messages.properties index 2a79e62b65..0b7e74c967 100644 --- a/proxy/src/main/resources/messages.properties +++ b/proxy/src/main/resources/messages.properties @@ -7,6 +7,7 @@ connect_kick=\u00a7cKicked whilst connecting to {0}: {1} current_server=\u00a76You are currently connected to {0}. fallback_kick=\u00a7cCould not connect to a default or fallback server, please try again later: {0} fallback_lobby=\u00a7cCould not connect to target server, you have been moved to a fallback server. +timeout=Server not reachable (timeout). Offline? Incorrectly configured address/port/firewall? lost_connection=[Proxy] Lost connection to server. mojang_fail=Error occurred while contacting login servers, are they down? no_permission=\u00a7cYou do not have permission to execute this command! @@ -20,7 +21,6 @@ server_kick=[Kicked] server_list=\u00a76You may connect to the following servers at this time: server_went_down=\u00a7cThe server you were previously on went down, you have been connected to a fallback server total_players=Total players online: {0} -name_too_long=Cannot have username longer than 16 characters name_invalid=Username contains invalid characters. ping_cannot_connect=\u00a7c[Bungee] Can''t connect to server. offline_mode_player=Not authenticated with Minecraft.net @@ -38,3 +38,4 @@ you_got_summoned=\u00a76Summoned to {0} by {1} command_perms_groups=\u00a76You have the following groups: {0} command_perms_permission=\u00a79- {0} command_ip=\u00a79IP of {0} is {1} +illegal_chat_characters=\u00a7cillegal characters in chat ({0})