diff --git a/Renci.SshClient/Renci.SshClient.Tests/ConnectionTest.cs b/Renci.SshClient/Renci.SshClient.Tests/ConnectionTest.cs index c6f4d089..441de42a 100644 --- a/Renci.SshClient/Renci.SshClient.Tests/ConnectionTest.cs +++ b/Renci.SshClient/Renci.SshClient.Tests/ConnectionTest.cs @@ -6,6 +6,7 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; using System.IO; using Renci.SshClient.Tests.Properties; using System.Security.Authentication; +using Renci.SshClient.Common; namespace Renci.SshClient.Tests { @@ -23,7 +24,7 @@ namespace Renci.SshClient.Tests } [TestMethod] - [ExpectedException(typeof(AuthenticationException))] + [ExpectedException(typeof(SshAuthenticationException))] public void Test_Connect_Using_Invalid_Password() { using (var client = new SshClient(Resources.HOST, Resources.USERNAME, "invalid password")) diff --git a/Renci.SshClient/Renci.SshClient.Tests/Security/TestCipher.cs b/Renci.SshClient/Renci.SshClient.Tests/Security/TestCipher.cs index 9fa084d3..d354b377 100644 --- a/Renci.SshClient/Renci.SshClient.Tests/Security/TestCipher.cs +++ b/Renci.SshClient/Renci.SshClient.Tests/Security/TestCipher.cs @@ -14,13 +14,12 @@ namespace Renci.SshClient.Tests.Security [TestMethod] public void Test_Cipher_TripleDES_Connection() { - using (var client = new SshClient(Resources.HOST, Resources.USERNAME, Resources.PASSWORD)) + var connectionInfo = new PasswordConnectionInfo(Resources.HOST, 22, Resources.USERNAME, Resources.PASSWORD); + connectionInfo.Encryptions.Clear(); + connectionInfo.Encryptions.Add("3des-cbc", typeof(CipherTripleDES)); + + using (var client = new SshClient(connectionInfo)) { - client.Connecting += delegate(object sender, Common.ConnectingEventArgs e) - { - e.Encryptions.Clear(); - e.Encryptions.Add("3des-cbc", typeof(CipherTripleDES).AssemblyQualifiedName); - }; client.Connect(); client.Disconnect(); } @@ -29,13 +28,12 @@ namespace Renci.SshClient.Tests.Security [TestMethod] public void Test_Cipher_AES128CBC_Connection() { - using (var client = new SshClient(Resources.HOST, Resources.USERNAME, Resources.PASSWORD)) + var connectionInfo = new PasswordConnectionInfo(Resources.HOST, 22, Resources.USERNAME, Resources.PASSWORD); + connectionInfo.Encryptions.Clear(); + connectionInfo.Encryptions.Add("aes128-cbc", typeof(CipherAES128CBC)); + + using (var client = new SshClient(connectionInfo)) { - client.Connecting += delegate(object sender, Common.ConnectingEventArgs e) - { - e.Encryptions.Clear(); - e.Encryptions.Add("aes128-cbc", typeof(CipherAES128CBC).AssemblyQualifiedName); - }; client.Connect(); client.Disconnect(); } @@ -44,13 +42,12 @@ namespace Renci.SshClient.Tests.Security [TestMethod] public void Test_Cipher_AES192CBC_Connection() { - using (var client = new SshClient(Resources.HOST, Resources.USERNAME, Resources.PASSWORD)) + var connectionInfo = new PasswordConnectionInfo(Resources.HOST, 22, Resources.USERNAME, Resources.PASSWORD); + connectionInfo.Encryptions.Clear(); + connectionInfo.Encryptions.Add("aes192-cbc", typeof(CipherAES192CBC)); + + using (var client = new SshClient(connectionInfo)) { - client.Connecting += delegate(object sender, Common.ConnectingEventArgs e) - { - e.Encryptions.Clear(); - e.Encryptions.Add("aes192-cbc", typeof(CipherAES192CBC).AssemblyQualifiedName); - }; client.Connect(); client.Disconnect(); } @@ -59,13 +56,12 @@ namespace Renci.SshClient.Tests.Security [TestMethod] public void Test_Cipher_AES256CBC_Connection() { - using (var client = new SshClient(Resources.HOST, Resources.USERNAME, Resources.PASSWORD)) + var connectionInfo = new PasswordConnectionInfo(Resources.HOST, 22, Resources.USERNAME, Resources.PASSWORD); + connectionInfo.Encryptions.Clear(); + connectionInfo.Encryptions.Add("aes256-cbc", typeof(CipherAES256CBC)); + + using (var client = new SshClient(connectionInfo)) { - client.Connecting += delegate(object sender, Common.ConnectingEventArgs e) - { - e.Encryptions.Clear(); - e.Encryptions.Add("aes256-cbc", typeof(CipherAES256CBC).AssemblyQualifiedName); - }; client.Connect(); client.Disconnect(); } diff --git a/Renci.SshClient/Renci.SshClient.Tests/Security/TestHMac.cs b/Renci.SshClient/Renci.SshClient.Tests/Security/TestHMac.cs index dbcab631..4d139319 100644 --- a/Renci.SshClient/Renci.SshClient.Tests/Security/TestHMac.cs +++ b/Renci.SshClient/Renci.SshClient.Tests/Security/TestHMac.cs @@ -13,14 +13,13 @@ namespace Renci.SshClient.Tests.Security { [TestMethod] public void Test_HMac_MD5_Connection() - { - using (var client = new SshClient(Resources.HOST, Resources.USERNAME, Resources.PASSWORD)) + { + var connectionInfo = new PasswordConnectionInfo(Resources.HOST, 22, Resources.USERNAME, Resources.PASSWORD); + connectionInfo.HmacAlgorithms.Clear(); + connectionInfo.HmacAlgorithms.Add("hmac-md5", typeof(HMacMD5)); + + using (var client = new SshClient(connectionInfo)) { - client.Connecting += delegate(object sender, Common.ConnectingEventArgs e) - { - e.HmacAlgorithms.Clear(); - e.HmacAlgorithms.Add("hmac-md5", typeof(HMacMD5).AssemblyQualifiedName); - }; client.Connect(); client.Disconnect(); } @@ -29,13 +28,12 @@ namespace Renci.SshClient.Tests.Security [TestMethod] public void Test_HMac_Sha1_Connection() { - using (var client = new SshClient(Resources.HOST, Resources.USERNAME, Resources.PASSWORD)) + var connectionInfo = new PasswordConnectionInfo(Resources.HOST, 22, Resources.USERNAME, Resources.PASSWORD); + connectionInfo.HmacAlgorithms.Clear(); + connectionInfo.HmacAlgorithms.Add("hmac-sha1", typeof(HMacSha1)); + + using (var client = new SshClient(connectionInfo)) { - client.Connecting += delegate(object sender, Common.ConnectingEventArgs e) - { - e.HmacAlgorithms.Clear(); - e.HmacAlgorithms.Add("hmac-sha1", typeof(HMacSha1).AssemblyQualifiedName); - }; client.Connect(); client.Disconnect(); } diff --git a/Renci.SshClient/Renci.SshClient.Tests/Security/TestHostKey.cs b/Renci.SshClient/Renci.SshClient.Tests/Security/TestHostKey.cs index 3d1acecc..a6974f85 100644 --- a/Renci.SshClient/Renci.SshClient.Tests/Security/TestHostKey.cs +++ b/Renci.SshClient/Renci.SshClient.Tests/Security/TestHostKey.cs @@ -14,13 +14,12 @@ namespace Renci.SshClient.Tests.Security [TestMethod] public void Test_HostKey_SshRsa_Connection() { - using (var client = new SshClient(Resources.HOST, Resources.USERNAME, Resources.PASSWORD)) + var connectionInfo = new PasswordConnectionInfo(Resources.HOST, 22, Resources.USERNAME, Resources.PASSWORD); + connectionInfo.HostKeyAlgorithms.Clear(); + connectionInfo.HostKeyAlgorithms.Add("ssh-rsa", typeof(CryptoPublicKeyRsa)); + + using (var client = new SshClient(connectionInfo)) { - client.Connecting += delegate(object sender, Common.ConnectingEventArgs e) - { - e.HostKeyAlgorithms.Clear(); - e.HostKeyAlgorithms.Add("ssh-rsa", typeof(CryptoPublicKeyRsa).AssemblyQualifiedName); - }; client.Connect(); client.Disconnect(); } @@ -29,13 +28,12 @@ namespace Renci.SshClient.Tests.Security [TestMethod] public void Test_HostKey_SshDss_Connection() { - using (var client = new SshClient(Resources.HOST, Resources.USERNAME, Resources.PASSWORD)) + var connectionInfo = new PasswordConnectionInfo(Resources.HOST, 22, Resources.USERNAME, Resources.PASSWORD); + connectionInfo.HostKeyAlgorithms.Clear(); + connectionInfo.HostKeyAlgorithms.Add("ssh-dss", typeof(CryptoPublicKeyDss)); + + using (var client = new SshClient(connectionInfo)) { - client.Connecting += delegate(object sender, Common.ConnectingEventArgs e) - { - e.HostKeyAlgorithms.Clear(); - e.HostKeyAlgorithms.Add("ssh-dss", typeof(CryptoPublicKeyDss).AssemblyQualifiedName); - }; client.Connect(); client.Disconnect(); } diff --git a/Renci.SshClient/Renci.SshClient.Tests/Security/TestKeyExchange.cs b/Renci.SshClient/Renci.SshClient.Tests/Security/TestKeyExchange.cs index 5e943d82..4f13baa8 100644 --- a/Renci.SshClient/Renci.SshClient.Tests/Security/TestKeyExchange.cs +++ b/Renci.SshClient/Renci.SshClient.Tests/Security/TestKeyExchange.cs @@ -15,13 +15,12 @@ namespace Renci.SshClient.Tests.Security [TestMethod] public void Test_KeyExchange_GroupExchange_Sha1_Connection() { - using (var client = new SshClient(Resources.HOST, Resources.USERNAME, Resources.PASSWORD)) + var connectionInfo = new PasswordConnectionInfo(Resources.HOST, 22, Resources.USERNAME, Resources.PASSWORD); + connectionInfo.KeyExchangeAlgorithms.Clear(); + connectionInfo.KeyExchangeAlgorithms.Add("diffie-hellman-group-exchange-sha1", typeof(KeyExchangeDiffieHellmanGroupExchangeSha1)); + + using (var client = new SshClient(connectionInfo)) { - client.Connecting += delegate(object sender, Common.ConnectingEventArgs e) - { - e.KeyExchangeAlgorithms.Clear(); - e.KeyExchangeAlgorithms.Add("diffie-hellman-group-exchange-sha1", typeof(KeyExchangeDiffieHellmanGroupExchangeSha1).AssemblyQualifiedName); - }; client.Connect(); client.Disconnect(); } @@ -30,13 +29,12 @@ namespace Renci.SshClient.Tests.Security [TestMethod] public void Test_KeyExchange_Group14_Sha1_Connection() { - using (var client = new SshClient(Resources.HOST, Resources.USERNAME, Resources.PASSWORD)) + var connectionInfo = new PasswordConnectionInfo(Resources.HOST, 22, Resources.USERNAME, Resources.PASSWORD); + connectionInfo.KeyExchangeAlgorithms.Clear(); + connectionInfo.KeyExchangeAlgorithms.Add("diffie-hellman-group14-sha1", typeof(KeyExchangeDiffieHellmanGroup14Sha1)); + + using (var client = new SshClient(connectionInfo)) { - client.Connecting += delegate(object sender, Common.ConnectingEventArgs e) - { - e.KeyExchangeAlgorithms.Clear(); - e.KeyExchangeAlgorithms.Add("diffie-hellman-group14-sha1", typeof(KeyExchangeDiffieHellmanGroup14Sha1).AssemblyQualifiedName); - }; client.Connect(); client.Disconnect(); } @@ -45,13 +43,12 @@ namespace Renci.SshClient.Tests.Security [TestMethod] public void Test_KeyExchange_Group1_Sha1_Connection() { - using (var client = new SshClient(Resources.HOST, Resources.USERNAME, Resources.PASSWORD)) + var connectionInfo = new PasswordConnectionInfo(Resources.HOST, 22, Resources.USERNAME, Resources.PASSWORD); + connectionInfo.KeyExchangeAlgorithms.Clear(); + connectionInfo.KeyExchangeAlgorithms.Add("diffie-hellman-group1-sha1", typeof(KeyExchangeDiffieHellmanGroup1Sha1)); + + using (var client = new SshClient(connectionInfo)) { - client.Connecting += delegate(object sender, Common.ConnectingEventArgs e) - { - e.KeyExchangeAlgorithms.Clear(); - e.KeyExchangeAlgorithms.Add("diffie-hellman-group1-sha1", typeof(KeyExchangeDiffieHellmanGroup1Sha1).AssemblyQualifiedName); - }; client.Connect(); client.Disconnect(); } @@ -60,13 +57,12 @@ namespace Renci.SshClient.Tests.Security [TestMethod] public void Test_KeyExchange_GroupExchange_Sha256_Connection() { - using (var client = new SshClient(Resources.HOST, Resources.USERNAME, Resources.PASSWORD)) + var connectionInfo = new PasswordConnectionInfo(Resources.HOST, 22, Resources.USERNAME, Resources.PASSWORD); + connectionInfo.KeyExchangeAlgorithms.Clear(); + connectionInfo.KeyExchangeAlgorithms.Add("diffie-hellman-group-exchange-sha256", typeof(KeyExchangeDiffieHellmanGroupExchangeSha256)); + + using (var client = new SshClient(connectionInfo)) { - client.Connecting += delegate(object sender, Common.ConnectingEventArgs e) - { - e.KeyExchangeAlgorithms.Clear(); - e.KeyExchangeAlgorithms.Add("diffie-hellman-group-exchange-sha256", typeof(KeyExchangeDiffieHellmanGroupExchangeSha256).AssemblyQualifiedName); - }; client.Connect(); client.Disconnect(); } diff --git a/Renci.SshClient/Renci.SshClient.Tests/SshClientTests/TestPortForwarding.cs b/Renci.SshClient/Renci.SshClient.Tests/SshClientTests/TestPortForwarding.cs index 150cefc3..cf437d8e 100644 --- a/Renci.SshClient/Renci.SshClient.Tests/SshClientTests/TestPortForwarding.cs +++ b/Renci.SshClient/Renci.SshClient.Tests/SshClientTests/TestPortForwarding.cs @@ -4,6 +4,7 @@ using System.IO; using System.Net; using Microsoft.VisualStudio.TestTools.UnitTesting; using Renci.SshClient.Tests.Properties; +using Renci.SshClient.Common; namespace Renci.SshClient.Tests.SshClientTests { @@ -14,7 +15,42 @@ namespace Renci.SshClient.Tests.SshClientTests public class TestPortForwarding { [TestMethod] - public void TestLocalPortForwarding() + [ExpectedException(typeof(SshConnectionException))] + public void Test_PortForwarding_Local_Without_Connecting() + { + using (var client = new SshClient(Resources.HOST, Resources.USERNAME, Resources.PASSWORD)) + { + var port1 = client.AddForwardedPort(8084, "www.renci.org", 80); + port1.Exception += delegate(object sender, ExceptionEventArgs e) + { + Assert.Fail(e.Exception.ToString()); + }; + port1.Start(); + + System.Threading.Tasks.Parallel.For(0, 100, + //new ParallelOptions + //{ + // MaxDegreeOfParallelism = 20, + //}, + (counter) => + { + var start = DateTime.Now; + var req = HttpWebRequest.Create("http://localhost:8084"); + using (var response = req.GetResponse()) + { + + var data = ReadStream(response.GetResponseStream()); + var end = DateTime.Now; + + Debug.WriteLine(string.Format("Request# {2}: Lenght: {0} Time: {1}", data.Length, (end - start), counter)); + } + } + ); + } + } + + [TestMethod] + public void Test_PortForwarding_Local() { using (var client = new SshClient(Resources.HOST, Resources.USERNAME, Resources.PASSWORD)) { @@ -46,11 +82,10 @@ namespace Renci.SshClient.Tests.SshClientTests } ); } - } [TestMethod] - public void TestRemotePortForwarding() + public void Test_PortForwarding_Remote() { // ****************************************************************** // ************* Tests are still in not finished ******************** diff --git a/Renci.SshClient/Renci.SshClient.Tests/SshClientTests/TestSshCommand.cs b/Renci.SshClient/Renci.SshClient.Tests/SshClientTests/TestSshCommand.cs index a6c56e4e..8a765abb 100644 --- a/Renci.SshClient/Renci.SshClient.Tests/SshClientTests/TestSshCommand.cs +++ b/Renci.SshClient/Renci.SshClient.Tests/SshClientTests/TestSshCommand.cs @@ -7,12 +7,25 @@ using System.Diagnostics; using System.Threading.Tasks; using System.Threading; using Renci.SshClient.Tests.Properties; +using Renci.SshClient.Common; namespace Renci.SshClient.Tests.SshClientTests { [TestClass] public class TestSshCommand { + [TestMethod] + [ExpectedException(typeof(SshConnectionException))] + public void Test_Execute_SingleCommand_Without_Connecting() + { + using (var client = new SshClient(Resources.HOST, Resources.USERNAME, Resources.PASSWORD)) + { + var result = ExecuteTestCommand(client); + + Assert.IsTrue(result); + } + } + [TestMethod] public void Test_Execute_SingleCommand() { diff --git a/Renci.SshClient/Renci.SshClient/Common/Extensions.cs b/Renci.SshClient/Renci.SshClient/Common/Extensions.cs index fa87158a..be5d4aa0 100644 --- a/Renci.SshClient/Renci.SshClient/Common/Extensions.cs +++ b/Renci.SshClient/Renci.SshClient/Common/Extensions.cs @@ -112,9 +112,10 @@ namespace Renci.SshClient /// /// The name. /// - internal static T CreateInstance(this string name) where T : class + internal static T CreateInstance(this Type type) where T : class { - var type = Type.GetType(name); + if (type == null) + return null; return Activator.CreateInstance(type) as T; } } diff --git a/Renci.SshClient/Renci.SshClient/Common/SshConnectionException.cs b/Renci.SshClient/Renci.SshClient/Common/SshConnectionException.cs index bf510867..380b87ab 100644 --- a/Renci.SshClient/Renci.SshClient/Common/SshConnectionException.cs +++ b/Renci.SshClient/Renci.SshClient/Common/SshConnectionException.cs @@ -8,6 +8,12 @@ namespace Renci.SshClient.Common { public DisconnectReasons DisconnectReason { get; private set; } + public SshConnectionException(string message) + : base(message) + { + this.DisconnectReason = DisconnectReasons.None; + } + public SshConnectionException(string message, DisconnectReasons disconnectReasonCode) : base(message) { diff --git a/Renci.SshClient/Renci.SshClient/ConnectionInfo.cs b/Renci.SshClient/Renci.SshClient/ConnectionInfo.cs index c99b7584..4b6db05e 100644 --- a/Renci.SshClient/Renci.SshClient/ConnectionInfo.cs +++ b/Renci.SshClient/Renci.SshClient/ConnectionInfo.cs @@ -1,20 +1,30 @@ using System; using System.Collections.Generic; using System.Collections.ObjectModel; +using Renci.SshClient.Security; +using Renci.SshClient.Compression; namespace Renci.SshClient { - public class ConnectionInfo + public abstract class ConnectionInfo { + public IDictionary KeyExchangeAlgorithms { get; private set; } + + public IDictionary Encryptions { get; private set; } + + public IDictionary HmacAlgorithms { get; private set; } + + public IDictionary HostKeyAlgorithms { get; private set; } + + public IDictionary SupportedAuthenticationMethods { get; private set; } + + public IDictionary CompressionAlgorithms { get; private set; } + public string Host { get; private set; } public int Port { get; private set; } public string Username { get; private set; } - public string Password { get; private set; } - - public ICollection KeyFiles { get; private set; } - public TimeSpan Timeout { get; set; } public int RetryAttempts { get; set; } @@ -27,24 +37,84 @@ namespace Renci.SshClient this.Timeout = TimeSpan.FromSeconds(30); this.RetryAttempts = 10; this.MaxSessions = 10; + + this.KeyExchangeAlgorithms = new Dictionary() + { + {"diffie-hellman-group-exchange-sha256", typeof(KeyExchangeDiffieHellmanGroupExchangeSha256)}, + {"diffie-hellman-group-exchange-sha1", typeof(KeyExchangeDiffieHellmanGroupExchangeSha1)}, + {"diffie-hellman-group14-sha1", typeof(KeyExchangeDiffieHellmanGroup14Sha1)}, + {"diffie-hellman-group1-sha1", typeof(KeyExchangeDiffieHellmanGroup1Sha1)}, + }; + + this.Encryptions = new Dictionary() + { + {"3des-cbc", typeof(CipherTripleDES)}, + {"aes128-cbc", typeof(CipherAES128CBC)}, + {"aes192-cbc", typeof(CipherAES192CBC)}, + {"aes256-cbc", typeof(CipherAES256CBC)}, + //{"blowfish-cbc", typeof(...)}, + //{"twofish256-cbc", typeof(...)}, + //{"twofish-cbc", typeof(...)}, + //{"twofish192-cbc", typeof(...)}, + //{"twofish128-cbc", typeof(...)}, + //{"serpent256-cbc", typeof(...)}, + //{"serpent192-cbc", typeof(...)}, + //{"serpent128-cbc", typeof(...)}, + //{"arcfour128", typeof(...)}, + //{"arcfour256", typeof(...)}, + //{"arcfour", typeof(...)}, + //{"idea-cbc", typeof(...)}, + //{"cast128-cbc", typeof(...)}, + //{"rijndael-cbc@lysator.liu.se", typeof(...)}, + //{"aes128-ctr", typeof(...)}, + //{"aes192-ctr", typeof(...)}, + //{"aes256-ctr", typeof(...)}, + }; + + this.HmacAlgorithms = new Dictionary() + { + {"hmac-md5", typeof(HMacMD5)}, + {"hmac-sha1", typeof(HMacSha1)}, + //{"umac-64@openssh.com", typeof(HMacSha1)}, + //{"hmac-ripemd160", typeof(HMacSha1)}, + //{"hmac-ripemd160@openssh.com", typeof(HMacSha1)}, + //{"hmac-md5-96", typeof(...)}, + //{"hmac-sha1-96", typeof(...)}, + //{"none", typeof(...)}, + }; + + this.HostKeyAlgorithms = new Dictionary() + { + {"ssh-rsa", typeof(CryptoPublicKeyRsa)}, + {"ssh-dss", typeof(CryptoPublicKeyDss)}, + }; + + this.SupportedAuthenticationMethods = new Dictionary() + { + {"none", typeof(UserAuthenticationNone)}, + {"publickey", typeof(UserAuthenticationPublicKey)}, + {"password", typeof(UserAuthenticationPassword)}, + {"keyboard-interactive", typeof(UserAuthenticationKeyboardInteractive)}, + //{"hostbased", typeof(...)}, + //{"gssapi-keyex", typeof(...)}, + //{"gssapi-with-mic", typeof(...)}, + }; + + this.CompressionAlgorithms = new Dictionary() + { + {"none", null}, + {"zlib", typeof(Zlib)}, + {"zlib@openssh.com", typeof(ZlibOpenSsh)}, + }; + } - public ConnectionInfo(string host, int port, string username, string password) + protected ConnectionInfo(string host, int port, string username) : this() { this.Host = host; this.Port = port; this.Username = username; - this.Password = password; - } - - public ConnectionInfo(string host, int port, string username, params PrivateKeyFile[] keyFiles) - : this() - { - this.Host = host; - this.Port = port; - this.Username = username; - this.KeyFiles = new Collection(keyFiles); } } } diff --git a/Renci.SshClient/Renci.SshClient/ForwardedPort.cs b/Renci.SshClient/Renci.SshClient/ForwardedPort.cs index 44d4bbbc..b06fc568 100644 --- a/Renci.SshClient/Renci.SshClient/ForwardedPort.cs +++ b/Renci.SshClient/Renci.SshClient/ForwardedPort.cs @@ -1,5 +1,6 @@  using System; +using Renci.SshClient.Common; namespace Renci.SshClient { public abstract class ForwardedPort @@ -30,7 +31,7 @@ namespace Renci.SshClient if (!this.Session.IsConnected) { - throw new InvalidOperationException("Not connected."); + throw new SshConnectionException("Not connected."); } } diff --git a/Renci.SshClient/Renci.SshClient/PasswordConnectionInfo.cs b/Renci.SshClient/Renci.SshClient/PasswordConnectionInfo.cs new file mode 100644 index 00000000..276dff5b --- /dev/null +++ b/Renci.SshClient/Renci.SshClient/PasswordConnectionInfo.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Renci.SshClient +{ + public class PasswordConnectionInfo : ConnectionInfo + { + public string Password { get; private set; } + + public PasswordConnectionInfo(string host, string username, string password) + : this(host, 22, username, password) + { + + } + + public PasswordConnectionInfo(string host, int port, string username, string password) + : base(host, port, username) + { + this.Password = password; + } + + } +} diff --git a/Renci.SshClient/Renci.SshClient/PrivateKeyConnectionInfo.cs b/Renci.SshClient/Renci.SshClient/PrivateKeyConnectionInfo.cs new file mode 100644 index 00000000..6e0a28c5 --- /dev/null +++ b/Renci.SshClient/Renci.SshClient/PrivateKeyConnectionInfo.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Collections.ObjectModel; + +namespace Renci.SshClient +{ + public class PrivateKeyConnectionInfo : ConnectionInfo + { + public ICollection KeyFiles { get; private set; } + + public PrivateKeyConnectionInfo(string host, string username, params PrivateKeyFile[] keyFiles) + : this(host, 22, username, keyFiles) + { + + } + + public PrivateKeyConnectionInfo(string host, int port, string username, params PrivateKeyFile[] keyFiles) + : base(host, port, username) + { + this.KeyFiles = new Collection(keyFiles); + } + + } +} diff --git a/Renci.SshClient/Renci.SshClient/Renci.SshClient.csproj b/Renci.SshClient/Renci.SshClient/Renci.SshClient.csproj index d30bb143..037a6f1a 100644 --- a/Renci.SshClient/Renci.SshClient/Renci.SshClient.csproj +++ b/Renci.SshClient/Renci.SshClient/Renci.SshClient.csproj @@ -93,6 +93,8 @@ + + diff --git a/Renci.SshClient/Renci.SshClient/Security/KeyExchange.cs b/Renci.SshClient/Renci.SshClient/Security/KeyExchange.cs index 92edee76..2807be2f 100644 --- a/Renci.SshClient/Renci.SshClient/Security/KeyExchange.cs +++ b/Renci.SshClient/Renci.SshClient/Security/KeyExchange.cs @@ -12,17 +12,17 @@ namespace Renci.SshClient.Security { public abstract class KeyExchange : Algorithm, IDisposable { - private string _clientCipherTypeName; + private Type _clientCipherType; - private string _serverCipherTypeName; + private Type _serverCipherType; - private string _cientHmacAlgorithmTypeName; + private Type _cientHmacAlgorithmType; - private string _serverHmacAlgorithmTypeName; + private Type _serverHmacAlgorithmType; - private string _compressionTypeName; + private Type _compressionType; - private string _decompressionTypeName; + private Type _decompressionType; protected Session Session { get; set; } @@ -64,7 +64,7 @@ namespace Renci.SshClient.Security this.SendMessage(session.ClientInitMessage); // Determine encryption algorithm - var clientEncryptionAlgorithmName = (from b in session.Encryptions.Keys + var clientEncryptionAlgorithmName = (from b in session.ConnectionInfo.Encryptions.Keys from a in message.EncryptionAlgorithmsClientToServer where a == b select a).FirstOrDefault(); @@ -75,7 +75,7 @@ namespace Renci.SshClient.Security } // Determine encryption algorithm - var serverDecryptionAlgorithmName = (from b in session.Encryptions.Keys + var serverDecryptionAlgorithmName = (from b in session.ConnectionInfo.Encryptions.Keys from a in message.EncryptionAlgorithmsServerToClient where a == b select a).FirstOrDefault(); @@ -85,7 +85,7 @@ namespace Renci.SshClient.Security } // Determine client hmac algorithm - var clientHmacAlgorithmName = (from b in session.HmacAlgorithms.Keys + var clientHmacAlgorithmName = (from b in session.ConnectionInfo.HmacAlgorithms.Keys from a in message.MacAlgorithmsClientToSserver where a == b select a).FirstOrDefault(); @@ -95,7 +95,7 @@ namespace Renci.SshClient.Security } // Determine server hmac algorithm - var serverHmacAlgorithmName = (from b in session.HmacAlgorithms.Keys + var serverHmacAlgorithmName = (from b in session.ConnectionInfo.HmacAlgorithms.Keys from a in message.MacAlgorithmsServerToClient where a == b select a).FirstOrDefault(); @@ -105,7 +105,7 @@ namespace Renci.SshClient.Security } // Determine compression algorithm - var compressionAlgorithmName = (from b in session.CompressionAlgorithms.Keys + var compressionAlgorithmName = (from b in session.ConnectionInfo.CompressionAlgorithms.Keys from a in message.CompressionAlgorithmsClientToServer where a == b select a).FirstOrDefault(); @@ -115,7 +115,7 @@ namespace Renci.SshClient.Security } // Determine decompression algorithm - var decompressionAlgorithmName = (from b in session.CompressionAlgorithms.Keys + var decompressionAlgorithmName = (from b in session.ConnectionInfo.CompressionAlgorithms.Keys from a in message.CompressionAlgorithmsServerToClient where a == b select a).FirstOrDefault(); @@ -124,12 +124,12 @@ namespace Renci.SshClient.Security throw new SshConnectionException("Decompression algorithm not found", DisconnectReasons.KeyExchangeFailed); } - this._clientCipherTypeName = session.Encryptions[clientEncryptionAlgorithmName]; - this._serverCipherTypeName = session.Encryptions[clientEncryptionAlgorithmName]; - this._cientHmacAlgorithmTypeName = session.HmacAlgorithms[clientHmacAlgorithmName]; - this._serverHmacAlgorithmTypeName = session.HmacAlgorithms[serverHmacAlgorithmName]; - this._compressionTypeName = session.CompressionAlgorithms[compressionAlgorithmName]; - this._decompressionTypeName = session.CompressionAlgorithms[decompressionAlgorithmName]; + this._clientCipherType = session.ConnectionInfo.Encryptions[clientEncryptionAlgorithmName]; + this._serverCipherType = session.ConnectionInfo.Encryptions[clientEncryptionAlgorithmName]; + this._cientHmacAlgorithmType = session.ConnectionInfo.HmacAlgorithms[clientHmacAlgorithmName]; + this._serverHmacAlgorithmType = session.ConnectionInfo.HmacAlgorithms[serverHmacAlgorithmName]; + this._compressionType = session.ConnectionInfo.CompressionAlgorithms[compressionAlgorithmName]; + this._decompressionType = session.ConnectionInfo.CompressionAlgorithms[decompressionAlgorithmName]; } public virtual void Finish() @@ -147,7 +147,7 @@ namespace Renci.SshClient.Security } // Create server cipher - this.ServerCipher = this._serverCipherTypeName.CreateInstance(); + this.ServerCipher = this._serverCipherType.CreateInstance(); // Calculate server to client initial IV var serverVector = this.Hash(this.GenerateSessionKey(this.SharedKey, this.ExchangeHash, 'B', this.Session.SessionId)); @@ -160,7 +160,7 @@ namespace Renci.SshClient.Security this.ServerCipher.Init(serverKey, serverVector); // Create client cipher - this.ClientCipher = this._clientCipherTypeName.CreateInstance(); + this.ClientCipher = this._clientCipherType.CreateInstance(); // Calculate client to server initial IV var clientVector = this.Hash(this.GenerateSessionKey(this.SharedKey, this.ExchangeHash, 'A', this.Session.SessionId)); @@ -173,27 +173,27 @@ namespace Renci.SshClient.Security this.ClientCipher.Init(clientKey, clientVector); // Create server HMac - this.ServerHMac = this._serverHmacAlgorithmTypeName.CreateInstance(); + this.ServerHMac = this._serverHmacAlgorithmType.CreateInstance(); this.ServerHMac.Init(this.Hash(this.GenerateSessionKey(this.SharedKey, this.ExchangeHash, 'F', this.Session.SessionId))); // Create client HMac - this.ClientHMac = this._cientHmacAlgorithmTypeName.CreateInstance(); + this.ClientHMac = this._cientHmacAlgorithmType.CreateInstance(); this.ClientHMac.Init(this.Hash(this.GenerateSessionKey(this.SharedKey, this.ExchangeHash, 'E', this.Session.SessionId))); - if (!string.IsNullOrEmpty(this._compressionTypeName)) + if (this._compressionType != null) { - var compressor = this._compressionTypeName.CreateInstance(); + var compressor = this._compressionType.CreateInstance(); compressor.Init(this.Session); this.Compressor = compressor; } - if (!string.IsNullOrEmpty(this._decompressionTypeName)) + if (this._decompressionType != null) { - var decompressor = this._decompressionTypeName.CreateInstance(); + var decompressor = this._decompressionType.CreateInstance(); decompressor.Init(this.Session); diff --git a/Renci.SshClient/Renci.SshClient/Security/KeyExchangeDiffieHellman.cs b/Renci.SshClient/Renci.SshClient/Security/KeyExchangeDiffieHellman.cs index fa3ac275..7f94b6ca 100644 --- a/Renci.SshClient/Renci.SshClient/Security/KeyExchangeDiffieHellman.cs +++ b/Renci.SshClient/Renci.SshClient/Security/KeyExchangeDiffieHellman.cs @@ -48,7 +48,7 @@ namespace Renci.SshClient.Security var data = bytes.Skip(4 + algorithmName.Length); - CryptoPublicKey key = this.Session.HostKeyAlgorithms[algorithmName].CreateInstance(); + CryptoPublicKey key = this.Session.ConnectionInfo.HostKeyAlgorithms[algorithmName].CreateInstance(); key.Load(data); diff --git a/Renci.SshClient/Renci.SshClient/Security/UserAuthenticationPassword.cs b/Renci.SshClient/Renci.SshClient/Security/UserAuthenticationPassword.cs index dec3a9a8..b6851c9f 100644 --- a/Renci.SshClient/Renci.SshClient/Security/UserAuthenticationPassword.cs +++ b/Renci.SshClient/Renci.SshClient/Security/UserAuthenticationPassword.cs @@ -19,6 +19,11 @@ namespace Renci.SshClient.Security protected override void OnAuthenticate() { + var passwordConnectionInfo = this.Session.ConnectionInfo as PasswordConnectionInfo; + + if (passwordConnectionInfo == null) + return; + // TODO: Handle all user authentication messages //Message.RegisterMessageType(MessageTypes.UserAuthenticationPasswordChangeRequired); @@ -26,7 +31,7 @@ namespace Renci.SshClient.Security { ServiceName = ServiceNames.Connection, Username = this.Username, - Password = this.Session.ConnectionInfo.Password ?? string.Empty, + Password = passwordConnectionInfo.Password ?? string.Empty, }); this.Session.WaitHandle(this._authenticationCompleted); diff --git a/Renci.SshClient/Renci.SshClient/Security/UserAuthenticationPublicKey.cs b/Renci.SshClient/Renci.SshClient/Security/UserAuthenticationPublicKey.cs index c1f96b2e..573933eb 100644 --- a/Renci.SshClient/Renci.SshClient/Security/UserAuthenticationPublicKey.cs +++ b/Renci.SshClient/Renci.SshClient/Security/UserAuthenticationPublicKey.cs @@ -22,12 +22,17 @@ namespace Renci.SshClient.Security protected override void OnAuthenticate() { - if (this.Session.ConnectionInfo.KeyFiles == null) + var privateKeyConnectionInfo = this.Session.ConnectionInfo as PrivateKeyConnectionInfo; + + if (privateKeyConnectionInfo == null) + return; + + if (privateKeyConnectionInfo.KeyFiles == null) return; this.Session.RegisterMessageType(MessageTypes.UserAuthenticationPublicKey); - foreach (var keyFile in this.Session.ConnectionInfo.KeyFiles) + foreach (var keyFile in privateKeyConnectionInfo.KeyFiles) { this._publicKeyRequestMessageResponseWaitHandle.Reset(); this._isSignatureRequired = false; @@ -40,7 +45,7 @@ namespace Renci.SshClient.Security PublicKeyData = keyFile.PublicKey, }; - if (this.Session.ConnectionInfo.KeyFiles.Count < 2) + if (privateKeyConnectionInfo.KeyFiles.Count < 2) { // If only one key file provided then send signature for very first request var signatureData = new SignatureData(message, this.Session.SessionId.GetSshString()).GetBytes(); diff --git a/Renci.SshClient/Renci.SshClient/Session.cs b/Renci.SshClient/Renci.SshClient/Session.cs index ecc51c82..ffbb7e06 100644 --- a/Renci.SshClient/Renci.SshClient/Session.cs +++ b/Renci.SshClient/Renci.SshClient/Session.cs @@ -182,14 +182,14 @@ namespace Renci.SshClient { this._clientInitMessage = new KeyExchangeInitMessage() { - KeyExchangeAlgorithms = this.KeyExchangeAlgorithms.Keys, - ServerHostKeyAlgorithms = this.HostKeyAlgorithms.Keys, - EncryptionAlgorithmsClientToServer = this.Encryptions.Keys, - EncryptionAlgorithmsServerToClient = this.Encryptions.Keys, - MacAlgorithmsClientToSserver = this.HmacAlgorithms.Keys, - MacAlgorithmsServerToClient = this.HmacAlgorithms.Keys, - CompressionAlgorithmsClientToServer = this.CompressionAlgorithms.Keys, - CompressionAlgorithmsServerToClient = this.CompressionAlgorithms.Keys, + KeyExchangeAlgorithms = this.ConnectionInfo.KeyExchangeAlgorithms.Keys, + ServerHostKeyAlgorithms = this.ConnectionInfo.HostKeyAlgorithms.Keys, + EncryptionAlgorithmsClientToServer = this.ConnectionInfo.Encryptions.Keys, + EncryptionAlgorithmsServerToClient = this.ConnectionInfo.Encryptions.Keys, + MacAlgorithmsClientToSserver = this.ConnectionInfo.HmacAlgorithms.Keys, + MacAlgorithmsServerToClient = this.ConnectionInfo.HmacAlgorithms.Keys, + CompressionAlgorithmsClientToServer = this.ConnectionInfo.CompressionAlgorithms.Keys, + CompressionAlgorithmsServerToClient = this.ConnectionInfo.CompressionAlgorithms.Keys, LanguagesClientToServer = new string[] { string.Empty }, LanguagesServerToClient = new string[] { string.Empty }, FirstKexPacketFollows = false, @@ -220,10 +220,6 @@ namespace Renci.SshClient public event EventHandler ErrorOccured; - public event EventHandler Connecting; - - public event EventHandler Connected; - public event EventHandler Disconnecting; public event EventHandler Disconnected; @@ -372,18 +368,6 @@ namespace Renci.SshClient #endregion - public IDictionary KeyExchangeAlgorithms { get; private set; } - - public IDictionary Encryptions { get; private set; } - - public IDictionary HmacAlgorithms { get; private set; } - - public IDictionary HostKeyAlgorithms { get; private set; } - - public IDictionary SupportedAuthenticationMethods { get; private set; } - - public IDictionary CompressionAlgorithms { get; private set; } - /// /// Initializes a new instance of the class. /// @@ -392,75 +376,6 @@ namespace Renci.SshClient { this.ConnectionInfo = connectionInfo; this.ClientVersion = string.Format("SSH-2.0-Renci.SshClient.{0}", this.GetType().Assembly.GetName().Version); - - this.KeyExchangeAlgorithms = new Dictionary() - { - {"diffie-hellman-group-exchange-sha256", typeof(KeyExchangeDiffieHellmanGroupExchangeSha256).AssemblyQualifiedName}, - {"diffie-hellman-group-exchange-sha1", typeof(KeyExchangeDiffieHellmanGroupExchangeSha1).AssemblyQualifiedName}, - {"diffie-hellman-group14-sha1", typeof(KeyExchangeDiffieHellmanGroup14Sha1).AssemblyQualifiedName}, - {"diffie-hellman-group1-sha1", typeof(KeyExchangeDiffieHellmanGroup1Sha1).AssemblyQualifiedName}, - }; - - this.Encryptions = new Dictionary() - { - {"3des-cbc", typeof(CipherTripleDES).AssemblyQualifiedName}, - {"aes128-cbc", typeof(CipherAES128CBC).AssemblyQualifiedName}, - {"aes192-cbc", typeof(CipherAES192CBC).AssemblyQualifiedName}, - {"aes256-cbc", typeof(CipherAES256CBC).AssemblyQualifiedName}, - //{"blowfish-cbc", typeof(...).AssemblyQualifiedName}, - //{"twofish256-cbc", typeof(...).AssemblyQualifiedName}, - //{"twofish-cbc", typeof(...).AssemblyQualifiedName}, - //{"twofish192-cbc", typeof(...).AssemblyQualifiedName}, - //{"twofish128-cbc", typeof(...).AssemblyQualifiedName}, - //{"serpent256-cbc", typeof(...).AssemblyQualifiedName}, - //{"serpent192-cbc", typeof(...).AssemblyQualifiedName}, - //{"serpent128-cbc", typeof(...).AssemblyQualifiedName}, - //{"arcfour128", typeof(...).AssemblyQualifiedName}, - //{"arcfour256", typeof(...).AssemblyQualifiedName}, - //{"arcfour", typeof(...).AssemblyQualifiedName}, - //{"idea-cbc", typeof(...).AssemblyQualifiedName}, - //{"cast128-cbc", typeof(...).AssemblyQualifiedName}, - //{"rijndael-cbc@lysator.liu.se", typeof(...).AssemblyQualifiedName}, - //{"aes128-ctr", typeof(...).AssemblyQualifiedName}, - //{"aes192-ctr", typeof(...).AssemblyQualifiedName}, - //{"aes256-ctr", typeof(...).AssemblyQualifiedName}, - }; - - this.HmacAlgorithms = new Dictionary() - { - {"hmac-md5", typeof(HMacMD5).AssemblyQualifiedName}, - {"hmac-sha1", typeof(HMacSha1).AssemblyQualifiedName}, - //{"umac-64@openssh.com", typeof(HMacSha1).AssemblyQualifiedName}, - //{"hmac-ripemd160", typeof(HMacSha1).AssemblyQualifiedName}, - //{"hmac-ripemd160@openssh.com", typeof(HMacSha1).AssemblyQualifiedName}, - //{"hmac-md5-96", typeof(...).AssemblyQualifiedName}, - //{"hmac-sha1-96", typeof(...).AssemblyQualifiedName}, - //{"none", typeof(...).AssemblyQualifiedName}, - }; - - this.HostKeyAlgorithms = new Dictionary() - { - {"ssh-rsa", typeof(CryptoPublicKeyRsa).AssemblyQualifiedName}, - {"ssh-dss", typeof(CryptoPublicKeyDss).AssemblyQualifiedName}, - }; - - this.SupportedAuthenticationMethods = new Dictionary() - { - {"none", typeof(UserAuthenticationNone).AssemblyQualifiedName}, - {"publickey", typeof(UserAuthenticationPublicKey).AssemblyQualifiedName}, - {"password", typeof(UserAuthenticationPassword).AssemblyQualifiedName}, - {"keyboard-interactive", typeof(UserAuthenticationKeyboardInteractive).AssemblyQualifiedName}, - //{"hostbased", typeof(...).AssemblyQualifiedName}, - //{"gssapi-keyex", typeof(...).AssemblyQualifiedName}, - //{"gssapi-with-mic", typeof(...).AssemblyQualifiedName}, - }; - - this.CompressionAlgorithms = new Dictionary() - { - {"none", string.Empty}, - {"zlib", typeof(Zlib).AssemblyQualifiedName}, - {"zlib@openssh.com", typeof(ZlibOpenSsh).AssemblyQualifiedName}, - }; } /// @@ -490,33 +405,13 @@ namespace Renci.SshClient if (this.IsConnected) return; - var eventArgs = new ConnectingEventArgs(this.KeyExchangeAlgorithms, - this.Encryptions, - this.HmacAlgorithms, - this.HostKeyAlgorithms, - this.SupportedAuthenticationMethods, - this.CompressionAlgorithms); - // Populate event args connection information - eventArgs.Timeout = this.ConnectionInfo.Timeout; - eventArgs.RetryAttempts = this.ConnectionInfo.RetryAttempts; - eventArgs.MaxSessions = this.ConnectionInfo.MaxSessions; - - if (this.Connecting != null) - { - this.Connecting(this, eventArgs); - - // Update connection information if it was changed by event handler - this.ConnectionInfo.Timeout = eventArgs.Timeout; - this.ConnectionInfo.RetryAttempts = eventArgs.RetryAttempts; - } - var ep = new IPEndPoint(Dns.GetHostAddresses(this.ConnectionInfo.Host)[0], this.ConnectionInfo.Port); this._socket = new Socket(ep.AddressFamily, SocketType.Stream, ProtocolType.Tcp); // Connect socket with 5 seconds timeout var connectResult = this._socket.BeginConnect(ep, null, null); - connectResult.AsyncWaitHandle.WaitOne(eventArgs.Timeout); + connectResult.AsyncWaitHandle.WaitOne(this.ConnectionInfo.Timeout); this._socket.EndConnect(connectResult); @@ -606,7 +501,9 @@ namespace Renci.SshClient // Query server supported authentication methods var username = this.ConnectionInfo.Username; + IEnumerable serverMethods = null; + using (var noneAuthentication = new UserAuthenticationNone()) { if (noneAuthentication.Authenticate(username, this)) @@ -618,14 +515,14 @@ namespace Renci.SshClient } var methodNames = from serverMethod in serverMethods - from clientMethod in this.SupportedAuthenticationMethods.Keys + from clientMethod in this.ConnectionInfo.SupportedAuthenticationMethods.Keys where serverMethod == clientMethod select serverMethod; foreach (var methodName in methodNames) { - var authentication = this.SupportedAuthenticationMethods[methodName].CreateInstance(); + var authentication = this.ConnectionInfo.SupportedAuthenticationMethods[methodName].CreateInstance(); authentication.Authenticating += delegate(object sender, AuthenticationEventArgs e) { @@ -651,11 +548,6 @@ namespace Renci.SshClient Monitor.Pulse(this); } - - if (this.Connected != null) - { - this.Connected(this, new EventArgs()); - } } finally { @@ -1146,7 +1038,7 @@ namespace Renci.SshClient this.UnRegisterMessageType(MessageTypes.ChannelEof); this.UnRegisterMessageType(MessageTypes.ChannelClose); - var keyExchangeAlgorithmName = (from c in this.KeyExchangeAlgorithms.Keys + var keyExchangeAlgorithmName = (from c in this.ConnectionInfo.KeyExchangeAlgorithms.Keys from s in message.KeyExchangeAlgorithms where s == c select c).FirstOrDefault(); @@ -1163,7 +1055,7 @@ namespace Renci.SshClient } // Create instance of key exchange algorithm that will be used - this._keyExchange = this.KeyExchangeAlgorithms[keyExchangeAlgorithmName].CreateInstance(); + this._keyExchange = this.ConnectionInfo.KeyExchangeAlgorithms[keyExchangeAlgorithmName].CreateInstance(); // Start the algorithm implementation this._keyExchange.Start(this, message); diff --git a/Renci.SshClient/Renci.SshClient/SftpClient.cs b/Renci.SshClient/Renci.SshClient/SftpClient.cs index 5ab4c60d..bb9ed38f 100644 --- a/Renci.SshClient/Renci.SshClient/SftpClient.cs +++ b/Renci.SshClient/Renci.SshClient/SftpClient.cs @@ -42,7 +42,7 @@ namespace Renci.SshClient } public SftpClient(string host, int port, string username, string password) - : this(new ConnectionInfo(host, port, username, password)) + : this(new PasswordConnectionInfo(host, port, username, password)) { } @@ -52,7 +52,7 @@ namespace Renci.SshClient } public SftpClient(string host, int port, string username, params PrivateKeyFile[] keyFiles) - : this(new ConnectionInfo(host, port, username, keyFiles)) + : this(new PrivateKeyConnectionInfo(host, port, username, keyFiles)) { } diff --git a/Renci.SshClient/Renci.SshClient/SshBaseClient.cs b/Renci.SshClient/Renci.SshClient/SshBaseClient.cs index 08bfe659..fb76fc00 100644 --- a/Renci.SshClient/Renci.SshClient/SshBaseClient.cs +++ b/Renci.SshClient/Renci.SshClient/SshBaseClient.cs @@ -38,11 +38,6 @@ namespace Renci.SshClient } } - /// - /// Occurs when client is about to connect to the server. - /// - public event EventHandler Connecting; - public event EventHandler Authenticating; /// @@ -68,7 +63,6 @@ namespace Renci.SshClient } this.Session = new Session(this.ConnectionInfo); - this.Session.Connecting += Session_Connecting; this.Session.Authenticating += Session_Authenticating; this.Session.Connect(); @@ -83,7 +77,6 @@ namespace Renci.SshClient this.OnDisconnecting(); this.Session.Disconnect(); - this.Session.Connecting -= Session_Connecting; this.Session.Authenticating -= Session_Authenticating; this.OnDisconnected(); @@ -129,14 +122,6 @@ namespace Renci.SshClient } - private void Session_Connecting(object sender, ConnectingEventArgs e) - { - if (this.Connecting != null) - { - this.Connecting(this, e); - } - } - private void Session_Authenticating(object sender, AuthenticationEventArgs e) { if (this.Authenticating != null) @@ -145,7 +130,6 @@ namespace Renci.SshClient } } - #region IDisposable Members private bool _isDisposed = false; diff --git a/Renci.SshClient/Renci.SshClient/SshClient.cs b/Renci.SshClient/Renci.SshClient/SshClient.cs index 9b4e60ea..c8eecb65 100644 --- a/Renci.SshClient/Renci.SshClient/SshClient.cs +++ b/Renci.SshClient/Renci.SshClient/SshClient.cs @@ -31,7 +31,7 @@ namespace Renci.SshClient } public SshClient(string host, int port, string username, string password) - : this(new ConnectionInfo(host, port, username, password)) + : this(new PasswordConnectionInfo(host, port, username, password)) { } @@ -41,7 +41,7 @@ namespace Renci.SshClient } public SshClient(string host, int port, string username, params PrivateKeyFile[] keyFiles) - : this(new ConnectionInfo(host, port, username, keyFiles)) + : this(new PrivateKeyConnectionInfo(host, port, username, keyFiles)) { } diff --git a/Renci.SshClient/Renci.SshClient/SshCommand.cs b/Renci.SshClient/Renci.SshClient/SshCommand.cs index 70392ed8..461591ec 100644 --- a/Renci.SshClient/Renci.SshClient/SshCommand.cs +++ b/Renci.SshClient/Renci.SshClient/SshCommand.cs @@ -77,6 +77,9 @@ namespace Renci.SshClient public IAsyncResult BeginExecute(AsyncCallback callback, object state) { + if (!this._session.IsConnected) + throw new SshConnectionException("Not connected."); + // Prevent from executing BeginExecute before calling EndExecute if (this._asyncResult != null) {