v1.0.0: initial release

This commit is contained in:
AJ ONeal 2018-08-06 12:27:33 -06:00
commit 5779325061
5 changed files with 247 additions and 0 deletions

41
LICENSE Normal file
View File

@ -0,0 +1,41 @@
Copyright 2018 AJ ONeal
This is open source software; you can redistribute it and/or modify it under the
terms of either:
a) the "MIT License"
b) the "Apache-2.0 License"
MIT License
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Apache-2.0 License Summary
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

70
README.md Normal file
View File

@ -0,0 +1,70 @@
sclient.js
==========
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.
Unwrap a TLS connection
```bash
$ sclient whatever.com:443 localhost:3000
> [listening] telebit.cloud:443 <= localhost:3000
```
Connect via Telnet
```bash
$ telnet localhost 3000
```
Connect via netcat (nc)
```bash
$ nc telnet localhost 3000
```
Install
=======
### macOS, Linux, Windows
First download and install the *current* version of [node.js](https://nodejs.org)
```bash
npm install -g sclient
```
```bash
npx sclient example.com:443 localhost:3000
```
Usage
=====
```bash
sclient <remote> <local> [-k | --insecure]
```
* remote
* must have servername (i.e. example.com)
* port is optional (default is 443)
* local
* address is optional (default is localhost)
* must have port (i.e. 3000)
Examples
========
Bridge between `telebit.cloud` and
```bash
sclient telebit.cloud 3000
```
```bash
sclient telebit.cloud:443 localhost:3000
```
```bash
sclient badtls.telebit.cloud:443 localhost:3000 -k
```

57
bin/sclient.js Executable file
View File

@ -0,0 +1,57 @@
'use strict';
var pkg = require('../package.json');
var remote = (process.argv[2]||'').split(':');
var local = (process.argv[3]||'').split(':');
var localAddress;
var localPort;
var rejectUnauthorized;
function usage() {
console.info("");
console.info("sclient.js v" + pkg.version);
console.info("Usage: sclient <servername:port> <port> [-k | --insecure]");
console.info(" ex: sclient whatever.com 3000");
console.info(" (whatever.com:443 localhost:3000)");
console.info(" ex: sclient whatever.com:4080 0.0.0.0:3000");
console.info("");
process.exit(0);
}
if (!remote[0]) {
usage();
return;
}
if (!remote[1]) {
remote[1] = 443;
}
if (!local[0]) {
usage();
return;
}
if (local[0] === String(parseInt(local[0], 10))) {
localPort = parseInt(local[0], 10);
localAddress = 'localhost';
} else {
localAddress = local[0];
localPort = parseInt(local[1], 10);
}
if (!localPort) {
usage();
return;
}
if (/^-k|--insecure$/.test(process.argv[4])) {
rejectUnauthorized = false;
}
var opts = {
remoteAddr: remote[0]
, remotePort: remote[1]
, localAddress: localAddress
, localPort: localPort
, rejectUnauthorized: rejectUnauthorized
};
require('../')(opts);

51
index.js Normal file
View File

@ -0,0 +1,51 @@
'use strict';
var net = require('net');
var tls = require('tls');
function listenForConns(opts) {
var server = net.createServer(function (c) {
var sclient = tls.connect({
servername: opts.remoteAddr, host: opts.remoteAddr, port: opts.remotePort
, rejectUnauthorized: opts.rejectUnauthorized
}, function () {
console.info('[connect] ' + sclient.localAddress.replace('::1', 'localhost') + ":" + sclient.localPort
+ " => " + opts.remoteAddr + ":" + opts.remotePort);
c.pipe(sclient);
sclient.pipe(c);
});
sclient.on('error', function (err) {
console.error('[error] (remote) ' + err.toString());
});
c.on('error', function (err) {
console.error('[error] (local) ' + err.toString());
});
});
server.on('error', function (err) {
console.error('[error] ' + err.toString());
});
server.listen({
host: opts.localAddress
, port: opts.localPort
}, function () {
console.info('[listening] ' + opts.remoteAddr + ":" + opts.remotePort
+ " <= " + opts.localAddress + ":" + opts.localPort);
});
}
function testConn(opts) {
// Test connection first
var tlsSock = tls.connect({
servername: opts.remoteAddr, host: opts.remoteAddr, port: opts.remotePort
, rejectUnauthorized: opts.rejectUnauthorized
}, function () {
tlsSock.end();
listenForConns(opts);
});
tlsSock.on('error', function (err) {
console.warn("[warn] '" + opts.remoteAddr + ":" + opts.remotePort + "' may not be accepting connections: ", err.toString(), '\n');
listenForConns(opts);
});
}
module.exports = testConn;

28
package.json Normal file
View File

@ -0,0 +1,28 @@
{
"name": "sclient",
"version": "1.0.0",
"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",
"bin": {
"sclient": "bin/sclient.js"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"files": [
"bin",
"lib"
],
"repository": {
"type": "git",
"url": "https://git.coolaj86.com/coolaj86/sclient.js.git"
},
"keywords": [
"stunnel",
"s_client",
"telebit",
"openssl"
],
"author": "AJ ONeal <coolaj86@gmail.com> (https://coolaj86.com/)",
"license": "(MIT OR Apache-2.0)"
}