Exemplo n.º 1
0
        protected void HandleConnectRequest(IPEndPoint address, BitStream stream)
        {
            if (!AllowConnections)
            {
                return;
            }

            var cParams = new ConnectionParameters();

            cParams.Nonce.Read(stream);
            cParams.ServerNonce.Read(stream);
            stream.Read(out cParams.ClientIdentity);

            if (cParams.ClientIdentity != ComputeClientIdentityToken(address, cParams.Nonce))
            {
                return;
            }

            stream.Read(out cParams.PuzzleDifficulty);
            stream.Read(out cParams.PuzzleSolution);


            var connect = FindConnection(address);

            if (connect != null)
            {
                var cp = connect.GetConnectionParameters();

                if (cp.Nonce == cParams.Nonce && cp.ServerNonce == cParams.ServerNonce)
                {
                    SendConnectAccept(connect);
                    return;
                }
            }

            var result = PuzzleManager.CheckSolution(cParams.PuzzleSolution, cParams.Nonce, cParams.ServerNonce, cParams.PuzzleDifficulty, cParams.ClientIdentity);

            if (result != ErrorCode.Success)
            {
                SendConnectReject(cParams, address, "Puzzle");
                return;
            }

            if (stream.ReadFlag())
            {
                if (PrivateKey == null)
                {
                    return;
                }

                cParams.UsingCrypto = true;
                cParams.PublicKey   = new AsymmetricKey(stream);
                cParams.PrivateKey  = PrivateKey;

                var decryptPos = stream.GetBytePosition();

                stream.SetBytePosition(decryptPos);

                cParams.SharedSecret = cParams.PrivateKey.ComputeSharedSecretKey(cParams.PublicKey);

                var theCipher = new SymmetricCipher(cParams.SharedSecret);

                if (!stream.DecryptAndCheckHash(NetConnection.MessageSignatureBytes, decryptPos, theCipher))
                {
                    return;
                }

                stream.Read(SymmetricCipher.KeySize, cParams.SymmetricKey);
                RandomUtil.Read(cParams.InitVector, SymmetricCipher.KeySize);
            }

            cParams.DebugObjectSizes = stream.ReadFlag();

            stream.Read(out uint connectSequence);

            if (connect != null)
            {
                Disconnect(connect, TerminationReason.ReasonSelfDisconnect, "NewConnection");
            }

            stream.ReadString(out string connectionClass);

            var conn = NetConnectionRep.Create(connectionClass);

            if (conn == null)
            {
                return;
            }

            conn.SetConnectionParameters(cParams);
            conn.SetNetAddress(address);
            conn.SetInitialRecvSequence(connectSequence);
            conn.SetInterface(this);

            if (cParams.UsingCrypto)
            {
                conn.SetSymmetricCipher(new SymmetricCipher(cParams.SymmetricKey, cParams.InitVector));
            }

            string errorString = null;

            if (!conn.ReadConnectRequest(stream, ref errorString))
            {
                SendConnectReject(cParams, address, errorString);
                return;
            }

            AddConnection(conn);

            conn.ConnectionState = NetConnectionState.Connected;
            conn.OnConnectionEstablished();

            SendConnectAccept(conn);
        }