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
This commit is contained in:
olegkap_cp
2010-12-22 03:00:28 +00:00
parent feafa2ef38
commit cdf4e52365
23 changed files with 327 additions and 270 deletions
@@ -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"))
@@ -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();
}
@@ -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();
}
@@ -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();
}
@@ -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();
}
@@ -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<ForwardedPortLocal>(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 ********************
@@ -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()
{
@@ -112,9 +112,10 @@ namespace Renci.SshClient
/// <typeparam name="T"></typeparam>
/// <param name="name">The name.</param>
/// <returns></returns>
internal static T CreateInstance<T>(this string name) where T : class
internal static T CreateInstance<T>(this Type type) where T : class
{
var type = Type.GetType(name);
if (type == null)
return null;
return Activator.CreateInstance(type) as T;
}
}
@@ -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)
{
@@ -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<string, Type> KeyExchangeAlgorithms { get; private set; }
public IDictionary<string, Type> Encryptions { get; private set; }
public IDictionary<string, Type> HmacAlgorithms { get; private set; }
public IDictionary<string, Type> HostKeyAlgorithms { get; private set; }
public IDictionary<string, Type> SupportedAuthenticationMethods { get; private set; }
public IDictionary<string, Type> 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<PrivateKeyFile> 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<string, Type>()
{
{"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<string, Type>()
{
{"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<string, Type>()
{
{"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<string, Type>()
{
{"ssh-rsa", typeof(CryptoPublicKeyRsa)},
{"ssh-dss", typeof(CryptoPublicKeyDss)},
};
this.SupportedAuthenticationMethods = new Dictionary<string, Type>()
{
{"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<string, Type>()
{
{"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<PrivateKeyFile>(keyFiles);
}
}
}
@@ -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.");
}
}
@@ -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;
}
}
}
@@ -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<PrivateKeyFile> 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<PrivateKeyFile>(keyFiles);
}
}
}
@@ -93,6 +93,8 @@
<Compile Include="Messages\Transport\KeyExchangeDhGroupExchangeInit.cs" />
<Compile Include="Messages\Transport\KeyExchangeDhGroupExchangeReply.cs" />
<Compile Include="Messages\Transport\KeyExchangeDhGroupExchangeRequest.cs" />
<Compile Include="PasswordConnectionInfo.cs" />
<Compile Include="PrivateKeyConnectionInfo.cs" />
<Compile Include="Security\CipherDES.cs" />
<Compile Include="Security\KeyExchangeDiffieHellmanGroupExchangeSha256.cs" />
<Compile Include="Security\HMac.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<Cipher>();
this.ServerCipher = this._serverCipherType.CreateInstance<Cipher>();
// 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<Cipher>();
this.ClientCipher = this._clientCipherType.CreateInstance<Cipher>();
// 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<HMac>();
this.ServerHMac = this._serverHmacAlgorithmType.CreateInstance<HMac>();
this.ServerHMac.Init(this.Hash(this.GenerateSessionKey(this.SharedKey, this.ExchangeHash, 'F', this.Session.SessionId)));
// Create client HMac
this.ClientHMac = this._cientHmacAlgorithmTypeName.CreateInstance<HMac>();
this.ClientHMac = this._cientHmacAlgorithmType.CreateInstance<HMac>();
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<Compressor>();
var compressor = this._compressionType.CreateInstance<Compressor>();
compressor.Init(this.Session);
this.Compressor = compressor;
}
if (!string.IsNullOrEmpty(this._decompressionTypeName))
if (this._decompressionType != null)
{
var decompressor = this._decompressionTypeName.CreateInstance<Compressor>();
var decompressor = this._decompressionType.CreateInstance<Compressor>();
decompressor.Init(this.Session);
@@ -48,7 +48,7 @@ namespace Renci.SshClient.Security
var data = bytes.Skip(4 + algorithmName.Length);
CryptoPublicKey key = this.Session.HostKeyAlgorithms[algorithmName].CreateInstance<CryptoPublicKey>();
CryptoPublicKey key = this.Session.ConnectionInfo.HostKeyAlgorithms[algorithmName].CreateInstance<CryptoPublicKey>();
key.Load(data);
@@ -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<PasswordChangeRequiredMessage>(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);
@@ -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<PublicKeyMessage>(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();
+15 -123
View File
@@ -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<ErrorEventArgs> ErrorOccured;
public event EventHandler<ConnectingEventArgs> Connecting;
public event EventHandler<EventArgs> Connected;
public event EventHandler<EventArgs> Disconnecting;
public event EventHandler<EventArgs> Disconnected;
@@ -372,18 +368,6 @@ namespace Renci.SshClient
#endregion
public IDictionary<string, string> KeyExchangeAlgorithms { get; private set; }
public IDictionary<string, string> Encryptions { get; private set; }
public IDictionary<string, string> HmacAlgorithms { get; private set; }
public IDictionary<string, string> HostKeyAlgorithms { get; private set; }
public IDictionary<string, string> SupportedAuthenticationMethods { get; private set; }
public IDictionary<string, string> CompressionAlgorithms { get; private set; }
/// <summary>
/// Initializes a new instance of the <see cref="Session"/> class.
/// </summary>
@@ -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<string, string>()
{
{"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<string, string>()
{
{"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<string, string>()
{
{"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<string, string>()
{
{"ssh-rsa", typeof(CryptoPublicKeyRsa).AssemblyQualifiedName},
{"ssh-dss", typeof(CryptoPublicKeyDss).AssemblyQualifiedName},
};
this.SupportedAuthenticationMethods = new Dictionary<string, string>()
{
{"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<string, string>()
{
{"none", string.Empty},
{"zlib", typeof(Zlib).AssemblyQualifiedName},
{"zlib@openssh.com", typeof(ZlibOpenSsh).AssemblyQualifiedName},
};
}
/// <summary>
@@ -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<string> 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<UserAuthentication>();
var authentication = this.ConnectionInfo.SupportedAuthenticationMethods[methodName].CreateInstance<UserAuthentication>();
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<KeyExchange>();
this._keyExchange = this.ConnectionInfo.KeyExchangeAlgorithms[keyExchangeAlgorithmName].CreateInstance<KeyExchange>();
// Start the algorithm implementation
this._keyExchange.Start(this, message);
@@ -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))
{
}
@@ -38,11 +38,6 @@ namespace Renci.SshClient
}
}
/// <summary>
/// Occurs when client is about to connect to the server.
/// </summary>
public event EventHandler<ConnectingEventArgs> Connecting;
public event EventHandler<AuthenticationEventArgs> Authenticating;
/// <summary>
@@ -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;
+2 -2
View File
@@ -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))
{
}
@@ -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)
{