ssh2shell 1.9.9 → 2.0.2
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/README.md +568 -749
- package/lib/ssh2shell.js +113 -88
- package/package.json +57 -57
- package/src/ssh2shell.coffee +112 -95
- package/test/Multiple primary hosts.js +4 -10
- package/test/devtest.js +5 -3
- package/test/issue69.js +24 -24
- package/test/keyboard-interactivetest.js +3 -20
- package/test/lots of commands.js +87 -0
- package/test/notificationstest.js +13 -10
- package/test/sshUserCommandsPosition.js +26 -0
- package/test/sudo no pass test.js +4 -4
- package/test/timeouttest.js +19 -63
- package/test/tunneltest.js +2 -2
- package/test/tunneltestSshUserCommands.js +71 -0
package/lib/ssh2shell.js
CHANGED
|
@@ -18,7 +18,9 @@
|
|
|
18
18
|
|
|
19
19
|
SSH2Shell.prototype.command = "";
|
|
20
20
|
|
|
21
|
-
SSH2Shell.prototype.
|
|
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.
|
|
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 ")
|
|
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.
|
|
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
|
|
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
|
|
245
|
-
this.emit('msg', this.sshObj.server.host + ": SSH
|
|
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
|
|
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.
|
|
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.
|
|
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(
|
|
420
|
-
if (
|
|
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.
|
|
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(
|
|
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
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
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
|
-
|
|
591
|
-
|
|
619
|
+
SSH2Shell.__super__.constructor.call(this, hosts);
|
|
620
|
+
if (typeIsArray(hosts) && hosts.length > 0) {
|
|
621
|
+
this._hosts = hosts;
|
|
592
622
|
} else {
|
|
593
|
-
this.
|
|
623
|
+
this._hosts = [hosts];
|
|
594
624
|
}
|
|
595
625
|
this.ssh2Client = require('ssh2').Client;
|
|
596
626
|
this.on("newPrimmaryHost", this._nextPrimaryHost);
|
|
@@ -604,78 +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 (typeof this.sshObj.msg === 'function') {
|
|
613
|
-
this.on("msg", this.sshObj.msg.send);
|
|
614
|
-
} else {
|
|
615
|
-
this.on("msg", (function(_this) {
|
|
616
|
-
return function(message) {
|
|
617
|
-
return console.log(message);
|
|
618
|
-
};
|
|
619
|
-
})(this));
|
|
620
|
-
}
|
|
621
|
-
this._loadDefaults();
|
|
622
|
-
if (this.sshObj.debug) {
|
|
623
|
-
this.emit('msg', this.sshObj.server.host + ": initiate");
|
|
624
|
-
}
|
|
625
|
-
this.on("keyboard-interactive", (function(_this) {
|
|
626
|
-
return function(name, instructions, instructionsLang, prompts, finish) {
|
|
627
|
-
var str;
|
|
628
|
-
if (_this.sshObj.debug) {
|
|
629
|
-
_this.emit('msg', _this.sshObj.server.host + ": Class.keyboard-interactive");
|
|
630
|
-
}
|
|
631
|
-
if (_this.sshObj.verbose) {
|
|
632
|
-
_this.emit('msg', "name: " + name);
|
|
633
|
-
_this.emit('msg', "instructions: " + instructions);
|
|
634
|
-
str = JSON.stringify(prompts, null, 4);
|
|
635
|
-
return _this.emit('msg', "Prompts object: " + str);
|
|
636
|
-
}
|
|
637
|
-
};
|
|
638
|
-
})(this));
|
|
639
637
|
this.on("error", (function(_this) {
|
|
640
638
|
return function(err, type, close, callback) {
|
|
641
639
|
if (close == null) {
|
|
642
640
|
close = false;
|
|
643
641
|
}
|
|
644
642
|
if (_this.sshObj.debug) {
|
|
645
|
-
_this.emit('msg',
|
|
643
|
+
_this.emit('msg', "Class.error: " + err + ", " + type);
|
|
646
644
|
}
|
|
647
645
|
if (err instanceof Error) {
|
|
648
646
|
_this.emit('msg', "Error: " + err.message + ", Level: " + err.level);
|
|
649
647
|
} else {
|
|
650
648
|
_this.emit('msg', (type + " error: ") + err);
|
|
651
649
|
}
|
|
652
|
-
if (typeof callback === 'function') {
|
|
653
|
-
callback(err, type);
|
|
654
|
-
}
|
|
655
650
|
if (close) {
|
|
656
|
-
return _this.
|
|
657
|
-
}
|
|
658
|
-
};
|
|
659
|
-
})(this));
|
|
660
|
-
this.on("end", (function(_this) {
|
|
661
|
-
return function(sessionText, sshObj) {
|
|
662
|
-
if (_this.sshObj.debug) {
|
|
663
|
-
return _this.emit('msg', _this.sshObj.server.host + ": Class.end");
|
|
651
|
+
return _this._stream.close();
|
|
664
652
|
}
|
|
665
653
|
};
|
|
666
654
|
})(this));
|
|
667
|
-
if (
|
|
668
|
-
|
|
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();
|
|
669
681
|
}
|
|
670
682
|
};
|
|
671
683
|
|
|
672
|
-
SSH2Shell.prototype._loadDefaults = function(
|
|
684
|
+
SSH2Shell.prototype._loadDefaults = function() {
|
|
673
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
|
+
}
|
|
674
697
|
if (this.sshObj.debug) {
|
|
675
698
|
this.emit('msg', this.sshObj.server.host + ": Load Defaults");
|
|
676
699
|
}
|
|
677
700
|
this.command = "";
|
|
678
701
|
this._buffer = "";
|
|
702
|
+
this.sshObj.sshToNextHost = false;
|
|
679
703
|
if (!this.sshObj.connectedMessage) {
|
|
680
704
|
this.sshObj.connectedMessage = "Connected";
|
|
681
705
|
}
|
|
@@ -785,10 +809,8 @@
|
|
|
785
809
|
if (_this.sshObj.verbose) {
|
|
786
810
|
_this.emit('msg', _this.sshObj.server.host + ": Timeout command: " + command + " response: " + response);
|
|
787
811
|
}
|
|
788
|
-
_this.
|
|
789
|
-
return _this.
|
|
790
|
-
return _this.sshObj.sessionText += _this._buffer;
|
|
791
|
-
});
|
|
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;
|
|
792
814
|
};
|
|
793
815
|
})(this);
|
|
794
816
|
if (typeof this.sshObj.onKeyboardInteractive === 'function') {
|
|
@@ -813,10 +835,7 @@
|
|
|
813
835
|
this.emit('msg', this.sshObj.server.host + ": Host loaded");
|
|
814
836
|
}
|
|
815
837
|
if (this.sshObj.verbose) {
|
|
816
|
-
this.emit('msg', this.sshObj);
|
|
817
|
-
}
|
|
818
|
-
if (typeof callback === 'function') {
|
|
819
|
-
return callback();
|
|
838
|
+
return this.emit('msg', this.sshObj);
|
|
820
839
|
}
|
|
821
840
|
};
|
|
822
841
|
|
|
@@ -893,7 +912,7 @@
|
|
|
893
912
|
}
|
|
894
913
|
_this._primaryhostSessionText += _this.sshObj.sessionText + "\n";
|
|
895
914
|
_this._allSessions += _this._primaryhostSessionText;
|
|
896
|
-
if (
|
|
915
|
+
if (_this._hosts.length === 0) {
|
|
897
916
|
_this.emit('end', _this._allSessions, _this.sshObj);
|
|
898
917
|
}
|
|
899
918
|
return _this._removeEvents();
|
|
@@ -920,12 +939,18 @@
|
|
|
920
939
|
if (_this.sshObj.debug) {
|
|
921
940
|
_this.emit('msg', _this.sshObj.server.host + ": Connection.close");
|
|
922
941
|
}
|
|
942
|
+
if (_this.idleTimer) {
|
|
943
|
+
clearTimeout(_this.idleTimer);
|
|
944
|
+
}
|
|
945
|
+
if (_this.dataReceivedTimer) {
|
|
946
|
+
clearTimeout(_this.dataReceivedTimer);
|
|
947
|
+
}
|
|
923
948
|
if (had_error) {
|
|
924
949
|
_this.emit("error", had_error, "Connection close");
|
|
925
950
|
} else {
|
|
926
951
|
_this.emit('msg', _this.sshObj.closedMessage);
|
|
927
952
|
}
|
|
928
|
-
if (
|
|
953
|
+
if (_this._hosts.length === 0) {
|
|
929
954
|
if (typeof _this._callback === 'function') {
|
|
930
955
|
return _this._callback(_this._allSessions);
|
|
931
956
|
}
|
package/package.json
CHANGED
|
@@ -1,57 +1,57 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "ssh2shell",
|
|
3
|
-
"version": "
|
|
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.2",
|
|
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
|
+
}
|