ssh2shell 1.9.10 → 2.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +549 -773
- package/lib/ssh2shell.js +113 -90
- package/package.json +57 -57
- package/src/ssh2shell.coffee +110 -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 +9 -32
- 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/src/ssh2shell.coffee
CHANGED
|
@@ -9,7 +9,8 @@ Stream = require('stream');
|
|
|
9
9
|
class SSH2Shell extends Stream
|
|
10
10
|
sshObj: {}
|
|
11
11
|
command: ""
|
|
12
|
-
|
|
12
|
+
_hosts: []
|
|
13
|
+
_sshToNextHost: false
|
|
13
14
|
_primaryhostSessionText: ""
|
|
14
15
|
_allSessions: ""
|
|
15
16
|
_connections: []
|
|
@@ -36,7 +37,7 @@ class SSH2Shell extends Stream
|
|
|
36
37
|
@.emit 'commandProcessing' , @command, @_buffer, @sshObj, @_stream
|
|
37
38
|
clearTimeout @idleTimer if @idleTimer
|
|
38
39
|
@idleTimer = setTimeout( =>
|
|
39
|
-
@.emit 'commandTimeout', @.command, @._buffer, @._stream, @.
|
|
40
|
+
@.emit 'commandTimeout', @.command, @._buffer, @._stream, @.connection
|
|
40
41
|
, @idleTime)
|
|
41
42
|
else if @command.length < 1 and not @standardPrompt.test(@_buffer)
|
|
42
43
|
@.emit 'commandProcessing' , @command, @_buffer, @sshObj, @_stream
|
|
@@ -50,21 +51,19 @@ class SSH2Shell extends Stream
|
|
|
50
51
|
|
|
51
52
|
#remove test coloring from responses like [32m[31m
|
|
52
53
|
unless @.sshObj.disableColorFilter
|
|
53
|
-
@emit 'msg', "#{@sshObj.server.host}: text formatting filter: "+@sshObj.textColorFilter+", filtered: "+@textColorFilter.test(@_buffer) if @sshObj.verbose and @sshObj.debug
|
|
54
54
|
@_buffer = @_buffer.replace(@textColorFilter, "")
|
|
55
55
|
|
|
56
56
|
#remove non-standard ascii from terminal responses
|
|
57
57
|
unless @.sshObj.disableASCIIFilter
|
|
58
|
-
@emit 'msg', "#{@sshObj.server.host}: Non-standard ASCII filtered: "+@asciiFilter.test(@_buffer) if @sshObj.verbose and @sshObj.debug
|
|
59
58
|
@_buffer = @_buffer.replace(@asciiFilter, "")
|
|
60
59
|
|
|
61
60
|
switch (true)
|
|
62
61
|
#check if sudo password is needed
|
|
63
62
|
when @command.length > 0 and @command.indexOf("sudo ") isnt -1
|
|
64
|
-
@emit 'msg', "#{@sshObj.server.host}: Sudo command data" if @sshObj.debug
|
|
63
|
+
@emit 'msg', "#{@sshObj.server.host}: Sudo command data" if @sshObj.debug
|
|
65
64
|
@_processPasswordPrompt()
|
|
66
65
|
#check if ssh authentication needs to be handled
|
|
67
|
-
when @command.length > 0 and @command.indexOf("ssh ")
|
|
66
|
+
when @sshObj.sshToNextHost and @command.length > 0 and @command.indexOf("ssh ") is 0
|
|
68
67
|
@emit 'msg', "#{@sshObj.server.host}: SSH command data" if @sshObj.debug
|
|
69
68
|
@_processSSHPrompt()
|
|
70
69
|
#check for standard prompt from a command
|
|
@@ -80,7 +79,7 @@ class SSH2Shell extends Stream
|
|
|
80
79
|
else
|
|
81
80
|
@emit 'msg', "Data processing: data received timeout" if @sshObj.debug
|
|
82
81
|
@idleTimer = setTimeout( =>
|
|
83
|
-
@.emit 'commandTimeout', @.command, @._buffer, @._stream, @.
|
|
82
|
+
@.emit 'commandTimeout', @.command, @._buffer, @._stream, @.connection
|
|
84
83
|
, @idleTime)
|
|
85
84
|
, @dataIdleTime)
|
|
86
85
|
|
|
@@ -101,7 +100,7 @@ class SSH2Shell extends Stream
|
|
|
101
100
|
#no password
|
|
102
101
|
switch (true)
|
|
103
102
|
when passwordPrompt and not @sshObj.server.password
|
|
104
|
-
@.emit 'msg', "#{@sshObj.server.host}: Sudo password prompt no password" if @sshObj.debug
|
|
103
|
+
@.emit 'msg', "#{@sshObj.server.host}: Sudo password prompt no password set" if @sshObj.debug
|
|
105
104
|
@_resetFromSudoError()
|
|
106
105
|
when passwordPrompt and not @sshObj.pwSent
|
|
107
106
|
@.emit 'msg', "#{@sshObj.server.host}: Sudo password prompt: Buffer: #{response}" if @sshObj.verbose
|
|
@@ -118,7 +117,7 @@ class SSH2Shell extends Stream
|
|
|
118
117
|
#add buffer to sessionText so the sudo response can be seen
|
|
119
118
|
@_resetFromSudoError()
|
|
120
119
|
when standardPrompt
|
|
121
|
-
@.emit 'msg', "#{@sshObj.server.host}: Sudo
|
|
120
|
+
@.emit 'msg', "#{@sshObj.server.host}: Sudo password accepted" if @sshObj.debug
|
|
122
121
|
@sshObj.pwSent = false
|
|
123
122
|
@.emit 'msg', "#{@sshObj.server.host}: Sudo Standard Response: #{response}" if @sshObj.verbose
|
|
124
123
|
@_commandComplete()
|
|
@@ -132,6 +131,7 @@ class SSH2Shell extends Stream
|
|
|
132
131
|
@sshObj.sessionText += "#{@_buffer}"
|
|
133
132
|
@_buffer = ""
|
|
134
133
|
@command = ""
|
|
134
|
+
#cancal command on host
|
|
135
135
|
@_stream.write '\x03'
|
|
136
136
|
|
|
137
137
|
_processSSHPrompt: =>
|
|
@@ -169,18 +169,23 @@ class SSH2Shell extends Stream
|
|
|
169
169
|
@_runExit()
|
|
170
170
|
else
|
|
171
171
|
@.emit 'msg', "#{@sshObj.server.host}: SSH no prompt was not detected"
|
|
172
|
-
@.emit 'msg', "#{@sshObj.server.host}: SSH
|
|
173
|
-
@.emit 'msg', "#{@sshObj.server.host}: SSH
|
|
174
|
-
@.emit 'msg', "#{@sshObj.server.host}: SSH
|
|
172
|
+
@.emit 'msg', "#{@sshObj.server.host}: SSH response: #{response}" if @sshObj.verbose
|
|
173
|
+
@.emit 'msg', "#{@sshObj.server.host}: SSH password prompt: #{@sshObj.passwordPrompt}" if @sshObj.verbose and not @sshObj.server.hasOwnProperty("password")
|
|
174
|
+
@.emit 'msg', "#{@sshObj.server.host}: SSH passphrase prompt: #{@sshObj.passphrasePrompt}" if @sshObj.verbose and @sshObj.server.hasOwnProperty("passPhrase")
|
|
175
|
+
@.emit 'msg', "#{@sshObj.server.host}: SSH standard prompt: #{@sshObj.standardPrompt}" if @sshObj.verbose
|
|
175
176
|
@_runExit()
|
|
176
177
|
else
|
|
177
178
|
@.emit 'msg', "#{@sshObj.server.host}: SSH post authentication prompt detection" if @sshObj.debug
|
|
178
|
-
|
|
179
|
+
#@sshObj.sshToNextHost = false
|
|
180
|
+
|
|
179
181
|
if standardPrompt
|
|
180
|
-
@.emit 'msg', "#{@sshObj.server.host}: SSH complete: normal prompt" if @sshObj.debug
|
|
182
|
+
@.emit 'msg', "#{@sshObj.server.host}: SSH complete: normal prompt" if @sshObj.debug
|
|
183
|
+
@sshObj.sessionText += "\n #{response}" if @sshObj.showBanner
|
|
181
184
|
@sshObj.exitCommands.push "exit"
|
|
182
185
|
@.emit 'msg', "#{@sshObj.connectedMessage}"
|
|
183
186
|
@.emit 'msg', "#{@sshObj.readyMessage}"
|
|
187
|
+
@.emit 'msg', "#{@sshObj.server.host}: SSH complete: next command" if @sshObj.debug
|
|
188
|
+
@sshObj.sshToNextHost = false
|
|
184
189
|
@_nextCommand()
|
|
185
190
|
#Password or passphase detected a second time after authentication indicating failure.
|
|
186
191
|
else if (passwordPrompt or passphrasePrompt)
|
|
@@ -196,7 +201,7 @@ class SSH2Shell extends Stream
|
|
|
196
201
|
|
|
197
202
|
#no connection so drop back to first host settings if there was one
|
|
198
203
|
#@sshObj.sessionText += "#{@_buffer}"
|
|
199
|
-
@.emit 'msg', "#{@sshObj.server.host}: SSH
|
|
204
|
+
@.emit 'msg', "#{@sshObj.server.host}: SSH response: #{response}" if @sshObj.verbose
|
|
200
205
|
if @_connections.length > 0
|
|
201
206
|
return @_previousHost()
|
|
202
207
|
|
|
@@ -224,18 +229,13 @@ class SSH2Shell extends Stream
|
|
|
224
229
|
@_checkCommand()
|
|
225
230
|
|
|
226
231
|
_commandComplete: =>
|
|
227
|
-
response = @_buffer.trim()
|
|
232
|
+
response = @_buffer.trim()
|
|
228
233
|
#check sudo su has been authenticated and add an extra exit command
|
|
229
|
-
|
|
230
|
-
if @command isnt "" and @command isnt "exit" and @command.indexOf("ssh ") is -1
|
|
234
|
+
if @command isnt "" and @command isnt "exit" and @sshObj.sshToNextHost isnt true
|
|
231
235
|
@.emit 'msg', "#{@sshObj.server.host}: Command complete:\nCommand:\n #{@command}\nResponse: #{response}" if @sshObj.verbose
|
|
232
236
|
@sshObj.sessionText += response
|
|
233
237
|
@.emit 'msg', "#{@sshObj.server.host}: Raising commandComplete event" if @sshObj.debug
|
|
234
238
|
@.emit 'commandComplete', @command, @_buffer, @sshObj
|
|
235
|
-
|
|
236
|
-
#if @command.indexOf("exit") != -1
|
|
237
|
-
# @_runExit()
|
|
238
|
-
#else
|
|
239
239
|
@_nextCommand()
|
|
240
240
|
|
|
241
241
|
_nextCommand: =>
|
|
@@ -269,10 +269,12 @@ class SSH2Shell extends Stream
|
|
|
269
269
|
@.emit 'msg', "#{@sshObj.server.host}: Load previous host config" if @sshObj.debug
|
|
270
270
|
@.emit 'end', "#{@sshObj.server.host}: \n#{@sshObj.sessionText}", @sshObj
|
|
271
271
|
@.emit 'msg', "#{@sshObj.server.host}: Previous hosts: #{@_connections.length}" if @sshObj.debug
|
|
272
|
+
|
|
272
273
|
if @_connections.length > 0
|
|
273
274
|
@sshObj = @_connections.pop()
|
|
274
275
|
@.emit 'msg', "#{@sshObj.server.host}: Reload previous host" if @sshObj.debug
|
|
275
|
-
|
|
276
|
+
#@_loadDefaults(@_runExit)
|
|
277
|
+
@_runExit()
|
|
276
278
|
else
|
|
277
279
|
@_runExit()
|
|
278
280
|
|
|
@@ -281,31 +283,36 @@ class SSH2Shell extends Stream
|
|
|
281
283
|
nextHost = @sshObj.hosts.shift()
|
|
282
284
|
@.emit 'msg', "#{@sshObj.server.host}: SSH to #{nextHost.server.host}" if @sshObj.debug
|
|
283
285
|
@.emit 'msg', "#{@sshObj.server.host}: Clearing previous event handlers" if @sshObj.debug
|
|
284
|
-
|
|
286
|
+
@.emit 'msg', "#{@sshObj.server.host}: Remove previous event handlers" if @sshObj.debug
|
|
287
|
+
@_removeEvents()
|
|
288
|
+
|
|
285
289
|
@_connections.push(@sshObj)
|
|
286
290
|
|
|
287
|
-
@sshObj = nextHost
|
|
291
|
+
@sshObj = nextHost
|
|
292
|
+
|
|
288
293
|
@_initiate(@_sshConnect)
|
|
289
294
|
|
|
290
295
|
|
|
291
|
-
_nextPrimaryHost: (
|
|
296
|
+
_nextPrimaryHost: ( connect )=>
|
|
292
297
|
|
|
293
|
-
if
|
|
298
|
+
if @_hosts.length > 0
|
|
294
299
|
if @sshObj.server
|
|
295
300
|
@.emit 'msg', "#{@sshObj.server.host}: Current primary host" if @sshObj.debug
|
|
296
|
-
|
|
297
|
-
|
|
301
|
+
@.emit 'msg', "#{@sshObj.server.host}: Remove previous event handlers" if @sshObj.debug
|
|
302
|
+
@_removeEvents()
|
|
303
|
+
@sshObj = @_hosts.shift()
|
|
298
304
|
@_primaryhostSessionText = "#{@sshObj.server.host}: "
|
|
299
305
|
|
|
300
306
|
@.emit 'msg', "#{@sshObj.server.host}: Next primary host" if @sshObj.debug
|
|
301
|
-
|
|
302
|
-
@_initiate(
|
|
307
|
+
|
|
308
|
+
@_initiate(connect)
|
|
303
309
|
else
|
|
304
310
|
@.emit 'msg', "#{@sshObj.server.host}: No more primary hosts" if @sshObj.debug
|
|
305
311
|
@_runExit
|
|
306
312
|
|
|
307
313
|
|
|
308
314
|
_sshConnect: =>
|
|
315
|
+
|
|
309
316
|
#add ssh commandline options from host.server.ssh
|
|
310
317
|
sshFlags = "-x"
|
|
311
318
|
sshOptions = ""
|
|
@@ -327,6 +334,7 @@ class SSH2Shell extends Stream
|
|
|
327
334
|
sshOptions += ' -o "StrictHostKeyChecking=no"'
|
|
328
335
|
sshOptions += " -p #{@sshObj.server.port}"
|
|
329
336
|
@sshObj.sshAuth = false
|
|
337
|
+
@sshObj.sshToNextHost = true
|
|
330
338
|
@command = "ssh #{sshFlags} #{sshOptions} #{@sshObj.server.userName}@#{@sshObj.server.host}"
|
|
331
339
|
@.emit 'msg', "#{@sshObj.server.host}: SSH command: connect" if @sshObj.debug
|
|
332
340
|
@_runCommand(@command)
|
|
@@ -337,7 +345,8 @@ class SSH2Shell extends Stream
|
|
|
337
345
|
if @sshObj.exitCommands and @sshObj.exitCommands.length > 0
|
|
338
346
|
@.emit 'msg', "#{@sshObj.server.host}: Queued exit commands: #{@sshObj.exitCommands.length}" if @sshObj.debug
|
|
339
347
|
@command = @sshObj.exitCommands.pop()
|
|
340
|
-
if @_connections and @_connections.length > 0
|
|
348
|
+
if @_connections and @_connections.length > 0
|
|
349
|
+
@.emit 'msg', "#{@sshObj.server.host}: Primary host: #{@_connections[0].server.host}" if @sshObj.verbose
|
|
341
350
|
@_connections[0].sessionText += "\n#{@sshObj.server.host}: #{@sshObj.sessionText}"
|
|
342
351
|
@_runCommand(@command)
|
|
343
352
|
#more hosts to connect to so process the next one
|
|
@@ -349,9 +358,7 @@ class SSH2Shell extends Stream
|
|
|
349
358
|
@.emit 'msg', "#{@sshObj.server.host}: load previous host" if @sshObj.debug
|
|
350
359
|
@.emit 'msg', "#{@sshObj.server.host}: #{@sshObj.closedMessage}"
|
|
351
360
|
@_previousHost()
|
|
352
|
-
|
|
353
|
-
#@connection.end()
|
|
354
|
-
else if @command == "exit"
|
|
361
|
+
else if @command is "exit"
|
|
355
362
|
@.emit 'msg', "#{@sshObj.server.host}: Manual exit command" if @sshObj.debug
|
|
356
363
|
@_runCommand("exit")
|
|
357
364
|
#Nothing more to do so end the stream with last exit
|
|
@@ -363,83 +370,92 @@ class SSH2Shell extends Stream
|
|
|
363
370
|
@_stream.close() #"exit#{@sshObj.enter}"
|
|
364
371
|
|
|
365
372
|
_removeEvents: =>
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
373
|
+
###
|
|
374
|
+
if @sshObj.debug
|
|
375
|
+
@.emit 'msg', "#{@sshObj.server.host}: Event handler count:"
|
|
376
|
+
@.emit 'msg', "keyboard-interactive: " + (@.listenerCount 'keyboard-interactive')
|
|
377
|
+
@.emit 'msg', "error: " + (@.listenerCount "error")
|
|
378
|
+
@.emit 'msg', "data: " + (@.listenerCount "data")
|
|
379
|
+
@.emit 'msg', "stderrData: " + (@.listenerCount "stderrData")
|
|
380
|
+
@.emit 'msg', "end: " + (@.listenerCount 'end')
|
|
381
|
+
@.emit 'msg', "commandProcessing: " + (@.listenerCount 'commandProcessing')
|
|
382
|
+
@.emit 'msg', "commandComplete: " + (@.listenerCount 'commandComplete')
|
|
383
|
+
@.emit 'msg', "commandTimeout: " + (@.listenerCount 'commandTimeout')
|
|
384
|
+
@.emit 'msg', "msg: " + (@.listenerCount 'msg')
|
|
385
|
+
###
|
|
386
|
+
@.removeListener "data", @sshObj.onData if typeof @sshObj.onData == 'function'
|
|
369
387
|
@.removeAllListeners "error"
|
|
370
|
-
@.removeListener "data", @sshObj.onData if typeof @sshObj.onData == 'function'
|
|
371
388
|
@.removeListener "stderrData", @sshObj.onStderrData if typeof @sshObj.onStderrData == 'function'
|
|
372
389
|
@.removeAllListeners 'end'
|
|
390
|
+
@.removeAllListeners 'keyboard-interactive'
|
|
373
391
|
@.removeAllListeners 'commandProcessing'
|
|
374
392
|
@.removeAllListeners 'commandComplete'
|
|
375
393
|
@.removeAllListeners 'commandTimeout'
|
|
376
394
|
@.removeAllListeners 'msg'
|
|
377
|
-
|
|
395
|
+
|
|
378
396
|
clearTimeout @idleTimer if @idleTimer
|
|
379
397
|
clearTimeout @dataReceivedTimer if @dataReceivedTimer
|
|
380
398
|
|
|
381
|
-
|
|
382
399
|
constructor: (hosts) ->
|
|
383
|
-
|
|
384
|
-
|
|
400
|
+
super hosts
|
|
401
|
+
if typeIsArray(hosts) and hosts.length > 0
|
|
402
|
+
@_hosts = hosts
|
|
385
403
|
else
|
|
386
|
-
@
|
|
387
|
-
@ssh2Client = require('ssh2').Client
|
|
404
|
+
@_hosts = [hosts]
|
|
405
|
+
@ssh2Client = require('ssh2').Client
|
|
406
|
+
|
|
388
407
|
@.on "newPrimmaryHost", @_nextPrimaryHost
|
|
389
|
-
|
|
390
|
-
|
|
408
|
+
|
|
409
|
+
@.on "data", (data) =>
|
|
391
410
|
@_onData( data )
|
|
411
|
+
|
|
392
412
|
@.on "stderrData", (data) =>
|
|
393
|
-
console.error data
|
|
394
|
-
|
|
413
|
+
console.error data
|
|
414
|
+
|
|
415
|
+
@.on "error", (err, type, close = false, callback) =>
|
|
416
|
+
@.emit 'msg', "Class.error: #{err}, #{type}" if @sshObj.debug
|
|
417
|
+
if ( err instanceof Error )
|
|
418
|
+
@.emit 'msg', "Error: " + err.message + ", Level: " + err.level
|
|
419
|
+
else
|
|
420
|
+
@.emit 'msg', "#{type} error: " + err
|
|
421
|
+
|
|
422
|
+
@_stream.close() if close
|
|
423
|
+
|
|
424
|
+
if @_hosts[0].server.tryKeyboard
|
|
425
|
+
@.on "keyboard-interactive", ( name, instructions, instructionsLang, prompts, finish ) =>
|
|
426
|
+
@.emit 'msg', "#{@sshObj.server.host}: Class.keyboard-interactive" if @sshObj.debug
|
|
427
|
+
if @sshObj.verbose
|
|
428
|
+
@.emit 'msg', "name: " + name
|
|
429
|
+
@.emit 'msg', "instructions: " + instructions
|
|
430
|
+
str = JSON.stringify(prompts, null, 4)
|
|
431
|
+
@.emit 'msg', "Prompts object: " + str
|
|
432
|
+
|
|
395
433
|
@_allSessions = ""
|
|
396
434
|
|
|
397
435
|
|
|
398
|
-
_initiate: (
|
|
399
|
-
@
|
|
436
|
+
_initiate: (action)=>
|
|
437
|
+
@.emit 'msg', "#{@sshObj.server.host}: initiate" if @sshObj.debug
|
|
438
|
+
|
|
439
|
+
@_loadDefaults()
|
|
440
|
+
#event handlers
|
|
441
|
+
|
|
442
|
+
if typeof action == 'function'
|
|
443
|
+
action()
|
|
444
|
+
|
|
445
|
+
_loadDefaults: () =>
|
|
400
446
|
|
|
401
447
|
if @sshObj.msg and @sshObj.msg.send and typeof @sshObj.msg.send == 'function'
|
|
402
448
|
@.on "msg", @sshObj.msg.send
|
|
403
|
-
else if typeof @sshObj.msg == 'function'
|
|
449
|
+
else if @sshObj.msg and typeof @sshObj.msg == 'function'
|
|
404
450
|
@.on "msg", @sshObj.msg
|
|
405
451
|
else
|
|
406
452
|
@.on "msg", ( message ) =>
|
|
407
|
-
console.log message
|
|
453
|
+
console.log message
|
|
408
454
|
|
|
409
|
-
@_loadDefaults()
|
|
410
|
-
|
|
411
|
-
@.emit 'msg', "#{@sshObj.server.host}: initiate" if @sshObj.debug
|
|
412
|
-
|
|
413
|
-
#event handlers
|
|
414
|
-
@.on "keyboard-interactive", ( name, instructions, instructionsLang, prompts, finish ) =>
|
|
415
|
-
@.emit 'msg', "#{@sshObj.server.host}: Class.keyboard-interactive" if @sshObj.debug
|
|
416
|
-
if @sshObj.verbose
|
|
417
|
-
@.emit 'msg', "name: " + name
|
|
418
|
-
@.emit 'msg', "instructions: " + instructions
|
|
419
|
-
str = JSON.stringify(prompts, null, 4)
|
|
420
|
-
@.emit 'msg', "Prompts object: " + str
|
|
421
|
-
|
|
422
|
-
@.on "error", (err, type, close = false, callback) =>
|
|
423
|
-
@.emit 'msg', "#{@sshObj.server.host}: Class.error" if @sshObj.debug
|
|
424
|
-
if ( err instanceof Error )
|
|
425
|
-
@.emit 'msg', "Error: " + err.message + ", Level: " + err.level
|
|
426
|
-
else
|
|
427
|
-
@.emit 'msg', "#{type} error: " + err
|
|
428
|
-
callback(err, type) if typeof callback == 'function'
|
|
429
|
-
@connection.end() if close
|
|
430
|
-
|
|
431
|
-
@.on "end", ( sessionText, sshObj ) =>
|
|
432
|
-
@.emit 'msg', "#{@sshObj.server.host}: Class.end" if @sshObj.debug
|
|
433
|
-
|
|
434
|
-
if typeof callback == 'function'
|
|
435
|
-
callback()
|
|
436
|
-
|
|
437
|
-
_loadDefaults: (callback) =>
|
|
438
|
-
|
|
439
|
-
|
|
440
455
|
@.emit 'msg', "#{@sshObj.server.host}: Load Defaults" if @sshObj.debug
|
|
441
456
|
@command = ""
|
|
442
457
|
@_buffer = ""
|
|
458
|
+
@sshObj.sshToNextHost = false
|
|
443
459
|
@sshObj.connectedMessage = "Connected" unless @sshObj.connectedMessage
|
|
444
460
|
@sshObj.readyMessage = "Ready" unless @sshObj.readyMessage
|
|
445
461
|
@sshObj.closedMessage = "Closed" unless @sshObj.closedMessage
|
|
@@ -474,7 +490,7 @@ class SSH2Shell extends Stream
|
|
|
474
490
|
@passwordPrompt = new RegExp(@sshObj.passPromptText+".*" + @sshObj.passwordPrompt + "\\s?$","i") unless @passwordPrompt
|
|
475
491
|
@passphrasePrompt = new RegExp(@sshObj.passPromptText+".*" + @sshObj.passphrasePrompt + "\\s?$","i") unless @passphrasePrompt
|
|
476
492
|
@standardPrompt = new RegExp("[" + @sshObj.standardPrompt + "]\\s?$") unless @standardPrompt
|
|
477
|
-
|
|
493
|
+
|
|
478
494
|
|
|
479
495
|
@sshObj.onCommandProcessing = @sshObj.onCommandProcessing ? ( command, response, sshObj, stream ) =>
|
|
480
496
|
|
|
@@ -485,10 +501,9 @@ class SSH2Shell extends Stream
|
|
|
485
501
|
response = response.replace(@command, "")
|
|
486
502
|
@.emit 'msg', "#{@sshObj.server.host}: Class.commandTimeout" if @sshObj.debug
|
|
487
503
|
@.emit 'msg', "#{@sshObj.server.host}: Timeout command: #{command} response: #{response}" if @sshObj.verbose
|
|
488
|
-
|
|
504
|
+
|
|
489
505
|
@.emit "error", "#{@sshObj.server.host}: Command timed out after #{@.idleTime/1000} seconds", "Timeout", true, (err, type)=>
|
|
490
|
-
|
|
491
|
-
|
|
506
|
+
@sshObj.sessionText += @_buffer
|
|
492
507
|
|
|
493
508
|
@.on "keyboard-interactive", @sshObj.onKeyboardInteractive if typeof @sshObj.onKeyboardInteractive == 'function'
|
|
494
509
|
@.on "error", @sshObj.onError if typeof @sshObj.onError == 'function'
|
|
@@ -502,8 +517,7 @@ class SSH2Shell extends Stream
|
|
|
502
517
|
@.emit 'msg', "#{@sshObj.server.host}: Host loaded" if @sshObj.verbose
|
|
503
518
|
@.emit 'msg', @sshObj if @sshObj.verbose
|
|
504
519
|
|
|
505
|
-
|
|
506
|
-
callback()
|
|
520
|
+
|
|
507
521
|
|
|
508
522
|
connect: (callback)=>
|
|
509
523
|
@_callback = callback if typeof callback == 'function'
|
|
@@ -555,10 +569,8 @@ class SSH2Shell extends Stream
|
|
|
555
569
|
|
|
556
570
|
@_primaryhostSessionText += @sshObj.sessionText+"\n"
|
|
557
571
|
@_allSessions += @_primaryhostSessionText
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
@.emit 'end', @_allSessions, @sshObj
|
|
561
|
-
|
|
572
|
+
if @_hosts.length == 0
|
|
573
|
+
@.emit 'end', @_allSessions, @sshObj
|
|
562
574
|
@_removeEvents()
|
|
563
575
|
|
|
564
576
|
|
|
@@ -573,11 +585,14 @@ class SSH2Shell extends Stream
|
|
|
573
585
|
|
|
574
586
|
@connection.on "close", (had_error) =>
|
|
575
587
|
@.emit 'msg', "#{@sshObj.server.host}: Connection.close" if @sshObj.debug
|
|
588
|
+
clearTimeout @idleTimer if @idleTimer
|
|
589
|
+
clearTimeout @dataReceivedTimer if @dataReceivedTimer
|
|
576
590
|
if had_error
|
|
577
591
|
@.emit "error", had_error, "Connection close"
|
|
578
592
|
else
|
|
579
593
|
@.emit 'msg', @sshObj.closedMessage
|
|
580
|
-
|
|
594
|
+
|
|
595
|
+
if @_hosts.length == 0
|
|
581
596
|
if typeof @_callback == 'function'
|
|
582
597
|
@_callback @_allSessions
|
|
583
598
|
else
|
|
@@ -19,15 +19,13 @@ var conParamsHost1 = {
|
|
|
19
19
|
userName: process.env.SERVER3_USER_NAME,
|
|
20
20
|
password: process.env.SERVER3_PASSWORD
|
|
21
21
|
},
|
|
22
|
-
debug =
|
|
22
|
+
debug = true,
|
|
23
23
|
verbose = false
|
|
24
24
|
|
|
25
25
|
//Host objects:
|
|
26
26
|
var host1 = {
|
|
27
27
|
server: conParamsHost1,
|
|
28
|
-
commands: [
|
|
29
|
-
"echo Host_1"
|
|
30
|
-
],
|
|
28
|
+
commands: ["echo Host_1"],
|
|
31
29
|
connectedMessage: "Connected to host1",
|
|
32
30
|
debug: debug,
|
|
33
31
|
verbose: verbose
|
|
@@ -35,18 +33,14 @@ var host1 = {
|
|
|
35
33
|
|
|
36
34
|
host2 = {
|
|
37
35
|
server: conParamsHost2,
|
|
38
|
-
commands: [
|
|
39
|
-
"echo Host_2"
|
|
40
|
-
],
|
|
36
|
+
commands: ["echo Host_2"],
|
|
41
37
|
debug: debug,
|
|
42
38
|
verbose: verbose
|
|
43
39
|
},
|
|
44
40
|
|
|
45
41
|
host3 = {
|
|
46
42
|
server: conParamsHost3,
|
|
47
|
-
commands: [
|
|
48
|
-
"echo Host_3"
|
|
49
|
-
],
|
|
43
|
+
commands: ["echo Host_3"],
|
|
50
44
|
debug: debug,
|
|
51
45
|
verbose: verbose
|
|
52
46
|
}
|
package/test/devtest.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
var dotenv = require('dotenv').config()
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var host = {
|
|
4
4
|
server: {
|
|
5
5
|
host: process.env.HOST,
|
|
6
6
|
port: process.env.PORT,
|
|
@@ -42,8 +42,10 @@ var sshObj = {
|
|
|
42
42
|
var SSH2Shell = require ('../lib/ssh2shell');
|
|
43
43
|
|
|
44
44
|
//run the commands in the shell session
|
|
45
|
-
var SSH = new SSH2Shell(
|
|
45
|
+
var SSH = new SSH2Shell(host);
|
|
46
|
+
|
|
46
47
|
SSH.on('end', function( sessionText, sshObj ){
|
|
47
|
-
this.emit('msg', sessionText);
|
|
48
|
+
this.emit('msg', "Session Text " + sessionText);
|
|
48
49
|
})
|
|
50
|
+
|
|
49
51
|
SSH.connect();
|
package/test/issue69.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
var dotenv = require('dotenv').config(),
|
|
2
|
-
debug =
|
|
3
|
-
verbose =
|
|
2
|
+
debug = true,
|
|
3
|
+
verbose = true
|
|
4
4
|
|
|
5
5
|
var host1 = {
|
|
6
|
-
server: {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
6
|
+
server: {
|
|
7
|
+
host: process.env.HOST,
|
|
8
|
+
port: process.env.PORT,
|
|
9
|
+
userName: process.env.USER_NAME,
|
|
10
|
+
password: process.env.PASSWORD
|
|
11
|
+
},
|
|
12
12
|
connectedMessage:'connected to host1',
|
|
13
13
|
debug: debug,
|
|
14
14
|
verbose: verbose
|
|
@@ -16,26 +16,26 @@ server: {
|
|
|
16
16
|
};
|
|
17
17
|
|
|
18
18
|
var host2 = {
|
|
19
|
-
server: {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
19
|
+
server: {
|
|
20
|
+
host: process.env.SERVER2_HOST,
|
|
21
|
+
port: process.env.PORT,
|
|
22
|
+
userName: process.env.SERVER2_USER_NAME,
|
|
23
|
+
password: process.env.SERVER2_PASSWORD
|
|
24
|
+
|
|
25
|
+
},
|
|
26
26
|
connectedMessage: 'connected to host2',
|
|
27
27
|
debug: debug,
|
|
28
28
|
verbose: verbose
|
|
29
29
|
};
|
|
30
30
|
|
|
31
31
|
var host3 = {
|
|
32
|
-
server: {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
32
|
+
server: {
|
|
33
|
+
host: process.env.SERVER3_HOST,
|
|
34
|
+
port: process.env.PORT,
|
|
35
|
+
userName: process.env.SERVER3_USER_NAME,
|
|
36
|
+
password: process.env.SERVER3_PASSWORD
|
|
37
|
+
|
|
38
|
+
},
|
|
39
39
|
commands: ['echo server3'],
|
|
40
40
|
connectedMessage:'connected to host3',
|
|
41
41
|
debug: debug,
|
|
@@ -47,11 +47,11 @@ host1.hosts = [host2];
|
|
|
47
47
|
|
|
48
48
|
var SSH2Shell = require ('../lib/ssh2shell'),
|
|
49
49
|
|
|
50
|
-
|
|
50
|
+
SSH = new SSH2Shell(host1);
|
|
51
51
|
|
|
52
52
|
var callback = function( sessionText ){
|
|
53
53
|
console.log ( "-----Callback session text:\n" + sessionText);
|
|
54
54
|
console.log ( "-----Callback end" );
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
-
|
|
57
|
+
SSH.connect(callback);
|
|
@@ -9,35 +9,18 @@ var host = {
|
|
|
9
9
|
tryKeyboard: true
|
|
10
10
|
},
|
|
11
11
|
commands: [
|
|
12
|
-
"`Test session text message: passed`",
|
|
13
|
-
"msg:console test notification: passed",
|
|
14
12
|
"ls -la"
|
|
15
13
|
],
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
console.log(message);
|
|
19
|
-
}
|
|
20
|
-
},
|
|
21
|
-
verbose: true,
|
|
22
|
-
debug: true,
|
|
14
|
+
verbose: false,
|
|
15
|
+
debug: false,
|
|
23
16
|
onEnd: function( sessionText, sshObj ){
|
|
24
17
|
this.emit("msg", sessionText);
|
|
25
18
|
}
|
|
26
|
-
|
|
27
19
|
};
|
|
28
20
|
//until npm published use the cloned dir path.
|
|
29
21
|
var SSH2Shell = require ('../lib/ssh2shell');
|
|
30
22
|
|
|
31
23
|
//run the commands in the shell session
|
|
32
24
|
var SSH = new SSH2Shell(host);
|
|
33
|
-
|
|
34
|
-
//Add the keyboard-interactive handler
|
|
35
|
-
SSH.on ('keyboard-interactive', function(name, instructions, instructionsLang, prompts, finish){
|
|
36
|
-
if (this.sshObj.debug) {
|
|
37
|
-
this.emit('msg', this.sshObj.server.host + ": instance.keyboard-interactive");
|
|
38
|
-
}
|
|
39
|
-
//if only the password is required then it will be the only thing returned in the array
|
|
40
|
-
finish([this.sshObj.server.password] );
|
|
41
|
-
});
|
|
42
|
-
|
|
25
|
+
|
|
43
26
|
SSH.connect();
|