/// <summary> /// Authenticates the specified session. /// </summary> /// <param name="session">The session to authenticate.</param> /// <returns>Result of authentication process.</returns> public override AuthenticationResult Authenticate(Session session) { _session = session; session.UserAuthenticationSuccessReceived += Session_UserAuthenticationSuccessReceived; session.UserAuthenticationFailureReceived += Session_UserAuthenticationFailureReceived; session.UserAuthenticationInformationRequestReceived += Session_UserAuthenticationInformationRequestReceived; session.RegisterMessage("SSH_MSG_USERAUTH_INFO_REQUEST"); try { session.SendMessage(_requestMessage); session.WaitOnHandle(_authenticationCompleted); } finally { session.UnRegisterMessage("SSH_MSG_USERAUTH_INFO_REQUEST"); session.UserAuthenticationSuccessReceived -= Session_UserAuthenticationSuccessReceived; session.UserAuthenticationFailureReceived -= Session_UserAuthenticationFailureReceived; session.UserAuthenticationInformationRequestReceived -= Session_UserAuthenticationInformationRequestReceived; } if (_exception != null) throw _exception; return _authenticationResult; }
/// <summary> /// Authenticates the specified session. /// </summary> /// <param name="session">The session to authenticate.</param> /// <returns> /// Result of authentication process. /// </returns> /// <exception cref="System.ArgumentNullException"><paramref name="session" /> is null.</exception> public override AuthenticationResult Authenticate(Session session) { if (session == null) throw new ArgumentNullException("session"); _session = session; session.UserAuthenticationSuccessReceived += Session_UserAuthenticationSuccessReceived; session.UserAuthenticationFailureReceived += Session_UserAuthenticationFailureReceived; session.MessageReceived += Session_MessageReceived; try { session.RegisterMessage("SSH_MSG_USERAUTH_PASSWD_CHANGEREQ"); session.SendMessage(_requestMessage); session.WaitOnHandle(_authenticationCompleted); } finally { session.UserAuthenticationSuccessReceived -= Session_UserAuthenticationSuccessReceived; session.UserAuthenticationFailureReceived -= Session_UserAuthenticationFailureReceived; session.MessageReceived -= Session_MessageReceived; } if (_exception != null) throw _exception; return _authenticationResult; }
internal ShellStream(Session session, string terminalName, uint columns, uint rows, uint width, uint height, int maxLines, PrivateKeyAgent forwardedPrivateKeyAgent, params KeyValuePair<TerminalModes, uint>[] terminalModeValues) { this._encoding = new Renci.SshNet.Common.ASCIIEncoding(); this._session = session; this._incoming = new Queue<byte>(); this._outgoing = new Queue<byte>(); this._channel = this._session.CreateChannel<ChannelSession>(); this._channel.DataReceived += new EventHandler<ChannelDataEventArgs>(Channel_DataReceived); this._channel.Closed += new EventHandler<ChannelEventArgs>(Channel_Closed); this._session.Disconnected += new EventHandler<EventArgs>(Session_Disconnected); this._session.ErrorOccured += new EventHandler<ExceptionEventArgs>(Session_ErrorOccured); this.forwardedPrivateKeyAgent = forwardedPrivateKeyAgent; this._channel.Open(); if (this.forwardedPrivateKeyAgent != null) { if (this._channel.SendPrivateKeyAgentForwardingRequest()) { this._session.RegisterMessage("SSH_MSG_CHANNEL_OPEN"); this._session.ChannelOpenReceived += OnChannelOpen; } } this._channel.SendPseudoTerminalRequest(terminalName, columns, rows, width, height, terminalModeValues); this._channel.SendShellRequest(); }
/// <summary> /// Authenticates the specified session. /// </summary> /// <param name="session">The session to authenticate.</param> /// <returns>Result of authentication process.</returns> public override AuthenticationResult Authenticate(Session session) { this._session = session; session.UserAuthenticationSuccessReceived += Session_UserAuthenticationSuccessReceived; session.UserAuthenticationFailureReceived += Session_UserAuthenticationFailureReceived; session.MessageReceived += Session_MessageReceived; session.RegisterMessage("SSH_MSG_USERAUTH_INFO_REQUEST"); session.SendMessage(this._requestMessage); session.WaitOnHandle(this._authenticationCompleted); session.UnRegisterMessage("SSH_MSG_USERAUTH_INFO_REQUEST"); session.UserAuthenticationSuccessReceived -= Session_UserAuthenticationSuccessReceived; session.UserAuthenticationFailureReceived -= Session_UserAuthenticationFailureReceived; session.MessageReceived -= Session_MessageReceived; if (this._exception != null) { throw this._exception; } return this._authenticationResult; }
/// <summary> /// Authenticates the specified session. /// </summary> /// <param name="session">The session to authenticate.</param> /// <returns> /// Result of authentication process. /// </returns> /// <exception cref="System.ArgumentNullException"><paramref name="session" /> is null.</exception> public override AuthenticationResult Authenticate(Session session) { if (session == null) throw new ArgumentNullException("session"); this._session = session; session.UserAuthenticationSuccessReceived += Session_UserAuthenticationSuccessReceived; session.UserAuthenticationFailureReceived += Session_UserAuthenticationFailureReceived; session.MessageReceived += Session_MessageReceived; session.RegisterMessage("SSH_MSG_USERAUTH_PASSWD_CHANGEREQ"); session.SendMessage(this._requestMessage); session.WaitHandle(this._authenticationCompleted); session.UserAuthenticationSuccessReceived -= Session_UserAuthenticationSuccessReceived; session.UserAuthenticationFailureReceived -= Session_UserAuthenticationFailureReceived; session.MessageReceived -= Session_MessageReceived; if (this._exception != null) { throw this._exception; } return this._authenticationResult; }
/// <summary> /// Authenticates the specified session. /// </summary> /// <param name="session">The session to authenticate.</param> /// <returns> /// Result of authentication process. /// </returns> public override AuthenticationResult Authenticate(Session session) { session.UserAuthenticationSuccessReceived += Session_UserAuthenticationSuccessReceived; session.UserAuthenticationFailureReceived += Session_UserAuthenticationFailureReceived; session.MessageReceived += Session_MessageReceived; session.RegisterMessage("SSH_MSG_USERAUTH_PK_OK"); foreach (var keyFile in KeyFiles) { _authenticationCompleted.Reset(); _isSignatureRequired = false; var message = new RequestMessagePublicKey(ServiceName.Connection, Username, keyFile.HostKey.Name, keyFile.HostKey.Data); if (KeyFiles.Count < 2) { // If only one key file provided then send signature for very first request var signatureData = new SignatureData(message, session.SessionId).GetBytes(); message.Signature = keyFile.HostKey.Sign(signatureData); } // Send public key authentication request session.SendMessage(message); session.WaitOnHandle(_authenticationCompleted); if (_isSignatureRequired) { _authenticationCompleted.Reset(); var signatureMessage = new RequestMessagePublicKey(ServiceName.Connection, Username, keyFile.HostKey.Name, keyFile.HostKey.Data); var signatureData = new SignatureData(message, session.SessionId).GetBytes(); signatureMessage.Signature = keyFile.HostKey.Sign(signatureData); // Send public key authentication request with signature session.SendMessage(signatureMessage); } session.WaitOnHandle(_authenticationCompleted); if (_authenticationResult == AuthenticationResult.Success) { break; } } session.UserAuthenticationSuccessReceived -= Session_UserAuthenticationSuccessReceived; session.UserAuthenticationFailureReceived -= Session_UserAuthenticationFailureReceived; session.MessageReceived -= Session_MessageReceived; session.UnRegisterMessage("SSH_MSG_USERAUTH_PK_OK"); return _authenticationResult; }
/// <summary> /// Authenticates the specified session. /// </summary> /// <param name="session">The session to authenticate.</param> /// <returns></returns> public override AuthenticationResult Authenticate(Session session) { if (this.Protocol == null) return AuthenticationResult.Failure; session.UserAuthenticationSuccessReceived += Session_UserAuthenticationSuccessReceived; session.UserAuthenticationFailureReceived += Session_UserAuthenticationFailureReceived; session.MessageReceived += Session_MessageReceived; session.RegisterMessage("SSH_MSG_USERAUTH_PK_OK"); foreach (var identity in this.Protocol.GetIdentities()) { this._authenticationCompleted.Reset(); this._isSignatureRequired = false; var message = new RequestMessagePublicKey(ServiceName.Connection, this.Username, identity.Type, identity.Blob); // Send public key authentication request session.SendMessage(message); session.WaitOnHandle(this._authenticationCompleted); if (this._isSignatureRequired) { this._authenticationCompleted.Reset(); var signatureMessage = new RequestMessagePublicKey(ServiceName.Connection, this.Username, identity.Type, identity.Blob); var signatureData = new SignatureData(message, session.SessionId).GetBytes(); signatureMessage.Signature = this.Protocol.SignData(identity, signatureData); // Send public key authentication request with signature session.SendMessage(signatureMessage); } session.WaitOnHandle(this._authenticationCompleted); if (this._authenticationResult == AuthenticationResult.Success) { break; } } session.UserAuthenticationSuccessReceived -= Session_UserAuthenticationSuccessReceived; session.UserAuthenticationFailureReceived -= Session_UserAuthenticationFailureReceived; session.MessageReceived -= Session_MessageReceived; session.UnRegisterMessage("SSH_MSG_USERAUTH_PK_OK"); return this._authenticationResult; }
/// <summary> /// Initializes a new instance of the <see cref="SshCommand"/> class. /// </summary> /// <param name="session">The session.</param> /// <param name="commandText">The command text.</param> /// <param name="encoding">The encoding.</param> internal SshCommand(Session session, string commandText, Encoding encoding) { if (session == null) throw new ArgumentNullException("session"); this._encoding = encoding; this._session = session; this.CommandText = commandText; this.CommandTimeout = new TimeSpan(0, 0, 0, 0, -1); this._session.Disconnected += Session_Disconnected; this._session.ErrorOccured += Session_ErrorOccured; }
/// <summary> /// Authenticates the specified session. /// </summary> /// <param name="session">The session.</param> /// <returns></returns> public override AuthenticationResult Authenticate(Session session) { session.UserAuthenticationSuccessReceived += Session_UserAuthenticationSuccessReceived; session.UserAuthenticationFailureReceived += Session_UserAuthenticationFailureReceived; session.SendMessage(new RequestMessageNone(ServiceName.Connection, this.Username)); session.WaitHandle(this._authenticationCompleted); session.UserAuthenticationSuccessReceived -= Session_UserAuthenticationSuccessReceived; session.UserAuthenticationFailureReceived -= Session_UserAuthenticationFailureReceived; return this._authenticationResult; }
/// <summary> /// Initializes a new instance of the <see cref="Shell"/> class. /// </summary> /// <param name="session">The session.</param> /// <param name="input">The input.</param> /// <param name="output">The output.</param> /// <param name="extendedOutput">The extended output.</param> /// <param name="terminalName">Name of the terminal.</param> /// <param name="columns">The columns.</param> /// <param name="rows">The rows.</param> /// <param name="width">The width.</param> /// <param name="height">The height.</param> /// <param name="terminalMode">The terminal mode.</param> /// <param name="bufferSize">Size of the buffer for output stream.</param> internal Shell(Session session, Stream input, Stream output, Stream extendedOutput, string terminalName, uint columns, uint rows, uint width, uint height, string terminalMode, int bufferSize) { this._session = session; this._input = input; this._outputStream = output; this._extendedOutputStream = extendedOutput; this._terminalName = terminalName; this._columns = columns; this._rows = rows; this._width = width; this._height = height; this._terminalMode = terminalMode; this._bufferSize = bufferSize; }
/// <summary> /// Authenticates the specified session. /// </summary> /// <param name="session">The session.</param> /// <returns> /// Result of authentication process. /// </returns> /// <exception cref="System.ArgumentNullException"><paramref name="session" /> is null.</exception> public override AuthenticationResult Authenticate(Session session) { if (session == null) throw new ArgumentNullException("session"); session.UserAuthenticationSuccessReceived += Session_UserAuthenticationSuccessReceived; session.UserAuthenticationFailureReceived += Session_UserAuthenticationFailureReceived; session.SendMessage(new RequestMessageNone(ServiceName.Connection, this.Username)); session.WaitOnHandle(this._authenticationCompleted); session.UserAuthenticationSuccessReceived -= Session_UserAuthenticationSuccessReceived; session.UserAuthenticationFailureReceived -= Session_UserAuthenticationFailureReceived; return this._authenticationResult; }
internal ShellStream(Session session, string terminalName, uint columns, uint rows, uint width, uint height, int maxLines, IDictionary<TerminalModes, uint> terminalModeValues) { this._encoding = session.ConnectionInfo.Encoding; this._session = session; this._incoming = new Queue<byte>(); this._outgoing = new Queue<byte>(); this._channel = this._session.CreateChannel<ChannelSession>(); this._channel.DataReceived += new EventHandler<ChannelDataEventArgs>(Channel_DataReceived); this._channel.Closed += new EventHandler<ChannelEventArgs>(Channel_Closed); this._session.Disconnected += new EventHandler<EventArgs>(Session_Disconnected); this._session.ErrorOccured += new EventHandler<ExceptionEventArgs>(Session_ErrorOccured); this._channel.Open(); this._channel.SendPseudoTerminalRequest(terminalName, columns, rows, width, height, terminalModeValues); this._channel.SendShellRequest(); }
private bool TryAuthenticate(Session session, IList<string> allowedAuthenticationMethods, IList<AuthenticationMethod> failedAuthenticationMethods, ref SshAuthenticationException authenticationException) { if (!allowedAuthenticationMethods.Any()) { authenticationException = new SshAuthenticationException("No authentication methods defined on SSH server."); return false; } // we want to try authentication methods in the order in which they were // passed in the ctor, not the order in which the SSH server returns // the allowed authentication methods var matchingAuthenticationMethods = AuthenticationMethods.Where(a => allowedAuthenticationMethods.Contains(a.Name)).ToList(); if (!matchingAuthenticationMethods.Any()) { authenticationException = new SshAuthenticationException(string.Format("No suitable authentication method found to complete authentication ({0}).", string.Join(",", allowedAuthenticationMethods.ToArray()))); return false; } foreach (var authenticationMethod in matchingAuthenticationMethods) { if (failedAuthenticationMethods.Contains(authenticationMethod)) continue; var authenticationResult = authenticationMethod.Authenticate(session); switch (authenticationResult) { case AuthenticationResult.PartialSuccess: if (TryAuthenticate(session, authenticationMethod.AllowedAuthentications.ToList(), failedAuthenticationMethods, ref authenticationException)) authenticationResult = AuthenticationResult.Success; break; case AuthenticationResult.Failure: failedAuthenticationMethods.Add(authenticationMethod); authenticationException = new SshAuthenticationException(string.Format("Permission denied ({0}).", authenticationMethod.Name)); break; case AuthenticationResult.Success: authenticationException = null; break; } if (authenticationResult == AuthenticationResult.Success) return true; } return false; }
/// <summary> /// Authenticates the specified session. /// </summary> /// <param name="session">The session to be authenticated.</param> /// <exception cref="ArgumentNullException"><paramref name="session"/> is null.</exception> /// <exception cref="SshAuthenticationException">No suitable authentication method found to complete authentication, or permission denied.</exception> public void Authenticate(Session session) { if (session == null) throw new ArgumentNullException("session"); session.RegisterMessage("SSH_MSG_USERAUTH_FAILURE"); session.RegisterMessage("SSH_MSG_USERAUTH_SUCCESS"); session.RegisterMessage("SSH_MSG_USERAUTH_BANNER"); session.UserAuthenticationBannerReceived += Session_UserAuthenticationBannerReceived; try { // the exception to report an authentication failure with SshAuthenticationException authenticationException = null; // try to authenticate against none var noneAuthenticationMethod = new NoneAuthenticationMethod(this.Username); var authenticated = noneAuthenticationMethod.Authenticate(session); if (authenticated != AuthenticationResult.Success) { var failedAuthenticationMethods = new List<AuthenticationMethod>(); if (TryAuthenticate(session, noneAuthenticationMethod.AllowedAuthentications.ToList(), failedAuthenticationMethods, ref authenticationException)) { authenticated = AuthenticationResult.Success; } } this.IsAuthenticated = authenticated == AuthenticationResult.Success; if (!IsAuthenticated) throw authenticationException; } finally { session.UserAuthenticationBannerReceived -= Session_UserAuthenticationBannerReceived; session.UnRegisterMessage("SSH_MSG_USERAUTH_FAILURE"); session.UnRegisterMessage("SSH_MSG_USERAUTH_SUCCESS"); session.UnRegisterMessage("SSH_MSG_USERAUTH_BANNER"); } }
/// <summary> /// Authenticates the specified session. /// </summary> /// <param name="session">The session to be authenticated.</param> /// <returns>true if authenticated; otherwise false.</returns> /// <exception cref="ArgumentNullException"><paramref name="session"/> is null.</exception> public bool Authenticate(Session session) { if (session == null) throw new ArgumentNullException("session"); this.Session = session; this.Session.RegisterMessage("SSH_MSG_USERAUTH_FAILURE"); this.Session.RegisterMessage("SSH_MSG_USERAUTH_SUCCESS"); this.Session.RegisterMessage("SSH_MSG_USERAUTH_BANNER"); this.Session.UserAuthenticationFailureReceived += Session_UserAuthenticationFailureReceived; this.Session.UserAuthenticationSuccessReceived += Session_UserAuthenticationSuccessMessageReceived; this.Session.UserAuthenticationBannerReceived += Session_UserAuthenticationBannerMessageReceived; this.Session.MessageReceived += Session_MessageReceived; this.OnAuthenticate(); this.Session.UserAuthenticationFailureReceived -= Session_UserAuthenticationFailureReceived; this.Session.UserAuthenticationSuccessReceived -= Session_UserAuthenticationSuccessMessageReceived; this.Session.UserAuthenticationBannerReceived -= Session_UserAuthenticationBannerMessageReceived; this.Session.MessageReceived -= Session_MessageReceived; this.Session.UnRegisterMessage("SSH_MSG_USERAUTH_FAILURE"); this.Session.UnRegisterMessage("SSH_MSG_USERAUTH_SUCCESS"); this.Session.UnRegisterMessage("SSH_MSG_USERAUTH_BANNER"); return this.IsAuthenticated; }
/// <summary> /// Authenticates the specified session. /// </summary> /// <param name="session">The session to authenticate.</param> /// <returns></returns> public abstract AuthenticationResult Authenticate(Session session);
/// <summary> /// Authenticates the specified session. /// </summary> /// <param name="session">The session to authenticate.</param> /// <returns></returns> public override AuthenticationResult Authenticate(Session session) { if (this.PrivateKeyAgent.Value == null) return AuthenticationResult.Failure; session.UserAuthenticationSuccessReceived += Session_UserAuthenticationSuccessReceived; session.UserAuthenticationFailureReceived += Session_UserAuthenticationFailureReceived; session.MessageReceived += Session_MessageReceived; session.RegisterMessage("SSH_MSG_USERAUTH_PK_OK"); foreach (var keyInfo in this.PrivateKeyAgent.Value.ListSsh2()) { var key = keyInfo.Key; this._authenticationCompleted.Reset(); this._isSignatureRequired = false; var message = new RequestMessagePublicKey(ServiceName.Connection, this.Username, key.Name, key.Data); // Send public key authentication request session.SendMessage(message); session.WaitHandle(this._authenticationCompleted); if (this._isSignatureRequired) { this._authenticationCompleted.Reset(); var signatureMessage = new RequestMessagePublicKey(ServiceName.Connection, this.Username, key.Name, key.Data); var signatureData = new SignatureData(message, session.SessionId).GetBytes(); var signature = this.PrivateKeyAgent.Value.SignSsh2(key.Data, signatureData); if (signature != null) { signatureMessage.Signature = signature; // Send public key authentication request with signature session.SendMessage(signatureMessage); } else { this._authenticationResult = AuthenticationResult.Failure; this._authenticationCompleted.Set(); } } session.WaitHandle(this._authenticationCompleted); if (this._authenticationResult == AuthenticationResult.Success) { break; } } session.UserAuthenticationSuccessReceived -= Session_UserAuthenticationSuccessReceived; session.UserAuthenticationFailureReceived -= Session_UserAuthenticationFailureReceived; session.MessageReceived -= Session_MessageReceived; session.UnRegisterMessage("SSH_MSG_USERAUTH_PK_OK"); return this._authenticationResult; }
/// <summary> /// Connects client to the server. /// </summary> public void Connect() { this.OnConnecting(); if (this.IsConnected) { this.Session.Disconnect(); } this.Session = new Session(this.ConnectionInfo); this.Session.HostKeyReceived += Session_HostKeyReceived; this.Session.ErrorOccured += Session_ErrorOccured; this.Session.Connect(); this.OnConnected(); }
/// <summary> /// Releases unmanaged and - optionally - managed resources /// </summary> /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged ResourceMessages.</param> protected virtual void Dispose(bool disposing) { // Check to see if Dispose has already been called. if (!this._isDisposed) { // If disposing equals true, dispose all managed // and unmanaged ResourceMessages. if (disposing) { // stop sending keep-alive messages before we close the // session StopKeepAliveTimer(); if (this.Session != null) { this.Session.ErrorOccured -= Session_ErrorOccured; this.Session.HostKeyReceived -= Session_HostKeyReceived; this.Session.Dispose(); this.Session = null; } if (_ownsConnectionInfo && _connectionInfo != null) { var connectionInfoDisposable = _connectionInfo as IDisposable; if (connectionInfoDisposable != null) connectionInfoDisposable.Dispose(); _connectionInfo = null; } } // Note disposing has been done. _isDisposed = true; } }
/// <summary> /// Connects client to the server. /// </summary> /// <exception cref="InvalidOperationException">The client is already connected.</exception> /// <exception cref="ObjectDisposedException">The method was called after the client was disposed.</exception> public void Connect() { CheckDisposed(); if (Session != null && Session.IsConnected) throw new InvalidOperationException("The client is already connected."); OnConnecting(); Session = new Session(ConnectionInfo); Session.HostKeyReceived += Session_HostKeyReceived; Session.ErrorOccured += Session_ErrorOccured; Session.Connect(); StartKeepAliveTimer(); OnConnected(); }
/// <summary> /// Authenticates the specified session. /// </summary> /// <param name="session">The session to be authenticated.</param> /// <returns>true if authenticated; otherwise false.</returns> /// <exception cref="ArgumentNullException"><paramref name="session"/> is null.</exception> /// <exception cref="SshAuthenticationException">No suitable authentication method found to complete authentication.</exception> public bool Authenticate(Session session) { var authenticated = AuthenticationResult.Failure; if (session == null) throw new ArgumentNullException("session"); session.RegisterMessage("SSH_MSG_USERAUTH_FAILURE"); session.RegisterMessage("SSH_MSG_USERAUTH_SUCCESS"); session.RegisterMessage("SSH_MSG_USERAUTH_BANNER"); session.UserAuthenticationBannerReceived += Session_UserAuthenticationBannerReceived; // Try to authenticate against none var noneAuthenticationMethod = new NoneAuthenticationMethod(this.Username); authenticated = noneAuthenticationMethod.Authenticate(session); var allowedAuthentications = noneAuthenticationMethod.AllowedAuthentications; var triedAuthentications = new List<string>(); while (authenticated != AuthenticationResult.Success) { // Find first authentication method var method = this.AuthenticationMethods.Where((a) => allowedAuthentications.Contains(a.Name) && !triedAuthentications.Contains(a.Name)).FirstOrDefault(); if (method == null) throw new SshAuthenticationException("No suitable authentication method found to complete authentication."); triedAuthentications.Add(method.Name); authenticated = method.Authenticate(session); if (authenticated == AuthenticationResult.PartialSuccess) { // If further authentication is required then continue to try another method allowedAuthentications = method.AllowedAuthentications; continue; } // If authentication was successful or failure, exit break; } session.UserAuthenticationBannerReceived -= Session_UserAuthenticationBannerReceived; session.UnRegisterMessage("SSH_MSG_USERAUTH_FAILURE"); session.UnRegisterMessage("SSH_MSG_USERAUTH_SUCCESS"); session.UnRegisterMessage("SSH_MSG_USERAUTH_BANNER"); this.IsAuthenticated = authenticated == AuthenticationResult.Success; return authenticated == AuthenticationResult.Success; }
/// <summary> /// Releases unmanaged and - optionally - managed resources /// </summary> /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged ResourceMessages.</param> protected virtual void Dispose(bool disposing) { // Check to see if Dispose has already been called. if (!this._isDisposed) { // If disposing equals true, dispose all managed // and unmanaged ResourceMessages. if (disposing) { // Dispose managed ResourceMessages. this.Session.ErrorOccured -= Session_ErrorOccured; this.Session.HostKeyReceived -= Session_HostKeyReceived; if (this.Session != null) { this.Session.Dispose(); this.Session = null; } if (this._keepAliveTimer != null) { this._keepAliveTimer.Dispose(); this._keepAliveTimer = null; } } // Note disposing has been done. _isDisposed = true; } }