test-ssh.js 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. var SSH2Stream = require('../lib/ssh');
  2. var utils = require('../lib/utils');
  3. var parseKey = utils.parseKey;
  4. var genPubKey = utils.genPublicKey;
  5. var basename = require('path').basename;
  6. var assert_ = require('assert');
  7. var inherits = require('util').inherits;
  8. var inspect = require('util').inspect;
  9. var TransformStream = require('stream').Transform;
  10. var fs = require('fs');
  11. var group = basename(__filename, '.js') + '/';
  12. var t = -1;
  13. var SERVER_KEY = fs.readFileSync(__dirname + '/fixtures/ssh_host_rsa_key');
  14. var HOST_KEYS = { 'ssh-rsa': makeServerKey(SERVER_KEY) };
  15. function SimpleStream() {
  16. TransformStream.call(this);
  17. this.buffer = '';
  18. }
  19. inherits(SimpleStream, TransformStream);
  20. SimpleStream.prototype._transform = function(chunk, encoding, cb) {
  21. this.buffer += chunk.toString('binary');
  22. cb(null, chunk);
  23. };
  24. var tests = [
  25. // client-side tests
  26. { run: function() {
  27. var algos = ['ssh-dss', 'ssh-rsa', 'ecdsa-sha2-nistp521'];
  28. var client = new SSH2Stream({
  29. algorithms: {
  30. serverHostKey: algos
  31. }
  32. });
  33. var clientBufStream = new SimpleStream();
  34. var clientReady = false;
  35. var server = new SSH2Stream({
  36. server: true,
  37. hostKeys: HOST_KEYS
  38. });
  39. var serverBufStream = new SimpleStream();
  40. var serverReady = false;
  41. function onNEWKEYS() {
  42. if (this === client) {
  43. assert(!clientReady, 'Already received client NEWKEYS event');
  44. clientReady = true;
  45. } else {
  46. assert(!serverReady, 'Already received server NEWKEYS event');
  47. serverReady = true;
  48. }
  49. if (clientReady && serverReady) {
  50. var traffic = clientBufStream.buffer;
  51. var algoList = algos.join(',');
  52. var re = new RegExp('\x00\x00\x00'
  53. + hexByte(algoList.length)
  54. + algoList);
  55. assert(re.test(traffic), 'Unexpected client algorithms');
  56. traffic = serverBufStream.buffer;
  57. assert(/\x00\x00\x00\x07ssh-rsa/.test(traffic),
  58. 'Unexpected server algorithms');
  59. next();
  60. }
  61. }
  62. client.on('NEWKEYS', onNEWKEYS);
  63. server.on('NEWKEYS', onNEWKEYS);
  64. client.pipe(clientBufStream)
  65. .pipe(server)
  66. .pipe(serverBufStream)
  67. .pipe(client);
  68. },
  69. what: 'Custom algorithms'
  70. },
  71. { run: function() {
  72. var serverIdent = 'testing \t';
  73. var expectedFullIdent = 'SSH-2.0-' + serverIdent;
  74. var client = new SSH2Stream({});
  75. client.on('header', function(header) {
  76. assert(header.identRaw === expectedFullIdent,
  77. '\nSaw: ' + inspect(header.identRaw) + '\n'
  78. + 'Expected: ' + inspect(expectedFullIdent));
  79. next();
  80. });
  81. var server = new SSH2Stream({
  82. server: true,
  83. hostKeys: HOST_KEYS,
  84. ident: serverIdent
  85. });
  86. client.pipe(server).pipe(client);
  87. },
  88. what: 'Remote ident is not trimmed'
  89. }
  90. ];
  91. function makeServerKey(raw) {
  92. var privateKey = parseKey(raw);
  93. return {
  94. privateKey: privateKey,
  95. publicKey: genPubKey(privateKey)
  96. };
  97. }
  98. function hexByte(n) {
  99. return String.fromCharCode(n);
  100. }
  101. function assert(expression, msg) {
  102. msg || (msg = 'failed assertion');
  103. assert_(expression, makeMsg(tests[t].what, msg));
  104. }
  105. function next() {
  106. if (Array.isArray(process._events.exit))
  107. process._events.exit = process._events.exit[1];
  108. if (++t === tests.length)
  109. return;
  110. var v = tests[t];
  111. v.run.call(v);
  112. }
  113. function makeMsg(what, msg) {
  114. return '[' + group + what + ']: ' + msg;
  115. }
  116. process.once('exit', function() {
  117. assert_(t === tests.length,
  118. makeMsg('_exit',
  119. 'Only finished ' + t + '/' + tests.length + ' tests'));
  120. });
  121. next();