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;
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| }
 |