WIP stunnel.js support

This commit is contained in:
AJ ONeal 2017-04-05 19:02:51 -06:00
parent fb5407c29e
commit 59721582c5
7 changed files with 114 additions and 56 deletions

View File

@ -198,7 +198,7 @@
type="button" type="button"
class="btn btn-success" class="btn btn-success"
ng-if="'oauth3-tunnel' !== vm.admin.network.iface" ng-if="'oauth3-tunnel' !== vm.admin.network.iface"
ng-click="vm.admin.network.iface = 'oauth3-tunnel'" ng-click="vm.enableTunnel()"
>Enable</button> >Enable</button>
<div ng-if="'oauth3-tunnel' === vm.admin.network.iface"> <div ng-if="'oauth3-tunnel' === vm.admin.network.iface">
<button <button
@ -212,7 +212,7 @@
type="button" type="button"
class="btn btn-link" class="btn btn-link"
ng-click="vm.admin.tunnel.advanced = false" ng-click="vm.admin.tunnel.advanced = false"
>Show Advanced Options</button> >Hide Advanced Options</button>
</div> </div>
</td> </td>
</tr> </tr>

View File

@ -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) { oauth3.checkSession().then(function (session) {
console.log('hasSession?', session); console.log('hasSession?', session);
}); });

View File

@ -136,6 +136,16 @@ function createServer(port, _delete_me_, content, opts) {
, addresses: addresses , addresses: addresses
, devices: devices.devices , devices: devices.devices
, device: devices.device , 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 server;
var insecureServer; var insecureServer;

View File

@ -39,11 +39,20 @@ module.exports = function (opts) {
function createServeInit() { function createServeInit() {
var PromiseA = require('bluebird'); 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 fs = PromiseA.promisifyAll(require('fs'));
var ownersPath = path.join(__dirname, '..', 'var', 'owners.json'); var ownersPath = path.join(__dirname, '..', 'var', 'owners.json');
var scmp = require('scmp');
return require('../packages/apis/com.daplie.caddy').create({ return require('../packages/apis/com.daplie.caddy').create({
PromiseA: PromiseA PromiseA: PromiseA
, OAUTH3: OAUTH3
, storage: { , storage: {
owners: { owners: {
all: function () { all: function () {
@ -60,6 +69,22 @@ module.exports = function (opts) {
return owner; 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) { , set: function (id, obj) {
var owners; var owners;
try { try {
@ -77,6 +102,61 @@ module.exports = function (opts) {
, recase: require('recase').create({}) , recase: require('recase').create({})
, request: PromiseA.promisify(require('request')) , request: PromiseA.promisify(require('request'))
, options: opts , 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); serveInit.init(req, res);
return; return;
} }
if ('/api/com.daplie.caddy/tunnel' === req.url) {
serveInit.tunnel(req, res);
return;
}
if ('/api/com.daplie.caddy/config' === req.url) { if ('/api/com.daplie.caddy/config' === req.url) {
serveInit.config(req, res); serveInit.config(req, res);
return; return;

View File

@ -62,6 +62,6 @@
"scmp": "git+https://github.com/freewil/scmp.git#1.x", "scmp": "git+https://github.com/freewil/scmp.git#1.x",
"serve-index": "^1.7.0", "serve-index": "^1.7.0",
"serve-static": "^1.10.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"
} }
} }

View File

@ -1,50 +1,6 @@
'use strict'; 'use strict';
module.exports.dependencies = [ 'OAUTH3', 'storage.owners', 'options.device' ]; 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) { module.exports.create = function (deps) {
var scmp = require('scmp'); var scmp = require('scmp');
var crypto = require('crypto'); var crypto = require('crypto');
@ -54,7 +10,7 @@ module.exports.create = function (deps) {
inflate: true, limit: '100kb', reviver: null, strict: true /* type, verify */ inflate: true, limit: '100kb', reviver: null, strict: true /* type, verify */
}); });
var api = module.exports.api; var api = deps.api;
/* /*
var owners; var owners;
@ -62,13 +18,6 @@ module.exports.create = function (deps) {
owners = _owners; 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) { function isAuthorized(req, res, fn) {
var auth = jwt.decode((req.headers.authorization||'').replace(/^bearer\s+/i, '')); var auth = jwt.decode((req.headers.authorization||'').replace(/^bearer\s+/i, ''));

@ -1 +1 @@
Subproject commit 8f773c9de4ee9fdb893026c1045740635308922b Subproject commit 3a805d071a4a84371b9bc674839d2511dd9aa4d3