Possible to have C# SSH client communicate with a NodeJS SSH Server?

Viewed 699

I have a C# application that needs to run certain commands on a piece of hardware over SSH. The application is using SSH.Net to make the connection, send the command, and the read the result. I have this working if I connect to my local machine using OpenSSH. Finally, I wanted to go a step further and setup my own SSH server so I could simulate multiple hardware devices at one time (need to simulate having 50+ devices to SSH into).

For this I have setup a simple SSH server using nodejs and the ssh2 package. So far I have the client connected, authenticated (all connections are accepted for now), and I can see a session object being created. Although where I'm hitting a wall is with the execution of commands sent by the client. I noticed that ssh2 has an event for exec on the session object but this never seems to trigger (regardless of what i put in SSH.Net's ShellStream).

The C# client code that initiates the connection is the following (command is already defined that the command string to be executed):

using(SshClient client = new SshClient(hostname, port, username, password))
{
    try
    {
        client.ErrorOccurred += Client_ErrorOccurred;
        client.Connect();

        ShellStream shellStream = client.CreateShellStream("xterm", Columns, Rows, Width, Height, BufferSize, terminalModes);

        var initialPrompt = await ReadDataAsync(shellStream);

        // The command I write to the stream will get executed on OpenSSH
        // but not on the nodejs SSH server
        shellStream.WriteLine(command);
        var output = await ReadDataAsync(shellStream);
        var results = $"Command: {command} \nResult: {output}";

        client.Disconnect();

        Console.WriteLine($"Prompt: {initialPrompt} \n{results}\n");
    }
    catch (Exception ex)
    {
        Console.WriteLine($"Exception during SSH connection: {ex.ToString()}");
    }
}

The nodejs server code that set ups the ssh2 server is following:

new ssh2.Server({
  hostKeys: [fs.readFileSync('host.key')]
}, function(client) {
  console.log('Client connected!');

  client.on('authentication', function(ctx) {
    ctx.accept();
  }).on('ready', function() {
    console.log('Client authenticated!');

    client.on('session', function(accept, reject) {
      var session = accept();

      // Code gets here but never triggers the exec
      session.once('exec', function(accept, reject, info) {
        console.log('Client wants to execute: ' + inspect(info.command));
        var stream = accept();
        stream.write('returned result\n');
        stream.exit(0);
        stream.end();
      });
    });
  }).on('end', function() {
    console.log('Client disconnected');
  });
}).listen(port, '127.0.0.1', function() {
  console.log('Listening on port ' + this.address().port);
});

I have seen various ssh2 client examples invoking a client.exec function but I was assuming that it did not matter that my client was not using the ssh2 node package. Is there something that I'm missing here?

1 Answers
Related