using System; using System.Collections.Generic; using System.IO; using System.Collections.ObjectModel; using System.Text; namespace Renci.SshNet { /// /// Provides client connection to SSH server. /// public class SshClient : BaseClient { /// /// Holds the list of forwarded ports /// private List _forwardedPorts = new List(); /// /// Gets the list of forwarded ports. /// public IEnumerable ForwardedPorts { get { return this._forwardedPorts.AsReadOnly(); } } #region Constructors /// /// Initializes a new instance of the class. /// /// The connection info. /// is null. public SshClient(ConnectionInfo connectionInfo) : base(connectionInfo) { } /// /// Initializes a new instance of the class. /// /// Connection host. /// Connection port. /// Authentication username. /// Authentication password. /// is null. /// is invalid, or is null or contains whitespace characters. /// is not within and . public SshClient(string host, int port, string username, string password) : this(new PasswordConnectionInfo(host, port, username, password)) { } /// /// Initializes a new instance of the class. /// /// Connection host. /// Authentication username. /// Authentication password. /// is null. /// is invalid, or is null or contains whitespace characters. public SshClient(string host, string username, string password) : this(host, 22, username, password) { } /// /// Initializes a new instance of the class. /// /// Connection host. /// Connection port. /// Authentication username. /// Authentication private key file(s) . /// is null. /// is invalid, -or- is null or contains whitespace characters. /// is not within and . public SshClient(string host, int port, string username, params PrivateKeyFile[] keyFiles) : this(new PrivateKeyConnectionInfo(host, port, username, keyFiles)) { } /// /// Initializes a new instance of the class. /// /// Connection host. /// Authentication username. /// Authentication private key file(s) . /// is null. /// is invalid, -or- is null or contains whitespace characters. public SshClient(string host, string username, params PrivateKeyFile[] keyFiles) : this(host, 22, username, keyFiles) { } #endregion /// /// Called when client is disconnecting from the server. /// protected override void OnDisconnecting() { base.OnDisconnecting(); foreach (var port in this._forwardedPorts) { port.Stop(); } } /// /// Adds forwarded port to the list. /// /// Type of forwarded port to add /// The bound host. /// The bound port. /// The connected host. /// The connected port. /// /// Forwarded port /// /// or is null. /// or is invalid. /// or is not within and . /// Client is not connected. public T AddForwardedPort(string boundHost, uint boundPort, string connectedHost, uint connectedPort) where T : ForwardedPort, new() { if (boundHost == null) throw new ArgumentNullException("boundHost"); if (connectedHost == null) throw new ArgumentNullException("connectedHost"); if (!boundHost.IsValidHost()) throw new ArgumentException("boundHost"); if (!boundPort.IsValidPort()) throw new ArgumentOutOfRangeException("boundPort"); if (!connectedHost.IsValidHost()) throw new ArgumentException("connectedHost"); if (!connectedPort.IsValidPort()) throw new ArgumentOutOfRangeException("connectedPort"); // Ensure that connection is established. this.EnsureConnection(); T port = new T(); port.Session = this.Session; port.BoundHost = boundHost; port.BoundPort = boundPort; port.Host = connectedHost; port.Port = connectedPort; this._forwardedPorts.Add(port); return port; } /// /// Adds forwarded port to the list bound to "localhost". /// /// Type of forwarded port to add /// The bound port. /// The connected host. /// The connected port. /// /// is null. /// , or is invalid. /// or is not within and . /// Client is not connected. public T AddForwardedPort(uint boundPort, string connectedHost, uint connectedPort) where T : ForwardedPort, new() { return this.AddForwardedPort("localhost", boundPort, connectedHost, connectedPort); } /// /// Stops and removes the forwarded port from the list. /// /// Forwarded port. /// is null. public void RemoveForwardedPort(ForwardedPort port) { if (port == null) throw new ArgumentNullException("port"); // Stop port forwarding before removing it port.Stop(); this._forwardedPorts.Remove(port); } /// /// Creates the command to be executed. /// /// The command text. /// object. public SshCommand CreateCommand(string commandText) { return this.CreateCommand(commandText, Renci.SshNet.Common.ASCIIEncoding.Current); } /// /// Creates the command to be executed with specified encoding. /// /// The command text. /// The encoding to use for results. /// object which uses specified encoding. public SshCommand CreateCommand(string commandText, Encoding encoding) { // Ensure that connection is established. this.EnsureConnection(); return new SshCommand(this.Session, commandText, encoding); } /// /// Creates and executes the command. /// /// The command text. /// public SshCommand RunCommand(string commandText) { var cmd = this.CreateCommand(commandText); cmd.Execute(); return cmd; } /// /// Creates the shell. /// /// The input. /// The output. /// The extended output. /// Name of the terminal. /// The columns. /// The rows. /// The width. /// The height. /// The terminal mode. /// Size of the internal read buffer. /// public Shell CreateShell(Stream input, Stream output, Stream extendedOutput, string terminalName, uint columns, uint rows, uint width, uint height, string terminalMode, int bufferSize) { // Ensure that connection is established. this.EnsureConnection(); return new Shell(this.Session, input, output, extendedOutput, terminalName, columns, rows, width, height, terminalMode, bufferSize); } /// /// Creates the shell. /// /// The input. /// The output. /// The extended output. /// Name of the terminal. /// The columns. /// The rows. /// The width. /// The height. /// The terminal mode. /// public Shell CreateShell(Stream input, Stream output, Stream extendedOutput, string terminalName, uint columns, uint rows, uint width, uint height, string terminalMode) { return this.CreateShell(input, output, extendedOutput, terminalName, columns, rows, width, height, terminalMode, 1024); } /// /// Creates the shell. /// /// The input. /// The output. /// The extended output. /// public Shell CreateShell(Stream input, Stream output, Stream extendedOutput) { return this.CreateShell(input, output, extendedOutput, string.Empty, 0, 0, 0, 0, string.Empty, 1024); } /// /// Creates the shell. /// /// The encoding to use to send the input. /// The input. /// The output. /// The extended output. /// Name of the terminal. /// The columns. /// The rows. /// The width. /// The height. /// The terminal mode. /// Size of the internal read buffer. /// public Shell CreateShell(Encoding encoding, string input, Stream output, Stream extendedOutput, string terminalName, uint columns, uint rows, uint width , uint height , string terminalMode, int bufferSize) { // Ensure that connection is established. this.EnsureConnection(); var inputStream = new MemoryStream(); var writer = new StreamWriter(inputStream, encoding); writer.Write(input); writer.Flush(); inputStream.Seek(0, SeekOrigin.Begin); return this.CreateShell(inputStream, output, extendedOutput, terminalName, columns, rows, width, height, terminalMode, bufferSize); } /// /// Creates the shell. /// /// The encoding. /// The input. /// The output. /// The extended output. /// Name of the terminal. /// The columns. /// The rows. /// The width. /// The height. /// The terminal mode. /// public Shell CreateShell(Encoding encoding, string input, Stream output, Stream extendedOutput, string terminalName, uint columns, uint rows, uint width, uint height, string terminalMode) { return this.CreateShell(encoding, input, output, extendedOutput, terminalName, columns, rows, width, height, terminalMode, 1024); } /// /// Creates the shell. /// /// The encoding. /// The input. /// The output. /// The extended output. /// public Shell CreateShell(Encoding encoding, string input, Stream output, Stream extendedOutput) { return this.CreateShell(encoding, input, output, extendedOutput, string.Empty, 0, 0, 0, 0, string.Empty, 1024); } } }