|

Introduction
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.
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.
SshStream ssh = new SshStream("remoteHost", "username", "password");
Now, we can set some properties:
ssh.Prompt = "#";
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:
ssh.Write( command );
string response = ssh.ReadResponse();
Of course, it's still possible to use the SshStream's standard Read/Write I/O methods available in the System.IO.Stream API.
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:
Scp scp = new Scp();
scp.To("C:\fileName", "remoteHost",
"/pub/fileName", "username", "password");
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).
Running the examples
The demo project is a simple console application demonstrating the use of SshStream and Scp classes. It asks the user for the hostname, username and password for a remote SSH server and shows examples of a simple SSH session, and file transfers to/from a remote SSH machine.
Here is a screen shot of an SSH connection to a Linux shell:

And here is a file transfer from a Linux machine to my PC using SCP:

In the demo project zip file you will also find an examples directory containing some classes showing the use of the original JSch API. These examples were translated directly from the Java examples posted with the original JSch library and show the use of advanced options such as public key authentication, known hosts files, key generation, SFTP and others.
References
- SharpSSH Homepage - New versions and bug fixes will be posted here, so please check this page for the latest updates.
- JSch - JSch is a pure Java implementation of the SSH2 protocol suite. My C# library is based on this project.
- Mentalis.org - Mentalis.org contains some great .NET projects for security and networking. I used their HMAC and Diffie Hellman classes as part of my SSH implementation.
- Granados - A full featured open source SSH1 and SSH2 implementation in C#. I found this project after finishing my own library.
History
- 2005-Oct-16
- 2005-Oct-22
- Fixed two bugs in
Scp class.
- 2005-Oct-29
- Added the option to use DSA signatures ('ssh-dss') for authenticating the server during the key-exchange phase.
- 2005-Oct-29
- All future updates will be posted in my homepage.
| You must Sign In to use this message board. |
|
| | Msgs 1 to 25 of 823 (Total in Forum: 823) (Refresh) | FirstPrevNext |
|
|
 |
|
|
Hello, all! I have a strange issue with SharpSSH 1.1.1.13 I have no issues using SFTP session connect() method from my WinXP machine with a linux host (little-endian X86 PC), but when connecting to another linux server (unknown processor type and endianness), I get an exception in verify() method, line 84, SignatureDSA.cs. The error message is "Bad Data \r\n" and the stack trace is: at System.Security.Cryptography.DSACryptoServiceProvider._ImportKey(IntPtr hCSP, Int32 algid, DSACspObject data)\r\n at System.Security.Cryptography.DSACryptoServiceProvider.ImportParameters(DSAParameters parameters)\r\n at Tamir.SharpSsh.jsch.jce.SignatureDSA.verify(Byte[] sig) in D:\\installs\\SharpSSH-1.1.1.13.src\\SharpSSH-1.1.1.13.src\\SharpSSH\\jsch\\jce\\SignatureDSA.cs:line 84\r\n at Tamir.SharpSsh.jsch.DHG1.next(Buffer _buf) in D:\\installs\\SharpSSH-1.1.1.13.src\\SharpSSH-1.1.1.13.src\\SharpSSH\\jsch\\DHG1.cs:line 293\r\n at Tamir.SharpSsh.jsch.Session.connect(Int32 connectTimeout) in D:\\installs\\SharpSSH-1.1.1.13.src\\SharpSSH-1.1.1.13.src\\SharpSSH\\jsch\\Session.cs:line 279 I don't know anything about the server that's causing the issue, since I don't have control over that machine. I was thinking that the issue may be that the other side is big-endian, and the DSA signature being verified is coming in in big-endian byte order. Of course, this is a guess, and I might be totally off here. Does anyone have any suggestions on how to resolve the issue or what additional info is needed in order to help figure out what's going on? Thank you in advance. Regards, Mark.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Found out some more info about the server:
Session protocol = SSH-2 SSH implementation = 3.2.9.1 SSH Secure Shell (non-commercial) Encryption algorithm = aes Compression = No File transfer protocol = SFTP-3 Server host key fingerprint ssh-dss 1024
I now think the issue may be that ssh-dss is used, and if I understand correctly, there is only partial support for it in SharpSSH. I was wondering if someone can comment on this in more detail. Any help would be appreciated.
Regards, Mark.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
When using SharpSSH 1.1.1.13, I transfer a 2-3 gb compressed tar file via SFTP from ESX to Windows, then back to ESX and try to untar it and tar gives me this...
gzip: stdin: invalid compressed data--format violated tar: Unexpected EOF in archive tar: Unexpected EOF in archive tar: Error is not recoverable: exiting now
The bytes in the origional and the one with the problem match exactly, help!
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
I have more information...
I did some testing transfering text files. In each case, I uploaded the text file with WinSCP, and the same text file with SharpSSH. Also I only transfered in binary mode.
First I started with a null byte. Both the WinSCP version and SharpSSH version uploaded matched as far as the bytes and the md5. Then I moved on to a text file with all 255 characters in it, which also matched. Then moved on to a text file with 500 mb worth of each 255 characters in a line over and over again, which matched also.
Moving on to compressed files... I uploaded a 1 mb zip file from windows, and it matched with the one uploaded by winscp. Then tried a 50 mb file, and it was corrupt. The zip test told me it had crc errors. I did similar tests with gzip, bzip, and rar, all with errors and corrupt files. Uncompressed tars as well did not transfer properly. In each case, the file size matched but the md5 checksum did not.
I consulted every resource I had at my disposal, and the most common responces are..
- Transfer in binary mode only - Your ISP could be adding line breaks to the file - sharpssh is to blame - an error in openssh could be the cause, because it's not the newest version.
Any help would be greatly appreciated!
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
In Session.cs, in disconnect() line 1529, there is a possibility, in certain error conditions that connectThread will be null, like in premature host port closures, premature to what the library expected.
So all I did was add
if(connectThread !=null)
before
lock (connectThread) { ...
This will prevent the inner exception of the true error from being swallowed up.
Rob Achmann maker of .Net thingys
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
hello Tamir,
is there any kind of licence restriction to use your components in my projects ?
Regards!
Javier Nicolas(Argentina)
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
|
I connect via WiMax. I've had some connectivity issues with SharpSSH becuase of this.
I noticed that even though you establish a conection, the underlying objects are not ready yet.
The call to socket.getInputStream() would throw an internal NullReference Exception, even though the socket object is valid.
The following code accounts for this.
if (proxy == null) { Stream In = null; Stream Out = null; if (socket_factory == null) { socket = Util.createSocket(host, port, connectTimeout); // r_achmann 17AUG2008 : On a bad, or unstable connection (like WiMax) // (or perhaps it's the quality of the router?) // the GetInputStream call can initially fail System.DateTime endDT = System.DateTime.Now.AddSeconds(2); while ((In == null || Out == null) && System.DateTime.Now <= endDT) { if (In == null) { try { In = socket.getInputStream(); } catch { } } if (Out == null) { try { Out = socket.getInputStream(); } catch { } } } } else { socket = socket_factory.createSocket(host, port); In = socket_factory.getInputStream(socket); Out = socket_factory.getOutputStream(socket); }
Rob Achmann maker of .Net thingys
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Depending on something to happen over a number of iterations makes for a shakey foundation of solid architecture.
Lets do something better. This code can be improved by making the 2 seconds configurable.
C:\Projects\SharpSSH-1.1.1.13.src\SharpSSH\jsch\Channel.cs
public virtual void connect() { if(!session.isConnected()) { throw new JSchException("session is down"); } try { Buffer buf=new Buffer(100); Packet packet=new Packet(buf); // send // byte SSH_MSG_CHANNEL_OPEN(90) // string channel type // // uint32 sender channel // 0 // uint32 initial window size // 0x100000(65536) // uint32 maxmum packet size // 0x4000(16384) packet.reset(); buf.putByte((byte)90); buf.putString(this.type); buf.putInt(this.id); buf.putInt(this.lwsize); buf.putInt(this.lmpsize); session.write(packet);
// r_achmann 17AUG2008 : iterative dependancies are shakey. // int retry=1000; System.DateTime endDT = System.DateTime.Now.AddSeconds(2); while(this.getRecipient()==-1 && session.isConnected() && System.DateTime.Now <= endDT ) // retry > 0) { // r_achmann 17AUG2008 why try/catch on this?? So expensive Thread.sleep(50); //try{} //catch(Exception ee){} //retry--; }
Rob Achmann maker of .Net thingys
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Call me persnikity, I like to keep track of what the captured exception _really_ was, when throwing a new one...
For example in C:\Projects\SharpSSH-1.1.1.13.src\SharpSSH\jsch\PortWatcher.cs, in function getPort.
The catch for getByName can now store the real reason of the exception with
catch(Exception uhe) { throw new JSchException("PortForwardingL: invalid address "+address+" specified.", uhe); }
Now, your exception handlers can report the true issues to support personnel.
To achieve this, just add a couple of constructors to C:\Projects\SharpSSH-1.1.1.13.src\SharpSSH\java\Exception.cs
(Note that to access, System.Exception, you must use the namespace 'redirection' up in the 'using' reference
public Exception(Ex ex) : base( string.Empty, ex) { }
and
public Exception(string msg, Ex ex) : base(msg, ex) { }
Then, C:\Projects\SharpSSH-1.1.1.13.src\SharpSSH\jsch\JSchException.cs add public JSchException(string msg, Exception ex) : base(msg, ex) { }
It's just more refined.
R.
Rob Achmann maker of .Net thingys
modified on Saturday, August 23, 2008 10:47 PM
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
|

Anyone have a working AES256CBC.cs file yet?
Here is mine...can't seem to get it to work. What happens is that the s2ccipher blows up when it gets 'invalid data'... for user auth phase after key exchange. the j var ends up being some huge number above 60 million as it's place in the buffer is probably wrong. Thus the 'read' code sends an exception 'Invalid Data'
Any help appreciated!
//////////////////////////////////////////////////////////////// using System; using System.Security.Cryptography;
namespace Tamir.SharpSsh.jsch.jce { /*r_achmann 17AUG2008 this version if added to support AES 256 */ /* -*-mode:java; c-basic-offset:2; -*- */ /* Copyright (c) 2002,2003,2004 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
public class AES256CBC : Cipher { private int mode; private const int ivsize = 32; // RijndaelManaged insists on this private const int bsize = 16; private System.Security.Cryptography.RijndaelManaged rijndael; private ICryptoTransform cipher; public override int getIVSize() { return ivsize; } public override int getBlockSize() { return bsize; } public override void init(int mode, byte[] key, byte[] iv) { this.mode = mode; rijndael = new RijndaelManaged(); rijndael.Mode = CipherMode.CBC; rijndael.Padding = PaddingMode.Zeros; rijndael.BlockSize = 256; rijndael.KeySize = 256;
byte[] tmp; if (iv.Length != ivsize) { tmp=new byte[ivsize]; if (iv.Length > ivsize) Array.Copy(iv, 0, tmp, 0, tmp.Length); else Array.Copy(iv, 0, tmp, 0, iv.Length); //tmp = rijndael.IV; iv = tmp; } if (key.Length != bsize) { tmp=new byte[bsize]; if (key.Length > bsize) Array.Copy(key, 0, tmp, 0, tmp.Length); else Array.Copy(key, 0, tmp, 0, key.Length); // tmp = rijndael.Key; key = tmp; }
try { // SecretKeySpec keyspec=new SecretKeySpec(key, "AES"); // cipher=javax.crypto.Cipher.getInstance("AES/CBC/"+pad);
// cipher.init((mode==ENCRYPT_MODE? // javax.crypto.Cipher.ENCRYPT_MODE: // javax.crypto.Cipher.DECRYPT_MODE), // keyspec, new IvParameterSpec(iv)); cipher = (mode == ENCRYPT_MODE ? rijndael.CreateEncryptor(key, iv) : rijndael.CreateDecryptor(key, iv)); } catch (Exception e) { Console.WriteLine(e); cipher = null; } } public override void update(byte[] foo, int s1, int len, byte[] bar, int s2) { //cipher.update(foo, s1, len, bar, s2); cipher.TransformBlock(foo, s1, len, bar, s2); }
public override string ToString() { return "aes256-cbc"; } }
} ////////////////////////////////////////////////////
RAchmann maker of .Net thingys
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Please help me its very very urgent. What is wrong with this code
scp.From("esqa.moneris.com","/root/test.txt","store3", "store3","c:\test.txt");
i get error : Unknow error during file transfer.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Hi
I just had a project where I need to interactively work with multiple applications that I run from a shell commandline.. A command can take some time to return values, and it can return values in chunks (e.g. during login until you get the first prompt you have about 3 blocks of text that are returned.. ). The existing blocking way of reading from the socket, try to find a match, and read again works, except when you search for something that never is returned. In my scenario, this can happen as I do not always know in advance what the result will contain (e.g. there could be an error message.. in this case I'd want the expect to time out after a certain time, and then I'd dump what I've received so far to a logfile for analysis.).
In order to do this, I had to move from blocking to non blocking reading.. basically I have an asynchronous read thread that runs all the time and writes whatever is received to a StringBuffer.. and then my expect method just looks at the StringBuffer.
So I've made the following changes to SshShell.cs
First the new variables
private int timeout; private AsyncCallback callBackReceive = null; private AsyncCallback callBackSend = null; private byte[] buffer;
private StringBuilder terminalContent;
public String TerminalContent { get { return terminalContent.ToString(); } }
Then I've modified the Init method by adding the following:
if (this.callBackReceive == null) this.callBackReceive = new AsyncCallback(this.readFromStream); if (this.callBackSend == null) this.callBackSend = new AsyncCallback(this.writeToStream); this.buffer = new byte[1024 * 10];
Then we have the implementation of these callbacks:
/// /// implements the callback to write to the stream /// /// private void writeToStream(IAsyncResult ar) { if (ar == null) return; IO.EndWrite(ar); }
/// /// implements the callback to read from the stream /// reads the next chunk of data from the server and adds it to the virtual terminal /// /// private void readFromStream(IAsyncResult ar) { if (ar == null) return; int nbBytes = IO.EndRead(ar); if (nbBytes > 0) { lock (this.terminalContent) { string tmp = System.Text.Encoding.Default.GetString(this.buffer, 0, nbBytes); if (RemoveTerminalEmulationCharacters) tmp = HandleTerminalChars(tmp); this.terminalContent.Append(tmp); } IO.BeginRead(this.buffer, 0, this.buffer.Length, this.callBackReceive, null); } else this.Close(); }
I also had to override the OnConnected method in order to start the reading process
protected override void OnConnected() { base.OnConnected(); if (!m_redirectToConsole) // we have to use synchronous data sending in synchronous mode this.IO.BeginRead(this.buffer, 0, this.buffer.Length, this.readFromStream, null); }
And finally, I've added a new set of Expect methods that take a timeout parameter
public bool Expect(string pattern, int timeout) { return Expect( new Regex( Regex.Escape(pattern), RegexOptions.Singleline ), timeout); }
public bool Expect(Regex pattern, int timeout) { StringBuilder resp = new StringBuilder(); byte[] buff = new byte[1024]; Match match = null; DateTime endTime = DateTime.Now.AddSeconds((double)timeout); if (timeout == 0) endTime = DateTime.MaxValue; // this also blocks until a match has been found int sleepTime = timeout * 1000 / 25; do { lock (this.terminalContent) { match = pattern.Match(this.terminalContent.ToString()); } if (!match.Success) System.Threading.Thread.Sleep(sleepTime); } while(!match.Success && DateTime.Now.CompareTo(endTime) < 0); // also stops the searching when the operation has timed out return match.Success; }
I also have a new method to clear the contents of the screen (important if you're expecting a value that is already present in the current stringbuffer:
/// /// cleans the contents of the screen /// public void CleanScreen() { lock (this.terminalContent) { this.terminalContent.Remove(0, this.terminalContent.Length); } }
I've done a few successful test runs and so far things appear to be working as expected so hopefully this will be useful for others as well (I think I saw a few people who are trying to do things where they could profit from this code.
Cheers Stephan
P.S. You'll see that I've prepared asynchronous writing as well.. I took an existing Telnet class I'm using in various projects as template and it does both asynch reading and writing but somehow when I tried asynchronous writing the writing would block.. so I've gone back to synchronous writing for the moment as it does the job just fine but if you have some time to experiment, you need to uncomment the commented lin in this code block and comment out the currently active two lines:
public virtual void Write(byte[] buffer, int offset, int count) { //this.IO.BeginWrite(buffer, offset, count, this.writeToStream, null); IO.Write(buffer, offset, count); IO.Flush(); }
|
| Sign In·View Thread·PermaLink | 5.00/5 (1 vote) |
|
|
|
 |
|
|
I keep getting an error when transfering large files, ones that are three gb or more. It keeps saying 'Index was outside the bounds of the array'. Works beautifully on smaller files (5 mb), but 3 gb files it fails.
Looks like it's failing here. Tamir.SharpSsh.Scp.From(String remoteFile, String localPath, Boolean _recursive)
modified on Wednesday, July 30, 2008 4:37 PM
|
| Sign In·View Thread·PermaLink | 1.00/5 (1 vote) |
|
|
|
 |
|
|
All,
I need to connect to a remote Box and execute a command. While executing the command, the output should be streamed and displayed as and when it comes. It should not wait for the command execution to complete and then display the output. All this should be done in non-interactive mode , with password authentication .
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
All,
I need to connect to a remote Box and execute a command. While executing the command, the output should be streamed and displayed as and when it comes. It should not wait for the command execution to complete and then display the output. All this should be done in non-interactive mode , with password authentication .
|
| Sign In·View Thread·PermaLink | 5.00/5 (1 vote) |
|
|
|
 |
|
|
I am using asp.Net, C#. I want change password of SFTP after a certain interval. I am working on Windows XP SshShell is not working here. Is there a way to do?
atul
modified on Friday, July 11, 2008 7:31 AM
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
When using the demo application, option 2 (SCP local to remote) i input the following:
local: c:\io.sys remote io.sys
it draws the progressbar and writes: connecting to host...
verify: False
Server or user error???
|
| Sign In·View Thread·PermaLink | 4.00/5 (2 votes) |
|
|
|
 |
|
|
 |
|
|
Hello Tamir, Last week i was looking for a SSH library for .NET. I found your SharpSSH and its cool. But now i am facing a problem. I am not able to connect to the remote host and i am getting an error in SshStream.cs class and it says "Count should be a positive value" I dont know why i am getting this error. But it would be really helpful if you/someone can help me out. I am just willing to log into the SSH terminal and just have to run few commands. Here is the code i am using: SshStream ssh = new SshStream("host", "username", "password"); ssh.Prompt = "#"; ssh.RemoveTerminalEmulationCharacters = true; ssh.Write(command); string response = ssh.ReadResponse(); Label1.Text = response; ssh.Close();
MNK
|
| Sign In·View Thread·PermaLink | 2.67/5 (3 votes) |
|
|
|
 |
|
|
Hi, First of all. Thank you for sharing out your knowledge. You done a good job. I am now comparing the response time between the direct communication through the putty SSH console with the application that is using this SSH library.
Both of the connection is to call up a c++ function at the linux server. And the time different for the application SSH library can take up to 10 times than the console.
Is there any where that i can eliminate or reduce this timing response? Thanks.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
When connecting to a MoveIT DMZ v5 server we are able to connect, but when we try and move files or check remote folder locations we receive an error
"Exception of type 'Tamir.SharpSsh.jsch.SftpException' was thrown."
This occurs when we are using either our implementation of SharpSSH or using the SharpSSHTest.exe binary downloaded from Sourceforge.
We are able to successfully connect and transfer files to another MoveIT DMZ v3 server without any issue.
Any assistance (or directions in which to look) would be highly appreciated.
Thanks
AJ
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Tamir,
I noticed that my OpenSSH server is sending a "\r" character after every 80 characters of output. Digging a little deeper, I've found that the "window-change" command must be sent to the server from the client to notify it of a size change (http://www.ietf.org/rfc/rfc4254.txt[^]).
I also found that there is a RequestWindowChange class within Tamir.SharpSsh.jsch. My project is using SshShell in the Tamir.SharpSsh namespace. Is there a way to access the RequestWindowChange this way? I want to control the size of the client window, allowing the column length to change as the user resizes the window. My client application uses a RichTextBox. Any suggestions?
Thanks, Dan
|
| Sign In·View Thread·PermaLink | |
| | | | |