ssh_tunnel_proxy 1.2.3 → 1.2.5

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.
@@ -28,7 +28,7 @@
28
28
  "<node_internals>/**"
29
29
  ],
30
30
  "program": "${file}",
31
- "args":["-c","-d"]
31
+ "args":["-c","-S"]
32
32
  }
33
33
  ]
34
34
  }
package/lib/index.js CHANGED
@@ -17,6 +17,7 @@ License: MIT
17
17
  */
18
18
 
19
19
  const net = require('net');
20
+ const process = require('process');
20
21
  const { Client } = require('electron-ssh2');
21
22
 
22
23
  const KeypairStorage = require('./keypair_storage');
@@ -32,6 +33,7 @@ class SSHTunnelProxy extends Client {
32
33
  this.retries = 0;
33
34
  this.debug_en = false;
34
35
  this.debug_ssh = false;
36
+ this._tunnelReadyTimeout = undefined;
35
37
  }
36
38
 
37
39
  // function to close all active sockets for tunnel restart and exception handling
@@ -61,20 +63,29 @@ class SSHTunnelProxy extends Client {
61
63
  return;
62
64
  }
63
65
 
66
+ stream.on('end', () => {
67
+ socket.resume();
68
+ });
69
+
64
70
  // pipe the data from the local socket to the remote port and visa versa
65
- socket.pipe(stream);
66
- stream.pipe(socket);
71
+ stream.pipe(socket).pipe(stream);
72
+
73
+ const shutdown_forward = () => {
74
+ stream.unpipe(socket);
75
+ socket.unpipe(stream);
76
+ stream.end();
77
+ }
67
78
 
68
79
  // if socket ends, close stream and pipes
69
80
  socket.on('close', () => {
70
- stream.end();
81
+ shutdown_forward();
71
82
  });
72
83
 
73
84
  // if socket error, emit error and close stream
74
85
  socket.on('error', (err) => {
75
86
  _this.emit('debug', err);
76
87
  _this.debug_en && _this.debug('socket on error:', err);
77
- stream.end();
88
+ shutdown_forward();
78
89
  });
79
90
  }
80
91
 
@@ -104,7 +115,7 @@ class SSHTunnelProxy extends Client {
104
115
  // create local socket server
105
116
  const server = this.listener[server_name][proxy_port];
106
117
  if (server && server.listening) {
107
- this.debug_en && this.debug('SSH Server :: closing forward:', proxy_port)
118
+ this.debug_en && this.debug('SSH Server :: closing forward 2:', proxy_port)
108
119
  server.close();
109
120
  }
110
121
  this.listener[server_name][proxy_port] = null;
@@ -122,6 +133,8 @@ class SSHTunnelProxy extends Client {
122
133
 
123
134
  // start listening on port
124
135
  try {
136
+ var status_msg = 'SSH Server :: before listen on ' + local_port;
137
+ _this.emit('debug', status_msg);
125
138
  _this.listener[server_name][proxy_port].listen(local_port, () => {
126
139
 
127
140
  // emit server listening on port message
@@ -130,7 +143,11 @@ class SSHTunnelProxy extends Client {
130
143
 
131
144
  // if all listeners have been successfully established, resolve setup connection
132
145
  if (listeners++ >= proxy_ports.length - 1) {
133
- _this.emit('ready', {});
146
+ _this.emit('ssh_tunnel_ready', {});
147
+ if (_this._tunnelReadyTimeout) {
148
+ clearTimeout(this._tunnelReadyTimeout);
149
+ _this._tunnelReadyTimeout = undefined
150
+ }
134
151
  resolve();
135
152
  }
136
153
  });
@@ -140,6 +157,35 @@ class SSHTunnelProxy extends Client {
140
157
  });
141
158
  }
142
159
 
160
+ // handle remote shell stream processing
161
+ remote_shell(err, stream) {
162
+ const _this = this;
163
+ if (err) throw err;
164
+
165
+ // disable local echo of input chars, use remote output only
166
+ process.stdin.setRawMode(true);
167
+
168
+ // forward data from local terminal to remote host
169
+ const stdinListener = (data) => {
170
+ stream.stdin.write(data);
171
+ };
172
+
173
+ // shutdown this process when stream ends (user logs out)
174
+ stream.on('close', function () {
175
+ process.stdin.setRawMode(false);
176
+ process.stdin.removeListener("data", stdinListener);
177
+ process.exit();
178
+ }).stderr.on('data', function (data) {
179
+ _this.debug_en && _this.debug('shell' + data);
180
+ });
181
+
182
+ // skip next stops double printing of input
183
+ stream.stdout.on("data", (data) => {
184
+ process.stdout.write(data);
185
+ })
186
+ process.stdin.on("data", stdinListener)
187
+ }
188
+
143
189
  // handle setting up ssh client and proxy forward ports
144
190
  do_ssh_connect(opts) {
145
191
 
@@ -159,7 +205,18 @@ class SSHTunnelProxy extends Client {
159
205
  }
160
206
 
161
207
  _this.on('ready', () => {
208
+
209
+ // if shell requested, enable remote terminal
210
+ if (opts.shell) {
211
+ _this.shell(_this.remote_shell);
212
+ }
213
+
214
+ // setup local forwarding ports to remote host
162
215
  _this.on_ssh_client_ready(opts.server_name, opts.proxy_ports, resolve);
216
+ if (_this._tunnelReadyTimeout) {
217
+ clearTimeout(this._tunnelReadyTimeout);
218
+ _this._tunnelReadyTimeout = undefined
219
+ }
163
220
  });
164
221
 
165
222
  _this.on('end', () => {
@@ -176,6 +233,10 @@ class SSHTunnelProxy extends Client {
176
233
  _this.debug_en && _this.debug('SSH Client :: error :: ' + err);
177
234
  _this.emit('debug', err);
178
235
  if (_this.listener[opts.server_name]) _this.listener[opts.server_name].isConnected = false;
236
+ if (_this._tunnelReadyTimeout) {
237
+ clearTimeout(this._tunnelReadyTimeout);
238
+ _this._tunnelReadyTimeout = undefined
239
+ }
179
240
  _this.ssh_retry_connect(opts);
180
241
  resolve();
181
242
  });
@@ -239,12 +300,13 @@ class SSHTunnelProxy extends Client {
239
300
  }
240
301
 
241
302
  // on network error, attempt to re-establish connection until 10 retries
303
+ //clearTimeout(this._readyTimeout);
242
304
  ssh_retry_connect(opts) {
243
305
  const _this = this;
244
306
  const invoke = () => {
245
307
  _this.connectSSH(opts);
246
308
  }
247
- if (this.retries++ < 10) setTimeout(invoke, 5000);
309
+ if (this.retries++ < 10) this._tunnelReadyTimeout = setTimeout(invoke, 5000);
248
310
  }
249
311
 
250
312
  // attempt to establish ssh tunnel to server with supplied parameters.
@@ -259,7 +321,7 @@ class SSHTunnelProxy extends Client {
259
321
  const msg = 'SSH connection to ' + opts.server_name + ' established at ' + hostport;
260
322
  _this.debug(msg);
261
323
  }
262
- _this.emit('status', '', 'ready', hostport);
324
+ //_this.emit('status', '', 'ready', hostport);
263
325
  _this.retries = 0;
264
326
  resolve();
265
327
  });
package/main.js CHANGED
@@ -17,6 +17,7 @@ var ngrokAPIKey = null;
17
17
  var privateKey = null;
18
18
  var service = null;
19
19
  var account = null;
20
+ var shell = null;
20
21
 
21
22
  function get_key_from_file(filename) {
22
23
  try {
@@ -83,6 +84,10 @@ function main(args) {
83
84
  case '--service':
84
85
  service = value;
85
86
  break;
87
+ case '-S':
88
+ case '--shell':
89
+ shell = true;
90
+ break;
86
91
  case '--a':
87
92
  account = value;
88
93
  break;
@@ -139,6 +144,9 @@ function main(args) {
139
144
  else if (config.private_key) {
140
145
  config.private_key = get_key_from_file(config.private_key);
141
146
  }
147
+ if (shell) {
148
+ config.shell=true;
149
+ }
142
150
 
143
151
  // create new tunnel and start connection
144
152
  var sshTunnelProxy = new SSHTunnelProxy();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ssh_tunnel_proxy",
3
- "version": "1.2.3",
3
+ "version": "1.2.5",
4
4
  "description": "obtain ngrok host port from api and establish a ssh connection",
5
5
  "main": "lib/index.js",
6
6
  "scripts": {