Search code examples
node.jssshssh2

Nodejs ssh2 server detect keystrokes


I'm trying to craete an interactive ssh server in nodejs which can handle a keypress on the client side like in a normal linux ssh session when you start an mc and afte you can use the arrow keys. I found the ssh2 package, but it can parse the data in the server side only after the 'enter' keypresses. How can I detect the y/n keypresses in this demo code without pressing the enter key?

var fs = require('fs');
var username = null;
var ssh2 = require('ssh2');

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

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

    client.on('session', function(accept, reject) {
      var session = accept();
      session.once('shell', function(accept, reject, info) {
        var stream = accept();
        stream.write("Do you want to continue? Y/N ");

        stream.on('data', function(data) {
          var args = data.toString();
          switch(args[0])
          {
            case "y":
              stream.write("Your choice: y\n");
              break;
            case "n":
              stream.write("Your choice: n\n");
              break;
            default:
              stream.stderr.write("Error!\n");
              break;
          }
          if(typeof stream != 'undefined')
          {
            stream.write("$ ");
          }
        });
      });
    });
  }).on('end', function() {
    console.log('Client disconnected');
  });
}).listen(2222, '127.0.0.1', function() {
  console.log('Listening on port ' + this.address().port);
});

Solution

  • Most SSH clients will only send individual keystrokes if they were able to allocate a pseudo-TTY on the server side. Otherwise they assume the server can only handle line-delimited input.

    By default, ssh2.Server will automatically reject any requests that your code is not handling, so for pseudo-TTY requests you need to listen for the 'pty' event on the session object and accept the request.

    Be aware though that by accepting such requests, you are acknowledging you will be able to appropriately handle any special escape sequences specific to the terminal type sent in the 'pty' request.