void NegotiateDesktop() { byte shareDesktopSetting = _c.ReceiveByte();//是否同意分享屏幕 bool shareDesktop = shareDesktopSetting != 0; var e = new CreatingDesktopEventArgs(shareDesktop); OnCreatingDesktop(e); var fbSource = _fbSource; Framebuffer = fbSource != null?fbSource.Capture() : null; VncStream.Require(Framebuffer != null, "No framebuffer. Make sure you've called SetFramebufferSource. It can be set to a VncFramebuffer.", VncFailureReason.SanityCheckFailed); _clientPixelFormat = Framebuffer.PixelFormat; _clientWidth = Framebuffer.Width; _clientHeight = Framebuffer.Height; _fbuAutoCache = null; _c.SendUInt16BE((ushort)Framebuffer.Width); _c.SendUInt16BE((ushort)Framebuffer.Height); var pixelFormat = new byte[VncPixelFormat.Size]; Framebuffer.PixelFormat.Encode(pixelFormat, 0); _c.Send(pixelFormat); _c.SendString(Framebuffer.Name, true); }
private void NegotiateDesktop() { this.logger?.Log(LogLevel.Info, () => "Negotiating desktop settings"); byte shareDesktopSetting = this.c.ReceiveByte(); bool shareDesktop = shareDesktopSetting != 0; var e = new CreatingDesktopEventArgs(shareDesktop); this.OnCreatingDesktop(e); var fbSource = this.fbSource; this.Framebuffer = fbSource != null?fbSource.Capture() : null; VncStream.Require( this.Framebuffer != null, "No framebuffer. Make sure you've called SetFramebufferSource. It can be set to a VncFramebuffer.", VncFailureReason.SanityCheckFailed); this.clientPixelFormat = this.Framebuffer.PixelFormat; this.clientWidth = this.Framebuffer.Width; this.clientHeight = this.Framebuffer.Height; this.fbuAutoCache = null; this.c.SendUInt16BE((ushort)this.Framebuffer.Width); this.c.SendUInt16BE((ushort)this.Framebuffer.Height); var pixelFormat = new byte[VncPixelFormat.Size]; this.Framebuffer.PixelFormat.Encode(pixelFormat, 0); this.c.Send(pixelFormat); this.c.SendString(this.Framebuffer.Name, true); this.logger?.Log(LogLevel.Info, () => $"The desktop {this.Framebuffer.Name} has initialized with pixel format {this.clientPixelFormat}; the screen size is {this.clientWidth}x{this.clientHeight}"); }
private void NegotiateSecurity(AuthenticationMethod[] methods) { this.logger?.Log(LogLevel.Info, () => "Negotiating security"); this.c.SendByte((byte)methods.Length); VncStream.Require( methods.Length > 0, "Client is not allowed in.", VncFailureReason.NoSupportedAuthenticationMethods); foreach (var method in methods) { this.c.SendByte((byte)method); } var selectedMethod = (AuthenticationMethod)this.c.ReceiveByte(); VncStream.Require( methods.Contains(selectedMethod), "Invalid authentication method.", VncFailureReason.UnrecognizedProtocolElement); bool success = true; if (selectedMethod == AuthenticationMethod.Password) { var challenge = this.passwordChallenge.GenerateChallenge(); using (new Utility.AutoClear(challenge)) { this.c.Send(challenge); var response = this.c.Receive(16); using (new Utility.AutoClear(response)) { var e = new PasswordProvidedEventArgs(this.passwordChallenge, challenge, response); this.OnPasswordProvided(e); success = e.IsAuthenticated; } } } this.c.SendUInt32BE(success ? 0 : (uint)1); VncStream.Require( success, "Failed to authenticate.", VncFailureReason.AuthenticationFailed); this.logger?.Log(LogLevel.Info, () => "The user authenticated successfully."); this.securityNegotiated = true; }
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); }
private void ThreadMain() { this.requester = new Utility.PeriodicThread(); try { this.InitFramebufferEncoder(); AuthenticationMethod[] methods; this.NegotiateVersion(out methods); this.NegotiateSecurity(methods); this.NegotiateDesktop(); this.NegotiateEncodings(); this.requester.Start(() => this.FramebufferSendChanges(), () => this.MaxUpdateRate, false); this.IsConnected = true; this.logger?.Log(LogLevel.Info, () => "The client has connected successfully"); this.OnConnected(); while (true) { var command = (VncMessageType)this.c.ReceiveByte(); this.logger?.Log(LogLevel.Info, () => $"Received the {command} command."); switch (command) { case VncMessageType.SetPixelFormat: this.HandleSetPixelFormat(); break; case VncMessageType.SetEncodings: this.HandleSetEncodings(); break; case VncMessageType.FrameBufferUpdateRequest: this.HandleFramebufferUpdateRequest(); break; case VncMessageType.KeyEvent: this.HandleKeyEvent(); break; case VncMessageType.PointerEvent: this.HandlePointerEvent(); break; case VncMessageType.ClientCutText: this.HandleReceiveClipboardData(); break; default: VncStream.Require( false, "Unsupported command.", VncFailureReason.UnrecognizedProtocolElement); break; } } } catch (Exception exception) { this.logger?.Log(LogLevel.Error, () => $"VNC server session stopped due to: {exception.Message}"); } this.requester.Stop(); this.c.Stream = null; if (this.IsConnected) { this.IsConnected = false; this.OnClosed(); } else { this.OnConnectionFailed(); } }
void ThreadMain() { _requester = new Utility.PeriodicThread(); try { InitFramebufferEncoder(); AuthenticationMethod[] methods; NegotiateVersion(out methods); NegotiateSecurity(methods); NegotiateDesktop();//绘画的桌面 NegotiateEncodings(); _requester.Start(FramebufferSendChanges, () => MaxUpdateRate, false); IsConnected = true; OnConnected(); while (true) { var command = _c.ReceiveByte(); switch (command) { case 0: HandleSetPixelFormat(); break; case 2: HandleSetEncodings(); break; case 3: HandleFramebufferUpdateRequest(); break; case 4: HandleKeyEvent(); break; case 5: HandlePointerEvent(); break; case 6: HandleReceiveClipboardData(); break; default: VncStream.Require(false, "Unsupported command.", VncFailureReason.UnrecognizedProtocolElement); break; } } } catch (ObjectDisposedException ex) { } catch (IOException ex) { } catch (VncException ex) { //Vnc错误 } _requester.Stop(); _c.Stream = null; if (IsConnected) { IsConnected = false; OnClosed(); } else { OnConnectionFailed(); } }
/// <summary> /// Reads the next client message and handles it. /// </summary> /// <remarks> /// The <see cref="VncServerSession"/> starts a main thread which read and processes messages. /// You don't normally need to call this method yourself; but it can be usefull when writing /// unit tests. /// </remarks> public void HandleMessage() { var command = (VncMessageType)this.c.ReceiveByte(); // If the same command is sent repeatedly (e.g. FramebufferUpdateRequest), suppress repeated requests if (this.previousCommand != command || this.commandCount >= 25) { if (this.commandCount > 0) { this.logger?.LogInformation($"Suppressed {this.commandCount} notifications of the {command} command at the Info level."); } this.logger?.LogInformation($"Received the {command} command."); this.commandCount = 0; } else { this.logger?.LogDebug($"Received the {command} command"); this.commandCount++; } this.previousCommand = command; switch (command) { case VncMessageType.SetPixelFormat: this.HandleSetPixelFormat(); break; case VncMessageType.SetEncodings: this.HandleSetEncodings(); break; case VncMessageType.FrameBufferUpdateRequest: this.HandleFramebufferUpdateRequest(); break; case VncMessageType.KeyEvent: this.HandleKeyEvent(); break; case VncMessageType.PointerEvent: this.HandlePointerEvent(); break; case VncMessageType.ClientCutText: this.HandleReceiveClipboardData(); break; case VncMessageType.SetDesktopSize: this.HandleSetDesktopSize(); break; default: VncStream.Require( false, "Unsupported command.", VncFailureReason.UnrecognizedProtocolElement); break; } }