mirror of
				https://github.com/hiskang/acme.sh
				synced 2025-11-04 12:28:12 +00:00 
			
		
		
		
	Merge branch 'dev' into dnsapi/dns_dnsever
This commit is contained in:
		
						commit
						b0dfd5f94d
					
				
							
								
								
									
										11
									
								
								.travis.yml
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								.travis.yml
									
									
									
									
									
								
							@ -13,12 +13,6 @@ env:
 | 
				
			|||||||
  global:
 | 
					  global:
 | 
				
			||||||
    - SHFMT_URL=https://github.com/mvdan/sh/releases/download/v0.4.0/shfmt_v0.4.0_linux_amd64
 | 
					    - SHFMT_URL=https://github.com/mvdan/sh/releases/download/v0.4.0/shfmt_v0.4.0_linux_amd64
 | 
				
			||||||
 | 
					
 | 
				
			||||||
addons:
 | 
					 | 
				
			||||||
  apt:
 | 
					 | 
				
			||||||
    sources:
 | 
					 | 
				
			||||||
    - debian-sid    # Grab shellcheck from the Debian repo (o_O)
 | 
					 | 
				
			||||||
    packages:
 | 
					 | 
				
			||||||
    - shellcheck
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
install:
 | 
					install:
 | 
				
			||||||
  - if [ "$TRAVIS_OS_NAME" = 'osx' ]; then
 | 
					  - if [ "$TRAVIS_OS_NAME" = 'osx' ]; then
 | 
				
			||||||
@ -29,9 +23,7 @@ install:
 | 
				
			|||||||
script:
 | 
					script:
 | 
				
			||||||
  - echo "NGROK_TOKEN=$(echo "$NGROK_TOKEN" | wc -c)"
 | 
					  - echo "NGROK_TOKEN=$(echo "$NGROK_TOKEN" | wc -c)"
 | 
				
			||||||
  - command -V openssl && openssl version
 | 
					  - command -V openssl && openssl version
 | 
				
			||||||
  - if [ "$TRAVIS_OS_NAME" = "linux" ]; then curl -sSL $SHFMT_URL -o ~/shfmt ; fi
 | 
					  - if [ "$TRAVIS_OS_NAME" = "linux" ]; then curl -sSL $SHFMT_URL -o ~/shfmt && chmod +x ~/shfmt && ~/shfmt -l -w -i 2 . ; fi
 | 
				
			||||||
  - if [ "$TRAVIS_OS_NAME" = "linux" ]; then chmod +x ~/shfmt ; fi
 | 
					 | 
				
			||||||
  - if [ "$TRAVIS_OS_NAME" = "linux" ]; then ~/shfmt -l -w -i 2 . ; fi
 | 
					 | 
				
			||||||
  - if [ "$TRAVIS_OS_NAME" = "linux" ]; then git diff --exit-code && echo "shfmt OK" ; fi
 | 
					  - if [ "$TRAVIS_OS_NAME" = "linux" ]; then git diff --exit-code && echo "shfmt OK" ; fi
 | 
				
			||||||
  - if [ "$TRAVIS_OS_NAME" = "linux" ]; then shellcheck -V ; fi
 | 
					  - if [ "$TRAVIS_OS_NAME" = "linux" ]; then shellcheck -V ; fi
 | 
				
			||||||
  - if [ "$TRAVIS_OS_NAME" = "linux" ]; then shellcheck -e SC2181 **/*.sh && echo "shellcheck OK" ; fi
 | 
					  - if [ "$TRAVIS_OS_NAME" = "linux" ]; then shellcheck -e SC2181 **/*.sh && echo "shellcheck OK" ; fi
 | 
				
			||||||
@ -40,7 +32,6 @@ script:
 | 
				
			|||||||
  - if [ "$TRAVIS_OS_NAME" = "linux" -a "$NGROK_TOKEN" ]; then sudo TEST_LOCAL="$TEST_LOCAL" NGROK_TOKEN="$NGROK_TOKEN" ./rundocker.sh testplat ubuntu:latest ; fi
 | 
					  - if [ "$TRAVIS_OS_NAME" = "linux" -a "$NGROK_TOKEN" ]; then sudo TEST_LOCAL="$TEST_LOCAL" NGROK_TOKEN="$NGROK_TOKEN" ./rundocker.sh testplat ubuntu:latest ; fi
 | 
				
			||||||
  - if [ "$TRAVIS_OS_NAME" = "osx" -a "$NGROK_TOKEN" ]; then sudo TEST_LOCAL="$TEST_LOCAL" NGROK_TOKEN="$NGROK_TOKEN" ACME_OPENSSL_BIN="$ACME_OPENSSL_BIN" ./letest.sh ; fi
 | 
					  - if [ "$TRAVIS_OS_NAME" = "osx" -a "$NGROK_TOKEN" ]; then sudo TEST_LOCAL="$TEST_LOCAL" NGROK_TOKEN="$NGROK_TOKEN" ACME_OPENSSL_BIN="$ACME_OPENSSL_BIN" ./letest.sh ; fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
matrix:
 | 
					matrix:
 | 
				
			||||||
  fast_finish: true
 | 
					  fast_finish: true
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
 | 
				
			|||||||
@ -3,6 +3,7 @@ FROM alpine:3.6
 | 
				
			|||||||
RUN apk update -f \
 | 
					RUN apk update -f \
 | 
				
			||||||
  && apk --no-cache add -f \
 | 
					  && apk --no-cache add -f \
 | 
				
			||||||
  openssl \
 | 
					  openssl \
 | 
				
			||||||
 | 
					  coreutils \
 | 
				
			||||||
  curl \
 | 
					  curl \
 | 
				
			||||||
  socat \
 | 
					  socat \
 | 
				
			||||||
  && rm -rf /var/cache/apk/*
 | 
					  && rm -rf /var/cache/apk/*
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										61
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										61
									
								
								README.md
									
									
									
									
									
								
							@ -37,6 +37,8 @@ Twitter: [@neilpangxa](https://twitter.com/neilpangxa)
 | 
				
			|||||||
- [splynx](https://forum.splynx.com/t/free-ssl-cert-for-splynx-lets-encrypt/297)
 | 
					- [splynx](https://forum.splynx.com/t/free-ssl-cert-for-splynx-lets-encrypt/297)
 | 
				
			||||||
- [archlinux](https://aur.archlinux.org/packages/acme.sh-git/)
 | 
					- [archlinux](https://aur.archlinux.org/packages/acme.sh-git/)
 | 
				
			||||||
- [opnsense.org](https://github.com/opnsense/plugins/tree/master/security/acme-client/src/opnsense/scripts/OPNsense/AcmeClient)
 | 
					- [opnsense.org](https://github.com/opnsense/plugins/tree/master/security/acme-client/src/opnsense/scripts/OPNsense/AcmeClient)
 | 
				
			||||||
 | 
					- [CentOS Web Panel](http://centos-webpanel.com/)
 | 
				
			||||||
 | 
					- [lnmp.org](https://lnmp.org/)
 | 
				
			||||||
- [more...](https://github.com/Neilpang/acme.sh/wiki/Blogs-and-tutorials)
 | 
					- [more...](https://github.com/Neilpang/acme.sh/wiki/Blogs-and-tutorials)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Tested OS
 | 
					# Tested OS
 | 
				
			||||||
@ -220,22 +222,7 @@ acme.sh --issue --standalone -d example.com -d www.example.com -d cp.example.com
 | 
				
			|||||||
More examples: https://github.com/Neilpang/acme.sh/wiki/How-to-issue-a-cert
 | 
					More examples: https://github.com/Neilpang/acme.sh/wiki/How-to-issue-a-cert
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# 5. Use Standalone TLS server to issue cert
 | 
					# 5. Use Apache mode
 | 
				
			||||||
 | 
					 | 
				
			||||||
**(requires you to be root/sudoer or have permission to listen on port 443 (TCP))**
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
acme.sh supports `tls-sni-01` validation.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Port `443` (TCP) **MUST** be free to listen on, otherwise you will be prompted to free it and try again.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
```bash
 | 
					 | 
				
			||||||
acme.sh --issue --tls -d example.com -d www.example.com -d cp.example.com
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
More examples: https://github.com/Neilpang/acme.sh/wiki/How-to-issue-a-cert
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# 6. Use Apache mode
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
**(requires you to be root/sudoer, since it is required to interact with Apache server)**
 | 
					**(requires you to be root/sudoer, since it is required to interact with Apache server)**
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -255,7 +242,7 @@ We don't want to mess your apache server, don't worry.**
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
More examples: https://github.com/Neilpang/acme.sh/wiki/How-to-issue-a-cert
 | 
					More examples: https://github.com/Neilpang/acme.sh/wiki/How-to-issue-a-cert
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# 7. Use Nginx mode
 | 
					# 6. Use Nginx mode
 | 
				
			||||||
 | 
					
 | 
				
			||||||
**(requires you to be root/sudoer, since it is required to interact with Nginx server)**
 | 
					**(requires you to be root/sudoer, since it is required to interact with Nginx server)**
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -279,7 +266,7 @@ We don't want to mess your nginx server, don't worry.**
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
More examples: https://github.com/Neilpang/acme.sh/wiki/How-to-issue-a-cert
 | 
					More examples: https://github.com/Neilpang/acme.sh/wiki/How-to-issue-a-cert
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# 8. Automatic DNS API integration
 | 
					# 7. Automatic DNS API integration
 | 
				
			||||||
 | 
					
 | 
				
			||||||
If your DNS provider supports API access, we can use that API to automatically issue the certs.
 | 
					If your DNS provider supports API access, we can use that API to automatically issue the certs.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -327,14 +314,14 @@ You don't have to do anything manually!
 | 
				
			|||||||
1. selectel.com(selectel.ru) DNS API
 | 
					1. selectel.com(selectel.ru) DNS API
 | 
				
			||||||
1. zonomi.com DNS API
 | 
					1. zonomi.com DNS API
 | 
				
			||||||
1. DreamHost.com API
 | 
					1. DreamHost.com API
 | 
				
			||||||
 | 
					1. DirectAdmin API
 | 
				
			||||||
 | 
					1. KingHost (https://www.kinghost.com.br/)
 | 
				
			||||||
 | 
					1. Zilore (https://zilore.com)
 | 
				
			||||||
 | 
					1. Loopia.se API
 | 
				
			||||||
 | 
					1. acme-dns (https://github.com/joohoi/acme-dns)
 | 
				
			||||||
 | 
					1. TELE3 (https://www.tele3.cz)
 | 
				
			||||||
1. DNSEver(https://www.dnsever.com)
 | 
					1. DNSEver(https://www.dnsever.com)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
And: 
 | 
					And: 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
**lexicon DNS API: https://github.com/Neilpang/acme.sh/wiki/How-to-use-lexicon-dns-api
 | 
					**lexicon DNS API: https://github.com/Neilpang/acme.sh/wiki/How-to-use-lexicon-dns-api
 | 
				
			||||||
@ -347,7 +334,9 @@ If your DNS provider is not on the supported list above, you can write your own
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
For more details: [How to use DNS API](dnsapi)
 | 
					For more details: [How to use DNS API](dnsapi)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# 9. Use DNS manual mode:
 | 
					# 8. Use DNS manual mode:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					See: https://github.com/Neilpang/acme.sh/wiki/dns-manual-mode first.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
If your dns provider doesn't support any api access, you can add the txt record by your hand.
 | 
					If your dns provider doesn't support any api access, you can add the txt record by your hand.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -381,7 +370,7 @@ Ok, it's done.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
**Please use dns api mode instead.**
 | 
					**Please use dns api mode instead.**
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# 10. Issue ECC certificates
 | 
					# 9. Issue ECC certificates
 | 
				
			||||||
 | 
					
 | 
				
			||||||
`Let's Encrypt` can now issue **ECDSA** certificates.
 | 
					`Let's Encrypt` can now issue **ECDSA** certificates.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -413,17 +402,17 @@ Valid values are:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# 11. Issue Wildcard certificates
 | 
					# 10. Issue Wildcard certificates
 | 
				
			||||||
 | 
					
 | 
				
			||||||
It's simple, just give a wildcard domain as the `-d` parameter.
 | 
					It's simple, just give a wildcard domain as the `-d` parameter.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
```sh
 | 
					```sh
 | 
				
			||||||
acme.sh  --issue -d example.com  -d *.example.com  --dns dns_cf
 | 
					acme.sh  --issue -d example.com  -d '*.example.com'  --dns dns_cf
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# 12. How to renew the certs
 | 
					# 11. How to renew the certs
 | 
				
			||||||
 | 
					
 | 
				
			||||||
No, you don't need to renew the certs manually. All the certs will be renewed automatically every **60** days.
 | 
					No, you don't need to renew the certs manually. All the certs will be renewed automatically every **60** days.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -440,7 +429,7 @@ acme.sh --renew -d example.com --force --ecc
 | 
				
			|||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# 13. How to stop cert renewal
 | 
					# 12. How to stop cert renewal
 | 
				
			||||||
 | 
					
 | 
				
			||||||
To stop renewal of a cert, you can execute the following to remove the cert from the renewal list:
 | 
					To stop renewal of a cert, you can execute the following to remove the cert from the renewal list:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -453,7 +442,7 @@ The cert/key file is not removed from the disk.
 | 
				
			|||||||
You can remove the respective directory (e.g. `~/.acme.sh/example.com`) by yourself.
 | 
					You can remove the respective directory (e.g. `~/.acme.sh/example.com`) by yourself.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# 14. How to upgrade `acme.sh`
 | 
					# 13. How to upgrade `acme.sh`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
acme.sh is in constant development, so it's strongly recommended to use the latest code.
 | 
					acme.sh is in constant development, so it's strongly recommended to use the latest code.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -478,25 +467,25 @@ acme.sh --upgrade --auto-upgrade 0
 | 
				
			|||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# 15. Issue a cert from an existing CSR
 | 
					# 14. Issue a cert from an existing CSR
 | 
				
			||||||
 | 
					
 | 
				
			||||||
https://github.com/Neilpang/acme.sh/wiki/Issue-a-cert-from-existing-CSR
 | 
					https://github.com/Neilpang/acme.sh/wiki/Issue-a-cert-from-existing-CSR
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# 16. Under the Hood
 | 
					# 15. Under the Hood
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Speak ACME language using shell, directly to "Let's Encrypt".
 | 
					Speak ACME language using shell, directly to "Let's Encrypt".
 | 
				
			||||||
 | 
					
 | 
				
			||||||
TODO:
 | 
					TODO:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# 17. Acknowledgments
 | 
					# 16. Acknowledgments
 | 
				
			||||||
 | 
					
 | 
				
			||||||
1. Acme-tiny: https://github.com/diafygi/acme-tiny
 | 
					1. Acme-tiny: https://github.com/diafygi/acme-tiny
 | 
				
			||||||
2. ACME protocol: https://github.com/ietf-wg-acme/acme
 | 
					2. ACME protocol: https://github.com/ietf-wg-acme/acme
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# 18. License & Others
 | 
					# 17. License & Others
 | 
				
			||||||
 | 
					
 | 
				
			||||||
License is GPLv3
 | 
					License is GPLv3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -505,7 +494,7 @@ Please Star and Fork me.
 | 
				
			|||||||
[Issues](https://github.com/Neilpang/acme.sh/issues) and [pull requests](https://github.com/Neilpang/acme.sh/pulls) are welcome.
 | 
					[Issues](https://github.com/Neilpang/acme.sh/issues) and [pull requests](https://github.com/Neilpang/acme.sh/pulls) are welcome.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# 19. Donate
 | 
					# 18. Donate
 | 
				
			||||||
Your donation makes **acme.sh** better:
 | 
					Your donation makes **acme.sh** better:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
1. PayPal/Alipay(支付宝)/Wechat(微信): [https://donate.acme.sh/](https://donate.acme.sh/)
 | 
					1. PayPal/Alipay(支付宝)/Wechat(微信): [https://donate.acme.sh/](https://donate.acme.sh/)
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										234
									
								
								acme.sh
									
									
									
									
									
								
							
							
						
						
									
										234
									
								
								acme.sh
									
									
									
									
									
								
							@ -1,6 +1,6 @@
 | 
				
			|||||||
#!/usr/bin/env sh
 | 
					#!/usr/bin/env sh
 | 
				
			||||||
 | 
					
 | 
				
			||||||
VER=2.7.7
 | 
					VER=2.7.9
 | 
				
			||||||
 | 
					
 | 
				
			||||||
PROJECT_NAME="acme.sh"
 | 
					PROJECT_NAME="acme.sh"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -47,6 +47,7 @@ DEFAULT_DNS_SLEEP=120
 | 
				
			|||||||
NO_VALUE="no"
 | 
					NO_VALUE="no"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
W_TLS="tls"
 | 
					W_TLS="tls"
 | 
				
			||||||
 | 
					W_DNS="dns"
 | 
				
			||||||
DNS_ALIAS_PREFIX="="
 | 
					DNS_ALIAS_PREFIX="="
 | 
				
			||||||
 | 
					
 | 
				
			||||||
MODE_STATELESS="stateless"
 | 
					MODE_STATELESS="stateless"
 | 
				
			||||||
@ -63,6 +64,7 @@ END_CSR="-----END CERTIFICATE REQUEST-----"
 | 
				
			|||||||
BEGIN_CERT="-----BEGIN CERTIFICATE-----"
 | 
					BEGIN_CERT="-----BEGIN CERTIFICATE-----"
 | 
				
			||||||
END_CERT="-----END CERTIFICATE-----"
 | 
					END_CERT="-----END CERTIFICATE-----"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					CONTENT_TYPE_JSON="application/jose+json"
 | 
				
			||||||
RENEW_SKIP=2
 | 
					RENEW_SKIP=2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ECC_SEP="_"
 | 
					ECC_SEP="_"
 | 
				
			||||||
@ -108,31 +110,35 @@ _STATELESS_WIKI="https://github.com/Neilpang/acme.sh/wiki/Stateless-Mode"
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
_DNS_ALIAS_WIKI="https://github.com/Neilpang/acme.sh/wiki/DNS-alias-mode"
 | 
					_DNS_ALIAS_WIKI="https://github.com/Neilpang/acme.sh/wiki/DNS-alias-mode"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					_DNS_MANUAL_WIKI="https://github.com/Neilpang/acme.sh/wiki/dns-manual-mode"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
_DNS_MANUAL_ERR="The dns manual mode can not renew automatically, you must issue it again manually. You'd better use the other modes instead."
 | 
					_DNS_MANUAL_ERR="The dns manual mode can not renew automatically, you must issue it again manually. You'd better use the other modes instead."
 | 
				
			||||||
 | 
					
 | 
				
			||||||
_DNS_MANUAL_WARN="It seems that you are using dns manual mode. please take care: $_DNS_MANUAL_ERR"
 | 
					_DNS_MANUAL_WARN="It seems that you are using dns manual mode. please take care: $_DNS_MANUAL_ERR"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					_DNS_MANUAL_ERROR="It seems that you are using dns manual mode. Read this link first: $_DNS_MANUAL_WIKI"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
__INTERACTIVE=""
 | 
					__INTERACTIVE=""
 | 
				
			||||||
if [ -t 1 ]; then
 | 
					if [ -t 1 ]; then
 | 
				
			||||||
  __INTERACTIVE="1"
 | 
					  __INTERACTIVE="1"
 | 
				
			||||||
fi
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
__green() {
 | 
					__green() {
 | 
				
			||||||
  if [ "$__INTERACTIVE${ACME_NO_COLOR}" = "1" ]; then
 | 
					  if [ "$__INTERACTIVE${ACME_NO_COLOR}" = "1" -o "${ACME_FORCE_COLOR}" = "1" ]; then
 | 
				
			||||||
    printf '\033[1;31;32m'
 | 
					    printf '\033[1;31;32m'
 | 
				
			||||||
  fi
 | 
					  fi
 | 
				
			||||||
  printf -- "%b" "$1"
 | 
					  printf -- "%b" "$1"
 | 
				
			||||||
  if [ "$__INTERACTIVE${ACME_NO_COLOR}" = "1" ]; then
 | 
					  if [ "$__INTERACTIVE${ACME_NO_COLOR}" = "1" -o "${ACME_FORCE_COLOR}" = "1" ]; then
 | 
				
			||||||
    printf '\033[0m'
 | 
					    printf '\033[0m'
 | 
				
			||||||
  fi
 | 
					  fi
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
__red() {
 | 
					__red() {
 | 
				
			||||||
  if [ "$__INTERACTIVE${ACME_NO_COLOR}" = "1" ]; then
 | 
					  if [ "$__INTERACTIVE${ACME_NO_COLOR}" = "1" -o "${ACME_FORCE_COLOR}" = "1" ]; then
 | 
				
			||||||
    printf '\033[1;31;40m'
 | 
					    printf '\033[1;31;40m'
 | 
				
			||||||
  fi
 | 
					  fi
 | 
				
			||||||
  printf -- "%b" "$1"
 | 
					  printf -- "%b" "$1"
 | 
				
			||||||
  if [ "$__INTERACTIVE${ACME_NO_COLOR}" = "1" ]; then
 | 
					  if [ "$__INTERACTIVE${ACME_NO_COLOR}" = "1" -o "${ACME_FORCE_COLOR}" = "1" ]; then
 | 
				
			||||||
    printf '\033[0m'
 | 
					    printf '\033[0m'
 | 
				
			||||||
  fi
 | 
					  fi
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -848,6 +854,16 @@ _dbase64() {
 | 
				
			|||||||
  fi
 | 
					  fi
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#file
 | 
				
			||||||
 | 
					_checkcert() {
 | 
				
			||||||
 | 
					  _cf="$1"
 | 
				
			||||||
 | 
					  if [ "$DEBUG" ]; then
 | 
				
			||||||
 | 
					    openssl x509 -noout -text -in "$_cf"
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
 | 
					    openssl x509 -noout -text -in "$_cf" >/dev/null 2>&1
 | 
				
			||||||
 | 
					  fi
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#Usage: hashalg  [outputhex]
 | 
					#Usage: hashalg  [outputhex]
 | 
				
			||||||
#Output Base64-encoded digest
 | 
					#Output Base64-encoded digest
 | 
				
			||||||
_digest() {
 | 
					_digest() {
 | 
				
			||||||
@ -1591,12 +1607,13 @@ _inithttp() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# body  url [needbase64] [POST|PUT]
 | 
					# body  url [needbase64] [POST|PUT] [ContentType]
 | 
				
			||||||
_post() {
 | 
					_post() {
 | 
				
			||||||
  body="$1"
 | 
					  body="$1"
 | 
				
			||||||
  _post_url="$2"
 | 
					  _post_url="$2"
 | 
				
			||||||
  needbase64="$3"
 | 
					  needbase64="$3"
 | 
				
			||||||
  httpmethod="$4"
 | 
					  httpmethod="$4"
 | 
				
			||||||
 | 
					  _postContentType="$5"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if [ -z "$httpmethod" ]; then
 | 
					  if [ -z "$httpmethod" ]; then
 | 
				
			||||||
    httpmethod="POST"
 | 
					    httpmethod="POST"
 | 
				
			||||||
@ -1604,6 +1621,7 @@ _post() {
 | 
				
			|||||||
  _debug $httpmethod
 | 
					  _debug $httpmethod
 | 
				
			||||||
  _debug "_post_url" "$_post_url"
 | 
					  _debug "_post_url" "$_post_url"
 | 
				
			||||||
  _debug2 "body" "$body"
 | 
					  _debug2 "body" "$body"
 | 
				
			||||||
 | 
					  _debug2 "_postContentType" "$_postContentType"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  _inithttp
 | 
					  _inithttp
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1614,10 +1632,18 @@ _post() {
 | 
				
			|||||||
    fi
 | 
					    fi
 | 
				
			||||||
    _debug "_CURL" "$_CURL"
 | 
					    _debug "_CURL" "$_CURL"
 | 
				
			||||||
    if [ "$needbase64" ]; then
 | 
					    if [ "$needbase64" ]; then
 | 
				
			||||||
 | 
					      if [ "$_postContentType" ]; then
 | 
				
			||||||
 | 
					        response="$($_CURL --user-agent "$USER_AGENT" -X $httpmethod -H "Content-Type: $_postContentType" -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" --data "$body" "$_post_url" | _base64)"
 | 
				
			||||||
 | 
					      else
 | 
				
			||||||
        response="$($_CURL --user-agent "$USER_AGENT" -X $httpmethod -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" --data "$body" "$_post_url" | _base64)"
 | 
					        response="$($_CURL --user-agent "$USER_AGENT" -X $httpmethod -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" --data "$body" "$_post_url" | _base64)"
 | 
				
			||||||
 | 
					      fi
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					      if [ "$_postContentType" ]; then
 | 
				
			||||||
 | 
					        response="$($_CURL --user-agent "$USER_AGENT" -X $httpmethod -H "Content-Type: $_postContentType" -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" --data "$body" "$_post_url")"
 | 
				
			||||||
      else
 | 
					      else
 | 
				
			||||||
        response="$($_CURL --user-agent "$USER_AGENT" -X $httpmethod -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" --data "$body" "$_post_url")"
 | 
					        response="$($_CURL --user-agent "$USER_AGENT" -X $httpmethod -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" --data "$body" "$_post_url")"
 | 
				
			||||||
      fi
 | 
					      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"
 | 
					      _err "Please refer to https://curl.haxx.se/libcurl/c/libcurl-errors.html for error code: $_ret"
 | 
				
			||||||
@ -1634,17 +1660,33 @@ _post() {
 | 
				
			|||||||
    _debug "_WGET" "$_WGET"
 | 
					    _debug "_WGET" "$_WGET"
 | 
				
			||||||
    if [ "$needbase64" ]; then
 | 
					    if [ "$needbase64" ]; then
 | 
				
			||||||
      if [ "$httpmethod" = "POST" ]; then
 | 
					      if [ "$httpmethod" = "POST" ]; then
 | 
				
			||||||
 | 
					        if [ "$_postContentType" ]; then
 | 
				
			||||||
 | 
					          response="$($_WGET -S -O - --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" --header "Content-Type: $_postContentType" --post-data="$body" "$_post_url" 2>"$HTTP_HEADER" | _base64)"
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
          response="$($_WGET -S -O - --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" --post-data="$body" "$_post_url" 2>"$HTTP_HEADER" | _base64)"
 | 
					          response="$($_WGET -S -O - --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" --post-data="$body" "$_post_url" 2>"$HTTP_HEADER" | _base64)"
 | 
				
			||||||
 | 
					        fi
 | 
				
			||||||
 | 
					      else
 | 
				
			||||||
 | 
					        if [ "$_postContentType" ]; then
 | 
				
			||||||
 | 
					          response="$($_WGET -S -O - --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" --header "Content-Type: $_postContentType" --method $httpmethod --body-data="$body" "$_post_url" 2>"$HTTP_HEADER" | _base64)"
 | 
				
			||||||
        else
 | 
					        else
 | 
				
			||||||
          response="$($_WGET -S -O - --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" --method $httpmethod --body-data="$body" "$_post_url" 2>"$HTTP_HEADER" | _base64)"
 | 
					          response="$($_WGET -S -O - --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" --method $httpmethod --body-data="$body" "$_post_url" 2>"$HTTP_HEADER" | _base64)"
 | 
				
			||||||
        fi
 | 
					        fi
 | 
				
			||||||
 | 
					      fi
 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
      if [ "$httpmethod" = "POST" ]; then
 | 
					      if [ "$httpmethod" = "POST" ]; then
 | 
				
			||||||
 | 
					        if [ "$_postContentType" ]; then
 | 
				
			||||||
 | 
					          response="$($_WGET -S -O - --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" --header "Content-Type: $_postContentType" --post-data="$body" "$_post_url" 2>"$HTTP_HEADER")"
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
          response="$($_WGET -S -O - --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" --post-data="$body" "$_post_url" 2>"$HTTP_HEADER")"
 | 
					          response="$($_WGET -S -O - --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" --post-data="$body" "$_post_url" 2>"$HTTP_HEADER")"
 | 
				
			||||||
 | 
					        fi
 | 
				
			||||||
 | 
					      else
 | 
				
			||||||
 | 
					        if [ "$_postContentType" ]; then
 | 
				
			||||||
 | 
					          response="$($_WGET -S -O - --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" --header "Content-Type: $_postContentType" --method $httpmethod --body-data="$body" "$_post_url" 2>"$HTTP_HEADER")"
 | 
				
			||||||
        else
 | 
					        else
 | 
				
			||||||
          response="$($_WGET -S -O - --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" --method $httpmethod --body-data="$body" "$_post_url" 2>"$HTTP_HEADER")"
 | 
					          response="$($_WGET -S -O - --user-agent="$USER_AGENT" --header "$_H5" --header "$_H4" --header "$_H3" --header "$_H2" --header "$_H1" --method $httpmethod --body-data="$body" "$_post_url" 2>"$HTTP_HEADER")"
 | 
				
			||||||
        fi
 | 
					        fi
 | 
				
			||||||
      fi
 | 
					      fi
 | 
				
			||||||
 | 
					    fi
 | 
				
			||||||
    _ret="$?"
 | 
					    _ret="$?"
 | 
				
			||||||
    if [ "$_ret" = "8" ]; then
 | 
					    if [ "$_ret" = "8" ]; then
 | 
				
			||||||
      _ret=0
 | 
					      _ret=0
 | 
				
			||||||
@ -1753,19 +1795,25 @@ _send_signed_request() {
 | 
				
			|||||||
    return 1
 | 
					    return 1
 | 
				
			||||||
  fi
 | 
					  fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if [ "$ACME_VERSION" = "2" ]; then
 | 
				
			||||||
 | 
					    __request_conent_type="$CONTENT_TYPE_JSON"
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
 | 
					    __request_conent_type=""
 | 
				
			||||||
 | 
					  fi
 | 
				
			||||||
  payload64=$(printf "%s" "$payload" | _base64 | _url_replace)
 | 
					  payload64=$(printf "%s" "$payload" | _base64 | _url_replace)
 | 
				
			||||||
  _debug3 payload64 "$payload64"
 | 
					  _debug3 payload64 "$payload64"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  MAX_REQUEST_RETRY_TIMES=5
 | 
					  MAX_REQUEST_RETRY_TIMES=5
 | 
				
			||||||
  _request_retry_times=0
 | 
					  _request_retry_times=0
 | 
				
			||||||
  while [ "${_request_retry_times}" -lt "$MAX_REQUEST_RETRY_TIMES" ]; do
 | 
					  while [ "${_request_retry_times}" -lt "$MAX_REQUEST_RETRY_TIMES" ]; do
 | 
				
			||||||
 | 
					    _request_retry_times=$(_math "$_request_retry_times" + 1)
 | 
				
			||||||
    _debug3 _request_retry_times "$_request_retry_times"
 | 
					    _debug3 _request_retry_times "$_request_retry_times"
 | 
				
			||||||
    if [ -z "$_CACHED_NONCE" ]; then
 | 
					    if [ -z "$_CACHED_NONCE" ]; then
 | 
				
			||||||
      _headers=""
 | 
					      _headers=""
 | 
				
			||||||
      if [ "$ACME_NEW_NONCE" ]; then
 | 
					      if [ "$ACME_NEW_NONCE" ]; then
 | 
				
			||||||
        _debug2 "Get nonce. ACME_NEW_NONCE" "$ACME_NEW_NONCE"
 | 
					        _debug2 "Get nonce. ACME_NEW_NONCE" "$ACME_NEW_NONCE"
 | 
				
			||||||
        nonceurl="$ACME_NEW_NONCE"
 | 
					        nonceurl="$ACME_NEW_NONCE"
 | 
				
			||||||
        if _post "" "$nonceurl" "" "HEAD"; then
 | 
					        if _post "" "$nonceurl" "" "HEAD" "$__request_conent_type"; then
 | 
				
			||||||
          _headers="$(cat "$HTTP_HEADER")"
 | 
					          _headers="$(cat "$HTTP_HEADER")"
 | 
				
			||||||
        fi
 | 
					        fi
 | 
				
			||||||
      fi
 | 
					      fi
 | 
				
			||||||
@ -1789,7 +1837,11 @@ _send_signed_request() {
 | 
				
			|||||||
    fi
 | 
					    fi
 | 
				
			||||||
    nonce="$_CACHED_NONCE"
 | 
					    nonce="$_CACHED_NONCE"
 | 
				
			||||||
    _debug2 nonce "$nonce"
 | 
					    _debug2 nonce "$nonce"
 | 
				
			||||||
 | 
					    if [ -z "$nonce" ]; then
 | 
				
			||||||
 | 
					      _info "Could not get nonce, let's try again."
 | 
				
			||||||
 | 
					      _sleep 2
 | 
				
			||||||
 | 
					      continue
 | 
				
			||||||
 | 
					    fi
 | 
				
			||||||
    if [ "$ACME_VERSION" = "2" ]; then
 | 
					    if [ "$ACME_VERSION" = "2" ]; then
 | 
				
			||||||
      if [ "$url" = "$ACME_NEW_ACCOUNT" ] || [ "$url" = "$ACME_REVOKE_CERT" ]; then
 | 
					      if [ "$url" = "$ACME_NEW_ACCOUNT" ] || [ "$url" = "$ACME_REVOKE_CERT" ]; then
 | 
				
			||||||
        protected="$JWK_HEADERPLACE_PART1$nonce\", \"url\": \"${url}$JWK_HEADERPLACE_PART2, \"jwk\": $jwk"'}'
 | 
					        protected="$JWK_HEADERPLACE_PART1$nonce\", \"url\": \"${url}$JWK_HEADERPLACE_PART2, \"jwk\": $jwk"'}'
 | 
				
			||||||
@ -1820,7 +1872,7 @@ _send_signed_request() {
 | 
				
			|||||||
    fi
 | 
					    fi
 | 
				
			||||||
    _debug3 body "$body"
 | 
					    _debug3 body "$body"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    response="$(_post "$body" "$url" "$needbase64")"
 | 
					    response="$(_post "$body" "$url" "$needbase64" "POST" "$__request_conent_type")"
 | 
				
			||||||
    _CACHED_NONCE=""
 | 
					    _CACHED_NONCE=""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if [ "$?" != "0" ]; then
 | 
					    if [ "$?" != "0" ]; then
 | 
				
			||||||
@ -1841,13 +1893,12 @@ _send_signed_request() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    _body="$response"
 | 
					    _body="$response"
 | 
				
			||||||
    if [ "$needbase64" ]; then
 | 
					    if [ "$needbase64" ]; then
 | 
				
			||||||
      _body="$(echo "$_body" | _dbase64)"
 | 
					      _body="$(echo "$_body" | _dbase64 | tr -d '\0')"
 | 
				
			||||||
      _debug3 _body "$_body"
 | 
					      _debug3 _body "$_body"
 | 
				
			||||||
    fi
 | 
					    fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if _contains "$_body" "JWS has invalid anti-replay nonce"; then
 | 
					    if _contains "$_body" "JWS has invalid anti-replay nonce"; then
 | 
				
			||||||
      _info "It seems the CA server is busy now, let's wait and retry."
 | 
					      _info "It seems the CA server is busy now, let's wait and retry."
 | 
				
			||||||
      _request_retry_times=$(_math "$_request_retry_times" + 1)
 | 
					 | 
				
			||||||
      _sleep 5
 | 
					      _sleep 5
 | 
				
			||||||
      continue
 | 
					      continue
 | 
				
			||||||
    fi
 | 
					    fi
 | 
				
			||||||
@ -2310,7 +2361,7 @@ _initpath() {
 | 
				
			|||||||
    fi
 | 
					    fi
 | 
				
			||||||
  fi
 | 
					  fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  _debug2 ACME_DIRECTORY "$ACME_DIRECTORY"
 | 
					  _debug ACME_DIRECTORY "$ACME_DIRECTORY"
 | 
				
			||||||
  _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"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -2967,6 +3018,8 @@ _on_before_issue() {
 | 
				
			|||||||
  _chk_pre_hook="$4"
 | 
					  _chk_pre_hook="$4"
 | 
				
			||||||
  _chk_local_addr="$5"
 | 
					  _chk_local_addr="$5"
 | 
				
			||||||
  _debug _on_before_issue
 | 
					  _debug _on_before_issue
 | 
				
			||||||
 | 
					  _debug _chk_main_domain "$_chk_main_domain"
 | 
				
			||||||
 | 
					  _debug _chk_alt_domains "$_chk_alt_domains"
 | 
				
			||||||
  #run pre hook
 | 
					  #run pre hook
 | 
				
			||||||
  if [ "$_chk_pre_hook" ]; then
 | 
					  if [ "$_chk_pre_hook" ]; then
 | 
				
			||||||
    _info "Run pre hook:'$_chk_pre_hook'"
 | 
					    _info "Run pre hook:'$_chk_pre_hook'"
 | 
				
			||||||
@ -2987,11 +3040,17 @@ _on_before_issue() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  _debug Le_LocalAddress "$_chk_local_addr"
 | 
					  _debug Le_LocalAddress "$_chk_local_addr"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  alldomains=$(echo "$_chk_main_domain,$_chk_alt_domains" | tr ',' ' ')
 | 
					 | 
				
			||||||
  _index=1
 | 
					  _index=1
 | 
				
			||||||
  _currentRoot=""
 | 
					  _currentRoot=""
 | 
				
			||||||
  _addrIndex=1
 | 
					  _addrIndex=1
 | 
				
			||||||
  for d in $alldomains; do
 | 
					  _w_index=1
 | 
				
			||||||
 | 
					  while true; do
 | 
				
			||||||
 | 
					    d="$(echo "$_chk_main_domain,$_chk_alt_domains," | cut -d , -f "$_w_index")"
 | 
				
			||||||
 | 
					    _w_index="$(_math "$_w_index" + 1)"
 | 
				
			||||||
 | 
					    _debug d "$d"
 | 
				
			||||||
 | 
					    if [ -z "$d" ]; then
 | 
				
			||||||
 | 
					      break
 | 
				
			||||||
 | 
					    fi
 | 
				
			||||||
    _debug "Check for domain" "$d"
 | 
					    _debug "Check for domain" "$d"
 | 
				
			||||||
    _currentRoot="$(_getfield "$_chk_web_roots" $_index)"
 | 
					    _currentRoot="$(_getfield "$_chk_web_roots" $_index)"
 | 
				
			||||||
    _debug "_currentRoot" "$_currentRoot"
 | 
					    _debug "_currentRoot" "$_currentRoot"
 | 
				
			||||||
@ -3087,7 +3146,7 @@ _on_issue_err() {
 | 
				
			|||||||
    )
 | 
					    )
 | 
				
			||||||
  fi
 | 
					  fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if [ "$IS_RENEW" = "1" ] && _hasfield "$Le_Webroot" "dns"; then
 | 
					  if [ "$IS_RENEW" = "1" ] && _hasfield "$Le_Webroot" "$W_DNS"; then
 | 
				
			||||||
    _err "$_DNS_MANUAL_ERR"
 | 
					    _err "$_DNS_MANUAL_ERR"
 | 
				
			||||||
  fi
 | 
					  fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -3123,7 +3182,7 @@ _on_issue_success() {
 | 
				
			|||||||
    fi
 | 
					    fi
 | 
				
			||||||
  fi
 | 
					  fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if _hasfield "$Le_Webroot" "dns"; then
 | 
					  if _hasfield "$Le_Webroot" "$W_DNS"; then
 | 
				
			||||||
    _err "$_DNS_MANUAL_WARN"
 | 
					    _err "$_DNS_MANUAL_WARN"
 | 
				
			||||||
  fi
 | 
					  fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -3207,10 +3266,16 @@ _regAccount() {
 | 
				
			|||||||
    return 1
 | 
					    return 1
 | 
				
			||||||
  fi
 | 
					  fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  _debug2 responseHeaders "$responseHeaders"
 | 
				
			||||||
  _accUri="$(echo "$responseHeaders" | grep "^Location:" | _head_n 1 | cut -d ' ' -f 2 | tr -d "\r\n")"
 | 
					  _accUri="$(echo "$responseHeaders" | grep "^Location:" | _head_n 1 | cut -d ' ' -f 2 | tr -d "\r\n")"
 | 
				
			||||||
  _debug "_accUri" "$_accUri"
 | 
					  _debug "_accUri" "$_accUri"
 | 
				
			||||||
 | 
					  if [ -z "$_accUri" ]; then
 | 
				
			||||||
 | 
					    _err "Can not find account id url."
 | 
				
			||||||
 | 
					    _err "$responseHeaders"
 | 
				
			||||||
 | 
					    return 1
 | 
				
			||||||
 | 
					  fi
 | 
				
			||||||
  _savecaconf "ACCOUNT_URL" "$_accUri"
 | 
					  _savecaconf "ACCOUNT_URL" "$_accUri"
 | 
				
			||||||
  export ACCOUNT_URL="$ACCOUNT_URL"
 | 
					  export ACCOUNT_URL="$_accUri"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  CA_KEY_HASH="$(__calcAccountKeyHash)"
 | 
					  CA_KEY_HASH="$(__calcAccountKeyHash)"
 | 
				
			||||||
  _debug "Calc CA_KEY_HASH" "$CA_KEY_HASH"
 | 
					  _debug "Calc CA_KEY_HASH" "$CA_KEY_HASH"
 | 
				
			||||||
@ -3390,6 +3455,9 @@ issue() {
 | 
				
			|||||||
    _main_domain=$(echo "$2,$3" | cut -d , -f 1)
 | 
					    _main_domain=$(echo "$2,$3" | cut -d , -f 1)
 | 
				
			||||||
    _alt_domains=$(echo "$2,$3" | cut -d , -f 2- | sed "s/,${NO_VALUE}$//")
 | 
					    _alt_domains=$(echo "$2,$3" | cut -d , -f 2- | sed "s/,${NO_VALUE}$//")
 | 
				
			||||||
  fi
 | 
					  fi
 | 
				
			||||||
 | 
					  _debug _main_domain "$_main_domain"
 | 
				
			||||||
 | 
					  _debug _alt_domains "$_alt_domains"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  _key_length="$4"
 | 
					  _key_length="$4"
 | 
				
			||||||
  _real_cert="$5"
 | 
					  _real_cert="$5"
 | 
				
			||||||
  _real_key="$6"
 | 
					  _real_key="$6"
 | 
				
			||||||
@ -3417,6 +3485,11 @@ issue() {
 | 
				
			|||||||
    mkdir -p "$DOMAIN_PATH"
 | 
					    mkdir -p "$DOMAIN_PATH"
 | 
				
			||||||
  fi
 | 
					  fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if _hasfield "$_web_roots" "$W_DNS" && [ -z "$FORCE_DNS_MANUAL" ]; then
 | 
				
			||||||
 | 
					    _err "$_DNS_MANUAL_ERROR"
 | 
				
			||||||
 | 
					    return 1
 | 
				
			||||||
 | 
					  fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  _debug "Using ACME_DIRECTORY: $ACME_DIRECTORY"
 | 
					  _debug "Using ACME_DIRECTORY: $ACME_DIRECTORY"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  _initAPI
 | 
					  _initAPI
 | 
				
			||||||
@ -3478,7 +3551,7 @@ issue() {
 | 
				
			|||||||
  _saved_account_key_hash="$(_readcaconf "CA_KEY_HASH")"
 | 
					  _saved_account_key_hash="$(_readcaconf "CA_KEY_HASH")"
 | 
				
			||||||
  _debug2 _saved_account_key_hash "$_saved_account_key_hash"
 | 
					  _debug2 _saved_account_key_hash "$_saved_account_key_hash"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if [ -z "$_saved_account_key_hash" ] || [ "$_saved_account_key_hash" != "$(__calcAccountKeyHash)" ]; then
 | 
					  if [ -z "$ACCOUNT_URL" ] || [ -z "$_saved_account_key_hash" ] || [ "$_saved_account_key_hash" != "$(__calcAccountKeyHash)" ]; then
 | 
				
			||||||
    if ! _regAccount "$_accountkeylength"; then
 | 
					    if ! _regAccount "$_accountkeylength"; then
 | 
				
			||||||
      _on_issue_err "$_post_hook"
 | 
					      _on_issue_err "$_post_hook"
 | 
				
			||||||
      return 1
 | 
					      return 1
 | 
				
			||||||
@ -3520,10 +3593,15 @@ issue() {
 | 
				
			|||||||
    if [ "$ACME_VERSION" = "2" ]; then
 | 
					    if [ "$ACME_VERSION" = "2" ]; then
 | 
				
			||||||
      #make new order request
 | 
					      #make new order request
 | 
				
			||||||
      _identifiers="{\"type\":\"dns\",\"value\":\"$_main_domain\"}"
 | 
					      _identifiers="{\"type\":\"dns\",\"value\":\"$_main_domain\"}"
 | 
				
			||||||
      for d in $(echo "$_alt_domains" | tr ',' ' '); do
 | 
					      _w_index=1
 | 
				
			||||||
        if [ "$d" ]; then
 | 
					      while true; do
 | 
				
			||||||
          _identifiers="$_identifiers,{\"type\":\"dns\",\"value\":\"$d\"}"
 | 
					        d="$(echo "$_alt_domains," | cut -d , -f "$_w_index")"
 | 
				
			||||||
 | 
					        _w_index="$(_math "$_w_index" + 1)"
 | 
				
			||||||
 | 
					        _debug d "$d"
 | 
				
			||||||
 | 
					        if [ -z "$d" ]; then
 | 
				
			||||||
 | 
					          break
 | 
				
			||||||
        fi
 | 
					        fi
 | 
				
			||||||
 | 
					        _identifiers="$_identifiers,{\"type\":\"dns\",\"value\":\"$d\"}"
 | 
				
			||||||
      done
 | 
					      done
 | 
				
			||||||
      _debug2 _identifiers "$_identifiers"
 | 
					      _debug2 _identifiers "$_identifiers"
 | 
				
			||||||
      if ! _send_signed_request "$ACME_NEW_ORDER" "{\"identifiers\": [$_identifiers]}"; then
 | 
					      if ! _send_signed_request "$ACME_NEW_ORDER" "{\"identifiers\": [$_identifiers]}"; then
 | 
				
			||||||
@ -3560,6 +3638,8 @@ issue() {
 | 
				
			|||||||
        _debug2 "_authz_url" "$_authz_url"
 | 
					        _debug2 "_authz_url" "$_authz_url"
 | 
				
			||||||
        if ! response="$(_get "$_authz_url")"; then
 | 
					        if ! response="$(_get "$_authz_url")"; then
 | 
				
			||||||
          _err "get to authz error."
 | 
					          _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
 | 
				
			||||||
@ -3578,10 +3658,16 @@ $_authorizations_map"
 | 
				
			|||||||
      _debug2 _authorizations_map "$_authorizations_map"
 | 
					      _debug2 _authorizations_map "$_authorizations_map"
 | 
				
			||||||
    fi
 | 
					    fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    alldomains=$(echo "$_main_domain,$_alt_domains" | tr ',' ' ')
 | 
					 | 
				
			||||||
    _index=0
 | 
					    _index=0
 | 
				
			||||||
    _currentRoot=""
 | 
					    _currentRoot=""
 | 
				
			||||||
    for d in $alldomains; do
 | 
					    _w_index=1
 | 
				
			||||||
 | 
					    while true; do
 | 
				
			||||||
 | 
					      d="$(echo "$_main_domain,$_alt_domains," | cut -d , -f "$_w_index")"
 | 
				
			||||||
 | 
					      _w_index="$(_math "$_w_index" + 1)"
 | 
				
			||||||
 | 
					      _debug d "$d"
 | 
				
			||||||
 | 
					      if [ -z "$d" ]; then
 | 
				
			||||||
 | 
					        break
 | 
				
			||||||
 | 
					      fi
 | 
				
			||||||
      _info "Getting webroot for domain" "$d"
 | 
					      _info "Getting webroot for domain" "$d"
 | 
				
			||||||
      _index=$(_math $_index + 1)
 | 
					      _index=$(_math $_index + 1)
 | 
				
			||||||
      _w="$(echo $_web_roots | cut -d , -f $_index)"
 | 
					      _w="$(echo $_web_roots | cut -d , -f $_index)"
 | 
				
			||||||
@ -3593,7 +3679,7 @@ $_authorizations_map"
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
      vtype="$VTYPE_HTTP"
 | 
					      vtype="$VTYPE_HTTP"
 | 
				
			||||||
      #todo, v2 wildcard force to use dns
 | 
					      #todo, v2 wildcard force to use dns
 | 
				
			||||||
      if _startswith "$_currentRoot" "dns"; then
 | 
					      if _startswith "$_currentRoot" "$W_DNS"; then
 | 
				
			||||||
        vtype="$VTYPE_DNS"
 | 
					        vtype="$VTYPE_DNS"
 | 
				
			||||||
      fi
 | 
					      fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -3610,6 +3696,7 @@ $_authorizations_map"
 | 
				
			|||||||
        _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"
 | 
				
			||||||
          _clearup
 | 
					          _clearup
 | 
				
			||||||
          _on_issue_err "$_post_hook"
 | 
					          _on_issue_err "$_post_hook"
 | 
				
			||||||
          return 1
 | 
					          return 1
 | 
				
			||||||
@ -3720,6 +3807,10 @@ $_authorizations_map"
 | 
				
			|||||||
        if [ "$d_api" ]; then
 | 
					        if [ "$d_api" ]; then
 | 
				
			||||||
          _info "Found domain api file: $d_api"
 | 
					          _info "Found domain api file: $d_api"
 | 
				
			||||||
        else
 | 
					        else
 | 
				
			||||||
 | 
					          if [ "$_currentRoot" != "$W_DNS" ]; then
 | 
				
			||||||
 | 
					            _err "Can not find dns api hook for: $_currentRoot"
 | 
				
			||||||
 | 
					            _info "You need to add the txt record manually."
 | 
				
			||||||
 | 
					          fi
 | 
				
			||||||
          _info "$(__red "Add the following TXT record:")"
 | 
					          _info "$(__red "Add the following TXT record:")"
 | 
				
			||||||
          _info "$(__red "Domain: '$(__green "$txtdomain")'")"
 | 
					          _info "$(__red "Domain: '$(__green "$txtdomain")'")"
 | 
				
			||||||
          _info "$(__red "TXT value: '$(__green "$txt")'")"
 | 
					          _info "$(__red "TXT value: '$(__green "$txt")'")"
 | 
				
			||||||
@ -3758,7 +3849,7 @@ $_authorizations_map"
 | 
				
			|||||||
    if [ "$dnsadded" = '0' ]; then
 | 
					    if [ "$dnsadded" = '0' ]; then
 | 
				
			||||||
      _savedomainconf "Le_Vlist" "$vlist"
 | 
					      _savedomainconf "Le_Vlist" "$vlist"
 | 
				
			||||||
      _debug "Dns record not added yet, so, save to $DOMAIN_CONF and exit."
 | 
					      _debug "Dns record not added yet, so, save to $DOMAIN_CONF and exit."
 | 
				
			||||||
      _err "Please add the TXT records to the domains, and retry again."
 | 
					      _err "Please add the TXT records to the domains, and re-run with --renew."
 | 
				
			||||||
      _clearup
 | 
					      _clearup
 | 
				
			||||||
      _on_issue_err "$_post_hook"
 | 
					      _on_issue_err "$_post_hook"
 | 
				
			||||||
      return 1
 | 
					      return 1
 | 
				
			||||||
@ -4022,13 +4113,15 @@ $_authorizations_map"
 | 
				
			|||||||
    fi
 | 
					    fi
 | 
				
			||||||
    if [ "$code" != "200" ]; then
 | 
					    if [ "$code" != "200" ]; then
 | 
				
			||||||
      _err "Sign failed, code is not 200."
 | 
					      _err "Sign failed, code is not 200."
 | 
				
			||||||
 | 
					      _err "$response"
 | 
				
			||||||
      _on_issue_err "$_post_hook"
 | 
					      _on_issue_err "$_post_hook"
 | 
				
			||||||
      return 1
 | 
					      return 1
 | 
				
			||||||
    fi
 | 
					    fi
 | 
				
			||||||
    Le_LinkCert="$(echo "$response" | tr -d '\r\n' | _egrep_o '"certificate" *: *"[^"]*"' | cut -d '"' -f 4)"
 | 
					    Le_LinkCert="$(echo "$response" | tr -d '\r\n' | _egrep_o '"certificate" *: *"[^"]*"' | cut -d '"' -f 4)"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if ! _get "$Le_LinkCert" >"$CERT_PATH"; then
 | 
					    if ! _get "$Le_LinkCert" >"$CERT_PATH"; then
 | 
				
			||||||
      _err "Sign failed, code is not 200."
 | 
					      _err "Sign failed, can not download cert:$Le_LinkCert."
 | 
				
			||||||
 | 
					      _err "$response"
 | 
				
			||||||
      _on_issue_err "$_post_hook"
 | 
					      _on_issue_err "$_post_hook"
 | 
				
			||||||
      return 1
 | 
					      return 1
 | 
				
			||||||
    fi
 | 
					    fi
 | 
				
			||||||
@ -4044,12 +4137,12 @@ $_authorizations_map"
 | 
				
			|||||||
    fi
 | 
					    fi
 | 
				
			||||||
  else
 | 
					  else
 | 
				
			||||||
    if ! _send_signed_request "${ACME_NEW_ORDER}" "{\"resource\": \"$ACME_NEW_ORDER_RES\", \"csr\": \"$der\"}" "needbase64"; then
 | 
					    if ! _send_signed_request "${ACME_NEW_ORDER}" "{\"resource\": \"$ACME_NEW_ORDER_RES\", \"csr\": \"$der\"}" "needbase64"; then
 | 
				
			||||||
      _err "Sign failed."
 | 
					      _err "Sign failed. $response"
 | 
				
			||||||
      _on_issue_err "$_post_hook"
 | 
					      _on_issue_err "$_post_hook"
 | 
				
			||||||
      return 1
 | 
					      return 1
 | 
				
			||||||
    fi
 | 
					    fi
 | 
				
			||||||
    _rcert="$response"
 | 
					    _rcert="$response"
 | 
				
			||||||
    Le_LinkCert="$(grep -i '^Location.*$' "$HTTP_HEADER" | _head_n 1 | tr -d "\r\n" | cut -d " " -f 2)"
 | 
					    Le_LinkCert="$(grep -i '^Location.*$' "$HTTP_HEADER" | _tail_n 1 | tr -d "\r\n" | cut -d " " -f 2)"
 | 
				
			||||||
    echo "$BEGIN_CERT" >"$CERT_PATH"
 | 
					    echo "$BEGIN_CERT" >"$CERT_PATH"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #if ! _get "$Le_LinkCert" | _base64 "multiline"  >> "$CERT_PATH" ; then
 | 
					    #if ! _get "$Le_LinkCert" | _base64 "multiline"  >> "$CERT_PATH" ; then
 | 
				
			||||||
@ -4068,6 +4161,13 @@ $_authorizations_map"
 | 
				
			|||||||
  _debug "Le_LinkCert" "$Le_LinkCert"
 | 
					  _debug "Le_LinkCert" "$Le_LinkCert"
 | 
				
			||||||
  _savedomainconf "Le_LinkCert" "$Le_LinkCert"
 | 
					  _savedomainconf "Le_LinkCert" "$Le_LinkCert"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if [ -z "$Le_LinkCert" ] || ! _checkcert "$CERT_PATH"; then
 | 
				
			||||||
 | 
					    response="$(echo "$response" | _dbase64 "multiline" | tr -d '\0' | _normalizeJson)"
 | 
				
			||||||
 | 
					    _err "Sign failed: $(echo "$response" | _egrep_o '"detail":"[^"]*"')"
 | 
				
			||||||
 | 
					    _on_issue_err "$_post_hook"
 | 
				
			||||||
 | 
					    return 1
 | 
				
			||||||
 | 
					  fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if [ "$Le_LinkCert" ]; then
 | 
					  if [ "$Le_LinkCert" ]; then
 | 
				
			||||||
    _info "$(__green "Cert success.")"
 | 
					    _info "$(__green "Cert success.")"
 | 
				
			||||||
    cat "$CERT_PATH"
 | 
					    cat "$CERT_PATH"
 | 
				
			||||||
@ -4078,26 +4178,18 @@ $_authorizations_map"
 | 
				
			|||||||
      _info "Your cert key is in $(__green " $CERT_KEY_PATH ")"
 | 
					      _info "Your cert key is in $(__green " $CERT_KEY_PATH ")"
 | 
				
			||||||
    fi
 | 
					    fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    cp "$CERT_PATH" "$CERT_FULLCHAIN_PATH"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if [ ! "$USER_PATH" ] || [ ! "$IN_CRON" ]; then
 | 
					    if [ ! "$USER_PATH" ] || [ ! "$IN_CRON" ]; then
 | 
				
			||||||
      USER_PATH="$PATH"
 | 
					      USER_PATH="$PATH"
 | 
				
			||||||
      _saveaccountconf "USER_PATH" "$USER_PATH"
 | 
					      _saveaccountconf "USER_PATH" "$USER_PATH"
 | 
				
			||||||
    fi
 | 
					    fi
 | 
				
			||||||
  fi
 | 
					  fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if [ -z "$Le_LinkCert" ]; then
 | 
					 | 
				
			||||||
    response="$(echo "$response" | _dbase64 "multiline" | _normalizeJson)"
 | 
					 | 
				
			||||||
    _err "Sign failed: $(echo "$response" | _egrep_o '"detail":"[^"]*"')"
 | 
					 | 
				
			||||||
    _on_issue_err "$_post_hook"
 | 
					 | 
				
			||||||
    return 1
 | 
					 | 
				
			||||||
  fi
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  _cleardomainconf "Le_Vlist"
 | 
					  _cleardomainconf "Le_Vlist"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if [ "$ACME_VERSION" = "2" ]; then
 | 
					  if [ "$ACME_VERSION" = "2" ]; then
 | 
				
			||||||
    _debug "v2 chain."
 | 
					    _debug "v2 chain."
 | 
				
			||||||
  else
 | 
					  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 '<>')
 | 
					    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 [ "$Le_LinkIssuer" ]; then
 | 
				
			||||||
@ -4121,6 +4213,10 @@ $_authorizations_map"
 | 
				
			|||||||
            echo "$BEGIN_CERT" >"$CA_CERT_PATH"
 | 
					            echo "$BEGIN_CERT" >"$CA_CERT_PATH"
 | 
				
			||||||
            _base64 "multiline" <"$CA_CERT_PATH.der" >>"$CA_CERT_PATH"
 | 
					            _base64 "multiline" <"$CA_CERT_PATH.der" >>"$CA_CERT_PATH"
 | 
				
			||||||
            echo "$END_CERT" >>"$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"
 | 
					            cat "$CA_CERT_PATH" >>"$CERT_FULLCHAIN_PATH"
 | 
				
			||||||
            rm -f "$CA_CERT_PATH.der"
 | 
					            rm -f "$CA_CERT_PATH.der"
 | 
				
			||||||
            break
 | 
					            break
 | 
				
			||||||
@ -4191,20 +4287,21 @@ $_authorizations_map"
 | 
				
			|||||||
  Le_NextRenewTime=$(_math "$Le_NextRenewTime" - 86400)
 | 
					  Le_NextRenewTime=$(_math "$Le_NextRenewTime" - 86400)
 | 
				
			||||||
  _savedomainconf "Le_NextRenewTime" "$Le_NextRenewTime"
 | 
					  _savedomainconf "Le_NextRenewTime" "$Le_NextRenewTime"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if ! _on_issue_success "$_post_hook" "$_renew_hook"; then
 | 
					 | 
				
			||||||
    _err "Call hook error."
 | 
					 | 
				
			||||||
    return 1
 | 
					 | 
				
			||||||
  fi
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if [ "$_real_cert$_real_key$_real_ca$_reload_cmd$_real_fullchain" ]; then
 | 
					  if [ "$_real_cert$_real_key$_real_ca$_reload_cmd$_real_fullchain" ]; then
 | 
				
			||||||
    _savedomainconf "Le_RealCertPath" "$_real_cert"
 | 
					    _savedomainconf "Le_RealCertPath" "$_real_cert"
 | 
				
			||||||
    _savedomainconf "Le_RealCACertPath" "$_real_ca"
 | 
					    _savedomainconf "Le_RealCACertPath" "$_real_ca"
 | 
				
			||||||
    _savedomainconf "Le_RealKeyPath" "$_real_key"
 | 
					    _savedomainconf "Le_RealKeyPath" "$_real_key"
 | 
				
			||||||
    _savedomainconf "Le_ReloadCmd" "$_reload_cmd"
 | 
					    _savedomainconf "Le_ReloadCmd" "$_reload_cmd"
 | 
				
			||||||
    _savedomainconf "Le_RealFullChainPath" "$_real_fullchain"
 | 
					    _savedomainconf "Le_RealFullChainPath" "$_real_fullchain"
 | 
				
			||||||
    _installcert "$_main_domain" "$_real_cert" "$_real_key" "$_real_ca" "$_real_fullchain" "$_reload_cmd"
 | 
					    if ! _installcert "$_main_domain" "$_real_cert" "$_real_key" "$_real_ca" "$_real_fullchain" "$_reload_cmd"; then
 | 
				
			||||||
 | 
					      return 1
 | 
				
			||||||
 | 
					    fi
 | 
				
			||||||
  fi
 | 
					  fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if ! _on_issue_success "$_post_hook" "$_renew_hook"; then
 | 
				
			||||||
 | 
					    _err "Call hook error."
 | 
				
			||||||
 | 
					    return 1
 | 
				
			||||||
 | 
					  fi
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#domain  [isEcc]
 | 
					#domain  [isEcc]
 | 
				
			||||||
@ -4230,7 +4327,7 @@ renew() {
 | 
				
			|||||||
  fi
 | 
					  fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  . "$DOMAIN_CONF"
 | 
					  . "$DOMAIN_CONF"
 | 
				
			||||||
 | 
					  _debug Le_API "$Le_API"
 | 
				
			||||||
  if [ "$Le_API" ]; then
 | 
					  if [ "$Le_API" ]; then
 | 
				
			||||||
    if [ "$_OLD_CA_HOST" = "$Le_API" ]; then
 | 
					    if [ "$_OLD_CA_HOST" = "$Le_API" ]; then
 | 
				
			||||||
      export Le_API="$DEFAULT_CA"
 | 
					      export Le_API="$DEFAULT_CA"
 | 
				
			||||||
@ -4579,19 +4676,19 @@ _installcert() {
 | 
				
			|||||||
    if [ -f "$_real_cert" ] && [ ! "$IS_RENEW" ]; then
 | 
					    if [ -f "$_real_cert" ] && [ ! "$IS_RENEW" ]; then
 | 
				
			||||||
      cp "$_real_cert" "$_backup_path/cert.bak"
 | 
					      cp "$_real_cert" "$_backup_path/cert.bak"
 | 
				
			||||||
    fi
 | 
					    fi
 | 
				
			||||||
    cat "$CERT_PATH" >"$_real_cert"
 | 
					    cat "$CERT_PATH" >"$_real_cert" || return 1
 | 
				
			||||||
  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"
 | 
					      cat "$CA_CERT_PATH" >>"$_real_ca" || return 1
 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
      if [ -f "$_real_ca" ] && [ ! "$IS_RENEW" ]; then
 | 
					      if [ -f "$_real_ca" ] && [ ! "$IS_RENEW" ]; then
 | 
				
			||||||
        cp "$_real_ca" "$_backup_path/ca.bak"
 | 
					        cp "$_real_ca" "$_backup_path/ca.bak"
 | 
				
			||||||
      fi
 | 
					      fi
 | 
				
			||||||
      cat "$CA_CERT_PATH" >"$_real_ca"
 | 
					      cat "$CA_CERT_PATH" >"$_real_ca" || return 1
 | 
				
			||||||
    fi
 | 
					    fi
 | 
				
			||||||
  fi
 | 
					  fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -4601,9 +4698,9 @@ _installcert() {
 | 
				
			|||||||
      cp "$_real_key" "$_backup_path/key.bak"
 | 
					      cp "$_real_key" "$_backup_path/key.bak"
 | 
				
			||||||
    fi
 | 
					    fi
 | 
				
			||||||
    if [ -f "$_real_key" ]; then
 | 
					    if [ -f "$_real_key" ]; then
 | 
				
			||||||
      cat "$CERT_KEY_PATH" >"$_real_key"
 | 
					      cat "$CERT_KEY_PATH" >"$_real_key" || return 1
 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
      cat "$CERT_KEY_PATH" >"$_real_key"
 | 
					      cat "$CERT_KEY_PATH" >"$_real_key" || return 1
 | 
				
			||||||
      chmod 600 "$_real_key"
 | 
					      chmod 600 "$_real_key"
 | 
				
			||||||
    fi
 | 
					    fi
 | 
				
			||||||
  fi
 | 
					  fi
 | 
				
			||||||
@ -4613,7 +4710,7 @@ _installcert() {
 | 
				
			|||||||
    if [ -f "$_real_fullchain" ] && [ ! "$IS_RENEW" ]; then
 | 
					    if [ -f "$_real_fullchain" ] && [ ! "$IS_RENEW" ]; then
 | 
				
			||||||
      cp "$_real_fullchain" "$_backup_path/fullchain.bak"
 | 
					      cp "$_real_fullchain" "$_backup_path/fullchain.bak"
 | 
				
			||||||
    fi
 | 
					    fi
 | 
				
			||||||
    cat "$CERT_FULLCHAIN_PATH" >"$_real_fullchain"
 | 
					    cat "$CERT_FULLCHAIN_PATH" >"$_real_fullchain" || return 1
 | 
				
			||||||
  fi
 | 
					  fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if [ "$_reload_cmd" ]; then
 | 
					  if [ "$_reload_cmd" ]; then
 | 
				
			||||||
@ -4834,6 +4931,8 @@ _deactivate() {
 | 
				
			|||||||
    _debug2 "authzUri" "$authzUri"
 | 
					    _debug2 "authzUri" "$authzUri"
 | 
				
			||||||
    if ! response="$(_get "$authzUri")"; then
 | 
					    if ! response="$(_get "$authzUri")"; then
 | 
				
			||||||
      _err "get to authz error."
 | 
					      _err "get to authz error."
 | 
				
			||||||
 | 
					      _err "_authorizations_seg" "$_authorizations_seg"
 | 
				
			||||||
 | 
					      _err "authzUri" "$authzUri"
 | 
				
			||||||
      _clearup
 | 
					      _clearup
 | 
				
			||||||
      _on_issue_err "$_post_hook"
 | 
					      _on_issue_err "$_post_hook"
 | 
				
			||||||
      return 1
 | 
					      return 1
 | 
				
			||||||
@ -5365,7 +5464,6 @@ Parameters:
 | 
				
			|||||||
  --webroot, -w  /path/to/webroot   Specifies the web root folder for web root mode.
 | 
					  --webroot, -w  /path/to/webroot   Specifies the web root folder for web root mode.
 | 
				
			||||||
  --standalone                      Use standalone mode.
 | 
					  --standalone                      Use standalone mode.
 | 
				
			||||||
  --stateless                       Use stateless mode, see: $_STATELESS_WIKI
 | 
					  --stateless                       Use stateless mode, see: $_STATELESS_WIKI
 | 
				
			||||||
  --tls                             Use standalone tls mode.
 | 
					 | 
				
			||||||
  --apache                          Use apache mode.
 | 
					  --apache                          Use apache mode.
 | 
				
			||||||
  --dns [dns_cf|dns_dp|dns_cx|/path/to/api/file]   Use dns mode or dns api.
 | 
					  --dns [dns_cf|dns_dp|dns_cx|/path/to/api/file]   Use dns mode or dns api.
 | 
				
			||||||
  --dnssleep  [$DEFAULT_DNS_SLEEP]                  The time in seconds to wait for all the txt records to take effect in dns api mode. Default $DEFAULT_DNS_SLEEP seconds.
 | 
					  --dnssleep  [$DEFAULT_DNS_SLEEP]                  The time in seconds to wait for all the txt records to take effect in dns api mode. Default $DEFAULT_DNS_SLEEP seconds.
 | 
				
			||||||
@ -5391,11 +5489,10 @@ Parameters:
 | 
				
			|||||||
  --cert-home                       Specifies the home dir to save all the certs, only valid for '--install' command.
 | 
					  --cert-home                       Specifies the home dir to save all the certs, only valid for '--install' command.
 | 
				
			||||||
  --config-home                     Specifies the home dir to save all the configurations.
 | 
					  --config-home                     Specifies the home dir to save all the configurations.
 | 
				
			||||||
  --useragent                       Specifies the user agent string. it will be saved for future use too.
 | 
					  --useragent                       Specifies the user agent string. it will be saved for future use too.
 | 
				
			||||||
  --accountemail                    Specifies the account email for registering, Only valid for the '--install' command.
 | 
					  --accountemail                    Specifies the account email, only valid for the '--install' and '--update-account' command.
 | 
				
			||||||
  --accountkey                      Specifies the account key path, Only valid for the '--install' command.
 | 
					  --accountkey                      Specifies the account key path, only valid for the '--install' command.
 | 
				
			||||||
  --days                            Specifies the days to renew the cert when using '--issue' command. The max value is $MAX_RENEW days.
 | 
					  --days                            Specifies the days to renew the cert when using '--issue' command. The max value is $MAX_RENEW days.
 | 
				
			||||||
  --httpport                        Specifies the standalone listening port. Only valid if the server is behind a reverse proxy or load balancer.
 | 
					  --httpport                        Specifies the standalone listening port. Only valid if the server is behind a reverse proxy or load balancer.
 | 
				
			||||||
  --tlsport                         Specifies the standalone tls listening port. Only valid if the server is behind a reverse proxy or load balancer.
 | 
					 | 
				
			||||||
  --local-address                   Specifies the standalone/tls server listening address, in case you have multiple ip addresses.
 | 
					  --local-address                   Specifies the standalone/tls server listening address, in case you have multiple ip addresses.
 | 
				
			||||||
  --listraw                         Only used for '--list' command, list the certs in raw format.
 | 
					  --listraw                         Only used for '--list' command, list the certs in raw format.
 | 
				
			||||||
  --stopRenewOnError, -se           Only valid for '--renew-all' command. Stop if one cert has error in renewal.
 | 
					  --stopRenewOnError, -se           Only valid for '--renew-all' command. Stop if one cert has error in renewal.
 | 
				
			||||||
@ -5404,6 +5501,7 @@ Parameters:
 | 
				
			|||||||
  --ca-path                         Specifies directory containing CA certificates in PEM format, used by wget or curl.
 | 
					  --ca-path                         Specifies directory containing CA certificates in PEM format, used by wget or curl.
 | 
				
			||||||
  --nocron                          Only valid for '--install' command, which means: do not install the default cron job. In this case, the certs will not be renewed automatically.
 | 
					  --nocron                          Only valid for '--install' command, which means: do not install the default cron job. In this case, the certs will not be renewed automatically.
 | 
				
			||||||
  --no-color                        Do not output color text.
 | 
					  --no-color                        Do not output color text.
 | 
				
			||||||
 | 
					  --force-color                     Force output of color text. Useful for non-interactive use with the aha tool for HTML E-Mails.
 | 
				
			||||||
  --ecc                             Specifies to use the ECC cert. Valid for '--install-cert', '--renew', '--revoke', '--toPkcs' and '--createCSR'
 | 
					  --ecc                             Specifies to use the ECC cert. Valid for '--install-cert', '--renew', '--revoke', '--toPkcs' and '--createCSR'
 | 
				
			||||||
  --csr                             Specifies the input csr.
 | 
					  --csr                             Specifies the input csr.
 | 
				
			||||||
  --pre-hook                        Command to be run before obtaining any certificates.
 | 
					  --pre-hook                        Command to be run before obtaining any certificates.
 | 
				
			||||||
@ -5417,6 +5515,8 @@ Parameters:
 | 
				
			|||||||
  --listen-v6                       Force standalone/tls server to listen at ipv6.
 | 
					  --listen-v6                       Force standalone/tls server to listen at ipv6.
 | 
				
			||||||
  --openssl-bin                     Specifies a custom openssl bin location.
 | 
					  --openssl-bin                     Specifies a custom openssl bin location.
 | 
				
			||||||
  --use-wget                        Force to use wget, if you have both curl and wget installed.
 | 
					  --use-wget                        Force to use wget, if you have both curl and wget installed.
 | 
				
			||||||
 | 
					  --yes-I-know-dns-manual-mode-enough-go-ahead-please  Force to use dns manual mode: $_DNS_MANUAL_WIKI
 | 
				
			||||||
 | 
					  --branch, -b                      Only valid for '--upgrade' command, specifies the branch name to upgrade to.
 | 
				
			||||||
  "
 | 
					  "
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -5746,16 +5846,8 @@ _process() {
 | 
				
			|||||||
          _webroot="$_webroot,$wvalue"
 | 
					          _webroot="$_webroot,$wvalue"
 | 
				
			||||||
        fi
 | 
					        fi
 | 
				
			||||||
        ;;
 | 
					        ;;
 | 
				
			||||||
      --tls)
 | 
					 | 
				
			||||||
        wvalue="$W_TLS"
 | 
					 | 
				
			||||||
        if [ -z "$_webroot" ]; then
 | 
					 | 
				
			||||||
          _webroot="$wvalue"
 | 
					 | 
				
			||||||
        else
 | 
					 | 
				
			||||||
          _webroot="$_webroot,$wvalue"
 | 
					 | 
				
			||||||
        fi
 | 
					 | 
				
			||||||
        ;;
 | 
					 | 
				
			||||||
      --dns)
 | 
					      --dns)
 | 
				
			||||||
        wvalue="dns"
 | 
					        wvalue="$W_DNS"
 | 
				
			||||||
        if [ "$2" ] && ! _startswith "$2" "-"; then
 | 
					        if [ "$2" ] && ! _startswith "$2" "-"; then
 | 
				
			||||||
          wvalue="$2"
 | 
					          wvalue="$2"
 | 
				
			||||||
          shift
 | 
					          shift
 | 
				
			||||||
@ -5849,12 +5941,6 @@ _process() {
 | 
				
			|||||||
        Le_HTTPPort="$_httpport"
 | 
					        Le_HTTPPort="$_httpport"
 | 
				
			||||||
        shift
 | 
					        shift
 | 
				
			||||||
        ;;
 | 
					        ;;
 | 
				
			||||||
      --tlsport)
 | 
					 | 
				
			||||||
        _tlsport="$2"
 | 
					 | 
				
			||||||
        Le_TLSPort="$_tlsport"
 | 
					 | 
				
			||||||
        shift
 | 
					 | 
				
			||||||
        ;;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      --listraw)
 | 
					      --listraw)
 | 
				
			||||||
        _listraw="raw"
 | 
					        _listraw="raw"
 | 
				
			||||||
        ;;
 | 
					        ;;
 | 
				
			||||||
@ -5881,6 +5967,9 @@ _process() {
 | 
				
			|||||||
      --no-color)
 | 
					      --no-color)
 | 
				
			||||||
        export ACME_NO_COLOR=1
 | 
					        export ACME_NO_COLOR=1
 | 
				
			||||||
        ;;
 | 
					        ;;
 | 
				
			||||||
 | 
					      --force-color)
 | 
				
			||||||
 | 
					        export ACME_FORCE_COLOR=1
 | 
				
			||||||
 | 
					        ;;
 | 
				
			||||||
      --ecc)
 | 
					      --ecc)
 | 
				
			||||||
        _ecc="isEcc"
 | 
					        _ecc="isEcc"
 | 
				
			||||||
        ;;
 | 
					        ;;
 | 
				
			||||||
@ -5919,6 +6008,9 @@ _process() {
 | 
				
			|||||||
          shift
 | 
					          shift
 | 
				
			||||||
        fi
 | 
					        fi
 | 
				
			||||||
        ;;
 | 
					        ;;
 | 
				
			||||||
 | 
					      --yes-I-know-dns-manual-mode-enough-go-ahead-please)
 | 
				
			||||||
 | 
					        export FORCE_DNS_MANUAL=1
 | 
				
			||||||
 | 
					        ;;
 | 
				
			||||||
      --log | --logfile)
 | 
					      --log | --logfile)
 | 
				
			||||||
        _log="1"
 | 
					        _log="1"
 | 
				
			||||||
        _logfile="$2"
 | 
					        _logfile="$2"
 | 
				
			||||||
@ -5972,6 +6064,10 @@ _process() {
 | 
				
			|||||||
        _use_wget="1"
 | 
					        _use_wget="1"
 | 
				
			||||||
        ACME_USE_WGET="1"
 | 
					        ACME_USE_WGET="1"
 | 
				
			||||||
        ;;
 | 
					        ;;
 | 
				
			||||||
 | 
					      --branch | -b)
 | 
				
			||||||
 | 
					        export BRANCH="$2"
 | 
				
			||||||
 | 
					        shift
 | 
				
			||||||
 | 
					        ;;
 | 
				
			||||||
      *)
 | 
					      *)
 | 
				
			||||||
        _err "Unknown parameter : $1"
 | 
					        _err "Unknown parameter : $1"
 | 
				
			||||||
        return 1
 | 
					        return 1
 | 
				
			||||||
 | 
				
			|||||||
@ -2,8 +2,12 @@
 | 
				
			|||||||
# Here is the script to deploy the cert to your cpanel using the cpanel API.
 | 
					# Here is the script to deploy the cert to your cpanel using the cpanel API.
 | 
				
			||||||
# Uses command line uapi.  --user option is needed only if run as root.
 | 
					# Uses command line uapi.  --user option is needed only if run as root.
 | 
				
			||||||
# Returns 0 when success.
 | 
					# Returns 0 when success.
 | 
				
			||||||
# Written by Santeri Kannisto <santeri.kannisto@2globalnomads.info>
 | 
					#
 | 
				
			||||||
# Public domain, 2017
 | 
					# Please note that I am no longer using Github. If you want to report an issue
 | 
				
			||||||
 | 
					# or contact me, visit https://forum.webseodesigners.com/web-design-seo-and-hosting-f16/
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Written by Santeri Kannisto <santeri.kannisto@webseodesigners.com>
 | 
				
			||||||
 | 
					# Public domain, 2017-2018
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#export DEPLOY_CPANEL_USER=myusername
 | 
					#export DEPLOY_CPANEL_USER=myusername
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -28,15 +32,9 @@ cpanel_uapi_deploy() {
 | 
				
			|||||||
    _err "The command uapi is not found."
 | 
					    _err "The command uapi is not found."
 | 
				
			||||||
    return 1
 | 
					    return 1
 | 
				
			||||||
  fi
 | 
					  fi
 | 
				
			||||||
  if ! _exists php; then
 | 
					 | 
				
			||||||
    _err "The command php is not found."
 | 
					 | 
				
			||||||
    return 1
 | 
					 | 
				
			||||||
  fi
 | 
					 | 
				
			||||||
  # read cert and key files and urlencode both
 | 
					  # read cert and key files and urlencode both
 | 
				
			||||||
  _certstr=$(cat "$_ccert")
 | 
					  _cert=$(_url_encode <"$_ccert")
 | 
				
			||||||
  _keystr=$(cat "$_ckey")
 | 
					  _key=$(_url_encode <"$_ckey")
 | 
				
			||||||
  _cert=$(php -r "echo urlencode(\"$_certstr\");")
 | 
					 | 
				
			||||||
  _key=$(php -r "echo urlencode(\"$_keystr\");")
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  _debug _cert "$_cert"
 | 
					  _debug _cert "$_cert"
 | 
				
			||||||
  _debug _key "$_key"
 | 
					  _debug _key "$_key"
 | 
				
			||||||
 | 
				
			|||||||
@ -1,11 +1,5 @@
 | 
				
			|||||||
#!/usr/bin/env sh
 | 
					#!/usr/bin/env sh
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#Here is a sample custom api script.
 | 
					 | 
				
			||||||
#This file name is "myapi.sh"
 | 
					 | 
				
			||||||
#So, here must be a method   myapi_deploy()
 | 
					 | 
				
			||||||
#Which will be called by acme.sh to deploy the cert
 | 
					 | 
				
			||||||
#returns 0 means success, otherwise error.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
########  Public functions #####################
 | 
					########  Public functions #####################
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#domain keyfile certfile cafile fullchain
 | 
					#domain keyfile certfile cafile fullchain
 | 
				
			||||||
 | 
				
			|||||||
@ -51,6 +51,7 @@ vault_cli_deploy() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  $VAULT_CMD write "${VAULT_PREFIX}/${_cdomain}/cert.pem" value=@"$_ccert" || return 1
 | 
					  $VAULT_CMD write "${VAULT_PREFIX}/${_cdomain}/cert.pem" value=@"$_ccert" || return 1
 | 
				
			||||||
  $VAULT_CMD write "${VAULT_PREFIX}/${_cdomain}/cert.key" value=@"$_ckey" || return 1
 | 
					  $VAULT_CMD write "${VAULT_PREFIX}/${_cdomain}/cert.key" value=@"$_ckey" || return 1
 | 
				
			||||||
 | 
					  $VAULT_CMD write "${VAULT_PREFIX}/${_cdomain}/chain.pem" value=@"$_cca" || return 1
 | 
				
			||||||
  $VAULT_CMD write "${VAULT_PREFIX}/${_cdomain}/fullchain.pem" value=@"$_cfullchain" || return 1
 | 
					  $VAULT_CMD write "${VAULT_PREFIX}/${_cdomain}/fullchain.pem" value=@"$_cfullchain" || return 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										131
									
								
								dnsapi/README.md
									
									
									
									
									
								
							
							
						
						
									
										131
									
								
								dnsapi/README.md
									
									
									
									
									
								
							@ -1,5 +1,9 @@
 | 
				
			|||||||
# How to use DNS API
 | 
					# How to use DNS API
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If your dns provider doesn't provide api access, you can use our dns alias mode: 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					https://github.com/Neilpang/acme.sh/wiki/DNS-alias-mode
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## 1. Use CloudFlare domain API to automatically issue cert
 | 
					## 1. Use CloudFlare domain API to automatically issue cert
 | 
				
			||||||
 | 
					
 | 
				
			||||||
First you need to login to your CloudFlare account to get your API key.
 | 
					First you need to login to your CloudFlare account to get your API key.
 | 
				
			||||||
@ -325,6 +329,8 @@ The `CY_Username`, `CY_Password` and `CY_OTP_Secret` will be saved in `~/.acme.s
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
## 17. Use Domain-Offensive/Resellerinterface/Domainrobot API
 | 
					## 17. Use Domain-Offensive/Resellerinterface/Domainrobot API
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ATTENTION: You need to be a registered Reseller to be able to use the ResellerInterface. As a normal user you can not use this method.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
You will need your login credentials (Partner ID+Password) to the Resellerinterface, and export them before you run `acme.sh`:
 | 
					You will need your login credentials (Partner ID+Password) to the Resellerinterface, and export them before you run `acme.sh`:
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
export DO_PID="KD-1234567"
 | 
					export DO_PID="KD-1234567"
 | 
				
			||||||
@ -525,8 +531,9 @@ For issues, please report to https://github.com/raidenii/acme.sh/issues.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
## 28. Use Name.com API
 | 
					## 28. Use Name.com API
 | 
				
			||||||
 | 
					
 | 
				
			||||||
You'll need to fill out the form at https://www.name.com/reseller/apply to apply
 | 
					Create your API token here: https://www.name.com/account/settings/api
 | 
				
			||||||
for API username and token.
 | 
					
 | 
				
			||||||
 | 
					Note: `Namecom_Username` should be your Name.com username and not the token name.  If you accidentally run the script with the token name as the username see `~/.acme.sh/account.conf` to fix the issue
 | 
				
			||||||
 | 
					
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
export Namecom_Username="testuser"
 | 
					export Namecom_Username="testuser"
 | 
				
			||||||
@ -638,6 +645,14 @@ acme.sh --issue --dns dns_inwx -d example.com -d www.example.com
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
The `INWX_User` and `INWX_Password` settings will be saved in `~/.acme.sh/account.conf` and will be reused when needed.
 | 
					The `INWX_User` and `INWX_Password` settings will be saved in `~/.acme.sh/account.conf` and will be reused when needed.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If your account is secured by mobile tan you have also defined the shared secret.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					export INWX_Shared_Secret="shared secret"
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					You may need to re-enable the mobile tan to gain the shared secret.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## 34. User Servercow API v1
 | 
					## 34. User Servercow API v1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Create a new user from the servercow control center. Don't forget to activate **DNS API** for this user.
 | 
					Create a new user from the servercow control center. Don't forget to activate **DNS API** for this user.
 | 
				
			||||||
@ -750,23 +765,125 @@ DNS API keys may be created at https://panel.dreamhost.com/?tree=home.api.
 | 
				
			|||||||
Ensure the created key has add and remove privelages.
 | 
					Ensure the created key has add and remove privelages.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
export DH_API_Key="<api key>"
 | 
					export DH_API_KEY="<api key>"
 | 
				
			||||||
acme.sh --issue --dns dns_dreamhost -d example.com -d www.example.com
 | 
					acme.sh --issue --dns dns_dreamhost -d example.com -d www.example.com
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
The 'DH_API_KEY' will be saved in `~/.acme.sh/account.conf` and will
 | 
					The 'DH_API_KEY' will be saved in `~/.acme.sh/account.conf` and will
 | 
				
			||||||
be reused when needed.
 | 
					be reused when needed.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## 41. Use DNSEver (https://www.dnsever.com/)
 | 
					## 41. Use DirectAdmin API
 | 
				
			||||||
 | 
					The DirectAdmin interface has it's own Let's encrypt functionality, but this
 | 
				
			||||||
 | 
					script can be used to generate certificates for names which are not hosted on
 | 
				
			||||||
 | 
					DirectAdmin
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					User must provide login data and URL to the DirectAdmin incl. port.
 | 
				
			||||||
 | 
					You can create an user which only has access to
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- CMD_API_DNS_CONTROL
 | 
				
			||||||
 | 
					- CMD_API_SHOW_DOMAINS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					By using the Login Keys function.
 | 
				
			||||||
 | 
					See also https://www.directadmin.com/api.php and https://www.directadmin.com/features.php?id=1298
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					export DA_Api="https://remoteUser:remotePassword@da.domain.tld:8443"
 | 
				
			||||||
 | 
					export DA_Api_Insecure=1
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					Set `DA_Api_Insecure` to 1 for insecure and 0 for secure -> difference is whether ssl cert is checked for validity (0) or whether it is just accepted (1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Ok, let's issue a cert now:
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					acme.sh --issue --dns dns_da -d example.com -d www.example.com
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The `DA_Api` and `DA_Api_Insecure` will be saved in `~/.acme.sh/account.conf` and will be reused when needed.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## 42. Use KingHost DNS API
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					API access must be enabled at https://painel.kinghost.com.br/painel.api.php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					export KINGHOST_Username="yourusername"
 | 
				
			||||||
 | 
					export KINGHOST_Password="yourpassword"
 | 
				
			||||||
 | 
					acme.sh --issue --dns dns_kinghost -d example.com -d *.example.com
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The `KINGHOST_username` and `KINGHOST_Password` will be saved in `~/.acme.sh/account.conf` and will be reused when needed.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## 43. Use Zilore DNS API
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					First, get your API key at https://my.zilore.com/account/api
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					export Zilore_Key="5dcad3a2-36cb-50e8-cb92-000002f9"
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Ok, let's issue a cert now:
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					acme.sh --issue --dns dns_zilore -d example.com -d *.example.com
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The `Zilore_Key` will be saved in `~/.acme.sh/account.conf` and will be reused when needed.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## 44. Use Loopia.se API
 | 
				
			||||||
 | 
					User must provide login credentials to the Loopia API.
 | 
				
			||||||
 | 
					The user needs the following permissions:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- addSubdomain
 | 
				
			||||||
 | 
					- updateZoneRecord
 | 
				
			||||||
 | 
					- getDomains
 | 
				
			||||||
 | 
					- removeSubdomain
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Set the login credentials:
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					export LOOPIA_User="user@loopiaapi"
 | 
				
			||||||
 | 
					export LOOPIA_Password="password"
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					And to issue a cert:
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					acme.sh --issue --dns dns_loopia -d example.com -d *.example.com
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The username and password will be saved in `~/.acme.sh/account.conf` and will be reused when needed.
 | 
				
			||||||
 | 
					## 45. Use ACME DNS API
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ACME DNS is a limited DNS server with RESTful HTTP API to handle ACME DNS challenges easily and securely. 
 | 
				
			||||||
 | 
					https://github.com/joohoi/acme-dns
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					export ACMEDNS_UPDATE_URL="https://auth.acme-dns.io/update"
 | 
				
			||||||
 | 
					export ACMEDNS_USERNAME="<username>"
 | 
				
			||||||
 | 
					export ACMEDNS_PASSWORD="<password>"
 | 
				
			||||||
 | 
					export ACMEDNS_SUBDOMAIN="<subdomain>"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					acme.sh --issue --dns dns_acmedns -d example.com -d www.example.com
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The credentials will be saved in `~/.acme.sh/account.conf` and will
 | 
				
			||||||
 | 
					be reused when needed.
 | 
				
			||||||
 | 
					## 46. Use TELE3 API
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					First you need to login to your TELE3 account to set your API-KEY.
 | 
				
			||||||
 | 
					https://www.tele3.cz/system-acme-api.html
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					export TELE3_Key="MS2I4uPPaI..."
 | 
				
			||||||
 | 
					export TELE3_Secret="kjhOIHGJKHg"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					acme.sh --issue --dns dns_tele3 -d example.com -d *.example.com
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The TELE3_Key and TELE3_Secret will be saved in ~/.acme.sh/account.conf and will be reused when needed.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## 47. Use DNSEver (https://www.dnsever.com/)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
You will need your login credentials (ID+PW) to the DNSEver, and export them before you run acme.sh:
 | 
					You will need your login credentials (ID+PW) to the DNSEver, and export them before you run acme.sh:
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
export DNSEVER_ID="KD-1234567"
 | 
					export DNSEVER_ID="KD-1234567"
 | 
				
			||||||
export DNSEVER_PW="cdfkjl3n2"
 | 
					export DNSEVER_PW="cdfkjl3n2"
 | 
				
			||||||
```
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
Ok, let's issue a cert now:
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
acme.sh --issue --dns dns_dnsever -d example.com -d www.example.com
 | 
					acme.sh --issue --dns dns_dnsever -d example.com -d www.example.com
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
The DNSEVER_ID and DNSEVER_PW will be saved in ~/.acme.sh/account.conf and will be reused when needed.
 | 
					The DNSEVER_ID and DNSEVER_PW will be saved in ~/.acme.sh/account.conf and will be reused when needed.
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										55
									
								
								dnsapi/dns_acmedns.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								dnsapi/dns_acmedns.sh
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,55 @@
 | 
				
			|||||||
 | 
					#!/usr/bin/env sh
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#Author: Wolfgang Ebner
 | 
				
			||||||
 | 
					#Report Bugs here: https://github.com/webner/acme.sh
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					########  Public functions #####################
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#Usage: dns_acmedns_add   _acme-challenge.www.domain.com   "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
 | 
				
			||||||
 | 
					dns_acmedns_add() {
 | 
				
			||||||
 | 
					  fulldomain=$1
 | 
				
			||||||
 | 
					  txtvalue=$2
 | 
				
			||||||
 | 
					  _info "Using acme-dns"
 | 
				
			||||||
 | 
					  _debug fulldomain "$fulldomain"
 | 
				
			||||||
 | 
					  _debug txtvalue "$txtvalue"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ACMEDNS_UPDATE_URL="${ACMEDNS_UPDATE_URL:-$(_readaccountconf_mutable ACMEDNS_UPDATE_URL)}"
 | 
				
			||||||
 | 
					  ACMEDNS_USERNAME="${ACMEDNS_USERNAME:-$(_readaccountconf_mutable ACMEDNS_USERNAME)}"
 | 
				
			||||||
 | 
					  ACMEDNS_PASSWORD="${ACMEDNS_PASSWORD:-$(_readaccountconf_mutable ACMEDNS_PASSWORD)}"
 | 
				
			||||||
 | 
					  ACMEDNS_SUBDOMAIN="${ACMEDNS_SUBDOMAIN:-$(_readaccountconf_mutable ACMEDNS_SUBDOMAIN)}"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if [ "$ACMEDNS_UPDATE_URL" = "" ]; then
 | 
				
			||||||
 | 
					    ACMEDNS_UPDATE_URL="https://auth.acme-dns.io/update"
 | 
				
			||||||
 | 
					  fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  _saveaccountconf_mutable ACMEDNS_UPDATE_URL "$ACMEDNS_UPDATE_URL"
 | 
				
			||||||
 | 
					  _saveaccountconf_mutable ACMEDNS_USERNAME "$ACMEDNS_USERNAME"
 | 
				
			||||||
 | 
					  _saveaccountconf_mutable ACMEDNS_PASSWORD "$ACMEDNS_PASSWORD"
 | 
				
			||||||
 | 
					  _saveaccountconf_mutable ACMEDNS_SUBDOMAIN "$ACMEDNS_SUBDOMAIN"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  export _H1="X-Api-User: $ACMEDNS_USERNAME"
 | 
				
			||||||
 | 
					  export _H2="X-Api-Key: $ACMEDNS_PASSWORD"
 | 
				
			||||||
 | 
					  data="{\"subdomain\":\"$ACMEDNS_SUBDOMAIN\", \"txt\": \"$txtvalue\"}"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  _debug data "$data"
 | 
				
			||||||
 | 
					  response="$(_post "$data" "$ACMEDNS_UPDATE_URL" "" "POST")"
 | 
				
			||||||
 | 
					  _debug response "$response"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if ! echo "$response" | grep "\"$txtvalue\"" >/dev/null; then
 | 
				
			||||||
 | 
					    _err "invalid response of acme-dns"
 | 
				
			||||||
 | 
					    return 1
 | 
				
			||||||
 | 
					  fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#Usage: fulldomain txtvalue
 | 
				
			||||||
 | 
					#Remove the txt record after validation.
 | 
				
			||||||
 | 
					dns_acmedns_rm() {
 | 
				
			||||||
 | 
					  fulldomain=$1
 | 
				
			||||||
 | 
					  txtvalue=$2
 | 
				
			||||||
 | 
					  _info "Using acme-dns"
 | 
				
			||||||
 | 
					  _debug fulldomain "$fulldomain"
 | 
				
			||||||
 | 
					  _debug txtvalue "$txtvalue"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					####################  Private functions below ##################################
 | 
				
			||||||
@ -76,10 +76,10 @@ dns_azure_add() {
 | 
				
			|||||||
  values="{\"value\":[\"$txtvalue\"]}"
 | 
					  values="{\"value\":[\"$txtvalue\"]}"
 | 
				
			||||||
  timestamp="$(_time)"
 | 
					  timestamp="$(_time)"
 | 
				
			||||||
  if [ "$_code" = "200" ]; then
 | 
					  if [ "$_code" = "200" ]; then
 | 
				
			||||||
    vlist="$(echo "$response" | _egrep_o "\"value\"\s*:\s*\[\s*\"[^\"]*\"\s*]" | cut -d : -f 2 | tr -d "[]\"")"
 | 
					    vlist="$(echo "$response" | _egrep_o "\"value\"\\s*:\\s*\\[\\s*\"[^\"]*\"\\s*]" | cut -d : -f 2 | tr -d "[]\"")"
 | 
				
			||||||
    _debug "existing TXT found"
 | 
					    _debug "existing TXT found"
 | 
				
			||||||
    _debug "$vlist"
 | 
					    _debug "$vlist"
 | 
				
			||||||
    existingts="$(echo "$response" | _egrep_o "\"acmetscheck\"\s*:\s*\"[^\"]*\"" | _head_n 1 | cut -d : -f 2 | tr -d "\"")"
 | 
					    existingts="$(echo "$response" | _egrep_o "\"acmetscheck\"\\s*:\\s*\"[^\"]*\"" | _head_n 1 | cut -d : -f 2 | tr -d "\"")"
 | 
				
			||||||
    if [ -z "$existingts" ]; then
 | 
					    if [ -z "$existingts" ]; then
 | 
				
			||||||
      # the record was not created by acme.sh. Copy the exisiting entires
 | 
					      # the record was not created by acme.sh. Copy the exisiting entires
 | 
				
			||||||
      existingts=$timestamp
 | 
					      existingts=$timestamp
 | 
				
			||||||
@ -99,6 +99,7 @@ dns_azure_add() {
 | 
				
			|||||||
  _azure_rest PUT "$acmeRecordURI" "$body" "$accesstoken"
 | 
					  _azure_rest PUT "$acmeRecordURI" "$body" "$accesstoken"
 | 
				
			||||||
  if [ "$_code" = "200" ] || [ "$_code" = '201' ]; then
 | 
					  if [ "$_code" = "200" ] || [ "$_code" = '201' ]; then
 | 
				
			||||||
    _info "validation value added"
 | 
					    _info "validation value added"
 | 
				
			||||||
 | 
					    return 0
 | 
				
			||||||
  else
 | 
					  else
 | 
				
			||||||
    _err "error adding validation value ($_code)"
 | 
					    _err "error adding validation value ($_code)"
 | 
				
			||||||
    return 1
 | 
					    return 1
 | 
				
			||||||
@ -171,7 +172,7 @@ dns_azure_rm() {
 | 
				
			|||||||
  _azure_rest GET "$acmeRecordURI" "" "$accesstoken"
 | 
					  _azure_rest GET "$acmeRecordURI" "" "$accesstoken"
 | 
				
			||||||
  timestamp="$(_time)"
 | 
					  timestamp="$(_time)"
 | 
				
			||||||
  if [ "$_code" = "200" ]; then
 | 
					  if [ "$_code" = "200" ]; then
 | 
				
			||||||
    vlist="$(echo "$response" | _egrep_o "\"value\"\s*:\s*\[\s*\"[^\"]*\"\s*]" | cut -d : -f 2 | tr -d "[]\"" | grep -v "$txtvalue")"
 | 
					    vlist="$(echo "$response" | _egrep_o "\"value\"\\s*:\\s*\\[\\s*\"[^\"]*\"\\s*]" | cut -d : -f 2 | tr -d "[]\"" | grep -v "$txtvalue")"
 | 
				
			||||||
    values=""
 | 
					    values=""
 | 
				
			||||||
    comma=""
 | 
					    comma=""
 | 
				
			||||||
    for v in $vlist; do
 | 
					    for v in $vlist; do
 | 
				
			||||||
@ -194,6 +195,7 @@ dns_azure_rm() {
 | 
				
			|||||||
      _azure_rest PUT "$acmeRecordURI" "$body" "$accesstoken"
 | 
					      _azure_rest PUT "$acmeRecordURI" "$body" "$accesstoken"
 | 
				
			||||||
      if [ "$_code" = "200" ] || [ "$_code" = '201' ]; then
 | 
					      if [ "$_code" = "200" ] || [ "$_code" = '201' ]; then
 | 
				
			||||||
        _info "validation value removed"
 | 
					        _info "validation value removed"
 | 
				
			||||||
 | 
					        return 0
 | 
				
			||||||
      else
 | 
					      else
 | 
				
			||||||
        _err "error removing validation value ($_code)"
 | 
					        _err "error removing validation value ($_code)"
 | 
				
			||||||
        return 1
 | 
					        return 1
 | 
				
			||||||
@ -226,8 +228,9 @@ _azure_rest() {
 | 
				
			|||||||
    else
 | 
					    else
 | 
				
			||||||
      response="$(_get "$ep")"
 | 
					      response="$(_get "$ep")"
 | 
				
			||||||
    fi
 | 
					    fi
 | 
				
			||||||
 | 
					    _ret="$?"
 | 
				
			||||||
    _secure_debug2 "response $response"
 | 
					    _secure_debug2 "response $response"
 | 
				
			||||||
    _code="$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\r\n")"
 | 
					    _code="$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\\r\\n")"
 | 
				
			||||||
    _debug "http response code $_code"
 | 
					    _debug "http response code $_code"
 | 
				
			||||||
    if [ "$_code" = "401" ]; then
 | 
					    if [ "$_code" = "401" ]; then
 | 
				
			||||||
      # we have an invalid access token set to expired
 | 
					      # we have an invalid access token set to expired
 | 
				
			||||||
@ -236,7 +239,7 @@ _azure_rest() {
 | 
				
			|||||||
      return 1
 | 
					      return 1
 | 
				
			||||||
    fi
 | 
					    fi
 | 
				
			||||||
    # See https://docs.microsoft.com/en-us/azure/architecture/best-practices/retry-service-specific#general-rest-and-retry-guidelines for retryable HTTP codes
 | 
					    # See https://docs.microsoft.com/en-us/azure/architecture/best-practices/retry-service-specific#general-rest-and-retry-guidelines for retryable HTTP codes
 | 
				
			||||||
    if [ "$?" != "0" ] || [ -z "$_code" ] || [ "$_code" = "408" ] || [ "$_code" = "500" ] || [ "$_code" = "503" ] || [ "$_code" = "504" ]; then
 | 
					    if [ "$_ret" != "0" ] || [ -z "$_code" ] || [ "$_code" = "408" ] || [ "$_code" = "500" ] || [ "$_code" = "503" ] || [ "$_code" = "504" ]; then
 | 
				
			||||||
      _request_retry_times="$(_math "$_request_retry_times" + 1)"
 | 
					      _request_retry_times="$(_math "$_request_retry_times" + 1)"
 | 
				
			||||||
      _info "REST call error $_code retrying $ep in $_request_retry_times s"
 | 
					      _info "REST call error $_code retrying $ep in $_request_retry_times s"
 | 
				
			||||||
      _sleep "$_request_retry_times"
 | 
					      _sleep "$_request_retry_times"
 | 
				
			||||||
@ -281,6 +284,7 @@ _azure_getaccess_token() {
 | 
				
			|||||||
  body="resource=$(printf "%s" 'https://management.core.windows.net/' | _url_encode)&client_id=$(printf "%s" "$clientID" | _url_encode)&client_secret=$(printf "%s" "$clientSecret" | _url_encode)&grant_type=client_credentials"
 | 
					  body="resource=$(printf "%s" 'https://management.core.windows.net/' | _url_encode)&client_id=$(printf "%s" "$clientID" | _url_encode)&client_secret=$(printf "%s" "$clientSecret" | _url_encode)&grant_type=client_credentials"
 | 
				
			||||||
  _secure_debug2 "data $body"
 | 
					  _secure_debug2 "data $body"
 | 
				
			||||||
  response="$(_post "$body" "https://login.microsoftonline.com/$tenantID/oauth2/token" "" "POST")"
 | 
					  response="$(_post "$body" "https://login.microsoftonline.com/$tenantID/oauth2/token" "" "POST")"
 | 
				
			||||||
 | 
					  _ret="$?"
 | 
				
			||||||
  _secure_debug2 "response $response"
 | 
					  _secure_debug2 "response $response"
 | 
				
			||||||
  response="$(echo "$response" | _normalizeJson)"
 | 
					  response="$(echo "$response" | _normalizeJson)"
 | 
				
			||||||
  accesstoken=$(echo "$response" | _egrep_o "\"access_token\":\"[^\"]*\"" | _head_n 1 | cut -d : -f 2 | tr -d \")
 | 
					  accesstoken=$(echo "$response" | _egrep_o "\"access_token\":\"[^\"]*\"" | _head_n 1 | cut -d : -f 2 | tr -d \")
 | 
				
			||||||
@ -290,7 +294,7 @@ _azure_getaccess_token() {
 | 
				
			|||||||
    _err "no acccess token received. Check your Azure settings see $WIKI"
 | 
					    _err "no acccess token received. Check your Azure settings see $WIKI"
 | 
				
			||||||
    return 1
 | 
					    return 1
 | 
				
			||||||
  fi
 | 
					  fi
 | 
				
			||||||
  if [ "$?" != "0" ]; then
 | 
					  if [ "$_ret" != "0" ]; then
 | 
				
			||||||
    _err "error $response"
 | 
					    _err "error $response"
 | 
				
			||||||
    return 1
 | 
					    return 1
 | 
				
			||||||
  fi
 | 
					  fi
 | 
				
			||||||
@ -304,7 +308,7 @@ _get_root() {
 | 
				
			|||||||
  domain=$1
 | 
					  domain=$1
 | 
				
			||||||
  subscriptionId=$2
 | 
					  subscriptionId=$2
 | 
				
			||||||
  accesstoken=$3
 | 
					  accesstoken=$3
 | 
				
			||||||
  i=2
 | 
					  i=1
 | 
				
			||||||
  p=1
 | 
					  p=1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ## Ref: https://docs.microsoft.com/en-us/rest/api/dns/zones/list
 | 
					  ## Ref: https://docs.microsoft.com/en-us/rest/api/dns/zones/list
 | 
				
			||||||
@ -324,9 +328,14 @@ _get_root() {
 | 
				
			|||||||
    fi
 | 
					    fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if _contains "$response" "\"name\":\"$h\"" >/dev/null; then
 | 
					    if _contains "$response" "\"name\":\"$h\"" >/dev/null; then
 | 
				
			||||||
      _domain_id=$(echo "$response" | _egrep_o "\{\"id\":\"[^\"]*$h\"" | head -n 1 | cut -d : -f 2 | tr -d \")
 | 
					      _domain_id=$(echo "$response" | _egrep_o "\\{\"id\":\"[^\"]*$h\"" | head -n 1 | cut -d : -f 2 | tr -d \")
 | 
				
			||||||
      if [ "$_domain_id" ]; then
 | 
					      if [ "$_domain_id" ]; then
 | 
				
			||||||
        _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
 | 
					        if [ "$i" = 1 ]; then
 | 
				
			||||||
 | 
					          #create the record at the domain apex (@) if only the domain name was provided as --domain-alias
 | 
				
			||||||
 | 
					          _sub_domain="@"
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					          _sub_domain=$(echo "$domain" | cut -d . -f 1-$p)
 | 
				
			||||||
 | 
					        fi
 | 
				
			||||||
        _domain=$h
 | 
					        _domain=$h
 | 
				
			||||||
        return 0
 | 
					        return 0
 | 
				
			||||||
      fi
 | 
					      fi
 | 
				
			||||||
 | 
				
			|||||||
@ -19,8 +19,8 @@ dns_cf_add() {
 | 
				
			|||||||
  if [ -z "$CF_Key" ] || [ -z "$CF_Email" ]; then
 | 
					  if [ -z "$CF_Key" ] || [ -z "$CF_Email" ]; then
 | 
				
			||||||
    CF_Key=""
 | 
					    CF_Key=""
 | 
				
			||||||
    CF_Email=""
 | 
					    CF_Email=""
 | 
				
			||||||
    _err "You don't specify cloudflare api key and email yet."
 | 
					    _err "You didn't specify a cloudflare api key and email yet."
 | 
				
			||||||
    _err "Please create you key and try again."
 | 
					    _err "Please create the key and try again."
 | 
				
			||||||
    return 1
 | 
					    return 1
 | 
				
			||||||
  fi
 | 
					  fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -94,8 +94,8 @@ dns_cf_rm() {
 | 
				
			|||||||
  if [ -z "$CF_Key" ] || [ -z "$CF_Email" ]; then
 | 
					  if [ -z "$CF_Key" ] || [ -z "$CF_Email" ]; then
 | 
				
			||||||
    CF_Key=""
 | 
					    CF_Key=""
 | 
				
			||||||
    CF_Email=""
 | 
					    CF_Email=""
 | 
				
			||||||
    _err "You don't specify cloudflare api key and email yet."
 | 
					    _err "You didn't specify a cloudflare api key and email yet."
 | 
				
			||||||
    _err "Please create you key and try again."
 | 
					    _err "Please create the key and try again."
 | 
				
			||||||
    return 1
 | 
					    return 1
 | 
				
			||||||
  fi
 | 
					  fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										184
									
								
								dnsapi/dns_da.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										184
									
								
								dnsapi/dns_da.sh
									
									
									
									
									
										Executable file
									
								
							@ -0,0 +1,184 @@
 | 
				
			|||||||
 | 
					#!/usr/bin/env sh
 | 
				
			||||||
 | 
					# -*- mode: sh; tab-width: 2; indent-tabs-mode: s; coding: utf-8 -*-
 | 
				
			||||||
 | 
					# vim: et ts=2 sw=2
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# DirectAdmin 1.41.0 API
 | 
				
			||||||
 | 
					# The DirectAdmin interface has it's own Let's encrypt functionality, but this
 | 
				
			||||||
 | 
					# script can be used to generate certificates for names which are not hosted on
 | 
				
			||||||
 | 
					# DirectAdmin
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# User must provide login data and URL to DirectAdmin incl. port.
 | 
				
			||||||
 | 
					# You can create login key, by using the Login Keys function
 | 
				
			||||||
 | 
					# ( https://da.example.com:8443/CMD_LOGIN_KEYS ), which only has access to 
 | 
				
			||||||
 | 
					# - CMD_API_DNS_CONTROL
 | 
				
			||||||
 | 
					# - CMD_API_SHOW_DOMAINS
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# See also https://www.directadmin.com/api.php and
 | 
				
			||||||
 | 
					# https://www.directadmin.com/features.php?id=1298
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Report bugs to https://github.com/TigerP/acme.sh/issues
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Values to export:
 | 
				
			||||||
 | 
					# export DA_Api="https://remoteUser:remotePassword@da.example.com:8443"
 | 
				
			||||||
 | 
					# export DA_Api_Insecure=1
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Set DA_Api_Insecure to 1 for insecure and 0 for secure -> difference is
 | 
				
			||||||
 | 
					# whether ssl cert is checked for validity (0) or whether it is just accepted
 | 
				
			||||||
 | 
					# (1)
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					########  Public functions #####################
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Usage: dns_myapi_add  _acme-challenge.www.example.com  "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
 | 
				
			||||||
 | 
					# Used to add txt record
 | 
				
			||||||
 | 
					dns_da_add() {
 | 
				
			||||||
 | 
					  fulldomain="${1}"
 | 
				
			||||||
 | 
					  txtvalue="${2}"
 | 
				
			||||||
 | 
					  _debug "Calling: dns_da_add() '${fulldomain}' '${txtvalue}'"
 | 
				
			||||||
 | 
					  _DA_credentials && _DA_getDomainInfo && _DA_addTxt
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Usage: dns_da_rm  _acme-challenge.www.example.com  "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
 | 
				
			||||||
 | 
					# Used to remove the txt record after validation
 | 
				
			||||||
 | 
					dns_da_rm() {
 | 
				
			||||||
 | 
					  fulldomain="${1}"
 | 
				
			||||||
 | 
					  txtvalue="${2}"
 | 
				
			||||||
 | 
					  _debug "Calling: dns_da_rm() '${fulldomain}' '${txtvalue}'"
 | 
				
			||||||
 | 
					  _DA_credentials && _DA_getDomainInfo && _DA_rmTxt
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					####################  Private functions below ##################################
 | 
				
			||||||
 | 
					# Usage: _DA_credentials
 | 
				
			||||||
 | 
					# It will check if the needed settings are available
 | 
				
			||||||
 | 
					_DA_credentials() {
 | 
				
			||||||
 | 
					  DA_Api="${DA_Api:-$(_readaccountconf_mutable DA_Api)}"
 | 
				
			||||||
 | 
					  DA_Api_Insecure="${DA_Api_Insecure:-$(_readaccountconf_mutable DA_Api_Insecure)}"
 | 
				
			||||||
 | 
					  if [ -z "${DA_Api}" ] || [ -z "${DA_Api_Insecure}" ]; then
 | 
				
			||||||
 | 
					    DA_Api=""
 | 
				
			||||||
 | 
					    DA_Api_Insecure=""
 | 
				
			||||||
 | 
					    _err "You haven't specified the DirectAdmin Login data, URL and whether you want check the DirectAdmin SSL cert. Please try again."
 | 
				
			||||||
 | 
					    return 1
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
 | 
					    _saveaccountconf_mutable DA_Api "${DA_Api}"
 | 
				
			||||||
 | 
					    _saveaccountconf_mutable DA_Api_Insecure "${DA_Api_Insecure}"
 | 
				
			||||||
 | 
					    # Set whether curl should use secure or insecure mode
 | 
				
			||||||
 | 
					    export HTTPS_INSECURE="${DA_Api_Insecure}"
 | 
				
			||||||
 | 
					  fi
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Usage: _get_root _acme-challenge.www.example.com
 | 
				
			||||||
 | 
					# Split the full domain to a domain and subdomain
 | 
				
			||||||
 | 
					#returns
 | 
				
			||||||
 | 
					# _sub_domain=_acme-challenge.www
 | 
				
			||||||
 | 
					# _domain=example.com
 | 
				
			||||||
 | 
					_get_root() {
 | 
				
			||||||
 | 
					  domain=$1
 | 
				
			||||||
 | 
					  i=2
 | 
				
			||||||
 | 
					  p=1
 | 
				
			||||||
 | 
					  # Get a list of all the domains
 | 
				
			||||||
 | 
					  # response will contain "list[]=example.com&list[]=example.org"
 | 
				
			||||||
 | 
					  _da_api CMD_API_SHOW_DOMAINS "" "${domain}"
 | 
				
			||||||
 | 
					  while true; do
 | 
				
			||||||
 | 
					    h=$(printf "%s" "$domain" | cut -d . -f $i-100)
 | 
				
			||||||
 | 
					    _debug h "$h"
 | 
				
			||||||
 | 
					    if [ -z "$h" ]; then
 | 
				
			||||||
 | 
					      # not valid
 | 
				
			||||||
 | 
					      _debug "The given domain $h is not valid"
 | 
				
			||||||
 | 
					      return 1
 | 
				
			||||||
 | 
					    fi
 | 
				
			||||||
 | 
					    if _contains "$response" "$h" >/dev/null; then
 | 
				
			||||||
 | 
					      _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
 | 
				
			||||||
 | 
					      _domain=$h
 | 
				
			||||||
 | 
					      return 0
 | 
				
			||||||
 | 
					    fi
 | 
				
			||||||
 | 
					    p=$i
 | 
				
			||||||
 | 
					    i=$(_math "$i" + 1)
 | 
				
			||||||
 | 
					  done
 | 
				
			||||||
 | 
					  _debug "Stop on 100"
 | 
				
			||||||
 | 
					  return 1
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Usage: _da_api CMD_API_* data example.com
 | 
				
			||||||
 | 
					# Use the DirectAdmin API and check the result
 | 
				
			||||||
 | 
					# returns
 | 
				
			||||||
 | 
					#  response="error=0&text=Result text&details="
 | 
				
			||||||
 | 
					_da_api() {
 | 
				
			||||||
 | 
					  cmd=$1
 | 
				
			||||||
 | 
					  data=$2
 | 
				
			||||||
 | 
					  domain=$3
 | 
				
			||||||
 | 
					  _debug "$domain; $data"
 | 
				
			||||||
 | 
					  response="$(_post "$data" "$DA_Api/$cmd" "" "POST")"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if [ "$?" != "0" ]; then
 | 
				
			||||||
 | 
					    _err "error $cmd"
 | 
				
			||||||
 | 
					    return 1
 | 
				
			||||||
 | 
					  fi
 | 
				
			||||||
 | 
					  _debug response "$response"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  case "${cmd}" in
 | 
				
			||||||
 | 
					    CMD_API_DNS_CONTROL)
 | 
				
			||||||
 | 
					      # Parse the result in general
 | 
				
			||||||
 | 
					      # error=0&text=Records Deleted&details=
 | 
				
			||||||
 | 
					      # error=1&text=Cannot View Dns Record&details=No domain provided
 | 
				
			||||||
 | 
					      err_field="$(_getfield "$response" 1 '&')"
 | 
				
			||||||
 | 
					      txt_field="$(_getfield "$response" 2 '&')"
 | 
				
			||||||
 | 
					      details_field="$(_getfield "$response" 3 '&')"
 | 
				
			||||||
 | 
					      error="$(_getfield "$err_field" 2 '=')"
 | 
				
			||||||
 | 
					      text="$(_getfield "$txt_field" 2 '=')"
 | 
				
			||||||
 | 
					      details="$(_getfield "$details_field" 2 '=')"
 | 
				
			||||||
 | 
					      _debug "error: ${error}, text: ${text}, details: ${details}"
 | 
				
			||||||
 | 
					      if [ "$error" != "0" ]; then
 | 
				
			||||||
 | 
					        _err "error $response"
 | 
				
			||||||
 | 
					        return 1
 | 
				
			||||||
 | 
					      fi
 | 
				
			||||||
 | 
					      ;;
 | 
				
			||||||
 | 
					    CMD_API_SHOW_DOMAINS) ;;
 | 
				
			||||||
 | 
					  esac
 | 
				
			||||||
 | 
					  return 0
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Usage: _DA_getDomainInfo
 | 
				
			||||||
 | 
					# Get the root zone if possible
 | 
				
			||||||
 | 
					_DA_getDomainInfo() {
 | 
				
			||||||
 | 
					  _debug "First detect the root zone"
 | 
				
			||||||
 | 
					  if ! _get_root "$fulldomain"; then
 | 
				
			||||||
 | 
					    _err "invalid domain"
 | 
				
			||||||
 | 
					    return 1
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
 | 
					    _debug "The root domain: $_domain"
 | 
				
			||||||
 | 
					    _debug "The sub domain: $_sub_domain"
 | 
				
			||||||
 | 
					  fi
 | 
				
			||||||
 | 
					  return 0
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Usage: _DA_addTxt
 | 
				
			||||||
 | 
					# Use the API to add a record
 | 
				
			||||||
 | 
					_DA_addTxt() {
 | 
				
			||||||
 | 
					  curData="domain=${_domain}&action=add&type=TXT&name=${_sub_domain}&value=\"${txtvalue}\""
 | 
				
			||||||
 | 
					  _debug "Calling _DA_addTxt: '${curData}' '${DA_Api}/CMD_API_DNS_CONTROL'"
 | 
				
			||||||
 | 
					  _da_api CMD_API_DNS_CONTROL "${curData}" "${_domain}"
 | 
				
			||||||
 | 
					  _debug "Result of _DA_addTxt: '$response'"
 | 
				
			||||||
 | 
					  if _contains "${response}" 'error=0'; then
 | 
				
			||||||
 | 
					    _debug "Add TXT succeeded"
 | 
				
			||||||
 | 
					    return 0
 | 
				
			||||||
 | 
					  fi
 | 
				
			||||||
 | 
					  _debug "Add TXT failed"
 | 
				
			||||||
 | 
					  return 1
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Usage: _DA_rmTxt
 | 
				
			||||||
 | 
					# Use the API to remove a record
 | 
				
			||||||
 | 
					_DA_rmTxt() {
 | 
				
			||||||
 | 
					  curData="domain=${_domain}&action=select&txtrecs0=name=${_sub_domain}&value=\"${txtvalue}\""
 | 
				
			||||||
 | 
					  _debug "Calling _DA_rmTxt: '${curData}' '${DA_Api}/CMD_API_DNS_CONTROL'"
 | 
				
			||||||
 | 
					  if _da_api CMD_API_DNS_CONTROL "${curData}" "${_domain}"; then
 | 
				
			||||||
 | 
					    _debug "Result of _DA_rmTxt: '$response'"
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
 | 
					    _err "Result of _DA_rmTxt: '$response'"
 | 
				
			||||||
 | 
					  fi
 | 
				
			||||||
 | 
					  if _contains "${response}" 'error=0'; then
 | 
				
			||||||
 | 
					    _debug "RM TXT succeeded"
 | 
				
			||||||
 | 
					    return 0
 | 
				
			||||||
 | 
					  fi
 | 
				
			||||||
 | 
					  _debug "RM TXT failed"
 | 
				
			||||||
 | 
					  return 1
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -20,12 +20,22 @@
 | 
				
			|||||||
dns_dgon_add() {
 | 
					dns_dgon_add() {
 | 
				
			||||||
  fulldomain="$(echo "$1" | _lower_case)"
 | 
					  fulldomain="$(echo "$1" | _lower_case)"
 | 
				
			||||||
  txtvalue=$2
 | 
					  txtvalue=$2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  DO_API_KEY="${DO_API_KEY:-$(_readaccountconf_mutable DO_API_KEY)}"
 | 
				
			||||||
 | 
					  # Check if API Key Exist
 | 
				
			||||||
 | 
					  if [ -z "$DO_API_KEY" ]; then
 | 
				
			||||||
 | 
					    DO_API_KEY=""
 | 
				
			||||||
 | 
					    _err "You did not specify DigitalOcean API key."
 | 
				
			||||||
 | 
					    _err "Please export DO_API_KEY and try again."
 | 
				
			||||||
 | 
					    return 1
 | 
				
			||||||
 | 
					  fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  _info "Using digitalocean dns validation - add record"
 | 
					  _info "Using digitalocean dns validation - add record"
 | 
				
			||||||
  _debug fulldomain "$fulldomain"
 | 
					  _debug fulldomain "$fulldomain"
 | 
				
			||||||
  _debug txtvalue "$txtvalue"
 | 
					  _debug txtvalue "$txtvalue"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ## save the env vars (key and domain split location) for later automated use
 | 
					  ## save the env vars (key and domain split location) for later automated use
 | 
				
			||||||
  _saveaccountconf DO_API_KEY "$DO_API_KEY"
 | 
					  _saveaccountconf_mutable DO_API_KEY "$DO_API_KEY"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ## split the domain for DO API
 | 
					  ## split the domain for DO API
 | 
				
			||||||
  if ! _get_base_domain "$fulldomain"; then
 | 
					  if ! _get_base_domain "$fulldomain"; then
 | 
				
			||||||
@ -39,7 +49,7 @@ dns_dgon_add() {
 | 
				
			|||||||
  export _H1="Content-Type: application/json"
 | 
					  export _H1="Content-Type: application/json"
 | 
				
			||||||
  export _H2="Authorization: Bearer $DO_API_KEY"
 | 
					  export _H2="Authorization: Bearer $DO_API_KEY"
 | 
				
			||||||
  PURL='https://api.digitalocean.com/v2/domains/'$_domain'/records'
 | 
					  PURL='https://api.digitalocean.com/v2/domains/'$_domain'/records'
 | 
				
			||||||
  PBODY='{"type":"TXT","name":"'$_sub_domain'","data":"'$txtvalue'"}'
 | 
					  PBODY='{"type":"TXT","name":"'$_sub_domain'","data":"'$txtvalue'","ttl":120}'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  _debug PURL "$PURL"
 | 
					  _debug PURL "$PURL"
 | 
				
			||||||
  _debug PBODY "$PBODY"
 | 
					  _debug PBODY "$PBODY"
 | 
				
			||||||
@ -65,6 +75,16 @@ dns_dgon_add() {
 | 
				
			|||||||
dns_dgon_rm() {
 | 
					dns_dgon_rm() {
 | 
				
			||||||
  fulldomain="$(echo "$1" | _lower_case)"
 | 
					  fulldomain="$(echo "$1" | _lower_case)"
 | 
				
			||||||
  txtvalue=$2
 | 
					  txtvalue=$2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  DO_API_KEY="${DO_API_KEY:-$(_readaccountconf_mutable DO_API_KEY)}"
 | 
				
			||||||
 | 
					  # Check if API Key Exist
 | 
				
			||||||
 | 
					  if [ -z "$DO_API_KEY" ]; then
 | 
				
			||||||
 | 
					    DO_API_KEY=""
 | 
				
			||||||
 | 
					    _err "You did not specify DigitalOcean API key."
 | 
				
			||||||
 | 
					    _err "Please export DO_API_KEY and try again."
 | 
				
			||||||
 | 
					    return 1
 | 
				
			||||||
 | 
					  fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  _info "Using digitalocean dns validation - remove record"
 | 
					  _info "Using digitalocean dns validation - remove record"
 | 
				
			||||||
  _debug fulldomain "$fulldomain"
 | 
					  _debug fulldomain "$fulldomain"
 | 
				
			||||||
  _debug txtvalue "$txtvalue"
 | 
					  _debug txtvalue "$txtvalue"
 | 
				
			||||||
@ -92,11 +112,11 @@ dns_dgon_rm() {
 | 
				
			|||||||
    domain_list="$(_get "$GURL")"
 | 
					    domain_list="$(_get "$GURL")"
 | 
				
			||||||
    ## 2) find record
 | 
					    ## 2) find record
 | 
				
			||||||
    ## check for what we are looing for: "type":"A","name":"$_sub_domain"
 | 
					    ## check for what we are looing for: "type":"A","name":"$_sub_domain"
 | 
				
			||||||
    record="$(echo "$domain_list" | _egrep_o "\"id\"\s*\:\s*\"*\d+\"*[^}]*\"name\"\s*\:\s*\"$_sub_domain\"[^}]*\"data\"\s*\:\s*\"$txtvalue\"")"
 | 
					    record="$(echo "$domain_list" | _egrep_o "\"id\"\s*\:\s*\"*[0-9]+\"*[^}]*\"name\"\s*\:\s*\"$_sub_domain\"[^}]*\"data\"\s*\:\s*\"$txtvalue\"")"
 | 
				
			||||||
    ## 3) check record and get next page
 | 
					    ## 3) check record and get next page
 | 
				
			||||||
    if [ -z "$record" ]; then
 | 
					    if [ -z "$record" ]; then
 | 
				
			||||||
      ## find the next page if we dont have a match
 | 
					      ## find the next page if we dont have a match
 | 
				
			||||||
      nextpage="$(echo "$domain_list" | _egrep_o "\"links\".*" | _egrep_o "\"next\".*" | _egrep_o "http.*page\=\d+")"
 | 
					      nextpage="$(echo "$domain_list" | _egrep_o "\"links\".*" | _egrep_o "\"next\".*" | _egrep_o "http.*page\=[0-9]+")"
 | 
				
			||||||
      if [ -z "$nextpage" ]; then
 | 
					      if [ -z "$nextpage" ]; then
 | 
				
			||||||
        _err "no record and no nextpage in digital ocean DNS removal"
 | 
					        _err "no record and no nextpage in digital ocean DNS removal"
 | 
				
			||||||
        return 1
 | 
					        return 1
 | 
				
			||||||
@ -108,7 +128,7 @@ dns_dgon_rm() {
 | 
				
			|||||||
  done
 | 
					  done
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ## we found the record
 | 
					  ## we found the record
 | 
				
			||||||
  rec_id="$(echo "$record" | _egrep_o "id\"\s*\:\s*\"*\d+" | _egrep_o "\d+")"
 | 
					  rec_id="$(echo "$record" | _egrep_o "id\"\s*\:\s*\"*[0-9]+" | _egrep_o "[0-9]+")"
 | 
				
			||||||
  _debug rec_id "$rec_id"
 | 
					  _debug rec_id "$rec_id"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ## delete the record
 | 
					  ## delete the record
 | 
				
			||||||
 | 
				
			|||||||
@ -39,7 +39,6 @@ dns_dnsimple_add() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  _get_records "$_account_id" "$_domain" "$_sub_domain"
 | 
					  _get_records "$_account_id" "$_domain" "$_sub_domain"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if [ "$_records_count" = "0" ]; then
 | 
					 | 
				
			||||||
  _info "Adding record"
 | 
					  _info "Adding record"
 | 
				
			||||||
  if _dnsimple_rest POST "$_account_id/zones/$_domain/records" "{\"type\":\"TXT\",\"name\":\"$_sub_domain\",\"content\":\"$txtvalue\",\"ttl\":120}"; then
 | 
					  if _dnsimple_rest POST "$_account_id/zones/$_domain/records" "{\"type\":\"TXT\",\"name\":\"$_sub_domain\",\"content\":\"$txtvalue\",\"ttl\":120}"; then
 | 
				
			||||||
    if printf -- "%s" "$response" | grep "\"name\":\"$_sub_domain\"" >/dev/null; then
 | 
					    if printf -- "%s" "$response" | grep "\"name\":\"$_sub_domain\"" >/dev/null; then
 | 
				
			||||||
@ -51,22 +50,6 @@ dns_dnsimple_add() {
 | 
				
			|||||||
    fi
 | 
					    fi
 | 
				
			||||||
  fi
 | 
					  fi
 | 
				
			||||||
  _err "Add txt record error."
 | 
					  _err "Add txt record error."
 | 
				
			||||||
  else
 | 
					 | 
				
			||||||
    _info "Updating record"
 | 
					 | 
				
			||||||
    _extract_record_id "$_records" "$_sub_domain"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if _dnsimple_rest \
 | 
					 | 
				
			||||||
      PATCH \
 | 
					 | 
				
			||||||
      "$_account_id/zones/$_domain/records/$_record_id" \
 | 
					 | 
				
			||||||
      "{\"type\":\"TXT\",\"name\":\"$_sub_domain\",\"content\":\"$txtvalue\",\"ttl\":120}"; then
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      _info "Updated!"
 | 
					 | 
				
			||||||
      return 0
 | 
					 | 
				
			||||||
    fi
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    _err "Update error"
 | 
					 | 
				
			||||||
    return 1
 | 
					 | 
				
			||||||
  fi
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# fulldomain
 | 
					# fulldomain
 | 
				
			||||||
@ -84,19 +67,19 @@ dns_dnsimple_rm() {
 | 
				
			|||||||
  fi
 | 
					  fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  _get_records "$_account_id" "$_domain" "$_sub_domain"
 | 
					  _get_records "$_account_id" "$_domain" "$_sub_domain"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  _extract_record_id "$_records" "$_sub_domain"
 | 
					  _extract_record_id "$_records" "$_sub_domain"
 | 
				
			||||||
 | 
					 | 
				
			||||||
  if [ "$_record_id" ]; then
 | 
					  if [ "$_record_id" ]; then
 | 
				
			||||||
 | 
					    echo "$_record_id" | while read -r item; do
 | 
				
			||||||
    if _dnsimple_rest DELETE "$_account_id/zones/$_domain/records/$_record_id"; then
 | 
					      if _dnsimple_rest DELETE "$_account_id/zones/$_domain/records/$item"; then
 | 
				
			||||||
      _info "removed record" "$_record_id"
 | 
					        _info "removed record" "$item"
 | 
				
			||||||
        return 0
 | 
					        return 0
 | 
				
			||||||
    fi
 | 
					      else
 | 
				
			||||||
  fi
 | 
					        _err "failed to remove record" "$item"
 | 
				
			||||||
 | 
					 | 
				
			||||||
  _err "failed to remove record" "$_record_id"
 | 
					 | 
				
			||||||
        return 1
 | 
					        return 1
 | 
				
			||||||
 | 
					      fi
 | 
				
			||||||
 | 
					    done
 | 
				
			||||||
 | 
					  fi
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
####################  Private functions bellow ##################################
 | 
					####################  Private functions bellow ##################################
 | 
				
			||||||
 | 
				
			|||||||
@ -53,8 +53,9 @@ dns_freedns_add() {
 | 
				
			|||||||
  i="$(_math "$i" - 1)"
 | 
					  i="$(_math "$i" - 1)"
 | 
				
			||||||
  sub_domain="$(echo "$fulldomain" | cut -d. -f -"$i")"
 | 
					  sub_domain="$(echo "$fulldomain" | cut -d. -f -"$i")"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  _debug top_domain "$top_domain"
 | 
					  _debug "top_domain: $top_domain"
 | 
				
			||||||
  _debug sub_domain "$sub_domain"
 | 
					  _debug "sub_domain: $sub_domain"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # Sometimes FreeDNS does not return the subdomain page but rather
 | 
					  # Sometimes FreeDNS does not return the subdomain page but rather
 | 
				
			||||||
  # returns a page regarding becoming a premium member.  This usually
 | 
					  # returns a page regarding becoming a premium member.  This usually
 | 
				
			||||||
  # happens after a period of inactivity.  Immediately trying again
 | 
					  # happens after a period of inactivity.  Immediately trying again
 | 
				
			||||||
@ -63,6 +64,7 @@ dns_freedns_add() {
 | 
				
			|||||||
  attempts=2
 | 
					  attempts=2
 | 
				
			||||||
  while [ "$attempts" -gt "0" ]; do
 | 
					  while [ "$attempts" -gt "0" ]; do
 | 
				
			||||||
    attempts="$(_math "$attempts" - 1)"
 | 
					    attempts="$(_math "$attempts" - 1)"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    htmlpage="$(_freedns_retrieve_subdomain_page "$FREEDNS_COOKIE")"
 | 
					    htmlpage="$(_freedns_retrieve_subdomain_page "$FREEDNS_COOKIE")"
 | 
				
			||||||
    if [ "$?" != "0" ]; then
 | 
					    if [ "$?" != "0" ]; then
 | 
				
			||||||
      if [ "$using_cached_cookies" = "true" ]; then
 | 
					      if [ "$using_cached_cookies" = "true" ]; then
 | 
				
			||||||
@ -71,10 +73,9 @@ dns_freedns_add() {
 | 
				
			|||||||
      fi
 | 
					      fi
 | 
				
			||||||
      return 1
 | 
					      return 1
 | 
				
			||||||
    fi
 | 
					    fi
 | 
				
			||||||
    _debug2 htmlpage "$htmlpage"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    subdomain_csv="$(echo "$htmlpage" | tr -d "\n\r" | _egrep_o '<form .*</form>' | sed 's/<tr>/@<tr>/g' | tr '@' '\n' | grep edit.php | grep "$top_domain")"
 | 
					    subdomain_csv="$(echo "$htmlpage" | tr -d "\n\r" | _egrep_o '<form .*</form>' | sed 's/<tr>/@<tr>/g' | tr '@' '\n' | grep edit.php | grep "$top_domain")"
 | 
				
			||||||
    _debug2 subdomain_csv "$subdomain_csv"
 | 
					    _debug3 "subdomain_csv: $subdomain_csv"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # The above beauty ends with striping out rows that do not have an
 | 
					    # The above beauty ends with striping out rows that do not have an
 | 
				
			||||||
    # href to edit.php and do not have the top domain we are looking for.
 | 
					    # href to edit.php and do not have the top domain we are looking for.
 | 
				
			||||||
@ -85,55 +86,25 @@ dns_freedns_add() {
 | 
				
			|||||||
    lines="$(echo "$subdomain_csv" | wc -l)"
 | 
					    lines="$(echo "$subdomain_csv" | wc -l)"
 | 
				
			||||||
    i=0
 | 
					    i=0
 | 
				
			||||||
    found=0
 | 
					    found=0
 | 
				
			||||||
 | 
					    DNSdomainid=""
 | 
				
			||||||
    while [ "$i" -lt "$lines" ]; do
 | 
					    while [ "$i" -lt "$lines" ]; do
 | 
				
			||||||
      i="$(_math "$i" + 1)"
 | 
					      i="$(_math "$i" + 1)"
 | 
				
			||||||
      line="$(echo "$subdomain_csv" | sed -n "${i}p")"
 | 
					      line="$(echo "$subdomain_csv" | sed -n "${i}p")"
 | 
				
			||||||
      _debug2 line "$line"
 | 
					      _debug2 "line: $line"
 | 
				
			||||||
      if [ $found = 0 ] && _contains "$line" "<td>$top_domain</td>"; then
 | 
					      if [ $found = 0 ] && _contains "$line" "<td>$top_domain</td>"; then
 | 
				
			||||||
        # this line will contain DNSdomainid for the top_domain
 | 
					        # this line will contain DNSdomainid for the top_domain
 | 
				
			||||||
        DNSdomainid="$(echo "$line" | _egrep_o "edit_domain_id *= *.*>" | cut -d = -f 2 | cut -d '>' -f 1)"
 | 
					        DNSdomainid="$(echo "$line" | _egrep_o "edit_domain_id *= *.*>" | cut -d = -f 2 | cut -d '>' -f 1)"
 | 
				
			||||||
        _debug2 DNSdomainid "$DNSdomainid"
 | 
					        _debug2 "DNSdomainid: $DNSdomainid"
 | 
				
			||||||
        found=1
 | 
					        found=1
 | 
				
			||||||
      else
 | 
					 | 
				
			||||||
        # lines contain DNS records for all subdomains
 | 
					 | 
				
			||||||
        DNSname="$(echo "$line" | _egrep_o 'edit.php.*</a>' | cut -d '>' -f 2 | cut -d '<' -f 1)"
 | 
					 | 
				
			||||||
        _debug2 DNSname "$DNSname"
 | 
					 | 
				
			||||||
        DNStype="$(echo "$line" | sed 's/<td/@<td/g' | tr '@' '\n' | sed -n '4p' | cut -d '>' -f 2 | cut -d '<' -f 1)"
 | 
					 | 
				
			||||||
        _debug2 DNStype "$DNStype"
 | 
					 | 
				
			||||||
        if [ "$DNSname" = "$fulldomain" ] && [ "$DNStype" = "TXT" ]; then
 | 
					 | 
				
			||||||
          DNSdataid="$(echo "$line" | _egrep_o 'data_id=.*' | cut -d = -f 2 | cut -d '>' -f 1)"
 | 
					 | 
				
			||||||
          # Now get current value for the TXT record.  This method may
 | 
					 | 
				
			||||||
          # not produce accurate results as the value field is truncated
 | 
					 | 
				
			||||||
          # on this webpage. To get full value we would need to load
 | 
					 | 
				
			||||||
          # another page. However we don't really need this so long as
 | 
					 | 
				
			||||||
          # there is only one TXT record for the acme challenge subdomain.
 | 
					 | 
				
			||||||
          DNSvalue="$(echo "$line" | sed 's/<td/@<td/g' | tr '@' '\n' | sed -n '5p' | cut -d '>' -f 2 | cut -d '<' -f 1)"
 | 
					 | 
				
			||||||
          _debug2 DNSvalue "$DNSvalue"
 | 
					 | 
				
			||||||
          if [ $found != 0 ]; then
 | 
					 | 
				
			||||||
        break
 | 
					        break
 | 
				
			||||||
            # we are breaking out of the loop at the first match of DNS name
 | 
					 | 
				
			||||||
            # and DNS type (if we are past finding the domainid). This assumes
 | 
					 | 
				
			||||||
            # that there is only ever one TXT record for the LetsEncrypt/acme
 | 
					 | 
				
			||||||
            # challenge subdomain.  This seems to be a reasonable assumption
 | 
					 | 
				
			||||||
            # as the acme client deletes the TXT record on successful validation.
 | 
					 | 
				
			||||||
          fi
 | 
					 | 
				
			||||||
        else
 | 
					 | 
				
			||||||
          DNSname=""
 | 
					 | 
				
			||||||
          DNStype=""
 | 
					 | 
				
			||||||
        fi
 | 
					 | 
				
			||||||
      fi
 | 
					      fi
 | 
				
			||||||
    done
 | 
					    done
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    _debug "DNSname: $DNSname DNStype: $DNStype DNSdomainid: $DNSdomainid DNSdataid: $DNSdataid"
 | 
					 | 
				
			||||||
    _debug "DNSvalue: $DNSvalue"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if [ -z "$DNSdomainid" ]; then
 | 
					    if [ -z "$DNSdomainid" ]; then
 | 
				
			||||||
      # If domain ID is empty then something went wrong (top level
 | 
					      # If domain ID is empty then something went wrong (top level
 | 
				
			||||||
      # domain not found at FreeDNS).
 | 
					      # domain not found at FreeDNS).
 | 
				
			||||||
      if [ "$attempts" = "0" ]; then
 | 
					      if [ "$attempts" = "0" ]; then
 | 
				
			||||||
        # exhausted maximum retry attempts
 | 
					        # exhausted maximum retry attempts
 | 
				
			||||||
        _debug "$htmlpage"
 | 
					 | 
				
			||||||
        _debug "$subdomain_csv"
 | 
					 | 
				
			||||||
        _err "Domain $top_domain not found at FreeDNS"
 | 
					        _err "Domain $top_domain not found at FreeDNS"
 | 
				
			||||||
        return 1
 | 
					        return 1
 | 
				
			||||||
      fi
 | 
					      fi
 | 
				
			||||||
@ -145,33 +116,10 @@ dns_freedns_add() {
 | 
				
			|||||||
    _info "Retry loading subdomain page ($attempts attempts remaining)"
 | 
					    _info "Retry loading subdomain page ($attempts attempts remaining)"
 | 
				
			||||||
  done
 | 
					  done
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if [ -z "$DNSdataid" ]; then
 | 
					  # Add in new TXT record with the value provided
 | 
				
			||||||
    # If data ID is empty then specific subdomain does not exist yet, need
 | 
					  _debug "Adding TXT record for $fulldomain, $txtvalue"
 | 
				
			||||||
    # to create it this should always be the case as the acme client
 | 
					 | 
				
			||||||
    # deletes the entry after domain is validated.
 | 
					 | 
				
			||||||
  _freedns_add_txt_record "$FREEDNS_COOKIE" "$DNSdomainid" "$sub_domain" "$txtvalue"
 | 
					  _freedns_add_txt_record "$FREEDNS_COOKIE" "$DNSdomainid" "$sub_domain" "$txtvalue"
 | 
				
			||||||
  return $?
 | 
					  return $?
 | 
				
			||||||
  else
 | 
					 | 
				
			||||||
    if [ "$txtvalue" = "$DNSvalue" ]; then
 | 
					 | 
				
			||||||
      # if value in TXT record matches value requested then DNS record
 | 
					 | 
				
			||||||
      # does not need to be updated. But...
 | 
					 | 
				
			||||||
      # Testing value match fails.  Website is truncating the value field.
 | 
					 | 
				
			||||||
      # So for now we will always go down the else path.  Though in theory
 | 
					 | 
				
			||||||
      # should never come here anyway as the acme client deletes
 | 
					 | 
				
			||||||
      # the TXT record on successful validation, so we should not even
 | 
					 | 
				
			||||||
      # have found a TXT record !!
 | 
					 | 
				
			||||||
      _info "No update necessary for $fulldomain at FreeDNS"
 | 
					 | 
				
			||||||
      return 0
 | 
					 | 
				
			||||||
    else
 | 
					 | 
				
			||||||
      # Delete the old TXT record (with the wrong value)
 | 
					 | 
				
			||||||
      if _freedns_delete_txt_record "$FREEDNS_COOKIE" "$DNSdataid"; then
 | 
					 | 
				
			||||||
        # And add in new TXT record with the value provided
 | 
					 | 
				
			||||||
        _freedns_add_txt_record "$FREEDNS_COOKIE" "$DNSdomainid" "$sub_domain" "$txtvalue"
 | 
					 | 
				
			||||||
      fi
 | 
					 | 
				
			||||||
      return $?
 | 
					 | 
				
			||||||
    fi
 | 
					 | 
				
			||||||
  fi
 | 
					 | 
				
			||||||
  return 0
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#Usage: fulldomain txtvalue
 | 
					#Usage: fulldomain txtvalue
 | 
				
			||||||
@ -205,7 +153,7 @@ dns_freedns_rm() {
 | 
				
			|||||||
    fi
 | 
					    fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    subdomain_csv="$(echo "$htmlpage" | tr -d "\n\r" | _egrep_o '<form .*</form>' | sed 's/<tr>/@<tr>/g' | tr '@' '\n' | grep edit.php | grep "$fulldomain")"
 | 
					    subdomain_csv="$(echo "$htmlpage" | tr -d "\n\r" | _egrep_o '<form .*</form>' | sed 's/<tr>/@<tr>/g' | tr '@' '\n' | grep edit.php | grep "$fulldomain")"
 | 
				
			||||||
    _debug2 subdomain_csv "$subdomain_csv"
 | 
					    _debug3 "subdomain_csv: $subdomain_csv"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # The above beauty ends with striping out rows that do not have an
 | 
					    # The above beauty ends with striping out rows that do not have an
 | 
				
			||||||
    # href to edit.php and do not have the domain name we are looking for.
 | 
					    # href to edit.php and do not have the domain name we are looking for.
 | 
				
			||||||
@ -216,35 +164,51 @@ dns_freedns_rm() {
 | 
				
			|||||||
    lines="$(echo "$subdomain_csv" | wc -l)"
 | 
					    lines="$(echo "$subdomain_csv" | wc -l)"
 | 
				
			||||||
    i=0
 | 
					    i=0
 | 
				
			||||||
    found=0
 | 
					    found=0
 | 
				
			||||||
 | 
					    DNSdataid=""
 | 
				
			||||||
    while [ "$i" -lt "$lines" ]; do
 | 
					    while [ "$i" -lt "$lines" ]; do
 | 
				
			||||||
      i="$(_math "$i" + 1)"
 | 
					      i="$(_math "$i" + 1)"
 | 
				
			||||||
      line="$(echo "$subdomain_csv" | sed -n "${i}p")"
 | 
					      line="$(echo "$subdomain_csv" | sed -n "${i}p")"
 | 
				
			||||||
      _debug2 line "$line"
 | 
					      _debug3 "line: $line"
 | 
				
			||||||
      DNSname="$(echo "$line" | _egrep_o 'edit.php.*</a>' | cut -d '>' -f 2 | cut -d '<' -f 1)"
 | 
					      DNSname="$(echo "$line" | _egrep_o 'edit.php.*</a>' | cut -d '>' -f 2 | cut -d '<' -f 1)"
 | 
				
			||||||
      _debug2 DNSname "$DNSname"
 | 
					      _debug2 "DNSname: $DNSname"
 | 
				
			||||||
 | 
					      if [ "$DNSname" = "$fulldomain" ]; then
 | 
				
			||||||
        DNStype="$(echo "$line" | sed 's/<td/@<td/g' | tr '@' '\n' | sed -n '4p' | cut -d '>' -f 2 | cut -d '<' -f 1)"
 | 
					        DNStype="$(echo "$line" | sed 's/<td/@<td/g' | tr '@' '\n' | sed -n '4p' | cut -d '>' -f 2 | cut -d '<' -f 1)"
 | 
				
			||||||
      _debug2 DNStype "$DNStype"
 | 
					        _debug2 "DNStype: $DNStype"
 | 
				
			||||||
      if [ "$DNSname" = "$fulldomain" ] && [ "$DNStype" = "TXT" ]; then
 | 
					        if [ "$DNStype" = "TXT" ]; then
 | 
				
			||||||
          DNSdataid="$(echo "$line" | _egrep_o 'data_id=.*' | cut -d = -f 2 | cut -d '>' -f 1)"
 | 
					          DNSdataid="$(echo "$line" | _egrep_o 'data_id=.*' | cut -d = -f 2 | cut -d '>' -f 1)"
 | 
				
			||||||
        _debug2 DNSdataid "$DNSdataid"
 | 
					          _debug2 "DNSdataid: $DNSdataid"
 | 
				
			||||||
          DNSvalue="$(echo "$line" | sed 's/<td/@<td/g' | tr '@' '\n' | sed -n '5p' | cut -d '>' -f 2 | cut -d '<' -f 1)"
 | 
					          DNSvalue="$(echo "$line" | sed 's/<td/@<td/g' | tr '@' '\n' | sed -n '5p' | cut -d '>' -f 2 | cut -d '<' -f 1)"
 | 
				
			||||||
        _debug2 DNSvalue "$DNSvalue"
 | 
					          if _startswith "$DNSvalue" """; then
 | 
				
			||||||
        #     if [ "$DNSvalue" = "$txtvalue" ]; then
 | 
					            # remove the quotation from the start
 | 
				
			||||||
        # Testing value match fails.  Website is truncating the value
 | 
					            DNSvalue="$(echo "$DNSvalue" | cut -c 7-)"
 | 
				
			||||||
        # field. So for now we will assume that there is only one TXT
 | 
					          fi
 | 
				
			||||||
        # field for the sub domain and just delete it. Currently this
 | 
					          if _endswith "$DNSvalue" "..."; then
 | 
				
			||||||
        # is a safe assumption.
 | 
					            # value was truncated, remove the dot dot dot from the end
 | 
				
			||||||
 | 
					            DNSvalue="$(echo "$DNSvalue" | sed 's/...$//')"
 | 
				
			||||||
 | 
					          elif _endswith "$DNSvalue" """; then
 | 
				
			||||||
 | 
					            # else remove the closing quotation from the end
 | 
				
			||||||
 | 
					            DNSvalue="$(echo "$DNSvalue" | sed 's/......$//')"
 | 
				
			||||||
 | 
					          fi
 | 
				
			||||||
 | 
					          _debug2 "DNSvalue: $DNSvalue"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          if [ -n "$DNSdataid" ] && _startswith "$txtvalue" "$DNSvalue"; then
 | 
				
			||||||
 | 
					            # Found a match. But note... Website is truncating the
 | 
				
			||||||
 | 
					            # value field so we are only testing that part that is not 
 | 
				
			||||||
 | 
					            # truncated.  This should be accurate enough.
 | 
				
			||||||
 | 
					            _debug "Deleting TXT record for $fulldomain, $txtvalue"
 | 
				
			||||||
            _freedns_delete_txt_record "$FREEDNS_COOKIE" "$DNSdataid"
 | 
					            _freedns_delete_txt_record "$FREEDNS_COOKIE" "$DNSdataid"
 | 
				
			||||||
            return $?
 | 
					            return $?
 | 
				
			||||||
        #     fi
 | 
					          fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        fi
 | 
				
			||||||
      fi
 | 
					      fi
 | 
				
			||||||
    done
 | 
					    done
 | 
				
			||||||
  done
 | 
					  done
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # If we get this far we did not find a match (after two attempts)
 | 
					  # If we get this far we did not find a match (after two attempts)
 | 
				
			||||||
  # Not necessarily an error, but log anyway.
 | 
					  # Not necessarily an error, but log anyway.
 | 
				
			||||||
  _debug2 "$subdomain_csv"
 | 
					  _debug3 "$subdomain_csv"
 | 
				
			||||||
  _info "Cannot delete TXT record for $fulldomain/$txtvalue. Does not exist at FreeDNS"
 | 
					  _info "Cannot delete TXT record for $fulldomain, $txtvalue. Does not exist at FreeDNS"
 | 
				
			||||||
  return 0
 | 
					  return 0
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -272,7 +236,7 @@ _freedns_login() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  # if cookies is not empty then logon successful
 | 
					  # if cookies is not empty then logon successful
 | 
				
			||||||
  if [ -z "$cookies" ]; then
 | 
					  if [ -z "$cookies" ]; then
 | 
				
			||||||
    _debug "$htmlpage"
 | 
					    _debug3 "htmlpage: $htmlpage"
 | 
				
			||||||
    _err "FreeDNS login failed for user $username. Check $HTTP_HEADER file"
 | 
					    _err "FreeDNS login failed for user $username. Check $HTTP_HEADER file"
 | 
				
			||||||
    return 1
 | 
					    return 1
 | 
				
			||||||
  fi
 | 
					  fi
 | 
				
			||||||
@ -301,7 +265,7 @@ _freedns_retrieve_subdomain_page() {
 | 
				
			|||||||
    return 1
 | 
					    return 1
 | 
				
			||||||
  fi
 | 
					  fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  _debug2 "$htmlpage"
 | 
					  _debug3 "htmlpage: $htmlpage"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  printf "%s" "$htmlpage"
 | 
					  printf "%s" "$htmlpage"
 | 
				
			||||||
  return 0
 | 
					  return 0
 | 
				
			||||||
@ -315,7 +279,7 @@ _freedns_add_txt_record() {
 | 
				
			|||||||
  domain_id="$2"
 | 
					  domain_id="$2"
 | 
				
			||||||
  subdomain="$3"
 | 
					  subdomain="$3"
 | 
				
			||||||
  value="$(printf '%s' "$4" | _url_encode)"
 | 
					  value="$(printf '%s' "$4" | _url_encode)"
 | 
				
			||||||
  url="http://freedns.afraid.org/subdomain/save.php?step=2"
 | 
					  url="https://freedns.afraid.org/subdomain/save.php?step=2"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  htmlpage="$(_post "type=TXT&domain_id=$domain_id&subdomain=$subdomain&address=%22$value%22&send=Save%21" "$url")"
 | 
					  htmlpage="$(_post "type=TXT&domain_id=$domain_id&subdomain=$subdomain&address=%22$value%22&send=Save%21" "$url")"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -323,17 +287,17 @@ _freedns_add_txt_record() {
 | 
				
			|||||||
    _err "FreeDNS failed to add TXT record for $subdomain bad RC from _post"
 | 
					    _err "FreeDNS failed to add TXT record for $subdomain bad RC from _post"
 | 
				
			||||||
    return 1
 | 
					    return 1
 | 
				
			||||||
  elif ! grep "200 OK" "$HTTP_HEADER" >/dev/null; then
 | 
					  elif ! grep "200 OK" "$HTTP_HEADER" >/dev/null; then
 | 
				
			||||||
    _debug "$htmlpage"
 | 
					    _debug3 "htmlpage: $htmlpage"
 | 
				
			||||||
    _err "FreeDNS failed to add TXT record for $subdomain. Check $HTTP_HEADER file"
 | 
					    _err "FreeDNS failed to add TXT record for $subdomain. Check $HTTP_HEADER file"
 | 
				
			||||||
    return 1
 | 
					    return 1
 | 
				
			||||||
  elif _contains "$htmlpage" "security code was incorrect"; then
 | 
					  elif _contains "$htmlpage" "security code was incorrect"; then
 | 
				
			||||||
    _debug "$htmlpage"
 | 
					    _debug3 "htmlpage: $htmlpage"
 | 
				
			||||||
    _err "FreeDNS failed to add TXT record for $subdomain as FreeDNS requested security code"
 | 
					    _err "FreeDNS failed to add TXT record for $subdomain as FreeDNS requested security code"
 | 
				
			||||||
    _err "Note that you cannot use automatic DNS validation for FreeDNS public domains"
 | 
					    _err "Note that you cannot use automatic DNS validation for FreeDNS public domains"
 | 
				
			||||||
    return 1
 | 
					    return 1
 | 
				
			||||||
  fi
 | 
					  fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  _debug2 "$htmlpage"
 | 
					  _debug3 "htmlpage: $htmlpage"
 | 
				
			||||||
  _info "Added acme challenge TXT record for $fulldomain at FreeDNS"
 | 
					  _info "Added acme challenge TXT record for $fulldomain at FreeDNS"
 | 
				
			||||||
  return 0
 | 
					  return 0
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -352,7 +316,7 @@ _freedns_delete_txt_record() {
 | 
				
			|||||||
    _err "FreeDNS failed to delete TXT record for $data_id bad RC from _get"
 | 
					    _err "FreeDNS failed to delete TXT record for $data_id bad RC from _get"
 | 
				
			||||||
    return 1
 | 
					    return 1
 | 
				
			||||||
  elif ! _contains "$htmlheader" "200 OK"; then
 | 
					  elif ! _contains "$htmlheader" "200 OK"; then
 | 
				
			||||||
    _debug "$htmlheader"
 | 
					    _debug2 "htmlheader: $htmlheader"
 | 
				
			||||||
    _err "FreeDNS failed to delete TXT record $data_id"
 | 
					    _err "FreeDNS failed to delete TXT record $data_id"
 | 
				
			||||||
    return 1
 | 
					    return 1
 | 
				
			||||||
  fi
 | 
					  fi
 | 
				
			||||||
 | 
				
			|||||||
@ -59,19 +59,13 @@ dns_gd_add() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  _info "Adding record"
 | 
					  _info "Adding record"
 | 
				
			||||||
  if _gd_rest PUT "domains/$_domain/records/TXT/$_sub_domain" "[$_add_data]"; then
 | 
					  if _gd_rest PUT "domains/$_domain/records/TXT/$_sub_domain" "[$_add_data]"; then
 | 
				
			||||||
    if [ "$response" = "{}" ]; then
 | 
					 | 
				
			||||||
    _info "Added, sleeping 10 seconds"
 | 
					    _info "Added, sleeping 10 seconds"
 | 
				
			||||||
    _sleep 10
 | 
					    _sleep 10
 | 
				
			||||||
    #todo: check if the record takes effect
 | 
					    #todo: check if the record takes effect
 | 
				
			||||||
    return 0
 | 
					    return 0
 | 
				
			||||||
    else
 | 
					  fi
 | 
				
			||||||
  _err "Add txt record error."
 | 
					  _err "Add txt record error."
 | 
				
			||||||
      _err "$response"
 | 
					 | 
				
			||||||
  return 1
 | 
					  return 1
 | 
				
			||||||
    fi
 | 
					 | 
				
			||||||
  fi
 | 
					 | 
				
			||||||
  _err "Add txt record error."
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#fulldomain
 | 
					#fulldomain
 | 
				
			||||||
@ -174,5 +168,9 @@ _gd_rest() {
 | 
				
			|||||||
    return 1
 | 
					    return 1
 | 
				
			||||||
  fi
 | 
					  fi
 | 
				
			||||||
  _debug2 response "$response"
 | 
					  _debug2 response "$response"
 | 
				
			||||||
 | 
					  if _contains "$response" "UNABLE_TO_AUTHENTICATE"; then
 | 
				
			||||||
 | 
					    _err "It seems that your api key or secret is not correct."
 | 
				
			||||||
 | 
					    return 1
 | 
				
			||||||
 | 
					  fi
 | 
				
			||||||
  return 0
 | 
					  return 0
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -33,8 +33,9 @@ dns_he_add() {
 | 
				
			|||||||
  # Fills in the $_zone_id
 | 
					  # Fills in the $_zone_id
 | 
				
			||||||
  _find_zone "$_full_domain" || return 1
 | 
					  _find_zone "$_full_domain" || return 1
 | 
				
			||||||
  _debug "Zone id \"$_zone_id\" will be used."
 | 
					  _debug "Zone id \"$_zone_id\" will be used."
 | 
				
			||||||
 | 
					  username_encoded="$(printf "%s" "${HE_Username}" | _url_encode)"
 | 
				
			||||||
  body="email=${HE_Username}&pass=${HE_Password}"
 | 
					  password_encoded="$(printf "%s" "${HE_Password}" | _url_encode)"
 | 
				
			||||||
 | 
					  body="email=${username_encoded}&pass=${password_encoded}"
 | 
				
			||||||
  body="$body&account="
 | 
					  body="$body&account="
 | 
				
			||||||
  body="$body&menu=edit_zone"
 | 
					  body="$body&menu=edit_zone"
 | 
				
			||||||
  body="$body&Type=TXT"
 | 
					  body="$body&Type=TXT"
 | 
				
			||||||
@ -71,7 +72,9 @@ dns_he_rm() {
 | 
				
			|||||||
  _debug "Zone id \"$_zone_id\" will be used."
 | 
					  _debug "Zone id \"$_zone_id\" will be used."
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # Find the record id to clean
 | 
					  # Find the record id to clean
 | 
				
			||||||
  body="email=${HE_Username}&pass=${HE_Password}"
 | 
					  username_encoded="$(printf "%s" "${HE_Username}" | _url_encode)"
 | 
				
			||||||
 | 
					  password_encoded="$(printf "%s" "${HE_Password}" | _url_encode)"
 | 
				
			||||||
 | 
					  body="email=${username_encoded}&pass=${password_encoded}"
 | 
				
			||||||
  body="$body&hosted_dns_zoneid=$_zone_id"
 | 
					  body="$body&hosted_dns_zoneid=$_zone_id"
 | 
				
			||||||
  body="$body&menu=edit_zone"
 | 
					  body="$body&menu=edit_zone"
 | 
				
			||||||
  body="$body&hosted_dns_editzone="
 | 
					  body="$body&hosted_dns_editzone="
 | 
				
			||||||
@ -112,9 +115,15 @@ dns_he_rm() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
_find_zone() {
 | 
					_find_zone() {
 | 
				
			||||||
  _domain="$1"
 | 
					  _domain="$1"
 | 
				
			||||||
  body="email=${HE_Username}&pass=${HE_Password}"
 | 
					  username_encoded="$(printf "%s" "${HE_Username}" | _url_encode)"
 | 
				
			||||||
 | 
					  password_encoded="$(printf "%s" "${HE_Password}" | _url_encode)"
 | 
				
			||||||
 | 
					  body="email=${username_encoded}&pass=${password_encoded}"
 | 
				
			||||||
  response="$(_post "$body" "https://dns.he.net/")"
 | 
					  response="$(_post "$body" "https://dns.he.net/")"
 | 
				
			||||||
  _debug2 response "$response"
 | 
					  _debug2 response "$response"
 | 
				
			||||||
 | 
					  if _contains "$response" '>Incorrect<'; then
 | 
				
			||||||
 | 
					    _err "Unable to login to dns.he.net please check username and password"
 | 
				
			||||||
 | 
					    return 1
 | 
				
			||||||
 | 
					  fi
 | 
				
			||||||
  _table="$(echo "$response" | tr -d "#" | sed "s/<table/#<table/g" | tr -d "\n" | tr "#" "\n" | grep 'id="domains_table"')"
 | 
					  _table="$(echo "$response" | tr -d "#" | sed "s/<table/#<table/g" | tr -d "\n" | tr "#" "\n" | grep 'id="domains_table"')"
 | 
				
			||||||
  _debug2 _table "$_table"
 | 
					  _debug2 _table "$_table"
 | 
				
			||||||
  _matches="$(echo "$_table" | sed "s/<tr/#<tr/g" | tr "#" "\n" | grep 'alt="edit"' | tr -d " " | sed "s/<td/#<td/g" | tr "#" "\n" | grep 'hosted_dns_zoneid')"
 | 
					  _matches="$(echo "$_table" | sed "s/<tr/#<tr/g" | tr "#" "\n" | grep 'alt="edit"' | tr -d " " | sed "s/<td/#<td/g" | tr "#" "\n" | grep 'hosted_dns_zoneid')"
 | 
				
			||||||
@ -143,7 +152,7 @@ _find_zone() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    _debug "Looking for zone \"${_attempted_zone}\""
 | 
					    _debug "Looking for zone \"${_attempted_zone}\""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    line_num="$(echo "$_zone_names" | grep -n "$_attempted_zone" | cut -d : -f 1)"
 | 
					    line_num="$(echo "$_zone_names" | grep -n "^$_attempted_zone" | cut -d : -f 1)"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if [ "$line_num" ]; then
 | 
					    if [ "$line_num" ]; then
 | 
				
			||||||
      _zone_id=$(echo "$_zone_ids" | sed -n "${line_num}p")
 | 
					      _zone_id=$(echo "$_zone_ids" | sed -n "${line_num}p")
 | 
				
			||||||
 | 
				
			|||||||
@ -4,6 +4,10 @@
 | 
				
			|||||||
#INWX_User="username"
 | 
					#INWX_User="username"
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
#INWX_Password="password"
 | 
					#INWX_Password="password"
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Dependencies:
 | 
				
			||||||
 | 
					# -------------
 | 
				
			||||||
 | 
					# - oathtool (When using 2 Factor Authentication)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
INWX_Api="https://api.domrobot.com/xmlrpc/"
 | 
					INWX_Api="https://api.domrobot.com/xmlrpc/"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -16,6 +20,7 @@ dns_inwx_add() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  INWX_User="${INWX_User:-$(_readaccountconf_mutable INWX_User)}"
 | 
					  INWX_User="${INWX_User:-$(_readaccountconf_mutable INWX_User)}"
 | 
				
			||||||
  INWX_Password="${INWX_Password:-$(_readaccountconf_mutable INWX_Password)}"
 | 
					  INWX_Password="${INWX_Password:-$(_readaccountconf_mutable INWX_Password)}"
 | 
				
			||||||
 | 
					  INWX_Shared_Secret="${INWX_Shared_Secret:-$(_readaccountconf_mutable INWX_Shared_Secret)}"
 | 
				
			||||||
  if [ -z "$INWX_User" ] || [ -z "$INWX_Password" ]; then
 | 
					  if [ -z "$INWX_User" ] || [ -z "$INWX_Password" ]; then
 | 
				
			||||||
    INWX_User=""
 | 
					    INWX_User=""
 | 
				
			||||||
    INWX_Password=""
 | 
					    INWX_Password=""
 | 
				
			||||||
@ -27,6 +32,7 @@ dns_inwx_add() {
 | 
				
			|||||||
  #save the api key and email to the account conf file.
 | 
					  #save the api key and email to the account conf file.
 | 
				
			||||||
  _saveaccountconf_mutable INWX_User "$INWX_User"
 | 
					  _saveaccountconf_mutable INWX_User "$INWX_User"
 | 
				
			||||||
  _saveaccountconf_mutable INWX_Password "$INWX_Password"
 | 
					  _saveaccountconf_mutable INWX_Password "$INWX_Password"
 | 
				
			||||||
 | 
					  _saveaccountconf_mutable INWX_Shared_Secret "$INWX_Shared_Secret"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  _debug "First detect the root zone"
 | 
					  _debug "First detect the root zone"
 | 
				
			||||||
  if ! _get_root "$fulldomain"; then
 | 
					  if ! _get_root "$fulldomain"; then
 | 
				
			||||||
@ -148,8 +154,46 @@ _inwx_login() {
 | 
				
			|||||||
  </methodCall>' $INWX_User $INWX_Password)
 | 
					  </methodCall>' $INWX_User $INWX_Password)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  response="$(_post "$xml_content" "$INWX_Api" "" "POST")"
 | 
					  response="$(_post "$xml_content" "$INWX_Api" "" "POST")"
 | 
				
			||||||
 | 
					  _H1=$(printf "Cookie: %s" "$(grep "domrobot=" "$HTTP_HEADER" | grep "^Set-Cookie:" | _tail_n 1 | _egrep_o 'domrobot=[^;]*;' | tr -d ';')")
 | 
				
			||||||
 | 
					  export _H1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  printf "Cookie: %s" "$(grep "domrobot=" "$HTTP_HEADER" | grep "^Set-Cookie:" | _tail_n 1 | _egrep_o 'domrobot=[^;]*;' | tr -d ';')"
 | 
					  #https://github.com/inwx/php-client/blob/master/INWX/Domrobot.php#L71
 | 
				
			||||||
 | 
					  if _contains "$response" "tfa"; then
 | 
				
			||||||
 | 
					    if [ -z "$INWX_Shared_Secret" ]; then
 | 
				
			||||||
 | 
					      _err "Mobile TAN detected."
 | 
				
			||||||
 | 
					      _err "Please define a shared secret."
 | 
				
			||||||
 | 
					      return 1
 | 
				
			||||||
 | 
					    fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if ! _exists oathtool; then
 | 
				
			||||||
 | 
					      _err "Please install oathtool to use 2 Factor Authentication."
 | 
				
			||||||
 | 
					      _err ""
 | 
				
			||||||
 | 
					      return 1
 | 
				
			||||||
 | 
					    fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    tan="$(oathtool --base32 --totp "${INWX_Shared_Secret}" 2>/dev/null)"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    xml_content=$(printf '<?xml version="1.0" encoding="UTF-8"?>
 | 
				
			||||||
 | 
					    <methodCall>
 | 
				
			||||||
 | 
					    <methodName>account.unlock</methodName>
 | 
				
			||||||
 | 
					    <params>
 | 
				
			||||||
 | 
					     <param>
 | 
				
			||||||
 | 
					      <value>
 | 
				
			||||||
 | 
					       <struct>
 | 
				
			||||||
 | 
					        <member>
 | 
				
			||||||
 | 
					         <name>tan</name>
 | 
				
			||||||
 | 
					         <value>
 | 
				
			||||||
 | 
					          <string>%s</string>
 | 
				
			||||||
 | 
					         </value>
 | 
				
			||||||
 | 
					        </member>
 | 
				
			||||||
 | 
					       </struct>
 | 
				
			||||||
 | 
					      </value>
 | 
				
			||||||
 | 
					     </param>
 | 
				
			||||||
 | 
					    </params>
 | 
				
			||||||
 | 
					    </methodCall>' "$tan")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    response="$(_post "$xml_content" "$INWX_Api" "" "POST")"
 | 
				
			||||||
 | 
					  fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -161,8 +205,8 @@ _get_root() {
 | 
				
			|||||||
  i=2
 | 
					  i=2
 | 
				
			||||||
  p=1
 | 
					  p=1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  _H1=$(_inwx_login)
 | 
					  _inwx_login
 | 
				
			||||||
  export _H1
 | 
					
 | 
				
			||||||
  xml_content='<?xml version="1.0" encoding="UTF-8"?>
 | 
					  xml_content='<?xml version="1.0" encoding="UTF-8"?>
 | 
				
			||||||
  <methodCall>
 | 
					  <methodCall>
 | 
				
			||||||
  <methodName>nameserver.list</methodName>
 | 
					  <methodName>nameserver.list</methodName>
 | 
				
			||||||
 | 
				
			|||||||
@ -128,7 +128,7 @@ _ISPC_addTxt() {
 | 
				
			|||||||
  curSerial="$(date +%s)"
 | 
					  curSerial="$(date +%s)"
 | 
				
			||||||
  curStamp="$(date +'%F %T')"
 | 
					  curStamp="$(date +'%F %T')"
 | 
				
			||||||
  params="\"server_id\":\"${server_id}\",\"zone\":\"${zone}\",\"name\":\"${fulldomain}.\",\"type\":\"txt\",\"data\":\"${txtvalue}\",\"aux\":\"0\",\"ttl\":\"3600\",\"active\":\"y\",\"stamp\":\"${curStamp}\",\"serial\":\"${curSerial}\""
 | 
					  params="\"server_id\":\"${server_id}\",\"zone\":\"${zone}\",\"name\":\"${fulldomain}.\",\"type\":\"txt\",\"data\":\"${txtvalue}\",\"aux\":\"0\",\"ttl\":\"3600\",\"active\":\"y\",\"stamp\":\"${curStamp}\",\"serial\":\"${curSerial}\""
 | 
				
			||||||
  curData="{\"session_id\":\"${sessionID}\",\"client_id\":\"${client_id}\",\"params\":{${params}}}"
 | 
					  curData="{\"session_id\":\"${sessionID}\",\"client_id\":\"${client_id}\",\"params\":{${params}},\"update_serial\":true}"
 | 
				
			||||||
  curResult="$(_post "${curData}" "${ISPC_Api}?dns_txt_add")"
 | 
					  curResult="$(_post "${curData}" "${ISPC_Api}?dns_txt_add")"
 | 
				
			||||||
  _debug "Calling _ISPC_addTxt: '${curData}' '${ISPC_Api}?dns_txt_add'"
 | 
					  _debug "Calling _ISPC_addTxt: '${curData}' '${ISPC_Api}?dns_txt_add'"
 | 
				
			||||||
  _debug "Result of _ISPC_addTxt: '$curResult'"
 | 
					  _debug "Result of _ISPC_addTxt: '$curResult'"
 | 
				
			||||||
@ -160,7 +160,7 @@ _ISPC_rmTxt() {
 | 
				
			|||||||
      *)
 | 
					      *)
 | 
				
			||||||
        unset IFS
 | 
					        unset IFS
 | 
				
			||||||
        _info "Retrieved Record ID."
 | 
					        _info "Retrieved Record ID."
 | 
				
			||||||
        curData="{\"session_id\":\"${sessionID}\",\"primary_id\":\"${record_id}\"}"
 | 
					        curData="{\"session_id\":\"${sessionID}\",\"primary_id\":\"${record_id}\",\"update_serial\":true}"
 | 
				
			||||||
        curResult="$(_post "${curData}" "${ISPC_Api}?dns_txt_delete")"
 | 
					        curResult="$(_post "${curData}" "${ISPC_Api}?dns_txt_delete")"
 | 
				
			||||||
        _debug "Calling _ISPC_rmTxt: '${curData}' '${ISPC_Api}?dns_txt_delete'"
 | 
					        _debug "Calling _ISPC_rmTxt: '${curData}' '${ISPC_Api}?dns_txt_delete'"
 | 
				
			||||||
        _debug "Result of _ISPC_rmTxt: '$curResult'"
 | 
					        _debug "Result of _ISPC_rmTxt: '$curResult'"
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										107
									
								
								dnsapi/dns_kinghost.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										107
									
								
								dnsapi/dns_kinghost.sh
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,107 @@
 | 
				
			|||||||
 | 
					#!/usr/bin/env sh
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					############################################################
 | 
				
			||||||
 | 
					# KingHost API support                                     #
 | 
				
			||||||
 | 
					# http://api.kinghost.net/doc/                             #
 | 
				
			||||||
 | 
					#                                                          #
 | 
				
			||||||
 | 
					# Author: Felipe Keller Braz <felipebraz@kinghost.com.br>  #
 | 
				
			||||||
 | 
					# Report Bugs here: https://github.com/kinghost/acme.sh    #
 | 
				
			||||||
 | 
					#                                                          #
 | 
				
			||||||
 | 
					# Values to export:                                        #
 | 
				
			||||||
 | 
					# export KINGHOST_Username="email@provider.com"            #
 | 
				
			||||||
 | 
					# export KINGHOST_Password="xxxxxxxxxx"                    #
 | 
				
			||||||
 | 
					############################################################
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					KING_Api="https://api.kinghost.net/acme"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Usage: add  _acme-challenge.www.domain.com   "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
 | 
				
			||||||
 | 
					# Used to add txt record
 | 
				
			||||||
 | 
					dns_kinghost_add() {
 | 
				
			||||||
 | 
					  fulldomain=$1
 | 
				
			||||||
 | 
					  txtvalue=$2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  KINGHOST_Username="${KINGHOST_Username:-$(_readaccountconf_mutable KINGHOST_Username)}"
 | 
				
			||||||
 | 
					  KINGHOST_Password="${KINGHOST_Password:-$(_readaccountconf_mutable KINGHOST_Password)}"
 | 
				
			||||||
 | 
					  if [ -z "$KINGHOST_Username" ] || [ -z "$KINGHOST_Password" ]; then
 | 
				
			||||||
 | 
					    KINGHOST_Username=""
 | 
				
			||||||
 | 
					    KINGHOST_Password=""
 | 
				
			||||||
 | 
					    _err "You don't specify KingHost api password and email yet."
 | 
				
			||||||
 | 
					    _err "Please create you key and try again."
 | 
				
			||||||
 | 
					    return 1
 | 
				
			||||||
 | 
					  fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  #save the credentials to the account conf file.
 | 
				
			||||||
 | 
					  _saveaccountconf_mutable KINGHOST_Username "$KINGHOST_Username"
 | 
				
			||||||
 | 
					  _saveaccountconf_mutable KINGHOST_Password "$KINGHOST_Password"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  _debug "Getting txt records"
 | 
				
			||||||
 | 
					  _kinghost_rest GET "dns" "name=$fulldomain&content=$txtvalue"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  #This API call returns "status":"ok" if dns record does not exists
 | 
				
			||||||
 | 
					  #We are creating a new txt record here, so we expect the "ok" status
 | 
				
			||||||
 | 
					  if ! echo "$response" | grep '"status":"ok"' >/dev/null; then
 | 
				
			||||||
 | 
					    _err "Error"
 | 
				
			||||||
 | 
					    _err "$response"
 | 
				
			||||||
 | 
					    return 1
 | 
				
			||||||
 | 
					  fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  _kinghost_rest POST "dns" "name=$fulldomain&content=$txtvalue"
 | 
				
			||||||
 | 
					  if ! echo "$response" | grep '"status":"ok"' >/dev/null; then
 | 
				
			||||||
 | 
					    _err "Error"
 | 
				
			||||||
 | 
					    _err "$response"
 | 
				
			||||||
 | 
					    return 1
 | 
				
			||||||
 | 
					  fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return 0
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Usage: fulldomain txtvalue
 | 
				
			||||||
 | 
					# Used to remove the txt record after validation
 | 
				
			||||||
 | 
					dns_kinghost_rm() {
 | 
				
			||||||
 | 
					  fulldomain=$1
 | 
				
			||||||
 | 
					  txtvalue=$2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  KINGHOST_Password="${KINGHOST_Password:-$(_readaccountconf_mutable KINGHOST_Password)}"
 | 
				
			||||||
 | 
					  KINGHOST_Username="${KINGHOST_Username:-$(_readaccountconf_mutable KINGHOST_Username)}"
 | 
				
			||||||
 | 
					  if [ -z "$KINGHOST_Password" ] || [ -z "$KINGHOST_Username" ]; then
 | 
				
			||||||
 | 
					    KINGHOST_Password=""
 | 
				
			||||||
 | 
					    KINGHOST_Username=""
 | 
				
			||||||
 | 
					    _err "You don't specify KingHost api key and email yet."
 | 
				
			||||||
 | 
					    _err "Please create you key and try again."
 | 
				
			||||||
 | 
					    return 1
 | 
				
			||||||
 | 
					  fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  _kinghost_rest DELETE "dns" "name=$fulldomain&content=$txtvalue"
 | 
				
			||||||
 | 
					  if ! echo "$response" | grep '"status":"ok"' >/dev/null; then
 | 
				
			||||||
 | 
					    _err "Error"
 | 
				
			||||||
 | 
					    _err "$response"
 | 
				
			||||||
 | 
					    return 1
 | 
				
			||||||
 | 
					  fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return 0
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					####################  Private functions below ##################################
 | 
				
			||||||
 | 
					_kinghost_rest() {
 | 
				
			||||||
 | 
					  method=$1
 | 
				
			||||||
 | 
					  uri="$2"
 | 
				
			||||||
 | 
					  data="$3"
 | 
				
			||||||
 | 
					  _debug "$uri"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  export _H1="X-Auth-Email: $KINGHOST_Username"
 | 
				
			||||||
 | 
					  export _H2="X-Auth-Key: $KINGHOST_Password"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if [ "$method" != "GET" ]; then
 | 
				
			||||||
 | 
					    _debug data "$data"
 | 
				
			||||||
 | 
					    response="$(_post "$data" "$KING_Api/$uri.json" "" "$method")"
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
 | 
					    response="$(_get "$KING_Api/$uri.json?$data")"
 | 
				
			||||||
 | 
					  fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if [ "$?" != "0" ]; then
 | 
				
			||||||
 | 
					    _err "error $uri"
 | 
				
			||||||
 | 
					    return 1
 | 
				
			||||||
 | 
					  fi
 | 
				
			||||||
 | 
					  _debug2 response "$response"
 | 
				
			||||||
 | 
					  return 0
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										227
									
								
								dnsapi/dns_loopia.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										227
									
								
								dnsapi/dns_loopia.sh
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,227 @@
 | 
				
			|||||||
 | 
					#!/usr/bin/env sh
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#LOOPIA_User="username"
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#LOOPIA_Password="password"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					LOOPIA_Api="https://api.loopia.se/RPCSERV"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					########  Public functions #####################
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#Usage: add  _acme-challenge.www.domain.com   "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
 | 
				
			||||||
 | 
					dns_loopia_add() {
 | 
				
			||||||
 | 
					  fulldomain=$1
 | 
				
			||||||
 | 
					  txtvalue=$2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  LOOPIA_User="${LOOPIA_User:-$(_readaccountconf_mutable LOOPIA_User)}"
 | 
				
			||||||
 | 
					  LOOPIA_Password="${LOOPIA_Password:-$(_readaccountconf_mutable LOOPIA_Password)}"
 | 
				
			||||||
 | 
					  if [ -z "$LOOPIA_User" ] || [ -z "$LOOPIA_Password" ]; then
 | 
				
			||||||
 | 
					    LOOPIA_User=""
 | 
				
			||||||
 | 
					    LOOPIA_Password=""
 | 
				
			||||||
 | 
					    _err "You don't specify loopia user and password yet."
 | 
				
			||||||
 | 
					    _err "Please create you key and try again."
 | 
				
			||||||
 | 
					    return 1
 | 
				
			||||||
 | 
					  fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  #save the api key and email to the account conf file.
 | 
				
			||||||
 | 
					  _saveaccountconf_mutable LOOPIA_User "$LOOPIA_User"
 | 
				
			||||||
 | 
					  _saveaccountconf_mutable LOOPIA_Password "$LOOPIA_Password"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  _debug "First detect the root zone"
 | 
				
			||||||
 | 
					  if ! _get_root "$fulldomain"; then
 | 
				
			||||||
 | 
					    _err "invalid domain"
 | 
				
			||||||
 | 
					    return 1
 | 
				
			||||||
 | 
					  fi
 | 
				
			||||||
 | 
					  _debug _sub_domain "$_sub_domain"
 | 
				
			||||||
 | 
					  _debug _domain "$_domain"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  _info "Adding record"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  _loopia_add_record "$_domain" "$_sub_domain"
 | 
				
			||||||
 | 
					  _loopia_update_record "$_domain" "$_sub_domain" "$txtvalue"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					dns_loopia_rm() {
 | 
				
			||||||
 | 
					  fulldomain=$1
 | 
				
			||||||
 | 
					  txtvalue=$2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  LOOPIA_User="${LOOPIA_User:-$(_readaccountconf_mutable LOOPIA_User)}"
 | 
				
			||||||
 | 
					  LOOPIA_Password="${LOOPIA_Password:-$(_readaccountconf_mutable LOOPIA_Password)}"
 | 
				
			||||||
 | 
					  if [ -z "$LOOPIA_User" ] || [ -z "$LOOPIA_Password" ]; then
 | 
				
			||||||
 | 
					    LOOPIA_User=""
 | 
				
			||||||
 | 
					    LOOPIA_Password=""
 | 
				
			||||||
 | 
					    _err "You don't specify LOOPIA user and password yet."
 | 
				
			||||||
 | 
					    _err "Please create you key and try again."
 | 
				
			||||||
 | 
					    return 1
 | 
				
			||||||
 | 
					  fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  #save the api key and email to the account conf file.
 | 
				
			||||||
 | 
					  _saveaccountconf_mutable LOOPIA_User "$LOOPIA_User"
 | 
				
			||||||
 | 
					  _saveaccountconf_mutable LOOPIA_Password "$LOOPIA_Password"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  _debug "First detect the root zone"
 | 
				
			||||||
 | 
					  if ! _get_root "$fulldomain"; then
 | 
				
			||||||
 | 
					    _err "invalid domain"
 | 
				
			||||||
 | 
					    return 1
 | 
				
			||||||
 | 
					  fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  xml_content=$(printf '<?xml version="1.0" encoding="UTF-8"?>
 | 
				
			||||||
 | 
					  <methodCall>
 | 
				
			||||||
 | 
					    <methodName>removeSubdomain</methodName>
 | 
				
			||||||
 | 
					    <params>
 | 
				
			||||||
 | 
					      <param>
 | 
				
			||||||
 | 
					        <value><string>%s</string></value>
 | 
				
			||||||
 | 
					      </param>
 | 
				
			||||||
 | 
					      <param>
 | 
				
			||||||
 | 
					        <value><string>%s</string></value>
 | 
				
			||||||
 | 
					      </param>
 | 
				
			||||||
 | 
					      <param>
 | 
				
			||||||
 | 
					        <value><string>%s</string></value>
 | 
				
			||||||
 | 
					      </param>
 | 
				
			||||||
 | 
					      <param>
 | 
				
			||||||
 | 
					        <value><string>%s</string></value>
 | 
				
			||||||
 | 
					      </param>
 | 
				
			||||||
 | 
					    </params>
 | 
				
			||||||
 | 
					  </methodCall>' $LOOPIA_User $LOOPIA_Password "$_domain" "$_sub_domain")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  response="$(_post "$xml_content" "$LOOPIA_Api" "" "POST")"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if ! _contains "$response" "OK"; then
 | 
				
			||||||
 | 
					    _err "Error could not get txt records"
 | 
				
			||||||
 | 
					    return 1
 | 
				
			||||||
 | 
					  fi
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					####################  Private functions below ##################################
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					_get_root() {
 | 
				
			||||||
 | 
					  domain=$1
 | 
				
			||||||
 | 
					  _debug "get root"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  domain=$1
 | 
				
			||||||
 | 
					  i=2
 | 
				
			||||||
 | 
					  p=1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  xml_content=$(printf '<?xml version="1.0" encoding="UTF-8"?>
 | 
				
			||||||
 | 
					  <methodCall>
 | 
				
			||||||
 | 
					  <methodName>getDomains</methodName>
 | 
				
			||||||
 | 
					  <params>
 | 
				
			||||||
 | 
					   <param>
 | 
				
			||||||
 | 
					    <value><string>%s</string></value>
 | 
				
			||||||
 | 
					   </param>
 | 
				
			||||||
 | 
					   <param>
 | 
				
			||||||
 | 
					    <value><string>%s</string></value>
 | 
				
			||||||
 | 
					   </param>
 | 
				
			||||||
 | 
					  </params>
 | 
				
			||||||
 | 
					  </methodCall>' $LOOPIA_User $LOOPIA_Password)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  response="$(_post "$xml_content" "$LOOPIA_Api" "" "POST")"
 | 
				
			||||||
 | 
					  while true; do
 | 
				
			||||||
 | 
					    h=$(echo "$domain" | cut -d . -f $i-100)
 | 
				
			||||||
 | 
					    if [ -z "$h" ]; then
 | 
				
			||||||
 | 
					      #not valid
 | 
				
			||||||
 | 
					      return 1
 | 
				
			||||||
 | 
					    fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if _contains "$response" "$h"; then
 | 
				
			||||||
 | 
					      _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
 | 
				
			||||||
 | 
					      _domain="$h"
 | 
				
			||||||
 | 
					      return 0
 | 
				
			||||||
 | 
					    fi
 | 
				
			||||||
 | 
					    p=$i
 | 
				
			||||||
 | 
					    i=$(_math "$i" + 1)
 | 
				
			||||||
 | 
					  done
 | 
				
			||||||
 | 
					  return 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					_loopia_update_record() {
 | 
				
			||||||
 | 
					  domain=$1
 | 
				
			||||||
 | 
					  sub_domain=$2
 | 
				
			||||||
 | 
					  txtval=$3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  xml_content=$(printf '<?xml version="1.0" encoding="UTF-8"?>
 | 
				
			||||||
 | 
					  <methodCall>
 | 
				
			||||||
 | 
					    <methodName>updateZoneRecord</methodName>
 | 
				
			||||||
 | 
					    <params>
 | 
				
			||||||
 | 
					      <param>
 | 
				
			||||||
 | 
					        <value><string>%s</string></value>
 | 
				
			||||||
 | 
					      </param>
 | 
				
			||||||
 | 
					      <param>
 | 
				
			||||||
 | 
					        <value><string>%s</string></value>
 | 
				
			||||||
 | 
					      </param>
 | 
				
			||||||
 | 
					      <param>
 | 
				
			||||||
 | 
					        <value><string>%s</string></value>
 | 
				
			||||||
 | 
					      </param>
 | 
				
			||||||
 | 
					      <param>
 | 
				
			||||||
 | 
					        <value><string>%s</string></value>
 | 
				
			||||||
 | 
					      </param>
 | 
				
			||||||
 | 
					      <param>
 | 
				
			||||||
 | 
					        <struct>
 | 
				
			||||||
 | 
					          <member>
 | 
				
			||||||
 | 
					            <name>type</name>
 | 
				
			||||||
 | 
					            <value><string>TXT</string></value>
 | 
				
			||||||
 | 
					          </member>
 | 
				
			||||||
 | 
					          <member>
 | 
				
			||||||
 | 
					            <name>priority</name>
 | 
				
			||||||
 | 
					            <value><int>0</int></value>
 | 
				
			||||||
 | 
					          </member>
 | 
				
			||||||
 | 
					          <member>
 | 
				
			||||||
 | 
					            <name>ttl</name>
 | 
				
			||||||
 | 
					            <value><int>60</int></value>
 | 
				
			||||||
 | 
					          </member>
 | 
				
			||||||
 | 
					          <member>
 | 
				
			||||||
 | 
					            <name>rdata</name>
 | 
				
			||||||
 | 
					            <value><string>%s</string></value>
 | 
				
			||||||
 | 
					          </member>
 | 
				
			||||||
 | 
					          <member>
 | 
				
			||||||
 | 
					            <name>record_id</name>
 | 
				
			||||||
 | 
					            <value><int>0</int></value>
 | 
				
			||||||
 | 
					          </member>
 | 
				
			||||||
 | 
					        </struct>
 | 
				
			||||||
 | 
					      </param>
 | 
				
			||||||
 | 
					    </params>
 | 
				
			||||||
 | 
					  </methodCall>' $LOOPIA_User $LOOPIA_Password "$domain" "$sub_domain" "$txtval")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  response="$(_post "$xml_content" "$LOOPIA_Api" "" "POST")"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if ! _contains "$response" "OK"; then
 | 
				
			||||||
 | 
					    _err "Error"
 | 
				
			||||||
 | 
					    return 1
 | 
				
			||||||
 | 
					  fi
 | 
				
			||||||
 | 
					  return 0
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					_loopia_add_record() {
 | 
				
			||||||
 | 
					  domain=$1
 | 
				
			||||||
 | 
					  sub_domain=$2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  xml_content=$(printf '<?xml version="1.0" encoding="UTF-8"?>
 | 
				
			||||||
 | 
					  <methodCall>
 | 
				
			||||||
 | 
					    <methodName>addSubdomain</methodName>
 | 
				
			||||||
 | 
					    <params>
 | 
				
			||||||
 | 
					      <param>
 | 
				
			||||||
 | 
					        <value><string>%s</string></value>
 | 
				
			||||||
 | 
					      </param>
 | 
				
			||||||
 | 
					      <param>
 | 
				
			||||||
 | 
					        <value><string>%s</string></value>
 | 
				
			||||||
 | 
					      </param>
 | 
				
			||||||
 | 
					      <param>
 | 
				
			||||||
 | 
					        <value><string>%s</string></value>
 | 
				
			||||||
 | 
					      </param>
 | 
				
			||||||
 | 
					      <param>
 | 
				
			||||||
 | 
					        <value><string>%s</string></value>
 | 
				
			||||||
 | 
					      </param>
 | 
				
			||||||
 | 
					    </params>
 | 
				
			||||||
 | 
					  </methodCall>' $LOOPIA_User $LOOPIA_Password "$domain" "$sub_domain")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  response="$(_post "$xml_content" "$LOOPIA_Api" "" "POST")"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if ! _contains "$response" "OK"; then
 | 
				
			||||||
 | 
					    _err "Error"
 | 
				
			||||||
 | 
					    return 1
 | 
				
			||||||
 | 
					  fi
 | 
				
			||||||
 | 
					  return 0
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -1,11 +1,12 @@
 | 
				
			|||||||
#!/usr/bin/env sh
 | 
					#!/usr/bin/env sh
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#Author: RaidneII
 | 
					#Author: RaidenII
 | 
				
			||||||
#Created 06/28/2017
 | 
					#Created 06/28/2017
 | 
				
			||||||
 | 
					#Updated 03/01/2018, rewrote to support name.com API v4
 | 
				
			||||||
#Utilize name.com API to finish dns-01 verifications.
 | 
					#Utilize name.com API to finish dns-01 verifications.
 | 
				
			||||||
########  Public functions #####################
 | 
					########  Public functions #####################
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Namecom_API="https://api.name.com/api"
 | 
					Namecom_API="https://api.name.com/v4"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#Usage: dns_namecom_add   _acme-challenge.www.domain.com   "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
 | 
					#Usage: dns_namecom_add   _acme-challenge.www.domain.com   "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
 | 
				
			||||||
dns_namecom_add() {
 | 
					dns_namecom_add() {
 | 
				
			||||||
@ -39,21 +40,18 @@ dns_namecom_add() {
 | 
				
			|||||||
  # Find domain in domain list.
 | 
					  # Find domain in domain list.
 | 
				
			||||||
  if ! _namecom_get_root "$fulldomain"; then
 | 
					  if ! _namecom_get_root "$fulldomain"; then
 | 
				
			||||||
    _err "Unable to find domain specified."
 | 
					    _err "Unable to find domain specified."
 | 
				
			||||||
    _namecom_logout
 | 
					 | 
				
			||||||
    return 1
 | 
					    return 1
 | 
				
			||||||
  fi
 | 
					  fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # Add TXT record.
 | 
					  # Add TXT record.
 | 
				
			||||||
  _namecom_addtxt_json="{\"hostname\":\"$_sub_domain\",\"type\":\"TXT\",\"content\":\"$txtvalue\",\"ttl\":\"300\",\"priority\":\"10\"}"
 | 
					  _namecom_addtxt_json="{\"host\":\"$_sub_domain\",\"type\":\"TXT\",\"answer\":\"$txtvalue\",\"ttl\":\"300\"}"
 | 
				
			||||||
  if _namecom_rest POST "dns/create/$_domain" "$_namecom_addtxt_json"; then
 | 
					  if _namecom_rest POST "domains/$_domain/records" "$_namecom_addtxt_json"; then
 | 
				
			||||||
    retcode=$(printf "%s\n" "$response" | _egrep_o "\"code\":100")
 | 
					    _retvalue=$(printf "%s\n" "$response" | _egrep_o "\"$_sub_domain\"")
 | 
				
			||||||
    if [ "$retcode" ]; then
 | 
					    if [ "$_retvalue" ]; then
 | 
				
			||||||
      _info "Successfully added TXT record, ready for validation."
 | 
					      _info "Successfully added TXT record, ready for validation."
 | 
				
			||||||
      _namecom_logout
 | 
					 | 
				
			||||||
      return 0
 | 
					      return 0
 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
      _err "Unable to add the DNS record."
 | 
					      _err "Unable to add the DNS record."
 | 
				
			||||||
      _namecom_logout
 | 
					 | 
				
			||||||
      return 1
 | 
					      return 1
 | 
				
			||||||
    fi
 | 
					    fi
 | 
				
			||||||
  fi
 | 
					  fi
 | 
				
			||||||
@ -72,38 +70,29 @@ dns_namecom_rm() {
 | 
				
			|||||||
  # Find domain in domain list.
 | 
					  # Find domain in domain list.
 | 
				
			||||||
  if ! _namecom_get_root "$fulldomain"; then
 | 
					  if ! _namecom_get_root "$fulldomain"; then
 | 
				
			||||||
    _err "Unable to find domain specified."
 | 
					    _err "Unable to find domain specified."
 | 
				
			||||||
    _namecom_logout
 | 
					 | 
				
			||||||
    return 1
 | 
					    return 1
 | 
				
			||||||
  fi
 | 
					  fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # Get the record id.
 | 
					  # Get the record id.
 | 
				
			||||||
  if _namecom_rest GET "dns/list/$_domain"; then
 | 
					  if _namecom_rest GET "domains/$_domain/records"; then
 | 
				
			||||||
    retcode=$(printf "%s\n" "$response" | _egrep_o "\"code\":100")
 | 
					    _record_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":[0-9]+,\"domainName\":\"$_domain\",\"host\":\"$_sub_domain\",\"fqdn\":\"$fulldomain.\",\"type\":\"TXT\",\"answer\":\"$txtvalue\"" | cut -d \" -f 3 | _egrep_o [0-9]+)
 | 
				
			||||||
    if [ "$retcode" ]; then
 | 
					 | 
				
			||||||
      _record_id=$(printf "%s\n" "$response" | _egrep_o "\"record_id\":\"[0-9]+\",\"name\":\"$fulldomain\",\"type\":\"TXT\"" | cut -d \" -f 4)
 | 
					 | 
				
			||||||
    _debug record_id "$_record_id"
 | 
					    _debug record_id "$_record_id"
 | 
				
			||||||
 | 
					    if [ "$_record_id" ]; then
 | 
				
			||||||
      _info "Successfully retrieved the record id for ACME challenge."
 | 
					      _info "Successfully retrieved the record id for ACME challenge."
 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
      _err "Unable to retrieve the record id."
 | 
					      _err "Unable to retrieve the record id."
 | 
				
			||||||
      _namecom_logout
 | 
					 | 
				
			||||||
      return 1
 | 
					      return 1
 | 
				
			||||||
    fi
 | 
					    fi
 | 
				
			||||||
  fi
 | 
					  fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # Remove the DNS record using record id.
 | 
					  # Remove the DNS record using record id.
 | 
				
			||||||
  _namecom_rmtxt_json="{\"record_id\":\"$_record_id\"}"
 | 
					  if _namecom_rest DELETE "domains/$_domain/records/$_record_id"; then
 | 
				
			||||||
  if _namecom_rest POST "dns/delete/$_domain" "$_namecom_rmtxt_json"; then
 | 
					 | 
				
			||||||
    retcode=$(printf "%s\n" "$response" | _egrep_o "\"code\":100")
 | 
					 | 
				
			||||||
    if [ "$retcode" ]; then
 | 
					 | 
				
			||||||
    _info "Successfully removed the TXT record."
 | 
					    _info "Successfully removed the TXT record."
 | 
				
			||||||
      _namecom_logout
 | 
					 | 
				
			||||||
    return 0
 | 
					    return 0
 | 
				
			||||||
  else
 | 
					  else
 | 
				
			||||||
      _err "Unable to remove the DNS record."
 | 
					    _err "Unable to delete record id."
 | 
				
			||||||
      _namecom_logout
 | 
					 | 
				
			||||||
    return 1
 | 
					    return 1
 | 
				
			||||||
  fi
 | 
					  fi
 | 
				
			||||||
  fi
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
####################  Private functions below ##################################
 | 
					####################  Private functions below ##################################
 | 
				
			||||||
@ -112,8 +101,9 @@ _namecom_rest() {
 | 
				
			|||||||
  param=$2
 | 
					  param=$2
 | 
				
			||||||
  data=$3
 | 
					  data=$3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  export _H1="Content-Type: application/json"
 | 
					  export _H1="Authorization: Basic $_namecom_auth"
 | 
				
			||||||
  export _H2="Api-Session-Token: $sessionkey"
 | 
					  export _H2="Content-Type: application/json"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if [ "$method" != "GET" ]; then
 | 
					  if [ "$method" != "GET" ]; then
 | 
				
			||||||
    response="$(_post "$data" "$Namecom_API/$param" "" "$method")"
 | 
					    response="$(_post "$data" "$Namecom_API/$param" "" "$method")"
 | 
				
			||||||
  else
 | 
					  else
 | 
				
			||||||
@ -130,20 +120,15 @@ _namecom_rest() {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
_namecom_login() {
 | 
					_namecom_login() {
 | 
				
			||||||
  namecom_login_json="{\"username\":\"$Namecom_Username\",\"api_token\":\"$Namecom_Token\"}"
 | 
					  # Auth string
 | 
				
			||||||
 | 
					  # Name.com API v4 uses http basic auth to authenticate
 | 
				
			||||||
 | 
					  # need to convert the token for http auth
 | 
				
			||||||
 | 
					  _namecom_auth=$(printf "%s:%s" "$Namecom_Username" "$Namecom_Token" | _base64)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if _namecom_rest POST "login" "$namecom_login_json"; then
 | 
					  if _namecom_rest GET "hello"; then
 | 
				
			||||||
    retcode=$(printf "%s\n" "$response" | _egrep_o "\"code\":100")
 | 
					    retcode=$(printf "%s\n" "$response" | _egrep_o "\"username\"\:\"$Namecom_Username\"")
 | 
				
			||||||
    if [ "$retcode" ]; then
 | 
					    if [ "$retcode" ]; then
 | 
				
			||||||
      _info "Successfully logged in. Fetching session token..."
 | 
					      _info "Successfully logged in."
 | 
				
			||||||
      sessionkey=$(printf "%s\n" "$response" | _egrep_o "\"session_token\":\".+" | cut -d \" -f 4)
 | 
					 | 
				
			||||||
      if [ ! -z "$sessionkey" ]; then
 | 
					 | 
				
			||||||
        _debug sessionkey "$sessionkey"
 | 
					 | 
				
			||||||
        _info "Session key obtained."
 | 
					 | 
				
			||||||
      else
 | 
					 | 
				
			||||||
        _err "Unable to get session key."
 | 
					 | 
				
			||||||
        return 1
 | 
					 | 
				
			||||||
      fi
 | 
					 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
      _err "Logging in failed."
 | 
					      _err "Logging in failed."
 | 
				
			||||||
      return 1
 | 
					      return 1
 | 
				
			||||||
@ -151,24 +136,12 @@ _namecom_login() {
 | 
				
			|||||||
  fi
 | 
					  fi
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
_namecom_logout() {
 | 
					 | 
				
			||||||
  if _namecom_rest GET "logout"; then
 | 
					 | 
				
			||||||
    retcode=$(printf "%s\n" "$response" | _egrep_o "\"code\":100")
 | 
					 | 
				
			||||||
    if [ "$retcode" ]; then
 | 
					 | 
				
			||||||
      _info "Successfully logged out."
 | 
					 | 
				
			||||||
    else
 | 
					 | 
				
			||||||
      _err "Error logging out."
 | 
					 | 
				
			||||||
      return 1
 | 
					 | 
				
			||||||
    fi
 | 
					 | 
				
			||||||
  fi
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
_namecom_get_root() {
 | 
					_namecom_get_root() {
 | 
				
			||||||
  domain=$1
 | 
					  domain=$1
 | 
				
			||||||
  i=2
 | 
					  i=2
 | 
				
			||||||
  p=1
 | 
					  p=1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if ! _namecom_rest GET "domain/list"; then
 | 
					  if ! _namecom_rest GET "domains"; then
 | 
				
			||||||
    return 1
 | 
					    return 1
 | 
				
			||||||
  fi
 | 
					  fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -8,12 +8,14 @@ dns_nsupdate_add() {
 | 
				
			|||||||
  txtvalue=$2
 | 
					  txtvalue=$2
 | 
				
			||||||
  _checkKeyFile || return 1
 | 
					  _checkKeyFile || return 1
 | 
				
			||||||
  [ -n "${NSUPDATE_SERVER}" ] || NSUPDATE_SERVER="localhost"
 | 
					  [ -n "${NSUPDATE_SERVER}" ] || NSUPDATE_SERVER="localhost"
 | 
				
			||||||
 | 
					  [ -n "${NSUPDATE_SERVER_PORT}" ] || NSUPDATE_SERVER_PORT=53
 | 
				
			||||||
  # save the dns server and key to the account conf file.
 | 
					  # save the dns server and key to the account conf file.
 | 
				
			||||||
  _saveaccountconf NSUPDATE_SERVER "${NSUPDATE_SERVER}"
 | 
					  _saveaccountconf NSUPDATE_SERVER "${NSUPDATE_SERVER}"
 | 
				
			||||||
 | 
					  _saveaccountconf NSUPDATE_SERVER_PORT "${NSUPDATE_SERVER_PORT}"
 | 
				
			||||||
  _saveaccountconf NSUPDATE_KEY "${NSUPDATE_KEY}"
 | 
					  _saveaccountconf NSUPDATE_KEY "${NSUPDATE_KEY}"
 | 
				
			||||||
  _info "adding ${fulldomain}. 60 in txt \"${txtvalue}\""
 | 
					  _info "adding ${fulldomain}. 60 in txt \"${txtvalue}\""
 | 
				
			||||||
  nsupdate -k "${NSUPDATE_KEY}" <<EOF
 | 
					  nsupdate -k "${NSUPDATE_KEY}" <<EOF
 | 
				
			||||||
server ${NSUPDATE_SERVER}
 | 
					server ${NSUPDATE_SERVER}  ${NSUPDATE_SERVER_PORT} 
 | 
				
			||||||
update add ${fulldomain}. 60 in txt "${txtvalue}"
 | 
					update add ${fulldomain}. 60 in txt "${txtvalue}"
 | 
				
			||||||
send
 | 
					send
 | 
				
			||||||
EOF
 | 
					EOF
 | 
				
			||||||
@ -30,9 +32,10 @@ dns_nsupdate_rm() {
 | 
				
			|||||||
  fulldomain=$1
 | 
					  fulldomain=$1
 | 
				
			||||||
  _checkKeyFile || return 1
 | 
					  _checkKeyFile || return 1
 | 
				
			||||||
  [ -n "${NSUPDATE_SERVER}" ] || NSUPDATE_SERVER="localhost"
 | 
					  [ -n "${NSUPDATE_SERVER}" ] || NSUPDATE_SERVER="localhost"
 | 
				
			||||||
 | 
					  [ -n "${NSUPDATE_SERVER_PORT}" ] || NSUPDATE_SERVER_PORT=53
 | 
				
			||||||
  _info "removing ${fulldomain}. txt"
 | 
					  _info "removing ${fulldomain}. txt"
 | 
				
			||||||
  nsupdate -k "${NSUPDATE_KEY}" <<EOF
 | 
					  nsupdate -k "${NSUPDATE_KEY}" <<EOF
 | 
				
			||||||
server ${NSUPDATE_SERVER}
 | 
					server ${NSUPDATE_SERVER}  ${NSUPDATE_SERVER_PORT} 
 | 
				
			||||||
update delete ${fulldomain}. txt
 | 
					update delete ${fulldomain}. txt
 | 
				
			||||||
send
 | 
					send
 | 
				
			||||||
EOF
 | 
					EOF
 | 
				
			||||||
 | 
				
			|||||||
@ -69,15 +69,21 @@ dns_pdns_add() {
 | 
				
			|||||||
#fulldomain
 | 
					#fulldomain
 | 
				
			||||||
dns_pdns_rm() {
 | 
					dns_pdns_rm() {
 | 
				
			||||||
  fulldomain=$1
 | 
					  fulldomain=$1
 | 
				
			||||||
 | 
					  txtvalue=$2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if [ -z "$PDNS_Ttl" ]; then
 | 
				
			||||||
 | 
					    PDNS_Ttl="$DEFAULT_PDNS_TTL"
 | 
				
			||||||
 | 
					  fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  _debug "Detect root zone"
 | 
					  _debug "Detect root zone"
 | 
				
			||||||
  if ! _get_root "$fulldomain"; then
 | 
					  if ! _get_root "$fulldomain"; then
 | 
				
			||||||
    _err "invalid domain"
 | 
					    _err "invalid domain"
 | 
				
			||||||
    return 1
 | 
					    return 1
 | 
				
			||||||
  fi
 | 
					  fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  _debug _domain "$_domain"
 | 
					  _debug _domain "$_domain"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if ! rm_record "$_domain" "$fulldomain"; then
 | 
					  if ! rm_record "$_domain" "$fulldomain" "$txtvalue"; then
 | 
				
			||||||
    return 1
 | 
					    return 1
 | 
				
			||||||
  fi
 | 
					  fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -88,9 +94,16 @@ set_record() {
 | 
				
			|||||||
  _info "Adding record"
 | 
					  _info "Adding record"
 | 
				
			||||||
  root=$1
 | 
					  root=$1
 | 
				
			||||||
  full=$2
 | 
					  full=$2
 | 
				
			||||||
  txtvalue=$3
 | 
					  new_challenge=$3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if ! _pdns_rest "PATCH" "/api/v1/servers/$PDNS_ServerId/zones/$root." "{\"rrsets\": [{\"changetype\": \"REPLACE\", \"name\": \"$full.\", \"type\": \"TXT\", \"ttl\": $PDNS_Ttl, \"records\": [{\"name\": \"$full.\", \"type\": \"TXT\", \"content\": \"\\\"$txtvalue\\\"\", \"disabled\": false, \"ttl\": $PDNS_Ttl}]}]}"; then
 | 
					  _record_string=""
 | 
				
			||||||
 | 
					  _build_record_string "$new_challenge"
 | 
				
			||||||
 | 
					  _list_existingchallenges
 | 
				
			||||||
 | 
					  for oldchallenge in $_existing_challenges; do
 | 
				
			||||||
 | 
					    _build_record_string "$oldchallenge"
 | 
				
			||||||
 | 
					  done
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if ! _pdns_rest "PATCH" "/api/v1/servers/$PDNS_ServerId/zones/$root" "{\"rrsets\": [{\"changetype\": \"REPLACE\", \"name\": \"$full.\", \"type\": \"TXT\", \"ttl\": $PDNS_Ttl, \"records\": [$_record_string]}]}"; then
 | 
				
			||||||
    _err "Set txt record error."
 | 
					    _err "Set txt record error."
 | 
				
			||||||
    return 1
 | 
					    return 1
 | 
				
			||||||
  fi
 | 
					  fi
 | 
				
			||||||
@ -106,15 +119,38 @@ rm_record() {
 | 
				
			|||||||
  _info "Remove record"
 | 
					  _info "Remove record"
 | 
				
			||||||
  root=$1
 | 
					  root=$1
 | 
				
			||||||
  full=$2
 | 
					  full=$2
 | 
				
			||||||
 | 
					  txtvalue=$3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if ! _pdns_rest "PATCH" "/api/v1/servers/$PDNS_ServerId/zones/$root." "{\"rrsets\": [{\"changetype\": \"DELETE\", \"name\": \"$full.\", \"type\": \"TXT\"}]}"; then
 | 
					  #Enumerate existing acme challenges
 | 
				
			||||||
 | 
					  _list_existingchallenges
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if _contains "$_existing_challenges" "$txtvalue"; then
 | 
				
			||||||
 | 
					    #Delete all challenges (PowerDNS API does not allow to delete content)
 | 
				
			||||||
 | 
					    if ! _pdns_rest "PATCH" "/api/v1/servers/$PDNS_ServerId/zones/$root" "{\"rrsets\": [{\"changetype\": \"DELETE\", \"name\": \"$full.\", \"type\": \"TXT\"}]}"; then
 | 
				
			||||||
      _err "Delete txt record error."
 | 
					      _err "Delete txt record error."
 | 
				
			||||||
      return 1
 | 
					      return 1
 | 
				
			||||||
    fi
 | 
					    fi
 | 
				
			||||||
 | 
					    _record_string=""
 | 
				
			||||||
 | 
					    #If the only existing challenge was the challenge to delete: nothing to do
 | 
				
			||||||
 | 
					    if ! [ "$_existing_challenges" = "$txtvalue" ]; then
 | 
				
			||||||
 | 
					      for oldchallenge in $_existing_challenges; do
 | 
				
			||||||
 | 
					        #Build up the challenges to re-add, ommitting the one what should be deleted
 | 
				
			||||||
 | 
					        if ! [ "$oldchallenge" = "$txtvalue" ]; then
 | 
				
			||||||
 | 
					          _build_record_string "$oldchallenge"
 | 
				
			||||||
 | 
					        fi
 | 
				
			||||||
 | 
					      done
 | 
				
			||||||
 | 
					      #Recreate the existing challenges
 | 
				
			||||||
 | 
					      if ! _pdns_rest "PATCH" "/api/v1/servers/$PDNS_ServerId/zones/$root" "{\"rrsets\": [{\"changetype\": \"REPLACE\", \"name\": \"$full.\", \"type\": \"TXT\", \"ttl\": $PDNS_Ttl, \"records\": [$_record_string]}]}"; then
 | 
				
			||||||
 | 
					        _err "Set txt record error."
 | 
				
			||||||
 | 
					        return 1
 | 
				
			||||||
 | 
					      fi
 | 
				
			||||||
 | 
					    fi
 | 
				
			||||||
    if ! notify_slaves "$root"; then
 | 
					    if ! notify_slaves "$root"; then
 | 
				
			||||||
      return 1
 | 
					      return 1
 | 
				
			||||||
    fi
 | 
					    fi
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
 | 
					    _info "Record not found, nothing to remove"
 | 
				
			||||||
 | 
					  fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return 0
 | 
					  return 0
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -122,7 +158,7 @@ rm_record() {
 | 
				
			|||||||
notify_slaves() {
 | 
					notify_slaves() {
 | 
				
			||||||
  root=$1
 | 
					  root=$1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if ! _pdns_rest "PUT" "/api/v1/servers/$PDNS_ServerId/zones/$root./notify"; then
 | 
					  if ! _pdns_rest "PUT" "/api/v1/servers/$PDNS_ServerId/zones/$root/notify"; then
 | 
				
			||||||
    _err "Notify slaves error."
 | 
					    _err "Notify slaves error."
 | 
				
			||||||
    return 1
 | 
					    return 1
 | 
				
			||||||
  fi
 | 
					  fi
 | 
				
			||||||
@ -144,15 +180,18 @@ _get_root() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  while true; do
 | 
					  while true; do
 | 
				
			||||||
    h=$(printf "%s" "$domain" | cut -d . -f $i-100)
 | 
					    h=$(printf "%s" "$domain" | cut -d . -f $i-100)
 | 
				
			||||||
    if [ -z "$h" ]; then
 | 
					 | 
				
			||||||
      return 1
 | 
					 | 
				
			||||||
    fi
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if _contains "$_zones_response" "\"name\": \"$h.\""; then
 | 
					    if _contains "$_zones_response" "\"name\": \"$h.\""; then
 | 
				
			||||||
      _domain="$h"
 | 
					      _domain="$h."
 | 
				
			||||||
 | 
					      if [ -z "$h" ]; then
 | 
				
			||||||
 | 
					        _domain="=2E"
 | 
				
			||||||
 | 
					      fi
 | 
				
			||||||
      return 0
 | 
					      return 0
 | 
				
			||||||
    fi
 | 
					    fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if [ -z "$h" ]; then
 | 
				
			||||||
 | 
					      return 1
 | 
				
			||||||
 | 
					    fi
 | 
				
			||||||
    i=$(_math $i + 1)
 | 
					    i=$(_math $i + 1)
 | 
				
			||||||
  done
 | 
					  done
 | 
				
			||||||
  _debug "$domain not found"
 | 
					  _debug "$domain not found"
 | 
				
			||||||
@ -182,3 +221,12 @@ _pdns_rest() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  return 0
 | 
					  return 0
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					_build_record_string() {
 | 
				
			||||||
 | 
					  _record_string="${_record_string:+${_record_string}, }{\"content\": \"\\\"${1}\\\"\", \"disabled\": false}"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					_list_existingchallenges() {
 | 
				
			||||||
 | 
					  _pdns_rest "GET" "/api/v1/servers/$PDNS_ServerId/zones/$root"
 | 
				
			||||||
 | 
					  _existing_challenges=$(echo "$response" | _normalizeJson | _egrep_o "\"name\":\"${fulldomain}[^]]*}" | _egrep_o 'content\":\"\\"[^\\]*' | sed -n 's/^content":"\\"//p')
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										69
									
								
								dnsapi/dns_tele3.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								dnsapi/dns_tele3.sh
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,69 @@
 | 
				
			|||||||
 | 
					#!/usr/bin/env sh
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# tele3.cz DNS API
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Author: Roman Blizik
 | 
				
			||||||
 | 
					# Report Bugs here: https://github.com/par-pa/acme.sh
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# --
 | 
				
			||||||
 | 
					# export TELE3_Key="MS2I4uPPaI..."
 | 
				
			||||||
 | 
					# export TELE3_Secret="kjhOIHGJKHg"
 | 
				
			||||||
 | 
					# --
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TELE3_API="https://www.tele3.cz/acme/"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					########  Public functions  #####################
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					dns_tele3_add() {
 | 
				
			||||||
 | 
					  _info "Using TELE3 DNS"
 | 
				
			||||||
 | 
					  data="\"ope\":\"add\", \"domain\":\"$1\", \"value\":\"$2\""
 | 
				
			||||||
 | 
					  if ! _tele3_call; then
 | 
				
			||||||
 | 
					    _err "Publish zone failed"
 | 
				
			||||||
 | 
					    return 1
 | 
				
			||||||
 | 
					  fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  _info "Zone published"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					dns_tele3_rm() {
 | 
				
			||||||
 | 
					  _info "Using TELE3 DNS"
 | 
				
			||||||
 | 
					  data="\"ope\":\"rm\", \"domain\":\"$1\", \"value\":\"$2\""
 | 
				
			||||||
 | 
					  if ! _tele3_call; then
 | 
				
			||||||
 | 
					    _err "delete TXT record failed"
 | 
				
			||||||
 | 
					    return 1
 | 
				
			||||||
 | 
					  fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  _info "TXT record successfully deleted"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					####################  Private functions below  ##################################
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					_tele3_init() {
 | 
				
			||||||
 | 
					  TELE3_Key="${TELE3_Key:-$(_readaccountconf_mutable TELE3_Key)}"
 | 
				
			||||||
 | 
					  TELE3_Secret="${TELE3_Secret:-$(_readaccountconf_mutable TELE3_Secret)}"
 | 
				
			||||||
 | 
					  if [ -z "$TELE3_Key" ] || [ -z "$TELE3_Secret" ]; then
 | 
				
			||||||
 | 
					    TELE3_Key=""
 | 
				
			||||||
 | 
					    TELE3_Secret=""
 | 
				
			||||||
 | 
					    _err "You must export variables: TELE3_Key and TELE3_Secret"
 | 
				
			||||||
 | 
					    return 1
 | 
				
			||||||
 | 
					  fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  #save the config variables to the account conf file.
 | 
				
			||||||
 | 
					  _saveaccountconf_mutable TELE3_Key "$TELE3_Key"
 | 
				
			||||||
 | 
					  _saveaccountconf_mutable TELE3_Secret "$TELE3_Secret"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					_tele3_call() {
 | 
				
			||||||
 | 
					  _tele3_init
 | 
				
			||||||
 | 
					  data="{\"key\":\"$TELE3_Key\", \"secret\":\"$TELE3_Secret\", $data}"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  _debug data "$data"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  response="$(_post "$data" "$TELE3_API" "" "POST")"
 | 
				
			||||||
 | 
					  _debug response "$response"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if [ "$response" != "success" ]; then
 | 
				
			||||||
 | 
					    _err "$response"
 | 
				
			||||||
 | 
					    return 1
 | 
				
			||||||
 | 
					  fi
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -50,9 +50,9 @@ _PDD_get_domain() {
 | 
				
			|||||||
  __last=0
 | 
					  __last=0
 | 
				
			||||||
  while [ $__last -eq 0 ]; do
 | 
					  while [ $__last -eq 0 ]; do
 | 
				
			||||||
    uri1="https://pddimp.yandex.ru/api2/admin/domain/domains?page=${__page}&on_page=20"
 | 
					    uri1="https://pddimp.yandex.ru/api2/admin/domain/domains?page=${__page}&on_page=20"
 | 
				
			||||||
    res1=$(_get "$uri1" | _normalizeJson)
 | 
					    res1="$(_get "$uri1" | _normalizeJson)"
 | 
				
			||||||
    #_debug "$res1"
 | 
					    _debug2 "res1" "$res1"
 | 
				
			||||||
    __found=$(echo "$res1" | sed -n -e 's#.* "found": \([^,]*\),.*#\1#p')
 | 
					    __found="$(echo "$res1" | sed -n -e 's#.* "found": \([^,]*\),.*#\1#p')"
 | 
				
			||||||
    _debug "found: $__found results on page"
 | 
					    _debug "found: $__found results on page"
 | 
				
			||||||
    if [ "$__found" -lt 20 ]; then
 | 
					    if [ "$__found" -lt 20 ]; then
 | 
				
			||||||
      _debug "last page: $__page"
 | 
					      _debug "last page: $__page"
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										139
									
								
								dnsapi/dns_zilore.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										139
									
								
								dnsapi/dns_zilore.sh
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,139 @@
 | 
				
			|||||||
 | 
					#!/usr/bin/env sh
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Zilore_API="https://api.zilore.com/dns/v1"
 | 
				
			||||||
 | 
					# Zilore_Key="YOUR-ZILORE-API-KEY"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					########  Public functions #####################
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					dns_zilore_add() {
 | 
				
			||||||
 | 
					  fulldomain=$1
 | 
				
			||||||
 | 
					  txtvalue=$2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  _info "Using Zilore"
 | 
				
			||||||
 | 
					  _debug fulldomain "$fulldomain"
 | 
				
			||||||
 | 
					  _debug txtvalue "$txtvalue"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Zilore_Key="${Zilore_Key:-$(_readaccountconf_mutable Zilore_Key)}"
 | 
				
			||||||
 | 
					  if [ -z "$Zilore_Key" ]; then
 | 
				
			||||||
 | 
					    Zilore_Key=""
 | 
				
			||||||
 | 
					    _err "Please define Zilore API key"
 | 
				
			||||||
 | 
					    return 1
 | 
				
			||||||
 | 
					  fi
 | 
				
			||||||
 | 
					  _saveaccountconf_mutable Zilore_Key "$Zilore_Key"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if ! _get_root "$fulldomain"; then
 | 
				
			||||||
 | 
					    _err "Unable to determine root domain"
 | 
				
			||||||
 | 
					    return 1
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
 | 
					    _debug _domain "$_domain"
 | 
				
			||||||
 | 
					  fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if _zilore_rest POST "domains/$_domain/records?record_type=TXT&record_ttl=600&record_name=$fulldomain&record_value=\"$txtvalue\""; then
 | 
				
			||||||
 | 
					    if _contains "$response" '"added"' >/dev/null; then
 | 
				
			||||||
 | 
					      _info "Added TXT record, waiting for validation"
 | 
				
			||||||
 | 
					      return 0
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					      _debug response "$response"
 | 
				
			||||||
 | 
					      _err "Error while adding DNS records"
 | 
				
			||||||
 | 
					      return 1
 | 
				
			||||||
 | 
					    fi
 | 
				
			||||||
 | 
					  fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return 1
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					dns_zilore_rm() {
 | 
				
			||||||
 | 
					  fulldomain=$1
 | 
				
			||||||
 | 
					  txtvalue=$2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  _info "Using Zilore"
 | 
				
			||||||
 | 
					  _debug fulldomain "$fulldomain"
 | 
				
			||||||
 | 
					  _debug txtvalue "$txtvalue"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Zilore_Key="${Zilore_Key:-$(_readaccountconf_mutable Zilore_Key)}"
 | 
				
			||||||
 | 
					  if [ -z "$Zilore_Key" ]; then
 | 
				
			||||||
 | 
					    Zilore_Key=""
 | 
				
			||||||
 | 
					    _err "Please define Zilore API key"
 | 
				
			||||||
 | 
					    return 1
 | 
				
			||||||
 | 
					  fi
 | 
				
			||||||
 | 
					  _saveaccountconf_mutable Zilore_Key "$Zilore_Key"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if ! _get_root "$fulldomain"; then
 | 
				
			||||||
 | 
					    _err "Unable to determine root domain"
 | 
				
			||||||
 | 
					    return 1
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
 | 
					    _debug _domain "$_domain"
 | 
				
			||||||
 | 
					  fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  _debug "Getting TXT records"
 | 
				
			||||||
 | 
					  _zilore_rest GET "domains/${_domain}/records?search_text=$txtvalue&search_record_type=TXT"
 | 
				
			||||||
 | 
					  _debug response "$response"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if ! _contains "$response" '"ok"' >/dev/null; then
 | 
				
			||||||
 | 
					    _err "Error while getting records list"
 | 
				
			||||||
 | 
					    return 1
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
 | 
					    _record_id=$(printf "%s\n" "$response" | _egrep_o "\"record_id\":\"[^\"]+\"" | cut -d : -f 2 | tr -d \" | _head_n 1)
 | 
				
			||||||
 | 
					    if [ -z "$_record_id" ]; then
 | 
				
			||||||
 | 
					      _err "Cannot determine _record_id"
 | 
				
			||||||
 | 
					      return 1
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					      _debug _record_id "$_record_id"
 | 
				
			||||||
 | 
					    fi
 | 
				
			||||||
 | 
					    if ! _zilore_rest DELETE "domains/${_domain}/records?record_id=$_record_id"; then
 | 
				
			||||||
 | 
					      _err "Error while deleting chosen record"
 | 
				
			||||||
 | 
					      return 1
 | 
				
			||||||
 | 
					    fi
 | 
				
			||||||
 | 
					    _contains "$response" '"ok"'
 | 
				
			||||||
 | 
					  fi
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					####################  Private functions below ##################################
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					_get_root() {
 | 
				
			||||||
 | 
					  domain=$1
 | 
				
			||||||
 | 
					  i=2
 | 
				
			||||||
 | 
					  while true; do
 | 
				
			||||||
 | 
					    h=$(printf "%s" "$domain" | cut -d . -f $i-100)
 | 
				
			||||||
 | 
					    _debug h "$h"
 | 
				
			||||||
 | 
					    if [ -z "$h" ]; then
 | 
				
			||||||
 | 
					      #not valid
 | 
				
			||||||
 | 
					      return 1
 | 
				
			||||||
 | 
					    fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if ! _zilore_rest GET "domains?search_text=$h"; then
 | 
				
			||||||
 | 
					      return 1
 | 
				
			||||||
 | 
					    fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if _contains "$response" "\"$h\"" >/dev/null; then
 | 
				
			||||||
 | 
					      _domain=$h
 | 
				
			||||||
 | 
					      return 0
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					      _debug "$h not found"
 | 
				
			||||||
 | 
					    fi
 | 
				
			||||||
 | 
					    i=$(_math "$i" + 1)
 | 
				
			||||||
 | 
					  done
 | 
				
			||||||
 | 
					  return 1
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					_zilore_rest() {
 | 
				
			||||||
 | 
					  method=$1
 | 
				
			||||||
 | 
					  param=$2
 | 
				
			||||||
 | 
					  data=$3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  export _H1="X-Auth-Key: $Zilore_Key"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if [ "$method" != "GET" ]; then
 | 
				
			||||||
 | 
					    response="$(_post "$data" "$Zilore_API/$param" "" "$method")"
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
 | 
					    response="$(_get "$Zilore_API/$param")"
 | 
				
			||||||
 | 
					  fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if [ "$?" != "0" ]; then
 | 
				
			||||||
 | 
					    _err "error $param"
 | 
				
			||||||
 | 
					    return 1
 | 
				
			||||||
 | 
					  fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  _debug2 response "$response"
 | 
				
			||||||
 | 
					  return 0
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user