Moved OpenAuthMod related code into OpenAuthModPacketHandler

This commit is contained in:
RaphiMC 2024-05-04 19:15:31 +02:00
parent 97d15f9c5d
commit eb1f66763e
No known key found for this signature in database
GPG key ID: 0F6BB0657A03AC94
5 changed files with 64 additions and 73 deletions

View file

@ -216,7 +216,7 @@ public class Client2ProxyHandler extends SimpleChannelInboundHandler<IPacket> {
this.proxyConnection.setUserOptions(userOptions); this.proxyConnection.setUserOptions(userOptions);
this.proxyConnection.getPacketHandlers().add(new StatusPacketHandler(this.proxyConnection)); this.proxyConnection.getPacketHandlers().add(new StatusPacketHandler(this.proxyConnection));
this.proxyConnection.getPacketHandlers().add(new OpenAuthModPacketHandler(this.proxyConnection)); this.proxyConnection.getPacketHandlers().add(new OpenAuthModPacketHandler(this.proxyConnection));
if (ViaProxy.getConfig().shouldSupportSimpleVoiceChat() && serverVersion.newerThan(ProtocolVersion.v1_12_2) && clientVersion.newerThan(ProtocolVersion.v1_12_2)) { if (ViaProxy.getConfig().shouldSupportSimpleVoiceChat() && serverVersion.newerThan(ProtocolVersion.v1_14) && clientVersion.newerThan(ProtocolVersion.v1_14)) {
this.proxyConnection.getPacketHandlers().add(new SimpleVoiceChatPacketHandler(this.proxyConnection)); this.proxyConnection.getPacketHandlers().add(new SimpleVoiceChatPacketHandler(this.proxyConnection));
} }
if (clientVersion.newerThanOrEqualTo(ProtocolVersion.v1_8)) { if (clientVersion.newerThanOrEqualTo(ProtocolVersion.v1_8)) {

View file

@ -37,6 +37,7 @@ import net.raphimc.viabedrock.protocol.storage.AuthChainData;
import net.raphimc.viaproxy.ViaProxy; import net.raphimc.viaproxy.ViaProxy;
import net.raphimc.viaproxy.plugins.events.FillPlayerDataEvent; import net.raphimc.viaproxy.plugins.events.FillPlayerDataEvent;
import net.raphimc.viaproxy.protocoltranslator.viaproxy.ViaProxyConfig; import net.raphimc.viaproxy.protocoltranslator.viaproxy.ViaProxyConfig;
import net.raphimc.viaproxy.proxy.packethandler.OpenAuthModPacketHandler;
import net.raphimc.viaproxy.proxy.session.ProxyConnection; import net.raphimc.viaproxy.proxy.session.ProxyConnection;
import net.raphimc.viaproxy.saves.impl.accounts.Account; import net.raphimc.viaproxy.saves.impl.accounts.Account;
import net.raphimc.viaproxy.saves.impl.accounts.BedrockAccount; import net.raphimc.viaproxy.saves.impl.accounts.BedrockAccount;
@ -109,7 +110,7 @@ public class ExternalInterface {
Logger.u_info("auth", proxyConnection.getC2P().remoteAddress(), proxyConnection.getGameProfile(), "Trying to join online mode server"); Logger.u_info("auth", proxyConnection.getC2P().remoteAddress(), proxyConnection.getGameProfile(), "Trying to join online mode server");
if (ViaProxy.getConfig().getAuthMethod() == ViaProxyConfig.AuthMethod.OPENAUTHMOD) { if (ViaProxy.getConfig().getAuthMethod() == ViaProxyConfig.AuthMethod.OPENAUTHMOD) {
try { try {
final ByteBuf response = proxyConnection.sendCustomPayload(OpenAuthModConstants.JOIN_CHANNEL, PacketTypes.writeString(Unpooled.buffer(), serverIdHash)).get(6, TimeUnit.SECONDS); final ByteBuf response = proxyConnection.getPacketHandler(OpenAuthModPacketHandler.class).sendCustomPayload(OpenAuthModConstants.JOIN_CHANNEL, PacketTypes.writeString(Unpooled.buffer(), serverIdHash)).get(6, TimeUnit.SECONDS);
if (response == null) throw new TimeoutException(); if (response == null) throw new TimeoutException();
if (response.isReadable() && !response.readBoolean()) throw new TimeoutException(); if (response.isReadable() && !response.readBoolean()) throw new TimeoutException();
} catch (TimeoutException e) { } catch (TimeoutException e) {
@ -132,7 +133,7 @@ public class ExternalInterface {
if (ViaProxy.getConfig().getAuthMethod() == ViaProxyConfig.AuthMethod.OPENAUTHMOD) { if (ViaProxy.getConfig().getAuthMethod() == ViaProxyConfig.AuthMethod.OPENAUTHMOD) {
try { try {
final ByteBuf response = proxyConnection.sendCustomPayload(OpenAuthModConstants.SIGN_NONCE_CHANNEL, PacketTypes.writeByteArray(Unpooled.buffer(), nonce)).get(5, TimeUnit.SECONDS); final ByteBuf response = proxyConnection.getPacketHandler(OpenAuthModPacketHandler.class).sendCustomPayload(OpenAuthModConstants.SIGN_NONCE_CHANNEL, PacketTypes.writeByteArray(Unpooled.buffer(), nonce)).get(5, TimeUnit.SECONDS);
if (response == null) throw new TimeoutException(); if (response == null) throw new TimeoutException();
if (!response.readBoolean()) throw new TimeoutException(); if (!response.readBoolean()) throw new TimeoutException();
packet.salt = response.readLong(); packet.salt = response.readLong();

View file

@ -19,8 +19,10 @@ package net.raphimc.viaproxy.proxy.packethandler;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion; import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil;
import io.netty.buffer.Unpooled; import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelFutureListener;
import net.lenni0451.mcstructs.text.components.StringComponent;
import net.raphimc.netminecraft.constants.ConnectionState; import net.raphimc.netminecraft.constants.ConnectionState;
import net.raphimc.netminecraft.constants.MCPackets; import net.raphimc.netminecraft.constants.MCPackets;
import net.raphimc.netminecraft.packet.IPacket; import net.raphimc.netminecraft.packet.IPacket;
@ -28,40 +30,51 @@ import net.raphimc.netminecraft.packet.PacketTypes;
import net.raphimc.netminecraft.packet.UnknownPacket; import net.raphimc.netminecraft.packet.UnknownPacket;
import net.raphimc.netminecraft.packet.impl.login.C2SLoginCustomPayloadPacket; import net.raphimc.netminecraft.packet.impl.login.C2SLoginCustomPayloadPacket;
import net.raphimc.netminecraft.packet.impl.login.C2SLoginKeyPacket1_7; import net.raphimc.netminecraft.packet.impl.login.C2SLoginKeyPacket1_7;
import net.raphimc.netminecraft.packet.impl.login.S2CLoginCustomPayloadPacket;
import net.raphimc.netminecraft.packet.impl.login.S2CLoginDisconnectPacket1_20_3;
import net.raphimc.viaproxy.proxy.external_interface.OpenAuthModConstants; import net.raphimc.viaproxy.proxy.external_interface.OpenAuthModConstants;
import net.raphimc.viaproxy.proxy.session.ProxyConnection; import net.raphimc.viaproxy.proxy.session.ProxyConnection;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
public class OpenAuthModPacketHandler extends PacketHandler { public class OpenAuthModPacketHandler extends PacketHandler {
private final int customPayloadId; private final int c2sCustomPayloadId;
private final int s2cCustomPayloadId;
private final AtomicInteger id = new AtomicInteger(0);
private final Map<Integer, CompletableFuture<ByteBuf>> customPayloadListener = new ConcurrentHashMap<>();
public OpenAuthModPacketHandler(ProxyConnection proxyConnection) { public OpenAuthModPacketHandler(ProxyConnection proxyConnection) {
super(proxyConnection); super(proxyConnection);
this.customPayloadId = MCPackets.C2S_PLUGIN_MESSAGE.getId(proxyConnection.getClientVersion().getVersion()); this.c2sCustomPayloadId = MCPackets.C2S_PLUGIN_MESSAGE.getId(proxyConnection.getClientVersion().getVersion());
this.s2cCustomPayloadId = MCPackets.S2C_PLUGIN_MESSAGE.getId(proxyConnection.getClientVersion().getVersion());
} }
@Override @Override
public boolean handleC2P(IPacket packet, List<ChannelFutureListener> listeners) { public boolean handleC2P(IPacket packet, List<ChannelFutureListener> listeners) {
if (packet instanceof UnknownPacket unknownPacket && this.proxyConnection.getC2pConnectionState() == ConnectionState.PLAY) { if (packet instanceof UnknownPacket unknownPacket && this.proxyConnection.getC2pConnectionState() == ConnectionState.PLAY) {
if (unknownPacket.packetId == this.customPayloadId) { if (unknownPacket.packetId == this.c2sCustomPayloadId) {
final ByteBuf data = Unpooled.wrappedBuffer(unknownPacket.data); final ByteBuf data = Unpooled.wrappedBuffer(unknownPacket.data);
final String channel = PacketTypes.readString(data, Short.MAX_VALUE); // channel final String channel = PacketTypes.readString(data, Short.MAX_VALUE); // channel
if (channel.equals(OpenAuthModConstants.DATA_CHANNEL) && this.proxyConnection.handleCustomPayload(PacketTypes.readVarInt(data), data)) { if (channel.equals(OpenAuthModConstants.DATA_CHANNEL) && this.handleCustomPayload(PacketTypes.readVarInt(data), data)) {
return false; return false;
} }
} }
} else if (packet instanceof C2SLoginCustomPayloadPacket loginCustomPayload) { } else if (packet instanceof C2SLoginCustomPayloadPacket loginCustomPayload) {
if (loginCustomPayload.response != null && this.proxyConnection.handleCustomPayload(loginCustomPayload.queryId, Unpooled.wrappedBuffer(loginCustomPayload.response))) { if (loginCustomPayload.response != null && this.handleCustomPayload(loginCustomPayload.queryId, Unpooled.wrappedBuffer(loginCustomPayload.response))) {
return false; return false;
} }
} else if (packet instanceof C2SLoginKeyPacket1_7 loginKeyPacket) { } else if (packet instanceof C2SLoginKeyPacket1_7 loginKeyPacket) {
if (this.proxyConnection.getClientVersion().olderThanOrEqualTo(ProtocolVersion.v1_12_2) && new String(loginKeyPacket.encryptedNonce, StandardCharsets.UTF_8).equals(OpenAuthModConstants.DATA_CHANNEL)) { // 1.8-1.12.2 OpenAuthMod response handling if (this.proxyConnection.getClientVersion().olderThanOrEqualTo(ProtocolVersion.v1_12_2) && new String(loginKeyPacket.encryptedNonce, StandardCharsets.UTF_8).equals(OpenAuthModConstants.DATA_CHANNEL)) { // 1.8-1.12.2 OpenAuthMod response handling
final ByteBuf byteBuf = Unpooled.wrappedBuffer(loginKeyPacket.encryptedSecretKey); final ByteBuf byteBuf = Unpooled.wrappedBuffer(loginKeyPacket.encryptedSecretKey);
this.proxyConnection.handleCustomPayload(PacketTypes.readVarInt(byteBuf), byteBuf); this.handleCustomPayload(PacketTypes.readVarInt(byteBuf), byteBuf);
return false; return false;
} }
} }
@ -69,4 +82,45 @@ public class OpenAuthModPacketHandler extends PacketHandler {
return true; return true;
} }
public CompletableFuture<ByteBuf> sendCustomPayload(final String channel, final ByteBuf data) {
if (channel.length() > 20) throw new IllegalStateException("Channel name can't be longer than 20 characters");
final CompletableFuture<ByteBuf> future = new CompletableFuture<>();
final int id = this.id.getAndIncrement();
switch (this.proxyConnection.getC2pConnectionState()) {
case LOGIN:
if (this.proxyConnection.getClientVersion().newerThanOrEqualTo(ProtocolVersion.v1_13)) {
this.proxyConnection.getC2P().writeAndFlush(new S2CLoginCustomPayloadPacket(id, channel, PacketTypes.readReadableBytes(data))).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE);
} else {
final ByteBuf disconnectPacketData = Unpooled.buffer();
PacketTypes.writeString(disconnectPacketData, channel);
PacketTypes.writeVarInt(disconnectPacketData, id);
disconnectPacketData.writeBytes(data);
this.proxyConnection.getC2P().writeAndFlush(new S2CLoginDisconnectPacket1_20_3(new StringComponent("§cYou need to install OpenAuthMod in order to join this server.§k\n" + Base64.getEncoder().encodeToString(ByteBufUtil.getBytes(disconnectPacketData)) + "\n" + OpenAuthModConstants.LEGACY_MAGIC_STRING))).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE);
}
break;
case PLAY:
final ByteBuf customPayloadPacket = Unpooled.buffer();
PacketTypes.writeVarInt(customPayloadPacket, this.s2cCustomPayloadId);
PacketTypes.writeString(customPayloadPacket, channel); // channel
PacketTypes.writeVarInt(customPayloadPacket, id);
customPayloadPacket.writeBytes(data);
this.proxyConnection.getC2P().writeAndFlush(customPayloadPacket).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE);
break;
default:
throw new IllegalStateException("Can't send a custom payload packet during " + this.proxyConnection.getC2pConnectionState());
}
this.customPayloadListener.put(id, future);
return future;
}
private boolean handleCustomPayload(final int id, final ByteBuf data) {
if (this.customPayloadListener.containsKey(id)) {
this.customPayloadListener.remove(id).complete(data);
return true;
}
return false;
}
} }

View file

@ -21,7 +21,6 @@ import com.mojang.authlib.GameProfile;
import com.viaversion.viaversion.api.connection.UserConnection; import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion; import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import io.netty.bootstrap.Bootstrap; import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.channel.Channel; import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelFuture;
import net.raphimc.netminecraft.constants.ConnectionState; import net.raphimc.netminecraft.constants.ConnectionState;
@ -30,7 +29,6 @@ import net.raphimc.netminecraft.util.ChannelType;
import java.net.SocketAddress; import java.net.SocketAddress;
import java.security.Key; import java.security.Key;
import java.util.concurrent.CompletableFuture;
public class DummyProxyConnection extends ProxyConnection { public class DummyProxyConnection extends ProxyConnection {
@ -118,16 +116,6 @@ public class DummyProxyConnection extends ProxyConnection {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
@Override
public CompletableFuture<ByteBuf> sendCustomPayload(String channel, ByteBuf data) {
throw new UnsupportedOperationException();
}
@Override
public boolean handleCustomPayload(int id, ByteBuf data) {
throw new UnsupportedOperationException();
}
@Override @Override
public boolean isClosed() { public boolean isClosed() {
return false; return false;

View file

@ -24,7 +24,6 @@ import com.viaversion.viaversion.libs.gson.JsonObject;
import com.viaversion.viaversion.libs.gson.JsonPrimitive; import com.viaversion.viaversion.libs.gson.JsonPrimitive;
import io.netty.bootstrap.Bootstrap; import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil;
import io.netty.buffer.Unpooled; import io.netty.buffer.Unpooled;
import io.netty.channel.*; import io.netty.channel.*;
import io.netty.util.AttributeKey; import io.netty.util.AttributeKey;
@ -39,13 +38,11 @@ import net.raphimc.netminecraft.netty.connection.NetClient;
import net.raphimc.netminecraft.netty.crypto.AESEncryption; import net.raphimc.netminecraft.netty.crypto.AESEncryption;
import net.raphimc.netminecraft.packet.PacketTypes; import net.raphimc.netminecraft.packet.PacketTypes;
import net.raphimc.netminecraft.packet.impl.login.C2SLoginHelloPacket1_7; import net.raphimc.netminecraft.packet.impl.login.C2SLoginHelloPacket1_7;
import net.raphimc.netminecraft.packet.impl.login.S2CLoginCustomPayloadPacket;
import net.raphimc.netminecraft.packet.impl.login.S2CLoginDisconnectPacket1_20_3; import net.raphimc.netminecraft.packet.impl.login.S2CLoginDisconnectPacket1_20_3;
import net.raphimc.netminecraft.packet.impl.status.S2CStatusResponsePacket; import net.raphimc.netminecraft.packet.impl.status.S2CStatusResponsePacket;
import net.raphimc.netminecraft.packet.registry.PacketRegistryUtil; import net.raphimc.netminecraft.packet.registry.PacketRegistryUtil;
import net.raphimc.netminecraft.util.ChannelType; import net.raphimc.netminecraft.util.ChannelType;
import net.raphimc.viaproxy.cli.ConsoleFormatter; import net.raphimc.viaproxy.cli.ConsoleFormatter;
import net.raphimc.viaproxy.proxy.external_interface.OpenAuthModConstants;
import net.raphimc.viaproxy.proxy.packethandler.PacketHandler; import net.raphimc.viaproxy.proxy.packethandler.PacketHandler;
import net.raphimc.viaproxy.proxy.util.CloseAndReturn; import net.raphimc.viaproxy.proxy.util.CloseAndReturn;
import net.raphimc.viaproxy.util.logging.Logger; import net.raphimc.viaproxy.util.logging.Logger;
@ -54,12 +51,7 @@ import java.net.SocketAddress;
import java.security.GeneralSecurityException; import java.security.GeneralSecurityException;
import java.security.Key; import java.security.Key;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Base64;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Function; import java.util.function.Function;
import java.util.function.Supplier; import java.util.function.Supplier;
@ -70,9 +62,6 @@ public class ProxyConnection extends NetClient {
private final Channel c2p; private final Channel c2p;
private final List<PacketHandler> packetHandlers = new ArrayList<>(); private final List<PacketHandler> packetHandlers = new ArrayList<>();
private final AtomicInteger customPayloadId = new AtomicInteger(0);
private final Map<Integer, CompletableFuture<ByteBuf>> customPayloadListener = new ConcurrentHashMap<>();
private SocketAddress serverAddress; private SocketAddress serverAddress;
private ProtocolVersion serverVersion; private ProtocolVersion serverVersion;
@ -248,47 +237,6 @@ public class ProxyConnection extends NetClient {
} }
} }
public CompletableFuture<ByteBuf> sendCustomPayload(final String channel, final ByteBuf data) {
if (channel.length() > 20) throw new IllegalStateException("Channel name can't be longer than 20 characters");
final CompletableFuture<ByteBuf> future = new CompletableFuture<>();
final int id = this.customPayloadId.getAndIncrement();
switch (this.c2pConnectionState) {
case LOGIN:
if (this.clientVersion.newerThanOrEqualTo(ProtocolVersion.v1_13)) {
this.c2p.writeAndFlush(new S2CLoginCustomPayloadPacket(id, channel, PacketTypes.readReadableBytes(data))).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE);
} else {
final ByteBuf disconnectPacketData = Unpooled.buffer();
PacketTypes.writeString(disconnectPacketData, channel);
PacketTypes.writeVarInt(disconnectPacketData, id);
disconnectPacketData.writeBytes(data);
this.c2p.writeAndFlush(new S2CLoginDisconnectPacket1_20_3(new StringComponent("§cYou need to install OpenAuthMod in order to join this server.§k\n" + Base64.getEncoder().encodeToString(ByteBufUtil.getBytes(disconnectPacketData)) + "\n" + OpenAuthModConstants.LEGACY_MAGIC_STRING))).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE);
}
break;
case PLAY:
final ByteBuf customPayloadPacket = Unpooled.buffer();
PacketTypes.writeVarInt(customPayloadPacket, MCPackets.S2C_PLUGIN_MESSAGE.getId(this.clientVersion.getVersion()));
PacketTypes.writeString(customPayloadPacket, channel); // channel
PacketTypes.writeVarInt(customPayloadPacket, id);
customPayloadPacket.writeBytes(data);
this.c2p.writeAndFlush(customPayloadPacket).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE);
break;
default:
throw new IllegalStateException("Can't send a custom payload packet during " + this.c2pConnectionState);
}
this.customPayloadListener.put(id, future);
return future;
}
public boolean handleCustomPayload(final int id, final ByteBuf data) {
if (this.customPayloadListener.containsKey(id)) {
this.customPayloadListener.remove(id).complete(data);
return true;
}
return false;
}
public void kickClient(final String message) throws CloseAndReturn { public void kickClient(final String message) throws CloseAndReturn {
Logger.u_err("proxy kick", this.c2p.remoteAddress(), this.getGameProfile(), ConsoleFormatter.convert(message)); Logger.u_err("proxy kick", this.c2p.remoteAddress(), this.getGameProfile(), ConsoleFormatter.convert(message));