From 14fd8f094cef46a9acb9402ead77da051ce63002 Mon Sep 17 00:00:00 2001 From: Nanit Date: Sat, 13 Nov 2021 11:45:45 +0200 Subject: [PATCH] Added BungeeGuard support --- README.md | 3 ++ build.gradle | 1 + .../limbo/connection/ClientConnection.java | 46 +++++++++++++++++++ .../limbo/server/data/InfoForwarding.java | 21 ++++++++- src/main/resources/settings.yml | 3 ++ 5 files changed, 73 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 9de6cfc..58f17f5 100644 --- a/README.md +++ b/README.md @@ -58,10 +58,13 @@ The server supports player info forwarding from the proxy. There are two type of * `LEGACY` - The **BungeeCord** IP forwarding. * `MODERN` - **Velocity** native info forwarding type. +* `BUNGEE_GUARD` - **BungeeGuard** forwarding type. If you use BungeeCord, or Velocity with `LEGACY` forwarding, just set this type in the config. If you use Velocity with `MODERN` info forwarding, set this type and paste secret key from Velocity config into `secret` field. +If you installed BungeeGuard on your proxy, then use `BUNGEE_GUARD` forwarding type. +Then add your tokens to `tokens` list. ### Contributing diff --git a/build.gradle b/build.gradle index 0049154..240a030 100644 --- a/build.gradle +++ b/build.gradle @@ -17,6 +17,7 @@ dependencies { implementation 'org.spongepowered:configurate-yaml:4.1.2' implementation 'io.netty:netty-all:4.1.54.Final' implementation 'net.kyori:adventure-nbt:4.9.2' + implementation 'com.grack:nanojson:1.7' } jar { diff --git a/src/main/java/ru/nanit/limbo/connection/ClientConnection.java b/src/main/java/ru/nanit/limbo/connection/ClientConnection.java index 8edab66..3340250 100644 --- a/src/main/java/ru/nanit/limbo/connection/ClientConnection.java +++ b/src/main/java/ru/nanit/limbo/connection/ClientConnection.java @@ -1,5 +1,9 @@ package ru.nanit.limbo.connection; +import com.grack.nanojson.JsonArray; +import com.grack.nanojson.JsonObject; +import com.grack.nanojson.JsonParser; +import com.grack.nanojson.JsonParserException; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import io.netty.channel.ChannelFutureListener; @@ -29,6 +33,7 @@ import java.net.InetSocketAddress; import java.net.SocketAddress; import java.security.InvalidKeyException; import java.security.MessageDigest; +import java.util.Arrays; import java.util.Collections; import java.util.UUID; import java.util.concurrent.ThreadLocalRandom; @@ -124,6 +129,10 @@ public class ClientConnection extends ChannelInboundHandlerAdapter { } else { disconnectLogin("You've enabled player info forwarding. You need to connect with proxy"); } + } else if (server.getConfig().getInfoForwarding().isBungeeGuard()) { + if (!checkBungeeGuardHandshake(handshake.getHost())) { + disconnectLogin("Invalid BungeeGuard token or handshake format"); + } } return; } @@ -292,6 +301,43 @@ public class ClientConnection extends ChannelInboundHandlerAdapter { this.address = new InetSocketAddress(host, ((InetSocketAddress)this.address).getPort()); } + private boolean checkBungeeGuardHandshake(String handshake) { + String[] split = handshake.split("\00"); + + if (split.length != 4) + return false; + + String socketAddressHostname = split[1]; + UUID uuid = UuidUtil.fromString(split[2]); + JsonArray arr; + + try { + arr = JsonParser.array().from(split[3]); + } catch (JsonParserException e) { + return false; + } + + String token = null; + + for (Object obj : arr) { + if (obj instanceof JsonObject) { + JsonObject prop = (JsonObject) obj; + if (prop.getString("name").equals("bungeeguard-token")) { + token = prop.getString("value"); + break; + } + } + } + + if (!server.getConfig().getInfoForwarding().hasToken(token)) + return false; + + setAddress(socketAddressHostname); + gameProfile.setUuid(uuid); + + return true; + } + private boolean checkVelocityKeyIntegrity(ByteMessage buf) { byte[] signature = new byte[32]; buf.readBytes(signature); diff --git a/src/main/java/ru/nanit/limbo/server/data/InfoForwarding.java b/src/main/java/ru/nanit/limbo/server/data/InfoForwarding.java index ae3ae89..711788a 100644 --- a/src/main/java/ru/nanit/limbo/server/data/InfoForwarding.java +++ b/src/main/java/ru/nanit/limbo/server/data/InfoForwarding.java @@ -6,11 +6,13 @@ import org.spongepowered.configurate.serialize.SerializationException; import org.spongepowered.configurate.serialize.TypeSerializer; import java.nio.charset.StandardCharsets; +import java.util.List; public class InfoForwarding { private Type type; private byte[] secretKey; + private List tokens; public Type getType() { return type; @@ -20,6 +22,14 @@ public class InfoForwarding { return secretKey; } + public List getTokens() { + return tokens; + } + + public boolean hasToken(String token) { + return tokens != null && token != null && tokens.contains(token); + } + public boolean isNone() { return type == Type.NONE; } @@ -32,10 +42,15 @@ public class InfoForwarding { return type == Type.MODERN; } + public boolean isBungeeGuard() { + return type == Type.BUNGEE_GUARD; + } + public enum Type { NONE, LEGACY, - MODERN + MODERN, + BUNGEE_GUARD } public static class Serializer implements TypeSerializer { @@ -54,6 +69,10 @@ public class InfoForwarding { forwarding.secretKey = node.node("secret").getString("").getBytes(StandardCharsets.UTF_8); } + if (forwarding.type == Type.BUNGEE_GUARD) { + forwarding.tokens = node.node("tokens").getList(String.class); + } + return forwarding; } diff --git a/src/main/resources/settings.yml b/src/main/resources/settings.yml index 4f53893..5345dd9 100644 --- a/src/main/resources/settings.yml +++ b/src/main/resources/settings.yml @@ -69,10 +69,13 @@ title: # - NONE # - LEGACY # - MODERN +# - BUNGEE_GUARD # Don't use secret if you not use MODERN type infoForwarding: type: NONE secret: '' + tokens: + - '' # Read timeout for connections in milliseconds readTimeout: 30000