A Secure Shell (SSH) library for .NET


Автор: Gal Tamir
Источник: http://www.codeproject.com

IIntroduction

Recently there was a need to connect to a SSH server from my C# code. I needed to perform a simple task: login to a remote Linux device, execute a command and read the response. I knew there were a number of free Java SSH libraries out there and I hoped to find a free .NET one that will allow me to do just that, but all I could find were commercial components. After experimenting with an open source Java SSH library called JSch I decided to try and port it to C# just for the sake of exercise. The result is the attached sharpSsh library and this article which explains how to use it.


Background

SSH (Secure Shell) is a protocol to log into another computer over a network, to execute commands in a remote machine, and to move files from one machine to another. It provides strong authentication and secure communications over unsecured channels. The JSch library is a pure Java implementation of the SSH2 protocol suite; It contains many features such as port forwarding, X11 forwarding, secure file transfer and supports numerous cipher and MAC algorithms. JSch is licensed under BSD style license.

My C# version is not a full port of JSch. I ported only the minimal required features in order to complete my simple task. The following list summarizes the supported features of the library:
• Key exchange: diffie-hellman-group-exchange-sha1, diffie-hellman-group1-sha1.
• Cipher: 3des-cbc
• MAC: hmac-md5
• Host key type: ssh-rsa and partial ssh-dss.
• Userauth: password, publickey (RSA)
• Generating RSA key pairs
• Changing the passphrase for a private key
• SCP and SFTP Please check my homepage for the latest version and feature list of SharpSSH.



What’s the difference between MVVM, MVP and MVC?

There is always some confusion about the differences between model-view-presenter, model-view-controller an MVVM pattern. So I try to define and distinguish them a bit more clearly.



Using the code

Let me begin with a small disclaimer. The code isn’t fully tested, and I cannot guarantee any level of performance, security or quality. The purpose of this library and article is to educate myself (and maybe you) about the SSH protocol and the differences between C# and Java. In order to provide the simplest API for SSH communication, I created two wrapper classes under the Tamir.SharpSsh namespace that encapsulates JSch’s internal structures:
• SshStream - A stream based class for reading and writing over the SSH channel.
• Scp - A class for handling file transfers over the SSH channel.



Reading and writing data over the SSH channel

The SshStream class makes reading and writing of data over an SSH channel as easy as any I/O read/write task. Its constructor gets three parameters: The remote hostname or IP address, a username and a password. It connects to the remote server as soon as it is constructed.

//Create a new SSH stream
SshStream s sh = new SshStream("remoteHost" , "username" , "password") ;
//..The SshStream hassuccessfullyestablished the connection .

Now, we can set some properties:

//Set the end of response matcher character ssh.Prompt = "#";
//Remove terminal emulation characters ssh.RemoveTerminalEmulationCharacters = true;

The Prompt property is a string that matches the end of a response. Setting this property is useful when using the ReadResponse() method which keeps reading and buffering data from the SSH channel until the Prompt string is matched in the response, only then will it return the result string. For example, a Linux shell prompt usually ends with '#' or '$', so after executing a command it will be useful to match these characters to detect the end of the command response (this property actually gets any regular expression pattern and matches it with the response, so it's possible to match more complex patterns such as "\[[^@]*@[^]]*]#\s" which matches the bash shell prompt [user@host dir]# of a Linux host). The default value of the Prompt property is "\n", which simply tells the ReadResponse() method to return one line of response.

The response string will typically contain escape sequence characters which are terminal emulation signals that instruct the connected SSH client how to display the response. However, if we are only interested in the 'clean' response content we can omit these characters by setting the RemoveTerminalEmulationCharacters property to true. Now, reading and writing to/from the SSH stream will be done as follows:

//Writing to the SSH channel
ssh.Write( command );
//Reading from the SSH channel
string response = ssh.ReadResponse();



Transferring files using SCP

Transferring files to and from an SSH server is pretty straightforward with the Scp class. The following snippet demonstrates how it's done:

//Create a new SCP instance
Scp scp = new Scp();
//Copy a file from local machine to remote SSH server
scp.To("C:\fileName", "remoteHost", "/pub/fileName", "username", "password");
//Copy a file from remote SSH server to local machine
scp.From("remoteHost", "/pub/fileName", "username", "password", "C:\fileName");

The Scp class also has some events for tracking the progress of file transfer:
• Scp.OnConnecting - Triggered on SSH connection initialization.
• Scp.OnStart - Triggered on file transfer start.
• Scp.OnEnd - Triggered on file transfer end.
• Scp.OnProgress - Triggered on file transfer progress update (The ProgressUpdateInterval property can be set to modify the progress update interval time in milliseconds).

© 2013, Saveli Bondini
Назад