コード例 #1
0
 private async Task HandlePacket(BbTcpPacket packet)
 {
     if (packet is BbTcpPacket_Hello_Ans && m_bRequestedHello)
     {
         m_bRequestedHello = false;
         BbTcpPacket_Hello_Ans hello_ans = (BbTcpPacket_Hello_Ans)packet;
         ServerName = hello_ans.Desc;
         ServerGUID = hello_ans.ServerGUID;
         ServerMinProtocolVersion = hello_ans.MinSupportedVersion;
         m_bRequiresPassword      = hello_ans.RequiresPassword;
         UsedProtocolVersion      = (byte)Math.Min(hello_ans.MaxSupportedVersion, BBProtocol.CURRENT_PROTOCOL_VERSION);
         if (UsedProtocolVersion < hello_ans.MinSupportedVersion || UsedProtocolVersion < BBProtocol.MIN_PROTOCOL_VERSION)
         {
             ProtocolIncompatible = true;
             Log.w(TAG, "Server supported protocol versions incompatible - " + ServerName);
             Disconnect(false, true);
         }
         SupportsScreenCapture = hello_ans.SupportsScreenCapture;
         IsProVersion          = hello_ans.IsProVersion;
         Log.d(TAG, "Received Hello Answer from " + ServerName + " Protocol Version: " + UsedProtocolVersion + " Needs Password: "******"Got Pong");
     }
     else if (packet is BbTcpPacket_EncryptionACK crypt)
     {
         await ContinueEncryptionNegotiation(crypt);
     }
     else if (packet is BbTcpPacket_Encryption_AuthAns auth)
     {
         if (m_abyTestedSharedSecret != null)
         {
             if (auth.ErrorCode == 0)
             {
                 Log.d(TAG, "DH+Auth negotiated encryption key for session is: " + BitConverter.ToString(m_abyTestedSharedSecret));
                 m_sendStreamCipher.Init(m_abyTestedSharedSecret);
                 m_recvStreamCipher.Init(m_abyTestedSharedSecret);
                 m_bAuthentificated          = true;
                 m_abyTestedSharedSecret     = null;
                 m_dhKeyExchange             = null;
                 m_requestedEncryptionMethod = EEncryptionMethod.NONE;
                 Log.d(TAG, "Password accepted, DH+Auth Encryption negotiation finished, transmissions will now be encrypted with " + m_sendStreamCipher.Algorithm);
                 Attach();
             }
             else
             {
                 Log.w(TAG, "Challenge failed - Password rejected. Trying again.");
                 m_abyTestedSharedSecret = null;
                 await Authenticate(true);
             }
         }
         else
         {
             Log.e(TAG, "Unexpected/Unrequested Encryption_AuthAns packet");
             Disconnect(false, false);
         }
     }
     else if (packet is BbTcpPacket_Attach_Ans attach_ans && m_bRequestedAttach)
     {
         m_bRequestedAttach = false;
         if (attach_ans.AttachResult == EAttachResult.ACCEPTED)
         {
             Attached    = true;
             WasAttached = true;
             ConnectedTime.Start();
             Connecting = false;
             ConnectionChanged?.Invoke(this, new ConnectionEventArgs(ConnectionEventArgs.EState.CONNECTED, SessionID));
             Log.d(TAG, "Attached to " + ServerName);
         }
         else
         {
             Log.d(TAG, "Cannot Attach to " + ServerName + " Error: " + attach_ans.AttachResult);
             Disconnect(false, false);
         }
     }
コード例 #2
0
        private async Task ReceiveTask()
        {
            NetworkStream stream;

            try
            {
                stream = m_tcpClient.GetStream();
            }
            catch (InvalidOperationException e)
            {
                throw new IOException("Receive: Unable to get stream (not connected?) - " + e.Message, e);
            }
            List <BbTcpPacket_Fragment> liFragments = new List <BbTcpPacket_Fragment>();

            while (true)
            {
                m_CancelToken.Token.ThrowIfCancellationRequested();
                try
                {
                    byte[] byHeader = new byte[BBProtocol.TCP_HEADERSIZE];
                    int    read     = 0;
                    while (read != byHeader.Length)
                    {
                        int len = await stream.ReadAsync(byHeader, read, byHeader.Length - read, m_CancelToken.Token);

                        if (len <= 0)
                        {
                            throw new IOException("Read < 0");
                        }
                        read += len;
                        m_CancelToken.Token.ThrowIfCancellationRequested();
                    }

                    if (m_recvStreamCipher.IsReady)
                    {
                        m_recvStreamCipher.Crypt(byHeader);
                    }

                    BbTcpPacket newPacket = new BbTcpPacket(byHeader);
                    if (newPacket.IsValid)
                    {
                        if (newPacket.IsComplete)
                        {
                            newPacket = newPacket.ReadPacket(new byte[0], UsedProtocolVersion);
                        }
                        else
                        {
                            byte[] byBody = new byte[newPacket.BodyLength];
                            read = 0;
                            while (read != byBody.Length)
                            {
                                int len = await stream.ReadAsync(byBody, read, byBody.Length - read, m_CancelToken.Token);

                                if (len <= 0)
                                {
                                    throw new IOException("Read < 0");
                                }
                                read += len;
                                m_CancelToken.Token.ThrowIfCancellationRequested();
                            }

                            if (m_recvStreamCipher.IsReady)
                            {
                                m_recvStreamCipher.Crypt(byBody);
                            }

                            newPacket = newPacket.ReadPacket(byBody, UsedProtocolVersion);
                        }

                        if (newPacket.IsValid && newPacket.IsComplete)
                        {
                            if (newPacket is BbTcpPacket_Fragment)
                            {
                                //Log.d(TAG, "Fragment received");
                                BbTcpPacket_Fragment found = liFragments.Find(x => x.FragmentID == ((BbTcpPacket_Fragment)newPacket).FragmentID);
                                if (found == null)
                                {
                                    liFragments.Add((BbTcpPacket_Fragment)newPacket);
                                }
                                else if (found.addFragment((BbTcpPacket_Fragment)newPacket)) // add. complete?
                                {
                                    newPacket = found.assemblePacket();
                                    liFragments.Remove(found);
                                    if (newPacket != null)
                                    {
                                        //Log.d(TAG, "Fragment completed from Opcode: " + newPacket.DbgGetOpcode());
                                        m_receivedPackets.Post(newPacket);
                                    }
                                    else
                                    {
                                        Log.d(TAG, "Error while completing Fragment: " + found.ParseError);
                                        throw new IOException("Error while completing Fragment: " + found.ParseError);
                                    }
                                }
                            }
                            else
                            {
                                //Log.d(TAG, "New Packet received");
                                m_receivedPackets.Post(newPacket);
                            }
                        }
                        else
                        {
                            Log.e(TAG, "Invalid Packet (body) received:" + newPacket.ParseError);
                            throw new IOException("Invalid Packet (body) received:" + newPacket.ParseError);
                        }
                    }
                    else
                    {
                        Log.e(TAG, "Invalid Packet (header) received:" + newPacket.ParseError);
                        throw new IOException("Invalid Packet (header) received:" + newPacket.ParseError);
                    }
                }
                catch (Exception e) when(e is NotSupportedException || e is ObjectDisposedException)
                {
                    Log.e(TAG, "Error while reading: " + e.Message + " stack: " + e.StackTrace);
                    throw new IOException("Error while reading", e);
                }
            }
        }