mirror of https://github.com/Minestom/Minestom.git
Move uuid into MessageSignature from MessageSender
This commit is contained in:
parent
29c5d1d64b
commit
fa9ab30410
|
@ -3,17 +3,27 @@ package net.minestom.server.crypto;
|
|||
import net.minestom.server.utils.binary.BinaryReader;
|
||||
import net.minestom.server.utils.binary.BinaryWriter;
|
||||
import net.minestom.server.utils.binary.Writeable;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.UUID;
|
||||
|
||||
public record MessageSignature(Instant timestamp, long salt, byte[] signature) implements Writeable {
|
||||
public record MessageSignature(UUID signer, Instant timestamp, long salt, byte[] signature) implements Writeable {
|
||||
public static final UUID UNSIGNED_SENDER = new UUID(0,0);
|
||||
public static final MessageSignature UNSIGNED = new MessageSignature(Instant.ofEpochMilli(0), 0, new byte[0]);
|
||||
public static final MessageSignature UNSIGNED = new MessageSignature(UNSIGNED_SENDER, Instant.ofEpochMilli(0), 0, new byte[0]);
|
||||
|
||||
public MessageSignature(BinaryReader reader) {
|
||||
this(Instant.ofEpochMilli(reader.readLong()), reader.readLong(), reader.readByteArray());
|
||||
public MessageSignature(UUID sender, BinaryReader reader) {
|
||||
this(sender, Instant.ofEpochMilli(reader.readLong()), reader.readLong(), reader.readByteArray());
|
||||
}
|
||||
|
||||
@Contract("_ -> new")
|
||||
public MessageSignature withSigner(UUID uuid) {
|
||||
return new MessageSignature(uuid, timestamp, salt, signature);
|
||||
}
|
||||
|
||||
public boolean unsigned() {
|
||||
return signer == UNSIGNED_SENDER;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -12,7 +12,6 @@ import java.nio.ByteBuffer;
|
|||
import java.nio.ByteOrder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.*;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* General purpose functional interface to verify signatures.<br>
|
||||
|
@ -63,17 +62,16 @@ public interface SignatureValidator {
|
|||
* <i>net.minecraft.client.player.LocalPlayer#signCommandArguments</i><br>
|
||||
*
|
||||
* @param validator validator acquired from {@link SignatureValidator#from(Player)}
|
||||
* @param signer uuid of the player who signed this component
|
||||
* @param signature signature data
|
||||
* @param component the component that was signed
|
||||
* @return true if the signature is valid
|
||||
*/
|
||||
static boolean validate(SignatureValidator validator, UUID signer, MessageSignature signature, Component component) {
|
||||
static boolean validate(SignatureValidator validator, MessageSignature signature, Component component) {
|
||||
final byte[] componentBytes = GsonComponentSerializer.gson().serialize(component).getBytes(StandardCharsets.UTF_8);
|
||||
byte[] signerDetails = new byte[32+ componentBytes.length];
|
||||
ByteBuffer bytebuffer = ByteBuffer.wrap(signerDetails).order(ByteOrder.BIG_ENDIAN);
|
||||
bytebuffer.putLong(signature.salt());
|
||||
bytebuffer.putLong(signer.getMostSignificantBits()).putLong(signer.getLeastSignificantBits());
|
||||
bytebuffer.putLong(signature.signer().getMostSignificantBits()).putLong(signature.signer().getLeastSignificantBits());
|
||||
bytebuffer.putLong(signature.timestamp().getEpochSecond());
|
||||
bytebuffer.put(componentBytes);
|
||||
return validator.validate(bytebuffer.array(), signature.signature());
|
||||
|
|
|
@ -669,8 +669,9 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
|
|||
if (type == MessageType.SYSTEM)
|
||||
Messenger.sendSystemMessage(this, message, ChatPosition.SYSTEM_MESSAGE);
|
||||
else
|
||||
Messenger.sendMessage(Collections.singleton(this), PlayerChatMessagePacket.unsigned(message,
|
||||
ChatPosition.CHAT, MessageSender.forUnsigned(Component.text("SYSTEM"))));
|
||||
Messenger.sendMessage(List.of(this), PlayerChatMessagePacket.unsigned(message,
|
||||
// TODO get name from source if possible
|
||||
ChatPosition.CHAT, new MessageSender(Component.empty(), null)));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -44,7 +44,8 @@ public class ChatMessageListener {
|
|||
|
||||
final Collection<Player> players = CONNECTION_MANAGER.getOnlinePlayers();
|
||||
final Component expectedMessage = Objects.requireNonNullElse(player.getLastPreviewedMessage(), Component.text(message));
|
||||
PlayerChatEvent event = new PlayerChatEvent(player, players, message, packet.signature(), MessageSender.forSigned(player), expectedMessage);
|
||||
PlayerChatEvent event = new PlayerChatEvent(player, players, message, packet.signature().withSigner(player.getUuid()),
|
||||
MessageSender.from(player), expectedMessage);
|
||||
|
||||
// Call the event
|
||||
EventDispatcher.callCancellable(event, () -> {
|
||||
|
@ -57,8 +58,8 @@ public class ChatMessageListener {
|
|||
|
||||
if (formatFunction != null) {
|
||||
// Let the event modify the message
|
||||
if (event.getSender().unsigned()) {
|
||||
// Event handler set unsigned sender, send message as unsigned -> players with
|
||||
if (event.getSignature().unsigned()) {
|
||||
// Event handler set message unsigned -> players with
|
||||
// "Only Show Secure Chat" option enabled won't see this message
|
||||
Messenger.sendMessage(event.getRecipients(), PlayerChatMessagePacket
|
||||
.unsigned(formatFunction.apply(event), ChatPosition.CHAT, event.getSender()));
|
||||
|
@ -71,7 +72,7 @@ public class ChatMessageListener {
|
|||
}
|
||||
} else {
|
||||
// There is no way the message got modified, send it with the original signature
|
||||
// TODO Should we handle poor design where the signature or sender uuid got altered?
|
||||
// TODO Should we handle poor design where the signature got altered?
|
||||
Messenger.sendMessage(event.getRecipients(), PlayerChatMessagePacket.signed(event.getMessage(),
|
||||
ChatPosition.CHAT, event.getSender(), event.getSignature()));
|
||||
}
|
||||
|
|
|
@ -1,43 +1,17 @@
|
|||
package net.minestom.server.message;
|
||||
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.minestom.server.crypto.MessageSignature;
|
||||
import net.minestom.server.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
|
||||
public record MessageSender(UUID uuid, @NotNull Component displayName, @Nullable Component teamName) {
|
||||
public record MessageSender(@NotNull Component displayName, @Nullable Component teamName) {
|
||||
|
||||
public static MessageSender forUnsigned(@NotNull Component displayName, @Nullable Component teamName) {
|
||||
return new MessageSender(MessageSignature.UNSIGNED_SENDER, displayName, teamName);
|
||||
}
|
||||
|
||||
public static MessageSender forUnsigned(@NotNull Component displayName) {
|
||||
return new MessageSender(MessageSignature.UNSIGNED_SENDER, displayName, null);
|
||||
}
|
||||
|
||||
public static MessageSender forSigned(@NotNull UUID uuid, @NotNull Component displayName) {
|
||||
return new MessageSender(uuid, displayName, null);
|
||||
}
|
||||
|
||||
public static MessageSender forSigned(Player player) {
|
||||
return player.getTeam() == null ? forSigned(player.getUuid(), Objects.requireNonNullElse(player.getDisplayName(),
|
||||
Component.text(player.getUsername()))) : new MessageSender(player.getUuid(),
|
||||
Objects.requireNonNullElse(player.getDisplayName(), Component.text(player.getUsername())),
|
||||
public static MessageSender from(Player player) {
|
||||
return new MessageSender(Objects.requireNonNullElse(player.getDisplayName(),
|
||||
Component.text(player.getUsername())), player.getTeam() == null ? null :
|
||||
player.getTeam().getTeamDisplayName());
|
||||
}
|
||||
|
||||
public static MessageSender forUnsigned(Player player) {
|
||||
return player.getTeam() == null ? forUnsigned(Objects.requireNonNullElse(player.getDisplayName(),
|
||||
Component.text(player.getUsername()))) : forUnsigned(
|
||||
Objects.requireNonNullElse(player.getDisplayName(), Component.text(player.getUsername())),
|
||||
player.getTeam().getTeamDisplayName());
|
||||
}
|
||||
|
||||
public boolean unsigned() {
|
||||
return MessageSignature.UNSIGNED_SENDER == uuid;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ public record ClientChatMessagePacket(@NotNull String message, MessageSignature
|
|||
}
|
||||
|
||||
public ClientChatMessagePacket(BinaryReader reader) {
|
||||
this(reader.readSizedString(256), new MessageSignature(reader), reader.readBoolean());
|
||||
this(reader.readSizedString(256), new MessageSignature(null, reader), reader.readBoolean());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -20,23 +20,26 @@ import java.util.function.UnaryOperator;
|
|||
/**
|
||||
* Represents an outgoing chat message packet.
|
||||
*/
|
||||
public record PlayerChatMessagePacket(@NotNull Component signedContent, @Nullable Component unsignedContent,
|
||||
int type, @NotNull UUID uuid,
|
||||
public record PlayerChatMessagePacket(@NotNull Component signedContent, @Nullable Component unsignedContent, int type,
|
||||
@NotNull Component displayName, @Nullable Component teamDisplayName,
|
||||
@NotNull MessageSignature signature) implements ComponentHoldingServerPacket {
|
||||
public PlayerChatMessagePacket(BinaryReader reader) {
|
||||
this(reader.readComponent(), reader.readNullableComponent(), reader.readVarInt(), reader.readUuid(),
|
||||
reader.readComponent(), reader.readNullableComponent(), new MessageSignature(reader));
|
||||
public static PlayerChatMessagePacket read(BinaryReader reader) {
|
||||
final Component signed = reader.readComponent();
|
||||
final Component unsigned = reader.readNullableComponent();
|
||||
final int type = reader.readVarInt();
|
||||
final UUID sender = reader.readUuid();
|
||||
return new PlayerChatMessagePacket(signed, unsigned, type, reader.readComponent(),
|
||||
reader.readNullableComponent(), new MessageSignature(sender, reader));
|
||||
}
|
||||
|
||||
public static PlayerChatMessagePacket unsigned(@NotNull Component message, ChatPosition type, @NotNull MessageSender sender) {
|
||||
return new PlayerChatMessagePacket(message, null, type.getID(), MessageSignature.UNSIGNED_SENDER,
|
||||
return new PlayerChatMessagePacket(message, null, type.getID(),
|
||||
sender.displayName(), sender.teamName(), MessageSignature.UNSIGNED);
|
||||
}
|
||||
|
||||
public static PlayerChatMessagePacket signed(@NotNull Component message, ChatPosition type, @NotNull MessageSender sender,
|
||||
@NotNull MessageSignature signature) {
|
||||
return new PlayerChatMessagePacket(message, null, type.getID(), sender.uuid(),
|
||||
return new PlayerChatMessagePacket(message, null, type.getID(),
|
||||
sender.displayName(), sender.teamName(), signature);
|
||||
}
|
||||
|
||||
|
@ -44,7 +47,7 @@ public record PlayerChatMessagePacket(@NotNull Component signedContent, @Nullabl
|
|||
@NotNull Component unsignedContent,
|
||||
ChatPosition type, @NotNull MessageSender sender,
|
||||
@NotNull MessageSignature signature) {
|
||||
return new PlayerChatMessagePacket(message, unsignedContent, type.getID(), sender.uuid(),
|
||||
return new PlayerChatMessagePacket(message, unsignedContent, type.getID(),
|
||||
sender.displayName(), sender.teamName(), signature);
|
||||
}
|
||||
|
||||
|
@ -53,7 +56,7 @@ public record PlayerChatMessagePacket(@NotNull Component signedContent, @Nullabl
|
|||
writer.writeComponent(signedContent);
|
||||
writer.writeNullableComponent(unsignedContent);
|
||||
writer.writeVarInt(type);
|
||||
writer.writeUuid(uuid);
|
||||
writer.writeUuid(signature.signer());
|
||||
writer.writeComponent(displayName);
|
||||
writer.writeNullableComponent(teamDisplayName);
|
||||
writer.write(signature);
|
||||
|
@ -71,7 +74,6 @@ public record PlayerChatMessagePacket(@NotNull Component signedContent, @Nullabl
|
|||
|
||||
@Override
|
||||
public @NotNull ServerPacket copyWithOperator(@NotNull UnaryOperator<Component> operator) {
|
||||
return new PlayerChatMessagePacket(signedContent, unsignedContent, type,
|
||||
uuid, displayName, teamDisplayName, signature);
|
||||
return new PlayerChatMessagePacket(signedContent, unsignedContent, type, displayName, teamDisplayName, signature);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue