[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#941126: stretch-pu: package dehydrated/0.6.2-2+deb9u1



Control: tag -1 -moreinfo

Hi there,

I finally got around to prepare this.
Hopefully I'll make in the next .-release.

On Wed, Sep 25, 2019 at 10:59:58AM +0200, Mattia Rizzolo wrote:
> It was brought to my attention that stretch's version of dehydrated has
> a few issues.  They could be resolved by adding a bunch of patches on
> top of the current versions, but I'd like to propose to instead
> backport the buster version as it is into stretch.
> 
> From my side, the buster version is much more tested by me, as well as
> somewhat "looked after" by the upstream developer (who, for example,
> contacted me a few months ago to be sure it had a few patches).

So I've done this.
Attached are two diffs, one from the version in stretch, 0.3.1-3+deb9u3,
the other from the version from buster, 0.6.2-2+deb10u1.  In fact, this
being a backport of the verison in buster I went with the version
0.6.2-2+deb10u1~deb9u1.

I retained the letsencrypt.sh compatibility binaries and script, as well
as reverted the debhelper bump and multi-arch field that I know you
frown upon.

> From what I can see, the breakages would pretty much account to the
> following:
>  * you need a new --accept-terms flag while creating a new account
>    (might break autoamted deployments who need to create a new account?)
>  * only since v0.6.0 the upstream developer made clear that users should
>    not hardcode a list of hook, and it's known many users did it, so
>    hook scripts may break due to unknown hook types
>  * this also changes the default endpoint to ACMEv2.  It should be
>    totally transparent for most users, and those who really need ACMEv1
>    (why?) would need to explicitly specify it.
To this list I need to add that apparently the DNS verification might
break if the user used a single TXT record that the several
_acme_challenge.* CNAMEd to., as now dehydrated deployes all the
challenges in one go and then asks LE to check, instead of doing one at
a time.  There is a simple workaround to this by using HOOK_CHAIN plus a
forgiving hook script.

I still consider the above "breakages" totally acceptable, as we really
ought to welcome ACMEv2 in face of those 4 trivialities above.

> If this route is accepted, I'd keep both stretch and buster updated at
> the same time, if case further changes are required in the future.

stretch is going to EOLed soon, but I'll still make sure that at least
in the last .-release they are in sync.


Can you please review the proposed changes?  I haven't yet tested them
properly, I'll do so in the next very few days, but please do have a
look.

-- 
regards,
                        Mattia Rizzolo

GPG Key: 66AE 2B4A FCCF 3F52 DA18  4D18 4B04 3FCD B944 4540      .''`.
More about me:  https://mapreri.org                             : :'  :
Launchpad user: https://launchpad.net/~mapreri                  `. `'`
Debian QA page: https://qa.debian.org/developer.php?login=mattia  `-
diffstat for dehydrated-0.3.1 dehydrated-0.6.2

 .gitignore                                                                     |    1 
 .travis.yml                                                                    |   10 
 CHANGELOG                                                                      |   59 
 LICENSE                                                                        |    2 
 README.md                                                                      |   63 
 debian/changelog                                                               |  104 
 debian/control                                                                 |   15 
 debian/copyright                                                               |    6 
 debian/dehydrated-apache2.lintian-overrides                                    |    2 
 debian/dehydrated.manpages                                                     |    2 
 debian/gbp.conf                                                                |    2 
 debian/generate-manpage                                                        |   29 
 debian/patches/Fixes-559-when-HTTP-2-is-used-header-names-are-lower-case.patch |   34 
 debian/patches/Make-the-upgrade-path-from-ACCOUNT_KEY-_JSON-to-the-new-A.patch |   45 
 debian/patches/Only-match-Replace-Nonce-header-at-beginning-of-line.patch      |   24 
 debian/patches/Update-the-default-License-Subscriber-Agreement-URL.patch       |   39 
 debian/patches/document-DOMAINS_D-parameter-in-example-config-fixes-575-.patch |   25 
 debian/patches/fixed-a-bug-that-resulted-in-a-deleted-domains.txt-when-u.patch |   22 
 debian/patches/fixed-fetching-of-account-information-fixes-652-fixes-647.patch |   30 
 debian/patches/follow-location-on-http-get-requests.patch                      |   27 
 debian/patches/implement-POST-as-GET-closes-626.patch                          |   43 
 debian/patches/release-0.6.4-fixed-account-id-handling-again.patch             |   57 
 debian/patches/release-0.6.5-fixed-apiv1-compatibility.patch                   |   45 
 debian/patches/series                                                          |   15 
 debian/patches/tiny-documentation-fix-per-certificate-config-can-overrid.patch |   21 
 debian/patches/use-temporary-file-for-DER-PEM-conversion-fixes-279.patch       |   50 
 debian/rules                                                                   |    8 
 dehydrated                                                                     | 1098 +++++++---
 docs/dns-verification.md                                                       |   17 
 docs/domains_txt.md                                                            |   67 
 docs/examples/config                                                           |   39 
 docs/examples/domains.txt                                                      |   28 
 docs/examples/hook.sh                                                          |  123 +
 docs/hook_chain.md                                                             |    1 
 docs/logo.jpg                                                                  |binary
 docs/man/dehydrated.1                                                          |  155 +
 docs/per-certificate-config.md                                                 |    7 
 docs/staging.md                                                                |    5 
 docs/troubleshooting.md                                                        |   12 
 docs/wellknown.md                                                              |   18 
 test.sh                                                                        |  221 --
 41 files changed, 1822 insertions(+), 749 deletions(-)

diff -Nru dehydrated-0.3.1/CHANGELOG dehydrated-0.6.2/CHANGELOG
--- dehydrated-0.3.1/CHANGELOG	2016-09-13 20:00:43.000000000 +0200
+++ dehydrated-0.6.2/CHANGELOG	2018-04-25 23:22:40.000000000 +0200
@@ -1,9 +1,64 @@
 # Change Log
 This file contains a log of major changes in dehydrated
 
-## [x.x.x] - xxxx-xx-xx
+## [0.6.2] - 2018-04-25
+## Added
+- New deploy_ocsp hook
+- Allow account registration with custom key
+
+## Changed
+- Don't walk certificate chain for ACMEv2 (certificate contains chain by default)
+- Improved documentation on wildcards
+
+## Fixes
+- Added workaround for compatibility with filesystem ACLs
+- Close unwanted external file-descriptors
+- Fixed JSON parsing on force-renewal
+- Fixed cleanup of challenge files/dns-entries on validation errors
+- A few more minor fixes
+
+## [0.6.1] - 2018-03-13
 ## Changed
-- ...
+- Use new ACME v2 endpoint by default
+
+## [0.6.0] - 2018-03-11
+## Changed
+- Challenge validation loop has been modified to loop over authorization identifiers instead of altnames (ACMEv2 + wildcard support)
+- Removed LICENSE parameter from config (terms of service is now acquired directly from the CA directory)
+
+## Added
+- Support for ACME v02 (including wildcard certificates!)
+- New hook: generate_csr (see example hook script for more information)
+- Calling random hook on startup to make it clear to hook script authors that unknown hooks should just be ignored...
+
+## [0.5.0] - 2018-01-13
+## Changed
+- Certificate chain is now cached (CHAINCACHE)
+- OpenSSL binary path is now configurable (OPENSSL)
+- Cleanup now also moves revoked certificates
+
+## Added
+- New feature for updating contact information (--account)
+- Allow automatic cleanup on exit (AUTO_CLEANUP)
+- Initial support for fetching OCSP status to be used for OCSP stapling (OCSP_FETCH)
+- Certificates can now have aliases to create multiple certificates with identical set of domains (see --alias and domains.txt documentation)
+- Allow dehydrated to run as specified user (/group)
+
+## [0.4.0] - 2017-02-05
+## Changed
+- dehydrated now asks you to read and accept the CAs terms of service before creating an account
+- Skip challenges for already validated domains
+- Removed need for some special commands (BusyBox compatibility)
+- Exported a few more variables for use in hook-scripts
+- fullchain.pem now actually contains the full chain instead of just the certificate with an intermediate cert
+
+## Added
+- Added private-key rollover functionality
+- Added `--lock-suffix` option for allowing parallel execution
+- Added `invalid_challenge` hook
+- Added `request_failure` hook
+- Added `exit_hook` hook
+- Added standalone `register` command
 
 ## [0.3.1] - 2016-09-13
 ## Changed
diff -Nru dehydrated-0.3.1/debian/changelog dehydrated-0.6.2/debian/changelog
--- dehydrated-0.3.1/debian/changelog	2019-11-05 14:20:34.000000000 +0100
+++ dehydrated-0.6.2/debian/changelog	2020-01-18 15:13:17.000000000 +0100
@@ -1,23 +1,109 @@
-dehydrated (0.3.1-3+deb9u3) stretch; urgency=medium
+dehydrated (0.6.2-2+deb10u1~deb9u1) UNRELEASED; urgency=medium
 
-  * Add patch from upstream to fix cert renewal when using HTTP/2.
-    Closes: #941414
+  * Backport 0.6.2-2 from buster into stretch.
+    + In the process, retain the letsencrypt.sh compatibility binaries.
+    + Also, revert debhelper compat bump and Multi-Arch field.
 
- -- Mattia Rizzolo <mattia@debian.org>  Tue, 05 Nov 2019 14:20:34 +0100
+ -- Mattia Rizzolo <mattia@debian.org>  Sat, 18 Jan 2020 15:13:17 +0100
 
-dehydrated (0.3.1-3+deb9u2) stretch; urgency=medium
+dehydrated (0.6.2-2+deb10u1) buster; urgency=medium
+
+  * Add three more patches from upstream.
+    Fixing the following bug:
+     + Fixed fetching of account information.
+     + Followup fixes for account ID handling, and APIv1 compatibility.
+
+ -- Mattia Rizzolo <mattia@debian.org>  Fri, 19 Jul 2019 14:59:11 +0200
+
+dehydrated (0.6.2-2) unstable; urgency=medium
+
+  * Add a number of patches from upstream.
+    Fixing the following bugs:
+     + HTTP/2 support, where header names are lowercase
+     + Avoid over matching, checking for the Replay-Nonce header only at BOL
+     + A bug causing deletion of domains.txt when incorrect parameters are used
+     + Document the DOMAINS_D config option
+     + Impoent POST-as-GET, for the upcoming change in LE's API
+     + Document PRIVATE_KEY_ROLLOVER per-cert config option
+  * d/control: bump Standards-Version to 4.3.0, no changes needed.
+
+ -- Mattia Rizzolo <mattia@debian.org>  Mon, 11 Mar 2019 16:25:53 +0100
+
+dehydrated (0.6.2-1) unstable; urgency=medium
+
+  * New upstream release 0.6.2.
+  * Remove all patches - applied upstream.
+  * d/control: update Homepage field.
+
+ -- Mattia Rizzolo <mattia@debian.org>  Tue, 08 May 2018 12:14:45 +0200
+
+dehydrated (0.6.1-2) unstable; urgency=medium
+
+  * Add patch from upstream to not duplicate the intermediate cert in the
+    fullchain.pem.  Closes: #896697
+  * d/control:
+    + Bump Standards-Version to 4.1.4, no changes needed.
+    + Update maintainer address to use the tracker.debian.org team.
+
+ -- Mattia Rizzolo <mattia@debian.org>  Mon, 23 Apr 2018 20:31:36 +0200
+
+dehydrated (0.6.1-1) unstable; urgency=low
+
+  * New upstream release 0.6.1.
+    Note: this release changes the default CA to use the ACMEv2 endpoint of
+    Let's Encrypt (previously it used the ACMEv1 endpoint).
+    Notable news of this realease is the support for wildcard certificates.
+  * d/patches:
+    - Remove patch present in the new upstream release.
+    - Add patch from upstream to have the example config reflect reality.
+  * d/copyright: Update.
+  * d/dehydrated.manapges: Update the path.
+  * Add a closes: to the previous changelog entry.
+
+ -- Mattia Rizzolo <mattia@debian.org>  Wed, 14 Mar 2018 03:11:53 +0100
+
+dehydrated (0.5.0-2) unstable; urgency=medium
 
   * Add patch from upstream to follow redirects on HTTP GET.
     This fixes an error when creating the fullchain.pem after the LE API
     introduced a new redirect.  Closes: #892723
 
- -- Mattia Rizzolo <mattia@debian.org>  Mon, 12 Mar 2018 11:48:10 +0100
+ -- Mattia Rizzolo <mattia@debian.org>  Sun, 11 Mar 2018 19:25:13 +0100
 
-dehydrated (0.3.1-3+deb9u1) stretch; urgency=medium
+dehydrated (0.5.0-1) unstable; urgency=medium
 
-  * Update the default License Subscriber Agreement URL.  Closes: #881974
+  * New upstream release 0.5.0.
+  * d/control:
+    + Mark dehydrated as Multi-Arch:foreign.
+    + Bump Standards-Version to 4.1.3, no changes needed.
+    + Set Rules-Requires-Root:no.
+    + Change Vcs-* fields to point to Salsa.
+    + Change homepage to https://dehydrated.de.
+  * d/rules:
+    + Remove simple get-orig-source target just calling uscan.
+    + Avoid gz-compressing the example config file.
+  * d/copyright: update.
+  * Bump debhelper compat version to 11.
+  * Drop lintian override for a false positive now fixed in lintian.
+  * Ship the new manpage from upstream instead of our auto-generated one.
+
+ -- Mattia Rizzolo <mattia@debian.org>  Mon, 22 Jan 2018 22:12:23 +0100
+
+dehydrated (0.4.0-2) unstable; urgency=medium
+
+  * Upload to unstable.
+
+ -- Mattia Rizzolo <mattia@debian.org>  Sat, 17 Jun 2017 15:33:47 +0200
+
+dehydrated (0.4.0-1) experimental; urgency=medium
+
+  * Import new upstream release 0.4.0.
+  * Drop all Debian patches.
+    They are either applied upstream, or related to some past migration
+    we're not dropping support for.
+  * Drop letsencrypt.sh and letsencrypt.sh-apache2 transitional packages.
 
- -- Mattia Rizzolo <mattia@debian.org>  Sat, 18 Nov 2017 14:00:07 +0100
+ -- Mattia Rizzolo <mattia@debian.org>  Sun, 12 Feb 2017 09:17:31 +0100
 
 dehydrated (0.3.1-3) unstable; urgency=medium
 
diff -Nru dehydrated-0.3.1/debian/control dehydrated-0.6.2/debian/control
--- dehydrated-0.3.1/debian/control	2019-11-05 14:12:17.000000000 +0100
+++ dehydrated-0.6.2/debian/control	2020-01-18 15:13:17.000000000 +0100
@@ -1,19 +1,20 @@
 Source: dehydrated
-Maintainer: Debian Let's Encrypt <letsencrypt-devel@lists.alioth.debian.org>
+Section: misc
+Priority: optional
+Maintainer: Debian Let's Encrypt Team <team+letsencrypt@tracker.debian.org>
 Uploaders:
  Daniel Beyer <dabe@deb.ymc.ch>,
  Mattia Rizzolo <mattia@debian.org>,
-Section: misc
-Priority: optional
-Standards-Version: 3.9.8
 Build-Depends:
  apache2-dev,
  debhelper (>= 10),
  dh-apache2,
  dh-exec,
-Vcs-Browser: https://anonscm.debian.org/git/letsencrypt/dehydrated.git
-Vcs-Git: https://anonscm.debian.org/git/letsencrypt/dehydrated.git
-Homepage: https://github.com/lukas2511/dehydrated
+Standards-Version: 4.3.0
+Rules-Requires-Root: no
+Vcs-Git: https://salsa.debian.org/letsencrypt-team/dehydrated.git
+Vcs-Browser: https://salsa.debian.org/letsencrypt-team/dehydrated
+Homepage: https://dehydrated.io
 
 Package: dehydrated
 Architecture: all
diff -Nru dehydrated-0.3.1/debian/copyright dehydrated-0.6.2/debian/copyright
--- dehydrated-0.3.1/debian/copyright	2019-11-05 14:12:17.000000000 +0100
+++ dehydrated-0.6.2/debian/copyright	2020-01-18 15:13:17.000000000 +0100
@@ -1,15 +1,15 @@
-Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
+Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0
 Upstream-Name: dehydrated
 Upstream-Contact: Lukas Schauer <lukas.schauer@googlemail.com>
 Source: https://github.com/lukas2511/dehydrated
 
 Files: *
-Copyright: 2015-2016 Lukas Schauer
+Copyright: 2015-2018 Lukas Schauer
 License: Expat
 
 Files: debian/*
 Copyright: 2016 Daniel Beyer <dabe@deb.ymc.ch>
-           2016 Mattia Rizzolo <mattia@debian.org>
+           2016-2018 Mattia Rizzolo <mattia@debian.org>
 License: Expat
 
 License: Expat
diff -Nru dehydrated-0.3.1/debian/dehydrated-apache2.lintian-overrides dehydrated-0.6.2/debian/dehydrated-apache2.lintian-overrides
--- dehydrated-0.3.1/debian/dehydrated-apache2.lintian-overrides	2019-11-05 14:12:17.000000000 +0100
+++ dehydrated-0.6.2/debian/dehydrated-apache2.lintian-overrides	2020-01-18 15:13:17.000000000 +0100
@@ -2,5 +2,3 @@
 # really need to be named after the actual binary that ships it.
 # (and of course there is no risk of name collisions)
 non-standard-apache2-configuration-name
-# These are in branches checking for the version
-apache2-deprecated-auth-config
diff -Nru dehydrated-0.3.1/debian/dehydrated.manpages dehydrated-0.6.2/debian/dehydrated.manpages
--- dehydrated-0.3.1/debian/dehydrated.manpages	2019-11-05 14:12:17.000000000 +0100
+++ dehydrated-0.6.2/debian/dehydrated.manpages	2020-01-18 15:13:17.000000000 +0100
@@ -1 +1 @@
-debian/dehydrated.1
+docs/man/dehydrated.1
diff -Nru dehydrated-0.3.1/debian/gbp.conf dehydrated-0.6.2/debian/gbp.conf
--- dehydrated-0.3.1/debian/gbp.conf	2019-11-05 14:12:17.000000000 +0100
+++ dehydrated-0.6.2/debian/gbp.conf	2020-01-18 15:13:17.000000000 +0100
@@ -1,6 +1,6 @@
 [DEFAULT]
 upstream-branch = upstream/master
-debian-branch = debian/stretch
+debian-branch = debian/stretch-updated
 upstream-tag = v%(version)s
 pristine-tar = True
 pristine-tar-commit = True
diff -Nru dehydrated-0.3.1/debian/generate-manpage dehydrated-0.6.2/debian/generate-manpage
--- dehydrated-0.3.1/debian/generate-manpage	2019-11-05 14:12:17.000000000 +0100
+++ dehydrated-0.6.2/debian/generate-manpage	1970-01-01 01:00:00.000000000 +0100
@@ -1,29 +0,0 @@
-#!/bin/bash
-set -e
-set -o pipefail
-
-date_string="$(date -u +%F -d "$(dpkg-parsechangelog -S Date)")"
-version_string="$(dpkg-parsechangelog -S Version | cut -d- -f-1)"
-
-# Fake presence of curl for ./dehydrated
-curl(){ return 0; } && export -f curl
-
-# Provide manpage header and intro
-cat <<EOF
-.TH "dehydrated" "1" "$date_string" "$version_string" "The dehydrated ACME client"
-.SH NAME
-dehydrated - ACME client implemented in Bash
-.SH DESCRIPTION
-.B dehydrated
-is a client for signing certificates with an ACME-server implemented as a
-relatively simple Bash script. It can be used with the Let’s Encrypt
-certificate authority (letsencrypt.org).
-.SH OPTIONS
-EOF
-
-# Provide usage information
-./dehydrated --help | sed -r 's|\./(dehydrated)|\1|'
-
-# Add a final newline
-echo
-
diff -Nru dehydrated-0.3.1/debian/patches/document-DOMAINS_D-parameter-in-example-config-fixes-575-.patch dehydrated-0.6.2/debian/patches/document-DOMAINS_D-parameter-in-example-config-fixes-575-.patch
--- dehydrated-0.3.1/debian/patches/document-DOMAINS_D-parameter-in-example-config-fixes-575-.patch	1970-01-01 01:00:00.000000000 +0100
+++ dehydrated-0.6.2/debian/patches/document-DOMAINS_D-parameter-in-example-config-fixes-575-.patch	2020-01-18 15:13:17.000000000 +0100
@@ -0,0 +1,25 @@
+From: Lukas Schauer <lukas@schauer.so>
+Date: Sat, 20 Oct 2018 13:05:20 +0200
+Subject: document DOMAINS_D parameter in example config (fixes #575,
+ closes #582)
+
+---
+ docs/examples/config | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/docs/examples/config b/docs/examples/config
+index 665704d..c1f9276 100644
+--- a/docs/examples/config
++++ b/docs/examples/config
+@@ -40,6 +40,11 @@
+ # default: <unset>
+ #CONFIG_D=
+ 
++# Directory for per-domain configuration files.
++# If not set, per-domain configurations are sourced from each certificates output directory.
++# default: <unset>
++#DOMAINS_D=
++
+ # Base directory for account key, generated certificates and list of domains (default: $SCRIPTDIR -- uses config directory if undefined)
+ #BASEDIR=$SCRIPTDIR
+ 
diff -Nru dehydrated-0.3.1/debian/patches/fixed-a-bug-that-resulted-in-a-deleted-domains.txt-when-u.patch dehydrated-0.6.2/debian/patches/fixed-a-bug-that-resulted-in-a-deleted-domains.txt-when-u.patch
--- dehydrated-0.3.1/debian/patches/fixed-a-bug-that-resulted-in-a-deleted-domains.txt-when-u.patch	1970-01-01 01:00:00.000000000 +0100
+++ dehydrated-0.6.2/debian/patches/fixed-a-bug-that-resulted-in-a-deleted-domains.txt-when-u.patch	2020-01-18 15:13:17.000000000 +0100
@@ -0,0 +1,22 @@
+From: Lukas Schauer <lukas@schauer.so>
+Date: Sat, 20 Oct 2018 12:27:23 +0200
+Subject: fixed a bug that resulted in a deleted domains.txt when using
+ incorrect parameters in combination with signcsr (fixes #597)
+
+---
+ dehydrated | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/dehydrated b/dehydrated
+index c27706a..2cefc6d 100755
+--- a/dehydrated
++++ b/dehydrated
+@@ -557,7 +557,7 @@ http_request() {
+       rm -f "${tempheaders}"
+ 
+       # remove temporary domains.txt file if used
+-      [[ -n "${PARAM_DOMAIN:-}" && -n "${DOMAINS_TXT:-}" ]] && rm "${DOMAINS_TXT}"
++      [[ "${COMMAND:-}" = "sign_domains" && -n "${PARAM_DOMAIN:-}" && -n "${DOMAINS_TXT:-}" ]] && rm "${DOMAINS_TXT}"
+       exit 1
+     fi
+   fi
diff -Nru dehydrated-0.3.1/debian/patches/fixed-fetching-of-account-information-fixes-652-fixes-647.patch dehydrated-0.6.2/debian/patches/fixed-fetching-of-account-information-fixes-652-fixes-647.patch
--- dehydrated-0.3.1/debian/patches/fixed-fetching-of-account-information-fixes-652-fixes-647.patch	1970-01-01 01:00:00.000000000 +0100
+++ dehydrated-0.6.2/debian/patches/fixed-fetching-of-account-information-fixes-652-fixes-647.patch	2020-01-18 15:13:17.000000000 +0100
@@ -0,0 +1,30 @@
+From: Lukas Schauer <lukas@schauer.so>
+Date: Tue, 25 Jun 2019 12:19:20 +0200
+Subject: fixed fetching of account information (fixes #652, fixes #647,
+ fixes #650, closes #648)
+
+---
+ dehydrated | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/dehydrated b/dehydrated
+index 69057e7..a29910b 100755
+--- a/dehydrated
++++ b/dehydrated
+@@ -396,7 +396,16 @@ init_system() {
+ 
+   # Read account information or request from CA if missing
+   if [[ -e "${ACCOUNT_KEY_JSON}" ]]; then
++    if [[ -z "$(cat "${ACCOUNT_KEY_JSON}" | get_json_int_value id)" ]]; then
++      echo "+ Fetching account information..."
++      ACCOUNT_URL="$(signed_request "${CA_NEW_ACCOUNT}" '{"onlyReturnExisting": true}' 4>&1 | grep -i ^Location: | awk '{print $2}' | tr -d '\r\n')"
++      ACCOUNT_INFO="$(signed_request "${ACCOUNT_URL}" '{}')"
++      echo "${ACCOUNT_INFO}" > "${ACCOUNT_KEY_JSON}"
++    fi
+     ACCOUNT_ID="$(cat "${ACCOUNT_KEY_JSON}" | get_json_int_value id)"
++    if [[ -z "${ACCOUNT_ID}" ]]; then
++      _exiterr "Unknown error on fetching account information"
++    fi
+     if [[ ${API} -eq 1 ]]; then
+       ACCOUNT_URL="${CA_REG}/${ACCOUNT_ID}"
+     else
diff -Nru dehydrated-0.3.1/debian/patches/Fixes-559-when-HTTP-2-is-used-header-names-are-lower-case.patch dehydrated-0.6.2/debian/patches/Fixes-559-when-HTTP-2-is-used-header-names-are-lower-case.patch
--- dehydrated-0.3.1/debian/patches/Fixes-559-when-HTTP-2-is-used-header-names-are-lower-case.patch	2019-11-05 14:17:57.000000000 +0100
+++ dehydrated-0.6.2/debian/patches/Fixes-559-when-HTTP-2-is-used-header-names-are-lower-case.patch	2020-01-18 15:13:17.000000000 +0100
@@ -1,26 +1,34 @@
-From: Florent <>
+From: Florent <fake@mail>
 Date: Wed, 9 May 2018 19:29:21 +0200
 Subject: Fixes #559 : when HTTP/2 is used,
  header names are lower case. So adding ignore case option (-i) to grep's.
 
-Acked-By: Mattia Rizzolo <mattia@debian.org>
-Bug: https://github.com/lukas2511/dehydrated/issues/559
-Bug-Debian: https://bugs.debian.org/941414
-Origin: upstream, e4e712c03ad70bd5100af1333c2801f4b5baa89a
 ---
- dehydrated | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
+ dehydrated | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
 
 diff --git a/dehydrated b/dehydrated
-index a0dbf04..c17b0d0 100755
+index adc3dca..ba0f5a0 100755
 --- a/dehydrated
 +++ b/dehydrated
-@@ -381,7 +381,7 @@ signed_request() {
-   payload64="$(printf '%s' "${2}" | urlbase64)"
+@@ -407,7 +407,7 @@ init_system() {
+     if [[ ${API} -eq 1 ]]; then
+       _exiterr "This is not implemented for ACMEv1! Consider switching to ACMEv2 :)"
+     else
+-      ACCOUNT_URL="$(signed_request "${CA_NEW_ACCOUNT}" '{"onlyReturnExisting": true}' 4>&1 | grep ^Location: | awk '{print $2}' | tr -d '\r\n')"
++      ACCOUNT_URL="$(signed_request "${CA_NEW_ACCOUNT}" '{"onlyReturnExisting": true}' 4>&1 | grep -i ^Location: | awk '{print $2}' | tr -d '\r\n')"
+       ACCOUNT_INFO="$(signed_request "${ACCOUNT_URL}" '{}')"
+     fi
+     ACCOUNT_ID="${ACCOUNT_URL##*/}"
+@@ -577,9 +577,9 @@ signed_request() {
  
    # Retrieve nonce from acme-server
--  nonce="$(http_request head "${CA}" | grep Replay-Nonce: | awk -F ': ' '{print $2}' | tr -d '\n\r')"
-+  nonce="$(http_request head "${CA}" | grep -i Replay-Nonce: | awk -F ': ' '{print $2}' | tr -d '\n\r')"
+   if [[ ${API} -eq 1 ]]; then
+-    nonce="$(http_request head "${CA}" | grep Replay-Nonce: | awk -F ': ' '{print $2}' | tr -d '\n\r')"
++    nonce="$(http_request head "${CA}" | grep -i Replay-Nonce: | awk -F ': ' '{print $2}' | tr -d '\n\r')"
+   else
+-    nonce="$(http_request head "${CA_NEW_NONCE}" | grep Replay-Nonce: | awk -F ': ' '{print $2}' | tr -d '\n\r')"
++    nonce="$(http_request head "${CA_NEW_NONCE}" | grep -i Replay-Nonce: | awk -F ': ' '{print $2}' | tr -d '\n\r')"
+   fi
  
    # Build header with just our public key and algorithm information
-   header='{"alg": "RS256", "jwk": {"e": "'"${pubExponent64}"'", "kty": "RSA", "n": "'"${pubMod64}"'"}}'
diff -Nru dehydrated-0.3.1/debian/patches/follow-location-on-http-get-requests.patch dehydrated-0.6.2/debian/patches/follow-location-on-http-get-requests.patch
--- dehydrated-0.3.1/debian/patches/follow-location-on-http-get-requests.patch	2019-11-05 14:17:57.000000000 +0100
+++ dehydrated-0.6.2/debian/patches/follow-location-on-http-get-requests.patch	1970-01-01 01:00:00.000000000 +0100
@@ -1,27 +0,0 @@
-From: Lukas Schauer <lukas@schauer.so>
-Date: Sat, 3 Feb 2018 22:03:58 +0100
-Subject: follow location on http get-requests
-
-For more info:
-https://community.letsencrypt.org/t/dehydrated-caused-rate-limits-to-be-reached/52477
-
-Ogigin: upstream, https://github.com/lukas2511/dehydrated/commit/7a0e71c6c2ccc6e98abca5ea1c7de28053e90c02
-Bug-Debian: https://bugs.debian.org/892723
-Signed-off-by: Mattia Rizzolo <mattia@debian.org>
----
- dehydrated | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/dehydrated b/dehydrated
-index 882c6bd..a0dbf04 100755
---- a/dehydrated
-+++ b/dehydrated
-@@ -337,7 +337,7 @@ http_request() {
-     statuscode="$(curl ${ip_version:-} -s -w "%{http_code}" -o "${tempcont}" "${2}" -I)"
-     curlret="${?}"
-   elif [[ "${1}" = "get" ]]; then
--    statuscode="$(curl ${ip_version:-} -s -w "%{http_code}" -o "${tempcont}" "${2}")"
-+    statuscode="$(curl ${ip_version:-} -L -s -w "%{http_code}" -o "${tempcont}" "${2}")"
-     curlret="${?}"
-   elif [[ "${1}" = "post" ]]; then
-     statuscode="$(curl ${ip_version:-} -s -w "%{http_code}" -o "${tempcont}" "${2}" -d "${3}")"
diff -Nru dehydrated-0.3.1/debian/patches/implement-POST-as-GET-closes-626.patch dehydrated-0.6.2/debian/patches/implement-POST-as-GET-closes-626.patch
--- dehydrated-0.3.1/debian/patches/implement-POST-as-GET-closes-626.patch	1970-01-01 01:00:00.000000000 +0100
+++ dehydrated-0.6.2/debian/patches/implement-POST-as-GET-closes-626.patch	2020-01-18 15:13:17.000000000 +0100
@@ -0,0 +1,43 @@
+From: Lukas Schauer <lukas@schauer.so>
+Date: Sun, 3 Mar 2019 19:58:04 +0100
+Subject: implement POST-as-GET (closes #626)
+
+---
+ dehydrated | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/dehydrated b/dehydrated
+index 2cefc6d..69057e7 100755
+--- a/dehydrated
++++ b/dehydrated
+@@ -705,7 +705,7 @@ sign_csr() {
+   for authorization in ${authorizations[*]}; do
+     if [[ "${API}" -eq 2 ]]; then
+       # Receive authorization ($authorization is authz uri)
+-      response="$(http_request get "$(echo "${authorization}" | _sed -e 's/\"(.*)".*/\1/')" | clean_json)"
++      response="$(signed_request "$(echo "${authorization}" | _sed -e 's/\"(.*)".*/\1/')" "" | clean_json)"
+       identifier="$(echo "${response}" | get_json_dict_value identifier | get_json_string_value value)"
+       echo " + Handling authorization for ${identifier}"
+     else
+@@ -793,7 +793,11 @@ sign_csr() {
+ 
+     while [[ "${reqstatus}" = "pending" ]]; do
+       sleep 1
+-      result="$(http_request get "${challenge_uris[${idx}]}")"
++      if [[ "${API}" -eq 2 ]]; then
++        result="$(signed_request "${challenge_uris[${idx}]}" "")"
++      else
++        result="$(http_request get "${challenge_uris[${idx}]}")"
++      fi
+       reqstatus="$(printf '%s\n' "${result}" | get_json_string_value status)"
+     done
+ 
+@@ -838,7 +842,7 @@ sign_csr() {
+     crt="$( printf -- '-----BEGIN CERTIFICATE-----\n%s\n-----END CERTIFICATE-----\n' "${crt64}" )"
+   else
+     result="$(signed_request "${finalize}" '{"csr": "'"${csr64}"'"}' | clean_json | get_json_string_value certificate)"
+-    crt="$(http_request get "${result}")"
++    crt="$(signed_request "${result}" "")"
+   fi
+ 
+   # Try to load the certificate to detect corruption
diff -Nru dehydrated-0.3.1/debian/patches/Make-the-upgrade-path-from-ACCOUNT_KEY-_JSON-to-the-new-A.patch dehydrated-0.6.2/debian/patches/Make-the-upgrade-path-from-ACCOUNT_KEY-_JSON-to-the-new-A.patch
--- dehydrated-0.3.1/debian/patches/Make-the-upgrade-path-from-ACCOUNT_KEY-_JSON-to-the-new-A.patch	2019-11-05 14:17:57.000000000 +0100
+++ dehydrated-0.6.2/debian/patches/Make-the-upgrade-path-from-ACCOUNT_KEY-_JSON-to-the-new-A.patch	1970-01-01 01:00:00.000000000 +0100
@@ -1,45 +0,0 @@
-From: Mattia Rizzolo <mattia@debian.org>
-Date: Wed, 30 Nov 2016 20:43:48 +0100
-Subject: Make the upgrade path from ACCOUNT_KEY{,
- _JSON} to the new ACCOUNTDIR more comprehensive
-
-i.e. before it would not account for an already set ACCOUNT_KEY option
-
-Forwarded: no
-Closes: #837308
----
- dehydrated | 18 ++++++++++--------
- 1 file changed, 10 insertions(+), 8 deletions(-)
-
-diff --git a/dehydrated b/dehydrated
-index 63e3fc3..7b88ae9 100755
---- a/dehydrated
-+++ b/dehydrated
-@@ -167,17 +167,19 @@ load_config() {
-   [[ -z "${ACCOUNTDIR}" ]] && ACCOUNTDIR="${BASEDIR}/accounts"
-   mkdir -p "${ACCOUNTDIR}/${CAHASH}"
-   [[ -f "${ACCOUNTDIR}/${CAHASH}/config" ]] && . "${ACCOUNTDIR}/${CAHASH}/config"
--  ACCOUNT_KEY="${ACCOUNTDIR}/${CAHASH}/account_key.pem"
--  ACCOUNT_KEY_JSON="${ACCOUNTDIR}/${CAHASH}/registration_info.json"
-+  local new_ACCOUNT_KEY="${ACCOUNTDIR}/${CAHASH}/account_key.pem"
-+  local new_ACCOUNT_KEY_JSON="${ACCOUNTDIR}/${CAHASH}/registration_info.json"
- 
--  if [[ -f "${BASEDIR}/private_key.pem" ]] && [[ ! -f "${ACCOUNT_KEY}" ]]; then
--    echo "! Moving private_key.pem to ${ACCOUNT_KEY}"
--    mv "${BASEDIR}/private_key.pem" "${ACCOUNT_KEY}"
-+  if [[ -f "${ACCOUNT_KEY:-"${BASEDIR}/private_key.pem"}" ]] && [[ ! -f "${new_ACCOUNT_KEY}" ]]; then
-+    echo "! Moving private_key.pem to ${new_ACCOUNT_KEY}"
-+    mv -v "${ACCOUNT_KEY:-"${BASEDIR}/private_key.pem"}" "${new_ACCOUNT_KEY}"
-   fi
--  if [[ -f "${BASEDIR}/private_key.json" ]] && [[ ! -f "${ACCOUNT_KEY_JSON}" ]]; then
--    echo "! Moving private_key.json to ${ACCOUNT_KEY_JSON}"
--    mv "${BASEDIR}/private_key.json" "${ACCOUNT_KEY_JSON}"
-+  if [[ -f "${ACCOUNT_KEY_JSON:-"${BASEDIR}/private_key.json"}" ]] && [[ ! -f "${new_ACCOUNT_KEY_JSON}" ]]; then
-+    echo "! Moving private_key.json to ${new_ACCOUNT_KEY_JSON}"
-+    mv -v "${ACCOUNT_KEY_JSON:-"${BASEDIR}/private_key.json"}" "${new_ACCOUNT_KEY_JSON}"
-   fi
-+  ACCOUNT_KEY="${new_ACCOUNT_KEY}"
-+  ACCOUNT_KEY_JSON="${new_ACCOUNT_KEY_JSON}"
- 
-   [[ -z "${CERTDIR}" ]] && CERTDIR="${BASEDIR}/certs"
-   [[ -z "${DOMAINS_TXT}" ]] && DOMAINS_TXT="${BASEDIR}/domains.txt"
diff -Nru dehydrated-0.3.1/debian/patches/Only-match-Replace-Nonce-header-at-beginning-of-line.patch dehydrated-0.6.2/debian/patches/Only-match-Replace-Nonce-header-at-beginning-of-line.patch
--- dehydrated-0.3.1/debian/patches/Only-match-Replace-Nonce-header-at-beginning-of-line.patch	1970-01-01 01:00:00.000000000 +0100
+++ dehydrated-0.6.2/debian/patches/Only-match-Replace-Nonce-header-at-beginning-of-line.patch	2020-01-18 15:13:17.000000000 +0100
@@ -0,0 +1,24 @@
+From: Lukas Schauer <lukas@schauer.so>
+Date: Wed, 9 May 2018 21:01:57 +0200
+Subject: Only match Replace-Nonce header at beginning of line
+
+---
+ dehydrated | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/dehydrated b/dehydrated
+index ba0f5a0..c27706a 100755
+--- a/dehydrated
++++ b/dehydrated
+@@ -577,9 +577,9 @@ signed_request() {
+ 
+   # Retrieve nonce from acme-server
+   if [[ ${API} -eq 1 ]]; then
+-    nonce="$(http_request head "${CA}" | grep -i Replay-Nonce: | awk -F ': ' '{print $2}' | tr -d '\n\r')"
++    nonce="$(http_request head "${CA}" | grep -i ^Replay-Nonce: | awk -F ': ' '{print $2}' | tr -d '\n\r')"
+   else
+-    nonce="$(http_request head "${CA_NEW_NONCE}" | grep -i Replay-Nonce: | awk -F ': ' '{print $2}' | tr -d '\n\r')"
++    nonce="$(http_request head "${CA_NEW_NONCE}" | grep -i ^Replay-Nonce: | awk -F ': ' '{print $2}' | tr -d '\n\r')"
+   fi
+ 
+   # Build header with just our public key and algorithm information
diff -Nru dehydrated-0.3.1/debian/patches/release-0.6.4-fixed-account-id-handling-again.patch dehydrated-0.6.2/debian/patches/release-0.6.4-fixed-account-id-handling-again.patch
--- dehydrated-0.3.1/debian/patches/release-0.6.4-fixed-account-id-handling-again.patch	1970-01-01 01:00:00.000000000 +0100
+++ dehydrated-0.6.2/debian/patches/release-0.6.4-fixed-account-id-handling-again.patch	2020-01-18 15:13:17.000000000 +0100
@@ -0,0 +1,57 @@
+From: Lukas Schauer <lukas@schauer.so>
+Date: Tue, 25 Jun 2019 15:28:09 +0200
+Subject: release 0.6.4 (fixed account id handling, again)
+
+---
+ dehydrated | 15 +++++++++------
+ 1 file changed, 9 insertions(+), 6 deletions(-)
+
+diff --git a/dehydrated b/dehydrated
+index a29910b..c066d27 100755
+--- a/dehydrated
++++ b/dehydrated
+@@ -243,6 +243,7 @@ load_config() {
+   [[ -f "${ACCOUNTDIR}/${CAHASH}/config" ]] && . "${ACCOUNTDIR}/${CAHASH}/config"
+   ACCOUNT_KEY="${ACCOUNTDIR}/${CAHASH}/account_key.pem"
+   ACCOUNT_KEY_JSON="${ACCOUNTDIR}/${CAHASH}/registration_info.json"
++  ACCOUNT_ID_JSON="${ACCOUNTDIR}/${CAHASH}/account_id.json"
+ 
+   if [[ -f "${BASEDIR}/private_key.pem" ]] && [[ ! -f "${ACCOUNT_KEY}" ]]; then
+     echo "! Moving private_key.pem to ${ACCOUNT_KEY}"
+@@ -328,6 +329,7 @@ init_system() {
+     echo "Using private key ${PARAM_ACCOUNT_KEY} instead of account key"
+     ACCOUNT_KEY="${PARAM_ACCOUNT_KEY}"
+     ACCOUNT_KEY_JSON="${PARAM_ACCOUNT_KEY}.json"
++    ACCOUNT_ID_JSON="${PARAM_ACCOUNT_KEY}_id.json"
+     [ "${COMMAND:-}" = "register" ] && register_new_key="yes"
+   else
+     # Check if private account key exists, if it doesn't exist yet generate a new one (rsa key)
+@@ -396,13 +398,14 @@ init_system() {
+ 
+   # Read account information or request from CA if missing
+   if [[ -e "${ACCOUNT_KEY_JSON}" ]]; then
+-    if [[ -z "$(cat "${ACCOUNT_KEY_JSON}" | get_json_int_value id)" ]]; then
+-      echo "+ Fetching account information..."
++    if [[ ! -e "${ACCOUNT_ID_JSON}" ]]; then
++      echo "+ Fetching account ID..."
+       ACCOUNT_URL="$(signed_request "${CA_NEW_ACCOUNT}" '{"onlyReturnExisting": true}' 4>&1 | grep -i ^Location: | awk '{print $2}' | tr -d '\r\n')"
+-      ACCOUNT_INFO="$(signed_request "${ACCOUNT_URL}" '{}')"
+-      echo "${ACCOUNT_INFO}" > "${ACCOUNT_KEY_JSON}"
++      ACCOUNT_ID="${ACCOUNT_URL##*/}"
++      echo '{"id": "'"${ACCOUNT_ID}"'"}' > "${ACCOUNT_ID_JSON}"
++    else
++      ACCOUNT_ID="$(cat "${ACCOUNT_ID_JSON}" | get_json_string_value id)"
+     fi
+-    ACCOUNT_ID="$(cat "${ACCOUNT_KEY_JSON}" | get_json_int_value id)"
+     if [[ -z "${ACCOUNT_ID}" ]]; then
+       _exiterr "Unknown error on fetching account information"
+     fi
+@@ -1525,7 +1528,7 @@ command_help() {
+ command_env() {
+   echo "# dehydrated configuration"
+   load_config
+-  typeset -p CA CERTDIR CHALLENGETYPE DOMAINS_D DOMAINS_TXT HOOK HOOK_CHAIN RENEW_DAYS ACCOUNT_KEY ACCOUNT_KEY_JSON KEYSIZE WELLKNOWN PRIVATE_KEY_RENEW OPENSSL_CNF CONTACT_EMAIL LOCKFILE
++  typeset -p CA CERTDIR CHALLENGETYPE DOMAINS_D DOMAINS_TXT HOOK HOOK_CHAIN RENEW_DAYS ACCOUNT_KEY ACCOUNT_KEY_JSON ACCOUNT_ID_JSON KEYSIZE WELLKNOWN PRIVATE_KEY_RENEW OPENSSL_CNF CONTACT_EMAIL LOCKFILE
+ }
+ 
+ # Main method (parses script arguments and calls command_* methods)
diff -Nru dehydrated-0.3.1/debian/patches/release-0.6.5-fixed-apiv1-compatibility.patch dehydrated-0.6.2/debian/patches/release-0.6.5-fixed-apiv1-compatibility.patch
--- dehydrated-0.3.1/debian/patches/release-0.6.5-fixed-apiv1-compatibility.patch	1970-01-01 01:00:00.000000000 +0100
+++ dehydrated-0.6.2/debian/patches/release-0.6.5-fixed-apiv1-compatibility.patch	2020-01-18 15:13:17.000000000 +0100
@@ -0,0 +1,45 @@
+From: Lukas Schauer <lukas@schauer.so>
+Date: Wed, 26 Jun 2019 12:29:39 +0200
+Subject: release 0.6.5 (fixed apiv1 compatibility...)
+
+---
+ dehydrated | 23 ++++++++++++-----------
+ 1 file changed, 12 insertions(+), 11 deletions(-)
+
+diff --git a/dehydrated b/dehydrated
+index c066d27..41c7fdf 100755
+--- a/dehydrated
++++ b/dehydrated
+@@ -398,20 +398,21 @@ init_system() {
+ 
+   # Read account information or request from CA if missing
+   if [[ -e "${ACCOUNT_KEY_JSON}" ]]; then
+-    if [[ ! -e "${ACCOUNT_ID_JSON}" ]]; then
+-      echo "+ Fetching account ID..."
+-      ACCOUNT_URL="$(signed_request "${CA_NEW_ACCOUNT}" '{"onlyReturnExisting": true}' 4>&1 | grep -i ^Location: | awk '{print $2}' | tr -d '\r\n')"
+-      ACCOUNT_ID="${ACCOUNT_URL##*/}"
+-      echo '{"id": "'"${ACCOUNT_ID}"'"}' > "${ACCOUNT_ID_JSON}"
+-    else
+-      ACCOUNT_ID="$(cat "${ACCOUNT_ID_JSON}" | get_json_string_value id)"
+-    fi
+-    if [[ -z "${ACCOUNT_ID}" ]]; then
+-      _exiterr "Unknown error on fetching account information"
+-    fi
+     if [[ ${API} -eq 1 ]]; then
++      ACCOUNT_ID="$(cat "${ACCOUNT_KEY_JSON}" | get_json_int_value id)"
+       ACCOUNT_URL="${CA_REG}/${ACCOUNT_ID}"
+     else
++      if [[ -e "${ACCOUNT_ID_JSON}" ]]; then
++        ACCOUNT_ID="$(cat "${ACCOUNT_ID_JSON}" | get_json_string_value id)"
++      else
++        echo "+ Fetching account ID..."
++        ACCOUNT_URL="$(signed_request "${CA_NEW_ACCOUNT}" '{"onlyReturnExisting": true}' 4>&1 | grep -i ^Location: | awk '{print $2}' | tr -d '\r\n')"
++        ACCOUNT_ID="${ACCOUNT_URL##*/}"
++        if [[ -z "${ACCOUNT_ID}" ]]; then
++          _exiterr "Unknown error on fetching account information"
++        fi
++        echo '{"id": "'"${ACCOUNT_ID}"'"}' > "${ACCOUNT_ID_JSON}"
++      fi
+       ACCOUNT_URL="${CA_ACCOUNT}/${ACCOUNT_ID}"
+     fi
+   else
diff -Nru dehydrated-0.3.1/debian/patches/series dehydrated-0.6.2/debian/patches/series
--- dehydrated-0.3.1/debian/patches/series	2019-11-05 14:17:57.000000000 +0100
+++ dehydrated-0.6.2/debian/patches/series	2020-01-18 15:13:17.000000000 +0100
@@ -1,9 +1,16 @@
-use-temporary-file-for-DER-PEM-conversion-fixes-279.patch
-Make-the-upgrade-path-from-ACCOUNT_KEY-_JSON-to-the-new-A.patch
+# letsencyrpt.sh compat
 added-temporary-wrapper-script-for-compatibility-with-old.patch
 Update-the-location-of-WELLKNOWN-in-the-notice-message-of.patch
 honor-config-if-the-user-provided-one-to-letsencrypt.sh-w.patch
 Support-both-config.sh-and-config-as-config-filenames-for.patch
-Update-the-default-License-Subscriber-Agreement-URL.patch
-follow-location-on-http-get-requests.patch
+
+# upstream fixes
 Fixes-559-when-HTTP-2-is-used-header-names-are-lower-case.patch
+Only-match-Replace-Nonce-header-at-beginning-of-line.patch
+fixed-a-bug-that-resulted-in-a-deleted-domains.txt-when-u.patch
+document-DOMAINS_D-parameter-in-example-config-fixes-575-.patch
+implement-POST-as-GET-closes-626.patch
+tiny-documentation-fix-per-certificate-config-can-overrid.patch
+fixed-fetching-of-account-information-fixes-652-fixes-647.patch
+release-0.6.4-fixed-account-id-handling-again.patch
+release-0.6.5-fixed-apiv1-compatibility.patch
diff -Nru dehydrated-0.3.1/debian/patches/tiny-documentation-fix-per-certificate-config-can-overrid.patch dehydrated-0.6.2/debian/patches/tiny-documentation-fix-per-certificate-config-can-overrid.patch
--- dehydrated-0.3.1/debian/patches/tiny-documentation-fix-per-certificate-config-can-overrid.patch	1970-01-01 01:00:00.000000000 +0100
+++ dehydrated-0.6.2/debian/patches/tiny-documentation-fix-per-certificate-config-can-overrid.patch	2020-01-18 15:13:17.000000000 +0100
@@ -0,0 +1,21 @@
+From: Lukas Schauer <lukas@schauer.so>
+Date: Sun, 3 Mar 2019 20:38:38 +0100
+Subject: tiny documentation fix: per-certificate-config can override
+ PRIVATE_KEY_ROLLOVER (closes #614)
+
+---
+ docs/per-certificate-config.md | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/docs/per-certificate-config.md b/docs/per-certificate-config.md
+index da88838..457a41a 100644
+--- a/docs/per-certificate-config.md
++++ b/docs/per-certificate-config.md
+@@ -7,6 +7,7 @@ To use this feature create a `config` file in the certificates output directory
+ Currently supported options:
+ 
+ - PRIVATE_KEY_RENEW
++- PRIVATE_KEY_ROLLOVER
+ - KEY_ALGO
+ - KEYSIZE
+ - OCSP_MUST_STAPLE
diff -Nru dehydrated-0.3.1/debian/patches/Update-the-default-License-Subscriber-Agreement-URL.patch dehydrated-0.6.2/debian/patches/Update-the-default-License-Subscriber-Agreement-URL.patch
--- dehydrated-0.3.1/debian/patches/Update-the-default-License-Subscriber-Agreement-URL.patch	2019-11-05 14:17:57.000000000 +0100
+++ dehydrated-0.6.2/debian/patches/Update-the-default-License-Subscriber-Agreement-URL.patch	1970-01-01 01:00:00.000000000 +0100
@@ -1,39 +0,0 @@
-From: Mattia Rizzolo <mattia@debian.org>
-Date: Sat, 18 Nov 2017 13:54:41 +0100
-Subject: Update the default License Subscriber Agreement URL
-
-Closes: #881974
-Signed-off-by: Mattia Rizzolo <mattia@debian.org>
----
- dehydrated           | 2 +-
- docs/examples/config | 4 ++--
- 2 files changed, 3 insertions(+), 3 deletions(-)
-
-diff --git a/dehydrated b/dehydrated
-index 7b88ae9..882c6bd 100755
---- a/dehydrated
-+++ b/dehydrated
-@@ -105,7 +105,7 @@ load_config() {
- 
-   # Default values
-   CA="https://acme-v01.api.letsencrypt.org/directory";
--  LICENSE="https://letsencrypt.org/documents/LE-SA-v1.1.1-August-1-2016.pdf";
-+  LICENSE="https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf";
-   CERTDIR=
-   ACCOUNTDIR=
-   CHALLENGETYPE="http-01"
-diff --git a/docs/examples/config b/docs/examples/config
-index 17621d2..d28214b 100644
---- a/docs/examples/config
-+++ b/docs/examples/config
-@@ -18,8 +18,8 @@
- # Path to certificate authority (default: https://acme-v01.api.letsencrypt.org/directory)
- #CA="https://acme-v01.api.letsencrypt.org/directory";
- 
--# Path to license agreement (default: https://letsencrypt.org/documents/LE-SA-v1.1.1-August-1-2016.pdf)
--#LICENSE="https://letsencrypt.org/documents/LE-SA-v1.1.1-August-1-2016.pdf";
-+# Path to license agreement (default: https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf)
-+#LICENSE="https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf";
- 
- # Which challenge should be used? Currently http-01 and dns-01 are supported
- #CHALLENGETYPE="http-01"
diff -Nru dehydrated-0.3.1/debian/patches/use-temporary-file-for-DER-PEM-conversion-fixes-279.patch dehydrated-0.6.2/debian/patches/use-temporary-file-for-DER-PEM-conversion-fixes-279.patch
--- dehydrated-0.3.1/debian/patches/use-temporary-file-for-DER-PEM-conversion-fixes-279.patch	2019-11-05 14:17:57.000000000 +0100
+++ dehydrated-0.6.2/debian/patches/use-temporary-file-for-DER-PEM-conversion-fixes-279.patch	1970-01-01 01:00:00.000000000 +0100
@@ -1,50 +0,0 @@
-From: Lukas Schauer <lukas@schauer.so>
-Date: Sat, 17 Sep 2016 13:02:48 +0200
-Subject: use temporary file for DER->PEM conversion (fixes #279)
-
-Origin: upstream, https://github.com/lukas2511/dehydrated/commit/7eca8aec5a6679ce5ca507386687d130cc38ce23
-Bug: https://github.com/lukas2511/dehydrated/issues/279
-Bug-Debian: https://bugs.debian.org/846319
----
- dehydrated | 21 ++++++++++++++-------
- 1 file changed, 14 insertions(+), 7 deletions(-)
-
-diff --git a/dehydrated b/dehydrated
-index 4cc2a66..63e3fc3 100755
---- a/dehydrated
-+++ b/dehydrated
-@@ -621,9 +621,13 @@ sign_domain() {
-   # Create fullchain.pem
-   echo " + Creating fullchain.pem..."
-   cat "${crt_path}" > "${CERTDIR}/${domain}/fullchain-${timestamp}.pem"
--  http_request get "$(openssl x509 -in "${CERTDIR}/${domain}/cert-${timestamp}.pem" -noout -text | grep 'CA Issuers - URI:' | cut -d':' -f2-)" > "${CERTDIR}/${domain}/chain-${timestamp}.pem"
--  if ! grep -q "BEGIN CERTIFICATE" "${CERTDIR}/${domain}/chain-${timestamp}.pem"; then
--    openssl x509 -in "${CERTDIR}/${domain}/chain-${timestamp}.pem" -inform DER -out "${CERTDIR}/${domain}/chain-${timestamp}.pem" -outform PEM
-+  tmpchain="$(_mktemp)"
-+  http_request get "$(openssl x509 -in "${CERTDIR}/${domain}/cert-${timestamp}.pem" -noout -text | grep 'CA Issuers - URI:' | cut -d':' -f2-)" > "${tmpchain}"
-+  if grep -q "BEGIN CERTIFICATE" "${tmpchain}"; then
-+    mv "${tmpchain}" "${CERTDIR}/${domain}/chain-${timestamp}.pem"
-+  else
-+    openssl x509 -in "${tmpchain}" -inform DER -out "${CERTDIR}/${domain}/chain-${timestamp}.pem" -outform PEM
-+    rm "${tmpchain}"
-   fi
-   cat "${CERTDIR}/${domain}/chain-${timestamp}.pem" >> "${CERTDIR}/${domain}/fullchain-${timestamp}.pem"
- 
-@@ -797,10 +801,13 @@ command_sign_csr() {
-   if [ -n "${PARAM_FULL_CHAIN:-}" ]; then
-     # get and convert ca cert
-     chainfile="$(_mktemp)"
--    http_request get "$(openssl x509 -in "${certfile}" -noout -text | grep 'CA Issuers - URI:' | cut -d':' -f2-)" > "${chainfile}"
--
--    if ! grep -q "BEGIN CERTIFICATE" "${chainfile}"; then
--      openssl x509 -inform DER -in "${chainfile}" -outform PEM -out "${chainfile}"
-+    tmpchain="$(_mktemp)"
-+    http_request get "$(openssl x509 -in "${certfile}" -noout -text | grep 'CA Issuers - URI:' | cut -d':' -f2-)" > "${tmpchain}"
-+    if grep -q "BEGIN CERTIFICATE" "${tmpchain}"; then
-+      mv "${tmpchain}" "${chainfile}"
-+    else
-+      openssl x509 -in "${tmpchain}" -inform DER -out "${chainfile}" -outform PEM
-+      rm "${tmpchain}"
-     fi
- 
-     echo "# CHAIN #" >&3
diff -Nru dehydrated-0.3.1/debian/rules dehydrated-0.6.2/debian/rules
--- dehydrated-0.3.1/debian/rules	2019-11-05 14:12:17.000000000 +0100
+++ dehydrated-0.6.2/debian/rules	2020-01-18 15:13:17.000000000 +0100
@@ -5,13 +5,9 @@
 %:
 	dh $@ --with apache2
 
-override_dh_installman:
-	./debian/generate-manpage > debian/dehydrated.1
-	dh_installman
-
 override_dh_installdocs:
 	dh_installdocs
 	rm -rv $(CURDIR)/debian/dehydrated/usr/share/doc/dehydrated/docs/examples
 
-get-orig-source:
-	uscan --verbose --rename --force
+override_dh_compress:
+	dh_compress -Xconfig -Xhook.sh -XREADME.md
diff -Nru dehydrated-0.3.1/dehydrated dehydrated-0.6.2/dehydrated
--- dehydrated-0.3.1/dehydrated	2016-09-13 20:00:43.000000000 +0200
+++ dehydrated-0.6.2/dehydrated	2018-04-25 23:22:40.000000000 +0200
@@ -1,16 +1,24 @@
 #!/usr/bin/env bash
 
 # dehydrated by lukas2511
-# Source: https://github.com/lukas2511/dehydrated
+# Source: https://dehydrated.io
 #
 # This script is licensed under The MIT License (see LICENSE for more information).
 
 set -e
 set -u
 set -o pipefail
-[[ -n "${ZSH_VERSION:-}" ]] && set -o SH_WORD_SPLIT && set +o FUNCTION_ARGZERO
+[[ -n "${ZSH_VERSION:-}" ]] && set -o SH_WORD_SPLIT && set +o FUNCTION_ARGZERO && set -o NULL_GLOB && set -o noglob
+[[ -z "${ZSH_VERSION:-}" ]] && shopt -s nullglob && set -f
+
 umask 077 # paranoid umask, we're creating private keys
 
+# Close weird external file descriptors
+exec 3>&-
+exec 4>&-
+
+VERSION="0.6.2"
+
 # Find directory in which this script is stored by traversing all symbolic links
 SOURCE="${0}"
 while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
@@ -21,6 +29,7 @@
 SCRIPTDIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
 
 BASEDIR="${SCRIPTDIR}"
+ORIGARGS="$@"
 
 # Create (identifiable) temporary files
 _mktemp() {
@@ -31,15 +40,15 @@
 # Check for script dependencies
 check_dependencies() {
   # just execute some dummy and/or version commands to see if required tools exist and are actually usable
-  openssl version > /dev/null 2>&1 || _exiterr "This script requires an openssl binary."
+  "${OPENSSL}" version > /dev/null 2>&1 || _exiterr "This script requires an openssl binary."
   _sed "" < /dev/null > /dev/null 2>&1 || _exiterr "This script requires sed with support for extended (modern) regular expressions."
   command -v grep > /dev/null 2>&1 || _exiterr "This script requires grep."
-  _mktemp -u > /dev/null 2>&1 || _exiterr "This script requires mktemp."
-  diff -u /dev/null /dev/null || _exiterr "This script requires diff."
+  command -v mktemp > /dev/null 2>&1 || _exiterr "This script requires mktemp."
+  command -v diff > /dev/null 2>&1 || _exiterr "This script requires diff."
 
   # curl returns with an error code in some ancient versions so we have to catch that
   set +e
-  curl -V > /dev/null 2>&1
+  CURL_VERSION="$(curl -V 2>&1 | head -n1 | awk '{print $2}')"
   retcode="$?"
   set -e
   if [[ ! "${retcode}" = "0" ]] && [[ ! "${retcode}" = "2" ]]; then
@@ -75,19 +84,28 @@
   IP_VERSION="${__IP_VERSION}"
 }
 
+hookscript_bricker_hook() {
+  # Hook scripts should ignore any hooks they don't know.
+  # Calling a random hook to make this clear to the hook script authors...
+  if [[ -n "${HOOK}" ]]; then
+    "${HOOK}" "this_hookscript_is_broken__dehydrated_is_working_fine__please_ignore_unknown_hooks_in_your_script"
+  fi
+}
+
 # verify configuration values
 verify_config() {
-  [[ "${CHALLENGETYPE}" =~ (http-01|dns-01) ]] || _exiterr "Unknown challenge type ${CHALLENGETYPE}... can not continue."
+  [[ "${CHALLENGETYPE}" == "http-01" || "${CHALLENGETYPE}" == "dns-01" ]] || _exiterr "Unknown challenge type ${CHALLENGETYPE}... cannot continue."
   if [[ "${CHALLENGETYPE}" = "dns-01" ]] && [[ -z "${HOOK}" ]]; then
-    _exiterr "Challenge type dns-01 needs a hook script for deployment... can not continue."
+    _exiterr "Challenge type dns-01 needs a hook script for deployment... cannot continue."
   fi
-  if [[ "${CHALLENGETYPE}" = "http-01" && ! -d "${WELLKNOWN}" ]]; then
+  if [[ "${CHALLENGETYPE}" = "http-01" && ! -d "${WELLKNOWN}" && ! "${COMMAND:-}" = "register" ]]; then
     _exiterr "WELLKNOWN directory doesn't exist, please create ${WELLKNOWN} and set appropriate permissions."
   fi
-  [[ "${KEY_ALGO}" =~ ^(rsa|prime256v1|secp384r1)$ ]] || _exiterr "Unknown public key algorithm ${KEY_ALGO}... can not continue."
+  [[ "${KEY_ALGO}" == "rsa" || "${KEY_ALGO}" == "prime256v1" || "${KEY_ALGO}" == "secp384r1" ]] || _exiterr "Unknown public key algorithm ${KEY_ALGO}... cannot continue."
   if [[ -n "${IP_VERSION}" ]]; then
-    [[ "${IP_VERSION}" = "4" || "${IP_VERSION}" = "6" ]] || _exiterr "Unknown IP version ${IP_VERSION}... can not continue."
+    [[ "${IP_VERSION}" = "4" || "${IP_VERSION}" = "6" ]] || _exiterr "Unknown IP version ${IP_VERSION}... cannot continue."
   fi
+  [[ "${API}" == "auto" || "${API}" == "1" || "${API}" == "2" ]] || _exiterr "Unsupported API version defined in config: ${API}"
 }
 
 # Setup default config values, search for and load configuration files
@@ -104,12 +122,13 @@
   fi
 
   # Default values
-  CA="https://acme-v01.api.letsencrypt.org/directory";
-  LICENSE="https://letsencrypt.org/documents/LE-SA-v1.1.1-August-1-2016.pdf";
+  CA="https://acme-v02.api.letsencrypt.org/directory";
+  OLDCA=
   CERTDIR=
   ACCOUNTDIR=
   CHALLENGETYPE="http-01"
   CONFIG_D=
+  CURL_OPTS=
   DOMAINS_D=
   DOMAINS_TXT=
   HOOK=
@@ -118,12 +137,20 @@
   KEYSIZE="4096"
   WELLKNOWN=
   PRIVATE_KEY_RENEW="yes"
+  PRIVATE_KEY_ROLLOVER="no"
   KEY_ALGO=rsa
-  OPENSSL_CNF="$(openssl version -d | cut -d\" -f2)/openssl.cnf"
+  OPENSSL=openssl
+  OPENSSL_CNF=
   CONTACT_EMAIL=
   LOCKFILE=
   OCSP_MUST_STAPLE="no"
+  OCSP_FETCH="no"
   IP_VERSION=
+  CHAINCACHE=
+  AUTO_CLEANUP="no"
+  DEHYDRATED_USER=
+  DEHYDRATED_GROUP=
+  API="auto"
 
   if [[ -z "${CONFIG:-}" ]]; then
     echo "#" >&2
@@ -140,32 +167,79 @@
 
   if [[ -n "${CONFIG_D}" ]]; then
     if [[ ! -d "${CONFIG_D}" ]]; then
-      _exiterr "The path ${CONFIG_D} specified for CONFIG_D does not point to a directory." >&2
+      _exiterr "The path ${CONFIG_D} specified for CONFIG_D does not point to a directory."
     fi
 
+    # Allow globbing
+    [[ -n "${ZSH_VERSION:-}" ]] && set +o noglob || set +f
+
     for check_config_d in "${CONFIG_D}"/*.sh; do
-      if [[ ! -e "${check_config_d}" ]]; then
-        echo "# !! WARNING !! Extra configuration directory ${CONFIG_D} exists, but no configuration found in it." >&2
-        break
-      elif [[ -f "${check_config_d}" ]] && [[ -r "${check_config_d}" ]]; then
+      if [[ -f "${check_config_d}" ]] && [[ -r "${check_config_d}" ]]; then
         echo "# INFO: Using additional config file ${check_config_d}"
         # shellcheck disable=SC1090
         . "${check_config_d}"
       else
-        _exiterr "Specified additional config ${check_config_d} is not readable or not a file at all." >&2
+        _exiterr "Specified additional config ${check_config_d} is not readable or not a file at all."
+      fi
+    done
+
+    # Disable globbing
+    [[ -n "${ZSH_VERSION:-}" ]] && set -o noglob || set -f
+  fi
+
+  # Check if we are running & are allowed to run as root
+  if [[ -n "$DEHYDRATED_USER" ]]; then
+    command -v sudo > /dev/null 2>&1 || _exiterr "DEHYDRATED_USER set but sudo not available. Please install sudo."
+    command -v getent > /dev/null 2>&1 || _exiterr "DEHYDRATED_USER set but getent not available. Please install getent."
+
+    TARGET_UID="$(getent passwd "${DEHYDRATED_USER}" | cut -d':' -f3)"
+    if [[ -z "${DEHYDRATED_GROUP}" ]]; then
+      if [[ "${EUID}" != "${TARGET_UID}" ]]; then
+        echo "# INFO: Running $0 as ${DEHYDRATED_USER}"
+        exec sudo -u "${DEHYDRATED_USER}" "${0}" ${ORIGARGS}
+      fi
+    else
+      TARGET_GID="$(getent group "${DEHYDRATED_GROUP}" | cut -d':' -f3)"
+      if [[ -z "${EGID:-}" ]]; then
+        command -v id > /dev/null 2>&1 || _exiterr "DEHYDRATED_GROUP set, don't know current gid and 'id' not available... Please provide 'id' binary."
+        EGID="$(id -g)"
       fi
-   done
+      if [[ "${EUID}" != "${TARGET_UID}" ]] || [[ "${EGID}" != "${TARGET_GID}" ]]; then
+        echo "# INFO: Running $0 as ${DEHYDRATED_USER}/${DEHYDRATED_GROUP}"
+        exec sudo -u "${DEHYDRATED_USER}" -g "${DEHYDRATED_GROUP}" "${0}" ${ORIGARGS}
+      fi
+    fi
+  elif [[ -n "${DEHYDRATED_GROUP}" ]]; then
+    _exiterr "DEHYDRATED_GROUP can only be used in combination with DEHYDRATED_USER."
   fi
 
+  # Check for missing dependencies
+  check_dependencies
+
   # Remove slash from end of BASEDIR. Mostly for cleaner outputs, doesn't change functionality.
-  BASEDIR="${BASEDIR%%/}"
+  [[ "$BASEDIR" != "/" ]] && BASEDIR="${BASEDIR%%/}"
 
   # Check BASEDIR and set default variables
   [[ -d "${BASEDIR}" ]] || _exiterr "BASEDIR does not exist: ${BASEDIR}"
 
+  if [[ -z "${OLDCA}" ]] && [[ "${CA}" = "https://acme-v02.api.letsencrypt.org/directory"; ]]; then
+    OLDCA="https://acme-v01.api.letsencrypt.org/directory";
+  fi
+
+  # Create new account directory or symlink to account directory from old CA
   CAHASH="$(echo "${CA}" | urlbase64)"
   [[ -z "${ACCOUNTDIR}" ]] && ACCOUNTDIR="${BASEDIR}/accounts"
-  mkdir -p "${ACCOUNTDIR}/${CAHASH}"
+  if [[ ! -e "${ACCOUNTDIR}/${CAHASH}" ]]; then
+    OLDCAHASH="$(echo "${OLDCA}" | urlbase64)"
+    mkdir -p "${ACCOUNTDIR}"
+    if [[ -n "${OLDCA}" ]] && [[ -e "${ACCOUNTDIR}/${OLDCAHASH}" ]]; then
+      echo "! Reusing account from ${OLDCA}"
+      ln -s "${OLDCAHASH}" "${ACCOUNTDIR}/${CAHASH}"
+    else
+      mkdir "${ACCOUNTDIR}/${CAHASH}"
+    fi
+  fi
+
   [[ -f "${ACCOUNTDIR}/${CAHASH}/config" ]] && . "${ACCOUNTDIR}/${CAHASH}/config"
   ACCOUNT_KEY="${ACCOUNTDIR}/${CAHASH}/account_key.pem"
   ACCOUNT_KEY_JSON="${ACCOUNTDIR}/${CAHASH}/registration_info.json"
@@ -180,9 +254,12 @@
   fi
 
   [[ -z "${CERTDIR}" ]] && CERTDIR="${BASEDIR}/certs"
+  [[ -z "${CHAINCACHE}" ]] && CHAINCACHE="${BASEDIR}/chains"
   [[ -z "${DOMAINS_TXT}" ]] && DOMAINS_TXT="${BASEDIR}/domains.txt"
   [[ -z "${WELLKNOWN}" ]] && WELLKNOWN="/var/www/dehydrated"
   [[ -z "${LOCKFILE}" ]] && LOCKFILE="${BASEDIR}/lock"
+  [[ -z "${OPENSSL_CNF}" ]] && OPENSSL_CNF="$("${OPENSSL}" version -d | cut -d\" -f2)/openssl.cnf"
+  [[ -n "${PARAM_LOCKFILE_SUFFIX:-}" ]] && LOCKFILE="${LOCKFILE}-${PARAM_LOCKFILE_SUFFIX}"
   [[ -n "${PARAM_NO_LOCK:-}" ]] && LOCKFILE=""
 
   [[ -n "${PARAM_HOOK:-}" ]] && HOOK="${PARAM_HOOK}"
@@ -192,7 +269,9 @@
   [[ -n "${PARAM_OCSP_MUST_STAPLE:-}" ]] && OCSP_MUST_STAPLE="${PARAM_OCSP_MUST_STAPLE}"
   [[ -n "${PARAM_IP_VERSION:-}" ]] && IP_VERSION="${PARAM_IP_VERSION}"
 
-  verify_config
+  if [ ! "${1:-}" = "noverify" ]; then
+    verify_config
+  fi
   store_configvars
 }
 
@@ -211,15 +290,36 @@
 
   # Get CA URLs
   CA_DIRECTORY="$(http_request get "${CA}")"
-  CA_NEW_CERT="$(printf "%s" "${CA_DIRECTORY}" | get_json_string_value new-cert)" &&
-  CA_NEW_AUTHZ="$(printf "%s" "${CA_DIRECTORY}" | get_json_string_value new-authz)" &&
-  CA_NEW_REG="$(printf "%s" "${CA_DIRECTORY}" | get_json_string_value new-reg)" &&
-  # shellcheck disable=SC2015
-  CA_REVOKE_CERT="$(printf "%s" "${CA_DIRECTORY}" | get_json_string_value revoke-cert)" ||
-  _exiterr "Problem retrieving ACME/CA-URLs, check if your configured CA points to the directory entrypoint."
+
+  # Automatic discovery of API version
+  if [[ "${API}" = "auto" ]]; then
+    grep -q newOrder <<< "${CA_DIRECTORY}" && API=2 || API=1
+  fi
+
+  if [[ ${API} -eq 1 ]]; then
+    # shellcheck disable=SC2015
+    CA_NEW_CERT="$(printf "%s" "${CA_DIRECTORY}" | get_json_string_value new-cert)" &&
+    CA_NEW_AUTHZ="$(printf "%s" "${CA_DIRECTORY}" | get_json_string_value new-authz)" &&
+    CA_NEW_REG="$(printf "%s" "${CA_DIRECTORY}" | get_json_string_value new-reg)" &&
+    CA_TERMS="$(printf "%s" "${CA_DIRECTORY}" | get_json_string_value terms-of-service)" &&
+    CA_REVOKE_CERT="$(printf "%s" "${CA_DIRECTORY}" | get_json_string_value revoke-cert)" ||
+    _exiterr "Problem retrieving ACME/CA-URLs, check if your configured CA points to the directory entrypoint."
+    # Since reg URI is missing from directory we will assume it is the same as CA_NEW_REG without the new part
+    CA_REG=${CA_NEW_REG/new-reg/reg}
+  else
+    # shellcheck disable=SC2015
+    CA_NEW_ORDER="$(printf "%s" "${CA_DIRECTORY}" | get_json_string_value newOrder)" &&
+    CA_NEW_NONCE="$(printf "%s" "${CA_DIRECTORY}" | get_json_string_value newNonce)" &&
+    CA_NEW_ACCOUNT="$(printf "%s" "${CA_DIRECTORY}" | get_json_string_value newAccount)" &&
+    CA_TERMS="$(printf "%s" "${CA_DIRECTORY}" | get_json_string_value termsOfService)" &&
+    CA_REVOKE_CERT="$(printf "%s" "${CA_DIRECTORY}" | get_json_string_value revokeCert)" ||
+    _exiterr "Problem retrieving ACME/CA-URLs, check if your configured CA points to the directory entrypoint."
+    # Since acct URI is missing from directory we will assume it is the same as CA_NEW_ACCOUNT without the new part
+    CA_ACCOUNT=${CA_NEW_ACCOUNT/new-acct/acct}
+  fi
 
   # Export some environment variables to be used in hook script
-  export WELLKNOWN BASEDIR CERTDIR CONFIG
+  export WELLKNOWN BASEDIR CERTDIR CONFIG COMMAND
 
   # Checking for private key ...
   register_new_key="no"
@@ -228,47 +328,96 @@
     echo "Using private key ${PARAM_ACCOUNT_KEY} instead of account key"
     ACCOUNT_KEY="${PARAM_ACCOUNT_KEY}"
     ACCOUNT_KEY_JSON="${PARAM_ACCOUNT_KEY}.json"
+    [ "${COMMAND:-}" = "register" ] && register_new_key="yes"
   else
     # Check if private account key exists, if it doesn't exist yet generate a new one (rsa key)
     if [[ ! -e "${ACCOUNT_KEY}" ]]; then
+      if [[ ! "${PARAM_ACCEPT_TERMS:-}" = "yes" ]]; then
+        printf '\n' >&2
+        printf 'To use dehydrated with this certificate authority you have to agree to their terms of service which you can find here: %s\n\n' "${CA_TERMS}" >&2
+        printf 'To accept these terms of service run `%s --register --accept-terms`.\n' "${0}" >&2
+        exit 1
+      fi
+
       echo "+ Generating account key..."
-      _openssl genrsa -out "${ACCOUNT_KEY}" "${KEYSIZE}"
+      local tmp_account_key="$(_mktemp)"
+      _openssl genrsa -out "${tmp_account_key}" "${KEYSIZE}"
+      cat "${tmp_account_key}" > "${ACCOUNT_KEY}"
+      rm "${tmp_account_key}"
       register_new_key="yes"
     fi
   fi
-  openssl rsa -in "${ACCOUNT_KEY}" -check 2>/dev/null > /dev/null || _exiterr "Account key is not valid, can not continue."
+  "${OPENSSL}" rsa -in "${ACCOUNT_KEY}" -check 2>/dev/null > /dev/null || _exiterr "Account key is not valid, cannot continue."
 
   # Get public components from private key and calculate thumbprint
-  pubExponent64="$(printf '%x' "$(openssl rsa -in "${ACCOUNT_KEY}" -noout -text | awk '/publicExponent/ {print $2}')" | hex2bin | urlbase64)"
-  pubMod64="$(openssl rsa -in "${ACCOUNT_KEY}" -noout -modulus | cut -d'=' -f2 | hex2bin | urlbase64)"
+  pubExponent64="$(printf '%x' "$("${OPENSSL}" rsa -in "${ACCOUNT_KEY}" -noout -text | awk '/publicExponent/ {print $2}')" | hex2bin | urlbase64)"
+  pubMod64="$("${OPENSSL}" rsa -in "${ACCOUNT_KEY}" -noout -modulus | cut -d'=' -f2 | hex2bin | urlbase64)"
 
-  thumbprint="$(printf '{"e":"%s","kty":"RSA","n":"%s"}' "${pubExponent64}" "${pubMod64}" | openssl dgst -sha256 -binary | urlbase64)"
+  thumbprint="$(printf '{"e":"%s","kty":"RSA","n":"%s"}' "${pubExponent64}" "${pubMod64}" | "${OPENSSL}" dgst -sha256 -binary | urlbase64)"
 
   # If we generated a new private key in the step above we have to register it with the acme-server
   if [[ "${register_new_key}" = "yes" ]]; then
     echo "+ Registering account key with ACME server..."
-    [[ ! -z "${CA_NEW_REG}" ]] || _exiterr "Certificate authority doesn't allow registrations."
-    # If an email for the contact has been provided then adding it to the registration request
     FAILED=false
-    if [[ -n "${CONTACT_EMAIL}" ]]; then
-      (signed_request "${CA_NEW_REG}" '{"resource": "new-reg", "contact":["mailto:'"${CONTACT_EMAIL}"'"], "agreement": "'"$LICENSE"'"}' > "${ACCOUNT_KEY_JSON}") || FAILED=true
-    else
-      (signed_request "${CA_NEW_REG}" '{"resource": "new-reg", "agreement": "'"$LICENSE"'"}' > "${ACCOUNT_KEY_JSON}") || FAILED=true
+
+    if [[ ${API} -eq 1 && -z "${CA_NEW_REG}" ]] || [[ ${API} -eq 2 && -z "${CA_NEW_ACCOUNT}" ]]; then
+      echo "Certificate authority doesn't allow registrations."
+      FAILED=true
+    fi
+
+    # If an email for the contact has been provided then adding it to the registration request
+    if [[ "${FAILED}" = "false" ]]; then
+      if [[ ${API} -eq 1 ]]; then
+        if [[ -n "${CONTACT_EMAIL}" ]]; then
+          (signed_request "${CA_NEW_REG}" '{"resource": "new-reg", "contact":["mailto:'"${CONTACT_EMAIL}"'"], "agreement": "'"${CA_TERMS}"'"}' > "${ACCOUNT_KEY_JSON}") || FAILED=true
+        else
+          (signed_request "${CA_NEW_REG}" '{"resource": "new-reg", "agreement": "'"${CA_TERMS}"'"}' > "${ACCOUNT_KEY_JSON}") || FAILED=true
+        fi
+      else
+        if [[ -n "${CONTACT_EMAIL}" ]]; then
+          (signed_request "${CA_NEW_ACCOUNT}" '{"contact":["mailto:'"${CONTACT_EMAIL}"'"], "termsOfServiceAgreed": true}' > "${ACCOUNT_KEY_JSON}") || FAILED=true
+        else
+          (signed_request "${CA_NEW_ACCOUNT}" '{"termsOfServiceAgreed": true}' > "${ACCOUNT_KEY_JSON}") || FAILED=true
+        fi
+      fi
     fi
+
     if [[ "${FAILED}" = "true" ]]; then
-      echo
-      echo
-      echo "Error registering account key. See message above for more information."
+      echo >&2
+      echo >&2
+      echo "Error registering account key. See message above for more information." >&2
       rm "${ACCOUNT_KEY}" "${ACCOUNT_KEY_JSON}"
       exit 1
     fi
+  elif [[ "${COMMAND:-}" = "register" ]]; then
+    echo "+ Account already registered!"
+    exit 0
   fi
 
+  # Read account information or request from CA if missing
+  if [[ -e "${ACCOUNT_KEY_JSON}" ]]; then
+    ACCOUNT_ID="$(cat "${ACCOUNT_KEY_JSON}" | get_json_int_value id)"
+    if [[ ${API} -eq 1 ]]; then
+      ACCOUNT_URL="${CA_REG}/${ACCOUNT_ID}"
+    else
+      ACCOUNT_URL="${CA_ACCOUNT}/${ACCOUNT_ID}"
+    fi
+  else
+    echo "Fetching missing account information from CA..."
+    if [[ ${API} -eq 1 ]]; then
+      _exiterr "This is not implemented for ACMEv1! Consider switching to ACMEv2 :)"
+    else
+      ACCOUNT_URL="$(signed_request "${CA_NEW_ACCOUNT}" '{"onlyReturnExisting": true}' 4>&1 | grep ^Location: | awk '{print $2}' | tr -d '\r\n')"
+      ACCOUNT_INFO="$(signed_request "${ACCOUNT_URL}" '{}')"
+    fi
+    ACCOUNT_ID="${ACCOUNT_URL##*/}"
+    echo "${ACCOUNT_INFO}" > "${ACCOUNT_KEY_JSON}"
+  fi
 }
 
 # Different sed version for different os types...
 _sed() {
-  if [[ "${OSTYPE}" = "Linux" ]]; then
+  if [[ "${OSTYPE}" = "Linux" || "${OSTYPE:0:5}" = "MINGW" ]]; then
     sed -r "${@}"
   else
     sed -E "${@}"
@@ -289,7 +438,7 @@
 # Encode data as url-safe formatted base64
 urlbase64() {
   # urlbase64: base64 encoded string with '+' replaced with '-' and '/' replaced with '_'
-  openssl base64 -e | tr -d '\n\r' | _sed -e 's:=*$::g' -e 'y:+/:-_:'
+  "${OPENSSL}" base64 -e | tr -d '\n\r' | _sed -e 's:=*$::g' -e 'y:+/:-_:'
 }
 
 # Convert hex string to binary data
@@ -305,11 +454,39 @@
   sed -n "${filter}"
 }
 
+# Get array value from json dictionary
+get_json_array_value() {
+  local filter
+  filter=$(printf 's/.*"%s": *\\[\([^]]*\)\\].*/\\1/p' "$1")
+  sed -n "${filter}"
+}
+
+# Get sub-dictionary from json
+get_json_dict_value() {
+  local filter
+  filter=$(printf 's/.*"%s": *{\([^}]*\)}.*/\\1/p' "$1")
+  sed -n "${filter}"
+}
+
+# Get integer value from json
+get_json_int_value() {
+  local filter
+  filter=$(printf 's/.*"%s": *\([0-9]*\).*/\\1/p' "$1")
+  sed -n "${filter}"
+}
+
+rm_json_arrays() {
+  local filter
+  filter='s/\[[^][]*\]/null/g'
+  # remove three levels of nested arrays
+  sed -e "${filter}" -e "${filter}" -e "${filter}"
+}
+
 # OpenSSL writes to stderr/stdout even when there are no errors. So just
 # display the output if the exit code was != 0 to simplify debugging.
 _openssl() {
   set +e
-  out="$(openssl "${@}" 2>&1)"
+  out="$("${OPENSSL}" "${@}" 2>&1)"
   res=$?
   set -e
   if [[ ${res} -ne 0 ]]; then
@@ -325,6 +502,7 @@
 # Send http(s) request with specified method
 http_request() {
   tempcont="$(_mktemp)"
+  tempheaders="$(_mktemp)"
 
   if [[ -n "${IP_VERSION:-}" ]]; then
       ip_version="-${IP_VERSION}"
@@ -332,13 +510,14 @@
 
   set +e
   if [[ "${1}" = "head" ]]; then
-    statuscode="$(curl ${ip_version:-} -s -w "%{http_code}" -o "${tempcont}" "${2}" -I)"
+    statuscode="$(curl ${ip_version:-} ${CURL_OPTS} -A "dehydrated/${VERSION} curl/${CURL_VERSION}" -s -w "%{http_code}" -o "${tempcont}" "${2}" -I)"
+    touch "${tempheaders}"
     curlret="${?}"
   elif [[ "${1}" = "get" ]]; then
-    statuscode="$(curl ${ip_version:-} -s -w "%{http_code}" -o "${tempcont}" "${2}")"
+    statuscode="$(curl ${ip_version:-} ${CURL_OPTS} -A "dehydrated/${VERSION} curl/${CURL_VERSION}" -L -s -w "%{http_code}" -o "${tempcont}" -D "${tempheaders}" "${2}")"
     curlret="${?}"
   elif [[ "${1}" = "post" ]]; then
-    statuscode="$(curl ${ip_version:-} -s -w "%{http_code}" -o "${tempcont}" "${2}" -d "${3}")"
+    statuscode="$(curl ${ip_version:-} ${CURL_OPTS} -A "dehydrated/${VERSION} curl/${CURL_VERSION}" -s -w "%{http_code}" -o "${tempcont}" "${2}" -D "${tempheaders}" -H 'Content-Type: application/jose+json' -d "${3}")"
     curlret="${?}"
   else
     set -e
@@ -351,26 +530,44 @@
   fi
 
   if [[ ! "${statuscode:0:1}" = "2" ]]; then
-    echo "  + ERROR: An error occurred while sending ${1}-request to ${2} (Status ${statuscode})" >&2
-    echo >&2
-    echo "Details:" >&2
-    cat "${tempcont}" >&2
-    echo >&2
-    echo >&2
-    rm -f "${tempcont}"
+    # check for existing registration warning
+    if [[ "${API}" = "1" ]] && [[ -n "${CA_NEW_REG:-}" ]] && [[ "${2}" = "${CA_NEW_REG:-}" ]] && [[ "${statuscode}" = "409" ]] && grep -q "Registration key is already in use" "${tempcont}"; then
+      # do nothing
+      :
+    # check for already-revoked warning
+    elif [[ -n "${CA_REVOKE_CERT:-}" ]] && [[ "${2}" = "${CA_REVOKE_CERT:-}" ]] && [[ "${statuscode}" = "409" ]]; then
+      grep -q "Certificate already revoked" "${tempcont}" && return
+    else
+      echo "  + ERROR: An error occurred while sending ${1}-request to ${2} (Status ${statuscode})" >&2
+      echo >&2
+      echo "Details:" >&2
+      cat "${tempheaders}" >&2
+      cat "${tempcont}" >&2
+      echo >&2
+      echo >&2
 
-    # Wait for hook script to clean the challenge if used
-    if [[ -n "${HOOK}" ]] && [[ "${HOOK_CHAIN}" != "yes" ]] && [[ -n "${challenge_token:+set}" ]]; then
-      "${HOOK}" "clean_challenge" '' "${challenge_token}" "${keyauth}"
-    fi
+      # An exclusive hook for the {1}-request error might be useful (e.g., for sending an e-mail to admins)
+      if [[ -n "${HOOK}" ]]; then
+        errtxt="$(cat ${tempcont})"
+        errheaders="$(cat ${tempheaders})"
+        "${HOOK}" "request_failure" "${statuscode}" "${errtxt}" "${1}" "${errheaders}"
+      fi
 
-    # remove temporary domains.txt file if used
-    [[ -n "${PARAM_DOMAIN:-}" && -n "${DOMAINS_TXT:-}" ]] && rm "${DOMAINS_TXT}"
-    exit 1
+      rm -f "${tempcont}"
+      rm -f "${tempheaders}"
+
+      # remove temporary domains.txt file if used
+      [[ -n "${PARAM_DOMAIN:-}" && -n "${DOMAINS_TXT:-}" ]] && rm "${DOMAINS_TXT}"
+      exit 1
+    fi
   fi
 
+  if { true >&4; } 2>/dev/null; then
+    cat "${tempheaders}" >&4
+  fi
   cat "${tempcont}"
   rm -f "${tempcont}"
+  rm -f "${tempheaders}"
 }
 
 # Send signed request
@@ -379,20 +576,39 @@
   payload64="$(printf '%s' "${2}" | urlbase64)"
 
   # Retrieve nonce from acme-server
-  nonce="$(http_request head "${CA}" | grep Replay-Nonce: | awk -F ': ' '{print $2}' | tr -d '\n\r')"
+  if [[ ${API} -eq 1 ]]; then
+    nonce="$(http_request head "${CA}" | grep Replay-Nonce: | awk -F ': ' '{print $2}' | tr -d '\n\r')"
+  else
+    nonce="$(http_request head "${CA_NEW_NONCE}" | grep Replay-Nonce: | awk -F ': ' '{print $2}' | tr -d '\n\r')"
+  fi
 
   # Build header with just our public key and algorithm information
   header='{"alg": "RS256", "jwk": {"e": "'"${pubExponent64}"'", "kty": "RSA", "n": "'"${pubMod64}"'"}}'
 
-  # Build another header which also contains the previously received nonce and encode it as urlbase64
-  protected='{"alg": "RS256", "jwk": {"e": "'"${pubExponent64}"'", "kty": "RSA", "n": "'"${pubMod64}"'"}, "nonce": "'"${nonce}"'"}'
-  protected64="$(printf '%s' "${protected}" | urlbase64)"
+  if [[ ${API} -eq 1 ]]; then
+    # Build another header which also contains the previously received nonce and encode it as urlbase64
+    protected='{"alg": "RS256", "jwk": {"e": "'"${pubExponent64}"'", "kty": "RSA", "n": "'"${pubMod64}"'"}, "nonce": "'"${nonce}"'"}'
+    protected64="$(printf '%s' "${protected}" | urlbase64)"
+  else
+    # Build another header which also contains the previously received nonce and url and encode it as urlbase64
+    if [[ -n "${ACCOUNT_URL:-}" ]]; then
+      protected='{"alg": "RS256", "kid": "'"${ACCOUNT_URL}"'", "url": "'"${1}"'", "nonce": "'"${nonce}"'"}'
+    else
+      protected='{"alg": "RS256", "jwk": {"e": "'"${pubExponent64}"'", "kty": "RSA", "n": "'"${pubMod64}"'"}, "url": "'"${1}"'", "nonce": "'"${nonce}"'"}'
+    fi
+    protected64="$(printf '%s' "${protected}" | urlbase64)"
+  fi
 
   # Sign header with nonce and our payload with our private key and encode signature as urlbase64
-  signed64="$(printf '%s' "${protected64}.${payload64}" | openssl dgst -sha256 -sign "${ACCOUNT_KEY}" | urlbase64)"
+  signed64="$(printf '%s' "${protected64}.${payload64}" | "${OPENSSL}" dgst -sha256 -sign "${ACCOUNT_KEY}" | urlbase64)"
 
-  # Send header + extended header + payload + signature to the acme-server
-  data='{"header": '"${header}"', "protected": "'"${protected64}"'", "payload": "'"${payload64}"'", "signature": "'"${signed64}"'"}'
+  if [[ ${API} -eq 1 ]]; then
+    # Send header + extended header + payload + signature to the acme-server
+    data='{"header": '"${header}"', "protected": "'"${protected64}"'", "payload": "'"${payload64}"'", "signature": "'"${signed64}"'"}'
+  else
+    # Send extended header + payload + signature to the acme-server
+    data='{"protected": "'"${protected64}"'", "payload": "'"${payload64}"'", "signature": "'"${signed64}"'"}'
+  fi
 
   http_request post "${1}" "${data}"
 }
@@ -402,29 +618,28 @@
 extract_altnames() {
   csr="${1}" # the CSR itself (not a file)
 
-  if ! <<<"${csr}" openssl req -verify -noout 2>/dev/null; then
+  if ! <<<"${csr}" "${OPENSSL}" req -verify -noout 2>/dev/null; then
     _exiterr "Certificate signing request isn't valid"
   fi
 
-  reqtext="$( <<<"${csr}" openssl req -noout -text )"
+  reqtext="$( <<<"${csr}" "${OPENSSL}" req -noout -text )"
   if <<<"${reqtext}" grep -q '^[[:space:]]*X509v3 Subject Alternative Name:[[:space:]]*$'; then
     # SANs used, extract these
-    altnames="$( <<<"${reqtext}" grep -A1 '^[[:space:]]*X509v3 Subject Alternative Name:[[:space:]]*$' | tail -n1 )"
+    altnames="$( <<<"${reqtext}" awk '/X509v3 Subject Alternative Name:/{print;getline;print;}' | tail -n1 )"
     # split to one per line:
     # shellcheck disable=SC1003
     altnames="$( <<<"${altnames}" _sed -e 's/^[[:space:]]*//; s/, /\'$'\n''/g' )"
     # we can only get DNS: ones signed
-    if grep -qv '^DNS:' <<<"${altnames}"; then
+    if grep -qEv '^(DNS|othername):' <<<"${altnames}"; then
       _exiterr "Certificate signing request contains non-DNS Subject Alternative Names"
     fi
     # strip away the DNS: prefix
-    altnames="$( <<<"${altnames}" _sed -e 's/^DNS://' )"
-    echo "${altnames}"
-
+    altnames="$( <<<"${altnames}" _sed -e 's/^(DNS:|othername:<unsupported>)//' )"
+    printf "%s" "${altnames}" | tr '\n' ' '
   else
     # No SANs, extract CN
-    altnames="$( <<<"${reqtext}" grep '^[[:space:]]*Subject:' | _sed -e 's/.* CN=([^ /,]*).*/\1/' )"
-    echo "${altnames}"
+    altnames="$( <<<"${reqtext}" grep '^[[:space:]]*Subject:' | _sed -e 's/.* CN ?= ?([^ /,]*).*/\1/' )"
+    printf "%s" "${altnames}"
   fi
 }
 
@@ -439,79 +654,140 @@
   fi
 
   shift 1 || true
-  altnames="${*:-}"
-  if [ -z "${altnames}" ]; then
-    altnames="$( extract_altnames "${csr}" )"
-  fi
+  export altnames="${*}"
 
-  if [[ -z "${CA_NEW_AUTHZ}" ]] || [[ -z "${CA_NEW_CERT}" ]]; then
+  if [[ ${API} -eq 1 ]]; then
+    if [[ -z "${CA_NEW_AUTHZ}" ]] || [[ -z "${CA_NEW_CERT}" ]]; then
+      _exiterr "Certificate authority doesn't allow certificate signing"
+    fi
+  elif [[ ${API} -eq 2 ]] && [[ -z "${CA_NEW_ORDER}" ]]; then
     _exiterr "Certificate authority doesn't allow certificate signing"
   fi
 
-  local idx=0
   if [[ -n "${ZSH_VERSION:-}" ]]; then
-    local -A challenge_uris challenge_tokens keyauths deploy_args
+    local -A challenge_names challenge_uris challenge_tokens authorizations keyauths deploy_args
   else
-    local -a challenge_uris challenge_tokens keyauths deploy_args
+    local -a challenge_names challenge_uris challenge_tokens authorizations keyauths deploy_args
   fi
 
-  # Request challenges
-  for altname in ${altnames}; do
-    # Ask the acme-server for new challenge token and extract them from the resulting json block
-    echo " + Requesting challenge for ${altname}..."
-    response="$(signed_request "${CA_NEW_AUTHZ}" '{"resource": "new-authz", "identifier": {"type": "dns", "value": "'"${altname}"'"}}' | clean_json)"
+  # Initial step: Find which authorizations we're dealing with
+  if [[ ${API} -eq 2 ]]; then
+    # Request new order and store authorization URIs
+    local challenge_identifiers=""
+    for altname in ${altnames}; do
+      challenge_identifiers+="$(printf '{"type": "dns", "value": "%s"}, ' "${altname}")"
+    done
+    challenge_identifiers="[${challenge_identifiers%, }]"
 
-    challenges="$(printf '%s\n' "${response}" | sed -n 's/.*\("challenges":[^\[]*\[[^]]*]\).*/\1/p')"
-    repl=$'\n''{' # fix syntax highlighting in Vim
-    challenge="$(printf "%s" "${challenges//\{/${repl}}" | grep \""${CHALLENGETYPE}"\")"
-    challenge_token="$(printf '%s' "${challenge}" | get_json_string_value token | _sed 's/[^A-Za-z0-9_\-]/_/g')"
-    challenge_uri="$(printf '%s' "${challenge}" | get_json_string_value uri)"
+    echo " + Requesting new certificate order from CA..."
+    result="$(signed_request "${CA_NEW_ORDER}" '{"identifiers": '"${challenge_identifiers}"'}')"
 
-    if [[ -z "${challenge_token}" ]] || [[ -z "${challenge_uri}" ]]; then
-      _exiterr "Can't retrieve challenges (${response})"
+    order_authorizations="$(echo ${result} | get_json_array_value authorizations)"
+    finalize="$(echo "${result}" | get_json_string_value finalize)"
+
+    local idx=0
+    for uri in ${order_authorizations}; do
+      authorizations[${idx}]="$(echo "${uri}" | _sed -e 's/\"(.*)".*/\1/')"
+      idx=$((idx+1))
+    done
+    echo " + Received ${idx} authorizations URLs from the CA"
+  else
+    # Copy $altnames to $authorizations (just doing this to reduce duplicate code later on)
+    local idx=0
+    for altname in ${altnames}; do
+      authorizations[${idx}]="${altname}"
+      idx=$((idx+1))
+    done
+  fi
+
+  # Check if authorizations are valid and gather challenge information for pending authorizations
+  local idx=0
+  for authorization in ${authorizations[*]}; do
+    if [[ "${API}" -eq 2 ]]; then
+      # Receive authorization ($authorization is authz uri)
+      response="$(http_request get "$(echo "${authorization}" | _sed -e 's/\"(.*)".*/\1/')" | clean_json)"
+      identifier="$(echo "${response}" | get_json_dict_value identifier | get_json_string_value value)"
+      echo " + Handling authorization for ${identifier}"
+    else
+      # Request new authorization ($authorization is altname)
+      identifier="${authorization}"
+      echo " + Requesting authorization for ${identifier}..."
+      response="$(signed_request "${CA_NEW_AUTHZ}" '{"resource": "new-authz", "identifier": {"type": "dns", "value": "'"${identifier}"'"}}' | clean_json)"
+    fi
+
+    # Check if authorization has already been validated
+    if [ "$(echo "${response}" | _sed 's/"challenges": \[\{.*\}\]//' | get_json_string_value status)" = "valid" ] && [ ! "${PARAM_FORCE:-no}" = "yes" ]; then
+      echo " + Found valid authorization for ${identifier}"
+      continue
+    fi
+
+    # Find challenge in authorization
+    challenges="$(echo "${response}" | _sed 's/.*"challenges": \[(\{.*\})\].*/\1/')"
+    challenge="$(<<<"${challenges}" _sed -e 's/^[^\[]+\[(.+)\]$/\1/' -e 's/\}(, (\{)|(\]))/}\'$'\n''\2/g' | grep \""${CHALLENGETYPE}"\" || true)"
+    if [ -z "${challenge}" ]; then
+      allowed_validations="$(grep -Eo '"type": "[^"]+"' <<< "${challenges}" | grep -Eo ' "[^"]+"' | _sed -e 's/"//g' -e 's/^ //g')"
+      _exiterr "Validating this certificate is not possible using ${CHALLENGETYPE}. Possible validation methods are: ${allowed_validations}"
+    fi
+
+    # Gather challenge information
+    challenge_names[${idx}]="${identifier}"
+    challenge_tokens[${idx}]="$(echo "${challenge}" | get_json_string_value token)"
+    if [[ ${API} -eq 2 ]]; then
+      challenge_uris[${idx}]="$(echo "${challenge}" | _sed 's/"validationRecord": ?\[[^]]+\]//g' | get_json_string_value url)"
+    else
+      challenge_uris[${idx}]="$(echo "${challenge}" | _sed 's/"validationRecord": ?\[[^]]+\]//g' | get_json_string_value uri)"
     fi
 
-    # Challenge response consists of the challenge token and the thumbprint of our public certificate
-    keyauth="${challenge_token}.${thumbprint}"
+    # Prepare challenge tokens and deployment parameters
+    keyauth="${challenge_tokens[${idx}]}.${thumbprint}"
 
     case "${CHALLENGETYPE}" in
       "http-01")
         # Store challenge response in well-known location and make world-readable (so that a webserver can access it)
-        printf '%s' "${keyauth}" > "${WELLKNOWN}/${challenge_token}"
-        chmod a+r "${WELLKNOWN}/${challenge_token}"
+        printf '%s' "${keyauth}" > "${WELLKNOWN}/${challenge_tokens[${idx}]}"
+        chmod a+r "${WELLKNOWN}/${challenge_tokens[${idx}]}"
         keyauth_hook="${keyauth}"
         ;;
       "dns-01")
         # Generate DNS entry content for dns-01 validation
-        keyauth_hook="$(printf '%s' "${keyauth}" | openssl dgst -sha256 -binary | urlbase64)"
+        keyauth_hook="$(printf '%s' "${keyauth}" | "${OPENSSL}" dgst -sha256 -binary | urlbase64)"
         ;;
     esac
 
-    challenge_uris[${idx}]="${challenge_uri}"
     keyauths[${idx}]="${keyauth}"
-    challenge_tokens[${idx}]="${challenge_token}"
-    # Note: assumes args will never have spaces!
-    deploy_args[${idx}]="${altname} ${challenge_token} ${keyauth_hook}"
+    deploy_args[${idx}]="${identifier} ${challenge_tokens[${idx}]} ${keyauth_hook}"
+
     idx=$((idx+1))
   done
+  local num_pending_challenges=${idx}
+  echo " + ${num_pending_challenges} pending challenge(s)"
 
-  # Wait for hook script to deploy the challenges if used
-  # shellcheck disable=SC2068
-  [[ -n "${HOOK}" ]] && [[ "${HOOK_CHAIN}" = "yes" ]] && "${HOOK}" "deploy_challenge" ${deploy_args[@]}
+  # Deploy challenge tokens
+  if [[ ${num_pending_challenges} -ne 0 ]]; then
+    echo " + Deploying challenge tokens..."
+    if [[ -n "${HOOK}" ]] && [[ "${HOOK_CHAIN}" = "yes" ]]; then
+      "${HOOK}" "deploy_challenge" ${deploy_args[@]}
+    elif [[ -n "${HOOK}" ]]; then
+      # Run hook script to deploy the challenge token
+      local idx=0
+      while [ ${idx} -lt ${num_pending_challenges} ]; do
+        "${HOOK}" "deploy_challenge" ${deploy_args[${idx}]}
+        idx=$((idx+1))
+      done
+    fi
+  fi
 
-  # Respond to challenges
-  idx=0
-  for altname in ${altnames}; do
-    challenge_token="${challenge_tokens[${idx}]}"
-    keyauth="${keyauths[${idx}]}"
-
-    # Wait for hook script to deploy the challenge if used
-    # shellcheck disable=SC2086
-    [[ -n "${HOOK}" ]] && [[ "${HOOK_CHAIN}" != "yes" ]] && "${HOOK}" "deploy_challenge" ${deploy_args[${idx}]}
+  # Validate pending challenges
+  local idx=0
+  while [ ${idx} -lt ${num_pending_challenges} ]; do
+    echo " + Responding to challenge for ${challenge_names[${idx}]} authorization..."
 
     # Ask the acme-server to verify our challenge and wait until it is no longer pending
-    echo " + Responding to challenge for ${altname}..."
-    result="$(signed_request "${challenge_uris[${idx}]}" '{"resource": "challenge", "keyAuthorization": "'"${keyauth}"'"}' | clean_json)"
+    if [[ ${API} -eq 1 ]]; then
+      result="$(signed_request "${challenge_uris[${idx}]}" '{"resource": "challenge", "keyAuthorization": "'"${keyauths[${idx}]}"'"}' | clean_json)"
+    else
+      result="$(signed_request "${challenge_uris[${idx}]}" '{"keyAuthorization": "'"${keyauths[${idx}]}"'"}' | clean_json)"
+    fi
 
     reqstatus="$(printf '%s\n' "${result}" | get_json_string_value status)"
 
@@ -521,43 +797,49 @@
       reqstatus="$(printf '%s\n' "${result}" | get_json_string_value status)"
     done
 
-    [[ "${CHALLENGETYPE}" = "http-01" ]] && rm -f "${WELLKNOWN}/${challenge_token}"
-
-    # Wait for hook script to clean the challenge if used
-    if [[ -n "${HOOK}" ]] && [[ "${HOOK_CHAIN}" != "yes" ]] && [[ -n "${challenge_token}" ]]; then
-      # shellcheck disable=SC2086
-      "${HOOK}" "clean_challenge" ${deploy_args[${idx}]}
-    fi
-    idx=$((idx+1))
+    [[ "${CHALLENGETYPE}" = "http-01" ]] && rm -f "${WELLKNOWN}/${challenge_tokens[${idx}]}"
 
     if [[ "${reqstatus}" = "valid" ]]; then
       echo " + Challenge is valid!"
     else
+      [[ -n "${HOOK}" ]] && "${HOOK}" "invalid_challenge" "${altname}" "${result}"
       break
     fi
+    idx=$((idx+1))
   done
 
-  # Wait for hook script to clean the challenges if used
-  # shellcheck disable=SC2068
-  [[ -n "${HOOK}" ]] && [[ "${HOOK_CHAIN}" = "yes" ]] && "${HOOK}" "clean_challenge" ${deploy_args[@]}
+  if [[ ${num_pending_challenges} -ne 0 ]]; then
+    echo " + Cleaning challenge tokens..."
 
-  if [[ "${reqstatus}" != "valid" ]]; then
-    # Clean up any remaining challenge_tokens if we stopped early
-    if [[ "${CHALLENGETYPE}" = "http-01" ]]; then
-      while [ ${idx} -lt ${#challenge_tokens[@]} ]; do
-        rm -f "${WELLKNOWN}/${challenge_tokens[${idx}]}"
-        idx=$((idx+1))
-      done
-    fi
+    # Clean challenge tokens using chained hook
+    [[ -n "${HOOK}" ]] && [[ "${HOOK_CHAIN}" = "yes" ]] && "${HOOK}" "clean_challenge" ${deploy_args[@]}
+
+    # Clean remaining challenge tokens if validation has failed
+    local idx=0
+    while [ ${idx} -lt ${num_pending_challenges} ]; do
+      # Delete challenge file
+      [[ "${CHALLENGETYPE}" = "http-01" ]] && rm -f "${WELLKNOWN}/${challenge_tokens[${idx}]}"
+      # Clean challenge token using non-chained hook
+      [[ -n "${HOOK}" ]] && [[ "${HOOK_CHAIN}" != "yes" ]] && "${HOOK}" "clean_challenge" ${deploy_args[${idx}]}
+      idx=$((idx+1))
+    done
 
-    _exiterr "Challenge is invalid! (returned: ${reqstatus}) (result: ${result})"
+    if [[ "${reqstatus}" != "valid" ]]; then
+      echo " + Challenge validation has failed :("
+      _exiterr "Challenge is invalid! (returned: ${reqstatus}) (result: ${result})"
+    fi
   fi
 
   # Finally request certificate from the acme-server and store it in cert-${timestamp}.pem and link from cert.pem
   echo " + Requesting certificate..."
-  csr64="$( <<<"${csr}" openssl req -outform DER | urlbase64)"
-  crt64="$(signed_request "${CA_NEW_CERT}" '{"resource": "new-cert", "csr": "'"${csr64}"'"}' | openssl base64 -e)"
-  crt="$( printf -- '-----BEGIN CERTIFICATE-----\n%s\n-----END CERTIFICATE-----\n' "${crt64}" )"
+  csr64="$( <<<"${csr}" "${OPENSSL}" req -config "${OPENSSL_CNF}" -outform DER | urlbase64)"
+  if [[ ${API} -eq 1 ]]; then
+    crt64="$(signed_request "${CA_NEW_CERT}" '{"resource": "new-cert", "csr": "'"${csr64}"'"}' | "${OPENSSL}" base64 -e)"
+    crt="$( printf -- '-----BEGIN CERTIFICATE-----\n%s\n-----END CERTIFICATE-----\n' "${crt64}" )"
+  else
+    result="$(signed_request "${finalize}" '{"csr": "'"${csr64}"'"}' | clean_json | get_json_string_value certificate)"
+    crt="$(http_request get "${result}")"
+  fi
 
   # Try to load the certificate to detect corruption
   echo " + Checking certificate..."
@@ -569,88 +851,298 @@
   echo " + Done!"
 }
 
+# grep issuer cert uri from certificate
+get_issuer_cert_uri() {
+  certificate="${1}"
+  "${OPENSSL}" x509 -in "${certificate}" -noout -text | (grep 'CA Issuers - URI:' | cut -d':' -f2-) || true
+}
+
+get_issuer_hash() {
+  certificate="${1}"
+  "${OPENSSL}" x509 -in "${certificate}" -noout -issuer_hash
+}
+
+get_ocsp_url() {
+  certificate="${1}"
+  "${OPENSSL}" x509 -in "${certificate}" -noout -ocsp_uri
+}
+
+# walk certificate chain, retrieving all intermediate certificates
+walk_chain() {
+  local certificate
+  certificate="${1}"
+
+  local issuer_cert_uri
+  issuer_cert_uri="${2:-}"
+  if [[ -z "${issuer_cert_uri}" ]]; then issuer_cert_uri="$(get_issuer_cert_uri "${certificate}")"; fi
+  if [[ -n "${issuer_cert_uri}" ]]; then
+    # create temporary files
+    local tmpcert
+    local tmpcert_raw
+    tmpcert_raw="$(_mktemp)"
+    tmpcert="$(_mktemp)"
+
+    # download certificate
+    http_request get "${issuer_cert_uri}" > "${tmpcert_raw}"
+
+    # PEM
+    if grep -q "BEGIN CERTIFICATE" "${tmpcert_raw}"; then mv "${tmpcert_raw}" "${tmpcert}"
+    # DER
+    elif "${OPENSSL}" x509 -in "${tmpcert_raw}" -inform DER -out "${tmpcert}" -outform PEM 2> /dev/null > /dev/null; then :
+    # PKCS7
+    elif "${OPENSSL}" pkcs7 -in "${tmpcert_raw}" -inform DER -out "${tmpcert}" -outform PEM -print_certs 2> /dev/null > /dev/null; then :
+    # Unknown certificate type
+    else _exiterr "Unknown certificate type in chain"
+    fi
+
+    local next_issuer_cert_uri
+    next_issuer_cert_uri="$(get_issuer_cert_uri "${tmpcert}")"
+    if [[ -n "${next_issuer_cert_uri}" ]]; then
+      printf "\n%s\n" "${issuer_cert_uri}"
+      cat "${tmpcert}"
+      walk_chain "${tmpcert}" "${next_issuer_cert_uri}"
+    fi
+    rm -f "${tmpcert}" "${tmpcert_raw}"
+  fi
+}
+
 # Create certificate for domain(s)
 sign_domain() {
+  local certdir="${1}"
+  shift
+  timestamp="${1}"
+  shift
   domain="${1}"
   altnames="${*}"
-  timestamp="$(date +%s)"
+
+  export altnames
 
   echo " + Signing domains..."
-  if [[ -z "${CA_NEW_AUTHZ}" ]] || [[ -z "${CA_NEW_CERT}" ]]; then
+  if [[ ${API} -eq 1 ]]; then
+    if [[ -z "${CA_NEW_AUTHZ}" ]] || [[ -z "${CA_NEW_CERT}" ]]; then
+      _exiterr "Certificate authority doesn't allow certificate signing"
+    fi
+  elif [[ ${API} -eq 2 ]] && [[ -z "${CA_NEW_ORDER}" ]]; then
     _exiterr "Certificate authority doesn't allow certificate signing"
   fi
 
-  # If there is no existing certificate directory => make it
-  if [[ ! -e "${CERTDIR}/${domain}" ]]; then
-    echo " + Creating new directory ${CERTDIR}/${domain} ..."
-    mkdir -p "${CERTDIR}/${domain}" || _exiterr "Unable to create directory ${CERTDIR}/${domain}"
-  fi
-
-  privkey="privkey.pem"
-  # generate a new private key if we need or want one
-  if [[ ! -r "${CERTDIR}/${domain}/privkey.pem" ]] || [[ "${PRIVATE_KEY_RENEW}" = "yes" ]]; then
-    echo " + Generating private key..."
-    privkey="privkey-${timestamp}.pem"
-    case "${KEY_ALGO}" in
-      rsa) _openssl genrsa -out "${CERTDIR}/${domain}/privkey-${timestamp}.pem" "${KEYSIZE}";;
-      prime256v1|secp384r1) _openssl ecparam -genkey -name "${KEY_ALGO}" -out "${CERTDIR}/${domain}/privkey-${timestamp}.pem";;
-    esac
-  fi
-
-  # Generate signing request config and the actual signing request
-  echo " + Generating signing request..."
-  SAN=""
-  for altname in ${altnames}; do
-    SAN+="DNS:${altname}, "
-  done
-  SAN="${SAN%%, }"
-  local tmp_openssl_cnf
-  tmp_openssl_cnf="$(_mktemp)"
-  cat "${OPENSSL_CNF}" > "${tmp_openssl_cnf}"
-  printf "[SAN]\nsubjectAltName=%s" "${SAN}" >> "${tmp_openssl_cnf}"
-  if [ "${OCSP_MUST_STAPLE}" = "yes" ]; then
-    printf "\n1.3.6.1.5.5.7.1.24=DER:30:03:02:01:05" >> "${tmp_openssl_cnf}"
+  local privkey="privkey.pem"
+  if [[ ! -e "${certdir}/cert-${timestamp}.csr" ]]; then
+    # generate a new private key if we need or want one
+    if [[ ! -r "${certdir}/privkey.pem" ]] || [[ "${PRIVATE_KEY_RENEW}" = "yes" ]]; then
+      echo " + Generating private key..."
+      privkey="privkey-${timestamp}.pem"
+      local tmp_privkey="$(_mktemp)"
+      case "${KEY_ALGO}" in
+        rsa) _openssl genrsa -out "${tmp_privkey}" "${KEYSIZE}";;
+        prime256v1|secp384r1) _openssl ecparam -genkey -name "${KEY_ALGO}" -out "${tmp_privkey}";;
+      esac
+      cat "${tmp_privkey}" > "${certdir}/privkey-${timestamp}.pem"
+      rm "${tmp_privkey}"
+    fi
+    # move rolloverkey into position (if any)
+    if [[ -r "${certdir}/privkey.pem" && -r "${certdir}/privkey.roll.pem" && "${PRIVATE_KEY_RENEW}" = "yes" && "${PRIVATE_KEY_ROLLOVER}" = "yes" ]]; then
+      echo " + Moving Rolloverkey into position....  "
+      mv "${certdir}/privkey.roll.pem" "${certdir}/privkey-tmp.pem"
+      mv "${certdir}/privkey-${timestamp}.pem" "${certdir}/privkey.roll.pem"
+      mv "${certdir}/privkey-tmp.pem" "${certdir}/privkey-${timestamp}.pem"
+    fi
+    # generate a new private rollover key if we need or want one
+    if [[ ! -r "${certdir}/privkey.roll.pem" && "${PRIVATE_KEY_ROLLOVER}" = "yes" && "${PRIVATE_KEY_RENEW}" = "yes" ]]; then
+      echo " + Generating private rollover key..."
+      case "${KEY_ALGO}" in
+        rsa) _openssl genrsa -out "${certdir}/privkey.roll.pem" "${KEYSIZE}";;
+        prime256v1|secp384r1) _openssl ecparam -genkey -name "${KEY_ALGO}" -out "${certdir}/privkey.roll.pem";;
+      esac
+    fi
+    # delete rolloverkeys if disabled
+    if [[ -r "${certdir}/privkey.roll.pem" && ! "${PRIVATE_KEY_ROLLOVER}" = "yes" ]]; then
+      echo " + Removing Rolloverkey (feature disabled)..."
+      rm -f "${certdir}/privkey.roll.pem"
+    fi
+
+    # Generate signing request config and the actual signing request
+    echo " + Generating signing request..."
+    SAN=""
+    for altname in ${altnames}; do
+      SAN="${SAN}DNS:${altname}, "
+    done
+    SAN="${SAN%%, }"
+    local tmp_openssl_cnf
+    tmp_openssl_cnf="$(_mktemp)"
+    cat "${OPENSSL_CNF}" > "${tmp_openssl_cnf}"
+    printf "[SAN]\nsubjectAltName=%s" "${SAN}" >> "${tmp_openssl_cnf}"
+    if [ "${OCSP_MUST_STAPLE}" = "yes" ]; then
+      printf "\n1.3.6.1.5.5.7.1.24=DER:30:03:02:01:05" >> "${tmp_openssl_cnf}"
+    fi
+    SUBJ="/CN=${domain}/"
+    if [[ "${OSTYPE:0:5}" = "MINGW" ]]; then
+      # The subject starts with a /, so MSYS will assume it's a path and convert
+      # it unless we escape it with another one:
+      SUBJ="/${SUBJ}"
+    fi
+    "${OPENSSL}" req -new -sha256 -key "${certdir}/${privkey}" -out "${certdir}/cert-${timestamp}.csr" -subj "${SUBJ}" -reqexts SAN -config "${tmp_openssl_cnf}"
+    rm -f "${tmp_openssl_cnf}"
   fi
-  openssl req -new -sha256 -key "${CERTDIR}/${domain}/${privkey}" -out "${CERTDIR}/${domain}/cert-${timestamp}.csr" -subj "/CN=${domain}/" -reqexts SAN -config "${tmp_openssl_cnf}"
-  rm -f "${tmp_openssl_cnf}"
 
-  crt_path="${CERTDIR}/${domain}/cert-${timestamp}.pem"
+  crt_path="${certdir}/cert-${timestamp}.pem"
   # shellcheck disable=SC2086
-  sign_csr "$(< "${CERTDIR}/${domain}/cert-${timestamp}.csr" )" ${altnames} 3>"${crt_path}"
+  sign_csr "$(< "${certdir}/cert-${timestamp}.csr")" ${altnames} 3>"${crt_path}"
 
   # Create fullchain.pem
   echo " + Creating fullchain.pem..."
-  cat "${crt_path}" > "${CERTDIR}/${domain}/fullchain-${timestamp}.pem"
-  http_request get "$(openssl x509 -in "${CERTDIR}/${domain}/cert-${timestamp}.pem" -noout -text | grep 'CA Issuers - URI:' | cut -d':' -f2-)" > "${CERTDIR}/${domain}/chain-${timestamp}.pem"
-  if ! grep -q "BEGIN CERTIFICATE" "${CERTDIR}/${domain}/chain-${timestamp}.pem"; then
-    openssl x509 -in "${CERTDIR}/${domain}/chain-${timestamp}.pem" -inform DER -out "${CERTDIR}/${domain}/chain-${timestamp}.pem" -outform PEM
+  if [[ ${API} -eq 1 ]]; then
+    cat "${crt_path}" > "${certdir}/fullchain-${timestamp}.pem"
+    local issuer_hash
+    issuer_hash="$(get_issuer_hash "${crt_path}")"
+    if [ -e "${CHAINCACHE}/${issuer_hash}.chain" ]; then
+      echo " + Using cached chain!"
+      cat "${CHAINCACHE}/${issuer_hash}.chain" > "${certdir}/chain-${timestamp}.pem"
+    else
+      echo " + Walking chain..."
+      local issuer_cert_uri
+      issuer_cert_uri="$(get_issuer_cert_uri "${crt_path}" || echo "unknown")"
+      (walk_chain "${crt_path}" > "${certdir}/chain-${timestamp}.pem") || _exiterr "Walking chain has failed, your certificate has been created and can be found at ${crt_path}, the corresponding private key at ${privkey}. If you want you can manually continue on creating and linking all necessary files. If this error occurs again you should manually generate the certificate chain and place it under ${CHAINCACHE}/${issuer_hash}.chain (see ${issuer_cert_uri})"
+      cat "${certdir}/chain-${timestamp}.pem" > "${CHAINCACHE}/${issuer_hash}.chain"
+    fi
+    cat "${certdir}/chain-${timestamp}.pem" >> "${certdir}/fullchain-${timestamp}.pem"
+  else
+    tmpcert="$(_mktemp)"
+    tmpchain="$(_mktemp)"
+    awk '{print >out}; /----END CERTIFICATE-----/{out=tmpchain}' out="${tmpcert}" tmpchain="${tmpchain}" "${certdir}/cert-${timestamp}.pem"
+    mv "${certdir}/cert-${timestamp}.pem" "${certdir}/fullchain-${timestamp}.pem"
+    cat "${tmpcert}" > "${certdir}/cert-${timestamp}.pem"
+    cat "${tmpchain}" > "${certdir}/chain-${timestamp}.pem"
+    rm "${tmpcert}" "${tmpchain}"
   fi
-  cat "${CERTDIR}/${domain}/chain-${timestamp}.pem" >> "${CERTDIR}/${domain}/fullchain-${timestamp}.pem"
 
   # Update symlinks
-  [[ "${privkey}" = "privkey.pem" ]] || ln -sf "privkey-${timestamp}.pem" "${CERTDIR}/${domain}/privkey.pem"
+  [[ "${privkey}" = "privkey.pem" ]] || ln -sf "privkey-${timestamp}.pem" "${certdir}/privkey.pem"
 
-  ln -sf "chain-${timestamp}.pem" "${CERTDIR}/${domain}/chain.pem"
-  ln -sf "fullchain-${timestamp}.pem" "${CERTDIR}/${domain}/fullchain.pem"
-  ln -sf "cert-${timestamp}.csr" "${CERTDIR}/${domain}/cert.csr"
-  ln -sf "cert-${timestamp}.pem" "${CERTDIR}/${domain}/cert.pem"
+  ln -sf "chain-${timestamp}.pem" "${certdir}/chain.pem"
+  ln -sf "fullchain-${timestamp}.pem" "${certdir}/fullchain.pem"
+  ln -sf "cert-${timestamp}.csr" "${certdir}/cert.csr"
+  ln -sf "cert-${timestamp}.pem" "${certdir}/cert.pem"
 
   # Wait for hook script to clean the challenge and to deploy cert if used
-  export KEY_ALGO
-  [[ -n "${HOOK}" ]] && "${HOOK}" "deploy_cert" "${domain}" "${CERTDIR}/${domain}/privkey.pem" "${CERTDIR}/${domain}/cert.pem" "${CERTDIR}/${domain}/fullchain.pem" "${CERTDIR}/${domain}/chain.pem" "${timestamp}"
+  [[ -n "${HOOK}" ]] && "${HOOK}" "deploy_cert" "${domain}" "${certdir}/privkey.pem" "${certdir}/cert.pem" "${certdir}/fullchain.pem" "${certdir}/chain.pem" "${timestamp}"
 
   unset challenge_token
   echo " + Done!"
 }
 
+# Usage: --version (-v)
+# Description: Print version information
+command_version() {
+  load_config noverify
+
+  echo "Dehydrated by Lukas Schauer"
+  echo "https://dehydrated.io";
+  echo ""
+  echo "Dehydrated version: ${VERSION}"
+  revision="$(cd "${SCRIPTDIR}"; git rev-parse HEAD 2>/dev/null || echo "unknown")"
+  echo "GIT-Revision: ${revision}"
+  echo ""
+  if [[ "${OSTYPE}" = "FreeBSD" ]]; then
+    echo "OS: $(uname -sr)"
+  else
+    echo "OS: $(cat /etc/issue | grep -v ^$ | head -n1 | _sed 's/\\(r|n|l) .*//g')"
+  fi
+  echo "Used software:"
+  [[ -n "${BASH_VERSION:-}" ]] && echo " bash: ${BASH_VERSION}"
+  [[ -n "${ZSH_VERSION:-}" ]] && echo " zsh: ${ZSH_VERSION}"
+  echo " curl: $(curl --version 2>&1 | head -n1 | cut -d" " -f1-2)"
+  if [[ "${OSTYPE}" = "FreeBSD" ]]; then
+    echo " awk, sed, mktemp: FreeBSD base system versions"
+  else
+    echo " awk: $(awk -W version 2>&1 | head -n1)"
+    echo " sed: $(sed --version 2>&1 | head -n1)"
+    echo " mktemp: $(mktemp --version 2>&1 | head -n1)"
+  fi
+  echo " grep: $(grep --version 2>&1 | head -n1)"
+  echo " diff: $(diff --version 2>&1 | head -n1)"
+  echo " openssl: $("${OPENSSL}" version 2>&1)"
+
+  exit 0
+}
+
+# Usage: --register
+# Description: Register account key
+command_register() {
+  init_system
+  echo "+ Done!"
+  exit 0
+}
+
+# Usage: --account
+# Description: Update account contact information
+command_account() {
+  init_system
+  FAILED=false
+
+  NEW_ACCOUNT_KEY_JSON="$(_mktemp)"
+
+  # Check if we have the registration id
+  if [[ -z "${ACCOUNT_ID}" ]]; then
+    _exiterr "Error retrieving registration id."
+  fi
+
+  echo "+ Updating registration id: ${ACCOUNT_ID} contact information..."
+  if [[ ${API} -eq 1 ]]; then
+    # If an email for the contact has been provided then adding it to the registered account
+    if [[ -n "${CONTACT_EMAIL}" ]]; then
+      (signed_request "${ACCOUNT_URL}" '{"resource": "reg", "contact":["mailto:'"${CONTACT_EMAIL}"'"]}' > "${NEW_ACCOUNT_KEY_JSON}") || FAILED=true
+    else
+      (signed_request "${ACCOUNT_URL}" '{"resource": "reg", "contact":[]}' > "${NEW_ACCOUNT_KEY_JSON}") || FAILED=true
+    fi
+  else
+    # If an email for the contact has been provided then adding it to the registered account
+    if [[ -n "${CONTACT_EMAIL}" ]]; then
+      (signed_request "${ACCOUNT_URL}" '{"contact":["mailto:'"${CONTACT_EMAIL}"'"]}' > "${NEW_ACCOUNT_KEY_JSON}") || FAILED=true
+    else
+      (signed_request "${ACCOUNT_URL}" '{"contact":[]}' > "${NEW_ACCOUNT_KEY_JSON}") || FAILED=true
+    fi
+  fi
+
+  if [[ "${FAILED}" = "true" ]]; then
+    rm "${NEW_ACCOUNT_KEY_JSON}"
+    _exiterr "Error updating account information. See message above for more information."
+  fi
+  if diff -q "${NEW_ACCOUNT_KEY_JSON}" "${ACCOUNT_KEY_JSON}" > /dev/null; then
+    echo "+ Account information was the same after the update"
+    rm "${NEW_ACCOUNT_KEY_JSON}"
+  else
+    ACCOUNT_KEY_JSON_BACKUP="${ACCOUNT_KEY_JSON%.*}-$(date +%s).json"
+    echo "+ Backup ${ACCOUNT_KEY_JSON} as ${ACCOUNT_KEY_JSON_BACKUP}"
+    cp -p "${ACCOUNT_KEY_JSON}" "${ACCOUNT_KEY_JSON_BACKUP}"
+    echo "+ Populate ${ACCOUNT_KEY_JSON}"
+    mv "${NEW_ACCOUNT_KEY_JSON}" "${ACCOUNT_KEY_JSON}"
+  fi
+  echo "+ Done!"
+  exit 0
+}
+
 # Usage: --cron (-c)
-# Description: Sign/renew non-existant/changed/expiring certificates.
+# Description: Sign/renew non-existent/changed/expiring certificates.
 command_sign_domains() {
   init_system
+  hookscript_bricker_hook
+
+  # Call startup hook
+  [[ -n "${HOOK}" ]] && "${HOOK}" "startup_hook"
+
+  if [ ! -d "${CHAINCACHE}" ]; then
+    echo " + Creating chain cache directory ${CHAINCACHE}"
+    mkdir "${CHAINCACHE}"
+  fi
 
   if [[ -n "${PARAM_DOMAIN:-}" ]]; then
     DOMAINS_TXT="$(_mktemp)"
-    printf -- "${PARAM_DOMAIN}" > "${DOMAINS_TXT}"
+    if [[ -n "${PARAM_ALIAS:-}" ]]; then
+      printf -- "${PARAM_DOMAIN} > ${PARAM_ALIAS}" > "${DOMAINS_TXT}"
+    else
+      printf -- "${PARAM_DOMAIN}" > "${DOMAINS_TXT}"
+    fi
   elif [[ -e "${DOMAINS_TXT}" ]]; then
     if [[ ! -r "${DOMAINS_TXT}" ]]; then
       _exiterr "domains.txt found but not readable"
@@ -662,14 +1154,18 @@
   # Generate certificates for all domains found in domains.txt. Check if existing certificate are about to expire
   ORIGIFS="${IFS}"
   IFS=$'\n'
-  for line in $(<"${DOMAINS_TXT}" tr -d '\r' | tr '[:upper:]' '[:lower:]' | _sed -e 's/^[[:space:]]*//g' -e 's/[[:space:]]*$//g' -e 's/[[:space:]]+/ /g' | (grep -vE '^(#|$)' || true)); do
+  for line in $(<"${DOMAINS_TXT}" tr -d '\r' | awk '{print tolower($0)}' | _sed -e 's/^[[:space:]]*//g' -e 's/[[:space:]]*$//g' -e 's/[[:space:]]+/ /g' -e 's/([^ ])>/\1 >/g' -e 's/> />/g' | (grep -vE '^(#|$)' || true)); do
     reset_configvars
     IFS="${ORIGIFS}"
+    alias="$(grep -Eo '>[^ ]+' <<< "${line}" || true)"
+    line="$(_sed -e 's/>[^ ]+[ ]*//g' <<< "${line}")"
+    aliascount="$(grep -Eo '>' <<< "${alias}" | awk 'END {print NR}' || true )"
+    [ ${aliascount} -gt 1 ] && _exiterr "Only one alias per line is allowed in domains.txt!"
+
     domain="$(printf '%s\n' "${line}" | cut -d' ' -f1)"
     morenames="$(printf '%s\n' "${line}" | cut -s -d' ' -f2-)"
-    cert="${CERTDIR}/${domain}/cert.pem"
-
-    force_renew="${PARAM_FORCE:-no}"
+    [ ${aliascount} -lt 1 ] && alias="${domain}" || alias="${alias#>}"
+    export alias
 
     if [[ -z "${morenames}" ]];then
       echo "Processing ${domain}"
@@ -677,14 +1173,32 @@
       echo "Processing ${domain} with alternative names: ${morenames}"
     fi
 
+    if [ "${alias:0:2}" = "*." ]; then
+      _exiterr "Please define a valid alias for your ${domain} wildcard-certificate. See domains.txt-documentation for more details."
+    fi
+
+    local certdir="${CERTDIR}/${alias}"
+    cert="${certdir}/cert.pem"
+    chain="${certdir}/chain.pem"
+
+    force_renew="${PARAM_FORCE:-no}"
+
+    timestamp="$(date +%s)"
+
+    # If there is no existing certificate directory => make it
+    if [[ ! -e "${certdir}" ]]; then
+      echo " + Creating new directory ${certdir} ..."
+      mkdir -p "${certdir}" || _exiterr "Unable to create directory ${certdir}"
+    fi
+
     # read cert config
     # for now this loads the certificate specific config in a subshell and parses a diff of set variables.
     # we could just source the config file but i decided to go this way to protect people from accidentally overriding
     # variables used internally by this script itself.
     if [[ -n "${DOMAINS_D}" ]]; then
-      certconfig="${DOMAINS_D}/${domain}"
+      certconfig="${DOMAINS_D}/${alias}"
     else
-      certconfig="${CERTDIR}/${domain}/config"
+      certconfig="${certdir}/config"
     fi
 
     if [ -f "${certconfig}" ]; then
@@ -705,22 +1219,41 @@
         config_var="$(echo "${cfgline:1}" | cut -d'=' -f1)"
         config_value="$(echo "${cfgline:1}" | cut -d'=' -f2-)"
         case "${config_var}" in
-          KEY_ALGO|OCSP_MUST_STAPLE|PRIVATE_KEY_RENEW|KEYSIZE|CHALLENGETYPE|HOOK|WELLKNOWN|HOOK_CHAIN|OPENSSL_CNF|RENEW_DAYS)
+          KEY_ALGO|OCSP_MUST_STAPLE|PRIVATE_KEY_RENEW|PRIVATE_KEY_ROLLOVER|KEYSIZE|CHALLENGETYPE|HOOK|WELLKNOWN|HOOK_CHAIN|OPENSSL_CNF|RENEW_DAYS)
             echo "   + ${config_var} = ${config_value}"
             declare -- "${config_var}=${config_value}"
             ;;
           _) ;;
-          *) echo "   ! Setting ${config_var} on a per-certificate base is not (yet) supported"
+          *) echo "   ! Setting ${config_var} on a per-certificate base is not (yet) supported" >&2
         esac
       done
       IFS="${ORIGIFS}"
     fi
     verify_config
+    hookscript_bricker_hook
+    export WELLKNOWN CHALLENGETYPE KEY_ALGO PRIVATE_KEY_ROLLOVER
 
+    skip="no"
+
+    # Allow for external CSR generation
+    local csr=""
+    if [[ -n "${HOOK}" ]]; then
+      csr="$("${HOOK}" "generate_csr" "${domain}" "${certdir}" "${domain} ${morenames}")"
+      if grep -qE "\-----BEGIN (NEW )?CERTIFICATE REQUEST-----" <<< "${csr}"; then
+        altnames="$(extract_altnames "${csr}")"
+        domain="$(cut -d' ' -f1 <<< "${altnames}")"
+        morenames="$(cut -s -d' ' -f2- <<< "${altnames}")"
+        echo " + Using CSR from hook script (real names: ${altnames})"
+      else
+        csr=""
+      fi
+    fi
+
+    # Check domain names of existing certificate
     if [[ -e "${cert}" ]]; then
       printf " + Checking domain name(s) of existing cert..."
 
-      certnames="$(openssl x509 -in "${cert}" -text -noout | grep DNS: | _sed 's/DNS://g' | tr -d ' ' | tr ',' '\n' | sort -u | tr '\n' ' ' | _sed 's/ $//')"
+      certnames="$("${OPENSSL}" x509 -in "${cert}" -text -noout | grep DNS: | _sed 's/DNS://g' | tr -d ' ' | tr ',' '\n' | sort -u | tr '\n' ' ' | _sed 's/ $//')"
       givennames="$(echo "${domain}" "${morenames}"| tr ' ' '\n' | sort -u | tr '\n' ' ' | _sed 's/ $//' | _sed 's/^ //')"
 
       if [[ "${certnames}" = "${givennames}" ]]; then
@@ -735,38 +1268,77 @@
       fi
     fi
 
+    # Check expire date of existing certificate
     if [[ -e "${cert}" ]]; then
       echo " + Checking expire date of existing cert..."
-      valid="$(openssl x509 -enddate -noout -in "${cert}" | cut -d= -f2- )"
+      valid="$("${OPENSSL}" x509 -enddate -noout -in "${cert}" | cut -d= -f2- )"
 
       printf " + Valid till %s " "${valid}"
-      if openssl x509 -checkend $((RENEW_DAYS * 86400)) -noout -in "${cert}"; then
+      if "${OPENSSL}" x509 -checkend $((RENEW_DAYS * 86400)) -noout -in "${cert}"; then
         printf "(Longer than %d days). " "${RENEW_DAYS}"
         if [[ "${force_renew}" = "yes" ]]; then
           echo "Ignoring because renew was forced!"
         else
           # Certificate-Names unchanged and cert is still valid
           echo "Skipping renew!"
-          [[ -n "${HOOK}" ]] && "${HOOK}" "unchanged_cert" "${domain}" "${CERTDIR}/${domain}/privkey.pem" "${CERTDIR}/${domain}/cert.pem" "${CERTDIR}/${domain}/fullchain.pem" "${CERTDIR}/${domain}/chain.pem"
-          continue
+          [[ -n "${HOOK}" ]] && "${HOOK}" "unchanged_cert" "${domain}" "${certdir}/privkey.pem" "${certdir}/cert.pem" "${certdir}/fullchain.pem" "${certdir}/chain.pem"
+          skip="yes"
         fi
       else
         echo "(Less than ${RENEW_DAYS} days). Renewing!"
       fi
     fi
 
-    # shellcheck disable=SC2086
-    if [[ "${PARAM_KEEP_GOING:-}" = "yes" ]]; then
-      sign_domain ${line} &
-      wait $! || true
-    else
-      sign_domain ${line}
+    local update_ocsp
+    update_ocsp="no"
+
+    # Sign certificate for this domain
+    if [[ ! "${skip}" = "yes" ]]; then
+      update_ocsp="yes"
+      [[ -z "${csr}" ]] || printf "%s" "${csr}" > "${certdir}/cert-${timestamp}.csr"
+      if [[ "${PARAM_KEEP_GOING:-}" = "yes" ]]; then
+        sign_domain "${certdir}" ${timestamp} ${domain} ${morenames} &
+        wait $! || true
+      else
+        sign_domain "${certdir}" ${timestamp} ${domain} ${morenames}
+      fi
+    fi
+
+    if [[ "${OCSP_FETCH}" = "yes" ]]; then
+      local ocsp_url
+      ocsp_url="$(get_ocsp_url "${cert}")"
+
+      if [[ ! -e "${certdir}/ocsp.der" ]]; then
+        update_ocsp="yes"
+      elif ! ("${OPENSSL}" ocsp -no_nonce -issuer "${chain}" -verify_other "${chain}" -cert "${cert}" -respin "${certdir}/ocsp.der" -status_age 432000 2>&1 | grep -q "${cert}: good"); then
+        update_ocsp="yes"
+      fi
+
+      if [[ "${update_ocsp}" = "yes" ]]; then
+        echo " + Updating OCSP stapling file"
+        ocsp_timestamp="$(date +%s)"
+        if grep -qE "^(0|(1\.0))\." <<< "$(${OPENSSL} version | awk '{print $2}')"; then
+          ocsp_log="$("${OPENSSL}" ocsp -no_nonce -issuer "${chain}" -verify_other "${chain}" -cert "${cert}" -respout "${certdir}/ocsp-${ocsp_timestamp}.der" -url "${ocsp_url}" -header "HOST" "$(echo "${ocsp_url}" | _sed -e 's/^http(s?):\/\///' -e 's/\/.*$//g')" 2>&1)" || _exiterr "Error while fetching OCSP information: ${ocsp_log}"
+        else
+          ocsp_log="$("${OPENSSL}" ocsp -no_nonce -issuer "${chain}" -verify_other "${chain}" -cert "${cert}" -respout "${certdir}/ocsp-${ocsp_timestamp}.der" -url "${ocsp_url}" 2>&1)" || _exiterr "Error while fetching OCSP information: ${ocsp_log}"
+        fi
+        ln -sf "ocsp-${ocsp_timestamp}.der" "${certdir}/ocsp.der"
+        [[ -n "${HOOK}" ]] && altnames="${domain} ${morenames}" "${HOOK}" "deploy_ocsp" "${domain}" "${certdir}/ocsp.der" "${ocsp_timestamp}"
+      else
+        echo " + OSCP stapling file is still valid (skipping update)"
+      fi
     fi
   done
+  reset_configvars
 
   # remove temporary domains.txt file if used
   [[ -n "${PARAM_DOMAIN:-}" ]] && rm -f "${DOMAINS_TXT}"
 
+  [[ -n "${HOOK}" ]] && "${HOOK}" "exit_hook"
+  if [[ "${AUTO_CLEANUP}" == "yes" ]]; then
+    echo "+ Running automatic cleanup"
+    command_cleanup noinit
+  fi
   exit 0
 }
 
@@ -779,14 +1351,19 @@
 
   init_system
 
+  # load csr
   csrfile="${1}"
   if [ ! -r "${csrfile}" ]; then
     _exiterr "Could not read certificate signing request ${csrfile}"
   fi
+  csr="$(cat "${csrfile}")"
+
+  # extract names
+  altnames="$(extract_altnames "${csr}")"
 
   # gen cert
   certfile="$(_mktemp)"
-  sign_csr "$(< "${csrfile}" )" 3> "${certfile}"
+  sign_csr "${csr}" ${altnames} 3> "${certfile}"
 
   # print cert
   echo "# CERT #" >&3
@@ -797,10 +1374,13 @@
   if [ -n "${PARAM_FULL_CHAIN:-}" ]; then
     # get and convert ca cert
     chainfile="$(_mktemp)"
-    http_request get "$(openssl x509 -in "${certfile}" -noout -text | grep 'CA Issuers - URI:' | cut -d':' -f2-)" > "${chainfile}"
-
-    if ! grep -q "BEGIN CERTIFICATE" "${chainfile}"; then
-      openssl x509 -inform DER -in "${chainfile}" -outform PEM -out "${chainfile}"
+    tmpchain="$(_mktemp)"
+    http_request get "$("${OPENSSL}" x509 -in "${certfile}" -noout -text | grep 'CA Issuers - URI:' | cut -d':' -f2-)" > "${tmpchain}"
+    if grep -q "BEGIN CERTIFICATE" "${tmpchain}"; then
+      mv "${tmpchain}" "${chainfile}"
+    else
+      "${OPENSSL}" x509 -in "${tmpchain}" -inform DER -out "${chainfile}" -outform PEM
+      rm "${tmpchain}"
     fi
 
     echo "# CHAIN #" >&3
@@ -837,8 +1417,12 @@
 
   echo "Revoking ${cert}"
 
-  cert64="$(openssl x509 -in "${cert}" -inform PEM -outform DER | urlbase64)"
-  response="$(signed_request "${CA_REVOKE_CERT}" '{"resource": "revoke-cert", "certificate": "'"${cert64}"'"}' | clean_json)"
+  cert64="$("${OPENSSL}" x509 -in "${cert}" -inform PEM -outform DER | urlbase64)"
+  if [[ ${API} -eq 1 ]]; then
+    response="$(signed_request "${CA_REVOKE_CERT}" '{"resource": "revoke-cert", "certificate": "'"${cert64}"'"}' | clean_json)"
+  else
+    response="$(signed_request "${CA_REVOKE_CERT}" '{"certificate": "'"${cert64}"'"}' | clean_json)"
+  fi
   # if there is a problem with our revoke request _request (via signed_request) will report this and "exit 1" out
   # so if we are here, it is safe to assume the request was successful
   echo " + Done."
@@ -849,13 +1433,18 @@
 # Usage: --cleanup (-gc)
 # Description: Move unused certificate files to archive directory
 command_cleanup() {
-  load_config
+  if [ ! "${1:-}" = "noinit" ]; then
+    load_config
+  fi
 
-  # Create global archive directory if not existant
+  # Create global archive directory if not existent
   if [[ ! -e "${BASEDIR}/archive" ]]; then
     mkdir "${BASEDIR}/archive"
   fi
 
+  # Allow globbing
+  [[ -n "${ZSH_VERSION:-}" ]] && set +o noglob || set +f
+
   # Loop over all certificate directories
   for certdir in "${CERTDIR}/"*; do
     # Skip if entry is not a folder
@@ -864,14 +1453,14 @@
     # Get certificate name
     certname="$(basename "${certdir}")"
 
-    # Create certitifaces archive directory if not existant
+    # Create certificates archive directory if not existent
     archivedir="${BASEDIR}/archive/${certname}"
     if [[ ! -e "${archivedir}" ]]; then
       mkdir "${archivedir}"
     fi
 
     # Loop over file-types (certificates, keys, signing-requests, ...)
-    for filetype in cert.csr cert.pem chain.pem fullchain.pem privkey.pem; do
+    for filetype in cert.csr cert.pem chain.pem fullchain.pem privkey.pem ocsp.der; do
       # Skip if symlink is broken
       [[ -r "${certdir}/${filetype}" ]] || continue
 
@@ -883,10 +1472,7 @@
       fileext="$(echo "${filetype}" | cut -d. -f2)"
 
       # Loop over all files of this type
-      for file in "${certdir}/${filebase}-"*".${fileext}"; do
-        # Handle case where no files match the wildcard
-        [[ -f "${file}" ]] || break
-
+      for file in "${certdir}/${filebase}-"*".${fileext}" "${certdir}/${filebase}-"*".${fileext}-revoked"; do
         # Check if current file is in use, if unused move to archive directory
         filename="$(basename "${file}")"
         if [[ ! "${filename}" = "${current}" ]]; then
@@ -926,7 +1512,7 @@
 command_env() {
   echo "# dehydrated configuration"
   load_config
-  typeset -p CA LICENSE CERTDIR CHALLENGETYPE DOMAINS_D DOMAINS_TXT HOOK HOOK_CHAIN RENEW_DAYS ACCOUNT_KEY ACCOUNT_KEY_JSON KEYSIZE WELLKNOWN PRIVATE_KEY_RENEW OPENSSL_CNF CONTACT_EMAIL LOCKFILE
+  typeset -p CA CERTDIR CHALLENGETYPE DOMAINS_D DOMAINS_TXT HOOK HOOK_CHAIN RENEW_DAYS ACCOUNT_KEY ACCOUNT_KEY_JSON KEYSIZE WELLKNOWN PRIVATE_KEY_RENEW OPENSSL_CNF CONTACT_EMAIL LOCKFILE
 }
 
 # Main method (parses script arguments and calls command_* methods)
@@ -948,6 +1534,7 @@
     fi
   }
 
+  # shellcheck disable=SC2199
   [[ -z "${@}" ]] && eval set -- "--help"
 
   while (( ${#} )); do
@@ -965,6 +1552,20 @@
         set_command sign_domains
         ;;
 
+      --register)
+        set_command register
+        ;;
+
+      --account)
+        set_command account
+        ;;
+
+      # PARAM_Usage: --accept-terms
+      # PARAM_Description: Accept CAs terms of service
+      --accept-terms)
+        PARAM_ACCEPT_TERMS="yes"
+        ;;
+
       --signcsr|-s)
         shift 1
         set_command sign_csr
@@ -979,6 +1580,10 @@
         PARAM_REVOKECERT="${1}"
         ;;
 
+      --version|-v)
+        set_command version
+        ;;
+
       --cleanup|-gc)
         set_command cleanup
         ;;
@@ -1013,6 +1618,15 @@
          fi
         ;;
 
+      # PARAM_Usage: --alias certalias
+      # PARAM_Description: Use specified name for certificate directory (and per-certificate config) instead of the primary domain (only used if --domain is specified)
+      --alias)
+        shift 1
+        check_parameters "${1:-}"
+        [[ -n "${PARAM_ALIAS:-}" ]] && _exiterr "Alias can only be specified once!"
+        PARAM_ALIAS="${1}"
+        ;;
+
       # PARAM_Usage: --keep-going (-g)
       # PARAM_Description: Keep going after encountering an error while creating/renewing multiple certificates in cron mode
       --keep-going|-g)
@@ -1031,6 +1645,14 @@
         PARAM_NO_LOCK="yes"
         ;;
 
+      # PARAM_Usage: --lock-suffix example.com
+      # PARAM_Description: Suffix lockfile name with a string (useful for with -d)
+      --lock-suffix)
+        shift 1
+        check_parameters "${1:-}"
+        PARAM_LOCKFILE_SUFFIX="${1}"
+        ;;
+
       # PARAM_Usage: --ocsp
       # PARAM_Description: Sets option in CSR indicating OCSP stapling to be mandatory
       --ocsp)
@@ -1099,9 +1721,12 @@
   case "${COMMAND}" in
     env) command_env;;
     sign_domains) command_sign_domains;;
+    register) command_register;;
+    account) command_account;;
     sign_csr) command_sign_csr "${PARAM_CSR}";;
     revoke) command_revoke "${PARAM_REVOKECERT}";;
     cleanup) command_cleanup;;
+    version) command_version;;
     *) command_help; exit 1;;
   esac
 }
@@ -1109,8 +1734,7 @@
 # Determine OS type
 OSTYPE="$(uname)"
 
-# Check for missing dependencies
-check_dependencies
-
-# Run script
-main "${@:-}"
+if [[ ! "${DEHYDRATED_NOOP:-}" = "NOOP" ]]; then
+  # Run script
+  main "${@:-}"
+fi
diff -Nru dehydrated-0.3.1/docs/dns-verification.md dehydrated-0.6.2/docs/dns-verification.md
--- dehydrated-0.3.1/docs/dns-verification.md	2016-09-13 20:00:43.000000000 +0200
+++ dehydrated-0.6.2/docs/dns-verification.md	2018-04-25 23:22:40.000000000 +0200
@@ -2,9 +2,18 @@
 
 This script also supports the new `dns-01`-type verification. This type of verification requires you to be able to create a specific `TXT` DNS record for each hostname included in the certificate.
 
-You need a hook script that deploys the challenge to your DNS server!
+You need a hook script that deploys the challenge to your DNS server.
 
-The hook script (indicated in the config file or the --hook/-k command line argument) gets four arguments: an operation name (clean_challenge, deploy_challenge, or deploy_cert) and some operands for that. For deploy_challenge $2 is the domain name for which the certificate is required, $3 is a "challenge token" (which is not needed for dns-01), and $4 is a token which needs to be inserted in a TXT record for the domain.
+The hook script (indicated in the config file or the `--hook/-k` command line argument) gets four arguments:
+
+$1 an operation name (`clean_challenge`, `deploy_challenge`, `deploy_cert`, `invalid_challenge` or `request_failure`) and some operands for that.
+For `deploy_challenge` 
+
+$2 is the domain name for which the certificate is required, 
+
+$3 is a "challenge token" (which is not needed for dns-01), and 
+
+$4 is a token which needs to be inserted in a TXT record for the domain.
 
 Typically, you will need to split the subdomain name in two, the subdomain name and the domain name separately. For example, for "my.example.com", you'll need "my" and "example.com" separately. You then have to prefix "_acme-challenge." before the subdomain name, as in "_acme-challenge.my" and set a TXT record for that on the domain (e.g. "example.com") which has the value supplied in $4
 
@@ -13,10 +22,10 @@
 _acme-challenge.my IN    TXT    $4
 ```
 
-That could be done manually (as most providers don't have a DNS API), by having your hook script echo $1, $2 and $4 and then wait (read -s -r -e < /dev/tty) - give it a little time to get into their DNS system. Usually providers give you a boxes to put "_acme-challenge.my" and the token value in, and a dropdown to choose the record type, TXT. 
+That could be done manually (as most providers don't have a DNS API), by having your hook script echo $1, $2 and $4 and then wait (`read -s -r -e < /dev/tty`) - give it a little time to get into their DNS system. Usually providers give you a boxes to put "_acme-challenge.my" and the token value in, and a dropdown to choose the record type, TXT. 
 
 Or when you do have a DNS API, pass the details accordingly to achieve the same thing.
 
-You can delete the TXT record when called with operation clean_challenge, when $2 is also the domain name.
+You can delete the TXT record when called with operation `clean_challenge`, when $2 is also the domain name.
 
 Here are some examples: [Examples for DNS-01 hooks](https://github.com/lukas2511/dehydrated/wiki/Examples-for-DNS-01-hooks)
diff -Nru dehydrated-0.3.1/docs/domains_txt.md dehydrated-0.6.2/docs/domains_txt.md
--- dehydrated-0.3.1/docs/domains_txt.md	2016-09-13 20:00:43.000000000 +0200
+++ dehydrated-0.6.2/docs/domains_txt.md	2018-04-25 23:22:40.000000000 +0200
@@ -1,13 +1,72 @@
-### domains.txt
+## domains.txt
 
-dehydrated uses the file `domains.txt` as configuration for which certificates should be requested.
+dehydrated uses the file `domains.txt` as configuration for which certificates
+should be requested.
 
 The file should have the following format:
 
 ```text
+example.org
 example.com www.example.com
 example.net www.example.net wiki.example.net
 ```
 
-This states that there should be two certificates `example.com` and `example.net`,
-with the other domains in the corresponding line being their alternative names.
+This states that there are the following certificates:
+  * `example.org` without any *alternative names*
+  * `example.com` with an *alternative name* of `www.example.com`
+  * `example.net` with the *alternative names*: `www.example.net` and
+    `wiki.example.net`
+
+### Aliases
+
+You can define an *alias* for your certificate which will (instead of the
+primary domain) be used as the directory name under your `CERTDIR` and for a
+per-certificate lookup. This is done using the `>` character.  This allows
+multiple certificates with identical sets of domains but different
+configuration to exist.
+
+Here is an example of using an *alias* called `certalias` for creating the
+certificate for `example.net` with *alternative names* `www.example.net` and
+`wiki.example.net`. The certificate will be stored in the directory `certalias`
+under your `CERTDIR`.
+
+```text
+example.net www.example.net wiki.example.net > certalias
+```
+
+### Wildcards
+
+Support for wildcards was added by the ACME v2 protocol.
+
+Certificates with a wildcard domain as the first (or only) name require an
+*alias* to be set.  *Aliases* can't start with `*.`.
+
+For example to create the wildcard for `*.service.example.com` your
+`domains.txt` could use the *alias* method like this:
+
+```text
+*.service.example.com > star_service_example_com
+```
+
+This creates a wildcard certificate for only `*.service.example.com` and will
+store it in the directory `star_service_example_com` under your `CERTDIR`. As a
+note this certificate will **NOT** be valid for `service.example.com` but only
+for `*.service.example.com`. So it would, for example, be valid for
+`foo.service.example.com`.
+
+
+Another way to create it is using *alternative names*. For example your
+`domains.txt` could do this:
+
+```text
+service.example.com *.service.example.com
+eggs.example.com *.ham.example.com
+```
+
+This creates two certificates one for `service.example.com` with an
+*alternative name* of `*.service.example.com` and a second certificate for
+`eggs.example.com` with an *alternative name* of `*.ham.example.com`.
+
+**Note:** The first certificate is valid for both `service.example.com` and for
+`*.service.example.com` which can be a useful way to create wildcard
+certificates.
diff -Nru dehydrated-0.3.1/docs/examples/config dehydrated-0.6.2/docs/examples/config
--- dehydrated-0.3.1/docs/examples/config	2016-09-13 20:00:43.000000000 +0200
+++ dehydrated-0.6.2/docs/examples/config	2018-04-25 23:22:40.000000000 +0200
@@ -10,16 +10,26 @@
 # Default values of this config are in comments        #
 ########################################################
 
+# Which user should dehydrated run as? This will be implictly enforced when running as root
+#DEHYDRATED_USER=
+
+# Which group should dehydrated run as? This will be implictly enforced when running as root
+#DEHYDRATED_GROUP=
+
 # Resolve names to addresses of IP version only. (curl)
 # supported values: 4, 6
 # default: <unset>
 #IP_VERSION=
 
-# Path to certificate authority (default: https://acme-v01.api.letsencrypt.org/directory)
-#CA="https://acme-v01.api.letsencrypt.org/directory";
+# Path to certificate authority (default: https://acme-v02.api.letsencrypt.org/directory)
+#CA="https://acme-v02.api.letsencrypt.org/directory";
 
-# Path to license agreement (default: https://letsencrypt.org/documents/LE-SA-v1.1.1-August-1-2016.pdf)
-#LICENSE="https://letsencrypt.org/documents/LE-SA-v1.1.1-August-1-2016.pdf";
+# Path to old certificate authority
+# Set this value to your old CA value when upgrading from ACMEv1 to ACMEv2 under a different endpoint.
+# If dehydrated detects an account-key for the old CA it will automatically reuse that key
+# instead of registering a new one.
+# default: https://acme-v01.api.letsencrypt.org/directory
+#OLDCA="https://acme-v01.api.letsencrypt.org/directory";
 
 # Which challenge should be used? Currently http-01 and dns-01 are supported
 #CHALLENGETYPE="http-01"
@@ -51,6 +61,12 @@
 # Path to openssl config file (default: <unset> - tries to figure out system default)
 #OPENSSL_CNF=
 
+# Path to OpenSSL binary (default: "openssl")
+#OPENSSL="openssl"
+
+# Extra options passed to the curl binary (default: <unset>)
+#CURL_OPTS=
+
 # Program or function called in certain situations
 #
 # After generating the challenge-response, or after failed challenge (in this case altname is empty)
@@ -72,6 +88,9 @@
 # Regenerate private keys instead of just signing new certificates on renewal (default: yes)
 #PRIVATE_KEY_RENEW="yes"
 
+# Create an extra private key for rollover (default: no)
+#PRIVATE_KEY_ROLLOVER="no"
+
 # Which public key algorithm should be used? Supported: rsa, prime256v1 and secp384r1
 #KEY_ALGO=rsa
 
@@ -83,3 +102,15 @@
 
 # Option to add CSR-flag indicating OCSP stapling to be mandatory (default: no)
 #OCSP_MUST_STAPLE="no"
+
+# Fetch OCSP responses (default: no)
+#OCSP_FETCH="no"
+
+# Issuer chain cache directory (default: $BASEDIR/chains)
+#CHAINCACHE="${BASEDIR}/chains"
+
+# Automatic cleanup (default: no)
+#AUTO_CLEANUP="no"
+
+# ACME API version (default: auto)
+#API=auto
diff -Nru dehydrated-0.3.1/docs/examples/domains.txt dehydrated-0.6.2/docs/examples/domains.txt
--- dehydrated-0.3.1/docs/examples/domains.txt	2016-09-13 20:00:43.000000000 +0200
+++ dehydrated-0.6.2/docs/examples/domains.txt	2018-04-25 23:22:40.000000000 +0200
@@ -1,2 +1,30 @@
+# Create certificate for 'example.org' with an alternative name of
+# 'www.example.org'. It will be stored in the directory ${CERT_DIR}/example.org
 example.org www.example.org
+
+# Create certificate for 'example.com' with alternative names of
+# 'www.example.com' & 'wiki.example.com'. It will be stored in the directory
+# ${CERT_DIR}/example.com
 example.com www.example.com wiki.example.com
+
+# Using the alias 'certalias' create certificate for 'example.net' with
+# alternate name 'www.example.net' and store it in the directory
+# ${CERTDIR}/certalias
+example.net www.example.net > certalias
+
+# Using the alias 'service_example_com' create a wildcard certificate for
+# '*.service.example.com' and store it in the directory
+# ${CERTDIR}/service_example_com
+# NOTE: It is NOT a certificate for 'service.example.com'
+*.service.example.com > service_example_com
+
+# Using the alias 'star_service_example_org' create a wildcard certificate for
+# '*.service.example.org' with an alternative name of `service.example.org'
+# and store it in the directory ${CERTDIR}/star_service_example_org
+# NOTE: It is a certificate for 'service.example.org'
+*.service.example.org service.example.org  > star_service_example_org
+
+# Create a certificate for 'service.example.net' with an alternative name of
+# '*.service.example.net' (which is a wildcard domain) and store it in the
+# directory ${CERTDIR}/service.example.net
+service.example.net *.service.example.net
diff -Nru dehydrated-0.3.1/docs/examples/hook.sh dehydrated-0.6.2/docs/examples/hook.sh
--- dehydrated-0.3.1/docs/examples/hook.sh	2016-09-13 20:00:43.000000000 +0200
+++ dehydrated-0.6.2/docs/examples/hook.sh	2018-04-25 23:22:40.000000000 +0200
@@ -1,6 +1,6 @@
 #!/usr/bin/env bash
 
-function deploy_challenge {
+deploy_challenge() {
     local DOMAIN="${1}" TOKEN_FILENAME="${2}" TOKEN_VALUE="${3}"
 
     # This hook is called once for every domain that needs to be
@@ -19,9 +19,12 @@
     #   validation, this is what you want to put in the _acme-challenge
     #   TXT record. For HTTP validation it is the value that is expected
     #   be found in the $TOKEN_FILENAME file.
+
+    # Simple example: Use nsupdate with local named
+    # printf 'server 127.0.0.1\nupdate add _acme-challenge.%s 300 IN TXT "%s"\nsend\n' "${DOMAIN}" "${TOKEN_VALUE}" | nsupdate -k /var/run/named/session.key
 }
 
-function clean_challenge {
+clean_challenge() {
     local DOMAIN="${1}" TOKEN_FILENAME="${2}" TOKEN_VALUE="${3}"
 
     # This hook is called after attempting to validate each domain,
@@ -29,9 +32,12 @@
     # files or DNS records that are no longer needed.
     #
     # The parameters are the same as for deploy_challenge.
+
+    # Simple example: Use nsupdate with local named
+    # printf 'server 127.0.0.1\nupdate delete _acme-challenge.%s TXT "%s"\nsend\n' "${DOMAIN}" "${TOKEN_VALUE}" | nsupdate -k /var/run/named/session.key
 }
 
-function deploy_cert {
+deploy_cert() {
     local DOMAIN="${1}" KEYFILE="${2}" CERTFILE="${3}" FULLCHAINFILE="${4}" CHAINFILE="${5}" TIMESTAMP="${6}"
 
     # This hook is called once for each certificate that has been
@@ -52,9 +58,35 @@
     #   The path of the file containing the intermediate certificate(s).
     # - TIMESTAMP
     #   Timestamp when the specified certificate was created.
+
+    # Simple example: Copy file to nginx config
+    # cp "${KEYFILE}" "${FULLCHAINFILE}" /etc/nginx/ssl/; chown -R nginx: /etc/nginx/ssl
+    # systemctl reload nginx
 }
 
-function unchanged_cert {
+deploy_ocsp() {
+    local DOMAIN="${1}" OCSPFILE="${2}" TIMESTAMP="${3}"
+
+    # This hook is called once for each updated ocsp stapling file that has
+    # been produced. Here you might, for instance, copy your new ocsp stapling
+    # files to service-specific locations and reload the service.
+    #
+    # Parameters:
+    # - DOMAIN
+    #   The primary domain name, i.e. the certificate common
+    #   name (CN).
+    # - OCSPFILE
+    #   The path of the ocsp stapling file
+    # - TIMESTAMP
+    #   Timestamp when the specified ocsp stapling file was created.
+
+    # Simple example: Copy file to nginx config
+    # cp "${OCSPFILE}" /etc/nginx/ssl/; chown -R nginx: /etc/nginx/ssl
+    # systemctl reload nginx
+}
+
+
+unchanged_cert() {
     local DOMAIN="${1}" KEYFILE="${2}" CERTFILE="${3}" FULLCHAINFILE="${4}" CHAINFILE="${5}"
 
     # This hook is called once for each certificate that is still
@@ -74,4 +106,85 @@
     #   The path of the file containing the intermediate certificate(s).
 }
 
-HANDLER=$1; shift; $HANDLER $@
+invalid_challenge() {
+    local DOMAIN="${1}" RESPONSE="${2}"
+
+    # This hook is called if the challenge response has failed, so domain
+    # owners can be aware and act accordingly.
+    #
+    # Parameters:
+    # - DOMAIN
+    #   The primary domain name, i.e. the certificate common
+    #   name (CN).
+    # - RESPONSE
+    #   The response that the verification server returned
+
+    # Simple example: Send mail to root
+    # printf "Subject: Validation of ${DOMAIN} failed!\n\nOh noez!" | sendmail root
+}
+
+request_failure() {
+    local STATUSCODE="${1}" REASON="${2}" REQTYPE="${3}" HEADERS="${4}"
+
+    # This hook is called when an HTTP request fails (e.g., when the ACME
+    # server is busy, returns an error, etc). It will be called upon any
+    # response code that does not start with '2'. Useful to alert admins
+    # about problems with requests.
+    #
+    # Parameters:
+    # - STATUSCODE
+    #   The HTML status code that originated the error.
+    # - REASON
+    #   The specified reason for the error.
+    # - REQTYPE
+    #   The kind of request that was made (GET, POST...)
+    # - HEADERS
+    #   HTTP headers returned by the CA
+
+    # Simple example: Send mail to root
+    # printf "Subject: HTTP request failed failed!\n\nA http request failed with status ${STATUSCODE}!" | sendmail root
+}
+
+generate_csr() {
+    local DOMAIN="${1}" CERTDIR="${2}" ALTNAMES="${3}"
+
+    # This hook is called before any certificate signing operation takes place.
+    # It can be used to generate or fetch a certificate signing request with external
+    # tools.
+    # The output should be just the cerificate signing request formatted as PEM.
+    #
+    # Parameters:
+    # - DOMAIN
+    #   The primary domain as specified in domains.txt. This does not need to
+    #   match with the domains in the CSR, it's basically just the directory name.
+    # - CERTDIR
+    #   Certificate output directory for this particular certificate. Can be used
+    #   for storing additional files.
+    # - ALTNAMES
+    #   All domain names for the current certificate as specified in domains.txt.
+    #   Again, this doesn't need to match with the CSR, it's just there for convenience.
+
+    # Simple example: Look for pre-generated CSRs
+    # if [ -e "${CERTDIR}/pre-generated.csr" ]; then
+    #   cat "${CERTDIR}/pre-generated.csr"
+    # fi
+}
+
+startup_hook() {
+  # This hook is called before the cron command to do some initial tasks
+  # (e.g. starting a webserver).
+
+  :
+}
+
+exit_hook() {
+  # This hook is called at the end of the cron command and can be used to
+  # do some final (cleanup or other) tasks.
+
+  :
+}
+
+HANDLER="$1"; shift
+if [[ "${HANDLER}" =~ ^(deploy_challenge|clean_challenge|deploy_cert|deploy_ocsp|unchanged_cert|invalid_challenge|request_failure|generate_csr|startup_hook|exit_hook)$ ]]; then
+  "$HANDLER" "$@"
+fi
diff -Nru dehydrated-0.3.1/docs/hook_chain.md dehydrated-0.6.2/docs/hook_chain.md
--- dehydrated-0.3.1/docs/hook_chain.md	2016-09-13 20:00:43.000000000 +0200
+++ dehydrated-0.6.2/docs/hook_chain.md	2018-04-25 23:22:40.000000000 +0200
@@ -60,4 +60,3 @@
 HOOK: deploy_cert lukas.im /etc/dehydrated/certs/lukas.im/privkey.pem /etc/dehydrated/certs/lukas.im/cert.pem /etc/dehydrated/certs/lukas.im/fullchain.pem /etc/dehydrated/certs/lukas.im/chain.pem 1460152408
  + Done!
 ```
-
Binary files /tmp/Ek5_XIRrYI/dehydrated-0.3.1/docs/logo.jpg and /tmp/fFA91J3CYf/dehydrated-0.6.2/docs/logo.jpg differ
diff -Nru dehydrated-0.3.1/docs/man/dehydrated.1 dehydrated-0.6.2/docs/man/dehydrated.1
--- dehydrated-0.3.1/docs/man/dehydrated.1	1970-01-01 01:00:00.000000000 +0100
+++ dehydrated-0.6.2/docs/man/dehydrated.1	2018-04-25 23:22:40.000000000 +0200
@@ -0,0 +1,155 @@
+.TH DEHYDRATED 1 2018-01-13 "Dehydrated ACME Client"
+.SH NAME
+dehydrated \- ACME client implemented as a shell-script
+.SH SYNOPSIS
+.B dehydrated
+[\fBcommand\fR [\fBargument\fR]]
+[\fBargument\fR [\fBargument\fR]]
+.IR ...
+.SH DESCRIPTION
+A client for ACME-based Certificate Authorities, such as LetsEncrypt.  It can
+be used to request and obtain TLS certificates from an ACME-based
+certificate authority.
+
+Before any certificates can be requested, Dehydrated needs
+to acquire an account with the Certificate Authorities. Optionally, an email
+address can be provided.  It will be used to e.g. notify about expiring
+certificates. You will usually need to accept the Terms of Service of the CA.
+Dehydrated will notify if no account is configured. Run with \fB--register
+--accept-terms\fR to create a new account.
+
+Next, all domain names must be provided in domains.txt. The format is line
+based: If the file contains two lines "example.com" and "example.net",
+Dehydrated will request two certificate, one for "example.com" and the other
+for "example.net". A single line while "example.com example.net" will request a
+single certificate valid for both "example.net" and "example.com" through the \fISubject
+Alternative Name\fR (SAN) field.
+
+For the next step, one way of verifying domain name ownership needs to be
+configured.  Dehydrated implements \fIhttp-01\fR and \fIdns-01\fR verification. 
+
+The \fIhttp-01\fR verification provides proof of ownership by providing a
+challenge token. In order to do that, the directory referenced in the
+\fIWELLKNOWN\fR config variable needs to be exposed at
+\fIhttp://{domain}/.well-known/acme-challenge/\fR, where {domain} is every
+domain name specified in \fIdomains.txt\fR.  Dehydrated does not provide its
+own challenge responder, but relies on an existing web server to provide the
+challenge response.  See \fIwellknown.md\fR for configuration examples of
+popular web servers.
+
+The \fIdns-01\fR verification works by providing a challenge token through DNS.
+This is especially interesting for hosts that cannot be exposed to the public
+Internet.  Because adding records to DNS zones is oftentimes highly specific to
+the software or the DNS provider at hand, there are many third party hooks
+available for dehydrated.  See \fIdns-verification.md\fR for hooks for popular
+DNS servers and DNS hosters.
+
+Finally, the certificates need to be requested and updated on a regular basis.
+This can happen through a cron job or a timer. Initially, you may enforce this
+by invoking \fIdehydrated -c\fR manually.
+
+After a successful run, certificates are stored in
+\fI/etc/dehydrated/certs/{domain}\fR, where {domain} is the domain name in the
+first column of \fIdomains.txt\fR.
+
+.SH OPTIONS
+
+.BR Commands
+.TP
+.BR \-\-version ", " \-v
+Print version information
+.TP
+.BR \-\-register
+Register account key
+.TP
+.BR \-\-account
+Update account contact information
+.TP
+.BR \-\-cron ", " \-c
+Sign/renew non\-existent/changed/expiring certificates.
+.TP
+.BR \-\-signcsr ", " \-s " " \fIpath/to/csr.pem\fR
+Sign a given CSR, output CRT on stdout (advanced usage)
+.TP
+.BR \-\-revoke ", " \-r " " \fIpath/to/cert.pem\fR
+Revoke specified certificate
+.TP
+.BR \-\-cleanup ", " \-gc
+Move unused certificate files to archive directory
+.TP
+.BR \-\-help ", " \-h
+Show help text
+.TP
+.BR \-\-env ", " \-e
+Output configuration variables for use in other scripts
+
+.PP
+.BR Parameters
+.TP
+.BR \-\-accept\-terms
+Accept CAs terms of service
+.TP
+.BR \-\-full\-chain ", " \-fc
+Print full chain when using \fB\-\-signcsr\fR
+.TP
+.BR \-\-ipv4 ", " \-4
+Resolve names to IPv4 addresses only
+.TP
+.BR \-\-ipv6 ", " \-6
+Resolve names to IPv6 addresses only
+.TP
+.BR \-\-domain ", " \-d " " \fIdomain.tld\fR
+Use specified domain name(s) instead of domains.txt entry (one certificate!)
+.TP
+.BR \-\-keep\-going ", " \-g
+Keep going after encountering an error while creating/renewing multiple
+certificates in cron mode
+.TP
+.BR \-\-force ", " \-x
+Force renew of certificate even if it is longer valid than value in RENEW_DAYS
+.TP
+.BR \-\-no\-lock ", " \-n
+Don't use lockfile (potentially dangerous!)
+.TP
+.BR \-\-lock\-suffix " " \fIexample.com\fR
+Suffix lockfile name with a string (useful for use with \-d)
+.TP
+.BR \-\-ocsp
+Sets option in CSR indicating OCSP stapling to be mandatory
+.TP
+.BR \-\-privkey ", " \-p " " \fIpath/to/key.pem\fR
+Use specified private key instead of account key (useful for revocation)
+.TP
+.BR \-\-config ", " \-f " " \fIpath/to/config\fR
+Use specified config file
+.TP
+.BR \-\-hook ", " \-k " " \fIpath/to/hook.sh\fR
+Use specified script for hooks
+.TP
+.BR \-\-out ", " \-o " " \fIcerts/directory\fR
+Output certificates into the specified directory
+.TP
+.BR \-\-challenge ", " \-t " " \fI[http\-01|dns\-01]\fR
+Which challenge should be used? Currently http\-01 and dns\-01 are supported
+.TP
+.BR \-\-algo ", " \-a " " \fI[rsa|prime256v1|secp384r1]\fR
+Which public key algorithm should be used? Supported: rsa, prime256v1 and
+secp384r1
+.SH DIAGNOSTICS
+The program exits 0 if everything was fine, 1 if an error occurred.
+.SH BUGS
+Please report any bugs that you may encounter at the project web site
+.UR https://github.com/lukas2511/dehydrated/issues
+.UE .
+.SH AUTHOR
+Dehydrated was written by Lukas Schauer. This man page was contributed by
+Daniel Molkentin.
+.SH COPYRIGHT
+Copyright 2015-2018 by Lukas Schauer and the respective contributors.
+Provided under the MIT License. See the LICENSE file that accompanies the
+distribution for licensing information.
+.SH SEE ALSO
+Full documentation along with configuration examples are provided in the \fIdocs\fR
+directory of the distribution, or at
+.UR https://github.com/lukas2511/dehydrated/tree/master/docs
+.UE .
diff -Nru dehydrated-0.3.1/docs/per-certificate-config.md dehydrated-0.6.2/docs/per-certificate-config.md
--- dehydrated-0.3.1/docs/per-certificate-config.md	2016-09-13 20:00:43.000000000 +0200
+++ dehydrated-0.6.2/docs/per-certificate-config.md	2018-04-25 23:22:40.000000000 +0200
@@ -16,3 +16,10 @@
 - WELLKNOWN
 - OPENSSL_CNF
 - RENEW_DAYS
+
+## DOMAINS_D
+
+If `DOMAINS_D` is set, dehydrated will use it for your per-certificate configurations.
+Instead of `certs/example.org/config` it will look for a configuration under `DOMAINS_D/example.org`.
+
+If an alias is set, it will be used instead of the primary domain name.
diff -Nru dehydrated-0.3.1/docs/staging.md dehydrated-0.6.2/docs/staging.md
--- dehydrated-0.3.1/docs/staging.md	2016-09-13 20:00:43.000000000 +0200
+++ dehydrated-0.6.2/docs/staging.md	2018-04-25 23:22:40.000000000 +0200
@@ -10,3 +10,8 @@
 ```bash
 CA="https://acme-staging.api.letsencrypt.org/directory";
 ```
+
+# ACMEv2 staging
+
+You can use `CA="https://acme-staging-v02.api.letsencrypt.org/directory"` to test dehydrated with
+the ACMEv2 staging endpoint.
diff -Nru dehydrated-0.3.1/docs/troubleshooting.md dehydrated-0.6.2/docs/troubleshooting.md
--- dehydrated-0.3.1/docs/troubleshooting.md	2016-09-13 20:00:43.000000000 +0200
+++ dehydrated-0.6.2/docs/troubleshooting.md	2018-04-25 23:22:40.000000000 +0200
@@ -11,12 +11,6 @@
 
 This will hopefully be fixed in the future.
 
-## "Provided agreement URL [LICENSE1] does not match current agreement URL [LICENSE2]"
-
-Set LICENSE in your config to the value in place of "LICENSE2".
-
-LICENSE1 and LICENSE2 are just placeholders for the real values in this troubleshooting document!
-
 ## "Error creating new cert :: Too many certificates already issued for: [...]"
 
 This is not an issue with dehydrated but an API limit with boulder (the ACME server).
@@ -31,8 +25,8 @@
 
 There are a few factors that could result in invalid challenges.
 
-If you are using http validation make sure that the path you have configured with WELLKNOWN is readable under your domain.
+If you are using HTTP validation make sure that the path you have configured with WELLKNOWN is readable under your domain.
 
-To test this create a file (e.g. `test.txt`) in that directory and try opening it with your browser: `http://example.org/.well-known/acme-challenge/test.txt`.
+To test this create a file (e.g. `test.txt`) in that directory and try opening it with your browser: `http://example.org/.well-known/acme-challenge/test.txt`. Note that if you have an IPv6 address, the challenge connection will be on IPv6. Be sure that you test HTTP connections on both IPv4 and IPv6. Checking the test file in your browser is often not sufficient because the browser just fails over to IPv4.
 
-If you get any error you'll have to fix your webserver configuration.
+If you get any error you'll have to fix your web server configuration.
diff -Nru dehydrated-0.3.1/docs/wellknown.md dehydrated-0.6.2/docs/wellknown.md
--- dehydrated-0.3.1/docs/wellknown.md	2016-09-13 20:00:43.000000000 +0200
+++ dehydrated-0.6.2/docs/wellknown.md	2018-04-25 23:22:40.000000000 +0200
@@ -24,7 +24,7 @@
 ```nginx
 server {
   [...]
-  location /.well-known/acme-challenge {
+  location ^~ /.well-known/acme-challenge {
     alias /var/www/dehydrated;
   }
   [...]
@@ -60,9 +60,19 @@
 With Lighttpd just add this to your config and it should work in any VHost:
 
 ```lighttpd
-modules += "alias"
-
+server.modules += ("alias")
 alias.url += (
- "/.well-known/acme-challenge/" => "/var/www/dehydrated/"
+ "/.well-known/acme-challenge/" => "/var/www/dehydrated/",
 )
 ```
+
+
+### Hiawatha example config
+
+With Hiawatha just add an alias to your config file for each VirtualHost and it should work:
+```hiawatha
+VirtualHost {
+    Hostname = example.tld subdomain.mywebsite.tld
+    Alias = /.well-known/acme-challenge:/var/www/dehydrated
+}
+```
diff -Nru dehydrated-0.3.1/.gitignore dehydrated-0.6.2/.gitignore
--- dehydrated-0.3.1/.gitignore	2016-09-13 20:00:43.000000000 +0200
+++ dehydrated-0.6.2/.gitignore	2018-04-25 23:22:40.000000000 +0200
@@ -6,3 +6,4 @@
 certs/*
 archive/*
 accounts/*
+chains/*
diff -Nru dehydrated-0.3.1/LICENSE dehydrated-0.6.2/LICENSE
--- dehydrated-0.3.1/LICENSE	2016-09-13 20:00:43.000000000 +0200
+++ dehydrated-0.6.2/LICENSE	2018-04-25 23:22:40.000000000 +0200
@@ -1,6 +1,6 @@
 The MIT License (MIT)
 
-Copyright (c) 2015 Lukas Schauer
+Copyright (c) 2015-2018 Lukas Schauer
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
diff -Nru dehydrated-0.3.1/README.md dehydrated-0.6.2/README.md
--- dehydrated-0.3.1/README.md	2016-09-13 20:00:43.000000000 +0200
+++ dehydrated-0.6.2/README.md	2018-04-25 23:22:40.000000000 +0200
@@ -1,32 +1,45 @@
-# dehydrated [![Build Status](https://travis-ci.org/lukas2511/dehydrated.svg?branch=master)](https://travis-ci.org/lukas2511/dehydrated)
+# dehydrated [![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=23P9DSJBTY7C8)
 
 ![](docs/logo.jpg)
 
-This is a client for signing certificates with an ACME-server (currently only provided by letsencrypt) implemented as a relatively simple bash-script.
+Dehydrated is a client for signing certificates with an ACME-server (e.g. Let's Encrypt) implemented as a relatively simple (zsh-compatible) bash-script.
+This client supports both ACME v1 and the new ACME v2 including support for wildcard certificates!
 
 It uses the `openssl` utility for everything related to actually handling keys and certificates, so you need to have that installed.
 
-Other dependencies are: curl, sed, grep, mktemp (all found on almost any system, curl being the only exception)
+Other dependencies are: cURL, sed, grep, awk, mktemp (all found pre-installed on almost any system, cURL being the only exception).
 
 Current features:
-- Signing of a list of domains
-- Signing of a CSR
-- Renewal if a certificate is about to expire or SAN (subdomains) changed
+- Signing of a list of domains (including wildcard domains!)
+- Signing of a custom CSR (either standalone or completely automated using hooks!)
+- Renewal if a certificate is about to expire or defined set of domains changed
 - Certificate revocation
 
-Please keep in mind that this software and even the acme-protocol are relatively young and may still have some unresolved issues.
-Feel free to report any issues you find with this script or contribute by submitting a pullrequest.
+Please keep in mind that this software, the ACME-protocol and all supported CA servers out there are relatively young and there might be a few issues. Feel free to report any issues you find with this script or contribute by submitting a pull request,
+but please check for duplicates first (feel free to comment on those to get things rolling).
 
-### Getting started
+## Getting started
 
 For getting started I recommend taking a look at [docs/domains_txt.md](docs/domains_txt.md), [docs/wellknown.md](docs/wellknown.md) and the [Usage](#usage) section on this page (you'll probably only need the `-c` option).
 
 Generally you want to set up your WELLKNOWN path first, and then fill in domains.txt.
 
-**Please note that you should use the staging URL when experimenting with this script to not hit letsencrypts rate limits.** See [docs/staging.md](docs/staging.md).
+**Please note that you should use the staging URL when experimenting with this script to not hit Let's Encrypt's rate limits.** See [docs/staging.md](docs/staging.md).
 
 If you have any problems take a look at our [Troubleshooting](docs/troubleshooting.md) guide.
 
+## Config
+
+dehydrated is looking for a config file in a few different places, it will use the first one it can find in this order:
+
+- `/etc/dehydrated/config`
+- `/usr/local/etc/dehydrated/config`
+- The current working directory of your shell
+- The directory from which dehydrated was run
+
+Have a look at [docs/examples/config](docs/examples/config) to get started, copy it to e.g. `/etc/dehydrated/config`
+and edit it to fit your needs.
+
 ## Usage:
 
 ```text
@@ -35,7 +48,10 @@
 Default command: help
 
 Commands:
- --cron (-c)                      Sign/renew non-existant/changed/expiring certificates.
+ --version (-v)                   Print version information
+ --register                       Register account key
+ --account                        Update account contact information
+ --cron (-c)                      Sign/renew non-existent/changed/expiring certificates.
  --signcsr (-s) path/to/csr.pem   Sign a given CSR, output CRT on stdout (advanced usage)
  --revoke (-r) path/to/cert.pem   Revoke specified certificate
  --cleanup (-gc)                  Move unused certificate files to archive directory
@@ -43,13 +59,16 @@
  --env (-e)                       Output configuration variables for use in other scripts
 
 Parameters:
+ --accept-terms                   Accept CAs terms of service
  --full-chain (-fc)               Print full chain when using --signcsr
  --ipv4 (-4)                      Resolve names to IPv4 addresses only
  --ipv6 (-6)                      Resolve names to IPv6 addresses only
  --domain (-d) domain.tld         Use specified domain name(s) instead of domains.txt entry (one certificate!)
+ --alias certalias                Use specified name for certificate directory (and per-certificate config) instead of the primary domain (only used if --domain is specified)
  --keep-going (-g)                Keep going after encountering an error while creating/renewing multiple certificates in cron mode
  --force (-x)                     Force renew of certificate even if it is longer valid than value in RENEW_DAYS
  --no-lock (-n)                   Don't use lockfile (potentially dangerous!)
+ --lock-suffix example.com        Suffix lockfile name with a string (useful for with -d)
  --ocsp                           Sets option in CSR indicating OCSP stapling to be mandatory
  --privkey (-p) path/to/key.pem   Use specified private key instead of account key (useful for revocation)
  --config (-f) path/to/config     Use specified config file
@@ -58,3 +77,25 @@
  --challenge (-t) http-01|dns-01  Which challenge should be used? Currently http-01 and dns-01 are supported
  --algo (-a) rsa|prime256v1|secp384r1 Which public key algorithm should be used? Supported: rsa, prime256v1 and secp384r1
 ```
+
+## Donate
+
+I'm a student hacker with a few (unfortunately) quite expensive hobbies (self-hosting, virtualization clusters, routing,
+high-speed networking, embedded hardware, etc.).
+I'm really having fun playing around with hard- and software and I'm steadily learning new things.
+Without those hobbies I probably would never have started working on dehydrated to begin with :)
+
+I'd really appreciate if you could [donate a bit of money](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=23P9DSJBTY7C8)
+so I can buy cool stuff (while still being able to afford food :D).  
+
+If you have hardware laying around that you think I'd enjoy playing with (e.g. decommissioned but still modern-ish servers,
+10G networking hardware, enterprise grade routers or APs, interesting ARM/MIPS boards, etc.) and that you would be willing
+to ship to me please contact me at `donations@dehydrated.io` or on Twitter [@lukas2511](https://twitter.com/lukas2511).
+
+If you want your name to be added to the [donations list](https://dehydrated.io/donations.html) please add a note or send me an
+email `donations@dehydrated.io`. I respect your privacy and won't publish your name without permission.
+
+Other ways of donating:
+ - [My Amazon Wishlist](http://www.amazon.de/registry/wishlist/1TUCFJK35IO4Q)
+ - Monero: 4Kkf4tF4r9DakxLj37HDXLJgmpVfQoFhT7JLDvXwtUZZMTbsK9spsAPXivWPAFcDUj6jHhY8hJSHX8Cb8ndMhKeQHPSkBZZiK89Fx8NTHk
+ - Bitcoin: 12487bHxcrREffTGwUDnoxF1uYxCA7ztKK
diff -Nru dehydrated-0.3.1/test.sh dehydrated-0.6.2/test.sh
--- dehydrated-0.3.1/test.sh	2016-09-13 20:00:43.000000000 +0200
+++ dehydrated-0.6.2/test.sh	1970-01-01 01:00:00.000000000 +0100
@@ -1,221 +0,0 @@
-#!/usr/bin/env bash
-
-# Fail early
-set -eu -o pipefail
-
-# Check if running in CI environment
-if [[ ! "${CI:-false}" == "true" ]]; then
-  echo "ERROR: Not running in CI environment!"
-  exit 1
-fi
-
-_TEST() {
-  echo
-  echo "${1} "
-}
-_SUBTEST() {
-  echo -n " + ${1} "
-}
-_PASS() {
-  echo -e "[\u001B[32mPASS\u001B[0m]"
-}
-_FAIL() {
-  echo -e "[\u001B[31mFAIL\u001B[0m]"
-  echo
-  echo "Problem: ${@}"
-  echo
-  echo "STDOUT:"
-  cat tmplog
-  echo
-  echo "STDERR:"
-  cat errorlog
-  exit 1
-}
-_CHECK_FILE() {
-  _SUBTEST "Checking if file '${1}' exists..."
-  if [[ -e "${1}" ]]; then
-    _PASS
-  else
-    _FAIL "Missing file: ${1}"
-  fi
-}
-_CHECK_LOG() {
-  _SUBTEST "Checking if log contains '${1}'..."
-  if grep -- "${1}" tmplog > /dev/null; then
-    _PASS
-  else
-    _FAIL "Missing in log: ${1}"
-  fi
-}
-_CHECK_NOT_LOG() {
-  _SUBTEST "Checking if log doesn't contain '${1}'..."
-  if grep -- "${1}" tmplog > /dev/null; then
-    _FAIL "Found in log: ${1}"
-  else
-    _PASS
-  fi
-}
-_CHECK_ERRORLOG() {
-  _SUBTEST "Checking if errorlog is empty..."
-  if [[ -z "$(cat errorlog)" ]]; then
-    _PASS
-  else
-    _FAIL "Non-empty errorlog"
-  fi
-}
-
-# If not found (should be cached in travis) download ngrok
-if [[ ! -e "ngrok/ngrok" ]]; then
-  (
-    mkdir -p ngrok
-    cd ngrok
-    wget https://dl.ngrok.com/ngrok_2.0.19_linux_amd64.zip -O ngrok.zip
-    unzip ngrok.zip ngrok
-    chmod +x ngrok
-  )
-fi
-
-# Run ngrok and grab temporary url from logfile
-ngrok/ngrok http 8080 --log stdout --log-format logfmt --log-level debug > tmp.log &
-ngrok/ngrok http 8080 --log stdout --log-format logfmt --log-level debug > tmp2.log &
-ngrok/ngrok http 8080 --log stdout --log-format logfmt --log-level debug > tmp3.log &
-sleep 2
-TMP_URL="$(grep -Eo "Hostname:[a-z0-9]+.ngrok.io" tmp.log | head -1 | cut -d':' -f2)"
-TMP2_URL="$(grep -Eo "Hostname:[a-z0-9]+.ngrok.io" tmp2.log | head -1 | cut -d':' -f2)"
-TMP3_URL="$(grep -Eo "Hostname:[a-z0-9]+.ngrok.io" tmp3.log | head -1 | cut -d':' -f2)"
-if [[ -z "${TMP_URL}" ]] || [[ -z "${TMP2_URL}" ]] || [[ -z "${TMP3_URL}" ]]; then
-  echo "Couldn't get an url from ngrok, not a dehydrated bug, tests can't continue."
-  exit 1
-fi
-
-# Run python webserver in .acme-challenges directory to serve challenge responses
-mkdir -p .acme-challenges/.well-known/acme-challenge
-(
-  cd .acme-challenges
-  python -m SimpleHTTPServer 8080 > /dev/null 2> /dev/null
-) &
-
-# Generate config and create empty domains.txt
-echo 'CA="https://testca.kurz.pw/directory";' > config
-echo 'LICENSE="https://testca.kurz.pw/terms/v1";' >> config
-echo 'WELLKNOWN=".acme-challenges/.well-known/acme-challenge"' >> config
-echo 'RENEW_DAYS="14"' >> config
-touch domains.txt
-
-# Check if help command is working
-_TEST "Checking if help command is working..."
-./dehydrated --help > tmplog 2> errorlog || _FAIL "Script execution failed"
-_CHECK_LOG "Default command: help"
-_CHECK_LOG "--help (-h)"
-_CHECK_LOG "--domain (-d) domain.tld"
-_CHECK_ERRORLOG
-
-# Run in cron mode with empty domains.txt (should only generate private key and exit)
-_TEST "First run in cron mode, checking if private key is generated and registered"
-./dehydrated --cron > tmplog 2> errorlog || _FAIL "Script execution failed"
-_CHECK_LOG "Registering account key"
-_CHECK_FILE accounts/*/account_key.pem
-_CHECK_ERRORLOG
-
-# Temporarily move config out of the way and try signing certificate by using temporary config location
-_TEST "Try signing using temporary config location and with domain as command line parameter"
-mv config tmp_config
-./dehydrated --cron --domain "${TMP_URL}" --domain "${TMP2_URL}" -f tmp_config > tmplog 2> errorlog || _FAIL "Script execution failed"
-_CHECK_NOT_LOG "Checking domain name(s) of existing cert"
-_CHECK_LOG "Generating private key"
-_CHECK_LOG "Requesting challenge for ${TMP_URL}"
-_CHECK_LOG "Requesting challenge for ${TMP2_URL}"
-_CHECK_LOG "Challenge is valid!"
-_CHECK_LOG "Creating fullchain.pem"
-_CHECK_LOG "Done!"
-_CHECK_ERRORLOG
-mv tmp_config config
-
-# Add third domain to command-lime, should force renewal.
-_TEST "Run in cron mode again, this time adding third domain, should force renewal."
-./dehydrated --cron --domain "${TMP_URL}" --domain "${TMP2_URL}" --domain "${TMP3_URL}" > tmplog 2> errorlog || _FAIL "Script execution failed"
-_CHECK_LOG "Domain name(s) are not matching!"
-_CHECK_LOG "Forcing renew."
-_CHECK_LOG "Generating private key"
-_CHECK_LOG "Requesting challenge for ${TMP_URL}"
-_CHECK_LOG "Requesting challenge for ${TMP2_URL}"
-_CHECK_LOG "Requesting challenge for ${TMP3_URL}"
-_CHECK_LOG "Challenge is valid!"
-_CHECK_LOG "Creating fullchain.pem"
-_CHECK_LOG "Done!"
-_CHECK_ERRORLOG
-
-# Prepare domains.txt
-# Modify TMP3_URL to be uppercase to check for upper-lower-case mismatch bugs
-echo "${TMP_URL} ${TMP2_URL} $(tr 'a-z' 'A-Z' <<<"${TMP3_URL}")" >> domains.txt
-
-# Run in cron mode again (should find a non-expiring certificate and do nothing)
-_TEST "Run in cron mode again, this time with domain in domains.txt, should find non-expiring certificate"
-./dehydrated --cron > tmplog 2> errorlog || _FAIL "Script execution failed"
-_CHECK_LOG "Checking domain name(s) of existing cert... unchanged."
-_CHECK_LOG "Skipping renew"
-_CHECK_ERRORLOG
-
-# Disable private key renew
-echo 'PRIVATE_KEY_RENEW="no"' >> config
-
-# Run in cron mode one last time, with domain in domains.txt and force-resign (should find certificate, resign anyway, and not generate private key)
-_TEST "Run in cron mode one last time, with domain in domains.txt and force-resign"
-./dehydrated --cron --force > tmplog 2> errorlog || _FAIL "Script execution failed"
-_CHECK_LOG "Checking domain name(s) of existing cert... unchanged."
-_CHECK_LOG "Ignoring because renew was forced!"
-_CHECK_NOT_LOG "Generating private key"
-_CHECK_LOG "Requesting challenge for ${TMP_URL}"
-_CHECK_LOG "Requesting challenge for ${TMP2_URL}"
-_CHECK_LOG "Requesting challenge for ${TMP3_URL}"
-_CHECK_LOG "Challenge is valid!"
-_CHECK_LOG "Creating fullchain.pem"
-_CHECK_LOG "Done!"
-_CHECK_ERRORLOG
-
-# Check if signcsr command is working
-_TEST "Running signcsr command"
-./dehydrated --signcsr certs/${TMP_URL}/cert.csr > tmplog 2> errorlog || _FAIL "Script execution failed"
-_CHECK_LOG "BEGIN CERTIFICATE"
-_CHECK_LOG "END CERTIFICATE"
-_CHECK_NOT_LOG "ERROR"
-
-# Check if renewal works
-_TEST "Run in cron mode again, to check if renewal works"
-echo 'RENEW_DAYS="300"' >> config
-./dehydrated --cron > tmplog 2> errorlog || _FAIL "Script execution failed"
-_CHECK_LOG "Checking domain name(s) of existing cert... unchanged."
-_CHECK_LOG "Renewing!"
-_CHECK_ERRORLOG
-
-# Check if certificate is valid in various ways
-_TEST "Verifying certificate..."
-_SUBTEST "Verifying certificate on its own..."
-openssl x509 -in "certs/${TMP_URL}/cert.pem" -noout -text > tmplog 2> errorlog && _PASS || _FAIL
-_CHECK_LOG "CN=${TMP_URL}"
-_CHECK_LOG "${TMP2_URL}"
-_SUBTEST "Verifying file with full chain..."
-openssl x509 -in "certs/${TMP_URL}/fullchain.pem" -noout -text > /dev/null 2>> errorlog && _PASS || _FAIL
-_SUBTEST "Verifying certificate against CA certificate..."
-(openssl verify -verbose -CAfile "certs/${TMP_URL}/fullchain.pem" -purpose sslserver "certs/${TMP_URL}/fullchain.pem" 2>&1 || true) | (grep -v ': OK$' || true) >> errorlog 2>> errorlog && _PASS || _FAIL
-_CHECK_ERRORLOG
-
-# Revoke certificate using certificate key
-_TEST "Revoking certificate..."
-./dehydrated --revoke "certs/${TMP_URL}/cert.pem" --privkey "certs/${TMP_URL}/privkey.pem" > tmplog 2> errorlog || _FAIL "Script execution failed"
-REAL_CERT="$(readlink -n "certs/${TMP_URL}/cert.pem")"
-_CHECK_LOG "Revoking certs/${TMP_URL}/${REAL_CERT}"
-_CHECK_LOG "Done."
-_CHECK_FILE "certs/${TMP_URL}/${REAL_CERT}-revoked"
-_CHECK_ERRORLOG
-
-# Test cleanup command
-_TEST "Cleaning up certificates"
-./dehydrated --cleanup > tmplog 2> errorlog || _FAIL "Script execution failed"
-_CHECK_LOG "Moving unused file to archive directory: ${TMP_URL}/cert-"
-_CHECK_LOG "Moving unused file to archive directory: ${TMP_URL}/chain-"
-_CHECK_LOG "Moving unused file to archive directory: ${TMP_URL}/fullchain-"
-_CHECK_ERRORLOG
-
-# All done
-exit 0
diff -Nru dehydrated-0.3.1/.travis.yml dehydrated-0.6.2/.travis.yml
--- dehydrated-0.3.1/.travis.yml	2016-09-13 20:00:43.000000000 +0200
+++ dehydrated-0.6.2/.travis.yml	1970-01-01 01:00:00.000000000 +0100
@@ -1,10 +0,0 @@
-sudo: false
-language: shell
-
-cache:
-  directories:
-    - ngrok
-
-script:
-  - export CI="true"
-  - ./test.sh
diffstat for dehydrated-0.6.2 dehydrated-0.6.2

 changelog                                                               |    8 
 compat                                                                  |    2 
 control                                                                 |   42 ++++
 gbp.conf                                                                |    2 
 letsencrypt.sh-apache2.NEWS                                             |   12 +
 letsencrypt.sh-apache2.apache2                                          |    1 
 letsencrypt.sh-apache2.lintian-overrides                                |    6 
 letsencrypt.sh.NEWS                                                     |   62 ++++++
 letsencrypt.sh.README.Debian                                            |   25 ++
 letsencrypt.sh.conf                                                     |   34 +++
 letsencrypt.sh.dirs                                                     |    1 
 letsencrypt.sh.install                                                  |    1 
 letsencrypt.sh.lintian-overrides                                        |    2 
 letsencrypt.sh.postinst                                                 |   92 ++++++++++
 letsencrypt.sh.postrm                                                   |   32 +++
 patches/Support-both-config.sh-and-config-as-config-filenames-for.patch |   30 +++
 patches/Update-the-location-of-WELLKNOWN-in-the-notice-message-of.patch |   31 +++
 patches/added-temporary-wrapper-script-for-compatibility-with-old.patch |   81 ++++++++
 patches/honor-config-if-the-user-provided-one-to-letsencrypt.sh-w.patch |   37 ++++
 patches/series                                                          |    7 
 rules                                                                   |    2 
 21 files changed, 505 insertions(+), 5 deletions(-)

diff -Nru dehydrated-0.6.2/debian/changelog dehydrated-0.6.2/debian/changelog
--- dehydrated-0.6.2/debian/changelog	2019-07-19 14:59:11.000000000 +0200
+++ dehydrated-0.6.2/debian/changelog	2020-01-18 15:13:17.000000000 +0100
@@ -1,3 +1,11 @@
+dehydrated (0.6.2-2+deb10u1~deb9u1) UNRELEASED; urgency=medium
+
+  * Backport 0.6.2-2 from buster into stretch.
+    + In the process, retain the letsencrypt.sh compatibility binaries.
+    + Also, revert debhelper compat bump and Multi-Arch field.
+
+ -- Mattia Rizzolo <mattia@debian.org>  Sat, 18 Jan 2020 15:13:17 +0100
+
 dehydrated (0.6.2-2+deb10u1) buster; urgency=medium
 
   * Add three more patches from upstream.
diff -Nru dehydrated-0.6.2/debian/compat dehydrated-0.6.2/debian/compat
--- dehydrated-0.6.2/debian/compat	2019-07-19 14:59:11.000000000 +0200
+++ dehydrated-0.6.2/debian/compat	2020-01-18 15:12:44.000000000 +0100
@@ -1 +1 @@
-11
+10
diff -Nru dehydrated-0.6.2/debian/control dehydrated-0.6.2/debian/control
--- dehydrated-0.6.2/debian/control	2019-07-19 14:59:11.000000000 +0200
+++ dehydrated-0.6.2/debian/control	2020-01-18 15:13:17.000000000 +0100
@@ -7,7 +7,7 @@
  Mattia Rizzolo <mattia@debian.org>,
 Build-Depends:
  apache2-dev,
- debhelper (>= 11),
+ debhelper (>= 10),
  dh-apache2,
  dh-exec,
 Standards-Version: 4.3.0
@@ -18,7 +18,6 @@
 
 Package: dehydrated
 Architecture: all
-Multi-Arch: foreign
 Depends:
  ca-certificates,
  curl,
@@ -47,3 +46,42 @@
  .
  Installing this package together with dehydrated is enough to have a fully
  functional ACME client, including replying to the HTTP challenge.
+
+Package: letsencrypt.sh
+Architecture: all
+Priority: extra
+Section: oldlibs
+Depends:
+ dehydrated,
+ ${misc:Depends},
+Description: ACME client - transitional dummy package to dehydrated
+ The dehydrated ACME client allows signing certificates with an
+ ACME server, like the one provided by the Let’s Encrypt certificate
+ authority (letsencrypt.org).  It is implemented as a relatively simple
+ Bash script, which uses curl to communicate with the ACME server and
+ OpenSSL to deal with keys, sign requests and certificates.
+ .
+ letsencrypt.sh was the old name of this project, it has been renamed to
+ dehydrated.  This transitional package provides a transitional  wrapper.
+ Once any local script has been adapted it is safe to remove it.
+
+Package: letsencrypt.sh-apache2
+Architecture: all
+Priority: extra
+Section: oldlibs
+Depends:
+ dehydrated-apache2,
+ ${misc:Depends},
+Recommends:
+ letsencrypt.sh,
+ ${misc:Recommends},
+Description: letsencrypt.sh support for Apache2 - transitional dummy package
+ This package provides an Apache2 config snippet to serve the http-01 challenge
+ responses for letsencrypt.sh.
+ .
+ Installing this package together with letsencrypt.sh is enough to have a fully
+ functional ACME client, including replying to the HTTP challenge.
+ .
+ letsencrypt.sh was the old name of this project, it has been renamed to
+ dehydrated.  This package depends on the new dehydrated-apache2 to easy the
+ transition.  Once any local script has been adapted it is safe to remove it.
diff -Nru dehydrated-0.6.2/debian/gbp.conf dehydrated-0.6.2/debian/gbp.conf
--- dehydrated-0.6.2/debian/gbp.conf	2019-07-19 14:59:11.000000000 +0200
+++ dehydrated-0.6.2/debian/gbp.conf	2020-01-18 15:13:17.000000000 +0100
@@ -1,6 +1,6 @@
 [DEFAULT]
 upstream-branch = upstream/master
-debian-branch = debian/buster
+debian-branch = debian/stretch-updated
 upstream-tag = v%(version)s
 pristine-tar = True
 pristine-tar-commit = True
diff -Nru dehydrated-0.6.2/debian/letsencrypt.sh-apache2.apache2 dehydrated-0.6.2/debian/letsencrypt.sh-apache2.apache2
--- dehydrated-0.6.2/debian/letsencrypt.sh-apache2.apache2	1970-01-01 01:00:00.000000000 +0100
+++ dehydrated-0.6.2/debian/letsencrypt.sh-apache2.apache2	2020-01-18 15:10:11.000000000 +0100
@@ -0,0 +1 @@
+conf debian/letsencrypt.sh.conf
diff -Nru dehydrated-0.6.2/debian/letsencrypt.sh-apache2.lintian-overrides dehydrated-0.6.2/debian/letsencrypt.sh-apache2.lintian-overrides
--- dehydrated-0.6.2/debian/letsencrypt.sh-apache2.lintian-overrides	1970-01-01 01:00:00.000000000 +0100
+++ dehydrated-0.6.2/debian/letsencrypt.sh-apache2.lintian-overrides	2020-01-18 15:10:11.000000000 +0100
@@ -0,0 +1,6 @@
+# letsencrypt.sh.conf is a cool name for this configuration file, and doesn't
+# really need to be named after the actual binary that ships it.
+# (and of course there is no risk of name collisions)
+non-standard-apache2-configuration-name
+# These are in branches checking for the version
+apache2-deprecated-auth-config
diff -Nru dehydrated-0.6.2/debian/letsencrypt.sh-apache2.NEWS dehydrated-0.6.2/debian/letsencrypt.sh-apache2.NEWS
--- dehydrated-0.6.2/debian/letsencrypt.sh-apache2.NEWS	1970-01-01 01:00:00.000000000 +0100
+++ dehydrated-0.6.2/debian/letsencrypt.sh-apache2.NEWS	2020-01-18 15:10:11.000000000 +0100
@@ -0,0 +1,12 @@
+letsencrypt.sh-apache2 (0.3.1-2) unstable; urgency=medium
+
+  The letsencrypt.sh project has been renamed to 'dehydrated' to comply with
+  the Let's Encrypt trademark policy.
+  Therefore, this package now depends on a new dehydrated-apache2 package, to
+  help administrators move to the new packages.
+  If you were using the default configuration, and moved everything over from
+  letsencrypt.sh to dehydrated (configuration and file), and updated the
+  relevant paths in letsencrypt.sh configuration, this should keep everything
+  running smoothly.
+
+ -- Mattia Rizzolo <mattia@debian.org>  Thu, 12 Jan 2017 18:56:35 +0100
diff -Nru dehydrated-0.6.2/debian/letsencrypt.sh.conf dehydrated-0.6.2/debian/letsencrypt.sh.conf
--- dehydrated-0.6.2/debian/letsencrypt.sh.conf	1970-01-01 01:00:00.000000000 +0100
+++ dehydrated-0.6.2/debian/letsencrypt.sh.conf	2020-01-18 15:10:11.000000000 +0100
@@ -0,0 +1,34 @@
+#
+# Apache configuration to serve http-01 ACME challenges responses.
+# This is included from the letsencrypt.sh-apache2 package, thought to be used
+# with letsencrypt.sh as packaged in Debian.
+
+
+<IfModule proxy_module>
+    # Do not proxy ACME challenge responses
+    ProxyPass /.well-known/acme-challenge/ !
+</IfModule>
+<IfModule !alias_module>
+    # Load the alias module, if not loaded already
+    Include /etc/apache2/mods-available/alias.load
+    Include /etc/apache2/mods-available/alias.conf
+</IfModule>
+<IfModule alias_module>
+    # Serve ACME challenge responses
+    Alias /.well-known/acme-challenge/ /var/lib/letsencrypt.sh/acme-challenges/
+</IfModule>
+
+<Directory /var/lib/letsencrypt.sh/acme-challenges/>
+    Options FollowSymlinks
+    Options -Indexes
+    AllowOverride None
+    # Apache >= 2.3
+    <IfModule mod_authz_core.c>
+        Require all granted
+    </IfModule>
+    # Apache < 2.3
+    <IfModule !mod_authz_core.c>
+        Order Allow,Deny
+        Allow from all
+    </IfModule>
+</Directory>
diff -Nru dehydrated-0.6.2/debian/letsencrypt.sh.dirs dehydrated-0.6.2/debian/letsencrypt.sh.dirs
--- dehydrated-0.6.2/debian/letsencrypt.sh.dirs	1970-01-01 01:00:00.000000000 +0100
+++ dehydrated-0.6.2/debian/letsencrypt.sh.dirs	2020-01-18 15:10:11.000000000 +0100
@@ -0,0 +1 @@
+/var/lib/letsencrypt.sh/acme-challenges/
diff -Nru dehydrated-0.6.2/debian/letsencrypt.sh.install dehydrated-0.6.2/debian/letsencrypt.sh.install
--- dehydrated-0.6.2/debian/letsencrypt.sh.install	1970-01-01 01:00:00.000000000 +0100
+++ dehydrated-0.6.2/debian/letsencrypt.sh.install	2020-01-18 15:10:11.000000000 +0100
@@ -0,0 +1 @@
+letsencrypt.sh usr/bin
diff -Nru dehydrated-0.6.2/debian/letsencrypt.sh.lintian-overrides dehydrated-0.6.2/debian/letsencrypt.sh.lintian-overrides
--- dehydrated-0.6.2/debian/letsencrypt.sh.lintian-overrides	1970-01-01 01:00:00.000000000 +0100
+++ dehydrated-0.6.2/debian/letsencrypt.sh.lintian-overrides	2020-01-18 15:10:11.000000000 +0100
@@ -0,0 +1,2 @@
+# "letsencrypt.sh" actually is the official name of the command
+letsencrypt.sh binary: script-with-language-extension usr/bin/letsencrypt.sh
diff -Nru dehydrated-0.6.2/debian/letsencrypt.sh.NEWS dehydrated-0.6.2/debian/letsencrypt.sh.NEWS
--- dehydrated-0.6.2/debian/letsencrypt.sh.NEWS	1970-01-01 01:00:00.000000000 +0100
+++ dehydrated-0.6.2/debian/letsencrypt.sh.NEWS	2020-01-18 15:10:11.000000000 +0100
@@ -0,0 +1,62 @@
+letsencrypt.sh (0.3.1-2) unstable; urgency=medium
+
+  The letsencrypt.sh project has been renamed to 'dehydrated' to comply with
+  the Let's Encrypt trademark policy.
+  Therefore, this package now depends on a new dehydrated package, and only
+  ships a wrapper script which invokes dehydrated pointin to the old
+  configuration.  Administrators are invited to move their configuration and
+  all of their files over under the dehydated namespace.  The following
+  should take care of most of them, assuming the default configuration is used:
+    mv -v /etc/letsencrypt.sh/domains.txt /etc/dehydrated/
+    mv -v /etc/letsencrypt.sh/conf.d/* /etc/dehydrated/conf.d/
+    mv -v /var/lib/letsencrypt.sh/accounts /var/lib/dehydrated/
+    mv -v /var/lib/letsencrypt.sh/certs /var/lib/dehydrated/
+  You also need to edit the configuration in /etc/dehydrated to use the new
+  paths (e.g. /var/lib/dehydrated instead of /var/lib/letsencrypt.sh).  Also
+  take care to reply any change manually done to /etc/letsencrypt.sh/config.sh
+  into config snippets in /etc/dehydrated/conf.d/.
+  After these you should be able to switch to use the `dehydrated` command, and
+  to remove the letsencrypt.sh package.
+  Before moving anything take care to make backups of the certificates and of
+  the configuration.
+
+ -- Mattia Rizzolo <mattia@debian.org>  Thu, 12 Jan 2017 18:43:24 +0100
+
+letsencrypt.sh (0.3.0-1) unstable; urgency=medium
+
+  The configuration options ACCOUNT_KEY and ACCOUNT_KEY_JSON have been
+  deprecated in favour of a multi-account structure.
+  There is a new ACCOUNTDIR option (defaulting to ${BASEDIR}/accounts) which
+  can be used to specify the starting path of where to place those keys.
+  In the event a ACCOUNT_KEY option is set and points to an existing file (or
+  a file is present in the former default location ${BASEDIR}/private_key.pem)
+  _and_ there is no file in the final new location, an automatic migration
+  is performed, by moving the relevant files.
+
+ -- Mattia Rizzolo <mattia@debian.org>  Wed, 30 Nov 2016 20:46:53 +0100
+
+letsencrypt.sh (0.2.0-1) unstable; urgency=medium
+
+  The configuration options PRIVATE_KEY and PRIVATE_KEY_JSON have been
+  renamed to ACCOUNT_KEY and ACCOUNT_KEY_JSON to avoid confusion with
+  the generic term "private key" which is already overloaded.
+  During upgrade from older versions it is checked whether those
+  old configurations options are used and an extra configuration file
+  /etc/letsencrypt.sh/conf.d/zzz_debian_old_private_key_configuration_in_use.sh
+  is automatically added to translate them to their new counterparts if
+  needed.
+
+  The default location for a domain.txt has been changed in Debian
+  from: ${BASEDIR}/domains.txt
+  to:   /etc/letsencrypt.sh/domains.txt
+  By default in Debian ${BASEDIR} is set to /var/lib/letsencrypt.sh.
+  During upgrade from older versions it is checked whether a
+  ${BASEDIR}/domains.txt is present and an extra configuration file
+  /etc/letsencrypt.sh/conf.d/000_debian_old_domains_txt_location.sh
+  is automatically added to support the previously used domain.txt file if
+  needed.
+
+  Nevertheless we strongly suggest you to adapt your setup to the newer
+  defaults and remove the automatically generated configuration files.
+
+ -- Daniel Beyer <dabe@deb.ymc.ch>  Mon, 13 Jun 2016 09:35:39 +0200
diff -Nru dehydrated-0.6.2/debian/letsencrypt.sh.postinst dehydrated-0.6.2/debian/letsencrypt.sh.postinst
--- dehydrated-0.6.2/debian/letsencrypt.sh.postinst	1970-01-01 01:00:00.000000000 +0100
+++ dehydrated-0.6.2/debian/letsencrypt.sh.postinst	2020-01-18 15:10:11.000000000 +0100
@@ -0,0 +1,92 @@
+#!/bin/bash
+# postinst script for letsencrypt.sh
+#
+# see: dh_installdeb(1)
+
+set -e
+
+#DEBHELPER#
+
+case "$1" in
+  configure)
+    if [ -n "$2" ] && \
+       `dpkg --compare-versions "$2" '<<' "0.2.0-1~"`; then
+      ### Only act on upgrade to 0.2.0-1 ###
+      # Get variable $BASEDIR
+      BASEDIR="$(echo $(. letsencrypt.sh -e 1>/dev/null && echo ${BASEDIR}))"
+      # Get variable $PRIVATE_KEY
+      PRIVATE_KEY="$(echo $(. letsencrypt.sh -e 1>/dev/null && echo ${PRIVATE_KEY:-}))"
+      # Get variable $PRIVATE_KEY_JSON
+      PRIVATE_KEY_JSON="$(echo $(. letsencrypt.sh -e 1>/dev/null && echo ${PRIVATE_KEY_JSON:-}))"
+      # Get variable $DOMAINS_TXT
+      eval $(letsencrypt.sh -e | grep -E -e '^declare -- DOMAINS_TXT=')
+
+      # Care about the location of domains.txt
+      if [ "/etc/letsencrypt.sh/domains.txt" = "${DOMAINS_TXT}" ] && \
+         [ -r "${BASEDIR}/domains.txt" ]; then
+        # New default location for domains.txt in use, but a domains.txt
+        # is present at the old default location. Let's provide a
+        # configuration to point domains.txt back to the old default location
+        cat > /etc/letsencrypt.sh/conf.d/000_debian_old_domains_txt_location.sh << EOF
+# This file was automatically provided by the letsencrypt.sh package during
+# upgrade from version $2.
+# Starting with version 0.2.0-1~ of letsencrypt.sh in Debian the domains.txt
+# file is looked for at '/etc/letsencrypt.sh/domains.txt'. Previously it was
+# looked for at '\${BASEDIR}/domains.txt'.
+# During upgrade from version $2 a file '\${BASEDIR}/domains.txt' was found
+# on the local system and this configuration was automatically created, since
+# otherwise the file '\${BASEDIR}/domains.txt' would no longer be respected,
+# which might prevent letsencrypt.sh to work properly.
+#
+# It is strongly suggested to move '\${BASEDIR}/domains.txt' to
+# '/etc/letsencrypt.sh/domains.txt' and remove this configuration file
+# '/etc/letsencrypt.sh/conf.d/000_debian_old_domains_txt_location' afterwards.
+#
+# NOTE: During upgrade \${BASEDIR} was set to '${BASEDIR}'
+
+DOMAINS_TXT="\${BASEDIR}/domains.txt"
+EOF
+      fi
+
+      # Care about gone config variables PRIVATE_KEY and PRIVATE_KEY_JSON
+      if [ -n "${PRIVATE_KEY}" ] || \
+         [ -n "${PRIVATE_KEY_JSON}" ]; then
+        cat > /etc/letsencrypt.sh/conf.d/zzz_debian_old_private_key_configuration_in_use.sh << EOF
+# This file was automatically provided by the letsencrypt.sh package during
+# upgrade from version $2.
+# Starting with version 0.2.0-1~ of letsencrypt.sh the configuration options
+# PRIVATE_KEY and PRIVATE_KEY_JSON have been renamed to ACCOUNT_KEY and
+# ACCOUNT_KEY_JSON.
+# During upgrade from version $2 it was found that one or both of the
+# old configuration options are in use on the local system and this
+# configuration file was automatically created, so letsencrypt.sh hopefully
+# continue to work as expected.
+#
+# It is strongly suggested to adapt the local configuration to use ACCOUNT_KEY
+# instead of PRIVATE_KEY and ACCOUNT_KEY_JSON instead of PRIVATE_KEY_JSON.
+# Once done so this configuration file should be removed
+# /etc/letsencrypt.sh/conf.d/zzz_debian_old_private_key_configuration_in_use.sh
+
+if [ -n "\${PRIVATE_KEY:-}" ]; then
+  ACCOUNT_KEY="\${PRIVATE_KEY}"
+fi
+if [ -n "\${PRIVATE_KEY_JSON:-}" ]; then
+  ACCOUNT_KEY_JSON="\${PRIVATE_KEY_JSON}"
+fi
+EOF
+      fi
+    fi
+  ;;
+
+  abort-upgrade|abort-remove|abort-deconfigure)
+  ;;
+
+  *)
+    echo "postinst called with unknown argument \`$1'" >&2
+    exit 1
+  ;;
+esac
+
+exit 0
+
+
diff -Nru dehydrated-0.6.2/debian/letsencrypt.sh.postrm dehydrated-0.6.2/debian/letsencrypt.sh.postrm
--- dehydrated-0.6.2/debian/letsencrypt.sh.postrm	1970-01-01 01:00:00.000000000 +0100
+++ dehydrated-0.6.2/debian/letsencrypt.sh.postrm	2020-01-18 15:10:11.000000000 +0100
@@ -0,0 +1,32 @@
+#!/bin/sh
+# postrm script for letsencrypt.sh
+#
+# see: dh_installdeb(1)
+
+set -e
+
+#DEBHELPER#
+
+case "$1" in
+  purge)
+    if [ -f "/etc/letsencrypt.sh/conf.d/000_debian_old_domains_txt_location.sh" ]; then
+      rm -f /etc/letsencrypt.sh/conf.d/000_debian_old_domains_txt_location.sh
+    fi
+
+    if [ -f "/etc/letsencrypt.sh/conf.d/zzz_debian_old_private_key_configuration_in_use.sh" ]; then
+      rm -f /etc/letsencrypt.sh/conf.d/zzz_debian_old_private_key_configuration_in_use.sh
+    fi
+  ;;
+
+  remove|disappear|upgrade|failed-upgrade|abort-install|abort-upgrade)
+  ;;
+
+  *)
+    echo "postrm called with unknown argument \`$1'" >&2
+    exit 1
+  ;;
+esac
+
+exit 0
+
+
diff -Nru dehydrated-0.6.2/debian/letsencrypt.sh.README.Debian dehydrated-0.6.2/debian/letsencrypt.sh.README.Debian
--- dehydrated-0.6.2/debian/letsencrypt.sh.README.Debian	1970-01-01 01:00:00.000000000 +0100
+++ dehydrated-0.6.2/debian/letsencrypt.sh.README.Debian	2020-01-18 15:10:11.000000000 +0100
@@ -0,0 +1,25 @@
+The letsencrypt.sh package in Debian is only a transitional package to 
+dehydrated.
+
+The project has been renamed from letsencrypt.sh to dehydrated to comply with
+the Let's Encrypt trademark policy.
+
+To use the program see /usr/share/doc/dehydrated/README.Debian.
+
+If you're upgrading from letsencrypt.sh to dehydrated (recommended), you need
+to move all of the files over under the dehydated namespace.  The following
+should take care of most of them, assuming the default configuration is used:
+    mv -v /etc/letsencrypt.sh/domains.txt /etc/dehydrated/
+    mv -v /etc/letsencrypt.sh/conf.d/* /etc/dehydrated/conf.d/
+    mv -v /var/lib/letsencrypt.sh/accounts /var/lib/dehydrated/
+    mv -v /var/lib/letsencrypt.sh/certs /var/lib/dehydrated/
+You also need to edit the configuration in /etc/dehydrated to use the new
+paths (e.g. /var/lib/dehydrated instead of /var/lib/letsencrypt.sh).  Also
+take care to reply any change manually done to /etc/letsencrypt.sh/config.sh
+into config snippets in /etc/dehydrated/conf.d/.
+After these you should be able to switch to use the `dehydrated` command, and
+to remove the letsencrypt.sh package.
+Before moving anything take care to make backups of the certificates and of
+the configuration.
+
+ -- Mattia Rizzolo <mattia@debian.org>  Tue, 12 Jan 2017 18:33:55 +0100
diff -Nru dehydrated-0.6.2/debian/patches/added-temporary-wrapper-script-for-compatibility-with-old.patch dehydrated-0.6.2/debian/patches/added-temporary-wrapper-script-for-compatibility-with-old.patch
--- dehydrated-0.6.2/debian/patches/added-temporary-wrapper-script-for-compatibility-with-old.patch	1970-01-01 01:00:00.000000000 +0100
+++ dehydrated-0.6.2/debian/patches/added-temporary-wrapper-script-for-compatibility-with-old.patch	2020-01-18 15:13:17.000000000 +0100
@@ -0,0 +1,81 @@
+From: Lukas Schauer <lukas@schauer.so>
+Date: Sat, 17 Sep 2016 12:44:41 +0200
+Subject: added temporary wrapper script for compatibility with old config
+ locations and symlinks, will be removed in a few weeks
+
+[ edit: drop changes in README.md ]
+---
+ letsencrypt.sh | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 64 insertions(+)
+ create mode 100755 letsencrypt.sh
+
+diff --git a/letsencrypt.sh b/letsencrypt.sh
+new file mode 100755
+index 0000000..3e66307
+--- /dev/null
++++ b/letsencrypt.sh
+@@ -0,0 +1,64 @@
++#!/usr/bin/env bash
++
++cat >&2 << EOF
++!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
++!! letsencrypt.sh has been renamed to dehydrated !!
++!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
++
++Due to trademark violation letsencrypt.sh had to be renamed and is know called dehydrated.
++
++To make a clean cut dehydrated doesn't use the old config locations /etc/letsencrypt.sh and
++/usr/local/etc/letsencrypt.sh anymore, also the script file has been renamed.
++
++If you were using the default WELLKNOWN location please also update your webserver to use /var/www/dehydrated.
++
++You are currently running (or reading) a temporary wrapper which handles the old config locations,
++you should update your setup to use /etc/dehydrated and the 'dehydrated' script file as soon as possible.
++
++Script execution will continue in 10 seconds.
++EOF
++
++sleep 10
++
++# parse given arguments for config
++tmpargs=("${@}")
++CONFIG=
++CONFIGARG=
++while (( ${#} )); do
++  case "${1}" in
++    --config|-f)
++      shift 1
++      CONFIGARG="${1}"
++      ;;
++    *)
++      shift 1
++      ;;
++  esac
++done
++set -- "${tmpargs[@]}"
++
++# look for default config locations
++if [[ -z "${CONFIGARG:-}" ]]; then
++  for check_config in "/etc/letsencrypt.sh" "/usr/local/etc/letsencrypt.sh" "${PWD}" "${SCRIPTDIR}"; do
++    if [[ -f "${check_config}/config" ]]; then
++      CONFIG="${check_config}/config"
++      break
++    fi
++  done
++fi
++
++# find dehydrated script directory
++SOURCE="${BASH_SOURCE[0]}"
++while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
++  DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
++  SOURCE="$(readlink "$SOURCE")"
++  [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
++done
++DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
++
++# add water
++if [[ -n "${CONFIG:-}" ]]; then
++	"${DIR}/dehydrated" --config "${CONFIG}" "${@}"
++else
++	"${DIR}/dehydrated" "${@}"
++fi
diff -Nru dehydrated-0.6.2/debian/patches/honor-config-if-the-user-provided-one-to-letsencrypt.sh-w.patch dehydrated-0.6.2/debian/patches/honor-config-if-the-user-provided-one-to-letsencrypt.sh-w.patch
--- dehydrated-0.6.2/debian/patches/honor-config-if-the-user-provided-one-to-letsencrypt.sh-w.patch	1970-01-01 01:00:00.000000000 +0100
+++ dehydrated-0.6.2/debian/patches/honor-config-if-the-user-provided-one-to-letsencrypt.sh-w.patch	2020-01-18 15:13:17.000000000 +0100
@@ -0,0 +1,37 @@
+From: Mattia Rizzolo <mattia@debian.org>
+Date: Mon, 2 Jan 2017 17:31:04 +0100
+Subject: honor --config if the user provided one to letsencrypt.sh wrapper
+
+---
+ letsencrypt.sh | 7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+diff --git a/letsencrypt.sh b/letsencrypt.sh
+index 98dabf0..0ceeda9 100755
+--- a/letsencrypt.sh
++++ b/letsencrypt.sh
+@@ -23,12 +23,11 @@ sleep 10
+ # parse given arguments for config
+ tmpargs=("${@}")
+ CONFIG=
+-CONFIGARG=
+ while (( ${#} )); do
+   case "${1}" in
+     --config|-f)
+       shift 1
+-      CONFIGARG="${1}"
++      CONFIG="${1}"
+       ;;
+     *)
+       shift 1
+@@ -37,8 +36,8 @@ while (( ${#} )); do
+ done
+ set -- "${tmpargs[@]}"
+ 
+-# look for default config locations
+-if [[ -z "${CONFIGARG:-}" ]]; then
++# if the user didn't already provide one, look for default config locations
++if [[ -z "${CONFIG:-}" ]]; then
+   for check_config in "/etc/letsencrypt.sh" "/usr/local/etc/letsencrypt.sh" "${PWD}" "${SCRIPTDIR}"; do
+     if [[ -f "${check_config}/config" ]]; then
+       CONFIG="${check_config}/config"
diff -Nru dehydrated-0.6.2/debian/patches/series dehydrated-0.6.2/debian/patches/series
--- dehydrated-0.6.2/debian/patches/series	2019-07-19 14:59:11.000000000 +0200
+++ dehydrated-0.6.2/debian/patches/series	2020-01-18 15:13:17.000000000 +0100
@@ -1,3 +1,10 @@
+# letsencyrpt.sh compat
+added-temporary-wrapper-script-for-compatibility-with-old.patch
+Update-the-location-of-WELLKNOWN-in-the-notice-message-of.patch
+honor-config-if-the-user-provided-one-to-letsencrypt.sh-w.patch
+Support-both-config.sh-and-config-as-config-filenames-for.patch
+
+# upstream fixes
 Fixes-559-when-HTTP-2-is-used-header-names-are-lower-case.patch
 Only-match-Replace-Nonce-header-at-beginning-of-line.patch
 fixed-a-bug-that-resulted-in-a-deleted-domains.txt-when-u.patch
diff -Nru dehydrated-0.6.2/debian/patches/Support-both-config.sh-and-config-as-config-filenames-for.patch dehydrated-0.6.2/debian/patches/Support-both-config.sh-and-config-as-config-filenames-for.patch
--- dehydrated-0.6.2/debian/patches/Support-both-config.sh-and-config-as-config-filenames-for.patch	1970-01-01 01:00:00.000000000 +0100
+++ dehydrated-0.6.2/debian/patches/Support-both-config.sh-and-config-as-config-filenames-for.patch	2020-01-18 15:13:17.000000000 +0100
@@ -0,0 +1,30 @@
+From: Mattia Rizzolo <mattia@debian.org>
+Date: Thu, 12 Jan 2017 18:19:12 +0100
+Subject: Support both 'config.sh' and 'config' as config filenames for
+ letsencrypt.sh
+
+---
+ letsencrypt.sh | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/letsencrypt.sh b/letsencrypt.sh
+index 0ceeda9..44bc9d8 100755
+--- a/letsencrypt.sh
++++ b/letsencrypt.sh
+@@ -39,10 +39,12 @@ set -- "${tmpargs[@]}"
+ # if the user didn't already provide one, look for default config locations
+ if [[ -z "${CONFIG:-}" ]]; then
+   for check_config in "/etc/letsencrypt.sh" "/usr/local/etc/letsencrypt.sh" "${PWD}" "${SCRIPTDIR}"; do
+-    if [[ -f "${check_config}/config" ]]; then
+-      CONFIG="${check_config}/config"
+-      break
+-    fi
++    for name in "config" "config.sh"; do
++      if [[ -f "${check_config}/${name}" ]]; then
++        CONFIG="${check_config}/${name}"
++        break
++      fi
++    done
+   done
+ fi
+ 
diff -Nru dehydrated-0.6.2/debian/patches/Update-the-location-of-WELLKNOWN-in-the-notice-message-of.patch dehydrated-0.6.2/debian/patches/Update-the-location-of-WELLKNOWN-in-the-notice-message-of.patch
--- dehydrated-0.6.2/debian/patches/Update-the-location-of-WELLKNOWN-in-the-notice-message-of.patch	1970-01-01 01:00:00.000000000 +0100
+++ dehydrated-0.6.2/debian/patches/Update-the-location-of-WELLKNOWN-in-the-notice-message-of.patch	2020-01-18 15:13:17.000000000 +0100
@@ -0,0 +1,31 @@
+From: Mattia Rizzolo <mattia@debian.org>
+Date: Mon, 2 Jan 2017 17:14:03 +0100
+Subject: Update the location of WELLKNOWN in the notice message of
+ letsencrypt.sh
+
++ fix typo s/know/now/
+
+Forwarded: not-needed
+---
+ letsencrypt.sh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/letsencrypt.sh b/letsencrypt.sh
+index 3e66307..98dabf0 100755
+--- a/letsencrypt.sh
++++ b/letsencrypt.sh
+@@ -5,12 +5,12 @@ cat >&2 << EOF
+ !! letsencrypt.sh has been renamed to dehydrated !!
+ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ 
+-Due to trademark violation letsencrypt.sh had to be renamed and is know called dehydrated.
++Due to trademark violation letsencrypt.sh had to be renamed and is now called dehydrated.
+ 
+ To make a clean cut dehydrated doesn't use the old config locations /etc/letsencrypt.sh and
+ /usr/local/etc/letsencrypt.sh anymore, also the script file has been renamed.
+ 
+-If you were using the default WELLKNOWN location please also update your webserver to use /var/www/dehydrated.
++If you were using the default WELLKNOWN location please also update your webserver to use /var/lib/dehydrated/acme-challenges.
+ 
+ You are currently running (or reading) a temporary wrapper which handles the old config locations,
+ you should update your setup to use /etc/dehydrated and the 'dehydrated' script file as soon as possible.
diff -Nru dehydrated-0.6.2/debian/rules dehydrated-0.6.2/debian/rules
--- dehydrated-0.6.2/debian/rules	2019-07-07 12:35:46.000000000 +0200
+++ dehydrated-0.6.2/debian/rules	2020-01-18 15:13:17.000000000 +0100
@@ -10,4 +10,4 @@
 	rm -rv $(CURDIR)/debian/dehydrated/usr/share/doc/dehydrated/docs/examples
 
 override_dh_compress:
-	dh_compress -Xconfig -Xhook.sh
+	dh_compress -Xconfig -Xhook.sh -XREADME.md

Attachment: signature.asc
Description: PGP signature


Reply to: