From 0fb206fe15107ca80a9199a0efec4e4a006ebb44 Mon Sep 17 00:00:00 2001 From: Philippe Kueck Date: Wed, 26 Oct 2016 11:52:26 +0200 Subject: [PATCH 001/189] add nsupdate script for dns-01 --- dnsapi/dns_nsupdate.sh | 94 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100755 dnsapi/dns_nsupdate.sh diff --git a/dnsapi/dns_nsupdate.sh b/dnsapi/dns_nsupdate.sh new file mode 100755 index 00000000..fd16c563 --- /dev/null +++ b/dnsapi/dns_nsupdate.sh @@ -0,0 +1,94 @@ +#!/usr/bin/env bash + + +######## Public functions ##################### + +#Usage: dns_nsupdate_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_nsupdate_add() { + fulldomain=$1 + txtvalue=$2 + _checkKeyFile || return 1 + NSUPDATE_SERVER=${NSUPDATE_SERVER:-localhost} + # save the dns server and key to the account conf file. + _saveaccountconf NSUPDATE_SERVER "${NSUPDATE_SERVER}" + _saveaccountconf NSUPDATE_KEY "${NSUPDATE_KEY}" + tmp=$(mktemp --tmpdir acme_nsupdate.XXXXXX) + cat > ${tmp} < ${tmp} <&2 + return 1 +} + +_debug() { + if [ -z "$DEBUG" ] ; then + return + fi + _err "$@" + return 0 +} + +_debug2() { + if [ "$DEBUG" ] && [ "$DEBUG" -ge "2" ] ; then + _debug "$@" + fi + return +} From 2d279c4c5cb49405d01a996a0ea11c0e8711662f Mon Sep 17 00:00:00 2001 From: Philippe Kueck Date: Wed, 26 Oct 2016 11:57:45 +0200 Subject: [PATCH 002/189] add nsupdate to sample config --- acme.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/acme.sh b/acme.sh index ce125793..cbd7f0dd 100755 --- a/acme.sh +++ b/acme.sh @@ -3363,6 +3363,11 @@ _initconf() { # #GD_Secret=\"sADDsdasdfsdfdssdgdsf\" +####################### +#nsupdate: +#NSUPDATE_KEY=\"/path/to/update.key\" +#NSUPDATE_SERVER=\"192.168.0.1\" + ####################### #PowerDNS: #PDNS_Url=\"http://ns.example.com:8081\" From 54d61bdc4ac46437c16f81fe0593c92610fce0e3 Mon Sep 17 00:00:00 2001 From: Philippe Kueck Date: Wed, 26 Oct 2016 16:14:47 +0200 Subject: [PATCH 003/189] - get rid of bash-only syntax like ${foo:-bar} - use sh instead of bash - remove redundant functions _info, _err, _debug and _debug2 - get rid of mktemp, pipe commands directly to nsupdate --- dnsapi/dns_nsupdate.sh | 46 +++++++----------------------------------- 1 file changed, 7 insertions(+), 39 deletions(-) diff --git a/dnsapi/dns_nsupdate.sh b/dnsapi/dns_nsupdate.sh index fd16c563..56023322 100755 --- a/dnsapi/dns_nsupdate.sh +++ b/dnsapi/dns_nsupdate.sh @@ -1,4 +1,4 @@ -#!/usr/bin/env bash +#!/usr/bin/env sh ######## Public functions ##################### @@ -8,18 +8,16 @@ dns_nsupdate_add() { fulldomain=$1 txtvalue=$2 _checkKeyFile || return 1 - NSUPDATE_SERVER=${NSUPDATE_SERVER:-localhost} + [ -n "${NSUPDATE_SERVER}" ] || NSUPDATE_SERVER="localhost" # save the dns server and key to the account conf file. _saveaccountconf NSUPDATE_SERVER "${NSUPDATE_SERVER}" _saveaccountconf NSUPDATE_KEY "${NSUPDATE_KEY}" - tmp=$(mktemp --tmpdir acme_nsupdate.XXXXXX) - cat > ${tmp} < ${tmp} <&2 - return 1 -} - -_debug() { - if [ -z "$DEBUG" ] ; then - return - fi - _err "$@" - return 0 -} - -_debug2() { - if [ "$DEBUG" ] && [ "$DEBUG" -ge "2" ] ; then - _debug "$@" - fi - return -} From 243593cdaa716393283bb8f879517f2146d8b57b Mon Sep 17 00:00:00 2001 From: Philippe Kueck Date: Mon, 14 Nov 2016 14:06:30 +0100 Subject: [PATCH 004/189] fix warnings and remove unused ${tmp} variable --- dnsapi/dns_nsupdate.sh | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/dnsapi/dns_nsupdate.sh b/dnsapi/dns_nsupdate.sh index 56023322..a024e314 100755 --- a/dnsapi/dns_nsupdate.sh +++ b/dnsapi/dns_nsupdate.sh @@ -13,16 +13,15 @@ dns_nsupdate_add() { _saveaccountconf NSUPDATE_SERVER "${NSUPDATE_SERVER}" _saveaccountconf NSUPDATE_KEY "${NSUPDATE_KEY}" _info "adding ${fulldomain}. 60 in txt \"${txtvalue}\"" - nsupdate -k ${NSUPDATE_KEY} < Date: Mon, 14 Nov 2016 22:11:05 +0800 Subject: [PATCH 005/189] run acmetest in CI --- .travis.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.travis.yml b/.travis.yml index 62feca32..46f0dff4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,6 +17,10 @@ script: - shellcheck -V - shellcheck -e SC2021,SC2126,SC2034 **/*.sh && echo "shellcheck OK" - ~/shfmt -l -w -i 2 . && echo "shfmt OK" || git diff --exit-code || (echo "Run shfmt to fix the formatting issues" && false) + - cd .. + - curl -sSL https://bin.equinox.io/c/4VmDzA7iaHb/ngrok-stable-linux-amd64.zip -o ngrok-stable-linux-amd64.zip && unzip ngrok-stable-linux-amd64.zip && export NGROK_BIN="$(pwd)/ngrok" + - git clone https://github.com/Neilpang/acmetest.git && cp -r acme.sh acmetest/ && cd acmetest && ./letest.sh + matrix: fast_finish: true From 13ffa1704822911db362d1e85b163e54ff73a92b Mon Sep 17 00:00:00 2001 From: Philippe Kueck Date: Mon, 14 Nov 2016 15:56:07 +0100 Subject: [PATCH 006/189] add documentation for dns_nsupdate --- README.md | 1 + dnsapi/README.md | 50 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/README.md b/README.md index e86392ec..58cadc61 100644 --- a/README.md +++ b/README.md @@ -244,6 +244,7 @@ You don't have do anything manually! 7. PowerDNS API 8. lexicon dns api: https://github.com/Neilpang/acme.sh/wiki/How-to-use-lexicon-dns-api (DigitalOcean, DNSimple, DnsMadeEasy, DNSPark, EasyDNS, Namesilo, NS1, PointHQ, Rage4 and Vultr etc.) +9. nsupdate ##### More APIs are coming soon... diff --git a/dnsapi/README.md b/dnsapi/README.md index 94603154..a56f68b7 100644 --- a/dnsapi/README.md +++ b/dnsapi/README.md @@ -112,10 +112,60 @@ acme.sh --issue --dns dns_pdns -d example.com -d www.example.com The `PDNS_Url`, `PDNS_ServerId`, `PDNS_Token` and `PDNS_Ttl` will be saved in `~/.acme.sh/account.conf`. + ## Use OVH/kimsufi/soyoustart/runabove API https://github.com/Neilpang/acme.sh/wiki/How-to-use-OVH-domain-api +## Use nsupdate to automatically issue cert + +First, generate a key for updating the zone +``` +b=$(dnssec-keygen -a hmac-sha512 -b 512 -n USER -K /tmp foo) +cat > /etc/named/keys/update.key < Date: Tue, 15 Nov 2016 17:28:15 +0800 Subject: [PATCH 007/189] Update README.md --- dnsapi/README.md | 60 +++++++++++++++++++++++++----------------------- 1 file changed, 31 insertions(+), 29 deletions(-) diff --git a/dnsapi/README.md b/dnsapi/README.md index 8f7df7b3..34be5070 100644 --- a/dnsapi/README.md +++ b/dnsapi/README.md @@ -1,6 +1,6 @@ # How to use dns api -## Use CloudFlare domain api to automatically issue cert +## 1. Use CloudFlare domain api to automatically issue cert For now, we support clourflare integeration. @@ -22,7 +22,7 @@ The `CF_Key` and `CF_Email` will be saved in `~/.acme.sh/account.conf`, when ne -## Use Dnspod.cn domain api to automatically issue cert +## 2. Use Dnspod.cn domain api to automatically issue cert For now, we support dnspod.cn integeration. @@ -43,7 +43,7 @@ acme.sh --issue --dns dns_dp -d example.com -d www.example.com The `DP_Id` and `DP_Key` will be saved in `~/.acme.sh/account.conf`, when next time you use dnspod.cn api, it will reuse this key. -## Use Cloudxns.com domain api to automatically issue cert +## 3. Use Cloudxns.com domain api to automatically issue cert For now, we support Cloudxns.com integeration. @@ -64,7 +64,7 @@ acme.sh --issue --dns dns_cx -d example.com -d www.example.com The `CX_Key` and `CX_Secret` will be saved in `~/.acme.sh/account.conf`, when next time you use Cloudxns.com api, it will reuse this key. -## Use Godaddy.com domain api to automatically issue cert +## 4. Use Godaddy.com domain api to automatically issue cert We support Godaddy integration. @@ -89,7 +89,7 @@ acme.sh --issue --dns dns_gd -d example.com -d www.example.com The `GD_Key` and `GD_Secret` will be saved in `~/.acme.sh/account.conf`, when next time you use cloudflare api, it will reuse this key. -## Use PowerDNS embedded api to automatically issue cert +## 5. Use PowerDNS embedded api to automatically issue cert We support PowerDNS embedded API integration. @@ -113,11 +113,11 @@ acme.sh --issue --dns dns_pdns -d example.com -d www.example.com The `PDNS_Url`, `PDNS_ServerId`, `PDNS_Token` and `PDNS_Ttl` will be saved in `~/.acme.sh/account.conf`. -## Use OVH/kimsufi/soyoustart/runabove API +## 6. Use OVH/kimsufi/soyoustart/runabove API https://github.com/Neilpang/acme.sh/wiki/How-to-use-OVH-domain-api -## Use nsupdate to automatically issue cert +## 7. Use nsupdate to automatically issue cert First, generate a key for updating the zone ``` @@ -166,27 +166,7 @@ acme.sh --issue --dns dns_nsupdate -d example.com -d www.example.com The `NSUPDATE_SERVER` and `NSUPDATE_KEY` settings will be saved in `~/.acme.sh/account.conf`. -# Use custom api - -If your api is not supported yet, you can write your own dns api. - -Let's assume you want to name it 'myapi', - -1. Create a bash script named `~/.acme.sh/dns_myapi.sh`, -2. In the script, you must have a function named `dns_myapi_add()`. Which will be called by acme.sh to add dns records. -3. Then you can use your api to issue cert like: - -``` -acme.sh --issue --dns dns_myapi -d example.com -d www.example.com -``` - -For more details, please check our sample script: [dns_myapi.sh](dns_myapi.sh) - -# Use lexicon dns api - -https://github.com/Neilpang/acme.sh/wiki/How-to-use-lexicon-dns-api - -## Use LuaDNS domain API +## 8. Use LuaDNS domain API Get your API token at https://api.luadns.com/settings @@ -204,7 +184,7 @@ acme.sh --issue --dns dns_lua --dnssleep 3 -d example.com -d www.example.c The `LUA_Key` and `LUA_Email` will be saved in `~/.acme.sh/account.conf`, and will be reused when needed. -## Use DNSMadeEasy domain API +## 9. Use DNSMadeEasy domain API Get your API credentials at https://cp.dnsmadeeasy.com/account/info @@ -222,5 +202,27 @@ acme.sh --issue --dns dns_me --dnssleep 3 -d example.com -d www.example.co The `ME_Key` and `ME_Secret` will be saved in `~/.acme.sh/account.conf`, and will be reused when needed. +# 10. Use custom api + +If your api is not supported yet, you can write your own dns api. + +Let's assume you want to name it 'myapi', + +1. Create a bash script named `~/.acme.sh/dns_myapi.sh`, +2. In the script, you must have a function named `dns_myapi_add()`. Which will be called by acme.sh to add dns records. +3. Then you can use your api to issue cert like: + +``` +acme.sh --issue --dns dns_myapi -d example.com -d www.example.com +``` + +For more details, please check our sample script: [dns_myapi.sh](dns_myapi.sh) + +# 11. Use lexicon dns api + +https://github.com/Neilpang/acme.sh/wiki/How-to-use-lexicon-dns-api + + + From b87503715004c8924d196ee017d33eeaf4f3a5eb Mon Sep 17 00:00:00 2001 From: neilpang Date: Tue, 15 Nov 2016 17:38:35 +0800 Subject: [PATCH 008/189] check NGROK_BIN --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 46f0dff4..991e4ed4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,6 +19,7 @@ script: - ~/shfmt -l -w -i 2 . && echo "shfmt OK" || git diff --exit-code || (echo "Run shfmt to fix the formatting issues" && false) - cd .. - curl -sSL https://bin.equinox.io/c/4VmDzA7iaHb/ngrok-stable-linux-amd64.zip -o ngrok-stable-linux-amd64.zip && unzip ngrok-stable-linux-amd64.zip && export NGROK_BIN="$(pwd)/ngrok" + - $NGROK_BIN - git clone https://github.com/Neilpang/acmetest.git && cp -r acme.sh acmetest/ && cd acmetest && ./letest.sh From 15777732d3d4e595d6bb6e712c3381b1d84f1e7d Mon Sep 17 00:00:00 2001 From: neilpang Date: Tue, 15 Nov 2016 19:20:41 +0800 Subject: [PATCH 009/189] test ngrok --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 991e4ed4..9ec5405d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -20,6 +20,7 @@ script: - cd .. - curl -sSL https://bin.equinox.io/c/4VmDzA7iaHb/ngrok-stable-linux-amd64.zip -o ngrok-stable-linux-amd64.zip && unzip ngrok-stable-linux-amd64.zip && export NGROK_BIN="$(pwd)/ngrok" - $NGROK_BIN + - $NGROK_BIN http 80 --log stdout --log-format logfmt --log-level debug - git clone https://github.com/Neilpang/acmetest.git && cp -r acme.sh acmetest/ && cd acmetest && ./letest.sh From a2801649b40a0f9e3716b525985f0e6e7bdfc85d Mon Sep 17 00:00:00 2001 From: neilpang Date: Tue, 15 Nov 2016 19:24:08 +0800 Subject: [PATCH 010/189] test ngrok --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 9ec5405d..62c86a29 100644 --- a/.travis.yml +++ b/.travis.yml @@ -20,6 +20,7 @@ script: - cd .. - curl -sSL https://bin.equinox.io/c/4VmDzA7iaHb/ngrok-stable-linux-amd64.zip -o ngrok-stable-linux-amd64.zip && unzip ngrok-stable-linux-amd64.zip && export NGROK_BIN="$(pwd)/ngrok" - $NGROK_BIN + - $NGROK_BIN authtoken "$NGROK_TOKEN" - $NGROK_BIN http 80 --log stdout --log-format logfmt --log-level debug - git clone https://github.com/Neilpang/acmetest.git && cp -r acme.sh acmetest/ && cd acmetest && ./letest.sh From 1c02b85802f53f39bbf06f2cacc02f0e9ae9c020 Mon Sep 17 00:00:00 2001 From: neilpang Date: Tue, 15 Nov 2016 19:29:02 +0800 Subject: [PATCH 011/189] test ngrok --- .travis.yml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 62c86a29..3d368d7e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -21,8 +21,13 @@ script: - curl -sSL https://bin.equinox.io/c/4VmDzA7iaHb/ngrok-stable-linux-amd64.zip -o ngrok-stable-linux-amd64.zip && unzip ngrok-stable-linux-amd64.zip && export NGROK_BIN="$(pwd)/ngrok" - $NGROK_BIN - $NGROK_BIN authtoken "$NGROK_TOKEN" - - $NGROK_BIN http 80 --log stdout --log-format logfmt --log-level debug - - git clone https://github.com/Neilpang/acmetest.git && cp -r acme.sh acmetest/ && cd acmetest && ./letest.sh + - git clone https://github.com/Neilpang/acmetest.git && cp -r acme.sh acmetest/ && cd acmetest + - $NGROK_BIN http 80 --log stdout --log-format logfmt --log-level debug > ngrok.tmp & + - echo "===========================" + - cat ngrok.tmp + - echo ============================== + - grep -o 'Hostname:[a-z0-9]+.ngrok.io' ngrok.tmp + - ./letest.sh matrix: From 7f944c2c8b532eaec65e3452150a4be6f2a69173 Mon Sep 17 00:00:00 2001 From: neilpang Date: Tue, 15 Nov 2016 19:38:28 +0800 Subject: [PATCH 012/189] test ngrok --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 3d368d7e..0cc14b6a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -23,6 +23,7 @@ script: - $NGROK_BIN authtoken "$NGROK_TOKEN" - git clone https://github.com/Neilpang/acmetest.git && cp -r acme.sh acmetest/ && cd acmetest - $NGROK_BIN http 80 --log stdout --log-format logfmt --log-level debug > ngrok.tmp & + - sleep 5 - echo "===========================" - cat ngrok.tmp - echo ============================== From 09f1c58872f2b8fd297e1c3e6cd3d4807482e95f Mon Sep 17 00:00:00 2001 From: neilpang Date: Tue, 15 Nov 2016 19:45:04 +0800 Subject: [PATCH 013/189] test ngrok --- .travis.yml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/.travis.yml b/.travis.yml index 0cc14b6a..fe615d82 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,15 +19,7 @@ script: - ~/shfmt -l -w -i 2 . && echo "shfmt OK" || git diff --exit-code || (echo "Run shfmt to fix the formatting issues" && false) - cd .. - curl -sSL https://bin.equinox.io/c/4VmDzA7iaHb/ngrok-stable-linux-amd64.zip -o ngrok-stable-linux-amd64.zip && unzip ngrok-stable-linux-amd64.zip && export NGROK_BIN="$(pwd)/ngrok" - - $NGROK_BIN - - $NGROK_BIN authtoken "$NGROK_TOKEN" - git clone https://github.com/Neilpang/acmetest.git && cp -r acme.sh acmetest/ && cd acmetest - - $NGROK_BIN http 80 --log stdout --log-format logfmt --log-level debug > ngrok.tmp & - - sleep 5 - - echo "===========================" - - cat ngrok.tmp - - echo ============================== - - grep -o 'Hostname:[a-z0-9]+.ngrok.io' ngrok.tmp - ./letest.sh From 1bb902984bb600b32004f98521631071f6fb440d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Armando=20L=C3=BCscher?= Date: Tue, 15 Nov 2016 14:13:58 +0100 Subject: [PATCH 014/189] Clean up readme. --- README.md | 210 +++++++++++++++++++++++++++++------------------------- 1 file changed, 112 insertions(+), 98 deletions(-) diff --git a/README.md b/README.md index bb5c7c55..e09ef89b 100644 --- a/README.md +++ b/README.md @@ -1,21 +1,23 @@ # An ACME Shell script: acme.sh [![Build Status](https://travis-ci.org/Neilpang/acme.sh.svg?branch=master)](https://travis-ci.org/Neilpang/acme.sh) - An ACME protocol client written purely in Shell (Unix shell) language. -- Fully ACME protocol implementation. -- Simple, powerful and very easy to use. You only need 3 minutes to learn. -- Bash, dash and sh compatible. +- Full ACME protocol implementation. +- Simple, powerful and very easy to use. You only need 3 minutes to learn it. +- Bash, dash and sh compatible. - Simplest shell script for Let's Encrypt free certificate client. -- Purely written in Shell with no dependencies on python or Let's Encrypt official client. -- Just one script, to issue, renew and install your certificates automatically. +- Purely written in Shell with no dependencies on python or the official Let's Encrypt client. +- Just one script to issue, renew and install your certificates automatically. - DOES NOT require `root/sudoer` access. It's probably the `easiest&smallest&smartest` shell script to automatically issue & renew the free certificates from Let's Encrypt. - Wiki: https://github.com/Neilpang/acme.sh/wiki + # [中文说明](https://github.com/Neilpang/acme.sh/wiki/%E8%AF%B4%E6%98%8E) -#Tested OS + +# Tested OS + | NO | Status| Platform| |----|-------|---------| |1|[![](https://cdn.rawgit.com/Neilpang/acmetest/master/status/ubuntu-latest.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)| Ubuntu @@ -38,41 +40,39 @@ Wiki: https://github.com/Neilpang/acme.sh/wiki |18|[![](https://cdn.rawgit.com/Neilpang/acmetest/master/status/solaris.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|SunOS/Solaris |19|[![](https://cdn.rawgit.com/Neilpang/acmetest/master/status/gentoo-stage3-amd64.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|Gentoo Linux -For all build statuses, check our [daily build project](https://github.com/Neilpang/acmetest): +For all build statuses, check our [daily build project](https://github.com/Neilpang/acmetest): https://github.com/Neilpang/acmetest -# Supported Mode -1. Webroot mode -2. Standalone mode -3. Apache mode -4. Dns mode +# Supported modes +- Webroot mode +- Standalone mode +- Apache mode +- DNS mode # 1. How to install -### 1. Install online: +### 1. Install online Check this project: https://github.com/Neilpang/get.acme.sh ```bash curl https://get.acme.sh | sh - ``` Or: ```bash wget -O - https://get.acme.sh | sh - ``` -### 2. Or, Install from git: +### 2. Or, Install from git -Clone this project: +Clone this project and launch installation: ```bash git clone https://github.com/Neilpang/acme.sh.git @@ -82,14 +82,14 @@ cd ./acme.sh You `don't have to be root` then, although `it is recommended`. -Advanced Installation: https://github.com/Neilpang/acme.sh/wiki/How-to-install +Advanced Installation: https://github.com/Neilpang/acme.sh/wiki/How-to-install The installer will perform 3 actions: -1. Create and copy `acme.sh` to your home dir (`$HOME`): `~/.acme.sh/`. -All certs will be placed in this folder. -2. Create alias for: `acme.sh=~/.acme.sh/acme.sh`. -3. Create everyday cron job to check and renew the cert if needed. +1. Create and copy `acme.sh` to your home dir (`$HOME`): `~/.acme.sh/`. +All certs will be placed in this folder too. +2. Create alias for: `acme.sh=~/.acme.sh/acme.sh`. +3. Create daily cron job to check and renew the certs if needed. Cron entry example: @@ -97,18 +97,17 @@ Cron entry example: 0 0 * * * "/home/user/.acme.sh"/acme.sh --cron --home "/home/user/.acme.sh" > /dev/null ``` -After the installation, you must close current terminal and reopen again to make the alias take effect. +After the installation, you must close the current terminal and reopen it to make the alias take effect. + +Ok, you are ready to issue certs now. -Ok, you are ready to issue cert now. Show help message: ``` - root@v1:~# acme.sh -h - ``` - -# 2. Just issue a cert: + +# 2. Just issue a cert **Example 1:** Single domain. @@ -119,56 +118,57 @@ acme.sh --issue -d example.com -w /home/wwwroot/example.com **Example 2:** Multiple domains in the same cert. ```bash -acme.sh --issue -d example.com -d www.example.com -d cp.example.com -w /home/wwwroot/example.com +acme.sh --issue -d example.com -d www.example.com -d cp.example.com -w /home/wwwroot/example.com ``` The parameter `/home/wwwroot/example.com` is the web root folder. You **MUST** have `write access` to this folder. -Second argument **"example.com"** is the main domain you want to issue cert for. -You must have at least a domain there. +Second argument **"example.com"** is the main domain you want to issue the cert for. +You must have at least one domain there. You must point and bind all the domains to the same webroot dir: `/home/wwwroot/example.com`. -Generate/issued certs will be placed in `~/.acme.sh/example.com/` +Generated/issued certs will be placed in `~/.acme.sh/example.com/` -The issued cert will be renewed every **60** days automatically. +The issued cert will be renewed automatically every **60** days. More examples: https://github.com/Neilpang/acme.sh/wiki/How-to-issue-a-cert -# 3. Install the issued cert to apache/nginx etc. +# 3. Install the issued cert to Apache/Nginx etc. -After you issue a cert, you probably want to install/copy the cert to your nginx/apache or other servers. -You **MUST** use this command to copy the certs to the target files, **Do NOT** use the certs files in **.acme.sh/** folder, they are for internal use only, the folder structure may change in future. +After you issue a cert, you probably want to install/copy the cert to your Apache/Nginx or other servers. +You **MUST** use this command to copy the certs to the target files, **DO NOT** use the certs files in **~/.acme.sh/** folder, they are for internal use only, the folder structure may change in the future. -**nginx** example +**Apache** example: ```bash acme.sh --installcert -d example.com \ ---keypath /path/to/keyfile/in/nginx/key.pem \ ---fullchainpath path/to/fullchain/nginx/cert.pem \ ---reloadcmd "service nginx restart" +--certpath /path/to/certfile/in/apache/cert.pem \ +--keypath /path/to/keyfile/in/apache/key.pem \ +--fullchainpath /path/to/fullchain/certfile/apache/fullchain.pem \ +--reloadcmd "service apache2 restart" ``` -**apache** example +**Nginx** example: ```bash acme.sh --installcert -d example.com \ ---certpath /path/to/certfile/in/apache/cert.pem \ ---keypath /path/to/keyfile/in/apache/key.pem \ ---fullchainpath path/to/fullchain/certfile/apache/fullchain.pem \ ---reloadcmd "service apache2 restart" +--keypath /path/to/keyfile/in/nginx/key.pem \ +--fullchainpath /path/to/fullchain/nginx/cert.pem \ +--reloadcmd "service nginx restart" ``` Only the domain is required, all the other parameters are optional. -Install/copy the issued cert/key to the production apache or nginx path. +Install/copy the issued cert/key to the production Apache or Nginx path. + +The cert will be `renewed every **60** days by default` (which is configurable). Once the cert is renewed, the Apache/Nginx service will be restarted automatically by the command: `service apache2 restart` or `service nginx restart`. -The cert will be `renewed every **60** days by default` (which is configurable). Once the cert is renewed, the apache/nginx will be automatically reloaded by the command: `service apache2 reload` or `service nginx reload`. # 4. Use Standalone server to issue cert -**(requires you be root/sudoer, or you have permission to listen tcp 80 port)** +**(requires you to be root/sudoer or have permission to listen on port 80 (TCP))** -The tcp `80` port **MUST** be free to listen, otherwise you will be prompted to free the `80` port and try again. +Port `80` (TCP) **MUST** be free to listen on, otherwise you will be prompted to free it and try again. ```bash acme.sh --issue --standalone -d example.com -d www.example.com -d cp.example.com @@ -176,13 +176,14 @@ acme.sh --issue --standalone -d example.com -d www.example.com -d cp.example.com More examples: https://github.com/Neilpang/acme.sh/wiki/How-to-issue-a-cert -# 5. Use Standalone tls server to issue cert -**(requires you be root/sudoer, or you have permission to listen tcp 443 port)** +# 5. Use Standalone TLS server to issue cert + +**(requires you to be root/sudoer or have permission to listen on port 443 (TCP))** acme.sh supports `tls-sni-01` validation. -The tcp `443` port **MUST** be free to listen, otherwise you will be prompted to free the `443` port and try again. +Port `443` (TCP) **MUST** be free to listen on, otherwise you will be prompted to free it and try again. ```bash acme.sh --issue --tls -d example.com -d www.example.com -d cp.example.com @@ -190,31 +191,33 @@ acme.sh --issue --tls -d example.com -d www.example.com -d cp.example.com More examples: https://github.com/Neilpang/acme.sh/wiki/How-to-issue-a-cert + # 6. Use Apache mode -**(requires you be root/sudoer, since it is required to interact with apache server)** +**(requires you to be root/sudoer, since it is required to interact with Apache server)** -If you are running a web server, apache or nginx, it is recommended to use the `Webroot mode`. +If you are running a web server, Apache or Nginx, it is recommended to use the `Webroot mode`. -Particularly, if you are running an apache server, you should use apache mode instead. This mode doesn't write any files to your web root folder. +Particularly, if you are running an Apache server, you should use Apache mode instead. This mode doesn't write any files to your web root folder. -Just set string "apache" as the second argument, it will force use of apache plugin automatically. +Just set string "apache" as the second argument and it will force use of apache plugin automatically. ``` -acme.sh --issue --apache -d example.com -d www.example.com -d user.example.com +acme.sh --issue --apache -d example.com -d www.example.com -d cp.example.com ``` More examples: https://github.com/Neilpang/acme.sh/wiki/How-to-issue-a-cert + # 7. Use DNS mode: Support the `dns-01` challenge. ```bash -acme.sh --issue --dns -d example.com -d www.example.com -d user.example.com +acme.sh --issue --dns -d example.com -d www.example.com -d cp.example.com ``` -You should get the output like below: +You should get an output like below: ``` Add the following txt record: @@ -226,7 +229,6 @@ Domain:_acme-challenge.www.example.com Txt value:9ihDbjxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx Please add those txt records to the domains. Waiting for the dns to take effect. - ``` Then just rerun with `renew` argument: @@ -237,53 +239,54 @@ acme.sh --renew -d example.com Ok, it's finished. + # 8. Automatic DNS API integration -If your DNS provider supports API access, we can use API to automatically issue the certs. +If your DNS provider supports API access, we can use that API to automatically issue the certs. -You don't have do anything manually! +You don't have to do anything manually! ### Currently acme.sh supports: -1. Cloudflare.com API -2. Dnspod.cn API -3. Cloudxns.com API -4. Godaddy.com API -5. OVH, kimsufi, soyoustart and runabove API -6. AWS Route 53, see: https://github.com/Neilpang/acme.sh/issues/65 -7. PowerDNS API -8. lexicon dns api: https://github.com/Neilpang/acme.sh/wiki/How-to-use-lexicon-dns-api - (DigitalOcean, DNSimple, DnsMadeEasy, DNSPark, EasyDNS, Namesilo, NS1, PointHQ, Rage4 and Vultr etc.) -9. LuaDNS.com API -10. DNSMadeEasy.com API -11. nsupdate +- CloudFlare.com API +- DNSPod.cn API +- CloudXNS.com API +- GoDaddy.com API +- OVH, kimsufi, soyoustart and runabove API +- AWS Route 53, see: https://github.com/Neilpang/acme.sh/issues/65 +- PowerDNS.com API +- lexicon DNS API: https://github.com/Neilpang/acme.sh/wiki/How-to-use-lexicon-dns-api + (DigitalOcean, DNSimple, DNSMadeEasy, DNSPark, EasyDNS, Namesilo, NS1, PointHQ, Rage4 and Vultr etc.) +- LuaDNS.com API +- DNSMadeEasy.com API -##### More APIs are coming soon... +**More APIs coming soon...** -If your DNS provider is not on the supported list above, you can write your own script API easily. If you do please consider submitting a [Pull Request](https://github.com/Neilpang/acme.sh/pulls) and contribute to the project. +If your DNS provider is not on the supported list above, you can write your own DNS API script easily. If you do, please consider submitting a [Pull Request](https://github.com/Neilpang/acme.sh/pulls) and contribute it to the project. -For more details: [How to use dns api](dnsapi) +For more details: [How to use DNS API](dnsapi) -# 9. Issue ECC certificate: -`Let's Encrypt` now can issue **ECDSA** certificates. +# 9. Issue ECC certificates -And we also support it. +`Let's Encrypt` can now issue **ECDSA** certificates. + +And we support them too! Just set the `length` parameter with a prefix `ec-`. For example: -### Single domain ECC cerfiticate: +### Single domain ECC cerfiticate ```bash -acme.sh --issue -w /home/wwwroot/example.com -d example.com --keylength ec-256 +acme.sh --issue -w /home/wwwroot/example.com -d example.com --keylength ec-256 ``` -SAN multi domain ECC certificate: +### SAN multi domain ECC certificate ```bash -acme.sh --issue -w /home/wwwroot/example.com -d example.com -d www.example.com --keylength ec-256 +acme.sh --issue -w /home/wwwroot/example.com -d example.com -d www.example.com --keylength ec-256 ``` Please look at the last parameter above. @@ -295,40 +298,48 @@ Valid values are: 3. **ec-521 (secp521r1, "ECDSA P-521", which is not supported by Let's Encrypt yet.)** -# 10. How to renew the cert +# 10. How to renew the issued certs -No, you don't need to renew the certs manually. All the certs will be renewed automatically every **60** days. +No, you don't need to renew the certs manually. All the certs will be renewed automatically every **60** days. However, you can also force to renew any cert: ``` -acme.sh --renew -d example.com --force +acme.sh --renew -d example.com --force ``` or, for ECC cert: + ``` -acme.sh --renew -d example.com --force --ecc +acme.sh --renew -d example.com --force --ecc ``` + # 11. How to upgrade `acme.sh` -acme.sh is in developing, it's strongly recommended to use the latest code. + +acme.sh is in constant developement, so it's strongly recommended to use the latest code. You can update acme.sh to the latest code: + ``` acme.sh --upgrade ``` -You can enable auto upgrade: +You can also enable auto upgrade: + ``` -acme.sh --upgrade --auto-upgrade +acme.sh --upgrade --auto-upgrade ``` -Then **acme.sh** will keep up to date automatically. + +Then **acme.sh** will be kept up to date automatically. Disable auto upgrade: + ``` -acme.sh --upgrade --auto-upgrade 0 +acme.sh --upgrade --auto-upgrade 0 ``` + # 12. Issue a cert from an existing CSR https://github.com/Neilpang/acme.sh/wiki/Issue-a-cert-from-existing-CSR @@ -340,22 +351,25 @@ Speak ACME language using shell, directly to "Let's Encrypt". TODO: -# Acknowledgment + +# Acknowledgments + 1. Acme-tiny: https://github.com/diafygi/acme-tiny 2. ACME protocol: https://github.com/ietf-wg-acme/acme 3. Certbot: https://github.com/certbot/certbot + # License & Others License is GPLv3 Please Star and Fork me. -[Issues](https://github.com/Neilpang/acme.sh/issues) and [pull requests](https://github.com/Neilpang/acme.sh/pulls) are welcomed. +[Issues](https://github.com/Neilpang/acme.sh/issues) and [pull requests](https://github.com/Neilpang/acme.sh/pulls) are welcome. # Donate -1. PayPal: donate@acme.sh + +1. PayPal: donate@acme.sh [Donate List](https://github.com/Neilpang/acme.sh/wiki/Donate-list) - From d20831e41a305fb34d52941ed67041d01969da7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Armando=20L=C3=BCscher?= Date: Tue, 15 Nov 2016 14:24:07 +0100 Subject: [PATCH 015/189] Update DNS API readme --- dnsapi/README.md | 129 ++++++++++++++++++++--------------------------- 1 file changed, 54 insertions(+), 75 deletions(-) diff --git a/dnsapi/README.md b/dnsapi/README.md index 34be5070..f1df726f 100644 --- a/dnsapi/README.md +++ b/dnsapi/README.md @@ -1,99 +1,80 @@ -# How to use dns api +# How to use DNS API -## 1. Use CloudFlare domain api to automatically issue cert +## 1. Use CloudFlare domain API to automatically issue cert -For now, we support clourflare integeration. - -First you need to login to your clourflare account to get your api key. +First you need to login to your CloudFlare account to get your API key. ``` export CF_Key="sdfsdfsdfljlbjkljlkjsdfoiwje" - export CF_Email="xxxx@sss.com" - ``` -Ok, let's issue cert now: +Ok, let's issue a cert now: ``` -acme.sh --issue --dns dns_cf -d example.com -d www.example.com +acme.sh --issue --dns dns_cf -d example.com -d www.example.com ``` -The `CF_Key` and `CF_Email` will be saved in `~/.acme.sh/account.conf`, when next time you use cloudflare api, it will reuse this key. +The `CF_Key` and `CF_Email` will be saved in `~/.acme.sh/account.conf` and will be reused when needed. +## 2. Use DNSPod.cn domain API to automatically issue cert -## 2. Use Dnspod.cn domain api to automatically issue cert - -For now, we support dnspod.cn integeration. - -First you need to login to your dnspod.cn account to get your api key and key id. +First you need to login to your DNSPod account to get your API Key and ID. ``` export DP_Id="1234" - export DP_Key="sADDsdasdgdsf" - ``` -Ok, let's issue cert now: +Ok, let's issue a cert now: ``` -acme.sh --issue --dns dns_dp -d example.com -d www.example.com +acme.sh --issue --dns dns_dp -d example.com -d www.example.com ``` -The `DP_Id` and `DP_Key` will be saved in `~/.acme.sh/account.conf`, when next time you use dnspod.cn api, it will reuse this key. +The `DP_Id` and `DP_Key` will be saved in `~/.acme.sh/account.conf` and will be reused when needed. -## 3. Use Cloudxns.com domain api to automatically issue cert +## 3. Use CloudXNS.com domain API to automatically issue cert -For now, we support Cloudxns.com integeration. - -First you need to login to your Cloudxns.com account to get your api key and key secret. +First you need to login to your CloudXNS account to get your API Key and Secret. ``` export CX_Key="1234" - export CX_Secret="sADDsdasdgdsf" - ``` -Ok, let's issue cert now: +Ok, let's issue a cert now: ``` -acme.sh --issue --dns dns_cx -d example.com -d www.example.com +acme.sh --issue --dns dns_cx -d example.com -d www.example.com ``` -The `CX_Key` and `CX_Secret` will be saved in `~/.acme.sh/account.conf`, when next time you use Cloudxns.com api, it will reuse this key. +The `CX_Key` and `CX_Secret` will be saved in `~/.acme.sh/account.conf` and will be reused when needed. -## 4. Use Godaddy.com domain api to automatically issue cert +## 4. Use GoDaddy.com domain API to automatically issue cert -We support Godaddy integration. - -First you need to login to your Godaddy account to get your api key and api secret. +First you need to login to your GoDaddy account to get your API Key and Secret. https://developer.godaddy.com/keys/ -Please Create a Production key, instead of a Test key. - +Please create a Production key, instead of a Test key. ``` export GD_Key="sdfsdfsdfljlbjkljlkjsdfoiwje" - export GD_Secret="asdfsdafdsfdsfdsfdsfdsafd" - ``` -Ok, let's issue cert now: +Ok, let's issue a cert now: ``` -acme.sh --issue --dns dns_gd -d example.com -d www.example.com +acme.sh --issue --dns dns_gd -d example.com -d www.example.com ``` -The `GD_Key` and `GD_Secret` will be saved in `~/.acme.sh/account.conf`, when next time you use cloudflare api, it will reuse this key. +The `GD_Key` and `GD_Secret` will be saved in `~/.acme.sh/account.conf` and will be reused when needed. -## 5. Use PowerDNS embedded api to automatically issue cert -We support PowerDNS embedded API integration. +## 5. Use PowerDNS embedded API to automatically issue cert -First you need to enable api and set your api-token in PowerDNS configuration. +First you need to login to your PowerDNS account to enable the API and set your API-Token in the configuration. https://doc.powerdns.com/md/httpapi/README/ @@ -102,21 +83,21 @@ export PDNS_Url="http://ns.example.com:8081" export PDNS_ServerId="localhost" export PDNS_Token="0123456789ABCDEF" export PDNS_Ttl=60 - ``` -Ok, let's issue cert now: +Ok, let's issue a cert now: ``` -acme.sh --issue --dns dns_pdns -d example.com -d www.example.com +acme.sh --issue --dns dns_pdns -d example.com -d www.example.com ``` -The `PDNS_Url`, `PDNS_ServerId`, `PDNS_Token` and `PDNS_Ttl` will be saved in `~/.acme.sh/account.conf`. +The `PDNS_Url`, `PDNS_ServerId`, `PDNS_Token` and `PDNS_Ttl` will be saved in `~/.acme.sh/account.conf` and will be reused when needed. -## 6. Use OVH/kimsufi/soyoustart/runabove API +## 6. Use OVH/kimsufi/soyoustart/runabove API to automatically issue cert https://github.com/Neilpang/acme.sh/wiki/How-to-use-OVH-domain-api + ## 7. Use nsupdate to automatically issue cert First, generate a key for updating the zone @@ -137,6 +118,7 @@ include "/etc/named/keys/update.key"; ``` Next, configure your zone to allow dynamic updates. + Depending on your named version, use either ``` zone "example.com" { @@ -153,18 +135,21 @@ zone "example.com" { }; } ``` -Finally, make the dns server and update key available to `acme.sh` + +Finally, make the DNS server and update Key available to `acme.sh` + ``` -export NSUPDATE_SERVER=dns.example.com -export NSUPDATE_KEY=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa== +export NSUPDATE_SERVER="dns.example.com" +export NSUPDATE_KEY="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa==" ``` -Ok, let's issue cert now: +Ok, let's issue a cert now: ``` -acme.sh --issue --dns dns_nsupdate -d example.com -d www.example.com +acme.sh --issue --dns dns_nsupdate -d example.com -d www.example.com ``` -The `NSUPDATE_SERVER` and `NSUPDATE_KEY` settings will be saved in `~/.acme.sh/account.conf`. +The `NSUPDATE_SERVER` and `NSUPDATE_KEY` settings will be saved in `~/.acme.sh/account.conf` and will be reused when needed. + ## 8. Use LuaDNS domain API @@ -172,17 +157,16 @@ Get your API token at https://api.luadns.com/settings ``` export LUA_Key="sdfsdfsdfljlbjkljlkjsdfoiwje" - export LUA_Email="xxxx@sss.com" - ``` To issue a cert: ``` -acme.sh --issue --dns dns_lua --dnssleep 3 -d example.com -d www.example.com +acme.sh --issue --dns dns_lua -d example.com -d www.example.com ``` -The `LUA_Key` and `LUA_Email` will be saved in `~/.acme.sh/account.conf`, and will be reused when needed. +The `LUA_Key` and `LUA_Email` will be saved in `~/.acme.sh/account.conf` and will be reused when needed. + ## 9. Use DNSMadeEasy domain API @@ -190,39 +174,34 @@ Get your API credentials at https://cp.dnsmadeeasy.com/account/info ``` export ME_Key="sdfsdfsdfljlbjkljlkjsdfoiwje" - export ME_Secret="qdfqsdfkjdskfj" - ``` To issue a cert: ``` -acme.sh --issue --dns dns_me --dnssleep 3 -d example.com -d www.example.com +acme.sh --issue --dns dns_me -d example.com -d www.example.com ``` -The `ME_Key` and `ME_Secret` will be saved in `~/.acme.sh/account.conf`, and will be reused when needed. +The `ME_Key` and `ME_Secret` will be saved in `~/.acme.sh/account.conf` and will be reused when needed. -# 10. Use custom api -If your api is not supported yet, you can write your own dns api. +# 10. Use custom API -Let's assume you want to name it 'myapi', +If your API is not supported yet, you can write your own DNS API. -1. Create a bash script named `~/.acme.sh/dns_myapi.sh`, -2. In the script, you must have a function named `dns_myapi_add()`. Which will be called by acme.sh to add dns records. -3. Then you can use your api to issue cert like: +Let's assume you want to name it 'myapi': + +1. Create a bash script named `~/.acme.sh/dns_myapi.sh`, +2. In the script you must have a function named `dns_myapi_add()` which will be called by acme.sh to add the DNS records. +3. Then you can use your API to issue cert like this: ``` -acme.sh --issue --dns dns_myapi -d example.com -d www.example.com +acme.sh --issue --dns dns_myapi -d example.com -d www.example.com ``` For more details, please check our sample script: [dns_myapi.sh](dns_myapi.sh) -# 11. Use lexicon dns api + +## 11. Use lexicon DNS API https://github.com/Neilpang/acme.sh/wiki/How-to-use-lexicon-dns-api - - - - - From c947322a69d62bb3780b07a80c066a2d6aac7f97 Mon Sep 17 00:00:00 2001 From: neilpang Date: Tue, 15 Nov 2016 21:49:35 +0800 Subject: [PATCH 016/189] sudo for travis --- .travis.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index fe615d82..f032890a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,5 @@ language: shell +sudo: required env: global: @@ -20,7 +21,7 @@ script: - cd .. - curl -sSL https://bin.equinox.io/c/4VmDzA7iaHb/ngrok-stable-linux-amd64.zip -o ngrok-stable-linux-amd64.zip && unzip ngrok-stable-linux-amd64.zip && export NGROK_BIN="$(pwd)/ngrok" - git clone https://github.com/Neilpang/acmetest.git && cp -r acme.sh acmetest/ && cd acmetest - - ./letest.sh + - sudo ./letest.sh matrix: From 9c1747581f53d3dc0bb82e9cae83ff59008a67f5 Mon Sep 17 00:00:00 2001 From: neil Date: Wed, 16 Nov 2016 13:10:56 +0800 Subject: [PATCH 017/189] Update README.md --- README.md | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index e09ef89b..ca51c73d 100644 --- a/README.md +++ b/README.md @@ -248,17 +248,18 @@ You don't have to do anything manually! ### Currently acme.sh supports: -- CloudFlare.com API -- DNSPod.cn API -- CloudXNS.com API -- GoDaddy.com API -- OVH, kimsufi, soyoustart and runabove API -- AWS Route 53, see: https://github.com/Neilpang/acme.sh/issues/65 -- PowerDNS.com API -- lexicon DNS API: https://github.com/Neilpang/acme.sh/wiki/How-to-use-lexicon-dns-api +1. CloudFlare.com API +1. DNSPod.cn API +1. CloudXNS.com API +1. GoDaddy.com API +1. OVH, kimsufi, soyoustart and runabove API +1. AWS Route 53, see: https://github.com/Neilpang/acme.sh/issues/65 +1. PowerDNS.com API +1. lexicon DNS API: https://github.com/Neilpang/acme.sh/wiki/How-to-use-lexicon-dns-api (DigitalOcean, DNSimple, DNSMadeEasy, DNSPark, EasyDNS, Namesilo, NS1, PointHQ, Rage4 and Vultr etc.) -- LuaDNS.com API -- DNSMadeEasy.com API +1. LuaDNS.com API +1. DNSMadeEasy.com API +1. nsupdate API **More APIs coming soon...** From 54ae008dd76c8381b84a2e40d9030d8267255847 Mon Sep 17 00:00:00 2001 From: neilpang Date: Wed, 16 Nov 2016 19:45:00 +0800 Subject: [PATCH 018/189] minor, message typo --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 54e33730..a6a6e977 100755 --- a/acme.sh +++ b/acme.sh @@ -2132,7 +2132,7 @@ _on_issue_err() { if [ "$LOG_FILE" ]; then _err "Please check log file for more details: $LOG_FILE" else - _err "Please use add '--debug' or '--log' to check more details." + _err "Please add '--debug' or '--log' to check more details." _err "See: $_DEBUG_WIKI" fi From 3e5b10244576c661d5cb3b960a55bff05aa9cb8a Mon Sep 17 00:00:00 2001 From: neilpang Date: Wed, 16 Nov 2016 22:20:47 +0800 Subject: [PATCH 019/189] fix error message for nc --- acme.sh | 37 +++++++++++++++++-------------------- 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/acme.sh b/acme.sh index a6a6e977..57420a85 100755 --- a/acme.sh +++ b/acme.sh @@ -1423,32 +1423,29 @@ _startserver() { #for centos ncat if _contains "$nchelp" "nmap.org"; then _debug "Using ncat: nmap.org" - if [ "$DEBUG" ]; then - if printf "%s\r\n\r\n%s" "HTTP/1.1 200 OK" "$content" | $_NC "$Le_HTTPPort"; then - return - fi - else - if printf "%s\r\n\r\n%s" "HTTP/1.1 200 OK" "$content" | $_NC "$Le_HTTPPort" >/dev/null 2>&1; then - return - fi + if ! _exec "printf \"%s\r\n\r\n%s\" \"HTTP/1.1 200 OK\" \"$content\" | $_NC \"$Le_HTTPPort\" >&2"; then + _exec_err + return 1 fi - _err "ncat listen error." + if [ "$DEBUG" ] ; then + _exec_err + fi + return fi # while true ; do - if [ "$DEBUG" ]; then - if ! printf "%s\r\n\r\n%s" "HTTP/1.1 200 OK" "$content" | $_NC -p "$Le_HTTPPort"; then - printf "%s\r\n\r\n%s" "HTTP/1.1 200 OK" "$content" | $_NC "$Le_HTTPPort" - fi - else - if ! printf "%s\r\n\r\n%s" "HTTP/1.1 200 OK" "$content" | $_NC -p "$Le_HTTPPort" >/dev/null 2>&1; then - printf "%s\r\n\r\n%s" "HTTP/1.1 200 OK" "$content" | $_NC "$Le_HTTPPort" >/dev/null 2>&1 - fi + if ! _exec "printf \"%s\r\n\r\n%s\" \"HTTP/1.1 200 OK\" \"$content\" | $_NC -p \"$Le_HTTPPort\" >&2"; then + _exec "printf \"%s\r\n\r\n%s\" \"HTTP/1.1 200 OK\" \"$content\" | $_NC \"$Le_HTTPPort\" >&2" fi + if [ "$?" != "0" ]; then _err "nc listen error." + _exec_err exit 1 fi + if [ "$DEBUG" ] ; then + _exec_err + fi # done } @@ -1781,14 +1778,14 @@ _exec() { fi if [ "$_EXEC_TEMP_ERR" ]; then - "$@" 2>"$_EXEC_TEMP_ERR" + eval "$@ 2>>$_EXEC_TEMP_ERR" else - "$@" + eval "$@" fi } _exec_err() { - [ "$_EXEC_TEMP_ERR" ] && _err "$(cat "$_EXEC_TEMP_ERR")" + [ "$_EXEC_TEMP_ERR" ] && _err "$(cat "$_EXEC_TEMP_ERR")" && echo "" >"$_EXEC_TEMP_ERR" } _apachePath() { From 8f9034fc8b7146aa111a219cdcfd5dbaac275b24 Mon Sep 17 00:00:00 2001 From: neilpang Date: Wed, 16 Nov 2016 22:28:33 +0800 Subject: [PATCH 020/189] fix shfmt --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index f032890a..a5e7a3b6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,7 +17,7 @@ script: - chmod +x ~/shfmt - shellcheck -V - shellcheck -e SC2021,SC2126,SC2034 **/*.sh && echo "shellcheck OK" - - ~/shfmt -l -w -i 2 . && echo "shfmt OK" || git diff --exit-code || (echo "Run shfmt to fix the formatting issues" && false) + - ~/shfmt -l -w -i 2 . && echo "shfmt OK" || git diff --exit-code - cd .. - curl -sSL https://bin.equinox.io/c/4VmDzA7iaHb/ngrok-stable-linux-amd64.zip -o ngrok-stable-linux-amd64.zip && unzip ngrok-stable-linux-amd64.zip && export NGROK_BIN="$(pwd)/ngrok" - git clone https://github.com/Neilpang/acmetest.git && cp -r acme.sh acmetest/ && cd acmetest From 9a6e18ce80f72abbce3051d4853e9bd22fb9a619 Mon Sep 17 00:00:00 2001 From: neilpang Date: Wed, 16 Nov 2016 22:37:03 +0800 Subject: [PATCH 021/189] fix shfmt --- .travis.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index a5e7a3b6..e78787f6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,7 +17,8 @@ script: - chmod +x ~/shfmt - shellcheck -V - shellcheck -e SC2021,SC2126,SC2034 **/*.sh && echo "shellcheck OK" - - ~/shfmt -l -w -i 2 . && echo "shfmt OK" || git diff --exit-code + - ~/shfmt -l -w -i 2 . + - git diff --exit-code && echo "shfmt OK" - cd .. - curl -sSL https://bin.equinox.io/c/4VmDzA7iaHb/ngrok-stable-linux-amd64.zip -o ngrok-stable-linux-amd64.zip && unzip ngrok-stable-linux-amd64.zip && export NGROK_BIN="$(pwd)/ngrok" - git clone https://github.com/Neilpang/acmetest.git && cp -r acme.sh acmetest/ && cd acmetest From fa574fe833330a4e19395738627822ad87b1ae43 Mon Sep 17 00:00:00 2001 From: neilpang Date: Wed, 16 Nov 2016 22:44:39 +0800 Subject: [PATCH 022/189] fix shfmt --- .travis.yml | 4 ++-- acme.sh | 6 +++--- dnsapi/dns_nsupdate.sh | 3 +-- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/.travis.yml b/.travis.yml index e78787f6..cf708c2f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,10 +15,10 @@ addons: script: - curl -sSL $SHFMT_URL -o ~/shfmt - chmod +x ~/shfmt - - shellcheck -V - - shellcheck -e SC2021,SC2126,SC2034 **/*.sh && echo "shellcheck OK" - ~/shfmt -l -w -i 2 . - git diff --exit-code && echo "shfmt OK" + - shellcheck -V + - shellcheck -e SC2021,SC2126,SC2034 **/*.sh && echo "shellcheck OK" - cd .. - curl -sSL https://bin.equinox.io/c/4VmDzA7iaHb/ngrok-stable-linux-amd64.zip -o ngrok-stable-linux-amd64.zip && unzip ngrok-stable-linux-amd64.zip && export NGROK_BIN="$(pwd)/ngrok" - git clone https://github.com/Neilpang/acmetest.git && cp -r acme.sh acmetest/ && cd acmetest diff --git a/acme.sh b/acme.sh index 57420a85..ba4688cf 100755 --- a/acme.sh +++ b/acme.sh @@ -1325,7 +1325,7 @@ _clear_conf() { _sdkey="$2" if [ "$_c_c_f" ]; then _conf_data="$(cat "$_c_c_f")" - echo "$_conf_data" | sed "s/^$_sdkey *=.*$//" > "$_c_c_f" + echo "$_conf_data" | sed "s/^$_sdkey *=.*$//" >"$_c_c_f" else _err "config file is empty, can not clear" fi @@ -1427,7 +1427,7 @@ _startserver() { _exec_err return 1 fi - if [ "$DEBUG" ] ; then + if [ "$DEBUG" ]; then _exec_err fi return @@ -1443,7 +1443,7 @@ _startserver() { _exec_err exit 1 fi - if [ "$DEBUG" ] ; then + if [ "$DEBUG" ]; then _exec_err fi # done diff --git a/dnsapi/dns_nsupdate.sh b/dnsapi/dns_nsupdate.sh index a024e314..5e7af831 100755 --- a/dnsapi/dns_nsupdate.sh +++ b/dnsapi/dns_nsupdate.sh @@ -1,6 +1,5 @@ #!/usr/bin/env sh - ######## Public functions ##################### #Usage: dns_nsupdate_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" @@ -22,7 +21,7 @@ EOF _err "error updating domain" return 1 fi - + return 0 } From ac26f841709e73fd56b3efa77911744b4b391cd1 Mon Sep 17 00:00:00 2001 From: neilpang Date: Wed, 16 Nov 2016 22:53:59 +0800 Subject: [PATCH 023/189] fix shfmt --- dnsapi/dns_nsupdate.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/dnsapi/dns_nsupdate.sh b/dnsapi/dns_nsupdate.sh index 5e7af831..8067d2fe 100755 --- a/dnsapi/dns_nsupdate.sh +++ b/dnsapi/dns_nsupdate.sh @@ -44,7 +44,6 @@ EOF return 0 } - #################### Private functions bellow ################################## _checkKeyFile() { From 7575094cf34e6e218fbad9face68362360b2eedb Mon Sep 17 00:00:00 2001 From: neilpang Date: Wed, 16 Nov 2016 23:53:32 +0800 Subject: [PATCH 024/189] fix _exists --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index ba4688cf..280cb415 100755 --- a/acme.sh +++ b/acme.sh @@ -249,7 +249,7 @@ _exists() { fi if command >/dev/null 2>&1; then command -v "$cmd" >/dev/null 2>&1 - elif which >/dev/null 2>&1; then + elif which ls >/dev/null 2>&1; then which "$cmd" >/dev/null 2>&1 fi ret="$?" From 4a56b2406b7b44f0f791008e7f99bf339e25292f Mon Sep 17 00:00:00 2001 From: neilpang Date: Thu, 17 Nov 2016 00:22:45 +0800 Subject: [PATCH 025/189] fix check email --- dnsapi/dns_cf.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/dnsapi/dns_cf.sh b/dnsapi/dns_cf.sh index cacb5b39..7f2a0977 100755 --- a/dnsapi/dns_cf.sh +++ b/dnsapi/dns_cf.sh @@ -22,6 +22,12 @@ dns_cf_add() { return 1 fi + if ! _contains "$CF_Email" "@"; then + _err "It seems that the CF_Email=$CF_Email is not a valid email address." + _err "Please check and retry." + return 1 + fi + #save the api key and email to the account conf file. _saveaccountconf CF_Key "$CF_Key" _saveaccountconf CF_Email "$CF_Email" From ab45b7783f19447c7d7bd8a06e368a6461933b86 Mon Sep 17 00:00:00 2001 From: neilpang Date: Thu, 17 Nov 2016 00:25:40 +0800 Subject: [PATCH 026/189] fix format --- dnsapi/dns_cf.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_cf.sh b/dnsapi/dns_cf.sh index 7f2a0977..dd8c9143 100755 --- a/dnsapi/dns_cf.sh +++ b/dnsapi/dns_cf.sh @@ -27,7 +27,7 @@ dns_cf_add() { _err "Please check and retry." return 1 fi - + #save the api key and email to the account conf file. _saveaccountconf CF_Key "$CF_Key" _saveaccountconf CF_Email "$CF_Email" From 82dc2244c00b9de6636eebff2a0ec3dce3bcb174 Mon Sep 17 00:00:00 2001 From: neil Date: Thu, 17 Nov 2016 13:17:29 +0800 Subject: [PATCH 027/189] fix _exists for busybox --- acme.sh | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/acme.sh b/acme.sh index 280cb415..a4a08392 100755 --- a/acme.sh +++ b/acme.sh @@ -247,9 +247,12 @@ _exists() { _usage "Usage: _exists cmd" return 1 fi - if command >/dev/null 2>&1; then + + if eval type type >/dev/null 2>&1; then + eval type "$cmd" >/dev/null 2>&1 + elif command >/dev/null 2>&1; then command -v "$cmd" >/dev/null 2>&1 - elif which ls >/dev/null 2>&1; then + elif which which >/dev/null 2>&1; then which "$cmd" >/dev/null 2>&1 fi ret="$?" From ce4be4e91eb5e2d34b4a3363fb2514e0088ae5ed Mon Sep 17 00:00:00 2001 From: neil Date: Thu, 17 Nov 2016 13:20:20 +0800 Subject: [PATCH 028/189] fix _exists --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index a4a08392..1397f870 100755 --- a/acme.sh +++ b/acme.sh @@ -252,7 +252,7 @@ _exists() { eval type "$cmd" >/dev/null 2>&1 elif command >/dev/null 2>&1; then command -v "$cmd" >/dev/null 2>&1 - elif which which >/dev/null 2>&1; then + else which "$cmd" >/dev/null 2>&1 fi ret="$?" From 2ce2a15fc6e5a77315db234483abe594bf8fe8c8 Mon Sep 17 00:00:00 2001 From: neil Date: Thu, 17 Nov 2016 13:40:10 +0800 Subject: [PATCH 029/189] add PULL_REQUEST_TEMPLATE template --- .github/PULL_REQUEST_TEMPLATE.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 .github/PULL_REQUEST_TEMPLATE.md diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 00000000..2df6e9c4 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,14 @@ + \ No newline at end of file From d5c00071d33943876d31559c36f5ad6da767e9c1 Mon Sep 17 00:00:00 2001 From: magna-z Date: Thu, 17 Nov 2016 14:52:00 +0300 Subject: [PATCH 030/189] Add functional in method dns_pdns_rm() --- dnsapi/dns_pdns.sh | 52 ++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 48 insertions(+), 4 deletions(-) diff --git a/dnsapi/dns_pdns.sh b/dnsapi/dns_pdns.sh index 5d6d99fd..a2c29075 100755 --- a/dnsapi/dns_pdns.sh +++ b/dnsapi/dns_pdns.sh @@ -12,6 +12,8 @@ DEFAULT_PDNS_TTL=60 ######## Public functions ##################### #Usage: add _acme-challenge.www.domain.com "123456789ABCDEF0000000000000000000000000000000000000" +#fulldomain +#txtvalue dns_pdns_add() { fulldomain=$1 txtvalue=$2 @@ -50,7 +52,7 @@ dns_pdns_add() { _saveaccountconf PDNS_Ttl "$PDNS_Ttl" fi - _debug "First detect the root zone" + _debug "Detect root zone" if ! _get_root "$fulldomain"; then _err "invalid domain" return 1 @@ -68,6 +70,18 @@ dns_pdns_add() { dns_pdns_rm() { fulldomain=$1 + _debug "Detect root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + _debug _domain "$_domain" + + if ! rm_record "$_domain" "$fulldomain"; then + return 1 + fi + + return 0 } set_record() { @@ -76,14 +90,43 @@ set_record() { full=$2 txtvalue=$3 - if ! _pdns_rest "PATCH" "/api/v1/servers/$PDNS_ServerId/zones/$root." "{\"rrsets\": [{\"name\": \"$full.\", \"changetype\": \"REPLACE\", \"type\": \"TXT\", \"ttl\": $PDNS_Ttl, \"records\": [{\"name\": \"$full.\", \"type\": \"TXT\", \"content\": \"\\\"$txtvalue\\\"\", \"disabled\": false, \"ttl\": $PDNS_Ttl}]}]}"; then + if ! _pdns_rest "PATCH" "/api/v1/servers/$PDNS_ServerId/zones/$root." "{\"rrsets\": [{\"changetype\": \"REPLACE\", \"name\": \"$full.\", \"type\": \"TXT\", \"ttl\": $PDNS_Ttl, \"records\": [{\"name\": \"$full.\", \"type\": \"TXT\", \"content\": \"\\\"$txtvalue\\\"\", \"disabled\": false, \"ttl\": $PDNS_Ttl}]}]}"; then _err "Set txt record error." return 1 fi - if ! _pdns_rest "PUT" "/api/v1/servers/$PDNS_ServerId/zones/$root./notify"; then - _err "Notify servers error." + + if ! notify_slaves "$root"; then return 1 fi + + return 0 +} + +rm_record() { + _info "Remove record" + root=$1 + full=$2 + + if ! _pdns_rest "PATCH" "/api/v1/servers/$PDNS_ServerId/zones/$root." "{\"rrsets\": [{\"changetype\": \"DELETE\", \"name\": \"$full.\", \"type\": \"TXT\"}]}"; then + _err "Delete txt record error." + return 1 + fi + + if ! notify_slaves "$root"; then + return 1 + fi + + return 0 +} + +notify_slaves() { + root=$1 + + if ! _pdns_rest "PUT" "/api/v1/servers/$PDNS_ServerId/zones/$root./notify"; then + _err "Notify slaves error." + return 1 + fi + return 0 } @@ -113,6 +156,7 @@ _get_root() { i=$(_math $i + 1) done _debug "$domain not found" + return 1 } From 3498a5856aed22ee696d70c1d269a03f7f96758f Mon Sep 17 00:00:00 2001 From: neilpang Date: Fri, 18 Nov 2016 19:40:41 +0800 Subject: [PATCH 031/189] fix bug https://github.com/Neilpang/acme.sh/issues/401 --- acme.sh | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/acme.sh b/acme.sh index 1397f870..2b2386d0 100755 --- a/acme.sh +++ b/acme.sh @@ -1705,8 +1705,6 @@ _initpath() { return 0 fi - mkdir -p "$CA_DIR" - domain="$1" _ilength="$2" @@ -1726,13 +1724,6 @@ _initpath() { _debug DOMAIN_PATH "$DOMAIN_PATH" fi - if [ ! -d "$DOMAIN_PATH" ]; then - if ! mkdir -p "$DOMAIN_PATH"; then - _err "Can not create domain path: $DOMAIN_PATH" - return 1 - fi - fi - if [ -z "$DOMAIN_CONF" ]; then DOMAIN_CONF="$DOMAIN_PATH/$domain.conf" fi @@ -3005,6 +2996,10 @@ renewAll() { for di in "${CERT_HOME}"/*.*/; do _debug di "$di" + if ! [ -d "$di" ] ; then + _debug "Not directory, skip: $di" + continue + fi d=$(basename "$di") _debug d "$d" ( @@ -3127,6 +3122,10 @@ list() { if [ "$_raw" ]; then printf "%s\n" "Main_Domain${_sep}KeyLength${_sep}SAN_Domains${_sep}Created${_sep}Renew" for di in "${CERT_HOME}"/*.*/; do + if ! [ -d "$di" ] ; then + _debug "Not directory, skip: $di" + continue + fi d=$(basename "$di") _debug d "$d" ( From 44483dba218947d8e9900912d06aa68ddd012376 Mon Sep 17 00:00:00 2001 From: neilpang Date: Fri, 18 Nov 2016 19:44:43 +0800 Subject: [PATCH 032/189] fix format --- acme.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/acme.sh b/acme.sh index 2b2386d0..6f948f51 100755 --- a/acme.sh +++ b/acme.sh @@ -2996,7 +2996,7 @@ renewAll() { for di in "${CERT_HOME}"/*.*/; do _debug di "$di" - if ! [ -d "$di" ] ; then + if ! [ -d "$di" ]; then _debug "Not directory, skip: $di" continue fi @@ -3122,7 +3122,7 @@ list() { if [ "$_raw" ]; then printf "%s\n" "Main_Domain${_sep}KeyLength${_sep}SAN_Domains${_sep}Created${_sep}Renew" for di in "${CERT_HOME}"/*.*/; do - if ! [ -d "$di" ] ; then + if ! [ -d "$di" ]; then _debug "Not directory, skip: $di" continue fi From a3c0c7546df4d4e8d8dc384b0642101572085fd3 Mon Sep 17 00:00:00 2001 From: neilpang Date: Fri, 18 Nov 2016 20:14:08 +0800 Subject: [PATCH 033/189] fix egrep performance --- acme.sh | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/acme.sh b/acme.sh index 6f948f51..e3f844ea 100755 --- a/acme.sh +++ b/acme.sh @@ -349,10 +349,8 @@ _sed_i() { } _egrep_o() { - if _contains "$(egrep -o 2>&1)" "egrep: illegal option -- o"; then + if ! egrep -o "$1" 2>/dev/null; then sed -n 's/.*\('"$1"'\).*/\1/p' - else - egrep -o "$1" fi } From 5a7b7b51c580898a101bf15ba51c532ef4fbde23 Mon Sep 17 00:00:00 2001 From: neilpang Date: Fri, 18 Nov 2016 21:40:03 +0800 Subject: [PATCH 034/189] fix ngrok --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index cf708c2f..8829e472 100644 --- a/.travis.yml +++ b/.travis.yml @@ -20,7 +20,6 @@ script: - shellcheck -V - shellcheck -e SC2021,SC2126,SC2034 **/*.sh && echo "shellcheck OK" - cd .. - - curl -sSL https://bin.equinox.io/c/4VmDzA7iaHb/ngrok-stable-linux-amd64.zip -o ngrok-stable-linux-amd64.zip && unzip ngrok-stable-linux-amd64.zip && export NGROK_BIN="$(pwd)/ngrok" - git clone https://github.com/Neilpang/acmetest.git && cp -r acme.sh acmetest/ && cd acmetest - sudo ./letest.sh From e009ec8b935342c1d8cf3ff9fe55e88f0f7051a2 Mon Sep 17 00:00:00 2001 From: neilpang Date: Sun, 20 Nov 2016 22:57:07 +0800 Subject: [PATCH 035/189] Support AWS Route53 api --- acme.sh | 24 +++-- dnsapi/dns_aws.sh | 220 ++++++++++++++++++++++++++++++++++++++++++++++ dnsapi/dns_me.sh | 2 +- 3 files changed, 239 insertions(+), 7 deletions(-) create mode 100644 dnsapi/dns_aws.sh diff --git a/acme.sh b/acme.sh index e3f844ea..36492cb8 100755 --- a/acme.sh +++ b/acme.sh @@ -329,6 +329,18 @@ _h2b() { done } +#hex string +_hex() { + _str="$1" + _str_len=${#_str} + _h_i=1 + while [ "$_h_i" -le "$_str_len" ]; do + _str_c="$(printf "%s" "$_str" | cut -c "$_h_i" )" + printf "%02x" "'$_str_c" + _h_i="$(_math "$_h_i" + 1)" + done +} + #options file _sed_i() { options="$1" @@ -426,23 +438,23 @@ _digest() { } -#Usage: hashalg secret [outputhex] -#Output Base64-encoded hmac +#Usage: hashalg secret_hex [outputhex] +#Output binary hmac _hmac() { alg="$1" - hmac_sec="$2" + secret_hex="$2" outputhex="$3" - if [ -z "$hmac_sec" ]; then + if [ -z "$secret_hex" ]; then _usage "Usage: _hmac hashalg secret [outputhex]" return 1 fi if [ "$alg" = "sha256" ] || [ "$alg" = "sha1" ]; then if [ "$outputhex" ]; then - openssl dgst -"$alg" -hmac "$hmac_sec" | cut -d = -f 2 | tr -d ' ' + openssl dgst -"$alg" -mac HMAC -macopt "hexkey:$secret_hex" | cut -d = -f 2 | tr -d ' ' else - openssl dgst -"$alg" -hmac "$hmac_sec" -binary | _base64 + openssl dgst -"$alg" -mac HMAC -macopt "hexkey:$secret_hex" -binary fi else _err "$alg is not supported yet" diff --git a/dnsapi/dns_aws.sh b/dnsapi/dns_aws.sh new file mode 100644 index 00000000..ecf1156c --- /dev/null +++ b/dnsapi/dns_aws.sh @@ -0,0 +1,220 @@ +#!/usr/bin/env sh + +# +#AWS_ACCESS_KEY_ID="sdfsdfsdfljlbjkljlkjsdfoiwje" +# +#AWS_SECRET_ACCESS_KEY="xxxxxxx" + +#This is the Amazon Route53 api wrapper for acme.sh + +AWS_HOST="route53.amazonaws.com" +AWS_URL="https://$AWS_HOST" + +AWS_WIKI="https://github.com/Neilpang/acme.sh/wiki/How-to-use-Amazon-Route53-API" + +######## Public functions ##################### + +#Usage: dns_myapi_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_aws_add() { + fulldomain=$1 + txtvalue=$2 + + if [ -z "$AWS_ACCESS_KEY_ID" ] || [ -z "$AWS_SECRET_ACCESS_KEY" ]; then + AWS_ACCESS_KEY_ID="" + AWS_SECRET_ACCESS_KEY="" + _err "You don't specify aws route53 api key id and and api key secret yet." + _err "Please create you key and try again. see $(__green $AWS_WIKI)" + return 1 + fi + + _saveaccountconf AWS_ACCESS_KEY_ID "$AWS_ACCESS_KEY_ID" + _saveaccountconf AWS_SECRET_ACCESS_KEY "$AWS_SECRET_ACCESS_KEY" + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + _debug _domain_id "$_domain_id" + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + _aws_tmpl_xml="UPSERT$fulldomainTXT300\"$txtvalue\"" + + if aws_rest POST "2013-04-01$_domain_id/rrset/" "" "$_aws_tmpl_xml" && _contains "$response" "ChangeResourceRecordSetsResponse"; then + _info "txt record updated sucess." + return 0 + fi + + return 1; +} + + + +#fulldomain +dns_aws_rm() { + fulldomain=$1 + +} + + +#################### Private functions bellow ################################## + +_get_root() { + domain=$1 + i=2 + p=1 + + if aws_rest GET "2013-04-01/hostedzone"; then + _debug "response" "$response" + while true; do + h=$(printf "%s" "$domain" | cut -d . -f $i-100) + if [ -z "$h" ]; then + #not valid + return 1 + fi + + if _contains "$response" "$h."; then + hostedzone="$(echo "$response" | _egrep_o ".*$h..*")" + _debug hostedzone "$hostedzone" + if [ -z "$hostedzone" ]; then + _err "Error, can not get hostedzone." + return 1 + fi + _domain_id=$(printf "%s\n" "$hostedzone" | _egrep_o ".*" | head -n 1 | _egrep_o ">.*<" | tr -d "<>") + if [ "$_domain_id" ]; then + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _domain=$h + return 0 + fi + return 1 + fi + p=$i + i=$(_math "$i" + 1) + done + fi + return 1 +} + + +#method uri qstr data +aws_rest() { + mtd="$1" + ep="$2" + qsr="$3" + data="$4" + + _debug mtd "$mtd" + _debug ep "$ep" + _debug qsr "$qsr" + _debug data "$data" + + CanonicalURI="/$ep" + _debug2 CanonicalURI "$CanonicalURI" + + CanonicalQueryString="$qsr" + _debug2 CanonicalQueryString "$CanonicalQueryString" + + RequestDate="$(date -u +"%Y%m%dT%H%M%SZ")" + _debug2 RequestDate "$RequestDate" + + #RequestDate="20161120T141056Z" ############## + + _H1="x-amz-date: $RequestDate" + + aws_host="$AWS_HOST" + CanonicalHeaders="host:$aws_host\nx-amz-date:$RequestDate\n" + _debug2 CanonicalHeaders "$CanonicalHeaders" + + SignedHeaders="host;x-amz-date" + _debug2 SignedHeaders "$SignedHeaders" + + RequestPayload="$data" + _debug2 RequestPayload "$RequestPayload" + + Hash="sha256" + + CanonicalRequest="$mtd\n$CanonicalURI\n$CanonicalQueryString\n$CanonicalHeaders\n$SignedHeaders\n$(printf "%s" "$RequestPayload" | _digest "$Hash" hex)" + _debug2 CanonicalRequest "$CanonicalRequest" + + HashedCanonicalRequest="$(printf "$CanonicalRequest%s" | _digest "$Hash" hex )" + _debug2 HashedCanonicalRequest "$HashedCanonicalRequest" + + Algorithm="AWS4-HMAC-SHA256" + _debug2 Algorithm "$Algorithm" + + RequestDateOnly="$(echo "$RequestDate" | cut -c 1-8 )" + _debug2 RequestDateOnly "$RequestDateOnly" + + Region="us-east-1" + Service="route53" + + CredentialScope="$RequestDateOnly/$Region/$Service/aws4_request" + _debug2 CredentialScope "$CredentialScope" + + StringToSign="$Algorithm\n$RequestDate\n$CredentialScope\n$HashedCanonicalRequest" + + _debug2 StringToSign "$StringToSign" + + kSecret="AWS4$AWS_SECRET_ACCESS_KEY" + + #kSecret="wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY" ############################ + + _debug2 kSecret "$kSecret" + + kSecretH="$(_hex "$kSecret")" + _debug2 kSecretH "$kSecretH" + + kDateH="$(printf "$RequestDateOnly%s" | _hmac "$Hash" "$kSecretH" hex)" + _debug2 kDateH "$kDateH" + + kRegionH="$(printf "$Region%s" | _hmac "$Hash" "$kDateH" hex)" + _debug2 kRegionH "$kRegionH" + + kServiceH="$(printf "$Service%s" | _hmac "$Hash" "$kRegionH" hex)" + _debug2 kServiceH "$kServiceH" + + kSigningH="$(printf "aws4_request%s" | _hmac "$Hash" "$kServiceH" hex)" + _debug2 kSigningH "$kSigningH" + + signature="$(printf "$StringToSign%s" | _hmac "$Hash" "$kSigningH" hex)" + _debug2 signature "$signature" + + Authorization="$Algorithm Credential=$AWS_ACCESS_KEY_ID/$CredentialScope, SignedHeaders=$SignedHeaders, Signature=$signature" + _debug2 Authorization "$Authorization" + + _H3="Authorization: $Authorization" + _debug _H3 "$_H3" + + url="$AWS_URL/$ep" + + if [ "$mtd" = "GET" ]; then + response="$(_get "$url")" + else + response="$(_post "$data" "$url")" + fi + + _ret="$?" + if [ "$_ret" = "0" ]; then + if _contains "$response" " Date: Sun, 20 Nov 2016 23:04:28 +0800 Subject: [PATCH 036/189] fix format --- acme.sh | 2 +- dnsapi/dns_aws.sh | 28 +++++----------------------- 2 files changed, 6 insertions(+), 24 deletions(-) diff --git a/acme.sh b/acme.sh index 36492cb8..63ec7d44 100755 --- a/acme.sh +++ b/acme.sh @@ -335,7 +335,7 @@ _hex() { _str_len=${#_str} _h_i=1 while [ "$_h_i" -le "$_str_len" ]; do - _str_c="$(printf "%s" "$_str" | cut -c "$_h_i" )" + _str_c="$(printf "%s" "$_str" | cut -c "$_h_i")" printf "%02x" "'$_str_c" _h_i="$(_math "$_h_i" + 1)" done diff --git a/dnsapi/dns_aws.sh b/dnsapi/dns_aws.sh index ecf1156c..c0ab72df 100644 --- a/dnsapi/dns_aws.sh +++ b/dnsapi/dns_aws.sh @@ -40,31 +40,28 @@ dns_aws_add() { _debug _domain "$_domain" _aws_tmpl_xml="UPSERT$fulldomainTXT300\"$txtvalue\"" - + if aws_rest POST "2013-04-01$_domain_id/rrset/" "" "$_aws_tmpl_xml" && _contains "$response" "ChangeResourceRecordSetsResponse"; then _info "txt record updated sucess." return 0 fi - return 1; + return 1 } - - #fulldomain dns_aws_rm() { fulldomain=$1 } - #################### Private functions bellow ################################## _get_root() { domain=$1 i=2 p=1 - + if aws_rest GET "2013-04-01/hostedzone"; then _debug "response" "$response" while true; do @@ -96,7 +93,6 @@ _get_root() { return 1 } - #method uri qstr data aws_rest() { mtd="$1" @@ -137,13 +133,13 @@ aws_rest() { CanonicalRequest="$mtd\n$CanonicalURI\n$CanonicalQueryString\n$CanonicalHeaders\n$SignedHeaders\n$(printf "%s" "$RequestPayload" | _digest "$Hash" hex)" _debug2 CanonicalRequest "$CanonicalRequest" - HashedCanonicalRequest="$(printf "$CanonicalRequest%s" | _digest "$Hash" hex )" + HashedCanonicalRequest="$(printf "$CanonicalRequest%s" | _digest "$Hash" hex)" _debug2 HashedCanonicalRequest "$HashedCanonicalRequest" Algorithm="AWS4-HMAC-SHA256" _debug2 Algorithm "$Algorithm" - RequestDateOnly="$(echo "$RequestDate" | cut -c 1-8 )" + RequestDateOnly="$(echo "$RequestDate" | cut -c 1-8)" _debug2 RequestDateOnly "$RequestDateOnly" Region="us-east-1" @@ -204,17 +200,3 @@ aws_rest() { return "$_ret" } - - - - - - - - - - - - - - From 2f1bc5864f03ce9b7b3c2e4cbf6f192fabb5f255 Mon Sep 17 00:00:00 2001 From: neilpang Date: Sun, 20 Nov 2016 23:09:57 +0800 Subject: [PATCH 037/189] fix format --- dnsapi/dns_aws.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_aws.sh b/dnsapi/dns_aws.sh index c0ab72df..15bf7b14 100644 --- a/dnsapi/dns_aws.sh +++ b/dnsapi/dns_aws.sh @@ -132,7 +132,7 @@ aws_rest() { CanonicalRequest="$mtd\n$CanonicalURI\n$CanonicalQueryString\n$CanonicalHeaders\n$SignedHeaders\n$(printf "%s" "$RequestPayload" | _digest "$Hash" hex)" _debug2 CanonicalRequest "$CanonicalRequest" - + HashedCanonicalRequest="$(printf "$CanonicalRequest%s" | _digest "$Hash" hex)" _debug2 HashedCanonicalRequest "$HashedCanonicalRequest" @@ -197,6 +197,6 @@ aws_rest() { return 1 fi fi - + return "$_ret" } From 5b771039fc705ed822a3331f5ee4761b5fab2346 Mon Sep 17 00:00:00 2001 From: neilpang Date: Sun, 20 Nov 2016 23:21:07 +0800 Subject: [PATCH 038/189] Support AWS Route53 api --- README.md | 2 +- acme.sh | 5 +++++ dnsapi/README.md | 20 ++++++++++++++++++-- 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index ca51c73d..69348bf9 100644 --- a/README.md +++ b/README.md @@ -253,7 +253,7 @@ You don't have to do anything manually! 1. CloudXNS.com API 1. GoDaddy.com API 1. OVH, kimsufi, soyoustart and runabove API -1. AWS Route 53, see: https://github.com/Neilpang/acme.sh/issues/65 +1. AWS Route 53 1. PowerDNS.com API 1. lexicon DNS API: https://github.com/Neilpang/acme.sh/wiki/How-to-use-lexicon-dns-api (DigitalOcean, DNSimple, DNSMadeEasy, DNSPark, EasyDNS, Namesilo, NS1, PointHQ, Rage4 and Vultr etc.) diff --git a/acme.sh b/acme.sh index 63ec7d44..7a305cf2 100755 --- a/acme.sh +++ b/acme.sh @@ -3613,6 +3613,11 @@ _initconf() { #PDNS_Token=\"0123456789ABCDEF\" #PDNS_Ttl=60 +####################### +#Amazon Route53: +#AWS_ACCESS_KEY_ID=XXXXXXXXXX +#AWS_SECRET_ACCESS_KEY=XXXXXXXXXXXXXXX + " >"$ACCOUNT_CONF_PATH" fi } diff --git a/dnsapi/README.md b/dnsapi/README.md index f1df726f..9a8730c9 100644 --- a/dnsapi/README.md +++ b/dnsapi/README.md @@ -185,7 +185,23 @@ acme.sh --issue --dns dns_me -d example.com -d www.example.com The `ME_Key` and `ME_Secret` will be saved in `~/.acme.sh/account.conf` and will be reused when needed. -# 10. Use custom API +## 10. Use Amazon Route53 domain API + +https://github.com/Neilpang/acme.sh/wiki/How-to-use-Amazon-Route53-API + +``` +export AWS_ACCESS_KEY_ID=XXXXXXXXXX +export AWS_SECRET_ACCESS_KEY=XXXXXXXXXXXXXXX +``` + +To issue a cert: +``` +acme.sh --issue --dns dns_aws -d example.com -d www.example.com +``` + +The `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` will be saved in `~/.acme.sh/account.conf` and will be reused when needed. + +# 11. Use custom API If your API is not supported yet, you can write your own DNS API. @@ -202,6 +218,6 @@ acme.sh --issue --dns dns_myapi -d example.com -d www.example.com For more details, please check our sample script: [dns_myapi.sh](dns_myapi.sh) -## 11. Use lexicon DNS API +## 12. Use lexicon DNS API https://github.com/Neilpang/acme.sh/wiki/How-to-use-lexicon-dns-api From 7834c252534d6d24c8a307feec7aa7428c65e7e6 Mon Sep 17 00:00:00 2001 From: neilpang Date: Mon, 21 Nov 2016 20:56:50 +0800 Subject: [PATCH 039/189] refactor HTTPS_INSECURE --- acme.sh | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/acme.sh b/acme.sh index 7a305cf2..6b63c9ed 100755 --- a/acme.sh +++ b/acme.sh @@ -1049,9 +1049,6 @@ _inithttp() { _ACME_CURL="$_ACME_CURL --cacert $CA_BUNDLE " fi - if [ "$HTTPS_INSECURE" ]; then - _ACME_CURL="$_ACME_CURL --insecure " - fi fi if [ -z "$_ACME_WGET" ] && _exists "wget"; then @@ -1062,9 +1059,6 @@ _inithttp() { if [ "$CA_BUNDLE" ]; then _ACME_WGET="$_ACME_WGET --ca-certificate $CA_BUNDLE " fi - if [ "$HTTPS_INSECURE" ]; then - _ACME_WGET="$_ACME_WGET --no-check-certificate " - fi fi __HTTP_INITIALIZED=1 @@ -1089,6 +1083,9 @@ _post() { if [ "$_ACME_CURL" ]; then _CURL="$_ACME_CURL" + if [ "$HTTPS_INSECURE" ]; then + _CURL="$_CURL --insecure " + fi _debug "_CURL" "$_CURL" if [ "$needbase64" ]; then response="$($_CURL --user-agent "$USER_AGENT" -X $httpmethod -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" --data "$body" "$url" | _base64)" @@ -1104,18 +1101,22 @@ _post() { fi fi elif [ "$_ACME_WGET" ]; then - _debug "_ACME_WGET" "$_ACME_WGET" + _WGET="$_ACME_WGET" + if [ "$HTTPS_INSECURE" ]; then + _WGET="$_WGET --no-check-certificate " + fi + _debug "_WGET" "$_WGET" if [ "$needbase64" ]; then if [ "$httpmethod" = "POST" ]; then - response="$($_ACME_WGET -S -O - --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" --post-data="$body" "$url" 2>"$HTTP_HEADER" | _base64)" + response="$($_WGET -S -O - --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" --post-data="$body" "$url" 2>"$HTTP_HEADER" | _base64)" else - response="$($_ACME_WGET -S -O - --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" --method $httpmethod --body-data="$body" "$url" 2>"$HTTP_HEADER" | _base64)" + response="$($_WGET -S -O - --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" --method $httpmethod --body-data="$body" "$url" 2>"$HTTP_HEADER" | _base64)" fi else if [ "$httpmethod" = "POST" ]; then - response="$($_ACME_WGET -S -O - --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" --post-data="$body" "$url" 2>"$HTTP_HEADER")" + response="$($_WGET -S -O - --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" --post-data="$body" "$url" 2>"$HTTP_HEADER")" else - response="$($_ACME_WGET -S -O - --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" --method $httpmethod --body-data="$body" "$url" 2>"$HTTP_HEADER")" + response="$($_WGET -S -O - --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" --method $httpmethod --body-data="$body" "$url" 2>"$HTTP_HEADER")" fi fi _ret="$?" @@ -1149,6 +1150,9 @@ _get() { if [ "$_ACME_CURL" ]; then _CURL="$_ACME_CURL" + if [ "$HTTPS_INSECURE" ]; then + _CURL="$_CURL --insecure " + fi if [ "$t" ]; then _CURL="$_CURL --connect-timeout $t" fi @@ -1168,6 +1172,9 @@ _get() { fi elif [ "$_ACME_WGET" ]; then _WGET="$_ACME_WGET" + if [ "$HTTPS_INSECURE" ]; then + _WGET="$_WGET --no-check-certificate " + fi if [ "$t" ]; then _WGET="$_WGET --timeout=$t" fi From a746139c53b26052b6eec79c16fd100204d4e04c Mon Sep 17 00:00:00 2001 From: neilpang Date: Tue, 22 Nov 2016 21:43:42 +0800 Subject: [PATCH 040/189] support OPENSSL_BIN and "--openssl-bin" --- acme.sh | 85 ++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 51 insertions(+), 34 deletions(-) diff --git a/acme.sh b/acme.sh index 6b63c9ed..674a428e 100755 --- a/acme.sh +++ b/acme.sh @@ -22,6 +22,8 @@ DEFAULT_ACCOUNT_EMAIL="" DEFAULT_ACCOUNT_KEY_LENGTH=2048 DEFAULT_DOMAIN_KEY_LENGTH=2048 +DEFAULT_OPENSSL_BIN="openssl" + STAGE_CA="https://acme-staging.api.letsencrypt.org" VTYPE_HTTP="http-01" @@ -95,11 +97,11 @@ _printargs() { _dlg_versions() { echo "Diagnosis versions: " - echo "openssl:" - if _exists openssl; then - openssl version 2>&1 + echo "openssl:$OPENSSL_BIN" + if _exists "$OPENSSL_BIN"; then + $OPENSSL_BIN version 2>&1 else - echo "openssl doesn't exists." + echo "$OPENSSL_BIN doesn't exists." fi echo "apache:" @@ -399,18 +401,18 @@ _getfile() { #Usage: multiline _base64() { if [ "$1" ]; then - openssl base64 -e + $OPENSSL_BIN base64 -e else - openssl base64 -e | tr -d '\r\n' + $OPENSSL_BIN base64 -e | tr -d '\r\n' fi } #Usage: multiline _dbase64() { if [ "$1" ]; then - openssl base64 -d -A + $OPENSSL_BIN base64 -d -A else - openssl base64 -d + $OPENSSL_BIN base64 -d fi } @@ -427,9 +429,9 @@ _digest() { if [ "$alg" = "sha256" ] || [ "$alg" = "sha1" ] || [ "$alg" = "md5" ]; then if [ "$outputhex" ]; then - openssl dgst -"$alg" -hex | cut -d = -f 2 | tr -d ' ' + $OPENSSL_BIN dgst -"$alg" -hex | cut -d = -f 2 | tr -d ' ' else - openssl dgst -"$alg" -binary | _base64 + $OPENSSL_BIN dgst -"$alg" -binary | _base64 fi else _err "$alg is not supported yet" @@ -452,9 +454,9 @@ _hmac() { if [ "$alg" = "sha256" ] || [ "$alg" = "sha1" ]; then if [ "$outputhex" ]; then - openssl dgst -"$alg" -mac HMAC -macopt "hexkey:$secret_hex" | cut -d = -f 2 | tr -d ' ' + $OPENSSL_BIN dgst -"$alg" -mac HMAC -macopt "hexkey:$secret_hex" | cut -d = -f 2 | tr -d ' ' else - openssl dgst -"$alg" -mac HMAC -macopt "hexkey:$secret_hex" -binary + $OPENSSL_BIN dgst -"$alg" -mac HMAC -macopt "hexkey:$secret_hex" -binary fi else _err "$alg is not supported yet" @@ -473,7 +475,7 @@ _sign() { return 1 fi - _sign_openssl="openssl dgst -sign $keyfile " + _sign_openssl="$OPENSSL_BIN dgst -sign $keyfile " if [ "$alg" = "sha256" ]; then _sign_openssl="$_sign_openssl -$alg" else @@ -484,7 +486,7 @@ _sign() { if grep "BEGIN RSA PRIVATE KEY" "$keyfile" >/dev/null 2>&1; then $_sign_openssl | _base64 elif grep "BEGIN EC PRIVATE KEY" "$keyfile" >/dev/null 2>&1; then - if ! _signedECText="$($_sign_openssl | openssl asn1parse -inform DER)"; then + if ! _signedECText="$($_sign_openssl | $OPENSSL_BIN asn1parse -inform DER)"; then _err "Sign failed: $_sign_openssl" _err "Key file: $keyfile" _err "Key content:$(wc -l <"$keyfile") lises" @@ -546,10 +548,10 @@ _createkey() { if _isEccKey "$length"; then _debug "Using ec name: $eccname" - openssl ecparam -name "$eccname" -genkey 2>/dev/null >"$f" + $OPENSSL_BIN ecparam -name "$eccname" -genkey 2>/dev/null >"$f" else _debug "Using RSA: $length" - openssl genrsa "$length" 2>/dev/null >"$f" + $OPENSSL_BIN genrsa "$length" 2>/dev/null >"$f" fi if [ "$?" != "0" ]; then @@ -634,7 +636,7 @@ _createcsr() { _csr_cn="$(_idn "$domain")" _debug2 _csr_cn "$_csr_cn" - openssl req -new -sha256 -key "$csrkey" -subj "/CN=$_csr_cn" -config "$csrconf" -out "$csr" + $OPENSSL_BIN req -new -sha256 -key "$csrkey" -subj "/CN=$_csr_cn" -config "$csrconf" -out "$csr" } #_signcsr key csr conf cert @@ -645,7 +647,7 @@ _signcsr() { cert="$4" _debug "_signcsr" - _msg="$(openssl x509 -req -days 365 -in "$csr" -signkey "$key" -extensions v3_req -extfile "$conf" -out "$cert" 2>&1)" + _msg="$($OPENSSL_BIN x509 -req -days 365 -in "$csr" -signkey "$key" -extensions v3_req -extfile "$conf" -out "$cert" 2>&1)" _ret="$?" _debug "$_msg" return $_ret @@ -658,7 +660,7 @@ _readSubjectFromCSR() { _usage "_readSubjectFromCSR mycsr.csr" return 1 fi - openssl req -noout -in "$_csrfile" -subject | _egrep_o "CN=.*" | cut -d = -f 2 | cut -d / -f 1 | tr -d '\n' + $OPENSSL_BIN req -noout -in "$_csrfile" -subject | _egrep_o "CN=.*" | cut -d = -f 2 | cut -d / -f 1 | tr -d '\n' } #_csrfile @@ -673,7 +675,7 @@ _readSubjectAltNamesFromCSR() { _csrsubj="$(_readSubjectFromCSR "$_csrfile")" _debug _csrsubj "$_csrsubj" - _dnsAltnames="$(openssl req -noout -text -in "$_csrfile" | grep "^ *DNS:.*" | tr -d ' \n')" + _dnsAltnames="$($OPENSSL_BIN req -noout -text -in "$_csrfile" | grep "^ *DNS:.*" | tr -d ' \n')" _debug _dnsAltnames "$_dnsAltnames" if _contains "$_dnsAltnames," "DNS:$_csrsubj,"; then @@ -694,7 +696,7 @@ _readKeyLengthFromCSR() { return 1 fi - _outcsr="$(openssl req -noout -text -in "$_csrfile")" + _outcsr="$($OPENSSL_BIN req -noout -text -in "$_csrfile")" if _contains "$_outcsr" "Public Key Algorithm: id-ecPublicKey"; then _debug "ECC CSR" echo "$_outcsr" | _egrep_o "^ *ASN1 OID:.*" | cut -d ':' -f 2 | tr -d ' ' @@ -748,9 +750,9 @@ toPkcs() { _initpath "$domain" "$_isEcc" if [ "$pfxPassword" ]; then - openssl pkcs12 -export -out "$CERT_PFX_PATH" -inkey "$CERT_KEY_PATH" -in "$CERT_PATH" -certfile "$CA_CERT_PATH" -password "pass:$pfxPassword" + $OPENSSL_BIN pkcs12 -export -out "$CERT_PFX_PATH" -inkey "$CERT_KEY_PATH" -in "$CERT_PATH" -certfile "$CA_CERT_PATH" -password "pass:$pfxPassword" else - openssl pkcs12 -export -out "$CERT_PFX_PATH" -inkey "$CERT_KEY_PATH" -in "$CERT_PATH" -certfile "$CA_CERT_PATH" + $OPENSSL_BIN pkcs12 -export -out "$CERT_PFX_PATH" -inkey "$CERT_KEY_PATH" -in "$CERT_PATH" -certfile "$CA_CERT_PATH" fi if [ "$?" = "0" ]; then @@ -912,7 +914,7 @@ _calcjwk() { if grep "BEGIN RSA PRIVATE KEY" "$keyfile" >/dev/null 2>&1; then _debug "RSA key" - pub_exp=$(openssl rsa -in "$keyfile" -noout -text | grep "^publicExponent:" | cut -d '(' -f 2 | cut -d 'x' -f 2 | cut -d ')' -f 1) + pub_exp=$($OPENSSL_BIN rsa -in "$keyfile" -noout -text | grep "^publicExponent:" | cut -d '(' -f 2 | cut -d 'x' -f 2 | cut -d ')' -f 1) if [ "${#pub_exp}" = "5" ]; then pub_exp=0$pub_exp fi @@ -921,7 +923,7 @@ _calcjwk() { e=$(echo "$pub_exp" | _h2b | _base64) _debug3 e "$e" - modulus=$(openssl rsa -in "$keyfile" -modulus -noout | cut -d '=' -f 2) + modulus=$($OPENSSL_BIN rsa -in "$keyfile" -modulus -noout | cut -d '=' -f 2) _debug3 modulus "$modulus" n="$(printf "%s" "$modulus" | _h2b | _base64 | _urlencode)" jwk='{"e": "'$e'", "kty": "RSA", "n": "'$n'"}' @@ -932,12 +934,12 @@ _calcjwk() { JWK_HEADERPLACE_PART2='", "alg": "RS256", "jwk": '$jwk'}' elif grep "BEGIN EC PRIVATE KEY" "$keyfile" >/dev/null 2>&1; then _debug "EC key" - crv="$(openssl ec -in "$keyfile" -noout -text 2>/dev/null | grep "^NIST CURVE:" | cut -d ":" -f 2 | tr -d " \r\n")" + crv="$($OPENSSL_BIN ec -in "$keyfile" -noout -text 2>/dev/null | grep "^NIST CURVE:" | cut -d ":" -f 2 | tr -d " \r\n")" _debug3 crv "$crv" if [ -z "$crv" ]; then _debug "Let's try ASN1 OID" - crv_oid="$(openssl ec -in "$keyfile" -noout -text 2>/dev/null | grep "^ASN1 OID:" | cut -d ":" -f 2 | tr -d " \r\n")" + crv_oid="$($OPENSSL_BIN ec -in "$keyfile" -noout -text 2>/dev/null | grep "^ASN1 OID:" | cut -d ":" -f 2 | tr -d " \r\n")" _debug3 crv_oid "$crv_oid" case "${crv_oid}" in "prime256v1") @@ -957,15 +959,15 @@ _calcjwk() { _debug3 crv "$crv" fi - pubi="$(openssl ec -in "$keyfile" -noout -text 2>/dev/null | grep -n pub: | cut -d : -f 1)" + pubi="$($OPENSSL_BIN ec -in "$keyfile" -noout -text 2>/dev/null | grep -n pub: | cut -d : -f 1)" pubi=$(_math "$pubi" + 1) _debug3 pubi "$pubi" - pubj="$(openssl ec -in "$keyfile" -noout -text 2>/dev/null | grep -n "ASN1 OID:" | cut -d : -f 1)" + pubj="$($OPENSSL_BIN ec -in "$keyfile" -noout -text 2>/dev/null | grep -n "ASN1 OID:" | cut -d : -f 1)" pubj=$(_math "$pubj" - 1) _debug3 pubj "$pubj" - pubtext="$(openssl ec -in "$keyfile" -noout -text 2>/dev/null | sed -n "$pubi,${pubj}p" | tr -d " \n\r")" + pubtext="$($OPENSSL_BIN ec -in "$keyfile" -noout -text 2>/dev/null | sed -n "$pubi,${pubj}p" | tr -d " \n\r")" _debug3 pubtext "$pubtext" xlen="$(printf "%s" "$pubtext" | tr -d ':' | wc -c)" @@ -1549,7 +1551,7 @@ _starttlsserver() { return 1 fi - __S_OPENSSL="openssl s_server -cert $TLS_CERT -key $TLS_KEY " + __S_OPENSSL="$OPENSSL_BIN s_server -cert $TLS_CERT -key $TLS_KEY " if [ "$opaddr" ]; then __S_OPENSSL="$__S_OPENSSL -accept $opaddr:$port" else @@ -1564,7 +1566,6 @@ _starttlsserver() { __S_OPENSSL="$__S_OPENSSL -6" fi - #start openssl _debug "$__S_OPENSSL" if [ "$DEBUG" ] && [ "$DEBUG" -ge "2" ]; then (printf "%s\r\n\r\n%s" "HTTP/1.1 200 OK" "$content" | $__S_OPENSSL -tlsextdebug) & @@ -1718,6 +1719,10 @@ _initpath() { CERT_HOME="$_DEFAULT_CERT_HOME" fi + if [ -z "$OPENSSL_BIN" ]; then + OPENSSL_BIN="$DEFAULT_OPENSSL_BIN" + fi + if [ -z "$1" ]; then return 0 fi @@ -3576,6 +3581,7 @@ _initconf() { #FORCE=1 # Force to issue cert #DEBUG=1 # Debug mode +#OPENSSL_BIN=openssl #USER_AGENT=\"$USER_AGENT\" @@ -3651,7 +3657,7 @@ _precheck() { fi fi - if ! _exists "openssl"; then + if ! _exists "$OPENSSL_BIN"; then _err "Please install openssl first." _err "We need openssl to generate keys." return 1 @@ -3979,6 +3985,7 @@ Parameters: --auto-upgrade [0|1] Valid for '--upgrade' command, indicating whether to upgrade automatically in future. --listen-v4 Force standalone/tls server to listen at ipv4. --listen-v6 Force standalone/tls server to listen at ipv6. + --openssl-bin Specifies a custom openssl bin location. " } @@ -4042,6 +4049,12 @@ _processAccountConf() { _saveaccountconf "ACCOUNT_EMAIL" "$ACCOUNT_EMAIL" fi + if [ "$_openssl_bin" ]; then + _saveaccountconf "OPENSSL_BIN" "$_openssl_bin" + elif [ "$OPENSSL_BIN" ] && [ "$OPENSSL_BIN" != "$DEFAULT_OPENSSL_BIN" ]; then + _saveaccountconf "OPENSSL_BIN" "$OPENSSL_BIN" + fi + if [ "$_auto_upgrade" ]; then _saveaccountconf "AUTO_UPGRADE" "$_auto_upgrade" elif [ "$AUTO_UPGRADE" ]; then @@ -4089,6 +4102,7 @@ _process() { _auto_upgrade="" _listen_v4="" _listen_v6="" + _openssl_bin="" while [ ${#} -gt 0 ]; do case "${1}" in @@ -4420,7 +4434,10 @@ _process() { _listen_v6="1" Le_Listen_V6="$_listen_v6" ;; - + --openssl-bin) + _openssl_bin="$2" + OPENSSL_BIN="$_openssl_bin" + ;; *) _err "Unknown parameter : $1" return 1 From 4441a6ff5953a2f2299331f060fa328787d92efd Mon Sep 17 00:00:00 2001 From: neilpang Date: Tue, 22 Nov 2016 21:59:40 +0800 Subject: [PATCH 041/189] support osx CI --- .travis.yml | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/.travis.yml b/.travis.yml index 8829e472..77017f3e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,24 +1,30 @@ language: shell sudo: required +os: + - linux + - osx + env: global: - SHFMT_URL=https://github.com/mvdan/sh/releases/download/v0.4.0/shfmt_v0.4.0_linux_amd64 addons: apt: - sources: - - debian-sid # Grab shellcheck from the Debian repo (o_O) packages: - shellcheck +before_install: + - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then brew update ; fi + - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install shellcheck; fi + script: - - curl -sSL $SHFMT_URL -o ~/shfmt - - chmod +x ~/shfmt - - ~/shfmt -l -w -i 2 . - - git diff --exit-code && echo "shfmt OK" - - shellcheck -V - - shellcheck -e SC2021,SC2126,SC2034 **/*.sh && echo "shellcheck OK" + - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then curl -sSL $SHFMT_URL -o ~/shfmt ; fi + - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; chmod +x ~/shfmt ; fi + - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; ~/shfmt -l -w -i 2 . ; fi + - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; git diff --exit-code && echo "shfmt OK" ; fi + - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; shellcheck -V ; fi + - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; shellcheck -e SC2021,SC2126,SC2034 **/*.sh && echo "shellcheck OK" ; fi - cd .. - git clone https://github.com/Neilpang/acmetest.git && cp -r acme.sh acmetest/ && cd acmetest - sudo ./letest.sh From 791c62ca645ef65c0fc00735dd425aa5ba0ef416 Mon Sep 17 00:00:00 2001 From: neilpang Date: Tue, 22 Nov 2016 22:02:10 +0800 Subject: [PATCH 042/189] fix ci --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 77017f3e..2a319042 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,6 +11,8 @@ env: addons: apt: + sources: + - debian-sid # Grab shellcheck from the Debian repo (o_O) packages: - shellcheck From 1fadae82c79a1c7f52f1a1b03075459441f9fb96 Mon Sep 17 00:00:00 2001 From: neilpang Date: Tue, 22 Nov 2016 22:03:59 +0800 Subject: [PATCH 043/189] fix ci --- .travis.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2a319042..5c388ba9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -21,12 +21,12 @@ before_install: - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install shellcheck; fi script: - - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then curl -sSL $SHFMT_URL -o ~/shfmt ; fi - - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; chmod +x ~/shfmt ; fi - - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; ~/shfmt -l -w -i 2 . ; fi - - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; git diff --exit-code && echo "shfmt OK" ; fi - - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; shellcheck -V ; fi - - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; shellcheck -e SC2021,SC2126,SC2034 **/*.sh && echo "shellcheck OK" ; fi + - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then then curl -sSL $SHFMT_URL -o ~/shfmt ; fi + - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then chmod +x ~/shfmt ; fi + - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then ~/shfmt -l -w -i 2 . ; fi + - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then git diff --exit-code && echo "shfmt OK" ; fi + - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then shellcheck -V ; fi + - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then shellcheck -e SC2021,SC2126,SC2034 **/*.sh && echo "shellcheck OK" ; fi - cd .. - git clone https://github.com/Neilpang/acmetest.git && cp -r acme.sh acmetest/ && cd acmetest - sudo ./letest.sh From bc18168662a34397a5ee45bbd57d70beb1c36434 Mon Sep 17 00:00:00 2001 From: neilpang Date: Tue, 22 Nov 2016 22:06:19 +0800 Subject: [PATCH 044/189] fix ci --- .travis.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 5c388ba9..90373171 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,9 +16,9 @@ addons: packages: - shellcheck -before_install: - - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then brew update ; fi - - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install shellcheck; fi +#before_install: +# - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update ; fi +# - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install shellcheck; fi script: - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then then curl -sSL $SHFMT_URL -o ~/shfmt ; fi From 41d804719f905bb7eaf7ee1cc6b748f9f92f126d Mon Sep 17 00:00:00 2001 From: neilpang Date: Tue, 22 Nov 2016 22:10:29 +0800 Subject: [PATCH 045/189] fix ci --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 90373171..ed54fd6e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -21,7 +21,7 @@ addons: # - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install shellcheck; fi script: - - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then then curl -sSL $SHFMT_URL -o ~/shfmt ; fi + - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then curl -sSL $SHFMT_URL -o ~/shfmt ; fi - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then chmod +x ~/shfmt ; fi - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then ~/shfmt -l -w -i 2 . ; fi - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then git diff --exit-code && echo "shfmt OK" ; fi From 28688488ff6c5841384bbe109b53c8fc4c734c20 Mon Sep 17 00:00:00 2001 From: neilpang Date: Tue, 22 Nov 2016 22:21:51 +0800 Subject: [PATCH 046/189] fix ci --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index ed54fd6e..53f21b37 100644 --- a/.travis.yml +++ b/.travis.yml @@ -21,6 +21,8 @@ addons: # - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install shellcheck; fi script: + - echo "TEST_LOCAL=$TEST_LOCAL" + - echo "NGROK_TOKEN=$(echo "$NGROK_TOKEN" | wc -c)" - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then curl -sSL $SHFMT_URL -o ~/shfmt ; fi - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then chmod +x ~/shfmt ; fi - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then ~/shfmt -l -w -i 2 . ; fi From 9eeae9ad7ea80dcb0e1f0d28e21b37c30891d0c9 Mon Sep 17 00:00:00 2001 From: neilpang Date: Tue, 22 Nov 2016 22:28:29 +0800 Subject: [PATCH 047/189] fix ch --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 53f21b37..8e00e251 100644 --- a/.travis.yml +++ b/.travis.yml @@ -31,7 +31,7 @@ script: - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then shellcheck -e SC2021,SC2126,SC2034 **/*.sh && echo "shellcheck OK" ; fi - cd .. - git clone https://github.com/Neilpang/acmetest.git && cp -r acme.sh acmetest/ && cd acmetest - - sudo ./letest.sh + - sudo NGROK_TOKEN="$NGROK_TOKEN" ./letest.sh matrix: From fa6234e417297108008c6af06f89ba88d4b3be23 Mon Sep 17 00:00:00 2001 From: neilpang Date: Tue, 22 Nov 2016 22:37:48 +0800 Subject: [PATCH 048/189] add NGROK_TOKEN_OSX --- .travis.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 8e00e251..e2b0a9d2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -31,7 +31,8 @@ script: - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then shellcheck -e SC2021,SC2126,SC2034 **/*.sh && echo "shellcheck OK" ; fi - cd .. - git clone https://github.com/Neilpang/acmetest.git && cp -r acme.sh acmetest/ && cd acmetest - - sudo NGROK_TOKEN="$NGROK_TOKEN" ./letest.sh + - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo NGROK_TOKEN="$NGROK_TOKEN" ./letest.sh ; fi + - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then sudo NGROK_TOKEN="$NGROK_TOKEN_OSX" ./letest.sh ; fi matrix: From cfbb3e86b39db37fafec005fbbb6acb53949edc9 Mon Sep 17 00:00:00 2001 From: neilpang Date: Tue, 22 Nov 2016 22:52:08 +0800 Subject: [PATCH 049/189] fix ci --- .travis.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index e2b0a9d2..84184d1d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,13 +16,14 @@ addons: packages: - shellcheck -#before_install: -# - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update ; fi -# - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install shellcheck; fi +before_install: + - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update ; fi + - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install openssl ; fi script: - echo "TEST_LOCAL=$TEST_LOCAL" - echo "NGROK_TOKEN=$(echo "$NGROK_TOKEN" | wc -c)" + - openssl version - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then curl -sSL $SHFMT_URL -o ~/shfmt ; fi - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then chmod +x ~/shfmt ; fi - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then ~/shfmt -l -w -i 2 . ; fi From d78c1f695e6f08a705b00f6e3349dc748f8d3a6c Mon Sep 17 00:00:00 2001 From: neilpang Date: Tue, 22 Nov 2016 23:10:41 +0800 Subject: [PATCH 050/189] fix ci --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 84184d1d..1482d2cc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,6 +19,7 @@ addons: before_install: - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update ; fi - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install openssl ; fi + - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then export PATH=/usr/local/bin:$PATH ; fi script: - echo "TEST_LOCAL=$TEST_LOCAL" From e55b2f4f8de195bb86314f6b3f21b92ee11f3fa6 Mon Sep 17 00:00:00 2001 From: neil Date: Wed, 23 Nov 2016 13:18:29 +0800 Subject: [PATCH 051/189] fix ci --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 1482d2cc..1d97bdb4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,7 +19,7 @@ addons: before_install: - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update ; fi - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install openssl ; fi - - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then export PATH=/usr/local/bin:$PATH ; fi + - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew link openssl --force ; fi script: - echo "TEST_LOCAL=$TEST_LOCAL" From 11e0ccdc91bc4077f46f057ef4eaf48c4ebfe672 Mon Sep 17 00:00:00 2001 From: neil Date: Wed, 23 Nov 2016 13:35:30 +0800 Subject: [PATCH 052/189] fix ci --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 1d97bdb4..122474df 100644 --- a/.travis.yml +++ b/.travis.yml @@ -20,6 +20,7 @@ before_install: - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update ; fi - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install openssl ; fi - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew link openssl --force ; fi + - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then export openssl="/usr/local/bin/openssl" ; fi script: - echo "TEST_LOCAL=$TEST_LOCAL" From 7fe19a030a84780e301f3b71d9f50c34928a2e57 Mon Sep 17 00:00:00 2001 From: neil Date: Wed, 23 Nov 2016 13:39:27 +0800 Subject: [PATCH 053/189] fix osx ci --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 122474df..7294a28f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -20,7 +20,7 @@ before_install: - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update ; fi - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install openssl ; fi - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew link openssl --force ; fi - - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then export openssl="/usr/local/bin/openssl" ; fi + - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then export OPENSSL_BIN="/usr/local/bin/openssl" ; fi script: - echo "TEST_LOCAL=$TEST_LOCAL" @@ -35,7 +35,7 @@ script: - cd .. - git clone https://github.com/Neilpang/acmetest.git && cp -r acme.sh acmetest/ && cd acmetest - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo NGROK_TOKEN="$NGROK_TOKEN" ./letest.sh ; fi - - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then sudo NGROK_TOKEN="$NGROK_TOKEN_OSX" ./letest.sh ; fi + - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then sudo NGROK_TOKEN="$NGROK_TOKEN_OSX" OPENSSL_BIN="/usr/local/bin/openssl" ./letest.sh ; fi matrix: From 340155e6a6bd7dc1d97d586f56f2a8dd101edfe6 Mon Sep 17 00:00:00 2001 From: neil Date: Wed, 23 Nov 2016 13:51:01 +0800 Subject: [PATCH 054/189] fix ci --- .travis.yml | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index 7294a28f..f4b52227 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,15 +17,14 @@ addons: - shellcheck before_install: - - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update ; fi - - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install openssl ; fi - - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew link openssl --force ; fi - - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then export OPENSSL_BIN="/usr/local/bin/openssl" ; fi + - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then + brew update && brew install openssl && brew link openssl --force + fi script: - echo "TEST_LOCAL=$TEST_LOCAL" - echo "NGROK_TOKEN=$(echo "$NGROK_TOKEN" | wc -c)" - - openssl version + - which openssl && openssl version - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then curl -sSL $SHFMT_URL -o ~/shfmt ; fi - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then chmod +x ~/shfmt ; fi - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then ~/shfmt -l -w -i 2 . ; fi @@ -35,7 +34,7 @@ script: - cd .. - git clone https://github.com/Neilpang/acmetest.git && cp -r acme.sh acmetest/ && cd acmetest - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo NGROK_TOKEN="$NGROK_TOKEN" ./letest.sh ; fi - - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then sudo NGROK_TOKEN="$NGROK_TOKEN_OSX" OPENSSL_BIN="/usr/local/bin/openssl" ./letest.sh ; fi + - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then sudo NGROK_TOKEN="$NGROK_TOKEN_OSX" ./letest.sh ; fi matrix: From 8dee328eae514bb55a1a373f17fd9f0bd11e982f Mon Sep 17 00:00:00 2001 From: neil Date: Wed, 23 Nov 2016 13:53:44 +0800 Subject: [PATCH 055/189] fix ci --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index f4b52227..1d61cc1f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,7 +18,7 @@ addons: before_install: - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then - brew update && brew install openssl && brew link openssl --force + brew update && brew install openssl && brew link openssl --force; fi script: From fa6e1746514bd23e57bfe5287cb363edad3abbfc Mon Sep 17 00:00:00 2001 From: neil Date: Wed, 23 Nov 2016 13:59:15 +0800 Subject: [PATCH 056/189] fix ci --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 1d61cc1f..7afbc90d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,7 +16,7 @@ addons: packages: - shellcheck -before_install: +install: - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update && brew install openssl && brew link openssl --force; fi From 8a09dc1b9be9b252660a7b7f3781e0ce4b17fe37 Mon Sep 17 00:00:00 2001 From: neil Date: Wed, 23 Nov 2016 18:50:34 +0800 Subject: [PATCH 057/189] fix ci --- .travis.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.travis.yml b/.travis.yml index 7afbc90d..e3063963 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,6 +19,10 @@ addons: install: - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update && brew install openssl && brew link openssl --force; + #we must reload PATH to make the new openssl live + _old_path="$PATH"; + export PATH=; + export PATH="$_old_path"; fi script: From 7cbe31baad614d5098e58e5f036955a60bd0d527 Mon Sep 17 00:00:00 2001 From: neil Date: Wed, 23 Nov 2016 18:51:49 +0800 Subject: [PATCH 058/189] fix ci --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index e3063963..811e59c5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,7 +19,6 @@ addons: install: - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update && brew install openssl && brew link openssl --force; - #we must reload PATH to make the new openssl live _old_path="$PATH"; export PATH=; export PATH="$_old_path"; From 10a6aec9982cc9326012f3de415410c51f1be93a Mon Sep 17 00:00:00 2001 From: neilpang Date: Wed, 23 Nov 2016 19:48:14 +0800 Subject: [PATCH 059/189] fix ci --- .travis.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 811e59c5..38fb496a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -20,7 +20,8 @@ install: - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update && brew install openssl && brew link openssl --force; _old_path="$PATH"; - export PATH=; + export PATH=""; + openssl version 2>&1 || true export PATH="$_old_path"; fi From 2ffab66d97ff6e5a0f7c23e1c6565d7acc923b07 Mon Sep 17 00:00:00 2001 From: neilpang Date: Wed, 23 Nov 2016 20:01:40 +0800 Subject: [PATCH 060/189] fix ci --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 38fb496a..5cadb562 100644 --- a/.travis.yml +++ b/.travis.yml @@ -21,7 +21,7 @@ install: brew update && brew install openssl && brew link openssl --force; _old_path="$PATH"; export PATH=""; - openssl version 2>&1 || true + openssl version 2>&1 || true; export PATH="$_old_path"; fi From a205762bf092e107f5f00f2831be4a17dcef5006 Mon Sep 17 00:00:00 2001 From: neilpang Date: Wed, 23 Nov 2016 20:21:43 +0800 Subject: [PATCH 061/189] fix ci --- .travis.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 5cadb562..27847a19 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,7 +18,11 @@ addons: install: - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then - brew update && brew install openssl && brew link openssl --force; + brew update && brew install openssl; + brew info openssl; + ln -s /usr/local/opt/openssl/lib/libcrypto.1.0.0.dylib /usr/local/lib/; + ln -s /usr/local/opt/openssl/lib/libssl.1.0.0.dylib /usr/local/lib/; + ln -s /usr/local/Cellar/openssl/1.0.2j/bin/openssl openssl; _old_path="$PATH"; export PATH=""; openssl version 2>&1 || true; From 670cb9d223ace2baa0e73391873fc1fd1f24d52e Mon Sep 17 00:00:00 2001 From: neilpang Date: Wed, 23 Nov 2016 20:35:47 +0800 Subject: [PATCH 062/189] fix ci --- .travis.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 27847a19..40a2019f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -22,8 +22,9 @@ install: brew info openssl; ln -s /usr/local/opt/openssl/lib/libcrypto.1.0.0.dylib /usr/local/lib/; ln -s /usr/local/opt/openssl/lib/libssl.1.0.0.dylib /usr/local/lib/; - ln -s /usr/local/Cellar/openssl/1.0.2j/bin/openssl openssl; + ln -s /usr/local/Cellar/openssl/1.0.2j/bin/openssl /usr/local/openssl; _old_path="$PATH"; + echo "PATH=$PATH" export PATH=""; openssl version 2>&1 || true; export PATH="$_old_path"; From d2aa3318388f7ed7900ea08845dbbc2c9beed395 Mon Sep 17 00:00:00 2001 From: neilpang Date: Wed, 23 Nov 2016 20:46:11 +0800 Subject: [PATCH 063/189] fix ci --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 40a2019f..8659ecd1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -26,7 +26,7 @@ install: _old_path="$PATH"; echo "PATH=$PATH" export PATH=""; - openssl version 2>&1 || true; + /usr/local/openssl version 2>&1 || true; export PATH="$_old_path"; fi @@ -43,7 +43,7 @@ script: - cd .. - git clone https://github.com/Neilpang/acmetest.git && cp -r acme.sh acmetest/ && cd acmetest - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo NGROK_TOKEN="$NGROK_TOKEN" ./letest.sh ; fi - - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then sudo NGROK_TOKEN="$NGROK_TOKEN_OSX" ./letest.sh ; fi + - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then sudo NGROK_TOKEN="$NGROK_TOKEN_OSX" OPENSSL_BIN="/usr/local/Cellar/openssl/1.0.2j/bin/openssl" ./letest.sh ; fi matrix: From 41266f05e93ff945526ef336a67c921c2d2b3dfe Mon Sep 17 00:00:00 2001 From: neilpang Date: Wed, 23 Nov 2016 21:01:47 +0800 Subject: [PATCH 064/189] fix CI --- .travis.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 8659ecd1..645032a3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -26,7 +26,8 @@ install: _old_path="$PATH"; echo "PATH=$PATH" export PATH=""; - /usr/local/openssl version 2>&1 || true; + export OPENSSL_BIN="/usr/local/openssl" + $OPENSSL_BIN version 2>&1 || true; export PATH="$_old_path"; fi @@ -43,7 +44,7 @@ script: - cd .. - git clone https://github.com/Neilpang/acmetest.git && cp -r acme.sh acmetest/ && cd acmetest - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo NGROK_TOKEN="$NGROK_TOKEN" ./letest.sh ; fi - - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then sudo NGROK_TOKEN="$NGROK_TOKEN_OSX" OPENSSL_BIN="/usr/local/Cellar/openssl/1.0.2j/bin/openssl" ./letest.sh ; fi + - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then sudo NGROK_TOKEN="$NGROK_TOKEN_OSX" OPENSSL_BIN="$OPENSSL_BIN" ./letest.sh ; fi matrix: From df86ff2191d01f34d32f5b3f593033836186b021 Mon Sep 17 00:00:00 2001 From: neilpang Date: Wed, 23 Nov 2016 21:17:51 +0800 Subject: [PATCH 065/189] fix ci --- .travis.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 645032a3..7e901528 100644 --- a/.travis.yml +++ b/.travis.yml @@ -24,9 +24,10 @@ install: ln -s /usr/local/opt/openssl/lib/libssl.1.0.0.dylib /usr/local/lib/; ln -s /usr/local/Cellar/openssl/1.0.2j/bin/openssl /usr/local/openssl; _old_path="$PATH"; - echo "PATH=$PATH" + echo "PATH=$PATH"; export PATH=""; - export OPENSSL_BIN="/usr/local/openssl" + export OPENSSL_BIN="/usr/local/openssl"; + openssl version 2>&1 || true; $OPENSSL_BIN version 2>&1 || true; export PATH="$_old_path"; fi From 74a7592b4b40468203451c0941086051b2113105 Mon Sep 17 00:00:00 2001 From: neilpang Date: Wed, 23 Nov 2016 22:07:24 +0800 Subject: [PATCH 066/189] fix ci, remove NGROK_TOKEN_OSX --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 7e901528..d70b7e49 100644 --- a/.travis.yml +++ b/.travis.yml @@ -45,7 +45,7 @@ script: - cd .. - git clone https://github.com/Neilpang/acmetest.git && cp -r acme.sh acmetest/ && cd acmetest - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo NGROK_TOKEN="$NGROK_TOKEN" ./letest.sh ; fi - - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then sudo NGROK_TOKEN="$NGROK_TOKEN_OSX" OPENSSL_BIN="$OPENSSL_BIN" ./letest.sh ; fi + - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then sudo NGROK_TOKEN="$NGROK_TOKEN" OPENSSL_BIN="$OPENSSL_BIN" ./letest.sh ; fi matrix: From 79db8dadddee3f5ebbe5f8c989ec78ee10fd249d Mon Sep 17 00:00:00 2001 From: neil Date: Thu, 24 Nov 2016 13:39:46 +0800 Subject: [PATCH 067/189] fix CI --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index d70b7e49..efa4790f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -33,6 +33,7 @@ install: fi script: + - echo "TRAVIS_PULL_REQUEST_BRANCH=$TRAVIS_PULL_REQUEST_BRANCH" - echo "TEST_LOCAL=$TEST_LOCAL" - echo "NGROK_TOKEN=$(echo "$NGROK_TOKEN" | wc -c)" - which openssl && openssl version From 72349507c4a57106d6d2864436787e5f31c37056 Mon Sep 17 00:00:00 2001 From: neil Date: Thu, 24 Nov 2016 13:45:00 +0800 Subject: [PATCH 068/189] fix ci --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index efa4790f..b7d92dac 100644 --- a/.travis.yml +++ b/.travis.yml @@ -33,7 +33,7 @@ install: fi script: - - echo "TRAVIS_PULL_REQUEST_BRANCH=$TRAVIS_PULL_REQUEST_BRANCH" + - env - echo "TEST_LOCAL=$TEST_LOCAL" - echo "NGROK_TOKEN=$(echo "$NGROK_TOKEN" | wc -c)" - which openssl && openssl version From 9e04222ee63016ab6675cf78dd4614cc31a8c45c Mon Sep 17 00:00:00 2001 From: neil Date: Thu, 24 Nov 2016 13:58:14 +0800 Subject: [PATCH 069/189] fix ci --- .travis.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index b7d92dac..94848c17 100644 --- a/.travis.yml +++ b/.travis.yml @@ -33,7 +33,6 @@ install: fi script: - - env - echo "TEST_LOCAL=$TEST_LOCAL" - echo "NGROK_TOKEN=$(echo "$NGROK_TOKEN" | wc -c)" - which openssl && openssl version @@ -45,8 +44,8 @@ script: - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then shellcheck -e SC2021,SC2126,SC2034 **/*.sh && echo "shellcheck OK" ; fi - cd .. - git clone https://github.com/Neilpang/acmetest.git && cp -r acme.sh acmetest/ && cd acmetest - - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo NGROK_TOKEN="$NGROK_TOKEN" ./letest.sh ; fi - - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then sudo NGROK_TOKEN="$NGROK_TOKEN" OPENSSL_BIN="$OPENSSL_BIN" ./letest.sh ; fi + - if [[ "$TRAVIS_OS_NAME" == "linux" ]] && [[ "$NGROK_TOKEN" ]]; then sudo NGROK_TOKEN="$NGROK_TOKEN" ./letest.sh ; fi + - if [[ "$TRAVIS_OS_NAME" == "osx" ]] && [[ "$NGROK_TOKEN" ]]; then sudo NGROK_TOKEN="$NGROK_TOKEN" OPENSSL_BIN="$OPENSSL_BIN" ./letest.sh ; fi matrix: From 8b1fb3cb0cd9d9beab1496c815a6b07ace5bb234 Mon Sep 17 00:00:00 2001 From: neil Date: Thu, 24 Nov 2016 14:13:23 +0800 Subject: [PATCH 070/189] Dev (#419) * fix CI * fix ci * fix ci --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index d70b7e49..94848c17 100644 --- a/.travis.yml +++ b/.travis.yml @@ -44,8 +44,8 @@ script: - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then shellcheck -e SC2021,SC2126,SC2034 **/*.sh && echo "shellcheck OK" ; fi - cd .. - git clone https://github.com/Neilpang/acmetest.git && cp -r acme.sh acmetest/ && cd acmetest - - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo NGROK_TOKEN="$NGROK_TOKEN" ./letest.sh ; fi - - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then sudo NGROK_TOKEN="$NGROK_TOKEN" OPENSSL_BIN="$OPENSSL_BIN" ./letest.sh ; fi + - if [[ "$TRAVIS_OS_NAME" == "linux" ]] && [[ "$NGROK_TOKEN" ]]; then sudo NGROK_TOKEN="$NGROK_TOKEN" ./letest.sh ; fi + - if [[ "$TRAVIS_OS_NAME" == "osx" ]] && [[ "$NGROK_TOKEN" ]]; then sudo NGROK_TOKEN="$NGROK_TOKEN" OPENSSL_BIN="$OPENSSL_BIN" ./letest.sh ; fi matrix: From be39ab32d1d1d4654a8bf053d0636b9737a271c1 Mon Sep 17 00:00:00 2001 From: baiyangliu Date: Thu, 24 Nov 2016 21:49:45 +0800 Subject: [PATCH 071/189] Add DNS API support for aliyun (#410) * Add DNS API support for aliyun * Update README.md * format * format * format * format... * format... * format * format * fix bug * fix bug * code format * code format * fix bug * just ok... * fix bug * fix bug * fix bug * change "echo" to "printf" * fix bug * code format * fix bug."head -c" in function _ali_nonce not supported by solaris * fix bug."head -c" in function _ali_nonce not supported by solaris * format * fix bug._ali_nonce not work on solaris * fix bug. _ali_nonce not work on solaris * fix bug. _ali_nonce not work on solaris * add aliyun.com to README.md --- README.md | 1 + dnsapi/README.md | 21 +++++- dnsapi/dns_ali.sh | 186 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 206 insertions(+), 2 deletions(-) create mode 100644 dnsapi/dns_ali.sh diff --git a/README.md b/README.md index 69348bf9..724f6eed 100644 --- a/README.md +++ b/README.md @@ -260,6 +260,7 @@ You don't have to do anything manually! 1. LuaDNS.com API 1. DNSMadeEasy.com API 1. nsupdate API +1. aliyun.com(阿里云) API **More APIs coming soon...** diff --git a/dnsapi/README.md b/dnsapi/README.md index 9a8730c9..ca9b08d9 100644 --- a/dnsapi/README.md +++ b/dnsapi/README.md @@ -201,7 +201,24 @@ acme.sh --issue --dns dns_aws -d example.com -d www.example.com The `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` will be saved in `~/.acme.sh/account.conf` and will be reused when needed. -# 11. Use custom API +## 11. Use Aliyun domain API to automatically issue cert + +First you need to login to your Aliyun account to get your API key. +[https://ak-console.aliyun.com/#/accesskey](https://ak-console.aliyun.com/#/accesskey) + +``` +export Ali_Key="sdfsdfsdfljlbjkljlkjsdfoiwje" +export Ali_Secret="jlsdflanljkljlfdsaklkjflsa" +``` + +Ok, let's issue a cert now: +``` +acme.sh --issue --dns dns_ali -d example.com -d www.example.com +``` + +The `Ali_Key` and `Ali_Secret` will be saved in `~/.acme.sh/account.conf` and will be reused when needed. + +# 12. Use custom API If your API is not supported yet, you can write your own DNS API. @@ -218,6 +235,6 @@ acme.sh --issue --dns dns_myapi -d example.com -d www.example.com For more details, please check our sample script: [dns_myapi.sh](dns_myapi.sh) -## 12. Use lexicon DNS API +## 13. Use lexicon DNS API https://github.com/Neilpang/acme.sh/wiki/How-to-use-lexicon-dns-api diff --git a/dnsapi/dns_ali.sh b/dnsapi/dns_ali.sh new file mode 100644 index 00000000..97b450a1 --- /dev/null +++ b/dnsapi/dns_ali.sh @@ -0,0 +1,186 @@ +#!/usr/bin/env sh + +Ali_API="https://alidns.aliyuncs.com/" + +#Ali_Key="LTqIA87hOKdjevsf5" +#Ali_Secret="0p5EYueFNq501xnCPzKNbx6K51qPH2" + +#Usage: dns_ali_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_ali_add() { + fulldomain=$1 + txtvalue=$2 + + if [ -z "$Ali_Key" ] || [ -z "$Ali_Secret" ]; then + Ali_Key="" + Ali_Secret="" + _err "You don't specify aliyun api key and secret yet." + return 1 + fi + + #save the api key and secret to the account conf file. + _saveaccountconf Ali_Key "$Ali_Key" + _saveaccountconf Ali_Secret "$Ali_Secret" + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + return 1 + fi + + _add_record_query "$_domain" "$_sub_domain" "$txtvalue" && _ali_rest "Add record" +} + +dns_ali_rm() { + fulldomain=$1 + _clean +} + +#################### Private functions bellow ################################## + +_get_root() { + domain=$1 + i=2 + p=1 + while true; do + h=$(printf "%s" "$domain" | cut -d . -f $i-100) + if [ -z "$h" ]; then + #not valid + return 1 + fi + + _describe_records_query "$h" + if ! _ali_rest "Get root" "ignore"; then + return 1 + fi + + if _contains "$response" "PageNumber"; then + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _debug _sub_domain "$_sub_domain" + _domain="$h" + _debug _domain "$_domain" + return 0 + fi + p="$i" + i=$(_math "$i" + 1) + done + return 1 +} + +_ali_rest() { + signature=$(printf "%s" "GET&%2F&$(_ali_urlencode "$query")" | _hmac "sha1" "$(_hex "$Ali_Secret&")" | _base64) + signature=$(_ali_urlencode "$signature") + url="$Ali_API?$query&Signature=$signature" + + if ! response="$(_get "$url")"; then + _err "Error <$1>" + return 1 + fi + + if [ -z "$2" ]; then + message="$(printf "%s" "$response" | _egrep_o "\"Message\":\"[^\"]*\"" | cut -d : -f 2 | tr -d \")" + if [ -n "$message" ]; then + _err "$message" + return 1 + fi + fi + + _debug2 response "$response" + return 0 +} + +_ali_urlencode() { + _str="$1" + _str_len=${#_str} + _u_i=1 + while [ "$_u_i" -le "$_str_len" ]; do + _str_c="$(printf "%s" "$_str" | cut -c "$_u_i")" + case $_str_c in [a-zA-Z0-9.~_-]) + printf "%s" "$_str_c" + ;; + *) + printf "%%%02X" "'$_str_c" + ;; + esac + _u_i="$(_math "$_u_i" + 1)" + done +} + +_ali_nonce() { + #_head_n 1 Date: Thu, 24 Nov 2016 22:27:14 +0800 Subject: [PATCH 072/189] fix for aliyun api --- acme.sh | 2 +- dnsapi/dns_ali.sh | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 674a428e..f695ded9 100755 --- a/acme.sh +++ b/acme.sh @@ -90,7 +90,7 @@ _printargs() { if [ -z "$2" ]; then printf -- "[$(date)] $1" else - printf -- "[$(date)] $1='$2'" + printf -- "%s" "[$(date)] $1='$2'" fi printf "\n" } diff --git a/dnsapi/dns_ali.sh b/dnsapi/dns_ali.sh index 97b450a1..30867219 100644 --- a/dnsapi/dns_ali.sh +++ b/dnsapi/dns_ali.sh @@ -26,6 +26,7 @@ dns_ali_add() { return 1 fi + _debug "Add record" _add_record_query "$_domain" "$_sub_domain" "$txtvalue" && _ali_rest "Add record" } From 93f3098aec5c47070236104d52d3a1f38f6b7a80 Mon Sep 17 00:00:00 2001 From: neilpang Date: Thu, 24 Nov 2016 22:36:21 +0800 Subject: [PATCH 073/189] minor --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index f695ded9..bcaa3014 100755 --- a/acme.sh +++ b/acme.sh @@ -2797,7 +2797,7 @@ issue() { status=$(echo "$response" | _egrep_o '"status":"[^"]*' | cut -d : -f 2 | tr -d '"') if [ "$status" = "valid" ]; then - _info "Success" + _info "$(__green Success)" _stopserver "$serverproc" serverproc="" _clearupwebbroot "$_currentRoot" "$removelevel" "$token" From 192ede5e64a5b63752dcf7b4c750c616f920db37 Mon Sep 17 00:00:00 2001 From: sjau Date: Thu, 24 Nov 2016 16:00:32 +0100 Subject: [PATCH 074/189] Added ISPConfig DNS API --- README.md | 1 + dnsapi/README.md | 26 ++++++- dnsapi/dns_ispconfig.sh | 158 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 183 insertions(+), 2 deletions(-) create mode 100755 dnsapi/dns_ispconfig.sh diff --git a/README.md b/README.md index 724f6eed..859e8fe3 100644 --- a/README.md +++ b/README.md @@ -261,6 +261,7 @@ You don't have to do anything manually! 1. DNSMadeEasy.com API 1. nsupdate API 1. aliyun.com(阿里云) API +1. ISPConfig 3.1 API **More APIs coming soon...** diff --git a/dnsapi/README.md b/dnsapi/README.md index ca9b08d9..dbd27fce 100644 --- a/dnsapi/README.md +++ b/dnsapi/README.md @@ -218,7 +218,29 @@ acme.sh --issue --dns dns_ali -d example.com -d www.example.com The `Ali_Key` and `Ali_Secret` will be saved in `~/.acme.sh/account.conf` and will be reused when needed. -# 12. Use custom API +## 12. Use ISPConfig 3.1 API + +This only works for ISPConfig 3.1 (and newer). + +Create a Remote User in the ISPConfig Control Panel. The Remote User must have access to at least `DNS zone functions` and `DNS txt functions`. + +``` +export ISPC_User="xxx" +export ISPC_Password="xxx" +export ISPC_Api="https://ispc.domain.tld:8080/remote/json.php" +export ISPC_Api_Insecure=1 +``` +If you have installed ISPConfig on a different port, then alter the 8080 accordingly. +Leaver ISPC_Api_Insecure set to 1 if you have not a valid ssl cert for your installation. Change it to 0 if you have a valid ssl cert. + +To issue a cert: +``` +acme.sh --issue --dns dns_ispconfig -d example.com -d www.example.com +``` + +The `ISPC_User`, `ISPC_Password`, `ISPC_Api`and `ISPC_Api_Insecure` will be saved in `~/.acme.sh/account.conf` and will be reused when needed. + +# 13. Use custom API If your API is not supported yet, you can write your own DNS API. @@ -235,6 +257,6 @@ acme.sh --issue --dns dns_myapi -d example.com -d www.example.com For more details, please check our sample script: [dns_myapi.sh](dns_myapi.sh) -## 13. Use lexicon DNS API +## 14. Use lexicon DNS API https://github.com/Neilpang/acme.sh/wiki/How-to-use-lexicon-dns-api diff --git a/dnsapi/dns_ispconfig.sh b/dnsapi/dns_ispconfig.sh new file mode 100755 index 00000000..eb55d356 --- /dev/null +++ b/dnsapi/dns_ispconfig.sh @@ -0,0 +1,158 @@ +#!/usr/bin/env sh + +# ISPConfig 3.1 API +# User must provide login data and URL to the ISPConfig installation incl. port. The remote user in ISPConfig must have access to: +# - DNS zone Functions +# - DNS txt Functions + +# Report bugs to https://github.com/sjau/acme.sh + +# Values to export: +# export ISPC_User="remoteUser" +# export ISPC_Password="remotePasword" +# export ISPC_Api="https://ispc.domain.tld:8080/remote/json.php" +# export ISPC_Api_Insecure=1 # Set 1 for insecure and 0 for secure -> difference is whether ssl cert is checked for validity (0) or whether it is just accepted (1) + +######## Public functions ##################### + +#Usage: dns_myapi_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_ispconfig_add() { + fulldomain="${1}" + txtvalue="${2}" + _ISPC_credentials && _ISPC_login && _ISPC_getZoneInfo && _ISPC_addTxt +} + +#Usage: dns_myapi_rm _acme-challenge.www.domain.com +dns_ispconfig_rm() { + fulldomain="${1}" + _ISPC_credentials && _ISPC_login && _ISPC_rmTxt +} + +#################### Private functions bellow ################################## + +_ISPC_credentials() { + if [ -z "${ISPC_User}" ] || [ -z "$ISPC_Password" ] || [ -z "${ISPC_Api}" ] || [ -z "${ISPC_Api_Insecure}" ]; then + ISPC_User="" + ISPC_Password="" + ISPC_Api="" + ISPC_Api_Insecure="" + _err "You haven't specified the ISPConfig Login data, URL and whether you want check the ISPC SSL cert. Please try again." + return 1 + else + _saveaccountconf ISPC_User "${ISPC_User}" + _saveaccountconf ISPC_Password "${ISPC_Password}" + _saveaccountconf ISPC_Api "${ISPC_Api}" + _saveaccountconf ISPC_Api_Insecure "${ISPC_Api_Insecure}" + # Set whether curl should use secure or insecure mode + HTTPS_INSECURE="${ISPC_Api_Insecure}" + fi +} + +_ISPC_login() { + _info "Getting Session ID" + curData="{\"username\":\"${ISPC_User}\",\"password\":\"${ISPC_Password}\",\"client_login\":false}" + curResult="$(_post "${curData}" "${ISPC_Api}?login")" + if _contains "${curResult}" '"code":"ok"'; then + sessionID=$(echo "${curResult}" | _egrep_o "response.*" | cut -d ':' -f 2 | cut -d '"' -f 2) + _info "Retrieved Session ID." + else + _err "Couldn't retrieve the Session ID." + return 1 + fi +} + +_ISPC_getZoneInfo() { + _info "Getting Zoneinfo" + zoneEnd=false + curZone="${fulldomain}" + while [ "${zoneEnd}" = false ]; do + # we can strip the first part of the fulldomain, since it's just the _acme-challenge string + curZone="${curZone#*.}" + # suffix . needed for zone -> domain.tld. + curData="{\"session_id\":\"${sessionID}\",\"primary_id\":[{\"origin\":\"${curZone}.\"}]}" + curResult="$(_post "${curData}" "${ISPC_Api}?dns_zone_get")" + if _contains "${curResult}" '"id":"'; then + zoneFound=true + zoneEnd=true + _info "Retrieved zone data." + fi + if [ "${curZone#*.}" != "$curZone" ]; then + _debug2 "$curZone still contains a '.' - so we can check next higher level" + else + zoneEnd=true + _err "Couldn't retrieve zone data." + return 1 + fi + done + if [ "${zoneFound}" ]; then + server_id=$(echo "${curResult}" | _egrep_o "server_id.*" | cut -d ':' -f 2 | cut -d '"' -f 2) + case "${server_id}" in + '' | *[!0-9]*) + _err "Server ID is not numeric." + return 1 + ;; + *) _info "Retrieved Server ID" ;; + esac + zone=$(echo "${curResult}" | _egrep_o "\"id.*" | cut -d ':' -f 2 | cut -d '"' -f 2) + case "${zone}" in + '' | *[!0-9]*) + _err "Zone ID is not numeric." + return 1 + ;; + *) _info "Retrieved Zone ID" ;; + esac + client_id=$(echo "${curResult}" | _egrep_o "sys_userid.*" | cut -d ':' -f 2 | cut -d '"' -f 2) + case "${client_id}" in + '' | *[!0-9]*) + _err "Client ID is not numeric." + return 1 + ;; + *) _info "Retrieved Client ID." ;; + esac + zoneFound="" + zoneEnd="" + fi +} + +_ISPC_addTxt() { + curSerial="$(date +%s)" + curStamp="$(date +'%F %T')" + params="\"server_id\":\"${server_id}\",\"zone\":\"${zone}\",\"name\":\"${fulldomain}.\",\"type\":\"txt\",\"data\":\"${txtvalue}\",\"aux\":\"0\",\"ttl\":\"3600\",\"active\":\"y\",\"stamp\":\"${curStamp}\",\"serial\":\"${curSerial}\"" + curData="{\"session_id\":\"${sessionID}\",\"client_id\":\"${client_id}\",\"params\":{${params}}}" + curResult="$(_post "${curData}" "${ISPC_Api}?dns_txt_add")" + record_id=$(echo "${curResult}" | _egrep_o "\"response.*" | cut -d ':' -f 2 | cut -d '"' -f 2) + case "${record_id}" in + '' | *[!0-9]*) + _err "Couldn't add ACME Challenge TXT record to zone." + return 1 + ;; + *) _info "Added ACME Challenge TXT record to zone." ;; + esac +} + +_ISPC_rmTxt() { + # Need to get the record ID. + curData="{\"session_id\":\"${sessionID}\",\"primary_id\":{\"name\":\"${fulldomain}.\",\"type\":\"TXT\"}}" + curResult="$(_post "${curData}" "${ISPC_Api}?dns_txt_get")" + if _contains "${curResult}" '"code":"ok"'; then + record_id=$(echo "${curResult}" | _egrep_o "\"id.*" | cut -d ':' -f 2 | cut -d '"' -f 2) + case "${record_id}" in + '' | *[!0-9]*) + _err "Record ID is not numeric." + return 1 + ;; + *) + unset IFS + _info "Retrieved Record ID." + curData="{\"session_id\":\"${sessionID}\",\"primary_id\":\"${record_id}\"}" + curResult="$(_post "${curData}" "${ISPC_Api}?dns_txt_delete")" + if _contains "${curResult}" '"code":"ok"'; then + _info "Removed ACME Challenge TXT record from zone." + else + _err "Couldn't remove ACME Challenge TXT record from zone." + return 1 + fi + ;; + esac + fi +} From 983f1f28ca273d4b4461cd9fb5a4211335ed9904 Mon Sep 17 00:00:00 2001 From: sjau Date: Thu, 24 Nov 2016 18:02:42 +0100 Subject: [PATCH 075/189] Fixed wrong zone getting JSON and added lots of debug info --- dnsapi/dns_ispconfig.sh | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/dnsapi/dns_ispconfig.sh b/dnsapi/dns_ispconfig.sh index eb55d356..315dd6ef 100755 --- a/dnsapi/dns_ispconfig.sh +++ b/dnsapi/dns_ispconfig.sh @@ -1,4 +1,4 @@ -#!/usr/bin/env sh +#!/usr/bin/env bash # ISPConfig 3.1 API # User must provide login data and URL to the ISPConfig installation incl. port. The remote user in ISPConfig must have access to: @@ -9,7 +9,7 @@ # Values to export: # export ISPC_User="remoteUser" -# export ISPC_Password="remotePasword" +# export ISPC_Password="remotePassword" # export ISPC_Api="https://ispc.domain.tld:8080/remote/json.php" # export ISPC_Api_Insecure=1 # Set 1 for insecure and 0 for secure -> difference is whether ssl cert is checked for validity (0) or whether it is just accepted (1) @@ -19,12 +19,14 @@ dns_ispconfig_add() { fulldomain="${1}" txtvalue="${2}" + _debug "Calling: dns_ispconfig_add() '${fulldomain}' '${txtvalue}'" _ISPC_credentials && _ISPC_login && _ISPC_getZoneInfo && _ISPC_addTxt } #Usage: dns_myapi_rm _acme-challenge.www.domain.com dns_ispconfig_rm() { fulldomain="${1}" + _debug "Calling: dns_ispconfig_rm() '${fulldomain}'" _ISPC_credentials && _ISPC_login && _ISPC_rmTxt } @@ -52,9 +54,12 @@ _ISPC_login() { _info "Getting Session ID" curData="{\"username\":\"${ISPC_User}\",\"password\":\"${ISPC_Password}\",\"client_login\":false}" curResult="$(_post "${curData}" "${ISPC_Api}?login")" + _debug "Calling _ISPC_login: '${curData}' '${ISPC_Api}?login'" + _debug "Result of _ISPC_login: '$curResult'" if _contains "${curResult}" '"code":"ok"'; then sessionID=$(echo "${curResult}" | _egrep_o "response.*" | cut -d ':' -f 2 | cut -d '"' -f 2) _info "Retrieved Session ID." + _debug "Session ID: '${sessionID}'" else _err "Couldn't retrieve the Session ID." return 1 @@ -69,12 +74,15 @@ _ISPC_getZoneInfo() { # we can strip the first part of the fulldomain, since it's just the _acme-challenge string curZone="${curZone#*.}" # suffix . needed for zone -> domain.tld. - curData="{\"session_id\":\"${sessionID}\",\"primary_id\":[{\"origin\":\"${curZone}.\"}]}" + curData="{\"session_id\":\"${sessionID}\",\"primary_id\":{\"origin\":\"${curZone}.\"}}" curResult="$(_post "${curData}" "${ISPC_Api}?dns_zone_get")" + _debug "Calling _ISPC_getZoneInfo: '${curData}' '${ISPC_Api}?login'" + _debug "Result of _ISPC_getZoneInfo: '$curResult'" if _contains "${curResult}" '"id":"'; then zoneFound=true zoneEnd=true _info "Retrieved zone data." + _debug "Zone data: '${curResult}'" fi if [ "${curZone#*.}" != "$curZone" ]; then _debug2 "$curZone still contains a '.' - so we can check next higher level" @@ -86,6 +94,7 @@ _ISPC_getZoneInfo() { done if [ "${zoneFound}" ]; then server_id=$(echo "${curResult}" | _egrep_o "server_id.*" | cut -d ':' -f 2 | cut -d '"' -f 2) + _debug "Server ID: '${server_id}'" case "${server_id}" in '' | *[!0-9]*) _err "Server ID is not numeric." @@ -94,6 +103,7 @@ _ISPC_getZoneInfo() { *) _info "Retrieved Server ID" ;; esac zone=$(echo "${curResult}" | _egrep_o "\"id.*" | cut -d ':' -f 2 | cut -d '"' -f 2) + _debug "Zone: '${zone}'" case "${zone}" in '' | *[!0-9]*) _err "Zone ID is not numeric." @@ -102,6 +112,7 @@ _ISPC_getZoneInfo() { *) _info "Retrieved Zone ID" ;; esac client_id=$(echo "${curResult}" | _egrep_o "sys_userid.*" | cut -d ':' -f 2 | cut -d '"' -f 2) + _debug "Client ID: '${client_id}'" case "${client_id}" in '' | *[!0-9]*) _err "Client ID is not numeric." @@ -120,7 +131,10 @@ _ISPC_addTxt() { params="\"server_id\":\"${server_id}\",\"zone\":\"${zone}\",\"name\":\"${fulldomain}.\",\"type\":\"txt\",\"data\":\"${txtvalue}\",\"aux\":\"0\",\"ttl\":\"3600\",\"active\":\"y\",\"stamp\":\"${curStamp}\",\"serial\":\"${curSerial}\"" curData="{\"session_id\":\"${sessionID}\",\"client_id\":\"${client_id}\",\"params\":{${params}}}" curResult="$(_post "${curData}" "${ISPC_Api}?dns_txt_add")" + _debug "Calling _ISPC_addTxt: '${curData}' '${ISPC_Api}?dns_txt_add'" + _debug "Result of _ISPC_addTxt: '$curResult'" record_id=$(echo "${curResult}" | _egrep_o "\"response.*" | cut -d ':' -f 2 | cut -d '"' -f 2) + _debug "Record ID: '${record_id}'" case "${record_id}" in '' | *[!0-9]*) _err "Couldn't add ACME Challenge TXT record to zone." @@ -134,8 +148,11 @@ _ISPC_rmTxt() { # Need to get the record ID. curData="{\"session_id\":\"${sessionID}\",\"primary_id\":{\"name\":\"${fulldomain}.\",\"type\":\"TXT\"}}" curResult="$(_post "${curData}" "${ISPC_Api}?dns_txt_get")" + _debug "Calling _ISPC_rmTxt: '${curData}' '${ISPC_Api}?dns_txt_get'" + _debug "Result of _ISPC_rmTxt: '$curResult'" if _contains "${curResult}" '"code":"ok"'; then record_id=$(echo "${curResult}" | _egrep_o "\"id.*" | cut -d ':' -f 2 | cut -d '"' -f 2) + _debug "Record ID: '${record_id}'" case "${record_id}" in '' | *[!0-9]*) _err "Record ID is not numeric." @@ -146,6 +163,8 @@ _ISPC_rmTxt() { _info "Retrieved Record ID." curData="{\"session_id\":\"${sessionID}\",\"primary_id\":\"${record_id}\"}" curResult="$(_post "${curData}" "${ISPC_Api}?dns_txt_delete")" + _debug "Calling _ISPC_rmTxt: '${curData}' '${ISPC_Api}?dns_txt_delete'" + _debug "Result of _ISPC_rmTxt: '$curResult'" if _contains "${curResult}" '"code":"ok"'; then _info "Removed ACME Challenge TXT record from zone." else From 5eed02f7e927742facd9d938a6e692a771271377 Mon Sep 17 00:00:00 2001 From: sjau Date: Fri, 25 Nov 2016 04:50:05 +0100 Subject: [PATCH 076/189] Changing shebang back to sh --- dnsapi/dns_ispconfig.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_ispconfig.sh b/dnsapi/dns_ispconfig.sh index 315dd6ef..789b6267 100755 --- a/dnsapi/dns_ispconfig.sh +++ b/dnsapi/dns_ispconfig.sh @@ -1,4 +1,4 @@ -#!/usr/bin/env bash +#!/usr/bin/env sh # ISPConfig 3.1 API # User must provide login data and URL to the ISPConfig installation incl. port. The remote user in ISPConfig must have access to: From 58bb94d7c73028441a3dfde7675a2150ae423685 Mon Sep 17 00:00:00 2001 From: neil Date: Fri, 25 Nov 2016 22:20:54 +0800 Subject: [PATCH 077/189] Update README.md --- dnsapi/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/README.md b/dnsapi/README.md index dbd27fce..c4245701 100644 --- a/dnsapi/README.md +++ b/dnsapi/README.md @@ -240,7 +240,7 @@ acme.sh --issue --dns dns_ispconfig -d example.com -d www.example.com The `ISPC_User`, `ISPC_Password`, `ISPC_Api`and `ISPC_Api_Insecure` will be saved in `~/.acme.sh/account.conf` and will be reused when needed. -# 13. Use custom API +# Use custom API If your API is not supported yet, you can write your own DNS API. @@ -257,6 +257,6 @@ acme.sh --issue --dns dns_myapi -d example.com -d www.example.com For more details, please check our sample script: [dns_myapi.sh](dns_myapi.sh) -## 14. Use lexicon DNS API +# Use lexicon DNS API https://github.com/Neilpang/acme.sh/wiki/How-to-use-lexicon-dns-api From 569d6c557c789a9ac749c9fe1b45ee606528fb23 Mon Sep 17 00:00:00 2001 From: neilpang Date: Tue, 29 Nov 2016 00:11:02 +0800 Subject: [PATCH 078/189] fix https://github.com/Neilpang/acme.sh/issues/426 --- acme.sh | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/acme.sh b/acme.sh index bcaa3014..d886bfee 100755 --- a/acme.sh +++ b/acme.sh @@ -87,10 +87,13 @@ __red() { } _printargs() { + if [ -z "$NO_TIMESTAMP" ] || [ "$NO_TIMESTAMP" = "0" ]; then + printf -- "%s" "[$(date)] " + fi if [ -z "$2" ]; then - printf -- "[$(date)] $1" + printf -- "%s" "$1" else - printf -- "%s" "[$(date)] $1='$2'" + printf -- "%s" "$1='$2'" fi printf "\n" } @@ -131,7 +134,9 @@ _info() { _err() { _log "$@" - printf -- "[$(date)] " >&2 + if [ -z "$NO_TIMESTAMP" ] || [ "$NO_TIMESTAMP" = "0" ]; then + printf -- "%s" "[$(date)] " >&2 + fi if [ -z "$2" ]; then __red "$1" >&2 else @@ -3580,7 +3585,7 @@ _initconf() { #STAGE=1 # Use the staging api #FORCE=1 # Force to issue cert #DEBUG=1 # Debug mode - +#NO_TIMESTAMP=1 #OPENSSL_BIN=openssl #USER_AGENT=\"$USER_AGENT\" From b43416af97b3cc48625773a3635d694e2e923198 Mon Sep 17 00:00:00 2001 From: neilpang Date: Fri, 2 Dec 2016 20:24:12 +0800 Subject: [PATCH 079/189] do not use script home --- acme.sh | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/acme.sh b/acme.sh index d886bfee..c7c9f9f0 100755 --- a/acme.sh +++ b/acme.sh @@ -1612,14 +1612,14 @@ __initHome() { fi fi - if [ -z "$LE_WORKING_DIR" ]; then - if [ -f "$DEFAULT_INSTALL_HOME/account.conf" ]; then - _debug "It seems that $PROJECT_NAME is already installed in $DEFAULT_INSTALL_HOME" - LE_WORKING_DIR="$DEFAULT_INSTALL_HOME" - else - LE_WORKING_DIR="$_SCRIPT_HOME" - fi - fi +# if [ -z "$LE_WORKING_DIR" ]; then +# if [ -f "$DEFAULT_INSTALL_HOME/account.conf" ]; then +# _debug "It seems that $PROJECT_NAME is already installed in $DEFAULT_INSTALL_HOME" +# LE_WORKING_DIR="$DEFAULT_INSTALL_HOME" +# else +# LE_WORKING_DIR="$_SCRIPT_HOME" +# fi +# fi if [ -z "$LE_WORKING_DIR" ]; then _debug "Using default home:$DEFAULT_INSTALL_HOME" From 219e9115c03723d01dbb2eca6c26797875529842 Mon Sep 17 00:00:00 2001 From: neilpang Date: Fri, 2 Dec 2016 20:30:52 +0800 Subject: [PATCH 080/189] fix format --- acme.sh | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/acme.sh b/acme.sh index c7c9f9f0..a669aba1 100755 --- a/acme.sh +++ b/acme.sh @@ -1612,14 +1612,14 @@ __initHome() { fi fi -# if [ -z "$LE_WORKING_DIR" ]; then -# if [ -f "$DEFAULT_INSTALL_HOME/account.conf" ]; then -# _debug "It seems that $PROJECT_NAME is already installed in $DEFAULT_INSTALL_HOME" -# LE_WORKING_DIR="$DEFAULT_INSTALL_HOME" -# else -# LE_WORKING_DIR="$_SCRIPT_HOME" -# fi -# fi + # if [ -z "$LE_WORKING_DIR" ]; then + # if [ -f "$DEFAULT_INSTALL_HOME/account.conf" ]; then + # _debug "It seems that $PROJECT_NAME is already installed in $DEFAULT_INSTALL_HOME" + # LE_WORKING_DIR="$DEFAULT_INSTALL_HOME" + # else + # LE_WORKING_DIR="$_SCRIPT_HOME" + # fi + # fi if [ -z "$LE_WORKING_DIR" ]; then _debug "Using default home:$DEFAULT_INSTALL_HOME" From 048e5210f751b88104fb4455644e6d09815b0d18 Mon Sep 17 00:00:00 2001 From: neil Date: Fri, 2 Dec 2016 21:12:20 +0800 Subject: [PATCH 081/189] do not use script home * do not use script home * fix format --- acme.sh | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/acme.sh b/acme.sh index d886bfee..a669aba1 100755 --- a/acme.sh +++ b/acme.sh @@ -1612,14 +1612,14 @@ __initHome() { fi fi - if [ -z "$LE_WORKING_DIR" ]; then - if [ -f "$DEFAULT_INSTALL_HOME/account.conf" ]; then - _debug "It seems that $PROJECT_NAME is already installed in $DEFAULT_INSTALL_HOME" - LE_WORKING_DIR="$DEFAULT_INSTALL_HOME" - else - LE_WORKING_DIR="$_SCRIPT_HOME" - fi - fi + # if [ -z "$LE_WORKING_DIR" ]; then + # if [ -f "$DEFAULT_INSTALL_HOME/account.conf" ]; then + # _debug "It seems that $PROJECT_NAME is already installed in $DEFAULT_INSTALL_HOME" + # LE_WORKING_DIR="$DEFAULT_INSTALL_HOME" + # else + # LE_WORKING_DIR="$_SCRIPT_HOME" + # fi + # fi if [ -z "$LE_WORKING_DIR" ]; then _debug "Using default home:$DEFAULT_INSTALL_HOME" From d69f0289caf15b1b8b8516a92b18ea68087024bc Mon Sep 17 00:00:00 2001 From: neilpang Date: Sun, 4 Dec 2016 12:22:36 +0800 Subject: [PATCH 082/189] fix issue when there is no one records in the domain. --- dnsapi/dns_cx.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_cx.sh b/dnsapi/dns_cx.sh index 0caf0c02..91556c67 100755 --- a/dnsapi/dns_cx.sh +++ b/dnsapi/dns_cx.sh @@ -69,11 +69,11 @@ existing_records() { _debug "Getting txt records" root=$1 sub=$2 - + count=0 if ! _rest GET "record/$_domain_id?:domain_id?host_id=0&offset=0&row_num=100"; then return 1 fi - count=0 + seg=$(printf "%s\n" "$response" | _egrep_o "{[^\{]*host\":\"$_sub_domain\"[^\}]*\}") _debug seg "$seg" if [ -z "$seg" ]; then From c572ce946bdbd56572d36d73a266a163e4396b54 Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 4 Dec 2016 13:46:07 +0800 Subject: [PATCH 083/189] Dev (#434) * do not use script home * fix format * fix issue when there is no one records in the domain. --- dnsapi/dns_cx.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_cx.sh b/dnsapi/dns_cx.sh index 0caf0c02..91556c67 100755 --- a/dnsapi/dns_cx.sh +++ b/dnsapi/dns_cx.sh @@ -69,11 +69,11 @@ existing_records() { _debug "Getting txt records" root=$1 sub=$2 - + count=0 if ! _rest GET "record/$_domain_id?:domain_id?host_id=0&offset=0&row_num=100"; then return 1 fi - count=0 + seg=$(printf "%s\n" "$response" | _egrep_o "{[^\{]*host\":\"$_sub_domain\"[^\}]*\}") _debug seg "$seg" if [ -z "$seg" ]; then From 5be3f22d06cd62397395b0de4e76f3f1d3c27405 Mon Sep 17 00:00:00 2001 From: neilpang Date: Sun, 4 Dec 2016 14:45:26 +0800 Subject: [PATCH 084/189] fix issue --- dnsapi/dns_cx.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dnsapi/dns_cx.sh b/dnsapi/dns_cx.sh index 91556c67..ff1c943d 100755 --- a/dnsapi/dns_cx.sh +++ b/dnsapi/dns_cx.sh @@ -74,7 +74,7 @@ existing_records() { return 1 fi - seg=$(printf "%s\n" "$response" | _egrep_o "{[^\{]*host\":\"$_sub_domain\"[^\}]*\}") + seg=$(printf "%s\n" "$response" | _egrep_o '{[^{]*host":"'"$_sub_domain"'"[^}]*\}') _debug seg "$seg" if [ -z "$seg" ]; then return 0 @@ -82,7 +82,7 @@ existing_records() { if printf "%s" "$response" | grep '"type":"TXT"' >/dev/null; then count=1 - record_id=$(printf "%s\n" "$seg" | _egrep_o "\"record_id\":\"[^\"]*\"" | cut -d : -f 2 | tr -d \") + record_id=$(printf "%s\n" "$seg" | _egrep_o '"record_id":"[^"]*"' | cut -d : -f 2 | tr -d \" | _head_n 1) _debug record_id "$record_id" return 0 fi @@ -170,7 +170,7 @@ _get_root() { _rest() { m=$1 ep="$2" - _debug "$ep" + _debug ep "$ep" url="$REST_API/$ep" _debug url "$url" From e4468562d273863489558d4c89549b87e43c23eb Mon Sep 17 00:00:00 2001 From: neilpang Date: Sun, 4 Dec 2016 21:24:38 +0800 Subject: [PATCH 085/189] fix cx --- dnsapi/dns_cx.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_cx.sh b/dnsapi/dns_cx.sh index 0c3d5c80..4117d29d 100755 --- a/dnsapi/dns_cx.sh +++ b/dnsapi/dns_cx.sh @@ -147,7 +147,7 @@ _get_root() { fi if _contains "$response" "$h."; then - seg=$(printf "%s" "$response" | _egrep_o '{[^{]*"'"$h"'."[^}]*}') + seg=$(echo "$response" | _egrep_o '{[^{]*"'"$h"'."[^}]*}') _debug seg "$seg" _domain_id=$(printf "%s" "$seg" | _egrep_o "\"id\":\"[^\"]*\"" | cut -d : -f 2 | tr -d \") _debug _domain_id "$_domain_id" From a62706678e65f28deebe2ac58a7b19483089aaed Mon Sep 17 00:00:00 2001 From: neilpang Date: Sun, 4 Dec 2016 21:33:36 +0800 Subject: [PATCH 086/189] fix for solaris --- dnsapi/dns_cx.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_cx.sh b/dnsapi/dns_cx.sh index 4117d29d..602a5012 100755 --- a/dnsapi/dns_cx.sh +++ b/dnsapi/dns_cx.sh @@ -147,9 +147,9 @@ _get_root() { fi if _contains "$response" "$h."; then - seg=$(echo "$response" | _egrep_o '{[^{]*"'"$h"'."[^}]*}') + seg=$(printf "%s\n" "$response" | _egrep_o '{[^{]*"'"$h"'."[^}]*}') _debug seg "$seg" - _domain_id=$(printf "%s" "$seg" | _egrep_o "\"id\":\"[^\"]*\"" | cut -d : -f 2 | tr -d \") + _domain_id=$(printf "%s\n" "$seg" | _egrep_o "\"id\":\"[^\"]*\"" | cut -d : -f 2 | tr -d \") _debug _domain_id "$_domain_id" if [ "$_domain_id" ]; then _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) From 8379f015d7e2280b4861478a086672d89dcabb37 Mon Sep 17 00:00:00 2001 From: kookxiang Date: Sat, 3 Dec 2016 23:32:50 +0800 Subject: [PATCH 087/189] Finish dns_cx_rm() method --- dnsapi/dns_cx.sh | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/dnsapi/dns_cx.sh b/dnsapi/dns_cx.sh index 602a5012..86a7b2d0 100755 --- a/dnsapi/dns_cx.sh +++ b/dnsapi/dns_cx.sh @@ -58,7 +58,15 @@ dns_cx_add() { #fulldomain dns_cx_rm() { fulldomain=$1 - + REST_API="$CX_Api" + if _get_root "$fulldomain"; then + record_id="" + existing_records "$_domain" "$_sub_domain" + if ! [ "$record_id" = "" ]; then + _rest DELETE "record/$record_id/$_domain_id" "{}" + _info "Deleted record ${fulldomain}" + fi + fi } #usage: root sub From c12be766e92ec7cd97048f6ffbb8559c6e730ac7 Mon Sep 17 00:00:00 2001 From: Marcello Barnaba Date: Sun, 4 Dec 2016 20:10:33 +0100 Subject: [PATCH 088/189] Fix Route53 API consumer Ignoring the Chthlulu argument :smiley:, Route53 returns its XML all on one line, making not possible to grep the hosted zone record with egrep/sed. This change splits the XML in multiple lines, so that parsing can succeed. --- dnsapi/dns_aws.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_aws.sh b/dnsapi/dns_aws.sh index 15bf7b14..2c58754d 100644 --- a/dnsapi/dns_aws.sh +++ b/dnsapi/dns_aws.sh @@ -72,7 +72,7 @@ _get_root() { fi if _contains "$response" "$h."; then - hostedzone="$(echo "$response" | _egrep_o ".*$h..*")" + hostedzone="$(echo "$response" | sed 's//\n&/g' | _egrep_o ".*$h..*")" _debug hostedzone "$hostedzone" if [ -z "$hostedzone" ]; then _err "Error, can not get hostedzone." From eea52a5fa632eb87943cf1d84f880cf0043291a8 Mon Sep 17 00:00:00 2001 From: neilpang Date: Tue, 6 Dec 2016 13:55:06 +0800 Subject: [PATCH 089/189] update api template --- dnsapi/dns_myapi.sh | 38 +++++++++----------------------------- 1 file changed, 9 insertions(+), 29 deletions(-) diff --git a/dnsapi/dns_myapi.sh b/dnsapi/dns_myapi.sh index 813a2ed1..f3e275d9 100755 --- a/dnsapi/dns_myapi.sh +++ b/dnsapi/dns_myapi.sh @@ -5,48 +5,28 @@ #So, here must be a method dns_myapi_add() #Which will be called by acme.sh to add the txt record to your api system. #returns 0 means success, otherwise error. - +# +#Author: Neilpang +#Report Bugs here: https://github.com/Neilpang/acme.sh +# ######## Public functions ##################### #Usage: dns_myapi_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" dns_myapi_add() { fulldomain=$1 txtvalue=$2 + _info "Using myapi" + _debug fulldomain "$fulldomain" + _debug txtvalue "$txtvalue" _err "Not implemented!" return 1 } -#fulldomain +#Usage: fulldomain +#Remove the txt record afer validation. dns_myapi_rm() { fulldomain=$1 } #################### Private functions bellow ################################## -_info() { - if [ -z "$2" ]; then - echo "[$(date)] $1" - else - echo "[$(date)] $1='$2'" - fi -} - -_err() { - _info "$@" >&2 - return 1 -} - -_debug() { - if [ -z "$DEBUG" ]; then - return - fi - _err "$@" - return 0 -} - -_debug2() { - if [ "$DEBUG" ] && [ "$DEBUG" -ge "2" ]; then - _debug "$@" - fi - return -} From e2d494321cc7ca58d423f1862c078f2549117fbb Mon Sep 17 00:00:00 2001 From: neilpang Date: Tue, 6 Dec 2016 14:02:31 +0800 Subject: [PATCH 090/189] update template --- .github/PULL_REQUEST_TEMPLATE.md | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 2df6e9c4..29ea4e42 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,14 +1,9 @@ \ No newline at end of file From 21f201e37148c7ef2385621ca7b994388e9ab8d3 Mon Sep 17 00:00:00 2001 From: neilpang Date: Tue, 6 Dec 2016 14:58:36 +0800 Subject: [PATCH 091/189] support cloudflare rm function --- acme.sh | 5 +++-- dnsapi/dns_cf.sh | 43 ++++++++++++++++++++++++++++++++++++++----- dnsapi/dns_myapi.sh | 7 +++++-- 3 files changed, 46 insertions(+), 9 deletions(-) diff --git a/acme.sh b/acme.sh index a669aba1..9e3ae4b5 100755 --- a/acme.sh +++ b/acme.sh @@ -1991,7 +1991,8 @@ _clearupdns() { keyauthorization=$(echo "$ventry" | cut -d "$sep" -f 2) vtype=$(echo "$ventry" | cut -d "$sep" -f 4) _currentRoot=$(echo "$ventry" | cut -d "$sep" -f 5) - + txt="$(printf "%s" "$keyauthorization" | _digest "sha256" | _urlencode)" + _debug txt "$txt" if [ "$keyauthorization" = "$STATE_VERIFIED" ]; then _info "$d is already verified, skip $vtype." continue @@ -2024,7 +2025,7 @@ _clearupdns() { txtdomain="_acme-challenge.$d" - if ! $rmcommand "$txtdomain"; then + if ! $rmcommand "$txtdomain" "$txt"; then _err "Error removing txt for domain:$txtdomain" return 1 fi diff --git a/dnsapi/dns_cf.sh b/dnsapi/dns_cf.sh index dd8c9143..6c191ead 100755 --- a/dnsapi/dns_cf.sh +++ b/dnsapi/dns_cf.sh @@ -55,9 +55,7 @@ dns_cf_add() { _info "Adding record" if _cf_rest POST "zones/$_domain_id/dns_records" "{\"type\":\"TXT\",\"name\":\"$fulldomain\",\"content\":\"$txtvalue\",\"ttl\":120}"; then if printf -- "%s" "$response" | grep "$fulldomain" >/dev/null; then - _info "Added, sleeping 10 seconds" - sleep 10 - #todo: check if the record takes effect + _info "Added, OK" return 0 else _err "Add txt record error." @@ -83,9 +81,44 @@ dns_cf_add() { } -#fulldomain +#fulldomain txtvalue dns_cf_rm() { fulldomain=$1 + txtvalue=$2 + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + _debug _domain_id "$_domain_id" + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + _debug "Getting txt records" + _cf_rest GET "zones/${_domain_id}/dns_records?type=TXT&name=$fulldomain&content=$txtvalue" + + if ! printf "%s" "$response" | grep \"success\":true >/dev/null; then + _err "Error" + return 1 + fi + + count=$(printf "%s\n" "$response" | _egrep_o "\"count\":[^,]*" | cut -d : -f 2) + _debug count "$count" + if [ "$count" = "0" ]; then + _info "Don't need to remove." + else + record_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":\"[^\"]*\"" | cut -d : -f 2 | tr -d \" | head -n 1) + _debug "record_id" "$record_id" + if [ -z "$record_id" ]; then + _err "Can not get record id to remove." + return 1 + fi + if ! _cf_rest DELETE "zones/$_domain_id/dns_records/$record_id"; then + _err "Delete record error." + return 1 + fi + _contains "$response" '"success":true' + fi } @@ -135,7 +168,7 @@ _cf_rest() { _H2="X-Auth-Key: $CF_Key" _H3="Content-Type: application/json" - if [ "$data" ]; then + if [ "$m" != "GET" ]; then _debug data "$data" response="$(_post "$data" "$CF_Api/$ep" "" "$m")" else diff --git a/dnsapi/dns_myapi.sh b/dnsapi/dns_myapi.sh index f3e275d9..e5a98dd9 100755 --- a/dnsapi/dns_myapi.sh +++ b/dnsapi/dns_myapi.sh @@ -22,11 +22,14 @@ dns_myapi_add() { return 1 } -#Usage: fulldomain +#Usage: fulldomain txtvalue #Remove the txt record afer validation. dns_myapi_rm() { fulldomain=$1 - + txtvalue=$2 + _info "Using myapi" + _debug fulldomain "$fulldomain" + _debug txtvalue "$txtvalue" } #################### Private functions bellow ################################## From c0d0100ca8dd6c20abb29dded178fa41e8f449b9 Mon Sep 17 00:00:00 2001 From: neilpang Date: Tue, 6 Dec 2016 15:18:02 +0800 Subject: [PATCH 092/189] fix format --- dnsapi/dns_cf.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_cf.sh b/dnsapi/dns_cf.sh index 6c191ead..b8ff06c1 100755 --- a/dnsapi/dns_cf.sh +++ b/dnsapi/dns_cf.sh @@ -101,7 +101,7 @@ dns_cf_rm() { _err "Error" return 1 fi - + count=$(printf "%s\n" "$response" | _egrep_o "\"count\":[^,]*" | cut -d : -f 2) _debug count "$count" if [ "$count" = "0" ]; then From f162ad193fb29a304b2ef2e74141404fb2b6d7e2 Mon Sep 17 00:00:00 2001 From: neilpang Date: Tue, 6 Dec 2016 15:46:22 +0800 Subject: [PATCH 093/189] support dnspod remove --- dnsapi/dns_dp.sh | 37 ++++++++++++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/dnsapi/dns_dp.sh b/dnsapi/dns_dp.sh index aa06d5fc..c6dd1ba3 100755 --- a/dnsapi/dns_dp.sh +++ b/dnsapi/dns_dp.sh @@ -6,9 +6,8 @@ # #DP_Key="sADDsdasdgdsf" -DP_Api="https://dnsapi.cn" +REST_API="https://dnsapi.cn" -#REST_API ######## Public functions ##################### #Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" @@ -24,8 +23,6 @@ dns_dp_add() { return 1 fi - REST_API="$DP_Api" - #save the api key and email to the account conf file. _saveaccountconf DP_Id "$DP_Id" _saveaccountconf DP_Key "$DP_Key" @@ -50,9 +47,39 @@ dns_dp_add() { fi } -#fulldomain +#fulldomain txtvalue dns_dp_rm() { fulldomain=$1 + txtvalue=$2 + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + + if ! _rest POST "Record.List" "login_token=$DP_Id,$DP_Key&format=json&domain_id=$_domain_id&sub_domain=$_sub_domain"; then + _err "Record.Lis error." + return 1 + fi + + if _contains "$response" 'No records'; then + _info "Don't need to remove." + return 0 + fi + + record_id=$(echo "$response" | _egrep_o '{[^{]*"value":"'$txtvalue'"' | cut -d , -f 1 | cut -d : -f 2 | tr -d \") + _debug record_id "$record_id" + if [ -z "$record_id" ]; then + _err "Can not get record id." + return 1 + fi + + if ! _rest POST "Record.Remove" "login_token=$DP_Id,$DP_Key&format=json&domain_id=$_domain_id&record_id=$record_id"; then + _err "Record.Remove error." + return 1 + fi + + _contains "$response" "Action completed successful" } From f1f30743068610c1967fcf36b765e7a57f457844 Mon Sep 17 00:00:00 2001 From: neilpang Date: Tue, 6 Dec 2016 15:54:19 +0800 Subject: [PATCH 094/189] fix format --- dnsapi/dns_dp.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_dp.sh b/dnsapi/dns_dp.sh index c6dd1ba3..155979af 100755 --- a/dnsapi/dns_dp.sh +++ b/dnsapi/dns_dp.sh @@ -67,7 +67,7 @@ dns_dp_rm() { return 0 fi - record_id=$(echo "$response" | _egrep_o '{[^{]*"value":"'$txtvalue'"' | cut -d , -f 1 | cut -d : -f 2 | tr -d \") + record_id=$(echo "$response" | _egrep_o '{[^{]*"value":"'"$txtvalue"'"' | cut -d , -f 1 | cut -d : -f 2 | tr -d \") _debug record_id "$record_id" if [ -z "$record_id" ]; then _err "Can not get record id." From dfbc244b00cadf6b937171bce45a95641fb548df Mon Sep 17 00:00:00 2001 From: neilpang Date: Tue, 6 Dec 2016 16:52:02 +0800 Subject: [PATCH 095/189] support aws remove --- dnsapi/dns_aws.sh | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/dnsapi/dns_aws.sh b/dnsapi/dns_aws.sh index 2c58754d..ca79326b 100644 --- a/dnsapi/dns_aws.sh +++ b/dnsapi/dns_aws.sh @@ -49,9 +49,28 @@ dns_aws_add() { return 1 } -#fulldomain +#fulldomain txtvalue dns_aws_rm() { fulldomain=$1 + txtvalue=$2 + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + _debug _domain_id "$_domain_id" + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + _aws_tmpl_xml="DELETE\"$txtvalue\"$fulldomain.TXT300" + + if aws_rest POST "2013-04-01$_domain_id/rrset/" "" "$_aws_tmpl_xml" && _contains "$response" "ChangeResourceRecordSetsResponse"; then + _info "txt record deleted sucess." + return 0 + fi + + return 1 } From b9ece28f68bdf94018e9b40e921666dce653c565 Mon Sep 17 00:00:00 2001 From: neilpang Date: Tue, 6 Dec 2016 19:02:46 +0800 Subject: [PATCH 096/189] add osx CI --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 859e8fe3..40dca816 100644 --- a/README.md +++ b/README.md @@ -39,6 +39,7 @@ Wiki: https://github.com/Neilpang/acme.sh/wiki |17|-----| OpenWRT: Tested and working. See [wiki page](https://github.com/Neilpang/acme.sh/wiki/How-to-run-on-OpenWRT) |18|[![](https://cdn.rawgit.com/Neilpang/acmetest/master/status/solaris.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|SunOS/Solaris |19|[![](https://cdn.rawgit.com/Neilpang/acmetest/master/status/gentoo-stage3-amd64.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|Gentoo Linux +|20|[![Build Status](https://travis-ci.org/Neilpang/acme.sh.svg?branch=master)](https://travis-ci.org/Neilpang/acme.sh)|OSX For all build statuses, check our [daily build project](https://github.com/Neilpang/acmetest): From b28a3db3d6931c690bfb9d4f57a550a3dd98ec50 Mon Sep 17 00:00:00 2001 From: neilpang Date: Tue, 6 Dec 2016 19:03:59 +0800 Subject: [PATCH 097/189] Mac OSX --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 40dca816..1e563795 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ Wiki: https://github.com/Neilpang/acme.sh/wiki |17|-----| OpenWRT: Tested and working. See [wiki page](https://github.com/Neilpang/acme.sh/wiki/How-to-run-on-OpenWRT) |18|[![](https://cdn.rawgit.com/Neilpang/acmetest/master/status/solaris.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|SunOS/Solaris |19|[![](https://cdn.rawgit.com/Neilpang/acmetest/master/status/gentoo-stage3-amd64.svg)](https://github.com/Neilpang/letest#here-are-the-latest-status)|Gentoo Linux -|20|[![Build Status](https://travis-ci.org/Neilpang/acme.sh.svg?branch=master)](https://travis-ci.org/Neilpang/acme.sh)|OSX +|20|[![Build Status](https://travis-ci.org/Neilpang/acme.sh.svg?branch=master)](https://travis-ci.org/Neilpang/acme.sh)|Mac OSX For all build statuses, check our [daily build project](https://github.com/Neilpang/acmetest): From 5efbaa48495d7380e170f575b805edfc8ad899b6 Mon Sep 17 00:00:00 2001 From: neilpang Date: Tue, 6 Dec 2016 20:50:33 +0800 Subject: [PATCH 098/189] minor, clear default confs --- acme.sh | 50 -------------------------------------------------- 1 file changed, 50 deletions(-) diff --git a/acme.sh b/acme.sh index 9e3ae4b5..4c4a03f1 100755 --- a/acme.sh +++ b/acme.sh @@ -3569,23 +3569,16 @@ _initconf() { if [ ! -f "$ACCOUNT_CONF_PATH" ]; then echo "#ACCOUNT_CONF_PATH=xxxx -#Account configurations: -#Here are the supported macros, uncomment them to make them take effect. - #ACCOUNT_EMAIL=aaa@example.com # the account email used to register account. #ACCOUNT_KEY_PATH=\"/path/to/account.key\" #CERT_HOME=\"/path/to/cert/home\" - #LOG_FILE=\"$DEFAULT_LOG_FILE\" #LOG_LEVEL=1 #AUTO_UPGRADE=\"1\" -#STAGE=1 # Use the staging api -#FORCE=1 # Force to issue cert -#DEBUG=1 # Debug mode #NO_TIMESTAMP=1 #OPENSSL_BIN=openssl @@ -3593,49 +3586,6 @@ _initconf() { #USER_PATH= -#dns api -####################### -#Cloudflare: -#api key -#CF_Key=\"sdfsdfsdfljlbjkljlkjsdfoiwje\" -#account email -#CF_Email=\"xxxx@sss.com\" - -####################### -#Dnspod.cn: -#api key id -#DP_Id=\"1234\" -#api key -#DP_Key=\"sADDsdasdgdsf\" - -####################### -#Cloudxns.com: -#CX_Key=\"1234\" -# -#CX_Secret=\"sADDsdasdgdsf\" - -####################### -#Godaddy.com: -#GD_Key=\"sdfdsgdgdfdasfds\" -# -#GD_Secret=\"sADDsdasdfsdfdssdgdsf\" - -####################### -#nsupdate: -#NSUPDATE_KEY=\"/path/to/update.key\" -#NSUPDATE_SERVER=\"192.168.0.1\" - -####################### -#PowerDNS: -#PDNS_Url=\"http://ns.example.com:8081\" -#PDNS_ServerId=\"localhost\" -#PDNS_Token=\"0123456789ABCDEF\" -#PDNS_Ttl=60 - -####################### -#Amazon Route53: -#AWS_ACCESS_KEY_ID=XXXXXXXXXX -#AWS_SECRET_ACCESS_KEY=XXXXXXXXXXXXXXX " >"$ACCOUNT_CONF_PATH" fi From c7c57cfa0e7dc2ce77eaa542a342dc79fbab557a Mon Sep 17 00:00:00 2001 From: neilpang Date: Wed, 7 Dec 2016 11:49:24 +0800 Subject: [PATCH 099/189] fix for solaris --- dnsapi/dns_cf.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_cf.sh b/dnsapi/dns_cf.sh index b8ff06c1..79f3ae83 100755 --- a/dnsapi/dns_cf.sh +++ b/dnsapi/dns_cf.sh @@ -144,7 +144,7 @@ _get_root() { fi if printf "%s" "$response" | grep "\"name\":\"$h\"" >/dev/null; then - _domain_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":\"[^\"]*\"" | head -n 1 | cut -d : -f 2 | tr -d \") + _domain_id=$(printf "%s\n" "$response" | _egrep_o "\[{\"id\":\"[^\"]*\"" | head -n 1 | cut -d : -f 2 | tr -d \") if [ "$_domain_id" ]; then _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) _domain=$h From 122cc48c29be40b15122ae9ad2ddda026e0c2fa0 Mon Sep 17 00:00:00 2001 From: neilpang Date: Wed, 7 Dec 2016 11:51:15 +0800 Subject: [PATCH 100/189] minor --- dnsapi/dns_cf.sh | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/dnsapi/dns_cf.sh b/dnsapi/dns_cf.sh index 79f3ae83..309eee51 100755 --- a/dnsapi/dns_cf.sh +++ b/dnsapi/dns_cf.sh @@ -70,9 +70,7 @@ dns_cf_add() { _cf_rest PUT "zones/$_domain_id/dns_records/$record_id" "{\"id\":\"$record_id\",\"type\":\"TXT\",\"name\":\"$fulldomain\",\"content\":\"$txtvalue\",\"zone_id\":\"$_domain_id\",\"zone_name\":\"$_domain\"}" if [ "$?" = "0" ]; then - _info "Updated, sleeping 10 seconds" - sleep 10 - #todo: check if the record takes effect + _info "Updated, OK" return 0 fi _err "Update error" From 39d1eeda2362837b5eebc96a0d591573f1f0c744 Mon Sep 17 00:00:00 2001 From: neilpang Date: Wed, 7 Dec 2016 12:41:22 +0800 Subject: [PATCH 101/189] fix for solaris --- dnsapi/dns_aws.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_aws.sh b/dnsapi/dns_aws.sh index ca79326b..63542ccb 100644 --- a/dnsapi/dns_aws.sh +++ b/dnsapi/dns_aws.sh @@ -91,13 +91,13 @@ _get_root() { fi if _contains "$response" "$h."; then - hostedzone="$(echo "$response" | sed 's//\n&/g' | _egrep_o ".*$h..*")" + hostedzone="$(echo "$response" | sed 's//\n&/g' | _egrep_o ".*$h.<.Name>.*<.HostedZone>")" _debug hostedzone "$hostedzone" if [ -z "$hostedzone" ]; then _err "Error, can not get hostedzone." return 1 fi - _domain_id=$(printf "%s\n" "$hostedzone" | _egrep_o ".*" | head -n 1 | _egrep_o ">.*<" | tr -d "<>") + _domain_id=$(printf "%s\n" "$hostedzone" | _egrep_o ".*<.Id>" | head -n 1 | _egrep_o ">.*<" | tr -d "<>") if [ "$_domain_id" ]; then _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) _domain=$h From 7d1c5fca0b211168bc9e5f9cfe916f92c22f9fed Mon Sep 17 00:00:00 2001 From: neilpang Date: Wed, 7 Dec 2016 13:52:31 +0800 Subject: [PATCH 102/189] fix for solaris --- dnsapi/dns_dp.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dnsapi/dns_dp.sh b/dnsapi/dns_dp.sh index 155979af..81edc225 100755 --- a/dnsapi/dns_dp.sh +++ b/dnsapi/dns_dp.sh @@ -102,7 +102,7 @@ existing_records() { fi if _contains "$response" "Action completed successful"; then - count=$(printf "%s" "$response" | grep 'TXT' | wc -l) + count=$(printf "%s" "$response" | grep 'TXT' | wc -l | tr -d ' ') record_id=$(printf "%s" "$response" | grep '^' | tail -1 | cut -d '>' -f 2 | cut -d '<' -f 1) return 0 else @@ -208,9 +208,9 @@ _rest() { if [ "$data" ]; then _debug2 data "$data" - response="$(_post "$data" "$url")" + response="$(_post "$data" "$url" | tr -d '\r')" else - response="$(_get "$url")" + response="$(_get "$url" | tr -d '\r')" fi if [ "$?" != "0" ]; then From 2728170c01510e1c5ca5aaa9f06226f19819d5f3 Mon Sep 17 00:00:00 2001 From: neilpang Date: Wed, 7 Dec 2016 14:30:17 +0800 Subject: [PATCH 103/189] add debug info --- dnsapi/dns_dp.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/dnsapi/dns_dp.sh b/dnsapi/dns_dp.sh index 81edc225..e2952d71 100755 --- a/dnsapi/dns_dp.sh +++ b/dnsapi/dns_dp.sh @@ -104,6 +104,7 @@ existing_records() { if _contains "$response" "Action completed successful"; then count=$(printf "%s" "$response" | grep 'TXT' | wc -l | tr -d ' ') record_id=$(printf "%s" "$response" | grep '^' | tail -1 | cut -d '>' -f 2 | cut -d '<' -f 1) + _debug record_id "$record_id" return 0 else _err "get existing records error." From 03d3f3afc39e688bb998f8e2f7d3c094a2aad1df Mon Sep 17 00:00:00 2001 From: neilpang Date: Wed, 7 Dec 2016 14:50:45 +0800 Subject: [PATCH 104/189] fix for solaris --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 4c4a03f1..5e672a59 100755 --- a/acme.sh +++ b/acme.sh @@ -3469,7 +3469,7 @@ _deactivate() { return 1 fi - entry="$(printf "%s\n" "$response" | _egrep_o '[^\{]*"status":"valid","uri"[^\}]*')" + entry="$(printf "%s\n" "$response" | _egrep_o '{"type":".*","status":"valid","uri"[^}]*')" _debug entry "$entry" if [ -z "$entry" ]; then From 947d14ffebe9ce35ccc5da9e61a0469cfb99efb8 Mon Sep 17 00:00:00 2001 From: neilpang Date: Fri, 9 Dec 2016 22:20:38 +0800 Subject: [PATCH 105/189] fix deactivate function --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 5e672a59..dc3ac7f0 100755 --- a/acme.sh +++ b/acme.sh @@ -3469,7 +3469,7 @@ _deactivate() { return 1 fi - entry="$(printf "%s\n" "$response" | _egrep_o '{"type":".*","status":"valid","uri"[^}]*')" + entry="$(printf "%s\n" "$response" | _egrep_o '{"type":"[^"]*","status":"valid","uri"[^}]*')" _debug entry "$entry" if [ -z "$entry" ]; then From c4236e58d1d8faf3491335e48b43e3fdc1112a9c Mon Sep 17 00:00:00 2001 From: neilpang Date: Sat, 10 Dec 2016 21:32:47 +0800 Subject: [PATCH 106/189] fix renew for different CA --- acme.sh | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/acme.sh b/acme.sh index dc3ac7f0..6803616a 100755 --- a/acme.sh +++ b/acme.sh @@ -529,6 +529,7 @@ _isEccKey() { _createkey() { length="$1" f="$2" + _debug2 "_createkey for file:$f" eccname="$length" if _startswith "$length" "ec-"; then length=$(printf "%s" "$length" | cut -d '-' -f 2-100) @@ -1685,6 +1686,7 @@ _initpath() { if [ -z "$CA_CONF" ]; then CA_CONF="$_DEFAULT_CA_CONF" fi + _debug3 CA_CONF "$CA_CONF" if [ -f "$CA_CONF" ]; then . "$CA_CONF" @@ -2990,6 +2992,12 @@ renew() { if [ "$Le_API" ]; then API="$Le_API" + #reload ca configs + ACCOUNT_KEY_PATH="" + ACCOUNT_JSON_PATH="" + CA_CONF="" + _debug3 "initpath again." + _initpath "$Le_Domain" "$_isEcc" fi if [ -z "$FORCE" ] && [ "$Le_NextRenewTime" ] && [ "$(_time)" -lt "$Le_NextRenewTime" ]; then From 4d8b99a3073778fb387a2ffa02198db835912331 Mon Sep 17 00:00:00 2001 From: neilpang Date: Tue, 13 Dec 2016 20:04:43 +0800 Subject: [PATCH 107/189] add more debug info --- acme.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/acme.sh b/acme.sh index 6803616a..436c3ef9 100755 --- a/acme.sh +++ b/acme.sh @@ -406,8 +406,10 @@ _getfile() { #Usage: multiline _base64() { if [ "$1" ]; then + _debug3 "base64 multiline:$1" $OPENSSL_BIN base64 -e else + _debug3 "base64 single line." $OPENSSL_BIN base64 -e | tr -d '\r\n' fi } @@ -932,6 +934,8 @@ _calcjwk() { modulus=$($OPENSSL_BIN rsa -in "$keyfile" -modulus -noout | cut -d '=' -f 2) _debug3 modulus "$modulus" n="$(printf "%s" "$modulus" | _h2b | _base64 | _urlencode)" + _debug3 n "$n" + jwk='{"e": "'$e'", "kty": "RSA", "n": "'$n'"}' _debug3 jwk "$jwk" From 24d2a8b9d52facff65e999a8a668c3720b2dbbb7 Mon Sep 17 00:00:00 2001 From: neilpang Date: Tue, 13 Dec 2016 20:27:49 +0800 Subject: [PATCH 108/189] add debug info --- acme.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/acme.sh b/acme.sh index 436c3ef9..33c0ed4a 100755 --- a/acme.sh +++ b/acme.sh @@ -406,7 +406,7 @@ _getfile() { #Usage: multiline _base64() { if [ "$1" ]; then - _debug3 "base64 multiline:$1" + _debug3 "base64 multiline:'$1'" $OPENSSL_BIN base64 -e else _debug3 "base64 single line." @@ -933,7 +933,7 @@ _calcjwk() { modulus=$($OPENSSL_BIN rsa -in "$keyfile" -modulus -noout | cut -d '=' -f 2) _debug3 modulus "$modulus" - n="$(printf "%s" "$modulus" | _h2b | _base64 | _urlencode)" + n="$(printf "%s" "$modulus" | _h2b | _base64| _urlencode)" _debug3 n "$n" jwk='{"e": "'$e'", "kty": "RSA", "n": "'$n'"}' From 1f6ffa3e88c8b0719d26943aa3b065571c47140b Mon Sep 17 00:00:00 2001 From: neilpang Date: Tue, 13 Dec 2016 20:32:50 +0800 Subject: [PATCH 109/189] fix warnings --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 33c0ed4a..c6af629a 100755 --- a/acme.sh +++ b/acme.sh @@ -933,7 +933,7 @@ _calcjwk() { modulus=$($OPENSSL_BIN rsa -in "$keyfile" -modulus -noout | cut -d '=' -f 2) _debug3 modulus "$modulus" - n="$(printf "%s" "$modulus" | _h2b | _base64| _urlencode)" + n="$(printf "%s" "$modulus" | _h2b | _base64 | _urlencode)" _debug3 n "$n" jwk='{"e": "'$e'", "kty": "RSA", "n": "'$n'"}' From b171aff4189634387be9fefbff64f716582136a4 Mon Sep 17 00:00:00 2001 From: neilpang Date: Tue, 13 Dec 2016 20:42:36 +0800 Subject: [PATCH 110/189] fix for wrt https://github.com/Neilpang/acme.sh/issues/465 I know it's a stupid fix, but it works. I will check it later. --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index c6af629a..3512b8d6 100755 --- a/acme.sh +++ b/acme.sh @@ -933,7 +933,7 @@ _calcjwk() { modulus=$($OPENSSL_BIN rsa -in "$keyfile" -modulus -noout | cut -d '=' -f 2) _debug3 modulus "$modulus" - n="$(printf "%s" "$modulus" | _h2b | _base64 | _urlencode)" + n="$(printf "%s" "$modulus" | _h2b | _base64 | tr -d '\r\n' | _urlencode)" _debug3 n "$n" jwk='{"e": "'$e'", "kty": "RSA", "n": "'$n'"}' From 329174b6d93b04cd239878f3fda07458532f7b29 Mon Sep 17 00:00:00 2001 From: klemens Date: Wed, 14 Dec 2016 21:32:24 +0100 Subject: [PATCH 111/189] spelling fixes --- README.md | 2 +- acme.sh | 4 ++-- dnsapi/dns_ali.sh | 2 +- dnsapi/dns_aws.sh | 6 +++--- dnsapi/dns_cf.sh | 2 +- dnsapi/dns_cx.sh | 2 +- dnsapi/dns_dp.sh | 2 +- dnsapi/dns_gd.sh | 2 +- dnsapi/dns_ispconfig.sh | 2 +- dnsapi/dns_lua.sh | 2 +- dnsapi/dns_me.sh | 2 +- dnsapi/dns_myapi.sh | 4 ++-- dnsapi/dns_nsupdate.sh | 2 +- dnsapi/dns_ovh.sh | 2 +- dnsapi/dns_pdns.sh | 2 +- 15 files changed, 19 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 1e563795..a9d5d31d 100644 --- a/README.md +++ b/README.md @@ -321,7 +321,7 @@ acme.sh --renew -d example.com --force --ecc # 11. How to upgrade `acme.sh` -acme.sh is in constant developement, so it's strongly recommended to use the latest code. +acme.sh is in constant development, so it's strongly recommended to use the latest code. You can update acme.sh to the latest code: diff --git a/acme.sh b/acme.sh index 6803616a..75d4be80 100755 --- a/acme.sh +++ b/acme.sh @@ -1913,7 +1913,7 @@ _setApache() { fi _info "JFYI, Config file $httpdconf is backuped to $APACHE_CONF_BACKUP_DIR/$httpdconfname" _info "In case there is an error that can not be restored automatically, you may try restore it yourself." - _info "The backup file will be deleted on sucess, just forget it." + _info "The backup file will be deleted on success, just forget it." #add alias @@ -3780,7 +3780,7 @@ install() { if [ -z "$NO_DETECT_SH" ]; then #Modify shebang if _exists bash; then - _info "Good, bash is found, so change the shebang to use bash as prefered." + _info "Good, bash is found, so change the shebang to use bash as preferred." _shebang='#!/usr/bin/env bash' _setShebang "$LE_WORKING_DIR/$PROJECT_ENTRY" "$_shebang" for subf in $_SUB_FOLDERS; do diff --git a/dnsapi/dns_ali.sh b/dnsapi/dns_ali.sh index 30867219..98c56f87 100644 --- a/dnsapi/dns_ali.sh +++ b/dnsapi/dns_ali.sh @@ -35,7 +35,7 @@ dns_ali_rm() { _clean } -#################### Private functions bellow ################################## +#################### Private functions below ################################## _get_root() { domain=$1 diff --git a/dnsapi/dns_aws.sh b/dnsapi/dns_aws.sh index 63542ccb..86d4d044 100644 --- a/dnsapi/dns_aws.sh +++ b/dnsapi/dns_aws.sh @@ -42,7 +42,7 @@ dns_aws_add() { _aws_tmpl_xml="UPSERT$fulldomainTXT300\"$txtvalue\"" if aws_rest POST "2013-04-01$_domain_id/rrset/" "" "$_aws_tmpl_xml" && _contains "$response" "ChangeResourceRecordSetsResponse"; then - _info "txt record updated sucess." + _info "txt record updated success." return 0 fi @@ -66,7 +66,7 @@ dns_aws_rm() { _aws_tmpl_xml="DELETE\"$txtvalue\"$fulldomain.TXT300" if aws_rest POST "2013-04-01$_domain_id/rrset/" "" "$_aws_tmpl_xml" && _contains "$response" "ChangeResourceRecordSetsResponse"; then - _info "txt record deleted sucess." + _info "txt record deleted success." return 0 fi @@ -74,7 +74,7 @@ dns_aws_rm() { } -#################### Private functions bellow ################################## +#################### Private functions below ################################## _get_root() { domain=$1 diff --git a/dnsapi/dns_cf.sh b/dnsapi/dns_cf.sh index 309eee51..e13e6d7e 100755 --- a/dnsapi/dns_cf.sh +++ b/dnsapi/dns_cf.sh @@ -120,7 +120,7 @@ dns_cf_rm() { } -#################### Private functions bellow ################################## +#################### Private functions below ################################## #_acme-challenge.www.domain.com #returns # _sub_domain=_acme-challenge.www diff --git a/dnsapi/dns_cx.sh b/dnsapi/dns_cx.sh index 86a7b2d0..f7f20812 100755 --- a/dnsapi/dns_cx.sh +++ b/dnsapi/dns_cx.sh @@ -131,7 +131,7 @@ update_record() { return 1 } -#################### Private functions bellow ################################## +#################### Private functions below ################################## #_acme-challenge.www.domain.com #returns # _sub_domain=_acme-challenge.www diff --git a/dnsapi/dns_dp.sh b/dnsapi/dns_dp.sh index e2952d71..06833b4b 100755 --- a/dnsapi/dns_dp.sh +++ b/dnsapi/dns_dp.sh @@ -158,7 +158,7 @@ update_record() { return 1 #error } -#################### Private functions bellow ################################## +#################### Private functions below ################################## #_acme-challenge.www.domain.com #returns # _sub_domain=_acme-challenge.www diff --git a/dnsapi/dns_gd.sh b/dnsapi/dns_gd.sh index 9470ed22..81000561 100755 --- a/dnsapi/dns_gd.sh +++ b/dnsapi/dns_gd.sh @@ -59,7 +59,7 @@ dns_gd_rm() { } -#################### Private functions bellow ################################## +#################### Private functions below ################################## #_acme-challenge.www.domain.com #returns # _sub_domain=_acme-challenge.www diff --git a/dnsapi/dns_ispconfig.sh b/dnsapi/dns_ispconfig.sh index 789b6267..a84d95d7 100755 --- a/dnsapi/dns_ispconfig.sh +++ b/dnsapi/dns_ispconfig.sh @@ -30,7 +30,7 @@ dns_ispconfig_rm() { _ISPC_credentials && _ISPC_login && _ISPC_rmTxt } -#################### Private functions bellow ################################## +#################### Private functions below ################################## _ISPC_credentials() { if [ -z "${ISPC_User}" ] || [ -z "$ISPC_Password" ] || [ -z "${ISPC_Api}" ] || [ -z "${ISPC_Api_Insecure}" ]; then diff --git a/dnsapi/dns_lua.sh b/dnsapi/dns_lua.sh index 2c7ec4b3..bc06b3ef 100755 --- a/dnsapi/dns_lua.sh +++ b/dnsapi/dns_lua.sh @@ -84,7 +84,7 @@ dns_lua_rm() { } -#################### Private functions bellow ################################## +#################### Private functions below ################################## #_acme-challenge.www.domain.com #returns # _sub_domain=_acme-challenge.www diff --git a/dnsapi/dns_me.sh b/dnsapi/dns_me.sh index 2a03f533..d7a1b19f 100755 --- a/dnsapi/dns_me.sh +++ b/dnsapi/dns_me.sh @@ -81,7 +81,7 @@ dns_me_rm() { } -#################### Private functions bellow ################################## +#################### Private functions below ################################## #_acme-challenge.www.domain.com #returns # _sub_domain=_acme-challenge.www diff --git a/dnsapi/dns_myapi.sh b/dnsapi/dns_myapi.sh index e5a98dd9..6bf62508 100755 --- a/dnsapi/dns_myapi.sh +++ b/dnsapi/dns_myapi.sh @@ -23,7 +23,7 @@ dns_myapi_add() { } #Usage: fulldomain txtvalue -#Remove the txt record afer validation. +#Remove the txt record after validation. dns_myapi_rm() { fulldomain=$1 txtvalue=$2 @@ -32,4 +32,4 @@ dns_myapi_rm() { _debug txtvalue "$txtvalue" } -#################### Private functions bellow ################################## +#################### Private functions below ################################## diff --git a/dnsapi/dns_nsupdate.sh b/dnsapi/dns_nsupdate.sh index 8067d2fe..7acb2ef7 100755 --- a/dnsapi/dns_nsupdate.sh +++ b/dnsapi/dns_nsupdate.sh @@ -44,7 +44,7 @@ EOF return 0 } -#################### Private functions bellow ################################## +#################### Private functions below ################################## _checkKeyFile() { if [ -z "${NSUPDATE_KEY}" ]; then diff --git a/dnsapi/dns_ovh.sh b/dnsapi/dns_ovh.sh index 377b3de1..18b9c341 100755 --- a/dnsapi/dns_ovh.sh +++ b/dnsapi/dns_ovh.sh @@ -182,7 +182,7 @@ dns_ovh_rm() { } -#################### Private functions bellow ################################## +#################### Private functions below ################################## _ovh_authentication() { diff --git a/dnsapi/dns_pdns.sh b/dnsapi/dns_pdns.sh index a2c29075..06763d88 100755 --- a/dnsapi/dns_pdns.sh +++ b/dnsapi/dns_pdns.sh @@ -130,7 +130,7 @@ notify_slaves() { return 0 } -#################### Private functions bellow ################################## +#################### Private functions below ################################## #_acme-challenge.www.domain.com #returns # _domain=domain.com From a3a04b5f769f58514cce19933b44b73e798bbc5f Mon Sep 17 00:00:00 2001 From: neilpang Date: Sat, 17 Dec 2016 20:51:00 +0800 Subject: [PATCH 112/189] revert last fix --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 3512b8d6..c6af629a 100755 --- a/acme.sh +++ b/acme.sh @@ -933,7 +933,7 @@ _calcjwk() { modulus=$($OPENSSL_BIN rsa -in "$keyfile" -modulus -noout | cut -d '=' -f 2) _debug3 modulus "$modulus" - n="$(printf "%s" "$modulus" | _h2b | _base64 | tr -d '\r\n' | _urlencode)" + n="$(printf "%s" "$modulus" | _h2b | _base64 | _urlencode)" _debug3 n "$n" jwk='{"e": "'$e'", "kty": "RSA", "n": "'$n'"}' From 96db9362c565cd9245b0051af50ab08f1b195eea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Armando=20L=C3=BCscher?= Date: Sun, 18 Dec 2016 03:17:35 +0100 Subject: [PATCH 113/189] Fix typo. --- acme.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/acme.sh b/acme.sh index 81e0e0cc..acbcc023 100755 --- a/acme.sh +++ b/acme.sh @@ -637,8 +637,8 @@ _createcsr() { _info "Multi domain" "$alt" printf -- "\nsubjectAltName=$alt" >>"$csrconf" fi - if [ "$Le_OCSP_Stable" ]; then - _savedomainconf Le_OCSP_Stable "$Le_OCSP_Stable" + if [ "$Le_OCSP_Staple" ]; then + _savedomainconf Le_OCSP_Staple "$Le_OCSP_Staple" printf -- "\nbasicConstraints = CA:FALSE\n1.3.6.1.5.5.7.1.24=DER:30:03:02:01:05" >>"$csrconf" fi @@ -4365,7 +4365,7 @@ _process() { shift ;; --ocsp-must-staple | --ocsp) - Le_OCSP_Stable="1" + Le_OCSP_Staple="1" ;; --log | --logfile) _log="1" From 0a3b6c4813b9faa1b5f7404455a4876972b052b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Armando=20L=C3=BCscher?= Date: Sun, 18 Dec 2016 05:29:27 +0100 Subject: [PATCH 114/189] Keep backwards compatible. --- acme.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index acbcc023..b67960d0 100755 --- a/acme.sh +++ b/acme.sh @@ -637,8 +637,9 @@ _createcsr() { _info "Multi domain" "$alt" printf -- "\nsubjectAltName=$alt" >>"$csrconf" fi - if [ "$Le_OCSP_Staple" ]; then + if [ "$Le_OCSP_Staple" ] || [ "$Le_OCSP_Stable" ]; then _savedomainconf Le_OCSP_Staple "$Le_OCSP_Staple" + _cleardomainconf Le_OCSP_Stable printf -- "\nbasicConstraints = CA:FALSE\n1.3.6.1.5.5.7.1.24=DER:30:03:02:01:05" >>"$csrconf" fi From 08b6cf023169788404ac05baf23e6017adaa7767 Mon Sep 17 00:00:00 2001 From: neilpang Date: Wed, 21 Dec 2016 19:56:28 +0800 Subject: [PATCH 115/189] fix https://github.com/Neilpang/acme.sh/issues/478 --- acme.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/acme.sh b/acme.sh index b67960d0..691eb7d8 100755 --- a/acme.sh +++ b/acme.sh @@ -2225,11 +2225,13 @@ _regAccount() { _reg_length="$1" if [ ! -f "$ACCOUNT_KEY_PATH" ] && [ -f "$_OLD_ACCOUNT_KEY" ]; then + mkdir -p "$CA_DIR" _info "mv $_OLD_ACCOUNT_KEY to $ACCOUNT_KEY_PATH" mv "$_OLD_ACCOUNT_KEY" "$ACCOUNT_KEY_PATH" fi if [ ! -f "$ACCOUNT_JSON_PATH" ] && [ -f "$_OLD_ACCOUNT_JSON" ]; then + mkdir -p "$CA_DIR" _info "mv $_OLD_ACCOUNT_JSON to $ACCOUNT_JSON_PATH" mv "$_OLD_ACCOUNT_JSON" "$ACCOUNT_JSON_PATH" fi From e2c939fb97da2dcd578e6aff0acec4b008afde11 Mon Sep 17 00:00:00 2001 From: neilpang Date: Wed, 21 Dec 2016 20:19:57 +0800 Subject: [PATCH 116/189] fix https://github.com/Neilpang/acme.sh/issues/480 --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 691eb7d8..a4375033 100755 --- a/acme.sh +++ b/acme.sh @@ -3359,7 +3359,7 @@ installcronjob() { _err "Can not install cronjob, $PROJECT_ENTRY not found." return 1 fi - if _exists uname && uname -a | grep solaris >/dev/null; then + if _exists uname && uname -a | grep SunOS >/dev/null; then crontab -l | { cat echo "0 0 * * * $lesh --cron --home \"$LE_WORKING_DIR\" > /dev/null" From 3a3b0dd5c1b5a8d9ec7c45f42194c5ae56a44cf8 Mon Sep 17 00:00:00 2001 From: neilpang Date: Wed, 21 Dec 2016 20:38:14 +0800 Subject: [PATCH 117/189] fix https://github.com/Neilpang/acme.sh/issues/481 --- acme.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index a4375033..aefc0155 100755 --- a/acme.sh +++ b/acme.sh @@ -3977,7 +3977,10 @@ _installOnline() { fi ( _info "Extracting $localname" - tar xzf $localname + if ! (tar xzf $localname || gtar xzf $localname); then + _err "Extraction error." + exit 1 + fi cd "$PROJECT_NAME-$BRANCH" chmod +x $PROJECT_ENTRY From 4743171b4f1f97c4054f4df6365f44630ee65753 Mon Sep 17 00:00:00 2001 From: neilpang Date: Thu, 22 Dec 2016 20:06:55 +0800 Subject: [PATCH 118/189] service nginx force-reload --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a9d5d31d..1a7766ef 100644 --- a/README.md +++ b/README.md @@ -147,7 +147,7 @@ acme.sh --installcert -d example.com \ --certpath /path/to/certfile/in/apache/cert.pem \ --keypath /path/to/keyfile/in/apache/key.pem \ --fullchainpath /path/to/fullchain/certfile/apache/fullchain.pem \ ---reloadcmd "service apache2 restart" +--reloadcmd "service apache2 force-reload" ``` **Nginx** example: @@ -155,7 +155,7 @@ acme.sh --installcert -d example.com \ acme.sh --installcert -d example.com \ --keypath /path/to/keyfile/in/nginx/key.pem \ --fullchainpath /path/to/fullchain/nginx/cert.pem \ ---reloadcmd "service nginx restart" +--reloadcmd "service nginx force-reload" ``` Only the domain is required, all the other parameters are optional. From 8c71bd57e750ee1ad827d706c02bfa3052d18076 Mon Sep 17 00:00:00 2001 From: neilpang Date: Tue, 27 Dec 2016 20:19:22 +0800 Subject: [PATCH 119/189] fix https://github.com/Neilpang/acme.sh/issues/491 --- dnsapi/dns_cx.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_cx.sh b/dnsapi/dns_cx.sh index f7f20812..dfc838ae 100755 --- a/dnsapi/dns_cx.sh +++ b/dnsapi/dns_cx.sh @@ -82,7 +82,7 @@ existing_records() { return 1 fi - seg=$(printf "%s\n" "$response" | _egrep_o '{[^{]*host":"'"$_sub_domain"'"[^}]*\}') + seg=$(printf "%s\n" "$response" | _egrep_o '[^{]*host":"'"$_sub_domain"'"[^}]*\}') _debug seg "$seg" if [ -z "$seg" ]; then return 0 @@ -155,7 +155,7 @@ _get_root() { fi if _contains "$response" "$h."; then - seg=$(printf "%s\n" "$response" | _egrep_o '{[^{]*"'"$h"'."[^}]*}') + seg=$(printf "%s\n" "$response" | _egrep_o '[^{]*"'"$h"'."[^}]*}') _debug seg "$seg" _domain_id=$(printf "%s\n" "$seg" | _egrep_o "\"id\":\"[^\"]*\"" | cut -d : -f 2 | tr -d \") _debug _domain_id "$_domain_id" From 15af89d51cdd7c64705471550dc8ade17713eec8 Mon Sep 17 00:00:00 2001 From: neilpang Date: Tue, 27 Dec 2016 20:40:52 +0800 Subject: [PATCH 120/189] fix https://github.com/Neilpang/acme.sh/issues/490 --- dnsapi/dns_cf.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_cf.sh b/dnsapi/dns_cf.sh index e13e6d7e..0b817d36 100755 --- a/dnsapi/dns_cf.sh +++ b/dnsapi/dns_cf.sh @@ -132,6 +132,7 @@ _get_root() { p=1 while true; do h=$(printf "%s" "$domain" | cut -d . -f $i-100) + _debug h "$h" if [ -z "$h" ]; then #not valid return 1 @@ -141,8 +142,8 @@ _get_root() { return 1 fi - if printf "%s" "$response" | grep "\"name\":\"$h\"" >/dev/null; then - _domain_id=$(printf "%s\n" "$response" | _egrep_o "\[{\"id\":\"[^\"]*\"" | head -n 1 | cut -d : -f 2 | tr -d \") + if _contains "$response" "\"name\":\"$h\"" >/dev/null; then + _domain_id=$(printf "%s\n" "$response" | _egrep_o "\[.\"id\":\"[^\"]*\"" | head -n 1 | cut -d : -f 2 | tr -d \") if [ "$_domain_id" ]; then _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) _domain=$h From 20444bf253841de76fedc80de824665aa0eafa61 Mon Sep 17 00:00:00 2001 From: neilpang Date: Tue, 27 Dec 2016 20:53:57 +0800 Subject: [PATCH 121/189] fix https://github.com/Neilpang/acme.sh/issues/465 --- acme.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/acme.sh b/acme.sh index aefc0155..4c096534 100755 --- a/acme.sh +++ b/acme.sh @@ -405,6 +405,7 @@ _getfile() { #Usage: multiline _base64() { + [ "" ];#urgly if [ "$1" ]; then _debug3 "base64 multiline:'$1'" $OPENSSL_BIN base64 -e From ec9975c3d9a521ebcf3573841810adfaa58a08c4 Mon Sep 17 00:00:00 2001 From: neilpang Date: Tue, 27 Dec 2016 21:29:44 +0800 Subject: [PATCH 122/189] fix format --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 4c096534..5199a820 100755 --- a/acme.sh +++ b/acme.sh @@ -405,7 +405,7 @@ _getfile() { #Usage: multiline _base64() { - [ "" ];#urgly + [ "" ] #urgly if [ "$1" ]; then _debug3 "base64 multiline:'$1'" $OPENSSL_BIN base64 -e From fe600441c9a121e0b6bdf125296f316d2b44d67c Mon Sep 17 00:00:00 2001 From: Georg Lutz Date: Thu, 29 Dec 2016 11:12:26 +0100 Subject: [PATCH 123/189] Add note about permissions of installed files --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 1a7766ef..dde2eeae 100644 --- a/README.md +++ b/README.md @@ -160,6 +160,8 @@ acme.sh --installcert -d example.com \ Only the domain is required, all the other parameters are optional. +The ownership and permission info of existing files are preserved. You may want to precreate the files to have defined ownership and permission. + Install/copy the issued cert/key to the production Apache or Nginx path. The cert will be `renewed every **60** days by default` (which is configurable). Once the cert is renewed, the Apache/Nginx service will be restarted automatically by the command: `service apache2 restart` or `service nginx restart`. From e5079b9dad0b8e12d4d043daacd5da93e8422d4a Mon Sep 17 00:00:00 2001 From: Paul Koppen Date: Mon, 2 Jan 2017 23:39:00 +0000 Subject: [PATCH 124/189] Add Alwaysdata DNS API. --- dnsapi/dns_ad.sh | 139 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 dnsapi/dns_ad.sh diff --git a/dnsapi/dns_ad.sh b/dnsapi/dns_ad.sh new file mode 100644 index 00000000..158ea951 --- /dev/null +++ b/dnsapi/dns_ad.sh @@ -0,0 +1,139 @@ +#!/usr/bin/env sh + +# +#AD_API_KEY="sdfsdfsdfljlbjkljlkjsdfoiwje" + +#This is the Alwaysdata api wrapper for acme.sh + +AD_HOST="api.alwaysdata.com" +AD_URL="https://$AD_API_KEY:@$AD_HOST" + +######## Public functions ##################### + +#Usage: dns_myapi_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_ad_add() { + fulldomain=$1 + txtvalue=$2 + + if [ -z "$AD_API_KEY" ]; then + AD_API_KEY="" + _err "You didn't specify the AD api key yet." + _err "Please create you key and try again." + return 1 + fi + + _saveaccountconf AD_API_KEY "$AD_API_KEY" + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + _debug _domain_id "$_domain_id" + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + _ad_tmpl_json="{\"domain\":$_domain_id,\"type\":\"TXT\",\"name\":\"$_sub_domain\",\"value\":\"$txtvalue\"}" + + if ad_rest POST "record/" "" "$_ad_tmpl_json" && [ -z "$response" ]; then + _info "txt record updated success." + return 0 + fi + + return 1 +} + +#fulldomain txtvalue +dns_ad_rm() { + fulldomain=$1 + txtvalue=$2 + + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + _debug _domain_id "$_domain_id" + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" + + if ad_rest DELETE "record/" "domain=$_domain_id&name=$_sub_domain" "" && [ -z "$response" ]; then + _info "txt record deleted success." + return 0 + fi + _debug response "$response" + + return 1 +} + +#################### Private functions below ################################## + +_get_root() { + domain=$1 + i=2 + p=1 + + if ad_rest GET "domain/"; then + while true; do + h=$(printf "%s" "$domain" | cut -d . -f $i-100) + if [ -z "$h" ]; then + #not valid + return 1 + fi + + if _contains "$response" "$h"; then + hostedzone="$(echo "$response" | tr -d "\n" | sed 's//\n&/g' | _egrep_o ".*$h<.name>.*<.object>")" + if [ -z "$hostedzone" ]; then + _err "Error, can not get domain record." + return 1 + fi + _domain_id=$(printf "%s\n" "$hostedzone" | _egrep_o ".*<.id>" | head -n 1 | _egrep_o ">.*<" | tr -d "<>") + if [ "$_domain_id" ]; then + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _domain=$h + return 0 + fi + return 1 + fi + p=$i + i=$(_math "$i" + 1) + done + fi + return 1 +} + +#method uri qstr data +ad_rest() { + mtd="$1" + ep="$2" + qsr="$3" + data="$4" + + _debug mtd "$mtd" + _debug ep "$ep" + _debug qsr "$qsr" + _debug data "$data" + + _H1="Accept: application/xml" + + url="$AD_URL/v1/$ep?$qsr" + + if [ "$mtd" = "GET" ]; then + response="$(_get "$url")" + elif [ "$mtd" = "DELETE" ]; then + response="$(_delete "$url")" + else + response="$(_post "$data" "$url")" + fi + + _ret="$?" + if [ "$_ret" = "0" ]; then + # Errors usually 404, otherwise just empty response. How to detect 404? + if _contains "$response" " Date: Tue, 3 Jan 2017 19:31:11 +0800 Subject: [PATCH 125/189] run pre-hook first --- acme.sh | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/acme.sh b/acme.sh index 5199a820..06b14ef6 100755 --- a/acme.sh +++ b/acme.sh @@ -2075,6 +2075,17 @@ _clearupwebbroot() { _on_before_issue() { _debug _on_before_issue + #run pre hook + if [ "$Le_PreHook" ]; then + _info "Run pre hook:'$Le_PreHook'" + if ! ( + cd "$DOMAIN_PATH" && eval "$Le_PreHook" + ); then + _err "Error when run pre hook." + return 1 + fi + fi + if _hasfield "$Le_Webroot" "$NO_VALUE"; then if ! _exists "nc"; then _err "Please install netcat(nc) tools first." @@ -2142,16 +2153,6 @@ _on_before_issue() { usingApache="" fi - #run pre hook - if [ "$Le_PreHook" ]; then - _info "Run pre hook:'$Le_PreHook'" - if ! ( - cd "$DOMAIN_PATH" && eval "$Le_PreHook" - ); then - _err "Error when run pre hook." - return 1 - fi - fi } _on_issue_err() { From 331b599a8184234f3f007acfca570ce43b26e31c Mon Sep 17 00:00:00 2001 From: Paul Koppen Date: Tue, 3 Jan 2017 11:41:11 +0000 Subject: [PATCH 126/189] Use _post for DELETE and switch to JSON API (Alwaysdata default). --- dnsapi/dns_ad.sh | 81 +++++++++++++++++++++++++----------------------- 1 file changed, 43 insertions(+), 38 deletions(-) diff --git a/dnsapi/dns_ad.sh b/dnsapi/dns_ad.sh index 158ea951..379b51f9 100644 --- a/dnsapi/dns_ad.sh +++ b/dnsapi/dns_ad.sh @@ -5,8 +5,7 @@ #This is the Alwaysdata api wrapper for acme.sh -AD_HOST="api.alwaysdata.com" -AD_URL="https://$AD_API_KEY:@$AD_HOST" +AD_API_URL="https://$AD_API_KEY:@api.alwaysdata.com/v1" ######## Public functions ##################### @@ -35,7 +34,7 @@ dns_ad_add() { _ad_tmpl_json="{\"domain\":$_domain_id,\"type\":\"TXT\",\"name\":\"$_sub_domain\",\"value\":\"$txtvalue\"}" - if ad_rest POST "record/" "" "$_ad_tmpl_json" && [ -z "$response" ]; then + if _ad_rest POST "record/" "$_ad_tmpl_json" && [ -z "$response" ]; then _info "txt record updated success." return 0 fi @@ -57,37 +56,51 @@ dns_ad_rm() { _debug _sub_domain "$_sub_domain" _debug _domain "$_domain" - if ad_rest DELETE "record/" "domain=$_domain_id&name=$_sub_domain" "" && [ -z "$response" ]; then - _info "txt record deleted success." - return 0 + _debug "Getting txt records" + _ad_rest GET "record/?domain=$_domain_id&name=$_sub_domain" + + if [ -n "$response" ]; then + record_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":\s*[0-9]+" | cut -d : -f 2 | tr -d \ | head -n 1) + _debug record_id "$record_id" + if [ -z "$record_id" ]; then + _err "Can not get record id to remove." + return 1 + fi + if _ad_rest DELETE "record/$record_id/" && [ -z "$response" ]; then + _info "txt record deleted success." + return 0 + fi + _debug response "$response" + return 1 fi - _debug response "$response" return 1 } #################### Private functions below ################################## - +#_acme-challenge.www.domain.com +#returns +# _sub_domain=_acme-challenge.www +# _domain=domain.com +# _domain_id=12345 _get_root() { domain=$1 i=2 p=1 - if ad_rest GET "domain/"; then + if _ad_rest GET "domain/"; then + response="$(echo "$response" | tr -d "\n" | sed 's/{/\n&/g')" while true; do h=$(printf "%s" "$domain" | cut -d . -f $i-100) + _debug h "$h" if [ -z "$h" ]; then #not valid return 1 fi - if _contains "$response" "$h"; then - hostedzone="$(echo "$response" | tr -d "\n" | sed 's//\n&/g' | _egrep_o ".*$h<.name>.*<.object>")" - if [ -z "$hostedzone" ]; then - _err "Error, can not get domain record." - return 1 - fi - _domain_id=$(printf "%s\n" "$hostedzone" | _egrep_o ".*<.id>" | head -n 1 | _egrep_o ">.*<" | tr -d "<>") + hostedzone="$(echo "$response" | _egrep_o "{.*\"name\":\s*\"$h\".*}")" + if [ "$hostedzone" ]; then + _domain_id=$(printf "%s\n" "$hostedzone" | _egrep_o "\"id\":\s*[0-9]+" | head -n 1 | cut -d : -f 2 | tr -d \ ) if [ "$_domain_id" ]; then _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) _domain=$h @@ -103,37 +116,29 @@ _get_root() { } #method uri qstr data -ad_rest() { +_ad_rest() { mtd="$1" ep="$2" - qsr="$3" - data="$4" + data="$3" _debug mtd "$mtd" _debug ep "$ep" - _debug qsr "$qsr" - _debug data "$data" - _H1="Accept: application/xml" + _H1="Accept: application/json" + _H2="Content-Type: application/json" - url="$AD_URL/v1/$ep?$qsr" - - if [ "$mtd" = "GET" ]; then - response="$(_get "$url")" - elif [ "$mtd" = "DELETE" ]; then - response="$(_delete "$url")" + if [ "$mtd" != "GET" ]; then + # both POST and DELETE. + _debug data "$data" + response="$(_post "$data" "$AD_API_URL/$ep" "" "$mtd")" else - response="$(_post "$data" "$url")" + response="$(_get "$AD_API_URL/$ep")" fi - _ret="$?" - if [ "$_ret" = "0" ]; then - # Errors usually 404, otherwise just empty response. How to detect 404? - if _contains "$response" " Date: Tue, 3 Jan 2017 12:09:57 +0000 Subject: [PATCH 127/189] Merge suggested improvements. * Use `_head_n`. * Add link to GitHub repo for bug reporting. --- dnsapi/dns_ad.sh | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_ad.sh b/dnsapi/dns_ad.sh index 379b51f9..81c20e09 100644 --- a/dnsapi/dns_ad.sh +++ b/dnsapi/dns_ad.sh @@ -4,6 +4,9 @@ #AD_API_KEY="sdfsdfsdfljlbjkljlkjsdfoiwje" #This is the Alwaysdata api wrapper for acme.sh +# +#Author: Paul Koppen +#Report Bugs here: https://github.com/wpk-/acme.sh AD_API_URL="https://$AD_API_KEY:@api.alwaysdata.com/v1" @@ -60,7 +63,7 @@ dns_ad_rm() { _ad_rest GET "record/?domain=$_domain_id&name=$_sub_domain" if [ -n "$response" ]; then - record_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":\s*[0-9]+" | cut -d : -f 2 | tr -d \ | head -n 1) + record_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":\s*[0-9]+" | cut -d : -f 2 | tr -d \ | _head_n 1) _debug record_id "$record_id" if [ -z "$record_id" ]; then _err "Can not get record id to remove." @@ -100,7 +103,7 @@ _get_root() { hostedzone="$(echo "$response" | _egrep_o "{.*\"name\":\s*\"$h\".*}")" if [ "$hostedzone" ]; then - _domain_id=$(printf "%s\n" "$hostedzone" | _egrep_o "\"id\":\s*[0-9]+" | head -n 1 | cut -d : -f 2 | tr -d \ ) + _domain_id=$(printf "%s\n" "$hostedzone" | _egrep_o "\"id\":\s*[0-9]+" | _head_n 1 | cut -d : -f 2 | tr -d \ ) if [ "$_domain_id" ]; then _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) _domain=$h From b2686e5b6da57b51f2ddb55e8ca06e69777c8cab Mon Sep 17 00:00:00 2001 From: Paul Koppen Date: Tue, 3 Jan 2017 12:13:27 +0000 Subject: [PATCH 128/189] Add Alwaysdata.com to list of supported API's. --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index dde2eeae..9b5891c9 100644 --- a/README.md +++ b/README.md @@ -265,6 +265,7 @@ You don't have to do anything manually! 1. nsupdate API 1. aliyun.com(阿里云) API 1. ISPConfig 3.1 API +1. Alwaysdata.com API **More APIs coming soon...** From 180f05f6f08bdfbec46d53c6b1b4bdcc7538e527 Mon Sep 17 00:00:00 2001 From: Paul Koppen Date: Tue, 3 Jan 2017 12:16:22 +0000 Subject: [PATCH 129/189] Add instructions for the Alwaysdata API. --- dnsapi/README.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/dnsapi/README.md b/dnsapi/README.md index c4245701..e32b4655 100644 --- a/dnsapi/README.md +++ b/dnsapi/README.md @@ -240,6 +240,23 @@ acme.sh --issue --dns dns_ispconfig -d example.com -d www.example.com The `ISPC_User`, `ISPC_Password`, `ISPC_Api`and `ISPC_Api_Insecure` will be saved in `~/.acme.sh/account.conf` and will be reused when needed. +## 13. Use Alwaysdata domain API + +First you need to login to your Alwaysdata account to get your API Key. + +```sh +export AD_API_KEY="myalwaysdataapikey" +``` + +Ok, let's issue a cert now: + +```sh +acme.sh --issue --dns dns_ad -d example.com -d www.example.com +``` + +The `AD_API_KEY` will be saved in `~/.acme.sh/account.conf` and will be reused +when needed. + # Use custom API If your API is not supported yet, you can write your own DNS API. From b90917a52951e85cb5eda4ae51d6daedd921fbf7 Mon Sep 17 00:00:00 2001 From: Paul Koppen Date: Tue, 3 Jan 2017 12:33:10 +0000 Subject: [PATCH 130/189] Improve legibility. --- dnsapi/dns_ad.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_ad.sh b/dnsapi/dns_ad.sh index 81c20e09..cbec6c9b 100644 --- a/dnsapi/dns_ad.sh +++ b/dnsapi/dns_ad.sh @@ -63,7 +63,7 @@ dns_ad_rm() { _ad_rest GET "record/?domain=$_domain_id&name=$_sub_domain" if [ -n "$response" ]; then - record_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":\s*[0-9]+" | cut -d : -f 2 | tr -d \ | _head_n 1) + record_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":\s*[0-9]+" | cut -d : -f 2 | tr -d " " | _head_n 1) _debug record_id "$record_id" if [ -z "$record_id" ]; then _err "Can not get record id to remove." From 7b4be7be4094176098d889d7a37feab0dd45ace9 Mon Sep 17 00:00:00 2001 From: Paul Koppen Date: Tue, 3 Jan 2017 12:35:10 +0000 Subject: [PATCH 131/189] Remove spaces from blank lines. --- dnsapi/dns_ad.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dnsapi/dns_ad.sh b/dnsapi/dns_ad.sh index cbec6c9b..1c7e85f9 100644 --- a/dnsapi/dns_ad.sh +++ b/dnsapi/dns_ad.sh @@ -36,12 +36,12 @@ dns_ad_add() { _debug _domain "$_domain" _ad_tmpl_json="{\"domain\":$_domain_id,\"type\":\"TXT\",\"name\":\"$_sub_domain\",\"value\":\"$txtvalue\"}" - + if _ad_rest POST "record/" "$_ad_tmpl_json" && [ -z "$response" ]; then _info "txt record updated success." return 0 fi - + return 1 } @@ -61,7 +61,7 @@ dns_ad_rm() { _debug "Getting txt records" _ad_rest GET "record/?domain=$_domain_id&name=$_sub_domain" - + if [ -n "$response" ]; then record_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":\s*[0-9]+" | cut -d : -f 2 | tr -d " " | _head_n 1) _debug record_id "$record_id" @@ -129,7 +129,7 @@ _ad_rest() { _H1="Accept: application/json" _H2="Content-Type: application/json" - + if [ "$mtd" != "GET" ]; then # both POST and DELETE. _debug data "$data" From 058e5d5f4b9b67f49527da71f9c0a3fbfbecc8c4 Mon Sep 17 00:00:00 2001 From: neilpang Date: Thu, 5 Jan 2017 22:32:26 +0800 Subject: [PATCH 132/189] LF --- .travis.yml | 108 ++++++++++++++++++++++++++-------------------------- 1 file changed, 54 insertions(+), 54 deletions(-) diff --git a/.travis.yml b/.travis.yml index 94848c17..0667919d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,54 +1,54 @@ -language: shell -sudo: required - -os: - - linux - - osx - -env: - global: - - SHFMT_URL=https://github.com/mvdan/sh/releases/download/v0.4.0/shfmt_v0.4.0_linux_amd64 - -addons: - apt: - sources: - - debian-sid # Grab shellcheck from the Debian repo (o_O) - packages: - - shellcheck - -install: - - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then - brew update && brew install openssl; - brew info openssl; - ln -s /usr/local/opt/openssl/lib/libcrypto.1.0.0.dylib /usr/local/lib/; - ln -s /usr/local/opt/openssl/lib/libssl.1.0.0.dylib /usr/local/lib/; - ln -s /usr/local/Cellar/openssl/1.0.2j/bin/openssl /usr/local/openssl; - _old_path="$PATH"; - echo "PATH=$PATH"; - export PATH=""; - export OPENSSL_BIN="/usr/local/openssl"; - openssl version 2>&1 || true; - $OPENSSL_BIN version 2>&1 || true; - export PATH="$_old_path"; - fi - -script: - - echo "TEST_LOCAL=$TEST_LOCAL" - - echo "NGROK_TOKEN=$(echo "$NGROK_TOKEN" | wc -c)" - - which openssl && openssl version - - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then curl -sSL $SHFMT_URL -o ~/shfmt ; fi - - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then chmod +x ~/shfmt ; fi - - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then ~/shfmt -l -w -i 2 . ; fi - - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then git diff --exit-code && echo "shfmt OK" ; fi - - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then shellcheck -V ; fi - - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then shellcheck -e SC2021,SC2126,SC2034 **/*.sh && echo "shellcheck OK" ; fi - - cd .. - - git clone https://github.com/Neilpang/acmetest.git && cp -r acme.sh acmetest/ && cd acmetest - - if [[ "$TRAVIS_OS_NAME" == "linux" ]] && [[ "$NGROK_TOKEN" ]]; then sudo NGROK_TOKEN="$NGROK_TOKEN" ./letest.sh ; fi - - if [[ "$TRAVIS_OS_NAME" == "osx" ]] && [[ "$NGROK_TOKEN" ]]; then sudo NGROK_TOKEN="$NGROK_TOKEN" OPENSSL_BIN="$OPENSSL_BIN" ./letest.sh ; fi - - -matrix: - fast_finish: true - - +language: shell +sudo: required + +os: + - linux + - osx + +env: + global: + - SHFMT_URL=https://github.com/mvdan/sh/releases/download/v0.4.0/shfmt_v0.4.0_linux_amd64 + +addons: + apt: + sources: + - debian-sid # Grab shellcheck from the Debian repo (o_O) + packages: + - shellcheck + +install: + - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then + brew update && brew install openssl; + brew info openssl; + ln -s /usr/local/opt/openssl/lib/libcrypto.1.0.0.dylib /usr/local/lib/; + ln -s /usr/local/opt/openssl/lib/libssl.1.0.0.dylib /usr/local/lib/; + ln -s /usr/local/Cellar/openssl/1.0.2j/bin/openssl /usr/local/openssl; + _old_path="$PATH"; + echo "PATH=$PATH"; + export PATH=""; + export OPENSSL_BIN="/usr/local/openssl"; + openssl version 2>&1 || true; + $OPENSSL_BIN version 2>&1 || true; + export PATH="$_old_path"; + fi + +script: + - echo "TEST_LOCAL=$TEST_LOCAL" + - echo "NGROK_TOKEN=$(echo "$NGROK_TOKEN" | wc -c)" + - which openssl && openssl version + - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then curl -sSL $SHFMT_URL -o ~/shfmt ; fi + - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then chmod +x ~/shfmt ; fi + - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then ~/shfmt -l -w -i 2 . ; fi + - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then git diff --exit-code && echo "shfmt OK" ; fi + - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then shellcheck -V ; fi + - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then shellcheck -e SC2021,SC2126,SC2034 **/*.sh && echo "shellcheck OK" ; fi + - cd .. + - git clone https://github.com/Neilpang/acmetest.git && cp -r acme.sh acmetest/ && cd acmetest + - if [[ "$TRAVIS_OS_NAME" == "linux" ]] && [[ "$NGROK_TOKEN" ]]; then sudo NGROK_TOKEN="$NGROK_TOKEN" ./letest.sh ; fi + - if [[ "$TRAVIS_OS_NAME" == "osx" ]] && [[ "$NGROK_TOKEN" ]]; then sudo NGROK_TOKEN="$NGROK_TOKEN" OPENSSL_BIN="$OPENSSL_BIN" ./letest.sh ; fi + + +matrix: + fast_finish: true + + From 5415381cf42f005953392267b75936db5199ddb9 Mon Sep 17 00:00:00 2001 From: Karsten Sperling Date: Fri, 6 Jan 2017 15:27:55 +1300 Subject: [PATCH 133/189] Add support for AWS_SESSION_TOKEN and fix bug when multiple hosted zones exist --- dnsapi/dns_aws.sh | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/dnsapi/dns_aws.sh b/dnsapi/dns_aws.sh index 86d4d044..38b03cd4 100644 --- a/dnsapi/dns_aws.sh +++ b/dnsapi/dns_aws.sh @@ -27,8 +27,10 @@ dns_aws_add() { return 1 fi - _saveaccountconf AWS_ACCESS_KEY_ID "$AWS_ACCESS_KEY_ID" - _saveaccountconf AWS_SECRET_ACCESS_KEY "$AWS_SECRET_ACCESS_KEY" + if [ -z "$AWS_SESSION_TOKEN" ]; then + _saveaccountconf AWS_ACCESS_KEY_ID "$AWS_ACCESS_KEY_ID" + _saveaccountconf AWS_SECRET_ACCESS_KEY "$AWS_SECRET_ACCESS_KEY" + fi _debug "First detect the root zone" if ! _get_root "$fulldomain"; then @@ -91,7 +93,7 @@ _get_root() { fi if _contains "$response" "$h."; then - hostedzone="$(echo "$response" | sed 's//\n&/g' | _egrep_o ".*$h.<.Name>.*<.HostedZone>")" + hostedzone="$(echo "$response" | sed 's//\n&/g' | _egrep_o ".*?$h.<.Name>.*?<.HostedZone>")" _debug hostedzone "$hostedzone" if [ -z "$hostedzone" ]; then _err "Error, can not get hostedzone." @@ -139,9 +141,13 @@ aws_rest() { aws_host="$AWS_HOST" CanonicalHeaders="host:$aws_host\nx-amz-date:$RequestDate\n" - _debug2 CanonicalHeaders "$CanonicalHeaders" - SignedHeaders="host;x-amz-date" + if [ -n "$AWS_SESSION_TOKEN" ]; then + _H2="x-amz-security-token: $AWS_SESSION_TOKEN" + CanonicalHeaders="${CanonicalHeaders}x-amz-security-token:$AWS_SESSION_TOKEN\n" + SignedHeaders="${SignedHeaders};x-amz-security-token" + fi + _debug2 CanonicalHeaders "$CanonicalHeaders" _debug2 SignedHeaders "$SignedHeaders" RequestPayload="$data" From 3cf85634ebb955ecee7616e88f4e1cef4458df41 Mon Sep 17 00:00:00 2001 From: Kevin Kaland Date: Sun, 8 Jan 2017 00:09:21 +0100 Subject: [PATCH 134/189] Trim potential closing curly brace. Fixes GH-517. --- dnsapi/dns_me.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_me.sh b/dnsapi/dns_me.sh index d7a1b19f..c94a3c90 100755 --- a/dnsapi/dns_me.sh +++ b/dnsapi/dns_me.sh @@ -103,7 +103,7 @@ _get_root() { fi if _contains "$response" "\"name\":\"$h\""; then - _domain_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":[^,]*" | head -n 1 | cut -d : -f 2) + _domain_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":[^,]*" | head -n 1 | cut -d : -f 2 | tr -d '}') if [ "$_domain_id" ]; then _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) _domain="$h" From 800f02ba381cb526860b12ffdf5c3f9577e93553 Mon Sep 17 00:00:00 2001 From: Bastian Bittorf Date: Mon, 9 Jan 2017 12:19:18 +0100 Subject: [PATCH 135/189] dnsapi/dns_lexicon.sh: shellcheck: fix 4 occurences of SC2021: "Don't use [] around ranges in tr, it replaces literal square brackets." this introduces another warning: "Use '[:lower:]' to support accents and foreign alphabets." This is more a style thingy because we really want to only catch A-Z. work around this by using a shellcheck-directive and a comment that the [:lower:] will not work with e.g. busybox-ash. if we later really want to use [:lower:], we should use 'sed' for that. --- .travis.yml | 2 +- dnsapi/dns_lexicon.sh | 13 +++++++++---- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index 0667919d..fd4ee25c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -41,7 +41,7 @@ script: - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then ~/shfmt -l -w -i 2 . ; fi - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then git diff --exit-code && echo "shfmt OK" ; fi - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then shellcheck -V ; fi - - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then shellcheck -e SC2021,SC2126,SC2034 **/*.sh && echo "shellcheck OK" ; fi + - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then shellcheck -e SC2126,SC2034 **/*.sh && echo "shellcheck OK" ; fi - cd .. - git clone https://github.com/Neilpang/acmetest.git && cp -r acme.sh acmetest/ && cd acmetest - if [[ "$TRAVIS_OS_NAME" == "linux" ]] && [[ "$NGROK_TOKEN" ]]; then sudo NGROK_TOKEN="$NGROK_TOKEN" ./letest.sh ; fi diff --git a/dnsapi/dns_lexicon.sh b/dnsapi/dns_lexicon.sh index 4ab65645..0398bd2e 100755 --- a/dnsapi/dns_lexicon.sh +++ b/dnsapi/dns_lexicon.sh @@ -30,7 +30,9 @@ dns_lexicon_add() { _savedomainconf PROVIDER "$PROVIDER" export PROVIDER - Lx_name=$(echo LEXICON_"${PROVIDER}"_USERNAME | tr '[a-z]' '[A-Z]') + # e.g. busybox-ash does not know [:upper:] + # shellcheck disable=SC2018,SC2019 + Lx_name=$(echo LEXICON_"${PROVIDER}"_USERNAME | tr 'a-z' 'A-Z') Lx_name_v=$(eval echo \$"$Lx_name") _debug "$Lx_name" "$Lx_name_v" if [ "$Lx_name_v" ]; then @@ -38,7 +40,8 @@ dns_lexicon_add() { eval export "$Lx_name" fi - Lx_token=$(echo LEXICON_"${PROVIDER}"_TOKEN | tr '[a-z]' '[A-Z]') + # shellcheck disable=SC2018,SC2019 + Lx_token=$(echo LEXICON_"${PROVIDER}"_TOKEN | tr 'a-z' 'A-Z') Lx_token_v=$(eval echo \$"$Lx_token") _debug "$Lx_token" "$Lx_token_v" if [ "$Lx_token_v" ]; then @@ -46,7 +49,8 @@ dns_lexicon_add() { eval export "$Lx_token" fi - Lx_password=$(echo LEXICON_"${PROVIDER}"_PASSWORD | tr '[a-z]' '[A-Z]') + # shellcheck disable=SC2018,SC2019 + Lx_password=$(echo LEXICON_"${PROVIDER}"_PASSWORD | tr 'a-z' 'A-Z') Lx_password_v=$(eval echo \$"$Lx_password") _debug "$Lx_password" "$Lx_password_v" if [ "$Lx_password_v" ]; then @@ -54,7 +58,8 @@ dns_lexicon_add() { eval export "$Lx_password" fi - Lx_domaintoken=$(echo LEXICON_"${PROVIDER}"_DOMAINTOKEN | tr '[a-z]' '[A-Z]') + # shellcheck disable=SC2018,SC2019 + Lx_domaintoken=$(echo LEXICON_"${PROVIDER}"_DOMAINTOKEN | tr 'a-z' 'A-Z') Lx_domaintoken_v=$(eval echo \$"$Lx_domaintoken") _debug "$Lx_domaintoken" "$Lx_domaintoken_v" if [ "$Lx_domaintoken_v" ]; then From d11d476126a6958211d9813ebf34c1e33f25055a Mon Sep 17 00:00:00 2001 From: neilpang Date: Mon, 9 Jan 2017 20:26:07 +0800 Subject: [PATCH 136/189] "Don't use [] around ranges in tr, it replaces literal square brackets." --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 06b14ef6..d0f97b1a 100755 --- a/acme.sh +++ b/acme.sh @@ -573,7 +573,7 @@ _createkey() { _is_idn() { _is_idn_d="$1" _debug2 _is_idn_d "$_is_idn_d" - _idn_temp=$(printf "%s" "$_is_idn_d" | tr -d '[0-9]' | tr -d '[a-z]' | tr -d '[A-Z]' | tr -d '.,-') + _idn_temp=$(printf "%s" "$_is_idn_d" | tr -d '0-9' | tr -d 'a-z' | tr -d 'A-Z' | tr -d '.,-') _debug2 _idn_temp "$_idn_temp" [ "$_idn_temp" ] } From 671a69947219a745cb3882b33d4b60a312b5cb60 Mon Sep 17 00:00:00 2001 From: neilpang Date: Mon, 9 Jan 2017 22:01:48 +0800 Subject: [PATCH 137/189] minor, fix shellcheck warning --- dnsapi/dns_dp.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dnsapi/dns_dp.sh b/dnsapi/dns_dp.sh index 06833b4b..3691be06 100755 --- a/dnsapi/dns_dp.sh +++ b/dnsapi/dns_dp.sh @@ -199,7 +199,7 @@ _get_root() { #Usage: method URI data _rest() { - m=$1 + m="$1" ep="$2" data="$3" _debug "$ep" @@ -207,11 +207,11 @@ _rest() { _debug url "$url" - if [ "$data" ]; then + if [ "$m" = "GET" ]; then + response="$(_get "$url" | tr -d '\r')" + else _debug2 data "$data" response="$(_post "$data" "$url" | tr -d '\r')" - else - response="$(_get "$url" | tr -d '\r')" fi if [ "$?" != "0" ]; then From 3b67cf4378c5dfc141dce4e66639d4fa7d2b462b Mon Sep 17 00:00:00 2001 From: Bastian Bittorf Date: Mon, 9 Jan 2017 15:08:41 +0100 Subject: [PATCH 138/189] dnsapi/dns_dp.sh: shellcheck: fix 1 occurence of SC2126 shellcheck message was: "Consider using grep -c instead of grep | wc" --- .travis.yml | 2 +- dnsapi/dns_dp.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index fd4ee25c..1924f82a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -41,7 +41,7 @@ script: - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then ~/shfmt -l -w -i 2 . ; fi - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then git diff --exit-code && echo "shfmt OK" ; fi - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then shellcheck -V ; fi - - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then shellcheck -e SC2126,SC2034 **/*.sh && echo "shellcheck OK" ; fi + - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then shellcheck -e SC2034 **/*.sh && echo "shellcheck OK" ; fi - cd .. - git clone https://github.com/Neilpang/acmetest.git && cp -r acme.sh acmetest/ && cd acmetest - if [[ "$TRAVIS_OS_NAME" == "linux" ]] && [[ "$NGROK_TOKEN" ]]; then sudo NGROK_TOKEN="$NGROK_TOKEN" ./letest.sh ; fi diff --git a/dnsapi/dns_dp.sh b/dnsapi/dns_dp.sh index 3691be06..301a1f6c 100755 --- a/dnsapi/dns_dp.sh +++ b/dnsapi/dns_dp.sh @@ -102,7 +102,7 @@ existing_records() { fi if _contains "$response" "Action completed successful"; then - count=$(printf "%s" "$response" | grep 'TXT' | wc -l | tr -d ' ') + count=$(printf "%s" "$response" | grep -c 'TXT' | tr -d ' ') record_id=$(printf "%s" "$response" | grep '^' | tail -1 | cut -d '>' -f 2 | cut -d '<' -f 1) _debug record_id "$record_id" return 0 From 5413bf8753bce20471a3023559e176db6e9c1977 Mon Sep 17 00:00:00 2001 From: neil Date: Tue, 10 Jan 2017 10:36:47 +0800 Subject: [PATCH 139/189] minor, clear account key cache if new-authz error. --- acme.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/acme.sh b/acme.sh index d0f97b1a..bd3a51b5 100755 --- a/acme.sh +++ b/acme.sh @@ -2356,6 +2356,12 @@ __get_domain_new_authz() { _err "Can not get domain new authz." return 1 fi + if _contains "$response" "No registration exists matching provided key"; then + _err "It seems there is an error, but it's recovered now, please try again." + _err "If you see this message for a second time, please report bug: $(__green "$PROJECT")" + _clearcaconf "CA_KEY_HASH" + break + fi if ! _contains "$response" "An error occurred while processing your request"; then _info "The new-authz request is ok." break From 1699e94f0ffdd056cd58891dd43a4386b2246471 Mon Sep 17 00:00:00 2001 From: Geoffroi Date: Wed, 11 Jan 2017 14:09:58 +0100 Subject: [PATCH 140/189] Adding kong deploy script (https://getkong.org) --- deploy/kong.sh | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 deploy/kong.sh diff --git a/deploy/kong.sh b/deploy/kong.sh new file mode 100644 index 00000000..cd9de10c --- /dev/null +++ b/deploy/kong.sh @@ -0,0 +1,83 @@ +#!/usr/bin/env sh + +# This deploy hook will deploy ssl cert on kong proxy engine based on api request_host parameter. +# Note that ssl plugin should be available on Kong instance +# The hook will match cdomain to request_host, in case of multiple domain it will always take the first +# one (acme.sh behaviour). +# If ssl config already exist it will update only cert and key not touching other parameter +# If ssl config doesn't exist it will only upload cert and key and not set other parameter +# Not that we deploy full chain +# See https://getkong.org/plugins/dynamic-ssl/ for other options +# Written by Geoffroi Genot + +######## Public functions ##################### + +#domain keyfile certfile cafile fullchain +kong.sh_deploy() { + _cdomain="$1" + _ckey="$2" + _ccert="$3" + _cca="$4" + _cfullchain="$5" + _info "Deploying certificate on Kong instance" + if [ -z "$KONG_URL" ] + then + _debug "KONG_URL Not set, using default http://localhost:8001" + KONG_URL="http://localhost:8001" + fi + + _debug _cdomain "$_cdomain" + _debug _ckey "$_ckey" + _debug _ccert "$_ccert" + _debug _cca "$_cca" + _debug _cfullchain "$_cfullchain" + + #Get uuid linked to the domain + uuid=$( _get "$KONG_URL/apis?request_host=$_cdomain" | _normalizeJson | _egrep_o '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}' ) + if [ "$uuid" = "" ] + then + _err "Unable to get Kong uuid for domain $_cdomain" + _err "Make sure that KONG_URL is correctly configured" + _err "Make sure that a Kong api request_host match the domain" + _err "Kong url: $KONG_URL" + return 1 + fi + #Save kong url if it's succesful (First run case) + _saveaccountconf KONG_URL "$KONG_URL" + #Generate DEIM + delim="-----MultipartDelimeter$(date "+%s%N")" + nl=$( printf "\\r\\n" ) + #Set Header + _H1="Content-Type: multipart/form-data; boundary=$delim" + #Generate data for request (Multipart/form-data with mixed content) + #set name to ssl + content="--$delim${nl}Content-Disposition: form-data; name=\"name\"${nl}${nl}ssl" + #add key + content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"config.key\"; filename=\"$(basename "$_ckey")\"${nl}Content-Type: application/octet-stream${nl}${nl}$(cat "$_ckey")" + #Add cert + content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"config.cert\"; filename=\"$(basename "$_cfullchain")\"${nl}Content-Type: application/octet-stream${nl}${nl}$(cat "$_cfullchain")" + #Close multipart + content="$content${nl}--$delim--${nl}" + #DEBUG + _debug header "$_H1" + _debug content "$content" + #Check if ssl plugins is aready enabled (if not => POST else => PATCH) + ssl_uuid=$(_get $KONG_URL/apis/$uuid/plugins | _egrep_o '"id":"[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}"[a-zA-Z0-9\-\,\"_\:]*"name":"ssl"' | _egrep_o '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}' ) + _debug ssl_uuid "$ssl_uuid" + if [ "$ssl_uuid" = "" ] + then + #Post certificate to Kong + response=$(_post "$content" "$KONG_URL/apis/$uuid/plugins" "" "POST" ) + else + #patch + response=$(_post "$content" "$KONG_URL/apis/$uuid/plugins/$ssl_uuid" "" "PATCH" ) + fi + if ! [ "$( echo "$response" | _egrep_o "ssl" )" = "ssl" ] + then + _err "An error occured with cert upload. Check response:" + _err "$response" + return 1 + fi + _debug response "$response" + _info "Certificate successfully deployed" +} From 07feb87deeab89fe55af42a532b463f1e3cc3ae8 Mon Sep 17 00:00:00 2001 From: Geoffroi Date: Wed, 11 Jan 2017 14:52:52 +0100 Subject: [PATCH 141/189] Travis fix --- deploy/kong.sh | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/deploy/kong.sh b/deploy/kong.sh index cd9de10c..0fa726a3 100644 --- a/deploy/kong.sh +++ b/deploy/kong.sh @@ -20,8 +20,7 @@ kong.sh_deploy() { _cca="$4" _cfullchain="$5" _info "Deploying certificate on Kong instance" - if [ -z "$KONG_URL" ] - then + if [ -z "$KONG_URL" ]; then _debug "KONG_URL Not set, using default http://localhost:8001" KONG_URL="http://localhost:8001" fi @@ -33,9 +32,8 @@ kong.sh_deploy() { _debug _cfullchain "$_cfullchain" #Get uuid linked to the domain - uuid=$( _get "$KONG_URL/apis?request_host=$_cdomain" | _normalizeJson | _egrep_o '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}' ) - if [ "$uuid" = "" ] - then + uuid=$( _get "$KONG_URL/apis?request_host=$_cdomain" | _normalizeJson | _egrep_o '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}') + if [ "$uuid" = "" ]; then _err "Unable to get Kong uuid for domain $_cdomain" _err "Make sure that KONG_URL is correctly configured" _err "Make sure that a Kong api request_host match the domain" @@ -46,7 +44,7 @@ kong.sh_deploy() { _saveaccountconf KONG_URL "$KONG_URL" #Generate DEIM delim="-----MultipartDelimeter$(date "+%s%N")" - nl=$( printf "\\r\\n" ) + nl=$(printf "\\r\\n") #Set Header _H1="Content-Type: multipart/form-data; boundary=$delim" #Generate data for request (Multipart/form-data with mixed content) @@ -62,18 +60,17 @@ kong.sh_deploy() { _debug header "$_H1" _debug content "$content" #Check if ssl plugins is aready enabled (if not => POST else => PATCH) - ssl_uuid=$(_get $KONG_URL/apis/$uuid/plugins | _egrep_o '"id":"[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}"[a-zA-Z0-9\-\,\"_\:]*"name":"ssl"' | _egrep_o '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}' ) + ssl_uuid=$(_get "$KONG_URL/apis/$uuid/plugins" | _egrep_o '"id":"[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}"[a-zA-Z0-9\-\,\"_\:]*"name":"ssl"' | _egrep_o '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}') _debug ssl_uuid "$ssl_uuid" if [ "$ssl_uuid" = "" ] then #Post certificate to Kong - response=$(_post "$content" "$KONG_URL/apis/$uuid/plugins" "" "POST" ) + response=$(_post "$content" "$KONG_URL/apis/$uuid/plugins" "" "POST") else #patch - response=$(_post "$content" "$KONG_URL/apis/$uuid/plugins/$ssl_uuid" "" "PATCH" ) + response=$(_post "$content" "$KONG_URL/apis/$uuid/plugins/$ssl_uuid" "" "PATCH") fi - if ! [ "$( echo "$response" | _egrep_o "ssl" )" = "ssl" ] - then + if ! [ "$( echo "$response" | _egrep_o "ssl" )" = "ssl" ]; then _err "An error occured with cert upload. Check response:" _err "$response" return 1 From e2cc350fbc90c18e5574361d15ce57f600eaa42c Mon Sep 17 00:00:00 2001 From: Geoffroi Date: Wed, 11 Jan 2017 14:54:52 +0100 Subject: [PATCH 142/189] Fix function name --- deploy/kong.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/kong.sh b/deploy/kong.sh index 0fa726a3..86a1835b 100644 --- a/deploy/kong.sh +++ b/deploy/kong.sh @@ -13,7 +13,7 @@ ######## Public functions ##################### #domain keyfile certfile cafile fullchain -kong.sh_deploy() { +kong_deploy() { _cdomain="$1" _ckey="$2" _ccert="$3" From 753d0e7df77b9dcf261da4547c679fec49df0961 Mon Sep 17 00:00:00 2001 From: Geoffroi Date: Wed, 11 Jan 2017 15:05:26 +0100 Subject: [PATCH 143/189] Syntax fix part 2 --- deploy/kong.sh | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/deploy/kong.sh b/deploy/kong.sh index 86a1835b..2eab3d4e 100644 --- a/deploy/kong.sh +++ b/deploy/kong.sh @@ -21,8 +21,8 @@ kong_deploy() { _cfullchain="$5" _info "Deploying certificate on Kong instance" if [ -z "$KONG_URL" ]; then - _debug "KONG_URL Not set, using default http://localhost:8001" - KONG_URL="http://localhost:8001" + _debug "KONG_URL Not set, using default http://localhost:8001" + KONG_URL="http://localhost:8001" fi _debug _cdomain "$_cdomain" @@ -32,7 +32,7 @@ kong_deploy() { _debug _cfullchain "$_cfullchain" #Get uuid linked to the domain - uuid=$( _get "$KONG_URL/apis?request_host=$_cdomain" | _normalizeJson | _egrep_o '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}') + uuid=$(_get "$KONG_URL/apis?request_host=$_cdomain" | _normalizeJson | _egrep_o '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}') if [ "$uuid" = "" ]; then _err "Unable to get Kong uuid for domain $_cdomain" _err "Make sure that KONG_URL is correctly configured" @@ -62,15 +62,14 @@ kong_deploy() { #Check if ssl plugins is aready enabled (if not => POST else => PATCH) ssl_uuid=$(_get "$KONG_URL/apis/$uuid/plugins" | _egrep_o '"id":"[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}"[a-zA-Z0-9\-\,\"_\:]*"name":"ssl"' | _egrep_o '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}') _debug ssl_uuid "$ssl_uuid" - if [ "$ssl_uuid" = "" ] - then + if [ "$ssl_uuid" = "" ]; then #Post certificate to Kong response=$(_post "$content" "$KONG_URL/apis/$uuid/plugins" "" "POST") else #patch response=$(_post "$content" "$KONG_URL/apis/$uuid/plugins/$ssl_uuid" "" "PATCH") fi - if ! [ "$( echo "$response" | _egrep_o "ssl" )" = "ssl" ]; then + if ! [ "$(echo "$response" | _egrep_o "ssl")" = "ssl" ]; then _err "An error occured with cert upload. Check response:" _err "$response" return 1 From 5fe91d65770d84e6de633384f94fcdcd5a9e6039 Mon Sep 17 00:00:00 2001 From: Geoffroi Date: Wed, 11 Jan 2017 16:17:16 +0100 Subject: [PATCH 144/189] Correction of test from comment of Neilpang + Correction of CRLF with sh not working correctly --- deploy/kong.sh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/deploy/kong.sh b/deploy/kong.sh index 2eab3d4e..3b9c5c79 100644 --- a/deploy/kong.sh +++ b/deploy/kong.sh @@ -33,7 +33,7 @@ kong_deploy() { #Get uuid linked to the domain uuid=$(_get "$KONG_URL/apis?request_host=$_cdomain" | _normalizeJson | _egrep_o '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}') - if [ "$uuid" = "" ]; then + if [ -z "$uuid" ]; then _err "Unable to get Kong uuid for domain $_cdomain" _err "Make sure that KONG_URL is correctly configured" _err "Make sure that a Kong api request_host match the domain" @@ -44,7 +44,7 @@ kong_deploy() { _saveaccountconf KONG_URL "$KONG_URL" #Generate DEIM delim="-----MultipartDelimeter$(date "+%s%N")" - nl=$(printf "\\r\\n") + nl="\015\012" #Set Header _H1="Content-Type: multipart/form-data; boundary=$delim" #Generate data for request (Multipart/form-data with mixed content) @@ -56,13 +56,15 @@ kong_deploy() { content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"config.cert\"; filename=\"$(basename "$_cfullchain")\"${nl}Content-Type: application/octet-stream${nl}${nl}$(cat "$_cfullchain")" #Close multipart content="$content${nl}--$delim--${nl}" + #Convert CRLF + content=$(printf %b "$content") #DEBUG _debug header "$_H1" _debug content "$content" #Check if ssl plugins is aready enabled (if not => POST else => PATCH) ssl_uuid=$(_get "$KONG_URL/apis/$uuid/plugins" | _egrep_o '"id":"[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}"[a-zA-Z0-9\-\,\"_\:]*"name":"ssl"' | _egrep_o '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}') _debug ssl_uuid "$ssl_uuid" - if [ "$ssl_uuid" = "" ]; then + if [ -z "$ssl_uuid" ]; then #Post certificate to Kong response=$(_post "$content" "$KONG_URL/apis/$uuid/plugins" "" "POST") else From 2fbf39915652975f0b15a4090919ac22ccc5c374 Mon Sep 17 00:00:00 2001 From: neilpang Date: Fri, 13 Jan 2017 20:49:58 +0800 Subject: [PATCH 145/189] minor --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index bd3a51b5..6eace3fd 100755 --- a/acme.sh +++ b/acme.sh @@ -4540,7 +4540,7 @@ _process() { if [ "$INSTALLONLINE" ]; then INSTALLONLINE="" - _installOnline $BRANCH + _installOnline exit fi From 3ca93f4a4c679b93361f3ae411fd0eceda813f3c Mon Sep 17 00:00:00 2001 From: Bastian Bittorf Date: Mon, 9 Jan 2017 17:04:09 +0100 Subject: [PATCH 146/189] shellcheck: fix several occurences of SC2034 message: SC2034: $VARNAME appears unused. Verify it or export it. most of these are related to the style: we generate global vars, which are used in other functions. the var "lexical_url" was really unused (left it as comment) the travis-check now does not need anymore special flags. Signed-off-by: Bastian Bittorf --- .travis.yml | 2 +- dnsapi/dns_ad.sh | 4 ++-- dnsapi/dns_aws.sh | 4 ++-- dnsapi/dns_cf.sh | 6 +++--- dnsapi/dns_cx.sh | 8 ++++---- dnsapi/dns_gd.sh | 4 ++-- dnsapi/dns_ispconfig.sh | 2 +- dnsapi/dns_lexicon.sh | 2 +- dnsapi/dns_lua.sh | 4 ++-- dnsapi/dns_me.sh | 6 +++--- dnsapi/dns_ovh.sh | 10 +++++----- dnsapi/dns_pdns.sh | 2 +- 12 files changed, 27 insertions(+), 27 deletions(-) diff --git a/.travis.yml b/.travis.yml index 1924f82a..1fff02e5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -41,7 +41,7 @@ script: - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then ~/shfmt -l -w -i 2 . ; fi - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then git diff --exit-code && echo "shfmt OK" ; fi - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then shellcheck -V ; fi - - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then shellcheck -e SC2034 **/*.sh && echo "shellcheck OK" ; fi + - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then shellcheck **/*.sh && echo "shellcheck OK" ; fi - cd .. - git clone https://github.com/Neilpang/acmetest.git && cp -r acme.sh acmetest/ && cd acmetest - if [[ "$TRAVIS_OS_NAME" == "linux" ]] && [[ "$NGROK_TOKEN" ]]; then sudo NGROK_TOKEN="$NGROK_TOKEN" ./letest.sh ; fi diff --git a/dnsapi/dns_ad.sh b/dnsapi/dns_ad.sh index 1c7e85f9..fc4a664b 100644 --- a/dnsapi/dns_ad.sh +++ b/dnsapi/dns_ad.sh @@ -127,8 +127,8 @@ _ad_rest() { _debug mtd "$mtd" _debug ep "$ep" - _H1="Accept: application/json" - _H2="Content-Type: application/json" + export _H1="Accept: application/json" + export _H2="Content-Type: application/json" if [ "$mtd" != "GET" ]; then # both POST and DELETE. diff --git a/dnsapi/dns_aws.sh b/dnsapi/dns_aws.sh index 38b03cd4..59ef6181 100644 --- a/dnsapi/dns_aws.sh +++ b/dnsapi/dns_aws.sh @@ -137,13 +137,13 @@ aws_rest() { #RequestDate="20161120T141056Z" ############## - _H1="x-amz-date: $RequestDate" + export _H1="x-amz-date: $RequestDate" aws_host="$AWS_HOST" CanonicalHeaders="host:$aws_host\nx-amz-date:$RequestDate\n" SignedHeaders="host;x-amz-date" if [ -n "$AWS_SESSION_TOKEN" ]; then - _H2="x-amz-security-token: $AWS_SESSION_TOKEN" + export _H2="x-amz-security-token: $AWS_SESSION_TOKEN" CanonicalHeaders="${CanonicalHeaders}x-amz-security-token:$AWS_SESSION_TOKEN\n" SignedHeaders="${SignedHeaders};x-amz-security-token" fi diff --git a/dnsapi/dns_cf.sh b/dnsapi/dns_cf.sh index 0b817d36..3718f9db 100755 --- a/dnsapi/dns_cf.sh +++ b/dnsapi/dns_cf.sh @@ -163,9 +163,9 @@ _cf_rest() { data="$3" _debug "$ep" - _H1="X-Auth-Email: $CF_Email" - _H2="X-Auth-Key: $CF_Key" - _H3="Content-Type: application/json" + export _H1="X-Auth-Email: $CF_Email" + export _H2="X-Auth-Key: $CF_Key" + export _H3="Content-Type: application/json" if [ "$m" != "GET" ]; then _debug data "$data" diff --git a/dnsapi/dns_cx.sh b/dnsapi/dns_cx.sh index dfc838ae..9c032fd7 100755 --- a/dnsapi/dns_cx.sh +++ b/dnsapi/dns_cx.sh @@ -193,10 +193,10 @@ _rest() { hmac=$(printf "%s" "$sec" | _digest md5 hex) _debug hmac "$hmac" - _H1="API-KEY: $CX_Key" - _H2="API-REQUEST-DATE: $cdate" - _H3="API-HMAC: $hmac" - _H4="Content-Type: application/json" + export _H1="API-KEY: $CX_Key" + export _H2="API-REQUEST-DATE: $cdate" + export _H3="API-HMAC: $hmac" + export _H4="Content-Type: application/json" if [ "$data" ]; then response="$(_post "$data" "$url" "" "$m")" diff --git a/dnsapi/dns_gd.sh b/dnsapi/dns_gd.sh index 81000561..1abeeacf 100755 --- a/dnsapi/dns_gd.sh +++ b/dnsapi/dns_gd.sh @@ -98,8 +98,8 @@ _gd_rest() { data="$3" _debug "$ep" - _H1="Authorization: sso-key $GD_Key:$GD_Secret" - _H2="Content-Type: application/json" + export _H1="Authorization: sso-key $GD_Key:$GD_Secret" + export _H2="Content-Type: application/json" if [ "$data" ]; then _debug data "$data" diff --git a/dnsapi/dns_ispconfig.sh b/dnsapi/dns_ispconfig.sh index a84d95d7..6d1f34c5 100755 --- a/dnsapi/dns_ispconfig.sh +++ b/dnsapi/dns_ispconfig.sh @@ -46,7 +46,7 @@ _ISPC_credentials() { _saveaccountconf ISPC_Api "${ISPC_Api}" _saveaccountconf ISPC_Api_Insecure "${ISPC_Api_Insecure}" # Set whether curl should use secure or insecure mode - HTTPS_INSECURE="${ISPC_Api_Insecure}" + export HTTPS_INSECURE="${ISPC_Api_Insecure}" fi } diff --git a/dnsapi/dns_lexicon.sh b/dnsapi/dns_lexicon.sh index 0398bd2e..c38ff3e3 100755 --- a/dnsapi/dns_lexicon.sh +++ b/dnsapi/dns_lexicon.sh @@ -2,7 +2,7 @@ # dns api wrapper of lexicon for acme.sh -lexicon_url="https://github.com/AnalogJ/lexicon" +# https://github.com/AnalogJ/lexicon lexicon_cmd="lexicon" wiki="https://github.com/Neilpang/acme.sh/wiki/How-to-use-lexicon-dns-api" diff --git a/dnsapi/dns_lua.sh b/dnsapi/dns_lua.sh index bc06b3ef..47f4497a 100755 --- a/dnsapi/dns_lua.sh +++ b/dnsapi/dns_lua.sh @@ -125,8 +125,8 @@ _LUA_rest() { data="$3" _debug "$ep" - _H1="Accept: application/json" - _H2="Authorization: Basic $LUA_auth" + export _H1="Accept: application/json" + export _H2="Authorization: Basic $LUA_auth" if [ "$data" ]; then _debug data "$data" response="$(_post "$data" "$LUA_Api/$ep" "" "$m")" diff --git a/dnsapi/dns_me.sh b/dnsapi/dns_me.sh index c94a3c90..9fe6baf8 100755 --- a/dnsapi/dns_me.sh +++ b/dnsapi/dns_me.sh @@ -126,9 +126,9 @@ _me_rest() { cdate=$(date -u +"%a, %d %b %Y %T %Z") hmac=$(printf "%s" "$cdate" | _hmac sha1 "$(_hex "$ME_Secret")" hex) - _H1="x-dnsme-apiKey: $ME_Key" - _H2="x-dnsme-requestDate: $cdate" - _H3="x-dnsme-hmac: $hmac" + export _H1="x-dnsme-apiKey: $ME_Key" + export _H2="x-dnsme-requestDate: $cdate" + export _H3="x-dnsme-hmac: $hmac" if [ "$data" ]; then _debug data "$data" diff --git a/dnsapi/dns_ovh.sh b/dnsapi/dns_ovh.sh index 18b9c341..8833c0a1 100755 --- a/dnsapi/dns_ovh.sh +++ b/dnsapi/dns_ovh.sh @@ -273,12 +273,12 @@ _ovh_rest() { _ovh_hex="$(printf "%s" "$_ovh_p" | _digest sha1 hex)" _debug2 _ovh_hex "$_ovh_hex" - _H1="X-Ovh-Application: $OVH_AK" - _H2="X-Ovh-Signature: \$1\$$_ovh_hex" + export _H1="X-Ovh-Application: $OVH_AK" + export _H2="X-Ovh-Signature: \$1\$$_ovh_hex" _debug2 _H2 "$_H2" - _H3="X-Ovh-Timestamp: $_ovh_t" - _H4="X-Ovh-Consumer: $OVH_CK" - _H5="Content-Type: application/json;charset=utf-8" + export _H3="X-Ovh-Timestamp: $_ovh_t" + export _H4="X-Ovh-Consumer: $OVH_CK" + export _H5="Content-Type: application/json;charset=utf-8" if [ "$data" ] || [ "$m" = "POST" ] || [ "$m" = "PUT" ]; then _debug data "$data" response="$(_post "$data" "$_ovh_url" "" "$m")" diff --git a/dnsapi/dns_pdns.sh b/dnsapi/dns_pdns.sh index 06763d88..ebc02949 100755 --- a/dnsapi/dns_pdns.sh +++ b/dnsapi/dns_pdns.sh @@ -165,7 +165,7 @@ _pdns_rest() { ep=$2 data=$3 - _H1="X-API-Key: $PDNS_Token" + export _H1="X-API-Key: $PDNS_Token" if [ ! "$method" = "GET" ]; then _debug data "$data" From 2f4b84c0743cb81d2a2f5a868da9e237777d7022 Mon Sep 17 00:00:00 2001 From: Bastian Bittorf Date: Fri, 13 Jan 2017 15:31:10 +0100 Subject: [PATCH 147/189] travis: use only POSIX constructs here, avoid bashisms e.g. [[ ]] -> [ ] and 'which' -> command -V Although this is not strictly needed, it keeps the project uniformly POSIX. Signed-off-by: Bastian Bittorf --- .travis.yml | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/.travis.yml b/.travis.yml index 1fff02e5..8d6d30ad 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,7 +17,7 @@ addons: - shellcheck install: - - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then + - if [ "$TRAVIS_OS_NAME" = 'osx' ]; then brew update && brew install openssl; brew info openssl; ln -s /usr/local/opt/openssl/lib/libcrypto.1.0.0.dylib /usr/local/lib/; @@ -35,17 +35,17 @@ install: script: - echo "TEST_LOCAL=$TEST_LOCAL" - echo "NGROK_TOKEN=$(echo "$NGROK_TOKEN" | wc -c)" - - which openssl && openssl version - - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then curl -sSL $SHFMT_URL -o ~/shfmt ; fi - - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then chmod +x ~/shfmt ; fi - - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then ~/shfmt -l -w -i 2 . ; fi - - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then git diff --exit-code && echo "shfmt OK" ; fi - - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then shellcheck -V ; fi - - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then shellcheck **/*.sh && echo "shellcheck OK" ; fi + - command -V openssl && openssl version + - if [ "$TRAVIS_OS_NAME" = "linux" ]; then curl -sSL $SHFMT_URL -o ~/shfmt ; fi + - if [ "$TRAVIS_OS_NAME" = "linux" ]; then chmod +x ~/shfmt ; fi + - if [ "$TRAVIS_OS_NAME" = "linux" ]; then ~/shfmt -l -w -i 2 . ; fi + - if [ "$TRAVIS_OS_NAME" = "linux" ]; then git diff --exit-code && echo "shfmt OK" ; fi + - if [ "$TRAVIS_OS_NAME" = "linux" ]; then shellcheck -V ; fi + - if [ "$TRAVIS_OS_NAME" = "linux" ]; then shellcheck **/*.sh && echo "shellcheck OK" ; fi - cd .. - git clone https://github.com/Neilpang/acmetest.git && cp -r acme.sh acmetest/ && cd acmetest - - if [[ "$TRAVIS_OS_NAME" == "linux" ]] && [[ "$NGROK_TOKEN" ]]; then sudo NGROK_TOKEN="$NGROK_TOKEN" ./letest.sh ; fi - - if [[ "$TRAVIS_OS_NAME" == "osx" ]] && [[ "$NGROK_TOKEN" ]]; then sudo NGROK_TOKEN="$NGROK_TOKEN" OPENSSL_BIN="$OPENSSL_BIN" ./letest.sh ; fi + - if [ "$TRAVIS_OS_NAME" = "linux" -a "$NGROK_TOKEN" ]; then sudo NGROK_TOKEN="$NGROK_TOKEN" ./letest.sh ; fi + - if [ "$TRAVIS_OS_NAME" = "osx" -a "$NGROK_TOKEN" ]; then sudo NGROK_TOKEN="$NGROK_TOKEN" OPENSSL_BIN="$OPENSSL_BIN" ./letest.sh ; fi matrix: From 38f2334360301396cd2baa6dd3eb899fd01cb00a Mon Sep 17 00:00:00 2001 From: Philipp Grosswiler Date: Mon, 16 Jan 2017 15:42:17 +0700 Subject: [PATCH 148/189] Added support for Linode DNS API. --- README.md | 1 + dnsapi/README.md | 19 ++++++++++++++ dnsapi/dns_linode.sh | 60 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 80 insertions(+) create mode 100755 dnsapi/dns_linode.sh diff --git a/README.md b/README.md index 9b5891c9..ea0e0de7 100644 --- a/README.md +++ b/README.md @@ -266,6 +266,7 @@ You don't have to do anything manually! 1. aliyun.com(阿里云) API 1. ISPConfig 3.1 API 1. Alwaysdata.com API +1. Linode.com API **More APIs coming soon...** diff --git a/dnsapi/README.md b/dnsapi/README.md index e32b4655..1895d376 100644 --- a/dnsapi/README.md +++ b/dnsapi/README.md @@ -257,6 +257,25 @@ acme.sh --issue --dns dns_ad -d example.com -d www.example.com The `AD_API_KEY` will be saved in `~/.acme.sh/account.conf` and will be reused when needed. +## 14. Use Linode domain API + +You will need to install the Linode CLI and set it up accordingly. + +[https://www.linode.com/docs/platform/linode-cli](https://www.linode.com/docs/platform/linode-cli) + +Follow the installation instructions appropriate for your platform and then run the configuration. + +```linode configure +``` + +Make sure Linode CLI is working correctly before proceeding. + +Due to the reload time of any changes in the DNS records, we have to use the `dnssleep` option to wait at least 15 minutes for the changes to take effect. + +```sh +acme.sh --issue --dns dns_linode --dnssleep 900 -d example.com -d www.example.com +``` + # Use custom API If your API is not supported yet, you can write your own DNS API. diff --git a/dnsapi/dns_linode.sh b/dnsapi/dns_linode.sh new file mode 100755 index 00000000..0af1ad7c --- /dev/null +++ b/dnsapi/dns_linode.sh @@ -0,0 +1,60 @@ +#!/usr/bin/env bash + +linode_cmd="/usr/bin/linode" + +######## Public functions ##################### + +#Usage: dns_linode_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_linode_add() { + fulldomain="${1}" + txtvalue="${2}" + + _info "Using Linode" + _debug "Calling: dns_linode_add() '${fulldomain}' '${txtvalue}'" + + domain=$(printf "%s" "${fulldomain}" | cut -d . -f 3-999) + name=$(printf "%s" "${fulldomain}" | cut -d . -f 1-2) + _debug name "${name}" + _debug domain "${domain}" + + _Linode_CLI && _Linode_addTXT +} + +#Usage: dns_linode_rm _acme-challenge.www.domain.com +dns_linode_rm() { + fulldomain="${1}" + + _info "Using Linode" + _debug "Calling: dns_linode_rm() '${fulldomain}'" + + domain=$(printf "%s" "${fulldomain}" | cut -d . -f 3-999) + name=$(printf "%s" "${fulldomain}" | cut -d . -f 1-2) + _debug name "${name}" + _debug domain "${domain}" + + _Linode_CLI && _Linode_rmTXT +} + +#################### Private functions below ################################## + +_Linode_CLI() { + if [ ! -f "${linode_cmd}" ]; then + _err "Please install the Linode CLI package and set it up accordingly before using this DNS API." + return 1 + fi +} + +_Linode_addTXT() { + _debug "$linode_cmd domain record-update ${domain} TXT ${name} --target ${txtvalue}" + $linode_cmd domain record-update ${domain} TXT ${name} --target ${txtvalue} + + if [ $? -ne 0 ]; then + _debug "$linode_cmd domain record-create ${domain} TXT ${name} ${txtvalue}" + $linode_cmd domain record-create ${domain} TXT ${name} ${txtvalue} + fi +} + +_Linode_rmTXT() { + _debug "$linode_cmd domain record-delete ${domain} TXT ${name}" + $linode_cmd domain record-delete ${domain} TXT ${name} +} From 27dbe77fad0e59ad9bce55df8d165ca512be0c65 Mon Sep 17 00:00:00 2001 From: neilpang Date: Mon, 16 Jan 2017 22:31:24 +0800 Subject: [PATCH 149/189] add "--config-home" --- acme.sh | 110 +++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 74 insertions(+), 36 deletions(-) diff --git a/acme.sh b/acme.sh index 6eace3fd..0cbae7ba 100755 --- a/acme.sh +++ b/acme.sh @@ -1,6 +1,6 @@ #!/usr/bin/env sh -VER=2.6.5 +VER=2.6.6 PROJECT_NAME="acme.sh" @@ -1634,7 +1634,11 @@ __initHome() { fi export LE_WORKING_DIR - _DEFAULT_ACCOUNT_CONF_PATH="$LE_WORKING_DIR/account.conf" + if [ -z "$CONFIG_HOME" ]; then + CONFIG_HOME="$LE_WORKING_DIR" + fi + + _DEFAULT_ACCOUNT_CONF_PATH="$CONFIG_HOME/account.conf" if [ -z "$ACCOUNT_CONF_PATH" ]; then if [ -f "$_DEFAULT_ACCOUNT_CONF_PATH" ]; then @@ -1646,12 +1650,12 @@ __initHome() { ACCOUNT_CONF_PATH="$_DEFAULT_ACCOUNT_CONF_PATH" fi - DEFAULT_LOG_FILE="$LE_WORKING_DIR/$PROJECT_NAME.log" + DEFAULT_LOG_FILE="$CONFIG_HOME/$PROJECT_NAME.log" - DEFAULT_CA_HOME="$LE_WORKING_DIR/ca" + DEFAULT_CA_HOME="$CONFIG_HOME/ca" if [ -z "$LE_TEMP_DIR" ]; then - LE_TEMP_DIR="$LE_WORKING_DIR/tmp" + LE_TEMP_DIR="$CONFIG_HOME/tmp" fi } @@ -1703,7 +1707,7 @@ _initpath() { fi if [ -z "$APACHE_CONF_BACKUP_DIR" ]; then - APACHE_CONF_BACKUP_DIR="$LE_WORKING_DIR" + APACHE_CONF_BACKUP_DIR="$CONFIG_HOME" fi if [ -z "$USER_AGENT" ]; then @@ -1711,7 +1715,7 @@ _initpath() { fi if [ -z "$HTTP_HEADER" ]; then - HTTP_HEADER="$LE_WORKING_DIR/http.header" + HTTP_HEADER="$CONFIG_HOME/http.header" fi _OLD_ACCOUNT_KEY="$LE_WORKING_DIR/account.key" @@ -1727,7 +1731,7 @@ _initpath() { ACCOUNT_JSON_PATH="$_DEFAULT_ACCOUNT_JSON_PATH" fi - _DEFAULT_CERT_HOME="$LE_WORKING_DIR" + _DEFAULT_CERT_HOME="$CONFIG_HOME" if [ -z "$CERT_HOME" ]; then CERT_HOME="$_DEFAULT_CERT_HOME" fi @@ -3350,7 +3354,9 @@ _installcert() { } +#confighome installcronjob() { + _c_home="$1" _initpath if ! _exists "crontab"; then _err "crontab doesn't exist, so, we can not install cron jobs." @@ -3367,15 +3373,20 @@ installcronjob() { _err "Can not install cronjob, $PROJECT_ENTRY not found." return 1 fi + + if [ "$_c_home" ]; then + _c_entry="--config-home \"$_c_home\"" + fi + if _exists uname && uname -a | grep SunOS >/dev/null; then crontab -l | { cat - echo "0 0 * * * $lesh --cron --home \"$LE_WORKING_DIR\" > /dev/null" + echo "0 0 * * * $lesh --cron --home \"$LE_WORKING_DIR\" $_c_entry > /dev/null" } | crontab -- else crontab -l | { cat - echo "0 0 * * * $lesh --cron --home \"$LE_WORKING_DIR\" > /dev/null" + echo "0 0 * * * $lesh --cron --home \"$LE_WORKING_DIR\" $_c_entry > /dev/null" } | crontab - fi fi @@ -3401,6 +3412,10 @@ uninstallcronjob() { fi LE_WORKING_DIR="$(echo "$cr" | cut -d ' ' -f 9 | tr -d '"')" _info LE_WORKING_DIR "$LE_WORKING_DIR" + if _contains "$cr" "--config-home"; then + CONFIG_HOME="$(echo "$cr" | cut -d ' ' -f 11 | tr -d '"')" + _debug CONFIG_HOME "$CONFIG_HOME" + fi fi _initpath @@ -3664,7 +3679,9 @@ _setShebang() { rm -f "$_file.tmp" } +#confighome _installalias() { + _c_home="$1" _initpath _envfile="$LE_WORKING_DIR/$PROJECT_ENTRY.env" @@ -3674,8 +3691,12 @@ _installalias() { echo "$(cat "$_envfile")" | sed "s|^alias le.sh.*$||" >"$_envfile" fi + if [ "$_c_home" ]; then + _c_entry="--config-home '$_c_home'" + fi + _setopt "$_envfile" "export LE_WORKING_DIR" "=" "\"$LE_WORKING_DIR\"" - _setopt "$_envfile" "alias $PROJECT_ENTRY" "=" "\"$LE_WORKING_DIR/$PROJECT_ENTRY\"" + _setopt "$_envfile" "alias $PROJECT_ENTRY" "=" "\"$LE_WORKING_DIR/$PROJECT_ENTRY $_c_entry\"" _profile="$(_detect_profile)" if [ "$_profile" ]; then @@ -3693,7 +3714,7 @@ _installalias() { if [ -f "$_csh_profile" ]; then _info "Installing alias to '$_csh_profile'" _setopt "$_cshfile" "setenv LE_WORKING_DIR" " " "\"$LE_WORKING_DIR\"" - _setopt "$_cshfile" "alias $PROJECT_ENTRY" " " "\"$LE_WORKING_DIR/$PROJECT_ENTRY\"" + _setopt "$_cshfile" "alias $PROJECT_ENTRY" " " "\"$LE_WORKING_DIR/$PROJECT_ENTRY $_c_entry\"" _setopt "$_csh_profile" "source \"$_cshfile\"" fi @@ -3702,13 +3723,13 @@ _installalias() { if [ -f "$_tcsh_profile" ]; then _info "Installing alias to '$_tcsh_profile'" _setopt "$_cshfile" "setenv LE_WORKING_DIR" " " "\"$LE_WORKING_DIR\"" - _setopt "$_cshfile" "alias $PROJECT_ENTRY" " " "\"$LE_WORKING_DIR/$PROJECT_ENTRY\"" + _setopt "$_cshfile" "alias $PROJECT_ENTRY" " " "\"$LE_WORKING_DIR/$PROJECT_ENTRY $_c_entry\"" _setopt "$_tcsh_profile" "source \"$_cshfile\"" fi } -# nocron +# nocron confighome install() { if [ -z "$LE_WORKING_DIR" ]; then @@ -3716,6 +3737,7 @@ install() { fi _nocron="$1" + _c_home="$2" if ! _initpath; then _err "Install failed." return 1 @@ -3754,6 +3776,13 @@ install() { chmod 700 "$LE_WORKING_DIR" + if ! mkdir -p "$CONFIG_HOME"; then + _err "Can not create config dir: $CONFIG_HOME" + return 1 + fi + + chmod 700 "$CONFIG_HOME" + cp "$PROJECT_ENTRY" "$LE_WORKING_DIR/" && chmod +x "$LE_WORKING_DIR/$PROJECT_ENTRY" if [ "$?" != "0" ]; then @@ -3763,7 +3792,7 @@ install() { _info "Installed to $LE_WORKING_DIR/$PROJECT_ENTRY" - _installalias + _installalias "$_c_home" for subf in $_SUB_FOLDERS; do if [ -d "$subf" ]; then @@ -3789,7 +3818,7 @@ install() { fi if [ -z "$_nocron" ]; then - installcronjob + installcronjob "$_c_home" fi if [ -z "$NO_DETECT_SH" ]; then @@ -3822,7 +3851,7 @@ uninstall() { _uninstallalias rm -f "$LE_WORKING_DIR/$PROJECT_ENTRY" - _info "The keys and certs are in $LE_WORKING_DIR, you can remove them by yourself." + _info "The keys and certs are in \"$(__green "$CONFIG_HOME")\", you can remove them by yourself." } @@ -3895,18 +3924,18 @@ Commands: --issue Issue a cert. --signcsr Issue a cert from an existing csr. --deploy Deploy the cert to your server. - --installcert Install the issued cert to apache/nginx or any other server. + --install-cert Install the issued cert to apache/nginx or any other server. --renew, -r Renew a cert. - --renewAll Renew all the certs. + --renew-all Renew all the certs. --revoke Revoke a cert. --list List all the certs. --showcsr Show the content of a csr. - --installcronjob Install the cron job to renew certs, you don't need to call this. The 'install' command can automatically install the cron job. - --uninstallcronjob Uninstall the cron job. The 'uninstall' command can do this automatically. + --install-cronjob Install the cron job to renew certs, you don't need to call this. The 'install' command can automatically install the cron job. + --uninstall-cronjob Uninstall the cron job. The 'uninstall' command can do this automatically. --cron Run cron job to renew all the certs. --toPkcs Export the certificate and key to a pfx file. - --updateaccount Update account info. - --registeraccount Register account key. + --update-account Update account info. + --register-account Register account key. --createAccountKey, -cak Create an account private key, professional use. --createDomainKey, -cdk Create an domain private key, professional use. --createCSR, -ccsr Create CSR , professional use. @@ -3941,7 +3970,8 @@ Parameters: --accountconf Specifies a customized account config file. --home Specifies the home dir for $PROJECT_NAME . - --certhome Specifies the home dir to save all the certs, only valid for '--install' command. + --cert-home Specifies the home dir to save all the certs, only valid for '--install' command. + --config-home Specifies the home dir to save all the configurations. --useragent Specifies the user agent string. it will be saved for future use too. --accountemail Specifies the account email for registering, Only valid for the '--install' command. --accountkey Specifies the account key path, Only valid for the '--install' command. @@ -3950,11 +3980,11 @@ Parameters: --tlsport Specifies the standalone tls listening port. Only valid if the server is behind a reverse proxy or load balancer. --local-address Specifies the standalone/tls server listening address, in case you have multiple ip addresses. --listraw Only used for '--list' command, list the certs in raw format. - --stopRenewOnError, -se Only valid for '--renewall' command. Stop if one cert has error in renewal. + --stopRenewOnError, -se Only valid for '--renew-all' command. Stop if one cert has error in renewal. --insecure Do not check the server certificate, in some devices, the api server's certificate may not be trusted. --ca-bundle Specifices the path to the CA certificate bundle to verify api server's certificate. --nocron Only valid for '--install' command, which means: do not install the default cron job. In this case, the certs will not be renewed automatically. - --ecc Specifies to use the ECC cert. Valid for '--installcert', '--renew', '--revoke', '--toPkcs' and '--createCSR' + --ecc Specifies to use the ECC cert. Valid for '--install-cert', '--renew', '--revoke', '--toPkcs' and '--createCSR' --csr Specifies the input csr. --pre-hook Command to be run before obtaining any certificates. --post-hook Command to be run after attempting to obtain/renew certificates. No matter the obain/renew is success or failed. @@ -4063,6 +4093,7 @@ _process() { _accountemail="" _accountkey="" _certhome="" + _confighome="" _httpport="" _tlsport="" _dnssleep="" @@ -4117,13 +4148,13 @@ _process() { --showcsr) _CMD="showcsr" ;; - --installcert | -i) + --installcert | -i|--install-cert) _CMD="installcert" ;; --renew | -r) _CMD="renew" ;; - --renewAll | --renewall) + --renewAll | --renewall|--renew-all) _CMD="renewAll" ;; --revoke) @@ -4132,10 +4163,10 @@ _process() { --list) _CMD="list" ;; - --installcronjob) + --installcronjob|--install-cronjob) _CMD="installcronjob" ;; - --uninstallcronjob) + --uninstallcronjob|--install-cronjob) _CMD="uninstallcronjob" ;; --cron) @@ -4156,10 +4187,10 @@ _process() { --deactivate) _CMD="deactivate" ;; - --updateaccount) + --updateaccount|--update-account) _CMD="updateaccount" ;; - --registeraccount) + --registeraccount|--register-account) _CMD="registeraccount" ;; --domain | -d) @@ -4301,11 +4332,16 @@ _process() { LE_WORKING_DIR="$2" shift ;; - --certhome) + --certhome|--cert-home) _certhome="$2" CERT_HOME="$_certhome" shift ;; + --config-home) + _confighome="$2" + CONFIG_HOME="$_confighome" + shift + ;; --useragent) _useragent="$2" USER_AGENT="$_useragent" @@ -4456,7 +4492,7 @@ _process() { fi case "${_CMD}" in - install) install "$_nocron" ;; + install) install "$_nocron" "$_confighome" ;; uninstall) uninstall "$_nocron" ;; upgrade) upgrade ;; issue) @@ -4495,7 +4531,7 @@ _process() { list) list "$_listraw" ;; - installcronjob) installcronjob ;; + installcronjob) installcronjob "$_confighome" ;; uninstallcronjob) uninstallcronjob ;; cron) cron ;; toPkcs) @@ -4512,7 +4548,9 @@ _process() { ;; *) - _err "Invalid command: $_CMD" + if [ "$_CMD" ]; then + _err "Invalid command: $_CMD" + fi showhelp return 1 ;; From 80941f84137c45014da23d7e3db17e3d267305c9 Mon Sep 17 00:00:00 2001 From: neilpang Date: Mon, 16 Jan 2017 22:36:13 +0800 Subject: [PATCH 150/189] minor --- acme.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/acme.sh b/acme.sh index 0cbae7ba..07500eed 100755 --- a/acme.sh +++ b/acme.sh @@ -3375,18 +3375,18 @@ installcronjob() { fi if [ "$_c_home" ]; then - _c_entry="--config-home \"$_c_home\"" + _c_entry="--config-home \"$_c_home\" " fi if _exists uname && uname -a | grep SunOS >/dev/null; then crontab -l | { cat - echo "0 0 * * * $lesh --cron --home \"$LE_WORKING_DIR\" $_c_entry > /dev/null" + echo "0 0 * * * $lesh --cron --home \"$LE_WORKING_DIR\" $_c_entry> /dev/null" } | crontab -- else crontab -l | { cat - echo "0 0 * * * $lesh --cron --home \"$LE_WORKING_DIR\" $_c_entry > /dev/null" + echo "0 0 * * * $lesh --cron --home \"$LE_WORKING_DIR\" $_c_entry> /dev/null" } | crontab - fi fi From ee20015d4460b2b9bd5647f9e3d4e5f9bd1dbc6d Mon Sep 17 00:00:00 2001 From: neil Date: Tue, 17 Jan 2017 13:04:02 +0800 Subject: [PATCH 151/189] fix format --- acme.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/acme.sh b/acme.sh index 07500eed..b58a3f47 100755 --- a/acme.sh +++ b/acme.sh @@ -4148,7 +4148,7 @@ _process() { --showcsr) _CMD="showcsr" ;; - --installcert | -i|--install-cert) + --installcert | -i| --install-cert) _CMD="installcert" ;; --renew | -r) @@ -4163,10 +4163,10 @@ _process() { --list) _CMD="list" ;; - --installcronjob|--install-cronjob) + --installcronjob | --install-cronjob) _CMD="installcronjob" ;; - --uninstallcronjob|--install-cronjob) + --uninstallcronjob|--uninstall-cronjob) _CMD="uninstallcronjob" ;; --cron) @@ -4187,10 +4187,10 @@ _process() { --deactivate) _CMD="deactivate" ;; - --updateaccount|--update-account) + --updateaccount | --update-account) _CMD="updateaccount" ;; - --registeraccount|--register-account) + --registeraccount | --register-account) _CMD="registeraccount" ;; --domain | -d) @@ -4332,7 +4332,7 @@ _process() { LE_WORKING_DIR="$2" shift ;; - --certhome|--cert-home) + --certhome | --cert-home) _certhome="$2" CERT_HOME="$_certhome" shift From db7e4bf9405c55e2361a8f2140c60b092c6c1d3c Mon Sep 17 00:00:00 2001 From: neil Date: Tue, 17 Jan 2017 13:06:44 +0800 Subject: [PATCH 152/189] fix format --- acme.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/acme.sh b/acme.sh index b58a3f47..c24b019d 100755 --- a/acme.sh +++ b/acme.sh @@ -4148,13 +4148,13 @@ _process() { --showcsr) _CMD="showcsr" ;; - --installcert | -i| --install-cert) + --installcert | -i | --install-cert) _CMD="installcert" ;; --renew | -r) _CMD="renew" ;; - --renewAll | --renewall|--renew-all) + --renewAll | --renewall | --renew-all) _CMD="renewAll" ;; --revoke) @@ -4166,7 +4166,7 @@ _process() { --installcronjob | --install-cronjob) _CMD="installcronjob" ;; - --uninstallcronjob|--uninstall-cronjob) + --uninstallcronjob | --uninstall-cronjob) _CMD="uninstallcronjob" ;; --cron) From 2aff36e74b4cf406bbd74ecf80dca64a0aef8d10 Mon Sep 17 00:00:00 2001 From: neilpang Date: Tue, 17 Jan 2017 20:13:15 +0800 Subject: [PATCH 153/189] fix comma in domain --- acme.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/acme.sh b/acme.sh index 6eace3fd..66abd882 100755 --- a/acme.sh +++ b/acme.sh @@ -2391,6 +2391,10 @@ issue() { Le_Webroot="$1" Le_Domain="$2" Le_Alt="$3" + if _contains "$Le_Domain" ","; then + Le_Domain=$(echo "$2,$3" | cut -d , -f 1) + Le_Alt=$(echo "$2,$3" | cut -d , -f 2- | sed "s/,${NO_VALUE}$//") + fi Le_Keylength="$4" Le_RealCertPath="$5" Le_RealKeyPath="$6" From 32b3717c32196dea163e87b40d428774fded5c25 Mon Sep 17 00:00:00 2001 From: neilpang Date: Tue, 17 Jan 2017 21:49:02 +0800 Subject: [PATCH 154/189] random minute --- acme.sh | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/acme.sh b/acme.sh index 66abd882..49f3c3fd 100755 --- a/acme.sh +++ b/acme.sh @@ -3371,15 +3371,18 @@ installcronjob() { _err "Can not install cronjob, $PROJECT_ENTRY not found." return 1 fi + + _t=$(_time) + random_minute=$(_math $_t % 60) if _exists uname && uname -a | grep SunOS >/dev/null; then crontab -l | { cat - echo "0 0 * * * $lesh --cron --home \"$LE_WORKING_DIR\" > /dev/null" + echo "$random_minute 0 * * * $lesh --cron --home \"$LE_WORKING_DIR\" > /dev/null" } | crontab -- else crontab -l | { cat - echo "0 0 * * * $lesh --cron --home \"$LE_WORKING_DIR\" > /dev/null" + echo "$random_minute 0 * * * $lesh --cron --home \"$LE_WORKING_DIR\" > /dev/null" } | crontab - fi fi From 0f21537f148e0522d305713b66677de387d95b28 Mon Sep 17 00:00:00 2001 From: neilpang Date: Tue, 17 Jan 2017 22:01:36 +0800 Subject: [PATCH 155/189] format --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 49f3c3fd..0ee1eeee 100755 --- a/acme.sh +++ b/acme.sh @@ -3371,7 +3371,7 @@ installcronjob() { _err "Can not install cronjob, $PROJECT_ENTRY not found." return 1 fi - + _t=$(_time) random_minute=$(_math $_t % 60) if _exists uname && uname -a | grep SunOS >/dev/null; then From f5b546b3c8c437b2e43406ac15df575e34210a9b Mon Sep 17 00:00:00 2001 From: neilpang Date: Sat, 21 Jan 2017 11:28:10 +0800 Subject: [PATCH 156/189] rename to LE_CONFIG_HOME --- acme.sh | 43 +++++++++++++++++++++++++++---------------- 1 file changed, 27 insertions(+), 16 deletions(-) diff --git a/acme.sh b/acme.sh index b9da2f46..33fd6201 100755 --- a/acme.sh +++ b/acme.sh @@ -1634,11 +1634,13 @@ __initHome() { fi export LE_WORKING_DIR - if [ -z "$CONFIG_HOME" ]; then - CONFIG_HOME="$LE_WORKING_DIR" + if [ -z "$LE_CONFIG_HOME" ]; then + LE_CONFIG_HOME="$LE_WORKING_DIR" fi + _debug "Using config home:$LE_CONFIG_HOME" + export LE_CONFIG_HOME - _DEFAULT_ACCOUNT_CONF_PATH="$CONFIG_HOME/account.conf" + _DEFAULT_ACCOUNT_CONF_PATH="$LE_CONFIG_HOME/account.conf" if [ -z "$ACCOUNT_CONF_PATH" ]; then if [ -f "$_DEFAULT_ACCOUNT_CONF_PATH" ]; then @@ -1650,12 +1652,12 @@ __initHome() { ACCOUNT_CONF_PATH="$_DEFAULT_ACCOUNT_CONF_PATH" fi - DEFAULT_LOG_FILE="$CONFIG_HOME/$PROJECT_NAME.log" + DEFAULT_LOG_FILE="$LE_CONFIG_HOME/$PROJECT_NAME.log" - DEFAULT_CA_HOME="$CONFIG_HOME/ca" + DEFAULT_CA_HOME="$LE_CONFIG_HOME/ca" if [ -z "$LE_TEMP_DIR" ]; then - LE_TEMP_DIR="$CONFIG_HOME/tmp" + LE_TEMP_DIR="$LE_CONFIG_HOME/tmp" fi } @@ -1707,7 +1709,7 @@ _initpath() { fi if [ -z "$APACHE_CONF_BACKUP_DIR" ]; then - APACHE_CONF_BACKUP_DIR="$CONFIG_HOME" + APACHE_CONF_BACKUP_DIR="$LE_CONFIG_HOME" fi if [ -z "$USER_AGENT" ]; then @@ -1715,7 +1717,7 @@ _initpath() { fi if [ -z "$HTTP_HEADER" ]; then - HTTP_HEADER="$CONFIG_HOME/http.header" + HTTP_HEADER="$LE_CONFIG_HOME/http.header" fi _OLD_ACCOUNT_KEY="$LE_WORKING_DIR/account.key" @@ -1731,7 +1733,7 @@ _initpath() { ACCOUNT_JSON_PATH="$_DEFAULT_ACCOUNT_JSON_PATH" fi - _DEFAULT_CERT_HOME="$CONFIG_HOME" + _DEFAULT_CERT_HOME="$LE_CONFIG_HOME" if [ -z "$CERT_HOME" ]; then CERT_HOME="$_DEFAULT_CERT_HOME" fi @@ -3418,8 +3420,8 @@ uninstallcronjob() { LE_WORKING_DIR="$(echo "$cr" | cut -d ' ' -f 9 | tr -d '"')" _info LE_WORKING_DIR "$LE_WORKING_DIR" if _contains "$cr" "--config-home"; then - CONFIG_HOME="$(echo "$cr" | cut -d ' ' -f 11 | tr -d '"')" - _debug CONFIG_HOME "$CONFIG_HOME" + LE_CONFIG_HOME="$(echo "$cr" | cut -d ' ' -f 11 | tr -d '"')" + _debug LE_CONFIG_HOME "$LE_CONFIG_HOME" fi fi _initpath @@ -3701,6 +3703,9 @@ _installalias() { fi _setopt "$_envfile" "export LE_WORKING_DIR" "=" "\"$LE_WORKING_DIR\"" + if [ "$_c_home" ]; then + _setopt "$_envfile" "export LE_CONFIG_HOME" "=" "\"$LE_CONFIG_HOME\"" + fi _setopt "$_envfile" "alias $PROJECT_ENTRY" "=" "\"$LE_WORKING_DIR/$PROJECT_ENTRY $_c_entry\"" _profile="$(_detect_profile)" @@ -3719,6 +3724,9 @@ _installalias() { if [ -f "$_csh_profile" ]; then _info "Installing alias to '$_csh_profile'" _setopt "$_cshfile" "setenv LE_WORKING_DIR" " " "\"$LE_WORKING_DIR\"" + if [ "$_c_home" ]; then + _setopt "$_cshfile" "setenv LE_CONFIG_HOME" " " "\"$LE_CONFIG_HOME\"" + fi _setopt "$_cshfile" "alias $PROJECT_ENTRY" " " "\"$LE_WORKING_DIR/$PROJECT_ENTRY $_c_entry\"" _setopt "$_csh_profile" "source \"$_cshfile\"" fi @@ -3728,6 +3736,9 @@ _installalias() { if [ -f "$_tcsh_profile" ]; then _info "Installing alias to '$_tcsh_profile'" _setopt "$_cshfile" "setenv LE_WORKING_DIR" " " "\"$LE_WORKING_DIR\"" + if [ "$_c_home" ]; then + _setopt "$_cshfile" "setenv LE_CONFIG_HOME" " " "\"$LE_CONFIG_HOME\"" + fi _setopt "$_cshfile" "alias $PROJECT_ENTRY" " " "\"$LE_WORKING_DIR/$PROJECT_ENTRY $_c_entry\"" _setopt "$_tcsh_profile" "source \"$_cshfile\"" fi @@ -3781,12 +3792,12 @@ install() { chmod 700 "$LE_WORKING_DIR" - if ! mkdir -p "$CONFIG_HOME"; then - _err "Can not create config dir: $CONFIG_HOME" + if ! mkdir -p "$LE_CONFIG_HOME"; then + _err "Can not create config dir: $LE_CONFIG_HOME" return 1 fi - chmod 700 "$CONFIG_HOME" + chmod 700 "$LE_CONFIG_HOME" cp "$PROJECT_ENTRY" "$LE_WORKING_DIR/" && chmod +x "$LE_WORKING_DIR/$PROJECT_ENTRY" @@ -3856,7 +3867,7 @@ uninstall() { _uninstallalias rm -f "$LE_WORKING_DIR/$PROJECT_ENTRY" - _info "The keys and certs are in \"$(__green "$CONFIG_HOME")\", you can remove them by yourself." + _info "The keys and certs are in \"$(__green "$LE_CONFIG_HOME")\", you can remove them by yourself." } @@ -4344,7 +4355,7 @@ _process() { ;; --config-home) _confighome="$2" - CONFIG_HOME="$_confighome" + LE_CONFIG_HOME="$_confighome" shift ;; --useragent) From be83a6a37ac7cfba048db5e06b04b9486ebf1fd5 Mon Sep 17 00:00:00 2001 From: neilpang Date: Sat, 21 Jan 2017 12:40:43 +0800 Subject: [PATCH 157/189] minor, fix alias --- acme.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/acme.sh b/acme.sh index 33fd6201..d9cd0228 100755 --- a/acme.sh +++ b/acme.sh @@ -3699,14 +3699,14 @@ _installalias() { fi if [ "$_c_home" ]; then - _c_entry="--config-home '$_c_home'" + _c_entry=" --config-home '$_c_home'" fi _setopt "$_envfile" "export LE_WORKING_DIR" "=" "\"$LE_WORKING_DIR\"" if [ "$_c_home" ]; then _setopt "$_envfile" "export LE_CONFIG_HOME" "=" "\"$LE_CONFIG_HOME\"" fi - _setopt "$_envfile" "alias $PROJECT_ENTRY" "=" "\"$LE_WORKING_DIR/$PROJECT_ENTRY $_c_entry\"" + _setopt "$_envfile" "alias $PROJECT_ENTRY" "=" "\"$LE_WORKING_DIR/$PROJECT_ENTRY$_c_entry\"" _profile="$(_detect_profile)" if [ "$_profile" ]; then @@ -3727,7 +3727,7 @@ _installalias() { if [ "$_c_home" ]; then _setopt "$_cshfile" "setenv LE_CONFIG_HOME" " " "\"$LE_CONFIG_HOME\"" fi - _setopt "$_cshfile" "alias $PROJECT_ENTRY" " " "\"$LE_WORKING_DIR/$PROJECT_ENTRY $_c_entry\"" + _setopt "$_cshfile" "alias $PROJECT_ENTRY" " " "\"$LE_WORKING_DIR/$PROJECT_ENTRY$_c_entry\"" _setopt "$_csh_profile" "source \"$_cshfile\"" fi @@ -3739,7 +3739,7 @@ _installalias() { if [ "$_c_home" ]; then _setopt "$_cshfile" "setenv LE_CONFIG_HOME" " " "\"$LE_CONFIG_HOME\"" fi - _setopt "$_cshfile" "alias $PROJECT_ENTRY" " " "\"$LE_WORKING_DIR/$PROJECT_ENTRY $_c_entry\"" + _setopt "$_cshfile" "alias $PROJECT_ENTRY" " " "\"$LE_WORKING_DIR/$PROJECT_ENTRY$_c_entry\"" _setopt "$_tcsh_profile" "source \"$_cshfile\"" fi From 78f0201dfafede2ef68a5776ab5f80a6d196d3af Mon Sep 17 00:00:00 2001 From: neilpang Date: Sat, 21 Jan 2017 13:32:12 +0800 Subject: [PATCH 158/189] add --remove --- acme.sh | 40 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index d9cd0228..2dc16e5a 100755 --- a/acme.sh +++ b/acme.sh @@ -3431,7 +3431,7 @@ uninstallcronjob() { revoke() { Le_Domain="$1" if [ -z "$Le_Domain" ]; then - _usage "Usage: $PROJECT_ENTRY --revoke -d domain.com" + _usage "Usage: $PROJECT_ENTRY --revoke -d domain.com [--ecc]" return 1 fi @@ -3489,6 +3489,37 @@ revoke() { return 1 } +#domain ecc +remove() { + Le_Domain="$1" + if [ -z "$Le_Domain" ]; then + _usage "Usage: $PROJECT_ENTRY --remove -d domain.com [--ecc]" + return 1 + fi + + _isEcc="$2" + + _initpath "$Le_Domain" "$_isEcc" + _removed_conf="$DOMAIN_CONF.removed" + if [ ! -f "$DOMAIN_CONF" ]; then + if [ -f "$_removed_conf" ]; then + _err "$Le_Domain is already removed, You can remove the folder by yourself: $DOMAIN_PATH" + else + _err "$Le_Domain is not a issued domain, skip." + fi + return 1 + fi + + if mv "$DOMAIN_CONF" "$_removed_conf"; then + _info "$Le_Domain is removed, the key and cert files are in $(__green $DOMAIN_PATH )" + _info "You can remove them by yourself." + return 0 + else + _err "Remove $Le_Domain failed." + return 1 + fi +} + #domain vtype _deactivate() { _d_domain="$1" @@ -3944,6 +3975,7 @@ Commands: --renew, -r Renew a cert. --renew-all Renew all the certs. --revoke Revoke a cert. + --remove Remove the cert from $PROJECT --list List all the certs. --showcsr Show the content of a csr. --install-cronjob Install the cron job to renew certs, you don't need to call this. The 'install' command can automatically install the cron job. @@ -4176,6 +4208,9 @@ _process() { --revoke) _CMD="revoke" ;; + --remove) + _CMD="remove" + ;; --list) _CMD="list" ;; @@ -4535,6 +4570,9 @@ _process() { revoke) revoke "$_domain" "$_ecc" ;; + remove) + remove "$_domain" "$_ecc" + ;; deactivate) deactivate "$_domain,$_altdomains" ;; From 68aea3af9e87d40df689dca19c5a97cd4c5b25bc Mon Sep 17 00:00:00 2001 From: neilpang Date: Sat, 21 Jan 2017 14:19:01 +0800 Subject: [PATCH 159/189] fix format --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 2dc16e5a..35b0cc7a 100755 --- a/acme.sh +++ b/acme.sh @@ -3511,7 +3511,7 @@ remove() { fi if mv "$DOMAIN_CONF" "$_removed_conf"; then - _info "$Le_Domain is removed, the key and cert files are in $(__green $DOMAIN_PATH )" + _info "$Le_Domain is removed, the key and cert files are in $(__green $DOMAIN_PATH)" _info "You can remove them by yourself." return 0 else From 25555b8c3ead26d7fb58ac8519f73efc61b786f6 Mon Sep 17 00:00:00 2001 From: neil Date: Sun, 22 Jan 2017 18:11:32 +0800 Subject: [PATCH 160/189] pass the paths to reload cmd --- acme.sh | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/acme.sh b/acme.sh index 35b0cc7a..33599448 100755 --- a/acme.sh +++ b/acme.sh @@ -3349,9 +3349,14 @@ _installcert() { fi if [ "$Le_ReloadCmd" ]; then - _info "Run Le_ReloadCmd: $Le_ReloadCmd" - if (cd "$DOMAIN_PATH" && eval "$Le_ReloadCmd"); then + if ( + export CERT_PATH + export CERT_KEY_PATH + export CA_CERT_PATH + export CERT_FULLCHAIN_PATH + cd "$DOMAIN_PATH" && eval "$Le_ReloadCmd" + ); then _info "$(__green "Reload success")" else _err "Reload error for :$Le_Domain" From 839bf0e2c9ccf97e6acc8a6cccc0c3d5b2e5600f Mon Sep 17 00:00:00 2001 From: neilpang Date: Sun, 22 Jan 2017 18:48:21 +0800 Subject: [PATCH 161/189] fix format --- acme.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/acme.sh b/acme.sh index 33599448..7ec84e6f 100755 --- a/acme.sh +++ b/acme.sh @@ -3351,12 +3351,12 @@ _installcert() { if [ "$Le_ReloadCmd" ]; then _info "Run Le_ReloadCmd: $Le_ReloadCmd" if ( - export CERT_PATH - export CERT_KEY_PATH - export CA_CERT_PATH - export CERT_FULLCHAIN_PATH - cd "$DOMAIN_PATH" && eval "$Le_ReloadCmd" - ); then + export CERT_PATH + export CERT_KEY_PATH + export CA_CERT_PATH + export CERT_FULLCHAIN_PATH + cd "$DOMAIN_PATH" && eval "$Le_ReloadCmd" + ); then _info "$(__green "Reload success")" else _err "Reload error for :$Le_Domain" From 11927a768eca90138dd123391d7a55cece468b85 Mon Sep 17 00:00:00 2001 From: neilpang Date: Sun, 29 Jan 2017 11:47:04 +0800 Subject: [PATCH 162/189] minor, rename --- acme.sh | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/acme.sh b/acme.sh index 7ec84e6f..eb3164f1 100755 --- a/acme.sh +++ b/acme.sh @@ -868,7 +868,7 @@ createCSR() { } -_urlencode() { +_url_replace() { tr '/+' '_-' | tr -d '= ' } @@ -935,7 +935,7 @@ _calcjwk() { modulus=$($OPENSSL_BIN rsa -in "$keyfile" -modulus -noout | cut -d '=' -f 2) _debug3 modulus "$modulus" - n="$(printf "%s" "$modulus" | _h2b | _base64 | _urlencode)" + n="$(printf "%s" "$modulus" | _h2b | _base64 | _url_replace)" _debug3 n "$n" jwk='{"e": "'$e'", "kty": "RSA", "n": "'$n'"}' @@ -990,14 +990,14 @@ _calcjwk() { x="$(printf "%s" "$pubtext" | cut -d : -f 2-"$xend")" _debug3 x "$x" - x64="$(printf "%s" "$x" | tr -d : | _h2b | _base64 | _urlencode)" + x64="$(printf "%s" "$x" | tr -d : | _h2b | _base64 | _url_replace)" _debug3 x64 "$x64" xend=$(_math "$xend" + 1) y="$(printf "%s" "$pubtext" | cut -d : -f "$xend"-10000)" _debug3 y "$y" - y64="$(printf "%s" "$y" | tr -d : | _h2b | _base64 | _urlencode)" + y64="$(printf "%s" "$y" | tr -d : | _h2b | _base64 | _url_replace)" _debug3 y64 "$y64" jwk='{"crv": "'$crv'", "kty": "EC", "x": "'$x64'", "y": "'$y64'"}' @@ -1241,7 +1241,7 @@ _send_signed_request() { return 1 fi - payload64=$(printf "%s" "$payload" | _base64 | _urlencode) + payload64=$(printf "%s" "$payload" | _base64 | _url_replace) _debug3 payload64 "$payload64" if [ -z "$_CACHED_NONCE" ]; then @@ -1267,7 +1267,7 @@ _send_signed_request() { protected="$JWK_HEADERPLACE_PART1$nonce$JWK_HEADERPLACE_PART2" _debug3 protected "$protected" - protected64="$(printf "%s" "$protected" | _base64 | _urlencode)" + protected64="$(printf "%s" "$protected" | _base64 | _url_replace)" _debug3 protected64 "$protected64" if ! _sig_t="$(printf "%s" "$protected64.$payload64" | _sign "$keyfile" "sha256")"; then @@ -1276,7 +1276,7 @@ _send_signed_request() { fi _debug3 _sig_t "$_sig_t" - sig="$(printf "%s" "$_sig_t" | _urlencode)" + sig="$(printf "%s" "$_sig_t" | _url_replace)" _debug3 sig "$sig" body="{\"header\": $JWK_HEADER, \"protected\": \"$protected64\", \"payload\": \"$payload64\", \"signature\": \"$sig\"}" @@ -2005,7 +2005,7 @@ _clearupdns() { keyauthorization=$(echo "$ventry" | cut -d "$sep" -f 2) vtype=$(echo "$ventry" | cut -d "$sep" -f 4) _currentRoot=$(echo "$ventry" | cut -d "$sep" -f 5) - txt="$(printf "%s" "$keyauthorization" | _digest "sha256" | _urlencode)" + txt="$(printf "%s" "$keyauthorization" | _digest "sha256" | _url_replace)" _debug txt "$txt" if [ "$keyauthorization" = "$STATE_VERIFIED" ]; then _info "$d is already verified, skip $vtype." @@ -2549,7 +2549,7 @@ issue() { if [ -z "$thumbprint" ]; then accountkey_json=$(printf "%s" "$jwk" | tr -d ' ') - thumbprint=$(printf "%s" "$accountkey_json" | _digest "sha256" | _urlencode) + thumbprint=$(printf "%s" "$accountkey_json" | _digest "sha256" | _url_replace) fi entry="$(printf "%s\n" "$response" | _egrep_o '[^\{]*"type":"'$vtype'"[^\}]*')" @@ -2600,7 +2600,7 @@ issue() { dnsadded='0' txtdomain="_acme-challenge.$d" _debug txtdomain "$txtdomain" - txt="$(printf "%s" "$keyauthorization" | _digest "sha256" | _urlencode)" + txt="$(printf "%s" "$keyauthorization" | _digest "sha256" | _url_replace)" _debug txt "$txt" d_api="$(_findHook "$d" dnsapi "$_currentRoot")" @@ -2875,7 +2875,7 @@ issue() { _clearup _info "Verify finished, start to sign." - der="$(_getfile "${CSR_PATH}" "${BEGIN_CSR}" "${END_CSR}" | tr -d "\r\n" | _urlencode)" + der="$(_getfile "${CSR_PATH}" "${BEGIN_CSR}" "${END_CSR}" | tr -d "\r\n" | _url_replace)" if ! _send_signed_request "$API/acme/new-cert" "{\"resource\": \"new-cert\", \"csr\": \"$der\"}" "needbase64"; then _err "Sign failed." @@ -3453,7 +3453,7 @@ revoke() { return 1 fi - cert="$(_getfile "${CERT_PATH}" "${BEGIN_CERT}" "${END_CERT}" | tr -d "\r\n" | _urlencode)" + cert="$(_getfile "${CERT_PATH}" "${BEGIN_CERT}" "${END_CERT}" | tr -d "\r\n" | _url_replace)" if [ -z "$cert" ]; then _err "Cert for $Le_Domain is empty found, skip." From 542d7977db1479f9383561ae1657dcfb2ecfcb2c Mon Sep 17 00:00:00 2001 From: neilpang Date: Mon, 30 Jan 2017 12:07:50 +0800 Subject: [PATCH 163/189] add new _url_encode --- acme.sh | 248 ++++++++++++++++++++++++++++++++++++++++++++-- dnsapi/dns_ali.sh | 2 +- dnsapi/dns_aws.sh | 2 +- dnsapi/dns_me.sh | 2 +- 4 files changed, 242 insertions(+), 12 deletions(-) diff --git a/acme.sh b/acme.sh index eb3164f1..22d49351 100755 --- a/acme.sh +++ b/acme.sh @@ -336,15 +336,245 @@ _h2b() { done } -#hex string -_hex() { - _str="$1" - _str_len=${#_str} - _h_i=1 - while [ "$_h_i" -le "$_str_len" ]; do - _str_c="$(printf "%s" "$_str" | cut -c "$_h_i")" - printf "%02x" "'$_str_c" - _h_i="$(_math "$_h_i" + 1)" +_is_solaris() { + _contains "${__OS__:=$(uname -a)}" "solaris" || _contains "${__OS__:=$(uname -a)}" "SunOS" +} + +#stdin output hexstr splited by one space +#input:"abc" +#output: " 61 62 63" +_hex_dump() { + if _is_solaris; then + od -A n -v -t x1 | tr -d "\r\n\t" | tr -s " " | tr -d "\n" + else + od -A n -v -t x1 | tr -d "\r\n\t" | tr -s " " | sed "s/ $//" | tr -d "\n" + fi +} + +#url encode, no-preserved chars +#A B C D E F G H I J K L M N O P Q R S T U V W X Y Z +#41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a + +#a b c d e f g h i j k l m n o p q r s t u v w x y z +#61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 71 72 73 74 75 76 77 78 79 7a + +#0 1 2 3 4 5 6 7 8 9 - _ . ~ +#30 31 32 33 34 35 36 37 38 39 2d 5f 2e 7e + +#stdin stdout +_url_encode() { + _hex_str=$(_hex_dump) + _debug3 "_url_encode" + _debug3 "_hex_str" "$_hex_str" + for _hex_code in $_hex_str; do + #upper case + case "${_hex_code}" in + "41" ) + printf "%s" "A" + ;; + "42" ) + printf "%s" "B" + ;; + "43" ) + printf "%s" "C" + ;; + "44" ) + printf "%s" "D" + ;; + "45" ) + printf "%s" "E" + ;; + "46" ) + printf "%s" "F" + ;; + "47" ) + printf "%s" "G" + ;; + "48" ) + printf "%s" "H" + ;; + "49" ) + printf "%s" "I" + ;; + "4a" ) + printf "%s" "J" + ;; + "4b" ) + printf "%s" "K" + ;; + "4c" ) + printf "%s" "L" + ;; + "4d" ) + printf "%s" "M" + ;; + "4e" ) + printf "%s" "N" + ;; + "4f" ) + printf "%s" "O" + ;; + "50" ) + printf "%s" "P" + ;; + "51" ) + printf "%s" "Q" + ;; + "52" ) + printf "%s" "R" + ;; + "53" ) + printf "%s" "S" + ;; + "54" ) + printf "%s" "T" + ;; + "55" ) + printf "%s" "U" + ;; + "56" ) + printf "%s" "V" + ;; + "57" ) + printf "%s" "W" + ;; + "58" ) + printf "%s" "X" + ;; + "59" ) + printf "%s" "Y" + ;; + "5a" ) + printf "%s" "Z" + ;; + + #lower case + "61" ) + printf "%s" "a" + ;; + "62" ) + printf "%s" "b" + ;; + "63" ) + printf "%s" "c" + ;; + "64" ) + printf "%s" "d" + ;; + "65" ) + printf "%s" "e" + ;; + "66" ) + printf "%s" "f" + ;; + "67" ) + printf "%s" "g" + ;; + "68" ) + printf "%s" "h" + ;; + "69" ) + printf "%s" "i" + ;; + "6a" ) + printf "%s" "j" + ;; + "6b" ) + printf "%s" "k" + ;; + "6c" ) + printf "%s" "l" + ;; + "6d" ) + printf "%s" "m" + ;; + "6e" ) + printf "%s" "n" + ;; + "6f" ) + printf "%s" "o" + ;; + "70" ) + printf "%s" "p" + ;; + "71" ) + printf "%s" "q" + ;; + "72" ) + printf "%s" "r" + ;; + "73" ) + printf "%s" "s" + ;; + "74" ) + printf "%s" "t" + ;; + "75" ) + printf "%s" "u" + ;; + "76" ) + printf "%s" "v" + ;; + "77" ) + printf "%s" "w" + ;; + "78" ) + printf "%s" "x" + ;; + "79" ) + printf "%s" "y" + ;; + "7a" ) + printf "%s" "z" + ;; + #numbers + "30" ) + printf "%s" "0" + ;; + "31" ) + printf "%s" "1" + ;; + "32" ) + printf "%s" "2" + ;; + "33" ) + printf "%s" "3" + ;; + "34" ) + printf "%s" "4" + ;; + "35" ) + printf "%s" "5" + ;; + "36" ) + printf "%s" "6" + ;; + "37" ) + printf "%s" "7" + ;; + "38" ) + printf "%s" "8" + ;; + "39" ) + printf "%s" "9" + ;; + "2d" ) + printf "%s" "-" + ;; + "5f" ) + printf "%s" "_" + ;; + "2e" ) + printf "%s" "." + ;; + "7e" ) + printf "%s" "~" + ;; + #other hex + *) + printf '%%%s' "$_hex_code" + ;; + esac done } diff --git a/dnsapi/dns_ali.sh b/dnsapi/dns_ali.sh index 98c56f87..9b6f85c8 100644 --- a/dnsapi/dns_ali.sh +++ b/dnsapi/dns_ali.sh @@ -67,7 +67,7 @@ _get_root() { } _ali_rest() { - signature=$(printf "%s" "GET&%2F&$(_ali_urlencode "$query")" | _hmac "sha1" "$(_hex "$Ali_Secret&")" | _base64) + signature=$(printf "%s" "GET&%2F&$(_ali_urlencode "$query")" | _hmac "sha1" "$(printf "%s" "$Ali_Secret&" | _hex_dump | sed "s/ //g")" | _base64) signature=$(_ali_urlencode "$signature") url="$Ali_API?$query&Signature=$signature" diff --git a/dnsapi/dns_aws.sh b/dnsapi/dns_aws.sh index 59ef6181..5e7b34f5 100644 --- a/dnsapi/dns_aws.sh +++ b/dnsapi/dns_aws.sh @@ -183,7 +183,7 @@ aws_rest() { _debug2 kSecret "$kSecret" - kSecretH="$(_hex "$kSecret")" + kSecretH="$(printf "%s" "$kSecret" | _hex_dump | sed "s/ //g")" _debug2 kSecretH "$kSecretH" kDateH="$(printf "$RequestDateOnly%s" | _hmac "$Hash" "$kSecretH" hex)" diff --git a/dnsapi/dns_me.sh b/dnsapi/dns_me.sh index 9fe6baf8..c6bec70d 100755 --- a/dnsapi/dns_me.sh +++ b/dnsapi/dns_me.sh @@ -124,7 +124,7 @@ _me_rest() { _debug "$ep" cdate=$(date -u +"%a, %d %b %Y %T %Z") - hmac=$(printf "%s" "$cdate" | _hmac sha1 "$(_hex "$ME_Secret")" hex) + hmac=$(printf "%s" "$cdate" | _hmac sha1 "$(printf "%s" "$ME_Secret" | _hex_dump | sed "s/ //g")" hex) export _H1="x-dnsme-apiKey: $ME_Key" export _H2="x-dnsme-requestDate: $cdate" From c3b1eb0837cd5585709d32f8b337158d18bc38eb Mon Sep 17 00:00:00 2001 From: neilpang Date: Mon, 30 Jan 2017 12:25:56 +0800 Subject: [PATCH 164/189] fix format --- acme.sh | 406 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 203 insertions(+), 203 deletions(-) diff --git a/acme.sh b/acme.sh index 22d49351..cf82153a 100755 --- a/acme.sh +++ b/acme.sh @@ -369,211 +369,211 @@ _url_encode() { for _hex_code in $_hex_str; do #upper case case "${_hex_code}" in - "41" ) - printf "%s" "A" - ;; - "42" ) - printf "%s" "B" - ;; - "43" ) - printf "%s" "C" - ;; - "44" ) - printf "%s" "D" - ;; - "45" ) - printf "%s" "E" - ;; - "46" ) - printf "%s" "F" - ;; - "47" ) - printf "%s" "G" - ;; - "48" ) - printf "%s" "H" - ;; - "49" ) - printf "%s" "I" - ;; - "4a" ) - printf "%s" "J" - ;; - "4b" ) - printf "%s" "K" - ;; - "4c" ) - printf "%s" "L" - ;; - "4d" ) - printf "%s" "M" - ;; - "4e" ) - printf "%s" "N" - ;; - "4f" ) - printf "%s" "O" - ;; - "50" ) - printf "%s" "P" - ;; - "51" ) - printf "%s" "Q" - ;; - "52" ) - printf "%s" "R" - ;; - "53" ) - printf "%s" "S" - ;; - "54" ) - printf "%s" "T" - ;; - "55" ) - printf "%s" "U" - ;; - "56" ) - printf "%s" "V" - ;; - "57" ) - printf "%s" "W" - ;; - "58" ) - printf "%s" "X" - ;; - "59" ) - printf "%s" "Y" - ;; - "5a" ) - printf "%s" "Z" - ;; + "41") + printf "%s" "A" + ;; + "42") + printf "%s" "B" + ;; + "43") + printf "%s" "C" + ;; + "44") + printf "%s" "D" + ;; + "45") + printf "%s" "E" + ;; + "46") + printf "%s" "F" + ;; + "47") + printf "%s" "G" + ;; + "48") + printf "%s" "H" + ;; + "49") + printf "%s" "I" + ;; + "4a") + printf "%s" "J" + ;; + "4b") + printf "%s" "K" + ;; + "4c") + printf "%s" "L" + ;; + "4d") + printf "%s" "M" + ;; + "4e") + printf "%s" "N" + ;; + "4f") + printf "%s" "O" + ;; + "50") + printf "%s" "P" + ;; + "51") + printf "%s" "Q" + ;; + "52") + printf "%s" "R" + ;; + "53") + printf "%s" "S" + ;; + "54") + printf "%s" "T" + ;; + "55") + printf "%s" "U" + ;; + "56") + printf "%s" "V" + ;; + "57") + printf "%s" "W" + ;; + "58") + printf "%s" "X" + ;; + "59") + printf "%s" "Y" + ;; + "5a") + printf "%s" "Z" + ;; - #lower case - "61" ) - printf "%s" "a" - ;; - "62" ) - printf "%s" "b" - ;; - "63" ) - printf "%s" "c" - ;; - "64" ) - printf "%s" "d" - ;; - "65" ) - printf "%s" "e" - ;; - "66" ) - printf "%s" "f" - ;; - "67" ) - printf "%s" "g" - ;; - "68" ) - printf "%s" "h" - ;; - "69" ) - printf "%s" "i" - ;; - "6a" ) - printf "%s" "j" - ;; - "6b" ) - printf "%s" "k" - ;; - "6c" ) - printf "%s" "l" - ;; - "6d" ) - printf "%s" "m" - ;; - "6e" ) - printf "%s" "n" - ;; - "6f" ) - printf "%s" "o" - ;; - "70" ) - printf "%s" "p" - ;; - "71" ) - printf "%s" "q" - ;; - "72" ) - printf "%s" "r" - ;; - "73" ) - printf "%s" "s" - ;; - "74" ) - printf "%s" "t" - ;; - "75" ) - printf "%s" "u" - ;; - "76" ) - printf "%s" "v" - ;; - "77" ) - printf "%s" "w" - ;; - "78" ) - printf "%s" "x" - ;; - "79" ) - printf "%s" "y" - ;; - "7a" ) - printf "%s" "z" - ;; - #numbers - "30" ) - printf "%s" "0" - ;; - "31" ) - printf "%s" "1" - ;; - "32" ) - printf "%s" "2" - ;; - "33" ) - printf "%s" "3" - ;; - "34" ) - printf "%s" "4" - ;; - "35" ) - printf "%s" "5" - ;; - "36" ) - printf "%s" "6" - ;; - "37" ) - printf "%s" "7" - ;; - "38" ) - printf "%s" "8" - ;; - "39" ) - printf "%s" "9" - ;; - "2d" ) - printf "%s" "-" - ;; - "5f" ) - printf "%s" "_" - ;; - "2e" ) - printf "%s" "." - ;; - "7e" ) - printf "%s" "~" - ;; - #other hex + #lower case + "61") + printf "%s" "a" + ;; + "62") + printf "%s" "b" + ;; + "63") + printf "%s" "c" + ;; + "64") + printf "%s" "d" + ;; + "65") + printf "%s" "e" + ;; + "66") + printf "%s" "f" + ;; + "67") + printf "%s" "g" + ;; + "68") + printf "%s" "h" + ;; + "69") + printf "%s" "i" + ;; + "6a") + printf "%s" "j" + ;; + "6b") + printf "%s" "k" + ;; + "6c") + printf "%s" "l" + ;; + "6d") + printf "%s" "m" + ;; + "6e") + printf "%s" "n" + ;; + "6f") + printf "%s" "o" + ;; + "70") + printf "%s" "p" + ;; + "71") + printf "%s" "q" + ;; + "72") + printf "%s" "r" + ;; + "73") + printf "%s" "s" + ;; + "74") + printf "%s" "t" + ;; + "75") + printf "%s" "u" + ;; + "76") + printf "%s" "v" + ;; + "77") + printf "%s" "w" + ;; + "78") + printf "%s" "x" + ;; + "79") + printf "%s" "y" + ;; + "7a") + printf "%s" "z" + ;; + #numbers + "30") + printf "%s" "0" + ;; + "31") + printf "%s" "1" + ;; + "32") + printf "%s" "2" + ;; + "33") + printf "%s" "3" + ;; + "34") + printf "%s" "4" + ;; + "35") + printf "%s" "5" + ;; + "36") + printf "%s" "6" + ;; + "37") + printf "%s" "7" + ;; + "38") + printf "%s" "8" + ;; + "39") + printf "%s" "9" + ;; + "2d") + printf "%s" "-" + ;; + "5f") + printf "%s" "_" + ;; + "2e") + printf "%s" "." + ;; + "7e") + printf "%s" "~" + ;; + #other hex *) - printf '%%%s' "$_hex_code" - ;; + printf '%%%s' "$_hex_code" + ;; esac done } From 0899803294d2bbebda8e098b5022d3fd808049bb Mon Sep 17 00:00:00 2001 From: neilpang Date: Mon, 30 Jan 2017 14:29:40 +0800 Subject: [PATCH 165/189] add my twitter --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 9b5891c9..7b9d0025 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,9 @@ It's probably the `easiest&smallest&smartest` shell script to automatically issu Wiki: https://github.com/Neilpang/acme.sh/wiki +Twitter: [@neilpangxa](https://twitter.com/neilpangxa) + + # [中文说明](https://github.com/Neilpang/acme.sh/wiki/%E8%AF%B4%E6%98%8E) From 59182dbc97dbbf017441a46c53f6dcac837431e6 Mon Sep 17 00:00:00 2001 From: Philipp Grosswiler Date: Tue, 31 Jan 2017 10:43:30 +0700 Subject: [PATCH 166/189] Removed Linode CLI dependency. --- dnsapi/dns_linode.sh | 176 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 152 insertions(+), 24 deletions(-) diff --git a/dnsapi/dns_linode.sh b/dnsapi/dns_linode.sh index 0af1ad7c..e1c32204 100755 --- a/dnsapi/dns_linode.sh +++ b/dnsapi/dns_linode.sh @@ -1,6 +1,13 @@ #!/usr/bin/env bash -linode_cmd="/usr/bin/linode" +#Author: Philipp Grosswiler + +#How to create the Linode API key: +#Sign into your Linode account and go to this page: https://manager.linode.com/profile/api +#Then add an API key with label ACME and copy the new key. +#export LINODE_API_KEY="..." + +LINODE_API_URL="https://api.linode.com/?api_key=$LINODE_API_KEY&api_action=" ######## Public functions ##################### @@ -9,52 +16,173 @@ dns_linode_add() { fulldomain="${1}" txtvalue="${2}" + if ! _Linode_API; then + return 1 + fi + _info "Using Linode" _debug "Calling: dns_linode_add() '${fulldomain}' '${txtvalue}'" - domain=$(printf "%s" "${fulldomain}" | cut -d . -f 3-999) - name=$(printf "%s" "${fulldomain}" | cut -d . -f 1-2) - _debug name "${name}" - _debug domain "${domain}" + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "Domain does not exist." + return 1 + fi + _debug _domain_id "$_domain_id" + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" - _Linode_CLI && _Linode_addTXT + _parameters="&DomainID=$_domain_id&Type=TXT&Name=$_sub_domain&Target=$txtvalue" + + if _rest GET "domain.resource.create" "$_parameters" && [ -n "$response" ]; then + _resource_id=$(printf "%s\n" "$response" | _egrep_o "\"ResourceID\":\s*[0-9]+" | cut -d : -f 2 | tr -d " " | _head_n 1) + _debug _resource_id "$_resource_id" + + if [ -z "$_resource_id" ]; then + _err "Error adding the domain resource." + return 1 + fi + + _info "Domain resource successfully added." + return 0 + fi + + return 1 } #Usage: dns_linode_rm _acme-challenge.www.domain.com dns_linode_rm() { fulldomain="${1}" + if ! _Linode_API; then + return 1 + fi + _info "Using Linode" _debug "Calling: dns_linode_rm() '${fulldomain}'" - domain=$(printf "%s" "${fulldomain}" | cut -d . -f 3-999) - name=$(printf "%s" "${fulldomain}" | cut -d . -f 1-2) - _debug name "${name}" - _debug domain "${domain}" + _debug "First detect the root zone" + if ! _get_root "$fulldomain"; then + _err "Domain does not exist." + return 1 + fi + _debug _domain_id "$_domain_id" + _debug _sub_domain "$_sub_domain" + _debug _domain "$_domain" - _Linode_CLI && _Linode_rmTXT + _parameters="&DomainID=$_domain_id" + + if _rest GET "domain.resource.list" "$_parameters" && [ -n "$response" ]; then + response="$(echo "$response" | tr -d "\n" | sed 's/{/\n&/g')" + + resource="$(echo "$response" | _egrep_o "{.*\"NAME\":\s*\"$_sub_domain\".*}")" + if [ "$resource" ]; then + _resource_id=$(printf "%s\n" "$resource" | _egrep_o "\"RESOURCEID\":\s*[0-9]+" | _head_n 1 | cut -d : -f 2 | tr -d \ ) + if [ "$_resource_id" ]; then + _debug _resource_id "$_resource_id" + + _parameters="&DomainID=$_domain_id&ResourceID=$_resource_id" + + if _rest GET "domain.resource.delete" "$_parameters" && [ -n "$response" ]; then + _resource_id=$(printf "%s\n" "$response" | _egrep_o "\"ResourceID\":\s*[0-9]+" | cut -d : -f 2 | tr -d " " | _head_n 1) + _debug _resource_id "$_resource_id" + + if [ -z "$_resource_id" ]; then + _err "Error deleting the domain resource." + return 1 + fi + + _info "Domain resource successfully deleted." + return 0 + fi + fi + + return 1 + fi + + return 0 + fi + + return 1 } #################### Private functions below ################################## -_Linode_CLI() { - if [ ! -f "${linode_cmd}" ]; then - _err "Please install the Linode CLI package and set it up accordingly before using this DNS API." +_Linode_API() { + if [ -z "$LINODE_API_KEY" ]; then + LINODE_API_KEY="" + + _err "You didn't specify the Linode API key yet." + _err "Please create your key and try again." + return 1 fi + + _saveaccountconf LINODE_API_KEY "$LINODE_API_KEY" } -_Linode_addTXT() { - _debug "$linode_cmd domain record-update ${domain} TXT ${name} --target ${txtvalue}" - $linode_cmd domain record-update ${domain} TXT ${name} --target ${txtvalue} +#################### Private functions below ################################## +#_acme-challenge.www.domain.com +#returns +# _sub_domain=_acme-challenge.www +# _domain=domain.com +# _domain_id=12345 +_get_root() { + domain=$1 + i=2 + p=1 - if [ $? -ne 0 ]; then - _debug "$linode_cmd domain record-create ${domain} TXT ${name} ${txtvalue}" - $linode_cmd domain record-create ${domain} TXT ${name} ${txtvalue} + if _rest GET "domain.list"; then + response="$(echo "$response" | tr -d "\n" | sed 's/{/\n&/g')" + while true; do + h=$(printf "%s" "$domain" | cut -d . -f $i-100) + _debug h "$h" + if [ -z "$h" ]; then + #not valid + return 1 + fi + + hostedzone="$(echo "$response" | _egrep_o "{.*\"DOMAIN\":\s*\"$h\".*}")" + if [ "$hostedzone" ]; then + _domain_id=$(printf "%s\n" "$hostedzone" | _egrep_o "\"DOMAINID\":\s*[0-9]+" | _head_n 1 | cut -d : -f 2 | tr -d \ ) + if [ "$_domain_id" ]; then + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _domain=$h + return 0 + fi + return 1 + fi + p=$i + i=$(_math "$i" + 1) + done fi + return 1 } -_Linode_rmTXT() { - _debug "$linode_cmd domain record-delete ${domain} TXT ${name}" - $linode_cmd domain record-delete ${domain} TXT ${name} -} +#method method action data +_rest() { + mtd="$1" + ep="$2" + data="$3" + + _debug mtd "$mtd" + _debug ep "$ep" + + export _H1="Accept: application/json" + export _H2="Content-Type: application/json" + + if [ "$mtd" != "GET" ]; then + # both POST and DELETE. + _debug data "$data" + response="$(_post "$data" "$LINODE_API_URL$ep" "" "$mtd")" + else + response="$(_get "$LINODE_API_URL$ep$data")" + fi + + if [ "$?" != "0" ]; then + _err "error $ep" + return 1 + fi + _debug2 response "$response" + return 0 +} \ No newline at end of file From dd17ac5045a8dc7832d90644271937f4550e793e Mon Sep 17 00:00:00 2001 From: Philipp Grosswiler Date: Tue, 31 Jan 2017 10:56:34 +0700 Subject: [PATCH 167/189] Added instructions on how to get the Linode API key. --- dnsapi/README.md | 16 +++++++++------- dnsapi/dns_linode.sh | 7 +------ 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/dnsapi/README.md b/dnsapi/README.md index 1895d376..df728acc 100644 --- a/dnsapi/README.md +++ b/dnsapi/README.md @@ -259,23 +259,25 @@ when needed. ## 14. Use Linode domain API -You will need to install the Linode CLI and set it up accordingly. +First you need to login to your Linode account to get your API Key. +[https://manager.linode.com/profile/api](https://manager.linode.com/profile/api) -[https://www.linode.com/docs/platform/linode-cli](https://www.linode.com/docs/platform/linode-cli) +Then add an API key with label *ACME* and copy the new key. -Follow the installation instructions appropriate for your platform and then run the configuration. - -```linode configure +```sh +export LINODE_API_KEY="..." ``` -Make sure Linode CLI is working correctly before proceeding. - Due to the reload time of any changes in the DNS records, we have to use the `dnssleep` option to wait at least 15 minutes for the changes to take effect. +Ok, let's issue a cert now: + ```sh acme.sh --issue --dns dns_linode --dnssleep 900 -d example.com -d www.example.com ``` +The `LINODE_API_KEY` will be saved in `~/.acme.sh/account.conf` and will be reused when needed. + # Use custom API If your API is not supported yet, you can write your own DNS API. diff --git a/dnsapi/dns_linode.sh b/dnsapi/dns_linode.sh index e1c32204..501a51af 100755 --- a/dnsapi/dns_linode.sh +++ b/dnsapi/dns_linode.sh @@ -1,12 +1,7 @@ -#!/usr/bin/env bash +#!/usr/bin/env sh #Author: Philipp Grosswiler -#How to create the Linode API key: -#Sign into your Linode account and go to this page: https://manager.linode.com/profile/api -#Then add an API key with label ACME and copy the new key. -#export LINODE_API_KEY="..." - LINODE_API_URL="https://api.linode.com/?api_key=$LINODE_API_KEY&api_action=" ######## Public functions ##################### From bcf96608d123d2cfd0f810b0c1138e0f37a4efea Mon Sep 17 00:00:00 2001 From: neilpang Date: Tue, 31 Jan 2017 12:38:37 +0800 Subject: [PATCH 168/189] fix for solaris --- dnsapi/dns_cx.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_cx.sh b/dnsapi/dns_cx.sh index 9c032fd7..fa821f76 100755 --- a/dnsapi/dns_cx.sh +++ b/dnsapi/dns_cx.sh @@ -155,7 +155,7 @@ _get_root() { fi if _contains "$response" "$h."; then - seg=$(printf "%s\n" "$response" | _egrep_o '[^{]*"'"$h"'."[^}]*}') + seg=$(printf "%s\n" "$response" | _egrep_o '"id":[^{]*"'"$h"'."[^}]*}') _debug seg "$seg" _domain_id=$(printf "%s\n" "$seg" | _egrep_o "\"id\":\"[^\"]*\"" | cut -d : -f 2 | tr -d \") _debug _domain_id "$_domain_id" From 646c0bfcb9290a98a8b835897114860e14376560 Mon Sep 17 00:00:00 2001 From: neilpang Date: Tue, 31 Jan 2017 12:51:59 +0800 Subject: [PATCH 169/189] fix for solaris --- dnsapi/dns_cx.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_cx.sh b/dnsapi/dns_cx.sh index fa821f76..2b6d5691 100755 --- a/dnsapi/dns_cx.sh +++ b/dnsapi/dns_cx.sh @@ -82,7 +82,7 @@ existing_records() { return 1 fi - seg=$(printf "%s\n" "$response" | _egrep_o '[^{]*host":"'"$_sub_domain"'"[^}]*\}') + seg=$(printf "%s\n" "$response" | _egrep_o '"record_id":[^{]*host":"'"$_sub_domain"'"[^}]*\}') _debug seg "$seg" if [ -z "$seg" ]; then return 0 From 1c22c2f76a0a7c0b3c03c40aaba0d0c6fd7723f3 Mon Sep 17 00:00:00 2001 From: neilpang Date: Tue, 31 Jan 2017 14:04:40 +0800 Subject: [PATCH 170/189] fix for solaris --- dnsapi/dns_ali.sh | 2 +- dnsapi/dns_aws.sh | 2 +- dnsapi/dns_me.sh | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dnsapi/dns_ali.sh b/dnsapi/dns_ali.sh index 9b6f85c8..f796f076 100644 --- a/dnsapi/dns_ali.sh +++ b/dnsapi/dns_ali.sh @@ -67,7 +67,7 @@ _get_root() { } _ali_rest() { - signature=$(printf "%s" "GET&%2F&$(_ali_urlencode "$query")" | _hmac "sha1" "$(printf "%s" "$Ali_Secret&" | _hex_dump | sed "s/ //g")" | _base64) + signature=$(printf "%s" "GET&%2F&$(_ali_urlencode "$query")" | _hmac "sha1" "$(printf "%s" "$Ali_Secret&" | _hex_dump | tr -d " ")" | _base64) signature=$(_ali_urlencode "$signature") url="$Ali_API?$query&Signature=$signature" diff --git a/dnsapi/dns_aws.sh b/dnsapi/dns_aws.sh index 5e7b34f5..1308c507 100644 --- a/dnsapi/dns_aws.sh +++ b/dnsapi/dns_aws.sh @@ -183,7 +183,7 @@ aws_rest() { _debug2 kSecret "$kSecret" - kSecretH="$(printf "%s" "$kSecret" | _hex_dump | sed "s/ //g")" + kSecretH="$(printf "%s" "$kSecret" | _hex_dump | tr -d " ")" _debug2 kSecretH "$kSecretH" kDateH="$(printf "$RequestDateOnly%s" | _hmac "$Hash" "$kSecretH" hex)" diff --git a/dnsapi/dns_me.sh b/dnsapi/dns_me.sh index c6bec70d..f63621d9 100755 --- a/dnsapi/dns_me.sh +++ b/dnsapi/dns_me.sh @@ -124,7 +124,7 @@ _me_rest() { _debug "$ep" cdate=$(date -u +"%a, %d %b %Y %T %Z") - hmac=$(printf "%s" "$cdate" | _hmac sha1 "$(printf "%s" "$ME_Secret" | _hex_dump | sed "s/ //g")" hex) + hmac=$(printf "%s" "$cdate" | _hmac sha1 "$(printf "%s" "$ME_Secret" | _hex_dump | tr -d " ")" hex) export _H1="x-dnsme-apiKey: $ME_Key" export _H2="x-dnsme-requestDate: $cdate" From c070407ab2dfd784f57188a2a34322aed020fc1b Mon Sep 17 00:00:00 2001 From: Philipp Grosswiler Date: Tue, 31 Jan 2017 13:38:16 +0700 Subject: [PATCH 171/189] Fixed Travis CI complaining about missing newline at end of file. --- dnsapi/dns_linode.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_linode.sh b/dnsapi/dns_linode.sh index 501a51af..6d54e6c1 100755 --- a/dnsapi/dns_linode.sh +++ b/dnsapi/dns_linode.sh @@ -180,4 +180,4 @@ _rest() { fi _debug2 response "$response" return 0 -} \ No newline at end of file +} From bb6326f4d423b9fe6b6677ffb058711724376fcb Mon Sep 17 00:00:00 2001 From: neilpang Date: Tue, 31 Jan 2017 15:57:43 +0800 Subject: [PATCH 172/189] fix for solaris --- dnsapi/dns_aws.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_aws.sh b/dnsapi/dns_aws.sh index 1308c507..555bd70b 100644 --- a/dnsapi/dns_aws.sh +++ b/dnsapi/dns_aws.sh @@ -93,7 +93,7 @@ _get_root() { fi if _contains "$response" "$h."; then - hostedzone="$(echo "$response" | sed 's//\n&/g' | _egrep_o ".*?$h.<.Name>.*?<.HostedZone>")" + hostedzone="$(echo "$response" | _egrep_o "[^<]*<.Id>$h.<.Name>.*<.HostedZone>")" _debug hostedzone "$hostedzone" if [ -z "$hostedzone" ]; then _err "Error, can not get hostedzone." From 5d833336d33ca82eb3f1634d83e21b8d805bf88b Mon Sep 17 00:00:00 2001 From: neilpang Date: Tue, 31 Jan 2017 18:41:32 +0800 Subject: [PATCH 173/189] minor --- dnsapi/dns_lua.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_lua.sh b/dnsapi/dns_lua.sh index 47f4497a..9506929c 100755 --- a/dnsapi/dns_lua.sh +++ b/dnsapi/dns_lua.sh @@ -46,12 +46,12 @@ dns_lua_add() { return 1 fi - count=$(printf "%s\n" "$response" | _egrep_o "\"name\":\"$fulldomain\"" | wc -l) + count=$(printf "%s\n" "$response" | _egrep_o "\"name\":\"$fulldomain\"" | wc -l | tr -s " ") _debug count "$count" if [ "$count" = "0" ]; then _info "Adding record" if _LUA_rest POST "zones/$_domain_id/records" "{\"type\":\"TXT\",\"name\":\"$fulldomain.\",\"content\":\"$txtvalue\",\"ttl\":120}"; then - if printf -- "%s" "$response" | grep "$fulldomain" >/dev/null; then + if _contains "$response" "$fulldomain"; then _info "Added" #todo: check if the record takes effect return 0 @@ -99,6 +99,7 @@ _get_root() { fi while true; do h=$(printf "%s" "$domain" | cut -d . -f $i-100) + _debug h "$h" if [ -z "$h" ]; then #not valid return 1 @@ -106,6 +107,7 @@ _get_root() { if _contains "$response" "\"name\":\"$h\""; then _domain_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":[^,]*,\"name\":\"$h\"" | cut -d : -f 2 | cut -d , -f 1) + _debug _domain_id "$_domain_id" if [ "$_domain_id" ]; then _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) _domain="$h" From 05cf405cb53a2ea1bc55d29535beefaffd8dbe97 Mon Sep 17 00:00:00 2001 From: neilpang Date: Tue, 31 Jan 2017 18:46:24 +0800 Subject: [PATCH 174/189] minor --- dnsapi/dns_lua.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_lua.sh b/dnsapi/dns_lua.sh index 9506929c..be77b9d9 100755 --- a/dnsapi/dns_lua.sh +++ b/dnsapi/dns_lua.sh @@ -46,7 +46,7 @@ dns_lua_add() { return 1 fi - count=$(printf "%s\n" "$response" | _egrep_o "\"name\":\"$fulldomain\"" | wc -l | tr -s " ") + count=$(printf "%s\n" "$response" | _egrep_o "\"name\":\"$fulldomain\"" | wc -l | tr -d " ") _debug count "$count" if [ "$count" = "0" ]; then _info "Adding record" From 53fa16d39f314a43e60b47c923cd5d854742e539 Mon Sep 17 00:00:00 2001 From: neilpang Date: Tue, 31 Jan 2017 18:59:00 +0800 Subject: [PATCH 175/189] minor --- dnsapi/dns_lua.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_lua.sh b/dnsapi/dns_lua.sh index be77b9d9..211dbb04 100755 --- a/dnsapi/dns_lua.sh +++ b/dnsapi/dns_lua.sh @@ -46,7 +46,7 @@ dns_lua_add() { return 1 fi - count=$(printf "%s\n" "$response" | _egrep_o "\"name\":\"$fulldomain\"" | wc -l | tr -d " ") + count=$(printf "%s\n" "$response" | _egrep_o "\"name\":\"$fulldomain.\",\"type\":\"TXT\"" | wc -l | tr -d " ") _debug count "$count" if [ "$count" = "0" ]; then _info "Adding record" From ab5c1b0a3a6843954ee959c4700f8e422c5b8002 Mon Sep 17 00:00:00 2001 From: neilpang Date: Tue, 31 Jan 2017 19:03:29 +0800 Subject: [PATCH 176/189] minor --- dnsapi/dns_lua.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_lua.sh b/dnsapi/dns_lua.sh index 211dbb04..0dd97fc3 100755 --- a/dnsapi/dns_lua.sh +++ b/dnsapi/dns_lua.sh @@ -63,7 +63,7 @@ dns_lua_add() { _err "Add txt record error." else _info "Updating record" - record_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":[^,]*,\"name\":\"$fulldomain.\",\"type\":\"TXT\"" | cut -d: -f2 | cut -d, -f1) + record_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":[^,]*,\"name\":\"$fulldomain.\",\"type\":\"TXT\"" | _head_n 1 | cut -d: -f2 | cut -d, -f1) _debug "record_id" "$record_id" _LUA_rest PUT "zones/$_domain_id/records/$record_id" "{\"id\":\"$record_id\",\"type\":\"TXT\",\"name\":\"$fulldomain.\",\"content\":\"$txtvalue\",\"zone_id\":\"$_domain_id\",\"ttl\":120}" From d78ba322bfbbaf93659c8b905b50431b3a7d14f4 Mon Sep 17 00:00:00 2001 From: neilpang Date: Tue, 31 Jan 2017 19:22:14 +0800 Subject: [PATCH 177/189] fix update --- dnsapi/dns_lua.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsapi/dns_lua.sh b/dnsapi/dns_lua.sh index 0dd97fc3..42d55e84 100755 --- a/dnsapi/dns_lua.sh +++ b/dnsapi/dns_lua.sh @@ -66,8 +66,8 @@ dns_lua_add() { record_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":[^,]*,\"name\":\"$fulldomain.\",\"type\":\"TXT\"" | _head_n 1 | cut -d: -f2 | cut -d, -f1) _debug "record_id" "$record_id" - _LUA_rest PUT "zones/$_domain_id/records/$record_id" "{\"id\":\"$record_id\",\"type\":\"TXT\",\"name\":\"$fulldomain.\",\"content\":\"$txtvalue\",\"zone_id\":\"$_domain_id\",\"ttl\":120}" - if [ "$?" = "0" ]; then + _LUA_rest PUT "zones/$_domain_id/records/$record_id" "{\"id\":$record_id,\"type\":\"TXT\",\"name\":\"$fulldomain.\",\"content\":\"$txtvalue\",\"zone_id\":$_domain_id,\"ttl\":120}" + if [ "$?" = "0" ] && _contains "$response" "updated_at" ; then _info "Updated!" #todo: check if the record takes effect return 0 From 5f8daeeb6d987687ac896c128c327c2096b02009 Mon Sep 17 00:00:00 2001 From: neilpang Date: Tue, 31 Jan 2017 20:03:41 +0800 Subject: [PATCH 178/189] minor, a better hex_dump --- acme.sh | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/acme.sh b/acme.sh index cf82153a..e5728b3c 100755 --- a/acme.sh +++ b/acme.sh @@ -344,11 +344,7 @@ _is_solaris() { #input:"abc" #output: " 61 62 63" _hex_dump() { - if _is_solaris; then - od -A n -v -t x1 | tr -d "\r\n\t" | tr -s " " | tr -d "\n" - else - od -A n -v -t x1 | tr -d "\r\n\t" | tr -s " " | sed "s/ $//" | tr -d "\n" - fi + od -A n -v -t x1 | tr -d "\r\t" | tr -s " " | sed "s/ $//" | tr -d "\n" } #url encode, no-preserved chars From 600a23514029477e794f356f4158ba36b3311a8f Mon Sep 17 00:00:00 2001 From: David Kerr Date: Tue, 31 Jan 2017 23:16:04 -0500 Subject: [PATCH 179/189] Add FreeDNS plugin --- dnsapi/dns_freedns.sh | 371 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 371 insertions(+) create mode 100755 dnsapi/dns_freedns.sh diff --git a/dnsapi/dns_freedns.sh b/dnsapi/dns_freedns.sh new file mode 100755 index 00000000..ad3f9da3 --- /dev/null +++ b/dnsapi/dns_freedns.sh @@ -0,0 +1,371 @@ +#!/usr/bin/env sh + +#This file name is "dns_freedns.sh" +#So, here must be a method dns_freedns_add() +#Which will be called by acme.sh to add the txt record to your api system. +#returns 0 means success, otherwise error. +# +#Author: David Kerr +#Report Bugs here: https://github.com/dkerr64/acme.sh +# +######## Public functions ##################### + +# Export FreeDNS userid and password in folowing variables... +# FREEDNS_User=username +# FREEDNS_Password=password +# login cookie is saved in acme account config file so userid / pw +# need to be set only when changed. + +#Usage: dns_freedns_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_freedns_add() { + fulldomain="$1" + txtvalue="$2" + + _info "Add TXT record using FreeDNS" + _debug "fulldomain: $fulldomain" + _debug "txtvalue: $txtvalue" + + if [ -z "$FREEDNS_User" ] || [ -z "$FREEDNS_Password" ]; then + FREEDNS_User="" + FREEDNS_Password="" + if [ -z "$FREEDNS_COOKIE" ]; then + _err "You did not specify the FreeDNS username and password yet." + _err "Please export as FREEDNS_User / FREEDNS_Password and try again." + return 1 + fi + using_cached_cookies="true" + else + FREEDNS_COOKIE="$(_freedns_login "$FREEDNS_User" "$FREEDNS_Password")" + if [ -z "$FREEDNS_COOKIE" ]; then + return 1 + fi + using_cached_cookies="false" + fi + + _debug "FreeDNS login cookies: $FREEDNS_COOKIE (cached = $using_cached_cookies)" + + _saveaccountconf FREEDNS_COOKIE "$FREEDNS_COOKIE" + + # split our full domain name into two parts... + i="$(echo "$fulldomain" | tr '.' ' ' | wc -w)" + i="$(_math "$i" - 1)" + top_domain="$(echo "$fulldomain" | cut -d. -f "$i"-100)" + i="$(_math "$i" - 1)" + sub_domain="$(echo "$fulldomain" | cut -d. -f -"$i")" + + # Sometimes FreeDNS does not reurn the subdomain page but rather + # returns a page regarding becoming a premium member. This usually + # happens after a period of inactivity. Immediately trying again + # returns the correct subdomain page. So, we will try twice to + # load the page and obtain our domain ID + attempts=2 + while [ "$attempts" -gt "0" ]; do + attempts="$(_math "$attempts" - 1)" + + htmlpage="$(_freedns_retrieve_subdomain_page "$FREEDNS_COOKIE")" + if [ "$?" != "0" ]; then + if [ "$using_cached_cookies" = "true" ]; then + _err "Has your FreeDNS username and password channged? If so..." + _err "Please export as FREEDNS_User / FREEDNS_Password and try again." + fi + return 1 + fi + + # Now convert the tables in the HTML to CSV. This litte gem from + # http://stackoverflow.com/questions/1403087/how-can-i-convert-an-html-table-to-csv + subdomain_csv="$(echo "$htmlpage" \ + | grep -i -e ']*>/\n/Ig' \ + | sed 's/<\/\?\(TABLE\|TR\)[^>]*>//Ig' \ + | sed 's/^]*>\|<\/\?T[DH][^>]*>$//Ig' \ + | sed 's/<\/T[DH][^>]*>]*>/,/Ig' \ + | grep 'edit.php?' \ + | grep "$top_domain")" + # The above beauty ends with striping out rows that do not have an + # href to edit.php and do not have the top domain we are looking for. + # So all we should be left with is CSV of table of subdomains we are + # interested in. + + # Now we have to read through this table and extract the data we need + lines="$(echo "$subdomain_csv" | wc -l)" + nl=' +' + i=0 + found=0 + while [ "$i" -lt "$lines" ]; do + i="$(_math "$i" + 1)" + line="$(echo "$subdomain_csv" | cut -d "$nl" -f "$i")" + tmp="$(echo "$line" | cut -d ',' -f 1)" + if [ $found = 0 ] && _startswith "$tmp" "$top_domain"; then + # this line will contain DNSdomainid for the top_domain + DNSdomainid="$(echo "$line" | cut -d ',' -f 2 | sed 's/^.*domain_id=//;s/>.*//')" + found=1 + else + # lines contain DNS records for all subdomains + DNSname="$(echo "$line" | cut -d ',' -f 2 | sed 's/^[^>]*>//;s/<\/a>.*//')" + DNStype="$(echo "$line" | cut -d ',' -f 3)" + if [ "$DNSname" = "$fulldomain" ] && [ "$DNStype" = "TXT" ]; then + DNSdataid="$(echo "$line" | cut -d ',' -f 2 | sed 's/^.*data_id=//;s/>.*//')" + # Now get current value for the TXT record. This method may + # not produce accurate results as the value field is truncated + # on this webpage. To get full value we would need to load + # another page. However we don't really need this so long as + # there is only one TXT record for the acme chalenge subdomain. + DNSvalue="$(echo "$line" | cut -d ',' -f 4 | sed 's/^[^"]*"//;s/".*//;s/<\/td>.*//')" + if [ $found != 0 ]; then + break + # we are breaking out of the loop at the first match of DNS name + # and DNS type (if we are past finding the domainid). This assumes + # that there is only ever one TXT record for the LetsEncrypt/acme + # challenge subdomain. This seems to be a reasonable assumption + # as the acme client deletes the TXT record on successful validation. + fi + else + DNSname="" + DNStype="" + fi + fi + done + + _debug "DNSname: $DNSname DNStype: $DNStype DNSdomainid: $DNSdomainid DNSdataid: $DNSdataid" + _debug "DNSvalue: $DNSvalue" + + if [ -z "$DNSdomainid" ]; then + # If domain ID is empty then something went wrong (top level + # domain not found at FreeDNS). + if [ "$attempts" = "0" ]; then + # exhausted maximum retry attempts + _debug "$htmlpage" + _debug "$subdomain_csv" + _err "Domain $top_domain not found at FreeDNS" + return 1 + fi + else + # break out of the 'retry' loop... we have found our domain ID + break + fi + _info "Domain $top_domain not found at FreeDNS" + _info "Retry loading subdomain page ($attempts attempts remaining)" + done + + if [ -z "$DNSdataid" ]; then + # If data ID is empty then specific subdomain does not exist yet, need + # to create it this should always be the case as the acme client + # deletes the entry after domain is validated. + _freedns_add_txt_record "$FREEDNS_COOKIE" "$DNSdomainid" "$sub_domain" "$txtvalue" + return $? + else + if [ "$txtvalue" = "$DNSvalue" ]; then + # if value in TXT record matches value requested then DNS record + # does not need to be updated. But... + # Testing value match fails. Website is truncating the value field. + # So for now we will always go down the else path. Though in theory + # should never come here anyway as the acme client deletes + # the TXT record on successful validation, so we should not even + # have found a TXT record !! + _info "No update necessary for $fulldomain at FreeDNS" + return 0 + else + # Delete the old TXT record (with the wrong value) + _freedns_delete_txt_record "$FREEDNS_COOKIE" "$DNSdataid" + if [ "$?" = "0" ]; then + # And add in new TXT record with the value provided + _freedns_add_txt_record "$FREEDNS_COOKIE" "$DNSdomainid" "$sub_domain" "$txtvalue" + fi + return $? + fi + fi + return 0 +} + +#Usage: fulldomain txtvalue +#Remove the txt record after validation. +dns_freedns_rm() { + fulldomain="$1" + txtvalue="$2" + + _info "Delete TXT record using FreeDNS" + _debug "fulldomain: $fulldomain" + _debug "txtvalue: $txtvalue" + + # Need to read cookie from conf file again in case new value set + # during login to FreeDNS when TXT record was created. + # acme.sh does not have a _readaccountconf() fuction + FREEDNS_COOKIE="$(_read_conf "$ACCOUNT_CONF_PATH" "FREEDNS_COOKIE")" + _debug "FreeDNS login cookies: $FREEDNS_COOKIE" + + # Sometimes FreeDNS does not reurn the subdomain page but rather + # returns a page regarding becoming a premium member. This usually + # happens after a period of inactivity. Immediately trying again + # returns the correct subdomain page. So, we will try twice to + # load the page and obtain our TXT record. + attempts=2 + while [ "$attempts" -gt "0" ]; do + attempts="$(_math "$attempts" - 1)" + + htmlpage="$(_freedns_retrieve_subdomain_page "$FREEDNS_COOKIE")" + if [ "$?" != "0" ]; then + return 1 + fi + + # Now convert the tables in the HTML to CSV. This litte gem from + # http://stackoverflow.com/questions/1403087/how-can-i-convert-an-html-table-to-csv + subdomain_csv="$(echo "$htmlpage" \ + | grep -i -e ']*>/\n/Ig' \ + | sed 's/<\/\?\(TABLE\|TR\)[^>]*>//Ig' \ + | sed 's/^]*>\|<\/\?T[DH][^>]*>$//Ig' \ + | sed 's/<\/T[DH][^>]*>]*>/,/Ig' \ + | grep 'edit.php?' \ + | grep "$fulldomain")" + # The above beauty ends with striping out rows that do not have an + # href to edit.php and do not have the domain name we are looking for. + # So all we should be left with is CSV of table of subdomains we are + # interested in. + + # Now we have to read through this table and extract the data we need + lines="$(echo "$subdomain_csv" | wc -l)" + nl=' +' + i=0 + found=0 + while [ "$i" -lt "$lines" ]; do + i="$(_math "$i" + 1)" + line="$(echo "$subdomain_csv" | cut -d "$nl" -f "$i")" + DNSname="$(echo "$line" | cut -d ',' -f 2 | sed 's/^[^>]*>//;s/<\/a>.*//')" + DNStype="$(echo "$line" | cut -d ',' -f 3)" + if [ "$DNSname" = "$fulldomain" ] && [ "$DNStype" = "TXT" ]; then + DNSdataid="$(echo "$line" | cut -d ',' -f 2 | sed 's/^.*data_id=//;s/>.*//')" + DNSvalue="$(echo "$line" | cut -d ',' -f 4 | sed 's/^[^"]*"//;s/".*//;s/<\/td>.*//')" + _debug "DNSvalue: $DNSvalue" + # if [ "$DNSvalue" = "$txtvalue" ]; then + # Testing value match fails. Website is truncating the value + # field. So for now we will assume that there is only one TXT + # field for the sub domain and just delete it. Currently this + # is a safe assumption. + _freedns_delete_txt_record "$FREEDNS_COOKIE" "$DNSdataid" + return $? + # fi + fi + done + done + + # If we get this far we did not find a match (after two attempts) + # Not necessarily an error, but log anyway. + _debug2 "$subdomain_csv" + _info "Cannot delete TXT record for $fulldomain/$txtvalue. Does not exist at FreeDNS" + return 0 +} + +#################### Private functions below ################################## + +# usage: _freedns_login username password +# print string "cookie=value" etc. +# returns 0 success +_freedns_login() { + username="$1" + password="$2" + url="https://freedns.afraid.org/zc.php?step=2" + + _debug "Login to FreeDNS as user $username" + + htmlpage="$(_post "username=$(printf '%s' "$username" | _url_encode)&password=$(printf '%s' "$password" | _url_encode)&submit=Login&action=auth" "$url")" + + if [ "$?" != "0" ]; then + _err "FreeDNS login failed for user $username bad RC from _post" + return 1 + fi + + cookies="$(grep -i '^Set-Cookie.*dns_cookie.*$' "$HTTP_HEADER" | _head_n 1 | tr -d "\r\n" | cut -d " " -f 2)" + + # if cookies is not empty then logon successful + if [ -z "$cookies" ]; then + _debug "$htmlpage" + _err "FreeDNS login failed for user $username. Check $HTTP_HEADER file" + return 1 + fi + + printf "%s" "$cookies" + return 0 +} + +# usage _freedns_retrieve_subdomain_page login_cookies +# echo page retrieved (html) +# returns 0 success +_freedns_retrieve_subdomain_page() { + export _H1="Cookie:$1" + url="https://freedns.afraid.org/subdomain/" + + _debug "Retrieve subdmoain page from FreeDNS" + + htmlpage="$(_get "$url")" + + if [ "$?" != "0" ]; then + _err "FreeDNS retrieve subdomins failed bad RC from _get" + return 1 + fi + + if [ -z "$htmlpage" ]; then + _err "FreeDNS returned empty subdomain page" + return 1 + fi + + _debug2 "$htmlpage" + + printf "%s" "$htmlpage" + return 0 +} + +# usage _freedns_add_txt_record login_cookies domain_id subdomain value +# returns 0 success +_freedns_add_txt_record() { + export _H1="Cookie:$1" + domain_id="$2" + subdomain="$3" + value="$(printf '%s' "$4" | _url_encode)" + url="http://freedns.afraid.org/subdomain/save.php?step=2" + + htmlpage="$(_post "type=TXT&domain_id=$domain_id&subdomain=$subdomain&address=%22$value%22&send=Save%21" "$url")" + + if [ "$?" != "0" ]; then + _err "FreeDNS failed to add TXT record for $subdomain bad RC from _post" + return 1 + fi + + if ! grep "200 OK" "$HTTP_HEADER" >/dev/null; then + _debug "$htmlpage" + _err "FreeDNS failed to add TXT record for $subdomain. Check $HTTP_HEADER file" + return 1 + fi + _info "Added acme challenge TXT record for $fulldomain at FreeDNS" + return 0 +} + +# usage _freedns_delete_txt_record login_cookies data_id +# returns 0 success +_freedns_delete_txt_record() { + export _H1="Cookie:$1" + data_id="$2" + url="https://freedns.afraid.org/subdomain/delete2.php" + + htmlheader="$(_get "$url?data_id%5B%5D=$data_id&submit=delete+selected" "onlyheader")" + + if [ "$?" != "0" ]; then + _err "FreeDNS failed to delete TXT record for $data_id bad RC from _get" + return 1 + fi + + if ! _contains "$htmlheader" "200 OK"; then + _debug "$htmlheader" + _err "FreeDNS failed to delete TXT record $data_id" + return 1 + fi + + _info "Deleted acme challenge TXT record for $fulldomain at FreeDNS" + return 0 +} + From 1476a9ecf144b3c5a033adc533b429fe1365e9a7 Mon Sep 17 00:00:00 2001 From: neilpang Date: Wed, 1 Feb 2017 16:12:43 +0800 Subject: [PATCH 180/189] fix format --- dnsapi/dns_lua.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_lua.sh b/dnsapi/dns_lua.sh index 42d55e84..828e8012 100755 --- a/dnsapi/dns_lua.sh +++ b/dnsapi/dns_lua.sh @@ -67,7 +67,7 @@ dns_lua_add() { _debug "record_id" "$record_id" _LUA_rest PUT "zones/$_domain_id/records/$record_id" "{\"id\":$record_id,\"type\":\"TXT\",\"name\":\"$fulldomain.\",\"content\":\"$txtvalue\",\"zone_id\":$_domain_id,\"ttl\":120}" - if [ "$?" = "0" ] && _contains "$response" "updated_at" ; then + if [ "$?" = "0" ] && _contains "$response" "updated_at"; then _info "Updated!" #todo: check if the record takes effect return 0 From 70b63a5ed442efe28587b8107c216db9e2965f70 Mon Sep 17 00:00:00 2001 From: neil Date: Wed, 1 Feb 2017 23:18:37 +0800 Subject: [PATCH 181/189] Create README.md --- deploy/README.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 deploy/README.md diff --git a/deploy/README.md b/deploy/README.md new file mode 100644 index 00000000..580eaac8 --- /dev/null +++ b/deploy/README.md @@ -0,0 +1 @@ +#Using deploy api From 0aed065a75dc3be7c906a156ebad1b30344d09ba Mon Sep 17 00:00:00 2001 From: David Kerr Date: Wed, 1 Feb 2017 17:08:26 -0500 Subject: [PATCH 182/189] Updates to README.md --- README.md | 1 + dnsapi/README.md | 26 ++++++++++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/README.md b/README.md index 90a64ee0..067e9b50 100644 --- a/README.md +++ b/README.md @@ -270,6 +270,7 @@ You don't have to do anything manually! 1. ISPConfig 3.1 API 1. Alwaysdata.com API 1. Linode.com API +1. FreeDNS **More APIs coming soon...** diff --git a/dnsapi/README.md b/dnsapi/README.md index df728acc..9f06483e 100644 --- a/dnsapi/README.md +++ b/dnsapi/README.md @@ -278,6 +278,32 @@ acme.sh --issue --dns dns_linode --dnssleep 900 -d example.com -d www.example.co The `LINODE_API_KEY` will be saved in `~/.acme.sh/account.conf` and will be reused when needed. +# 15. Use FreeDNS + +FreeDNS (https://freedns.afraid.org/) does not provide an API to update DNS records (other than IPv4 and IPv6 +dynamic DNS addresses). The acme.sh plugin therefore retrieves and updates domain TXT records by logging +into the FreeDNS website to read the HTML and posting updates as HTTP. The plugin needs to know your +userid and password for the FreeDNS website. + +```sh +export FREEDNS_User="..." +export FREEDNS_Password="..." +``` + +You need only provide this the first time you run the acme.sh client with FreeDNS validation and then again +whenever you change your password at the FreeDNS site. The acme.sh FreeDNS plugin does not store your userid +or password but rather saves an authentication token returned by FreeDNS in `~/.acme.sh/account.conf` and +reuses that when needed. + +Now you can issue a certificate. + +```sh +acme.sh --issue --dns dns_freedns --dnssleep 30 -d example.com -d www.example.com +``` + +FreeDNS updates records quite quickly so it is possible to reduce the dnssleep time, in the above example +to 30 seconds. + # Use custom API If your API is not supported yet, you can write your own DNS API. From 40e6ba1100e2ed61508131873fa99225748aded4 Mon Sep 17 00:00:00 2001 From: David Kerr Date: Wed, 1 Feb 2017 17:12:52 -0500 Subject: [PATCH 183/189] fix heading level to match others. --- dnsapi/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/README.md b/dnsapi/README.md index 9f06483e..65acb7d9 100644 --- a/dnsapi/README.md +++ b/dnsapi/README.md @@ -278,7 +278,7 @@ acme.sh --issue --dns dns_linode --dnssleep 900 -d example.com -d www.example.co The `LINODE_API_KEY` will be saved in `~/.acme.sh/account.conf` and will be reused when needed. -# 15. Use FreeDNS +## 15. Use FreeDNS FreeDNS (https://freedns.afraid.org/) does not provide an API to update DNS records (other than IPv4 and IPv6 dynamic DNS addresses). The acme.sh plugin therefore retrieves and updates domain TXT records by logging From 6c4cc357b5ba12c5bd5682750647b198d40a8cdc Mon Sep 17 00:00:00 2001 From: neil Date: Fri, 3 Feb 2017 11:13:38 +0800 Subject: [PATCH 184/189] _readlink --- acme.sh | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/acme.sh b/acme.sh index 7ec84e6f..d4cbe1fd 100755 --- a/acme.sh +++ b/acme.sh @@ -1594,14 +1594,18 @@ _starttlsserver() { _readlink() { _rf="$1" if ! readlink -f "$_rf" 2>/dev/null; then - if _startswith "$_rf" "\./$PROJECT_ENTRY"; then - printf -- "%s" "$(pwd)/$PROJECT_ENTRY" + if _startswith "$_rf" "/"; then + echo "$_rf" return 0 fi - readlink "$_rf" + echo "$(pwd)/$_rf" | _conapath fi } +_conapath() { + sed "s#/\./#/#g" +} + __initHome() { if [ -z "$_SCRIPT_HOME" ]; then if _exists readlink && _exists dirname; then @@ -4440,7 +4444,7 @@ _process() { HTTPS_INSECURE="1" ;; --ca-bundle) - _ca_bundle="$(readlink -f "$2")" + _ca_bundle="$(_readlink -f "$2")" CA_BUNDLE="$_ca_bundle" shift ;; From 50a9680f17f0719450f3f1874d723d0db2c4a1fb Mon Sep 17 00:00:00 2001 From: David Kerr Date: Fri, 3 Feb 2017 11:13:12 -0500 Subject: [PATCH 185/189] Travis error... remove blank line at end of file. --- dnsapi/dns_freedns.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/dnsapi/dns_freedns.sh b/dnsapi/dns_freedns.sh index ad3f9da3..28aaa77a 100755 --- a/dnsapi/dns_freedns.sh +++ b/dnsapi/dns_freedns.sh @@ -368,4 +368,3 @@ _freedns_delete_txt_record() { _info "Deleted acme challenge TXT record for $fulldomain at FreeDNS" return 0 } - From e6b940e24754ede06e8b2618d50347bf8f39185b Mon Sep 17 00:00:00 2001 From: David Kerr Date: Fri, 3 Feb 2017 22:59:22 -0500 Subject: [PATCH 186/189] Minor edits to FreeDNS documentation --- README.md | 2 +- dnsapi/README.md | 7 ++----- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 067e9b50..c6362ed7 100644 --- a/README.md +++ b/README.md @@ -270,7 +270,7 @@ You don't have to do anything manually! 1. ISPConfig 3.1 API 1. Alwaysdata.com API 1. Linode.com API -1. FreeDNS +1. FreeDNS (https://freedns.afraid.org/) **More APIs coming soon...** diff --git a/dnsapi/README.md b/dnsapi/README.md index 65acb7d9..fc613e2a 100644 --- a/dnsapi/README.md +++ b/dnsapi/README.md @@ -278,7 +278,7 @@ acme.sh --issue --dns dns_linode --dnssleep 900 -d example.com -d www.example.co The `LINODE_API_KEY` will be saved in `~/.acme.sh/account.conf` and will be reused when needed. -## 15. Use FreeDNS +## 15. Use FreeDNS FreeDNS (https://freedns.afraid.org/) does not provide an API to update DNS records (other than IPv4 and IPv6 dynamic DNS addresses). The acme.sh plugin therefore retrieves and updates domain TXT records by logging @@ -298,12 +298,9 @@ reuses that when needed. Now you can issue a certificate. ```sh -acme.sh --issue --dns dns_freedns --dnssleep 30 -d example.com -d www.example.com +acme.sh --issue --dns dns_freedns -d example.com -d www.example.com ``` -FreeDNS updates records quite quickly so it is possible to reduce the dnssleep time, in the above example -to 30 seconds. - # Use custom API If your API is not supported yet, you can write your own DNS API. From f78b656f5f6c20bde86c10b1bfb40bf2f210d899 Mon Sep 17 00:00:00 2001 From: David Kerr Date: Sat, 4 Feb 2017 10:21:58 -0500 Subject: [PATCH 187/189] Add error message if fails to add TXT record for missing security code (probably a FreeDNS public domain) --- dnsapi/README.md | 4 ++++ dnsapi/dns_freedns.sh | 19 ++++++++++--------- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/dnsapi/README.md b/dnsapi/README.md index fc613e2a..6a86bf4c 100644 --- a/dnsapi/README.md +++ b/dnsapi/README.md @@ -301,6 +301,10 @@ Now you can issue a certificate. acme.sh --issue --dns dns_freedns -d example.com -d www.example.com ``` +Note that you cannot use acme.sh automatic DNS validation for FreeDNS public domains or for a subdomain that +you create under a FreeDNS public domain. You must own the top level domain in order to automaitcally +validate with acme.sh at FreeDNS. + # Use custom API If your API is not supported yet, you can write your own DNS API. diff --git a/dnsapi/dns_freedns.sh b/dnsapi/dns_freedns.sh index 28aaa77a..8d519fd5 100755 --- a/dnsapi/dns_freedns.sh +++ b/dnsapi/dns_freedns.sh @@ -307,9 +307,7 @@ _freedns_retrieve_subdomain_page() { if [ "$?" != "0" ]; then _err "FreeDNS retrieve subdomins failed bad RC from _get" return 1 - fi - - if [ -z "$htmlpage" ]; then + elif [ -z "$htmlpage" ]; then _err "FreeDNS returned empty subdomain page" return 1 fi @@ -334,13 +332,18 @@ _freedns_add_txt_record() { if [ "$?" != "0" ]; then _err "FreeDNS failed to add TXT record for $subdomain bad RC from _post" return 1 - fi - - if ! grep "200 OK" "$HTTP_HEADER" >/dev/null; then + elif ! grep "200 OK" "$HTTP_HEADER" >/dev/null; then _debug "$htmlpage" _err "FreeDNS failed to add TXT record for $subdomain. Check $HTTP_HEADER file" return 1 + elif _contains "$htmlpage" "security code was incorrect"; then + _debug "$htmlpage" + _err "FreeDNS failed to add TXT record for $subdomain as FreeDNS requested seurity code" + _err "Note that you cannot use automatic DNS validation for FreeDNS public domains" + return 1 fi + + _debug2 "$htmlpage" _info "Added acme challenge TXT record for $fulldomain at FreeDNS" return 0 } @@ -357,9 +360,7 @@ _freedns_delete_txt_record() { if [ "$?" != "0" ]; then _err "FreeDNS failed to delete TXT record for $data_id bad RC from _get" return 1 - fi - - if ! _contains "$htmlheader" "200 OK"; then + elif ! _contains "$htmlheader" "200 OK"; then _debug "$htmlheader" _err "FreeDNS failed to delete TXT record $data_id" return 1 From 87f5ec5be52208c2daaf040c646bee69fdcb7771 Mon Sep 17 00:00:00 2001 From: David Kerr Date: Sat, 4 Feb 2017 10:36:51 -0500 Subject: [PATCH 188/189] Add Accept-Language:en-US to HTTP header as precaution against future multi-lingual FreeDNS pages. --- dnsapi/dns_freedns.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/dnsapi/dns_freedns.sh b/dnsapi/dns_freedns.sh index 8d519fd5..f30c8958 100755 --- a/dnsapi/dns_freedns.sh +++ b/dnsapi/dns_freedns.sh @@ -267,6 +267,7 @@ dns_freedns_rm() { # print string "cookie=value" etc. # returns 0 success _freedns_login() { + export _H1="Accept-Language:en-US" username="$1" password="$2" url="https://freedns.afraid.org/zc.php?step=2" @@ -298,6 +299,7 @@ _freedns_login() { # returns 0 success _freedns_retrieve_subdomain_page() { export _H1="Cookie:$1" + export _H2="Accept-Language:en-US" url="https://freedns.afraid.org/subdomain/" _debug "Retrieve subdmoain page from FreeDNS" @@ -322,6 +324,7 @@ _freedns_retrieve_subdomain_page() { # returns 0 success _freedns_add_txt_record() { export _H1="Cookie:$1" + export _H2="Accept-Language:en-US" domain_id="$2" subdomain="$3" value="$(printf '%s' "$4" | _url_encode)" @@ -352,6 +355,7 @@ _freedns_add_txt_record() { # returns 0 success _freedns_delete_txt_record() { export _H1="Cookie:$1" + export _H2="Accept-Language:en-US" data_id="$2" url="https://freedns.afraid.org/subdomain/delete2.php" From 9bdb799b412bf86cddbe62d630e94a023fcc532d Mon Sep 17 00:00:00 2001 From: neilpang Date: Sun, 5 Feb 2017 13:16:51 +0800 Subject: [PATCH 189/189] fix bug when the od command is missing --- acme.sh | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index bc211522..df4a0b4a 100755 --- a/acme.sh +++ b/acme.sh @@ -340,11 +340,29 @@ _is_solaris() { _contains "${__OS__:=$(uname -a)}" "solaris" || _contains "${__OS__:=$(uname -a)}" "SunOS" } +#_ascii_hex str +#this can only process ascii chars, should only be used when od command is missing as a backup way. +_ascii_hex() { + _debug2 "Using _ascii_hex" + _str="$1" + _str_len=${#_str} + _h_i=1 + while [ "$_h_i" -le "$_str_len" ]; do + _str_c="$(printf "%s" "$_str" | cut -c "$_h_i")" + printf " %02x" "'$_str_c" + _h_i="$(_math "$_h_i" + 1)" + done +} + #stdin output hexstr splited by one space #input:"abc" #output: " 61 62 63" _hex_dump() { - od -A n -v -t x1 | tr -d "\r\t" | tr -s " " | sed "s/ $//" | tr -d "\n" + #in wired some system, the od command is missing. + if ! od -A n -v -t x1 | tr -d "\r\t" | tr -s " " | sed "s/ $//" | tr -d "\n" 2>/dev/null; then + str=$(cat) + _ascii_hex "$str" + fi } #url encode, no-preserved chars