public async Task ClientTest() { for (int i = ProtocolInformation.MinSupportedClientVersion; i <= ProtocolInformation.MaxSupportedClientVersion; i++) { var stream = new MemoryStream (); var client = new ClientRemoteInterface( new BigEndianStream(stream), i); foreach (Type item in client.EndPoint.GetPackets ()) { stream = new MemoryStream (); client = new ClientRemoteInterface( new BigEndianStream(stream), i); if (PacketEndPoint.IsPacketSupported(item, i) == true) { try { var packet = Activator.CreateInstance(item) as Packet; if (packet is HandshakeRequest) (packet as HandshakeRequest).ProtocolVersion = (byte) i; await client.SendPacketAsync(packet); stream.Seek(0, SeekOrigin.Begin); client.EndPoint.Stream.Context = PacketContext.Server; await client.ReadPacketAsync (); Assert.AreEqual(stream.Position, stream.Length, item.Name); } catch (Exception ex) { Assert.Fail(item.ToString (), ex); } } } } }
private static async void WaitForClient(int port) { TcpListener listener = new TcpListener(new IPEndPoint(IPAddress.Any, port)); try { listener.Start(); } catch (Exception ex) { Console.WriteLine("Could not bind to the specific port" + Environment.NewLine + ex.ToString()); Environment.Exit(1); return; } while (true) { bool error = false; Console.WriteLine("Waiting for a client to connect at " + listener.LocalEndpoint.ToString()); var client = await listener.AcceptTcpClientAsync(); Console.WriteLine("Client connected"); using (ConsoleHelpers.ChangeForegroundColor(ConsoleColor.Magenta)) Console.WriteLine("Waiting for Handshake Request (0x02)"); var clientRemoteInterface = new ClientRemoteInterface( new BigEndianStream( new FullyReadStream( client.GetStream())), 39); var packet = clientRemoteInterface.ReadPacket(); if (packet is PlayerListPing) { Console.WriteLine("Server list Ping (0xFE) received. answering..."); await clientRemoteInterface.SendPacketAsync(new DisconnectPacket { Reason = "Minecraft Client Debug Server§0§1" }); client.Close(); continue; } else if (packet is HandshakeRequest) { var handshakePacket = packet as HandshakeRequest; using (ConsoleHelpers.ChangeForegroundColor(ConsoleColor.Green)) { Console.WriteLine("<Handshake packet>"); error = error || !Test(" Username: "******"Username out of range"); Console.WriteLine(" Host: " + handshakePacket.Host); error = error || !Test(" Protocol Version: " + handshakePacket.ProtocolVersion, handshakePacket.ProtocolVersion == 39, "Protocol Version missmatch"); Console.WriteLine("</Handshake packet>"); } if (error) { await clientRemoteInterface.SendPacketAsync(new DisconnectPacket { Reason = "0x02 expected" }); client.Close(); continue; } byte[] randomBuffer = new byte[4]; new Random().NextBytes(randomBuffer); var buffer = new byte[4]; new Random().NextBytes(buffer); //buffer = MD5.Create().ComputeHash(buffer); buffer[0] = 42; var serverId = BitConverter.ToString(buffer).Replace("-", "").ToLower(); var encryptionRequest = new EncryptionKeyRequest { ServerId = serverId, PublicKey = _keyPair.GetPublic(), VerifyToken = randomBuffer }; using (ConsoleHelpers.ChangeForegroundColor(ConsoleColor.Yellow)) { Console.WriteLine("<Handshake response packet>"); Console.WriteLine(" ServerId: " + serverId); Console.WriteLine(" Public Key: " + BitConverter.ToString(_keyPair.GetPublic()).Replace("-", "").ToLower()); Console.WriteLine(" VerifyToken: " + BitConverter.ToString(randomBuffer).Replace("-", "").ToLower()); Console.WriteLine("</Handshake response packet>"); } await clientRemoteInterface.SendPacketAsync(encryptionRequest); using (ConsoleHelpers.ChangeForegroundColor(ConsoleColor.Magenta)) Console.WriteLine("Waiting for 0xFC Encryption response packet"); packet = clientRemoteInterface.ReadPacket(); if (packet is EncryptionKeyResponse) { var encryptionKeyResponse = packet as EncryptionKeyResponse; Console.WriteLine("<Encryption key response packet>"); Console.WriteLine(" Shared Key: " + FormatArray(encryptionKeyResponse.SharedKey.ToArray())); Console.WriteLine(" Verify Token: " + FormatArray(encryptionKeyResponse.VerifyToken.ToArray())); Console.WriteLine("</Encryption key response packet>"); Console.WriteLine("Decryption Verify Token"); var verification = Pdelvo.Minecraft.Network.ProtocolSecurity.RSADecrypt(encryptionKeyResponse.VerifyToken.ToArray(), _keyPair.GetPrivate(), true); error = error || Test("Received Verify Token: " + FormatArray(verification), verification.Length == randomBuffer.Length && verification.Zip(randomBuffer, (a, b) => a == b).All(a => a), "Verification Token missmatch"); if (error) { using (ConsoleHelpers.ChangeForegroundColor(ConsoleColor.Red)) { Console.WriteLine("Verfiy Token was not encrypted correctly"); if (verification.Length == randomBuffer.Length && verification.Zip(randomBuffer, (a, b) => a == b).All(a => a)) { Console.WriteLine("The provided verify token is the one sended to the server, which is not correct. the token must be encrypted using the rsa public key in the handshake packet."); } } await clientRemoteInterface.SendPacketAsync(new DisconnectPacket { Reason = "Verify Token missmatch" }); client.Close(); continue; } Console.WriteLine("Decrypting aes key..."); byte[] encryptedKey = encryptionKeyResponse.SharedKey.ToArray(); var decrypt = Pdelvo.Minecraft.Network.ProtocolSecurity.RSADecrypt(encryptedKey, _keyPair.GetPrivate(), true); //using(ConsoleHelpers.ChangeForegroundColor(ConsoleColor.Green)) // Console.WriteLine("Received shared key: " + ); } else { error = true; Console.WriteLine("Invalid packet received. 0xFC expected. Packet was " + packet.ToString()); await clientRemoteInterface.SendPacketAsync(new DisconnectPacket { Reason = "0x02 expected" }); client.Close(); continue; } } else { error = true; Console.WriteLine("Invalid packet received. 0x02 expected. Packet was " + packet.ToString()); await clientRemoteInterface.SendPacketAsync(new DisconnectPacket { Reason = "0x02 expected" }); client.Close(); continue; } } }
public async Task TestPlayerPing() { var playerPing = new PlayerListPing (); var stream = new MemoryStream (); var oldServer = new ServerRemoteInterface( new BigEndianStream(stream), 46); oldServer.SendPacketAsync(playerPing); stream.Seek(0, SeekOrigin.Begin); var server = new ClientRemoteInterface( new BigEndianStream(stream), 0); Packet packet = server.ReadPacket (); Assert.IsInstanceOfType(packet, typeof (PlayerListPing)); var p = packet as PlayerListPing; Assert.AreEqual(p.MagicByte, 0); stream = new MemoryStream (); var newServer = new ServerRemoteInterface( new BigEndianStream(stream), 47); newServer.SendPacketAsync(playerPing); stream.Seek(0, SeekOrigin.Begin); server = new ClientRemoteInterface( new BigEndianStream(stream), 0); packet = server.ReadPacket (); Assert.IsInstanceOfType(packet, typeof (PlayerListPing)); p = packet as PlayerListPing; Assert.AreEqual(p.MagicByte, 1); }