var SSH2Stream = require('../lib/ssh'); var fs = require('fs'); var path = require('path'); var inspect = require('util').inspect; var inherits = require('util').inherits; var TransformStream = require('stream').Transform; var assert = require('assert'); var t = -1; var group = path.basename(__filename, '.js') + '/'; var fixturesdir = path.join(__dirname, 'fixtures'); var HOST_KEY_RSA = fs.readFileSync(path.join(fixturesdir, 'openssh_new_rsa')); var SERVER_CONFIG = { server: true, hostKeys: { 'ssh-rsa': HOST_KEY_RSA } }; function SimpleStream() { TransformStream.call(this); this.buffer = ''; } inherits(SimpleStream, TransformStream); SimpleStream.prototype._transform = function(chunk, encoding, cb) { this.buffer += chunk.toString('binary'); cb(); }; var tests = [ { run: function() { var what = this.what; var serverError = false; var server = new SSH2Stream(SERVER_CONFIG); var client = new SimpleStream(); client.pipe(server).pipe(client); server.on('error', function(err) { serverError = err; assert(err.message === 'Protocol version not supported', makeMsg(what, 'Wrong error message')); }).on('end', function() { assert(client.buffer === server.config.ident + '\r\n', makeMsg(what, 'Wrong server ident: ' + inspect(client.buffer))); assert(serverError, makeMsg(what, 'Expected server error')); next(); }); client.push('SSH-1.0-aaa\r\n'); }, what: 'Incompatible client SSH protocol version' }, { run: function() { var what = this.what; var serverError = false; var server = new SSH2Stream(SERVER_CONFIG); var client = new SimpleStream(); client.pipe(server).pipe(client); server.on('error', function(err) { serverError = err; assert(err.message === 'Bad identification start', makeMsg(what, 'Wrong error message')); }).on('end', function() { assert(client.buffer === server.config.ident + '\r\n', makeMsg(what, 'Wrong server ident: ' + inspect(client.buffer))); assert(serverError, makeMsg(what, 'Expected server error')); next(); }); client.push('LOL-2.0-asdf\r\n'); }, what: 'Malformed client protocol identification' }, { run: function() { var what = this.what; var serverError = false; var server = new SSH2Stream(SERVER_CONFIG); var client = new SimpleStream(); client.pipe(server).pipe(client); server.on('error', function(err) { serverError = err; assert(err.message === 'Max identification string size exceeded', makeMsg(what, 'Wrong error message')); }).on('end', function() { assert(client.buffer === server.config.ident + '\r\n', makeMsg(what, 'Wrong server ident: ' + inspect(client.buffer))); assert(serverError, makeMsg(what, 'Expected server error')); next(); }); var ident = 'SSH-2.0-'; for (var i = 0; i < 30; ++i) ident += 'foobarbaz'; ident += '\r\n'; client.push(ident); }, what: 'SSH client protocol identification too long (> 255 characters)' }, { run: function() { var what = this.what; var serverError = false; var server = new SSH2Stream(SERVER_CONFIG); var client = new SimpleStream(); client.pipe(server).pipe(client); server.on('error', function(err) { serverError = err; assert(err.message === 'Bad packet length', makeMsg(what, 'Wrong error message')); }).on('end', function() { assert(client.buffer.length, makeMsg(what, 'Expected server data')); assert(serverError, makeMsg(what, 'Expected server error')); next(); }); client.push('SSH-2.0-asdf\r\n'); // 500,000 byte packet_length client.push(Buffer.from([0x00, 0x07, 0xA1, 0x20, 0x00, 0x00, 0x00, 0x00])); }, what: 'Bad packet length (max)' }, { run: function() { var what = this.what; var serverError = false; var server = new SSH2Stream(SERVER_CONFIG); var client = new SimpleStream(); client.pipe(server).pipe(client); server.on('error', function(err) { serverError = err; assert(err.message === 'Bad packet length', makeMsg(what, 'Wrong error message')); }).on('end', function() { assert(client.buffer.length, makeMsg(what, 'Expected server data')); assert(serverError, makeMsg(what, 'Expected server error')); next(); }); client.push('SSH-2.0-asdf\r\n'); client.push(Buffer.from([0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00])); }, what: 'Bad packet length (min)' }, ]; function next() { if (Array.isArray(process._events.exit)) process._events.exit = process._events.exit[1]; if (++t === tests.length) return; var v = tests[t]; v.run.call(v); } function makeMsg(what, msg) { return '[' + group + what + ']: ' + msg; } process.once('exit', function() { assert(t === tests.length, makeMsg('_exit', 'Only finished ' + t + '/' + tests.length + ' tests')); }); next();