Merge 17eefaaa1a
into 3102433f31
This commit is contained in:
commit
530b1811c0
|
@ -0,0 +1,396 @@
|
|||
From 2b48760148e5ef1812f4e6b6fb5f9cdaef1bc560 Mon Sep 17 00:00:00 2001
|
||||
From: Ismael Hanbel <soportexism4@gmail.com>
|
||||
Date: Sat, 8 Jul 2023 20:36:35 +0200
|
||||
Subject: [PATCH] Rework-information-forwarding.patch
|
||||
|
||||
|
||||
diff --git a/api/src/main/java/io/github/waterfallmc/waterfall/forwarding/ForwardingMode.java b/api/src/main/java/io/github/waterfallmc/waterfall/forwarding/ForwardingMode.java
|
||||
new file mode 100644
|
||||
index 00000000..d6c17460
|
||||
--- /dev/null
|
||||
+++ b/api/src/main/java/io/github/waterfallmc/waterfall/forwarding/ForwardingMode.java
|
||||
@@ -0,0 +1,12 @@
|
||||
+package io.github.waterfallmc.waterfall.forwarding;
|
||||
+
|
||||
+/**
|
||||
+ * + * This enum represents the forwarding modes supported by Waterfall.
|
||||
+ * +
|
||||
+ */
|
||||
+
|
||||
+public enum ForwardingMode {
|
||||
+ BUNGEECORD_LEGACY,
|
||||
+ BUNGEEGUARD,
|
||||
+ VELOCITY_MODERN
|
||||
+}
|
||||
\ No newline at end of file
|
||||
diff --git a/api/src/main/java/net/md_5/bungee/Util.java b/api/src/main/java/net/md_5/bungee/Util.java
|
||||
index 91efc0a6..8d83f41c 100644
|
||||
--- a/api/src/main/java/net/md_5/bungee/Util.java
|
||||
+++ b/api/src/main/java/net/md_5/bungee/Util.java
|
||||
@@ -8,7 +8,9 @@ import java.net.InetSocketAddress;
|
||||
import java.net.SocketAddress;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
+import java.security.SecureRandom;
|
||||
import java.util.Locale;
|
||||
+import java.util.Random;
|
||||
import java.util.UUID;
|
||||
|
||||
import io.github.waterfallmc.waterfall.utils.Hex;
|
||||
@@ -141,4 +143,22 @@ public class Util
|
||||
{
|
||||
return new UUID( UnsignedLongs.parseUnsignedLong( uuid.substring( 0, 16 ), 16 ), UnsignedLongs.parseUnsignedLong( uuid.substring( 16 ), 16 ) );
|
||||
}
|
||||
+
|
||||
+ // Waterfall start: Forwarding rework
|
||||
+ /**
|
||||
+ * Generates an alphanumeric A-Z,a-z,0-9 byte-sequence.
|
||||
+ *
|
||||
+ * @param len the length of the sequence
|
||||
+ * @return a UTF/ASCII compatible alphanumeric byte-sequence
|
||||
+ */
|
||||
+ public static byte[] randomAlphanumericSequence(int len) {
|
||||
+ Random random = new SecureRandom();
|
||||
+ byte[] ret = new byte[len];
|
||||
+ for (int i = 0; i < len; i++) {
|
||||
+ int seq = random.nextInt(62);
|
||||
+ ret[i] = (byte) (seq < 10 ? seq + 48 : seq < 36 ? seq + 55 : seq + 61);
|
||||
+ }
|
||||
+ return ret;
|
||||
+ }
|
||||
+ // Waterfall end: Forwarding rework
|
||||
}
|
||||
diff --git a/api/src/main/java/net/md_5/bungee/api/ProxyConfig.java b/api/src/main/java/net/md_5/bungee/api/ProxyConfig.java
|
||||
index 469fe0e1..b78c0d5f 100644
|
||||
--- a/api/src/main/java/net/md_5/bungee/api/ProxyConfig.java
|
||||
+++ b/api/src/main/java/net/md_5/bungee/api/ProxyConfig.java
|
||||
@@ -2,6 +2,8 @@ package net.md_5.bungee.api;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
+
|
||||
+import io.github.waterfallmc.waterfall.forwarding.ForwardingMode;
|
||||
import net.md_5.bungee.api.config.ListenerInfo;
|
||||
import net.md_5.bungee.api.config.ServerInfo;
|
||||
|
||||
@@ -275,4 +277,11 @@ public interface ProxyConfig
|
||||
* @return the configured limit
|
||||
*/
|
||||
int getPluginChannelNameLimit();
|
||||
+
|
||||
+ /**
|
||||
+ * Represents the forwarding mode as configured.
|
||||
+ *
|
||||
+ * @return the mode set in the config
|
||||
+ */
|
||||
+ ForwardingMode getForwardingMode();
|
||||
}
|
||||
diff --git a/api/src/main/java/net/md_5/bungee/api/plugin/PluginManager.java b/api/src/main/java/net/md_5/bungee/api/plugin/PluginManager.java
|
||||
index 1ba5b249..c0797a4a 100644
|
||||
--- a/api/src/main/java/net/md_5/bungee/api/plugin/PluginManager.java
|
||||
+++ b/api/src/main/java/net/md_5/bungee/api/plugin/PluginManager.java
|
||||
@@ -49,7 +49,7 @@ import org.yaml.snakeyaml.introspector.PropertyUtils;
|
||||
* example event handling and plugin management.
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
-public final class PluginManager
|
||||
+public final class PluginManager
|
||||
{
|
||||
|
||||
/*========================================================================*/
|
||||
@@ -440,6 +440,14 @@ public final class PluginManager
|
||||
Preconditions.checkNotNull( desc.getName(), "Plugin from %s has no name", file );
|
||||
Preconditions.checkNotNull( desc.getMain(), "Plugin from %s has no main", file );
|
||||
|
||||
+ // Waterfall start: Forwarding rework
|
||||
+ if (desc.getName().equals("BungeeGuard")) {
|
||||
+ proxy.getLogger().warning("Detected the plugin BungeeGuard. " +
|
||||
+ "Waterfall now supports the functionality this plugin provides natively. " +
|
||||
+ "Please refer to the Waterfall documentation for more information.");
|
||||
+ }
|
||||
+ // Waterfall end: Forwarding rework
|
||||
+
|
||||
desc.setFile( file );
|
||||
toLoad.put( desc.getName(), desc );
|
||||
}
|
||||
diff --git a/proxy/src/main/java/io/github/waterfallmc/waterfall/conf/WaterfallConfiguration.java b/proxy/src/main/java/io/github/waterfallmc/waterfall/conf/WaterfallConfiguration.java
|
||||
index da0efa36..03c628f4 100644
|
||||
--- a/proxy/src/main/java/io/github/waterfallmc/waterfall/conf/WaterfallConfiguration.java
|
||||
+++ b/proxy/src/main/java/io/github/waterfallmc/waterfall/conf/WaterfallConfiguration.java
|
||||
@@ -1,11 +1,16 @@
|
||||
package io.github.waterfallmc.waterfall.conf;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
+import io.github.waterfallmc.waterfall.forwarding.ForwardingMode;
|
||||
+import net.md_5.bungee.BungeeCord;
|
||||
+import net.md_5.bungee.Util;
|
||||
import net.md_5.bungee.conf.Configuration;
|
||||
import net.md_5.bungee.conf.YamlConfig;
|
||||
import net.md_5.bungee.protocol.ProtocolConstants;
|
||||
|
||||
import java.io.File;
|
||||
+import java.nio.charset.StandardCharsets;
|
||||
+import java.util.logging.Logger;
|
||||
|
||||
public class WaterfallConfiguration extends Configuration {
|
||||
|
||||
@@ -45,6 +50,9 @@ public class WaterfallConfiguration extends Configuration {
|
||||
private boolean disableEntityMetadataRewrite = false;
|
||||
private boolean disableTabListRewrite = true;
|
||||
|
||||
+ private ForwardingMode forwardingMode = ForwardingMode.BUNGEECORD_LEGACY;
|
||||
+ private byte[] forwardingSecret = Util.randomAlphanumericSequence(12);
|
||||
+
|
||||
/*
|
||||
* Plugin Message limiting options
|
||||
* Allows for more control over server-client communication
|
||||
@@ -77,6 +85,25 @@ public class WaterfallConfiguration extends Configuration {
|
||||
disableTabListRewrite = config.getBoolean("disable_tab_list_rewrite", disableTabListRewrite);
|
||||
pluginChannelLimit = config.getInt("registered_plugin_channels_limit", pluginChannelLimit);
|
||||
pluginChannelNameLimit = config.getInt("plugin_channel_name_limit", pluginChannelNameLimit);
|
||||
+ // Forwarding options
|
||||
+ forwardingMode = ForwardingMode.valueOf(config.getString("forwarding_mode", ForwardingMode.BUNGEECORD_LEGACY.toString()).toUpperCase());
|
||||
+ Logger logger = BungeeCord.getInstance().getLogger();
|
||||
+ if (super.isIpForward()) {
|
||||
+ if ((forwardingMode) == ForwardingMode.BUNGEECORD_LEGACY) {
|
||||
+ logger.warning("The forwarding mode is set as BungeeCord legacy, it is recommended that you use another mode to avoid spoofing information attacks.");
|
||||
+ }
|
||||
+
|
||||
+ } else {
|
||||
+ logger.warning("Information forwarding (ip-forwarding) is disabled. " +
|
||||
+ "Player UUIDs may not be consistent across the servers. " +
|
||||
+ "For the optimal experience please enable ip_forward in the config.yml and " +
|
||||
+ "configure forwarding and on your servers.");
|
||||
+ }
|
||||
+
|
||||
+ if (config.getString("forwarding_secret", "").isEmpty()) {
|
||||
+ config.regenerateForwardingSecret();
|
||||
+ logger.warning("A new forwarding secret has been generated. If this was the " +
|
||||
+ "first start of the proxy please configure forwarding for your network.");
|
||||
+ }
|
||||
+ forwardingSecret = config.getString("forwarding_secret", "").getBytes(StandardCharsets.UTF_8);
|
||||
+ }
|
||||
|
||||
@Override
|
||||
@@ -123,4 +150,13 @@ public class WaterfallConfiguration extends Configuration {
|
||||
public int getPluginChannelNameLimit() {
|
||||
return pluginChannelNameLimit;
|
||||
}
|
||||
+
|
||||
+ @Override
|
||||
+ public ForwardingMode getForwardingMode() {
|
||||
+ return forwardingMode;
|
||||
+ }
|
||||
+
|
||||
+ public byte[] getForwardingSecret() {
|
||||
+ return forwardingSecret;
|
||||
+ }
|
||||
}
|
||||
diff --git a/proxy/src/main/java/io/github/waterfallmc/waterfall/forwarding/VelocityForwardingUtil.java b/proxy/src/main/java/io/github/waterfallmc/waterfall/forwarding/VelocityForwardingUtil.java
|
||||
new file mode 100644
|
||||
index 00000000..b9990f92
|
||||
--- /dev/null
|
||||
+++ b/proxy/src/main/java/io/github/waterfallmc/waterfall/forwarding/VelocityForwardingUtil.java
|
||||
@@ -0,0 +1,69 @@
|
||||
+package io.github.waterfallmc.waterfall.forwarding;
|
||||
+
|
||||
+import io.github.waterfallmc.waterfall.conf.WaterfallConfiguration;
|
||||
+import io.netty.buffer.ByteBuf;
|
||||
+import io.netty.buffer.ByteBufUtil;
|
||||
+import io.netty.buffer.Unpooled;
|
||||
+import lombok.experimental.UtilityClass;
|
||||
+import net.md_5.bungee.BungeeCord;
|
||||
+import net.md_5.bungee.protocol.DefinedPacket;
|
||||
+import net.md_5.bungee.protocol.Property;
|
||||
+
|
||||
+import javax.crypto.Mac;
|
||||
+import javax.crypto.SecretKey;
|
||||
+import javax.crypto.spec.SecretKeySpec;
|
||||
+import java.security.InvalidKeyException;
|
||||
+import java.security.NoSuchAlgorithmException;
|
||||
+import java.util.UUID;
|
||||
+
|
||||
+@UtilityClass
|
||||
+public class VelocityForwardingUtil {
|
||||
+
|
||||
+ public static final String VELOCITY_IP_FORWARDING_CHANNEL = "velocity:player_info";
|
||||
+ public static final int FORWARDING_VERSION = 1;
|
||||
+
|
||||
+ public static final String MODERN_IP_FORWARDING_FAILURE = "Your server did not send a forwarding request to the proxy. Is it set up correctly?";
|
||||
+
|
||||
+ public static byte[] writeForwardingData(String address, String name, UUID playerUUID, Property[] properties) {
|
||||
+
|
||||
+ ByteBuf buf = Unpooled.buffer(2048);
|
||||
+
|
||||
+ try {
|
||||
+ DefinedPacket.writeVarInt(FORWARDING_VERSION, buf);
|
||||
+ DefinedPacket.writeString(address, buf);
|
||||
+ DefinedPacket.writeUUID(playerUUID, buf);
|
||||
+ DefinedPacket.writeString(name, buf);
|
||||
+ DefinedPacket.writeVarInt(properties.length, buf);
|
||||
+ for (Property property : properties) {
|
||||
+ DefinedPacket.writeString(property.getName(), buf);
|
||||
+ DefinedPacket.writeString(property.getValue(), buf);
|
||||
+ String signature = property.getSignature();
|
||||
+ if (signature != null && !signature.isEmpty()) {
|
||||
+ buf.writeBoolean(true);
|
||||
+ DefinedPacket.writeString(signature, buf);
|
||||
+ } else {
|
||||
+ buf.writeBoolean(false);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ byte[] forwardingSecret = ((WaterfallConfiguration) BungeeCord.getInstance().config).getForwardingSecret();
|
||||
+ SecretKey key = new SecretKeySpec(forwardingSecret, "HmacSHA256");
|
||||
+ Mac mac = Mac.getInstance("HmacSHA256");
|
||||
+ mac.init(key);
|
||||
+ mac.update(buf.array(), buf.arrayOffset(), buf.readableBytes());
|
||||
+ byte[] sig = mac.doFinal();
|
||||
+
|
||||
+ ByteBuf finished = Unpooled.wrappedBuffer(Unpooled.wrappedBuffer(sig), buf);
|
||||
+ byte[] encoded = ByteBufUtil.getBytes(finished);
|
||||
+ finished.release();
|
||||
+ return encoded;
|
||||
+ } catch (InvalidKeyException e) {
|
||||
+ buf.release();
|
||||
+ throw new RuntimeException("Unable to authenticate data", e);
|
||||
+ } catch (NoSuchAlgorithmException e) {
|
||||
+ // Should never happen
|
||||
+ buf.release();
|
||||
+ throw new AssertionError(e);
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
\ No newline at end of file
|
||||
diff --git a/proxy/src/main/java/net/md_5/bungee/ServerConnector.java b/proxy/src/main/java/net/md_5/bungee/ServerConnector.java
|
||||
index 60232e52..dfde3535 100644
|
||||
--- a/proxy/src/main/java/net/md_5/bungee/ServerConnector.java
|
||||
+++ b/proxy/src/main/java/net/md_5/bungee/ServerConnector.java
|
||||
@@ -2,15 +2,15 @@ package net.md_5.bungee;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.base.Preconditions;
|
||||
+import io.github.waterfallmc.waterfall.conf.WaterfallConfiguration;
|
||||
+import io.github.waterfallmc.waterfall.forwarding.ForwardingMode;
|
||||
+import io.github.waterfallmc.waterfall.forwarding.VelocityForwardingUtil;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.ByteBufAllocator;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
-import java.util.Locale;
|
||||
-import java.util.Arrays; // Waterfall
|
||||
-import java.util.Queue;
|
||||
-import java.util.Set;
|
||||
-import java.util.UUID;
|
||||
+import java.util.*;
|
||||
+
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import net.md_5.bungee.api.ChatColor;
|
||||
@@ -35,11 +35,7 @@ import net.md_5.bungee.netty.ChannelWrapper;
|
||||
import net.md_5.bungee.netty.HandlerBoss;
|
||||
import net.md_5.bungee.netty.PacketHandler;
|
||||
import net.md_5.bungee.netty.PipelineUtils;
|
||||
-import net.md_5.bungee.protocol.DefinedPacket;
|
||||
-import net.md_5.bungee.protocol.MinecraftDecoder;
|
||||
-import net.md_5.bungee.protocol.PacketWrapper;
|
||||
-import net.md_5.bungee.protocol.Protocol;
|
||||
-import net.md_5.bungee.protocol.ProtocolConstants;
|
||||
+import net.md_5.bungee.protocol.*;
|
||||
import net.md_5.bungee.protocol.packet.EncryptionRequest;
|
||||
import net.md_5.bungee.protocol.packet.EntityStatus;
|
||||
import net.md_5.bungee.protocol.packet.GameState;
|
||||
@@ -73,6 +69,8 @@ public class ServerConnector extends PacketHandler
|
||||
private ForgeServerHandler handshakeHandler;
|
||||
private boolean obsolete;
|
||||
|
||||
+ private boolean didForwardInformation = false; // Waterfall: Forwarding rework
|
||||
+
|
||||
private enum State
|
||||
{
|
||||
|
||||
@@ -106,6 +104,8 @@ public class ServerConnector extends PacketHandler
|
||||
Handshake originalHandshake = user.getPendingConnection().getHandshake();
|
||||
Handshake copiedHandshake = new Handshake( originalHandshake.getProtocolVersion(), originalHandshake.getHost(), originalHandshake.getPort(), 2 );
|
||||
|
||||
+ if(BungeeCord.getInstance().config.getForwardingMode() != ForwardingMode.VELOCITY_MODERN) // Waterfall: Forwarding rework
|
||||
+
|
||||
if ( BungeeCord.getInstance().config.isIpForward() && user.getSocketAddress() instanceof InetSocketAddress )
|
||||
{
|
||||
String newHost = copiedHandshake.getHost() + "\00" + AddressUtil.sanitizeAddress( user.getAddress() ) + "\00" + user.getUUID();
|
||||
@@ -120,6 +120,15 @@ public class ServerConnector extends PacketHandler
|
||||
properties = profile.getProperties();
|
||||
}
|
||||
|
||||
+ // Waterfall start: Forwarding rework
|
||||
+ if (BungeeCord.getInstance().config.getForwardingMode() == ForwardingMode.BUNGEEGUARD) {
|
||||
+ List<Property> temp = new ArrayList<>(Arrays.asList(properties));
|
||||
+ String token = new String(((WaterfallConfiguration) BungeeCord.getInstance().config).getForwardingSecret(), StandardCharsets.UTF_8);
|
||||
+ temp.add(new Property("bungeeguard-token", token, null));
|
||||
+ properties = temp.toArray(new Property[0]);
|
||||
+ }
|
||||
+ // Waterfall end: Forwarding rework
|
||||
+
|
||||
if ( user.getForgeClientHandler().isFmlTokenInHandshake() )
|
||||
{
|
||||
// Get the current properties and copy them into a slightly bigger array.
|
||||
@@ -171,6 +180,12 @@ public class ServerConnector extends PacketHandler
|
||||
@Override
|
||||
public void handle(LoginSuccess loginSuccess) throws Exception
|
||||
{
|
||||
+ // Waterfall start: Forwarding rework
|
||||
+ if (!didForwardInformation && BungeeCord.getInstance().config.isIpForward()
|
||||
+ && BungeeCord.getInstance().config.getForwardingMode() == ForwardingMode.VELOCITY_MODERN) {
|
||||
+ throw new QuietException(VelocityForwardingUtil.MODERN_IP_FORWARDING_FAILURE);
|
||||
+ }
|
||||
+ // Waterfall end: Forwarding rework
|
||||
Preconditions.checkState( thisState == State.LOGIN_SUCCESS, "Not expecting LOGIN_SUCCESS" );
|
||||
ch.setProtocol( Protocol.GAME );
|
||||
thisState = State.LOGIN;
|
||||
@@ -480,6 +495,20 @@ public class ServerConnector extends PacketHandler
|
||||
@Override
|
||||
public void handle(LoginPayloadRequest loginPayloadRequest)
|
||||
{
|
||||
+ // Waterfall start: Forwarding rework
|
||||
+ if (!didForwardInformation && BungeeCord.getInstance().config.isIpForward()
|
||||
+ && BungeeCord.getInstance().config.getForwardingMode() == ForwardingMode.VELOCITY_MODERN
|
||||
+ && loginPayloadRequest.getChannel().equals(VelocityForwardingUtil.VELOCITY_IP_FORWARDING_CHANNEL)) {
|
||||
+
|
||||
+ byte[] forwardingData = VelocityForwardingUtil
|
||||
+ .writeForwardingData(user.getAddress().getAddress().getHostAddress(),
|
||||
+ user.getName(), user.getUniqueId(),
|
||||
+ user.getPendingConnection().getLoginProfile().getProperties());
|
||||
+ ch.write(new LoginPayloadResponse(loginPayloadRequest.getId(), forwardingData));
|
||||
+ didForwardInformation = true;
|
||||
+ return;
|
||||
+ }
|
||||
+ // Waterfall end: Forwarding rework
|
||||
ch.write( new LoginPayloadResponse( loginPayloadRequest.getId(), null ) );
|
||||
}
|
||||
|
||||
diff --git a/proxy/src/main/java/net/md_5/bungee/conf/YamlConfig.java b/proxy/src/main/java/net/md_5/bungee/conf/YamlConfig.java
|
||||
index 0dd69778..e3220e08 100644
|
||||
--- a/proxy/src/main/java/net/md_5/bungee/conf/YamlConfig.java
|
||||
+++ b/proxy/src/main/java/net/md_5/bungee/conf/YamlConfig.java
|
||||
@@ -10,6 +10,7 @@ import java.io.InputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.Writer;
|
||||
import java.net.SocketAddress;
|
||||
+import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
@@ -332,4 +333,10 @@ public class YamlConfig implements ConfigurationAdapter
|
||||
Collection<String> permissions = get( "permissions." + group, null );
|
||||
return ( permissions == null ) ? Collections.EMPTY_SET : permissions;
|
||||
}
|
||||
+
|
||||
+ // Waterfall start: Forwarding rework
|
||||
+ public void regenerateForwardingSecret() {
|
||||
+ set("forwarding_secret", new String(Util.randomAlphanumericSequence(12), StandardCharsets.UTF_8));
|
||||
+ }
|
||||
+ // Waterfall end: Forwarding rework
|
||||
}
|
||||
--
|
||||
2.41.0.windows.1
|
||||
|
Loading…
Reference in New Issue