using System; namespace ScreenConnect; public abstract class NetworkConnection : IDisposable { protected BlockBufferReadStream ReadStream { get; } protected BlockBufferWriteStream WriteStream { get; } public BinaryReader Reader { get; } public BinaryWriter Writer { get; } public bool IsChannelSecure { get; private set; } public NetworkConnection() { ReadStream = new BlockBufferReadStream(delegate(BlockBufferReadStream stream) { ArraySegment buffer = GetBuffer(stream); int count = Receive(buffer); stream.SetBuffer(buffer.Array, 0, count); }); WriteStream = new BlockBufferWriteStream(delegate(BlockBufferWriteStream stream) { if (stream.BufferCompletedCount != 0) { Send(stream.GetBufferCompletedSegment()); } ArraySegment buffer = GetBuffer(stream); stream.SetBuffer(buffer); }); Reader = new BinaryReader(ReadStream); Writer = new BinaryWriter(WriteStream); } private static ArraySegment GetBuffer(BlockBufferStream stream) { if (stream.GetBufferFullSegment().Count == 0) { return Extensions.CreateArraySegment(2912); } return stream.GetBufferFullSegment(); } protected abstract int Receive(ArraySegment buffer); protected abstract void Send(ArraySegment buffer); public abstract void Dispose(); public virtual void GetLocalAddresses(ref byte[] ipAddressBytes, ref byte[] macAddressBytes) { ipAddressBytes = null; macAddressBytes = null; } public void SkipAvailableUntilNonZero() { ReadStream.SkipAvailableUntilNonZero(); } public int GetUnflushedByteCount() { return WriteStream.GetUnflushedByteCount(); } public void WriteZerosAndFlush() { WriteStream.WriteZerosForFlush(); WriteStream.Flush(); } public void StartSecureChannel(byte[] secretKey, byte[] clientRandom, byte[] serverRandom) { Extensions.DeriveSecureRandomValuesForConnection(secretKey, clientRandom, serverRandom, out var clientWriteKey, out var serverWriteKey, out var clientWriteInitializationVector, out var serverWriteInitializationVector); ReadStream.StartSecureChannel(serverWriteKey, serverWriteInitializationVector); WriteStream.StartSecureChannel(clientWriteKey, clientWriteInitializationVector); IsChannelSecure = true; } }