mirror of
https://github.com/sshnet/SSH.NET.git
synced 2026-09-10 09:15:47 +00:00
Execute command callback on different thread
Add ConnectingEventArgs to allow more control during connection stage
This commit is contained in:
@@ -3,13 +3,13 @@ namespace Renci.SshClient.Tests
|
||||
{
|
||||
public static class ConnectionData
|
||||
{
|
||||
public static string Host { get { return "152.54.8.155"; } }
|
||||
public static string Host { get { return "oleg-centos.edc.renci.org"; } }
|
||||
|
||||
public static int Port { get { return 22; } }
|
||||
|
||||
public static string Username { get { return "oleg"; } }
|
||||
public static string Username { get { return "tester"; } }
|
||||
|
||||
public static string Password { get { return "Maya2kap#"; } }
|
||||
public static string Password { get { return "tester"; } }
|
||||
|
||||
public static string RsaKeyFilePath { get { return @"RSA key path"; } }
|
||||
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Renci.SshClient.Common
|
||||
{
|
||||
public class ConnectingEventArgs : EventArgs
|
||||
{
|
||||
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; }
|
||||
|
||||
public string Host { get; set; }
|
||||
|
||||
public int Port { get; set; }
|
||||
|
||||
public string Username { get; set; }
|
||||
|
||||
public string Password { get; set; }
|
||||
|
||||
public PrivateKeyFile KeyFile { get; set; }
|
||||
|
||||
public TimeSpan Timeout { get; set; }
|
||||
|
||||
public int RetryAttempts { get; set; }
|
||||
|
||||
public int MaxSessions { get; set; }
|
||||
|
||||
public ConnectingEventArgs(
|
||||
IDictionary<string, string> keyExchangeAlgorithms,
|
||||
IDictionary<string, string> encryptions,
|
||||
IDictionary<string, string> hmacAlgorithms,
|
||||
IDictionary<string, string> hostKeyAlgorithms,
|
||||
IDictionary<string, string> supportedAuthenticationMethods,
|
||||
IDictionary<string, string> compressionAlgorithms)
|
||||
{
|
||||
this.KeyExchangeAlgorithms = keyExchangeAlgorithms;
|
||||
this.Encryptions = encryptions;
|
||||
this.HmacAlgorithms = hmacAlgorithms;
|
||||
this.HostKeyAlgorithms = hostKeyAlgorithms;
|
||||
this.SupportedAuthenticationMethods = supportedAuthenticationMethods;
|
||||
this.CompressionAlgorithms = compressionAlgorithms;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -64,6 +64,7 @@
|
||||
<Compile Include="Common\ChannelEventArgs.cs" />
|
||||
<Compile Include="Common\ChannelOpenFailedEventArgs.cs" />
|
||||
<Compile Include="Common\ChannelRequestEventArgs.cs" />
|
||||
<Compile Include="Common\ConnectingEventArgs.cs" />
|
||||
<Compile Include="Common\SshConnectionException.cs" />
|
||||
<Compile Include="Common\SshOperationTimeoutException.cs" />
|
||||
<Compile Include="Messages\Connection\ChannelOpen\ChannelOpenInfo.cs" />
|
||||
|
||||
@@ -220,7 +220,7 @@ namespace Renci.SshClient
|
||||
|
||||
public event EventHandler<ErrorEventArgs> ErrorOccured;
|
||||
|
||||
public event EventHandler<EventArgs> Connecting;
|
||||
public event EventHandler<ConnectingEventArgs> Connecting;
|
||||
|
||||
public event EventHandler<EventArgs> Connected;
|
||||
|
||||
@@ -450,25 +450,49 @@ namespace Renci.SshClient
|
||||
if (this.IsConnected)
|
||||
return;
|
||||
|
||||
if (this.Connecting != null)
|
||||
{
|
||||
// TODO: Create custom ConnectingEventArgs to allow to pass different connection parameters
|
||||
this.Connecting(this, new EventArgs());
|
||||
}
|
||||
|
||||
lock (this)
|
||||
{
|
||||
// If connected dont connect again
|
||||
// If connected don't connect again
|
||||
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.Host = this.ConnectionInfo.Host;
|
||||
eventArgs.Port = this.ConnectionInfo.Port;
|
||||
eventArgs.Username = this.ConnectionInfo.Username;
|
||||
eventArgs.Password = this.ConnectionInfo.Password;
|
||||
eventArgs.KeyFile = this.ConnectionInfo.KeyFile;
|
||||
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.Host = eventArgs.Host;
|
||||
this.ConnectionInfo.Port = eventArgs.Port;
|
||||
this.ConnectionInfo.Username = eventArgs.Username;
|
||||
this.ConnectionInfo.Password = eventArgs.Password;
|
||||
this.ConnectionInfo.KeyFile = eventArgs.KeyFile;
|
||||
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(this.ConnectionInfo.Timeout);
|
||||
connectResult.AsyncWaitHandle.WaitOne(eventArgs.Timeout);
|
||||
|
||||
this._socket.EndConnect(connectResult);
|
||||
|
||||
@@ -554,7 +578,7 @@ namespace Renci.SshClient
|
||||
foreach (var methodName in this.SupportedAuthenticationMethods.Keys)
|
||||
{
|
||||
var userAuthentication = this.SupportedAuthenticationMethods[methodName].CreateInstance<UserAuthentication>();
|
||||
|
||||
|
||||
userAuthentication.Init(this);
|
||||
|
||||
if (userAuthentication.Execute())
|
||||
|
||||
@@ -5,6 +5,7 @@ using System.Text;
|
||||
using System.IO;
|
||||
using Renci.SshClient.Sftp;
|
||||
using Renci.SshClient.Security;
|
||||
using Renci.SshClient.Common;
|
||||
|
||||
namespace Renci.SshClient
|
||||
{
|
||||
@@ -37,6 +38,11 @@ namespace Renci.SshClient
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when client is about to connect to the server.
|
||||
/// </summary>
|
||||
public event EventHandler<ConnectingEventArgs> Connecting;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SshBaseClient"/> class.
|
||||
/// </summary>
|
||||
@@ -60,6 +66,7 @@ namespace Renci.SshClient
|
||||
}
|
||||
|
||||
this.Session = new Session(this.ConnectionInfo);
|
||||
this.Session.Connecting += Session_Connecting;
|
||||
this.Session.Connect();
|
||||
|
||||
this.OnConnected();
|
||||
@@ -73,6 +80,7 @@ namespace Renci.SshClient
|
||||
this.OnDisconnecting();
|
||||
|
||||
this.Session.Disconnect();
|
||||
this.Session.Connecting -= Session_Connecting;
|
||||
|
||||
this.OnDisconnected();
|
||||
}
|
||||
@@ -117,6 +125,15 @@ namespace Renci.SshClient
|
||||
|
||||
}
|
||||
|
||||
private void Session_Connecting(object sender, ConnectingEventArgs e)
|
||||
{
|
||||
if (this.Connecting != null)
|
||||
{
|
||||
this.Connecting(this, e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#region IDisposable Members
|
||||
|
||||
private bool _isDisposed = false;
|
||||
|
||||
@@ -8,6 +8,7 @@ using Renci.SshClient.Common;
|
||||
using Renci.SshClient.Messages;
|
||||
using Renci.SshClient.Messages.Connection;
|
||||
using Renci.SshClient.Messages.Transport;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Renci.SshClient
|
||||
{
|
||||
@@ -203,8 +204,8 @@ namespace Renci.SshClient
|
||||
this._asyncResult.IsCompleted = true;
|
||||
if (this._callback != null)
|
||||
{
|
||||
// TODO: Execute this method on different thread since it will be run on message listener
|
||||
this._callback(this._asyncResult);
|
||||
// Execute callback on different thread
|
||||
Task.Factory.StartNew(() => { this._callback(this._asyncResult); });
|
||||
}
|
||||
((EventWaitHandle)_asyncResult.AsyncWaitHandle).Set();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user