From 8a12a8676156df0bfbe637f01e406c3e6c3ced39 Mon Sep 17 00:00:00 2001 From: AJ ONeal Date: Sun, 7 Apr 2019 17:35:26 -0600 Subject: [PATCH] v3.0.4: ACME dns-01 challenge reference implementation for Greenlock v2.7+ (and v3) --- README.md | 18 +++++++++--------- index.js | 24 ++++++++++++++---------- package.json | 12 +++++------- test.js | 34 ++++++++-------------------------- 4 files changed, 36 insertions(+), 52 deletions(-) diff --git a/README.md b/README.md index 8590323..8eb74ae 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# [le-challenge-dns](https://git.coolaj86.com/coolaj86/le-challenge-dns.js) +# [greenlock-challenge-dns](https://git.coolaj86.com/coolaj86/greenlock-challenge-dns.js) | A [Root](https://rootprojects.org) Project | @@ -16,17 +16,17 @@ _acme-challenge.example.com TXT xxxxxxxxxxxxxxxx TTL 60 Other ACME Challenge Reference Implementations: -* [le-challenge-manual](https://git.coolaj86.com/coolaj86/le-challenge-manual.js.git) -* [le-challenge-http](https://git.coolaj86.com/coolaj86/le-challenge-http.js.git) -* [**le-challenge-dns**](https://git.coolaj86.com/coolaj86/le-challenge-dns.js.git) +* [greenlock-challenge-manual](https://git.coolaj86.com/coolaj86/greenlock-challenge-manual.js.git) +* [greenlock-challenge-http](https://git.coolaj86.com/coolaj86/greenlock-challenge-http.js.git) +* [**greenlock-challenge-dns**](https://git.coolaj86.com/coolaj86/greenlock-challenge-dns.js.git) ## Install ```bash -npm install --save le-challenge-dns@3.x +npm install --save greenlock-challenge-dns@3.x ``` -If you have `greenlock@v2.6` or lower, you'll need the old `le-challenge-dns@3.x` instead. +If you have `greenlock@v2.6` or lower, you'll need the old `greenlock-challenge-dns@3.x` instead. ## Usage @@ -35,9 +35,9 @@ var Greenlock = require('greenlock'); Greenlock.create({ ... -, challenges: { 'http-01': require('le-challenge-http') - , 'dns-01': require('le-challenge-dns').create({ debug: true }) - , 'tls-alpn-01': require('le-challenge-manual') +, challenges: { 'http-01': require('greenlock-challenge-http') + , 'dns-01': require('greenlock-challenge-dns').create({ debug: true }) + , 'tls-alpn-01': require('greenlock-challenge-manual') } ... }); diff --git a/index.js b/index.js index 19e94a2..f7f1e14 100644 --- a/index.js +++ b/index.js @@ -24,7 +24,7 @@ Challenge.create = function (config) { return Challenge._removeDns(opts); }; - // Optional (only really useful for http) + // Optional (only really useful for http and testing) // Called when the challenge needs to be retrieved challenger.get = function (opts) { return Challenge._getDns(opts); @@ -43,7 +43,7 @@ Challenge.create = function (config) { Challenge._setDns = function (args, cb) { // if you need per-run / per-domain options set them in approveDomains() and they'll be on 'args' here. if (!args.challenge) { - console.error("You must be using Greenlock v2.7+ to use le-challenge-dns v3+"); + console.error("You must be using Greenlock v2.7+ to use greenlock-challenge-dns v3+"); process.exit(); } var ch = args.challenge; @@ -65,7 +65,7 @@ Challenge._setDns = function (args, cb) { process.stdin.resume(); process.stdin.once('data', function () { process.stdin.pause(); - cb(null); + cb(null, null); }); }; @@ -73,10 +73,10 @@ Challenge._setDns = function (args, cb) { Challenge._removeDns = function (args) { var ch = args.challenge; console.info(""); - console.info("[ACME http-01 '" + ch.altname + "' COMPLETE]: " + ch.status); + console.info("[ACME dns-01 '" + ch.altname + "' COMPLETE]: " + ch.status); console.info("Challenge complete. You may now remove the DNS-01 challenge record:"); console.info(""); - console.info("\tTXT\t" + args.challenge.altname + "\t" + args.challenge.dnsAuthorization); + console.info("\tTXT\t" + ch.altname + "\t" + ch.dnsAuthorization); console.info(""); return null; @@ -86,13 +86,16 @@ Challenge._removeDns = function (args) { // but it's not something you would implement because the Greenlock server isn't the NameServer. Challenge._getDns = function (args) { var ch = args.challenge; + // because the way to mock a DNS challenge is weird + var altname = (ch.altname || ch.dnsHost || ch.identifier.value); + var dnsHost = (ch.dnsHost || ch.identifier.value); - if (!Challenge._getCache[ch.altname + ':' + ch.token]) { - Challenge._getCache[ch.altname + ':' + ch.token] = true; + if (ch._test || !Challenge._getCache[ch.token]) { + Challenge._getCache[ch.token] = true; console.info(""); - console.info("[ACME " + ch.type + " '" + ch.altname + "' REQUEST]: " + ch.status); + console.info("[ACME " + ch.type + " '" + altname + "' REQUEST]: " + ch.status); console.info("The '" + ch.type + "' challenge request has arrived!"); - console.info('dig TXT ' + ch.dnsHost); + console.info('dig TXT ' + dnsHost); console.info("(paste in the \"DNS Authorization\" you received a moment ago to respond)"); process.stdout.write("> "); } @@ -103,7 +106,7 @@ Challenge._getDns = function (args) { process.stdin.once('data', function (chunk) { process.stdin.pause(); - var result = chunk.toString('utf8'); + var result = chunk.toString('utf8').trim(); try { result = JSON.parse(result); } catch(e) { @@ -120,6 +123,7 @@ Challenge._getDns = function (args) { }); }); }; +Challenge._getCache = {}; function dnsChallengeToJson(ch) { return { diff --git a/package.json b/package.json index 5c08038..b526057 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { - "name": "le-challenge-dns", - "version": "3.0.3", + "name": "greenlock-challenge-dns", + "version": "3.0.4", "description": "A manual (interactive CLI) dns-based strategy for Greenlock / Let's Encrypt / ACME DNS-01 challenges", "main": "index.js", "files": [], @@ -9,7 +9,7 @@ }, "repository": { "type": "git", - "url": "git+https://git.coolaj86.com/coolaj86/le-challenge-dns.js.git" + "url": "git+https://git.coolaj86.com/coolaj86/greenlock-challenge-dns.js.git" }, "keywords": [ "Let's Encrypt", @@ -18,9 +18,7 @@ "dns-01", "wildcard", "wildcards", - "letsencrypt", "manual", - "interactive", "cli", "dns", "challenge" @@ -28,8 +26,8 @@ "author": "AJ ONeal (https://coolaj86.com/)", "license": "(MIT OR Apache-2.0)", "bugs": { - "url": "https://git.coolaj86.com/coolaj86/le-challenge-dns.js/issues" + "url": "https://git.coolaj86.com/coolaj86/greenlock-challenge-dns.js/issues" }, - "homepage": "https://git.coolaj86.com/coolaj86/le-challenge-dns.js", + "homepage": "https://git.coolaj86.com/coolaj86/greenlock-challenge-dns.js", "dependencies": {} } diff --git a/test.js b/test.js index 927df90..6bc6e23 100644 --- a/test.js +++ b/test.js @@ -1,36 +1,18 @@ 'use strict'; -/*global Promise*/ -var challenge = require('./').create({}); +var tester = require('greenlock-challenge-test'); -var opts = challenge.getOptions && challenge.getOptions() || challenge.options; +var type = 'dns-01'; +var challenger = require('greenlock-challenge-dns').create({}); -function run() { - // this will cause the prompt to appear - return new Promise(function (resolve, reject) { - challenge.set(opts, function () { - // this will cause the final completion message to appear - return Promise.resolve(challenge.remove(opts)).then(resolve).catch(reject); - }); - }); -} +// The dry-run tests can pass on, literally, 'example.com' +// but the integration tests require that you have control over the domain +var domain = '*.example.com'; -opts.challenge = { - type: 'http-01' -, identifier: { type: 'dns', value: 'example.com' } -, wildcard: false -, expires: '2012-01-01T12:00:00.000Z' -, token: 'abc123' -, thumbprint: '<>' -, keyAuthorization: 'abc123.xxxx' -, dnsHost: '_acme-challenge.example.com' -, dnsAuthorization: 'yyyy' -, altname: 'example.com' -}; -run(opts).then(function () { +tester.test(type, domain, challenger).then(function () { console.info("PASS"); }).catch(function (err) { console.error("FAIL"); console.error(err); - process.exit(18); + process.exit(20); });