From 6fdf889b0ba30b8da403f747d4760ca475202409 Mon Sep 17 00:00:00 2001 From: AJ ONeal Date: Wed, 12 Sep 2018 13:57:16 -0600 Subject: [PATCH] v1.4.2: add undocumented staging features: vpn and --socks5 --- bin/sclient.js | 57 ++++++++++++++++++++++++++++++++++++-------------- package.json | 2 +- 2 files changed, 42 insertions(+), 17 deletions(-) diff --git a/bin/sclient.js b/bin/sclient.js index 8e35a02..dae97d7 100755 --- a/bin/sclient.js +++ b/bin/sclient.js @@ -21,19 +21,6 @@ function parseFlags(argv) { var args = argv.slice(); var flags = {}; - args.sort(function (a, b) { - if ('-' === a[0]) { - if ('-' === b[0]) { - return 0; - } - return 1; - } - if ('-' === b[0]) { - return -1; - } - return 0; - }); - args.some(function (arg, i) { if (/^-k|--?insecure$/.test(arg)) { flags.rejectUnauthorized = false; @@ -70,6 +57,32 @@ function parseFlags(argv) { return true; } }); + args.some(function (arg, i) { + if (/^--?socks5$/.test(arg)) { + flags.socks5 = args[i + 1]; + if (!flags.socks5 || /^-/.test(flags.socks5)) { + usage(); + process.exit(202); + } + args.splice(i, 2); + return true; + } + }); + + // This works for most (but not all) + // of the ssh and rsync flags - because they mostly don't have arguments + args.sort(function (a, b) { + if ('-' === a[0]) { + if ('-' === b[0]) { + return 0; + } + return 1; + } + if ('-' === b[0]) { + return -1; + } + return 0; + }); return { flags: flags @@ -109,6 +122,10 @@ function testRemote(opts) { var remote = args.shift() + ':' + opts.remotePath; args = [ remote, '-e', 'ssh ' + args.join(' ') ]; } + if (opts.socks5) { + args.push('-D'); + args.push('localhost:' + opts.socks5); + } args = args.concat(opts.args); var child = spawn(opts.command, args, { stdio: 'inherit' }); child.on('exit', function () { @@ -139,7 +156,7 @@ function main() { // Re-arrange argument order for ssh if (cmd.flags.wrapSsh) { cmd.args.splice(3, 0, 'ssh'); - } else if (-1 !== [ 'ssh', 'rsync' ].indexOf((cmd.args[2]||'').split(':')[0])) { + } else if (-1 !== [ 'ssh', 'rsync', 'vpn' ].indexOf((cmd.args[2]||'').split(':')[0])) { cmd.flags.wrapSsh = true; binParam = cmd.args.splice(2, 1); cmd.args.splice(3, 0, binParam[0]); @@ -157,7 +174,7 @@ function main() { } local = (cmd.args[3]||'').split(':'); - if (-1 !== [ 'ssh', 'rsync' ].indexOf(local[0])) { + if (-1 !== [ 'ssh', 'rsync', 'vpn' ].indexOf(local[0])) { cmd.flags.wrapSsh = true; } @@ -212,16 +229,24 @@ function main() { opts.stdin = process.stdin; opts.stdout = process.stdout; // no need for port - } else if (-1 !== [ 'ssh', 'rsync' ].indexOf(localAddress)) { + } else if (-1 !== [ 'ssh', 'rsync', 'vpn' ].indexOf(localAddress)) { cmd.flags.wrapSsh = true; opts.localAddress = 'localhost'; opts.localPort = local[1] || 0; // choose at random opts.command = localAddress; opts.args = cmd.args.slice(4); // node, sclient, ssh, addr + opts.socks5 = cmd.flags.socks5; if ('rsync' === opts.command) { opts.remotePath = opts.remotePort; opts.remotePort = 0; } + if ('vpn' === opts.command) { + opts.command = 'ssh'; + if (!opts.socks5) { + usage(); + return; + } + } if (!opts.remotePort) { opts.remotePort = cmd.flags.port || 443; } diff --git a/package.json b/package.json index b7a5f94..90a9f14 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "sclient", - "version": "1.4.1", + "version": "1.4.2", "description": "Secure Client for exposing TLS (aka SSL) secured services as plain-text connections locally. Also ideal for multiplexing a single port with multiple protocols using SNI.", "main": "index.js", "homepage": "https://telebit.cloud/sclient/",