2016-10-11 19:41:29 +00:00
|
|
|
'use strict';
|
|
|
|
|
2016-10-11 23:20:10 +00:00
|
|
|
module.exports.create = function (opts, servers) {
|
2016-10-11 19:41:29 +00:00
|
|
|
// servers = { plainserver, server }
|
2016-10-11 23:20:10 +00:00
|
|
|
var Oauth3 = require('oauth3-cli');
|
|
|
|
var Tunnel = require('daplie-tunnel').create({
|
|
|
|
Oauth3: Oauth3
|
|
|
|
, PromiseA: opts.PromiseA
|
|
|
|
, CLI: {
|
2017-01-08 00:54:56 +00:00
|
|
|
init: function (rs, ws/*, state, options*/) {
|
2016-10-11 23:20:10 +00:00
|
|
|
// noop
|
2017-01-08 00:54:56 +00:00
|
|
|
return ws;
|
2016-10-11 23:20:10 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}).Tunnel;
|
2016-10-11 19:41:29 +00:00
|
|
|
var stunnel = require('stunnel');
|
2016-10-11 23:20:10 +00:00
|
|
|
var killcount = 0;
|
2016-10-11 19:41:29 +00:00
|
|
|
|
2016-10-11 23:20:10 +00:00
|
|
|
/*
|
|
|
|
var Dup = {
|
|
|
|
write: function (chunk, encoding, cb) {
|
|
|
|
this.__my_socket.push(chunk, encoding);
|
|
|
|
cb();
|
|
|
|
}
|
|
|
|
, read: function (size) {
|
|
|
|
var x = this.__my_socket.read(size);
|
|
|
|
if (x) { this.push(x); }
|
|
|
|
}
|
|
|
|
, setTimeout: function () {
|
|
|
|
console.log('TODO implement setTimeout on Duplex');
|
|
|
|
}
|
|
|
|
};
|
2016-10-11 19:41:29 +00:00
|
|
|
|
2016-10-11 23:20:10 +00:00
|
|
|
var httpServer = require('http').createServer(function (req, res) {
|
|
|
|
console.log('req.socket.encrypted', req.socket.encrypted);
|
|
|
|
res.end('Hello, tunneled World!');
|
|
|
|
});
|
|
|
|
|
|
|
|
var tlsServer = require('tls').createServer(opts.httpsOptions, function (tlsSocket) {
|
|
|
|
console.log('tls connection');
|
|
|
|
// things get a little messed up here
|
|
|
|
httpServer.emit('connection', tlsSocket);
|
|
|
|
|
|
|
|
// try again
|
|
|
|
//servers.server.emit('connection', tlsSocket);
|
|
|
|
});
|
|
|
|
*/
|
|
|
|
|
|
|
|
process.on('SIGINT', function () {
|
|
|
|
killcount += 1;
|
|
|
|
console.log('[quit] closing http and https servers');
|
|
|
|
if (killcount >= 3) {
|
|
|
|
process.exit(1);
|
|
|
|
}
|
|
|
|
if (servers.server) {
|
|
|
|
servers.server.close();
|
|
|
|
}
|
|
|
|
if (servers.insecureServer) {
|
|
|
|
servers.insecureServer.close();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
return Tunnel.token({
|
2016-10-11 19:41:29 +00:00
|
|
|
refreshToken: opts.refreshToken
|
|
|
|
, email: opts.email
|
2017-02-02 03:00:00 +00:00
|
|
|
, domains: opts.sites.map(function (site) {
|
|
|
|
return site.name;
|
|
|
|
})
|
2016-10-19 20:09:10 +00:00
|
|
|
, device: { hostname: opts.devicename || opts.device }
|
2016-10-11 19:41:29 +00:00
|
|
|
}).then(function (result) {
|
|
|
|
// { jwt, tunnelUrl }
|
2017-02-02 03:00:00 +00:00
|
|
|
var locals = [];
|
|
|
|
opts.sites.map(function (site) {
|
|
|
|
locals.push({
|
|
|
|
protocol: 'https'
|
|
|
|
, hostname: site.name
|
|
|
|
, port: opts.port
|
|
|
|
});
|
|
|
|
locals.push({
|
|
|
|
protocol: 'http'
|
|
|
|
, hostname: site.name
|
|
|
|
, port: opts.insecurePort || opts.port
|
|
|
|
});
|
|
|
|
});
|
2016-10-11 23:20:10 +00:00
|
|
|
return stunnel.connect({
|
2016-10-11 19:41:29 +00:00
|
|
|
token: result.jwt
|
|
|
|
, stunneld: result.tunnelUrl
|
2016-10-11 23:20:10 +00:00
|
|
|
// XXX TODO BUG // this is just for testing
|
|
|
|
, insecure: /*opts.insecure*/ true
|
2017-02-02 03:00:00 +00:00
|
|
|
, locals: locals
|
2016-10-11 23:20:10 +00:00
|
|
|
// a simple passthru is proving to not be so simple
|
|
|
|
, net: require('net') /*
|
|
|
|
{
|
|
|
|
createConnection: function (info, cb) {
|
|
|
|
// data is the hello packet / first chunk
|
|
|
|
// info = { data, servername, port, host, remoteAddress: { family, address, port } }
|
|
|
|
|
|
|
|
var myDuplex = new (require('stream').Duplex)();
|
|
|
|
var myDuplex2 = new (require('stream').Duplex)();
|
|
|
|
// duplex = { write, push, end, events: [ 'readable', 'data', 'error', 'end' ] };
|
|
|
|
|
|
|
|
myDuplex2.__my_socket = myDuplex;
|
|
|
|
myDuplex.__my_socket = myDuplex2;
|
|
|
|
|
|
|
|
myDuplex2._write = Dup.write;
|
|
|
|
myDuplex2._read = Dup.read;
|
|
|
|
|
|
|
|
myDuplex._write = Dup.write;
|
|
|
|
myDuplex._read = Dup.read;
|
|
|
|
|
|
|
|
myDuplex.remoteFamily = info.remoteFamily;
|
|
|
|
myDuplex.remoteAddress = info.remoteAddress;
|
|
|
|
myDuplex.remotePort = info.remotePort;
|
|
|
|
|
|
|
|
// socket.local{Family,Address,Port}
|
|
|
|
myDuplex.localFamily = 'IPv4';
|
|
|
|
myDuplex.localAddress = '127.0.01';
|
|
|
|
myDuplex.localPort = info.port;
|
|
|
|
|
|
|
|
myDuplex.setTimeout = Dup.setTimeout;
|
|
|
|
|
|
|
|
// this doesn't seem to work so well
|
|
|
|
//servers.server.emit('connection', myDuplex);
|
|
|
|
|
|
|
|
// try a little more manual wrapping / unwrapping
|
|
|
|
var firstByte = info.data[0];
|
|
|
|
if (firstByte < 32 || firstByte >= 127) {
|
|
|
|
tlsServer.emit('connection', myDuplex);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
httpServer.emit('connection', myDuplex);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (cb) {
|
|
|
|
process.nextTick(cb);
|
|
|
|
}
|
|
|
|
|
|
|
|
return myDuplex2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//*/
|
2016-10-11 19:41:29 +00:00
|
|
|
});
|
|
|
|
});
|
|
|
|
};
|