From 942b056c58f2d95cd02bfa9f9c9c831587c56aa8 Mon Sep 17 00:00:00 2001 From: Haowei Wen Date: Sat, 2 Jul 2022 12:53:41 +0800 Subject: [PATCH 1/4] disable papermc's username check --- .../authlibinjector/AuthlibInjector.java | 2 + .../PaperUsernameCheckTransformer.java | 62 +++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 src/main/java/moe/yushi/authlibinjector/transform/support/PaperUsernameCheckTransformer.java diff --git a/src/main/java/moe/yushi/authlibinjector/AuthlibInjector.java b/src/main/java/moe/yushi/authlibinjector/AuthlibInjector.java index 07c9d1d..6ec32e1 100644 --- a/src/main/java/moe/yushi/authlibinjector/AuthlibInjector.java +++ b/src/main/java/moe/yushi/authlibinjector/AuthlibInjector.java @@ -61,6 +61,7 @@ import moe.yushi.authlibinjector.transform.support.MC52974Workaround; import moe.yushi.authlibinjector.transform.support.MC52974_1710Workaround; import moe.yushi.authlibinjector.transform.support.MainArgumentsTransformer; +import moe.yushi.authlibinjector.transform.support.PaperUsernameCheckTransformer; import moe.yushi.authlibinjector.transform.support.ProxyParameterWorkaround; import moe.yushi.authlibinjector.transform.support.SkinWhitelistTransformUnit; import moe.yushi.authlibinjector.transform.support.UsernameCharacterCheckTransformer; @@ -277,6 +278,7 @@ private static ClassTransformer createTransformer(APIMetadata config) { transformer.units.add(new ConcatenateURLTransformUnit()); transformer.units.add(new BungeeCordAllowedCharactersTransformer()); transformer.units.add(new UsernameCharacterCheckTransformer()); + transformer.units.add(new PaperUsernameCheckTransformer()); transformer.units.add(new SkinWhitelistTransformUnit()); SkinWhitelistTransformUnit.getWhitelistedDomains().addAll(config.getSkinDomains()); diff --git a/src/main/java/moe/yushi/authlibinjector/transform/support/PaperUsernameCheckTransformer.java b/src/main/java/moe/yushi/authlibinjector/transform/support/PaperUsernameCheckTransformer.java new file mode 100644 index 0000000..beab295 --- /dev/null +++ b/src/main/java/moe/yushi/authlibinjector/transform/support/PaperUsernameCheckTransformer.java @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2022 Haowei Wen and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package moe.yushi.authlibinjector.transform.support; + +import static org.objectweb.asm.Opcodes.*; +import java.util.Optional; +import org.objectweb.asm.ClassVisitor; +import org.objectweb.asm.MethodVisitor; +import moe.yushi.authlibinjector.transform.TransformContext; +import moe.yushi.authlibinjector.transform.TransformUnit; + +/** + * Disables PaperMC's username check. + * See . + */ +public class PaperUsernameCheckTransformer implements TransformUnit { + + @Override + public Optional transform(ClassLoader classLoader, String className, ClassVisitor writer, TransformContext context) { + if (!context.getStringConstants().contains("Invalid characters in username")) { + return Optional.empty(); + } + + return Optional.of(new ClassVisitor(ASM9, writer) { + @Override + public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) { + return new MethodVisitor(ASM9, super.visitMethod(access, name, descriptor, signature, exceptions)) { + + @Override + public void visitFieldInsn(int opcode, String owner, String name, String descriptor) { + if (opcode == GETFIELD && "iKnowThisMayNotBeTheBestIdeaButPleaseDisableUsernameValidation".equals(name)) { + context.markModified(); + visitInsn(POP); + visitInsn(ICONST_1); + } else { + super.visitFieldInsn(opcode, owner, name, descriptor); + } + } + }; + } + }); + } + + @Override + public String toString() { + return "Paper Username Checker Transformer"; + } +} From 8fa86e7f93f61a1336299fef7fa4fcf3cd405143 Mon Sep 17 00:00:00 2001 From: Haowei Wen Date: Sat, 2 Jul 2022 13:24:51 +0800 Subject: [PATCH 2/4] add -Dauthlibinjector.usernameCheck option --- README.en.md | 11 ++++++++--- README.md | 5 +++++ .../moe/yushi/authlibinjector/AuthlibInjector.java | 10 ++++++++-- src/main/java/moe/yushi/authlibinjector/Config.java | 2 ++ 4 files changed, 23 insertions(+), 5 deletions(-) diff --git a/README.en.md b/README.en.md index 7788c81..d913e07 100644 --- a/README.en.md +++ b/README.en.md @@ -87,7 +87,7 @@ Configure Minecraft server with the following JVM parameter: -Dauthlibinjector.mojangAntiFeatures={default|enabled|disabled} Whether to turn on Minecraft's anti-features. - It's enabled by default if the authentication server does NOT send feature.enable_mojang_anti_features option. + It's disabled by default if the authentication server does NOT send feature.enable_mojang_anti_features option. These anti-features include: - Minecraft server blocklist @@ -101,8 +101,13 @@ Configure Minecraft server with the following JVM parameter: -Dauthlibinjector.profileKey={default|enabled|disabled} Whether to enable the profile signing key feature. This feature is introduced in 22w17a, and is used to implement the multiplayer secure chat signing. If this this feature is enabled, Minecraft will send a POST request to /minecraftservices/player/certificates to retrieve the key pair issued by the authentication server. - It's enabled by default if the authentication server sends feature.enable_profile_key option. + It's disabled by default if the authentication server does NOT send feature.enable_profile_key option. If the profile signing key isn't present, the player will be unable to join servers that enable enforce-secure-profile=true option. - And other players' Minecraft client will log a warning when receiving an unsigned chat message. + And other players' Minecraft client will log a warning message when receiving an unsigned chat message. + +-Dauthlibinjector.usernameCheck={default|enabled|disabled} + Whether to enable username validation. If disabled, Minecraft, BungeeCord and Paper will NOT perform username validation. + It's disabled by default if the authentication server does NOT send feature.usernameCheck option. + Turning on this option will prevent players whose username contains special characters from joining the server. ``` diff --git a/README.md b/README.md index ac4de15..0fdc9be 100644 --- a/README.md +++ b/README.md @@ -112,6 +112,11 @@ gradle 当缺少消息签名密钥时, 玩家将无法进入设置了 enforce-secure-profile=true 选项的服务器. 而当其他玩家的客户端在收到无有效签名的聊天消息时, 会在日志中记录警告. + +-Dauthlibinjector.usernameCheck={default|enabled|disabled} + 是否启用玩家用户名检查, 若禁用, 则 authlib-injector 将关闭 Minecraft、BungeeCord 和 Paper 的用户名检查功能. + 若验证服务器未设置 feature.usernameCheck 选项, 则默认禁用. + 注意, 开启此功能将导致用户名包含非英文字符的玩家无法进入服务器. ``` ## 捐助 diff --git a/src/main/java/moe/yushi/authlibinjector/AuthlibInjector.java b/src/main/java/moe/yushi/authlibinjector/AuthlibInjector.java index 6ec32e1..aa94b6e 100644 --- a/src/main/java/moe/yushi/authlibinjector/AuthlibInjector.java +++ b/src/main/java/moe/yushi/authlibinjector/AuthlibInjector.java @@ -277,8 +277,14 @@ private static ClassTransformer createTransformer(APIMetadata config) { transformer.units.add(new CitizensTransformer()); transformer.units.add(new ConcatenateURLTransformUnit()); transformer.units.add(new BungeeCordAllowedCharactersTransformer()); - transformer.units.add(new UsernameCharacterCheckTransformer()); - transformer.units.add(new PaperUsernameCheckTransformer()); + + boolean usernameCheckDefault = Boolean.TRUE.equals(config.getMeta().get("feature.usernameCheck")); + if (Config.usernameCheck.isEnabled(usernameCheckDefault)) { + log(INFO, "Username check is enforced"); + } else { + transformer.units.add(new UsernameCharacterCheckTransformer()); + transformer.units.add(new PaperUsernameCheckTransformer()); + } transformer.units.add(new SkinWhitelistTransformUnit()); SkinWhitelistTransformUnit.getWhitelistedDomains().addAll(config.getSkinDomains()); diff --git a/src/main/java/moe/yushi/authlibinjector/Config.java b/src/main/java/moe/yushi/authlibinjector/Config.java index a5293fe..341f473 100644 --- a/src/main/java/moe/yushi/authlibinjector/Config.java +++ b/src/main/java/moe/yushi/authlibinjector/Config.java @@ -61,6 +61,7 @@ public boolean isEnabled(boolean defaultValue) { public static FeatureOption legacySkinPolyfill; public static FeatureOption mojangAntiFeatures; public static FeatureOption profileKey; + public static FeatureOption usernameCheck; public static boolean noShowServerName; public static int httpdPort; @@ -179,6 +180,7 @@ static void init() { legacySkinPolyfill = parseFeatureOption("authlibinjector.legacySkinPolyfill"); mojangAntiFeatures = parseFeatureOption("authlibinjector.mojangAntiFeatures"); profileKey = parseFeatureOption("authlibinjector.profileKey"); + usernameCheck = parseFeatureOption("authlibinjector.usernameCheck"); httpdDisabled = System.getProperty("authlibinjector.disableHttpd") != null; noShowServerName = System.getProperty("authlibinjector.noShowServerName") != null; httpdPort = Integer.getInteger("authlibinjector.httpdPort", 0); From 381ae455afe2cc82182679826e67b88c75695c85 Mon Sep 17 00:00:00 2001 From: Haowei Wen Date: Sat, 2 Jul 2022 13:28:14 +0800 Subject: [PATCH 3/4] rename feature.usernameCheck -> feature.username_check --- src/main/java/moe/yushi/authlibinjector/AuthlibInjector.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/moe/yushi/authlibinjector/AuthlibInjector.java b/src/main/java/moe/yushi/authlibinjector/AuthlibInjector.java index aa94b6e..97c30e3 100644 --- a/src/main/java/moe/yushi/authlibinjector/AuthlibInjector.java +++ b/src/main/java/moe/yushi/authlibinjector/AuthlibInjector.java @@ -278,7 +278,7 @@ private static ClassTransformer createTransformer(APIMetadata config) { transformer.units.add(new ConcatenateURLTransformUnit()); transformer.units.add(new BungeeCordAllowedCharactersTransformer()); - boolean usernameCheckDefault = Boolean.TRUE.equals(config.getMeta().get("feature.usernameCheck")); + boolean usernameCheckDefault = Boolean.TRUE.equals(config.getMeta().get("feature.username_check")); if (Config.usernameCheck.isEnabled(usernameCheckDefault)) { log(INFO, "Username check is enforced"); } else { From 74b890ff01d11580fba332f736bb4e4567abfb23 Mon Sep 17 00:00:00 2001 From: Haowei Wen Date: Sat, 2 Jul 2022 14:00:25 +0800 Subject: [PATCH 4/4] polish --- .../support/BungeeCordAllowedCharactersTransformer.java | 4 ++-- .../transform/support/PaperUsernameCheckTransformer.java | 2 +- .../transform/support/UsernameCharacterCheckTransformer.java | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/moe/yushi/authlibinjector/transform/support/BungeeCordAllowedCharactersTransformer.java b/src/main/java/moe/yushi/authlibinjector/transform/support/BungeeCordAllowedCharactersTransformer.java index 3c0f4b1..57eeb18 100644 --- a/src/main/java/moe/yushi/authlibinjector/transform/support/BungeeCordAllowedCharactersTransformer.java +++ b/src/main/java/moe/yushi/authlibinjector/transform/support/BungeeCordAllowedCharactersTransformer.java @@ -25,10 +25,10 @@ import moe.yushi.authlibinjector.transform.TransformUnit; /** - * Hacks BungeeCord to allow non-ASCII characters in username. + * Hacks BungeeCord to allow special characters to occur in the username. * * Since , - * BungeeCord allows only ASCII characters in username when online-mode is on. + * BungeeCord allows only certain characters to occur in the username when online-mode is on. */ public class BungeeCordAllowedCharactersTransformer implements TransformUnit { diff --git a/src/main/java/moe/yushi/authlibinjector/transform/support/PaperUsernameCheckTransformer.java b/src/main/java/moe/yushi/authlibinjector/transform/support/PaperUsernameCheckTransformer.java index beab295..d964e68 100644 --- a/src/main/java/moe/yushi/authlibinjector/transform/support/PaperUsernameCheckTransformer.java +++ b/src/main/java/moe/yushi/authlibinjector/transform/support/PaperUsernameCheckTransformer.java @@ -57,6 +57,6 @@ public void visitFieldInsn(int opcode, String owner, String name, String descrip @Override public String toString() { - return "Paper Username Checker Transformer"; + return "Paper Username Check Transformer"; } } diff --git a/src/main/java/moe/yushi/authlibinjector/transform/support/UsernameCharacterCheckTransformer.java b/src/main/java/moe/yushi/authlibinjector/transform/support/UsernameCharacterCheckTransformer.java index ade5b34..944c820 100644 --- a/src/main/java/moe/yushi/authlibinjector/transform/support/UsernameCharacterCheckTransformer.java +++ b/src/main/java/moe/yushi/authlibinjector/transform/support/UsernameCharacterCheckTransformer.java @@ -97,6 +97,6 @@ public void visitMethodInsn(int opcode, String owner, String name, String descri @Override public String toString() { - return "Username Character Checker Transformer"; + return "Username Character Check Transformer"; } }