You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
179 lines
7.0 KiB
179 lines
7.0 KiB
|
4 weeks ago
|
using System;
|
||
|
|
using System.Collections.Generic;
|
||
|
|
using System.Collections.Concurrent;
|
||
|
|
using System.Text;
|
||
|
|
using System.Threading;
|
||
|
|
using System.Threading.Tasks;
|
||
|
|
using Renci.SshNet;
|
||
|
|
|
||
|
|
namespace EGFramework{
|
||
|
|
public class EGSsh : IModule, IProtocolSend, IProtocolReceived
|
||
|
|
{
|
||
|
|
public Dictionary<string,SshClient> SshClientDevices { set; get; } = new Dictionary<string, SshClient>();
|
||
|
|
|
||
|
|
public string ErrorLogs { set; get; }
|
||
|
|
|
||
|
|
public Encoding StringEncoding { set; get; } = Encoding.UTF8;
|
||
|
|
|
||
|
|
public ConcurrentQueue<ResponseMsg> ResponseMsgs { set; get; } = new ConcurrentQueue<ResponseMsg>();
|
||
|
|
|
||
|
|
public int TimeOutDelay = 5000;
|
||
|
|
public void Init()
|
||
|
|
{
|
||
|
|
this.EGRegisterSendAction(request=>{
|
||
|
|
if(request.protocolType == ProtocolType.SSHClient){
|
||
|
|
if(request.req.ToProtocolData() != null && request.req.ToProtocolData() != ""){
|
||
|
|
this.SendStringData(request.sender,request.req.ToProtocolData());
|
||
|
|
}else if(request.req.ToProtocolByteData() != null && request.req.ToProtocolByteData().Length > 0){
|
||
|
|
this.SendByteData(request.sender,request.req.ToProtocolByteData());
|
||
|
|
}
|
||
|
|
}
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// Connect Ssh Server by using username and passwd
|
||
|
|
/// </summary>
|
||
|
|
public async Task<bool> ConnectSsh(string host,string username,string password){
|
||
|
|
try{
|
||
|
|
//Reconnect
|
||
|
|
if(SshClientDevices.ContainsKey(host)){
|
||
|
|
if(SshClientDevices[host].IsConnected){
|
||
|
|
return true;
|
||
|
|
}else{
|
||
|
|
CancellationTokenSource sourceReconnect = new CancellationTokenSource();
|
||
|
|
CancellationToken tokenReconnect = sourceReconnect.Token;
|
||
|
|
tokenReconnect.Register(() => EG.Print("Ssh connect timeout!"));
|
||
|
|
await SshClientDevices[host].ConnectAsync(tokenReconnect);
|
||
|
|
if(!SshClientDevices[host].IsConnected){
|
||
|
|
return false;
|
||
|
|
}else{
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
//First Connect
|
||
|
|
SshClient client = new SshClient(host, username, password);
|
||
|
|
CancellationTokenSource source = new CancellationTokenSource();
|
||
|
|
CancellationToken token = source.Token;
|
||
|
|
token.Register(() => EG.Print("Ssh connect timeout!"));
|
||
|
|
source.CancelAfter(TimeOutDelay);
|
||
|
|
await client.ConnectAsync(token);
|
||
|
|
if(!client.IsConnected){
|
||
|
|
return false;
|
||
|
|
}else{
|
||
|
|
SshClientDevices.Add(host,client);
|
||
|
|
}
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
catch(Exception e){
|
||
|
|
ErrorLogs = "[ssh connect error]" + e.ToString();
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// Connect Ssh Server by using private key file
|
||
|
|
/// </summary>
|
||
|
|
public async Task<bool> ConnectSsh(string host,string username,PrivateKeyFile keyFile){
|
||
|
|
try{
|
||
|
|
//Reconnect
|
||
|
|
if(SshClientDevices.ContainsKey(host)){
|
||
|
|
if(SshClientDevices[host].IsConnected){
|
||
|
|
return true;
|
||
|
|
}else{
|
||
|
|
CancellationTokenSource sourceReconnect = new CancellationTokenSource();
|
||
|
|
CancellationToken tokenReconnect = sourceReconnect.Token;
|
||
|
|
tokenReconnect.Register(() => EG.Print("Ssh connect timeout!"));
|
||
|
|
await SshClientDevices[host].ConnectAsync(tokenReconnect);
|
||
|
|
if(!SshClientDevices[host].IsConnected){
|
||
|
|
return false;
|
||
|
|
}else{
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
//First Connect
|
||
|
|
SshClient client = new SshClient(host, username, keyFile);
|
||
|
|
CancellationTokenSource source = new CancellationTokenSource();
|
||
|
|
CancellationToken token = source.Token;
|
||
|
|
token.Register(() => EG.Print("Ssh connect timeout!"));
|
||
|
|
source.CancelAfter(TimeOutDelay);
|
||
|
|
await client.ConnectAsync(token);
|
||
|
|
if(!client.IsConnected){
|
||
|
|
return false;
|
||
|
|
}else{
|
||
|
|
SshClientDevices.Add(host,client);
|
||
|
|
}
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
catch(Exception e){
|
||
|
|
ErrorLogs = "[ssh connect error]" + e.ToString();
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
public void DisconnectSsh(string host){
|
||
|
|
if(SshClientDevices.ContainsKey(host)){
|
||
|
|
if (SshClientDevices[host].IsConnected)
|
||
|
|
{
|
||
|
|
SshClientDevices[host].Disconnect();
|
||
|
|
SshClientDevices[host].Dispose();
|
||
|
|
SshClientDevices.Remove(host);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public ConcurrentQueue<ResponseMsg> GetReceivedMsg()
|
||
|
|
{
|
||
|
|
return ResponseMsgs;
|
||
|
|
}
|
||
|
|
|
||
|
|
public void SendByteData(string destination, byte[] data)
|
||
|
|
{
|
||
|
|
if(SshClientDevices.ContainsKey(destination)){
|
||
|
|
if (SshClientDevices[destination].IsConnected)
|
||
|
|
{
|
||
|
|
SshCommand cmd = SshClientDevices[destination].RunCommand(StringEncoding.GetString(data));
|
||
|
|
ResponseMsg receivedMsgs = new ResponseMsg(cmd.Result,StringEncoding.GetBytes(cmd.Result),destination, ProtocolType.SSHClient);
|
||
|
|
ResponseMsgs.Enqueue(receivedMsgs);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public void SendStringData(string destination, string data)
|
||
|
|
{
|
||
|
|
if(SshClientDevices.ContainsKey(destination)){
|
||
|
|
if (SshClientDevices[destination].IsConnected)
|
||
|
|
{
|
||
|
|
SshCommand cmd = SshClientDevices[destination].RunCommand(data);
|
||
|
|
ResponseMsg receivedMsgs = new ResponseMsg(cmd.Result,StringEncoding.GetBytes(cmd.Result),destination, ProtocolType.SSHClient);
|
||
|
|
ResponseMsgs.Enqueue(receivedMsgs);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public void SetEncoding(Encoding textEncoding)
|
||
|
|
{
|
||
|
|
this.StringEncoding = textEncoding;
|
||
|
|
}
|
||
|
|
|
||
|
|
public IArchitecture GetArchitecture()
|
||
|
|
{
|
||
|
|
return EGArchitectureImplement.Interface;
|
||
|
|
//throw new System.NotImplementedException();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public static class CanGetEGSShClientExtension{
|
||
|
|
public static EGSsh EGSsh(this IEGFramework self){
|
||
|
|
return self.GetModule<EGSsh>();
|
||
|
|
}
|
||
|
|
|
||
|
|
public static SshClient EGGetSshClient(this IEGFramework self,string host){
|
||
|
|
return self.GetModule<EGSsh>().SshClientDevices[host];
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|