Using SSH as data transport layer only

0 votes
asked Jul 17 by rexh (200 points)

How do I do if all I need is raw data send and receive over SSH?

Following is one way to use SSH as a pure data transport layer.

  public Test()
  {
     var ssh = new Rebex.Net.Ssh();
     ssh.Connect(sHost, nPort);
     ssh.Login(sUsername, sPassword);
     Scripting scripting = ssh.StartScripting();
     scripting.Terminal.DataReceived += Terminal_DataReceived;
     while (scripting.Process(int.MaxValue) != TerminalState.Disconnected);
  }
  private void Terminal_DataReceived(object sender, DataReceivedEventArgs e)
  {
     // process the e.RawData
  }

This is not the most efficient way because of the overhead incurred by all the data decoding provided by the scripting and the screen construction of the VirtualTerminal. I will implement my own decoding, etc.

1 Answer

0 votes
answered Jul 17 by Lukas Matyska (47,190 points)
selected Jul 17 by rexh
 
Best answer

If you want to access raw SSH channel using low-level API, you can use IShellChannelFactory.CreateShellChannel() method.

It can be used like this:

var ssh = new Ssh();
ssh.Connect(...);
ssh.Login(...);

var factory = (IShellChannelFactory)ssh;
var options = new TerminalOptions() { TerminalName = "vt100" };
var channel = factory.CreateShellChannel(options, 80, 24);

Using given channel, you can use:

  • Poll() - to determine state of the channel
  • Receive() - to receive raw data sent by server
  • Send() - to send raw data to server

Just to demonstrate how it can be used, a very simple console SSH client can be written like this:

var buffer = new byte[8 * 1024];
while (true)
{
    switch (channel.Poll(50 * 1000))
    {
        case PollResult.NoData:
            if (!Console.KeyAvailable)
                break;
            string command = Console.ReadLine();
            byte[] commandRaw = Encoding.UTF8.GetBytes(command + "\r");
            channel.Send(commandRaw, 0, commandRaw.Length);
            break;

        case PollResult.DataAvailable:
            int n = channel.Receive(buffer, 0, buffer.Length);
            Console.Write(Encoding.UTF8.GetString(buffer, 0, n));
            break;

        case PollResult.Closed:
            Console.WriteLine("Disconnected");
            return;
    }
}
commented Jul 17 by rexh (200 points)
Thank you very much Lukas!
commented Jul 27 by wowa (100 points)
Lukas,

I have the same need - we have a set up with one Windows PC communicating with Ubuntu server by 6-7 console connections simultanuously (having not so fast data exchange over all of them in parallel), and we want just to secure them with SSH, so it seems to be the same task as in this topic. Now, if we need only this type of simple communications (without any sophisticated scripting abilities, virtual terminals, etc), what is the minimum component/module set that we should buy to be able to achieve this?
commented Jul 27 by Lukas Matyska (47,190 points)
The product which covers the above functionality is Rebex Terminal Emulation: https://www.rebex.net/terminal-emulation.net/purchase.aspx
commented Sep 6 by rexh (200 points)
I have couple questions regarding the SshChannel.
What is the ExtendedDataReceived event for? (What is extended data?)

Does the SendBreak simply send the 0xFF 0xF3 to the host?
What is it for and what is the meaning of breaklength parameter?

Thanks!
commented Sep 6 by Lukas Matyska (47,190 points)
I have created new question for your comment.
Please see my answer at https://forum.rebex.net/8980/sshchannel-extendeddatareceived-sendbreak-breaklength
commented Sep 6 by rexh (200 points)
Thank you Lukas!
...