mirror of
https://github.com/acmesh-official/acme.sh.git
synced 2026-01-02 02:02:09 +08:00
Compare commits
30 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c86631b40c | ||
|
|
8ef5daa807 | ||
|
|
fa47ea4196 | ||
|
|
683592fa86 | ||
|
|
477a04760c | ||
|
|
b4a62bfa30 | ||
|
|
10eec7d48c | ||
|
|
b8cc10ab5d | ||
|
|
be0df07dfb | ||
|
|
5244097e2d | ||
|
|
1ba4ab2bd1 | ||
|
|
2e855f8983 | ||
|
|
51b4a9e350 | ||
|
|
237d28cf83 | ||
|
|
5723fd112f | ||
|
|
73b89c554e | ||
|
|
950d024a11 | ||
|
|
815a3be48b | ||
|
|
b9994e52eb | ||
|
|
80d63dbb7c | ||
|
|
6b817d4563 | ||
|
|
1081d98bf9 | ||
|
|
91d82da497 | ||
|
|
0ca46774ac | ||
|
|
9b173dcd71 | ||
|
|
a3361806ab | ||
|
|
5bdfdfefbe | ||
|
|
f82ff90f06 | ||
|
|
c7849a43e1 | ||
|
|
874bd093cb |
12
.github/FUNDING.yml
vendored
Normal file
12
.github/FUNDING.yml
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
# These are supported funding model platforms
|
||||
|
||||
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
|
||||
patreon: # Replace with a single Patreon username
|
||||
open_collective: acmesh
|
||||
ko_fi: # Replace with a single Ko-fi username
|
||||
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
|
||||
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
|
||||
liberapay: # Replace with a single Liberapay username
|
||||
issuehunt: # Replace with a single IssueHunt username
|
||||
otechie: # Replace with a single Otechie username
|
||||
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
|
||||
32
README.md
32
README.md
@@ -1,6 +1,6 @@
|
||||
# An ACME Shell script: acme.sh [](https://travis-ci.org/Neilpang/acme.sh)
|
||||
|
||||
[](https://gitter.im/acme-sh/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
<a href="https://opencollective.com/acmesh" alt="Financial Contributors on Open Collective"><img src="https://opencollective.com/acmesh/all/badge.svg?label=financial+contributors" /></a> [](https://gitter.im/acme-sh/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
- An ACME protocol client written purely in Shell (Unix shell) language.
|
||||
- Full ACME protocol implementation.
|
||||
- Support ACME v1 and ACME v2
|
||||
@@ -451,6 +451,36 @@ TODO:
|
||||
2. ACME protocol: https://github.com/ietf-wg-acme/acme
|
||||
|
||||
|
||||
## Contributors
|
||||
|
||||
### Code Contributors
|
||||
|
||||
This project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)].
|
||||
<a href="https://github.com/Neilpang/acme.sh/graphs/contributors"><img src="https://opencollective.com/acmesh/contributors.svg?width=890&button=false" /></a>
|
||||
|
||||
### Financial Contributors
|
||||
|
||||
Become a financial contributor and help us sustain our community. [[Contribute](https://opencollective.com/acmesh/contribute)]
|
||||
|
||||
#### Individuals
|
||||
|
||||
<a href="https://opencollective.com/acmesh"><img src="https://opencollective.com/acmesh/individuals.svg?width=890"></a>
|
||||
|
||||
#### Organizations
|
||||
|
||||
Support this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/acmesh/contribute)]
|
||||
|
||||
<a href="https://opencollective.com/acmesh/organization/0/website"><img src="https://opencollective.com/acmesh/organization/0/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/acmesh/organization/1/website"><img src="https://opencollective.com/acmesh/organization/1/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/acmesh/organization/2/website"><img src="https://opencollective.com/acmesh/organization/2/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/acmesh/organization/3/website"><img src="https://opencollective.com/acmesh/organization/3/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/acmesh/organization/4/website"><img src="https://opencollective.com/acmesh/organization/4/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/acmesh/organization/5/website"><img src="https://opencollective.com/acmesh/organization/5/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/acmesh/organization/6/website"><img src="https://opencollective.com/acmesh/organization/6/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/acmesh/organization/7/website"><img src="https://opencollective.com/acmesh/organization/7/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/acmesh/organization/8/website"><img src="https://opencollective.com/acmesh/organization/8/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/acmesh/organization/9/website"><img src="https://opencollective.com/acmesh/organization/9/avatar.svg"></a>
|
||||
|
||||
# 19. License & Others
|
||||
|
||||
License is GPLv3
|
||||
|
||||
150
acme.sh
150
acme.sh
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
VER=2.8.2
|
||||
VER=2.8.4
|
||||
|
||||
PROJECT_NAME="acme.sh"
|
||||
|
||||
@@ -90,6 +90,9 @@ DEBUG_LEVEL_3=3
|
||||
DEBUG_LEVEL_DEFAULT=$DEBUG_LEVEL_1
|
||||
DEBUG_LEVEL_NONE=0
|
||||
|
||||
DOH_CLOUDFLARE=1
|
||||
DOH_GOOGLE=2
|
||||
|
||||
HIDDEN_VALUE="[hidden](please add '--output-insecure' to see this value)"
|
||||
|
||||
SYSLOG_ERROR="user.error"
|
||||
@@ -135,6 +138,8 @@ _DNS_MANUAL_WIKI="https://github.com/Neilpang/acme.sh/wiki/dns-manual-mode"
|
||||
|
||||
_NOTIFY_WIKI="https://github.com/Neilpang/acme.sh/wiki/notify"
|
||||
|
||||
_SUDO_WIKI="https://github.com/Neilpang/acme.sh/wiki/sudo"
|
||||
|
||||
_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"
|
||||
@@ -809,6 +814,11 @@ _json_encode() {
|
||||
echo "$_j_str" | _hex_dump | _lower_case | sed 's/0a/5c 6e/g' | tr -d ' ' | _h2b | tr -d "\r\n"
|
||||
}
|
||||
|
||||
#convert '\/' to '\'
|
||||
_json_decode() {
|
||||
sed 's#\\/#/#g'
|
||||
}
|
||||
|
||||
#options file
|
||||
_sed_i() {
|
||||
options="$1"
|
||||
@@ -1695,18 +1705,37 @@ _post() {
|
||||
if [ "$HTTPS_INSECURE" ]; then
|
||||
_CURL="$_CURL --insecure "
|
||||
fi
|
||||
if [ "$httpmethod" = "HEAD" ]; then
|
||||
_CURL="$_CURL -I "
|
||||
fi
|
||||
_debug "_CURL" "$_CURL"
|
||||
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)"
|
||||
if [ "$body" ]; 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)"
|
||||
fi
|
||||
else
|
||||
response="$($_CURL --user-agent "$USER_AGENT" -X $httpmethod -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" --data "$body" "$_post_url" | _base64)"
|
||||
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" "$_post_url" | _base64)"
|
||||
else
|
||||
response="$($_CURL --user-agent "$USER_AGENT" -X $httpmethod -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" "$_post_url" | _base64)"
|
||||
fi
|
||||
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")"
|
||||
if [ "$body" ]; 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")"
|
||||
else
|
||||
response="$($_CURL --user-agent "$USER_AGENT" -X $httpmethod -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" --data "$body" "$_post_url")"
|
||||
fi
|
||||
else
|
||||
response="$($_CURL --user-agent "$USER_AGENT" -X $httpmethod -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" --data "$body" "$_post_url")"
|
||||
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" "$_post_url")"
|
||||
else
|
||||
response="$($_CURL --user-agent "$USER_AGENT" -X $httpmethod -H "$_H1" -H "$_H2" -H "$_H3" -H "$_H4" -H "$_H5" "$_post_url")"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
_ret="$?"
|
||||
@@ -1722,6 +1751,9 @@ _post() {
|
||||
if [ "$HTTPS_INSECURE" ]; then
|
||||
_WGET="$_WGET --no-check-certificate "
|
||||
fi
|
||||
if [ "$httpmethod" = "HEAD" ]; then
|
||||
_WGET="$_WGET --read-timeout=3.0 --tries=2 "
|
||||
fi
|
||||
_debug "_WGET" "$_WGET"
|
||||
if [ "$needbase64" ]; then
|
||||
if [ "$httpmethod" = "POST" ]; then
|
||||
@@ -1744,6 +1776,12 @@ _post() {
|
||||
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")"
|
||||
fi
|
||||
elif [ "$httpmethod" = "HEAD" ]; then
|
||||
if [ "$_postContentType" ]; then
|
||||
response="$($_WGET --spider -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 --spider -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")"
|
||||
@@ -1876,7 +1914,7 @@ _send_signed_request() {
|
||||
if [ "$ACME_NEW_NONCE" ]; then
|
||||
_debug2 "Get nonce with HEAD. ACME_NEW_NONCE" "$ACME_NEW_NONCE"
|
||||
nonceurl="$ACME_NEW_NONCE"
|
||||
if _post "" "$nonceurl" "" "HEAD" "$__request_conent_type"; then
|
||||
if _post "" "$nonceurl" "" "HEAD" "$__request_conent_type" >/dev/null; then
|
||||
_headers="$(cat "$HTTP_HEADER")"
|
||||
_debug2 _headers "$_headers"
|
||||
_CACHED_NONCE="$(echo "$_headers" | grep -i "Replay-Nonce:" | _head_n 1 | tr -d "\r\n " | cut -d ':' -f 2)"
|
||||
@@ -2362,7 +2400,7 @@ _initAPI() {
|
||||
_debug "_init api for server: $_api_server"
|
||||
|
||||
if [ -z "$ACME_NEW_ACCOUNT" ]; then
|
||||
response=$(_get "$_api_server")
|
||||
response=$(_get "$_api_server" | _json_decode)
|
||||
if [ "$?" != "0" ]; then
|
||||
_debug2 "response" "$response"
|
||||
_err "Can not init api."
|
||||
@@ -2797,6 +2835,11 @@ _setNginx() {
|
||||
_debug NGINX_CONF "$NGINX_CONF"
|
||||
NGINX_CONF="$(echo "$NGINX_CONF" | cut -d = -f 2)"
|
||||
_debug NGINX_CONF "$NGINX_CONF"
|
||||
if [ -z "$NGINX_CONF" ]; then
|
||||
_err "Can not find nginx conf."
|
||||
NGINX_CONF=""
|
||||
return 1
|
||||
fi
|
||||
if [ ! -f "$NGINX_CONF" ]; then
|
||||
_err "'$NGINX_CONF' doesn't exist."
|
||||
NGINX_CONF=""
|
||||
@@ -3601,7 +3644,7 @@ __trigger_validation() {
|
||||
}
|
||||
|
||||
#endpoint domain type
|
||||
_ns_lookup() {
|
||||
_ns_lookup_impl() {
|
||||
_ns_ep="$1"
|
||||
_ns_domain="$2"
|
||||
_ns_type="$3"
|
||||
@@ -3625,7 +3668,7 @@ _ns_lookup_cf() {
|
||||
_cf_ld="$1"
|
||||
_cf_ld_type="$2"
|
||||
_cf_ep="https://cloudflare-dns.com/dns-query"
|
||||
_ns_lookup "$_cf_ep" "$_cf_ld" "$_cf_ld_type"
|
||||
_ns_lookup_impl "$_cf_ep" "$_cf_ld" "$_cf_ld_type"
|
||||
}
|
||||
|
||||
#domain, type
|
||||
@@ -3638,6 +3681,44 @@ _ns_purge_cf() {
|
||||
_debug2 response "$response"
|
||||
}
|
||||
|
||||
#checks if cf server is available
|
||||
_ns_is_available_cf() {
|
||||
if _get "https://cloudflare-dns.com"; then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
#domain, type
|
||||
_ns_lookup_google() {
|
||||
_cf_ld="$1"
|
||||
_cf_ld_type="$2"
|
||||
_cf_ep="https://dns.google/resolve"
|
||||
_ns_lookup_impl "$_cf_ep" "$_cf_ld" "$_cf_ld_type"
|
||||
}
|
||||
|
||||
#domain, type
|
||||
_ns_lookup() {
|
||||
if [ -z "$DOH_USE" ]; then
|
||||
_debug "Detect dns server first."
|
||||
if _ns_is_available_cf; then
|
||||
_debug "Use cloudflare doh server"
|
||||
export DOH_USE=$DOH_CLOUDFLARE
|
||||
else
|
||||
_debug "Use google doh server"
|
||||
export DOH_USE=$DOH_GOOGLE
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$DOH_USE" = "$DOH_CLOUDFLARE" ] || [ -z "$DOH_USE" ]; then
|
||||
_ns_lookup_cf "$@"
|
||||
else
|
||||
_ns_lookup_google "$@"
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
#txtdomain, alias, txt
|
||||
__check_txt() {
|
||||
_c_txtdomain="$1"
|
||||
@@ -3646,7 +3727,7 @@ __check_txt() {
|
||||
_debug "_c_txtdomain" "$_c_txtdomain"
|
||||
_debug "_c_aliasdomain" "$_c_aliasdomain"
|
||||
_debug "_c_txt" "$_c_txt"
|
||||
_answers="$(_ns_lookup_cf "$_c_aliasdomain" TXT)"
|
||||
_answers="$(_ns_lookup "$_c_aliasdomain" TXT)"
|
||||
_contains "$_answers" "$_c_txt"
|
||||
|
||||
}
|
||||
@@ -3655,7 +3736,13 @@ __check_txt() {
|
||||
__purge_txt() {
|
||||
_p_txtdomain="$1"
|
||||
_debug _p_txtdomain "$_p_txtdomain"
|
||||
_ns_purge_cf "$_p_txtdomain" "TXT"
|
||||
if [ "$DOH_USE" = "$DOH_CLOUDFLARE" ] || [ -z "$DOH_USE" ]; then
|
||||
_ns_purge_cf "$_p_txtdomain" "TXT"
|
||||
else
|
||||
_debug "no purge api for google dns api, just sleep 5 secs"
|
||||
_sleep 5
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
#wait and check each dns entries
|
||||
@@ -4939,18 +5026,14 @@ list() {
|
||||
if [ "$_raw" ]; then
|
||||
printf "%s\n" "Main_Domain${_sep}KeyLength${_sep}SAN_Domains${_sep}Created${_sep}Renew"
|
||||
for di in "${CERT_HOME}"/*.*/; do
|
||||
if ! [ -d "$di" ]; then
|
||||
_debug "Not directory, skip: $di"
|
||||
continue
|
||||
fi
|
||||
d=$(basename "$di")
|
||||
_debug d "$d"
|
||||
(
|
||||
if _endswith "$d" "$ECC_SUFFIX"; then
|
||||
_isEcc=$(echo "$d" | cut -d "$ECC_SEP" -f 2)
|
||||
_isEcc="ecc"
|
||||
d=$(echo "$d" | cut -d "$ECC_SEP" -f 1)
|
||||
fi
|
||||
_initpath "$d" "$_isEcc"
|
||||
DOMAIN_CONF="$di/$d.conf"
|
||||
if [ -f "$DOMAIN_CONF" ]; then
|
||||
. "$DOMAIN_CONF"
|
||||
printf "%s\n" "$Le_Domain${_sep}\"$Le_Keylength\"${_sep}$Le_Alt${_sep}$Le_CertCreateTimeStr${_sep}$Le_NextRenewTimeStr"
|
||||
@@ -6233,6 +6316,23 @@ _processAccountConf() {
|
||||
|
||||
}
|
||||
|
||||
_checkSudo() {
|
||||
if [ "$SUDO_GID" ] && [ "$SUDO_COMMAND" ] && [ "$SUDO_USER" ] && [ "$SUDO_UID" ]; then
|
||||
if [ "$SUDO_USER" = "root" ] && [ "$SUDO_UID" = "0" ]; then
|
||||
#it's root using sudo, no matter it's using sudo or not, just fine
|
||||
return 0
|
||||
fi
|
||||
if [ "$SUDO_COMMAND" = "/bin/su" ] || [ "$SUDO_COMMAND" = "/bin/bash" ]; then
|
||||
#it's a normal user doing "sudo su", or `sudo -i` or `sudo -s`
|
||||
#fine
|
||||
return 0
|
||||
fi
|
||||
#otherwise
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
_process() {
|
||||
_CMD=""
|
||||
_domain=""
|
||||
@@ -6484,6 +6584,10 @@ _process() {
|
||||
;;
|
||||
--nginx)
|
||||
wvalue="$NGINX"
|
||||
if [ "$2" ] && ! _startswith "$2" "-"; then
|
||||
wvalue="$NGINX$2"
|
||||
shift
|
||||
fi
|
||||
if [ -z "$_webroot" ]; then
|
||||
_webroot="$wvalue"
|
||||
else
|
||||
@@ -6761,6 +6865,14 @@ _process() {
|
||||
done
|
||||
|
||||
if [ "${_CMD}" != "install" ]; then
|
||||
if [ "$__INTERACTIVE" ] && ! _checkSudo; then
|
||||
if [ -z "$FORCE" ]; then
|
||||
#Use "echo" here, instead of _info. it's too early
|
||||
echo "It seems that you are using sudo, please read this link first:"
|
||||
echo "$_SUDO_WIKI"
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
__initHome
|
||||
if [ "$_log" ]; then
|
||||
if [ -z "$_logfile" ]; then
|
||||
|
||||
@@ -185,7 +185,7 @@ _clean() {
|
||||
return 1
|
||||
fi
|
||||
|
||||
record_id="$(echo "$response" | tr '{' "\n" | grep "$_sub_domain" | grep "$txtvalue" | tr "," "\n" | grep RecordId | cut -d '"' -f 4)"
|
||||
record_id="$(echo "$response" | tr '{' "\n" | grep "$_sub_domain" | grep -- "$txtvalue" | tr "," "\n" | grep RecordId | cut -d '"' -f 4)"
|
||||
_debug2 record_id "$record_id"
|
||||
|
||||
if [ -z "$record_id" ]; then
|
||||
|
||||
155
dnsapi/dns_domeneshop.sh
Normal file
155
dnsapi/dns_domeneshop.sh
Normal file
@@ -0,0 +1,155 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
DOMENESHOP_Api_Endpoint="https://api.domeneshop.no/v0"
|
||||
|
||||
##################### Public functions #####################
|
||||
|
||||
# Usage: dns_domeneshop_add <full domain> <txt record>
|
||||
# Example: dns_domeneshop_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
|
||||
dns_domeneshop_add() {
|
||||
fulldomain=$1
|
||||
txtvalue=$2
|
||||
|
||||
# Get token and secret
|
||||
DOMENESHOP_Token="${DOMENESHOP_Token:-$(_readaccountconf_mutable DOMENESHOP_Token)}"
|
||||
DOMENESHOP_Secret="${DOMENESHOP_Secret:-$(_readaccountconf_mutable DOMENESHOP_Secret)}"
|
||||
|
||||
if [ -z "$DOMENESHOP_Token" ] || [ -z "$DOMENESHOP_Secret" ]; then
|
||||
DOMENESHOP_Token=""
|
||||
DOMENESHOP_Secret=""
|
||||
_err "You need to spesify a Domeneshop/Domainnameshop API Token and Secret."
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Save the api token and secret.
|
||||
_saveaccountconf_mutable DOMENESHOP_Token "$DOMENESHOP_Token"
|
||||
_saveaccountconf_mutable DOMENESHOP_Secret "$DOMENESHOP_Secret"
|
||||
|
||||
# Get the domain name id
|
||||
if ! _get_domainid "$fulldomain"; then
|
||||
_err "Did not find domainname"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Create record
|
||||
_domeneshop_rest POST "domains/$_domainid/dns" "{\"type\":\"TXT\",\"host\":\"$_sub_domain\",\"data\":\"$txtvalue\",\"ttl\":120}"
|
||||
}
|
||||
|
||||
# Usage: dns_domeneshop_rm <full domain> <txt record>
|
||||
# Example: dns_domeneshop_rm _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
|
||||
dns_domeneshop_rm() {
|
||||
fulldomain=$1
|
||||
txtvalue=$2
|
||||
|
||||
# Get token and secret
|
||||
DOMENESHOP_Token="${DOMENESHOP_Token:-$(_readaccountconf_mutable DOMENESHOP_Token)}"
|
||||
DOMENESHOP_Secret="${DOMENESHOP_Secret:-$(_readaccountconf_mutable DOMENESHOP_Secret)}"
|
||||
|
||||
if [ -z "$DOMENESHOP_Token" ] || [ -z "$DOMENESHOP_Secret" ]; then
|
||||
DOMENESHOP_Token=""
|
||||
DOMENESHOP_Secret=""
|
||||
_err "You need to spesify a Domeneshop/Domainnameshop API Token and Secret."
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Get the domain name id
|
||||
if ! _get_domainid "$fulldomain"; then
|
||||
_err "Did not find domainname"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Find record
|
||||
if ! _get_recordid "$_domainid" "$_sub_domain" "$txtvalue"; then
|
||||
_err "Did not find dns record"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Remove record
|
||||
_domeneshop_rest DELETE "domains/$_domainid/dns/$_recordid"
|
||||
}
|
||||
|
||||
##################### Private functions #####################
|
||||
|
||||
_get_domainid() {
|
||||
domain=$1
|
||||
|
||||
# Get domains
|
||||
_domeneshop_rest GET "domains"
|
||||
|
||||
if ! _contains "$response" "\"id\":"; then
|
||||
_err "failed to get domain names"
|
||||
return 1
|
||||
fi
|
||||
|
||||
i=2
|
||||
p=1
|
||||
while true; do
|
||||
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
|
||||
_debug "h" "$h"
|
||||
if [ -z "$h" ]; then
|
||||
#not valid
|
||||
return 1
|
||||
fi
|
||||
|
||||
if _contains "$response" "\"$h\"" >/dev/null; then
|
||||
# We have found the domain name.
|
||||
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
|
||||
_domain=$h
|
||||
_domainid=$(printf "%s" "$response" | _egrep_o "[^{]*\"domain\":\"$_domain\"[^}]*" | _egrep_o "\"id\":[0-9]+" | cut -d : -f 2)
|
||||
return 0
|
||||
fi
|
||||
p=$i
|
||||
i=$(_math "$i" + 1)
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
_get_recordid() {
|
||||
domainid=$1
|
||||
subdomain=$2
|
||||
txtvalue=$3
|
||||
|
||||
# Get all dns records for the domainname
|
||||
_domeneshop_rest GET "domains/$domainid/dns"
|
||||
|
||||
if ! _contains "$response" "\"id\":"; then
|
||||
_debug "No records in dns"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! _contains "$response" "\"host\":\"$subdomain\""; then
|
||||
_debug "Record does not exist"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Get the id of the record in question
|
||||
_recordid=$(printf "%s" "$response" | _egrep_o "[^{]*\"host\":\"$subdomain\"[^}]*" | _egrep_o "[^{]*\"data\":\"$txtvalue\"[^}]*" | _egrep_o "\"id\":[0-9]+" | cut -d : -f 2)
|
||||
if [ -z "$_recordid" ]; then
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
_domeneshop_rest() {
|
||||
method=$1
|
||||
endpoint=$2
|
||||
data=$3
|
||||
|
||||
credentials=$(printf "%b" "$DOMENESHOP_Token:$DOMENESHOP_Secret" | _base64)
|
||||
|
||||
export _H1="Authorization: Basic $credentials"
|
||||
export _H2="Content-Type: application/json"
|
||||
|
||||
if [ "$method" != "GET" ]; then
|
||||
response="$(_post "$data" "$DOMENESHOP_Api_Endpoint/$endpoint" "" "$method")"
|
||||
else
|
||||
response="$(_get "$DOMENESHOP_Api_Endpoint/$endpoint")"
|
||||
fi
|
||||
|
||||
if [ "$?" != "0" ]; then
|
||||
_err "error $endpoint"
|
||||
return 1
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
@@ -31,7 +31,8 @@ dns_linode_v4_add() {
|
||||
_payload="{
|
||||
\"type\": \"TXT\",
|
||||
\"name\": \"$_sub_domain\",
|
||||
\"target\": \"$txtvalue\"
|
||||
\"target\": \"$txtvalue\",
|
||||
\"ttl_sec\": 300
|
||||
}"
|
||||
|
||||
if _rest POST "/$_domain_id/records" "$_payload" && [ -n "$response" ]; then
|
||||
|
||||
@@ -110,7 +110,7 @@ _get_root() {
|
||||
return 1
|
||||
fi
|
||||
|
||||
if _contains "$response" "$host"; then
|
||||
if _contains "$response" "<domain>$host"; then
|
||||
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
|
||||
_domain="$host"
|
||||
return 0
|
||||
|
||||
90
notify/xmpp.sh
Normal file
90
notify/xmpp.sh
Normal file
@@ -0,0 +1,90 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
#Support xmpp via sendxmpp
|
||||
|
||||
#XMPP_BIN="/usr/bin/sendxmpp"
|
||||
#XMPP_BIN_ARGS="-n -t --tls-ca-path=/etc/ssl/certs"
|
||||
#XMPP_TO="zzzz@example.com"
|
||||
|
||||
xmpp_send() {
|
||||
_subject="$1"
|
||||
_content="$2"
|
||||
_statusCode="$3" #0: success, 1: error 2($RENEW_SKIP): skipped
|
||||
_debug "_subject" "$_subject"
|
||||
_debug "_content" "$_content"
|
||||
_debug "_statusCode" "$_statusCode"
|
||||
|
||||
XMPP_BIN="${XMPP_BIN:-$(_readaccountconf_mutable XMPP_BIN)}"
|
||||
if [ -n "$XMPP_BIN" ] && ! _exists "$XMPP_BIN"; then
|
||||
_err "It seems that the command $XMPP_BIN is not in path."
|
||||
return 1
|
||||
fi
|
||||
_XMPP_BIN=$(_xmpp_bin)
|
||||
if [ -n "$XMPP_BIN" ]; then
|
||||
_saveaccountconf_mutable XMPP_BIN "$XMPP_BIN"
|
||||
else
|
||||
_clearaccountconf "XMPP_BIN"
|
||||
fi
|
||||
|
||||
XMPP_BIN_ARGS="${XMPP_BIN_ARGS:-$(_readaccountconf_mutable XMPP_BIN_ARGS)}"
|
||||
if [ -n "$XMPP_BIN_ARGS" ]; then
|
||||
_saveaccountconf_mutable XMPP_BIN_ARGS "$XMPP_BIN_ARGS"
|
||||
else
|
||||
_clearaccountconf "XMPP_BIN_ARGS"
|
||||
fi
|
||||
|
||||
XMPP_TO="${XMPP_TO:-$(_readaccountconf_mutable XMPP_TO)}"
|
||||
if [ -n "$XMPP_TO" ]; then
|
||||
if ! _xmpp_valid "$XMPP_TO"; then
|
||||
_err "It seems that the XMPP_TO=$XMPP_TO is not a valid xmpp address."
|
||||
return 1
|
||||
fi
|
||||
|
||||
_saveaccountconf_mutable XMPP_TO "$XMPP_TO"
|
||||
fi
|
||||
|
||||
result=$({ _xmpp_message | eval "$(_xmpp_cmnd)"; } 2>&1)
|
||||
|
||||
# shellcheck disable=SC2181
|
||||
if [ $? -ne 0 ]; then
|
||||
_debug "xmpp send error."
|
||||
_err "$result"
|
||||
return 1
|
||||
fi
|
||||
|
||||
_debug "xmpp send success."
|
||||
return 0
|
||||
}
|
||||
|
||||
_xmpp_bin() {
|
||||
if [ -n "$XMPP_BIN" ]; then
|
||||
_XMPP_BIN="$XMPP_BIN"
|
||||
elif _exists "sendxmpp"; then
|
||||
_XMPP_BIN="sendxmpp"
|
||||
else
|
||||
_err "Please install sendxmpp first."
|
||||
return 1
|
||||
fi
|
||||
|
||||
echo "$_XMPP_BIN"
|
||||
}
|
||||
|
||||
_xmpp_cmnd() {
|
||||
case $(basename "$_XMPP_BIN") in
|
||||
sendxmpp)
|
||||
echo "'$_XMPP_BIN' '$XMPP_TO' $XMPP_BIN_ARGS"
|
||||
;;
|
||||
*)
|
||||
_err "Command $XMPP_BIN is not supported, use sendxmpp."
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
_xmpp_message() {
|
||||
echo "$_subject"
|
||||
}
|
||||
|
||||
_xmpp_valid() {
|
||||
_contains "$1" "@"
|
||||
}
|
||||
Reference in New Issue
Block a user