Unverified Commit b203f2ab authored by F-Plass's avatar F-Plass Committed by GitHub
Browse files

Merge branch 'acmesh-official:master' into master

parents 3bcb91f6 5490a2f3
# Comment to a new issue.
issuesOpened: >
If this is a bug report, please upgrade to the latest code and try again:
如果有 bug, 请先更新到最新版试试:
```
acme.sh --upgrade
```
please also provide the log with `--debug 2`.
同时请提供调试输出 `--debug 2`
see: https://github.com/acmesh-official/acme.sh/wiki/How-to-debug-acme.sh
Without `--debug 2` log, your issue will NEVER get replied.
没有调试输出, 你的 issue 不会得到任何解答.
pullRequestOpened: >
First, NEVER send a PR to `master` branch, it will NEVER be accepted. Please send to the `dev` branch instead.
If this is a PR to support new DNS API or new notification API, please read this guide first:
https://github.com/acmesh-official/acme.sh/wiki/DNS-API-Dev-Guide
Please check the guide items one by one.
Then add your usage here:
https://github.com/acmesh-official/acme.sh/wiki/dnsapi
Or some other wiki pages:
https://github.com/acmesh-official/acme.sh/wiki/deployhooks
https://github.com/acmesh-official/acme.sh/wiki/notify
...@@ -59,24 +59,24 @@ jobs: ...@@ -59,24 +59,24 @@ jobs:
run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
- name: Set env file - name: Set env file
run: | run: |
cd ../acmetest cd ../acmetest
if [ "${{ secrets.TokenName1}}" ] ; then if [ "${{ secrets.TokenName1}}" ] ; then
echo "${{ secrets.TokenName1}}=${{ secrets.TokenValue1}}" >> env.list echo "${{ secrets.TokenName1}}=${{ secrets.TokenValue1}}" >> docker.env
fi fi
if [ "${{ secrets.TokenName2}}" ] ; then if [ "${{ secrets.TokenName2}}" ] ; then
echo "${{ secrets.TokenName2}}=${{ secrets.TokenValue2}}" >> env.list echo "${{ secrets.TokenName2}}=${{ secrets.TokenValue2}}" >> docker.env
fi fi
if [ "${{ secrets.TokenName3}}" ] ; then if [ "${{ secrets.TokenName3}}" ] ; then
echo "${{ secrets.TokenName3}}=${{ secrets.TokenValue3}}" >> env.list echo "${{ secrets.TokenName3}}=${{ secrets.TokenValue3}}" >> docker.env
fi fi
if [ "${{ secrets.TokenName4}}" ] ; then if [ "${{ secrets.TokenName4}}" ] ; then
echo "${{ secrets.TokenName4}}=${{ secrets.TokenValue4}}" >> env.list echo "${{ secrets.TokenName4}}=${{ secrets.TokenValue4}}" >> docker.env
fi fi
if [ "${{ secrets.TokenName5}}" ] ; then if [ "${{ secrets.TokenName5}}" ] ; then
echo "${{ secrets.TokenName5}}=${{ secrets.TokenValue5}}" >> env.list echo "${{ secrets.TokenName5}}=${{ secrets.TokenValue5}}" >> docker.env
fi fi
echo "TEST_DNS_NO_WILDCARD" >> env.list echo "TEST_DNS_NO_WILDCARD" >> docker.env
echo "TEST_DNS_SLEEP" >> env.list echo "TEST_DNS_SLEEP" >> docker.env
- name: Run acmetest - name: Run acmetest
run: cd ../acmetest && ./rundocker.sh testall run: cd ../acmetest && ./rundocker.sh testall
...@@ -170,7 +170,7 @@ jobs: ...@@ -170,7 +170,7 @@ jobs:
./letest.sh ./letest.sh
FreeBSD: FreeBSD:
runs-on: macos-latest runs-on: macos-10.15
needs: Windows needs: Windows
env: env:
TEST_DNS : ${{ secrets.TEST_DNS }} TEST_DNS : ${{ secrets.TEST_DNS }}
...@@ -184,7 +184,7 @@ jobs: ...@@ -184,7 +184,7 @@ jobs:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- name: Clone acmetest - name: Clone acmetest
run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
- uses: vmactions/freebsd-vm@v0.0.7 - uses: vmactions/freebsd-vm@v0.1.4
with: with:
envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}'
prepare: pkg install -y socat curl prepare: pkg install -y socat curl
...@@ -209,7 +209,7 @@ jobs: ...@@ -209,7 +209,7 @@ jobs:
./letest.sh ./letest.sh
Solaris: Solaris:
runs-on: macos-latest runs-on: macos-10.15
needs: FreeBSD needs: FreeBSD
env: env:
TEST_DNS : ${{ secrets.TEST_DNS }} TEST_DNS : ${{ secrets.TEST_DNS }}
...@@ -223,11 +223,13 @@ jobs: ...@@ -223,11 +223,13 @@ jobs:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- name: Clone acmetest - name: Clone acmetest
run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
- uses: vmactions/solaris-vm@v0.0.1 - uses: vmactions/solaris-vm@v0.0.3
with: with:
envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}' envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}'
prepare: pkgutil -y -i socat curl prepare: pkgutil -y -i socat
run: | run: |
pkg set-mediator -v -I default@1.1 openssl
export PATH=/usr/gnu/bin:$PATH
if [ "${{ secrets.TokenName1}}" ] ; then if [ "${{ secrets.TokenName1}}" ] ; then
export ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}} export ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}}
fi fi
...@@ -245,5 +247,3 @@ jobs: ...@@ -245,5 +247,3 @@ jobs:
fi fi
cd ../acmetest cd ../acmetest
./letest.sh ./letest.sh
name: FreeBSD
on:
push:
branches:
- '*'
paths:
- '*.sh'
- '.github/workflows/FreeBSD.yml'
pull_request:
branches:
- dev
paths:
- '*.sh'
- '.github/workflows/FreeBSD.yml'
jobs:
FreeBSD:
strategy:
matrix:
include:
- TEST_ACME_Server: "LetsEncrypt.org_test"
CA_ECDSA: ""
CA: ""
CA_EMAIL: ""
TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1
- TEST_ACME_Server: "ZeroSSL.com"
CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA"
CA: "ZeroSSL RSA Domain Secure Site CA"
CA_EMAIL: "githubtest@acme.sh"
TEST_PREFERRED_CHAIN: ""
runs-on: macos-10.15
env:
TEST_LOCAL: 1
TEST_ACME_Server: ${{ matrix.TEST_ACME_Server }}
CA_ECDSA: ${{ matrix.CA_ECDSA }}
CA: ${{ matrix.CA }}
CA_EMAIL: ${{ matrix.CA_EMAIL }}
TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }}
steps:
- uses: actions/checkout@v2
- uses: vmactions/cf-tunnel@v0.0.3
id: tunnel
with:
protocol: http
port: 8080
- name: Set envs
run: echo "TestingDomain=${{steps.tunnel.outputs.server}}" >> $GITHUB_ENV
- name: Clone acmetest
run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
- uses: vmactions/freebsd-vm@v0.1.5
with:
envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN'
nat: |
"8080": "80"
prepare: pkg install -y socat curl
usesh: true
run: |
cd ../acmetest \
&& ./letest.sh
name: LetsEncrypt
on:
push:
branches:
- '*'
paths:
- '**.sh'
- '**.yml'
pull_request:
branches:
- dev
paths:
- '**.sh'
- '**.yml'
jobs:
CheckToken:
runs-on: ubuntu-latest
outputs:
hasToken: ${{ steps.step_one.outputs.hasToken }}
env:
NGROK_TOKEN : ${{ secrets.NGROK_TOKEN }}
steps:
- name: Set the value
id: step_one
run: |
if [ "$NGROK_TOKEN" ] ; then
echo "::set-output name=hasToken::true"
else
echo "::set-output name=hasToken::false"
fi
- name: Check the value
run: echo ${{ steps.step_one.outputs.hasToken }}
Ubuntu:
runs-on: ubuntu-latest
needs: CheckToken
if: "contains(needs.CheckToken.outputs.hasToken, 'true')"
env:
NGROK_TOKEN : ${{ secrets.NGROK_TOKEN }}
TEST_LOCAL: 1
steps:
- uses: actions/checkout@v2
- name: Install tools
run: sudo apt-get install -y socat
- name: Clone acmetest
run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
- name: Run acmetest
run: cd ../acmetest && sudo --preserve-env ./letest.sh
MacOS:
runs-on: macos-latest
needs: Ubuntu
env:
NGROK_TOKEN : ${{ secrets.NGROK_TOKEN }}
TEST_LOCAL: 1
steps:
- uses: actions/checkout@v2
- name: Install tools
run: brew install socat
- name: Clone acmetest
run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
- name: Run acmetest
run: cd ../acmetest && sudo --preserve-env ./letest.sh
Windows:
runs-on: windows-latest
needs: MacOS
env:
NGROK_TOKEN : ${{ secrets.NGROK_TOKEN }}
TEST_LOCAL: 1
#The 80 port is used by Windows server, we have to use a custom port, ngrok will also use this port.
Le_HTTPPort: 8888
steps:
- name: Set git to use LF
run: |
git config --global core.autocrlf false
- uses: actions/checkout@v2
- name: Install cygwin base packages with chocolatey
run: |
choco config get cacheLocation
choco install --no-progress cygwin
shell: cmd
- name: Install cygwin additional packages
run: |
C:\tools\cygwin\cygwinsetup.exe -qgnNdO -R C:/tools/cygwin -s http://mirrors.kernel.org/sourceware/cygwin/ -P socat,curl,cron,unzip,git
shell: cmd
- name: Set ENV
shell: cmd
run: |
echo PATH=C:\tools\cygwin\bin;C:\tools\cygwin\usr\bin >> %GITHUB_ENV%
- name: Check ENV
shell: cmd
run: |
echo "PATH=%PATH%"
- name: Clone acmetest
shell: cmd
run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
- name: Run acmetest
shell: cmd
run: cd ../acmetest && bash.exe -c ./letest.sh
FreeBSD:
runs-on: macos-latest
needs: Windows
env:
NGROK_TOKEN : ${{ secrets.NGROK_TOKEN }}
TEST_LOCAL: 1
steps:
- uses: actions/checkout@v2
- name: Clone acmetest
run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
- uses: vmactions/freebsd-vm@v0.0.7
with:
envs: 'NGROK_TOKEN TEST_LOCAL'
prepare: pkg install -y socat curl
usesh: true
run: |
cd ../acmetest && ./letest.sh
Solaris:
runs-on: macos-latest
needs: FreeBSD
env:
NGROK_TOKEN : ${{ secrets.NGROK_TOKEN }}
TEST_LOCAL: 1
steps:
- uses: actions/checkout@v2
- uses: vmactions/ngrok-tunnel@v0.0.1
id: ngrok
with:
protocol: http
port: 8080
- name: Set envs
run: echo "TestingDomain=${{steps.ngrok.outputs.server}}" >> $GITHUB_ENV
- name: Clone acmetest
run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
- uses: vmactions/solaris-vm@v0.0.1
with:
envs: 'TEST_LOCAL TestingDomain'
nat: |
"8080": "80"
prepare: pkgutil -y -i socat curl
run: |
cd ../acmetest && ./letest.sh
name: Linux
on:
push:
branches:
- '*'
paths:
- '*.sh'
- '.github/workflows/Linux.yml'
pull_request:
branches:
- dev
paths:
- '*.sh'
- '.github/workflows/Linux.yml'
jobs:
Linux:
strategy:
matrix:
os: ["ubuntu:latest", "debian:latest", "almalinux:latest", "fedora:latest", "centos:latest", "opensuse/leap:latest", "alpine:latest", "oraclelinux:8", "kalilinux/kali", "archlinux:latest", "mageia", "gentoo/stage3-amd64"]
runs-on: ubuntu-latest
env:
TEST_LOCAL: 1
TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1
steps:
- uses: actions/checkout@v2
- name: Clone acmetest
run: |
cd .. \
&& git clone https://github.com/acmesh-official/acmetest.git \
&& cp -r acme.sh acmetest/
- name: Run acmetest
run: |
cd ../acmetest \
&& ./rundocker.sh testplat ${{ matrix.os }}
name: MacOS
on:
push:
branches:
- '*'
paths:
- '*.sh'
- '.github/workflows/MacOS.yml'
pull_request:
branches:
- dev
paths:
- '*.sh'
- '.github/workflows/MacOS.yml'
jobs:
MacOS:
strategy:
matrix:
include:
- TEST_ACME_Server: "LetsEncrypt.org_test"
CA_ECDSA: ""
CA: ""
CA_EMAIL: ""
TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1
- TEST_ACME_Server: "ZeroSSL.com"
CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA"
CA: "ZeroSSL RSA Domain Secure Site CA"
CA_EMAIL: "githubtest@acme.sh"
TEST_PREFERRED_CHAIN: ""
runs-on: macos-latest
env:
TEST_LOCAL: 1
TEST_ACME_Server: ${{ matrix.TEST_ACME_Server }}
CA_ECDSA: ${{ matrix.CA_ECDSA }}
CA: ${{ matrix.CA }}
CA_EMAIL: ${{ matrix.CA_EMAIL }}
TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }}
steps:
- uses: actions/checkout@v2
- name: Install tools
run: brew install socat
- name: Clone acmetest
run: |
cd .. \
&& git clone https://github.com/acmesh-official/acmetest.git \
&& cp -r acme.sh acmetest/
- name: Run acmetest
run: |
cd ../acmetest \
&& sudo --preserve-env ./letest.sh
...@@ -4,14 +4,14 @@ on: ...@@ -4,14 +4,14 @@ on:
branches: branches:
- '*' - '*'
paths: paths:
- '**.sh' - '*.sh'
- '**.yml' - '.github/workflows/PebbleStrict.yml'
pull_request: pull_request:
branches: branches:
- dev - dev
paths: paths:
- '**.sh' - '*.sh'
- '**.yml' - '.github/workflows/PebbleStrict.yml'
jobs: jobs:
PebbleStrict: PebbleStrict:
...@@ -19,7 +19,7 @@ jobs: ...@@ -19,7 +19,7 @@ jobs:
env: env:
TestingDomain: example.com TestingDomain: example.com
TestingAltDomains: www.example.com TestingAltDomains: www.example.com
ACME_DIRECTORY: https://localhost:14000/dir TEST_ACME_Server: https://localhost:14000/dir
HTTPS_INSECURE: 1 HTTPS_INSECURE: 1
Le_HTTPPort: 5002 Le_HTTPPort: 5002
TEST_LOCAL: 1 TEST_LOCAL: 1
...@@ -35,5 +35,28 @@ jobs: ...@@ -35,5 +35,28 @@ jobs:
run: curl --request POST --data '{"ip":"10.30.50.1"}' http://localhost:8055/set-default-ipv4 run: curl --request POST --data '{"ip":"10.30.50.1"}' http://localhost:8055/set-default-ipv4
- name: Clone acmetest - name: Clone acmetest
run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
- name: Run acmetest
run: cd ../acmetest && ./letest.sh
PebbleStrict_IPCert:
runs-on: ubuntu-latest
env:
TestingDomain: 10.30.50.1
ACME_DIRECTORY: https://localhost:14000/dir
HTTPS_INSECURE: 1
Le_HTTPPort: 5002
Le_TLSPort: 5001
TEST_LOCAL: 1
TEST_CA: "Pebble Intermediate CA"
TEST_IPCERT: 1
steps:
- uses: actions/checkout@v2
- name: Install tools
run: sudo apt-get install -y socat
- name: Run Pebble
run: cd .. && curl https://raw.githubusercontent.com/letsencrypt/pebble/master/docker-compose.yml >docker-compose.yml && docker-compose up -d
- name: Clone acmetest
run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
- name: Run acmetest - name: Run acmetest
run: cd ../acmetest && ./letest.sh run: cd ../acmetest && ./letest.sh
\ No newline at end of file
name: Solaris
on:
push:
branches:
- '*'
paths:
- '*.sh'
- '.github/workflows/Solaris.yml'
pull_request:
branches:
- dev
paths:
- '*.sh'
- '.github/workflows/Solaris.yml'
jobs:
Solaris:
strategy:
matrix:
include:
- TEST_ACME_Server: "LetsEncrypt.org_test"
CA_ECDSA: ""
CA: ""
CA_EMAIL: ""
TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1
- TEST_ACME_Server: "ZeroSSL.com"
CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA"
CA: "ZeroSSL RSA Domain Secure Site CA"
CA_EMAIL: "githubtest@acme.sh"
TEST_PREFERRED_CHAIN: ""
runs-on: macos-10.15
env:
TEST_LOCAL: 1
TEST_ACME_Server: ${{ matrix.TEST_ACME_Server }}
CA_ECDSA: ${{ matrix.CA_ECDSA }}
CA: ${{ matrix.CA }}
CA_EMAIL: ${{ matrix.CA_EMAIL }}
TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }}
steps:
- uses: actions/checkout@v2
- uses: vmactions/cf-tunnel@v0.0.3
id: tunnel
with:
protocol: http
port: 8080
- name: Set envs
run: echo "TestingDomain=${{steps.tunnel.outputs.server}}" >> $GITHUB_ENV
- name: Clone acmetest
run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
- uses: vmactions/solaris-vm@v0.0.3
with:
envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN'
nat: |
"8080": "80"
prepare: pkgutil -y -i socat curl
run: |
cd ../acmetest \
&& ./letest.sh
name: Ubuntu
on:
push:
branches:
- '*'
paths:
- '*.sh'
- '.github/workflows/Ubuntu.yml'
pull_request:
branches:
- dev
paths:
- '*.sh'
- '.github/workflows/Ubuntu.yml'
jobs:
Ubuntu:
strategy:
matrix:
include:
- TEST_ACME_Server: "LetsEncrypt.org_test"
CA_ECDSA: ""
CA: ""
CA_EMAIL: ""
TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1
- TEST_ACME_Server: "ZeroSSL.com"
CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA"
CA: "ZeroSSL RSA Domain Secure Site CA"
CA_EMAIL: "githubtest@acme.sh"
TEST_PREFERRED_CHAIN: ""
runs-on: ubuntu-latest
env:
TEST_LOCAL: 1
TEST_ACME_Server: ${{ matrix.TEST_ACME_Server }}
CA_ECDSA: ${{ matrix.CA_ECDSA }}
CA: ${{ matrix.CA }}
CA_EMAIL: ${{ matrix.CA_EMAIL }}
NO_ECC_384: ${{ matrix.NO_ECC_384 }}
TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }}
steps:
- uses: actions/checkout@v2
- name: Install tools
run: sudo apt-get install -y socat
- name: Clone acmetest
run: |
cd .. \
&& git clone https://github.com/acmesh-official/acmetest.git \
&& cp -r acme.sh acmetest/
- name: Run acmetest
run: |
cd ../acmetest \
&& sudo --preserve-env ./letest.sh
name: Windows
on:
push:
branches:
- '*'
paths:
- '*.sh'
- '.github/workflows/Windows.yml'
pull_request:
branches:
- dev
paths:
- '*.sh'
- '.github/workflows/Windows.yml'
jobs:
Windows:
strategy:
matrix:
include:
- TEST_ACME_Server: "LetsEncrypt.org_test"
CA_ECDSA: ""
CA: ""
CA_EMAIL: ""
TEST_PREFERRED_CHAIN: (STAGING) Pretend Pear X1
- TEST_ACME_Server: "ZeroSSL.com"
CA_ECDSA: "ZeroSSL ECC Domain Secure Site CA"
CA: "ZeroSSL RSA Domain Secure Site CA"
CA_EMAIL: "githubtest@acme.sh"
TEST_PREFERRED_CHAIN: ""
runs-on: windows-latest
env:
TEST_ACME_Server: ${{ matrix.TEST_ACME_Server }}
CA_ECDSA: ${{ matrix.CA_ECDSA }}
CA: ${{ matrix.CA }}
CA_EMAIL: ${{ matrix.CA_EMAIL }}
TEST_LOCAL: 1
#The 80 port is used by Windows server, we have to use a custom port, tunnel will also use this port.
Le_HTTPPort: 8888
TEST_PREFERRED_CHAIN: ${{ matrix.TEST_PREFERRED_CHAIN }}
steps:
- name: Set git to use LF
run: |
git config --global core.autocrlf false
- uses: actions/checkout@v2
- name: Install cygwin base packages with chocolatey
run: |
choco config get cacheLocation
choco install --no-progress cygwin
shell: cmd
- name: Install cygwin additional packages
run: |
C:\tools\cygwin\cygwinsetup.exe -qgnNdO -R C:/tools/cygwin -s http://mirrors.kernel.org/sourceware/cygwin/ -P socat,curl,cron,unzip,git,xxd
shell: cmd
- name: Set ENV
shell: cmd
run: |
echo PATH=C:\tools\cygwin\bin;C:\tools\cygwin\usr\bin;%PATH% >> %GITHUB_ENV%
- name: Check ENV
shell: cmd
run: |
echo "PATH=%PATH%"
- name: Clone acmetest
shell: cmd
run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
- name: Run acmetest
shell: cmd
run: cd ../acmetest && bash.exe -c ./letest.sh
...@@ -6,6 +6,11 @@ on: ...@@ -6,6 +6,11 @@ on:
- '*' - '*'
tags: tags:
- '*' - '*'
paths:
- '**.sh'
- "Dockerfile"
- '.github/workflows/dockerhub.yml'
jobs: jobs:
CheckToken: CheckToken:
......
...@@ -5,13 +5,13 @@ on: ...@@ -5,13 +5,13 @@ on:
- '*' - '*'
paths: paths:
- '**.sh' - '**.sh'
- '**.yml' - '.github/workflows/shellcheck.yml'
pull_request: pull_request:
branches: branches:
- dev - dev
paths: paths:
- '**.sh' - '**.sh'
- '**.yml' - '.github/workflows/shellcheck.yml'
jobs: jobs:
ShellCheck: ShellCheck:
......
FROM alpine:3.12 FROM alpine:3.12
RUN apk update -f \ RUN apk --no-cache add -f \
&& apk --no-cache add -f \
openssl \ openssl \
openssh-client \ openssh-client \
coreutils \ coreutils \
...@@ -12,8 +11,7 @@ RUN apk update -f \ ...@@ -12,8 +11,7 @@ RUN apk update -f \
tzdata \ tzdata \
oath-toolkit-oathtool \ oath-toolkit-oathtool \
tar \ tar \
libidn \ libidn
&& rm -rf /var/cache/apk/*
ENV LE_CONFIG_HOME /acme.sh ENV LE_CONFIG_HOME /acme.sh
...@@ -22,7 +20,7 @@ ARG AUTO_UPGRADE=1 ...@@ -22,7 +20,7 @@ ARG AUTO_UPGRADE=1
ENV AUTO_UPGRADE $AUTO_UPGRADE ENV AUTO_UPGRADE $AUTO_UPGRADE
#Install #Install
ADD ./ /install_acme.sh/ COPY ./ /install_acme.sh/
RUN cd /install_acme.sh && ([ -f /install_acme.sh/acme.sh ] && /install_acme.sh/acme.sh --install || curl https://get.acme.sh | sh) && rm -rf /install_acme.sh/ RUN cd /install_acme.sh && ([ -f /install_acme.sh/acme.sh ] && /install_acme.sh/acme.sh --install || curl https://get.acme.sh | sh) && rm -rf /install_acme.sh/
...@@ -57,6 +55,7 @@ RUN for verb in help \ ...@@ -57,6 +55,7 @@ RUN for verb in help \
deactivate-account \ deactivate-account \
set-notify \ set-notify \
set-default-ca \ set-default-ca \
set-default-chain \
; do \ ; do \
printf -- "%b" "#!/usr/bin/env sh\n/root/.acme.sh/acme.sh --${verb} --config-home /acme.sh \"\$@\"" >/usr/local/bin/--${verb} && chmod +x /usr/local/bin/--${verb} \ printf -- "%b" "#!/usr/bin/env sh\n/root/.acme.sh/acme.sh --${verb} --config-home /acme.sh \"\$@\"" >/usr/local/bin/--${verb} && chmod +x /usr/local/bin/--${verb} \
; done ; done
......
# An ACME Shell script: acme.sh # An ACME Shell script: acme.sh
![LetsEncrypt](https://github.com/acmesh-official/acme.sh/workflows/LetsEncrypt/badge.svg) [![FreeBSD](https://github.com/acmesh-official/acme.sh/actions/workflows/FreeBSD.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/FreeBSD.yml)
[![MacOS](https://github.com/acmesh-official/acme.sh/actions/workflows/MacOS.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/MacOS.yml)
[![Ubuntu](https://github.com/acmesh-official/acme.sh/actions/workflows/Ubuntu.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Ubuntu.yml)
[![Windows](https://github.com/acmesh-official/acme.sh/actions/workflows/Windows.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Windows.yml)
[![Solaris](https://github.com/acmesh-official/acme.sh/actions/workflows/Solaris.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Solaris.yml)
![Shellcheck](https://github.com/acmesh-official/acme.sh/workflows/Shellcheck/badge.svg) ![Shellcheck](https://github.com/acmesh-official/acme.sh/workflows/Shellcheck/badge.svg)
![PebbleStrict](https://github.com/acmesh-official/acme.sh/workflows/PebbleStrict/badge.svg) ![PebbleStrict](https://github.com/acmesh-official/acme.sh/workflows/PebbleStrict/badge.svg)
![DockerHub](https://github.com/acmesh-official/acme.sh/workflows/Build%20DockerHub/badge.svg) ![DockerHub](https://github.com/acmesh-official/acme.sh/workflows/Build%20DockerHub/badge.svg)
...@@ -15,18 +20,18 @@ ...@@ -15,18 +20,18 @@
- An ACME protocol client written purely in Shell (Unix shell) language. - An ACME protocol client written purely in Shell (Unix shell) language.
- Full ACME protocol implementation. - Full ACME protocol implementation.
- Support ACME v1 and ACME v2 - Support ECDSA certs
- Support ACME v2 wildcard certs - Support SAN and wildcard certs
- Simple, powerful and very easy to use. You only need 3 minutes to learn it. - Simple, powerful and very easy to use. You only need 3 minutes to learn it.
- Bash, dash and sh compatible. - Bash, dash and sh compatible.
- Purely written in Shell with no dependencies on python or the official Let's Encrypt client. - Purely written in Shell with no dependencies on python.
- Just one script to issue, renew and install your certificates automatically. - Just one script to issue, renew and install your certificates automatically.
- DOES NOT require `root/sudoer` access. - DOES NOT require `root/sudoer` access.
- Docker friendly - Docker ready
- IPv6 support - IPv6 ready
- Cron job notifications for renewal or error etc. - Cron job notifications for renewal or error etc.
It's probably the `easiest & smartest` shell script to automatically issue & renew the free certificates from Let's Encrypt. It's probably the `easiest & smartest` shell script to automatically issue & renew the free certificates.
Wiki: https://github.com/acmesh-official/acme.sh/wiki Wiki: https://github.com/acmesh-official/acme.sh/wiki
...@@ -57,37 +62,39 @@ Twitter: [@neilpangxa](https://twitter.com/neilpangxa) ...@@ -57,37 +62,39 @@ Twitter: [@neilpangxa](https://twitter.com/neilpangxa)
| NO | Status| Platform| | NO | Status| Platform|
|----|-------|---------| |----|-------|---------|
|1|[![MacOS](https://github.com/acmesh-official/acme.sh/workflows/LetsEncrypt/badge.svg)](https://github.com/acmesh-official/acme.sh/actions?query=workflow%3ALetsEncrypt)|Mac OSX |1|[![MacOS](https://github.com/acmesh-official/acme.sh/actions/workflows/MacOS.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/MacOS.yml)|Mac OSX
|2|[![Windows](https://github.com/acmesh-official/acme.sh/workflows/LetsEncrypt/badge.svg)](https://github.com/acmesh-official/acme.sh/actions?query=workflow%3ALetsEncrypt)|Windows (cygwin with curl, openssl and crontab included) |2|[![Windows](https://github.com/acmesh-official/acme.sh/actions/workflows/Windows.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Windows.yml)|Windows (cygwin with curl, openssl and crontab included)
|3|[![FreeBSD](https://github.com/acmesh-official/acme.sh/workflows/LetsEncrypt/badge.svg)](https://github.com/acmesh-official/acme.sh/actions?query=workflow%3ALetsEncrypt)|FreeBSD |3|[![FreeBSD](https://github.com/acmesh-official/acme.sh/actions/workflows/FreeBSD.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/FreeBSD.yml)|FreeBSD
|4|[![Solaris](https://github.com/acmesh-official/acme.sh/workflows/LetsEncrypt/badge.svg)](https://github.com/acmesh-official/acme.sh/actions?query=workflow%3ALetsEncrypt)|Solaris |4|[![Solaris](https://github.com/acmesh-official/acme.sh/actions/workflows/Solaris.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Solaris.yml)|Solaris
|5|[![Ubuntu](https://github.com/acmesh-official/acme.sh/workflows/LetsEncrypt/badge.svg)](https://github.com/acmesh-official/acme.sh/actions?query=workflow%3ALetsEncrypt)| Ubuntu |5|[![Ubuntu](https://github.com/acmesh-official/acme.sh/actions/workflows/Ubuntu.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Ubuntu.yml)| Ubuntu
|6|[![](https://acmesh-official.github.io/acmetest/status/pfsense.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|pfsense |6|NA|pfsense
|7|[![](https://acmesh-official.github.io/acmetest/status/openbsd.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|OpenBSD |7|NA|OpenBSD
|8|[![](https://acmesh-official.github.io/acmetest/status/debian-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)| Debian |8|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)| Debian
|9|[![](https://acmesh-official.github.io/acmetest/status/centos-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|CentOS |9|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|CentOS
|10|[![](https://acmesh-official.github.io/acmetest/status/opensuse-leap-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|openSUSE |10|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|openSUSE
|11|[![](https://acmesh-official.github.io/acmetest/status/alpine-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|Alpine Linux (with curl) |11|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Alpine Linux (with curl)
|12|[![](https://acmesh-official.github.io/acmetest/status/archlinux-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|Archlinux |12|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Archlinux
|13|[![](https://acmesh-official.github.io/acmetest/status/fedora-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|fedora |13|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|fedora
|14|[![](https://acmesh-official.github.io/acmetest/status/kalilinux-kali.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|Kali Linux |14|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Kali Linux
|15|[![](https://acmesh-official.github.io/acmetest/status/oraclelinux-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|Oracle Linux |15|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Oracle Linux
|16|[![](https://acmesh-official.github.io/acmetest/status/proxmox.svg)](https://github.com/acmesh-official/letest#here-are-the-latest-status)| Proxmox: See Proxmox VE Wiki. Version [4.x, 5.0, 5.1](https://pve.proxmox.com/wiki/HTTPS_Certificate_Configuration_(Version_4.x,_5.0_and_5.1)#Let.27s_Encrypt_using_acme.sh), version [5.2 and up](https://pve.proxmox.com/wiki/Certificate_Management) |16|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Mageia
|17|-----| Cloud Linux https://github.com/acmesh-official/acme.sh/issues/111 |17|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|Gentoo Linux
|18|[![](https://acmesh-official.github.io/acmetest/status/mageia.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|Mageia |18|[![Linux](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml/badge.svg)](https://github.com/acmesh-official/acme.sh/actions/workflows/Linux.yml)|ClearLinux
|19|-----| OpenWRT: Tested and working. See [wiki page](https://github.com/acmesh-official/acme.sh/wiki/How-to-run-on-OpenWRT) |19|-----| Cloud Linux https://github.com/acmesh-official/acme.sh/issues/111
|20|[![](https://acmesh-official.github.io/acmetest/status/gentoo-stage3-amd64.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|Gentoo Linux |20|-----| OpenWRT: Tested and working. See [wiki page](https://github.com/acmesh-official/acme.sh/wiki/How-to-run-on-OpenWRT)
|21|[![](https://acmesh-official.github.io/acmetest/status/clearlinux-latest.svg)](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|ClearLinux |21|[![](https://acmesh-official.github.io/acmetest/status/proxmox.svg)](https://github.com/acmesh-official/letest#here-are-the-latest-status)| Proxmox: See Proxmox VE Wiki. Version [4.x, 5.0, 5.1](https://pve.proxmox.com/wiki/HTTPS_Certificate_Configuration_(Version_4.x,_5.0_and_5.1)#Let.27s_Encrypt_using_acme.sh), version [5.2 and up](https://pve.proxmox.com/wiki/Certificate_Management)
For all build statuses, check our [weekly build project](https://github.com/acmesh-official/acmetest):
Check our [testing project](https://github.com/acmesh-official/acmetest):
https://github.com/acmesh-official/acmetest https://github.com/acmesh-official/acmetest
# Supported CA # Supported CA
- Letsencrypt.org CA(default) - [ZeroSSL.com CA](https://github.com/acmesh-official/acme.sh/wiki/ZeroSSL.com-CA)(default)
- [ZeroSSL.com CA](https://github.com/acmesh-official/acme.sh/wiki/ZeroSSL.com-CA) - Letsencrypt.org CA
- [BuyPass.com CA](https://github.com/acmesh-official/acme.sh/wiki/BuyPass.com-CA) - [BuyPass.com CA](https://github.com/acmesh-official/acme.sh/wiki/BuyPass.com-CA)
- [SSL.com CA](https://github.com/acmesh-official/acme.sh/wiki/SSL.com-CA)
- [Pebble strict Mode](https://github.com/letsencrypt/pebble) - [Pebble strict Mode](https://github.com/letsencrypt/pebble)
- Any other [RFC8555](https://tools.ietf.org/html/rfc8555)-compliant CA - Any other [RFC8555](https://tools.ietf.org/html/rfc8555)-compliant CA
...@@ -469,7 +476,7 @@ TODO: ...@@ -469,7 +476,7 @@ TODO:
### Code Contributors ### Code Contributors
This project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)]. This project exists thanks to all the people who contribute.
<a href="https://github.com/acmesh-official/acme.sh/graphs/contributors"><img src="https://opencollective.com/acmesh/contributors.svg?width=890&button=false" /></a> <a href="https://github.com/acmesh-official/acme.sh/graphs/contributors"><img src="https://opencollective.com/acmesh/contributors.svg?width=890&button=false" /></a>
### Financial Contributors ### Financial Contributors
......
#!/usr/bin/env sh #!/usr/bin/env sh
VER=2.8.9 VER=3.0.2
PROJECT_NAME="acme.sh" PROJECT_NAME="acme.sh"
...@@ -20,8 +20,7 @@ _SUB_FOLDER_DEPLOY="deploy" ...@@ -20,8 +20,7 @@ _SUB_FOLDER_DEPLOY="deploy"
_SUB_FOLDERS="$_SUB_FOLDER_DNSAPI $_SUB_FOLDER_DEPLOY $_SUB_FOLDER_NOTIFY" _SUB_FOLDERS="$_SUB_FOLDER_DNSAPI $_SUB_FOLDER_DEPLOY $_SUB_FOLDER_NOTIFY"
LETSENCRYPT_CA_V1="https://acme-v01.api.letsencrypt.org/directory" CA_LETSENCRYPT_V1="https://acme-v01.api.letsencrypt.org/directory"
LETSENCRYPT_STAGING_CA_V1="https://acme-staging.api.letsencrypt.org/directory"
CA_LETSENCRYPT_V2="https://acme-v02.api.letsencrypt.org/directory" CA_LETSENCRYPT_V2="https://acme-v02.api.letsencrypt.org/directory"
CA_LETSENCRYPT_V2_TEST="https://acme-staging-v02.api.letsencrypt.org/directory" CA_LETSENCRYPT_V2_TEST="https://acme-staging-v02.api.letsencrypt.org/directory"
...@@ -32,18 +31,22 @@ CA_BUYPASS_TEST="https://api.test4.buypass.no/acme/directory" ...@@ -32,18 +31,22 @@ CA_BUYPASS_TEST="https://api.test4.buypass.no/acme/directory"
CA_ZEROSSL="https://acme.zerossl.com/v2/DV90" CA_ZEROSSL="https://acme.zerossl.com/v2/DV90"
_ZERO_EAB_ENDPOINT="http://api.zerossl.com/acme/eab-credentials-email" _ZERO_EAB_ENDPOINT="http://api.zerossl.com/acme/eab-credentials-email"
DEFAULT_CA=$CA_LETSENCRYPT_V2 CA_SSLCOM_RSA="https://acme.ssl.com/sslcom-dv-rsa"
CA_SSLCOM_ECC="https://acme.ssl.com/sslcom-dv-ecc"
DEFAULT_CA=$CA_ZEROSSL
DEFAULT_STAGING_CA=$CA_LETSENCRYPT_V2_TEST DEFAULT_STAGING_CA=$CA_LETSENCRYPT_V2_TEST
CA_NAMES=" CA_NAMES="
ZeroSSL.com,zerossl
LetsEncrypt.org,letsencrypt LetsEncrypt.org,letsencrypt
LetsEncrypt.org_test,letsencrypt_test,letsencrypttest LetsEncrypt.org_test,letsencrypt_test,letsencrypttest
BuyPass.com,buypass BuyPass.com,buypass
BuyPass.com_test,buypass_test,buypasstest BuyPass.com_test,buypass_test,buypasstest
ZeroSSL.com,zerossl SSL.com,sslcom
" "
CA_SERVERS="$CA_LETSENCRYPT_V2,$CA_LETSENCRYPT_V2_TEST,$CA_BUYPASS,$CA_BUYPASS_TEST,$CA_ZEROSSL" CA_SERVERS="$CA_ZEROSSL,$CA_LETSENCRYPT_V2,$CA_LETSENCRYPT_V2_TEST,$CA_BUYPASS,$CA_BUYPASS_TEST,$CA_SSLCOM_RSA"
DEFAULT_USER_AGENT="$PROJECT_NAME/$VER ($PROJECT)" DEFAULT_USER_AGENT="$PROJECT_NAME/$VER ($PROJECT)"
...@@ -56,6 +59,9 @@ VTYPE_HTTP="http-01" ...@@ -56,6 +59,9 @@ VTYPE_HTTP="http-01"
VTYPE_DNS="dns-01" VTYPE_DNS="dns-01"
VTYPE_ALPN="tls-alpn-01" VTYPE_ALPN="tls-alpn-01"
ID_TYPE_DNS="dns"
ID_TYPE_IP="ip"
LOCAL_ANY_ADDRESS="0.0.0.0" LOCAL_ANY_ADDRESS="0.0.0.0"
DEFAULT_RENEW=60 DEFAULT_RENEW=60
...@@ -102,6 +108,8 @@ DEBUG_LEVEL_NONE=0 ...@@ -102,6 +108,8 @@ DEBUG_LEVEL_NONE=0
DOH_CLOUDFLARE=1 DOH_CLOUDFLARE=1
DOH_GOOGLE=2 DOH_GOOGLE=2
DOH_ALI=3
DOH_DP=4
HIDDEN_VALUE="[hidden](please add '--output-insecure' to see this value)" HIDDEN_VALUE="[hidden](please add '--output-insecure' to see this value)"
...@@ -156,6 +164,8 @@ _REVOKE_WIKI="https://github.com/acmesh-official/acme.sh/wiki/revokecert" ...@@ -156,6 +164,8 @@ _REVOKE_WIKI="https://github.com/acmesh-official/acme.sh/wiki/revokecert"
_ZEROSSL_WIKI="https://github.com/acmesh-official/acme.sh/wiki/ZeroSSL.com-CA" _ZEROSSL_WIKI="https://github.com/acmesh-official/acme.sh/wiki/ZeroSSL.com-CA"
_SSLCOM_WIKI="https://github.com/acmesh-official/acme.sh/wiki/SSL.com-CA"
_SERVER_WIKI="https://github.com/acmesh-official/acme.sh/wiki/Server" _SERVER_WIKI="https://github.com/acmesh-official/acme.sh/wiki/Server"
_PREFERRED_CHAIN_WIKI="https://github.com/acmesh-official/acme.sh/wiki/Preferred-Chain" _PREFERRED_CHAIN_WIKI="https://github.com/acmesh-official/acme.sh/wiki/Preferred-Chain"
...@@ -419,19 +429,27 @@ _secure_debug3() { ...@@ -419,19 +429,27 @@ _secure_debug3() {
} }
_upper_case() { _upper_case() {
# shellcheck disable=SC2018,SC2019 if _is_solaris; then
tr 'a-z' 'A-Z' tr '[:lower:]' '[:upper:]'
else
# shellcheck disable=SC2018,SC2019
tr 'a-z' 'A-Z'
fi
} }
_lower_case() { _lower_case() {
# shellcheck disable=SC2018,SC2019 if _is_solaris; then
tr 'A-Z' 'a-z' tr '[:upper:]' '[:lower:]'
else
# shellcheck disable=SC2018,SC2019
tr 'A-Z' 'a-z'
fi
} }
_startswith() { _startswith() {
_str="$1" _str="$1"
_sub="$2" _sub="$2"
echo "$_str" | grep "^$_sub" >/dev/null 2>&1 echo "$_str" | grep -- "^$_sub" >/dev/null 2>&1
} }
_endswith() { _endswith() {
...@@ -562,8 +580,16 @@ if _exists xargs && [ "$(printf %s '\\x41' | xargs printf)" = 'A' ]; then ...@@ -562,8 +580,16 @@ if _exists xargs && [ "$(printf %s '\\x41' | xargs printf)" = 'A' ]; then
fi fi
_h2b() { _h2b() {
if _exists xxd && xxd -r -p 2>/dev/null; then if _exists xxd; then
return if _contains "$(xxd --help 2>&1)" "assumes -c30"; then
if xxd -r -p -c 9999 2>/dev/null; then
return
fi
else
if xxd -r -p 2>/dev/null; then
return
fi
fi
fi fi
hex=$(cat) hex=$(cat)
...@@ -1124,7 +1150,7 @@ _createkey() { ...@@ -1124,7 +1150,7 @@ _createkey() {
if _isEccKey "$length"; then if _isEccKey "$length"; then
_debug "Using ec name: $eccname" _debug "Using ec name: $eccname"
if _opkey="$(${ACME_OPENSSL_BIN:-openssl} ecparam -name "$eccname" -genkey 2>/dev/null)"; then if _opkey="$(${ACME_OPENSSL_BIN:-openssl} ecparam -name "$eccname" -noout -genkey 2>/dev/null)"; then
echo "$_opkey" >"$f" echo "$_opkey" >"$f"
else else
_err "error ecc key name: $eccname" _err "error ecc key name: $eccname"
...@@ -1132,7 +1158,11 @@ _createkey() { ...@@ -1132,7 +1158,11 @@ _createkey() {
fi fi
else else
_debug "Using RSA: $length" _debug "Using RSA: $length"
if _opkey="$(${ACME_OPENSSL_BIN:-openssl} genrsa "$length" 2>/dev/null)"; then __traditional=""
if _contains "$(${ACME_OPENSSL_BIN:-openssl} help genrsa 2>&1)" "-traditional"; then
__traditional="-traditional"
fi
if _opkey="$(${ACME_OPENSSL_BIN:-openssl} genrsa $__traditional "$length" 2>/dev/null)"; then
echo "$_opkey" >"$f" echo "$_opkey" >"$f"
else else
_err "error rsa key: $length" _err "error rsa key: $length"
...@@ -1199,23 +1229,31 @@ _createcsr() { ...@@ -1199,23 +1229,31 @@ _createcsr() {
_debug2 csr "$csr" _debug2 csr "$csr"
_debug2 csrconf "$csrconf" _debug2 csrconf "$csrconf"
printf "[ req_distinguished_name ]\n[ req ]\ndistinguished_name = req_distinguished_name\nreq_extensions = v3_req\n[ v3_req ]\n\nkeyUsage = nonRepudiation, digitalSignature, keyEncipherment" >"$csrconf" printf "[ req_distinguished_name ]\n[ req ]\ndistinguished_name = req_distinguished_name\nreq_extensions = v3_req\n[ v3_req ]\n\n" >"$csrconf"
if [ "$acmeValidationv1" ]; then if [ "$acmeValidationv1" ]; then
domainlist="$(_idn "$domainlist")" domainlist="$(_idn "$domainlist")"
printf -- "\nsubjectAltName=DNS:$domainlist" >>"$csrconf" _debug2 domainlist "$domainlist"
alt=""
for dl in $(echo "$domainlist" | tr "," ' '); do
if [ "$alt" ]; then
alt="$alt,$(_getIdType "$dl" | _upper_case):$dl"
else
alt="$(_getIdType "$dl" | _upper_case):$dl"
fi
done
printf -- "\nsubjectAltName=$alt" >>"$csrconf"
elif [ -z "$domainlist" ] || [ "$domainlist" = "$NO_VALUE" ]; then elif [ -z "$domainlist" ] || [ "$domainlist" = "$NO_VALUE" ]; then
#single domain #single domain
_info "Single domain" "$domain" _info "Single domain" "$domain"
printf -- "\nsubjectAltName=DNS:$(_idn "$domain")" >>"$csrconf" printf -- "\nsubjectAltName=$(_getIdType "$domain" | _upper_case):$(_idn "$domain")" >>"$csrconf"
else else
domainlist="$(_idn "$domainlist")" domainlist="$(_idn "$domainlist")"
_debug2 domainlist "$domainlist" _debug2 domainlist "$domainlist"
if _contains "$domainlist" ","; then alt="$(_getIdType "$domain" | _upper_case):$domain"
alt="DNS:$(_idn "$domain"),DNS:$(echo "$domainlist" | sed "s/,,/,/g" | sed "s/,/,DNS:/g")" for dl in $(echo "$domainlist" | tr "," ' '); do
else alt="$alt,$(_getIdType "$dl" | _upper_case):$dl"
alt="DNS:$(_idn "$domain"),DNS:$domainlist" done
fi
#multi #multi
_info "Multi domain" "$alt" _info "Multi domain" "$alt"
printf -- "\nsubjectAltName=$alt" >>"$csrconf" printf -- "\nsubjectAltName=$alt" >>"$csrconf"
...@@ -1751,7 +1789,7 @@ _inithttp() { ...@@ -1751,7 +1789,7 @@ _inithttp() {
if [ -z "$ACME_HTTP_NO_REDIRECTS" ]; then if [ -z "$ACME_HTTP_NO_REDIRECTS" ]; then
_ACME_CURL="$_ACME_CURL -L " _ACME_CURL="$_ACME_CURL -L "
fi fi
if [ "$DEBUG" ] && [ "$DEBUG" -ge "2" ]; then if [ "$DEBUG" ] && [ "$DEBUG" -ge 2 ]; then
_CURL_DUMP="$(_mktemp)" _CURL_DUMP="$(_mktemp)"
_ACME_CURL="$_ACME_CURL --trace-ascii $_CURL_DUMP " _ACME_CURL="$_ACME_CURL --trace-ascii $_CURL_DUMP "
fi fi
...@@ -1791,6 +1829,8 @@ _inithttp() { ...@@ -1791,6 +1829,8 @@ _inithttp() {
} }
_HTTP_MAX_RETRY=8
# body url [needbase64] [POST|PUT|DELETE] [ContentType] # body url [needbase64] [POST|PUT|DELETE] [ContentType]
_post() { _post() {
body="$1" body="$1"
...@@ -1798,6 +1838,33 @@ _post() { ...@@ -1798,6 +1838,33 @@ _post() {
needbase64="$3" needbase64="$3"
httpmethod="$4" httpmethod="$4"
_postContentType="$5" _postContentType="$5"
_sleep_retry_sec=1
_http_retry_times=0
_hcode=0
while [ "${_http_retry_times}" -le "$_HTTP_MAX_RETRY" ]; do
[ "$_http_retry_times" = "$_HTTP_MAX_RETRY" ]
_lastHCode="$?"
_debug "Retrying post"
_post_impl "$body" "$_post_url" "$needbase64" "$httpmethod" "$_postContentType" "$_lastHCode"
_hcode="$?"
_debug _hcode "$_hcode"
if [ "$_hcode" = "0" ]; then
break
fi
_http_retry_times=$(_math $_http_retry_times + 1)
_sleep $_sleep_retry_sec
done
return $_hcode
}
# body url [needbase64] [POST|PUT|DELETE] [ContentType] [displayError]
_post_impl() {
body="$1"
_post_url="$2"
needbase64="$3"
httpmethod="$4"
_postContentType="$5"
displayError="$6"
if [ -z "$httpmethod" ]; then if [ -z "$httpmethod" ]; then
httpmethod="POST" httpmethod="POST"
...@@ -1849,7 +1916,9 @@ _post() { ...@@ -1849,7 +1916,9 @@ _post() {
fi fi
_ret="$?" _ret="$?"
if [ "$_ret" != "0" ]; then if [ "$_ret" != "0" ]; then
_err "Please refer to https://curl.haxx.se/libcurl/c/libcurl-errors.html for error code: $_ret" if [ -z "$displayError" ] || [ "$displayError" = "0" ]; then
_err "Please refer to https://curl.haxx.se/libcurl/c/libcurl-errors.html for error code: $_ret"
fi
if [ "$DEBUG" ] && [ "$DEBUG" -ge "2" ]; then if [ "$DEBUG" ] && [ "$DEBUG" -ge "2" ]; then
_err "Here is the curl dump log:" _err "Here is the curl dump log:"
_err "$(cat "$_CURL_DUMP")" _err "$(cat "$_CURL_DUMP")"
...@@ -1905,7 +1974,9 @@ _post() { ...@@ -1905,7 +1974,9 @@ _post() {
_debug "wget returns 8, the server returns a 'Bad request' response, lets process the response later." _debug "wget returns 8, the server returns a 'Bad request' response, lets process the response later."
fi fi
if [ "$_ret" != "0" ]; then if [ "$_ret" != "0" ]; then
_err "Please refer to https://www.gnu.org/software/wget/manual/html_node/Exit-Status.html for error code: $_ret" if [ -z "$displayError" ] || [ "$displayError" = "0" ]; then
_err "Please refer to https://www.gnu.org/software/wget/manual/html_node/Exit-Status.html for error code: $_ret"
fi
fi fi
_sed_i "s/^ *//g" "$HTTP_HEADER" _sed_i "s/^ *//g" "$HTTP_HEADER"
else else
...@@ -1919,13 +1990,38 @@ _post() { ...@@ -1919,13 +1990,38 @@ _post() {
# url getheader timeout # url getheader timeout
_get() { _get() {
url="$1"
onlyheader="$2"
t="$3"
_sleep_retry_sec=1
_http_retry_times=0
_hcode=0
while [ "${_http_retry_times}" -le "$_HTTP_MAX_RETRY" ]; do
[ "$_http_retry_times" = "$_HTTP_MAX_RETRY" ]
_lastHCode="$?"
_debug "Retrying GET"
_get_impl "$url" "$onlyheader" "$t" "$_lastHCode"
_hcode="$?"
_debug _hcode "$_hcode"
if [ "$_hcode" = "0" ]; then
break
fi
_http_retry_times=$(_math $_http_retry_times + 1)
_sleep $_sleep_retry_sec
done
return $_hcode
}
# url getheader timeout displayError
_get_impl() {
_debug GET _debug GET
url="$1" url="$1"
onlyheader="$2" onlyheader="$2"
t="$3" t="$3"
displayError="$4"
_debug url "$url" _debug url "$url"
_debug "timeout=$t" _debug "timeout=$t"
_debug "displayError" "$displayError"
_inithttp _inithttp
if [ "$_ACME_CURL" ] && [ "${ACME_USE_WGET:-0}" = "0" ]; then if [ "$_ACME_CURL" ] && [ "${ACME_USE_WGET:-0}" = "0" ]; then
...@@ -1944,7 +2040,9 @@ _get() { ...@@ -1944,7 +2040,9 @@ _get() {
fi fi
ret=$? ret=$?
if [ "$ret" != "0" ]; then if [ "$ret" != "0" ]; then
_err "Please refer to https://curl.haxx.se/libcurl/c/libcurl-errors.html for error code: $ret" if [ -z "$displayError" ] || [ "$displayError" = "0" ]; then
_err "Please refer to https://curl.haxx.se/libcurl/c/libcurl-errors.html for error code: $ret"
fi
if [ "$DEBUG" ] && [ "$DEBUG" -ge "2" ]; then if [ "$DEBUG" ] && [ "$DEBUG" -ge "2" ]; then
_err "Here is the curl dump log:" _err "Here is the curl dump log:"
_err "$(cat "$_CURL_DUMP")" _err "$(cat "$_CURL_DUMP")"
...@@ -1970,7 +2068,9 @@ _get() { ...@@ -1970,7 +2068,9 @@ _get() {
_debug "wget returns 8, the server returns a 'Bad request' response, lets process the response later." _debug "wget returns 8, the server returns a 'Bad request' response, lets process the response later."
fi fi
if [ "$ret" != "0" ]; then if [ "$ret" != "0" ]; then
_err "Please refer to https://www.gnu.org/software/wget/manual/html_node/Exit-Status.html for error code: $ret" if [ -z "$displayError" ] || [ "$displayError" = "0" ]; then
_err "Please refer to https://www.gnu.org/software/wget/manual/html_node/Exit-Status.html for error code: $ret"
fi
fi fi
else else
ret=$? ret=$?
...@@ -2026,7 +2126,7 @@ _send_signed_request() { ...@@ -2026,7 +2126,7 @@ _send_signed_request() {
if _post "" "$nonceurl" "" "HEAD" "$__request_conent_type" >/dev/null; then if _post "" "$nonceurl" "" "HEAD" "$__request_conent_type" >/dev/null; then
_headers="$(cat "$HTTP_HEADER")" _headers="$(cat "$HTTP_HEADER")"
_debug2 _headers "$_headers" _debug2 _headers "$_headers"
_CACHED_NONCE="$(echo "$_headers" | grep -i "Replay-Nonce:" | _head_n 1 | tr -d "\r\n " | cut -d ':' -f 2)" _CACHED_NONCE="$(echo "$_headers" | grep -i "Replay-Nonce:" | _head_n 1 | tr -d "\r\n " | cut -d ':' -f 2 | cut -d , -f 1)"
fi fi
fi fi
if [ -z "$_CACHED_NONCE" ]; then if [ -z "$_CACHED_NONCE" ]; then
...@@ -2058,17 +2158,15 @@ _send_signed_request() { ...@@ -2058,17 +2158,15 @@ _send_signed_request() {
_sleep 2 _sleep 2
continue continue
fi fi
if [ "$ACME_VERSION" = "2" ]; then
if [ "$url" = "$ACME_NEW_ACCOUNT" ]; then if [ "$url" = "$ACME_NEW_ACCOUNT" ]; then
protected="$JWK_HEADERPLACE_PART1$nonce\", \"url\": \"${url}$JWK_HEADERPLACE_PART2, \"jwk\": $jwk"'}'
elif [ "$url" = "$ACME_REVOKE_CERT" ] && [ "$keyfile" != "$ACCOUNT_KEY_PATH" ]; then
protected="$JWK_HEADERPLACE_PART1$nonce\", \"url\": \"${url}$JWK_HEADERPLACE_PART2, \"jwk\": $jwk"'}'
else
protected="$JWK_HEADERPLACE_PART1$nonce\", \"url\": \"${url}$JWK_HEADERPLACE_PART2, \"kid\": \"${ACCOUNT_URL}\""'}'
fi
else
protected="$JWK_HEADERPLACE_PART1$nonce\", \"url\": \"${url}$JWK_HEADERPLACE_PART2, \"jwk\": $jwk"'}' protected="$JWK_HEADERPLACE_PART1$nonce\", \"url\": \"${url}$JWK_HEADERPLACE_PART2, \"jwk\": $jwk"'}'
elif [ "$url" = "$ACME_REVOKE_CERT" ] && [ "$keyfile" != "$ACCOUNT_KEY_PATH" ]; then
protected="$JWK_HEADERPLACE_PART1$nonce\", \"url\": \"${url}$JWK_HEADERPLACE_PART2, \"jwk\": $jwk"'}'
else
protected="$JWK_HEADERPLACE_PART1$nonce\", \"url\": \"${url}$JWK_HEADERPLACE_PART2, \"kid\": \"${ACCOUNT_URL}\""'}'
fi fi
_debug3 protected "$protected" _debug3 protected "$protected"
protected64="$(printf "%s" "$protected" | _base64 | _url_replace)" protected64="$(printf "%s" "$protected" | _base64 | _url_replace)"
...@@ -2106,7 +2204,7 @@ _send_signed_request() { ...@@ -2106,7 +2204,7 @@ _send_signed_request() {
fi fi
_debug2 response "$response" _debug2 response "$response"
_CACHED_NONCE="$(echo "$responseHeaders" | grep -i "Replay-Nonce:" | _head_n 1 | tr -d "\r\n " | cut -d ':' -f 2)" _CACHED_NONCE="$(echo "$responseHeaders" | grep -i "Replay-Nonce:" | _head_n 1 | tr -d "\r\n " | cut -d ':' -f 2 | cut -d , -f 1)"
if ! _startswith "$code" "2"; then if ! _startswith "$code" "2"; then
_body="$response" _body="$response"
...@@ -2121,6 +2219,12 @@ _send_signed_request() { ...@@ -2121,6 +2219,12 @@ _send_signed_request() {
_sleep $_sleep_retry_sec _sleep $_sleep_retry_sec
continue continue
fi fi
if _contains "$_body" "The Replay Nonce is not recognized"; then
_info "The replay Nonce is not valid, let's get a new one, Sleeping $_sleep_retry_sec seconds."
_CACHED_NONCE=""
_sleep $_sleep_retry_sec
continue
fi
fi fi
return 0 return 0
done done
...@@ -2248,7 +2352,7 @@ _getdeployconf() { ...@@ -2248,7 +2352,7 @@ _getdeployconf() {
return 0 # do nothing return 0 # do nothing
fi fi
_saved=$(_readdomainconf "SAVED_$_rac_key") _saved=$(_readdomainconf "SAVED_$_rac_key")
eval "export $_rac_key=\"$_saved\"" eval "export $_rac_key=\"\$_saved\""
} }
#_saveaccountconf key value base64encode #_saveaccountconf key value base64encode
...@@ -2279,6 +2383,13 @@ _clearaccountconf() { ...@@ -2279,6 +2383,13 @@ _clearaccountconf() {
_clear_conf "$ACCOUNT_CONF_PATH" "$1" _clear_conf "$ACCOUNT_CONF_PATH" "$1"
} }
#key
_clearaccountconf_mutable() {
_clearaccountconf "SAVED_$1"
#remove later
_clearaccountconf "$1"
}
#_savecaconf key value #_savecaconf key value
_savecaconf() { _savecaconf() {
_save_conf "$CA_CONF" "$1" "$2" _save_conf "$CA_CONF" "$1" "$2"
...@@ -2332,7 +2443,7 @@ _startserver() { ...@@ -2332,7 +2443,7 @@ _startserver() {
echo 'HTTP/1.0 200 OK'; \ echo 'HTTP/1.0 200 OK'; \
echo 'Content-Length\: $_content_len'; \ echo 'Content-Length\: $_content_len'; \
echo ''; \ echo ''; \
printf -- '$content';" & printf '%s' '$content';" &
serverproc="$!" serverproc="$!"
} }
...@@ -2507,76 +2618,56 @@ __initHome() { ...@@ -2507,76 +2618,56 @@ __initHome() {
fi fi
} }
_clearAPI() {
ACME_NEW_ACCOUNT=""
ACME_KEY_CHANGE=""
ACME_NEW_AUTHZ=""
ACME_NEW_ORDER=""
ACME_REVOKE_CERT=""
ACME_NEW_NONCE=""
ACME_AGREEMENT=""
}
#server #server
_initAPI() { _initAPI() {
_api_server="${1:-$ACME_DIRECTORY}" _api_server="${1:-$ACME_DIRECTORY}"
_debug "_init api for server: $_api_server" _debug "_init api for server: $_api_server"
if [ -z "$ACME_NEW_ACCOUNT" ]; then MAX_API_RETRY_TIMES=10
_sleep_retry_sec=10
_request_retry_times=0
while [ -z "$ACME_NEW_ACCOUNT" ] && [ "${_request_retry_times}" -lt "$MAX_API_RETRY_TIMES" ]; do
_request_retry_times=$(_math "$_request_retry_times" + 1)
response=$(_get "$_api_server") response=$(_get "$_api_server")
if [ "$?" != "0" ]; then if [ "$?" != "0" ]; then
_debug2 "response" "$response" _debug2 "response" "$response"
_err "Can not init api." _info "Can not init api for: $_api_server."
return 1 _info "Sleep $_sleep_retry_sec and retry."
_sleep "$_sleep_retry_sec"
continue
fi fi
response=$(echo "$response" | _json_decode) response=$(echo "$response" | _json_decode)
_debug2 "response" "$response" _debug2 "response" "$response"
ACME_KEY_CHANGE=$(echo "$response" | _egrep_o 'key-change" *: *"[^"]*"' | cut -d '"' -f 3) ACME_KEY_CHANGE=$(echo "$response" | _egrep_o 'keyChange" *: *"[^"]*"' | cut -d '"' -f 3)
if [ -z "$ACME_KEY_CHANGE" ]; then
ACME_KEY_CHANGE=$(echo "$response" | _egrep_o 'keyChange" *: *"[^"]*"' | cut -d '"' -f 3)
fi
export ACME_KEY_CHANGE export ACME_KEY_CHANGE
ACME_NEW_AUTHZ=$(echo "$response" | _egrep_o 'new-authz" *: *"[^"]*"' | cut -d '"' -f 3) ACME_NEW_AUTHZ=$(echo "$response" | _egrep_o 'newAuthz" *: *"[^"]*"' | cut -d '"' -f 3)
if [ -z "$ACME_NEW_AUTHZ" ]; then
ACME_NEW_AUTHZ=$(echo "$response" | _egrep_o 'newAuthz" *: *"[^"]*"' | cut -d '"' -f 3)
fi
export ACME_NEW_AUTHZ export ACME_NEW_AUTHZ
ACME_NEW_ORDER=$(echo "$response" | _egrep_o 'new-cert" *: *"[^"]*"' | cut -d '"' -f 3) ACME_NEW_ORDER=$(echo "$response" | _egrep_o 'newOrder" *: *"[^"]*"' | cut -d '"' -f 3)
ACME_NEW_ORDER_RES="new-cert"
if [ -z "$ACME_NEW_ORDER" ]; then
ACME_NEW_ORDER=$(echo "$response" | _egrep_o 'new-order" *: *"[^"]*"' | cut -d '"' -f 3)
ACME_NEW_ORDER_RES="new-order"
if [ -z "$ACME_NEW_ORDER" ]; then
ACME_NEW_ORDER=$(echo "$response" | _egrep_o 'newOrder" *: *"[^"]*"' | cut -d '"' -f 3)
fi
fi
export ACME_NEW_ORDER export ACME_NEW_ORDER
export ACME_NEW_ORDER_RES
ACME_NEW_ACCOUNT=$(echo "$response" | _egrep_o 'newAccount" *: *"[^"]*"' | cut -d '"' -f 3)
ACME_NEW_ACCOUNT=$(echo "$response" | _egrep_o 'new-reg" *: *"[^"]*"' | cut -d '"' -f 3)
ACME_NEW_ACCOUNT_RES="new-reg"
if [ -z "$ACME_NEW_ACCOUNT" ]; then
ACME_NEW_ACCOUNT=$(echo "$response" | _egrep_o 'new-account" *: *"[^"]*"' | cut -d '"' -f 3)
ACME_NEW_ACCOUNT_RES="new-account"
if [ -z "$ACME_NEW_ACCOUNT" ]; then
ACME_NEW_ACCOUNT=$(echo "$response" | _egrep_o 'newAccount" *: *"[^"]*"' | cut -d '"' -f 3)
if [ "$ACME_NEW_ACCOUNT" ]; then
export ACME_VERSION=2
fi
fi
fi
export ACME_NEW_ACCOUNT export ACME_NEW_ACCOUNT
export ACME_NEW_ACCOUNT_RES
ACME_REVOKE_CERT=$(echo "$response" | _egrep_o 'revoke-cert" *: *"[^"]*"' | cut -d '"' -f 3) ACME_REVOKE_CERT=$(echo "$response" | _egrep_o 'revokeCert" *: *"[^"]*"' | cut -d '"' -f 3)
if [ -z "$ACME_REVOKE_CERT" ]; then
ACME_REVOKE_CERT=$(echo "$response" | _egrep_o 'revokeCert" *: *"[^"]*"' | cut -d '"' -f 3)
fi
export ACME_REVOKE_CERT export ACME_REVOKE_CERT
ACME_NEW_NONCE=$(echo "$response" | _egrep_o 'new-nonce" *: *"[^"]*"' | cut -d '"' -f 3) ACME_NEW_NONCE=$(echo "$response" | _egrep_o 'newNonce" *: *"[^"]*"' | cut -d '"' -f 3)
if [ -z "$ACME_NEW_NONCE" ]; then
ACME_NEW_NONCE=$(echo "$response" | _egrep_o 'newNonce" *: *"[^"]*"' | cut -d '"' -f 3)
fi
export ACME_NEW_NONCE export ACME_NEW_NONCE
ACME_AGREEMENT=$(echo "$response" | _egrep_o 'terms-of-service" *: *"[^"]*"' | cut -d '"' -f 3) ACME_AGREEMENT=$(echo "$response" | _egrep_o 'termsOfService" *: *"[^"]*"' | cut -d '"' -f 3)
if [ -z "$ACME_AGREEMENT" ]; then
ACME_AGREEMENT=$(echo "$response" | _egrep_o 'termsOfService" *: *"[^"]*"' | cut -d '"' -f 3)
fi
export ACME_AGREEMENT export ACME_AGREEMENT
_debug "ACME_KEY_CHANGE" "$ACME_KEY_CHANGE" _debug "ACME_KEY_CHANGE" "$ACME_KEY_CHANGE"
...@@ -2586,9 +2677,17 @@ _initAPI() { ...@@ -2586,9 +2677,17 @@ _initAPI() {
_debug "ACME_REVOKE_CERT" "$ACME_REVOKE_CERT" _debug "ACME_REVOKE_CERT" "$ACME_REVOKE_CERT"
_debug "ACME_AGREEMENT" "$ACME_AGREEMENT" _debug "ACME_AGREEMENT" "$ACME_AGREEMENT"
_debug "ACME_NEW_NONCE" "$ACME_NEW_NONCE" _debug "ACME_NEW_NONCE" "$ACME_NEW_NONCE"
_debug "ACME_VERSION" "$ACME_VERSION" if [ "$ACME_NEW_ACCOUNT" ] && [ "$ACME_NEW_ORDER" ]; then
return 0
fi
_info "Sleep $_sleep_retry_sec and retry."
_sleep "$_sleep_retry_sec"
done
if [ "$ACME_NEW_ACCOUNT" ] && [ "$ACME_NEW_ORDER" ]; then
return 0
fi fi
_err "Can not init api, for $_api_server"
return 1
} }
#[domain] [keylength or isEcc flag] #[domain] [keylength or isEcc flag]
...@@ -2632,15 +2731,44 @@ _initpath() { ...@@ -2632,15 +2731,44 @@ _initpath() {
_ACME_SERVER_HOST="$(echo "$ACME_DIRECTORY" | cut -d : -f 2 | tr -s / | cut -d / -f 2)" _ACME_SERVER_HOST="$(echo "$ACME_DIRECTORY" | cut -d : -f 2 | tr -s / | cut -d / -f 2)"
_debug2 "_ACME_SERVER_HOST" "$_ACME_SERVER_HOST" _debug2 "_ACME_SERVER_HOST" "$_ACME_SERVER_HOST"
CA_DIR="$CA_HOME/$_ACME_SERVER_HOST" _ACME_SERVER_PATH="$(echo "$ACME_DIRECTORY" | cut -d : -f 2- | tr -s / | cut -d / -f 3-)"
_debug2 "_ACME_SERVER_PATH" "$_ACME_SERVER_PATH"
CA_DIR="$CA_HOME/$_ACME_SERVER_HOST/$_ACME_SERVER_PATH"
_DEFAULT_CA_CONF="$CA_DIR/ca.conf" _DEFAULT_CA_CONF="$CA_DIR/ca.conf"
if [ -z "$CA_CONF" ]; then if [ -z "$CA_CONF" ]; then
CA_CONF="$_DEFAULT_CA_CONF" CA_CONF="$_DEFAULT_CA_CONF"
fi fi
_debug3 CA_CONF "$CA_CONF" _debug3 CA_CONF "$CA_CONF"
_OLD_CADIR="$CA_HOME/$_ACME_SERVER_HOST"
_OLD_ACCOUNT_KEY="$_OLD_CADIR/account.key"
_OLD_ACCOUNT_JSON="$_OLD_CADIR/account.json"
_OLD_CA_CONF="$_OLD_CADIR/ca.conf"
_DEFAULT_ACCOUNT_KEY_PATH="$CA_DIR/account.key"
_DEFAULT_ACCOUNT_JSON_PATH="$CA_DIR/account.json"
if [ -z "$ACCOUNT_KEY_PATH" ]; then
ACCOUNT_KEY_PATH="$_DEFAULT_ACCOUNT_KEY_PATH"
if [ -f "$_OLD_ACCOUNT_KEY" ] && ! [ -f "$ACCOUNT_KEY_PATH" ]; then
mkdir -p "$CA_DIR"
mv "$_OLD_ACCOUNT_KEY" "$ACCOUNT_KEY_PATH"
fi
fi
if [ -z "$ACCOUNT_JSON_PATH" ]; then
ACCOUNT_JSON_PATH="$_DEFAULT_ACCOUNT_JSON_PATH"
if [ -f "$_OLD_ACCOUNT_JSON" ] && ! [ -f "$ACCOUNT_JSON_PATH" ]; then
mkdir -p "$CA_DIR"
mv "$_OLD_ACCOUNT_JSON" "$ACCOUNT_JSON_PATH"
fi
fi
if [ -f "$_OLD_CA_CONF" ] && ! [ -f "$CA_CONF" ]; then
mkdir -p "$CA_DIR"
mv "$_OLD_CA_CONF" "$CA_CONF"
fi
if [ -f "$CA_CONF" ]; then if [ -f "$CA_CONF" ]; then
. "$CA_CONF" . "$CA_CONF"
fi fi
...@@ -2661,19 +2789,6 @@ _initpath() { ...@@ -2661,19 +2789,6 @@ _initpath() {
HTTP_HEADER="$LE_CONFIG_HOME/http.header" HTTP_HEADER="$LE_CONFIG_HOME/http.header"
fi fi
_OLD_ACCOUNT_KEY="$LE_WORKING_DIR/account.key"
_OLD_ACCOUNT_JSON="$LE_WORKING_DIR/account.json"
_DEFAULT_ACCOUNT_KEY_PATH="$CA_DIR/account.key"
_DEFAULT_ACCOUNT_JSON_PATH="$CA_DIR/account.json"
if [ -z "$ACCOUNT_KEY_PATH" ]; then
ACCOUNT_KEY_PATH="$_DEFAULT_ACCOUNT_KEY_PATH"
fi
if [ -z "$ACCOUNT_JSON_PATH" ]; then
ACCOUNT_JSON_PATH="$_DEFAULT_ACCOUNT_JSON_PATH"
fi
_DEFAULT_CERT_HOME="$LE_CONFIG_HOME" _DEFAULT_CERT_HOME="$LE_CONFIG_HOME"
if [ -z "$CERT_HOME" ]; then if [ -z "$CERT_HOME" ]; then
CERT_HOME="$_DEFAULT_CERT_HOME" CERT_HOME="$_DEFAULT_CERT_HOME"
...@@ -3071,6 +3186,11 @@ _checkConf() { ...@@ -3071,6 +3186,11 @@ _checkConf() {
_debug "Try include files" _debug "Try include files"
for included in $(cat "$2" | tr "\t" " " | grep "^ *include *.*;" | sed "s/include //" | tr -d " ;"); do for included in $(cat "$2" | tr "\t" " " | grep "^ *include *.*;" | sed "s/include //" | tr -d " ;"); do
_debug "check included $included" _debug "check included $included"
if ! _startswith "$included" "/" && _exists dirname; then
_relpath="$(dirname "$2")"
_debug "_relpath" "$_relpath"
included="$_relpath/$included"
fi
if _checkConf "$1" "$included"; then if _checkConf "$1" "$included"; then
return 0 return 0
fi fi
...@@ -3281,6 +3401,8 @@ _on_before_issue() { ...@@ -3281,6 +3401,8 @@ _on_before_issue() {
if [ "$_chk_pre_hook" ]; then if [ "$_chk_pre_hook" ]; then
_info "Run pre hook:'$_chk_pre_hook'" _info "Run pre hook:'$_chk_pre_hook'"
if ! ( if ! (
export Le_Domain="$_chk_main_domain"
export Le_Alt="$_chk_alt_domains"
cd "$DOMAIN_PATH" && eval "$_chk_pre_hook" cd "$DOMAIN_PATH" && eval "$_chk_pre_hook"
); then ); then
_err "Error when run pre hook." _err "Error when run pre hook."
...@@ -3342,7 +3464,7 @@ _on_before_issue() { ...@@ -3342,7 +3464,7 @@ _on_before_issue() {
_netprc="$(_ss "$_checkport" | grep "$_checkport")" _netprc="$(_ss "$_checkport" | grep "$_checkport")"
netprc="$(echo "$_netprc" | grep "$_checkaddr")" netprc="$(echo "$_netprc" | grep "$_checkaddr")"
if [ -z "$netprc" ]; then if [ -z "$netprc" ]; then
netprc="$(echo "$_netprc" | grep "$LOCAL_ANY_ADDRESS")" netprc="$(echo "$_netprc" | grep "$LOCAL_ANY_ADDRESS:$_checkport")"
fi fi
if [ "$netprc" ]; then if [ "$netprc" ]; then
_err "$netprc" _err "$netprc"
...@@ -3499,15 +3621,6 @@ _regAccount() { ...@@ -3499,15 +3621,6 @@ _regAccount() {
_initAPI _initAPI
mkdir -p "$CA_DIR" mkdir -p "$CA_DIR"
if [ ! -f "$ACCOUNT_KEY_PATH" ] && [ -f "$_OLD_ACCOUNT_KEY" ]; then
_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
_info "mv $_OLD_ACCOUNT_JSON to $ACCOUNT_JSON_PATH"
mv "$_OLD_ACCOUNT_JSON" "$ACCOUNT_JSON_PATH"
fi
if [ ! -f "$ACCOUNT_KEY_PATH" ]; then if [ ! -f "$ACCOUNT_KEY_PATH" ]; then
if ! _create_account_key "$_reg_length"; then if ! _create_account_key "$_reg_length"; then
...@@ -3531,68 +3644,66 @@ _regAccount() { ...@@ -3531,68 +3644,66 @@ _regAccount() {
if [ "$_email" ]; then if [ "$_email" ]; then
_savecaconf "CA_EMAIL" "$_email" _savecaconf "CA_EMAIL" "$_email"
fi fi
if [ "$ACME_VERSION" = "2" ]; then
if [ "$ACME_DIRECTORY" = "$CA_ZEROSSL" ]; then if [ "$ACME_DIRECTORY" = "$CA_ZEROSSL" ]; then
if [ -z "$_eab_id" ] || [ -z "$_eab_hmac_key" ]; then if [ -z "$_eab_id" ] || [ -z "$_eab_hmac_key" ]; then
_info "No EAB credentials found for ZeroSSL, let's get one" _info "No EAB credentials found for ZeroSSL, let's get one"
if [ -z "$_email" ]; then if [ -z "$_email" ]; then
_err "Please provide a email address for ZeroSSL account." _info "$(__green "$PROJECT_NAME is using ZeroSSL as default CA now.")"
_err "See ZeroSSL usage: $_ZEROSSL_WIKI" _info "$(__green "Please update your account with an email address first.")"
return 1 _info "$(__green "$PROJECT_ENTRY --register-account -m my@example.com")"
fi _info "See: $(__green "$_ZEROSSL_WIKI")"
_eabresp=$(_post "email=$_email" $_ZERO_EAB_ENDPOINT) return 1
if [ "$?" != "0" ]; then fi
_debug2 "$_eabresp" _eabresp=$(_post "email=$_email" $_ZERO_EAB_ENDPOINT)
_err "Can not get EAB credentials from ZeroSSL." if [ "$?" != "0" ]; then
return 1 _debug2 "$_eabresp"
fi _err "Can not get EAB credentials from ZeroSSL."
_eab_id="$(echo "$_eabresp" | tr ',}' '\n' | grep '"eab_kid"' | cut -d : -f 2 | tr -d '"')" return 1
if [ -z "$_eab_id" ]; then fi
_err "Can not resolve _eab_id" _secure_debug2 _eabresp "$_eabresp"
return 1 _eab_id="$(echo "$_eabresp" | tr ',}' '\n\n' | grep '"eab_kid"' | cut -d : -f 2 | tr -d '"')"
fi _secure_debug2 _eab_id "$_eab_id"
_eab_hmac_key="$(echo "$_eabresp" | tr ',}' '\n' | grep '"eab_hmac_key"' | cut -d : -f 2 | tr -d '"')" if [ -z "$_eab_id" ]; then
if [ -z "$_eab_hmac_key" ]; then _err "Can not resolve _eab_id"
_err "Can not resolve _eab_hmac_key" return 1
return 1 fi
fi _eab_hmac_key="$(echo "$_eabresp" | tr ',}' '\n\n' | grep '"eab_hmac_key"' | cut -d : -f 2 | tr -d '"')"
_savecaconf CA_EAB_KEY_ID "$_eab_id" _secure_debug2 _eab_hmac_key "$_eab_hmac_key"
_savecaconf CA_EAB_HMAC_KEY "$_eab_hmac_key" if [ -z "$_eab_hmac_key" ]; then
_err "Can not resolve _eab_hmac_key"
return 1
fi fi
_savecaconf CA_EAB_KEY_ID "$_eab_id"
_savecaconf CA_EAB_HMAC_KEY "$_eab_hmac_key"
fi fi
if [ "$_eab_id" ] && [ "$_eab_hmac_key" ]; then fi
eab_protected="{\"alg\":\"HS256\",\"kid\":\"$_eab_id\",\"url\":\"${ACME_NEW_ACCOUNT}\"}" if [ "$_eab_id" ] && [ "$_eab_hmac_key" ]; then
_debug3 eab_protected "$eab_protected" eab_protected="{\"alg\":\"HS256\",\"kid\":\"$_eab_id\",\"url\":\"${ACME_NEW_ACCOUNT}\"}"
_debug3 eab_protected "$eab_protected"
eab_protected64=$(printf "%s" "$eab_protected" | _base64 | _url_replace) eab_protected64=$(printf "%s" "$eab_protected" | _base64 | _url_replace)
_debug3 eab_protected64 "$eab_protected64" _debug3 eab_protected64 "$eab_protected64"
eab_payload64=$(printf "%s" "$jwk" | _base64 | _url_replace) eab_payload64=$(printf "%s" "$jwk" | _base64 | _url_replace)
_debug3 eab_payload64 "$eab_payload64" _debug3 eab_payload64 "$eab_payload64"
eab_sign_t="$eab_protected64.$eab_payload64" eab_sign_t="$eab_protected64.$eab_payload64"
_debug3 eab_sign_t "$eab_sign_t" _debug3 eab_sign_t "$eab_sign_t"
key_hex="$(_durl_replace_base64 "$_eab_hmac_key" | _dbase64 | _hex_dump | tr -d ' ')" key_hex="$(_durl_replace_base64 "$_eab_hmac_key" | _dbase64 multi | _hex_dump | tr -d ' ')"
_debug3 key_hex "$key_hex" _debug3 key_hex "$key_hex"
eab_signature=$(printf "%s" "$eab_sign_t" | _hmac sha256 $key_hex | _base64 | _url_replace) eab_signature=$(printf "%s" "$eab_sign_t" | _hmac sha256 $key_hex | _base64 | _url_replace)
_debug3 eab_signature "$eab_signature" _debug3 eab_signature "$eab_signature"
externalBinding=",\"externalAccountBinding\":{\"protected\":\"$eab_protected64\", \"payload\":\"$eab_payload64\", \"signature\":\"$eab_signature\"}" externalBinding=",\"externalAccountBinding\":{\"protected\":\"$eab_protected64\", \"payload\":\"$eab_payload64\", \"signature\":\"$eab_signature\"}"
_debug3 externalBinding "$externalBinding" _debug3 externalBinding "$externalBinding"
fi fi
if [ "$_email" ]; then if [ "$_email" ]; then
email_sg="\"contact\": [\"mailto:$_email\"], " email_sg="\"contact\": [\"mailto:$_email\"], "
fi
regjson="{$email_sg\"termsOfServiceAgreed\": true$externalBinding}"
else
_reg_res="$ACME_NEW_ACCOUNT_RES"
regjson='{"resource": "'$_reg_res'", "terms-of-service-agreed": true, "agreement": "'$ACME_AGREEMENT'"}'
if [ "$_email" ]; then
regjson='{"resource": "'$_reg_res'", "contact": ["mailto:'$_email'"], "terms-of-service-agreed": true, "agreement": "'$ACME_AGREEMENT'"}'
fi
fi fi
regjson="{$email_sg\"termsOfServiceAgreed\": true$externalBinding}"
_info "Registering account: $ACME_DIRECTORY" _info "Registering account: $ACME_DIRECTORY"
...@@ -3647,16 +3758,6 @@ _regAccount() { ...@@ -3647,16 +3758,6 @@ _regAccount() {
updateaccount() { updateaccount() {
_initpath _initpath
if [ ! -f "$ACCOUNT_KEY_PATH" ] && [ -f "$_OLD_ACCOUNT_KEY" ]; then
_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
_info "mv $_OLD_ACCOUNT_JSON to $ACCOUNT_JSON_PATH"
mv "$_OLD_ACCOUNT_JSON" "$ACCOUNT_JSON_PATH"
fi
if [ ! -f "$ACCOUNT_KEY_PATH" ]; then if [ ! -f "$ACCOUNT_KEY_PATH" ]; then
_err "Account key is not found at: $ACCOUNT_KEY_PATH" _err "Account key is not found at: $ACCOUNT_KEY_PATH"
return 1 return 1
...@@ -3677,20 +3778,13 @@ updateaccount() { ...@@ -3677,20 +3778,13 @@ updateaccount() {
_initAPI _initAPI
_email="$(_getAccountEmail)" _email="$(_getAccountEmail)"
if [ "$ACME_VERSION" = "2" ]; then
if [ "$ACCOUNT_EMAIL" ]; then if [ "$ACCOUNT_EMAIL" ]; then
updjson='{"contact": ["mailto:'$_email'"]}' updjson='{"contact": ["mailto:'$_email'"]}'
else
updjson='{"contact": []}'
fi
else else
# ACMEv1: Updates happen the same way a registration is done. updjson='{"contact": []}'
# https://tools.ietf.org/html/draft-ietf-acme-acme-01#section-6.3
_regAccount
return
fi fi
# this part handles ACMEv2 account updates.
_send_signed_request "$_accUri" "$updjson" _send_signed_request "$_accUri" "$updjson"
if [ "$code" = '200' ]; then if [ "$code" = '200' ]; then
...@@ -3706,16 +3800,6 @@ updateaccount() { ...@@ -3706,16 +3800,6 @@ updateaccount() {
deactivateaccount() { deactivateaccount() {
_initpath _initpath
if [ ! -f "$ACCOUNT_KEY_PATH" ] && [ -f "$_OLD_ACCOUNT_KEY" ]; then
_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
_info "mv $_OLD_ACCOUNT_JSON to $ACCOUNT_JSON_PATH"
mv "$_OLD_ACCOUNT_JSON" "$ACCOUNT_JSON_PATH"
fi
if [ ! -f "$ACCOUNT_KEY_PATH" ]; then if [ ! -f "$ACCOUNT_KEY_PATH" ]; then
_err "Account key is not found at: $ACCOUNT_KEY_PATH" _err "Account key is not found at: $ACCOUNT_KEY_PATH"
return 1 return 1
...@@ -3735,11 +3819,8 @@ deactivateaccount() { ...@@ -3735,11 +3819,8 @@ deactivateaccount() {
fi fi
_initAPI _initAPI
if [ "$ACME_VERSION" = "2" ]; then _djson="{\"status\":\"deactivated\"}"
_djson="{\"status\":\"deactivated\"}"
else
_djson="{\"resource\": \"reg\", \"status\":\"deactivated\"}"
fi
if _send_signed_request "$_accUri" "$_djson" && _contains "$response" '"deactivated"'; then if _send_signed_request "$_accUri" "$_djson" && _contains "$response" '"deactivated"'; then
_info "Deactivate account success for $_accUri." _info "Deactivate account success for $_accUri."
_accid=$(echo "$response" | _egrep_o "\"id\" *: *[^,]*," | cut -d : -f 2 | tr -d ' ,') _accid=$(echo "$response" | _egrep_o "\"id\" *: *[^,]*," | cut -d : -f 2 | tr -d ' ,')
...@@ -3844,11 +3925,9 @@ __trigger_validation() { ...@@ -3844,11 +3925,9 @@ __trigger_validation() {
_debug2 _t_key_authz "$_t_key_authz" _debug2 _t_key_authz "$_t_key_authz"
_t_vtype="$3" _t_vtype="$3"
_debug2 _t_vtype "$_t_vtype" _debug2 _t_vtype "$_t_vtype"
if [ "$ACME_VERSION" = "2" ]; then
_send_signed_request "$_t_url" "{}" _send_signed_request "$_t_url" "{}"
else
_send_signed_request "$_t_url" "{\"resource\": \"challenge\", \"type\": \"$_t_vtype\", \"keyAuthorization\": \"$_t_key_authz\"}"
fi
} }
#endpoint domain type #endpoint domain type
...@@ -3891,7 +3970,15 @@ _ns_purge_cf() { ...@@ -3891,7 +3970,15 @@ _ns_purge_cf() {
#checks if cf server is available #checks if cf server is available
_ns_is_available_cf() { _ns_is_available_cf() {
if _get "https://cloudflare-dns.com" >/dev/null 2>&1; then if _get "https://cloudflare-dns.com" "" 1 >/dev/null 2>&1; then
return 0
else
return 1
fi
}
_ns_is_available_google() {
if _get "https://dns.google" "" 1 >/dev/null 2>&1; then
return 0 return 0
else else
return 1 return 1
...@@ -3906,6 +3993,38 @@ _ns_lookup_google() { ...@@ -3906,6 +3993,38 @@ _ns_lookup_google() {
_ns_lookup_impl "$_cf_ep" "$_cf_ld" "$_cf_ld_type" _ns_lookup_impl "$_cf_ep" "$_cf_ld" "$_cf_ld_type"
} }
_ns_is_available_ali() {
if _get "https://dns.alidns.com" "" 1 >/dev/null 2>&1; then
return 0
else
return 1
fi
}
#domain, type
_ns_lookup_ali() {
_cf_ld="$1"
_cf_ld_type="$2"
_cf_ep="https://dns.alidns.com/resolve"
_ns_lookup_impl "$_cf_ep" "$_cf_ld" "$_cf_ld_type"
}
_ns_is_available_dp() {
if _get "https://doh.pub" "" 1 >/dev/null 2>&1; then
return 0
else
return 1
fi
}
#dnspod
_ns_lookup_dp() {
_cf_ld="$1"
_cf_ld_type="$2"
_cf_ep="https://doh.pub/dns-query"
_ns_lookup_impl "$_cf_ep" "$_cf_ld" "$_cf_ld_type"
}
#domain, type #domain, type
_ns_lookup() { _ns_lookup() {
if [ -z "$DOH_USE" ]; then if [ -z "$DOH_USE" ]; then
...@@ -3913,16 +4032,30 @@ _ns_lookup() { ...@@ -3913,16 +4032,30 @@ _ns_lookup() {
if _ns_is_available_cf; then if _ns_is_available_cf; then
_debug "Use cloudflare doh server" _debug "Use cloudflare doh server"
export DOH_USE=$DOH_CLOUDFLARE export DOH_USE=$DOH_CLOUDFLARE
else elif _ns_is_available_google; then
_debug "Use google doh server" _debug "Use google doh server"
export DOH_USE=$DOH_GOOGLE export DOH_USE=$DOH_GOOGLE
elif _ns_is_available_ali; then
_debug "Use aliyun doh server"
export DOH_USE=$DOH_ALI
elif _ns_is_available_dp; then
_debug "Use dns pod doh server"
export DOH_USE=$DOH_DP
else
_err "No doh"
fi fi
fi fi
if [ "$DOH_USE" = "$DOH_CLOUDFLARE" ] || [ -z "$DOH_USE" ]; then if [ "$DOH_USE" = "$DOH_CLOUDFLARE" ] || [ -z "$DOH_USE" ]; then
_ns_lookup_cf "$@" _ns_lookup_cf "$@"
else elif [ "$DOH_USE" = "$DOH_GOOGLE" ]; then
_ns_lookup_google "$@" _ns_lookup_google "$@"
elif [ "$DOH_USE" = "$DOH_ALI" ]; then
_ns_lookup_ali "$@"
elif [ "$DOH_USE" = "$DOH_DP" ]; then
_ns_lookup_dp "$@"
else
_err "Unknown doh provider: DOH_USE=$DOH_USE"
fi fi
} }
...@@ -3947,7 +4080,7 @@ __purge_txt() { ...@@ -3947,7 +4080,7 @@ __purge_txt() {
if [ "$DOH_USE" = "$DOH_CLOUDFLARE" ] || [ -z "$DOH_USE" ]; then if [ "$DOH_USE" = "$DOH_CLOUDFLARE" ] || [ -z "$DOH_USE" ]; then
_ns_purge_cf "$_p_txtdomain" "TXT" _ns_purge_cf "$_p_txtdomain" "TXT"
else else
_debug "no purge api for google dns api, just sleep 5 secs" _debug "no purge api for this doh api, just sleep 5 secs"
_sleep 5 _sleep 5
fi fi
...@@ -4009,12 +4142,42 @@ _check_dns_entries() { ...@@ -4009,12 +4142,42 @@ _check_dns_entries() {
} }
#file #file
_get_cert_issuers() { _get_chain_issuers() {
_cfile="$1"
if _contains "$(${ACME_OPENSSL_BIN:-openssl} help crl2pkcs7 2>&1)" "Usage: crl2pkcs7" || _contains "$(${ACME_OPENSSL_BIN:-openssl} crl2pkcs7 -help 2>&1)" "Usage: crl2pkcs7" || _contains "$(${ACME_OPENSSL_BIN:-openssl} crl2pkcs7 help 2>&1)" "unknown option help"; then
${ACME_OPENSSL_BIN:-openssl} crl2pkcs7 -nocrl -certfile $_cfile | ${ACME_OPENSSL_BIN:-openssl} pkcs7 -print_certs -text -noout | grep -i 'Issuer:' | _egrep_o "CN *=[^,]*" | cut -d = -f 2
else
_cindex=1
for _startn in $(grep -n -- "$BEGIN_CERT" "$_cfile" | cut -d : -f 1); do
_endn="$(grep -n -- "$END_CERT" "$_cfile" | cut -d : -f 1 | _head_n $_cindex | _tail_n 1)"
_debug2 "_startn" "$_startn"
_debug2 "_endn" "$_endn"
if [ "$DEBUG" ]; then
_debug2 "cert$_cindex" "$(sed -n "$_startn,${_endn}p" "$_cfile")"
fi
sed -n "$_startn,${_endn}p" "$_cfile" | ${ACME_OPENSSL_BIN:-openssl} x509 -text -noout | grep 'Issuer:' | _egrep_o "CN *=[^,]*" | cut -d = -f 2 | sed "s/ *\(.*\)/\1/"
_cindex=$(_math $_cindex + 1)
done
fi
}
#
_get_chain_subjects() {
_cfile="$1" _cfile="$1"
if _contains "$(${ACME_OPENSSL_BIN:-openssl} help crl2pkcs7 2>&1)" "Usage: crl2pkcs7" || _contains "$(${ACME_OPENSSL_BIN:-openssl} crl2pkcs7 help 2>&1)" "unknown option help"; then if _contains "$(${ACME_OPENSSL_BIN:-openssl} help crl2pkcs7 2>&1)" "Usage: crl2pkcs7" || _contains "$(${ACME_OPENSSL_BIN:-openssl} crl2pkcs7 -help 2>&1)" "Usage: crl2pkcs7" || _contains "$(${ACME_OPENSSL_BIN:-openssl} crl2pkcs7 help 2>&1)" "unknown option help"; then
${ACME_OPENSSL_BIN:-openssl} crl2pkcs7 -nocrl -certfile $_cfile | ${ACME_OPENSSL_BIN:-openssl} pkcs7 -print_certs -text -noout | grep 'Issuer:' | _egrep_o "CN *=[^,]*" | cut -d = -f 2 ${ACME_OPENSSL_BIN:-openssl} crl2pkcs7 -nocrl -certfile $_cfile | ${ACME_OPENSSL_BIN:-openssl} pkcs7 -print_certs -text -noout | grep -i 'Subject:' | _egrep_o "CN *=[^,]*" | cut -d = -f 2
else else
${ACME_OPENSSL_BIN:-openssl} x509 -in $_cfile -text -noout | grep 'Issuer:' | _egrep_o "CN *=[^,]*" | cut -d = -f 2 _cindex=1
for _startn in $(grep -n -- "$BEGIN_CERT" "$_cfile" | cut -d : -f 1); do
_endn="$(grep -n -- "$END_CERT" "$_cfile" | cut -d : -f 1 | _head_n $_cindex | _tail_n 1)"
_debug2 "_startn" "$_startn"
_debug2 "_endn" "$_endn"
if [ "$DEBUG" ]; then
_debug2 "cert$_cindex" "$(sed -n "$_startn,${_endn}p" "$_cfile")"
fi
sed -n "$_startn,${_endn}p" "$_cfile" | ${ACME_OPENSSL_BIN:-openssl} x509 -text -noout | grep -i 'Subject:' | _egrep_o "CN *=[^,]*" | cut -d = -f 2 | sed "s/ *\(.*\)/\1/"
_cindex=$(_math $_cindex + 1)
done
fi fi
} }
...@@ -4022,14 +4185,42 @@ _get_cert_issuers() { ...@@ -4022,14 +4185,42 @@ _get_cert_issuers() {
_match_issuer() { _match_issuer() {
_cfile="$1" _cfile="$1"
_missuer="$2" _missuer="$2"
_fissuers="$(_get_cert_issuers $_cfile)" _fissuers="$(_get_chain_issuers $_cfile)"
_debug2 _fissuers "$_fissuers" _debug2 _fissuers "$_fissuers"
if _contains "$_fissuers" "$_missuer"; then _rootissuer="$(echo "$_fissuers" | _lower_case | _tail_n 1)"
return 0 _debug2 _rootissuer "$_rootissuer"
fi
_fissuers="$(echo "$_fissuers" | _lower_case)"
_missuer="$(echo "$_missuer" | _lower_case)" _missuer="$(echo "$_missuer" | _lower_case)"
_contains "$_fissuers" "$_missuer" _contains "$_rootissuer" "$_missuer"
}
#ip
_isIPv4() {
for seg in $(echo "$1" | tr '.' ' '); do
if [ $seg -ge 0 ] 2>/dev/null && [ $seg -le 255 ] 2>/dev/null; then
continue
fi
return 1
done
return 0
}
#ip6
_isIPv6() {
_contains "$1" ":"
}
#ip
_isIP() {
_isIPv4 "$1" || _isIPv6 "$1"
}
#identifier
_getIdType() {
if _isIP "$1"; then
echo "$ID_TYPE_IP"
else
echo "$ID_TYPE_DNS"
fi
} }
#webroot, domain domainlist keylength #webroot, domain domainlist keylength
...@@ -4069,6 +4260,10 @@ issue() { ...@@ -4069,6 +4260,10 @@ issue() {
if [ -z "$_ACME_IS_RENEW" ]; then if [ -z "$_ACME_IS_RENEW" ]; then
_initpath "$_main_domain" "$_key_length" _initpath "$_main_domain" "$_key_length"
mkdir -p "$DOMAIN_PATH" mkdir -p "$DOMAIN_PATH"
elif ! _hasfield "$_web_roots" "$W_DNS"; then
Le_OrderFinalize=""
Le_LinkOrder=""
Le_LinkCert=""
fi fi
if _hasfield "$_web_roots" "$W_DNS" && [ -z "$FORCE_DNS_MANUAL" ]; then if _hasfield "$_web_roots" "$W_DNS" && [ -z "$FORCE_DNS_MANUAL" ]; then
...@@ -4076,10 +4271,6 @@ issue() { ...@@ -4076,10 +4271,6 @@ issue() {
return 1 return 1
fi fi
_debug "Using ACME_DIRECTORY: $ACME_DIRECTORY"
_initAPI
if [ -f "$DOMAIN_CONF" ]; then if [ -f "$DOMAIN_CONF" ]; then
Le_NextRenewTime=$(_readdomainconf Le_NextRenewTime) Le_NextRenewTime=$(_readdomainconf Le_NextRenewTime)
_debug Le_NextRenewTime "$Le_NextRenewTime" _debug Le_NextRenewTime "$Le_NextRenewTime"
...@@ -4099,6 +4290,11 @@ issue() { ...@@ -4099,6 +4290,11 @@ issue() {
fi fi
fi fi
_debug "Using ACME_DIRECTORY: $ACME_DIRECTORY"
if ! _initAPI; then
return 1
fi
_savedomainconf "Le_Domain" "$_main_domain" _savedomainconf "Le_Domain" "$_main_domain"
_savedomainconf "Le_Alt" "$_alt_domains" _savedomainconf "Le_Alt" "$_alt_domains"
_savedomainconf "Le_Webroot" "$_web_roots" _savedomainconf "Le_Webroot" "$_web_roots"
...@@ -4182,74 +4378,72 @@ issue() { ...@@ -4182,74 +4378,72 @@ issue() {
sep='#' sep='#'
dvsep=',' dvsep=','
if [ -z "$vlist" ]; then if [ -z "$vlist" ]; then
if [ "$ACME_VERSION" = "2" ]; then #make new order request
#make new order request _identifiers="{\"type\":\"$(_getIdType "$_main_domain")\",\"value\":\"$(_idn "$_main_domain")\"}"
_identifiers="{\"type\":\"dns\",\"value\":\"$(_idn "$_main_domain")\"}" _w_index=1
_w_index=1 while true; do
while true; do d="$(echo "$_alt_domains," | cut -d , -f "$_w_index")"
d="$(echo "$_alt_domains," | cut -d , -f "$_w_index")" _w_index="$(_math "$_w_index" + 1)"
_w_index="$(_math "$_w_index" + 1)" _debug d "$d"
_debug d "$d" if [ -z "$d" ]; then
if [ -z "$d" ]; then break
break
fi
_identifiers="$_identifiers,{\"type\":\"dns\",\"value\":\"$(_idn "$d")\"}"
done
_debug2 _identifiers "$_identifiers"
if ! _send_signed_request "$ACME_NEW_ORDER" "{\"identifiers\": [$_identifiers]}"; then
_err "Create new order error."
_clearup
_on_issue_err "$_post_hook"
return 1
fi
Le_LinkOrder="$(echo "$responseHeaders" | grep -i '^Location.*$' | _tail_n 1 | tr -d "\r\n " | cut -d ":" -f 2-)"
_debug Le_LinkOrder "$Le_LinkOrder"
Le_OrderFinalize="$(echo "$response" | _egrep_o '"finalize" *: *"[^"]*"' | cut -d '"' -f 4)"
_debug Le_OrderFinalize "$Le_OrderFinalize"
if [ -z "$Le_OrderFinalize" ]; then
_err "Create new order error. Le_OrderFinalize not found. $response"
_clearup
_on_issue_err "$_post_hook"
return 1
fi fi
_identifiers="$_identifiers,{\"type\":\"$(_getIdType "$d")\",\"value\":\"$(_idn "$d")\"}"
done
_debug2 _identifiers "$_identifiers"
if ! _send_signed_request "$ACME_NEW_ORDER" "{\"identifiers\": [$_identifiers]}"; then
_err "Create new order error."
_clearup
_on_issue_err "$_post_hook"
return 1
fi
Le_LinkOrder="$(echo "$responseHeaders" | grep -i '^Location.*$' | _tail_n 1 | tr -d "\r\n " | cut -d ":" -f 2-)"
_debug Le_LinkOrder "$Le_LinkOrder"
Le_OrderFinalize="$(echo "$response" | _egrep_o '"finalize" *: *"[^"]*"' | cut -d '"' -f 4)"
_debug Le_OrderFinalize "$Le_OrderFinalize"
if [ -z "$Le_OrderFinalize" ]; then
_err "Create new order error. Le_OrderFinalize not found. $response"
_clearup
_on_issue_err "$_post_hook"
return 1
fi
#for dns manual mode
_savedomainconf "Le_OrderFinalize" "$Le_OrderFinalize"
#for dns manual mode _authorizations_seg="$(echo "$response" | _json_decode | _egrep_o '"authorizations" *: *\[[^\[]*\]' | cut -d '[' -f 2 | tr -d ']' | tr -d '"')"
_savedomainconf "Le_OrderFinalize" "$Le_OrderFinalize" _debug2 _authorizations_seg "$_authorizations_seg"
if [ -z "$_authorizations_seg" ]; then
_err "_authorizations_seg not found."
_clearup
_on_issue_err "$_post_hook"
return 1
fi
_authorizations_seg="$(echo "$response" | _json_decode | _egrep_o '"authorizations" *: *\[[^\[]*\]' | cut -d '[' -f 2 | tr -d ']' | tr -d '"')" #domain and authz map
_debug2 _authorizations_seg "$_authorizations_seg" _authorizations_map=""
if [ -z "$_authorizations_seg" ]; then for _authz_url in $(echo "$_authorizations_seg" | tr ',' ' '); do
_err "_authorizations_seg not found." _debug2 "_authz_url" "$_authz_url"
if ! _send_signed_request "$_authz_url"; then
_err "get to authz error."
_err "_authorizations_seg" "$_authorizations_seg"
_err "_authz_url" "$_authz_url"
_clearup _clearup
_on_issue_err "$_post_hook" _on_issue_err "$_post_hook"
return 1 return 1
fi fi
#domain and authz map response="$(echo "$response" | _normalizeJson)"
_authorizations_map="" _debug2 response "$response"
for _authz_url in $(echo "$_authorizations_seg" | tr ',' ' '); do _d="$(echo "$response" | _egrep_o '"value" *: *"[^"]*"' | cut -d : -f 2 | tr -d ' "')"
_debug2 "_authz_url" "$_authz_url" if _contains "$response" "\"wildcard\" *: *true"; then
if ! _send_signed_request "$_authz_url"; then _d="*.$_d"
_err "get to authz error." fi
_err "_authorizations_seg" "$_authorizations_seg" _debug2 _d "$_d"
_err "_authz_url" "$_authz_url" _authorizations_map="$_d,$response
_clearup
_on_issue_err "$_post_hook"
return 1
fi
response="$(echo "$response" | _normalizeJson)"
_debug2 response "$response"
_d="$(echo "$response" | _egrep_o '"value" *: *"[^"]*"' | cut -d : -f 2 | tr -d ' "')"
if _contains "$response" "\"wildcard\" *: *true"; then
_d="*.$_d"
fi
_debug2 _d "$_d"
_authorizations_map="$_d,$response
$_authorizations_map" $_authorizations_map"
done done
_debug2 _authorizations_map "$_authorizations_map" _debug2 _authorizations_map "$_authorizations_map"
fi
_index=0 _index=0
_currentRoot="" _currentRoot=""
...@@ -4280,33 +4474,25 @@ $_authorizations_map" ...@@ -4280,33 +4474,25 @@ $_authorizations_map"
vtype="$VTYPE_ALPN" vtype="$VTYPE_ALPN"
fi fi
if [ "$ACME_VERSION" = "2" ]; then _idn_d="$(_idn "$d")"
_idn_d="$(_idn "$d")" _candidates="$(echo "$_authorizations_map" | grep -i "^$_idn_d,")"
_candidates="$(echo "$_authorizations_map" | grep -i "^$_idn_d,")" _debug2 _candidates "$_candidates"
_debug2 _candidates "$_candidates" if [ "$(echo "$_candidates" | wc -l)" -gt 1 ]; then
if [ "$(echo "$_candidates" | wc -l)" -gt 1 ]; then for _can in $_candidates; do
for _can in $_candidates; do if _startswith "$(echo "$_can" | tr '.' '|')" "$(echo "$_idn_d" | tr '.' '|'),"; then
if _startswith "$(echo "$_can" | tr '.' '|')" "$(echo "$_idn_d" | tr '.' '|'),"; then _candidates="$_can"
_candidates="$_can" break
break fi
fi done
done fi
fi response="$(echo "$_candidates" | sed "s/$_idn_d,//")"
response="$(echo "$_candidates" | sed "s/$_idn_d,//")" _debug2 "response" "$response"
_debug2 "response" "$response" if [ -z "$response" ]; then
if [ -z "$response" ]; then _err "get to authz error."
_err "get to authz error." _err "_authorizations_map" "$_authorizations_map"
_err "_authorizations_map" "$_authorizations_map" _clearup
_clearup _on_issue_err "$_post_hook"
_on_issue_err "$_post_hook" return 1
return 1
fi
else
if ! __get_domain_new_authz "$d"; then
_clearup
_on_issue_err "$_post_hook"
return 1
fi
fi fi
if [ -z "$thumbprint" ]; then if [ -z "$thumbprint" ]; then
...@@ -4347,11 +4533,9 @@ $_authorizations_map" ...@@ -4347,11 +4533,9 @@ $_authorizations_map"
_on_issue_err "$_post_hook" _on_issue_err "$_post_hook"
return 1 return 1
fi fi
if [ "$ACME_VERSION" = "2" ]; then
uri="$(echo "$entry" | _egrep_o '"url":"[^"]*' | cut -d '"' -f 4 | _head_n 1)" uri="$(echo "$entry" | _egrep_o '"url":"[^"]*' | cut -d '"' -f 4 | _head_n 1)"
else
uri="$(echo "$entry" | _egrep_o '"uri":"[^"]*' | cut -d '"' -f 4)"
fi
_debug uri "$uri" _debug uri "$uri"
if [ -z "$uri" ]; then if [ -z "$uri" ]; then
...@@ -4646,36 +4830,14 @@ $_authorizations_map" ...@@ -4646,36 +4830,14 @@ $_authorizations_map"
return 1 return 1
fi fi
_debug "sleep 2 secs to verify"
sleep 2
_debug "checking"
if [ "$ACME_VERSION" = "2" ]; then
_send_signed_request "$uri"
else
response="$(_get "$uri")"
fi
if [ "$?" != "0" ]; then
_err "$d:Verify error:$response"
_clearupwebbroot "$_currentRoot" "$removelevel" "$token"
_clearup
_on_issue_err "$_post_hook" "$vlist"
return 1
fi
_debug2 original "$response" _debug2 original "$response"
response="$(echo "$response" | _normalizeJson)" response="$(echo "$response" | _normalizeJson)"
_debug2 response "$response" _debug2 response "$response"
status=$(echo "$response" | _egrep_o '"status":"[^"]*' | cut -d : -f 2 | tr -d '"') status=$(echo "$response" | _egrep_o '"status":"[^"]*' | cut -d : -f 2 | tr -d '"')
if [ "$status" = "valid" ]; then _debug2 status "$status"
_info "$(__green Success)" if _contains "$status" "invalid"; then
_stopserver "$serverproc"
serverproc=""
_clearupwebbroot "$_currentRoot" "$removelevel" "$token"
break
fi
if [ "$status" = "invalid" ]; then
error="$(echo "$response" | _egrep_o '"error":\{[^\}]*')" error="$(echo "$response" | _egrep_o '"error":\{[^\}]*')"
_debug2 error "$error" _debug2 error "$error"
errordetail="$(echo "$error" | _egrep_o '"detail": *"[^"]*' | cut -d '"' -f 4)" errordetail="$(echo "$error" | _egrep_o '"detail": *"[^"]*' | cut -d '"' -f 4)"
...@@ -4697,10 +4859,18 @@ $_authorizations_map" ...@@ -4697,10 +4859,18 @@ $_authorizations_map"
return 1 return 1
fi fi
if _contains "$status" "valid"; then
_info "$(__green Success)"
_stopserver "$serverproc"
serverproc=""
_clearupwebbroot "$_currentRoot" "$removelevel" "$token"
break
fi
if [ "$status" = "pending" ]; then if [ "$status" = "pending" ]; then
_info "Pending" _info "Pending, The CA is processing your order, please just wait. ($waittimes/$MAX_RETRY_TIMES)"
elif [ "$status" = "processing" ]; then elif [ "$status" = "processing" ]; then
_info "Processing" _info "Processing, The CA is processing your order, please just wait. ($waittimes/$MAX_RETRY_TIMES)"
else else
_err "$d:Verify error:$response" _err "$d:Verify error:$response"
_clearupwebbroot "$_currentRoot" "$removelevel" "$token" _clearupwebbroot "$_currentRoot" "$removelevel" "$token"
...@@ -4708,7 +4878,19 @@ $_authorizations_map" ...@@ -4708,7 +4878,19 @@ $_authorizations_map"
_on_issue_err "$_post_hook" "$vlist" _on_issue_err "$_post_hook" "$vlist"
return 1 return 1
fi fi
_debug "sleep 2 secs to verify again"
sleep 2
_debug "checking"
_send_signed_request "$uri"
if [ "$?" != "0" ]; then
_err "$d:Verify error:$response"
_clearupwebbroot "$_currentRoot" "$removelevel" "$token"
_clearup
_on_issue_err "$_post_hook" "$vlist"
return 1
fi
done done
done done
...@@ -4717,138 +4899,129 @@ $_authorizations_map" ...@@ -4717,138 +4899,129 @@ $_authorizations_map"
_info "Verify finished, start to sign." _info "Verify finished, start to sign."
der="$(_getfile "${CSR_PATH}" "${BEGIN_CSR}" "${END_CSR}" | tr -d "\r\n" | _url_replace)" der="$(_getfile "${CSR_PATH}" "${BEGIN_CSR}" "${END_CSR}" | tr -d "\r\n" | _url_replace)"
if [ "$ACME_VERSION" = "2" ]; then _info "Lets finalize the order."
_info "Lets finalize the order." _info "Le_OrderFinalize" "$Le_OrderFinalize"
_info "Le_OrderFinalize" "$Le_OrderFinalize" if ! _send_signed_request "${Le_OrderFinalize}" "{\"csr\": \"$der\"}"; then
if ! _send_signed_request "${Le_OrderFinalize}" "{\"csr\": \"$der\"}"; then _err "Sign failed."
_err "Sign failed." _on_issue_err "$_post_hook"
_on_issue_err "$_post_hook" return 1
return 1 fi
fi if [ "$code" != "200" ]; then
if [ "$code" != "200" ]; then _err "Sign failed, finalize code is not 200."
_err "Sign failed, finalize code is not 200." _err "$response"
_err "$response" _on_issue_err "$_post_hook"
_on_issue_err "$_post_hook" return 1
return 1 fi
fi if [ -z "$Le_LinkOrder" ]; then
if [ -z "$Le_LinkOrder" ]; then Le_LinkOrder="$(echo "$responseHeaders" | grep -i '^Location.*$' | _tail_n 1 | tr -d "\r\n \t" | cut -d ":" -f 2-)"
Le_LinkOrder="$(echo "$responseHeaders" | grep -i '^Location.*$' | _tail_n 1 | tr -d "\r\n \t" | cut -d ":" -f 2-)" fi
fi
_savedomainconf "Le_LinkOrder" "$Le_LinkOrder" _savedomainconf "Le_LinkOrder" "$Le_LinkOrder"
_link_cert_retry=0 _link_cert_retry=0
_MAX_CERT_RETRY=30 _MAX_CERT_RETRY=30
while [ "$_link_cert_retry" -lt "$_MAX_CERT_RETRY" ]; do while [ "$_link_cert_retry" -lt "$_MAX_CERT_RETRY" ]; do
if _contains "$response" "\"status\":\"valid\""; then if _contains "$response" "\"status\":\"valid\""; then
_debug "Order status is valid." _debug "Order status is valid."
Le_LinkCert="$(echo "$response" | _egrep_o '"certificate" *: *"[^"]*"' | cut -d '"' -f 4)" Le_LinkCert="$(echo "$response" | _egrep_o '"certificate" *: *"[^"]*"' | cut -d '"' -f 4)"
_debug Le_LinkCert "$Le_LinkCert" _debug Le_LinkCert "$Le_LinkCert"
if [ -z "$Le_LinkCert" ]; then if [ -z "$Le_LinkCert" ]; then
_err "Sign error, can not find Le_LinkCert" _err "Sign error, can not find Le_LinkCert"
_err "$response"
_on_issue_err "$_post_hook"
return 1
fi
break
elif _contains "$response" "\"processing\""; then
_info "Order status is processing, lets sleep and retry."
_retryafter=$(echo "$responseHeaders" | grep -i "^Retry-After *:" | cut -d : -f 2 | tr -d ' ' | tr -d '\r')
_debug "_retryafter" "$_retryafter"
if [ "$_retryafter" ]; then
_info "Retry after: $_retryafter"
_sleep $_retryafter
else
_sleep 2
fi
else
_err "Sign error, wrong status"
_err "$response" _err "$response"
_on_issue_err "$_post_hook" _on_issue_err "$_post_hook"
return 1 return 1
fi fi
#the order is processing, so we are going to poll order status break
if [ -z "$Le_LinkOrder" ]; then elif _contains "$response" "\"processing\""; then
_err "Sign error, can not get order link location header" _info "Order status is processing, lets sleep and retry."
_err "responseHeaders" "$responseHeaders" _retryafter=$(echo "$responseHeaders" | grep -i "^Retry-After *:" | cut -d : -f 2 | tr -d ' ' | tr -d '\r')
_on_issue_err "$_post_hook" _debug "_retryafter" "$_retryafter"
return 1 if [ "$_retryafter" ]; then
fi _info "Retry after: $_retryafter"
_info "Polling order status: $Le_LinkOrder" _sleep $_retryafter
if ! _send_signed_request "$Le_LinkOrder"; then else
_err "Sign failed, can not post to Le_LinkOrder cert:$Le_LinkOrder." _sleep 2
_err "$response"
_on_issue_err "$_post_hook"
return 1
fi fi
_link_cert_retry="$(_math $_link_cert_retry + 1)" else
done _err "Sign error, wrong status"
if [ -z "$Le_LinkCert" ]; then
_err "Sign failed, can not get Le_LinkCert, retry time limit."
_err "$response" _err "$response"
_on_issue_err "$_post_hook" _on_issue_err "$_post_hook"
return 1 return 1
fi fi
_info "Downloading cert." #the order is processing, so we are going to poll order status
_info "Le_LinkCert" "$Le_LinkCert" if [ -z "$Le_LinkOrder" ]; then
if ! _send_signed_request "$Le_LinkCert"; then _err "Sign error, can not get order link location header"
_err "Sign failed, can not download cert:$Le_LinkCert." _err "responseHeaders" "$responseHeaders"
_err "$response"
_on_issue_err "$_post_hook" _on_issue_err "$_post_hook"
return 1 return 1
fi fi
_info "Polling order status: $Le_LinkOrder"
echo "$response" >"$CERT_PATH" if ! _send_signed_request "$Le_LinkOrder"; then
_split_cert_chain "$CERT_PATH" "$CERT_FULLCHAIN_PATH" "$CA_CERT_PATH" _err "Sign failed, can not post to Le_LinkOrder cert:$Le_LinkOrder."
_err "$response"
if [ "$_preferred_chain" ] && [ -f "$CERT_FULLCHAIN_PATH" ]; then
if ! _match_issuer "$CERT_FULLCHAIN_PATH" "$_preferred_chain"; then
rels="$(echo "$responseHeaders" | tr -d ' <>' | grep -i "^link:" | grep -i 'rel="alternate"' | cut -d : -f 2- | cut -d ';' -f 1)"
_debug2 "rels" "$rels"
for rel in $rels; do
_info "Try rel: $rel"
if ! _send_signed_request "$rel"; then
_err "Sign failed, can not download cert:$rel"
_err "$response"
continue
fi
_relcert="$CERT_PATH.alt"
_relfullchain="$CERT_FULLCHAIN_PATH.alt"
_relca="$CA_CERT_PATH.alt"
echo "$response" >"$_relcert"
_split_cert_chain "$_relcert" "$_relfullchain" "$_relca"
if _match_issuer "$_relfullchain" "$_preferred_chain"; then
_info "Matched issuer in: $rel"
cat $_relcert >"$CERT_PATH"
cat $_relfullchain >"$CERT_FULLCHAIN_PATH"
cat $_relca >"$CA_CERT_PATH"
break
fi
done
fi
fi
else
if ! _send_signed_request "${ACME_NEW_ORDER}" "{\"resource\": \"$ACME_NEW_ORDER_RES\", \"csr\": \"$der\"}" "needbase64"; then
_err "Sign failed. $response"
_on_issue_err "$_post_hook" _on_issue_err "$_post_hook"
return 1 return 1
fi fi
_rcert="$response" _link_cert_retry="$(_math $_link_cert_retry + 1)"
Le_LinkCert="$(grep -i '^Location.*$' "$HTTP_HEADER" | _tail_n 1 | tr -d "\r\n" | cut -d " " -f 2)" done
echo "$BEGIN_CERT" >"$CERT_PATH"
#if ! _get "$Le_LinkCert" | _base64 "multiline" >> "$CERT_PATH" ; then if [ -z "$Le_LinkCert" ]; then
# _debug "Get cert failed. Let's try last response." _err "Sign failed, can not get Le_LinkCert, retry time limit."
# printf -- "%s" "$_rcert" | _dbase64 "multiline" | _base64 "multiline" >> "$CERT_PATH" _err "$response"
#fi _on_issue_err "$_post_hook"
return 1
fi
_info "Downloading cert."
_info "Le_LinkCert" "$Le_LinkCert"
if ! _send_signed_request "$Le_LinkCert"; then
_err "Sign failed, can not download cert:$Le_LinkCert."
_err "$response"
_on_issue_err "$_post_hook"
return 1
fi
if ! printf -- "%s" "$_rcert" | _dbase64 "multiline" | _base64 "multiline" >>"$CERT_PATH"; then echo "$response" >"$CERT_PATH"
_debug "Try cert link." _split_cert_chain "$CERT_PATH" "$CERT_FULLCHAIN_PATH" "$CA_CERT_PATH"
_get "$Le_LinkCert" | _base64 "multiline" >>"$CERT_PATH" if [ -z "$_preferred_chain" ]; then
_preferred_chain=$(_readcaconf DEFAULT_PREFERRED_CHAIN)
fi
if [ "$_preferred_chain" ] && [ -f "$CERT_FULLCHAIN_PATH" ]; then
if [ "$DEBUG" ]; then
_debug "default chain issuers: " "$(_get_chain_issuers "$CERT_FULLCHAIN_PATH")"
fi
if ! _match_issuer "$CERT_FULLCHAIN_PATH" "$_preferred_chain"; then
rels="$(echo "$responseHeaders" | tr -d ' <>' | grep -i "^link:" | grep -i 'rel="alternate"' | cut -d : -f 2- | cut -d ';' -f 1)"
_debug2 "rels" "$rels"
for rel in $rels; do
_info "Try rel: $rel"
if ! _send_signed_request "$rel"; then
_err "Sign failed, can not download cert:$rel"
_err "$response"
continue
fi
_relcert="$CERT_PATH.alt"
_relfullchain="$CERT_FULLCHAIN_PATH.alt"
_relca="$CA_CERT_PATH.alt"
echo "$response" >"$_relcert"
_split_cert_chain "$_relcert" "$_relfullchain" "$_relca"
if [ "$DEBUG" ]; then
_debug "rel chain issuers: " "$(_get_chain_issuers "$_relfullchain")"
fi
if _match_issuer "$_relfullchain" "$_preferred_chain"; then
_info "Matched issuer in: $rel"
cat $_relcert >"$CERT_PATH"
cat $_relfullchain >"$CERT_FULLCHAIN_PATH"
cat $_relca >"$CA_CERT_PATH"
rm -f "$_relcert"
rm -f "$_relfullchain"
rm -f "$_relca"
break
fi
rm -f "$_relcert"
rm -f "$_relfullchain"
rm -f "$_relca"
done
fi fi
echo "$END_CERT" >>"$CERT_PATH"
fi fi
_debug "Le_LinkCert" "$Le_LinkCert" _debug "Le_LinkCert" "$Le_LinkCert"
...@@ -4865,10 +5038,10 @@ $_authorizations_map" ...@@ -4865,10 +5038,10 @@ $_authorizations_map"
_info "$(__green "Cert success.")" _info "$(__green "Cert success.")"
cat "$CERT_PATH" cat "$CERT_PATH"
_info "Your cert is in $(__green " $CERT_PATH ")" _info "Your cert is in: $(__green "$CERT_PATH")"
if [ -f "$CERT_KEY_PATH" ]; then if [ -f "$CERT_KEY_PATH" ]; then
_info "Your cert key is in $(__green " $CERT_KEY_PATH ")" _info "Your cert key is in: $(__green "$CERT_KEY_PATH")"
fi fi
if [ ! "$USER_PATH" ] || [ ! "$_ACME_IN_CRON" ]; then if [ ! "$USER_PATH" ] || [ ! "$_ACME_IN_CRON" ]; then
...@@ -4877,55 +5050,8 @@ $_authorizations_map" ...@@ -4877,55 +5050,8 @@ $_authorizations_map"
fi fi
fi fi
if [ "$ACME_VERSION" = "2" ]; then [ -f "$CA_CERT_PATH" ] && _info "The intermediate CA cert is in: $(__green "$CA_CERT_PATH")"
_debug "v2 chain." [ -f "$CERT_FULLCHAIN_PATH" ] && _info "And the full chain certs is there: $(__green "$CERT_FULLCHAIN_PATH")"
else
cp "$CERT_PATH" "$CERT_FULLCHAIN_PATH"
Le_LinkIssuer=$(grep -i '^Link' "$HTTP_HEADER" | _head_n 1 | cut -d " " -f 2 | cut -d ';' -f 1 | tr -d '<>')
if [ "$Le_LinkIssuer" ]; then
if ! _contains "$Le_LinkIssuer" ":"; then
_info "$(__red "Relative issuer link found.")"
Le_LinkIssuer="$_ACME_SERVER_HOST$Le_LinkIssuer"
fi
_debug Le_LinkIssuer "$Le_LinkIssuer"
_savedomainconf "Le_LinkIssuer" "$Le_LinkIssuer"
_link_issuer_retry=0
_MAX_ISSUER_RETRY=5
while [ "$_link_issuer_retry" -lt "$_MAX_ISSUER_RETRY" ]; do
_debug _link_issuer_retry "$_link_issuer_retry"
if [ "$ACME_VERSION" = "2" ]; then
if _send_signed_request "$Le_LinkIssuer"; then
echo "$response" >"$CA_CERT_PATH"
break
fi
else
if _get "$Le_LinkIssuer" >"$CA_CERT_PATH.der"; then
echo "$BEGIN_CERT" >"$CA_CERT_PATH"
_base64 "multiline" <"$CA_CERT_PATH.der" >>"$CA_CERT_PATH"
echo "$END_CERT" >>"$CA_CERT_PATH"
if ! _checkcert "$CA_CERT_PATH"; then
_err "Can not get the ca cert."
break
fi
cat "$CA_CERT_PATH" >>"$CERT_FULLCHAIN_PATH"
rm -f "$CA_CERT_PATH.der"
break
fi
fi
_link_issuer_retry=$(_math $_link_issuer_retry + 1)
_sleep "$_link_issuer_retry"
done
if [ "$_link_issuer_retry" = "$_MAX_ISSUER_RETRY" ]; then
_err "Max retry for issuer ca cert is reached."
fi
else
_debug "No Le_LinkIssuer header found."
fi
fi
[ -f "$CA_CERT_PATH" ] && _info "The intermediate CA cert is in $(__green " $CA_CERT_PATH ")"
[ -f "$CERT_FULLCHAIN_PATH" ] && _info "And the full chain certs is there: $(__green " $CERT_FULLCHAIN_PATH ")"
Le_CertCreateTime=$(_time) Le_CertCreateTime=$(_time)
_savedomainconf "Le_CertCreateTime" "$Le_CertCreateTime" _savedomainconf "Le_CertCreateTime" "$Le_CertCreateTime"
...@@ -5036,17 +5162,16 @@ renew() { ...@@ -5036,17 +5162,16 @@ renew() {
. "$DOMAIN_CONF" . "$DOMAIN_CONF"
_debug Le_API "$Le_API" _debug Le_API "$Le_API"
if [ -z "$Le_API" ] || [ "$CA_LETSENCRYPT_V1" = "$Le_API" ]; then
if [ "$Le_API" = "$LETSENCRYPT_CA_V1" ]; then #if this is from an old version, Le_API is empty,
_cleardomainconf Le_API #so, we force to use letsencrypt server
Le_API="$DEFAULT_CA" Le_API="$CA_LETSENCRYPT_V2"
fi
if [ "$Le_API" = "$LETSENCRYPT_STAGING_CA_V1" ]; then
_cleardomainconf Le_API
Le_API="$DEFAULT_STAGING_CA"
fi fi
if [ "$Le_API" ]; then if [ "$Le_API" ]; then
if [ "$Le_API" != "$ACME_DIRECTORY" ]; then
_clearAPI
fi
export ACME_DIRECTORY="$Le_API" export ACME_DIRECTORY="$Le_API"
#reload ca configs #reload ca configs
ACCOUNT_KEY_PATH="" ACCOUNT_KEY_PATH=""
...@@ -5222,6 +5347,7 @@ signcsr() { ...@@ -5222,6 +5347,7 @@ signcsr() {
_renew_hook="${10}" _renew_hook="${10}"
_local_addr="${11}" _local_addr="${11}"
_challenge_alias="${12}" _challenge_alias="${12}"
_preferred_chain="${13}"
_csrsubj=$(_readSubjectFromCSR "$_csrfile") _csrsubj=$(_readSubjectFromCSR "$_csrfile")
if [ "$?" != "0" ]; then if [ "$?" != "0" ]; then
...@@ -5259,16 +5385,13 @@ signcsr() { ...@@ -5259,16 +5385,13 @@ signcsr() {
return 1 return 1
fi fi
if [ -z "$ACME_VERSION" ] && _contains "$_csrsubj,$_csrdomainlist" "*."; then
export ACME_VERSION=2
fi
_initpath "$_csrsubj" "$_csrkeylength" _initpath "$_csrsubj" "$_csrkeylength"
mkdir -p "$DOMAIN_PATH" mkdir -p "$DOMAIN_PATH"
_info "Copy csr to: $CSR_PATH" _info "Copy csr to: $CSR_PATH"
cp "$_csrfile" "$CSR_PATH" cp "$_csrfile" "$CSR_PATH"
issue "$_csrW" "$_csrsubj" "$_csrdomainlist" "$_csrkeylength" "$_real_cert" "$_real_key" "$_real_ca" "$_reload_cmd" "$_real_fullchain" "$_pre_hook" "$_post_hook" "$_renew_hook" "$_local_addr" "$_challenge_alias" issue "$_csrW" "$_csrsubj" "$_csrdomainlist" "$_csrkeylength" "$_real_cert" "$_real_key" "$_real_ca" "$_reload_cmd" "$_real_fullchain" "$_pre_hook" "$_post_hook" "$_renew_hook" "$_local_addr" "$_challenge_alias" "$_preferred_chain"
} }
...@@ -5471,7 +5594,7 @@ _installcert() { ...@@ -5471,7 +5594,7 @@ _installcert() {
mkdir -p "$_backup_path" mkdir -p "$_backup_path"
if [ "$_real_cert" ]; then if [ "$_real_cert" ]; then
_info "Installing cert to:$_real_cert" _info "Installing cert to: $_real_cert"
if [ -f "$_real_cert" ] && [ ! "$_ACME_IS_RENEW" ]; then if [ -f "$_real_cert" ] && [ ! "$_ACME_IS_RENEW" ]; then
cp "$_real_cert" "$_backup_path/cert.bak" cp "$_real_cert" "$_backup_path/cert.bak"
fi fi
...@@ -5479,7 +5602,7 @@ _installcert() { ...@@ -5479,7 +5602,7 @@ _installcert() {
fi fi
if [ "$_real_ca" ]; then if [ "$_real_ca" ]; then
_info "Installing CA to:$_real_ca" _info "Installing CA to: $_real_ca"
if [ "$_real_ca" = "$_real_cert" ]; then if [ "$_real_ca" = "$_real_cert" ]; then
echo "" >>"$_real_ca" echo "" >>"$_real_ca"
cat "$CA_CERT_PATH" >>"$_real_ca" || return 1 cat "$CA_CERT_PATH" >>"$_real_ca" || return 1
...@@ -5492,7 +5615,7 @@ _installcert() { ...@@ -5492,7 +5615,7 @@ _installcert() {
fi fi
if [ "$_real_key" ]; then if [ "$_real_key" ]; then
_info "Installing key to:$_real_key" _info "Installing key to: $_real_key"
if [ -f "$_real_key" ] && [ ! "$_ACME_IS_RENEW" ]; then if [ -f "$_real_key" ] && [ ! "$_ACME_IS_RENEW" ]; then
cp "$_real_key" "$_backup_path/key.bak" cp "$_real_key" "$_backup_path/key.bak"
fi fi
...@@ -5505,7 +5628,7 @@ _installcert() { ...@@ -5505,7 +5628,7 @@ _installcert() {
fi fi
if [ "$_real_fullchain" ]; then if [ "$_real_fullchain" ]; then
_info "Installing full chain to:$_real_fullchain" _info "Installing full chain to: $_real_fullchain"
if [ -f "$_real_fullchain" ] && [ ! "$_ACME_IS_RENEW" ]; then if [ -f "$_real_fullchain" ] && [ ! "$_ACME_IS_RENEW" ]; then
cp "$_real_fullchain" "$_backup_path/fullchain.bak" cp "$_real_fullchain" "$_backup_path/fullchain.bak"
fi fi
...@@ -5600,8 +5723,16 @@ installcronjob() { ...@@ -5600,8 +5723,16 @@ installcronjob() {
if [ -f "$LE_WORKING_DIR/$PROJECT_ENTRY" ]; then if [ -f "$LE_WORKING_DIR/$PROJECT_ENTRY" ]; then
lesh="\"$LE_WORKING_DIR\"/$PROJECT_ENTRY" lesh="\"$LE_WORKING_DIR\"/$PROJECT_ENTRY"
else else
_err "Can not install cronjob, $PROJECT_ENTRY not found." _debug "_SCRIPT_" "$_SCRIPT_"
return 1 _script="$(_readlink "$_SCRIPT_")"
_debug _script "$_script"
if [ -f "$_script" ]; then
_info "Using the current script from: $_script"
lesh="$_script"
else
_err "Can not install cronjob, $PROJECT_ENTRY not found."
return 1
fi
fi fi
if [ "$_c_home" ]; then if [ "$_c_home" ]; then
_c_entry="--config-home \"$_c_home\" " _c_entry="--config-home \"$_c_home\" "
...@@ -5673,7 +5804,7 @@ uninstallcronjob() { ...@@ -5673,7 +5804,7 @@ uninstallcronjob() {
_info "Removing cron job" _info "Removing cron job"
cr="$($_CRONTAB -l | grep "$PROJECT_ENTRY --cron")" cr="$($_CRONTAB -l | grep "$PROJECT_ENTRY --cron")"
if [ "$cr" ]; then if [ "$cr" ]; then
if _exists uname && uname -a | grep solaris >/dev/null; then if _exists uname && uname -a | grep SunOS >/dev/null; then
$_CRONTAB -l | sed "/$PROJECT_ENTRY --cron/d" | $_CRONTAB -- $_CRONTAB -l | sed "/$PROJECT_ENTRY --cron/d" | $_CRONTAB --
else else
$_CRONTAB -l | sed "/$PROJECT_ENTRY --cron/d" | $_CRONTAB - $_CRONTAB -l | sed "/$PROJECT_ENTRY --cron/d" | $_CRONTAB -
...@@ -5713,6 +5844,23 @@ revoke() { ...@@ -5713,6 +5844,23 @@ revoke() {
return 1 return 1
fi fi
. "$DOMAIN_CONF"
_debug Le_API "$Le_API"
if [ "$Le_API" ]; then
if [ "$Le_API" != "$ACME_DIRECTORY" ]; then
_clearAPI
fi
export ACME_DIRECTORY="$Le_API"
#reload ca configs
ACCOUNT_KEY_PATH=""
ACCOUNT_JSON_PATH=""
CA_CONF=""
_debug3 "initpath again."
_initpath "$Le_Domain" "$_isEcc"
_initAPI
fi
cert="$(_getfile "${CERT_PATH}" "${BEGIN_CERT}" "${END_CERT}" | tr -d "\r\n" | _url_replace)" cert="$(_getfile "${CERT_PATH}" "${BEGIN_CERT}" "${END_CERT}" | tr -d "\r\n" | _url_replace)"
if [ -z "$cert" ]; then if [ -z "$cert" ]; then
...@@ -5722,11 +5870,8 @@ revoke() { ...@@ -5722,11 +5870,8 @@ revoke() {
_initAPI _initAPI
if [ "$ACME_VERSION" = "2" ]; then data="{\"certificate\": \"$cert\",\"reason\":$_reason}"
data="{\"certificate\": \"$cert\",\"reason\":$_reason}"
else
data="{\"resource\": \"revoke-cert\", \"certificate\": \"$cert\"}"
fi
uri="${ACME_REVOKE_CERT}" uri="${ACME_REVOKE_CERT}"
if [ -f "$CERT_KEY_PATH" ]; then if [ -f "$CERT_KEY_PATH" ]; then
...@@ -5795,60 +5940,62 @@ remove() { ...@@ -5795,60 +5940,62 @@ remove() {
_deactivate() { _deactivate() {
_d_domain="$1" _d_domain="$1"
_d_type="$2" _d_type="$2"
_initpath _initpath "$_d_domain" "$_d_type"
if [ "$ACME_VERSION" = "2" ]; then . "$DOMAIN_CONF"
_identifiers="{\"type\":\"dns\",\"value\":\"$_d_domain\"}" _debug Le_API "$Le_API"
if ! _send_signed_request "$ACME_NEW_ORDER" "{\"identifiers\": [$_identifiers]}"; then
_err "Can not get domain new order."
return 1
fi
_authorizations_seg="$(echo "$response" | _egrep_o '"authorizations" *: *\[[^\]*\]' | cut -d '[' -f 2 | tr -d ']' | tr -d '"')"
_debug2 _authorizations_seg "$_authorizations_seg"
if [ -z "$_authorizations_seg" ]; then
_err "_authorizations_seg not found."
_clearup
_on_issue_err "$_post_hook"
return 1
fi
authzUri="$_authorizations_seg" if [ "$Le_API" ]; then
_debug2 "authzUri" "$authzUri" if [ "$Le_API" != "$ACME_DIRECTORY" ]; then
if ! _send_signed_request "$authzUri"; then _clearAPI
_err "get to authz error."
_err "_authorizations_seg" "$_authorizations_seg"
_err "authzUri" "$authzUri"
_clearup
_on_issue_err "$_post_hook"
return 1
fi fi
export ACME_DIRECTORY="$Le_API"
#reload ca configs
ACCOUNT_KEY_PATH=""
ACCOUNT_JSON_PATH=""
CA_CONF=""
_debug3 "initpath again."
_initpath "$Le_Domain" "$_d_type"
_initAPI
fi
response="$(echo "$response" | _normalizeJson)" _identifiers="{\"type\":\"$(_getIdType "$_d_domain")\",\"value\":\"$_d_domain\"}"
_debug2 response "$response" if ! _send_signed_request "$ACME_NEW_ORDER" "{\"identifiers\": [$_identifiers]}"; then
_URL_NAME="url" _err "Can not get domain new order."
else return 1
if ! __get_domain_new_authz "$_d_domain"; then fi
_err "Can not get domain new authz token." _authorizations_seg="$(echo "$response" | _egrep_o '"authorizations" *: *\[[^\]*\]' | cut -d '[' -f 2 | tr -d ']' | tr -d '"')"
return 1 _debug2 _authorizations_seg "$_authorizations_seg"
fi if [ -z "$_authorizations_seg" ]; then
_err "_authorizations_seg not found."
_clearup
_on_issue_err "$_post_hook"
return 1
fi
authzUri="$(echo "$responseHeaders" | grep "^Location:" | _head_n 1 | cut -d ':' -f 2- | tr -d "\r\n")" authzUri="$_authorizations_seg"
_debug "authzUri" "$authzUri" _debug2 "authzUri" "$authzUri"
if [ "$code" ] && [ ! "$code" = '201' ]; then if ! _send_signed_request "$authzUri"; then
_err "new-authz error: $response" _err "get to authz error."
return 1 _err "_authorizations_seg" "$_authorizations_seg"
fi _err "authzUri" "$authzUri"
_URL_NAME="uri" _clearup
_on_issue_err "$_post_hook"
return 1
fi fi
entries="$(echo "$response" | tr '][' '==' | _egrep_o "challenges\": *=[^=]*=" | tr '}{' '\n' | grep "\"status\": *\"valid\"")" response="$(echo "$response" | _normalizeJson)"
_debug2 response "$response"
_URL_NAME="url"
entries="$(echo "$response" | tr '][' '==' | _egrep_o "challenges\": *=[^=]*=" | tr '}{' '\n\n' | grep "\"status\": *\"valid\"")"
if [ -z "$entries" ]; then if [ -z "$entries" ]; then
_info "No valid entries found." _info "No valid entries found."
if [ -z "$thumbprint" ]; then if [ -z "$thumbprint" ]; then
thumbprint="$(__calc_account_thumbprint)" thumbprint="$(__calc_account_thumbprint)"
fi fi
_debug "Trigger validation." _debug "Trigger validation."
vtype="$VTYPE_DNS" vtype="$(_getIdType "$_d_domain")"
entry="$(echo "$response" | _egrep_o '[^\{]*"type":"'$vtype'"[^\}]*')" entry="$(echo "$response" | _egrep_o '[^\{]*"type":"'$vtype'"[^\}]*')"
_debug entry "$entry" _debug entry "$entry"
if [ -z "$entry" ]; then if [ -z "$entry" ]; then
...@@ -5894,11 +6041,7 @@ _deactivate() { ...@@ -5894,11 +6041,7 @@ _deactivate() {
_info "Deactivate: $_vtype" _info "Deactivate: $_vtype"
if [ "$ACME_VERSION" = "2" ]; then _djson="{\"status\":\"deactivated\"}"
_djson="{\"status\":\"deactivated\"}"
else
_djson="{\"resource\": \"authz\", \"status\":\"deactivated\"}"
fi
if _send_signed_request "$authzUri" "$_djson" && _contains "$response" '"deactivated"'; then if _send_signed_request "$authzUri" "$_djson" && _contains "$response" '"deactivated"'; then
_info "Deactivate: $_vtype success." _info "Deactivate: $_vtype success."
...@@ -6461,6 +6604,8 @@ Commands: ...@@ -6461,6 +6604,8 @@ Commands:
--deactivate Deactivate the domain authz, professional use. --deactivate Deactivate the domain authz, professional use.
--set-default-ca Used with '--server', Set the default CA to use. --set-default-ca Used with '--server', Set the default CA to use.
See: $_SERVER_WIKI See: $_SERVER_WIKI
--set-default-chain Set the default preferred chain for a CA.
See: $_PREFERRED_CHAIN_WIKI
Parameters: Parameters:
...@@ -6609,7 +6754,7 @@ _getRepoHash() { ...@@ -6609,7 +6754,7 @@ _getRepoHash() {
_hash_path=$1 _hash_path=$1
shift shift
_hash_url="https://api.github.com/repos/acmesh-official/$PROJECT_NAME/git/refs/$_hash_path" _hash_url="https://api.github.com/repos/acmesh-official/$PROJECT_NAME/git/refs/$_hash_path"
_get $_hash_url | tr -d "\r\n" | tr '{},' '\n' | grep '"sha":' | cut -d '"' -f 4 _get $_hash_url | tr -d "\r\n" | tr '{},' '\n\n\n' | grep '"sha":' | cut -d '"' -f 4
} }
_getUpgradeHash() { _getUpgradeHash() {
...@@ -6682,9 +6827,10 @@ _checkSudo() { ...@@ -6682,9 +6827,10 @@ _checkSudo() {
return 0 return 0
} }
#server #server #keylength
_selectServer() { _selectServer() {
_server="$1" _server="$1"
_skeylength="$2"
_server_lower="$(echo "$_server" | _lower_case)" _server_lower="$(echo "$_server" | _lower_case)"
_sindex=0 _sindex=0
for snames in $CA_NAMES; do for snames in $CA_NAMES; do
...@@ -6695,6 +6841,9 @@ _selectServer() { ...@@ -6695,6 +6841,9 @@ _selectServer() {
if [ "$_server_lower" = "$sname" ]; then if [ "$_server_lower" = "$sname" ]; then
_debug2 "_selectServer match $sname" _debug2 "_selectServer match $sname"
_serverdir="$(_getfield "$CA_SERVERS" $_sindex)" _serverdir="$(_getfield "$CA_SERVERS" $_sindex)"
if [ "$_serverdir" = "$CA_SSLCOM_RSA" ] && _isEccKey "$_skeylength"; then
_serverdir="$CA_SSLCOM_ECC"
fi
_debug "Selected server: $_serverdir" _debug "Selected server: $_serverdir"
ACME_DIRECTORY="$_serverdir" ACME_DIRECTORY="$_serverdir"
export ACME_DIRECTORY export ACME_DIRECTORY
...@@ -6712,6 +6861,9 @@ _getCAShortName() { ...@@ -6712,6 +6861,9 @@ _getCAShortName() {
if [ -z "$caurl" ]; then if [ -z "$caurl" ]; then
caurl="$DEFAULT_CA" caurl="$DEFAULT_CA"
fi fi
if [ "$CA_SSLCOM_ECC" = "$caurl" ]; then
caurl="$CA_SSLCOM_RSA" #just hack to get the short name
fi
caurl_lower="$(echo $caurl | _lower_case)" caurl_lower="$(echo $caurl | _lower_case)"
_sindex=0 _sindex=0
for surl in $(echo "$CA_SERVERS" | _lower_case | tr , ' '); do for surl in $(echo "$CA_SERVERS" | _lower_case | tr , ' '); do
...@@ -6740,6 +6892,18 @@ setdefaultca() { ...@@ -6740,6 +6892,18 @@ setdefaultca() {
_info "Changed default CA to: $(__green "$ACME_DIRECTORY")" _info "Changed default CA to: $(__green "$ACME_DIRECTORY")"
} }
#preferred-chain
setdefaultchain() {
_initpath
_preferred_chain="$1"
if [ -z "$_preferred_chain" ]; then
_err "Please give a '--preferred-chain value' value."
return 1
fi
mkdir -p "$CA_DIR"
_savecaconf "DEFAULT_PREFERRED_CHAIN" "$_preferred_chain"
}
_process() { _process() {
_CMD="" _CMD=""
_domain="" _domain=""
...@@ -6891,6 +7055,9 @@ _process() { ...@@ -6891,6 +7055,9 @@ _process() {
--set-default-ca) --set-default-ca)
_CMD="setdefaultca" _CMD="setdefaultca"
;; ;;
--set-default-chain)
_CMD="setdefaultchain"
;;
-d | --domain) -d | --domain)
_dvalue="$2" _dvalue="$2"
...@@ -6904,10 +7071,6 @@ _process() { ...@@ -6904,10 +7071,6 @@ _process() {
return 1 return 1
fi fi
if _startswith "$_dvalue" "*."; then
_debug "Wildcard domain"
export ACME_VERSION=2
fi
if [ -z "$_domain" ]; then if [ -z "$_domain" ]; then
_domain="$_dvalue" _domain="$_dvalue"
else else
...@@ -6930,7 +7093,6 @@ _process() { ...@@ -6930,7 +7093,6 @@ _process() {
;; ;;
--server) --server)
_server="$2" _server="$2"
_selectServer "$_server"
shift shift
;; ;;
--debug) --debug)
...@@ -7029,7 +7191,6 @@ _process() { ...@@ -7029,7 +7191,6 @@ _process() {
Le_DNSSleep="$_dnssleep" Le_DNSSleep="$_dnssleep"
shift shift
;; ;;
--keylength | -k) --keylength | -k)
_keylength="$2" _keylength="$2"
shift shift
...@@ -7038,7 +7199,6 @@ _process() { ...@@ -7038,7 +7199,6 @@ _process() {
_accountkeylength="$2" _accountkeylength="$2"
shift shift
;; ;;
--cert-file | --certpath) --cert-file | --certpath)
_cert_file="$2" _cert_file="$2"
shift shift
...@@ -7302,6 +7462,10 @@ _process() { ...@@ -7302,6 +7462,10 @@ _process() {
shift 1 shift 1
done done
if [ "$_server" ]; then
_selectServer "$_server" "${_ecc:-$_keylength}"
fi
if [ "${_CMD}" != "install" ]; then if [ "${_CMD}" != "install" ]; then
if [ "$__INTERACTIVE" ] && ! _checkSudo; then if [ "$__INTERACTIVE" ] && ! _checkSudo; then
if [ -z "$FORCE" ]; then if [ -z "$FORCE" ]; then
...@@ -7365,7 +7529,7 @@ _process() { ...@@ -7365,7 +7529,7 @@ _process() {
deploy "$_domain" "$_deploy_hook" "$_ecc" deploy "$_domain" "$_deploy_hook" "$_ecc"
;; ;;
signcsr) signcsr)
signcsr "$_csr" "$_webroot" "$_cert_file" "$_key_file" "$_ca_file" "$_reloadcmd" "$_fullchain_file" "$_pre_hook" "$_post_hook" "$_renew_hook" "$_local_address" "$_challenge_alias" signcsr "$_csr" "$_webroot" "$_cert_file" "$_key_file" "$_ca_file" "$_reloadcmd" "$_fullchain_file" "$_pre_hook" "$_post_hook" "$_renew_hook" "$_local_address" "$_challenge_alias" "$_preferred_chain"
;; ;;
showcsr) showcsr)
showcsr "$_csr" "$_domain" showcsr "$_csr" "$_domain"
...@@ -7424,6 +7588,9 @@ _process() { ...@@ -7424,6 +7588,9 @@ _process() {
setdefaultca) setdefaultca)
setdefaultca setdefaultca
;; ;;
setdefaultchain)
setdefaultchain "$_preferred_chain"
;;
*) *)
if [ "$_CMD" ]; then if [ "$_CMD" ]; then
_err "Invalid command: $_CMD" _err "Invalid command: $_CMD"
......
...@@ -17,6 +17,8 @@ cleverreach_deploy() { ...@@ -17,6 +17,8 @@ cleverreach_deploy() {
_cca="$4" _cca="$4"
_cfullchain="$5" _cfullchain="$5"
_rest_endpoint="https://rest.cleverreach.com"
_debug _cdomain "$_cdomain" _debug _cdomain "$_cdomain"
_debug _ckey "$_ckey" _debug _ckey "$_ckey"
_debug _ccert "$_ccert" _debug _ccert "$_ccert"
...@@ -25,6 +27,7 @@ cleverreach_deploy() { ...@@ -25,6 +27,7 @@ cleverreach_deploy() {
_getdeployconf DEPLOY_CLEVERREACH_CLIENT_ID _getdeployconf DEPLOY_CLEVERREACH_CLIENT_ID
_getdeployconf DEPLOY_CLEVERREACH_CLIENT_SECRET _getdeployconf DEPLOY_CLEVERREACH_CLIENT_SECRET
_getdeployconf DEPLOY_CLEVERREACH_SUBCLIENT_ID
if [ -z "${DEPLOY_CLEVERREACH_CLIENT_ID}" ]; then if [ -z "${DEPLOY_CLEVERREACH_CLIENT_ID}" ]; then
_err "CleverReach Client ID is not found, please define DEPLOY_CLEVERREACH_CLIENT_ID." _err "CleverReach Client ID is not found, please define DEPLOY_CLEVERREACH_CLIENT_ID."
...@@ -37,11 +40,12 @@ cleverreach_deploy() { ...@@ -37,11 +40,12 @@ cleverreach_deploy() {
_savedeployconf DEPLOY_CLEVERREACH_CLIENT_ID "${DEPLOY_CLEVERREACH_CLIENT_ID}" _savedeployconf DEPLOY_CLEVERREACH_CLIENT_ID "${DEPLOY_CLEVERREACH_CLIENT_ID}"
_savedeployconf DEPLOY_CLEVERREACH_CLIENT_SECRET "${DEPLOY_CLEVERREACH_CLIENT_SECRET}" _savedeployconf DEPLOY_CLEVERREACH_CLIENT_SECRET "${DEPLOY_CLEVERREACH_CLIENT_SECRET}"
_savedeployconf DEPLOY_CLEVERREACH_SUBCLIENT_ID "${DEPLOY_CLEVERREACH_SUBCLIENT_ID}"
_info "Obtaining a CleverReach access token" _info "Obtaining a CleverReach access token"
_data="{\"grant_type\": \"client_credentials\", \"client_id\": \"${DEPLOY_CLEVERREACH_CLIENT_ID}\", \"client_secret\": \"${DEPLOY_CLEVERREACH_CLIENT_SECRET}\"}" _data="{\"grant_type\": \"client_credentials\", \"client_id\": \"${DEPLOY_CLEVERREACH_CLIENT_ID}\", \"client_secret\": \"${DEPLOY_CLEVERREACH_CLIENT_SECRET}\"}"
_auth_result="$(_post "$_data" "https://rest.cleverreach.com/oauth/token.php" "" "POST" "application/json")" _auth_result="$(_post "$_data" "$_rest_endpoint/oauth/token.php" "" "POST" "application/json")"
_debug _data "$_data" _debug _data "$_data"
_debug _auth_result "$_auth_result" _debug _auth_result "$_auth_result"
...@@ -50,14 +54,32 @@ cleverreach_deploy() { ...@@ -50,14 +54,32 @@ cleverreach_deploy() {
_debug _regex "$_regex" _debug _regex "$_regex"
_access_token=$(echo "$_auth_result" | _json_decode | sed -n "s/$_regex/\1/p") _access_token=$(echo "$_auth_result" | _json_decode | sed -n "s/$_regex/\1/p")
_debug _subclient "${DEPLOY_CLEVERREACH_SUBCLIENT_ID}"
if [ -n "${DEPLOY_CLEVERREACH_SUBCLIENT_ID}" ]; then
_info "Obtaining token for sub-client ${DEPLOY_CLEVERREACH_SUBCLIENT_ID}"
export _H1="Authorization: Bearer ${_access_token}"
_subclient_token_result="$(_get "$_rest_endpoint/v3/clients/$DEPLOY_CLEVERREACH_SUBCLIENT_ID/token")"
_access_token=$(echo "$_subclient_token_result" | sed -n "s/\"//p")
_debug _subclient_token_result "$_access_token"
_info "Destroying parent token at CleverReach, as it not needed anymore"
_destroy_result="$(_post "" "$_rest_endpoint/v3/oauth/token.json" "" "DELETE" "application/json")"
_debug _destroy_result "$_destroy_result"
fi
_info "Uploading certificate and key to CleverReach" _info "Uploading certificate and key to CleverReach"
_certData="{\"cert\":\"$(_json_encode <"$_cfullchain")\", \"key\":\"$(_json_encode <"$_ckey")\"}" _certData="{\"cert\":\"$(_json_encode <"$_cfullchain")\", \"key\":\"$(_json_encode <"$_ckey")\"}"
export _H1="Authorization: Bearer ${_access_token}" export _H1="Authorization: Bearer ${_access_token}"
_add_cert_result="$(_post "$_certData" "https://rest.cleverreach.com/v3/ssl" "" "POST" "application/json")" _add_cert_result="$(_post "$_certData" "$_rest_endpoint/v3/ssl" "" "POST" "application/json")"
_debug "Destroying token at CleverReach" if [ -z "${DEPLOY_CLEVERREACH_SUBCLIENT_ID}" ]; then
_post "" "https://rest.cleverreach.com/v3/oauth/token.json" "" "DELETE" "application/json" _info "Destroying token at CleverReach, as it not needed anymore"
_destroy_result="$(_post "" "$_rest_endpoint/v3/oauth/token.json" "" "DELETE" "application/json")"
_debug _destroy_result "$_destroy_result"
fi
if ! echo "$_add_cert_result" | grep '"error":' >/dev/null; then if ! echo "$_add_cert_result" | grep '"error":' >/dev/null; then
_info "Uploaded certificate successfully" _info "Uploaded certificate successfully"
......
#!/usr/bin/env sh
# Here is a script to deploy cert to hashicorp consul using curl
# (https://www.consul.io/)
#
# it requires following environment variables:
#
# CONSUL_PREFIX - this contains the prefix path in consul
# CONSUL_HTTP_ADDR - consul requires this to find your consul server
#
# additionally, you need to ensure that CONSUL_HTTP_TOKEN is available
# to access the consul server
#returns 0 means success, otherwise error.
######## Public functions #####################
#domain keyfile certfile cafile fullchain
consul_deploy() {
_cdomain="$1"
_ckey="$2"
_ccert="$3"
_cca="$4"
_cfullchain="$5"
_debug _cdomain "$_cdomain"
_debug _ckey "$_ckey"
_debug _ccert "$_ccert"
_debug _cca "$_cca"
_debug _cfullchain "$_cfullchain"
# validate required env vars
_getdeployconf CONSUL_PREFIX
if [ -z "$CONSUL_PREFIX" ]; then
_err "CONSUL_PREFIX needs to be defined (contains prefix path in vault)"
return 1
fi
_savedeployconf CONSUL_PREFIX "$CONSUL_PREFIX"
_getdeployconf CONSUL_HTTP_ADDR
if [ -z "$CONSUL_HTTP_ADDR" ]; then
_err "CONSUL_HTTP_ADDR needs to be defined (contains consul connection address)"
return 1
fi
_savedeployconf CONSUL_HTTP_ADDR "$CONSUL_HTTP_ADDR"
CONSUL_CMD=$(command -v consul)
# force CLI, but the binary does not exist => error
if [ -n "$USE_CLI" ] && [ -z "$CONSUL_CMD" ]; then
_err "Cannot find the consul binary!"
return 1
fi
# use the CLI first
if [ -n "$USE_CLI" ] || [ -n "$CONSUL_CMD" ]; then
_info "Found consul binary, deploying with CLI"
consul_deploy_cli "$CONSUL_CMD" "$CONSUL_PREFIX"
else
_info "Did not find consul binary, deploying with API"
consul_deploy_api "$CONSUL_HTTP_ADDR" "$CONSUL_PREFIX" "$CONSUL_HTTP_TOKEN"
fi
}
consul_deploy_api() {
CONSUL_HTTP_ADDR="$1"
CONSUL_PREFIX="$2"
CONSUL_HTTP_TOKEN="$3"
URL="$CONSUL_HTTP_ADDR/v1/kv/$CONSUL_PREFIX"
export _H1="X-Consul-Token: $CONSUL_HTTP_TOKEN"
if [ -n "$FABIO" ]; then
_post "$(cat "$_cfullchain")" "$URL/${_cdomain}-cert.pem" '' "PUT" || return 1
_post "$(cat "$_ckey")" "$URL/${_cdomain}-key.pem" '' "PUT" || return 1
else
_post "$(cat "$_ccert")" "$URL/${_cdomain}/cert.pem" '' "PUT" || return 1
_post "$(cat "$_ckey")" "$URL/${_cdomain}/cert.key" '' "PUT" || return 1
_post "$(cat "$_cca")" "$URL/${_cdomain}/chain.pem" '' "PUT" || return 1
_post "$(cat "$_cfullchain")" "$URL/${_cdomain}/fullchain.pem" '' "PUT" || return 1
fi
}
consul_deploy_cli() {
CONSUL_CMD="$1"
CONSUL_PREFIX="$2"
if [ -n "$FABIO" ]; then
$CONSUL_CMD kv put "${CONSUL_PREFIX}/${_cdomain}-cert.pem" @"$_cfullchain" || return 1
$CONSUL_CMD kv put "${CONSUL_PREFIX}/${_cdomain}-key.pem" @"$_ckey" || return 1
else
$CONSUL_CMD kv put "${CONSUL_PREFIX}/${_cdomain}/cert.pem" value=@"$_ccert" || return 1
$CONSUL_CMD kv put "${CONSUL_PREFIX}/${_cdomain}/cert.key" value=@"$_ckey" || return 1
$CONSUL_CMD kv put "${CONSUL_PREFIX}/${_cdomain}/chain.pem" value=@"$_cca" || return 1
$CONSUL_CMD kv put "${CONSUL_PREFIX}/${_cdomain}/fullchain.pem" value=@"$_cfullchain" || return 1
fi
}
...@@ -56,9 +56,9 @@ gcore_cdn_deploy() { ...@@ -56,9 +56,9 @@ gcore_cdn_deploy() {
_request="{\"username\":\"$Le_Deploy_gcore_cdn_username\",\"password\":\"$Le_Deploy_gcore_cdn_password\"}" _request="{\"username\":\"$Le_Deploy_gcore_cdn_username\",\"password\":\"$Le_Deploy_gcore_cdn_password\"}"
_debug _request "$_request" _debug _request "$_request"
export _H1="Content-Type:application/json" export _H1="Content-Type:application/json"
_response=$(_post "$_request" "https://api.gcdn.co/auth/signin") _response=$(_post "$_request" "https://api.gcdn.co/auth/jwt/login")
_debug _response "$_response" _debug _response "$_response"
_regex=".*\"token\":\"\([-._0-9A-Za-z]*\)\".*$" _regex=".*\"access\":\"\([-._0-9A-Za-z]*\)\".*$"
_debug _regex "$_regex" _debug _regex "$_regex"
_token=$(echo "$_response" | sed -n "s/$_regex/\1/p") _token=$(echo "$_response" | sed -n "s/$_regex/\1/p")
_debug _token "$_token" _debug _token "$_token"
...@@ -72,12 +72,15 @@ gcore_cdn_deploy() { ...@@ -72,12 +72,15 @@ gcore_cdn_deploy() {
export _H2="Authorization:Token $_token" export _H2="Authorization:Token $_token"
_response=$(_get "https://api.gcdn.co/resources") _response=$(_get "https://api.gcdn.co/resources")
_debug _response "$_response" _debug _response "$_response"
_regex=".*(\"id\".*?\"cname\":\"$_cdomain\".*?})" _regex="\"primary_resource\":null},"
_debug _regex "$_regex"
_response=$(echo "$_response" | sed "s/$_regex/$_regex\n/g")
_debug _response "$_response"
_regex="^.*\"cname\":\"$_cdomain\".*$" _regex="^.*\"cname\":\"$_cdomain\".*$"
_debug _regex "$_regex" _debug _regex "$_regex"
_resource=$(echo "$_response" | sed 's/},{/},\n{/g' | _egrep_o "$_regex") _resource=$(echo "$_response" | _egrep_o "$_regex")
_debug _resource "$_resource" _debug _resource "$_resource"
_regex=".*\"id\":\([0-9]*\).*\"rules\".*$" _regex=".*\"id\":\([0-9]*\).*$"
_debug _regex "$_regex" _debug _regex "$_regex"
_resourceId=$(echo "$_resource" | sed -n "s/$_regex/\1/p") _resourceId=$(echo "$_resource" | sed -n "s/$_regex/\1/p")
_debug _resourceId "$_resourceId" _debug _resourceId "$_resourceId"
......
...@@ -54,11 +54,6 @@ haproxy_deploy() { ...@@ -54,11 +54,6 @@ haproxy_deploy() {
DEPLOY_HAPROXY_ISSUER_DEFAULT="no" DEPLOY_HAPROXY_ISSUER_DEFAULT="no"
DEPLOY_HAPROXY_RELOAD_DEFAULT="true" DEPLOY_HAPROXY_RELOAD_DEFAULT="true"
if [ -f "${DOMAIN_CONF}" ]; then
# shellcheck disable=SC1090
. "${DOMAIN_CONF}"
fi
_debug _cdomain "${_cdomain}" _debug _cdomain "${_cdomain}"
_debug _ckey "${_ckey}" _debug _ckey "${_ckey}"
_debug _ccert "${_ccert}" _debug _ccert "${_ccert}"
...@@ -66,6 +61,8 @@ haproxy_deploy() { ...@@ -66,6 +61,8 @@ haproxy_deploy() {
_debug _cfullchain "${_cfullchain}" _debug _cfullchain "${_cfullchain}"
# PEM_PATH is optional. If not provided then assume "${DEPLOY_HAPROXY_PEM_PATH_DEFAULT}" # PEM_PATH is optional. If not provided then assume "${DEPLOY_HAPROXY_PEM_PATH_DEFAULT}"
_getdeployconf DEPLOY_HAPROXY_PEM_PATH
_debug2 DEPLOY_HAPROXY_PEM_PATH "${DEPLOY_HAPROXY_PEM_PATH}"
if [ -n "${DEPLOY_HAPROXY_PEM_PATH}" ]; then if [ -n "${DEPLOY_HAPROXY_PEM_PATH}" ]; then
Le_Deploy_haproxy_pem_path="${DEPLOY_HAPROXY_PEM_PATH}" Le_Deploy_haproxy_pem_path="${DEPLOY_HAPROXY_PEM_PATH}"
_savedomainconf Le_Deploy_haproxy_pem_path "${Le_Deploy_haproxy_pem_path}" _savedomainconf Le_Deploy_haproxy_pem_path "${Le_Deploy_haproxy_pem_path}"
...@@ -82,6 +79,8 @@ haproxy_deploy() { ...@@ -82,6 +79,8 @@ haproxy_deploy() {
fi fi
# PEM_NAME is optional. If not provided then assume "${DEPLOY_HAPROXY_PEM_NAME_DEFAULT}" # PEM_NAME is optional. If not provided then assume "${DEPLOY_HAPROXY_PEM_NAME_DEFAULT}"
_getdeployconf DEPLOY_HAPROXY_PEM_NAME
_debug2 DEPLOY_HAPROXY_PEM_NAME "${DEPLOY_HAPROXY_PEM_NAME}"
if [ -n "${DEPLOY_HAPROXY_PEM_NAME}" ]; then if [ -n "${DEPLOY_HAPROXY_PEM_NAME}" ]; then
Le_Deploy_haproxy_pem_name="${DEPLOY_HAPROXY_PEM_NAME}" Le_Deploy_haproxy_pem_name="${DEPLOY_HAPROXY_PEM_NAME}"
_savedomainconf Le_Deploy_haproxy_pem_name "${Le_Deploy_haproxy_pem_name}" _savedomainconf Le_Deploy_haproxy_pem_name "${Le_Deploy_haproxy_pem_name}"
...@@ -90,6 +89,8 @@ haproxy_deploy() { ...@@ -90,6 +89,8 @@ haproxy_deploy() {
fi fi
# BUNDLE is optional. If not provided then assume "${DEPLOY_HAPROXY_BUNDLE_DEFAULT}" # BUNDLE is optional. If not provided then assume "${DEPLOY_HAPROXY_BUNDLE_DEFAULT}"
_getdeployconf DEPLOY_HAPROXY_BUNDLE
_debug2 DEPLOY_HAPROXY_BUNDLE "${DEPLOY_HAPROXY_BUNDLE}"
if [ -n "${DEPLOY_HAPROXY_BUNDLE}" ]; then if [ -n "${DEPLOY_HAPROXY_BUNDLE}" ]; then
Le_Deploy_haproxy_bundle="${DEPLOY_HAPROXY_BUNDLE}" Le_Deploy_haproxy_bundle="${DEPLOY_HAPROXY_BUNDLE}"
_savedomainconf Le_Deploy_haproxy_bundle "${Le_Deploy_haproxy_bundle}" _savedomainconf Le_Deploy_haproxy_bundle "${Le_Deploy_haproxy_bundle}"
...@@ -98,6 +99,8 @@ haproxy_deploy() { ...@@ -98,6 +99,8 @@ haproxy_deploy() {
fi fi
# ISSUER is optional. If not provided then assume "${DEPLOY_HAPROXY_ISSUER_DEFAULT}" # ISSUER is optional. If not provided then assume "${DEPLOY_HAPROXY_ISSUER_DEFAULT}"
_getdeployconf DEPLOY_HAPROXY_ISSUER
_debug2 DEPLOY_HAPROXY_ISSUER "${DEPLOY_HAPROXY_ISSUER}"
if [ -n "${DEPLOY_HAPROXY_ISSUER}" ]; then if [ -n "${DEPLOY_HAPROXY_ISSUER}" ]; then
Le_Deploy_haproxy_issuer="${DEPLOY_HAPROXY_ISSUER}" Le_Deploy_haproxy_issuer="${DEPLOY_HAPROXY_ISSUER}"
_savedomainconf Le_Deploy_haproxy_issuer "${Le_Deploy_haproxy_issuer}" _savedomainconf Le_Deploy_haproxy_issuer "${Le_Deploy_haproxy_issuer}"
...@@ -106,6 +109,8 @@ haproxy_deploy() { ...@@ -106,6 +109,8 @@ haproxy_deploy() {
fi fi
# RELOAD is optional. If not provided then assume "${DEPLOY_HAPROXY_RELOAD_DEFAULT}" # RELOAD is optional. If not provided then assume "${DEPLOY_HAPROXY_RELOAD_DEFAULT}"
_getdeployconf DEPLOY_HAPROXY_RELOAD
_debug2 DEPLOY_HAPROXY_RELOAD "${DEPLOY_HAPROXY_RELOAD}"
if [ -n "${DEPLOY_HAPROXY_RELOAD}" ]; then if [ -n "${DEPLOY_HAPROXY_RELOAD}" ]; then
Le_Deploy_haproxy_reload="${DEPLOY_HAPROXY_RELOAD}" Le_Deploy_haproxy_reload="${DEPLOY_HAPROXY_RELOAD}"
_savedomainconf Le_Deploy_haproxy_reload "${Le_Deploy_haproxy_reload}" _savedomainconf Le_Deploy_haproxy_reload "${Le_Deploy_haproxy_reload}"
...@@ -190,7 +195,7 @@ haproxy_deploy() { ...@@ -190,7 +195,7 @@ haproxy_deploy() {
_info "Updating OCSP stapling info" _info "Updating OCSP stapling info"
_debug _ocsp "${_ocsp}" _debug _ocsp "${_ocsp}"
_info "Extracting OCSP URL" _info "Extracting OCSP URL"
_ocsp_url=$(openssl x509 -noout -ocsp_uri -in "${_pem}") _ocsp_url=$(${ACME_OPENSSL_BIN:-openssl} x509 -noout -ocsp_uri -in "${_pem}")
_debug _ocsp_url "${_ocsp_url}" _debug _ocsp_url "${_ocsp_url}"
# Only process OCSP if URL was present # Only process OCSP if URL was present
...@@ -203,9 +208,9 @@ haproxy_deploy() { ...@@ -203,9 +208,9 @@ haproxy_deploy() {
# Only process the certificate if we have a .issuer file # Only process the certificate if we have a .issuer file
if [ -r "${_issuer}" ]; then if [ -r "${_issuer}" ]; then
# Check if issuer cert is also a root CA cert # Check if issuer cert is also a root CA cert
_subjectdn=$(openssl x509 -in "${_issuer}" -subject -noout | cut -d'/' -f2,3,4,5,6,7,8,9,10) _subjectdn=$(${ACME_OPENSSL_BIN:-openssl} x509 -in "${_issuer}" -subject -noout | cut -d'/' -f2,3,4,5,6,7,8,9,10)
_debug _subjectdn "${_subjectdn}" _debug _subjectdn "${_subjectdn}"
_issuerdn=$(openssl x509 -in "${_issuer}" -issuer -noout | cut -d'/' -f2,3,4,5,6,7,8,9,10) _issuerdn=$(${ACME_OPENSSL_BIN:-openssl} x509 -in "${_issuer}" -issuer -noout | cut -d'/' -f2,3,4,5,6,7,8,9,10)
_debug _issuerdn "${_issuerdn}" _debug _issuerdn "${_issuerdn}"
_info "Requesting OCSP response" _info "Requesting OCSP response"
# If the issuer is a CA cert then our command line has "-CAfile" added # If the issuer is a CA cert then our command line has "-CAfile" added
...@@ -216,7 +221,7 @@ haproxy_deploy() { ...@@ -216,7 +221,7 @@ haproxy_deploy() {
fi fi
_debug _cafile_argument "${_cafile_argument}" _debug _cafile_argument "${_cafile_argument}"
# if OpenSSL/LibreSSL is v1.1 or above, the format for the -header option has changed # if OpenSSL/LibreSSL is v1.1 or above, the format for the -header option has changed
_openssl_version=$(openssl version | cut -d' ' -f2) _openssl_version=$(${ACME_OPENSSL_BIN:-openssl} version | cut -d' ' -f2)
_debug _openssl_version "${_openssl_version}" _debug _openssl_version "${_openssl_version}"
_openssl_major=$(echo "${_openssl_version}" | cut -d '.' -f1) _openssl_major=$(echo "${_openssl_version}" | cut -d '.' -f1)
_openssl_minor=$(echo "${_openssl_version}" | cut -d '.' -f2) _openssl_minor=$(echo "${_openssl_version}" | cut -d '.' -f2)
...@@ -226,7 +231,7 @@ haproxy_deploy() { ...@@ -226,7 +231,7 @@ haproxy_deploy() {
_header_sep=" " _header_sep=" "
fi fi
# Request the OCSP response from the issuer and store it # Request the OCSP response from the issuer and store it
_openssl_ocsp_cmd="openssl ocsp \ _openssl_ocsp_cmd="${ACME_OPENSSL_BIN:-openssl} ocsp \
-issuer \"${_issuer}\" \ -issuer \"${_issuer}\" \
-cert \"${_pem}\" \ -cert \"${_pem}\" \
-url \"${_ocsp_url}\" \ -url \"${_ocsp_url}\" \
......
...@@ -45,7 +45,7 @@ kong_deploy() { ...@@ -45,7 +45,7 @@ kong_deploy() {
#Generate data for request (Multipart/form-data with mixed content) #Generate data for request (Multipart/form-data with mixed content)
if [ -z "$ssl_uuid" ]; then if [ -z "$ssl_uuid" ]; then
#set sni to domain #set sni to domain
content="--$delim${nl}Content-Disposition: form-data; name=\"snis\"${nl}${nl}$_cdomain" content="--$delim${nl}Content-Disposition: form-data; name=\"snis[]\"${nl}${nl}$_cdomain"
fi fi
#add key #add key
content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"key\"; filename=\"$(basename "$_ckey")\"${nl}Content-Type: application/octet-stream${nl}${nl}$(cat "$_ckey")" content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"key\"; filename=\"$(basename "$_ckey")\"${nl}Content-Type: application/octet-stream${nl}${nl}$(cat "$_ckey")"
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment