Make evil more harder

Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com>
This commit is contained in:
Joshua Castle 2024-04-07 23:15:55 -07:00
parent fa2e4e5a94
commit 070a19a02d
No known key found for this signature in database
GPG Key ID: 7ECA1A2FC38ABA9F
5 changed files with 108 additions and 19 deletions

View File

@ -27,17 +27,15 @@ package org.geysermc.geyser.network;
import com.github.steveice10.mc.protocol.codec.MinecraftCodec;
import com.github.steveice10.mc.protocol.codec.PacketCodec;
import io.netty.buffer.ByteBuf;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.cloudburstmc.protocol.bedrock.codec.BedrockCodec;
import org.cloudburstmc.protocol.bedrock.codec.BedrockCodecHelper;
import org.cloudburstmc.protocol.bedrock.codec.v582.serializer.TrimDataSerializer_v582;
import org.cloudburstmc.protocol.bedrock.codec.v622.Bedrock_v622;
import org.cloudburstmc.protocol.bedrock.codec.v630.Bedrock_v630;
import org.cloudburstmc.protocol.bedrock.codec.v649.Bedrock_v649;
import org.cloudburstmc.protocol.bedrock.codec.v662.Bedrock_v662;
import org.cloudburstmc.protocol.bedrock.netty.codec.packet.BedrockPacketCodec;
import org.cloudburstmc.protocol.bedrock.packet.TrimDataPacket;
import org.cloudburstmc.protocol.bedrock.packet.LabTablePacket;
import org.cloudburstmc.protocol.bedrock.packet.PhotoTransferPacket;
import org.geysermc.geyser.session.GeyserSession;
import java.util.ArrayList;
@ -170,11 +168,9 @@ public final class GameProtocol {
private static BedrockCodec processCodec(BedrockCodec codec) {
return codec.toBuilder()
.updateSerializer(TrimDataPacket.class, new TrimDataSerializer_v582() {
@Override
public void deserialize(ByteBuf buffer, BedrockCodecHelper helper, TrimDataPacket packet) {
}
})
// De-register unused serverbound EDU packets
.deregisterPacket(PhotoTransferPacket.class)
.deregisterPacket(LabTablePacket.class)
.build();
}

View File

@ -25,12 +25,16 @@
package org.geysermc.geyser.network;
import io.netty.buffer.ByteBuf;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.DefaultEventLoopGroup;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.util.concurrent.DefaultThreadFactory;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.cloudburstmc.protocol.bedrock.BedrockPeer;
import org.cloudburstmc.protocol.bedrock.BedrockServerSession;
import org.cloudburstmc.protocol.bedrock.netty.codec.packet.BedrockPacketCodec;
import org.cloudburstmc.protocol.bedrock.netty.initializer.BedrockServerInitializer;
import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.api.event.bedrock.SessionInitializeEvent;
@ -63,6 +67,10 @@ public class GeyserServerInitializer extends BedrockServerInitializer {
bedrockServerSession.setLogging(true);
GeyserSession session = new GeyserSession(this.geyser, bedrockServerSession, this.eventLoopGroup.next());
Channel channel = bedrockServerSession.getPeer().getChannel();
channel.pipeline().addAfter(BedrockPacketCodec.NAME, InvalidPacketHandler.NAME, new InvalidPacketHandler(session));
bedrockServerSession.setPacketHandler(new UpstreamPacketHandler(this.geyser, session));
this.geyser.eventBus().fire(new SessionInitializeEvent(session));
} catch (Throwable e) {
@ -72,6 +80,38 @@ public class GeyserServerInitializer extends BedrockServerInitializer {
}
}
@Override
protected void postInitChannel(Channel channel) throws Exception {
super.postInitChannel(channel);
channel.pipeline().addLast(new SimpleChannelInboundHandler<ByteBuf>() {
private static final int allowedExceptions = 5;
private static final long delayUntilExceptionsReset = 60;
private long lastException;
private int exceptionCounts;
@Override
protected void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) throws Exception {
ctx.fireChannelRead(msg);
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
final long currentTime = System.currentTimeMillis();
if (currentTime >= lastException + (delayUntilExceptionsReset * 1000)) {
exceptionCounts = 0;
}
lastException = currentTime;
if (exceptionCounts++ > allowedExceptions) {
ctx.pipeline().get(GeyserBedrockPeer.class).close("Too many exceptions created.");
return;
}
super.exceptionCaught(ctx, cause);
}
});
}
@Override
protected BedrockPeer createPeer(Channel channel) {
return new GeyserBedrockPeer(channel, this::createSession);

View File

@ -0,0 +1,57 @@
/*
* Copyright (c) 2019-2024 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @author GeyserMC
* @link https://github.com/GeyserMC/Geyser
*/
package org.geysermc.geyser.network;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.codec.DecoderException;
import lombok.RequiredArgsConstructor;
import org.geysermc.geyser.session.GeyserSession;
@RequiredArgsConstructor
public class InvalidPacketHandler extends ChannelInboundHandlerAdapter {
public static final String NAME = "rak-error-handler";
private final GeyserSession session;
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
if (!(cause instanceof DecoderException)) {
super.exceptionCaught(ctx, cause);
return;
}
Throwable actualCause = cause.getCause();
if (!(actualCause instanceof IllegalArgumentException)) {
super.exceptionCaught(ctx, actualCause);
return;
}
// Kick users that try to send Clientbound packets
session.disconnect("Invalid packet received!");
}
}

View File

@ -74,7 +74,6 @@ import java.util.function.IntFunction;
import java.util.function.Supplier;
import static org.cloudburstmc.netty.channel.raknet.RakConstants.DEFAULT_GLOBAL_PACKET_LIMIT;
import static org.cloudburstmc.netty.channel.raknet.RakConstants.DEFAULT_OFFLINE_PACKET_LIMIT;
import static org.cloudburstmc.netty.channel.raknet.RakConstants.DEFAULT_PACKET_LIMIT;
public final class GeyserServer {
@ -217,11 +216,6 @@ public final class GeyserServer {
int rakPacketLimit = positivePropOrDefault("Geyser.RakPacketLimit", DEFAULT_PACKET_LIMIT);
this.geyser.getLogger().debug("Setting RakNet packet limit to " + rakPacketLimit);
boolean isWhitelistedProxyProtocol = this.geyser.getConfig().getBedrock().isEnableProxyProtocol()
&& !this.geyser.getConfig().getBedrock().getProxyProtocolWhitelistedIPs().isEmpty();
int rakOfflinePacketLimit = positivePropOrDefault("Geyser.RakOfflinePacketLimit", isWhitelistedProxyProtocol ? Integer.MAX_VALUE : DEFAULT_OFFLINE_PACKET_LIMIT);
this.geyser.getLogger().debug("Setting RakNet offline packet limit to " + rakOfflinePacketLimit);
int rakGlobalPacketLimit = positivePropOrDefault("Geyser.RakGlobalPacketLimit", DEFAULT_GLOBAL_PACKET_LIMIT);
this.geyser.getLogger().debug("Setting RakNet global packet limit to " + rakGlobalPacketLimit);
@ -231,7 +225,6 @@ public final class GeyserServer {
.option(RakChannelOption.RAK_HANDLE_PING, true)
.option(RakChannelOption.RAK_MAX_MTU, this.geyser.getConfig().getMtu())
.option(RakChannelOption.RAK_PACKET_LIMIT, rakPacketLimit)
.option(RakChannelOption.RAK_OFFLINE_PACKET_LIMIT, rakOfflinePacketLimit)
.option(RakChannelOption.RAK_GLOBAL_PACKET_LIMIT, rakGlobalPacketLimit)
.childHandler(serverInitializer);
}

View File

@ -113,9 +113,12 @@ viaproxy = { group = "net.raphimc", name = "ViaProxy", version.ref = "viaproxy"
viaversion = { group = "com.viaversion", name = "viaversion", version.ref = "viaversion" }
websocket = { group = "org.java-websocket", name = "Java-WebSocket", version.ref = "websocket" }
protocol-common = { group = "org.cloudburstmc.protocol", name = "common", version.ref = "protocol-connection" }
protocol-codec = { group = "org.cloudburstmc.protocol", name = "bedrock-codec", version.ref = "protocol" }
protocol-connection = { group = "org.cloudburstmc.protocol", name = "bedrock-connection", version.ref = "protocol-connection" }
#protocol-common = { group = "org.cloudburstmc.protocol", name = "common", version.ref = "protocol-connection" }
#protocol-codec = { group = "org.cloudburstmc.protocol", name = "bedrock-codec", version.ref = "protocol" }
#protocol-connection = { group = "org.cloudburstmc.protocol", name = "bedrock-connection", version.ref = "protocol-connection" }
protocol-common = { group = "com.github.CloudburstMC.Protocol", name = "common", version = "packet-flow-SNAPSHOT" }
protocol-codec = { group = "com.github.CloudburstMC.Protocol", name = "bedrock-codec", version = "packet-flow-SNAPSHOT" }
protocol-connection = { group = "com.github.CloudburstMC.Protocol", name = "bedrock-connection", version = "packet-flow-SNAPSHOT" }
math = { group = "org.cloudburstmc.math", name = "immutable", version = "2.0" }