WIP stunnel.js support
This commit is contained in:
		
							parent
							
								
									fb5407c29e
								
							
						
					
					
						commit
						59721582c5
					
				@ -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>
 | 
				
			||||||
 | 
				
			|||||||
@ -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);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
				
			|||||||
@ -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;
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										84
									
								
								lib/app.js
									
									
									
									
									
								
							
							
						
						
									
										84
									
								
								lib/app.js
									
									
									
									
									
								
							@ -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;
 | 
				
			||||||
 | 
				
			|||||||
@ -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"
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -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
 | 
				
			||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user