ssh2shell 1.9.9 → 2.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +568 -749
- package/lib/ssh2shell.js +113 -88
- package/package.json +57 -57
- package/src/ssh2shell.coffee +112 -95
- package/test/Multiple primary hosts.js +4 -10
- package/test/devtest.js +5 -3
- package/test/issue69.js +24 -24
- package/test/keyboard-interactivetest.js +3 -20
- package/test/lots of commands.js +87 -0
- package/test/notificationstest.js +13 -10
- package/test/sshUserCommandsPosition.js +26 -0
- package/test/sudo no pass test.js +4 -4
- package/test/timeouttest.js +19 -63
- package/test/tunneltest.js +2 -2
- package/test/tunneltestSshUserCommands.js +71 -0
package/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,81 +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
|
-
|
|
395
|
-
@_allSessions = ""
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
_initiate: (callback)=>
|
|
399
|
-
@_removeEvents()
|
|
400
|
-
|
|
401
|
-
if typeof @sshObj.msg == 'function'
|
|
402
|
-
@.on "msg", @sshObj.msg.send
|
|
403
|
-
else
|
|
404
|
-
@.on "msg", ( message ) =>
|
|
405
|
-
console.log message
|
|
406
|
-
|
|
407
|
-
@_loadDefaults()
|
|
408
|
-
|
|
409
|
-
@.emit 'msg', "#{@sshObj.server.host}: initiate" if @sshObj.debug
|
|
410
|
-
|
|
411
|
-
#event handlers
|
|
412
|
-
@.on "keyboard-interactive", ( name, instructions, instructionsLang, prompts, finish ) =>
|
|
413
|
-
@.emit 'msg', "#{@sshObj.server.host}: Class.keyboard-interactive" if @sshObj.debug
|
|
414
|
-
if @sshObj.verbose
|
|
415
|
-
@.emit 'msg', "name: " + name
|
|
416
|
-
@.emit 'msg', "instructions: " + instructions
|
|
417
|
-
str = JSON.stringify(prompts, null, 4)
|
|
418
|
-
@.emit 'msg', "Prompts object: " + str
|
|
419
|
-
|
|
413
|
+
console.error data
|
|
414
|
+
|
|
420
415
|
@.on "error", (err, type, close = false, callback) =>
|
|
421
|
-
@.emit 'msg', "#{
|
|
416
|
+
@.emit 'msg', "Class.error: #{err}, #{type}" if @sshObj.debug
|
|
422
417
|
if ( err instanceof Error )
|
|
423
418
|
@.emit 'msg', "Error: " + err.message + ", Level: " + err.level
|
|
424
419
|
else
|
|
425
420
|
@.emit 'msg', "#{type} error: " + err
|
|
426
|
-
callback(err, type) if typeof callback == 'function'
|
|
427
|
-
@connection.end() if close
|
|
428
|
-
|
|
429
|
-
@.on "end", ( sessionText, sshObj ) =>
|
|
430
|
-
@.emit 'msg', "#{@sshObj.server.host}: Class.end" if @sshObj.debug
|
|
431
421
|
|
|
432
|
-
|
|
433
|
-
|
|
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
|
+
|
|
433
|
+
@_allSessions = ""
|
|
434
434
|
|
|
435
|
-
_loadDefaults: (callback) =>
|
|
436
435
|
|
|
437
|
-
|
|
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: () =>
|
|
446
|
+
|
|
447
|
+
if @sshObj.msg and @sshObj.msg.send and typeof @sshObj.msg.send == 'function'
|
|
448
|
+
@.on "msg", @sshObj.msg.send
|
|
449
|
+
else if @sshObj.msg and typeof @sshObj.msg == 'function'
|
|
450
|
+
@.on "msg", @sshObj.msg
|
|
451
|
+
else
|
|
452
|
+
@.on "msg", ( message ) =>
|
|
453
|
+
console.log message
|
|
454
|
+
|
|
438
455
|
@.emit 'msg', "#{@sshObj.server.host}: Load Defaults" if @sshObj.debug
|
|
439
456
|
@command = ""
|
|
440
457
|
@_buffer = ""
|
|
458
|
+
@sshObj.sshToNextHost = false
|
|
441
459
|
@sshObj.connectedMessage = "Connected" unless @sshObj.connectedMessage
|
|
442
460
|
@sshObj.readyMessage = "Ready" unless @sshObj.readyMessage
|
|
443
461
|
@sshObj.closedMessage = "Closed" unless @sshObj.closedMessage
|
|
@@ -472,7 +490,7 @@ class SSH2Shell extends Stream
|
|
|
472
490
|
@passwordPrompt = new RegExp(@sshObj.passPromptText+".*" + @sshObj.passwordPrompt + "\\s?$","i") unless @passwordPrompt
|
|
473
491
|
@passphrasePrompt = new RegExp(@sshObj.passPromptText+".*" + @sshObj.passphrasePrompt + "\\s?$","i") unless @passphrasePrompt
|
|
474
492
|
@standardPrompt = new RegExp("[" + @sshObj.standardPrompt + "]\\s?$") unless @standardPrompt
|
|
475
|
-
|
|
493
|
+
|
|
476
494
|
|
|
477
495
|
@sshObj.onCommandProcessing = @sshObj.onCommandProcessing ? ( command, response, sshObj, stream ) =>
|
|
478
496
|
|
|
@@ -483,10 +501,9 @@ class SSH2Shell extends Stream
|
|
|
483
501
|
response = response.replace(@command, "")
|
|
484
502
|
@.emit 'msg', "#{@sshObj.server.host}: Class.commandTimeout" if @sshObj.debug
|
|
485
503
|
@.emit 'msg', "#{@sshObj.server.host}: Timeout command: #{command} response: #{response}" if @sshObj.verbose
|
|
486
|
-
|
|
504
|
+
|
|
487
505
|
@.emit "error", "#{@sshObj.server.host}: Command timed out after #{@.idleTime/1000} seconds", "Timeout", true, (err, type)=>
|
|
488
|
-
|
|
489
|
-
|
|
506
|
+
@sshObj.sessionText += @_buffer
|
|
490
507
|
|
|
491
508
|
@.on "keyboard-interactive", @sshObj.onKeyboardInteractive if typeof @sshObj.onKeyboardInteractive == 'function'
|
|
492
509
|
@.on "error", @sshObj.onError if typeof @sshObj.onError == 'function'
|
|
@@ -500,8 +517,7 @@ class SSH2Shell extends Stream
|
|
|
500
517
|
@.emit 'msg', "#{@sshObj.server.host}: Host loaded" if @sshObj.verbose
|
|
501
518
|
@.emit 'msg', @sshObj if @sshObj.verbose
|
|
502
519
|
|
|
503
|
-
|
|
504
|
-
callback()
|
|
520
|
+
|
|
505
521
|
|
|
506
522
|
connect: (callback)=>
|
|
507
523
|
@_callback = callback if typeof callback == 'function'
|
|
@@ -553,10 +569,8 @@ class SSH2Shell extends Stream
|
|
|
553
569
|
|
|
554
570
|
@_primaryhostSessionText += @sshObj.sessionText+"\n"
|
|
555
571
|
@_allSessions += @_primaryhostSessionText
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
@.emit 'end', @_allSessions, @sshObj
|
|
559
|
-
|
|
572
|
+
if @_hosts.length == 0
|
|
573
|
+
@.emit 'end', @_allSessions, @sshObj
|
|
560
574
|
@_removeEvents()
|
|
561
575
|
|
|
562
576
|
|
|
@@ -571,11 +585,14 @@ class SSH2Shell extends Stream
|
|
|
571
585
|
|
|
572
586
|
@connection.on "close", (had_error) =>
|
|
573
587
|
@.emit 'msg', "#{@sshObj.server.host}: Connection.close" if @sshObj.debug
|
|
588
|
+
clearTimeout @idleTimer if @idleTimer
|
|
589
|
+
clearTimeout @dataReceivedTimer if @dataReceivedTimer
|
|
574
590
|
if had_error
|
|
575
591
|
@.emit "error", had_error, "Connection close"
|
|
576
592
|
else
|
|
577
593
|
@.emit 'msg', @sshObj.closedMessage
|
|
578
|
-
|
|
594
|
+
|
|
595
|
+
if @_hosts.length == 0
|
|
579
596
|
if typeof @_callback == 'function'
|
|
580
597
|
@_callback @_allSessions
|
|
581
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();
|