From 08178f51b7bdda09ac208c0cdd1ee7704dbe15fd Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Mon, 27 Sep 2021 14:45:53 -0400 Subject: [PATCH] Remove time syncer checks This check has caused more harm than good (with needing to use an external NTP source and some providers not allowing Cloudflare's NTP server), and is also a technical vulnerability in BungeeGuard. In order to exploit this, you would need to capture traffic between the Geyser server and the Floodgate instance. --- .../addon/data/BungeeProxyDataHandler.java | 4 -- .../geysermc/floodgate/FloodgatePlatform.java | 5 +- .../player/FloodgateHandshakeHandler.java | 47 ------------------- .../addon/data/SpigotDataHandler.java | 4 -- .../addon/data/VelocityProxyDataHandler.java | 4 -- 5 files changed, 4 insertions(+), 60 deletions(-) diff --git a/bungee/src/main/java/org/geysermc/floodgate/addon/data/BungeeProxyDataHandler.java b/bungee/src/main/java/org/geysermc/floodgate/addon/data/BungeeProxyDataHandler.java index 65472c5a..2e1908b5 100644 --- a/bungee/src/main/java/org/geysermc/floodgate/addon/data/BungeeProxyDataHandler.java +++ b/bungee/src/main/java/org/geysermc/floodgate/addon/data/BungeeProxyDataHandler.java @@ -141,10 +141,6 @@ public class BungeeProxyDataHandler extends ChannelInboundHandlerAdapter { ctx.channel().attr(kickMessageAttribute) .set(config.getDisconnect().getInvalidArgumentsLength()); break; - case TIMESTAMP_DENIED: - ctx.channel().attr(kickMessageAttribute) - .set(Constants.TIMESTAMP_DENIED_MESSAGE); - break; default: break; } diff --git a/common/src/main/java/org/geysermc/floodgate/FloodgatePlatform.java b/common/src/main/java/org/geysermc/floodgate/FloodgatePlatform.java index d63fee1a..de6429b0 100644 --- a/common/src/main/java/org/geysermc/floodgate/FloodgatePlatform.java +++ b/common/src/main/java/org/geysermc/floodgate/FloodgatePlatform.java @@ -104,7 +104,10 @@ public class FloodgatePlatform { guice = guice.createChildInjector(new ConfigLoadedModule(config)); PlayerLink link = guice.getInstance(PlayerLinkLoader.class).load(); - TimeSyncerHolder.init(); + if (config.isProxy()) { + // We can't assume, for now, that the backend Floodgate instances are updated to remove this + TimeSyncerHolder.init(); + } InstanceHolder.set(api, link, this.injector, packetHandlers, handshakeHandlers, KEY); diff --git a/common/src/main/java/org/geysermc/floodgate/player/FloodgateHandshakeHandler.java b/common/src/main/java/org/geysermc/floodgate/player/FloodgateHandshakeHandler.java index f13b6271..2243d6ca 100644 --- a/common/src/main/java/org/geysermc/floodgate/player/FloodgateHandshakeHandler.java +++ b/common/src/main/java/org/geysermc/floodgate/player/FloodgateHandshakeHandler.java @@ -66,12 +66,6 @@ import org.geysermc.floodgate.util.Utils; @RequiredArgsConstructor public final class FloodgateHandshakeHandler { - private final Cache handleCache = - CacheBuilder.newBuilder() - .maximumSize(500) - .expireAfterWrite(10, TimeUnit.SECONDS) - .build(); - private final HandshakeHandlersImpl handshakeHandlers; private final SimpleFloodgateApi api; private final FloodgateCipher cipher; @@ -119,46 +113,6 @@ public final class FloodgateHandshakeHandler { ); } - // timestamp checks - - TimeSyncer timeSyncer = TimeSyncerHolder.get(); - - if (!timeSyncer.hasUsefulOffset()) { - logger.warn("We couldn't make sure that your system clock is accurate. " + - "This can cause issues with logging in."); - } - - // the time syncer is accurate, but we have to account for some minor differences - final int errorMargin = 150; // 150ms - - long timeDifference = timeSyncer.getRealMillis() - bedrockData.getTimestamp(); - if (timeDifference > 6000 + errorMargin || timeDifference < -errorMargin) { - if (Constants.DEBUG_MODE || logger.isDebug()) { - logger.info("Current time: " + System.currentTimeMillis()); - logger.info("Stored time: " + bedrockData.getTimestamp()); - logger.info("Time offset: " + timeSyncer.getTimeOffset()); - } - throw callHandlerAndReturnResult( - ResultType.TIMESTAMP_DENIED, - channel, bedrockData, hostname - ); - } - - Long cachedTimestamp = handleCache.getIfPresent(bedrockData.getXuid()); - if (cachedTimestamp != null) { - // the cached timestamp should be older than the received timestamp - // and it should also not be possible to reuse the handshake - long diff = bedrockData.getTimestamp() - cachedTimestamp; - if (diff == 0 || diff < 0 && -diff > errorMargin) { - throw callHandlerAndReturnResult( - ResultType.TIMESTAMP_DENIED, - channel, bedrockData, hostname - ); - } - } - - handleCache.put(bedrockData.getXuid(), bedrockData.getTimestamp()); - // we'll use the LinkedPlayer provided by Bungee or Velocity (if they included one) if (bedrockData.hasPlayerLink()) { throw handlePart2(channel, hostname, bedrockData, bedrockData.getLinkedPlayer()); @@ -310,7 +264,6 @@ public final class FloodgateHandshakeHandler { NOT_FLOODGATE_DATA, DECRYPT_ERROR, INVALID_DATA_LENGTH, - TIMESTAMP_DENIED, SUCCESS } diff --git a/spigot/src/main/java/org/geysermc/floodgate/addon/data/SpigotDataHandler.java b/spigot/src/main/java/org/geysermc/floodgate/addon/data/SpigotDataHandler.java index 7353d361..ee99391a 100644 --- a/spigot/src/main/java/org/geysermc/floodgate/addon/data/SpigotDataHandler.java +++ b/spigot/src/main/java/org/geysermc/floodgate/addon/data/SpigotDataHandler.java @@ -109,10 +109,6 @@ public final class SpigotDataHandler extends ChannelInboundHandlerAdapter { ); ctx.close(); return true; - case TIMESTAMP_DENIED: - logger.info(Constants.TIMESTAMP_DENIED_MESSAGE); - ctx.close(); - return true; default: // only continue when SUCCESS return true; } diff --git a/velocity/src/main/java/org/geysermc/floodgate/addon/data/VelocityProxyDataHandler.java b/velocity/src/main/java/org/geysermc/floodgate/addon/data/VelocityProxyDataHandler.java index 1b34eea7..afa3feae 100644 --- a/velocity/src/main/java/org/geysermc/floodgate/addon/data/VelocityProxyDataHandler.java +++ b/velocity/src/main/java/org/geysermc/floodgate/addon/data/VelocityProxyDataHandler.java @@ -141,10 +141,6 @@ public final class VelocityProxyDataHandler extends ChannelInboundHandlerAdapter ctx.channel().attr(kickMessageAttribute) .set(config.getDisconnect().getInvalidArgumentsLength()); return; - case TIMESTAMP_DENIED: - ctx.channel().attr(kickMessageAttribute) - .set(Constants.TIMESTAMP_DENIED_MESSAGE); - return; default: // only continue when SUCCESS return; }