using Renci.SshNet; using Renci.SshNet.Common; using Step.CmsConnectManager.Exceptions; using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading; using static Step.CmsConnectManager.CMSConnectConstants; namespace Step.CmsConnectManager { public class SSHAdapter { // Internal Private Variable private string Host; private string Username; private string Password; public SSHAdapter(string host, string username, string password) { this.Host = host; this.Username = username; this.Password = password; } // Override sendCommand for single command public List SendSSHCommand(string command) { return SendSSHCommand(new List { command }); } // Send multiple SSH Command public List SendSSHCommand(IEnumerable command) { SshCommand sshCmd; List returnedValues = new List(); // Create the SSH Gateway SshClient _sshGateway = new SshClient(this.Host, this.Username, this.Password); try { // Connect _sshGateway.Connect(); foreach (string cmd in command) { // Run command sshCmd = _sshGateway.RunCommand(cmd); // Add return values if esists returnedValues.AddRange(sshCmd.Result.Split(new[] { "\n" }, StringSplitOptions.None)); // Check for errors if (sshCmd.ExitStatus != 0) { _sshGateway.Disconnect(); throw new GatewayException("Internal Gateway Error: " + sshCmd.Error); } } // Disconnect _sshGateway.Disconnect(); } catch (SocketException e) { throw new GatewayException("Connection Error: - Host:" + this.Host); } catch (SshConnectionException e) { throw new GatewayException("Connection Error: - Host:" + this.Host); } catch (ProxyException e) { throw new GatewayException("Proxy Error: - Host:" + this.Host); } catch (SshAuthenticationException e) { throw new GatewayException("Authentication Error: - Host:" + this.Host); } catch (SshException e) { throw new GatewayException("Internal command Error: - Host:" + this.Host); } catch (GatewayException e) { throw new GatewayException(e.Message); } catch (Exception e) { throw new GatewayException("Unknown Error: " + e); } return returnedValues; } // Send REBOOT Command public void SendSSHReboot(int seconds) { // Send SSH Command SendSSHCommand(SSH_GW_REBOOT_COMMAND + seconds); // Wait the time for reboot Thread.Sleep((seconds + 5) * 1000); // Save actual timestamp DateTime nowAfterReboot = DateTime.Now; //Create the Instance SshClient _sshGateway = new SshClient(this.Host, this.Username, this.Password); // Phase 1 Wait Disconnection Cycle bool disconnected = false; do { try { // If TimeSpan > TOT MIN -> Exception if ((DateTime.Now - nowAfterReboot) > TimeSpan.FromMinutes(REBOOT_MINUTES_MAX)) throw new GatewayException("Timeout Error during reboot - Gateway has never been rebooted"); // Try Connection _sshGateway.Connect(); Thread.Sleep(REBOOT_MSWAIT_BETWEEN_OP); _sshGateway.Disconnect(); } catch (SocketException e) { // Not Connected disconnected = true; } catch (SshConnectionException e) { // Not Connected disconnected = true; } catch (SshException e) { // Not Connected disconnected = true; } catch (GatewayException e) { // Error throw new GatewayException(e.Message); } catch (Exception e) { // Error throw new GatewayException("Unknown Error during reboot: " + e); } } while (!disconnected); // Phase 2 Wait Re-connection Cycle bool connected = false; do { try { // If TimeSpan > TOT MIN -> Exception if ((DateTime.Now - nowAfterReboot) > TimeSpan.FromMinutes(REBOOT_MINUTES_MAX)) throw new GatewayException("Timeout Error during reboot - Gateway not found during reboot"); // Try Connection _sshGateway.Connect(); connected = true; } catch (SocketException e) { //Not Connected Thread.Sleep(REBOOT_MSWAIT_BETWEEN_OP); } catch (SshConnectionException e) { //Not Connected Thread.Sleep(REBOOT_MSWAIT_BETWEEN_OP); } catch (SshException e) { //Not Connected Thread.Sleep(REBOOT_MSWAIT_BETWEEN_OP); } catch (GatewayException e) { //Error throw new GatewayException(e.Message); } catch (Exception e) { //Error throw new GatewayException("Unknown Error during reboot: " + e); } } while (!connected); _sshGateway.Disconnect(); } // SSH command generator for Proxy setting public string GenerateSshProxyCommand(GatewayProxyConfiguration configuration) { StringBuilder command = new StringBuilder(SSH_SET_PROXY_COMMAND); // Call the script without an argument will disable the Proxy if (configuration.hasProxy) { /* 1St parameter. Must be one of these: * - Address:Port * - User:Password@Address:Port */ // Setup Username & password if needed if (!string.IsNullOrWhiteSpace(configuration.username) && !string.IsNullOrWhiteSpace(configuration.password)) command.Append(configuration.username).Append(":").Append(configuration.password).Append("@"); // Setup Address & Port command.Append(configuration.address).Append(":").Append(configuration.port).Append(" "); /* 2nd parameter. Must be: * "no_proxy1,no_proxy2,…,no_proxyN" */ if (configuration.noproxyAddresses != null) { command.Append("\""); command.Append(string.Join(",", configuration.noproxyAddresses)); command.Append("\""); } } return command.ToString(); } // SSH command generator for Network setting public string GenerateSshNetworkCommand(GatewayNetworkConfiguration configuration) { StringBuilder command = new StringBuilder(SSH_SET_NETWORK_COMMAND); if (configuration.hasDhcp) { command.Append("DHCP"); } else { // Set IP address / Netmask IPNetwork tempIpNetw = IPNetwork.Parse(configuration.ipAddress, configuration.netMaskAddress); command.Append(configuration.ipAddress).Append("/").Append(tempIpNetw.Cidr).Append(" "); if (configuration.defaultGatewayAddress != null) command.Append(configuration.defaultGatewayAddress); } return command.ToString(); } // SSH command generator for Dns setting public string GenerateSshDnsCommand(GatewayNetworkConfiguration configuration) { StringBuilder command = new StringBuilder(SSH_SET_DNSIP_COMMAND); if (configuration.dnsAddresses != null) command.Append(string.Join(",", configuration.dnsAddresses)); return command.ToString(); } // SSH command generator for Dns-Suffix setting public string GenerateSshDnsSuffxCommand(GatewayNetworkConfiguration configuration) { StringBuilder command = new StringBuilder(SSH_SET_DNSSUFFIX_COMMAND); if (configuration.dnsPrefixes != null) command.Append(string.Join(",", configuration.dnsPrefixes)); return command.ToString(); } } }