void NegotiateSecurity(AuthenticationMethod[] methods) { _c.SendByte((byte)methods.Length); //验证密码 VncStream.Require(methods.Length > 0, "Client is not allowed in.", VncFailureReason.NoSupportedAuthenticationMethods); foreach (var method in methods) { _c.SendByte((byte)method); } var selectedMethod = (AuthenticationMethod)_c.ReceiveByte(); VncStream.Require(methods.Contains(selectedMethod), "Invalid authentication method.", VncFailureReason.UnrecognizedProtocolElement); bool success = true; if (selectedMethod == AuthenticationMethod.Password) { var challenge = VncPasswordChallenge.GenerateChallenge(); using (new Utility.AutoClear(challenge)) { _c.Send(challenge); var response = _c.Receive(16); using (new Utility.AutoClear(response)) { var e = new PasswordProvidedEventArgs(challenge, response); OnPasswordProvided(e); success = e.IsAuthenticated; } } } _c.SendUInt32BE(success ? 0 : (uint)1); if (!success) { _c.SendString("Password authentication failed!", true); } VncStream.Require(success, "Failed to authenticate.", VncFailureReason.AuthenticationFailed); }
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); } }