1
0
mirror of https://github.com/GeyserMC/Floodgate.git synced 2025-12-19 14:59:20 +00:00

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.
This commit is contained in:
Camotoy
2021-09-27 14:45:53 -04:00
parent f4734722cc
commit 08178f51b7
5 changed files with 4 additions and 60 deletions

View File

@@ -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;
}

View File

@@ -104,7 +104,10 @@ public class FloodgatePlatform {
guice = guice.createChildInjector(new ConfigLoadedModule(config));
PlayerLink link = guice.getInstance(PlayerLinkLoader.class).load();
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);

View File

@@ -66,12 +66,6 @@ import org.geysermc.floodgate.util.Utils;
@RequiredArgsConstructor
public final class FloodgateHandshakeHandler {
private final Cache<String, Long> 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
}

View File

@@ -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;
}

View File

@@ -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;
}