Example #1
0
        public override void ReadPacket()
        {
            SharedSecretLength = Read <VarInt>();
            SharedSecret       = ReadArray <byte>(SharedSecretLength);
            VerifyTokenLength  = Read <VarInt>();
            VerifyToken        = ReadArray <byte>(VerifyTokenLength);

            VerifyToken = PacketCryptography.Decrypt(VerifyToken);

            if (!VerifyToken.SequenceEqual(PacketCryptography.VerifyToken))
            {
                Client.Send(new DisconnectLoginPaket(Client)
                {
                    Reason = new ChatMessage()
                    {
                        Text = "Verification Failed"
                    }
                });
                return;
            }

            SharedSecret = PacketCryptography.Decrypt(SharedSecret);

            var v = Utils.GetUUID(Player, (Utils.GetHash(Utils.BaseServerHash,
                                                         SharedSecret,
                                                         PacketCryptography.PublicKeyToAsn1(Utils.ServerKey))));

            Client.Crypto = PacketCryptography.GenerateAes(SharedSecret);

            var v2 = v.GetAwaiter().GetResult();

            if (v2 == null)
            {
                Client.Send(new DisconnectLoginPaket(Client)
                {
                    Reason = new ChatMessage()
                    {
                        Text = "Coud not get UUID"
                    }
                });
                return;
            }
            else
            {
                Player.UUID = v2;
            }

            Client.Send(new LoginSuccessPacket(Client));
        }
        public override void Read()
        {
            if (Buffer != null)
            {
                var length       = Buffer.ReadVarInt();
                var sharedsecret = Buffer.Read(length);

                length = Buffer.ReadVarInt();
                var verifytoken = Buffer.Read(length);

                Client.SharedKey = PacketCryptography.Decrypt(sharedsecret);

                var recv = PacketCryptography.GenerateAES((byte[])Client.SharedKey.Clone());
                var send = PacketCryptography.GenerateAES((byte[])Client.SharedKey.Clone());

                var packetToken = PacketCryptography.Decrypt(verifytoken);

                if (!packetToken.SequenceEqual(PacketCryptography.VerifyToken))
                {
                    //Wrong token! :(
                    ConsoleFunctions.WriteWarningLine("Wrong token!");
                    return;
                }

                Client.Decrypter = recv.CreateDecryptor();
                Client.Encrypter = send.CreateEncryptor();

                Client.EncryptionEnabled = true;
                Client.Player            = new Player(Globals.LevelManager.MainLevel)
                {
                    Uuid     = getUUID(Client.Username),
                    Username = Client.Username,
                    Wrapper  = Client,
                    Gamemode = Globals.LevelManager.MainLevel.DefaultGamemode
                };

                if (Client.Player.IsAuthenticated())
                {
                    new LoginSucces(Client)
                    {
                        Username = Client.Username, UUID = Client.Player.Uuid
                    }.Write();
                    Client.PacketMode = PacketMode.Play;

                    new SetCompression(Client).Write();

                    new JoinGame(Client)
                    {
                        Player = Client.Player
                    }.Write();
                    new SpawnPosition(Client).Write();
                    Client.StartKeepAliveTimer();
                    Client.Player.SendChunksFromPosition();
                }
                else
                {
                    new LoginSucces(Client)
                    {
                        Username = Client.Username, UUID = Client.Player.Uuid
                    }.Write();
                    new Disconnect(Client)
                    {
                        Reason = "Authentication failed! Try restarting your client."
                    }.Write();
                }
            }
        }
Example #3
0
        public async Task StartConnectionAsync()
        {
            while (!Cancellation.IsCancellationRequested && this.Tcp.Connected)
            {
                Packet packet = this.Compressed ? await this.GetNextCompressedPacketAsync() : await this.GetNextPacketAsync();

                Packet returnPacket;

                if (this.State == ClientState.Play && packet.PacketData.Length < 1)
                {
                    this.Disconnect();
                }

                switch (this.State)
                {
                case ClientState.Status:     //server ping/list
                    switch (packet.PacketId)
                    {
                    case 0x00:
                        var status = new ServerStatus(OriginServer);
                        await PacketHandler.CreateAsync(new RequestResponse(status), this.MinecraftStream);

                        break;

                    case 0x01:
                        await PacketHandler.CreateAsync(new PingPong(packet.PacketData), this.MinecraftStream);

                        this.Disconnect();
                        break;
                    }
                    break;

                case ClientState.Handshaking:
                    if (packet.PacketId == 0x00)
                    {
                        if (packet == null)
                        {
                            throw new InvalidOperationException();
                        }

                        var handshake = await PacketHandler.CreateAsync(new Handshake(packet.PacketData));

                        var nextState = handshake.NextState;

                        if (nextState != ClientState.Status && nextState != ClientState.Login)
                        {
                            this.Logger.LogDebug($"Client sent unexpected state ({(int)nextState}), forcing it to disconnect");
                            await this.DisconnectAsync(Chat.ChatMessage.Simple("you seem suspicious"));
                        }

                        this.State = nextState;
                        this.Logger.LogMessage($"Handshaking with client (protocol: {handshake.Version}, server: {handshake.ServerAddress}:{handshake.ServerPort})");
                    }
                    else
                    {
                        //Handle legacy ping stuff
                    }
                    break;

                case ClientState.Login:
                    switch (packet.PacketId)
                    {
                    default:
                        this.Logger.LogError("Client in state Login tried to send an unimplemented packet. Forcing it to disconnect.");
                        await this.DisconnectAsync(ChatMessage.Simple("Unknown Packet Id."));

                        break;

                    case 0x00:
                        var loginStart = await PacketHandler.CreateAsync(new LoginStart(packet.PacketData));

                        string username = loginStart.Username;

                        if (Config.MulitplayerDebugMode)
                        {
                            username = $"Player{new Random().Next(1, 999)}";
                            this.Logger.LogDebug($"Overriding username from {loginStart.Username} to {username}");
                        }

                        this.Logger.LogDebug($"Received login request from user {loginStart.Username}");

                        if (this.OriginServer.CheckPlayerOnline(username))
                        {
                            await this.OriginServer.Clients.FirstOrDefault(c => c.Player.Username == username).DisconnectAsync(Chat.ChatMessage.Simple("Logged in from another location"));
                        }

                        if (this.Config.OnlineMode)
                        {
                            var users = await MinecraftAPI.GetUsersAsync(new string[] { loginStart.Username });

                            var uid = users.FirstOrDefault();

                            var uuid = Guid.Parse(uid.Id);
                            this.Player = new Player(uuid, loginStart.Username, this);

                            PacketCryptography.GenerateKeyPair();

                            var pubKey = PacketCryptography.PublicKeyToAsn();

                            this.Token = PacketCryptography.GetRandomToken();

                            returnPacket = await PacketHandler.CreateAsync(new EncryptionRequest(pubKey, this.Token), this.MinecraftStream);

                            break;
                        }

                        this.Player = new Player(Guid.NewGuid(), username, this);
                        await ConnectAsync(this.Player.Uuid);

                        break;

                    case 0x01:
                        var encryptionResponse = await PacketHandler.CreateAsync(new EncryptionResponse(packet.PacketData));

                        JoinedResponse response;

                        this.SharedKey = PacketCryptography.Decrypt(encryptionResponse.SharedSecret);

                        var dec2 = PacketCryptography.Decrypt(encryptionResponse.VerifyToken);

                        var dec2Base64 = Convert.ToBase64String(dec2);

                        var tokenBase64 = Convert.ToBase64String(this.Token);

                        if (!dec2Base64.Equals(tokenBase64))
                        {
                            await this.DisconnectAsync(Chat.ChatMessage.Simple("Invalid token.."));

                            break;
                        }

                        var encodedKey = PacketCryptography.PublicKeyToAsn();

                        var serverId = PacketCryptography.MinecraftShaDigest(SharedKey.Concat(encodedKey).ToArray());

                        response = await MinecraftAPI.HasJoined(this.Player.Username, serverId);

                        if (response is null)
                        {
                            this.Logger.LogWarning($"Failed to auth {this.Player.Username}");
                            await this.DisconnectAsync(Chat.ChatMessage.Simple("Unable to authenticate.."));

                            break;
                        }
                        this.EncryptionEnabled = true;
                        this.MinecraftStream   = new AesStream(this.Tcp.GetStream(), this.SharedKey);

                        await ConnectAsync(new Guid(response.Id));

                        break;

                    case 0x02:
                        // Login Plugin Response
                        break;
                    }
                    break;

                case ClientState.Play:

                    ///this.Logger.LogDebugAsync($"Received Play packet with Packet ID 0x{packet.PacketId.ToString("X")}");

                    await PacketHandler.HandlePlayPackets(packet, this);

                    break;
                }
            }

            Logger.LogMessage($"Disconnected client");

            if (this.IsPlaying)
            {
                await this.OriginServer.Events.InvokePlayerLeave(new PlayerLeaveEventArgs(this));
            }

            this.OriginServer.Broadcast(string.Format(this.Config.LeaveMessage, this.Player.Username));

            this.Player = null;

            if (Tcp.Connected)
            {
                this.Tcp.Close();
            }
        }