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:
@@ -141,10 +141,6 @@ public class BungeeProxyDataHandler extends ChannelInboundHandlerAdapter {
|
|||||||
ctx.channel().attr(kickMessageAttribute)
|
ctx.channel().attr(kickMessageAttribute)
|
||||||
.set(config.getDisconnect().getInvalidArgumentsLength());
|
.set(config.getDisconnect().getInvalidArgumentsLength());
|
||||||
break;
|
break;
|
||||||
case TIMESTAMP_DENIED:
|
|
||||||
ctx.channel().attr(kickMessageAttribute)
|
|
||||||
.set(Constants.TIMESTAMP_DENIED_MESSAGE);
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -104,7 +104,10 @@ public class FloodgatePlatform {
|
|||||||
guice = guice.createChildInjector(new ConfigLoadedModule(config));
|
guice = guice.createChildInjector(new ConfigLoadedModule(config));
|
||||||
PlayerLink link = guice.getInstance(PlayerLinkLoader.class).load();
|
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();
|
TimeSyncerHolder.init();
|
||||||
|
}
|
||||||
|
|
||||||
InstanceHolder.set(api, link, this.injector, packetHandlers, handshakeHandlers, KEY);
|
InstanceHolder.set(api, link, this.injector, packetHandlers, handshakeHandlers, KEY);
|
||||||
|
|
||||||
|
|||||||
@@ -66,12 +66,6 @@ import org.geysermc.floodgate.util.Utils;
|
|||||||
|
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public final class FloodgateHandshakeHandler {
|
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 HandshakeHandlersImpl handshakeHandlers;
|
||||||
private final SimpleFloodgateApi api;
|
private final SimpleFloodgateApi api;
|
||||||
private final FloodgateCipher cipher;
|
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)
|
// we'll use the LinkedPlayer provided by Bungee or Velocity (if they included one)
|
||||||
if (bedrockData.hasPlayerLink()) {
|
if (bedrockData.hasPlayerLink()) {
|
||||||
throw handlePart2(channel, hostname, bedrockData, bedrockData.getLinkedPlayer());
|
throw handlePart2(channel, hostname, bedrockData, bedrockData.getLinkedPlayer());
|
||||||
@@ -310,7 +264,6 @@ public final class FloodgateHandshakeHandler {
|
|||||||
NOT_FLOODGATE_DATA,
|
NOT_FLOODGATE_DATA,
|
||||||
DECRYPT_ERROR,
|
DECRYPT_ERROR,
|
||||||
INVALID_DATA_LENGTH,
|
INVALID_DATA_LENGTH,
|
||||||
TIMESTAMP_DENIED,
|
|
||||||
SUCCESS
|
SUCCESS
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -109,10 +109,6 @@ public final class SpigotDataHandler extends ChannelInboundHandlerAdapter {
|
|||||||
);
|
);
|
||||||
ctx.close();
|
ctx.close();
|
||||||
return true;
|
return true;
|
||||||
case TIMESTAMP_DENIED:
|
|
||||||
logger.info(Constants.TIMESTAMP_DENIED_MESSAGE);
|
|
||||||
ctx.close();
|
|
||||||
return true;
|
|
||||||
default: // only continue when SUCCESS
|
default: // only continue when SUCCESS
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -141,10 +141,6 @@ public final class VelocityProxyDataHandler extends ChannelInboundHandlerAdapter
|
|||||||
ctx.channel().attr(kickMessageAttribute)
|
ctx.channel().attr(kickMessageAttribute)
|
||||||
.set(config.getDisconnect().getInvalidArgumentsLength());
|
.set(config.getDisconnect().getInvalidArgumentsLength());
|
||||||
return;
|
return;
|
||||||
case TIMESTAMP_DENIED:
|
|
||||||
ctx.channel().attr(kickMessageAttribute)
|
|
||||||
.set(Constants.TIMESTAMP_DENIED_MESSAGE);
|
|
||||||
return;
|
|
||||||
default: // only continue when SUCCESS
|
default: // only continue when SUCCESS
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user