From eb76a9451f8c31dbdbd0c511ab04b655d736c6f9 Mon Sep 17 00:00:00 2001 From: bundabrg Date: Tue, 12 May 2020 19:49:09 +0800 Subject: [PATCH 1/9] Implement Minecraft Education v1.12.60 support Changes: * Support both MCEE and MCPE versions. * Config entry to enable/disable education support * Enable 2 way encryption by default now whilst still performing mitm --- .gitignore | 4 ++- pom.xml | 10 ++++++- .../com/nukkitx/proxypass/Configuration.java | 3 ++ .../java/com/nukkitx/proxypass/ProxyPass.java | 13 +++++++-- .../network/ProxyBedrockEventHandler.java | 16 +++++++---- .../session/DownstreamPacketHandler.java | 12 ++++++++ .../bedrock/session/ProxyPlayerSession.java | 4 +-- .../session/UpstreamPacketHandler.java | 20 +++++++++---- .../network/bedrock/util/ForgeryUtils.java | 28 +++++++++++++++++++ .../network/bedrock/util/RecipeUtils.java | 2 +- src/main/resources/config.yml | 2 ++ 11 files changed, 97 insertions(+), 17 deletions(-) diff --git a/.gitignore b/.gitignore index 68dda6d..f25b734 100644 --- a/.gitignore +++ b/.gitignore @@ -205,4 +205,6 @@ config.yml logs/ logs/* packet-logs/ -packet-logs/* \ No newline at end of file +packet-logs/* +data/* +sessions/* \ No newline at end of file diff --git a/pom.xml b/pom.xml index edf4dcf..00ce7ca 100644 --- a/pom.xml +++ b/pom.xml @@ -37,10 +37,18 @@ 1.3.9 provided + com.nukkitx.protocol bedrock-v390 - 2.5.5 + 2.5.7-SNAPSHOT + compile + + + + com.nukkitx.protocol + bedrock-v363 + 2.5.7-SNAPSHOT compile diff --git a/src/main/java/com/nukkitx/proxypass/Configuration.java b/src/main/java/com/nukkitx/proxypass/Configuration.java index 9ed9ff2..f1660d3 100644 --- a/src/main/java/com/nukkitx/proxypass/Configuration.java +++ b/src/main/java/com/nukkitx/proxypass/Configuration.java @@ -27,6 +27,9 @@ public class Configuration { @JsonProperty("log-packets") private boolean loggingPackets = false; + @JsonProperty("education") + private boolean education = false; + @JsonProperty("ignored-packets") private Set ignoredPackets = Collections.emptySet(); diff --git a/src/main/java/com/nukkitx/proxypass/ProxyPass.java b/src/main/java/com/nukkitx/proxypass/ProxyPass.java index 3da9c44..802377e 100644 --- a/src/main/java/com/nukkitx/proxypass/ProxyPass.java +++ b/src/main/java/com/nukkitx/proxypass/ProxyPass.java @@ -13,6 +13,7 @@ import com.nukkitx.protocol.bedrock.BedrockClient; import com.nukkitx.protocol.bedrock.BedrockPacketCodec; import com.nukkitx.protocol.bedrock.BedrockServer; +import com.nukkitx.protocol.bedrock.v363.Bedrock_v363; import com.nukkitx.protocol.bedrock.v390.Bedrock_v390; import com.nukkitx.proxypass.network.ProxyBedrockEventHandler; import lombok.AccessLevel; @@ -37,8 +38,6 @@ public class ProxyPass { public static final ObjectMapper JSON_MAPPER = new ObjectMapper().disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); public static final YAMLMapper YAML_MAPPER = (YAMLMapper) new YAMLMapper().disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); public static final String MINECRAFT_VERSION; - public static final BedrockPacketCodec CODEC = Bedrock_v390.V390_CODEC; - public static final int PROTOCOL_VERSION = CODEC.getProtocolVersion(); private static final DefaultPrettyPrinter PRETTY_PRINTER = new DefaultPrettyPrinter(); static { @@ -56,6 +55,8 @@ public class ProxyPass { MINECRAFT_VERSION = minecraftVersion; } + public BedrockPacketCodec CODEC; + public int PROTOCOL_VERSION; private final AtomicBoolean running = new AtomicBoolean(true); private BedrockServer bedrockServer; private final Set clients = Collections.newSetFromMap(new ConcurrentHashMap<>()); @@ -86,6 +87,14 @@ public void boot() throws IOException { configuration = Configuration.load(configPath); + if (configuration.isEducation()) { + CODEC = Bedrock_v363.V363_CODEC; + } else { + CODEC = Bedrock_v390.V390_CODEC; + } + + PROTOCOL_VERSION = CODEC.getProtocolVersion(); + proxyAddress = configuration.getProxy().getAddress(); targetAddress = configuration.getDestination().getAddress(); diff --git a/src/main/java/com/nukkitx/proxypass/network/ProxyBedrockEventHandler.java b/src/main/java/com/nukkitx/proxypass/network/ProxyBedrockEventHandler.java index e11611f..50d09ef 100644 --- a/src/main/java/com/nukkitx/proxypass/network/ProxyBedrockEventHandler.java +++ b/src/main/java/com/nukkitx/proxypass/network/ProxyBedrockEventHandler.java @@ -13,22 +13,28 @@ import java.net.InetSocketAddress; @Log4j2 -@RequiredArgsConstructor @ParametersAreNonnullByDefault public class ProxyBedrockEventHandler implements BedrockServerEventHandler { - private static final BedrockPong ADVERTISEMENT = new BedrockPong(); private final ProxyPass proxy; + private final BedrockPong ADVERTISEMENT = new BedrockPong(); - static { - ADVERTISEMENT.setEdition("MCPE"); + public ProxyBedrockEventHandler(ProxyPass proxy) { + this.proxy = proxy; + + if (proxy.getConfiguration().isEducation()) { + ADVERTISEMENT.setEdition("MCEE"); + } else { + ADVERTISEMENT.setEdition("MCPE"); + } ADVERTISEMENT.setGameType("Survival"); ADVERTISEMENT.setVersion(ProxyPass.MINECRAFT_VERSION); - ADVERTISEMENT.setProtocolVersion(ProxyPass.PROTOCOL_VERSION); + ADVERTISEMENT.setProtocolVersion(proxy.PROTOCOL_VERSION); ADVERTISEMENT.setMotd("ProxyPass"); ADVERTISEMENT.setPlayerCount(0); ADVERTISEMENT.setMaximumPlayerCount(20); ADVERTISEMENT.setSubMotd("https://github.com/NukkitX/ProxyPass"); + } @Override diff --git a/src/main/java/com/nukkitx/proxypass/network/bedrock/session/DownstreamPacketHandler.java b/src/main/java/com/nukkitx/proxypass/network/bedrock/session/DownstreamPacketHandler.java index 6f8aff1..a7d6259 100644 --- a/src/main/java/com/nukkitx/proxypass/network/bedrock/session/DownstreamPacketHandler.java +++ b/src/main/java/com/nukkitx/proxypass/network/bedrock/session/DownstreamPacketHandler.java @@ -15,6 +15,7 @@ import com.nukkitx.protocol.bedrock.util.EncryptionUtils; import com.nukkitx.proxypass.ProxyPass; import com.nukkitx.proxypass.network.bedrock.util.BlockPaletteUtils; +import com.nukkitx.proxypass.network.bedrock.util.ForgeryUtils; import com.nukkitx.proxypass.network.bedrock.util.RecipeUtils; import lombok.RequiredArgsConstructor; import lombok.Value; @@ -46,6 +47,17 @@ public boolean handle(ServerToClientHandshakePacket packet) { SecretKey key = EncryptionUtils.getSecretKey(this.player.getProxyKeyPair().getPrivate(), serverKey, Base64.getDecoder().decode(saltJwt.getJWTClaimsSet().getStringClaim("salt"))); session.enableEncryption(key); + + ServerToClientHandshakePacket p = new ServerToClientHandshakePacket(); + p.setJwt(ForgeryUtils.forgeHandshake( + player.getProxyKeyPair(), + saltJwt.getJWTClaimsSet().getStringClaim("signedToken"), + Base64.getDecoder().decode(saltJwt.getJWTClaimsSet().getStringClaim("salt"))).serialize() + ); + player.getUpstream().sendPacketImmediately(p); + player.getUpstream().enableEncryption(EncryptionUtils.getSecretKey(player.getProxyKeyPair().getPrivate(), + ((UpstreamPacketHandler)player.getUpstream().getPacketHandler()).getRemotePublicKey(),Base64.getDecoder().decode(saltJwt.getJWTClaimsSet().getStringClaim("salt")))); + } catch (ParseException | NoSuchAlgorithmException | InvalidKeySpecException | InvalidKeyException e) { throw new RuntimeException(e); } diff --git a/src/main/java/com/nukkitx/proxypass/network/bedrock/session/ProxyPlayerSession.java b/src/main/java/com/nukkitx/proxypass/network/bedrock/session/ProxyPlayerSession.java index 655e309..1c5d791 100644 --- a/src/main/java/com/nukkitx/proxypass/network/bedrock/session/ProxyPlayerSession.java +++ b/src/main/java/com/nukkitx/proxypass/network/bedrock/session/ProxyPlayerSession.java @@ -122,9 +122,9 @@ public void handle(BedrockSession session, ByteBuf compressed, Collection ProxyPass.PROTOCOL_VERSION) { + if (protocolVersion > proxy.PROTOCOL_VERSION) { status.setStatus(PlayStatusPacket.Status.FAILED_SERVER); } else { status.setStatus(PlayStatusPacket.Status.FAILED_CLIENT); } } - session.setPacketCodec(ProxyPass.CODEC); + session.setPacketCodec(proxy.CODEC); JsonNode certData; try { @@ -111,6 +120,7 @@ public boolean handle(LoginPacket packet) { throw new RuntimeException("Identity Public Key was not found!"); } ECPublicKey identityPublicKey = EncryptionUtils.generateKey(payload.get("identityPublicKey").textValue()); + this.remotePublicKey = identityPublicKey; JWSObject clientJwt = JWSObject.parse(packet.getSkinData().toString()); verifyJwt(clientJwt, identityPublicKey); @@ -131,7 +141,7 @@ private void initializeProxySession() { log.error("Unable to connect to downstream server " + proxy.getTargetAddress(), throwable); return; } - downstream.setPacketCodec(ProxyPass.CODEC); + downstream.setPacketCodec(proxy.CODEC); ProxyPlayerSession proxySession = new ProxyPlayerSession(this.session, downstream, this.proxy, this.authData); this.player = proxySession; @@ -150,7 +160,7 @@ private void initializeProxySession() { LoginPacket login = new LoginPacket(); login.setChainData(chainData); login.setSkinData(AsciiString.of(skinData.serialize())); - login.setProtocolVersion(ProxyPass.PROTOCOL_VERSION); + login.setProtocolVersion(proxy.PROTOCOL_VERSION); downstream.sendPacketImmediately(login); this.session.setBatchedHandler(proxySession.getUpstreamBatchHandler()); diff --git a/src/main/java/com/nukkitx/proxypass/network/bedrock/util/ForgeryUtils.java b/src/main/java/com/nukkitx/proxypass/network/bedrock/util/ForgeryUtils.java index bbedfac..4fcda63 100644 --- a/src/main/java/com/nukkitx/proxypass/network/bedrock/util/ForgeryUtils.java +++ b/src/main/java/com/nukkitx/proxypass/network/bedrock/util/ForgeryUtils.java @@ -71,4 +71,32 @@ public static JWSObject forgeSkinData(KeyPair pair, JSONObject skinData) { return jws; } + + public static SignedJWT forgeHandshake(KeyPair pair, String signedToken, byte[] token) { + String publicKeyBase64 = Base64.getEncoder().encodeToString(pair.getPublic().getEncoded()); + URI x5u = URI.create(publicKeyBase64); + + JWSHeader header = new JWSHeader.Builder(JWSAlgorithm.ES384).x509CertURL(x5u).build(); + + long timestamp = System.currentTimeMillis(); + Date nbf = new Date(timestamp - TimeUnit.SECONDS.toMillis(1)); + Date exp = new Date(timestamp + TimeUnit.DAYS.toMillis(1)); + + JWTClaimsSet.Builder claimsBuilder = new JWTClaimsSet.Builder() + .claim("salt", Base64.getEncoder().encodeToString(token)); + + if (signedToken != null) { + claimsBuilder.claim("signedToken", signedToken); + } + + SignedJWT jwt = new SignedJWT(header, claimsBuilder.build()); + + try { + EncryptionUtils.signJwt(jwt, (ECPrivateKey) pair.getPrivate()); + } catch (JOSEException e) { + throw new RuntimeException(e); + } + + return jwt; + } } diff --git a/src/main/java/com/nukkitx/proxypass/network/bedrock/util/RecipeUtils.java b/src/main/java/com/nukkitx/proxypass/network/bedrock/util/RecipeUtils.java index 154c337..fa3e8c6 100644 --- a/src/main/java/com/nukkitx/proxypass/network/bedrock/util/RecipeUtils.java +++ b/src/main/java/com/nukkitx/proxypass/network/bedrock/util/RecipeUtils.java @@ -95,7 +95,7 @@ public static void writeRecipes(CraftingDataPacket packet, ProxyPass proxy) { entries.add(entry); } - Recipes recipes = new Recipes(ProxyPass.CODEC.getProtocolVersion(), entries, packet.getPotionMixData(), packet.getContainerMixData()); + Recipes recipes = new Recipes(proxy.CODEC.getProtocolVersion(), entries, packet.getPotionMixData(), packet.getContainerMixData()); proxy.saveJson("recipes.json", recipes); } diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 990cf5e..c675c9b 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -11,6 +11,8 @@ destination: packet-testing: false ## Log packets for each session log-packets: true +## Minecraft Education Support +education: false ## Packets to ignore to make your log more refined. These default packet are generally spammed ignored-packets: From 57eb08f855c7a08f0346d2c82deec28fe432ee67 Mon Sep 17 00:00:00 2001 From: bundabrg Date: Mon, 29 Jun 2020 12:59:43 +0800 Subject: [PATCH 2/9] Update for 1.16 --- src/main/java/com/nukkitx/proxypass/ProxyPass.java | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/nukkitx/proxypass/ProxyPass.java b/src/main/java/com/nukkitx/proxypass/ProxyPass.java index 095934e..8096af0 100644 --- a/src/main/java/com/nukkitx/proxypass/ProxyPass.java +++ b/src/main/java/com/nukkitx/proxypass/ProxyPass.java @@ -38,8 +38,8 @@ public class ProxyPass { public static final ObjectMapper JSON_MAPPER = new ObjectMapper().disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); public static final YAMLMapper YAML_MAPPER = (YAMLMapper) new YAMLMapper().disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); public static final String MINECRAFT_VERSION; - public static final BedrockPacketCodec CODEC = Bedrock_v407.V407_CODEC; - public static final int PROTOCOL_VERSION = CODEC.getProtocolVersion(); + public static BedrockPacketCodec CODEC; + public static int PROTOCOL_VERSION; private static final DefaultPrettyPrinter PRETTY_PRINTER = new DefaultPrettyPrinter(); static { @@ -57,8 +57,6 @@ public class ProxyPass { MINECRAFT_VERSION = minecraftVersion; } - public BedrockPacketCodec CODEC; - public int PROTOCOL_VERSION; private final AtomicBoolean running = new AtomicBoolean(true); private BedrockServer bedrockServer; private final Set clients = Collections.newSetFromMap(new ConcurrentHashMap<>()); @@ -92,7 +90,7 @@ public void boot() throws IOException { if (configuration.isEducation()) { CODEC = Bedrock_v363.V363_CODEC; } else { - CODEC = Bedrock_v390.V390_CODEC; + CODEC = Bedrock_v407.V407_CODEC; } PROTOCOL_VERSION = CODEC.getProtocolVersion(); From 3114e1b9e2521b3c72c7374bc24b1129eec655a6 Mon Sep 17 00:00:00 2001 From: bundabrg Date: Mon, 29 Jun 2020 19:22:13 +0800 Subject: [PATCH 3/9] Set raknetProtocol Version from codec --- .../nukkitx/proxypass/network/ProxyBedrockEventHandler.java | 2 +- .../network/bedrock/session/UpstreamPacketHandler.java | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/nukkitx/proxypass/network/ProxyBedrockEventHandler.java b/src/main/java/com/nukkitx/proxypass/network/ProxyBedrockEventHandler.java index 50d09ef..ea54585 100644 --- a/src/main/java/com/nukkitx/proxypass/network/ProxyBedrockEventHandler.java +++ b/src/main/java/com/nukkitx/proxypass/network/ProxyBedrockEventHandler.java @@ -29,7 +29,7 @@ public ProxyBedrockEventHandler(ProxyPass proxy) { } ADVERTISEMENT.setGameType("Survival"); ADVERTISEMENT.setVersion(ProxyPass.MINECRAFT_VERSION); - ADVERTISEMENT.setProtocolVersion(proxy.PROTOCOL_VERSION); + ADVERTISEMENT.setProtocolVersion(ProxyPass.PROTOCOL_VERSION); ADVERTISEMENT.setMotd("ProxyPass"); ADVERTISEMENT.setPlayerCount(0); ADVERTISEMENT.setMaximumPlayerCount(20); diff --git a/src/main/java/com/nukkitx/proxypass/network/bedrock/session/UpstreamPacketHandler.java b/src/main/java/com/nukkitx/proxypass/network/bedrock/session/UpstreamPacketHandler.java index 16420f0..060c2f6 100644 --- a/src/main/java/com/nukkitx/proxypass/network/bedrock/session/UpstreamPacketHandler.java +++ b/src/main/java/com/nukkitx/proxypass/network/bedrock/session/UpstreamPacketHandler.java @@ -138,13 +138,13 @@ public boolean handle(LoginPacket packet) { private void initializeProxySession() { log.debug("Initializing proxy session"); BedrockClient client = proxy.newClient(); - client.setRakNetVersion(10); + client.setRakNetVersion(ProxyPass.CODEC.getRaknetProtocolVersion()); client.connect(proxy.getTargetAddress()).whenComplete((downstream, throwable) -> { if (throwable != null) { log.error("Unable to connect to downstream server " + proxy.getTargetAddress(), throwable); return; } - downstream.setPacketCodec(proxy.CODEC); + downstream.setPacketCodec(ProxyPass.CODEC); ProxyPlayerSession proxySession = new ProxyPlayerSession(this.session, downstream, this.proxy, this.authData); this.player = proxySession; @@ -163,7 +163,7 @@ private void initializeProxySession() { LoginPacket login = new LoginPacket(); login.setChainData(chainData); login.setSkinData(AsciiString.of(skinData.serialize())); - login.setProtocolVersion(proxy.PROTOCOL_VERSION); + login.setProtocolVersion(ProxyPass.PROTOCOL_VERSION); downstream.sendPacketImmediately(login); this.session.setBatchHandler(proxySession.getUpstreamBatchHandler()); From e85aec1821b377689c8168830fdc1b1b5e065ecf Mon Sep 17 00:00:00 2001 From: bundabrg Date: Tue, 30 Jun 2020 10:42:58 +0800 Subject: [PATCH 4/9] Try resolve merge issues with Master and 1.16 branches --- README.md | 2 +- pom.xml | 6 ++++-- .../network/bedrock/session/ProxyPlayerSession.java | 4 ++-- .../network/bedrock/session/UpstreamPacketHandler.java | 6 +++--- .../nukkitx/proxypass/network/bedrock/util/RecipeUtils.java | 2 +- 5 files changed, 11 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index b86270c..9f637c0 100644 --- a/README.md +++ b/README.md @@ -11,4 +11,4 @@ __ProxyPass requires Java 8 u162 or later to function correctly due to the encr __[Jenkins](https://ci.nukkitx.com/job/NukkitX/job/ProxyPass/job/master/)__ -__[Protocol library](https://github.com/NukkitX/Protocol) used in this project__ +__[Protocol library](https://github.com/NukkitX/Protocol) used in this project__ \ No newline at end of file diff --git a/pom.xml b/pom.xml index 576ab50..82244a7 100644 --- a/pom.xml +++ b/pom.xml @@ -88,6 +88,7 @@ org.apache.maven.plugins maven-jar-plugin + 3.2.0 @@ -101,11 +102,12 @@ org.apache.maven.plugins maven-shade-plugin + 3.2.3 com.github.edwgiz maven-shade-plugin.log4j2-cachefile-transformer - 2.8.1 + 2.13.1 @@ -119,7 +121,7 @@ + implementation="com.github.edwgiz.maven_shade_plugin.log4j2_cache_transformer.PluginsCacheFileTransformer"> diff --git a/src/main/java/com/nukkitx/proxypass/network/bedrock/session/ProxyPlayerSession.java b/src/main/java/com/nukkitx/proxypass/network/bedrock/session/ProxyPlayerSession.java index ba7e686..a5fd088 100644 --- a/src/main/java/com/nukkitx/proxypass/network/bedrock/session/ProxyPlayerSession.java +++ b/src/main/java/com/nukkitx/proxypass/network/bedrock/session/ProxyPlayerSession.java @@ -133,11 +133,11 @@ public void handle(BedrockSession session, ByteBuf compressed, Collection proxy.PROTOCOL_VERSION) { + if (protocolVersion > ProxyPass.PROTOCOL_VERSION) { status.setStatus(PlayStatusPacket.Status.LOGIN_FAILED_SERVER_OLD); } else { status.setStatus(PlayStatusPacket.Status.LOGIN_FAILED_CLIENT_OLD); } } - session.setPacketCodec(proxy.CODEC); + session.setPacketCodec(ProxyPass.CODEC); JsonNode certData; try { diff --git a/src/main/java/com/nukkitx/proxypass/network/bedrock/util/RecipeUtils.java b/src/main/java/com/nukkitx/proxypass/network/bedrock/util/RecipeUtils.java index b7838a0..9a62ac4 100644 --- a/src/main/java/com/nukkitx/proxypass/network/bedrock/util/RecipeUtils.java +++ b/src/main/java/com/nukkitx/proxypass/network/bedrock/util/RecipeUtils.java @@ -95,7 +95,7 @@ public static void writeRecipes(CraftingDataPacket packet, ProxyPass proxy) { entries.add(entry); } - Recipes recipes = new Recipes(proxy.CODEC.getProtocolVersion(), entries, packet.getPotionMixData(), packet.getContainerMixData()); + Recipes recipes = new Recipes(ProxyPass.CODEC.getProtocolVersion(), entries, packet.getPotionMixData(), packet.getContainerMixData()); proxy.saveJson("recipes.json", recipes); } From a91c8420abc493225835c3ff6aad12b33017366b Mon Sep 17 00:00:00 2001 From: bundabrg Date: Tue, 12 May 2020 19:49:09 +0800 Subject: [PATCH 5/9] Implement Minecraft Education v1.12.60 support Changes: * Support both MCEE and MCPE versions. * Config entry to enable/disable education support * Enable 2 way encryption by default now whilst still performing mitm * Update for 1.16 * Set raknetProtocol Version from codec --- .gitignore | 4 ++- README.md | 2 +- pom.xml | 8 ++++++ .../com/nukkitx/proxypass/Configuration.java | 3 ++ .../java/com/nukkitx/proxypass/ProxyPass.java | 13 +++++++-- .../network/ProxyBedrockEventHandler.java | 14 +++++++--- .../session/DownstreamPacketHandler.java | 12 ++++++++ .../session/UpstreamPacketHandler.java | 12 +++++++- .../network/bedrock/util/ForgeryUtils.java | 28 +++++++++++++++++++ src/main/resources/config.yml | 3 ++ 10 files changed, 90 insertions(+), 9 deletions(-) diff --git a/.gitignore b/.gitignore index 68dda6d..f25b734 100644 --- a/.gitignore +++ b/.gitignore @@ -205,4 +205,6 @@ config.yml logs/ logs/* packet-logs/ -packet-logs/* \ No newline at end of file +packet-logs/* +data/* +sessions/* \ No newline at end of file diff --git a/README.md b/README.md index b86270c..9f637c0 100644 --- a/README.md +++ b/README.md @@ -11,4 +11,4 @@ __ProxyPass requires Java 8 u162 or later to function correctly due to the encr __[Jenkins](https://ci.nukkitx.com/job/NukkitX/job/ProxyPass/job/master/)__ -__[Protocol library](https://github.com/NukkitX/Protocol) used in this project__ +__[Protocol library](https://github.com/NukkitX/Protocol) used in this project__ \ No newline at end of file diff --git a/pom.xml b/pom.xml index 0251d97..82244a7 100644 --- a/pom.xml +++ b/pom.xml @@ -37,12 +37,20 @@ 1.3.9 provided + com.nukkitx.protocol bedrock-v407 2.6.0-SNAPSHOT compile + + + com.nukkitx.protocol + bedrock-v363 + 2.6.0-SNAPSHOT + compile + com.fasterxml.jackson.core jackson-databind diff --git a/src/main/java/com/nukkitx/proxypass/Configuration.java b/src/main/java/com/nukkitx/proxypass/Configuration.java index 5673272..a4d26ab 100644 --- a/src/main/java/com/nukkitx/proxypass/Configuration.java +++ b/src/main/java/com/nukkitx/proxypass/Configuration.java @@ -30,6 +30,9 @@ public class Configuration { @JsonProperty("log-to") private LogTo logTo = LogTo.FILE; + @JsonProperty("education") + private boolean education = false; + @JsonProperty("ignored-packets") private Set ignoredPackets = Collections.emptySet(); diff --git a/src/main/java/com/nukkitx/proxypass/ProxyPass.java b/src/main/java/com/nukkitx/proxypass/ProxyPass.java index ffe7cef..7d47d33 100644 --- a/src/main/java/com/nukkitx/proxypass/ProxyPass.java +++ b/src/main/java/com/nukkitx/proxypass/ProxyPass.java @@ -12,6 +12,7 @@ import com.nukkitx.protocol.bedrock.BedrockClient; import com.nukkitx.protocol.bedrock.BedrockPacketCodec; import com.nukkitx.protocol.bedrock.BedrockServer; +import com.nukkitx.protocol.bedrock.v363.Bedrock_v363; import com.nukkitx.protocol.bedrock.v407.Bedrock_v407; import com.nukkitx.proxypass.network.ProxyBedrockEventHandler; import io.netty.util.ResourceLeakDetector; @@ -37,8 +38,8 @@ public class ProxyPass { public static final ObjectMapper JSON_MAPPER = new ObjectMapper().disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); public static final YAMLMapper YAML_MAPPER = (YAMLMapper) new YAMLMapper().disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); public static final String MINECRAFT_VERSION; - public static final BedrockPacketCodec CODEC = Bedrock_v407.V407_CODEC; - public static final int PROTOCOL_VERSION = CODEC.getProtocolVersion(); + public static BedrockPacketCodec CODEC; + public static int PROTOCOL_VERSION; private static final DefaultPrettyPrinter PRETTY_PRINTER = new DefaultPrettyPrinter(); static { @@ -87,6 +88,14 @@ public void boot() throws IOException { configuration = Configuration.load(configPath); + if (configuration.isEducation()) { + CODEC = Bedrock_v363.V363_CODEC; + } else { + CODEC = Bedrock_v407.V407_CODEC; + } + + PROTOCOL_VERSION = CODEC.getProtocolVersion(); + proxyAddress = configuration.getProxy().getAddress(); targetAddress = configuration.getDestination().getAddress(); diff --git a/src/main/java/com/nukkitx/proxypass/network/ProxyBedrockEventHandler.java b/src/main/java/com/nukkitx/proxypass/network/ProxyBedrockEventHandler.java index e11611f..ea54585 100644 --- a/src/main/java/com/nukkitx/proxypass/network/ProxyBedrockEventHandler.java +++ b/src/main/java/com/nukkitx/proxypass/network/ProxyBedrockEventHandler.java @@ -13,15 +13,20 @@ import java.net.InetSocketAddress; @Log4j2 -@RequiredArgsConstructor @ParametersAreNonnullByDefault public class ProxyBedrockEventHandler implements BedrockServerEventHandler { - private static final BedrockPong ADVERTISEMENT = new BedrockPong(); private final ProxyPass proxy; + private final BedrockPong ADVERTISEMENT = new BedrockPong(); - static { - ADVERTISEMENT.setEdition("MCPE"); + public ProxyBedrockEventHandler(ProxyPass proxy) { + this.proxy = proxy; + + if (proxy.getConfiguration().isEducation()) { + ADVERTISEMENT.setEdition("MCEE"); + } else { + ADVERTISEMENT.setEdition("MCPE"); + } ADVERTISEMENT.setGameType("Survival"); ADVERTISEMENT.setVersion(ProxyPass.MINECRAFT_VERSION); ADVERTISEMENT.setProtocolVersion(ProxyPass.PROTOCOL_VERSION); @@ -29,6 +34,7 @@ public class ProxyBedrockEventHandler implements BedrockServerEventHandler { ADVERTISEMENT.setPlayerCount(0); ADVERTISEMENT.setMaximumPlayerCount(20); ADVERTISEMENT.setSubMotd("https://github.com/NukkitX/ProxyPass"); + } @Override diff --git a/src/main/java/com/nukkitx/proxypass/network/bedrock/session/DownstreamPacketHandler.java b/src/main/java/com/nukkitx/proxypass/network/bedrock/session/DownstreamPacketHandler.java index 727024b..dffd66b 100644 --- a/src/main/java/com/nukkitx/proxypass/network/bedrock/session/DownstreamPacketHandler.java +++ b/src/main/java/com/nukkitx/proxypass/network/bedrock/session/DownstreamPacketHandler.java @@ -16,6 +16,7 @@ import com.nukkitx.protocol.bedrock.util.EncryptionUtils; import com.nukkitx.proxypass.ProxyPass; import com.nukkitx.proxypass.network.bedrock.util.BlockPaletteUtils; +import com.nukkitx.proxypass.network.bedrock.util.ForgeryUtils; import com.nukkitx.proxypass.network.bedrock.util.RecipeUtils; import lombok.RequiredArgsConstructor; import lombok.Value; @@ -47,6 +48,17 @@ public boolean handle(ServerToClientHandshakePacket packet) { SecretKey key = EncryptionUtils.getSecretKey(this.player.getProxyKeyPair().getPrivate(), serverKey, Base64.getDecoder().decode(saltJwt.getJWTClaimsSet().getStringClaim("salt"))); session.enableEncryption(key); + + ServerToClientHandshakePacket p = new ServerToClientHandshakePacket(); + p.setJwt(ForgeryUtils.forgeHandshake( + player.getProxyKeyPair(), + saltJwt.getJWTClaimsSet().getStringClaim("signedToken"), + Base64.getDecoder().decode(saltJwt.getJWTClaimsSet().getStringClaim("salt"))).serialize() + ); + player.getUpstream().sendPacketImmediately(p); + player.getUpstream().enableEncryption(EncryptionUtils.getSecretKey(player.getProxyKeyPair().getPrivate(), + ((UpstreamPacketHandler)player.getUpstream().getPacketHandler()).getRemotePublicKey(),Base64.getDecoder().decode(saltJwt.getJWTClaimsSet().getStringClaim("salt")))); + } catch (ParseException | NoSuchAlgorithmException | InvalidKeySpecException | InvalidKeyException e) { throw new RuntimeException(e); } diff --git a/src/main/java/com/nukkitx/proxypass/network/bedrock/session/UpstreamPacketHandler.java b/src/main/java/com/nukkitx/proxypass/network/bedrock/session/UpstreamPacketHandler.java index 58ad902..c7e442e 100644 --- a/src/main/java/com/nukkitx/proxypass/network/bedrock/session/UpstreamPacketHandler.java +++ b/src/main/java/com/nukkitx/proxypass/network/bedrock/session/UpstreamPacketHandler.java @@ -12,12 +12,14 @@ import com.nukkitx.protocol.bedrock.BedrockClient; import com.nukkitx.protocol.bedrock.BedrockServerSession; import com.nukkitx.protocol.bedrock.handler.BedrockPacketHandler; +import com.nukkitx.protocol.bedrock.packet.ClientToServerHandshakePacket; import com.nukkitx.protocol.bedrock.packet.LoginPacket; import com.nukkitx.protocol.bedrock.packet.PlayStatusPacket; import com.nukkitx.protocol.bedrock.util.EncryptionUtils; import com.nukkitx.proxypass.ProxyPass; import com.nukkitx.proxypass.network.bedrock.util.ForgeryUtils; import io.netty.util.AsciiString; +import lombok.Getter; import lombok.RequiredArgsConstructor; import lombok.extern.log4j.Log4j2; import net.minidev.json.JSONObject; @@ -37,6 +39,8 @@ public class UpstreamPacketHandler implements BedrockPacketHandler { private ArrayNode chainData; private AuthData authData; private ProxyPlayerSession player; + @Getter + private ECPublicKey remotePublicKey; private static boolean validateChainData(JsonNode data) throws Exception { ECPublicKey lastKey = null; @@ -64,6 +68,11 @@ private static boolean verifyJwt(JWSObject jwt, ECPublicKey key) throws JOSEExce return jwt.verify(new DefaultJWSVerifierFactory().createJWSVerifier(jwt.getHeader(), key)); } + public boolean handle(ClientToServerHandshakePacket packet) { + // This is handled ourselves and we don't want a duplicate packet + return true; + } + @Override public boolean handle(LoginPacket packet) { int protocolVersion = packet.getProtocolVersion(); @@ -112,6 +121,7 @@ public boolean handle(LoginPacket packet) { throw new RuntimeException("Identity Public Key was not found!"); } ECPublicKey identityPublicKey = EncryptionUtils.generateKey(payload.get("identityPublicKey").textValue()); + this.remotePublicKey = identityPublicKey; JWSObject clientJwt = JWSObject.parse(packet.getSkinData().toString()); verifyJwt(clientJwt, identityPublicKey); @@ -128,7 +138,7 @@ public boolean handle(LoginPacket packet) { private void initializeProxySession() { log.debug("Initializing proxy session"); BedrockClient client = proxy.newClient(); - client.setRakNetVersion(10); + client.setRakNetVersion(ProxyPass.CODEC.getRaknetProtocolVersion()); client.connect(proxy.getTargetAddress()).whenComplete((downstream, throwable) -> { if (throwable != null) { log.error("Unable to connect to downstream server " + proxy.getTargetAddress(), throwable); diff --git a/src/main/java/com/nukkitx/proxypass/network/bedrock/util/ForgeryUtils.java b/src/main/java/com/nukkitx/proxypass/network/bedrock/util/ForgeryUtils.java index 9a45233..5603012 100644 --- a/src/main/java/com/nukkitx/proxypass/network/bedrock/util/ForgeryUtils.java +++ b/src/main/java/com/nukkitx/proxypass/network/bedrock/util/ForgeryUtils.java @@ -63,4 +63,32 @@ public static JWSObject forgeSkinData(KeyPair pair, JSONObject skinData) { return jws; } + + public static SignedJWT forgeHandshake(KeyPair pair, String signedToken, byte[] token) { + String publicKeyBase64 = Base64.getEncoder().encodeToString(pair.getPublic().getEncoded()); + URI x5u = URI.create(publicKeyBase64); + + JWSHeader header = new JWSHeader.Builder(JWSAlgorithm.ES384).x509CertURL(x5u).build(); + + long timestamp = System.currentTimeMillis(); + Date nbf = new Date(timestamp - TimeUnit.SECONDS.toMillis(1)); + Date exp = new Date(timestamp + TimeUnit.DAYS.toMillis(1)); + + JWTClaimsSet.Builder claimsBuilder = new JWTClaimsSet.Builder() + .claim("salt", Base64.getEncoder().encodeToString(token)); + + if (signedToken != null) { + claimsBuilder.claim("signedToken", signedToken); + } + + SignedJWT jwt = new SignedJWT(header, claimsBuilder.build()); + + try { + EncryptionUtils.signJwt(jwt, (ECPrivateKey) pair.getPrivate()); + } catch (JOSEException e) { + throw new RuntimeException(e); + } + + return jwt; + } } diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index dcde463..f79ff99 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -15,6 +15,9 @@ log-packets: true ## Valid options: console, file or both log-to: file +## Minecraft Education Support +education: false + ## Packets to ignore to make your log more refined. These default packet are generally spammed ignored-packets: - "NetworkStackLatencyPacket" From c3e5d6680961fe6954241d4abc621b9bc7ed981e Mon Sep 17 00:00:00 2001 From: bundabrg Date: Sun, 26 Jul 2020 19:19:03 +0800 Subject: [PATCH 6/9] Merge Fixes --- pom.xml | 11 +++++++++++ .../proxypass/network/ProxyBedrockEventHandler.java | 5 +---- .../bedrock/session/DownstreamPacketHandler.java | 2 +- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index 82244a7..545341a 100644 --- a/pom.xml +++ b/pom.xml @@ -14,6 +14,17 @@ nukkitx-repo https://repo.nukkitx.com/snapshot + + + bundabrg-repo + https://repo.worldguard.com.au/repository/maven-public + + true + + + true + + diff --git a/src/main/java/com/nukkitx/proxypass/network/ProxyBedrockEventHandler.java b/src/main/java/com/nukkitx/proxypass/network/ProxyBedrockEventHandler.java index 4c50069..f402a85 100644 --- a/src/main/java/com/nukkitx/proxypass/network/ProxyBedrockEventHandler.java +++ b/src/main/java/com/nukkitx/proxypass/network/ProxyBedrockEventHandler.java @@ -35,13 +35,10 @@ public ProxyBedrockEventHandler(ProxyPass proxy) { ADVERTISEMENT.setMaximumPlayerCount(20); ADVERTISEMENT.setSubMotd("https://github.com/NukkitX/ProxyPass"); - } - - public ProxyBedrockEventHandler(ProxyPass proxy) { - this.proxy = proxy; int port = this.proxy.getProxyAddress().getPort(); ADVERTISEMENT.setIpv4Port(port); ADVERTISEMENT.setIpv6Port(port); + } @Override diff --git a/src/main/java/com/nukkitx/proxypass/network/bedrock/session/DownstreamPacketHandler.java b/src/main/java/com/nukkitx/proxypass/network/bedrock/session/DownstreamPacketHandler.java index dffd66b..cb0b850 100644 --- a/src/main/java/com/nukkitx/proxypass/network/bedrock/session/DownstreamPacketHandler.java +++ b/src/main/java/com/nukkitx/proxypass/network/bedrock/session/DownstreamPacketHandler.java @@ -147,7 +147,7 @@ private void dumpCreativeItems(ItemData[] contents) { @Override public boolean handle(CreativeContentPacket packet) { - dumpCreativeItems(packet.getEntries().values().toArray(new ItemData[0])); + dumpCreativeItems(packet.getContents()); return false; } From edd2933aca31b2e2ad1177f7e28205df4c36eeef Mon Sep 17 00:00:00 2001 From: bundabrg Date: Thu, 20 Aug 2020 15:45:10 +0800 Subject: [PATCH 7/9] Update for MCEE 1.14.31 --- pom.xml | 4 ++-- src/main/java/com/nukkitx/proxypass/ProxyPass.java | 8 ++++---- .../network/bedrock/session/ProxyPlayerSession.java | 3 ++- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/pom.xml b/pom.xml index 545341a..c31626d 100644 --- a/pom.xml +++ b/pom.xml @@ -51,14 +51,14 @@ com.nukkitx.protocol - bedrock-v407 + bedrock-v409 2.6.0-SNAPSHOT compile com.nukkitx.protocol - bedrock-v363 + education-v390 2.6.0-SNAPSHOT compile diff --git a/src/main/java/com/nukkitx/proxypass/ProxyPass.java b/src/main/java/com/nukkitx/proxypass/ProxyPass.java index 49eb069..24edddb 100644 --- a/src/main/java/com/nukkitx/proxypass/ProxyPass.java +++ b/src/main/java/com/nukkitx/proxypass/ProxyPass.java @@ -12,8 +12,8 @@ import com.nukkitx.protocol.bedrock.BedrockClient; import com.nukkitx.protocol.bedrock.BedrockPacketCodec; import com.nukkitx.protocol.bedrock.BedrockServer; -import com.nukkitx.protocol.bedrock.v363.Bedrock_v363; -import com.nukkitx.protocol.bedrock.v407.Bedrock_v407; +import com.nukkitx.protocol.bedrock.v408.Bedrock_v408; +import com.nukkitx.protocol.education.v390.Education_v390; import com.nukkitx.proxypass.network.ProxyBedrockEventHandler; import io.netty.util.ResourceLeakDetector; import lombok.AccessLevel; @@ -88,9 +88,9 @@ public void boot() throws IOException { configuration = Configuration.load(configPath); if (configuration.isEducation()) { - CODEC = Bedrock_v363.V363_CODEC; + CODEC = Education_v390.V390_CODEC; } else { - CODEC = Bedrock_v407.V407_CODEC; + CODEC = Bedrock_v408.V408_CODEC; } PROTOCOL_VERSION = CODEC.getProtocolVersion(); diff --git a/src/main/java/com/nukkitx/proxypass/network/bedrock/session/ProxyPlayerSession.java b/src/main/java/com/nukkitx/proxypass/network/bedrock/session/ProxyPlayerSession.java index a5fd088..898f1ee 100644 --- a/src/main/java/com/nukkitx/proxypass/network/bedrock/session/ProxyPlayerSession.java +++ b/src/main/java/com/nukkitx/proxypass/network/bedrock/session/ProxyPlayerSession.java @@ -144,7 +144,8 @@ public void handle(BedrockSession session, ByteBuf compressed, Collection Date: Thu, 11 Feb 2021 15:39:13 +0800 Subject: [PATCH 8/9] Updates --- pom.xml | 12 ++++++------ src/main/java/com/nukkitx/proxypass/ProxyPass.java | 8 ++++---- .../network/bedrock/session/ProxyPlayerSession.java | 4 ++-- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/pom.xml b/pom.xml index c31626d..8e8040d 100644 --- a/pom.xml +++ b/pom.xml @@ -50,16 +50,16 @@ - com.nukkitx.protocol - bedrock-v409 - 2.6.0-SNAPSHOT + au.com.grieve.reversion + bedrock-v428 + 1.1.0-SNAPSHOT compile - com.nukkitx.protocol - education-v390 - 2.6.0-SNAPSHOT + au.com.grieve.reversion + education-v391 + 1.1.0-SNAPSHOT compile diff --git a/src/main/java/com/nukkitx/proxypass/ProxyPass.java b/src/main/java/com/nukkitx/proxypass/ProxyPass.java index 24edddb..0a08156 100644 --- a/src/main/java/com/nukkitx/proxypass/ProxyPass.java +++ b/src/main/java/com/nukkitx/proxypass/ProxyPass.java @@ -1,5 +1,7 @@ package com.nukkitx.proxypass; +import au.com.grieve.reversion.protocol.bedrock.v428.Bedrock_v428; +import au.com.grieve.reversion.protocol.education.v391.Education_v391; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.core.util.DefaultIndenter; import com.fasterxml.jackson.core.util.DefaultPrettyPrinter; @@ -12,8 +14,6 @@ import com.nukkitx.protocol.bedrock.BedrockClient; import com.nukkitx.protocol.bedrock.BedrockPacketCodec; import com.nukkitx.protocol.bedrock.BedrockServer; -import com.nukkitx.protocol.bedrock.v408.Bedrock_v408; -import com.nukkitx.protocol.education.v390.Education_v390; import com.nukkitx.proxypass.network.ProxyBedrockEventHandler; import io.netty.util.ResourceLeakDetector; import lombok.AccessLevel; @@ -88,9 +88,9 @@ public void boot() throws IOException { configuration = Configuration.load(configPath); if (configuration.isEducation()) { - CODEC = Education_v390.V390_CODEC; + CODEC = Education_v391.V391_CODEC; } else { - CODEC = Bedrock_v408.V408_CODEC; + CODEC = Bedrock_v428.V428_CODEC; } PROTOCOL_VERSION = CODEC.getProtocolVersion(); diff --git a/src/main/java/com/nukkitx/proxypass/network/bedrock/session/ProxyPlayerSession.java b/src/main/java/com/nukkitx/proxypass/network/bedrock/session/ProxyPlayerSession.java index 898f1ee..6d5421f 100644 --- a/src/main/java/com/nukkitx/proxypass/network/bedrock/session/ProxyPlayerSession.java +++ b/src/main/java/com/nukkitx/proxypass/network/bedrock/session/ProxyPlayerSession.java @@ -136,8 +136,8 @@ public void handle(BedrockSession session, ByteBuf compressed, Collection Date: Fri, 6 May 2022 11:48:46 +0800 Subject: [PATCH 9/9] WIP --- pom.xml | 4 ++-- src/main/java/com/nukkitx/proxypass/ProxyPass.java | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/pom.xml b/pom.xml index b7a45b4..d410454 100644 --- a/pom.xml +++ b/pom.xml @@ -51,14 +51,14 @@ au.com.grieve.reversion - bedrock-v422 + bedrock-v423 1.1.0-SNAPSHOT compile au.com.grieve.reversion - education-v391 + education-v392 1.1.0-SNAPSHOT compile diff --git a/src/main/java/com/nukkitx/proxypass/ProxyPass.java b/src/main/java/com/nukkitx/proxypass/ProxyPass.java index f2a52e0..1b51e00 100644 --- a/src/main/java/com/nukkitx/proxypass/ProxyPass.java +++ b/src/main/java/com/nukkitx/proxypass/ProxyPass.java @@ -1,7 +1,7 @@ package com.nukkitx.proxypass; -import au.com.grieve.reversion.protocol.bedrock.v428.Bedrock_v428; -import au.com.grieve.reversion.protocol.education.v391.Education_v391; +import au.com.grieve.reversion.protocol.bedrock.v423.Bedrock_v423; +import au.com.grieve.reversion.protocol.education.v392.Education_v392; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.core.util.DefaultIndenter; import com.fasterxml.jackson.core.util.DefaultPrettyPrinter; @@ -91,9 +91,9 @@ public void boot() throws IOException { configuration = Configuration.load(configPath); if (configuration.isEducation()) { - CODEC = Education_v391.V391_CODEC; + CODEC = Education_v392.V392_CODEC; } else { - CODEC = Bedrock_v428.V428_CODEC; + CODEC = Bedrock_v423.V423_CODEC; } PROTOCOL_VERSION = CODEC.getProtocolVersion();