ssh2shell 2.0.11 → 2.0.13

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
@@ -1,1024 +1,1094 @@
1
- // Generated by CoffeeScript 1.12.7
2
- (function() {
3
- var SSH2Shell, Stream, typeIsArray,
4
- bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
5
- extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
6
- hasProp = {}.hasOwnProperty;
7
-
8
- typeIsArray = Array.isArray || function(value) {
9
- return {}.toString.call(value) === '[object Array]';
10
- };
11
-
12
- Stream = require('stream');
13
-
14
- SSH2Shell = (function(superClass) {
15
- extend(SSH2Shell, superClass);
16
-
17
- SSH2Shell.prototype.sshObj = {};
18
-
19
- SSH2Shell.prototype.command = "";
20
-
21
- SSH2Shell.prototype._hosts = [];
22
-
23
- SSH2Shell.prototype._sshToNextHost = false;
24
-
25
- SSH2Shell.prototype._primaryhostSessionText = "";
26
-
27
- SSH2Shell.prototype._allSessions = "";
28
-
29
- SSH2Shell.prototype._connections = [];
30
-
31
- SSH2Shell.prototype._stream = {};
32
-
33
- SSH2Shell.prototype._buffer = "";
34
-
35
- SSH2Shell.prototype.idleTime = 5000;
36
-
37
- SSH2Shell.prototype.asciiFilter = "";
38
-
39
- SSH2Shell.prototype.textColorFilter = "";
40
-
41
- SSH2Shell.prototype.passwordPrompt = "";
42
-
43
- SSH2Shell.prototype.passphrasePrompt = "";
44
-
45
- SSH2Shell.prototype.standardPrompt = "";
46
-
47
- SSH2Shell.prototype._callback = function() {};
48
-
49
- SSH2Shell.prototype.onCommandProcessing = function() {};
50
-
51
- SSH2Shell.prototype.onCommandComplete = function() {};
52
-
53
- SSH2Shell.prototype.onCommandTimeout = function() {};
54
-
55
- SSH2Shell.prototype.onEnd = function() {};
56
-
57
- SSH2Shell.prototype._onData = function(data) {
58
- this._buffer += data;
59
- if (this.command.length > 0 && !this.standardPrompt.test(this._sanitizeResponse())) {
60
- this.emit('commandProcessing', this.command, this._buffer, this.sshObj, this._stream);
61
- if (this.idleTimer) {
62
- clearTimeout(this.idleTimer);
63
- }
64
- this.idleTimer = setTimeout((function(_this) {
65
- return function() {
66
- return _this.emit('commandTimeout', _this.command, _this._buffer, _this._stream, _this.connection);
67
- };
68
- })(this), this.idleTime);
69
- } else if (this.command.length < 1 && !this.standardPrompt.test(this._buffer)) {
70
- this.emit('commandProcessing', this.command, this._buffer, this.sshObj, this._stream);
71
- }
72
- if (this.dataReceivedTimer) {
73
- clearTimeout(this.dataReceivedTimer);
74
- }
75
- return this.dataReceivedTimer = setTimeout((function(_this) {
76
- return function() {
77
- if (_this.idleTimer) {
78
- clearTimeout(_this.idleTimer);
79
- }
80
- if (!_this.sshObj.disableColorFilter) {
81
- _this._buffer = _this._buffer.replace(_this.textColorFilter, "");
82
- }
83
- if (!_this.sshObj.disableASCIIFilter) {
84
- _this._buffer = _this._buffer.replace(_this.asciiFilter, "");
85
- }
86
- switch (true) {
87
- case _this.command.length > 0 && _this.command.indexOf("sudo ") !== -1:
88
- if (_this.sshObj.debug) {
89
- _this.emit('msg', _this.sshObj.server.host + ": Sudo command data");
90
- }
91
- return _this._processPasswordPrompt();
92
- case _this.sshObj.sshToNextHost && _this.command.length > 0 && _this.command.indexOf("ssh ") === 0:
93
- if (_this.sshObj.debug) {
94
- _this.emit('msg', _this.sshObj.server.host + ": SSH command data");
95
- }
96
- return _this._processSSHPrompt();
97
- case _this.command.length > 0 && _this.standardPrompt.test(_this._sanitizeResponse()):
98
- if (_this.sshObj.debug) {
99
- _this.emit('msg', _this.sshObj.server.host + ": Normal prompt detected");
100
- }
101
- _this.sshObj.pwSent = false;
102
- return _this._commandComplete();
103
- case _this.command.length < 1 && _this.standardPrompt.test(_this._buffer):
104
- if (_this.sshObj.debug) {
105
- _this.emit('msg', _this.sshObj.server.host + ": First prompt detected");
106
- }
107
- if (_this.sshObj.showBanner) {
108
- _this.sshObj.sessionText += _this._buffer;
109
- }
110
- return _this._nextCommand();
111
- default:
112
- if (_this.sshObj.debug) {
113
- _this.emit('msg', "Data processing: data received timeout");
114
- }
115
- return _this.idleTimer = setTimeout(function() {
116
- return _this.emit('commandTimeout', _this.command, _this._buffer, _this._stream, _this.connection);
117
- }, _this.idleTime);
118
- }
119
- };
120
- })(this), this.dataIdleTime);
121
- };
122
-
123
- SSH2Shell.prototype._sanitizeResponse = function() {
124
- return this._buffer.replace(this.command.substr(0, this._buffer.length), "");
125
- };
126
-
127
- SSH2Shell.prototype._processPasswordPrompt = function() {
128
- var passwordPrompt, response, standardPrompt;
129
- response = this._sanitizeResponse().trim();
130
- passwordPrompt = this.passwordPrompt.test(response);
131
- standardPrompt = this.standardPrompt.test(response);
132
- if (this.sshObj.debug) {
133
- this.emit('msg', this.sshObj.server.host + ": Sudo Password prompt detected: " + passwordPrompt);
134
- }
135
- if (this.sshObj.debug) {
136
- this.emit('msg', this.sshObj.server.host + ": Sudo Password prompt: Password sent: " + this.sshObj.pwSent);
137
- }
138
- if (this.sshObj.debug) {
139
- this.emit('msg', this.sshObj.server.host + ": Sudo Password: " + this.sshObj.server.password);
140
- }
141
- if (this.sshObj.verbose) {
142
- this.emit('msg', this.sshObj.server.host + ": Sudo Response: " + response);
143
- }
144
- switch (true) {
145
- case passwordPrompt && !this.sshObj.server.password:
146
- if (this.sshObj.debug) {
147
- this.emit('msg', this.sshObj.server.host + ": Sudo password prompt no password set");
148
- }
149
- return this._resetFromSudoError();
150
- case passwordPrompt && !this.sshObj.pwSent:
151
- if (this.sshObj.verbose) {
152
- this.emit('msg', this.sshObj.server.host + ": Sudo password prompt: Buffer: " + response);
153
- }
154
- if (this.sshObj.debug) {
155
- this.emit('msg', this.sshObj.server.host + ": Sudo password prompt: Send password ");
156
- }
157
- if (this.sshObj.verbose) {
158
- this.emit('msg', this.sshObj.server.host + ": Sudo sent password: " + this.sshObj.server.password);
159
- }
160
- this.sshObj.pwSent = true;
161
- return this._runCommand("" + this.sshObj.server.password);
162
- case passwordPrompt && this.sshObj.pwSent:
163
- if (this.sshObj.verbose) {
164
- this.emit('msg', this.sshObj.server.host + ": Sudo password faied: response: " + response);
165
- }
166
- if (this.sshObj.debug) {
167
- this.emit('error', this.sshObj.server.host + ": Sudo password was incorrect for " + this.sshObj.server.userName + ", Sudo authentication");
168
- }
169
- if (this.sshObj.debug) {
170
- this.emit('msg', this.sshObj.server.host + ": Sudo failed password prompt: Password: [" + this.sshObj.server.password + "]");
171
- }
172
- this.sshObj.pwSent = false;
173
- return this._resetFromSudoError();
174
- case standardPrompt:
175
- if (this.sshObj.debug) {
176
- this.emit('msg', this.sshObj.server.host + ": Sudo password accepted");
177
- }
178
- this.sshObj.pwSent = false;
179
- if (this.sshObj.verbose) {
180
- this.emit('msg', this.sshObj.server.host + ": Sudo Standard Response: " + response);
181
- }
182
- return this._commandComplete();
183
- default:
184
- return this.idleTimer = setTimeout((function(_this) {
185
- return function() {
186
- return _this.emit('commandTimeout', _this.command, response, _this._stream, _this._connection);
187
- };
188
- })(this), this.idleTime);
189
- }
190
- };
191
-
192
- SSH2Shell.prototype._resetFromSudoError = function() {
193
- this.sshObj.pwSent = false;
194
- this.sshObj.sessionText += "" + this._buffer;
195
- this._buffer = "";
196
- this.command = "";
197
- return this._stream.write('\x03');
198
- };
199
-
200
- SSH2Shell.prototype._processSSHPrompt = function() {
201
- var passphrasePrompt, passwordPrompt, response, standardPrompt, using;
202
- response = this._sanitizeResponse().trim();
203
- if (this.idleTimer) {
204
- clearTimeout(this.idleTimer);
205
- }
206
- passwordPrompt = this.passwordPrompt.test(response) && !this.sshObj.server.hasOwnProperty("passPhrase");
207
- passphrasePrompt = this.passphrasePrompt.test(response) && this.sshObj.server.hasOwnProperty("passPhrase");
208
- standardPrompt = this.standardPrompt.test(response);
209
- if (this.sshObj.verbose) {
210
- this.emit('msg', this.sshObj.server.host + ": SSH: Password previously sent: " + this.sshObj.sshAuth);
211
- }
212
- if (!this.sshObj.sshAuth) {
213
- if (this.sshObj.debug) {
214
- this.emit('msg', this.sshObj.server.host + ": First SSH prompt detection");
215
- }
216
- if (passwordPrompt) {
217
- if (this.sshObj.debug) {
218
- this.emit('msg', this.sshObj.server.host + ": SSH send password");
219
- }
220
- this.sshObj.sshAuth = true;
221
- this._buffer = "";
222
- return this._runCommand("" + this.sshObj.server.password);
223
- } else if (passphrasePrompt) {
224
- if (this.sshObj.debug) {
225
- this.emit('msg', this.sshObj.server.host + ": SSH send passphrase");
226
- }
227
- this.sshObj.sshAuth = true;
228
- this._buffer = "";
229
- return this._runCommand("" + this.sshObj.server.passPhrase);
230
- } else if (standardPrompt) {
231
- if (this.sshObj.debug) {
232
- this.emit('msg', this.sshObj.server.host + ": SSH standard prompt: connection failed");
233
- }
234
- this.emit('msg', this.sshObj.server.host + ": SSH connection failed");
235
- this.emit('msg', this.sshObj.server.host + ": SSH failed response: " + response);
236
- this.sshObj.sessionText += this.sshObj.server.host + ": SSH failed: response: " + response;
237
- return this._runExit();
238
- } else {
239
- this.emit('msg', this.sshObj.server.host + ": SSH no prompt was not detected");
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);
245
- }
246
- if (this.sshObj.verbose && this.sshObj.server.hasOwnProperty("passPhrase")) {
247
- this.emit('msg', this.sshObj.server.host + ": SSH passphrase prompt: " + this.sshObj.passphrasePrompt);
248
- }
249
- if (this.sshObj.verbose) {
250
- this.emit('msg', this.sshObj.server.host + ": SSH standard prompt: " + this.sshObj.standardPrompt);
251
- }
252
- return this._runExit();
253
- }
254
- } else {
255
- if (this.sshObj.debug) {
256
- this.emit('msg', this.sshObj.server.host + ": SSH post authentication prompt detection");
257
- }
258
- if (standardPrompt) {
259
- if (this.sshObj.debug) {
260
- this.emit('msg', this.sshObj.server.host + ": SSH complete: normal prompt");
261
- }
262
- if (this.sshObj.showBanner) {
263
- this.sshObj.sessionText += "\n " + response;
264
- }
265
- this.sshObj.exitCommands.push("exit");
266
- this.emit('msg', "" + this.sshObj.connectedMessage);
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;
272
- return this._nextCommand();
273
- } else if (passwordPrompt || passphrasePrompt) {
274
- this.emit('msg', this.sshObj.server.host + ": SSH authentication failed");
275
- if (this.sshObj.debug) {
276
- this.emit('msg', this.sshObj.server.host + ": SSH auth failed");
277
- }
278
- if (this.sshObj.verbose) {
279
- this.emit('msg', this.sshObj.server.host + ": SSH: failed response: " + response);
280
- }
281
- this.sshObj.sshAuth = false;
282
- using = (function() {
283
- switch (false) {
284
- case !passwordPrompt:
285
- return "SSH password: " + this.sshObj.server.password;
286
- case !passphrasePrompt:
287
- return "SSH passphrase: " + this.sshObj.server.passPhrase;
288
- }
289
- }).call(this);
290
- this.emit('error', this.sshObj.server.host + ": SSH authentication failed for " + this.sshObj.server.userName + "@" + this.sshObj.server.host, "Nested host authentication");
291
- if (this.sshObj.debug) {
292
- this.emit('msg', (this.sshObj.server.host + ": SSH auth failed: Using ") + using);
293
- }
294
- if (this.sshObj.verbose) {
295
- this.emit('msg', this.sshObj.server.host + ": SSH response: " + response);
296
- }
297
- if (this._connections.length > 0) {
298
- return this._previousHost();
299
- }
300
- return this._runExit();
301
- }
302
- }
303
- };
304
-
305
- SSH2Shell.prototype._processNotifications = function() {
306
- var msgNote, sessionNote;
307
- if (this.command) {
308
- if ((sessionNote = this.command.match(/^`(.*)`$/))) {
309
- if (this.sshObj.debug) {
310
- this.emit('msg', this.sshObj.server.host + ": Notifications: sessionText output");
311
- }
312
- if (this._connections.length > 0) {
313
- this.sshObj.sessionText += this.sshObj.server.host + ": Note: " + sessionNote[1] + this.sshObj.enter;
314
- } else {
315
- this.sshObj.sessionText += "Note: " + sessionNote[1] + this.sshObj.enter;
316
- }
317
- if (this.sshObj.verbose) {
318
- this.emit('msg', sessionNote[1]);
319
- }
320
- return this._nextCommand();
321
- } else if ((msgNote = this.command.match(/^msg:(.*)$/))) {
322
- if (this.sshObj.debug) {
323
- this.emit('msg', this.sshObj.server.host + ": Notifications: msg to output");
324
- }
325
- this.emit('msg', this.sshObj.server.host + ": Note: " + msgNote[1]);
326
- return this._nextCommand();
327
- } else {
328
- if (this.sshObj.debug) {
329
- this.emit('msg', this.sshObj.server.host + ": Notifications: Normal Command to run");
330
- }
331
- return this._checkCommand();
332
- }
333
- }
334
- };
335
-
336
- SSH2Shell.prototype._commandComplete = function() {
337
- var response;
338
- response = this._buffer.trim();
339
- if (this.command !== "" && this.command !== "exit" && this.sshObj.sshToNextHost !== true) {
340
- if (this.sshObj.verbose) {
341
- this.emit('msg', this.sshObj.server.host + ": Command complete:\nCommand:\n " + this.command + "\nResponse: " + response);
342
- }
343
- this.sshObj.sessionText += response;
344
- if (this.sshObj.debug) {
345
- this.emit('msg', this.sshObj.server.host + ": Raising commandComplete event");
346
- }
347
- this.emit('commandComplete', this.command, this._buffer, this.sshObj);
348
- }
349
- return this._nextCommand();
350
- };
351
-
352
- SSH2Shell.prototype._nextCommand = function() {
353
- this._buffer = "";
354
- if (this.sshObj.commands.length > 0) {
355
- if (this.sshObj.verbose) {
356
- this.emit('msg', this.sshObj.server.host + ": Host.commands: " + this.sshObj.commands);
357
- }
358
- this.command = this.sshObj.commands.shift();
359
- if (this.sshObj.verbose) {
360
- this.emit('msg', this.sshObj.server.host + ": Next command from host.commands: " + this.command);
361
- }
362
- return this._processNotifications();
363
- } else {
364
- if (this.sshObj.debug) {
365
- this.emit('msg', this.sshObj.server.host + ": No commands so exit");
366
- }
367
- return this._runExit();
368
- }
369
- };
370
-
371
- SSH2Shell.prototype._checkCommand = function() {
372
- if (this.command !== "") {
373
- return this._runCommand(this.command);
374
- } else {
375
- if (this.sshObj.debug) {
376
- this.emit('msg', this.sshObj.server.host + ": No command so exit");
377
- }
378
- return this._runExit();
379
- }
380
- };
381
-
382
- SSH2Shell.prototype._runCommand = function(command) {
383
- if (this.sshObj.verbose) {
384
- this.emit('msg', this.sshObj.server.host + ": sending: " + command);
385
- }
386
- if (this.sshObj.debug) {
387
- this.emit('msg', this.sshObj.server.host + ": run command");
388
- }
389
- return this._stream.write("" + command + this.sshObj.enter);
390
- };
391
-
392
- SSH2Shell.prototype._previousHost = function() {
393
- if (this.sshObj.debug) {
394
- this.emit('msg', this.sshObj.server.host + ": Load previous host config");
395
- }
396
- this.emit('end', this.sshObj.server.host + ": \n" + this.sshObj.sessionText, this.sshObj);
397
- if (this.sshObj.debug) {
398
- this.emit('msg', this.sshObj.server.host + ": Previous hosts: " + this._connections.length);
399
- }
400
- if (this._connections.length > 0) {
401
- this.sshObj = this._connections.pop();
402
- if (this.sshObj.debug) {
403
- this.emit('msg', this.sshObj.server.host + ": Reload previous host");
404
- }
405
- return this._runExit();
406
- } else {
407
- return this._runExit();
408
- }
409
- };
410
-
411
- SSH2Shell.prototype._nextHost = function() {
412
- var nextHost;
413
- nextHost = this.sshObj.hosts.shift();
414
- if (this.sshObj.debug) {
415
- this.emit('msg', this.sshObj.server.host + ": SSH to " + nextHost.server.host);
416
- }
417
- if (this.sshObj.debug) {
418
- this.emit('msg', this.sshObj.server.host + ": Clearing previous event handlers");
419
- }
420
- if (this.sshObj.debug) {
421
- this.emit('msg', this.sshObj.server.host + ": Remove previous event handlers");
422
- }
423
- this._removeListeners();
424
- this._connections.push(this.sshObj);
425
- this.sshObj = nextHost;
426
- return this._initiate(this._sshConnect);
427
- };
428
-
429
- SSH2Shell.prototype._nextPrimaryHost = function(connect) {
430
- if (this._hosts.length > 0) {
431
- if (this.sshObj.server) {
432
- if (this.sshObj.debug) {
433
- this.emit('msg', this.sshObj.server.host + ": Current primary host");
434
- }
435
- if (this.sshObj.debug) {
436
- this.emit('msg', this.sshObj.server.host + ": Remove previous event handlers");
437
- }
438
- this.emit('end', this._primaryhostSessionText, this.sshObj);
439
- this._removeListeners();
440
- }
441
- this.sshObj = this._hosts.shift();
442
- this._primaryhostSessionText = this.sshObj.server.host + ": ";
443
- if (this.sshObj.debug) {
444
- this.emit('msg', this.sshObj.server.host + ": Next primary host");
445
- }
446
- return this._initiate(connect);
447
- } else {
448
- if (this.sshObj.debug) {
449
- this.emit('msg', this.sshObj.server.host + ": No more primary hosts");
450
- }
451
- return this._runExit;
452
- }
453
- };
454
-
455
- SSH2Shell.prototype._sshConnect = function() {
456
- var option, ref, shellQuote, sshFlags, sshOptions, value;
457
- sshFlags = "-x";
458
- sshOptions = "";
459
- if (this.sshObj.server.ssh) {
460
- if (this.sshObj.server.ssh.forceProtocolVersion) {
461
- sshFlags += this.sshObj.server.ssh.forceProtocolVersion;
462
- }
463
- if (this.sshObj.server.ssh.forceAddressType) {
464
- sshFlags += this.sshObj.server.ssh.forceAddressType;
465
- }
466
- if (this.sshObj.server.ssh.disablePseudoTTY) {
467
- sshFlags += "T";
468
- }
469
- if (this.sshObj.server.ssh.forcePseudoTTY) {
470
- sshFlags += "t";
471
- }
472
- if (this.sshObj.server.ssh.verbose) {
473
- sshFlags += "v";
474
- }
475
- if (this.sshObj.server.ssh.cipherSpec) {
476
- sshOptions += " -c " + this.sshObj.server.ssh.cipherSpec;
477
- }
478
- if (this.sshObj.server.ssh.escape) {
479
- sshOptions += " -e " + this.sshObj.server.ssh.escape;
480
- }
481
- if (this.sshObj.server.ssh.logFile) {
482
- sshOptions += " -E " + this.sshObj.server.ssh.logFile;
483
- }
484
- if (this.sshObj.server.ssh.configFile) {
485
- sshOptions += " -F " + this.sshObj.server.ssh.configFile;
486
- }
487
- if (this.sshObj.server.ssh.identityFile) {
488
- sshOptions += " -i " + this.sshObj.server.ssh.identityFile;
489
- }
490
- if (this.sshObj.server.ssh.loginName) {
491
- sshOptions += " -l " + this.sshObj.server.ssh.loginName;
492
- }
493
- if (this.sshObj.server.ssh.macSpec) {
494
- sshOptions += " -m " + this.sshObj.server.ssh.macSpec;
495
- }
496
- shellQuote = function(value) {
497
- return "'" + String(value).replace(/'/g, "'\\''") + "'";
498
- };
499
- ref = this.sshObj.server.ssh.options || {};
500
- for (option in ref) {
501
- value = ref[option];
502
- sshOptions += " -o " + shellQuote(option + "=" + value);
503
- }
504
- }
505
- sshOptions += ' -o "StrictHostKeyChecking=no"';
506
- sshOptions += " -p " + this.sshObj.server.port;
507
- this.sshObj.sshAuth = false;
508
- this.sshObj.sshToNextHost = true;
509
- this.command = "ssh " + sshFlags + " " + sshOptions + " " + this.sshObj.server.userName + "@" + this.sshObj.server.host;
510
- if (this.sshObj.debug) {
511
- this.emit('msg', this.sshObj.server.host + ": SSH command: connect");
512
- }
513
- return this._runCommand(this.command);
514
- };
515
-
516
- SSH2Shell.prototype._runExit = function() {
517
- if (this.sshObj.debug) {
518
- this.emit('msg', this.sshObj.server.host + ": Process an exit");
519
- }
520
- if (this.sshObj.exitCommands && this.sshObj.exitCommands.length > 0) {
521
- if (this.sshObj.debug) {
522
- this.emit('msg', this.sshObj.server.host + ": Queued exit commands: " + this.sshObj.exitCommands.length);
523
- }
524
- this.command = this.sshObj.exitCommands.pop();
525
- if (this._connections && this._connections.length > 0) {
526
- if (this.sshObj.verbose) {
527
- this.emit('msg', this.sshObj.server.host + ": Primary host: " + this._connections[0].server.host);
528
- }
529
- this._connections[0].sessionText += "\n" + this.sshObj.server.host + ": " + this.sshObj.sessionText;
530
- }
531
- return this._runCommand(this.command);
532
- } else if (this.sshObj.hosts && this.sshObj.hosts.length > 0) {
533
- if (this.sshObj.debug) {
534
- this.emit('msg', this.sshObj.server.host + ": Next host from this host");
535
- }
536
- return this._nextHost();
537
- } else if (this._connections && this._connections.length > 0) {
538
- if (this.sshObj.debug) {
539
- this.emit('msg', this.sshObj.server.host + ": load previous host");
540
- }
541
- this.emit('msg', this.sshObj.server.host + ": " + this.sshObj.closedMessage);
542
- return this._previousHost();
543
- } else if (this.command === "exit") {
544
- if (this.sshObj.debug) {
545
- this.emit('msg', this.sshObj.server.host + ": Manual exit command");
546
- }
547
- return this._runCommand("exit");
548
- } else {
549
- return this.close();
550
- }
551
- };
552
-
553
- SSH2Shell.prototype.close = function() {
554
- if (this.sshObj.debug) {
555
- this.emit('msg', this.sshObj.server.host + ": Exit command: Stream: close");
556
- }
557
- return this._stream.close();
558
- };
559
-
560
- SSH2Shell.prototype._removeListeners = function() {
561
-
562
- /*
563
- if @sshObj.debug
564
- @.emit 'msg', "#{@sshObj.server.host}: Event handler count:"
565
- @.emit 'msg', "keyboard-interactive: " + (@.listenerCount 'keyboard-interactive')
566
- @.emit 'msg', "error: " + (@.listenerCount "error")
567
- @.emit 'msg', "data: " + (@.listenerCount "data")
568
- @.emit 'msg', "stderrData: " + (@.listenerCount "stderrData")
569
- @.emit 'msg', "end: " + (@.listenerCount 'end')
570
- @.emit 'msg', "commandProcessing: " + (@.listenerCount 'commandProcessing')
571
- @.emit 'msg', "commandComplete: " + (@.listenerCount 'commandComplete')
572
- @.emit 'msg', "commandTimeout: " + (@.listenerCount 'commandTimeout')
573
- @.emit 'msg', "msg: " + (@.listenerCount 'msg')
574
- */
575
- if (typeof this.sshObj.onKeyboardInteractive === 'function') {
576
- this.removeListener("keyboard-interactive", this.sshObj.onKeyboardInteractive);
577
- }
578
- if (typeof this.sshObj.onStderrData === 'function') {
579
- this.removeListener("stderrData", this.sshObj.onStderrData);
580
- }
581
- if (typeof this.sshObj.onData === 'function') {
582
- this.removeListener("data", this.sshObj.onData);
583
- }
584
- if (typeof this.sshObj.onError === 'function') {
585
- this.removeListener("error", this.sshObj.onError);
586
- }
587
- if (typeof this.sshObj.onStderrData === 'function') {
588
- this.removeListener("stderrData", this.sshObj.onStderrData);
589
- }
590
- if (typeof this.sshObj.onEnd === 'function') {
591
- this.removeListener("end", this.sshObj.onEnd);
592
- }
593
- if (typeof this.sshObj.onCommandProcessing === 'function') {
594
- this.removeListener("commandProcessing", this.sshObj.onCommandProcessing);
595
- }
596
- if (typeof this.sshObj.onCommandComplete === 'function') {
597
- this.removeListener("commandComplete", this.sshObj.onCommandComplete);
598
- }
599
- if (typeof this.sshObj.onCommandTimeout === 'function') {
600
- this.removeListener("commandTimeout", this.sshObj.onCommandTimeout);
601
- }
602
- if (typeof this.sshObj.msg === 'function') {
603
- this.removeListener("msg", this.sshObj.msg);
604
- }
605
- if (this.idleTimer) {
606
- clearTimeout(this.idleTimer);
607
- }
608
- if (this.dataReceivedTimer) {
609
- return clearTimeout(this.dataReceivedTimer);
610
- }
611
- };
612
-
613
- function SSH2Shell(hosts) {
614
- this._connect = bind(this._connect, this);
615
- this.connect = bind(this.connect, this);
616
- this._loadDefaults = bind(this._loadDefaults, this);
617
- this._initiate = bind(this._initiate, this);
618
- this._removeListeners = bind(this._removeListeners, this);
619
- this.close = bind(this.close, this);
620
- this._runExit = bind(this._runExit, this);
621
- this._sshConnect = bind(this._sshConnect, this);
622
- this._nextPrimaryHost = bind(this._nextPrimaryHost, this);
623
- this._nextHost = bind(this._nextHost, this);
624
- this._previousHost = bind(this._previousHost, this);
625
- this._runCommand = bind(this._runCommand, this);
626
- this._checkCommand = bind(this._checkCommand, this);
627
- this._nextCommand = bind(this._nextCommand, this);
628
- this._commandComplete = bind(this._commandComplete, this);
629
- this._processNotifications = bind(this._processNotifications, this);
630
- this._processSSHPrompt = bind(this._processSSHPrompt, this);
631
- this._resetFromSudoError = bind(this._resetFromSudoError, this);
632
- this._processPasswordPrompt = bind(this._processPasswordPrompt, this);
633
- this._sanitizeResponse = bind(this._sanitizeResponse, this);
634
- this._onData = bind(this._onData, this);
635
- this.onEnd = bind(this.onEnd, this);
636
- this.onCommandTimeout = bind(this.onCommandTimeout, this);
637
- this.onCommandComplete = bind(this.onCommandComplete, this);
638
- this.onCommandProcessing = bind(this.onCommandProcessing, this);
639
- this._callback = bind(this._callback, this);
640
- SSH2Shell.__super__.constructor.call(this, hosts);
641
- if (typeIsArray(hosts) && hosts.length > 0) {
642
- this._hosts = hosts;
643
- } else {
644
- this._hosts = [hosts];
645
- }
646
- this.ssh2Client = require('ssh2').Client;
647
- this.on("msg", (function(_this) {
648
- return function(message) {
649
- return console.log(message);
650
- };
651
- })(this));
652
- this.on("newPrimmaryHost", this._nextPrimaryHost);
653
- this.on("data", (function(_this) {
654
- return function(data) {
655
- return _this._onData(data);
656
- };
657
- })(this));
658
- this.on("stderrData", (function(_this) {
659
- return function(data) {
660
- return console.error(data);
661
- };
662
- })(this));
663
- this.on("error", (function(_this) {
664
- return function(err, type, close, callback) {
665
- if (close == null) {
666
- close = false;
667
- }
668
- if (_this.sshObj.debug) {
669
- _this.emit('msg', "Class.error: " + err + ", " + type);
670
- }
671
- if (err instanceof Error) {
672
- _this.emit('msg', "Error: " + err.message + ", Level: " + err.level);
673
- } else {
674
- _this.emit('msg', (type + " error: ") + err);
675
- }
676
- if (close) {
677
- return _this._stream.close();
678
- }
679
- };
680
- })(this));
681
- if (this._hosts[0].server.tryKeyboard) {
682
- this.on("keyboard-interactive", (function(_this) {
683
- return function(name, instructions, instructionsLang, prompts, finish) {
684
- var str;
685
- if (_this.sshObj.debug) {
686
- _this.emit('msg', _this.sshObj.server.host + ": Class.keyboard-interactive");
687
- }
688
- if (_this.sshObj.verbose) {
689
- _this.emit('msg', "name: " + name);
690
- _this.emit('msg', "instructions: " + instructions);
691
- str = JSON.stringify(prompts, null, 4);
692
- return _this.emit('msg', "Prompts object: " + str);
693
- }
694
- };
695
- })(this));
696
- }
697
- this._allSessions = "";
698
- }
699
-
700
- SSH2Shell.prototype._initiate = function(action) {
701
- if (this.sshObj.debug) {
702
- this.emit('msg', this.sshObj.server.host + ": initiate");
703
- }
704
- this._loadDefaults();
705
- if (typeof action === 'function') {
706
- return action();
707
- }
708
- };
709
-
710
- SSH2Shell.prototype._loadDefaults = function() {
711
- var ref, ref1, ref2, ref3, ref4, ref5, ref6;
712
- if (this.sshObj.msg && this.sshObj.msg.send && typeof this.sshObj.msg.send === 'function') {
713
- this.sshObj.msg = this.sshObj.msg.send;
714
- }
715
- if (this.listenerCount("msg") > 0) {
716
- this.removeAllListeners("msg");
717
- }
718
- if (typeof this.sshObj.msg === 'function') {
719
- this.on("msg", this.sshObj.msg);
720
- } else {
721
- this.on("msg", (function(_this) {
722
- return function(message) {
723
- return console.log(message);
724
- };
725
- })(this));
726
- }
727
- if (this.sshObj.debug) {
728
- this.emit('msg', this.sshObj.server.host + ": Load Defaults");
729
- }
730
- this.command = "";
731
- this._buffer = "";
732
- this.sshObj.sshToNextHost = false;
733
- if (!this.sshObj.connectedMessage) {
734
- this.sshObj.connectedMessage = "Connected";
735
- }
736
- if (!this.sshObj.readyMessage) {
737
- this.sshObj.readyMessage = "Ready";
738
- }
739
- if (!this.sshObj.closedMessage) {
740
- this.sshObj.closedMessage = "Closed";
741
- }
742
- if (!this.sshObj.showBanner) {
743
- this.sshObj.showBanner = false;
744
- }
745
- if (!this.sshObj.verbose) {
746
- this.sshObj.verbose = false;
747
- }
748
- if (!this.sshObj.debug) {
749
- this.sshObj.debug = false;
750
- }
751
- if (!this.sshObj.hosts) {
752
- this.sshObj.hosts = [];
753
- }
754
- if (!this.sshObj.commands) {
755
- this.sshObj.commands = [];
756
- }
757
- if (!this.sshObj.standardPrompt) {
758
- this.sshObj.standardPrompt = ">$%#";
759
- }
760
- if (!this.sshObj.passwordPrompt) {
761
- this.sshObj.passwordPrompt = this.sshObj.passwordPromt;
762
- }
763
- if (!this.sshObj.passphrasePrompt) {
764
- this.sshObj.passphrasePrompt = this.sshObj.passphrasePromt;
765
- }
766
- if (!this.sshObj.passwordPrompt) {
767
- this.sshObj.passwordPrompt = ":";
768
- }
769
- if (!this.sshObj.passphrasePrompt) {
770
- this.sshObj.passphrasePrompt = ":";
771
- }
772
- if (!this.sshObj.passPromptText) {
773
- this.sshObj.passPromptText = "Password";
774
- }
775
- if (!this.sshObj.enter) {
776
- this.sshObj.enter = "\n";
777
- }
778
- if (!this.sshObj.asciiFilter) {
779
- this.sshObj.asciiFilter = "[^\r\n\x20-\x7e]";
780
- }
781
- if (this.sshObj.disableColorFilter !== true) {
782
- this.sshObj.disableColorFilter = false;
783
- }
784
- if (this.sshObj.disableASCIIFilter !== true) {
785
- this.sshObj.disableASCIIFilter = false;
786
- }
787
- if (!this.sshObj.textColorFilter) {
788
- this.sshObj.textColorFilter = "(\[{1}[0-9;]+m{1})";
789
- }
790
- if (!this.sshObj.exitCommands) {
791
- this.sshObj.exitCommands = [];
792
- }
793
- this.sshObj.pwSent = false;
794
- this.sshObj.sshAuth = false;
795
- this.sshObj.server.hashKey = (ref = this.sshObj.server.hashKey) != null ? ref : "";
796
- if (!this.sshObj.sessionText) {
797
- this.sshObj.sessionText = "";
798
- }
799
- this.sshObj.streamEncoding = (ref1 = this.sshObj.streamEncoding) != null ? ref1 : "utf8";
800
- if (!this.sshObj.window) {
801
- this.sshObj.window = true;
802
- }
803
- if (!this.sshObj.pty) {
804
- this.sshObj.pty = true;
805
- }
806
- this.idleTime = (ref2 = this.sshObj.idleTimeOut) != null ? ref2 : 5000;
807
- this.dataIdleTime = (ref3 = this.sshObj.dataIdleTime) != null ? ref3 : 500;
808
- if (!this.asciiFilter) {
809
- this.asciiFilter = new RegExp(this.sshObj.asciiFilter, "g");
810
- }
811
- if (!this.textColorFilter) {
812
- this.textColorFilter = new RegExp(this.sshObj.textColorFilter, "g");
813
- }
814
- if (!this.passwordPrompt) {
815
- this.passwordPrompt = new RegExp(this.sshObj.passPromptText + ".*" + this.sshObj.passwordPrompt + "\\s?$", "i");
816
- }
817
- if (!this.passphrasePrompt) {
818
- this.passphrasePrompt = new RegExp(this.sshObj.passPromptText + ".*" + this.sshObj.passphrasePrompt + "\\s?$", "i");
819
- }
820
- if (!this.standardPrompt) {
821
- this.standardPrompt = new RegExp("[" + this.sshObj.standardPrompt + "]\\s?$");
822
- }
823
- this.sshObj.onCommandProcessing = (ref4 = this.sshObj.onCommandProcessing) != null ? ref4 : (function(_this) {
824
- return function(command, response, sshObj, stream) {};
825
- })(this);
826
- this.sshObj.onCommandComplete = (ref5 = this.sshObj.onCommandComplete) != null ? ref5 : (function(_this) {
827
- return function(command, response, sshObj) {
828
- if (_this.sshObj.debug) {
829
- return _this.emit('msg', _this.sshObj.server.host + ": Class.commandComplete");
830
- }
831
- };
832
- })(this);
833
- this.sshObj.onCommandTimeout = (ref6 = this.sshObj.onCommandTimeout) != null ? ref6 : (function(_this) {
834
- return function(command, response, stream, connection) {
835
- response = response.replace(_this.command, "");
836
- if (_this.sshObj.debug) {
837
- _this.emit('msg', _this.sshObj.server.host + ": Class.commandTimeout");
838
- }
839
- if (_this.sshObj.verbose) {
840
- _this.emit('msg', _this.sshObj.server.host + ": Timeout command: " + command + " response: " + response);
841
- }
842
- _this.emit("error", _this.sshObj.server.host + ": Command timed out after " + (_this.idleTime / 1000) + " seconds", "Timeout", true, function(err, type) {});
843
- return _this.sshObj.sessionText += _this._buffer;
844
- };
845
- })(this);
846
- if (typeof this.sshObj.onKeyboardInteractive === 'function') {
847
- this.on("keyboard-interactive", this.sshObj.onKeyboardInteractive);
848
- }
849
- if (typeof this.sshObj.onError === 'function') {
850
- this.on("error", this.sshObj.onError);
851
- }
852
- if (typeof this.sshObj.onData === 'function') {
853
- this.on("data", this.sshObj.onData);
854
- }
855
- if (typeof this.sshObj.onStderrData === 'function') {
856
- this.on("stderrData", this.sshObj.onStderrData);
857
- }
858
- this.on("commandProcessing", this.sshObj.onCommandProcessing);
859
- this.on("commandComplete", this.sshObj.onCommandComplete);
860
- this.on("commandTimeout", this.sshObj.onCommandTimeout);
861
- if (typeof this.sshObj.onEnd === 'function') {
862
- this.on("end", this.sshObj.onEnd);
863
- }
864
- if (this.sshObj.debug) {
865
- this.emit('msg', this.sshObj.server.host + ": Host loaded");
866
- }
867
- if (this.sshObj.verbose) {
868
- return this.emit('msg', this.sshObj);
869
- }
870
- };
871
-
872
- SSH2Shell.prototype.connect = function(callback) {
873
- if (typeof callback === 'function') {
874
- this._callback = callback;
875
- }
876
- return this.emit("newPrimaryHost", this._nextPrimaryHost(this._connect));
877
- };
878
-
879
- SSH2Shell.prototype._connect = function() {
880
- var e;
881
- this.connection = new this.ssh2Client();
882
- this.connection.on("keyboard-interactive", (function(_this) {
883
- return function(name, instructions, instructionsLang, prompts, finish) {
884
- if (_this.sshObj.debug) {
885
- _this.emit('msg', _this.sshObj.server.host + ": Connection.keyboard-interactive");
886
- }
887
- return _this.emit("keyboard-interactive", name, instructions, instructionsLang, prompts, finish);
888
- };
889
- })(this));
890
- this.connection.on("connect", (function(_this) {
891
- return function() {
892
- if (_this.sshObj.debug) {
893
- _this.emit('msg', _this.sshObj.server.host + ": Connection.connect");
894
- }
895
- return _this.emit('msg', _this.sshObj.connectedMessage);
896
- };
897
- })(this));
898
- this.connection.on("ready", (function(_this) {
899
- return function() {
900
- if (_this.sshObj.debug) {
901
- _this.emit('msg', _this.sshObj.server.host + ": Connection.ready");
902
- }
903
- _this.emit('msg', _this.sshObj.readyMessage);
904
- return _this.connection.shell(_this.sshObj.window, {
905
- pty: _this.sshObj.pty
906
- }, function(err, _stream) {
907
- _this._stream = _stream;
908
- if (err instanceof Error) {
909
- _this.emit('error', err, "Shell", true);
910
- return;
911
- }
912
- if (_this.sshObj.debug) {
913
- _this.emit('msg', _this.sshObj.server.host + ": Connection.shell");
914
- }
915
- _this._stream.setEncoding(_this.sshObj.streamEncoding);
916
- _this._stream.on("error", function(err) {
917
- if (_this.sshObj.debug) {
918
- _this.emit('msg', _this.sshObj.server.host + ": Stream.error");
919
- }
920
- return _this.emit('error', err, "Stream");
921
- });
922
- _this._stream.stderr.on('data', function(data) {
923
- if (_this.sshObj.debug) {
924
- _this.emit('msg', _this.sshObj.server.host + ": Stream.stderr.data");
925
- }
926
- return _this.emit('stderrData', data);
927
- });
928
- _this._stream.on("data", function(data) {
929
- var e;
930
- try {
931
- return _this.emit('data', data);
932
- } catch (error) {
933
- e = error;
934
- err = new Error(e + " " + e.stack);
935
- err.level = "Data handling";
936
- return _this.emit('error', err, "Stream.read", true);
937
- }
938
- });
939
- _this._stream.on("finish", function() {
940
- if (_this.sshObj.debug) {
941
- _this.emit('msg', _this.sshObj.server.host + ": Stream.finish");
942
- }
943
- _this._primaryhostSessionText += _this.sshObj.sessionText + "\n";
944
- _this._allSessions += _this._primaryhostSessionText;
945
- if (_this._hosts.length === 0) {
946
- return _this.emit('end', _this._allSessions, _this.sshObj);
947
- }
948
- });
949
- return _this._stream.on("close", function(code, signal) {
950
- if (_this.sshObj.debug) {
951
- _this.emit('msg', _this.sshObj.server.host + ": Stream.close");
952
- }
953
- return _this.connection.end();
954
- });
955
- });
956
- };
957
- })(this));
958
- this.connection.on("error", (function(_this) {
959
- return function(err) {
960
- if (_this.sshObj.debug) {
961
- _this.emit('msg', _this.sshObj.server.host + ": Connection.error");
962
- }
963
- return _this.emit("error", err, "Connection");
964
- };
965
- })(this));
966
- this.connection.on("close", (function(_this) {
967
- return function(had_error) {
968
- if (_this.sshObj.debug) {
969
- _this.emit('msg', _this.sshObj.server.host + ": Connection.close");
970
- }
971
- if (_this.idleTimer) {
972
- clearTimeout(_this.idleTimer);
973
- }
974
- if (_this.dataReceivedTimer) {
975
- clearTimeout(_this.dataReceivedTimer);
976
- }
977
- if (had_error) {
978
- _this.emit("error", had_error, "Connection close");
979
- } else {
980
- _this.emit('msg', _this.sshObj.closedMessage);
981
- }
982
- if (_this._hosts.length === 0) {
983
- if (typeof _this._callback === 'function') {
984
- _this._callback(_this._allSessions);
985
- _this._removeListeners();
986
- return _this._allSessions;
987
- }
988
- } else {
989
- return _this.emit("newPrimaryHost", _this._nextPrimaryHost(_this._connect));
990
- }
991
- };
992
- })(this));
993
- if (this.sshObj.server && this.sshObj.commands) {
994
- try {
995
- if (!this.sshObj.server.username) {
996
- this.sshObj.server.username = this.sshObj.server.userName;
997
- }
998
- if (!this.sshObj.server.hostHash) {
999
- this.sshObj.server.hostHash = this.sshObj.server.hashMethod;
1000
- }
1001
- if (!this.sshObj.server.passphrase) {
1002
- this.sshObj.server.passphrase = this.sshObj.server.passPhrase;
1003
- }
1004
- this.connection.connect(this.sshObj.server);
1005
- } catch (error) {
1006
- e = error;
1007
- this.emit('error', e + " " + e.stack, "Connection.connect", true);
1008
- }
1009
- } else {
1010
- this.emit('error', "Missing connection parameters", "Parameters", false, function(err, type, close) {
1011
- this.emit('msg', this.sshObj.server);
1012
- return this.emit('msg', this.sshObj.commands);
1013
- });
1014
- }
1015
- return this._stream;
1016
- };
1017
-
1018
- return SSH2Shell;
1019
-
1020
- })(Stream);
1021
-
1022
- module.exports = SSH2Shell;
1023
-
1024
- }).call(this);
1
+ // Generated by CoffeeScript 1.12.7
2
+ (function() {
3
+ var SSH2Shell, Stream, typeIsArray,
4
+ bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
5
+ extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
6
+ hasProp = {}.hasOwnProperty;
7
+
8
+ typeIsArray = Array.isArray || function(value) {
9
+ return {}.toString.call(value) === '[object Array]';
10
+ };
11
+
12
+ Stream = require('stream');
13
+
14
+ SSH2Shell = (function(superClass) {
15
+ extend(SSH2Shell, superClass);
16
+
17
+ SSH2Shell.prototype.sshObj = {};
18
+
19
+ SSH2Shell.prototype.command = "";
20
+
21
+ SSH2Shell.prototype._hosts = [];
22
+
23
+ SSH2Shell.prototype._sshToNextHost = false;
24
+
25
+ SSH2Shell.prototype._primaryhostSessionText = "";
26
+
27
+ SSH2Shell.prototype._allSessions = "";
28
+
29
+ SSH2Shell.prototype._connections = [];
30
+
31
+ SSH2Shell.prototype._stream = {};
32
+
33
+ SSH2Shell.prototype._buffer = "";
34
+
35
+ SSH2Shell.prototype.idleTime = 5000;
36
+
37
+ SSH2Shell.prototype.asciiFilter = "";
38
+
39
+ SSH2Shell.prototype.textColorFilter = "";
40
+
41
+ SSH2Shell.prototype.passwordPrompt = "";
42
+
43
+ SSH2Shell.prototype.passphrasePrompt = "";
44
+
45
+ SSH2Shell.prototype.standardPrompt = "";
46
+
47
+ SSH2Shell.prototype._callback = function() {};
48
+
49
+ SSH2Shell.prototype.onCommandProcessing = function() {};
50
+
51
+ SSH2Shell.prototype.onCommandComplete = function() {};
52
+
53
+ SSH2Shell.prototype.onCommandTimeout = function() {};
54
+
55
+ SSH2Shell.prototype.onEnd = function() {};
56
+
57
+ SSH2Shell.prototype._onData = function(data) {
58
+ this._buffer += data;
59
+ if (this.command.length > 0 && !this.standardPrompt.test(this._sanitizeResponse())) {
60
+ this.emit('commandProcessing', this.command, this._buffer, this.sshObj, this._stream);
61
+ if (this.idleTimer) {
62
+ clearTimeout(this.idleTimer);
63
+ }
64
+ this.idleTimer = setTimeout((function(_this) {
65
+ return function() {
66
+ return _this.emit('commandTimeout', _this.command, _this._buffer, _this._stream, _this.connection);
67
+ };
68
+ })(this), this.idleTime);
69
+ } else if (this.command.length < 1 && !this.standardPrompt.test(this._buffer)) {
70
+ this.emit('commandProcessing', this.command, this._buffer, this.sshObj, this._stream);
71
+ }
72
+ if (this.dataReceivedTimer) {
73
+ clearTimeout(this.dataReceivedTimer);
74
+ }
75
+ return this.dataReceivedTimer = setTimeout((function(_this) {
76
+ return function() {
77
+ if (_this.idleTimer) {
78
+ clearTimeout(_this.idleTimer);
79
+ }
80
+ if (!_this.sshObj.disableColorFilter) {
81
+ _this._buffer = _this._buffer.replace(_this.textColorFilter, "");
82
+ }
83
+ if (!_this.sshObj.disableASCIIFilter) {
84
+ _this._buffer = _this._buffer.replace(_this.asciiFilter, "");
85
+ }
86
+ switch (true) {
87
+ case _this.command.length > 0 && _this.command.indexOf("sudo ") !== -1:
88
+ if (_this.sshObj.debug) {
89
+ _this.emit('msg', _this.sshObj.server.host + ": Sudo command data");
90
+ }
91
+ return _this._processPasswordPrompt();
92
+ case _this.sshObj.sshToNextHost && _this.command.length > 0 && _this.command.indexOf("ssh ") === 0:
93
+ if (_this.sshObj.debug) {
94
+ _this.emit('msg', _this.sshObj.server.host + ": SSH command data");
95
+ }
96
+ return _this._processSSHPrompt();
97
+ case _this.command.length > 0 && _this.standardPrompt.test(_this._sanitizeResponse()):
98
+ if (_this.sshObj.debug) {
99
+ _this.emit('msg', _this.sshObj.server.host + ": Normal prompt detected");
100
+ }
101
+ _this.sshObj.pwSent = false;
102
+ return _this._commandComplete();
103
+ case _this.command.length < 1 && _this.standardPrompt.test(_this._buffer):
104
+ if (_this.sshObj.debug) {
105
+ _this.emit('msg', _this.sshObj.server.host + ": First prompt detected");
106
+ }
107
+ if (_this.sshObj.showBanner) {
108
+ _this.sshObj.sessionText += _this._buffer;
109
+ }
110
+ return _this._nextCommand();
111
+ default:
112
+ if (_this.sshObj.debug) {
113
+ _this.emit('msg', "Data processing: data received timeout");
114
+ }
115
+ return _this.idleTimer = setTimeout(function() {
116
+ return _this.emit('commandTimeout', _this.command, _this._buffer, _this._stream, _this.connection);
117
+ }, _this.idleTime);
118
+ }
119
+ };
120
+ })(this), this.dataIdleTime);
121
+ };
122
+
123
+ SSH2Shell.prototype._sanitizeResponse = function() {
124
+ return this._buffer.replace(this.command.substr(0, this._buffer.length), "");
125
+ };
126
+
127
+ SSH2Shell.prototype._processPasswordPrompt = function() {
128
+ var passwordPrompt, response, standardPrompt;
129
+ response = this._sanitizeResponse().trim();
130
+ passwordPrompt = this.passwordPrompt.test(response);
131
+ standardPrompt = this.standardPrompt.test(response);
132
+ if (this.sshObj.debug) {
133
+ this.emit('msg', this.sshObj.server.host + ": Sudo Password prompt detected: " + passwordPrompt);
134
+ }
135
+ if (this.sshObj.debug) {
136
+ this.emit('msg', this.sshObj.server.host + ": Sudo Password prompt: Password sent: " + this.sshObj.pwSent);
137
+ }
138
+ if (this.sshObj.debug) {
139
+ this.emit('msg', this.sshObj.server.host + ": Sudo Password: " + this.sshObj.server.password);
140
+ }
141
+ if (this.sshObj.verbose) {
142
+ this.emit('msg', this.sshObj.server.host + ": Sudo Response: " + response);
143
+ }
144
+ switch (true) {
145
+ case passwordPrompt && !this.sshObj.server.password:
146
+ if (this.sshObj.debug) {
147
+ this.emit('msg', this.sshObj.server.host + ": Sudo password prompt no password set");
148
+ }
149
+ return this._resetFromSudoError();
150
+ case passwordPrompt && !this.sshObj.pwSent:
151
+ if (this.sshObj.verbose) {
152
+ this.emit('msg', this.sshObj.server.host + ": Sudo password prompt: Buffer: " + response);
153
+ }
154
+ if (this.sshObj.debug) {
155
+ this.emit('msg', this.sshObj.server.host + ": Sudo password prompt: Send password ");
156
+ }
157
+ if (this.sshObj.verbose) {
158
+ this.emit('msg', this.sshObj.server.host + ": Sudo sent password: " + this.sshObj.server.password);
159
+ }
160
+ this.sshObj.pwSent = true;
161
+ return this._runCommand("" + this.sshObj.server.password);
162
+ case passwordPrompt && this.sshObj.pwSent:
163
+ if (this.sshObj.verbose) {
164
+ this.emit('msg', this.sshObj.server.host + ": Sudo password faied: response: " + response);
165
+ }
166
+ if (this.sshObj.debug) {
167
+ this.emit('error', this.sshObj.server.host + ": Sudo password was incorrect for " + this.sshObj.server.userName + ", Sudo authentication");
168
+ }
169
+ if (this.sshObj.debug) {
170
+ this.emit('msg', this.sshObj.server.host + ": Sudo failed password prompt: Password: [" + this.sshObj.server.password + "]");
171
+ }
172
+ this.sshObj.pwSent = false;
173
+ return this._resetFromSudoError();
174
+ case standardPrompt:
175
+ if (this.sshObj.debug) {
176
+ this.emit('msg', this.sshObj.server.host + ": Sudo password accepted");
177
+ }
178
+ this.sshObj.pwSent = false;
179
+ if (this.sshObj.verbose) {
180
+ this.emit('msg', this.sshObj.server.host + ": Sudo Standard Response: " + response);
181
+ }
182
+ return this._commandComplete();
183
+ default:
184
+ return this.idleTimer = setTimeout((function(_this) {
185
+ return function() {
186
+ return _this.emit('commandTimeout', _this.command, response, _this._stream, _this._connection);
187
+ };
188
+ })(this), this.idleTime);
189
+ }
190
+ };
191
+
192
+ SSH2Shell.prototype._resetFromSudoError = function() {
193
+ this.sshObj.pwSent = false;
194
+ this.sshObj.sessionText += "" + this._buffer;
195
+ this._buffer = "";
196
+ this.command = "";
197
+ return this._stream.write('\x03');
198
+ };
199
+
200
+ SSH2Shell.prototype._processSSHPrompt = function() {
201
+ var passphrasePrompt, passwordPrompt, response, standardPrompt, using;
202
+ response = this._sanitizeResponse().trim();
203
+ if (this.idleTimer) {
204
+ clearTimeout(this.idleTimer);
205
+ }
206
+ passwordPrompt = this.passwordPrompt.test(response) && !this.sshObj.server.hasOwnProperty("passPhrase");
207
+ passphrasePrompt = this.passphrasePrompt.test(response) && this.sshObj.server.hasOwnProperty("passPhrase");
208
+ standardPrompt = this.standardPrompt.test(response);
209
+ if (this.sshObj.verbose) {
210
+ this.emit('msg', this.sshObj.server.host + ": SSH: Password previously sent: " + this.sshObj.sshAuth);
211
+ }
212
+ if (!this.sshObj.sshAuth) {
213
+ if (this.sshObj.debug) {
214
+ this.emit('msg', this.sshObj.server.host + ": First SSH prompt detection");
215
+ }
216
+ if (passwordPrompt) {
217
+ if (this.sshObj.debug) {
218
+ this.emit('msg', this.sshObj.server.host + ": SSH send password");
219
+ }
220
+ this.sshObj.sshAuth = true;
221
+ this._buffer = "";
222
+ return this._runCommand("" + this.sshObj.server.password);
223
+ } else if (passphrasePrompt) {
224
+ if (this.sshObj.debug) {
225
+ this.emit('msg', this.sshObj.server.host + ": SSH send passphrase");
226
+ }
227
+ this.sshObj.sshAuth = true;
228
+ this._buffer = "";
229
+ return this._runCommand("" + this.sshObj.server.passPhrase);
230
+ } else if (standardPrompt) {
231
+ if (this.sshObj.debug) {
232
+ this.emit('msg', this.sshObj.server.host + ": SSH standard prompt: connection failed");
233
+ }
234
+ this.emit('msg', this.sshObj.server.host + ": SSH connection failed");
235
+ this.emit('msg', this.sshObj.server.host + ": SSH failed response: " + response);
236
+ this.sshObj.sessionText += this.sshObj.server.host + ": SSH failed: response: " + response;
237
+ return this._runExit();
238
+ } else {
239
+ this.emit('msg', this.sshObj.server.host + ": SSH no prompt was not detected");
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);
245
+ }
246
+ if (this.sshObj.verbose && this.sshObj.server.hasOwnProperty("passPhrase")) {
247
+ this.emit('msg', this.sshObj.server.host + ": SSH passphrase prompt: " + this.sshObj.passphrasePrompt);
248
+ }
249
+ if (this.sshObj.verbose) {
250
+ this.emit('msg', this.sshObj.server.host + ": SSH standard prompt: " + this.sshObj.standardPrompt);
251
+ }
252
+ return this._runExit();
253
+ }
254
+ } else {
255
+ if (this.sshObj.debug) {
256
+ this.emit('msg', this.sshObj.server.host + ": SSH post authentication prompt detection");
257
+ }
258
+ if (standardPrompt) {
259
+ if (this.sshObj.debug) {
260
+ this.emit('msg', this.sshObj.server.host + ": SSH complete: normal prompt");
261
+ }
262
+ if (this.sshObj.showBanner) {
263
+ this.sshObj.sessionText += "\n " + response;
264
+ }
265
+ this.sshObj.exitCommands.push("exit");
266
+ this.emit('msg', "" + this.sshObj.connectedMessage);
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;
272
+ return this._nextCommand();
273
+ } else if (passwordPrompt || passphrasePrompt) {
274
+ this.emit('msg', this.sshObj.server.host + ": SSH authentication failed");
275
+ if (this.sshObj.debug) {
276
+ this.emit('msg', this.sshObj.server.host + ": SSH auth failed");
277
+ }
278
+ if (this.sshObj.verbose) {
279
+ this.emit('msg', this.sshObj.server.host + ": SSH: failed response: " + response);
280
+ }
281
+ this.sshObj.sshAuth = false;
282
+ using = (function() {
283
+ switch (false) {
284
+ case !passwordPrompt:
285
+ return "SSH password: " + this.sshObj.server.password;
286
+ case !passphrasePrompt:
287
+ return "SSH passphrase: " + this.sshObj.server.passPhrase;
288
+ }
289
+ }).call(this);
290
+ this.emit('error', this.sshObj.server.host + ": SSH authentication failed for " + this.sshObj.server.userName + "@" + this.sshObj.server.host, "Nested host authentication");
291
+ if (this.sshObj.debug) {
292
+ this.emit('msg', (this.sshObj.server.host + ": SSH auth failed: Using ") + using);
293
+ }
294
+ if (this.sshObj.verbose) {
295
+ this.emit('msg', this.sshObj.server.host + ": SSH response: " + response);
296
+ }
297
+ if (this._connections.length > 0) {
298
+ return this._previousHost();
299
+ }
300
+ return this._runExit();
301
+ }
302
+ }
303
+ };
304
+
305
+ SSH2Shell.prototype._processNotifications = function() {
306
+ var msgNote, sessionNote;
307
+ if (this.command) {
308
+ if ((sessionNote = this.command.match(/^`(.*)`$/))) {
309
+ if (this.sshObj.debug) {
310
+ this.emit('msg', this.sshObj.server.host + ": Notifications: sessionText output");
311
+ }
312
+ if (this._connections.length > 0) {
313
+ this.sshObj.sessionText += this.sshObj.server.host + ": Note: " + sessionNote[1] + this.sshObj.enter;
314
+ } else {
315
+ this.sshObj.sessionText += "Note: " + sessionNote[1] + this.sshObj.enter;
316
+ }
317
+ if (this.sshObj.verbose) {
318
+ this.emit('msg', sessionNote[1]);
319
+ }
320
+ return this._nextCommand();
321
+ } else if ((msgNote = this.command.match(/^msg:(.*)$/))) {
322
+ if (this.sshObj.debug) {
323
+ this.emit('msg', this.sshObj.server.host + ": Notifications: msg to output");
324
+ }
325
+ this.emit('msg', this.sshObj.server.host + ": Note: " + msgNote[1]);
326
+ return this._nextCommand();
327
+ } else {
328
+ if (this.sshObj.debug) {
329
+ this.emit('msg', this.sshObj.server.host + ": Notifications: Normal Command to run");
330
+ }
331
+ return this._checkCommand();
332
+ }
333
+ }
334
+ };
335
+
336
+ SSH2Shell.prototype._commandComplete = function() {
337
+ var response;
338
+ response = this._buffer.trim();
339
+ if (this.command !== "" && this.command !== "exit" && this.sshObj.sshToNextHost !== true) {
340
+ if (this.sshObj.verbose) {
341
+ this.emit('msg', this.sshObj.server.host + ": Command complete:\nCommand:\n " + this.command + "\nResponse: " + response);
342
+ }
343
+ this.sshObj.sessionText += response;
344
+ if (this.sshObj.debug) {
345
+ this.emit('msg', this.sshObj.server.host + ": Raising commandComplete event");
346
+ }
347
+ this.emit('commandComplete', this.command, this._buffer, this.sshObj);
348
+ }
349
+ return this._nextCommand();
350
+ };
351
+
352
+ SSH2Shell.prototype._nextCommand = function() {
353
+ this._buffer = "";
354
+ if (this.sshObj.commands.length > 0) {
355
+ if (this.sshObj.verbose) {
356
+ this.emit('msg', this.sshObj.server.host + ": Host.commands: " + this.sshObj.commands);
357
+ }
358
+ this.command = this.sshObj.commands.shift();
359
+ if (this.sshObj.verbose) {
360
+ this.emit('msg', this.sshObj.server.host + ": Next command from host.commands: " + this.command);
361
+ }
362
+ return this._processNotifications();
363
+ } else {
364
+ if (this.sshObj.debug) {
365
+ this.emit('msg', this.sshObj.server.host + ": No commands so exit");
366
+ }
367
+ return this._runExit();
368
+ }
369
+ };
370
+
371
+ SSH2Shell.prototype._checkCommand = function() {
372
+ if (this.command !== "") {
373
+ return this._runCommand(this.command);
374
+ } else {
375
+ if (this.sshObj.debug) {
376
+ this.emit('msg', this.sshObj.server.host + ": No command so exit");
377
+ }
378
+ return this._runExit();
379
+ }
380
+ };
381
+
382
+ SSH2Shell.prototype._runCommand = function(command) {
383
+ if (this.sshObj.verbose) {
384
+ this.emit('msg', this.sshObj.server.host + ": sending: " + command);
385
+ }
386
+ if (this.sshObj.debug) {
387
+ this.emit('msg', this.sshObj.server.host + ": run command");
388
+ }
389
+ return this._stream.write("" + command + this.sshObj.enter);
390
+ };
391
+
392
+ SSH2Shell.prototype._previousHost = function() {
393
+ if (this.sshObj.debug) {
394
+ this.emit('msg', this.sshObj.server.host + ": Load previous host config");
395
+ }
396
+ this.emit('end', this.sshObj.server.host + ": \n" + this.sshObj.sessionText, this.sshObj);
397
+ if (this.sshObj.debug) {
398
+ this.emit('msg', this.sshObj.server.host + ": Previous hosts: " + this._connections.length);
399
+ }
400
+ if (this._connections.length > 0) {
401
+ this.sshObj = this._connections.pop();
402
+ if (this.sshObj.debug) {
403
+ this.emit('msg', this.sshObj.server.host + ": Reload previous host");
404
+ }
405
+ return this._runExit();
406
+ } else {
407
+ return this._runExit();
408
+ }
409
+ };
410
+
411
+ SSH2Shell.prototype._nextHost = function() {
412
+ var nextHost;
413
+ nextHost = this.sshObj.hosts.shift();
414
+ if (this.sshObj.debug) {
415
+ this.emit('msg', this.sshObj.server.host + ": SSH to " + nextHost.server.host);
416
+ }
417
+ if (this.sshObj.debug) {
418
+ this.emit('msg', this.sshObj.server.host + ": Clearing previous event handlers");
419
+ }
420
+ if (this.sshObj.debug) {
421
+ this.emit('msg', this.sshObj.server.host + ": Remove previous event handlers");
422
+ }
423
+ this._removeListeners();
424
+ this._connections.push(this.sshObj);
425
+ this.sshObj = nextHost;
426
+ return this._initiate(this._sshConnect);
427
+ };
428
+
429
+ SSH2Shell.prototype._nextPrimaryHost = function(connect) {
430
+ if (this._hosts.length > 0) {
431
+ if (this.sshObj.server) {
432
+ if (this.sshObj.debug) {
433
+ this.emit('msg', this.sshObj.server.host + ": Current primary host");
434
+ }
435
+ if (this.sshObj.debug) {
436
+ this.emit('msg', this.sshObj.server.host + ": Remove previous event handlers");
437
+ }
438
+ this.emit('end', this._primaryhostSessionText, this.sshObj);
439
+ this._removeListeners();
440
+ }
441
+ this.sshObj = this._hosts.shift();
442
+ this._primaryhostSessionText = this.sshObj.server.host + ": ";
443
+ if (this.sshObj.debug) {
444
+ this.emit('msg', this.sshObj.server.host + ": Next primary host");
445
+ }
446
+ return this._initiate(connect);
447
+ } else {
448
+ if (this.sshObj.debug) {
449
+ this.emit('msg', this.sshObj.server.host + ": No more primary hosts");
450
+ }
451
+ return this._runExit;
452
+ }
453
+ };
454
+
455
+ SSH2Shell.prototype._sshConnect = function() {
456
+ var option, ref, safeHost, safeOption, safePort, safeUser, safeValue, shellControlChars, shellQuote, sshFlags, sshOptions, value;
457
+ sshFlags = "-x";
458
+ sshOptions = "";
459
+ shellQuote = function(value) {
460
+ return "'" + String(value).replace(/'/g, "'\\''") + "'";
461
+ };
462
+ shellControlChars = /[;&|`$\n\r]/;
463
+ if (this.sshObj.server.ssh) {
464
+ if (this.sshObj.server.ssh.forceProtocolVersion) {
465
+ sshFlags += this.sshObj.server.ssh.forceProtocolVersion;
466
+ }
467
+ if (this.sshObj.server.ssh.forceAddressType) {
468
+ sshFlags += this.sshObj.server.ssh.forceAddressType;
469
+ }
470
+ if (this.sshObj.server.ssh.disablePseudoTTY) {
471
+ sshFlags += "T";
472
+ }
473
+ if (this.sshObj.server.ssh.forcePseudoTTY) {
474
+ sshFlags += "t";
475
+ }
476
+ if (this.sshObj.server.ssh.verbose) {
477
+ sshFlags += "v";
478
+ }
479
+ if (this.sshObj.server.ssh.cipherSpec) {
480
+ if (shellControlChars.test(this.sshObj.server.ssh.cipherSpec)) {
481
+ this.emit('error', "Malicious characters detected in SSH cipherSpec.", "Security Alert", true);
482
+ return;
483
+ }
484
+ sshOptions += " -c " + shellQuote(this.sshObj.server.ssh.cipherSpec);
485
+ }
486
+ if (this.sshObj.server.ssh.escape) {
487
+ if (shellControlChars.test(this.sshObj.server.ssh.escape)) {
488
+ this.emit('error', "Malicious characters detected in SSH escape sequence.", "Security Alert", true);
489
+ return;
490
+ }
491
+ sshOptions += " -e " + shellQuote(this.sshObj.server.ssh.escape);
492
+ }
493
+ if (this.sshObj.server.ssh.logFile) {
494
+ if (shellControlChars.test(this.sshObj.server.ssh.logFile)) {
495
+ this.emit('error', "Malicious characters detected in SSH logFile path.", "Security Alert", true);
496
+ return;
497
+ }
498
+ sshOptions += " -E " + shellQuote(this.sshObj.server.ssh.logFile);
499
+ }
500
+ if (this.sshObj.server.ssh.configFile) {
501
+ if (shellControlChars.test(this.sshObj.server.ssh.configFile)) {
502
+ this.emit('error', "Malicious characters detected in SSH configFile path.", "Security Alert", true);
503
+ return;
504
+ }
505
+ sshOptions += " -F " + shellQuote(this.sshObj.server.ssh.configFile);
506
+ }
507
+ if (this.sshObj.server.ssh.identityFile) {
508
+ if (shellControlChars.test(this.sshObj.server.ssh.identityFile)) {
509
+ this.emit('error', "Malicious characters detected in SSH identityFile path.", "Security Alert", true);
510
+ return;
511
+ }
512
+ sshOptions += " -i " + shellQuote(this.sshObj.server.ssh.identityFile);
513
+ }
514
+ if (this.sshObj.server.ssh.loginName) {
515
+ if (shellControlChars.test(this.sshObj.server.ssh.loginName)) {
516
+ this.emit('error', "Malicious characters detected in SSH loginName.", "Security Alert", true);
517
+ return;
518
+ }
519
+ sshOptions += " -l " + shellQuote(this.sshObj.server.ssh.loginName);
520
+ }
521
+ if (this.sshObj.server.ssh.macSpec) {
522
+ if (shellControlChars.test(this.sshObj.server.ssh.macSpec)) {
523
+ this.emit('error', "Malicious characters detected in SSH macSpec.", "Security Alert", true);
524
+ return;
525
+ }
526
+ sshOptions += " -m " + shellQuote(this.sshObj.server.ssh.macSpec);
527
+ }
528
+ ref = this.sshObj.server.ssh.options || {};
529
+ for (option in ref) {
530
+ value = ref[option];
531
+ if (shellControlChars.test(option) || shellControlChars.test(value)) {
532
+ this.emit('error', "Malicious characters detected in SSH options.", "Security Alert", true);
533
+ return;
534
+ }
535
+ safeOption = String(option).replace(/[^a-zA-Z0-9]/g, "");
536
+ safeValue = shellQuote(value);
537
+ sshOptions += " -o " + safeOption + "=" + safeValue;
538
+ }
539
+ }
540
+ sshOptions += ' -o "StrictHostKeyChecking=no"';
541
+ safePort = String(this.sshObj.server.port || 22).replace(/[^0-9]/g, "");
542
+ sshOptions += " -p " + safePort;
543
+ safeUser = shellQuote(this.sshObj.server.userName);
544
+ safeHost = shellQuote(this.sshObj.server.host);
545
+ this.sshObj.sshAuth = false;
546
+ this.sshObj.sshToNextHost = true;
547
+ this.command = "ssh " + sshFlags + " " + sshOptions + " " + safeUser + "@" + safeHost;
548
+ if (this.sshObj.debug) {
549
+ this.emit('msg', this.sshObj.server.host + ": SSH command: connect");
550
+ }
551
+ return this._runCommand(this.command);
552
+ };
553
+
554
+ SSH2Shell.prototype._runExit = function() {
555
+ if (this.sshObj.debug) {
556
+ this.emit('msg', this.sshObj.server.host + ": Process an exit");
557
+ }
558
+ if (this.sshObj.exitCommands && this.sshObj.exitCommands.length > 0) {
559
+ if (this.sshObj.debug) {
560
+ this.emit('msg', this.sshObj.server.host + ": Queued exit commands: " + this.sshObj.exitCommands.length);
561
+ }
562
+ this.command = this.sshObj.exitCommands.pop();
563
+ if (this._connections && this._connections.length > 0) {
564
+ if (this.sshObj.verbose) {
565
+ this.emit('msg', this.sshObj.server.host + ": Primary host: " + this._connections[0].server.host);
566
+ }
567
+ this._connections[0].sessionText += "\n" + this.sshObj.server.host + ": " + this.sshObj.sessionText;
568
+ }
569
+ return this._runCommand(this.command);
570
+ } else if (this.sshObj.hosts && this.sshObj.hosts.length > 0) {
571
+ if (this.sshObj.debug) {
572
+ this.emit('msg', this.sshObj.server.host + ": Next host from this host");
573
+ }
574
+ return this._nextHost();
575
+ } else if (this._connections && this._connections.length > 0) {
576
+ if (this.sshObj.debug) {
577
+ this.emit('msg', this.sshObj.server.host + ": load previous host");
578
+ }
579
+ this.emit('msg', this.sshObj.server.host + ": " + this.sshObj.closedMessage);
580
+ return this._previousHost();
581
+ } else if (this.command === "exit") {
582
+ if (this.sshObj.debug) {
583
+ this.emit('msg', this.sshObj.server.host + ": Manual exit command");
584
+ }
585
+ return this._runCommand("exit");
586
+ } else {
587
+ return this.close();
588
+ }
589
+ };
590
+
591
+ SSH2Shell.prototype.close = function() {
592
+ if (this.sshObj.debug) {
593
+ this.emit('msg', this.sshObj.server.host + ": Exit command: Stream: close");
594
+ }
595
+ return this._stream.close();
596
+ };
597
+
598
+ SSH2Shell.prototype._removeListeners = function() {
599
+
600
+ /*
601
+ if @sshObj.debug
602
+ @.emit 'msg', "#{@sshObj.server.host}: Event handler count:"
603
+ @.emit 'msg', "keyboard-interactive: " + (@.listenerCount 'keyboard-interactive')
604
+ @.emit 'msg', "error: " + (@.listenerCount "error")
605
+ @.emit 'msg', "data: " + (@.listenerCount "data")
606
+ @.emit 'msg', "stderrData: " + (@.listenerCount "stderrData")
607
+ @.emit 'msg', "end: " + (@.listenerCount 'end')
608
+ @.emit 'msg', "commandProcessing: " + (@.listenerCount 'commandProcessing')
609
+ @.emit 'msg', "commandComplete: " + (@.listenerCount 'commandComplete')
610
+ @.emit 'msg', "commandTimeout: " + (@.listenerCount 'commandTimeout')
611
+ @.emit 'msg', "msg: " + (@.listenerCount 'msg')
612
+ */
613
+ if (typeof this.sshObj.onKeyboardInteractive === 'function') {
614
+ this.removeListener("keyboard-interactive", this.sshObj.onKeyboardInteractive);
615
+ }
616
+ if (typeof this.sshObj.onStderrData === 'function') {
617
+ this.removeListener("stderrData", this.sshObj.onStderrData);
618
+ }
619
+ if (typeof this.sshObj.onData === 'function') {
620
+ this.removeListener("data", this.sshObj.onData);
621
+ }
622
+ if (typeof this.sshObj.onError === 'function') {
623
+ this.removeListener("error", this.sshObj.onError);
624
+ }
625
+ if (typeof this.sshObj.onStderrData === 'function') {
626
+ this.removeListener("stderrData", this.sshObj.onStderrData);
627
+ }
628
+ if (typeof this.sshObj.onEnd === 'function') {
629
+ this.removeListener("end", this.sshObj.onEnd);
630
+ }
631
+ if (typeof this.sshObj.onCommandProcessing === 'function') {
632
+ this.removeListener("commandProcessing", this.sshObj.onCommandProcessing);
633
+ }
634
+ if (typeof this.sshObj.onCommandComplete === 'function') {
635
+ this.removeListener("commandComplete", this.sshObj.onCommandComplete);
636
+ }
637
+ if (typeof this.sshObj.onCommandTimeout === 'function') {
638
+ this.removeListener("commandTimeout", this.sshObj.onCommandTimeout);
639
+ }
640
+ if (typeof this.sshObj.msg === 'function') {
641
+ this.removeListener("msg", this.sshObj.msg);
642
+ }
643
+ if (this.idleTimer) {
644
+ clearTimeout(this.idleTimer);
645
+ }
646
+ if (this.dataReceivedTimer) {
647
+ return clearTimeout(this.dataReceivedTimer);
648
+ }
649
+ };
650
+
651
+ function SSH2Shell(hosts) {
652
+ this._connect = bind(this._connect, this);
653
+ this.connect = bind(this.connect, this);
654
+ this._loadDefaults = bind(this._loadDefaults, this);
655
+ this._initiate = bind(this._initiate, this);
656
+ this._removeListeners = bind(this._removeListeners, this);
657
+ this.close = bind(this.close, this);
658
+ this._runExit = bind(this._runExit, this);
659
+ this._sshConnect = bind(this._sshConnect, this);
660
+ this._nextPrimaryHost = bind(this._nextPrimaryHost, this);
661
+ this._nextHost = bind(this._nextHost, this);
662
+ this._previousHost = bind(this._previousHost, this);
663
+ this._runCommand = bind(this._runCommand, this);
664
+ this._checkCommand = bind(this._checkCommand, this);
665
+ this._nextCommand = bind(this._nextCommand, this);
666
+ this._commandComplete = bind(this._commandComplete, this);
667
+ this._processNotifications = bind(this._processNotifications, this);
668
+ this._processSSHPrompt = bind(this._processSSHPrompt, this);
669
+ this._resetFromSudoError = bind(this._resetFromSudoError, this);
670
+ this._processPasswordPrompt = bind(this._processPasswordPrompt, this);
671
+ this._sanitizeResponse = bind(this._sanitizeResponse, this);
672
+ this._onData = bind(this._onData, this);
673
+ this.onEnd = bind(this.onEnd, this);
674
+ this.onCommandTimeout = bind(this.onCommandTimeout, this);
675
+ this.onCommandComplete = bind(this.onCommandComplete, this);
676
+ this.onCommandProcessing = bind(this.onCommandProcessing, this);
677
+ this._callback = bind(this._callback, this);
678
+ SSH2Shell.__super__.constructor.call(this, hosts);
679
+ if (typeIsArray(hosts) && hosts.length > 0) {
680
+ this._hosts = hosts;
681
+ } else {
682
+ this._hosts = [hosts];
683
+ }
684
+ this.ssh2Client = require('ssh2').Client;
685
+ this.on("msg", (function(_this) {
686
+ return function(message) {
687
+ return console.log(message);
688
+ };
689
+ })(this));
690
+ this.on("newPrimmaryHost", this._nextPrimaryHost);
691
+ this.on("data", (function(_this) {
692
+ return function(data) {
693
+ return _this._onData(data);
694
+ };
695
+ })(this));
696
+ this.on("stderrData", (function(_this) {
697
+ return function(data) {
698
+ return console.error(data);
699
+ };
700
+ })(this));
701
+ this.on("error", (function(_this) {
702
+ return function(err, type, close, callback) {
703
+ if (close == null) {
704
+ close = false;
705
+ }
706
+ if (_this.sshObj.debug) {
707
+ _this.emit('msg', "Class.error: " + err + ", " + type);
708
+ }
709
+ if (err instanceof Error) {
710
+ _this.emit('msg', "Error: " + err.message + ", Level: " + err.level);
711
+ } else {
712
+ _this.emit('msg', (type + " error: ") + err);
713
+ }
714
+ if (close) {
715
+ return _this._stream.close();
716
+ }
717
+ };
718
+ })(this));
719
+ if (this._hosts[0].server.tryKeyboard) {
720
+ this.on("keyboard-interactive", (function(_this) {
721
+ return function(name, instructions, instructionsLang, prompts, finish) {
722
+ var str;
723
+ if (_this.sshObj.debug) {
724
+ _this.emit('msg', _this.sshObj.server.host + ": Class.keyboard-interactive");
725
+ }
726
+ if (_this.sshObj.verbose) {
727
+ _this.emit('msg', "name: " + name);
728
+ _this.emit('msg', "instructions: " + instructions);
729
+ str = JSON.stringify(prompts, null, 4);
730
+ return _this.emit('msg', "Prompts object: " + str);
731
+ }
732
+ };
733
+ })(this));
734
+ }
735
+ this._allSessions = "";
736
+ }
737
+
738
+ SSH2Shell.prototype._initiate = function(action) {
739
+ if (this.sshObj.debug) {
740
+ this.emit('msg', this.sshObj.server.host + ": initiate");
741
+ }
742
+ this._loadDefaults();
743
+ if (typeof action === 'function') {
744
+ return action();
745
+ }
746
+ };
747
+
748
+ SSH2Shell.prototype._loadDefaults = function() {
749
+ var cleanPass, cleanPrompt, cleanStandard, cleanText, escapeRegex, ref, ref1, ref2, ref3, ref4, ref5, ref6, safeAsciiPattern, safeColorPattern;
750
+ if (this.sshObj.msg && this.sshObj.msg.send && typeof this.sshObj.msg.send === 'function') {
751
+ this.sshObj.msg = this.sshObj.msg.send;
752
+ }
753
+ if (this.listenerCount("msg") > 0) {
754
+ this.removeAllListeners("msg");
755
+ }
756
+ if (typeof this.sshObj.msg === 'function') {
757
+ this.on("msg", this.sshObj.msg);
758
+ } else {
759
+ this.on("msg", (function(_this) {
760
+ return function(message) {
761
+ return console.log(message);
762
+ };
763
+ })(this));
764
+ }
765
+ if (this.sshObj.debug) {
766
+ this.emit('msg', this.sshObj.server.host + ": Load Defaults");
767
+ }
768
+ this.command = "";
769
+ this._buffer = "";
770
+ this.sshObj.sshToNextHost = false;
771
+ if (!this.sshObj.connectedMessage) {
772
+ this.sshObj.connectedMessage = "Connected";
773
+ }
774
+ if (!this.sshObj.readyMessage) {
775
+ this.sshObj.readyMessage = "Ready";
776
+ }
777
+ if (!this.sshObj.closedMessage) {
778
+ this.sshObj.closedMessage = "Closed";
779
+ }
780
+ if (!this.sshObj.showBanner) {
781
+ this.sshObj.showBanner = false;
782
+ }
783
+ if (!this.sshObj.verbose) {
784
+ this.sshObj.verbose = false;
785
+ }
786
+ if (!this.sshObj.debug) {
787
+ this.sshObj.debug = false;
788
+ }
789
+ if (!this.sshObj.hosts) {
790
+ this.sshObj.hosts = [];
791
+ }
792
+ if (!this.sshObj.commands) {
793
+ this.sshObj.commands = [];
794
+ }
795
+ if (!this.sshObj.standardPrompt) {
796
+ this.sshObj.standardPrompt = ">$%#";
797
+ }
798
+ if (!this.sshObj.passwordPrompt) {
799
+ this.sshObj.passwordPrompt = this.sshObj.passwordPromt;
800
+ }
801
+ if (!this.sshObj.passphrasePrompt) {
802
+ this.sshObj.passphrasePrompt = this.sshObj.passphrasePromt;
803
+ }
804
+ if (!this.sshObj.passwordPrompt) {
805
+ this.sshObj.passwordPrompt = ":";
806
+ }
807
+ if (!this.sshObj.passphrasePrompt) {
808
+ this.sshObj.passphrasePrompt = ":";
809
+ }
810
+ if (!this.sshObj.passPromptText) {
811
+ this.sshObj.passPromptText = "Password";
812
+ }
813
+ this.sshObj.enter = /^[\r\n]+$/.test(this.sshObj.enter || "") ? this.sshObj.enter : "\n";
814
+ if (!this.sshObj.textColorFilter) {
815
+ this.sshObj.textColorFilter = "(\[{1}[0-9;]+m{1})";
816
+ }
817
+ if (this.sshObj.disableColorFilter !== true) {
818
+ this.sshObj.disableColorFilter = false;
819
+ }
820
+ if (!this.sshObj.asciiFilter) {
821
+ this.sshObj.asciiFilter = "[^\r\n\x20-\x7e]";
822
+ }
823
+ if (this.sshObj.disableASCIIFilter !== true) {
824
+ this.sshObj.disableASCIIFilter = false;
825
+ }
826
+ if (!this.sshObj.exitCommands) {
827
+ this.sshObj.exitCommands = [];
828
+ }
829
+ this.sshObj.pwSent = false;
830
+ this.sshObj.sshAuth = false;
831
+ this.sshObj.server.hashKey = (ref = this.sshObj.server.hashKey) != null ? ref : "";
832
+ if (!this.sshObj.sessionText) {
833
+ this.sshObj.sessionText = "";
834
+ }
835
+ this.sshObj.streamEncoding = (ref1 = this.sshObj.streamEncoding) != null ? ref1 : "utf8";
836
+ if (!this.sshObj.window) {
837
+ this.sshObj.window = true;
838
+ }
839
+ if (!this.sshObj.pty) {
840
+ this.sshObj.pty = true;
841
+ }
842
+ this.idleTime = (ref2 = this.sshObj.idleTimeOut) != null ? ref2 : 5000;
843
+ this.dataIdleTime = (ref3 = this.sshObj.dataIdleTime) != null ? ref3 : 500;
844
+ escapeRegex = function(str) {
845
+ return String(str).replace(/[|\\{}()[\]^$+*?.]/g, '\\$&');
846
+ };
847
+ if (!this.asciiFilter) {
848
+ if (this.sshObj.asciiFilter === "[^\r\n\x20-\x7e]") {
849
+ this.asciiFilter = /[^\t\r\n\x20-\x7e]/g;
850
+ } else {
851
+ safeAsciiPattern = /^\[\^?[a-zA-Z0-9\s\\x00-\\x7f\-\[\]]+\]$/;
852
+ if (safeAsciiPattern.test(this.sshObj.asciiFilter)) {
853
+ this.asciiFilter = new RegExp(this.sshObj.asciiFilter, "g");
854
+ } else {
855
+ if (this.sshObj.debug) {
856
+ this.emit('msg', (this.sshObj.server.host + ": AsciiFilter: incorrect regular expression reverting to default: ") + this.sshObj.asciiFilter);
857
+ }
858
+ this.asciiFilter = /[^\t\r\n\x20-\x7e]/g;
859
+ }
860
+ }
861
+ }
862
+ if (!this.textColorFilter) {
863
+ if (this.sshObj.textColorFilter === "(\[{1}[0-9;]+m{1})") {
864
+ this.textColorFilter = /\x1b\[[0-9;]*m/g;
865
+ } else {
866
+ safeColorPattern = /^(\\x1b|\\033)?\\?\[[0-9;]*\*?[a-zA-Z]$/;
867
+ if (safeColorPattern.test(this.sshObj.textColorFilter)) {
868
+ this.textColorFilter = new RegExp(this.sshObj.textColorFilter, "g");
869
+ } else {
870
+ if (this.sshObj.debug) {
871
+ this.emit('msg', (this.sshObj.server.host + ": TextColorFilter: incorrect regular expression reverting to default: ") + this.sshObj.textColorFilter);
872
+ }
873
+ this.textColorFilter = /\x1b\[[0-9;]*m/g;
874
+ }
875
+ }
876
+ }
877
+ if (!this.passwordPrompt) {
878
+ cleanText = escapeRegex(this.sshObj.passPromptText || "Password");
879
+ cleanPrompt = escapeRegex(this.sshObj.passwordPrompt || ":");
880
+ this.passwordPrompt = new RegExp(cleanText + "[^\\n]*" + cleanPrompt + "\\s?$", "i");
881
+ }
882
+ if (!this.passphrasePrompt) {
883
+ cleanText = escapeRegex(this.sshObj.passPromptText || "Password");
884
+ cleanPass = escapeRegex(this.sshObj.passphrasePrompt || ":");
885
+ this.passphrasePrompt = new RegExp(cleanText + "[^\\n]*" + cleanPass + "\\s?$", "i");
886
+ }
887
+ if (!this.standardPrompt) {
888
+ cleanStandard = escapeRegex(this.sshObj.standardPrompt || ">$%#");
889
+ this.standardPrompt = new RegExp("[" + cleanStandard + "]\\s?$");
890
+ }
891
+ this.sshObj.onCommandProcessing = (ref4 = this.sshObj.onCommandProcessing) != null ? ref4 : (function(_this) {
892
+ return function(command, response, sshObj, stream) {};
893
+ })(this);
894
+ this.sshObj.onCommandComplete = (ref5 = this.sshObj.onCommandComplete) != null ? ref5 : (function(_this) {
895
+ return function(command, response, sshObj) {
896
+ if (_this.sshObj.debug) {
897
+ return _this.emit('msg', _this.sshObj.server.host + ": Class.commandComplete");
898
+ }
899
+ };
900
+ })(this);
901
+ this.sshObj.onCommandTimeout = (ref6 = this.sshObj.onCommandTimeout) != null ? ref6 : (function(_this) {
902
+ return function(command, response, stream, connection) {
903
+ response = response.replace(_this.command, "");
904
+ if (_this.sshObj.debug) {
905
+ _this.emit('msg', _this.sshObj.server.host + ": Class.commandTimeout");
906
+ }
907
+ if (_this.sshObj.verbose) {
908
+ _this.emit('msg', _this.sshObj.server.host + ": Timeout command: " + command + " response: " + response);
909
+ }
910
+ return _this.emit("error", _this.sshObj.server.host + ": Command timed out after " + (_this.idleTime / 1000) + " seconds", "Timeout", true, function(err, type) {
911
+ _this.sshObj.sessionText += _this._buffer;
912
+ return _this._buffer = "";
913
+ });
914
+ };
915
+ })(this);
916
+ if (typeof this.sshObj.onKeyboardInteractive === 'function') {
917
+ this.on("keyboard-interactive", this.sshObj.onKeyboardInteractive);
918
+ }
919
+ if (typeof this.sshObj.onError === 'function') {
920
+ this.on("error", this.sshObj.onError);
921
+ }
922
+ if (typeof this.sshObj.onData === 'function') {
923
+ this.on("data", this.sshObj.onData);
924
+ }
925
+ if (typeof this.sshObj.onStderrData === 'function') {
926
+ this.on("stderrData", this.sshObj.onStderrData);
927
+ }
928
+ this.on("commandProcessing", this.sshObj.onCommandProcessing);
929
+ this.on("commandComplete", this.sshObj.onCommandComplete);
930
+ this.on("commandTimeout", this.sshObj.onCommandTimeout);
931
+ if (typeof this.sshObj.onEnd === 'function') {
932
+ this.on("end", this.sshObj.onEnd);
933
+ }
934
+ if (this.sshObj.debug) {
935
+ this.emit('msg', this.sshObj.server.host + ": Host loaded");
936
+ }
937
+ if (this.sshObj.verbose) {
938
+ return this.emit('msg', this.sshObj);
939
+ }
940
+ };
941
+
942
+ SSH2Shell.prototype.connect = function(callback) {
943
+ if (typeof callback === 'function') {
944
+ this._callback = callback;
945
+ }
946
+ return this.emit("newPrimaryHost", this._nextPrimaryHost(this._connect));
947
+ };
948
+
949
+ SSH2Shell.prototype._connect = function() {
950
+ var e;
951
+ this.connection = new this.ssh2Client();
952
+ this.connection.on("keyboard-interactive", (function(_this) {
953
+ return function(name, instructions, instructionsLang, prompts, finish) {
954
+ if (_this.sshObj.debug) {
955
+ _this.emit('msg', _this.sshObj.server.host + ": Connection.keyboard-interactive");
956
+ }
957
+ return _this.emit("keyboard-interactive", name, instructions, instructionsLang, prompts, finish);
958
+ };
959
+ })(this));
960
+ this.connection.on("connect", (function(_this) {
961
+ return function() {
962
+ if (_this.sshObj.debug) {
963
+ _this.emit('msg', _this.sshObj.server.host + ": Connection.connect");
964
+ }
965
+ return _this.emit('msg', _this.sshObj.connectedMessage);
966
+ };
967
+ })(this));
968
+ this.connection.on("ready", (function(_this) {
969
+ return function() {
970
+ if (_this.sshObj.debug) {
971
+ _this.emit('msg', _this.sshObj.server.host + ": Connection.ready");
972
+ }
973
+ _this.emit('msg', _this.sshObj.readyMessage);
974
+ return _this.connection.shell(_this.sshObj.window, {
975
+ pty: _this.sshObj.pty
976
+ }, function(err, _stream) {
977
+ _this._stream = _stream;
978
+ if (err instanceof Error) {
979
+ _this.emit('error', err, "Shell", true);
980
+ return;
981
+ }
982
+ if (_this.sshObj.debug) {
983
+ _this.emit('msg', _this.sshObj.server.host + ": Connection.shell");
984
+ }
985
+ _this._stream.setEncoding(_this.sshObj.streamEncoding);
986
+ _this._stream.on("error", function(err) {
987
+ if (_this.sshObj.debug) {
988
+ _this.emit('msg', _this.sshObj.server.host + ": Stream.error");
989
+ }
990
+ return _this.emit('error', err, "Stream");
991
+ });
992
+ _this._stream.stderr.on('data', function(data) {
993
+ if (_this.sshObj.debug) {
994
+ _this.emit('msg', _this.sshObj.server.host + ": Stream.stderr.data");
995
+ }
996
+ return _this.emit('stderrData', data);
997
+ });
998
+ _this._stream.on("data", function(data) {
999
+ var e;
1000
+ try {
1001
+ return _this.emit('data', data);
1002
+ } catch (error) {
1003
+ e = error;
1004
+ err = new Error(e + " " + e.stack);
1005
+ err.level = "Data handling";
1006
+ return _this.emit('error', err, "Stream.read", true);
1007
+ }
1008
+ });
1009
+ _this._stream.on("finish", function() {
1010
+ if (_this.sshObj.debug) {
1011
+ _this.emit('msg', _this.sshObj.server.host + ": Stream.finish");
1012
+ }
1013
+ _this._primaryhostSessionText += _this.sshObj.sessionText + "\n";
1014
+ _this._allSessions += _this._primaryhostSessionText;
1015
+ if (_this._hosts.length === 0) {
1016
+ return _this.emit('end', _this._allSessions, _this.sshObj);
1017
+ }
1018
+ });
1019
+ return _this._stream.on("close", function(code, signal) {
1020
+ if (_this.sshObj.debug) {
1021
+ _this.emit('msg', _this.sshObj.server.host + ": Stream.close");
1022
+ }
1023
+ return _this.connection.end();
1024
+ });
1025
+ });
1026
+ };
1027
+ })(this));
1028
+ this.connection.on("error", (function(_this) {
1029
+ return function(err) {
1030
+ if (_this.sshObj.debug) {
1031
+ _this.emit('msg', _this.sshObj.server.host + ": Connection.error");
1032
+ }
1033
+ return _this.emit("error", err, "Connection");
1034
+ };
1035
+ })(this));
1036
+ this.connection.on("close", (function(_this) {
1037
+ return function(had_error) {
1038
+ if (_this.sshObj.debug) {
1039
+ _this.emit('msg', _this.sshObj.server.host + ": Connection.close");
1040
+ }
1041
+ if (_this.idleTimer) {
1042
+ clearTimeout(_this.idleTimer);
1043
+ }
1044
+ if (_this.dataReceivedTimer) {
1045
+ clearTimeout(_this.dataReceivedTimer);
1046
+ }
1047
+ if (had_error) {
1048
+ _this.emit("error", had_error, "Connection close");
1049
+ } else {
1050
+ _this.emit('msg', _this.sshObj.closedMessage);
1051
+ }
1052
+ if (_this._hosts.length === 0) {
1053
+ if (typeof _this._callback === 'function') {
1054
+ _this._callback(_this._allSessions);
1055
+ _this._removeListeners();
1056
+ return _this._allSessions;
1057
+ }
1058
+ } else {
1059
+ return _this.emit("newPrimaryHost", _this._nextPrimaryHost(_this._connect));
1060
+ }
1061
+ };
1062
+ })(this));
1063
+ if (this.sshObj.server && this.sshObj.commands) {
1064
+ try {
1065
+ if (!this.sshObj.server.username) {
1066
+ this.sshObj.server.username = this.sshObj.server.userName;
1067
+ }
1068
+ if (!this.sshObj.server.hostHash) {
1069
+ this.sshObj.server.hostHash = this.sshObj.server.hashMethod;
1070
+ }
1071
+ if (!this.sshObj.server.passphrase) {
1072
+ this.sshObj.server.passphrase = this.sshObj.server.passPhrase;
1073
+ }
1074
+ this.connection.connect(this.sshObj.server);
1075
+ } catch (error) {
1076
+ e = error;
1077
+ this.emit('error', e + " " + e.stack, "Connection.connect", true);
1078
+ }
1079
+ } else {
1080
+ this.emit('error', "Missing connection parameters", "Parameters", false, function(err, type, close) {
1081
+ this.emit('msg', this.sshObj.server);
1082
+ return this.emit('msg', this.sshObj.commands);
1083
+ });
1084
+ }
1085
+ return this._stream;
1086
+ };
1087
+
1088
+ return SSH2Shell;
1089
+
1090
+ })(Stream);
1091
+
1092
+ module.exports = SSH2Shell;
1093
+
1094
+ }).call(this);