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