bdy 1.11.0-dev → 1.12.0-dev

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.
Files changed (58) hide show
  1. package/distTs/package.json +16 -5
  2. package/distTs/src/agent/agent.js +62 -36
  3. package/distTs/src/agent/linux.js +9 -4
  4. package/distTs/src/agent/manager.js +61 -42
  5. package/distTs/src/agent/osx.js +12 -5
  6. package/distTs/src/agent/socket/client.js +26 -7
  7. package/distTs/src/agent/socket/tunnel.js +56 -32
  8. package/distTs/src/agent/socket.js +83 -63
  9. package/distTs/src/agent/system.js +3 -1
  10. package/distTs/src/agent/windows.js +6 -6
  11. package/distTs/src/command/agent/install.js +4 -4
  12. package/distTs/src/command/agent/run.js +2 -2
  13. package/distTs/src/command/agent/status.js +6 -7
  14. package/distTs/src/command/agent/tunnel/http.js +4 -5
  15. package/distTs/src/command/agent/tunnel/tcp.js +3 -3
  16. package/distTs/src/command/agent/tunnel/tls.js +3 -3
  17. package/distTs/src/command/config/add/http.js +3 -3
  18. package/distTs/src/command/config/add/tcp.js +3 -3
  19. package/distTs/src/command/config/add/tls.js +3 -3
  20. package/distTs/src/command/config/get/region.js +1 -1
  21. package/distTs/src/command/pre.js +1 -1
  22. package/distTs/src/command/tunnel/http.js +2 -1
  23. package/distTs/src/command/tunnel/tcp.js +3 -3
  24. package/distTs/src/command/tunnel/tls.js +4 -4
  25. package/distTs/src/format.js +14 -15
  26. package/distTs/src/index.js +1 -1
  27. package/distTs/src/input.js +13 -12
  28. package/distTs/src/logger.js +12 -13
  29. package/distTs/src/tunnel/agent.js +3 -1
  30. package/distTs/src/tunnel/api/agent.js +1 -0
  31. package/distTs/src/tunnel/api/buddy.js +2 -0
  32. package/distTs/src/tunnel/cfg.js +6 -2
  33. package/distTs/src/tunnel/compression.js +17 -14
  34. package/distTs/src/tunnel/dns.js +20 -29
  35. package/distTs/src/tunnel/html.js +2 -0
  36. package/distTs/src/tunnel/http/log.js +30 -8
  37. package/distTs/src/tunnel/http/serve.js +3 -2
  38. package/distTs/src/tunnel/http/stream.js +5 -1
  39. package/distTs/src/tunnel/http.js +67 -26
  40. package/distTs/src/tunnel/identification.js +21 -14
  41. package/distTs/src/tunnel/latency.js +19 -11
  42. package/distTs/src/tunnel/output/interactive/tunnel.js +16 -9
  43. package/distTs/src/tunnel/output/noninteractive/agent/tunnels.js +4 -2
  44. package/distTs/src/tunnel/output/noninteractive/config/tunnel.js +6 -4
  45. package/distTs/src/tunnel/output/noninteractive/config/tunnels.js +2 -0
  46. package/distTs/src/tunnel/output/noninteractive/tunnel.js +13 -11
  47. package/distTs/src/tunnel/server/cert.js +2 -0
  48. package/distTs/src/tunnel/server/http1.js +15 -10
  49. package/distTs/src/tunnel/server/http2.js +18 -12
  50. package/distTs/src/tunnel/server/sftp.js +32 -15
  51. package/distTs/src/tunnel/server/ssh.js +49 -31
  52. package/distTs/src/tunnel/server/tls.js +11 -5
  53. package/distTs/src/tunnel/ssh/client.js +45 -31
  54. package/distTs/src/tunnel/tcp.js +61 -42
  55. package/distTs/src/tunnel/tunnel.js +196 -112
  56. package/distTs/src/types/tunnel.js +135 -0
  57. package/distTs/src/utils.js +2 -87
  58. package/package.json +16 -5
@@ -1,6 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  class OutputNoninteractiveConfigTunnels {
4
+ terminal;
5
+ tunnels;
4
6
  constructor(terminal, tunnels) {
5
7
  this.terminal = terminal;
6
8
  this.tunnels = tunnels;
@@ -3,9 +3,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- const utils_1 = require("../../../utils");
7
6
  const format_1 = __importDefault(require("../../../format"));
7
+ const tunnel_1 = require("../../../types/tunnel");
8
8
  class OutputNoninteractiveTunnel {
9
+ tunnel;
10
+ terminal;
9
11
  constructor(terminal, tunnel) {
10
12
  this.tunnel = tunnel;
11
13
  this.terminal = terminal;
@@ -44,16 +46,16 @@ class OutputNoninteractiveTunnel {
44
46
  process.exit();
45
47
  }
46
48
  start() {
47
- this.tunnel.on(utils_1.TUNNEL_EVENT_OPEN, (t) => this.onOpen(t));
48
- this.tunnel.on(utils_1.TUNNEL_EVENT_CLOSED, (t) => this.onClosed(t));
49
- this.tunnel.on(utils_1.TUNNEL_EVENT_TCP_OPEN, (t) => this.onTcpOpen(t));
50
- this.tunnel.on(utils_1.TUNNEL_EVENT_TCP_CLOSED, (t) => this.onTcpClosed(t));
51
- this.tunnel.on(utils_1.TUNNEL_EVENT_TLS_OPEN, (t) => this.onTlsOpen(t));
52
- this.tunnel.on(utils_1.TUNNEL_EVENT_TLS_CLOSED, (t) => this.onTlsClosed(t));
53
- this.tunnel.on(utils_1.TUNNEL_EVENT_HTTP_IDENTIFIED, (t, type) => this.onHttpIdentified(t, type));
54
- this.tunnel.on(utils_1.TUNNEL_EVENT_HTTP_REQUEST, (t, logRequest) => this.onHttpRequest(t, logRequest));
55
- this.tunnel.on(utils_1.TUNNEL_EVENT_HTTP_RESPONSE, (t, logRequest) => this.onHttpResponse(t, logRequest));
56
- this.tunnel.on(utils_1.TUNNEL_EVENT_STOPPED, (t) => this.onStopped(t));
49
+ this.tunnel.on(tunnel_1.TUNNEL_EVENT.OPEN, (t) => this.onOpen(t));
50
+ this.tunnel.on(tunnel_1.TUNNEL_EVENT.CLOSED, (t) => this.onClosed(t));
51
+ this.tunnel.on(tunnel_1.TUNNEL_EVENT.TCP_OPEN, (t) => this.onTcpOpen(t));
52
+ this.tunnel.on(tunnel_1.TUNNEL_EVENT.TCP_CLOSED, (t) => this.onTcpClosed(t));
53
+ this.tunnel.on(tunnel_1.TUNNEL_EVENT.TLS_OPEN, (t) => this.onTlsOpen(t));
54
+ this.tunnel.on(tunnel_1.TUNNEL_EVENT.TLS_CLOSED, (t) => this.onTlsClosed(t));
55
+ this.tunnel.on(tunnel_1.TUNNEL_EVENT.HTTP_IDENTIFIED, (t, type) => this.onHttpIdentified(t, type));
56
+ this.tunnel.on(tunnel_1.TUNNEL_EVENT.HTTP_REQUEST, (t, logRequest) => this.onHttpRequest(t, logRequest));
57
+ this.tunnel.on(tunnel_1.TUNNEL_EVENT.HTTP_RESPONSE, (t, logRequest) => this.onHttpResponse(t, logRequest));
58
+ this.tunnel.on(tunnel_1.TUNNEL_EVENT.STOPPED, () => this.onStopped());
57
59
  }
58
60
  }
59
61
  exports.default = OutputNoninteractiveTunnel;
@@ -13,6 +13,8 @@ const toPositiveHex = (hexString) => {
13
13
  return hexAsInt.toString() + hexString.substring(1);
14
14
  };
15
15
  class ServerCert {
16
+ key;
17
+ cert;
16
18
  constructor() {
17
19
  const keyPair = node_forge_1.default.pki.rsa.generateKeyPair(2048);
18
20
  const cert = node_forge_1.default.pki.createCertificate();
@@ -8,32 +8,36 @@ const logger_1 = __importDefault(require("../../logger"));
8
8
  const uuid_1 = require("uuid");
9
9
  const http_1 = __importDefault(require("http"));
10
10
  const texts_1 = require("../../texts");
11
- const utils_1 = require("../../utils");
11
+ const tunnel_1 = require("../../types/tunnel");
12
12
  class ServerHttp1 extends events_1.default {
13
+ server;
13
14
  constructor(host) {
14
15
  super();
15
16
  this.server = http_1.default.createServer((req, res) => this.processRequest(req, res, host));
16
17
  this.server.on('connection', (socket) => {
17
18
  socket.id = (0, uuid_1.v4)();
18
- this.emit(utils_1.HTTP1_SOCKET_OPEN, socket);
19
+ this.emit(tunnel_1.TUNNEL_HTTP_SOCKET.OPEN, socket);
19
20
  socket.once('close', () => {
20
- this.emit(utils_1.HTTP1_SOCKET_CLOSED, socket);
21
+ this.emit(tunnel_1.TUNNEL_HTTP_SOCKET.CLOSED, socket);
21
22
  });
22
23
  });
23
24
  this.server.listen();
24
25
  }
25
26
  stop() {
26
- this.server.close();
27
- this.server.removeAllListeners();
27
+ if (this.server) {
28
+ this.server.close();
29
+ this.server.removeAllListeners();
30
+ }
28
31
  this.server = null;
29
32
  }
30
- handleSshTunnel(stream, info, ip) {
33
+ handleSshTunnel(stream, _, ip) {
31
34
  logger_1.default.debug((0, texts_1.LOG_HTTP1_CONNECTION)(ip));
32
35
  stream.remoteAddress = ip;
33
- this.server.emit('connection', stream);
36
+ if (this.server)
37
+ this.server.emit('connection', stream);
34
38
  }
35
39
  retryRequest(logRequest) {
36
- const address = this.server.address();
40
+ const address = this.server?.address();
37
41
  if (!address || !address.port)
38
42
  return;
39
43
  let req = http_1.default.request({
@@ -50,7 +54,8 @@ class ServerHttp1 extends events_1.default {
50
54
  res.resume();
51
55
  });
52
56
  req.on('close', () => {
53
- req.removeAllListeners();
57
+ if (req)
58
+ req.removeAllListeners();
54
59
  req = null;
55
60
  });
56
61
  req.end();
@@ -69,7 +74,7 @@ class ServerHttp1 extends events_1.default {
69
74
  if (!this.checkHostHeader(req, res, host))
70
75
  return;
71
76
  logger_1.default.debug((0, texts_1.LOG_HTTP1_REQUEST)(req.method, req.url));
72
- this.emit(utils_1.HTTP1_REQUEST, req, res);
77
+ this.emit(tunnel_1.TUNNEL_EVENT.HTTP_REQUEST, req, res);
73
78
  }
74
79
  }
75
80
  exports.default = ServerHttp1;
@@ -8,51 +8,57 @@ const http2_1 = __importDefault(require("http2"));
8
8
  const logger_js_1 = __importDefault(require("../../logger.js"));
9
9
  const uuid_1 = require("uuid");
10
10
  const texts_1 = require("../../texts");
11
- const utils_1 = require("../../utils");
11
+ const tunnel_1 = require("../../types/tunnel");
12
12
  class ServerHttp2 extends events_1.default {
13
+ server;
13
14
  constructor(host) {
14
15
  super();
15
16
  this.server = http2_1.default.createServer((req, res) => this.processRequest(req, res, host));
16
17
  this.server.on('session', (session) => {
17
18
  session.id = (0, uuid_1.v4)();
18
- this.emit(utils_1.HTTP2_SESSION_OPEN, session);
19
+ this.emit(tunnel_1.TUNNEL_EVENT.HTTP_SESSION_OPEN, session);
19
20
  session.once('close', () => {
20
- this.emit(utils_1.HTTP2_SESSION_CLOSED, session);
21
+ this.emit(tunnel_1.TUNNEL_EVENT.HTTP_SESSION_CLOSED, session);
21
22
  });
22
23
  });
23
24
  this.server.listen();
24
25
  }
25
26
  stop() {
26
- this.server.close();
27
- this.server.removeAllListeners();
27
+ if (this.server) {
28
+ this.server.close();
29
+ this.server.removeAllListeners();
30
+ }
28
31
  this.server = null;
29
32
  }
30
33
  handleSshTunnel(stream, info, ip) {
31
34
  logger_js_1.default.debug((0, texts_1.LOG_HTTP2_CONNECTION)(ip));
32
35
  stream.remoteAddress = ip;
33
- this.server.emit('connection', stream);
36
+ if (this.server)
37
+ this.server.emit('connection', stream);
34
38
  }
35
39
  retryRequest(logRequest) {
36
- const address = this.server.address();
40
+ const address = this.server?.address();
37
41
  if (!address || !address.port)
38
42
  return;
39
43
  let client = http2_1.default.connect(`http://localhost:${address.port}`, {
40
44
  maxSessionMemory: 100,
41
- noDelay: true
42
45
  });
43
46
  let req = client.request(logRequest.headers);
44
47
  if (logRequest.requestBody.data.length > 0)
45
48
  req.write(logRequest.requestBody.data);
46
49
  req.on('response', () => {
47
- req.resume();
50
+ if (req)
51
+ req.resume();
48
52
  });
49
53
  req.on('error', (err) => {
50
54
  logger_js_1.default.debug(texts_1.LOG_ERROR);
51
55
  logger_js_1.default.debug(err);
52
56
  });
53
57
  req.on('close', () => {
54
- req.removeAllListeners();
55
- client.close();
58
+ if (req)
59
+ req.removeAllListeners();
60
+ if (client)
61
+ client.close();
56
62
  req = null;
57
63
  client = null;
58
64
  });
@@ -72,7 +78,7 @@ class ServerHttp2 extends events_1.default {
72
78
  if (!this.checkHostHeader(req, res, host))
73
79
  return;
74
80
  logger_js_1.default.debug((0, texts_1.LOG_HTTP2_REQUEST)(req.method, req.url));
75
- this.emit(utils_1.HTTP2_REQUEST, req, res);
81
+ this.emit(tunnel_1.TUNNEL_EVENT.HTTP_REQUEST, req, res);
76
82
  }
77
83
  }
78
84
  exports.default = ServerHttp2;
@@ -6,10 +6,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const logger_1 = __importDefault(require("../../logger"));
7
7
  const ssh2_1 = __importDefault(require("ssh2"));
8
8
  const promises_1 = __importDefault(require("fs/promises"));
9
- const path_1 = __importDefault(require("path"));
9
+ const path_1 = require("path");
10
10
  const node_os_1 = require("node:os");
11
11
  const { flagsToString, STATUS_CODE } = ssh2_1.default.utils.sftp;
12
12
  class ServerSftp {
13
+ openHandlers;
14
+ count;
15
+ sftp;
13
16
  constructor(sftp) {
14
17
  logger_1.default.debug('Creating sftp server');
15
18
  this.openHandlers = new Map();
@@ -79,11 +82,7 @@ class ServerSftp {
79
82
  }
80
83
  const fd = this.openHandlers.get(id);
81
84
  const buffer = Buffer.alloc(length);
82
- const r = await fd.read(buffer, {
83
- offset: 0,
84
- length,
85
- position: offset,
86
- });
85
+ const r = await fd.read(buffer, 0, length, offset);
87
86
  if (r.bytesRead <= 0) {
88
87
  this.sftp.status(reqId, STATUS_CODE.EOF);
89
88
  }
@@ -142,6 +141,16 @@ class ServerSftp {
142
141
  this.debugEnd('SFTP close handler failed', s, err);
143
142
  }
144
143
  }
144
+ stats2attributes(stat) {
145
+ return {
146
+ mode: stat.mode,
147
+ uid: stat.uid,
148
+ gid: stat.gid,
149
+ size: stat.size,
150
+ atime: stat.atime.getTime() / 1000,
151
+ mtime: stat.mtime.getTime() / 1000
152
+ };
153
+ }
145
154
  async fstat(reqId, handle) {
146
155
  const s = this.debugStart('SFTP want to stat file');
147
156
  try {
@@ -153,7 +162,7 @@ class ServerSftp {
153
162
  }
154
163
  const fd = this.openHandlers.get(id);
155
164
  const attrs = await fd.stat();
156
- this.sftp.attrs(reqId, attrs);
165
+ this.sftp.attrs(reqId, this.stats2attributes(attrs));
157
166
  this.debugEnd('SFTP stat file succeed', s);
158
167
  }
159
168
  catch (err) {
@@ -287,13 +296,13 @@ class ServerSftp {
287
296
  }
288
297
  else {
289
298
  const name = dir.name;
290
- const fullPath = path_1.default.join(fd.path, name);
299
+ const fullPath = (0, path_1.join)(fd.path, name);
291
300
  const stat = await promises_1.default.lstat(fullPath);
292
301
  const longname = await this.longname(fullPath, name, stat);
293
302
  names.push({
294
303
  filename: name,
295
304
  longname,
296
- attrs: stat,
305
+ attrs: this.stats2attributes(stat),
297
306
  });
298
307
  r += 1;
299
308
  }
@@ -310,7 +319,7 @@ class ServerSftp {
310
319
  const s = this.debugStart(`SFTP want to stat ${path}`);
311
320
  try {
312
321
  const attrs = await promises_1.default.stat(path);
313
- this.sftp.attrs(reqId, attrs);
322
+ this.sftp.attrs(reqId, this.stats2attributes(attrs));
314
323
  this.debugEnd('SFTP stat path succeed', s);
315
324
  }
316
325
  catch (err) {
@@ -352,9 +361,14 @@ class ServerSftp {
352
361
  p = p.replaceAll('~', (0, node_os_1.homedir)());
353
362
  }
354
363
  const realPath = await promises_1.default.realpath(p);
364
+ const name = (0, path_1.basename)(realPath);
365
+ const stat = await promises_1.default.lstat(realPath);
366
+ const longname = await this.longname(realPath, name, stat);
355
367
  this.sftp.name(reqId, [
356
368
  {
357
369
  filename: realPath,
370
+ longname,
371
+ attrs: this.stats2attributes(stat)
358
372
  },
359
373
  ]);
360
374
  this.debugEnd('SFTP realpath succeed', s);
@@ -368,9 +382,14 @@ class ServerSftp {
368
382
  const s = this.debugStart(`SFTP want readlink ${path}`);
369
383
  try {
370
384
  const realPath = await promises_1.default.readlink(path);
385
+ const name = (0, path_1.basename)(realPath);
386
+ const stats = await promises_1.default.lstat(realPath);
387
+ const longname = await this.longname(realPath, name, stats);
371
388
  this.sftp.name(reqId, [
372
389
  {
373
390
  filename: realPath,
391
+ longname,
392
+ attrs: this.stats2attributes(stats)
374
393
  },
375
394
  ]);
376
395
  this.debugEnd('SFTP readlink succeed', s);
@@ -465,7 +484,7 @@ class ServerSftp {
465
484
  const s = this.debugStart(`SFTP want to lstat ${path}`);
466
485
  try {
467
486
  const attrs = await promises_1.default.lstat(path);
468
- this.sftp.attrs(reqId, attrs);
487
+ this.sftp.attrs(reqId, this.stats2attributes(attrs));
469
488
  this.debugEnd('SFTP lstat path succeed', s);
470
489
  }
471
490
  catch (err) {
@@ -477,19 +496,17 @@ class ServerSftp {
477
496
  if (this.sftp) {
478
497
  this.sftp.removeAllListeners();
479
498
  this.sftp.end();
480
- this.sftp = null;
481
499
  }
482
500
  if (this.openHandlers) {
483
- this.openHandlers.forEach((fd) => {
501
+ this.openHandlers.forEach((fd, id) => {
484
502
  try {
485
503
  fd.close();
486
504
  }
487
505
  catch {
488
506
  // do nothing
489
507
  }
490
- fd = null;
508
+ this.openHandlers.delete(id);
491
509
  });
492
- this.openHandlers = null;
493
510
  }
494
511
  this.count = 0;
495
512
  }
@@ -14,8 +14,12 @@ const buddy_1 = __importDefault(require("../api/buddy"));
14
14
  const pipeStreamToChannel = (stream, channel) => {
15
15
  channel.once('exit', (code, signal) => {
16
16
  logger_1.default.debug(`shell channel exit: ${code}, signal: ${signal}`);
17
- if (stream.exit)
18
- stream.exit(signal || code);
17
+ if (stream.exit) {
18
+ if (signal)
19
+ stream.exit(signal);
20
+ else
21
+ stream.exit(code);
22
+ }
19
23
  });
20
24
  channel.on('close', () => {
21
25
  stream.end();
@@ -24,13 +28,16 @@ const pipeStreamToChannel = (stream, channel) => {
24
28
  channel.stderr.pipe(stream.stderr);
25
29
  };
26
30
  class ServerSsh extends events_1.default {
31
+ agent;
32
+ login;
33
+ password;
34
+ server;
27
35
  constructor(agent, login, password, hostKey) {
28
36
  super();
29
37
  this.agent = agent;
30
38
  this.login = login;
31
39
  this.password = password;
32
40
  this.server = new ssh2_1.default.Server({
33
- keepAlive: true,
34
41
  hostKeys: [hostKey],
35
42
  highWaterMark: 16 * 1024 * 1024,
36
43
  ident: 'ssh2 server',
@@ -38,29 +45,35 @@ class ServerSsh extends events_1.default {
38
45
  this.server.listen();
39
46
  }
40
47
  stop() {
41
- this.server.close();
42
- this.server.removeAllListeners();
48
+ if (this.server) {
49
+ this.server.close();
50
+ this.server.removeAllListeners();
51
+ }
43
52
  this.server = null;
44
53
  }
45
54
  handleSshTunnel(stream) {
46
- this.server.injectSocket(stream);
55
+ if (this.server)
56
+ this.server.injectSocket(stream);
47
57
  }
48
58
  checkValueSafe(input, allowed) {
49
59
  const autoReject = input.length !== allowed.length;
50
60
  if (autoReject)
51
61
  allowed = input;
52
62
  const isMatch = (0, crypto_1.timingSafeEqual)(input, allowed);
53
- return (!autoReject && isMatch);
63
+ return !autoReject && isMatch;
54
64
  }
55
65
  async verifyKey(ctx, keys) {
56
66
  try {
57
67
  for (let i = 0; i < keys.length; i += 1) {
58
68
  const publicKey = ssh2_1.default.utils.parseKey(keys[i]);
69
+ if (publicKey instanceof Error)
70
+ continue;
59
71
  if (ctx.key.algo !== publicKey.type)
60
72
  continue;
61
73
  if (!this.checkValueSafe(ctx.key.data, publicKey.getPublicSSH()))
62
74
  continue;
63
- if (ctx.signature && !publicKey.verify(ctx.blob, ctx.signature, ctx.hashAlgo))
75
+ if (ctx.signature &&
76
+ !publicKey.verify(ctx.blob || '', ctx.signature, ctx.hashAlgo))
64
77
  continue;
65
78
  return true;
66
79
  }
@@ -85,7 +98,7 @@ class ServerSsh extends events_1.default {
85
98
  host: '127.0.0.1',
86
99
  port: 22,
87
100
  username: 'root',
88
- privateKey: privateKey
101
+ privateKey: privateKey,
89
102
  });
90
103
  });
91
104
  }
@@ -146,15 +159,15 @@ class ServerSsh extends events_1.default {
146
159
  }
147
160
  localExec(stream, command, env) {
148
161
  const s = process.hrtime();
149
- (0, child_process_1.exec)(command, {
150
- env,
151
- }, (err, stdout, stderr) => {
162
+ const opts = {};
163
+ if (env)
164
+ opts.env = env;
165
+ (0, child_process_1.exec)(command, opts, (err, stdout, stderr) => {
152
166
  if (stream) {
153
167
  stream.stderr.write(stderr);
154
168
  stream.write(stdout);
155
169
  stream.exit(!err ? 0 : 1);
156
170
  stream.end();
157
- stream = null;
158
171
  }
159
172
  const [seconds, nano] = process.hrtime(s);
160
173
  const ms = seconds * 1000 + nano / 1000 / 1000;
@@ -173,7 +186,6 @@ class ServerSsh extends events_1.default {
173
186
  pty = null;
174
187
  x11 = null;
175
188
  session.removeAllListeners();
176
- session = null;
177
189
  if (sftp) {
178
190
  sftp.destroy();
179
191
  sftp = null;
@@ -183,7 +195,6 @@ class ServerSsh extends events_1.default {
183
195
  channel = null;
184
196
  }
185
197
  client.removeListener('close', closeSession);
186
- client = null;
187
198
  };
188
199
  client.on('close', closeSession);
189
200
  session.on('close', closeSession);
@@ -215,7 +226,7 @@ class ServerSsh extends events_1.default {
215
226
  pty.rows = info.rows;
216
227
  pty.width = info.width;
217
228
  if (channel && channel.setWindow)
218
- channel.setWindow(pty.rows, pty.cols, pty.height, pty.width);
229
+ channel.setWindow(pty.rows || 1, pty.cols || 1, pty.height || 1, pty.width || 1);
219
230
  if (accept)
220
231
  accept();
221
232
  });
@@ -227,10 +238,12 @@ class ServerSsh extends events_1.default {
227
238
  return;
228
239
  }
229
240
  const stream = accept();
230
- proxyClient.shell(pty, {
231
- env,
232
- x11
233
- }, (err, c) => {
241
+ const opts = {};
242
+ if (env)
243
+ opts.env = env;
244
+ if (x11)
245
+ opts.x11 = x11;
246
+ proxyClient.shell(pty || {}, opts, (err, c) => {
234
247
  if (err || !c) {
235
248
  if (reject)
236
249
  reject();
@@ -296,11 +309,14 @@ class ServerSsh extends events_1.default {
296
309
  this.localExec(stream, info.command, env);
297
310
  return;
298
311
  }
299
- proxyClient.exec(info.command, {
300
- env,
301
- pty,
302
- x11
303
- }, (err, c) => {
312
+ const opts = {};
313
+ if (env)
314
+ opts.env = env;
315
+ if (pty)
316
+ opts.pty = pty;
317
+ if (x11)
318
+ opts.x11 = x11;
319
+ proxyClient.exec(info.command, opts, (err, c) => {
304
320
  if (err || !c) {
305
321
  if (reject)
306
322
  reject();
@@ -309,12 +325,14 @@ class ServerSsh extends events_1.default {
309
325
  pipeStreamToChannel(stream, c);
310
326
  });
311
327
  });
312
- session.on('env', (accept, reject, info) => {
328
+ session.on('env', (accept, _, info) => {
313
329
  logger_1.default.debug('ssh env');
314
330
  logger_1.default.debug(info);
315
- Object.keys(info || {}).forEach((key) => {
316
- env[key] = info[key];
317
- });
331
+ if (info.key) {
332
+ if (!env)
333
+ env = {};
334
+ env[info.key] = info.val;
335
+ }
318
336
  if (accept)
319
337
  accept();
320
338
  });
@@ -377,7 +395,7 @@ class ServerSsh extends events_1.default {
377
395
  let accepted = false;
378
396
  const socket = node_net_1.default.connect({
379
397
  host: destIP,
380
- port: destPort
398
+ port: destPort,
381
399
  });
382
400
  socket.on('connect', () => {
383
401
  accepted = true;
@@ -409,7 +427,7 @@ class ServerSsh extends events_1.default {
409
427
  return;
410
428
  }
411
429
  if (name === 'tcpip-forward') {
412
- let { bindAddr, bindPort } = info;
430
+ const { bindAddr, bindPort } = info;
413
431
  proxyClient.forwardIn(bindAddr, bindPort, (err, port) => {
414
432
  if (err) {
415
433
  reject();
@@ -6,8 +6,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const events_1 = __importDefault(require("events"));
7
7
  const tls_1 = __importDefault(require("tls"));
8
8
  const cert_js_1 = __importDefault(require("./cert.js"));
9
- const utils_1 = require("../../utils");
9
+ const tunnel_1 = require("../../types/tunnel");
10
10
  class ServerTls extends events_1.default {
11
+ key;
12
+ cert;
13
+ ca;
14
+ server;
11
15
  constructor(key, cert, ca) {
12
16
  super();
13
17
  this.key = key;
@@ -22,19 +26,21 @@ class ServerTls extends events_1.default {
22
26
  handshakeTimeout: 60000,
23
27
  key: this.key,
24
28
  cert: this.cert,
25
- ca: this.ca,
29
+ ca: this.ca || undefined,
26
30
  rejectUnauthorized: !!this.ca,
27
31
  requestCert: !!this.ca,
28
32
  }, (socket) => this.processSocket(socket));
29
33
  }
30
34
  async processSocket(socket) {
31
- this.emit(utils_1.TLS_SOCKET, socket);
35
+ this.emit(tunnel_1.TUNNEL_EVENT.TLS_SOCKET, socket);
32
36
  }
33
37
  handleSshTunnel(channel) {
34
- this.server.emit('connection', channel);
38
+ if (this.server)
39
+ this.server.emit('connection', channel);
35
40
  }
36
41
  stop() {
37
- this.server.removeAllListeners();
42
+ if (this.server)
43
+ this.server.removeAllListeners();
38
44
  this.server = null;
39
45
  }
40
46
  }