using RemoteFrameBuffer.Common; using System.Text; namespace RemoteFrameBuffer.Client { public class RemoteFrameBufferClientProtocol_3_3 : RemoteFrameBufferClientProtocol { public override RfbProtoVersion Version => new(3, 3); public RemoteFrameBufferClientProtocol_3_3(Stream s) : base(s) { this.Phase = RfbClientProtocolPhase.Constructed; } public override void Handshake(CancellationToken token) { if (this.Phase != RfbClientProtocolPhase.Constructed) { throw new InvalidOperationException("In wrong phase when calling Handshake"); } this.Phase = RfbClientProtocolPhase.Handshake; Byte[] buf; // Request protocol version this.vncStream.Write(Encoding.ASCII.GetBytes("RFB 003.003\n")); // Read security type buf = new Byte[4]; CancellationTokenSource readTimeout = new CancellationTokenSource(TimeSpan.FromSeconds(5)); CancellationTokenSource readTokenSource = CancellationTokenSource.CreateLinkedTokenSource(token, readTimeout.Token); this.vncStream.ReadExactlyAsync(buf, 0, buf.Length, readTokenSource.Token).AsTask().Wait(); if (BitConverter.IsLittleEndian) { Array.Reverse(buf); } this.SecurityType = (RemoteFramebufferSecurityType)BitConverter.ToUInt32(buf, 0); Console.Error.WriteLine($"Server uses security type {this.SecurityType}"); switch (this.SecurityType) { case RemoteFramebufferSecurityType.Invalid: throw new Exception("Connection failed"); case RemoteFramebufferSecurityType.None: break;// RFB 3.3 straight up jumps to initialization here case RemoteFramebufferSecurityType.VncAuthentication: throw new NotImplementedException("VNC Authentication is not implemented"); default: throw new NotSupportedException("RFB version 3.3 doesn't support the security type returned by the server"); } this.Phase = RfbClientProtocolPhase.HandshakeDone; } } }