From cdf4e52365ee742101c552ca88eadf24106bcbc4 Mon Sep 17 00:00:00 2001 From: olegkap_cp Date: Wed, 22 Dec 2010 03:00:28 +0000 Subject: [PATCH] Remove Connecting and Connected events as they are useless Move algorithms definition into ConnectionInfo class Add PasswordConnectionInfo and PrivateKeyConnectionInfo classed and inherit from ConnectionInfo to allow future addition of different authentication methods --- .../Renci.SshClient.Tests/ConnectionTest.cs | 3 +- .../Security/TestCipher.cs | 44 +++--- .../Security/TestHMac.cs | 24 ++- .../Security/TestHostKey.cs | 22 ++- .../Security/TestKeyExchange.cs | 44 +++--- .../SshClientTests/TestPortForwarding.cs | 41 +++++- .../SshClientTests/TestSshCommand.cs | 13 ++ .../Renci.SshClient/Common/Extensions.cs | 5 +- .../Common/SshConnectionException.cs | 6 + .../Renci.SshClient/ConnectionInfo.cs | 102 +++++++++++-- .../Renci.SshClient/ForwardedPort.cs | 3 +- .../Renci.SshClient/PasswordConnectionInfo.cs | 25 ++++ .../PrivateKeyConnectionInfo.cs | 26 ++++ .../Renci.SshClient/Renci.SshClient.csproj | 2 + .../Renci.SshClient/Security/KeyExchange.cs | 52 +++---- .../Security/KeyExchangeDiffieHellman.cs | 2 +- .../Security/UserAuthenticationPassword.cs | 7 +- .../Security/UserAuthenticationPublicKey.cs | 11 +- Renci.SshClient/Renci.SshClient/Session.cs | 138 ++---------------- Renci.SshClient/Renci.SshClient/SftpClient.cs | 4 +- .../Renci.SshClient/SshBaseClient.cs | 16 -- Renci.SshClient/Renci.SshClient/SshClient.cs | 4 +- Renci.SshClient/Renci.SshClient/SshCommand.cs | 3 + 23 files changed, 327 insertions(+), 270 deletions(-) create mode 100644 Renci.SshClient/Renci.SshClient/PasswordConnectionInfo.cs create mode 100644 Renci.SshClient/Renci.SshClient/PrivateKeyConnectionInfo.cs 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) {