77 lines
2.5 KiB
Java
77 lines
2.5 KiB
Java
package net.minecraft.network.chat;
|
|
|
|
import com.mojang.logging.LogUtils;
|
|
import java.util.function.BooleanSupplier;
|
|
import net.minecraft.util.SignatureValidator;
|
|
import org.jetbrains.annotations.Nullable;
|
|
import org.slf4j.Logger;
|
|
|
|
@FunctionalInterface
|
|
public interface SignedMessageValidator {
|
|
Logger LOGGER = LogUtils.getLogger();
|
|
SignedMessageValidator ACCEPT_UNSIGNED = PlayerChatMessage::removeSignature;
|
|
SignedMessageValidator REJECT_ALL = playerChatMessage -> {
|
|
LOGGER.error("Received chat message from {}, but they have no chat session initialized and secure chat is enforced", playerChatMessage.sender());
|
|
return null;
|
|
};
|
|
|
|
@Nullable
|
|
PlayerChatMessage updateAndValidate(PlayerChatMessage message);
|
|
|
|
public static class KeyBased implements SignedMessageValidator {
|
|
private final SignatureValidator validator;
|
|
private final BooleanSupplier expired;
|
|
@Nullable
|
|
private PlayerChatMessage lastMessage;
|
|
private boolean isChainValid = true;
|
|
|
|
public KeyBased(SignatureValidator validator, BooleanSupplier expired) {
|
|
this.validator = validator;
|
|
this.expired = expired;
|
|
}
|
|
|
|
private boolean validateChain(PlayerChatMessage message) {
|
|
if (message.equals(this.lastMessage)) {
|
|
return true;
|
|
} else if (this.lastMessage != null && !message.link().isDescendantOf(this.lastMessage.link())) {
|
|
LOGGER.error(
|
|
"Received out-of-order chat message from {}: expected index > {} for session {}, but was {} for session {}",
|
|
message.sender(),
|
|
this.lastMessage.link().index(),
|
|
this.lastMessage.link().sessionId(),
|
|
message.link().index(),
|
|
message.link().sessionId()
|
|
);
|
|
return false;
|
|
} else {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
private boolean validate(PlayerChatMessage message) {
|
|
if (this.expired.getAsBoolean()) {
|
|
LOGGER.error("Received message with expired profile public key from {} with session {}", message.sender(), message.link().sessionId());
|
|
return false;
|
|
} else if (!message.verify(this.validator)) {
|
|
LOGGER.error(
|
|
"Received message with invalid signature (is the session wrong, or signature cache out of sync?): {}", PlayerChatMessage.describeSigned(message)
|
|
);
|
|
return false;
|
|
} else {
|
|
return this.validateChain(message);
|
|
}
|
|
}
|
|
|
|
@Nullable
|
|
@Override
|
|
public PlayerChatMessage updateAndValidate(PlayerChatMessage playerChatMessage) {
|
|
this.isChainValid = this.isChainValid && this.validate(playerChatMessage);
|
|
if (!this.isChainValid) {
|
|
return null;
|
|
} else {
|
|
this.lastMessage = playerChatMessage;
|
|
return playerChatMessage;
|
|
}
|
|
}
|
|
}
|
|
}
|