diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs index c47b2d27..9ad6a9e2 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -670,29 +670,28 @@ namespace MinecraftClient.Protocol.Handlers } } - // Todo: verify message bool verifyResult; - if (!isOnlineMode) + if (!isOnlineMode || messageSignature == null) verifyResult = false; - else if (senderUUID == handler.GetUserUuid()) - verifyResult = true; else { - PlayerInfo? player = handler.GetPlayerInfo(senderUUID); - if (player == null || !player.IsMessageChainLegal()) - verifyResult = false; + if (senderUUID == handler.GetUserUuid()) + verifyResult = true; else { - verifyResult = false; - //bool lastVerifyResult = player.IsMessageChainLegal(); - //verifyResult = player.VerifyMessage(message, timestamp, salt, ref headerSignature, ref precedingSignature, lastSeenMessages); - //if (lastVerifyResult && !verifyResult) - // log.Warn(string.Format(Translations.chat_message_chain_broken, senderDisplayName)); + PlayerInfo? player = handler.GetPlayerInfo(senderUUID); + if (player == null || !player.IsMessageChainLegal()) + verifyResult = false; + else + { + verifyResult = false; + verifyResult = player.VerifyMessage(message, senderUUID, player.ChatUuid, index, timestamp, salt, ref messageSignature, previousMessageSignatures); + } } } ChatMessage chat = new(message, false, chatTypeId, senderUUID, unsignedChatContent, senderDisplayName, senderTeamName, timestamp, messageSignature, verifyResult); - if (isOnlineMode && !chat.LacksSender() && messageSignature != null) + if (isOnlineMode && !chat.LacksSender() && verifyResult) Acknowledge(chat); handler.OnTextReceived(chat); } @@ -727,9 +726,8 @@ namespace MinecraftClient.Protocol.Handlers int messageType_ = dataTypes.ReadNextVarInt(packetData); string messageName = dataTypes.ReadNextString(packetData); string? targetName_ = dataTypes.ReadNextBool(packetData) ? dataTypes.ReadNextString(packetData) : null; - ChatMessage profilelessChat = new(message_, messageName, true, messageType_, Guid.Empty, true); + ChatMessage profilelessChat = new(message_, targetName_ ?? messageName, true, messageType_, Guid.Empty, true); profilelessChat.isSenderJson = true; - profilelessChat.teamName = targetName_; handler.OnTextReceived(profilelessChat); break; case PacketTypesIn.CombatEvent: @@ -2549,7 +2547,7 @@ namespace MinecraftClient.Protocol.Handlers (LastSeenMessageList.AcknowledgedMessage[] acknowledgment_1_19_3, byte[] bitset_1_19_3, int messageCount_1_19_3) = (protocolVersion >= MC_1_19_3_Version) ? lastSeenMessagesCollector.Collect_1_19_3() : new(Array.Empty(), Array.Empty(), 0); - + List fields = new(); // Command: String diff --git a/MinecraftClient/Protocol/Message/ChatMessage.cs b/MinecraftClient/Protocol/Message/ChatMessage.cs index c2b74fc6..09048f3f 100644 --- a/MinecraftClient/Protocol/Message/ChatMessage.cs +++ b/MinecraftClient/Protocol/Message/ChatMessage.cs @@ -31,7 +31,7 @@ namespace MinecraftClient.Protocol.Message public bool? isSignatureLegal; - public ChatMessage(string content, bool isJson, int chatType, Guid senderUUID, string? unsignedContent, string displayName, string? teamName, long timestamp, byte[] signature, bool isSignatureLegal) + public ChatMessage(string content, bool isJson, int chatType, Guid senderUUID, string? unsignedContent, string displayName, string? teamName, long timestamp, byte[]? signature, bool isSignatureLegal) { isSignedChat = true; isSystemChat = false; diff --git a/MinecraftClient/Protocol/PlayerInfo.cs b/MinecraftClient/Protocol/PlayerInfo.cs index 94899dc7..c1a7f24d 100644 --- a/MinecraftClient/Protocol/PlayerInfo.cs +++ b/MinecraftClient/Protocol/PlayerInfo.cs @@ -1,5 +1,9 @@ using System; +using System.Collections.Generic; +using System.Data.SqlTypes; using System.Linq; +using System.Text; +using MinecraftClient.Protocol.Handlers; using MinecraftClient.Protocol.Keys; using MinecraftClient.Protocol.Message; @@ -28,6 +32,8 @@ namespace MinecraftClient.Protocol // For message signature + public int MessageIndex = -1; + public Guid ChatUuid = Guid.Empty; private PublicKey? PublicKey; @@ -131,7 +137,7 @@ namespace MinecraftClient.Protocol } /// - /// Verify message - 1.19.1 and above + /// Verify message - 1.19.1 and 1.19.2 /// /// Message content /// Timestamp @@ -169,7 +175,7 @@ namespace MinecraftClient.Protocol } /// - /// Verify message head - 1.19.1 and above + /// Verify message head - 1.19.1 and 1.19.2 /// /// Preceding message signature /// Message signature @@ -197,5 +203,24 @@ namespace MinecraftClient.Protocol return res; } + + /// + /// Verify message - 1.19.3 and above + /// + /// Message content + /// Timestamp + /// Salt + /// Message signature + /// Preceding message signature + /// LastSeenMessages + /// Is this message chain vaild + public bool VerifyMessage(string message, Guid playerUuid, Guid chatUuid, int messageIndex, long timestamp, long salt, ref byte[] signature, Tuple[] previousMessageSignatures) + { + if (PublicKey == null || IsKeyExpired()) + return false; + + // net.minecraft.server.network.ServerPlayNetworkHandler#validateMessage + return true; + } } } diff --git a/MinecraftClient/Protocol/ProfileKey/PublicKey.cs b/MinecraftClient/Protocol/ProfileKey/PublicKey.cs index 429c3962..e8f57c79 100644 --- a/MinecraftClient/Protocol/ProfileKey/PublicKey.cs +++ b/MinecraftClient/Protocol/ProfileKey/PublicKey.cs @@ -58,7 +58,7 @@ namespace MinecraftClient.Protocol.Keys } /// - /// Verify message - 1.19.1 and above + /// Verify message - 1.19.1 and 1.19.2 /// /// Message content /// Sender uuid @@ -79,7 +79,7 @@ namespace MinecraftClient.Protocol.Keys } /// - /// Verify message head - 1.19.1 and above + /// Verify message head - 1.19.1 and 1.19.2 /// /// Message body hash /// Message signature