public void NegotiateSecurityIncorrectPasswordTest()
        {
            using (var stream = new TestStream())
            {
                // Have the client send authentication method 'Password', which is what the server expects
                VncStream clientStream = new VncStream(stream.Input);
                clientStream.SendByte((byte)AuthenticationMethod.Password);
                clientStream.Send(new byte[16]); // An empty response
                stream.Input.Position = 0;

                var session = new VncServerSession();
                session.Connect(stream, null, startThread: false);

                Assert.False(session.NegotiateSecurity(new AuthenticationMethod[] { AuthenticationMethod.Password }));

                VncStream serverStream = new VncStream(stream.Output);
                stream.Output.Position = 0;

                // Server will have offered 1 authentication method, and failed to authenticate
                // the client
                Assert.Equal(1, serverStream.ReceiveByte());                                   // 1 authentication method offered
                Assert.Equal((byte)AuthenticationMethod.Password, serverStream.ReceiveByte()); // The authentication method offered
                Assert.NotEqual(0u, serverStream.ReceiveUInt32BE());                           // Challenge, part 1
                Assert.NotEqual(0u, serverStream.ReceiveUInt32BE());                           // Challenge, part 2
                Assert.NotEqual(0u, serverStream.ReceiveUInt32BE());                           // Challenge, part 3
                Assert.NotEqual(0u, serverStream.ReceiveUInt32BE());                           // Challenge, part 4
                Assert.Equal(1u, serverStream.ReceiveUInt32BE());                              // Authentication failed
                Assert.Equal("Failed to authenticate", serverStream.ReceiveString());          // Error message

                Assert.Equal(stream.Output.Length, stream.Output.Position);
                Assert.Equal(stream.Input.Length, stream.Input.Position);
            }
        }
        public void NegotiateSecurityInvalidMethodTest()
        {
            using (var stream = new TestStream())
            {
                // Have the client send authentication method 'None', while we only accept 'Password'
                VncStream clientStream = new VncStream(stream.Input);
                clientStream.SendByte((byte)AuthenticationMethod.None);
                stream.Input.Position = 0;

                var session = new VncServerSession();
                session.Connect(stream, null, startThread: false);

                Assert.False(session.NegotiateSecurity(new AuthenticationMethod[] { AuthenticationMethod.Password }));

                VncStream serverStream = new VncStream(stream.Output);
                stream.Output.Position = 0;

                // Server will have offered 1 authentication method, and disconnected when the client
                // accepted an invalid authentication method.
                Assert.Equal(1, serverStream.ReceiveByte());                                   // 1 authentication method offered
                Assert.Equal((byte)AuthenticationMethod.Password, serverStream.ReceiveByte()); // The authentication method offered
                Assert.Equal(1u, serverStream.ReceiveUInt32BE());                              // authentication failed
                Assert.Equal("Invalid authentication method.", serverStream.ReceiveString());  // error message
            }
        }
        public void NegotiateSecurityNoSecurityTypesTest()
        {
            using (var stream = new TestStream())
            {
                var session = new VncServerSession();
                session.Connect(stream, null, startThread: false);

                Assert.False(session.NegotiateSecurity(Array.Empty <AuthenticationMethod>()));

                VncStream serverStream = new VncStream(stream.Output);
                stream.Output.Position = 0;

                // Server should have sent a zero-length array, and a message explaining
                // the disconnect reason
                Assert.Equal(0, serverStream.ReceiveByte());
                Assert.Equal("The server and client could not agree on any authentication method.", serverStream.ReceiveString());
            }
        }
        public void NegotiateSecuritySuccessTest()
        {
            using (var stream = new TestStream())
            {
                // Have the client send authentication method 'None', which is what the server expects
                VncStream clientStream = new VncStream(stream.Input);
                clientStream.SendByte((byte)AuthenticationMethod.None);
                stream.Input.Position = 0;

                var session = new VncServerSession();
                session.Connect(stream, null, startThread: false);

                Assert.True(session.NegotiateSecurity(new AuthenticationMethod[] { AuthenticationMethod.None }));

                VncStream serverStream = new VncStream(stream.Output);
                stream.Output.Position = 0;

                // Server will have offered 1 authentication method, and successfully authenticated
                // the client
                Assert.Equal(1, serverStream.ReceiveByte());                               // 1 authentication method offered
                Assert.Equal((byte)AuthenticationMethod.None, serverStream.ReceiveByte()); // The authentication method offered
                Assert.Equal(0u, serverStream.ReceiveUInt32BE());                          // authentication succeeded
            }
        }