made workaround for the TLS issue that I should have ignored...
This commit is contained in:
		
							parent
							
								
									f2b05ee7af
								
							
						
					
					
						commit
						eacf2e0dbf
					
				| @ -114,7 +114,7 @@ function readConfigAndRun(args) { | |||||||
| 
 | 
 | ||||||
|   // TODO maybe move to config.state.addresses (?)
 |   // TODO maybe move to config.state.addresses (?)
 | ||||||
|   config.addresses = addresses; |   config.addresses = addresses; | ||||||
|   config.device = { hostname: 'TODO: fetch hostname from device and from ip and try to make a match' }; |   config.device = { hostname: 'daplien-pod' }; | ||||||
| 
 | 
 | ||||||
|   if (config.tcp.ports) { |   if (config.tcp.ports) { | ||||||
|     run(config); |     run(config); | ||||||
|  | |||||||
							
								
								
									
										52
									
								
								lib/app.js
									
									
									
									
									
								
							
							
						
						
									
										52
									
								
								lib/app.js
									
									
									
									
									
								
							| @ -1,6 +1,6 @@ | |||||||
| 'use strict'; | 'use strict'; | ||||||
| 
 | 
 | ||||||
| module.exports = function (deps, conf, overrideHttp) { | module.exports = function (myDeps, conf, overrideHttp) { | ||||||
|   var express = require('express'); |   var express = require('express'); | ||||||
|   //var finalhandler = require('finalhandler');
 |   //var finalhandler = require('finalhandler');
 | ||||||
|   var serveStatic = require('serve-static'); |   var serveStatic = require('serve-static'); | ||||||
| @ -100,16 +100,12 @@ module.exports = function (deps, conf, overrideHttp) { | |||||||
|       } |       } | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     return require('../packages/apis/com.daplie.goldilocks').create({ |     myDeps.PromiseA = PromiseA; | ||||||
|       PromiseA: PromiseA |     myDeps.OAUTH3 = OAUTH3; | ||||||
|     , OAUTH3: OAUTH3 |     myDeps.storage = { owners: owners }; | ||||||
|     , storage: { |     myDeps.recase = require('recase').create({}); | ||||||
|         owners: owners |     myDeps.request = request; | ||||||
|       } |     myDeps.api = { | ||||||
|     , recase: require('recase').create({}) |  | ||||||
|     , request: request |  | ||||||
|     , options: conf |  | ||||||
|     , api: { |  | ||||||
|       // TODO move loopback to oauth3.api('tunnel:loopback')
 |       // TODO move loopback to oauth3.api('tunnel:loopback')
 | ||||||
|       loopback: function (deps, session, opts2) { |       loopback: function (deps, session, opts2) { | ||||||
|         var crypto = require('crypto'); |         var crypto = require('crypto'); | ||||||
| @ -157,7 +153,7 @@ module.exports = function (deps, conf, overrideHttp) { | |||||||
|               if (!d.device) { |               if (!d.device) { | ||||||
|                 return; |                 return; | ||||||
|               } |               } | ||||||
|                 if (d.device !== deps.options.device.hostname) { |               if (d.device !== conf.device.hostname) { | ||||||
|                 return; |                 return; | ||||||
|               } |               } | ||||||
|               domainsMap[d.name] = true; |               domainsMap[d.name] = true; | ||||||
| @ -165,14 +161,14 @@ module.exports = function (deps, conf, overrideHttp) { | |||||||
|           */ |           */ | ||||||
| 
 | 
 | ||||||
|             //console.log('domains matching hostname', Object.keys(domainsMap));
 |             //console.log('domains matching hostname', Object.keys(domainsMap));
 | ||||||
|               //console.log('device', deps.options.device);
 |             //console.log('device', conf.device);
 | ||||||
|             return oauth3.api('tunnel.token', { |             return oauth3.api('tunnel.token', { | ||||||
|               data: { |               data: { | ||||||
|                 // filter to all domains that are on this device
 |                 // filter to all domains that are on this device
 | ||||||
|                 //domains: Object.keys(domainsMap)
 |                 //domains: Object.keys(domainsMap)
 | ||||||
|                 device: { |                 device: { | ||||||
|                     hostname: deps.options.device.hostname |                   hostname: conf.device.hostname | ||||||
|                   , id: deps.options.device.uid || deps.options.device.id |                 , id: conf.device.uid || conf.device.id | ||||||
|                 } |                 } | ||||||
|               } |               } | ||||||
|             }).then(function (result) { |             }).then(function (result) { | ||||||
| @ -181,15 +177,30 @@ module.exports = function (deps, conf, overrideHttp) { | |||||||
|               if (!result.tunnelUrl) { |               if (!result.tunnelUrl) { | ||||||
|                 result.tunnelUrl = ('wss://' + (new Buffer(result.jwt.split('.')[1], 'base64').toString('ascii')).aud + '/'); |                 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 = { |               var opts3 = { | ||||||
|                 token: result.jwt |                 token: result.jwt | ||||||
|               , stunneld: result.tunnelUrl |               , stunneld: result.tunnelUrl | ||||||
|                 // we'll provide faux networking and pipe as we please
 |                 // we'll provide faux networking and pipe as we please
 | ||||||
|                 , services: { https: { '*': 443 }, http: { '*': 80 }, smtp: { '*': 25}, smtps: { '*': 587 /*also 465/starttls*/ } /*, ssh: { '*': 22 }*/ } |               , services: services | ||||||
|                 , net: deps.tunnel.net || deps.net |               , net: myDeps.tunnel.net | ||||||
|               }; |               }; | ||||||
| 
 | 
 | ||||||
|  |               console.log('blah 2'); | ||||||
|               if (tun) { |               if (tun) { | ||||||
|  |                 console.log('balh 3'); | ||||||
|                 if (tun.append) { |                 if (tun.append) { | ||||||
|                   tun.append(result.jwt); |                   tun.append(result.jwt); | ||||||
|                 } |                 } | ||||||
| @ -199,7 +210,9 @@ module.exports = function (deps, conf, overrideHttp) { | |||||||
|                 } |                 } | ||||||
|               } |               } | ||||||
| 
 | 
 | ||||||
|  |               console.log('might have tunnel?'); | ||||||
|               if (!tun) { |               if (!tun) { | ||||||
|  |                 console.log('connecting to the tunnel'); | ||||||
|                 tun = stunnel.connect(opts3); |                 tun = stunnel.connect(opts3); | ||||||
|                 conf.tun = true; |                 conf.tun = true; | ||||||
|               } |               } | ||||||
| @ -210,8 +223,9 @@ module.exports = function (deps, conf, overrideHttp) { | |||||||
|         }); |         }); | ||||||
|         //, { token: token, refresh: refresh });
 |         //, { token: token, refresh: refresh });
 | ||||||
|       } |       } | ||||||
|       } |     }; | ||||||
|     }, conf); | 
 | ||||||
|  |     return require('../packages/apis/com.daplie.goldilocks').create(myDeps, conf); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   app = express(); |   app = express(); | ||||||
|  | |||||||
| @ -11,8 +11,10 @@ module.exports.create = function (deps, config) { | |||||||
|   var modules = { }; |   var modules = { }; | ||||||
|   var program = { |   var program = { | ||||||
|     tlsOptions: require('localhost.daplie.me-certificates').merge({}) |     tlsOptions: require('localhost.daplie.me-certificates').merge({}) | ||||||
|   , acmeDirectoryUrl: 'https://acme-v01.api.letsencrypt.org/directory' | //  , acmeDirectoryUrl: 'https://acme-v01.api.letsencrypt.org/directory'
 | ||||||
|   , challengeType: 'tls-sni-01' |   , acmeDirectoryUrl: 'https://acme-staging.api.letsencrypt.org/directory' | ||||||
|  | //  , challengeType: 'tls-sni-01' // won't work with a tunnel
 | ||||||
|  |   , challengeType: 'http-01' | ||||||
|   }; |   }; | ||||||
|   var secureContexts = {}; |   var secureContexts = {}; | ||||||
|   var tunnelAdminTlsOpts = {}; |   var tunnelAdminTlsOpts = {}; | ||||||
| @ -191,8 +193,8 @@ module.exports.create = function (deps, config) { | |||||||
|   function peek(conn, firstChunk, opts) { |   function peek(conn, firstChunk, opts) { | ||||||
|     // TODO port/service-based routing can do here
 |     // TODO port/service-based routing can do here
 | ||||||
| 
 | 
 | ||||||
|     // TLS
 |     // TLS byte 1 is handshake and byte 6 is client hello
 | ||||||
|     if (22 === firstChunk[0]) { |     if (0x16 === firstChunk[0]/* && 0x01 === firstChunk[5]*/) { | ||||||
|       console.log('tryTls'); |       console.log('tryTls'); | ||||||
|       opts.servername = (parseSni(firstChunk)||'').toLowerCase() || 'localhost.invalid'; |       opts.servername = (parseSni(firstChunk)||'').toLowerCase() || 'localhost.invalid'; | ||||||
|       tlsRouter.get(opts.localAddress || conn.localAddress, conn.localPort)(conn, firstChunk, opts); |       tlsRouter.get(opts.localAddress || conn.localAddress, conn.localPort)(conn, firstChunk, opts); | ||||||
| @ -205,6 +207,7 @@ module.exports.create = function (deps, config) { | |||||||
|       // even though we've already peeked, this logic is just as well to let be
 |       // even though we've already peeked, this logic is just as well to let be
 | ||||||
|       // since it works properly either way, unlike the tls socket
 |       // since it works properly either way, unlike the tls socket
 | ||||||
|       conn.once('data', function (chunk) { |       conn.once('data', function (chunk) { | ||||||
|  |         console.log('hyperPeek re-peek data', chunk.toString('utf8')); | ||||||
|         tcpRouter.get(opts.localAddress || conn.localAddress, conn.localPort)(conn, chunk, opts); |         tcpRouter.get(opts.localAddress || conn.localAddress, conn.localPort)(conn, chunk, opts); | ||||||
|       }); |       }); | ||||||
|       return; |       return; | ||||||
| @ -275,7 +278,7 @@ module.exports.create = function (deps, config) { | |||||||
|       modules.http = require('./modules/http.js').create(deps, config); |       modules.http = require('./modules/http.js').create(deps, config); | ||||||
|     } |     } | ||||||
|     modules.http.checkServername(opts.domain).then(function (stuff) { |     modules.http.checkServername(opts.domain).then(function (stuff) { | ||||||
|       if (!stuff.domains) { |       if (!stuff || !stuff.domains) { | ||||||
|         // TODO once precheck is implemented we can just let it pass if it passes, yknow?
 |         // TODO once precheck is implemented we can just let it pass if it passes, yknow?
 | ||||||
|         cb(new Error('domain is not allowed')); |         cb(new Error('domain is not allowed')); | ||||||
|         return; |         return; | ||||||
| @ -284,9 +287,10 @@ module.exports.create = function (deps, config) { | |||||||
|       complete(null, { |       complete(null, { | ||||||
|         domain: stuff.domain || stuff.domains[0] |         domain: stuff.domain || stuff.domains[0] | ||||||
|       , domains: stuff.domains |       , domains: stuff.domains | ||||||
|       , email: program.email |       , email: stuff.email || program.email | ||||||
|       , server: program.acmeDirectoryUrl |       , server: stuff.acmeDirectoryUrl || program.acmeDirectoryUrl | ||||||
|       , challengeType: program.challengeType |       , challengeType: stuff.challengeType || program.challengeType | ||||||
|  |       , challenge: stuff.challenge | ||||||
|       }); |       }); | ||||||
|       return; |       return; | ||||||
|     }, cb); |     }, cb); | ||||||
| @ -321,35 +325,76 @@ module.exports.create = function (deps, config) { | |||||||
|   deps.tunnel = deps.tunnel || {}; |   deps.tunnel = deps.tunnel || {}; | ||||||
|   deps.tunnel.net = { |   deps.tunnel.net = { | ||||||
|     createConnection: function (opts, cb) { |     createConnection: function (opts, cb) { | ||||||
|       var Duplex = require('stream').Duplex; |       console.log('[gl.tunnel] creating connection'); | ||||||
|       var myDuplex = new Duplex(); | 
 | ||||||
|  |       // here "reader" means the socket that looks like the connection being accepted
 | ||||||
|  |       // here "writer" means the remote-looking part of the socket that driving the connection
 | ||||||
|  |       var writer; | ||||||
|       var wrapOpts = {}; |       var wrapOpts = {}; | ||||||
|  |       var rawTls = opts.tls || (0x16 === opts.data[0]) && (0x01 === opts.data[5]); | ||||||
|  | 
 | ||||||
|  |       function usePair(err, reader) { | ||||||
|  |         if (err) { | ||||||
|  |           process.nextTick(function () { | ||||||
|  |             writer.emit('error', err); | ||||||
|  |           }); | ||||||
|  |           return; | ||||||
|  |         } | ||||||
| 
 | 
 | ||||||
|         // this has the normal net/tcp stuff plus our custom stuff
 |         // this has the normal net/tcp stuff plus our custom stuff
 | ||||||
|         // opts = { address, port,
 |         // opts = { address, port,
 | ||||||
|       //          hostname, servername, encrypted, data, localAddress, localPort, remoteAddress, remotePort, remoteFamily }
 |         //          hostname, servername, tls, encrypted, data, localAddress, localPort, remoteAddress, remotePort, remoteFamily }
 | ||||||
|         Object.keys(opts).forEach(function (key) { |         Object.keys(opts).forEach(function (key) { | ||||||
|           wrapOpts[key] = opts[key]; |           wrapOpts[key] = opts[key]; | ||||||
|         myDuplex[key] = opts[key]; |           try { | ||||||
|  |             reader[key] = opts[key]; | ||||||
|  |           } catch(e) { | ||||||
|  |             // can't set real socket getters, like remoteAddr
 | ||||||
|  |           } | ||||||
|         }); |         }); | ||||||
| 
 | 
 | ||||||
|         // A few more extra specialty options
 |         // A few more extra specialty options
 | ||||||
|       wrapOpts.firstChunk = opts.data; |  | ||||||
|       wrapOpts.hyperPeek = !!opts.data; |  | ||||||
|         wrapOpts.localAddress = wrapOpts.localAddress || '127.0.0.2'; // TODO use the tunnel's external address
 |         wrapOpts.localAddress = wrapOpts.localAddress || '127.0.0.2'; // TODO use the tunnel's external address
 | ||||||
|         wrapOpts.localPort = wrapOpts.localPort || 'tunnel-0'; |         wrapOpts.localPort = wrapOpts.localPort || 'tunnel-0'; | ||||||
|  |         try { | ||||||
|  |           reader._remoteAddress = wrapOpts.remoteAddress; | ||||||
|  |           reader._remotePort = wrapOpts.remotePort; | ||||||
|  |           reader._localAddress = wrapOpts.localAddress; | ||||||
|  |           reader._localPort = wrapOpts.localPort; | ||||||
|  |         } catch(e) { | ||||||
|  |         } | ||||||
| 
 | 
 | ||||||
|       netHandler(myDuplex, wrapOpts); |         netHandler(reader, wrapOpts); | ||||||
| 
 | 
 | ||||||
|         process.nextTick(function () { |         process.nextTick(function () { | ||||||
|           //opts.data = wrapOpts.data;
 |           //opts.data = wrapOpts.data;
 | ||||||
| 
 | 
 | ||||||
|           // this cb will cause the stream to emit its (actually) first data event
 |           // this cb will cause the stream to emit its (actually) first data event
 | ||||||
|           // (even though it already gave a peek into that first data chunk)
 |           // (even though it already gave a peek into that first data chunk)
 | ||||||
|  |           console.log('[tunnel] callback, data should begin to flow'); | ||||||
|           cb(); |           cb(); | ||||||
|         }); |         }); | ||||||
|  |       } | ||||||
| 
 | 
 | ||||||
|       return myDuplex; |       wrapOpts.firstChunk = opts.data; | ||||||
|  |       wrapOpts.hyperPeek = !!opts.data; | ||||||
|  |       // encrypted meaning is *terminated* TLS
 | ||||||
|  |       // tls meaning is *raw* TLS
 | ||||||
|  |       if (rawTls) { | ||||||
|  |         // TLS sockets must actually use a socket with a file descriptor
 | ||||||
|  |         // https://nodejs.org/api/net.html#net_class_net_socket
 | ||||||
|  | 
 | ||||||
|  |         writer = require('socket-pair').create(function (err, other) { | ||||||
|  |           usePair(err, other); | ||||||
|  |         }); | ||||||
|  |       } | ||||||
|  |       else { | ||||||
|  |         // stream-pair can only be used by TCP sockets, not tls
 | ||||||
|  |         writer = require('stream-pair').create(); | ||||||
|  |         usePair(null, writer.other); | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       return writer; | ||||||
|     } |     } | ||||||
|   }; |   }; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -64,6 +64,7 @@ | |||||||
|     "serve-index": "^1.7.0", |     "serve-index": "^1.7.0", | ||||||
|     "serve-static": "^1.10.0", |     "serve-static": "^1.10.0", | ||||||
|     "server-destroy": "^1.0.1", |     "server-destroy": "^1.0.1", | ||||||
|  |     "stream-pair": "^1.0.3", | ||||||
|     "stunnel": "git+https://git.daplie.com/Daplie/node-tunnel-client.git#v1" |     "stunnel": "git+https://git.daplie.com/Daplie/node-tunnel-client.git#v1" | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user