From 59721582c561bd8e7ff8021fb39cd3097a790bba Mon Sep 17 00:00:00 2001 From: AJ ONeal Date: Wed, 5 Apr 2017 19:02:51 -0600 Subject: [PATCH] WIP stunnel.js support --- admin/public/index.html | 4 +- admin/public/js/app.js | 15 +++++ bin/goldilocks.js | 10 +++ lib/app.js | 84 +++++++++++++++++++++++++ package.json | 2 +- packages/apis/com.daplie.caddy/index.js | 53 +--------------- packages/assets/org.oauth3 | 2 +- 7 files changed, 114 insertions(+), 56 deletions(-) diff --git a/admin/public/index.html b/admin/public/index.html index 9851f8f..816b0e7 100644 --- a/admin/public/index.html +++ b/admin/public/index.html @@ -198,7 +198,7 @@ type="button" class="btn btn-success" ng-if="'oauth3-tunnel' !== vm.admin.network.iface" - ng-click="vm.admin.network.iface = 'oauth3-tunnel'" + ng-click="vm.enableTunnel()" >Enable
+ >Hide Advanced Options
diff --git a/admin/public/js/app.js b/admin/public/js/app.js index ac543f3..3fcaade 100644 --- a/admin/public/js/app.js +++ b/admin/public/js/app.js @@ -239,6 +239,21 @@ angular.module('com.daplie.cloud', [ 'org.oauth3' ]) }); }; + vm.enableTunnel = function (/*opts*/) { + vm.admin.network.iface = 'oauth3-tunnel'; + + return oauth3.request({ + method: 'POST' + , url: 'https://' + vm.clientUri + '/api/com.daplie.caddy/tunnel' + /* + , data: { + method: 'GET' + , url: 'https://api.ipify.org?format=json' + } + */ + }); + }; + oauth3.checkSession().then(function (session) { console.log('hasSession?', session); }); diff --git a/bin/goldilocks.js b/bin/goldilocks.js index b926c3d..bbb4be3 100755 --- a/bin/goldilocks.js +++ b/bin/goldilocks.js @@ -136,6 +136,16 @@ function createServer(port, _delete_me_, content, opts) { , addresses: addresses , devices: devices.devices , device: devices.device + , net: { + createConnection: function (opts, cb) { + // opts = { host, port, data + // , /*proprietary to tunneler*/ servername, remoteAddress, remoteFamily, remotePort + // , secure (tls already terminated by a proxy) } + // // http://stackoverflow.com/questions/10348906/how-to-know-if-a-request-is-http-or-https-in-node-js + // var packerStream = require('tunnel-packer').Stream; + // TODO here we will have the tls termination (or re-forward) + } + } }; var server; var insecureServer; diff --git a/lib/app.js b/lib/app.js index 311cdce..307b9af 100644 --- a/lib/app.js +++ b/lib/app.js @@ -39,11 +39,20 @@ module.exports = function (opts) { 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'); + require('../packages/assets/org.oauth3/oauth3.tunnel.js'); + OAUTH3._hooks = require('../packages/assets/org.oauth3/oauth3.node.storage.js'); var fs = PromiseA.promisifyAll(require('fs')); var ownersPath = path.join(__dirname, '..', 'var', 'owners.json'); + var scmp = require('scmp'); + return require('../packages/apis/com.daplie.caddy').create({ PromiseA: PromiseA + , OAUTH3: OAUTH3 , storage: { owners: { all: function () { @@ -60,6 +69,22 @@ module.exports = function (opts) { return owner; })); } + , get: function (id) { + var me = this; + + return me.all().then(function (owners) { + return owners.filter(function (owner) { + return scmp(id, owner.id); + })[0]; + }); + } + , exists: function (id) { + var me = this; + + return me.get(id).then(function (owner) { + return !!owner; + }); + } , set: function (id, obj) { var owners; try { @@ -77,6 +102,61 @@ module.exports = function (opts) { , recase: require('recase').create({}) , request: PromiseA.promisify(require('request')) , options: opts + , api: { + tunnel: function (deps, session) { + var OAUTH3 = deps.OAUTH3; + var url = require('url'); + var providerUri = session.token.aud; + var urlObj = url.parse(OAUTH3.url.normalize(session.token.azp)); + var oauth3 = OAUTH3.create(urlObj, { + 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) { + var domainsMap = {}; + domains.forEach(function (d) { + if (!d.device) { + return; + } + if (d.device !== deps.options.device.hostname) { + return; + } + domainsMap[d.name] = true; + }); + + //console.log('domains matching hostname', Object.keys(domainsMap)); + //console.log('device', deps.options.device); + return oauth3.api('tunnel.token', { + data: { + // filter to all domains that are on this device + domains: Object.keys(domainsMap) + , device: { + hostname: deps.options.device.hostname + , id: deps.options.device.uid || deps.options.device.id + } + } + }).then(function (result) { + console.log('got a token from the tunnel server?'); + console.log(result); + if (!result.tunnelUrl) { + result.tunnelUrl = ('wss://' + (new Buffer(results.jwt.split('.')[1], 'base64').toString('ascii')).aud + '/'); + } + var opts = { + token: results.jwt + , stunneld: results.tunnelUrl + // we'll provide faux networking and pipe as we please + , services: { https: { '*': 443 }, http: { '*': 80 }, smtp: { '*': 25}, smtps: { '*': 587 /*also 465/starttls*/ } /*, ssh: { '*': 22 }*/ } + , net: opts.net + }; + }); + }); + }); + //, { token: token, refresh: refresh }); + } + } }); } @@ -160,6 +240,10 @@ module.exports = function (opts) { serveInit.init(req, res); return; } + if ('/api/com.daplie.caddy/tunnel' === req.url) { + serveInit.tunnel(req, res); + return; + } if ('/api/com.daplie.caddy/config' === req.url) { serveInit.config(req, res); return; diff --git a/package.json b/package.json index 02abc86..058c171 100644 --- a/package.json +++ b/package.json @@ -62,6 +62,6 @@ "scmp": "git+https://github.com/freewil/scmp.git#1.x", "serve-index": "^1.7.0", "serve-static": "^1.10.0", - "stunnel": "git+https://git.daplie.com/Daplie/node-tunnel-client.git#master" + "stunnel": "git+https://git.daplie.com/Daplie/node-tunnel-client.git#v1" } } diff --git a/packages/apis/com.daplie.caddy/index.js b/packages/apis/com.daplie.caddy/index.js index 5e6898a..1507b0d 100644 --- a/packages/apis/com.daplie.caddy/index.js +++ b/packages/apis/com.daplie.caddy/index.js @@ -1,50 +1,6 @@ 'use strict'; module.exports.dependencies = [ 'OAUTH3', 'storage.owners', 'options.device' ]; -module.exports.api = { - tunnel: function (deps, session) { - var OAUTH3 = deps.OAUTH3; - var url = require('url'); - var providerUri = session.token.aud; - var urlObj = url.parse(OAUTH3.url.normalize(session.token.azp)); - var oauth3 = OAUTH3.create(urlObj, { - 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) { - var domainsMap = {}; - domains.forEach(function (d) { - if (!d.device) { - return; - } - if (d.device !== deps.options.device.hostname) { - return; - } - domainsMap[d.name] = true; - }); - - console.log('domains matching hostname', Object.keys(domainsMap)); - console.log('device', deps.options.device); - return oauth3.api('tunnel.token', { - data: { - // filter to all domains that are on this device - domains: Object.keys(domainsMap) - , device: { - hostname: deps.options.device.hostname - , id: deps.options.device.uid || deps.options.device.id - } - } - }).then(function (result) { - console.log(result); - }); - }); - }); - //, { token: token, refresh: refresh }); - } -}; module.exports.create = function (deps) { var scmp = require('scmp'); var crypto = require('crypto'); @@ -54,7 +10,7 @@ module.exports.create = function (deps) { inflate: true, limit: '100kb', reviver: null, strict: true /* type, verify */ }); - var api = module.exports.api; + var api = deps.api; /* var owners; @@ -62,13 +18,6 @@ module.exports.create = function (deps) { owners = _owners; }); */ - deps.storage.owners.exists = function (id) { - return deps.storage.owners.all().then(function (owners) { - return owners.some(function (owner) { - return scmp(id, owner.id); - }); - }); - }; function isAuthorized(req, res, fn) { var auth = jwt.decode((req.headers.authorization||'').replace(/^bearer\s+/i, '')); diff --git a/packages/assets/org.oauth3 b/packages/assets/org.oauth3 index 8f773c9..3a805d0 160000 --- a/packages/assets/org.oauth3 +++ b/packages/assets/org.oauth3 @@ -1 +1 @@ -Subproject commit 8f773c9de4ee9fdb893026c1045740635308922b +Subproject commit 3a805d071a4a84371b9bc674839d2511dd9aa4d3