diff --git a/bin/letsencrypt.js b/bin/letsencrypt.js index f529bb4..603592f 100755 --- a/bin/letsencrypt.js +++ b/bin/letsencrypt.js @@ -2,6 +2,7 @@ 'use strict'; var cli = require('cli'); +var mkdirp = require('mkdirp'); cli.parse({ email: [ false, " Email used for registration and recovery contact. (default: null)", 'email' ] @@ -9,8 +10,8 @@ cli.parse({ , duplicate: [ false, " Allow getting a certificate that duplicates an existing one", 'boolean', false ] , 'agree-tos': [ false, " Agree to the Let's Encrypt Subscriber Agreement", 'boolean', false ] , debug: [ false, " show traces and logs", 'boolean', false ] -, 'tls-sni-01-port': [ false, " Port number to perform tls-sni-01 challenge. Boulder in testing mode defaults to 5001. (default: 443 and 5001)", 'int' ] -, 'http-01-port': [ false, " Port used in the SimpleHttp challenge.", 'int', 80 ] +, 'tls-sni-01-port': [ false, " Port number to perform tls-sni-01 challenge. Boulder in testing mode defaults to 5001. (default: 443,5001)" ] +, 'http-01-port': [ false, " Port used in the SimpleHttp challenge. (default: 80)" ] , 'rsa-key-size': [ false, " Size (in bits) of the RSA key.", 'int', 2048 ] , 'cert-path': [ false, " Path to where new cert.pem is saved", 'string',':conf/live/:hostname/cert.pem' ] , 'fullchain-path': [ false, " Path to where new fullchain.pem (cert + chain) is saved", 'string', ':conf/live/:hostname/fullchain.pem' ] @@ -53,23 +54,53 @@ cli.main(function(_, options) { args[key] = val; }); - var LE = require('letsencrypt'); - var handlers; - - if (args.standalone) { - handlers = require('../lib/standalone'); - } - else if (args.webrootPath) { - handlers = require('../lib/webroot'); + if (args.domains) { + args.domains = args.domains.split(','); } - LE.create({}, handlers).register(args, function (err, results) { + if (args.tlsSni01Port) { + args.tlsSni01Port = args.tlsSni01Port.split(',').map(function (port) { + return parseInt(port, 10); + }); + } + + if (args.http01Port) { + args.http01Port = args.http01Port.split(',').map(function (port) { + return parseInt(port, 10); + }); + } + + mkdirp(args.configDir, function (err) { if (err) { - console.error(err.stack); + console.error("Could not create --config-dir '" + args.configDir + "':", err.code); + console.error("Try setting --config-dir '/tmp'"); return; } - // should get back account, path to certs, pems, etc? - console.log(results); + var LE = require('letsencrypt'); + var handlers; + + if (args.standalone) { + handlers = require('../lib/standalone'); + handlers.startServers(args.http01Ports || [80], args.tlsSni01Port || [443, 5001]); + } + else if (args.webrootPath) { + handlers = require('../lib/webroot'); + } + + LE.create({}, handlers).register(args, function (err, results) { + if (err) { + console.error(err.stack); + return; + } + + if (handlers.closeServers) { + handlers.closeServers(); + } + + // should get back account, path to certs, pems, etc? + console.log('results'); + console.log(results); + }); }); }); diff --git a/lib/standalone.js b/lib/standalone.js index e69de29..5f4ecb6 100644 --- a/lib/standalone.js +++ b/lib/standalone.js @@ -0,0 +1,62 @@ +'use strict'; + +var handlers = module.exports = { + // + // set,get,remove challenges + // + _challenges: {} +, setChallenge: function (args, key, value, cb) { + handlers._challenges[key] = value; + cb(null); + } +, getChallenge: function (args, key, cb) { + cb(null, handlers._challenges[key]); + } +, removeChallenge: function (args, key, cb) { + delete handlers._challenges[key]; + cb(null); + } + +, _servers: [] +, httpResponder: function (req, res) { + var acmeChallengePrefix = '/.well-known/acme-challenge/'; + + if (0 !== req.url.indexOf(acmeChallengePrefix)) { + res.end('Hello World!'); + return; + } + + var key = req.url.slice(acmeChallengePrefix.length); + + handlers.getChallenge(req.headers.host, key, function (err, val) { + res.end(val || '_'); + }); + } +, startServers: function (plainPorts, tlsPorts) { + var httpsOptions = require('localhost.daplie.com-certificates'); + var https = require('https'); + var http = require('http'); + + // tls-sni-01-port + if (handlers._servers.length) { + return; + } + + plainPorts.forEach(function (port) { + http.createServer(handlers.httpResponder).listen(port, function () { + console.info('Listening http on', this.address()); + }); + }); + tlsPorts.forEach(function (port) { + https.createServer(httpsOptions, handlers.httpResponder).listen(port, function () { + console.info('Listening https on', this.address()); + }); + }); + } +, closeServers: function () { + handlers._servers.forEach(function (server) { + server.close(); + }); + handlers._servers = []; + } +}; diff --git a/package.json b/package.json index 51be234..6e08678 100644 --- a/package.json +++ b/package.json @@ -34,6 +34,8 @@ "homepage": "https://github.com/Daplie/node-letsencrypt-cli", "dependencies": { "cli": "^0.11.1", - "homedir": "^0.6.0" + "homedir": "^0.6.0", + "localhost.daplie.com-certificates": "^1.1.2", + "mkdirp": "^0.5.1" } }