Пример #1
0
        // Ran on server
        internal static void HandleHailResponse(ulong clientId, Stream stream)
        {
            if (!NetworkingManager.Singleton.PendingClients.ContainsKey(clientId) || NetworkingManager.Singleton.PendingClients[clientId].ConnectionState != PendingClient.State.PendingHail)
            {
                return;
            }
            if (!NetworkingManager.Singleton.NetworkConfig.EnableEncryption)
            {
                return;
            }

            using (PooledBitReader reader = PooledBitReader.Get(stream))
            {
                if (NetworkingManager.Singleton.PendingClients[clientId].KeyExchange != null)
                {
                    byte[] diffieHellmanPublic = reader.ReadByteArray();
                    NetworkingManager.Singleton.PendingClients[clientId].AesKey = NetworkingManager.Singleton.PendingClients[clientId].KeyExchange.GetSharedSecret(diffieHellmanPublic);
                }
            }

            NetworkingManager.Singleton.PendingClients[clientId].ConnectionState = PendingClient.State.PendingConnection;
            NetworkingManager.Singleton.PendingClients[clientId].KeyExchange     = null; // Give to GC

            // Send greetings, they have passed all the handshakes
            using (PooledBitStream outStream = PooledBitStream.Get())
            {
                using (PooledBitWriter writer = PooledBitWriter.Get(outStream))
                {
                    writer.WriteInt64Packed(DateTime.Now.Ticks); // This serves no purpose.
                }

                InternalMessageSender.Send(clientId, MLAPIConstants.MLAPI_GREETINGS, "MLAPI_INTERNAL", outStream, SecuritySendFlags.None, null);
            }
        }
Пример #2
0
        /// <summary>
        /// [6th step] This function run only on the macchine hosting the game, and check if we need to acquire a new frame, if true it send a broadcast command
        /// </summary>
        private void AcquireIfNeccessary()
        {
            long currentFrame = (long)Math.Floor((Time.time - timeInitAcquisition) / secBetweenFrame);
            if (currentFrame <= frameCounter) return;

            Debug.Log("Time remain expired, schedule frame: " + frameCounter);

            for (int c = 0; c < 1; c++)
            {
                using (PooledBitStream stream = PooledBitStream.Get())
                {
                    using (PooledBitWriter writer = PooledBitWriter.Get(stream))
                    {
                        writer.WriteInt64Packed(frameCounter);

                        InvokeClientRpcOnEveryonePerformance(ScheduleAcquisitionPerformance, stream, "MLAPI_TIME_SYNC");
                    }
                }
            }
            
            frameCounter++;
        }
        // Ran on server
        internal static void HandleHailResponse(uint clientId, Stream stream, int channelId)
        {
            if (!netManager.PendingClients.ContainsKey(clientId) || netManager.PendingClients[clientId].ConnectionState != PendingClient.State.PendingHail)
            {
                return;
            }
            if (!netManager.NetworkConfig.EnableEncryption)
            {
                return;
            }

            using (PooledBitReader reader = PooledBitReader.Get(stream))
            {
                if (NetworkingManager.Singleton.PendingClients[clientId].KeyExchange != null)
                {
                    byte[] diffieHellmanPublic = reader.ReadByteArray();
                    netManager.PendingClients[clientId].AesKey = netManager.PendingClients[clientId].KeyExchange.GetSharedSecret(diffieHellmanPublic);
                    if (netManager.NetworkConfig.SignKeyExchange)
                    {
                        byte[]                   diffieHellmanPublicSignature = reader.ReadByteArray();
                        X509Certificate2         certificate = netManager.NetworkConfig.ServerX509Certificate;
                        RSACryptoServiceProvider rsa         = certificate.PrivateKey as RSACryptoServiceProvider;

                        if (rsa != null)
                        {
                            using (SHA256Managed sha = new SHA256Managed())
                            {
                                byte[] clientHash = rsa.Decrypt(diffieHellmanPublicSignature, false);
                                byte[] serverHash = sha.ComputeHash(diffieHellmanPublic);
                                if (clientHash.Length != serverHash.Length)
                                {
                                    //Man in the middle.
                                    if (LogHelper.CurrentLogLevel <= LogLevel.Normal)
                                    {
                                        if (LogHelper.CurrentLogLevel <= LogLevel.Normal)
                                        {
                                            LogHelper.LogWarning("Signature length doesnt match for the key exchange public part. Disconnecting");
                                        }
                                    }
                                    netManager.DisconnectClient(clientId);
                                    return;
                                }
                                for (int i = 0; i < clientHash.Length; i++)
                                {
                                    if (clientHash[i] != serverHash[i])
                                    {
                                        //Man in the middle.
                                        if (LogHelper.CurrentLogLevel <= LogLevel.Normal)
                                        {
                                            if (LogHelper.CurrentLogLevel <= LogLevel.Normal)
                                            {
                                                LogHelper.LogWarning("Signature doesnt match for the key exchange public part. Disconnecting");
                                            }
                                        }
                                        netManager.DisconnectClient(clientId);
                                        return;
                                    }
                                }
                            }
                        }
                        else
                        {
                            throw new CryptographicException("[MLAPI] Only RSA certificates are supported. No valid RSA key was found");
                        }
                    }
                }
            }

            netManager.PendingClients[clientId].ConnectionState = PendingClient.State.PendingConnection;
            netManager.PendingClients[clientId].KeyExchange     = null; // Give to GC

            // Send greetings, they have passed all the handshakes
            using (PooledBitStream outStream = PooledBitStream.Get())
            {
                using (PooledBitWriter writer = PooledBitWriter.Get(outStream))
                {
                    writer.WriteInt64Packed(DateTime.Now.Ticks); // This serves no purpose.
                }
                InternalMessageHandler.Send(clientId, MLAPIConstants.MLAPI_GREETINGS, "MLAPI_INTERNAL", outStream, SecuritySendFlags.None, true);
            }
        }