protected void Arrange() { _serverEndPoint = new IPEndPoint(IPAddress.Loopback, 8122); _connectionInfo = new ConnectionInfo( _serverEndPoint.Address.ToString(), _serverEndPoint.Port, "user", new PasswordAuthenticationMethod("user", "password")); _connectionInfo.Timeout = TimeSpan.FromMilliseconds(200); _actualException = null; _serviceFactoryMock = new Mock<IServiceFactory>(MockBehavior.Strict); _serverListener = new AsyncSocketListener(_serverEndPoint); _serverListener.Connected += (socket) => { _serverSocket = socket; socket.Send(Encoding.ASCII.GetBytes("\r\n")); socket.Send(Encoding.ASCII.GetBytes("WELCOME banner\r\n")); socket.Send(Encoding.ASCII.GetBytes("SSH-2.0-SshStub\r\n")); }; _serverListener.BytesReceived += (received, socket) => { var badPacket = new byte[] {0x0a, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05}; _serverSocket.Send(badPacket, 0, badPacket.Length, SocketFlags.None); _serverSocket.Shutdown(SocketShutdown.Send); }; _serverListener.Start(); }
public void ConnectShouldSkipLinesBeforeProtocolIdentificationString() { var serverEndPoint = new IPEndPoint(IPAddress.Loopback, 8122); var connectionInfo = CreateConnectionInfo(serverEndPoint, TimeSpan.FromSeconds(5)); using (var serverStub = new AsyncSocketListener(serverEndPoint)) { serverStub.Connected += socket => { socket.Send(Encoding.ASCII.GetBytes("\r\n")); socket.Send(Encoding.ASCII.GetBytes("WELCOME banner\r\n")); socket.Send(Encoding.ASCII.GetBytes("SSH-666-SshStub\r\n")); socket.Shutdown(SocketShutdown.Send); }; serverStub.Start(); using (var session = new Session(connectionInfo, _serviceFactoryMock.Object)) { try { session.Connect(); Assert.Fail(); } catch (SshConnectionException ex) { Assert.IsNull(ex.InnerException); Assert.AreEqual("Server version '666' is not supported.", ex.Message); Assert.AreEqual("SSH-666-SshStub", connectionInfo.ServerVersion); } } } }
public void Start() { _httpRequestParser = new HttpRequestParser(); _listener = new AsyncSocketListener(_endPoint); _listener.BytesReceived += OnBytesReceived; _listener.Start(); }
public void CleanUp() { if (_client != null) { _client.Dispose(); _client = null; } if (_listener != null) { _listener.Stop(); _listener = null; } }
public void CleanUp() { if (_remoteListener != null) { _remoteListener.Stop(); _remoteListener = null; } if (_channelThread != null) { if (_channelThread.IsAlive) _channelThread.Abort(); } }
public void SocketShouldBeClosedAndBindShouldEndWhenForwardedPortSignalsClosingEvent() { _sessionMock.Setup(p => p.IsConnected).Returns(true); _sessionMock.Setup(p => p.SendMessage(It.IsAny<ChannelOpenMessage>())) .Callback<Message>(m => _sessionMock.Raise(p => p.ChannelOpenConfirmationReceived += null, new MessageEventArgs<ChannelOpenConfirmationMessage>( new ChannelOpenConfirmationMessage(((ChannelOpenMessage)m).LocalChannelNumber, _remoteWindowSize, _remotePacketSize, _remoteChannelNumber)))); _sessionMock.Setup(p => p.WaitOnHandle(It.IsAny<EventWaitHandle>())) .Callback<WaitHandle>(p => p.WaitOne(Session.Infinite)); var localPortEndPoint = new IPEndPoint(IPAddress.Loopback, 8122); using (var localPortListener = new AsyncSocketListener(localPortEndPoint)) { localPortListener.Start(); localPortListener.Connected += socket => { var channel = new ChannelDirectTcpip(_sessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize); channel.Open(_remoteHost, _port, _forwardedPortMock.Object, socket); var closeForwardedPortThread = new Thread(() => { // sleep for a short period to allow channel to actually start receiving from socket Thread.Sleep(100); // raise Closing event on forwarded port _forwardedPortMock.Raise(p => p.Closing += null, EventArgs.Empty); }); closeForwardedPortThread.Start(); channel.Bind(); closeForwardedPortThread.Join(); }; var client = new Socket(localPortEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp); client.Connect(localPortEndPoint); // attempt to receive from socket to verify it was shut down by channel var buffer = new byte[16]; var bytesReceived = client.Receive(buffer, 0, buffer.Length, SocketFlags.None); Assert.AreEqual(0, bytesReceived); Assert.IsTrue(client.Connected); // signal to server that we also shut down the socket at our end client.Shutdown(SocketShutdown.Send); } }
public void SocketShouldBeClosedAndEofShouldBeSentToServerWhenClientShutsDownSocket() { _sessionMock.Setup(p => p.IsConnected).Returns(true); _sessionMock.Setup(p => p.SendMessage(It.IsAny<ChannelOpenMessage>())) .Callback<Message>(m => _sessionMock.Raise(p => p.ChannelOpenConfirmationReceived += null, new MessageEventArgs<ChannelOpenConfirmationMessage>( new ChannelOpenConfirmationMessage(((ChannelOpenMessage) m).LocalChannelNumber, _remoteWindowSize, _remotePacketSize, _remoteChannelNumber)))); _sessionMock.Setup(p => p.WaitOnHandle(It.IsAny<EventWaitHandle>())) .Callback<WaitHandle>(p => p.WaitOne(Session.Infinite)); _sessionMock.Setup(p => p.ConnectionInfo).Returns(_connectionInfoMock.Object); _connectionInfoMock.Setup(p => p.Timeout).Returns(TimeSpan.FromSeconds(60)); _sessionMock.Setup(p => p.TrySendMessage(It.IsAny<ChannelEofMessage>())) .Returns(true) .Callback<Message>( m => new Thread(() => { Thread.Sleep(50); _sessionMock.Raise(s => s.ChannelEofReceived += null, new MessageEventArgs<ChannelEofMessage>(new ChannelEofMessage(_localChannelNumber))); }).Start()); _sessionMock.Setup(p => p.TrySendMessage(It.IsAny<ChannelCloseMessage>())) .Returns(true) .Callback<Message>( m => new Thread(() => { Thread.Sleep(50); _sessionMock.Raise(s => s.ChannelCloseReceived += null, new MessageEventArgs<ChannelCloseMessage>(new ChannelCloseMessage(_localChannelNumber))); }).Start()); var channelBindFinishedWaitHandle = new ManualResetEvent(false); Socket handler = null; ChannelDirectTcpip channel = null; var localPortEndPoint = new IPEndPoint(IPAddress.Loopback, 8122); using (var localPortListener = new AsyncSocketListener(localPortEndPoint)) { localPortListener.Start(); localPortListener.Connected += socket => { channel = new ChannelDirectTcpip(_sessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize); channel.Open(_remoteHost, _port, _forwardedPortMock.Object, socket); channel.Bind(); channel.Close(); handler = socket; channelBindFinishedWaitHandle.Set(); }; var client = new Socket(localPortEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp); client.Connect(localPortEndPoint); client.Shutdown(SocketShutdown.Send); Assert.IsFalse(client.Connected); channelBindFinishedWaitHandle.WaitOne(); Assert.IsNotNull(handler); Assert.IsFalse(handler.Connected); _sessionMock.Verify(p => p.TrySendMessage(It.IsAny<ChannelEofMessage>()), Times.Once); _sessionMock.Verify(p => p.TrySendMessage(It.IsAny<ChannelCloseMessage>()), Times.Once); channel.Close(); _sessionMock.Verify(p => p.TrySendMessage(It.IsAny<ChannelEofMessage>()), Times.Once); _sessionMock.Verify(p => p.TrySendMessage(It.IsAny<ChannelCloseMessage>()), Times.Once); } }
protected virtual void Arrange() { Random = new Random(); _serverEndPoint = new IPEndPoint(IPAddress.Loopback, 8122); ConnectionInfo = new ConnectionInfo( _serverEndPoint.Address.ToString(), _serverEndPoint.Port, "user", new PasswordAuthenticationMethod("user", "password")); ConnectionInfo.Timeout = TimeSpan.FromSeconds(20); _keyExchangeAlgorithm = Random.Next().ToString(CultureInfo.InvariantCulture); SessionId = new byte[10]; Random.NextBytes(SessionId); DisconnectedRegister = new List<EventArgs>(); DisconnectReceivedRegister = new List<MessageEventArgs<DisconnectMessage>>(); ErrorOccurredRegister = new List<ExceptionEventArgs>(); ServerBytesReceivedRegister = new List<byte[]>(); _serviceFactoryMock = new Mock<IServiceFactory>(MockBehavior.Strict); _keyExchangeMock = new Mock<IKeyExchange>(MockBehavior.Strict); _clientAuthenticationMock = new Mock<IClientAuthentication>(MockBehavior.Strict); Session = new Session(ConnectionInfo, _serviceFactoryMock.Object); Session.Disconnected += (sender, args) => DisconnectedRegister.Add(args); Session.DisconnectReceived += (sender, args) => DisconnectReceivedRegister.Add(args); Session.ErrorOccured += (sender, args) => ErrorOccurredRegister.Add(args); Session.KeyExchangeInitReceived += (sender, args) => { var newKeysMessage = new NewKeysMessage(); var newKeys = newKeysMessage.GetPacket(8, null); ServerSocket.Send(newKeys, 4, newKeys.Length - 4, SocketFlags.None); }; _serviceFactoryMock.Setup(p => p.CreateKeyExchange(ConnectionInfo.KeyExchangeAlgorithms, new[] { _keyExchangeAlgorithm })).Returns(_keyExchangeMock.Object); _keyExchangeMock.Setup(p => p.Name).Returns(_keyExchangeAlgorithm); _keyExchangeMock.Setup(p => p.Start(Session, It.IsAny<KeyExchangeInitMessage>())); _keyExchangeMock.Setup(p => p.ExchangeHash).Returns(SessionId); _keyExchangeMock.Setup(p => p.CreateServerCipher()).Returns((Cipher) null); _keyExchangeMock.Setup(p => p.CreateClientCipher()).Returns((Cipher) null); _keyExchangeMock.Setup(p => p.CreateServerHash()).Returns((HashAlgorithm) null); _keyExchangeMock.Setup(p => p.CreateClientHash()).Returns((HashAlgorithm) null); _keyExchangeMock.Setup(p => p.CreateCompressor()).Returns((Compressor) null); _keyExchangeMock.Setup(p => p.CreateDecompressor()).Returns((Compressor) null); _keyExchangeMock.Setup(p => p.Dispose()); _serviceFactoryMock.Setup(p => p.CreateClientAuthentication()).Returns(_clientAuthenticationMock.Object); _clientAuthenticationMock.Setup(p => p.Authenticate(ConnectionInfo, Session)); ServerListener = new AsyncSocketListener(_serverEndPoint); ServerListener.Connected += socket => { ServerSocket = socket; socket.Send(Encoding.ASCII.GetBytes("\r\n")); socket.Send(Encoding.ASCII.GetBytes("WELCOME banner\r\n")); socket.Send(Encoding.ASCII.GetBytes("SSH-2.0-SshStub\r\n")); }; var counter = 0; ServerListener.BytesReceived += (received, socket) => { ServerBytesReceivedRegister.Add(received); switch (counter++) { case 0: var keyExchangeInitMessage = new KeyExchangeInitMessage { CompressionAlgorithmsClientToServer = new string[0], CompressionAlgorithmsServerToClient = new string[0], EncryptionAlgorithmsClientToServer = new string[0], EncryptionAlgorithmsServerToClient = new string[0], KeyExchangeAlgorithms = new[] {_keyExchangeAlgorithm}, LanguagesClientToServer = new string[0], LanguagesServerToClient = new string[0], MacAlgorithmsClientToServer = new string[0], MacAlgorithmsServerToClient = new string[0], ServerHostKeyAlgorithms = new string[0] }; var keyExchangeInit = keyExchangeInitMessage.GetPacket(8, null); ServerSocket.Send(keyExchangeInit, 4, keyExchangeInit.Length - 4, SocketFlags.None); break; case 1: var serviceAcceptMessage = ServiceAcceptMessageBuilder.Create(ServiceName.UserAuthentication) .Build(); ServerSocket.Send(serviceAcceptMessage, 0, serviceAcceptMessage.Length, SocketFlags.None); break; } }; ServerListener.Start(); Session.Connect(); }
protected virtual void SetupData() { Random = new Random(); _serverEndPoint = new IPEndPoint(IPAddress.Loopback, 8122); ConnectionInfo = new ConnectionInfo( _serverEndPoint.Address.ToString(), _serverEndPoint.Port, "user", new PasswordAuthenticationMethod("user", "password")) { Timeout = TimeSpan.FromSeconds(20) }; _keyExchangeAlgorithm = Random.Next().ToString(CultureInfo.InvariantCulture); SessionId = new byte[10]; Random.NextBytes(SessionId); DisconnectedRegister = new List<EventArgs>(); DisconnectReceivedRegister = new List<MessageEventArgs<DisconnectMessage>>(); ErrorOccurredRegister = new List<ExceptionEventArgs>(); ServerBytesReceivedRegister = new List<byte[]>(); _disconnectMessage = new DisconnectMessage(DisconnectReason.ServiceNotAvailable, "Not today!"); Session = new Session(ConnectionInfo, _serviceFactoryMock.Object); Session.Disconnected += (sender, args) => DisconnectedRegister.Add(args); Session.DisconnectReceived += (sender, args) => DisconnectReceivedRegister.Add(args); Session.ErrorOccured += (sender, args) => ErrorOccurredRegister.Add(args); Session.KeyExchangeInitReceived += (sender, args) => { var newKeysMessage = new NewKeysMessage(); var newKeys = newKeysMessage.GetPacket(8, null); ServerSocket.Send(newKeys, 4, newKeys.Length - 4, SocketFlags.None); }; ServerListener = new AsyncSocketListener(_serverEndPoint); ServerListener.Connected += socket => { ServerSocket = socket; socket.Send(Encoding.ASCII.GetBytes("\r\n")); socket.Send(Encoding.ASCII.GetBytes("WELCOME banner\r\n")); socket.Send(Encoding.ASCII.GetBytes("SSH-2.0-SshStub\r\n")); }; var counter = 0; ServerListener.BytesReceived += (received, socket) => { ServerBytesReceivedRegister.Add(received); switch (counter++) { case 0: var keyExchangeInitMessage = new KeyExchangeInitMessage { CompressionAlgorithmsClientToServer = new string[0], CompressionAlgorithmsServerToClient = new string[0], EncryptionAlgorithmsClientToServer = new string[0], EncryptionAlgorithmsServerToClient = new string[0], KeyExchangeAlgorithms = new[] { _keyExchangeAlgorithm }, LanguagesClientToServer = new string[0], LanguagesServerToClient = new string[0], MacAlgorithmsClientToServer = new string[0], MacAlgorithmsServerToClient = new string[0], ServerHostKeyAlgorithms = new string[0] }; var keyExchangeInit = keyExchangeInitMessage.GetPacket(8, null); ServerSocket.Send(keyExchangeInit, 4, keyExchangeInit.Length - 4, SocketFlags.None); break; case 1: var serviceAcceptMessage =ServiceAcceptMessageBuilder.Create(ServiceName.UserAuthentication).Build(); ServerSocket.Send(serviceAcceptMessage, 0, serviceAcceptMessage.Length, SocketFlags.None); break; } }; }
public void ConnectShouldSshConnectionExceptionWhenServerResponseDoesNotContainProtocolIdentificationString() { var serverEndPoint = new IPEndPoint(IPAddress.Loopback, 8122); // response ends with CRLF using (var serverStub = new AsyncSocketListener(serverEndPoint)) { serverStub.Connected += socket => { socket.Send(Encoding.ASCII.GetBytes("\r\n")); socket.Send(Encoding.ASCII.GetBytes("WELCOME banner\r\n")); socket.Shutdown(SocketShutdown.Send); }; serverStub.Start(); using (var session = new Session(CreateConnectionInfo(serverEndPoint, TimeSpan.FromSeconds(5)), _serviceFactoryMock.Object)) { try { session.Connect(); Assert.Fail(); } catch (SshConnectionException ex) { Assert.IsNull(ex.InnerException); Assert.AreEqual("Server response does not contain SSH protocol identification.", ex.Message); } } } // response does not end with CRLF using (var serverStub = new AsyncSocketListener(serverEndPoint)) { serverStub.Connected += socket => { socket.Send(Encoding.ASCII.GetBytes("\r\n")); socket.Send(Encoding.ASCII.GetBytes("WELCOME banner")); socket.Shutdown(SocketShutdown.Send); }; serverStub.Start(); using (var session = new Session(CreateConnectionInfo(serverEndPoint, TimeSpan.FromSeconds(5)), _serviceFactoryMock.Object)) { try { session.Connect(); Assert.Fail(); } catch (SshConnectionException ex) { Assert.IsNull(ex.InnerException); Assert.AreEqual("Server response does not contain SSH protocol identification.", ex.Message); } } } // last line is empty using (var serverStub = new AsyncSocketListener(serverEndPoint)) { serverStub.Connected += socket => { socket.Send(Encoding.ASCII.GetBytes("\r\n")); socket.Send(Encoding.ASCII.GetBytes("WELCOME banner\r\n")); socket.Send(Encoding.ASCII.GetBytes("\r\n")); socket.Shutdown(SocketShutdown.Send); }; serverStub.Start(); using (var session = new Session(CreateConnectionInfo(serverEndPoint, TimeSpan.FromSeconds(5)), _serviceFactoryMock.Object)) { try { session.Connect(); Assert.Fail(); } catch (SshConnectionException ex) { Assert.IsNull(ex.InnerException); Assert.AreEqual("Server response does not contain SSH protocol identification.", ex.Message); } } } }
public void ConnectShouldThrowSshOperationExceptionWhenServerDoesNotRespondWithinConnectionTimeout() { var serverEndPoint = new IPEndPoint(IPAddress.Loopback, 8122); var timeout = TimeSpan.FromMilliseconds(500); Socket clientSocket = null; using (var serverStub = new AsyncSocketListener(serverEndPoint)) { serverStub.Connected += socket => { socket.Send(Encoding.ASCII.GetBytes("\r\n")); socket.Send(Encoding.ASCII.GetBytes("WELCOME banner\r\n")); clientSocket = socket; }; serverStub.Start(); using (var session = new Session(CreateConnectionInfo(serverEndPoint, TimeSpan.FromMilliseconds(500)), _serviceFactoryMock.Object)) { try { session.Connect(); Assert.Fail(); } catch (SshOperationTimeoutException ex) { Assert.IsNull(ex.InnerException); Assert.AreEqual(string.Format(CultureInfo.InvariantCulture, "Socket read operation has timed out after {0:F0} milliseconds.", timeout.TotalMilliseconds), ex.Message); Assert.IsNotNull(clientSocket); Assert.IsTrue(clientSocket.Connected); // shut down socket clientSocket.Shutdown(SocketShutdown.Send); } } } }
private void Arrange() { var random = new Random(); _localChannelNumber = (uint) random.Next(0, int.MaxValue); _localWindowSize = (uint) random.Next(2000, 3000); _localPacketSize = (uint) random.Next(1000, 2000); _remoteHost = random.Next().ToString(CultureInfo.InvariantCulture); _port = (uint) random.Next(IPEndPoint.MinPort, IPEndPoint.MaxPort); _channelBindFinishedWaitHandle = new ManualResetEvent(false); _clientReceivedFinishedWaitHandle = new ManualResetEvent(false); _channelException = null; _remoteChannelNumber = (uint)random.Next(0, int.MaxValue); _remoteWindowSize = (uint)random.Next(0, int.MaxValue); _remotePacketSize = (uint)random.Next(100, 200); _sessionMock = new Mock<ISession>(MockBehavior.Strict); _forwardedPortMock = new Mock<IForwardedPort>(MockBehavior.Strict); var sequence = new MockSequence(); _sessionMock.InSequence(sequence).Setup(p => p.IsConnected).Returns(true); _sessionMock.InSequence(sequence) .Setup(p => p.SendMessage(It.Is<ChannelOpenMessage>(m => AssertExpectedMessage(m)))); _sessionMock.InSequence(sequence) .Setup(p => p.WaitOnHandle(It.IsNotNull<WaitHandle>())) .Callback<WaitHandle>( w => { _sessionMock.Raise( s => s.ChannelOpenConfirmationReceived += null, new MessageEventArgs<ChannelOpenConfirmationMessage>( new ChannelOpenConfirmationMessage( _localChannelNumber, _remoteWindowSize, _remotePacketSize, _remoteChannelNumber))); w.WaitOne(); }); _sessionMock.InSequence(sequence).Setup(p => p.IsConnected).Returns(true); _sessionMock.InSequence(sequence) .Setup( p => p.TrySendMessage(It.Is<ChannelEofMessage>(m => m.LocalChannelNumber == _remoteChannelNumber))) .Returns(true); _sessionMock.InSequence(sequence).Setup(p => p.IsConnected).Returns(true); _sessionMock.InSequence(sequence) .Setup( p => p.TrySendMessage(It.Is<ChannelCloseMessage>(m => m.LocalChannelNumber == _remoteChannelNumber))) .Returns(true); _sessionMock.InSequence(sequence) .Setup(p => p.WaitOnHandle(It.IsNotNull<WaitHandle>())) .Callback<WaitHandle>( w => { _sessionMock.Raise( s => s.ChannelCloseReceived += null, new MessageEventArgs<ChannelCloseMessage>(new ChannelCloseMessage(_localChannelNumber))); w.WaitOne(); }); var localEndpoint = new IPEndPoint(IPAddress.Loopback, 8122); _listener = new AsyncSocketListener(localEndpoint); _listener.Connected += socket => { try { _channel = new ChannelDirectTcpip( _sessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize); _channel.Open(_remoteHost, _port, _forwardedPortMock.Object, socket); _channel.Bind(); } catch (Exception ex) { _channelException = ex; } finally { _channelBindFinishedWaitHandle.Set(); } }; _listener.Start(); _client = new Socket(localEndpoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp); _client.Connect(localEndpoint); var clientReceiveThread = new Thread( () => { var buffer = new byte[16]; var bytesReceived = _client.Receive(buffer, 0, buffer.Length, SocketFlags.None); if (bytesReceived == 0) { _client.Shutdown(SocketShutdown.Send); _clientReceivedFinishedWaitHandle.Set(); } } ); clientReceiveThread.Start(); // give channel time to bind to socket Thread.Sleep(200); }
private void Arrange() { var random = new Random(); _localChannelNumber = (uint) random.Next(0, int.MaxValue); _localWindowSize = (uint) random.Next(2000, 3000); _localPacketSize = (uint) random.Next(1000, 2000); _remoteChannelNumber = (uint) random.Next(0, int.MaxValue); _remoteWindowSize = (uint) random.Next(0, int.MaxValue); _remotePacketSize = (uint) random.Next(100, 200); _channelBindFinishedWaitHandle = new ManualResetEvent(false); _channelException = null; _connectedRegister = new List<Socket>(); _disconnectedRegister = new List<Socket>(); _connectionInfoTimeout = TimeSpan.FromSeconds(5); _remoteEndpoint = new IPEndPoint(IPAddress.Loopback, 8122); _sessionMock = new Mock<ISession>(MockBehavior.Strict); _connectionInfoMock = new Mock<IConnectionInfo>(MockBehavior.Strict); _forwardedPortMock = new Mock<IForwardedPort>(MockBehavior.Strict); var sequence = new MockSequence(); _sessionMock.InSequence(sequence).Setup(p => p.IsConnected).Returns(true); _sessionMock.InSequence(sequence).Setup(p => p.ConnectionInfo).Returns(_connectionInfoMock.Object); _connectionInfoMock.InSequence(sequence).Setup(p => p.Timeout).Returns(_connectionInfoTimeout); _sessionMock.InSequence(sequence).Setup( p => p.SendMessage( It.Is<ChannelOpenConfirmationMessage>( m => m.LocalChannelNumber == _remoteChannelNumber && m.InitialWindowSize == _localWindowSize && m.MaximumPacketSize == _localPacketSize && m.RemoteChannelNumber == _localChannelNumber) )); _sessionMock.InSequence(sequence).Setup(p => p.IsConnected).Returns(true); _sessionMock.InSequence(sequence) .Setup( p => p.TrySendMessage(It.Is<ChannelEofMessage>(m => m.LocalChannelNumber == _remoteChannelNumber))) .Returns(true); _sessionMock.InSequence(sequence).Setup(p => p.IsConnected).Returns(true); _sessionMock.InSequence(sequence) .Setup( p => p.TrySendMessage(It.Is<ChannelCloseMessage>(m => m.LocalChannelNumber == _remoteChannelNumber))) .Returns(true); _sessionMock.InSequence(sequence) .Setup(p => p.WaitOnHandle(It.IsNotNull<WaitHandle>())) .Callback<WaitHandle>( w => { _sessionMock.Raise( s => s.ChannelCloseReceived += null, new MessageEventArgs<ChannelCloseMessage>(new ChannelCloseMessage(_localChannelNumber))); w.WaitOne(); }); _remoteListener = new AsyncSocketListener(_remoteEndpoint); _remoteListener.Connected += socket => _connectedRegister.Add(socket); _remoteListener.Disconnected += socket => _disconnectedRegister.Add(socket); _remoteListener.Start(); _channel = new ChannelForwardedTcpip( _sessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize, _remoteChannelNumber, _remoteWindowSize, _remotePacketSize); _channelThread = new Thread(() => { try { _channel.Bind(_remoteEndpoint, _forwardedPortMock.Object); } catch (Exception ex) { _channelException = ex; } finally { _channelBindFinishedWaitHandle.Set(); } }); _channelThread.Start(); // give channel time to bind to remote endpoint Thread.Sleep(100); }