begin cli
This commit is contained in:
		
							parent
							
								
									04e788ddb4
								
							
						
					
					
						commit
						1928278e3f
					
				
							
								
								
									
										94
									
								
								bin/holepunch.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										94
									
								
								bin/holepunch.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,94 @@
 | 
				
			|||||||
 | 
					#!/usr/bin/env node
 | 
				
			||||||
 | 
					'use strict';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var cli = require('cli');
 | 
				
			||||||
 | 
					//var mkdirp = require('mkdirp');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// TODO link with RVPN service: server, email, domains, agree-tos
 | 
				
			||||||
 | 
					// TODO txt records for browser plugin: TXT _http.example.com _https.example.com
 | 
				
			||||||
 | 
					cli.parse({
 | 
				
			||||||
 | 
					  debug: [ false, " show traces and logs", 'boolean', false ]
 | 
				
			||||||
 | 
					, 'plain-ports': [ false, " Port numbers to test with plaintext loopback. (default: 65080) (formats: <port>,<internal:external>,<internal:external1|external2>)", 'string' ]
 | 
				
			||||||
 | 
					, 'tls-ports': [ false, " Port numbers to test with tls loopback. (default: null)", 'string' ]
 | 
				
			||||||
 | 
					, 'ipify-urls': [ false, " Comma separated list of URLs to test for external ip. (default: api.ipify.org)", 'string' ]
 | 
				
			||||||
 | 
					, 'protocols': [ false, " Comma separated list of ip mapping protocols. (default: none,upnp,pmp)", 'string' ]
 | 
				
			||||||
 | 
					, 'rvpn-configs': [ false, " Comma separated list of Reverse VPN config files in the order they should be tried. (default: null)", 'string' ]
 | 
				
			||||||
 | 
					// TODO allow standalone, webroot, etc
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ignore certonly and extraneous arguments
 | 
				
			||||||
 | 
					cli.main(function(_, options) {
 | 
				
			||||||
 | 
					  console.log('');
 | 
				
			||||||
 | 
					  var args = {};
 | 
				
			||||||
 | 
					  //var hp = require('../');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function parsePorts(portstr) {
 | 
				
			||||||
 | 
					    var parts = portstr.split(':');
 | 
				
			||||||
 | 
					    var opts = {
 | 
				
			||||||
 | 
					      internal: parseInt(parts[0], 10)
 | 
				
			||||||
 | 
					    , external: (parts[1]||parts[0]).split('|').map(function (port) {
 | 
				
			||||||
 | 
					        return parseInt(port, 10);
 | 
				
			||||||
 | 
					      })
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return opts;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function exists(x) {
 | 
				
			||||||
 | 
					    return x;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  console.log('options');
 | 
				
			||||||
 | 
					  console.log(options);
 | 
				
			||||||
 | 
					  args.debug = options.debug;
 | 
				
			||||||
 | 
					  args.plainPorts = options['plain-ports'];
 | 
				
			||||||
 | 
					  args.tlsPorts = options['tls-ports'];
 | 
				
			||||||
 | 
					  args.protocols = options.protocols;
 | 
				
			||||||
 | 
					  args.ipifyUrls = options['ipify-urls'];
 | 
				
			||||||
 | 
					  args.rvpnConfigs = options['rvpn-configs'];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if ('false' === args.ipifyUrls || false === args.ipifyUrls) {
 | 
				
			||||||
 | 
					    args.ipifyUrls = [];
 | 
				
			||||||
 | 
					  } else {
 | 
				
			||||||
 | 
					    args.ipifyUrls = (args.ipifyUrls || 'api.ipify.org').split(',');
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  if ('false' === args.protocols || false === args.protocols) {
 | 
				
			||||||
 | 
					    args.protocols = [];
 | 
				
			||||||
 | 
					  } else {
 | 
				
			||||||
 | 
					    args.protocols = (args.protocols || 'none,upnp,pmp').split(',');
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  // Coerce to string. cli returns a number although we request a string.
 | 
				
			||||||
 | 
					  args.tlsPorts = (args.tlsPorts || "").toString().split(',').filter(exists).map(parsePorts);
 | 
				
			||||||
 | 
					  args.rvpnConfigs = (args.rvpnConfigs || "").toString().split(',').filter(exists);
 | 
				
			||||||
 | 
					  if ('false' === args.plainPorts || false === args.plainPorts) {
 | 
				
			||||||
 | 
					    args.plainPorts = [];
 | 
				
			||||||
 | 
					  } else {
 | 
				
			||||||
 | 
					    args.plainPorts = (args.plainPorts || "65080").toString().split(',').map(parsePorts);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  console.log('args');
 | 
				
			||||||
 | 
					  console.log(args);
 | 
				
			||||||
 | 
					  /*
 | 
				
			||||||
 | 
					  return hp.create({
 | 
				
			||||||
 | 
					    debug: args.debug
 | 
				
			||||||
 | 
					  , plainPorts: args.plainPorts
 | 
				
			||||||
 | 
					  , tlsPorts: args.plainPorts
 | 
				
			||||||
 | 
					  }).register(args, function (err, results) {
 | 
				
			||||||
 | 
					    if (err) {
 | 
				
			||||||
 | 
					      console.error('[Error]: letsencrypt-cli');
 | 
				
			||||||
 | 
					      console.error(err.stack || err);
 | 
				
			||||||
 | 
					      return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // should get back account, path to certs, pems, etc?
 | 
				
			||||||
 | 
					    console.log('\nCertificates installed at:');
 | 
				
			||||||
 | 
					    console.log(Object.keys(results).filter(function (key) {
 | 
				
			||||||
 | 
					      return /Path/.test(key);
 | 
				
			||||||
 | 
					    }).map(function (key) {
 | 
				
			||||||
 | 
					      return results[key];
 | 
				
			||||||
 | 
					    }).join('\n'));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    process.exit(0);
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					  */
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
							
								
								
									
										60
									
								
								lib/loopback-listener.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								lib/loopback-listener.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,60 @@
 | 
				
			|||||||
 | 
					'use strict';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var http = require('http');
 | 
				
			||||||
 | 
					var https = require('https');
 | 
				
			||||||
 | 
					var express = require('express');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var middleware = module.exports.middleware = require('./middleware');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					module.exports.create = function (opts) {
 | 
				
			||||||
 | 
					  var httpsOptions = opts.httpsOptions || require('localhost.daplie.com-certificates');
 | 
				
			||||||
 | 
					  var results = {
 | 
				
			||||||
 | 
					    plainServers: []
 | 
				
			||||||
 | 
					  , tlsServers: []
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					  var app = express();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  app.use('/', middleware(opts));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  (opts.plainPorts||[]).forEach(function (plainPort) {
 | 
				
			||||||
 | 
					    var plainServer = http.createServer();
 | 
				
			||||||
 | 
					    plainServer.__plainPort = plainPort;
 | 
				
			||||||
 | 
					    http.on('request', app);
 | 
				
			||||||
 | 
					    results.plainServers.push(plainServer);
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  (opts.tlsPorts||[]).forEach(function (tlsPort) {
 | 
				
			||||||
 | 
					    var tlsServer = https.createServer(httpsOptions);
 | 
				
			||||||
 | 
					    tlsServer.__tlsPort = tlsPort;
 | 
				
			||||||
 | 
					    http.on('request', app);
 | 
				
			||||||
 | 
					    results.tlsServers.push(tlsServer);
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function onListen() {
 | 
				
			||||||
 | 
					    /*jshint validthis: true*/
 | 
				
			||||||
 | 
					    var server = this;
 | 
				
			||||||
 | 
					    var addr = server.address();
 | 
				
			||||||
 | 
					    var proto = 'honorCipherOrder' in server ? 'https' : 'http';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    console.info('Listening on ' + proto + '://' + addr.address + ':' + addr.port);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  process.nextTick(function () {
 | 
				
			||||||
 | 
					    results.plainServers.forEach(function (plainServer) {
 | 
				
			||||||
 | 
					      plainServer.listen(
 | 
				
			||||||
 | 
					        plainServer.__plainPort.port
 | 
				
			||||||
 | 
					      , plainServer.__plainPort.address || '0.0.0.0'
 | 
				
			||||||
 | 
					      , onListen
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    results.tlsServers.forEach(function (tlsServer) {
 | 
				
			||||||
 | 
					      tlsServer.listen(
 | 
				
			||||||
 | 
					        tlsServer.__tlsPort.port
 | 
				
			||||||
 | 
					      , tlsServer.__tlsPort.address || '0.0.0.0'
 | 
				
			||||||
 | 
					      , onListen
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return results;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
							
								
								
									
										60
									
								
								lib/middleware.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								lib/middleware.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,60 @@
 | 
				
			|||||||
 | 
					'use strict';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var scmp = require('scmp');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function middleware(opts) {
 | 
				
			||||||
 | 
					  var key = opts.key;
 | 
				
			||||||
 | 
					  var val = opts.value;
 | 
				
			||||||
 | 
					  var vhost = opts.vhost;
 | 
				
			||||||
 | 
					  var pathnamePrefix = opts.prefix || '/.well-known/com.daplie.loopback/';
 | 
				
			||||||
 | 
					  var defaultHostname = 'loopback.daplie.invalid';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (!key) {
 | 
				
			||||||
 | 
					    opts.key = require('crypto').randomBytes(8).toString('hex');
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  if (!val) {
 | 
				
			||||||
 | 
					    opts.value = require('crypto').randomBytes(16).toString('hex');
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  if (!vhost && vhost !== false) {
 | 
				
			||||||
 | 
					    vhost = defaultHostname;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  if ('/' !== pathnamePrefix[pathnamePrefix.length - 1]) {
 | 
				
			||||||
 | 
					    pathnamePrefix += '/';
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return function (req, res, next) {
 | 
				
			||||||
 | 
					    var hostname = (req.hostname || req.headers.host || '').toLowerCase();
 | 
				
			||||||
 | 
					    var urlpath = (req.pathname || req.url);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (vhost !== false && vhost !== hostname) {
 | 
				
			||||||
 | 
					      if (opts.debug) {
 | 
				
			||||||
 | 
					        console.log("[HP] Host '" + hostname + "' failed to match '" + vhost + "'");
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      next();
 | 
				
			||||||
 | 
					      return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (0 !== urlpath.indexOf(pathnamePrefix)) {
 | 
				
			||||||
 | 
					      if (opts.debug) {
 | 
				
			||||||
 | 
					        console.log("[HP] Pathname '" + urlpath + "'"
 | 
				
			||||||
 | 
					          + " failed to match '" + pathnamePrefix + "'");
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      next();
 | 
				
			||||||
 | 
					      return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (scmp(key, urlpath.substr(pathnamePrefix.length, key.length))) {
 | 
				
			||||||
 | 
					      if (opts.debug) {
 | 
				
			||||||
 | 
					        console.log("[HP] Pathname '" + urlpath + "'"
 | 
				
			||||||
 | 
					          + " failed to match '" + pathnamePrefix + key + "'");
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      next();
 | 
				
			||||||
 | 
					      return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    res.setHeader('Content-Type', 'text/plain');
 | 
				
			||||||
 | 
					    res.end(val);
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					module.exports = middleware;
 | 
				
			||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user