ssh2shell 1.9.10 → 2.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/ssh2shell.js CHANGED
@@ -18,7 +18,9 @@
18
18
 
19
19
  SSH2Shell.prototype.command = "";
20
20
 
21
- SSH2Shell.prototype.hosts = [];
21
+ SSH2Shell.prototype._hosts = [];
22
+
23
+ SSH2Shell.prototype._sshToNextHost = false;
22
24
 
23
25
  SSH2Shell.prototype._primaryhostSessionText = "";
24
26
 
@@ -61,7 +63,7 @@
61
63
  }
62
64
  this.idleTimer = setTimeout((function(_this) {
63
65
  return function() {
64
- return _this.emit('commandTimeout', _this.command, _this._buffer, _this._stream, _this._connection);
66
+ return _this.emit('commandTimeout', _this.command, _this._buffer, _this._stream, _this.connection);
65
67
  };
66
68
  })(this), this.idleTime);
67
69
  } else if (this.command.length < 1 && !this.standardPrompt.test(this._buffer)) {
@@ -76,15 +78,9 @@
76
78
  clearTimeout(_this.idleTimer);
77
79
  }
78
80
  if (!_this.sshObj.disableColorFilter) {
79
- if (_this.sshObj.verbose && _this.sshObj.debug) {
80
- _this.emit('msg', (_this.sshObj.server.host + ": text formatting filter: ") + _this.sshObj.textColorFilter + ", filtered: " + _this.textColorFilter.test(_this._buffer));
81
- }
82
81
  _this._buffer = _this._buffer.replace(_this.textColorFilter, "");
83
82
  }
84
83
  if (!_this.sshObj.disableASCIIFilter) {
85
- if (_this.sshObj.verbose && _this.sshObj.debug) {
86
- _this.emit('msg', (_this.sshObj.server.host + ": Non-standard ASCII filtered: ") + _this.asciiFilter.test(_this._buffer));
87
- }
88
84
  _this._buffer = _this._buffer.replace(_this.asciiFilter, "");
89
85
  }
90
86
  switch (true) {
@@ -93,7 +89,7 @@
93
89
  _this.emit('msg', _this.sshObj.server.host + ": Sudo command data");
94
90
  }
95
91
  return _this._processPasswordPrompt();
96
- case _this.command.length > 0 && _this.command.indexOf("ssh ") !== -1:
92
+ case _this.sshObj.sshToNextHost && _this.command.length > 0 && _this.command.indexOf("ssh ") === 0:
97
93
  if (_this.sshObj.debug) {
98
94
  _this.emit('msg', _this.sshObj.server.host + ": SSH command data");
99
95
  }
@@ -117,7 +113,7 @@
117
113
  _this.emit('msg', "Data processing: data received timeout");
118
114
  }
119
115
  return _this.idleTimer = setTimeout(function() {
120
- return _this.emit('commandTimeout', _this.command, _this._buffer, _this._stream, _this._connection);
116
+ return _this.emit('commandTimeout', _this.command, _this._buffer, _this._stream, _this.connection);
121
117
  }, _this.idleTime);
122
118
  }
123
119
  };
@@ -148,7 +144,7 @@
148
144
  switch (true) {
149
145
  case passwordPrompt && !this.sshObj.server.password:
150
146
  if (this.sshObj.debug) {
151
- this.emit('msg', this.sshObj.server.host + ": Sudo password prompt no password");
147
+ this.emit('msg', this.sshObj.server.host + ": Sudo password prompt no password set");
152
148
  }
153
149
  return this._resetFromSudoError();
154
150
  case passwordPrompt && !this.sshObj.pwSent:
@@ -177,7 +173,7 @@
177
173
  return this._resetFromSudoError();
178
174
  case standardPrompt:
179
175
  if (this.sshObj.debug) {
180
- this.emit('msg', this.sshObj.server.host + ": Sudo prompt: Standard prompt detected");
176
+ this.emit('msg', this.sshObj.server.host + ": Sudo password accepted");
181
177
  }
182
178
  this.sshObj.pwSent = false;
183
179
  if (this.sshObj.verbose) {
@@ -241,14 +237,17 @@
241
237
  return this._runExit();
242
238
  } else {
243
239
  this.emit('msg', this.sshObj.server.host + ": SSH no prompt was not detected");
244
- if (this.sshObj.verbose && !this.sshObj.server.hasOwnProperty("passPhrase")) {
245
- this.emit('msg', this.sshObj.server.host + ": SSH password prompt " + this.sshObj.passwordPrompt);
240
+ if (this.sshObj.verbose) {
241
+ this.emit('msg', this.sshObj.server.host + ": SSH response: " + response);
242
+ }
243
+ if (this.sshObj.verbose && !this.sshObj.server.hasOwnProperty("password")) {
244
+ this.emit('msg', this.sshObj.server.host + ": SSH password prompt: " + this.sshObj.passwordPrompt);
246
245
  }
247
246
  if (this.sshObj.verbose && this.sshObj.server.hasOwnProperty("passPhrase")) {
248
- this.emit('msg', this.sshObj.server.host + ": SSH passphrase prompt " + this.sshObj.passphrasePrompt);
247
+ this.emit('msg', this.sshObj.server.host + ": SSH passphrase prompt: " + this.sshObj.passphrasePrompt);
249
248
  }
250
249
  if (this.sshObj.verbose) {
251
- this.emit('msg', this.sshObj.server.host + ": SSH standard prompt " + this.sshObj.standardPrompt);
250
+ this.emit('msg', this.sshObj.server.host + ": SSH standard prompt: " + this.sshObj.standardPrompt);
252
251
  }
253
252
  return this._runExit();
254
253
  }
@@ -260,9 +259,16 @@
260
259
  if (this.sshObj.debug) {
261
260
  this.emit('msg', this.sshObj.server.host + ": SSH complete: normal prompt");
262
261
  }
262
+ if (this.sshObj.showBanner) {
263
+ this.sshObj.sessionText += "\n " + response;
264
+ }
263
265
  this.sshObj.exitCommands.push("exit");
264
266
  this.emit('msg', "" + this.sshObj.connectedMessage);
265
267
  this.emit('msg', "" + this.sshObj.readyMessage);
268
+ if (this.sshObj.debug) {
269
+ this.emit('msg', this.sshObj.server.host + ": SSH complete: next command");
270
+ }
271
+ this.sshObj.sshToNextHost = false;
266
272
  return this._nextCommand();
267
273
  } else if (passwordPrompt || passphrasePrompt) {
268
274
  this.emit('msg', this.sshObj.server.host + ": SSH authentication failed");
@@ -286,7 +292,7 @@
286
292
  this.emit('msg', (this.sshObj.server.host + ": SSH auth failed: Using ") + using);
287
293
  }
288
294
  if (this.sshObj.verbose) {
289
- this.emit('msg', this.sshObj.server.host + ": SSH resonse: " + response);
295
+ this.emit('msg', this.sshObj.server.host + ": SSH response: " + response);
290
296
  }
291
297
  if (this._connections.length > 0) {
292
298
  return this._previousHost();
@@ -330,7 +336,7 @@
330
336
  SSH2Shell.prototype._commandComplete = function() {
331
337
  var response;
332
338
  response = this._buffer.trim();
333
- if (this.command !== "" && this.command !== "exit" && this.command.indexOf("ssh ") === -1) {
339
+ if (this.command !== "" && this.command !== "exit" && this.sshObj.sshToNextHost !== true) {
334
340
  if (this.sshObj.verbose) {
335
341
  this.emit('msg', this.sshObj.server.host + ": Command complete:\nCommand:\n " + this.command + "\nResponse: " + response);
336
342
  }
@@ -396,7 +402,7 @@
396
402
  if (this.sshObj.debug) {
397
403
  this.emit('msg', this.sshObj.server.host + ": Reload previous host");
398
404
  }
399
- return this._loadDefaults(this._runExit);
405
+ return this._runExit();
400
406
  } else {
401
407
  return this._runExit();
402
408
  }
@@ -411,24 +417,32 @@
411
417
  if (this.sshObj.debug) {
412
418
  this.emit('msg', this.sshObj.server.host + ": Clearing previous event handlers");
413
419
  }
420
+ if (this.sshObj.debug) {
421
+ this.emit('msg', this.sshObj.server.host + ": Remove previous event handlers");
422
+ }
423
+ this._removeEvents();
414
424
  this._connections.push(this.sshObj);
415
425
  this.sshObj = nextHost;
416
426
  return this._initiate(this._sshConnect);
417
427
  };
418
428
 
419
- SSH2Shell.prototype._nextPrimaryHost = function(callback) {
420
- if (typeIsArray(this.hosts) && this.hosts.length > 0) {
429
+ SSH2Shell.prototype._nextPrimaryHost = function(connect) {
430
+ if (this._hosts.length > 0) {
421
431
  if (this.sshObj.server) {
422
432
  if (this.sshObj.debug) {
423
433
  this.emit('msg', this.sshObj.server.host + ": Current primary host");
424
434
  }
435
+ if (this.sshObj.debug) {
436
+ this.emit('msg', this.sshObj.server.host + ": Remove previous event handlers");
437
+ }
438
+ this._removeEvents();
425
439
  }
426
- this.sshObj = this.hosts.shift();
440
+ this.sshObj = this._hosts.shift();
427
441
  this._primaryhostSessionText = this.sshObj.server.host + ": ";
428
442
  if (this.sshObj.debug) {
429
443
  this.emit('msg', this.sshObj.server.host + ": Next primary host");
430
444
  }
431
- return this._initiate(callback);
445
+ return this._initiate(connect);
432
446
  } else {
433
447
  if (this.sshObj.debug) {
434
448
  this.emit('msg', this.sshObj.server.host + ": No more primary hosts");
@@ -487,6 +501,7 @@
487
501
  sshOptions += ' -o "StrictHostKeyChecking=no"';
488
502
  sshOptions += " -p " + this.sshObj.server.port;
489
503
  this.sshObj.sshAuth = false;
504
+ this.sshObj.sshToNextHost = true;
490
505
  this.command = "ssh " + sshFlags + " " + sshOptions + " " + this.sshObj.server.userName + "@" + this.sshObj.server.host;
491
506
  if (this.sshObj.debug) {
492
507
  this.emit('msg', this.sshObj.server.host + ": SSH command: connect");
@@ -504,6 +519,9 @@
504
519
  }
505
520
  this.command = this.sshObj.exitCommands.pop();
506
521
  if (this._connections && this._connections.length > 0) {
522
+ if (this.sshObj.verbose) {
523
+ this.emit('msg', this.sshObj.server.host + ": Primary host: " + this._connections[0].server.host);
524
+ }
507
525
  this._connections[0].sessionText += "\n" + this.sshObj.server.host + ": " + this.sshObj.sessionText;
508
526
  }
509
527
  return this._runCommand(this.command);
@@ -536,18 +554,29 @@
536
554
  };
537
555
 
538
556
  SSH2Shell.prototype._removeEvents = function() {
539
- if (this.sshObj.debug) {
540
- this.emit('msg', this.sshObj.server.host + ": Clearing host event handlers");
541
- }
542
- this.removeAllListeners('keyboard-interactive');
543
- this.removeAllListeners("error");
557
+
558
+ /*
559
+ if @sshObj.debug
560
+ @.emit 'msg', "#{@sshObj.server.host}: Event handler count:"
561
+ @.emit 'msg', "keyboard-interactive: " + (@.listenerCount 'keyboard-interactive')
562
+ @.emit 'msg', "error: " + (@.listenerCount "error")
563
+ @.emit 'msg', "data: " + (@.listenerCount "data")
564
+ @.emit 'msg', "stderrData: " + (@.listenerCount "stderrData")
565
+ @.emit 'msg', "end: " + (@.listenerCount 'end')
566
+ @.emit 'msg', "commandProcessing: " + (@.listenerCount 'commandProcessing')
567
+ @.emit 'msg', "commandComplete: " + (@.listenerCount 'commandComplete')
568
+ @.emit 'msg', "commandTimeout: " + (@.listenerCount 'commandTimeout')
569
+ @.emit 'msg', "msg: " + (@.listenerCount 'msg')
570
+ */
544
571
  if (typeof this.sshObj.onData === 'function') {
545
572
  this.removeListener("data", this.sshObj.onData);
546
573
  }
574
+ this.removeAllListeners("error");
547
575
  if (typeof this.sshObj.onStderrData === 'function') {
548
576
  this.removeListener("stderrData", this.sshObj.onStderrData);
549
577
  }
550
578
  this.removeAllListeners('end');
579
+ this.removeAllListeners('keyboard-interactive');
551
580
  this.removeAllListeners('commandProcessing');
552
581
  this.removeAllListeners('commandComplete');
553
582
  this.removeAllListeners('commandTimeout');
@@ -587,10 +616,11 @@
587
616
  this.onCommandComplete = bind(this.onCommandComplete, this);
588
617
  this.onCommandProcessing = bind(this.onCommandProcessing, this);
589
618
  this._callback = bind(this._callback, this);
590
- if (typeIsArray(hosts)) {
591
- this.hosts = hosts;
619
+ SSH2Shell.__super__.constructor.call(this, hosts);
620
+ if (typeIsArray(hosts) && hosts.length > 0) {
621
+ this._hosts = hosts;
592
622
  } else {
593
- this.hosts = [hosts];
623
+ this._hosts = [hosts];
594
624
  }
595
625
  this.ssh2Client = require('ssh2').Client;
596
626
  this.on("newPrimmaryHost", this._nextPrimaryHost);
@@ -604,80 +634,72 @@
604
634
  return console.error(data);
605
635
  };
606
636
  })(this));
607
- this._allSessions = "";
608
- }
609
-
610
- SSH2Shell.prototype._initiate = function(callback) {
611
- this._removeEvents();
612
- if (this.sshObj.msg && this.sshObj.msg.send && typeof this.sshObj.msg.send === 'function') {
613
- this.on("msg", this.sshObj.msg.send);
614
- } else if (typeof this.sshObj.msg === 'function') {
615
- this.on("msg", this.sshObj.msg);
616
- } else {
617
- this.on("msg", (function(_this) {
618
- return function(message) {
619
- return console.log(message);
620
- };
621
- })(this));
622
- }
623
- this._loadDefaults();
624
- if (this.sshObj.debug) {
625
- this.emit('msg', this.sshObj.server.host + ": initiate");
626
- }
627
- this.on("keyboard-interactive", (function(_this) {
628
- return function(name, instructions, instructionsLang, prompts, finish) {
629
- var str;
630
- if (_this.sshObj.debug) {
631
- _this.emit('msg', _this.sshObj.server.host + ": Class.keyboard-interactive");
632
- }
633
- if (_this.sshObj.verbose) {
634
- _this.emit('msg', "name: " + name);
635
- _this.emit('msg', "instructions: " + instructions);
636
- str = JSON.stringify(prompts, null, 4);
637
- return _this.emit('msg', "Prompts object: " + str);
638
- }
639
- };
640
- })(this));
641
637
  this.on("error", (function(_this) {
642
638
  return function(err, type, close, callback) {
643
639
  if (close == null) {
644
640
  close = false;
645
641
  }
646
642
  if (_this.sshObj.debug) {
647
- _this.emit('msg', _this.sshObj.server.host + ": Class.error");
643
+ _this.emit('msg', "Class.error: " + err + ", " + type);
648
644
  }
649
645
  if (err instanceof Error) {
650
646
  _this.emit('msg', "Error: " + err.message + ", Level: " + err.level);
651
647
  } else {
652
648
  _this.emit('msg', (type + " error: ") + err);
653
649
  }
654
- if (typeof callback === 'function') {
655
- callback(err, type);
656
- }
657
650
  if (close) {
658
- return _this.connection.end();
659
- }
660
- };
661
- })(this));
662
- this.on("end", (function(_this) {
663
- return function(sessionText, sshObj) {
664
- if (_this.sshObj.debug) {
665
- return _this.emit('msg', _this.sshObj.server.host + ": Class.end");
651
+ return _this._stream.close();
666
652
  }
667
653
  };
668
654
  })(this));
669
- if (typeof callback === 'function') {
670
- return callback();
655
+ if (this._hosts[0].server.tryKeyboard) {
656
+ this.on("keyboard-interactive", (function(_this) {
657
+ return function(name, instructions, instructionsLang, prompts, finish) {
658
+ var str;
659
+ if (_this.sshObj.debug) {
660
+ _this.emit('msg', _this.sshObj.server.host + ": Class.keyboard-interactive");
661
+ }
662
+ if (_this.sshObj.verbose) {
663
+ _this.emit('msg', "name: " + name);
664
+ _this.emit('msg', "instructions: " + instructions);
665
+ str = JSON.stringify(prompts, null, 4);
666
+ return _this.emit('msg', "Prompts object: " + str);
667
+ }
668
+ };
669
+ })(this));
670
+ }
671
+ this._allSessions = "";
672
+ }
673
+
674
+ SSH2Shell.prototype._initiate = function(action) {
675
+ if (this.sshObj.debug) {
676
+ this.emit('msg', this.sshObj.server.host + ": initiate");
677
+ }
678
+ this._loadDefaults();
679
+ if (typeof action === 'function') {
680
+ return action();
671
681
  }
672
682
  };
673
683
 
674
- SSH2Shell.prototype._loadDefaults = function(callback) {
684
+ SSH2Shell.prototype._loadDefaults = function() {
675
685
  var ref, ref1, ref2, ref3, ref4, ref5, ref6;
686
+ if (this.sshObj.msg && this.sshObj.msg.send && typeof this.sshObj.msg.send === 'function') {
687
+ this.on("msg", this.sshObj.msg.send);
688
+ } else if (this.sshObj.msg && typeof this.sshObj.msg === 'function') {
689
+ this.on("msg", this.sshObj.msg);
690
+ } else {
691
+ this.on("msg", (function(_this) {
692
+ return function(message) {
693
+ return console.log(message);
694
+ };
695
+ })(this));
696
+ }
676
697
  if (this.sshObj.debug) {
677
698
  this.emit('msg', this.sshObj.server.host + ": Load Defaults");
678
699
  }
679
700
  this.command = "";
680
701
  this._buffer = "";
702
+ this.sshObj.sshToNextHost = false;
681
703
  if (!this.sshObj.connectedMessage) {
682
704
  this.sshObj.connectedMessage = "Connected";
683
705
  }
@@ -787,10 +809,8 @@
787
809
  if (_this.sshObj.verbose) {
788
810
  _this.emit('msg', _this.sshObj.server.host + ": Timeout command: " + command + " response: " + response);
789
811
  }
790
- _this._runExit();
791
- return _this.emit("error", _this.sshObj.server.host + ": Command timed out after " + (_this.idleTime / 1000) + " seconds", "Timeout", true, function(err, type) {
792
- return _this.sshObj.sessionText += _this._buffer;
793
- });
812
+ _this.emit("error", _this.sshObj.server.host + ": Command timed out after " + (_this.idleTime / 1000) + " seconds", "Timeout", true, function(err, type) {});
813
+ return _this.sshObj.sessionText += _this._buffer;
794
814
  };
795
815
  })(this);
796
816
  if (typeof this.sshObj.onKeyboardInteractive === 'function') {
@@ -815,10 +835,7 @@
815
835
  this.emit('msg', this.sshObj.server.host + ": Host loaded");
816
836
  }
817
837
  if (this.sshObj.verbose) {
818
- this.emit('msg', this.sshObj);
819
- }
820
- if (typeof callback === 'function') {
821
- return callback();
838
+ return this.emit('msg', this.sshObj);
822
839
  }
823
840
  };
824
841
 
@@ -895,7 +912,7 @@
895
912
  }
896
913
  _this._primaryhostSessionText += _this.sshObj.sessionText + "\n";
897
914
  _this._allSessions += _this._primaryhostSessionText;
898
- if (typeIsArray(_this.hosts) && _this.hosts.length === 0) {
915
+ if (_this._hosts.length === 0) {
899
916
  _this.emit('end', _this._allSessions, _this.sshObj);
900
917
  }
901
918
  return _this._removeEvents();
@@ -922,12 +939,18 @@
922
939
  if (_this.sshObj.debug) {
923
940
  _this.emit('msg', _this.sshObj.server.host + ": Connection.close");
924
941
  }
942
+ if (_this.idleTimer) {
943
+ clearTimeout(_this.idleTimer);
944
+ }
945
+ if (_this.dataReceivedTimer) {
946
+ clearTimeout(_this.dataReceivedTimer);
947
+ }
925
948
  if (had_error) {
926
949
  _this.emit("error", had_error, "Connection close");
927
950
  } else {
928
951
  _this.emit('msg', _this.sshObj.closedMessage);
929
952
  }
930
- if (typeIsArray(_this.hosts) && _this.hosts.length === 0) {
953
+ if (_this._hosts.length === 0) {
931
954
  if (typeof _this._callback === 'function') {
932
955
  return _this._callback(_this._allSessions);
933
956
  }
package/package.json CHANGED
@@ -1,57 +1,57 @@
1
- {
2
- "name": "ssh2shell",
3
- "version": "1.9.10",
4
- "author": "cmp-202",
5
- "description": "A wrapper class for ssh2 to run multiple sequential commands in an SSH shell session, handle command responses, and tunnel through to other hosts using nested host objects",
6
- "main": "./lib/ssh2shell.js",
7
- "engines": {
8
- "node": ">=4.5.0"
9
- },
10
- "dependencies": {
11
- "ssh2": "^1.4.0"
12
- },
13
- "devDependencies": {
14
- "coffee-script": "^1.12.7",
15
- "dotenv": "^8.6.0"
16
- },
17
- "scripts": {},
18
- "keywords": [
19
- "SSH",
20
- "ssh2",
21
- "shell",
22
- "server",
23
- "client",
24
- "multiple",
25
- "command",
26
- "commands",
27
- "tunnel",
28
- "deploy",
29
- "host",
30
- "hosts",
31
- "automation",
32
- "fingerprint",
33
- "validation",
34
- "hash",
35
- "cipher",
36
- "persistent",
37
- "sequential",
38
- "console",
39
- "sudo",
40
- "su",
41
- "prompt",
42
- "session",
43
- "connection"
44
- ],
45
- "repository": {
46
- "type": "git",
47
- "url": "http://github.com/cmp-202/ssh2shell"
48
- },
49
- "bugs": {
50
- "url": "https://github.com/cmp-202/ssh2shell/issues"
51
- },
52
- "homepage": "https://github.com/cmp-202/ssh2shell/wiki",
53
- "directories": {
54
- "test": "test"
55
- },
56
- "license": "ISC"
57
- }
1
+ {
2
+ "name": "ssh2shell",
3
+ "version": "2.0.3",
4
+ "author": "cmp-202",
5
+ "description": "A wrapper class for ssh2 to run multiple sequential commands in an SSH shell session, handle command responses, and tunnel through to other hosts using nested host objects",
6
+ "main": "./lib/ssh2shell.js",
7
+ "engines": {
8
+ "node": ">=4.5.0"
9
+ },
10
+ "dependencies": {
11
+ "ssh2": "^1.4.0"
12
+ },
13
+ "devDependencies": {
14
+ "coffee-script": "^1.12.7",
15
+ "dotenv": "^8.6.0"
16
+ },
17
+ "scripts": {},
18
+ "keywords": [
19
+ "SSH",
20
+ "ssh2",
21
+ "shell",
22
+ "server",
23
+ "client",
24
+ "multiple",
25
+ "command",
26
+ "commands",
27
+ "tunnel",
28
+ "deploy",
29
+ "host",
30
+ "hosts",
31
+ "automation",
32
+ "fingerprint",
33
+ "validation",
34
+ "hash",
35
+ "cipher",
36
+ "persistent",
37
+ "sequential",
38
+ "console",
39
+ "sudo",
40
+ "su",
41
+ "prompt",
42
+ "session",
43
+ "connection"
44
+ ],
45
+ "repository": {
46
+ "type": "git",
47
+ "url": "http://github.com/cmp-202/ssh2shell"
48
+ },
49
+ "bugs": {
50
+ "url": "https://github.com/cmp-202/ssh2shell/issues"
51
+ },
52
+ "homepage": "https://github.com/cmp-202/ssh2shell/wiki",
53
+ "directories": {
54
+ "test": "test"
55
+ },
56
+ "license": "ISC"
57
+ }