mirror of
https://github.com/sshnet/SSH.NET.git
synced 2026-09-10 17:25:51 +00:00
Add KeepAliveRequestInfo class
Add EndOfWriteRequestInfo class Refactor channel request messages to allow custom channel reuqest support
This commit is contained in:
@@ -3,6 +3,7 @@ using System.Threading;
|
||||
using Renci.SshNet.Common;
|
||||
using Renci.SshNet.Messages;
|
||||
using Renci.SshNet.Messages.Connection;
|
||||
using System.Globalization;
|
||||
|
||||
namespace Renci.SshNet.Channels
|
||||
{
|
||||
@@ -540,7 +541,21 @@ namespace Renci.SshNet.Channels
|
||||
{
|
||||
if (e.Message.LocalChannelNumber == this.LocalChannelNumber)
|
||||
{
|
||||
this.OnRequest(e.Message.Info);
|
||||
if (this._session.ConnectionInfo.ChannelRequests.ContainsKey(e.Message.RequestName))
|
||||
{
|
||||
// Get request specific class
|
||||
RequestInfo requestInfo = this._session.ConnectionInfo.ChannelRequests[e.Message.RequestName];
|
||||
|
||||
// Load request specific data
|
||||
requestInfo.Load(e.Message.RequestData);
|
||||
|
||||
// Raise request specific event
|
||||
this.OnRequest(requestInfo);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, "Request '{0}' is not supported.", e.Message.RequestName));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ using System.Globalization;
|
||||
namespace Renci.SshNet.Channels
|
||||
{
|
||||
/// <summary>
|
||||
/// Implements "forwarded-tcpip" SSH channel.
|
||||
/// Implements Session SSH channel.
|
||||
/// </summary>
|
||||
internal class ChannelSession : Channel
|
||||
{
|
||||
@@ -271,6 +271,37 @@ namespace Renci.SshNet.Channels
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends eow@openssh.com request.
|
||||
/// </summary>
|
||||
/// <returns>true if request was successful; otherwise false.</returns>
|
||||
public bool SendEndOfWriteRequest()
|
||||
{
|
||||
this._channelRequestResponse.Reset();
|
||||
|
||||
this.SendMessage(new ChannelRequestMessage(this.RemoteChannelNumber, new EndOfWriteRequestInfo()));
|
||||
|
||||
this._channelRequestResponse.WaitOne();
|
||||
|
||||
return this._channelRequestSucces;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends keepalive@openssh.com request.
|
||||
/// </summary>
|
||||
/// <returns>true if request was successful; otherwise false.</returns>
|
||||
public bool SendKeepAliveRequest()
|
||||
{
|
||||
this._channelRequestResponse.Reset();
|
||||
|
||||
this.SendMessage(new ChannelRequestMessage(this.RemoteChannelNumber, new KeepAliveRequestInfo()));
|
||||
|
||||
this._channelRequestResponse.WaitOne();
|
||||
|
||||
return this._channelRequestSucces;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Called when channel request was successful
|
||||
/// </summary>
|
||||
|
||||
@@ -8,6 +8,7 @@ using Renci.SshNet.Messages.Authentication;
|
||||
using Renci.SshNet.Common;
|
||||
using System.Threading;
|
||||
using System.Net;
|
||||
using Renci.SshNet.Messages.Connection;
|
||||
namespace Renci.SshNet
|
||||
{
|
||||
/// <summary>
|
||||
@@ -68,6 +69,11 @@ namespace Renci.SshNet
|
||||
/// </summary>
|
||||
public IDictionary<string, Type> CompressionAlgorithms { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets supported channel requests for this connection.
|
||||
/// </summary>
|
||||
public IDictionary<string, RequestInfo> ChannelRequests { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets connection host.
|
||||
/// </summary>
|
||||
@@ -194,6 +200,22 @@ namespace Renci.SshNet
|
||||
{"zlib@openssh.com", typeof(ZlibOpenSsh)},
|
||||
};
|
||||
|
||||
this.ChannelRequests = new Dictionary<string, RequestInfo>()
|
||||
{
|
||||
{EnvironmentVariableRequestInfo.NAME, new EnvironmentVariableRequestInfo()},
|
||||
{ExecRequestInfo.NAME, new ExecRequestInfo()},
|
||||
{ExitSignalRequestInfo.NAME, new ExitSignalRequestInfo()},
|
||||
{ExitStatusRequestInfo.NAME, new ExitStatusRequestInfo()},
|
||||
{PseudoTerminalRequestInfo.NAME, new PseudoTerminalRequestInfo()},
|
||||
{ShellRequestInfo.NAME, new ShellRequestInfo()},
|
||||
{SignalRequestInfo.NAME, new SignalRequestInfo()},
|
||||
{SubsystemRequestInfo.NAME, new SubsystemRequestInfo()},
|
||||
{WindowChangeRequestInfo.NAME, new WindowChangeRequestInfo()},
|
||||
{X11ForwardingRequestInfo.NAME, new X11ForwardingRequestInfo()},
|
||||
{XonXoffRequestInfo.NAME, new XonXoffRequestInfo()},
|
||||
{EndOfWriteRequestInfo.NAME, new EndOfWriteRequestInfo()},
|
||||
{KeepAliveRequestInfo.NAME, new KeepAliveRequestInfo()},
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
+8
-78
@@ -15,32 +15,12 @@ namespace Renci.SshNet.Messages.Connection
|
||||
/// <value>
|
||||
/// The name of the request.
|
||||
/// </value>
|
||||
public string RequestName
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.Info.RequestName;
|
||||
}
|
||||
}
|
||||
public string RequestName { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the reply is needed.
|
||||
/// Gets channel request data.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if reply is needed; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
public bool WantReply
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.Info.WantReply;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets channel request information.
|
||||
/// </summary>
|
||||
public RequestInfo Info { get; private set; }
|
||||
public byte[] RequestData { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ChannelRequestMessage"/> class.
|
||||
@@ -58,7 +38,8 @@ namespace Renci.SshNet.Messages.Connection
|
||||
public ChannelRequestMessage(uint localChannelName, RequestInfo info)
|
||||
{
|
||||
this.LocalChannelNumber = localChannelName;
|
||||
this.Info = info;
|
||||
this.RequestName = info.RequestName;
|
||||
this.RequestData = info.GetBytes();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -68,59 +49,8 @@ namespace Renci.SshNet.Messages.Connection
|
||||
{
|
||||
base.LoadData();
|
||||
|
||||
var requestName = this.ReadString();
|
||||
var bytes = this.ReadBytes();
|
||||
|
||||
if (requestName == EnvironmentVariableRequestInfo.NAME)
|
||||
{
|
||||
this.Info = new EnvironmentVariableRequestInfo();
|
||||
}
|
||||
else if (requestName == ExecRequestInfo.NAME)
|
||||
{
|
||||
this.Info = new ExecRequestInfo();
|
||||
}
|
||||
else if (requestName == ExitSignalRequestInfo.NAME)
|
||||
{
|
||||
this.Info = new ExitSignalRequestInfo();
|
||||
}
|
||||
else if (requestName == ExitStatusRequestInfo.NAME)
|
||||
{
|
||||
this.Info = new ExitStatusRequestInfo();
|
||||
}
|
||||
else if (requestName == PseudoTerminalRequestInfo.NAME)
|
||||
{
|
||||
this.Info = new PseudoTerminalRequestInfo();
|
||||
}
|
||||
else if (requestName == ShellRequestInfo.NAME)
|
||||
{
|
||||
this.Info = new ShellRequestInfo();
|
||||
}
|
||||
else if (requestName == SignalRequestInfo.NAME)
|
||||
{
|
||||
this.Info = new SignalRequestInfo();
|
||||
}
|
||||
else if (requestName == SubsystemRequestInfo.NAME)
|
||||
{
|
||||
this.Info = new SubsystemRequestInfo();
|
||||
}
|
||||
else if (requestName == WindowChangeRequestInfo.NAME)
|
||||
{
|
||||
this.Info = new WindowChangeRequestInfo();
|
||||
}
|
||||
else if (requestName == X11ForwardingRequestInfo.NAME)
|
||||
{
|
||||
this.Info = new X11ForwardingRequestInfo();
|
||||
}
|
||||
else if (requestName == XonXoffRequestInfo.NAME)
|
||||
{
|
||||
this.Info = new XonXoffRequestInfo();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, "Request '{0}' is not supported.", requestName));
|
||||
}
|
||||
|
||||
this.Info.Load(bytes);
|
||||
this.RequestName = this.ReadString();
|
||||
this.RequestData = this.ReadBytes();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -131,7 +61,7 @@ namespace Renci.SshNet.Messages.Connection
|
||||
base.SaveData();
|
||||
|
||||
this.Write(this.RequestName);
|
||||
this.Write(this.Info.GetBytes());
|
||||
this.Write(this.RequestData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Renci.SshNet.Messages.Connection
|
||||
{
|
||||
public class EndOfWriteRequestInfo : RequestInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// Channel request name
|
||||
/// </summary>
|
||||
public const string NAME = "eow@openssh.com";
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of the request.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The name of the request.
|
||||
/// </value>
|
||||
public override string RequestName
|
||||
{
|
||||
get { return EndOfWriteRequestInfo.NAME; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="EndOfWriteRequestInfo"/> class.
|
||||
/// </summary>
|
||||
public EndOfWriteRequestInfo()
|
||||
{
|
||||
this.WantReply = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Renci.SshNet.Messages.Connection
|
||||
{
|
||||
public class KeepAliveRequestInfo : RequestInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// Channel request name
|
||||
/// </summary>
|
||||
public const string NAME = "keepalive@openssh.com";
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of the request.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The name of the request.
|
||||
/// </value>
|
||||
public override string RequestName
|
||||
{
|
||||
get { return KeepAliveRequestInfo.NAME; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="EndOfWriteRequestInfo"/> class.
|
||||
/// </summary>
|
||||
public KeepAliveRequestInfo()
|
||||
{
|
||||
this.WantReply = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -103,6 +103,8 @@
|
||||
<Compile Include="ForwardedPortLocal.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Messages\Connection\ChannelRequest\EndOfWriteRequestInfo.cs" />
|
||||
<Compile Include="Messages\Connection\ChannelRequest\KeepAliveRequestInfo.cs" />
|
||||
<Compile Include="Security\Algorithm.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
|
||||
Reference in New Issue
Block a user