diff --git a/bin/goldilocks.js b/bin/goldilocks.js index 70526cd..0896544 100755 --- a/bin/goldilocks.js +++ b/bin/goldilocks.js @@ -137,6 +137,8 @@ function readConfigAndRun(args) { config.addresses = addresses; config.device = { hostname: 'daplien-pod' }; + config.tunnel = args.tunnel || config.tunnel; + var PromiseA = require('bluebird'); var tcpProm, dnsProm; diff --git a/lib/app.js b/lib/app.js index caf4289..8ac1eda 100644 --- a/lib/app.js +++ b/lib/app.js @@ -15,7 +15,6 @@ module.exports = function (myDeps, conf, overrideHttp) { //var server; var serveInit; var app; - var tun; var request; /* @@ -43,7 +42,6 @@ module.exports = function (myDeps, conf, overrideHttp) { function createServeInit() { var PromiseA = require('bluebird'); - var stunnel = require('stunnel'); var OAUTH3 = require('../packages/assets/org.oauth3'); require('../packages/assets/org.oauth3/oauth3.domains.js'); require('../packages/assets/org.oauth3/oauth3.dns.js'); @@ -143,8 +141,7 @@ module.exports = function (myDeps, conf, overrideHttp) { providerUri: providerUri , session: session }); - //var crypto = require('crypto'); - //var id = crypto.createHash('sha256').update(session.token.sub).digest('hex'); + return oauth3.setProvider(providerUri).then(function () { /* return oauth3.api('domains.list').then(function (domains) { @@ -173,55 +170,13 @@ module.exports = function (myDeps, conf, overrideHttp) { } }).then(function (result) { console.log('got a token from the tunnel server?'); - console.log(result); - if (!result.tunnelUrl) { - result.tunnelUrl = ('wss://' + (new Buffer(result.jwt.split('.')[1], 'base64').toString('ascii')).aud + '/'); - } - var services = { https: { '*': 443 }, http: { '*': 80 }, smtp: { '*': 25}, smtps: { '*': 587 /*also 465/starttls*/ } /*, ssh: { '*': 22 }*/ }; - /* - console.log('blah'); - console.log(result.jwt); - console.log(result.tunnelUrl); - console.log(services); - console.log('deps.tunnel'); - console.log(deps.tunnel); - console.log('deps.tunnel.net'); - console.log(deps.tunnel.net.toString()); - console.log('deps.net'); - console.log(deps.net); - */ - var opts3 = { - token: result.jwt - , stunneld: result.tunnelUrl - // we'll provide faux networking and pipe as we please - , services: services - , net: myDeps.tunnel.net - }; - - console.log('blah 2'); - if (tun) { - console.log('balh 3'); - if (tun.append) { - tun.append(result.jwt); - } - else if (tun.end) { - tun.end(); - tun = null; - } - } - - console.log('might have tunnel?'); - if (!tun) { - console.log('connecting to the tunnel'); - tun = stunnel.connect(opts3); - conf.tun = true; - } + result.owner = session.id; + deps.tunneler.add(result); }); /* }); */ }); - //, { token: token, refresh: refresh }); } }; diff --git a/lib/goldilocks.js b/lib/goldilocks.js index ae6c552..151a55d 100644 --- a/lib/goldilocks.js +++ b/lib/goldilocks.js @@ -184,6 +184,7 @@ module.exports.create = function (deps, config) { return writer; } }; + deps.tunneler = require('./tunnel-manager').create(deps, config); var listenPromises = []; var tcpPortMap = {}; diff --git a/lib/tunnel-manager.js b/lib/tunnel-manager.js new file mode 100644 index 0000000..48be059 --- /dev/null +++ b/lib/tunnel-manager.js @@ -0,0 +1,57 @@ +'use strict'; + +module.exports.create = function (deps, config) { + var stunnel = require('stunnel'); + var activeTunnels = {}; + + function addToken(data) { + if (!data.tunnelUrl) { + var decoded; + try { + decoded = JSON.parse(new Buffer(data.jwt.split('.')[1], 'base64').toString('ascii')); + } catch (err) { + console.warn('invalid web token given to tunnel manager', err); + return; + } + if (!decoded.aud) { + console.warn('tunnel manager given token with no tunnelUrl or audience'); + return; + } + data.tunnelUrl = 'wss://' + decoded.aud + '/'; + } + + if (!activeTunnels[data.tunnelUrl]) { + console.log('creating new tunnel client for', data.tunnelUrl); + // We create the tunnel without an initial token so we can append the token and + // get the promise that should tell us more about if it worked or not. + activeTunnels[data.tunnelUrl] = stunnel.connect({ + stunneld: data.tunnelUrl + , net: deps.tunnel.net + // NOTE: the ports here aren't that important since we are providing a custom + // `net.createConnection` that doesn't actually use the port. What is important + // is that any services we are interested in are listed in this object and have + // a '*' sub-property. + , services: { + https: { '*': 443 } + , http: { '*': 80 } + , smtp: { '*': 25 } + , smtps: { '*': 587 /*also 465/starttls*/ } + , ssh: { '*': 22 } + } + }); + } + + console.log('appending token to tunnel at', data.tunnelUrl); + return activeTunnels[data.tunnelUrl].append(data.jwt); + } + + if (typeof config.tunnel === 'string') { + config.tunnel.split(',').forEach(function (jwt) { + addToken({ jwt: jwt, owner: 'config' }); + }); + } + + return { + add: addToken + }; +};