ssh_tunnel_proxy 1.2.11 → 2.0.1

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.
@@ -0,0 +1,184 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ var __generator = (this && this.__generator) || function (thisArg, body) {
11
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
12
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
13
+ function verb(n) { return function (v) { return step([n, v]); }; }
14
+ function step(op) {
15
+ if (f) throw new TypeError("Generator is already executing.");
16
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
17
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
18
+ if (y = 0, t) op = [op[0] & 2, t.value];
19
+ switch (op[0]) {
20
+ case 0: case 1: t = op; break;
21
+ case 4: _.label++; return { value: op[1], done: false };
22
+ case 5: _.label++; y = op[1]; op = [0]; continue;
23
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
24
+ default:
25
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
26
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
27
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
28
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
29
+ if (t[2]) _.ops.pop();
30
+ _.trys.pop(); continue;
31
+ }
32
+ op = body.call(thisArg, _);
33
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
34
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
35
+ }
36
+ };
37
+ import * as process from 'process';
38
+ import { readFileSync } from 'fs';
39
+ import { homedir } from 'os';
40
+ import { Command } from 'commander';
41
+ import { SSHTunnelProxy, KeypairStorage } from './index';
42
+ function get_default_config() {
43
+ var configs = [];
44
+ try {
45
+ configs = JSON.parse(readFileSync(homedir() + '/.config/ssh_tunnel_proxy/config.json').toString());
46
+ }
47
+ catch (err) {
48
+ console.log('Error loading config file:', err);
49
+ }
50
+ return configs;
51
+ }
52
+ export function main() {
53
+ var _this = this;
54
+ var program = new Command();
55
+ program
56
+ .name('ssh2-node')
57
+ .description('Nodejs ssh2 command line client')
58
+ .version('1.2.12')
59
+ .option('-4 --forceIPv4 [forceIPv4]', 'Only connect via resolved IPv4 address for host. Default: false')
60
+ .option('-6 --forceIPv6 [forceIPv6]', 'Only connect via resolved IPv6 address for host. Default: false')
61
+ .option('-b --bind [bind]', 'bind_address')
62
+ .option('-C --compress [compress]', 'Requests compression of all data')
63
+ .option('-c --cipher [cipher]', 'cipher_spec')
64
+ .option('-D --dynamic_forward [dynamic_forward]', " Specifies a local 'dynamic' application-level port forwarding.")
65
+ .option('-e --escape [escape]', 'escape_char Sets the escape character for sessions with a pty.')
66
+ .option('-F --config [config]', 'configfile')
67
+ .option('-f --background [background]', 'Requests ssh to go to background just before command execution.')
68
+ .option('-g --local_forward_remote [local_forward_remote]', 'Allows remote hosts to connect to local forwarded ports.')
69
+ .option('-i --identity [identity]', 'Private key filename.')
70
+ .option('-L --local_forward_out [local_forward_out...]', 'bind_address:port:host:hostport')
71
+ .option('-l --login_name [login_name]', 'login_name')
72
+ .option('-N --no_exec [no_exec]', 'Do not execute a remote command.')
73
+ .option('-n --redirect_stdin [redirect_stdin]', 'Redirects stdin from /dev/null')
74
+ .option('-o --option [option]', 'option')
75
+ .option('-p --port [port]', 'port Port to connect to on the remote host.')
76
+ .option('-q --quiet [quiet]', 'Quiet mode. Causes most warning and diagnostic messages to be suppressed.')
77
+ .option('-R --local_forward_in [local_forward_in...]', 'bind_address:port:host:hostport')
78
+ .option('-s --subsystem [subsystem]', 'May be used to request invocation of a subsystem on the remote system.')
79
+ .option('-T --disable_tty [disable_tty]', 'Disable pseudo-tty allocation.')
80
+ .option('-t --force_tty [force_tty]', 'Force pseudo-tty allocation.')
81
+ .option('-V --version [version]', 'Display the version number and exit.')
82
+ .option('-v --verbose [verbose]', 'Verbose mode. Causes ssh to print debugging messages about its progress.')
83
+ .option('-W --forward_stdin_stdout [forward_stdin_stdout]', 'host:port Requests that standard input and output on the client be forwarded to host on port ver the secure channel.')
84
+ .option('-X --x11 [x11]', 'Enables X11 forwarding.')
85
+ .option('-x --x11_disable [x11_disable]', 'Disables X11 forwarding.')
86
+ .option('-Y --x11_trusted [x11_trusted]', 'Enables trusted X11 forwarding.')
87
+ .option('-y --log [log]', 'Send log information using the syslog(3)')
88
+ .option('-H --ngrok [ngrok]', 'Obtain connectiion hostport from ngrok')
89
+ .option('-J --keychain_service [keychain_service]', 'Service name to obtain private key from system keychain.')
90
+ .option('-j --keychain_account [keychain_account]', 'Account name to obtain private key from system keychain.')
91
+ .argument('[userhost_arg]', 'Connect to hostname in config.')
92
+ .argument('[exec...]', 'Command to exec on remote host.');
93
+ program.parse(process.argv);
94
+ var opts = program.opts();
95
+ var args = program.processedArgs;
96
+ var username = '';
97
+ var config_host = '';
98
+ var host = '';
99
+ var userhost_arg = "".concat(args[0]);
100
+ args.shift();
101
+ var cmd = args.join(' ');
102
+ var exec = [];
103
+ if (cmd.length > 0)
104
+ exec.push(cmd);
105
+ if (userhost_arg) {
106
+ if (userhost_arg.indexOf('@') >= 0) {
107
+ var userhost = userhost_arg.split('@');
108
+ username = userhost[0];
109
+ host = userhost[1];
110
+ }
111
+ else {
112
+ config_host = userhost_arg;
113
+ }
114
+ }
115
+ else {
116
+ console.log('user@host or host name in config not provided');
117
+ return;
118
+ }
119
+ var configs = [];
120
+ if (config_host) {
121
+ configs = get_default_config();
122
+ }
123
+ if (!config_host) {
124
+ var config = {
125
+ hostname: 'cli',
126
+ username: username,
127
+ host: host,
128
+ private_key_filename: opts.identity.trim(),
129
+ };
130
+ configs = [config];
131
+ }
132
+ var keypairStorage = new KeypairStorage();
133
+ var remote_server = '';
134
+ configs.forEach(function (config) { return __awaiter(_this, void 0, void 0, function () {
135
+ var service_name, _a, sshTunnelProxy;
136
+ return __generator(this, function (_b) {
137
+ switch (_b.label) {
138
+ case 0:
139
+ if (config.disabled)
140
+ return [2];
141
+ if (config_host && config_host !== config.hostname)
142
+ return [2];
143
+ remote_server = config_host;
144
+ if (!config.service_name) return [3, 2];
145
+ config.server_name = config.hostname || config_host || 'ssh_tunnel_proxy';
146
+ service_name = config.service_name || 'ssh_client';
147
+ _a = config;
148
+ return [4, keypairStorage.get_keypair(service_name, config.server_name)];
149
+ case 1:
150
+ _a.private_key = _b.sent();
151
+ _b.label = 2;
152
+ case 2:
153
+ opts.port && (config.port = opts.port);
154
+ opts.local_forward_out && (config.proxy_ports = opts.local_forward_out);
155
+ opts.local_forward_in && (config.remote_ports = opts.local_forward_in);
156
+ opts.keychain_service && (config.service_name = opts.keychain_service);
157
+ opts.keychain_account && (config.server_name = opts.keychain_account);
158
+ opts.ngrok && (config.ngrok_api = opts.ngrok);
159
+ opts.identity && (config.private_key_filename = opts.identity.trim());
160
+ opts.compress && (config.compress = opts.compress);
161
+ opts.cypher && (config.cypher = opts.cypher);
162
+ if (exec.length > 0) {
163
+ config.exec = exec;
164
+ }
165
+ else {
166
+ config.shell = true;
167
+ }
168
+ sshTunnelProxy = new SSHTunnelProxy();
169
+ sshTunnelProxy.debug_en = opts.verbose;
170
+ return [4, sshTunnelProxy.connectSSH(config, null)];
171
+ case 3:
172
+ _b.sent();
173
+ if (exec.length > 0) {
174
+ process.exit();
175
+ }
176
+ return [2];
177
+ }
178
+ });
179
+ }); });
180
+ if (config_host && !remote_server) {
181
+ console.log("Remote host ".concat(config_host, " not found"));
182
+ }
183
+ }
184
+ //# sourceMappingURL=ssh2-node.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ssh2-node.js","sourceRoot":"","sources":["../../src/ssh2-node.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,65 @@
1
+ /// <reference types="node" />
2
+ /// <reference types="node" />
3
+ /// <reference types="node" />
4
+ /// <reference types="node" />
5
+ import { Server, Socket } from 'net';
6
+ import { Writable } from 'stream';
7
+ import { EventEmitter } from 'events';
8
+ import { Client, Channel } from 'electron-ssh2';
9
+ import { KeypairStorage } from './keypair_storage';
10
+ import { NgrokApi } from './ngrok_service';
11
+ import { main } from './ssh2-node';
12
+ interface Listener {
13
+ [key: string]: Server;
14
+ }
15
+ export type SSHConfig = {
16
+ hostname: string;
17
+ username: string;
18
+ password?: string;
19
+ host?: string;
20
+ port?: string;
21
+ proxy_ports?: Array<string>;
22
+ remote_ports?: Array<string>;
23
+ private_key?: string | null;
24
+ private_key_filename?: string | null;
25
+ disabled?: boolean;
26
+ server_name?: string;
27
+ service_name?: string;
28
+ compress?: string;
29
+ cypher?: string;
30
+ exec?: Array<string>;
31
+ shell?: boolean;
32
+ ngrok_api?: string;
33
+ keepaliveInterval?: number;
34
+ };
35
+ export declare class SSHTunnelProxy extends EventEmitter {
36
+ protected client: Client;
37
+ protected keypairStorage: KeypairStorage;
38
+ protected config: SSHConfig;
39
+ protected listener: Listener;
40
+ protected retries: number;
41
+ protected networkOnline: boolean;
42
+ protected _tunnelReadyTimeout: ReturnType<typeof setTimeout>;
43
+ debug_en: boolean;
44
+ debug_ssh: boolean;
45
+ constructor();
46
+ protected close_sockets(proxy_ports: Array<string>): void;
47
+ protected setup_ssh_forward(socket: Socket, remote_hostname: string, remote_port: string): void;
48
+ setupProxyPorts(proxy_ports: Array<string>): Promise<void>;
49
+ execCmd(cmd: string, dataStream?: Writable, errStream?: Writable): Promise<void>;
50
+ protected remote_shell(err: Error, stream: Channel): void;
51
+ protected cleanup_events(client: Client): void;
52
+ do_ssh_connect(opts: SSHConfig): Promise<void>;
53
+ validate_port_number(port: number, whitelist: object): boolean;
54
+ validate_local_forward(proxy_ports: Array<string>, whitelist: object): boolean;
55
+ protected ssh_retry_connect(opts: SSHConfig): void;
56
+ protected ssh_start_tunnel(opts: SSHConfig): Promise<unknown>;
57
+ connectSSH(opts: SSHConfig, whitelist: object | null): Promise<void>;
58
+ onNetworkOnline(): void;
59
+ onNetworkOffline(): void;
60
+ generateAndStoreKeypair(serviceName: string, account: string): void;
61
+ getPublicKey(serviceName: string, account: string): void;
62
+ getClient(): Client;
63
+ protected debug(...args: any[]): void;
64
+ }
65
+ export { KeypairStorage, NgrokApi, main as sshcli };
@@ -0,0 +1,12 @@
1
+ export declare class KeypairStorage {
2
+ generate_and_store_keypair(service_name: string, account: string): Promise<unknown>;
3
+ get_public_key_from_keychain(service_name: string, account: string): Promise<unknown>;
4
+ get_public_key_from_private(private_key: string): any;
5
+ generate_keypair(): {
6
+ public_key: any;
7
+ private_key: any;
8
+ };
9
+ get_keypair(service: string, server: string): Promise<string>;
10
+ set_keypair(service: string, server: string, key: string): Promise<void>;
11
+ delete_keypair(service: string, server: string): Promise<boolean>;
12
+ }
@@ -0,0 +1,11 @@
1
+ import { Ngrok } from '@ngrok/ngrok-api';
2
+ export type Hostport = {
3
+ host: string;
4
+ port: string;
5
+ };
6
+ export declare class NgrokApi {
7
+ ngrok: Ngrok;
8
+ constructor(apiToken: any);
9
+ get_hostport<Hostport>(): Promise<Hostport>;
10
+ parse_ngrok_hostport<Hostport>(endpoints: any): Hostport;
11
+ }
@@ -0,0 +1 @@
1
+ export declare function main(): void;
package/package.json CHANGED
@@ -1,31 +1,61 @@
1
1
  {
2
2
  "name": "ssh_tunnel_proxy",
3
- "version": "1.2.11",
3
+ "author": "Autonomous",
4
+ "license": "MIT",
5
+ "version": "2.0.1",
4
6
  "description": "obtain ngrok host port from api and establish a ssh connection",
5
- "main": "lib/index.js",
7
+ "main": "dist/cjs/index.js",
8
+ "module": "dist/esm/index.js",
9
+ "types": "typings/index.d.ts",
6
10
  "scripts": {
11
+ "build": "npm run build:cjs && npm run build:esm && npm run build:types",
12
+ "build:cjs": "node tools/cleanup cjs && tsc -p config/tsconfig.cjs.json",
13
+ "build:esm": "node tools/cleanup esm && tsc -p config/tsconfig.esm.json",
14
+ "build:types": "node tools/cleanup types && tsc -p config/tsconfig.types.json",
15
+ "lint": "eslint \"src/*.ts\"",
16
+ "prepare": "npm run build",
17
+ "prepublishOnly": "npm test && npm run lint",
18
+ "preversion": "npm run lint",
19
+ "version": "git add -A src",
20
+ "postversion": "git push && git push --tags",
7
21
  "test": "mocha"
8
22
  },
9
- "author": "Autonomous",
10
- "license": "MIT",
23
+ "repository": {
24
+ "type": "git",
25
+ "url": "git+https://github.com/autonomous1/ssh_tunnel_proxy"
26
+ },
27
+ "files": [
28
+ "dist/**/*",
29
+ "ssh2-node"
30
+ ],
31
+ "bin": {
32
+ "ssh2-node": "./ssh2-node"
33
+ },
11
34
  "dependencies": {
12
35
  "@ngrok/ngrok-api": "^0.9.0",
13
36
  "bluebird": "^3.7.2",
37
+ "commander": "^10.0.0",
14
38
  "electron-ssh2": "^0.1.2",
15
39
  "form-data": "^4.0.0",
16
40
  "fs": "^0.0.1-security",
17
41
  "keytar": "^7.9.0",
18
42
  "net": "^1.0.2",
19
- "ngrok": "^4.3.3",
43
+ "os": "^0.1.2",
20
44
  "socksv5": "^0.0.6",
21
45
  "split": "^1.0.1",
22
46
  "sshpk": "^1.17.0",
23
47
  "through": "^2.3.8"
24
48
  },
25
49
  "devDependencies": {
26
- "eslint": "^8.33.0",
50
+ "@types/node": "^18.13.0",
51
+ "@typescript-eslint/eslint-plugin": "^5.52.0",
52
+ "@typescript-eslint/parser": "^5.52.0",
53
+ "eslint": "^8.34.0",
54
+ "eslint-config-standard-with-typescript": "^34.0.0",
55
+ "eslint-plugin-import": "^2.27.5",
56
+ "eslint-plugin-n": "^15.6.1",
57
+ "eslint-plugin-promise": "^6.1.1",
27
58
  "mocha": "^10.2.0",
28
- "rewire": "^6.0.0",
29
- "sinon": "^15.0.1"
59
+ "typescript": "^4.9.5"
30
60
  }
31
61
  }
package/ssh2-node CHANGED
@@ -1,181 +1,2 @@
1
- #!/usr/bin/node
2
- const process = require('process');
3
- const fs = require('fs');
4
- const { SSHTunnelProxy, KeypairStorage } = require('./lib/index.js');
5
-
6
- const keypairStorage = new KeypairStorage();
7
- const homedir = require('os').homedir();
8
- var debug = false;
9
- var exec = [];
10
- var remote_host = null;
11
- var proxies = [];
12
- var configs = null;
13
- var host = null;
14
- var port = null;
15
- var username = null;
16
- var password = null;
17
- var forwardOut = [];
18
- var forwardIn = [];
19
- var ngrokAPIKey = null;
20
- var privateKey = null;
21
- var service = null;
22
- var account = null;
23
- var shell = null;
24
-
25
- function get_config(filename) {
26
- try {
27
- configs = JSON.parse(fs.readFileSync(filename), 'utf8');
28
- } catch (err) {
29
- console.log('Error loading config file:', err);
30
- }
31
- }
32
-
33
- function get_default_config() {
34
- try {
35
- configs = JSON.parse(fs.readFileSync(homedir + '/.config/ssh_tunnel_proxy/config.json'), 'utf8');
36
- } catch (err) {
37
- //console.log('Error loading config file:', err);
38
- }
39
- }
40
-
41
- function main(args) {
42
-
43
- // parse command line args
44
- for (let i = 0; i < args.length; i++) {
45
- const arg = args[i].split('=');
46
- const cmd = arg[0];
47
- const value = arg[1];
48
- switch (cmd) {
49
- case '--a':
50
- account = value;
51
- break;
52
- case '-c':
53
- case '--config':
54
- if (value) get_config(value);
55
- else get_default_config();
56
- break;
57
- case '-d':
58
- case '--debug':
59
- debug = true;
60
- break;
61
- case '-e':
62
- case '--exec':
63
- exec.push(value);
64
- break;
65
- case '-h':
66
- case '--host':
67
- host = value;
68
- break;
69
- case '-p':
70
- case '--port':
71
- port = value;
72
- break;
73
- case '-P':
74
- case '--password':
75
- password = value;
76
- break;
77
- case '-k':
78
- case '--key':
79
- privateKey = value;
80
- break;
81
- case '-L':
82
- case '--LocalForward':
83
- forwardOut.push(value);
84
- break;
85
- case '-n':
86
- case '--ngrok':
87
- ngrokAPIKey = value;
88
- break;
89
- case '-r':
90
- case '--remote':
91
- remote_host = value;
92
- break;
93
- case '-R':
94
- case '--RemoteForward':
95
- forwardIn.push(value);
96
- break;
97
- case '-s':
98
- case '--service':
99
- service = value;
100
- break;
101
- case '-S':
102
- case '--shell':
103
- shell = true;
104
- break;
105
- case '-u':
106
- case '--username':
107
- username = value;
108
- break;
109
- default:
110
- if (i == 2) remote_host = cmd;
111
- if (i > 2) console.log('Invalid argument:', arg);
112
- }
113
- }
114
-
115
- // prevent process from exiting
116
- //process.stdin.resume();
117
-
118
- // if no config file specified attempt to load default config
119
- if (!configs) {
120
- get_default_config();
121
- }
122
-
123
- // no default config build config from args
124
- if (!remote_host) {
125
- var config = {
126
- enabled: true,
127
- username: username,
128
- password: password,
129
- host: host,
130
- port: port,
131
- proxy_ports: forwardOut,
132
- remote_ports: forwardIn,
133
- service_name: service,
134
- server_name: account,
135
- ngrok_api: ngrokAPIKey,
136
- private_key: privateKey
137
- };
138
- configs = [config];
139
- }
140
-
141
- // process each tunnel config in ssh proxy tunnel list
142
- var remote_server = null;
143
- configs.forEach(async config => {
144
-
145
- // skip tunnel if not enabled
146
- if (config.disabled) return;
147
-
148
- // if remote host specified, only select tunnel for remote host
149
- if (remote_host && remote_host !== config.hostname) return;
150
- config.server_name = config.hostname || remote_host || 'ssh_tunnel_proxy';
151
- remote_server = remote_host;
152
-
153
- // if system key storage name specified get key from system keychain
154
- if (config.server_name) {
155
- const service_name = config.service_name || 'ssh_tunnel_proxy';
156
- config.private_key = await keypairStorage.get_keypair(service_name, config.server_name);
157
- }
158
-
159
- // if private key filename specified, read private key
160
- if (privateKey) {
161
- config.private_key_filename = privateKey;
162
- }
163
- if (shell || exec.length === 0) {
164
- config.shell = true;
165
- }
166
- if (exec.length > 0) {
167
- config.exec = exec;
168
- }
169
- // create new tunnel and start connection
170
- var sshTunnelProxy = new SSHTunnelProxy();
171
- proxies.push(sshTunnelProxy);
172
- sshTunnelProxy.debug_en = debug;
173
- sshTunnelProxy.connectSSH(config);
174
- });
175
- if (remote_host && !remote_server) {
176
- console.log(`Remote host ${remote_host} not found`);
177
- }
178
-
179
- }
180
-
181
- main(process.argv);
1
+ #!/usr/bin/env node
2
+ require('.').sshcli();
package/.eslintrc.json DELETED
@@ -1,15 +0,0 @@
1
- {
2
- "env": {
3
- "browser": true,
4
- "commonjs": true,
5
- "es2021": true
6
- },
7
- "extends": "eslint:recommended",
8
- "overrides": [
9
- ],
10
- "parserOptions": {
11
- "ecmaVersion": "latest"
12
- },
13
- "rules": {
14
- }
15
- }
@@ -1,34 +0,0 @@
1
- {
2
- // Use IntelliSense to learn about possible attributes.
3
- // Hover to view descriptions of existing attributes.
4
- // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5
- "version": "0.2.0",
6
- "configurations": [
7
- {
8
- "name": "debug mocha",
9
- "request": "launch",
10
- "runtimeArgs": [
11
- "run-script",
12
- "test"
13
- ],
14
- "runtimeVersion": "19.4.0",
15
- "runtimeExecutable": "npm",
16
- "skipFiles": [
17
- "<node_internals>/**"
18
- ],
19
- "type": "node"
20
- },
21
- {
22
- "type": "node",
23
- "runtimeVersion": "19.4.0",
24
- "request": "launch",
25
- "name": "Launch node cli",
26
- "cwd": "${fileDirname}",
27
- "skipFiles": [
28
- "<node_internals>/**"
29
- ],
30
- "program": "${file}",
31
- "args":["-c","-r=nqs"]
32
- }
33
- ]
34
- }