mirror of
https://github.com/sshnet/SSH.NET.git
synced 2026-10-18 14:36:11 +08:00
Add ErrorOccured to BaseClient to allow catching of exceptions that happened on the other thread
Fix SymbolicLink method Minor changes
This commit is contained in:
@@ -1,8 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Renci.SshClient.Security;
|
||||
using Renci.SshClient.Tests.Properties;
|
||||
|
||||
@@ -68,6 +64,18 @@ namespace Renci.SshClient.Tests.Security
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Add test to test re-keying
|
||||
[TestMethod]
|
||||
public void Test_KeyExchange_Rekeying()
|
||||
{
|
||||
var connectionInfo = new PasswordConnectionInfo(Resources.HOST, 22, Resources.USERNAME, Resources.PASSWORD);
|
||||
|
||||
using (var client = new SshClient(connectionInfo))
|
||||
{
|
||||
client.Connect();
|
||||
// TODO: Add test to test re-keying
|
||||
Assert.Inconclusive();
|
||||
client.Disconnect();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using Renci.SshClient.Common;
|
||||
|
||||
@@ -68,6 +69,11 @@ namespace Renci.SshClient
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when an error occurred.
|
||||
/// </summary>
|
||||
public event EventHandler<ErrorEventArgs> ErrorOccurred;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="BaseClient"/> class.
|
||||
/// </summary>
|
||||
@@ -92,6 +98,7 @@ namespace Renci.SshClient
|
||||
|
||||
this.Session = new Session(this.ConnectionInfo);
|
||||
this.Session.Connect();
|
||||
this.Session.ErrorOccured += Session_ErrorOccured;
|
||||
|
||||
this.OnConnected();
|
||||
}
|
||||
@@ -164,12 +171,20 @@ namespace Renci.SshClient
|
||||
throw new SshConnectionException("Client not connected.");
|
||||
}
|
||||
|
||||
private void Session_ErrorOccured(object sender, System.IO.ErrorEventArgs e)
|
||||
{
|
||||
if (this.ErrorOccurred != null)
|
||||
{
|
||||
this.ErrorOccurred(this, e);
|
||||
}
|
||||
}
|
||||
|
||||
#region IDisposable Members
|
||||
|
||||
private bool _isDisposed = false;
|
||||
|
||||
/// <summary>
|
||||
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
|
||||
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged ResourceMessages.
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
@@ -181,17 +196,19 @@ namespace Renci.SshClient
|
||||
/// <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 resources.</param>
|
||||
/// <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 resources.
|
||||
// and unmanaged ResourceMessages.
|
||||
if (disposing)
|
||||
{
|
||||
// Dispose managed resources.
|
||||
// Dispose managed ResourceMessages.
|
||||
this.Session.ErrorOccured -= Session_ErrorOccured;
|
||||
|
||||
if (this.Session != null)
|
||||
{
|
||||
this.Session.Dispose();
|
||||
@@ -202,7 +219,6 @@ namespace Renci.SshClient
|
||||
this._keepAliveTimer.Dispose();
|
||||
this._keepAliveTimer = null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Note disposing has been done.
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace Renci.SshClient
|
||||
/// Gets or sets the command that async result was created for.
|
||||
/// </summary>
|
||||
/// <value>The channel.</value>
|
||||
internal SshCommand Command { get; private set; }
|
||||
private SshCommand _command;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the bytes received. If SFTP only file bytes are counted.
|
||||
@@ -60,7 +60,20 @@ namespace Renci.SshClient
|
||||
/// <param name="command">The command.</param>
|
||||
internal CommandAsyncResult(SshCommand command)
|
||||
{
|
||||
this.Command = command;
|
||||
this._command = command;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validates that command object is valid to be used with this instance.
|
||||
/// </summary>
|
||||
/// <param name="command">The command.</param>
|
||||
public void ValidateCommand(SshCommand command)
|
||||
{
|
||||
if (this._command != command)
|
||||
{
|
||||
throw new InvalidOperationException("Invalid IAsyncResult parameter");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -120,7 +120,8 @@ namespace Renci.SshClient.Channels
|
||||
// data transfer can take longer then connection specified timeout
|
||||
System.Threading.WaitHandle.WaitAny(new WaitHandle[] { this._channelEof, readerTaskError });
|
||||
|
||||
this._socket.Close();
|
||||
this._socket.Dispose();
|
||||
this._socket = null;
|
||||
|
||||
// Wait for task to finish and will throw any errors if any
|
||||
readerTask.Wait();
|
||||
@@ -162,6 +163,12 @@ namespace Renci.SshClient.Channels
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (this._socket != null)
|
||||
{
|
||||
this._socket.Dispose();
|
||||
this._socket = null;
|
||||
}
|
||||
|
||||
if (this._channelEof != null)
|
||||
{
|
||||
this._channelEof.Dispose();
|
||||
|
||||
@@ -3,8 +3,6 @@ using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Threading.Tasks;
|
||||
using Renci.SshClient.Channels;
|
||||
using Renci.SshClient.Common;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Renci.SshClient
|
||||
{
|
||||
@@ -37,7 +35,6 @@ namespace Renci.SshClient
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
// TODO: Check what the best place to call dispose for this socket.
|
||||
var socket = this._listener.AcceptSocket();
|
||||
|
||||
Task.Factory.StartNew(() =>
|
||||
@@ -99,7 +96,7 @@ namespace Renci.SshClient
|
||||
private bool _isDisposed = false;
|
||||
|
||||
/// <summary>
|
||||
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
|
||||
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged ResourceMessages.
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
@@ -111,17 +108,17 @@ namespace Renci.SshClient
|
||||
/// <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 resources.</param>
|
||||
/// <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 resources.
|
||||
// and unmanaged ResourceMessages.
|
||||
if (disposing)
|
||||
{
|
||||
// Dispose managed resources.
|
||||
// Dispose managed ResourceMessages.
|
||||
if (this._listenerTask != null)
|
||||
{
|
||||
this._listenerTask.Dispose();
|
||||
|
||||
@@ -1,20 +1,18 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Security.Cryptography;
|
||||
|
||||
namespace Renci.SshClient.Security
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents base class for hash algoritm classes
|
||||
/// Represents base class for hash algorithm classes
|
||||
/// </summary>
|
||||
public abstract class HMac : Algorithm, IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// Instance of initialized hash algorithm that being used
|
||||
/// </summary>
|
||||
protected System.Security.Cryptography.HMAC _hmac;
|
||||
// TODO: Refactor code so this member will not be protected
|
||||
protected abstract HMAC Hash { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes algorithm with specified key.
|
||||
@@ -29,7 +27,7 @@ namespace Renci.SshClient.Security
|
||||
/// <returns>The hash</returns>
|
||||
internal byte[] ComputeHash(byte[] hashData)
|
||||
{
|
||||
return this._hmac.ComputeHash(hashData);
|
||||
return this.Hash.ComputeHash(hashData);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -42,16 +40,14 @@ namespace Renci.SshClient.Security
|
||||
{
|
||||
get
|
||||
{
|
||||
return this._hmac.HashSize;
|
||||
return this.Hash.HashSize;
|
||||
}
|
||||
}
|
||||
|
||||
#region IDisposable Members
|
||||
|
||||
private bool _disposed = false;
|
||||
|
||||
/// <summary>
|
||||
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
|
||||
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged ResourceMessages.
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
@@ -63,27 +59,9 @@ namespace Renci.SshClient.Security
|
||||
/// <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 resources.</param>
|
||||
/// <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._disposed)
|
||||
{
|
||||
// If disposing equals true, dispose all managed
|
||||
// and unmanaged resources.
|
||||
if (disposing)
|
||||
{
|
||||
// Dispose managed resources.
|
||||
if (this._hmac != null)
|
||||
{
|
||||
this._hmac.Dispose();
|
||||
this._hmac = null;
|
||||
}
|
||||
}
|
||||
|
||||
// Note disposing has been done.
|
||||
this._disposed = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Security.Cryptography;
|
||||
|
||||
namespace Renci.SshClient.Security
|
||||
{
|
||||
@@ -10,6 +9,13 @@ namespace Renci.SshClient.Security
|
||||
/// </summary>
|
||||
internal class HMacMD5 : HMac
|
||||
{
|
||||
private HMACMD5 _hash;
|
||||
|
||||
protected override HMAC Hash
|
||||
{
|
||||
get { return this._hash; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets algorithm name.
|
||||
/// </summary>
|
||||
@@ -24,7 +30,19 @@ namespace Renci.SshClient.Security
|
||||
/// <param name="key">The hash key.</param>
|
||||
public override void Init(IEnumerable<byte> key)
|
||||
{
|
||||
this._hmac = new System.Security.Cryptography.HMACMD5(key.Take(16).ToArray());
|
||||
this._hash = new HMACMD5(key.Take(16).ToArray());
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
// Dispose managed ResourceMessages.
|
||||
if (this._hash != null)
|
||||
{
|
||||
this._hash.Dispose();
|
||||
this._hash = null;
|
||||
}
|
||||
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Security.Cryptography;
|
||||
|
||||
namespace Renci.SshClient.Security
|
||||
@@ -11,6 +9,13 @@ namespace Renci.SshClient.Security
|
||||
/// </summary>
|
||||
internal class HMacSha1 : HMac
|
||||
{
|
||||
private HMACSHA1 _hash;
|
||||
|
||||
protected override HMAC Hash
|
||||
{
|
||||
get { return this._hash; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets algorithm name.
|
||||
/// </summary>
|
||||
@@ -25,7 +30,19 @@ namespace Renci.SshClient.Security
|
||||
/// <param name="key">The hash key.</param>
|
||||
public override void Init(IEnumerable<byte> key)
|
||||
{
|
||||
this._hmac = new System.Security.Cryptography.HMACSHA1(key.Take(20).ToArray());
|
||||
this._hash = new HMACSHA1(key.Take(20).ToArray());
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
// Dispose managed ResourceMessages.
|
||||
if (this._hash != null)
|
||||
{
|
||||
this._hash.Dispose();
|
||||
this._hash = null;
|
||||
}
|
||||
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -156,6 +156,10 @@ namespace Renci.SshClient.Security
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the server side cipher to use.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public Cipher CreateServerCipher()
|
||||
{
|
||||
// Resolve Session ID
|
||||
@@ -177,6 +181,10 @@ namespace Renci.SshClient.Security
|
||||
return serverCipher;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the client side cipher to use.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public Cipher CreateClientCipher()
|
||||
{
|
||||
// Resolve Session ID
|
||||
@@ -198,6 +206,10 @@ namespace Renci.SshClient.Security
|
||||
return clientCipher;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the server side hash algorithm to use.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public HMac CreateServerHash()
|
||||
{
|
||||
// Resolve Session ID
|
||||
@@ -211,6 +223,10 @@ namespace Renci.SshClient.Security
|
||||
return serverHMac;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the client side hash algorithm to use.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public HMac CreateClientHash()
|
||||
{
|
||||
// Resolve Session ID
|
||||
@@ -224,6 +240,10 @@ namespace Renci.SshClient.Security
|
||||
return clientHMac;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the compression algorithm to use to deflate data.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public Compressor CreateCompressor()
|
||||
{
|
||||
if (this._compressionType == null)
|
||||
@@ -236,6 +256,10 @@ namespace Renci.SshClient.Security
|
||||
return compressor;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the compression algorithm to use to inflate data.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public Compressor CreateDecompressor()
|
||||
{
|
||||
if (this._compressionType == null)
|
||||
@@ -374,7 +398,7 @@ namespace Renci.SshClient.Security
|
||||
#region IDisposable Members
|
||||
|
||||
/// <summary>
|
||||
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
|
||||
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged ResourceMessages.
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
@@ -386,7 +410,7 @@ namespace Renci.SshClient.Security
|
||||
/// <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 resources.</param>
|
||||
/// <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)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -430,6 +430,7 @@ namespace Renci.SshClient
|
||||
Name = messageAttribute.Name,
|
||||
Number = messageAttribute.Number,
|
||||
Enabled = false,
|
||||
Activated = false,
|
||||
Type = type,
|
||||
}).ToList();
|
||||
|
||||
@@ -440,11 +441,8 @@ namespace Renci.SshClient
|
||||
Match versionMatch = null;
|
||||
// Get server version from the server,
|
||||
// ignore text lines which are sent before if any
|
||||
NetworkStream ns = null;
|
||||
try
|
||||
using (var ns = new NetworkStream(this._socket))
|
||||
{
|
||||
|
||||
ns = new NetworkStream(this._socket);
|
||||
using (var sr = new StreamReader(ns))
|
||||
{
|
||||
while (true)
|
||||
@@ -464,14 +462,6 @@ namespace Renci.SshClient
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (ns != null)
|
||||
{
|
||||
ns.Dispose();
|
||||
ns = null;
|
||||
}
|
||||
}
|
||||
|
||||
// Get server SSH version
|
||||
var version = versionMatch.Result("${protoversion}");
|
||||
@@ -528,6 +518,21 @@ namespace Renci.SshClient
|
||||
throw new SshAuthenticationException("User cannot be authenticated.");
|
||||
}
|
||||
|
||||
// Register Connection messages
|
||||
this.RegisterMessage("SSH_MSG_GLOBAL_REQUEST");
|
||||
this.RegisterMessage("SSH_MSG_REQUEST_SUCCESS");
|
||||
this.RegisterMessage("SSH_MSG_REQUEST_FAILURE");
|
||||
this.RegisterMessage("SSH_MSG_CHANNEL_OPEN_CONFIRMATION");
|
||||
this.RegisterMessage("SSH_MSG_CHANNEL_OPEN_FAILURE");
|
||||
this.RegisterMessage("SSH_MSG_CHANNEL_WINDOW_ADJUST");
|
||||
this.RegisterMessage("SSH_MSG_CHANNEL_EXTENDED_DATA");
|
||||
this.RegisterMessage("SSH_MSG_CHANNEL_REQUEST");
|
||||
this.RegisterMessage("SSH_MSG_CHANNEL_SUCCESS");
|
||||
this.RegisterMessage("SSH_MSG_CHANNEL_FAILURE");
|
||||
this.RegisterMessage("SSH_MSG_CHANNEL_DATA");
|
||||
this.RegisterMessage("SSH_MSG_CHANNEL_EOF");
|
||||
this.RegisterMessage("SSH_MSG_CHANNEL_CLOSE");
|
||||
|
||||
Monitor.Pulse(this);
|
||||
}
|
||||
}
|
||||
@@ -1025,22 +1030,12 @@ namespace Renci.SshClient
|
||||
{
|
||||
this._keyExchangeCompletedWaitHandle.Reset();
|
||||
|
||||
// Connection type messages are not allowed during key exchange phase
|
||||
this.UnRegisterMessage("SSH_MSG_GLOBAL_REQUEST");
|
||||
this.UnRegisterMessage("SSH_MSG_REQUEST_SUCCESS");
|
||||
this.UnRegisterMessage("SSH_MSG_REQUEST_FAILURE");
|
||||
this.UnRegisterMessage("SSH_MSG_CHANNEL_OPEN_CONFIRMATION");
|
||||
this.UnRegisterMessage("SSH_MSG_CHANNEL_OPEN_FAILURE");
|
||||
this.UnRegisterMessage("SSH_MSG_CHANNEL_WINDOW_ADJUST");
|
||||
this.UnRegisterMessage("SSH_MSG_CHANNEL_EXTENDED_DATA");
|
||||
this.UnRegisterMessage("SSH_MSG_CHANNEL_REQUEST");
|
||||
this.UnRegisterMessage("SSH_MSG_CHANNEL_SUCCESS");
|
||||
this.UnRegisterMessage("SSH_MSG_CHANNEL_FAILURE");
|
||||
this.UnRegisterMessage("SSH_MSG_CHANNEL_DATA");
|
||||
this.UnRegisterMessage("SSH_MSG_CHANNEL_EOF");
|
||||
this.UnRegisterMessage("SSH_MSG_CHANNEL_CLOSE");
|
||||
// TODO: Replace it with algorithm which disables all messages but relevant for key exchange
|
||||
|
||||
// Disable all registered messages except key exchange related
|
||||
foreach (var messageMetadata in this._messagesMetadata)
|
||||
{
|
||||
if (messageMetadata.Activated == true && messageMetadata.Number < 20 || messageMetadata.Number > 30)
|
||||
messageMetadata.Enabled = false;
|
||||
}
|
||||
|
||||
var keyExchangeAlgorithmName = (from c in this.ConnectionInfo.KeyExchangeAlgorithms.Keys
|
||||
from s in message.KeyExchangeAlgorithms
|
||||
@@ -1116,20 +1111,12 @@ namespace Renci.SshClient
|
||||
this._keyExchange = null;
|
||||
}
|
||||
|
||||
// Register Connection messages
|
||||
this.RegisterMessage("SSH_MSG_GLOBAL_REQUEST");
|
||||
this.RegisterMessage("SSH_MSG_REQUEST_SUCCESS");
|
||||
this.RegisterMessage("SSH_MSG_REQUEST_FAILURE");
|
||||
this.RegisterMessage("SSH_MSG_CHANNEL_OPEN_CONFIRMATION");
|
||||
this.RegisterMessage("SSH_MSG_CHANNEL_OPEN_FAILURE");
|
||||
this.RegisterMessage("SSH_MSG_CHANNEL_WINDOW_ADJUST");
|
||||
this.RegisterMessage("SSH_MSG_CHANNEL_EXTENDED_DATA");
|
||||
this.RegisterMessage("SSH_MSG_CHANNEL_REQUEST");
|
||||
this.RegisterMessage("SSH_MSG_CHANNEL_SUCCESS");
|
||||
this.RegisterMessage("SSH_MSG_CHANNEL_FAILURE");
|
||||
this.RegisterMessage("SSH_MSG_CHANNEL_DATA");
|
||||
this.RegisterMessage("SSH_MSG_CHANNEL_EOF");
|
||||
this.RegisterMessage("SSH_MSG_CHANNEL_CLOSE");
|
||||
// Enable all active registered messages
|
||||
foreach (var messageMetadata in this._messagesMetadata)
|
||||
{
|
||||
if (messageMetadata.Activated == true)
|
||||
messageMetadata.Enabled = true;
|
||||
}
|
||||
|
||||
if (this.NewKeysReceived != null)
|
||||
{
|
||||
@@ -1460,7 +1447,7 @@ namespace Renci.SshClient
|
||||
{
|
||||
Parallel.ForEach(
|
||||
from m in this._messagesMetadata where m.Name == messageName select m,
|
||||
(item) => { item.Enabled = true; });
|
||||
(item) => { item.Enabled = true; item.Activated = true; });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1474,7 +1461,7 @@ namespace Renci.SshClient
|
||||
{
|
||||
Parallel.ForEach(
|
||||
from m in this._messagesMetadata where m.Name == messageName select m,
|
||||
(item) => { item.Enabled = false; });
|
||||
(item) => { item.Enabled = false; item.Activated = false; });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1486,8 +1473,7 @@ namespace Renci.SshClient
|
||||
private Message LoadMessage(IEnumerable<byte> data)
|
||||
{
|
||||
var messageType = data.FirstOrDefault();
|
||||
|
||||
var messageMetadata = (from m in this._messagesMetadata where m.Number == messageType && m.Enabled == true select m).SingleOrDefault();
|
||||
var messageMetadata = (from m in this._messagesMetadata where m.Number == messageType && m.Enabled && m.Activated select m).SingleOrDefault();
|
||||
|
||||
if (messageMetadata == null)
|
||||
throw new SshException(string.Format("Message type {0} is not valid.", messageType));
|
||||
@@ -1512,8 +1498,6 @@ namespace Renci.SshClient
|
||||
{
|
||||
var message = this.ReceiveMessage();
|
||||
|
||||
//Debug.WriteLine(string.Format("{0} : {1}", DateTime.Now, message));
|
||||
|
||||
if (message == null)
|
||||
{
|
||||
throw new NullReferenceException("The 'message' variable cannot be null");
|
||||
@@ -1527,10 +1511,6 @@ namespace Renci.SshClient
|
||||
catch (Exception exp)
|
||||
{
|
||||
this.RaiseError(exp);
|
||||
// TODO: This exception can be swallowed if it occurs while running in the background, look for possible solutions
|
||||
// It can be swollen if call async, when asynch method is finished ensure all async method check for exception to be raised
|
||||
// Or if it is running in port forwarding mode, some event should be raised at this case to handle and error and if not handle then throw
|
||||
// throw an exception and let it be swallowed then if not handled by the event handler
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1568,7 +1548,7 @@ namespace Renci.SshClient
|
||||
private bool _disposed = false;
|
||||
|
||||
/// <summary>
|
||||
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
|
||||
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged ResourceMessages.
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
@@ -1580,14 +1560,14 @@ namespace Renci.SshClient
|
||||
/// <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 resources.</param>
|
||||
/// <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._disposed)
|
||||
{
|
||||
// If disposing equals true, dispose all managed
|
||||
// and unmanaged resources.
|
||||
// and unmanaged ResourceMessages.
|
||||
if (disposing)
|
||||
{
|
||||
this._isDisconnecting = true;
|
||||
@@ -1690,8 +1670,9 @@ namespace Renci.SshClient
|
||||
|
||||
public bool Enabled { get; set; }
|
||||
|
||||
public bool Activated { get; set; }
|
||||
|
||||
public Type Type { get; set; }
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -213,12 +213,10 @@ namespace Renci.SshClient
|
||||
/// <summary>
|
||||
/// Creates a symbolic link from old path to new path.
|
||||
/// </summary>
|
||||
/// <param name="linkPath">The old path.</param>
|
||||
/// <param name="path">The new path.</param>
|
||||
public void SymbolicLink(string linkPath, string path)
|
||||
/// <param name="path">The old path.</param>
|
||||
/// <param name="linkPath">The new path.</param>
|
||||
public void SymbolicLink(string path, string linkPath)
|
||||
{
|
||||
// TODO: Need to be tested, currently does not work
|
||||
|
||||
// Ensure that connection is established.
|
||||
this.EnsureConnection();
|
||||
|
||||
@@ -226,7 +224,7 @@ namespace Renci.SshClient
|
||||
|
||||
var linkFullPath = this._sftpSession.ResolvePath(linkPath);
|
||||
|
||||
var cmd = new SymbolicLinkCommand(this._sftpSession, linkFullPath, fullPath);
|
||||
var cmd = new SymbolicLinkCommand(this._sftpSession, fullPath, linkFullPath);
|
||||
|
||||
cmd.CommandTimeout = this.OperationTimeout;
|
||||
|
||||
@@ -413,7 +411,7 @@ namespace Renci.SshClient
|
||||
/// <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 resources.</param>
|
||||
/// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged ResourceMessages.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (this._sftpSession != null)
|
||||
|
||||
@@ -172,11 +172,7 @@ namespace Renci.SshClient
|
||||
{
|
||||
CommandAsyncResult channelAsyncResult = asynchResult as CommandAsyncResult;
|
||||
|
||||
// TODO: Create a method to perform this check in the method
|
||||
if (channelAsyncResult.Command != this)
|
||||
{
|
||||
throw new InvalidOperationException("Invalid IAsyncResult parameter");
|
||||
}
|
||||
channelAsyncResult.ValidateCommand(this);
|
||||
|
||||
// Make sure that operation completed if not wait for it to finish
|
||||
this.WaitHandle(this._asyncResult.AsyncWaitHandle);
|
||||
@@ -334,7 +330,7 @@ namespace Renci.SshClient
|
||||
private bool _isDisposed = false;
|
||||
|
||||
/// <summary>
|
||||
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
|
||||
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged ResourceMessages.
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
@@ -346,42 +342,42 @@ namespace Renci.SshClient
|
||||
/// <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 resources.</param>
|
||||
/// <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 resources.
|
||||
// and unmanaged ResourceMessages.
|
||||
if (disposing)
|
||||
{
|
||||
|
||||
this._session.Disconnected -= Session_Disconnected;
|
||||
this._session.ErrorOccured -= Session_ErrorOccured;
|
||||
|
||||
// Dispose managed resources.
|
||||
// Dispose managed ResourceMessages.
|
||||
if (this.OutputStream != null)
|
||||
{
|
||||
this.OutputStream.Dispose();
|
||||
this.OutputStream = null;
|
||||
}
|
||||
|
||||
// Dispose managed resources.
|
||||
// Dispose managed ResourceMessages.
|
||||
if (this.ExtendedOutputStream != null)
|
||||
{
|
||||
this.ExtendedOutputStream.Dispose();
|
||||
this.ExtendedOutputStream = null;
|
||||
}
|
||||
|
||||
// Dispose managed resources.
|
||||
// Dispose managed ResourceMessages.
|
||||
if (this._sessionErrorOccuredWaitHandle != null)
|
||||
{
|
||||
this._sessionErrorOccuredWaitHandle.Dispose();
|
||||
this._sessionErrorOccuredWaitHandle = null;
|
||||
}
|
||||
|
||||
// Dispose managed resources.
|
||||
// Dispose managed ResourceMessages.
|
||||
if (this._channel != null)
|
||||
{
|
||||
this._channel.DataReceived -= Channel_DataReceived;
|
||||
|
||||
Reference in New Issue
Block a user