Merge branch 'dev' of https://github.com/Neilpang/acme.sh into dev
commit
7368a790a3
@ -1,4 +1,6 @@
|
||||
# How to use DNS API
|
||||
DNS api usage:
|
||||
|
||||
|
||||
https://github.com/Neilpang/acme.sh/wiki/dnsapi
|
||||
|
||||
|
@ -0,0 +1,83 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
## Acmeproxy DNS provider to be used with acmeproxy (http://github.com/mdbraber/acmeproxy)
|
||||
## API integration by Maarten den Braber
|
||||
##
|
||||
## Report any bugs via https://github.com/mdbraber/acme.sh
|
||||
|
||||
dns_acmeproxy_add() {
|
||||
fulldomain="${1}"
|
||||
txtvalue="${2}"
|
||||
action="present"
|
||||
|
||||
_debug "Calling: _acmeproxy_request() '${fulldomain}' '${txtvalue}' '${action}'"
|
||||
_acmeproxy_request "$fulldomain" "$txtvalue" "$action"
|
||||
}
|
||||
|
||||
dns_acmeproxy_rm() {
|
||||
fulldomain="${1}"
|
||||
txtvalue="${2}"
|
||||
action="cleanup"
|
||||
|
||||
_debug "Calling: _acmeproxy_request() '${fulldomain}' '${txtvalue}' '${action}'"
|
||||
_acmeproxy_request "$fulldomain" "$txtvalue" "$action"
|
||||
}
|
||||
|
||||
_acmeproxy_request() {
|
||||
|
||||
## Nothing to see here, just some housekeeping
|
||||
fulldomain=$1
|
||||
txtvalue=$2
|
||||
action=$3
|
||||
|
||||
_info "Using acmeproxy"
|
||||
_debug fulldomain "$fulldomain"
|
||||
_debug txtvalue "$txtvalue"
|
||||
|
||||
ACMEPROXY_ENDPOINT="${ACMEPROXY_ENDPOINT:-$(_readaccountconf_mutable ACMEPROXY_ENDPOINT)}"
|
||||
ACMEPROXY_USERNAME="${ACMEPROXY_USERNAME:-$(_readaccountconf_mutable ACMEPROXY_USERNAME)}"
|
||||
ACMEPROXY_PASSWORD="${ACMEPROXY_PASSWORD:-$(_readaccountconf_mutable ACMEPROXY_PASSWORD)}"
|
||||
|
||||
## Check for the endpoint
|
||||
if [ -z "$ACMEPROXY_ENDPOINT" ]; then
|
||||
ACMEPROXY_ENDPOINT=""
|
||||
_err "You didn't specify the endpoint"
|
||||
_err "Please set them via 'export ACMEPROXY_ENDPOINT=https://ip:port' and try again."
|
||||
return 1
|
||||
fi
|
||||
|
||||
## Save the credentials to the account file
|
||||
_saveaccountconf_mutable ACMEPROXY_ENDPOINT "$ACMEPROXY_ENDPOINT"
|
||||
_saveaccountconf_mutable ACMEPROXY_USERNAME "$ACMEPROXY_USERNAME"
|
||||
_saveaccountconf_mutable ACMEPROXY_PASSWORD "$ACMEPROXY_PASSWORD"
|
||||
|
||||
if [ -z "$ACMEPROXY_USERNAME" ] || [ -z "$ACMEPROXY_PASSWORD" ]; then
|
||||
_info "ACMEPROXY_USERNAME and/or ACMEPROXY_PASSWORD not set - using without client authentication! Make sure you're using server authentication (e.g. IP-based)"
|
||||
export _H1="Accept: application/json"
|
||||
export _H2="Content-Type: application/json"
|
||||
else
|
||||
## Base64 encode the credentials
|
||||
credentials=$(printf "%b" "$ACMEPROXY_USERNAME:$ACMEPROXY_PASSWORD" | _base64)
|
||||
|
||||
## Construct the HTTP Authorization header
|
||||
export _H1="Authorization: Basic $credentials"
|
||||
export _H2="Accept: application/json"
|
||||
export _H3="Content-Type: application/json"
|
||||
fi
|
||||
|
||||
## Add the challenge record to the acmeproxy grid member
|
||||
response="$(_post "{\"fqdn\": \"$fulldomain.\", \"value\": \"$txtvalue\"}" "$ACMEPROXY_ENDPOINT/$action" "" "POST")"
|
||||
|
||||
## Let's see if we get something intelligible back from the unit
|
||||
if echo "$response" | grep "\"$txtvalue\"" >/dev/null; then
|
||||
_info "Successfully updated the txt record"
|
||||
return 0
|
||||
else
|
||||
_err "Error encountered during record addition"
|
||||
_err "$response"
|
||||
return 1
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
#################### Private functions below ##################################
|
@ -0,0 +1,130 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
#Created by RaidenII, to use DuckDNS's API to add/remove text records
|
||||
#modified by helbgd @ 03/13/2018 to support ddnss.de
|
||||
#modified by mod242 @ 04/24/2018 to support different ddnss domains
|
||||
#Please note: the Wildcard Feature must be turned on for the Host record
|
||||
#and the checkbox for TXT needs to be enabled
|
||||
|
||||
# Pass credentials before "acme.sh --issue --dns dns_ddnss ..."
|
||||
# --
|
||||
# export DDNSS_Token="aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"
|
||||
# --
|
||||
#
|
||||
|
||||
DDNSS_DNS_API="https://ddnss.de/upd.php"
|
||||
|
||||
######## Public functions #####################
|
||||
|
||||
#Usage: dns_ddnss_add _acme-challenge.domain.ddnss.de "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
|
||||
dns_ddnss_add() {
|
||||
fulldomain=$1
|
||||
txtvalue=$2
|
||||
|
||||
DDNSS_Token="${DDNSS_Token:-$(_readaccountconf_mutable DDNSS_Token)}"
|
||||
if [ -z "$DDNSS_Token" ]; then
|
||||
_err "You must export variable: DDNSS_Token"
|
||||
_err "The token for your DDNSS account is necessary."
|
||||
_err "You can look it up in your DDNSS account."
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Now save the credentials.
|
||||
_saveaccountconf_mutable DDNSS_Token "$DDNSS_Token"
|
||||
|
||||
# Unfortunately, DDNSS does not seems to support lookup domain through API
|
||||
# So I assume your credentials (which are your domain and token) are correct
|
||||
# If something goes wrong, we will get a KO response from DDNSS
|
||||
|
||||
if ! _ddnss_get_domain; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Now add the TXT record to DDNSS DNS
|
||||
_info "Trying to add TXT record"
|
||||
if _ddnss_rest GET "key=$DDNSS_Token&host=$_ddnss_domain&txtm=1&txt=$txtvalue"; then
|
||||
if [ "$response" = "Updated 1 hostname." ]; then
|
||||
_info "TXT record has been successfully added to your DDNSS domain."
|
||||
_info "Note that all subdomains under this domain uses the same TXT record."
|
||||
return 0
|
||||
else
|
||||
_err "Errors happened during adding the TXT record, response=$response"
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
_err "Errors happened during adding the TXT record."
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
#Usage: fulldomain txtvalue
|
||||
#Remove the txt record after validation.
|
||||
dns_ddnss_rm() {
|
||||
fulldomain=$1
|
||||
txtvalue=$2
|
||||
|
||||
DDNSS_Token="${DDNSS_Token:-$(_readaccountconf_mutable DDNSS_Token)}"
|
||||
if [ -z "$DDNSS_Token" ]; then
|
||||
_err "You must export variable: DDNSS_Token"
|
||||
_err "The token for your DDNSS account is necessary."
|
||||
_err "You can look it up in your DDNSS account."
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! _ddnss_get_domain; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Now remove the TXT record from DDNS DNS
|
||||
_info "Trying to remove TXT record"
|
||||
if _ddnss_rest GET "key=$DDNSS_Token&host=$_ddnss_domain&txtm=1&txt=."; then
|
||||
if [ "$response" = "Updated 1 hostname." ]; then
|
||||
_info "TXT record has been successfully removed from your DDNSS domain."
|
||||
return 0
|
||||
else
|
||||
_err "Errors happened during removing the TXT record, response=$response"
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
_err "Errors happened during removing the TXT record."
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
#################### Private functions below ##################################
|
||||
|
||||
#fulldomain=_acme-challenge.domain.ddnss.de
|
||||
#returns
|
||||
# _ddnss_domain=domain
|
||||
_ddnss_get_domain() {
|
||||
|
||||
# We'll extract the domain/username from full domain
|
||||
_ddnss_domain="$(echo "$fulldomain" | _lower_case | _egrep_o '[.][^.][^.]*[.](ddnss|dyn-ip24|dyndns|dyn|dyndns1|home-webserver|myhome-server|dynip)\..*' | cut -d . -f 2-)"
|
||||
|
||||
if [ -z "$_ddnss_domain" ]; then
|
||||
_err "Error extracting the domain."
|
||||
return 1
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
#Usage: method URI
|
||||
_ddnss_rest() {
|
||||
method=$1
|
||||
param="$2"
|
||||
_debug param "$param"
|
||||
url="$DDNSS_DNS_API?$param"
|
||||
_debug url "$url"
|
||||
|
||||
# DDNSS uses GET to update domain info
|
||||
if [ "$method" = "GET" ]; then
|
||||
response="$(_get "$url" | sed 's/<[a-zA-Z\/][^>]*>//g' | _tail_n 1)"
|
||||
else
|
||||
_err "Unsupported method"
|
||||
return 1
|
||||
fi
|
||||
|
||||
_debug2 response "$response"
|
||||
return 0
|
||||
}
|
@ -0,0 +1,176 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
#DD_API_User="xxxxx"
|
||||
#DD_API_Key="xxxxxx"
|
||||
|
||||
_DD_BASE="https://durabledns.com/services/dns"
|
||||
|
||||
######## Public functions #####################
|
||||
|
||||
#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
|
||||
dns_durabledns_add() {
|
||||
fulldomain=$1
|
||||
txtvalue=$2
|
||||
|
||||
DD_API_User="${DD_API_User:-$(_readaccountconf_mutable DD_API_User)}"
|
||||
DD_API_Key="${DD_API_Key:-$(_readaccountconf_mutable DD_API_Key)}"
|
||||
if [ -z "$DD_API_User" ] || [ -z "$DD_API_Key" ]; then
|
||||
DD_API_User=""
|
||||
DD_API_Key=""
|
||||
_err "You didn't specify a durabledns api user or key yet."
|
||||
_err "You can get yours from here https://durabledns.com/dashboard/index.php"
|
||||
return 1
|
||||
fi
|
||||
|
||||
#save the api key and email to the account conf file.
|
||||
_saveaccountconf_mutable DD_API_User "$DD_API_User"
|
||||
_saveaccountconf_mutable DD_API_Key "$DD_API_Key"
|
||||
|
||||
_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"
|
||||
|
||||
_dd_soap createRecord string zonename "$_domain." string name "$_sub_domain" string type "TXT" string data "$txtvalue" int aux 0 int ttl 10 string ddns_enabled N
|
||||
_contains "$response" "createRecordResponse"
|
||||
}
|
||||
|
||||
dns_durabledns_rm() {
|
||||
fulldomain=$1
|
||||
txtvalue=$2
|
||||
|
||||
DD_API_User="${DD_API_User:-$(_readaccountconf_mutable DD_API_User)}"
|
||||
DD_API_Key="${DD_API_Key:-$(_readaccountconf_mutable DD_API_Key)}"
|
||||
if [ -z "$DD_API_User" ] || [ -z "$DD_API_Key" ]; then
|
||||
DD_API_User=""
|
||||
DD_API_Key=""
|
||||
_err "You didn't specify a durabledns api user or key yet."
|
||||
_err "You can get yours from here https://durabledns.com/dashboard/index.php"
|
||||
return 1
|
||||
fi
|
||||
|
||||
_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"
|
||||
|
||||
_debug "Find record id"
|
||||
if ! _dd_soap listRecords string zonename "$_domain."; then
|
||||
_err "can not listRecords"
|
||||
return 1
|
||||
fi
|
||||
|
||||
subtxt="$(echo "$txtvalue" | cut -c 1-30)"
|
||||
record="$(echo "$response" | sed 's/<item\>/#<item>/g' | tr '#' '\n' | grep ">$subtxt")"
|
||||
_debug record "$record"
|
||||
if [ -z "$record" ]; then
|
||||
_err "can not find record for txtvalue" "$txtvalue"
|
||||
_err "$response"
|
||||
return 1
|
||||
fi
|
||||
|
||||
recordid="$(echo "$record" | _egrep_o '<id xsi:type="xsd:int">[0-9]*</id>' | cut -d '>' -f 2 | cut -d '<' -f 1)"
|
||||
_debug recordid "$recordid"
|
||||
if [ -z "$recordid" ]; then
|
||||
_err "can not find record id"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! _dd_soap deleteRecord string zonename "$_domain." int id "$recordid"; then
|
||||
_err "delete error"
|
||||
return 1
|
||||
fi
|
||||
|
||||
_contains "$response" "Success"
|
||||
}
|
||||
|
||||
#_acme-challenge.www.domain.com
|
||||
#returns
|
||||
# _sub_domain=_acme-challenge.www
|
||||
# _domain=domain.com
|
||||
_get_root() {
|
||||
domain=$1
|
||||
if ! _dd_soap "listZones"; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
i=1
|
||||
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.</origin>"; 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
|
||||
|
||||
}
|
||||
|
||||
#method
|
||||
_dd_soap() {
|
||||
_method="$1"
|
||||
shift
|
||||
_urn="${_method}wsdl"
|
||||
# put the parameters to xml
|
||||
body="<tns:$_method>
|
||||
<apiuser xsi:type=\"xsd:string\">$DD_API_User</apiuser>
|
||||
<apikey xsi:type=\"xsd:string\">$DD_API_Key</apikey>
|
||||
"
|
||||
while [ "$1" ]; do
|
||||
_t="$1"
|
||||
shift
|
||||
_k="$1"
|
||||
shift
|
||||
_v="$1"
|
||||
shift
|
||||
body="$body<$_k xsi:type=\"xsd:$_t\">$_v</$_k>"
|
||||
done
|
||||
body="$body</tns:$_method>"
|
||||
_debug2 "SOAP request ${body}"
|
||||
|
||||
# build SOAP XML
|
||||
_xml='<?xml version="1.0" encoding="utf-8"?>
|
||||
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
|
||||
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
|
||||
xmlns:tns="urn:'$_urn'"
|
||||
xmlns:types="urn:'$_urn'/encodedTypes"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
|
||||
<soap:Body soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">'"$body"'</soap:Body>
|
||||
</soap:Envelope>'
|
||||
|
||||
_debug2 _xml "$_xml"
|
||||
# set SOAP headers
|
||||
_action="SOAPAction: \"urn:$_urn#$_method\""
|
||||
_debug2 "_action" "$_action"
|
||||
export _H1="$_action"
|
||||
export _H2="Content-Type: text/xml; charset=utf-8"
|
||||
|
||||
_url="$_DD_BASE/$_method.php"
|
||||
_debug "_url" "$_url"
|
||||
if ! response="$(_post "${_xml}" "${_url}")"; then
|
||||
_err "Error <$1>"
|
||||
return 1
|
||||
fi
|
||||
_debug2 "response" "$response"
|
||||
response="$(echo "$response" | tr -d "\r\n" | _egrep_o ":${_method}Response .*:${_method}Response><")"
|
||||
_debug2 "response" "$response"
|
||||
return 0
|
||||
}
|
@ -0,0 +1,180 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
#This is the Internet.BS api wrapper for acme.sh
|
||||
#
|
||||
#Author: <alexey@nelexa.ru> Ne-Lexa
|
||||
#Report Bugs here: https://github.com/Ne-Lexa/acme.sh
|
||||
|
||||
#INTERNETBS_API_KEY="sdfsdfsdfljlbjkljlkjsdfoiwje"
|
||||
#INTERNETBS_API_PASSWORD="sdfsdfsdfljlbjkljlkjsdfoiwje"
|
||||
|
||||
INTERNETBS_API_URL="https://api.internet.bs"
|
||||
|
||||
######## Public functions #####################
|
||||
|
||||
#Usage: dns_myapi_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
|
||||
dns_internetbs_add() {
|
||||
fulldomain=$1
|
||||
txtvalue=$2
|
||||
|
||||
INTERNETBS_API_KEY="${INTERNETBS_API_KEY:-$(_readaccountconf_mutable INTERNETBS_API_KEY)}"
|
||||
INTERNETBS_API_PASSWORD="${INTERNETBS_API_PASSWORD:-$(_readaccountconf_mutable INTERNETBS_API_PASSWORD)}"
|
||||
|
||||
if [ -z "$INTERNETBS_API_KEY" ] || [ -z "$INTERNETBS_API_PASSWORD" ]; then
|
||||
INTERNETBS_API_KEY=""
|
||||
INTERNETBS_API_PASSWORD=""
|
||||
_err "You didn't specify the INTERNET.BS api key and password yet."
|
||||
_err "Please create you key and try again."
|
||||
return 1
|
||||
fi
|
||||
|
||||
_saveaccountconf_mutable INTERNETBS_API_KEY "$INTERNETBS_API_KEY"
|
||||
_saveaccountconf_mutable INTERNETBS_API_PASSWORD "$INTERNETBS_API_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"
|
||||
|
||||
# https://testapi.internet.bs/Domain/DnsRecord/Add?ApiKey=testapi&Password=testpass&FullRecordName=w3.test-api-domain7.net&Type=CNAME&Value=www.internet.bs%&ResponseFormat=json
|
||||
if _internetbs_rest POST "Domain/DnsRecord/Add" "FullRecordName=${_sub_domain}.${_domain}&Type=TXT&Value=${txtvalue}&ResponseFormat=json"; then
|
||||
if ! _contains "$response" "\"status\":\"SUCCESS\""; then
|
||||
_err "ERROR add TXT record"
|
||||
_err "$response"
|
||||
return 1
|
||||
fi
|
||||
|
||||
_info "txt record add success."
|
||||
return 0
|
||||
fi
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
#Usage: fulldomain txtvalue
|
||||
#Remove the txt record after validation.
|
||||
dns_internetbs_rm() {
|
||||
fulldomain=$1
|
||||
txtvalue=$2
|
||||
|
||||
INTERNETBS_API_KEY="${INTERNETBS_API_KEY:-$(_readaccountconf_mutable INTERNETBS_API_KEY)}"
|
||||
INTERNETBS_API_PASSWORD="${INTERNETBS_API_PASSWORD:-$(_readaccountconf_mutable INTERNETBS_API_PASSWORD)}"
|
||||
|
||||
if [ -z "$INTERNETBS_API_KEY" ] || [ -z "$INTERNETBS_API_PASSWORD" ]; then
|
||||
INTERNETBS_API_KEY=""
|
||||
INTERNETBS_API_PASSWORD=""
|
||||
_err "You didn't specify the INTERNET.BS api key and password yet."
|
||||
_err "Please create you key and try again."
|
||||
return 1
|
||||
fi
|
||||
|
||||
_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"
|
||||
|
||||
_debug "Getting txt records"
|
||||
# https://testapi.internet.bs/Domain/DnsRecord/List?ApiKey=testapi&Password=testpass&Domain=test-api-domain7.net&FilterType=CNAME&ResponseFormat=json
|
||||
_internetbs_rest POST "Domain/DnsRecord/List" "Domain=$_domain&FilterType=TXT&ResponseFormat=json"
|
||||
|
||||
if ! _contains "$response" "\"status\":\"SUCCESS\""; then
|
||||
_err "ERROR list dns records"
|
||||
_err "$response"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if _contains "$response" "\name\":\"${_sub_domain}.${_domain}\""; then
|
||||
_info "txt record find."
|
||||
|
||||
# https://testapi.internet.bs/Domain/DnsRecord/Remove?ApiKey=testapi&Password=testpass&FullRecordName=www.test-api-domain7.net&Type=cname&ResponseFormat=json
|
||||
_internetbs_rest POST "Domain/DnsRecord/Remove" "FullRecordName=${_sub_domain}.${_domain}&Type=TXT&ResponseFormat=json"
|
||||
|
||||
if ! _contains "$response" "\"status\":\"SUCCESS\""; then
|
||||
_err "ERROR remove dns record"
|
||||
_err "$response"
|
||||
return 1
|
||||
fi
|
||||
|
||||
_info "txt record deleted success."
|
||||
return 0
|
||||
fi
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
#################### Private functions below ##################################
|
||||
#_acme-challenge.www.domain.com
|
||||
#returns
|
||||
# _sub_domain=_acme-challenge.www
|
||||
# _domain=domain.com
|
||||
# _domain_id=12345
|
||||
_get_root() {
|
||||
domain=$1
|
||||
i=2
|
||||
p=1
|
||||
|
||||
# https://testapi.internet.bs/Domain/List?ApiKey=testapi&Password=testpass&CompactList=yes&ResponseFormat=json
|
||||
if _internetbs_rest POST "Domain/List" "CompactList=yes&ResponseFormat=json"; then
|
||||
|
||||
if ! _contains "$response" "\"status\":\"SUCCESS\""; then
|
||||
_err "ERROR fetch domain list"
|
||||
_err "$response"
|
||||
return 1
|
||||
fi
|
||||
|
||||
while true; do
|
||||
h=$(printf "%s" "$domain" | cut -d . -f ${i}-100)
|
||||
_debug h "$h"
|
||||
if [ -z "$h" ]; then
|
||||
#not valid
|
||||
return 1
|
||||
fi
|
||||
|
||||
if _contains "$response" "\"$h\""; then
|
||||
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-${p})
|
||||
_domain=${h}
|
||||
return 0
|
||||
fi
|
||||
|
||||
p=${i}
|
||||
i=$(_math "$i" + 1)
|
||||
done
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
#Usage: method URI data
|
||||
_internetbs_rest() {
|
||||
m="$1"
|
||||
ep="$2"
|
||||
data="$3"
|
||||
url="${INTERNETBS_API_URL}/${ep}"
|
||||
|
||||
_debug url "$url"
|
||||
|
||||
apiKey="$(printf "%s" "${INTERNETBS_API_KEY}" | _url_encode)"
|
||||
password="$(printf "%s" "${INTERNETBS_API_PASSWORD}" | _url_encode)"
|
||||
|
||||
if [ "$m" = "GET" ]; then
|
||||
response="$(_get "${url}?ApiKey=${apiKey}&Password=${password}&${data}" | tr -d '\r')"
|
||||
else
|
||||
_debug2 data "$data"
|
||||
response="$(_post "$data" "${url}?ApiKey=${apiKey}&Password=${password}" | tr -d '\r')"
|
||||
fi
|
||||
|
||||
if [ "$?" != "0" ]; then
|
||||
_err "error $ep"
|
||||
return 1
|
||||
fi
|
||||
|
||||
_debug2 response "$response"
|
||||
return 0
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
#Nsd_ZoneFile="/etc/nsd/zones/example.com.zone"
|
||||
#Nsd_Command="sudo nsd-control reload"
|
||||
|
||||
# args: fulldomain txtvalue
|
||||
dns_nsd_add() {
|
||||
fulldomain=$1
|
||||
txtvalue=$2
|
||||
ttlvalue=300
|
||||
|
||||
Nsd_ZoneFile="${Nsd_ZoneFile:-$(_readdomainconf Nsd_ZoneFile)}"
|
||||
Nsd_Command="${Nsd_Command:-$(_readdomainconf Nsd_Command)}"
|
||||
|
||||
# Arg checks
|
||||
if [ -z "$Nsd_ZoneFile" ] || [ -z "$Nsd_Command" ]; then
|
||||
Nsd_ZoneFile=""
|
||||
Nsd_Command=""
|
||||
_err "Specify ENV vars Nsd_ZoneFile and Nsd_Command"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ ! -f "$Nsd_ZoneFile" ]; then
|
||||
Nsd_ZoneFile=""
|
||||
Nsd_Command=""
|
||||
_err "No such file: $Nsd_ZoneFile"
|
||||
return 1
|
||||
fi
|
||||
|
||||
_savedomainconf Nsd_ZoneFile "$Nsd_ZoneFile"
|
||||
_savedomainconf Nsd_Command "$Nsd_Command"
|
||||
|
||||
echo "$fulldomain. $ttlvalue IN TXT \"$txtvalue\"" >>"$Nsd_ZoneFile"
|
||||
_info "Added TXT record for $fulldomain"
|
||||
_debug "Running $Nsd_Command"
|
||||
if eval "$Nsd_Command"; then
|
||||
_info "Successfully updated the zone"
|
||||
return 0
|
||||
else
|
||||
_err "Problem updating the zone"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# args: fulldomain txtvalue
|
||||
dns_nsd_rm() {
|
||||
fulldomain=$1
|
||||
txtvalue=$2
|
||||
ttlvalue=300
|
||||
|
||||
Nsd_ZoneFile="${Nsd_ZoneFile:-$(_readdomainconf Nsd_ZoneFile)}"
|
||||
Nsd_Command="${Nsd_Command:-$(_readdomainconf Nsd_Command)}"
|
||||
|
||||
sed -i "/$fulldomain. $ttlvalue IN TXT \"$txtvalue\"/d" "$Nsd_ZoneFile"
|
||||
_info "Removed TXT record for $fulldomain"
|
||||
_debug "Running $Nsd_Command"
|
||||
if eval "$Nsd_Command"; then
|
||||
_info "Successfully reloaded NSD "
|
||||
return 0
|
||||
else
|
||||
_err "Problem reloading NSD"
|
||||
return 1
|
||||
fi
|
||||
}
|
@ -0,0 +1,139 @@
|
||||
#!/usr/bin/env sh
|
||||
# -*- mode: sh; tab-width: 2; indent-tabs-mode: s; coding: utf-8 -*-
|
||||
|
||||
# one.com ui wrapper for acme.sh
|
||||
# Author: github: @diseq
|
||||
# Created: 2019-02-17
|
||||
#
|
||||
# export ONECOM_User="username"
|
||||
# export ONECOM_Password="password"
|
||||
#
|
||||
# Usage:
|
||||
# acme.sh --issue --dns dns_one -d example.com
|
||||
#
|
||||
# only single domain supported atm
|
||||
|
||||
dns_one_add() {
|
||||
mysubdomain=$(printf -- "%s" "$1" | rev | cut -d"." -f3- | rev)
|
||||
mydomain=$(printf -- "%s" "$1" | rev | cut -d"." -f1-2 | rev)
|
||||
txtvalue=$2
|
||||
|
||||
# get credentials
|
||||
ONECOM_User="${ONECOM_User:-$(_readaccountconf_mutable ONECOM_User)}"
|
||||
ONECOM_Password="${ONECOM_Password:-$(_readaccountconf_mutable ONECOM_Password)}"
|
||||
if [ -z "$ONECOM_User" ] || [ -z "$ONECOM_Password" ]; then
|
||||
ONECOM_User=""
|
||||
ONECOM_Password=""
|
||||
_err "You didn't specify a one.com username and password yet."
|
||||
_err "Please create the key and try again."
|
||||
return 1
|
||||
fi
|
||||
|
||||
#save the api key and email to the account conf file.
|
||||
_saveaccountconf_mutable ONECOM_User "$ONECOM_User"
|
||||
_saveaccountconf_mutable ONECOM_Password "$ONECOM_Password"
|
||||
|
||||
# Login with user and password
|
||||
postdata="loginDomain=true"
|
||||
postdata="$postdata&displayUsername=$ONECOM_User"
|
||||
postdata="$postdata&username=$ONECOM_User"
|
||||
postdata="$postdata&targetDomain=$mydomain"
|
||||
postdata="$postdata&password1=$ONECOM_Password"
|
||||
postdata="$postdata&loginTarget="
|
||||
#_debug postdata "$postdata"
|
||||
|
||||
response="$(_post "$postdata" "https://www.one.com/admin/login.do" "" "POST" "application/x-www-form-urlencoded")"
|
||||
#_debug response "$response"
|
||||
|
||||
JSESSIONID="$(grep "JSESSIONID" "$HTTP_HEADER" | grep "^[Ss]et-[Cc]ookie:" | _tail_n 1 | _egrep_o 'JSESSIONID=[^;]*;' | tr -d ';')"
|
||||
_debug jsessionid "$JSESSIONID"
|
||||
|
||||
export _H1="Cookie: ${JSESSIONID}"
|
||||
|
||||
# get entries
|
||||
response="$(_get "https://www.one.com/admin/api/domains/$mydomain/dns/custom_records")"
|
||||
_debug response "$response"
|
||||
|
||||
CSRF_G_TOKEN="$(grep "CSRF_G_TOKEN=" "$HTTP_HEADER" | grep "^Set-Cookie:" | _tail_n 1 | _egrep_o 'CSRF_G_TOKEN=[^;]*;' | tr -d ';')"
|
||||
export _H2="Cookie: ${CSRF_G_TOKEN}"
|
||||
|
||||
# Update the IP address for domain entry
|
||||
postdata="{\"type\":\"dns_custom_records\",\"attributes\":{\"priority\":0,\"ttl\":600,\"type\":\"TXT\",\"prefix\":\"$mysubdomain\",\"content\":\"$txtvalue\"}}"
|
||||
_debug postdata "$postdata"
|
||||
response="$(_post "$postdata" "https://www.one.com/admin/api/domains/$mydomain/dns/custom_records" "" "POST" "application/json")"
|
||||
response="$(echo "$response" | _normalizeJson)"
|
||||
_debug response "$response"
|
||||
|
||||
id=$(echo "$response" | sed -n "s/{\"result\":{\"data\":{\"type\":\"dns_custom_records\",\"id\":\"\([^\"]*\)\",\"attributes\":{\"prefix\":\"$mysubdomain\",\"type\":\"TXT\",\"content\":\"$txtvalue\",\"priority\":0,\"ttl\":600}}},\"metadata\":null}/\1/p")
|
||||
|
||||
if [ -z "$id" ]; then
|
||||
_err "Add txt record error."
|
||||
return 1
|
||||
else
|
||||
_info "Added, OK ($id)"
|
||||
return 0
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
dns_one_rm() {
|
||||
mysubdomain=$(printf -- "%s" "$1" | rev | cut -d"." -f3- | rev)
|
||||
mydomain=$(printf -- "%s" "$1" | rev | cut -d"." -f1-2 | rev)
|
||||
txtvalue=$2
|
||||
|
||||
# get credentials
|
||||
ONECOM_User="${ONECOM_User:-$(_readaccountconf_mutable ONECOM_User)}"
|
||||
ONECOM_Password="${ONECOM_Password:-$(_readaccountconf_mutable ONECOM_Password)}"
|
||||
if [ -z "$ONECOM_User" ] || [ -z "$ONECOM_Password" ]; then
|
||||
ONECOM_User=""
|
||||
ONECOM_Password=""
|
||||
_err "You didn't specify a one.com username and password yet."
|
||||
_err "Please create the key and try again."
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Login with user and password
|
||||
postdata="loginDomain=true"
|
||||
postdata="$postdata&displayUsername=$ONECOM_User"
|
||||
postdata="$postdata&username=$ONECOM_User"
|
||||
postdata="$postdata&targetDomain=$mydomain"
|
||||
postdata="$postdata&password1=$ONECOM_Password"
|
||||
postdata="$postdata&loginTarget="
|
||||
|
||||
response="$(_post "$postdata" "https://www.one.com/admin/login.do" "" "POST" "application/x-www-form-urlencoded")"
|
||||
#_debug response "$response"
|
||||
|
||||
JSESSIONID="$(grep "JSESSIONID" "$HTTP_HEADER" | grep "^[Ss]et-[Cc]ookie:" | _tail_n 1 | _egrep_o 'JSESSIONID=[^;]*;' | tr -d ';')"
|
||||
_debug jsessionid "$JSESSIONID"
|
||||
|
||||
export _H1="Cookie: ${JSESSIONID}"
|
||||
|
||||
# get entries
|
||||
response="$(_get "https://www.one.com/admin/api/domains/$mydomain/dns/custom_records")"
|
||||
response="$(echo "$response" | _normalizeJson)"
|
||||
_debug response "$response"
|
||||
|
||||
CSRF_G_TOKEN="$(grep "CSRF_G_TOKEN=" "$HTTP_HEADER" | grep "^Set-Cookie:" | _tail_n 1 | _egrep_o 'CSRF_G_TOKEN=[^;]*;' | tr -d ';')"
|
||||
export _H2="Cookie: ${CSRF_G_TOKEN}"
|
||||
|
||||
id=$(printf -- "%s" "$response" | sed -n "s/.*{\"type\":\"dns_custom_records\",\"id\":\"\([^\"]*\)\",\"attributes\":{\"prefix\":\"$mysubdomain\",\"type\":\"TXT\",\"content\":\"$txtvalue\",\"priority\":0,\"ttl\":600}.*/\1/p")
|
||||
|
||||
if [ -z "$id" ]; then
|
||||
_err "Txt record not found."
|
||||
return 1
|
||||
fi
|
||||
|
||||
# delete entry
|
||||
response="$(_post "$postdata" "https://www.one.com/admin/api/domains/$mydomain/dns/custom_records/$id" "" "DELETE" "application/json")"
|
||||
response="$(echo "$response" | _normalizeJson)"
|
||||
_debug response "$response"
|
||||
|
||||
if [ "$response" = '{"result":null,"metadata":null}' ]; then
|
||||
_info "Removed, OK"
|
||||
return 0
|
||||
else
|
||||
_err "Removing txt record error."
|
||||
return 1
|
||||
fi
|
||||
|
||||
}
|
@ -0,0 +1,261 @@
|
||||
#!/usr/bin/env sh
|
||||
# -*- mode: sh; tab-width: 2; indent-tabs-mode: s; coding: utf-8 -*-
|
||||
|
||||
# Schlundtech DNS API
|
||||
# Author: mod242
|
||||
# Created: 2019-40-29
|
||||
# Completly based on the autoDNS xml api wrapper by auerswald@gmail.com
|
||||
#
|
||||
# export SCHLUNDTECH_USER="username"
|
||||
# export SCHLUNDTECH_PASSWORD="password"
|
||||
#
|
||||
# Usage:
|
||||
# acme.sh --issue --dns dns_schlundtech -d example.com
|
||||
|
||||
SCHLUNDTECH_API="https://gateway.schlundtech.de"
|
||||
|
||||
# Arguments:
|
||||
# txtdomain
|
||||
# txt
|
||||
dns_schlundtech_add() {
|
||||
fulldomain="$1"
|
||||
txtvalue="$2"
|
||||
|
||||
SCHLUNDTECH_USER="${SCHLUNDTECH_USER:-$(_readaccountconf_mutable SCHLUNDTECH_USER)}"
|
||||
SCHLUNDTECH_PASSWORD="${SCHLUNDTECH_PASSWORD:-$(_readaccountconf_mutable SCHLUNDTECH_PASSWORD)}"
|
||||
|
||||
if [ -z "$SCHLUNDTECH_USER" ] || [ -z "$SCHLUNDTECH_PASSWORD" ]; then
|
||||
_err "You didn't specify schlundtech user and password."
|
||||
return 1
|
||||
fi
|
||||
|
||||
_saveaccountconf_mutable SCHLUNDTECH_USER "$SCHLUNDTECH_USER"
|
||||
_saveaccountconf_mutable SCHLUNDTECH_PASSWORD "$SCHLUNDTECH_PASSWORD"
|
||||
|
||||
_debug "First detect the root zone"
|
||||
|
||||
if ! _get_autodns_zone "$fulldomain"; then
|
||||
_err "invalid domain"
|
||||
return 1
|
||||
fi
|
||||
|
||||
_debug _sub_domain "$_sub_domain"
|
||||
_debug _zone "$_zone"
|
||||
_debug _system_ns "$_system_ns"
|
||||
|
||||
_info "Adding TXT record"
|
||||
|
||||
autodns_response="$(_autodns_zone_update "$_zone" "$_sub_domain" "$txtvalue" "$_system_ns")"
|
||||
|
||||
if [ "$?" -eq "0" ]; then
|
||||
_info "Added, OK"
|
||||
return 0
|
||||
fi
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
# Arguments:
|
||||
# txtdomain
|
||||
# txt
|
||||
dns_schlundtech_rm() {
|
||||
fulldomain="$1"
|
||||
txtvalue="$2"
|
||||
|
||||
SCHLUNDTECH_USER="${SCHLUNDTECH_USER:-$(_readaccountconf_mutable SCHLUNDTECH_USER)}"
|
||||
SCHLUNDTECH_PASSWORD="${SCHLUNDTECH_PASSWORD:-$(_readaccountconf_mutable SCHLUNDTECH_PASSWORD)}"
|
||||
|
||||
if [ -z "$SCHLUNDTECH_USER" ] || [ -z "$SCHLUNDTECH_PASSWORD" ]; then
|
||||
_err "You didn't specify schlundtech user and password."
|
||||
return 1
|
||||
fi
|
||||
|
||||
_debug "First detect the root zone"
|
||||
|
||||
if ! _get_autodns_zone "$fulldomain"; then
|
||||
_err "zone not found"
|
||||
return 1
|
||||
fi
|
||||
|
||||
_debug _sub_domain "$_sub_domain"
|
||||
_debug _zone "$_zone"
|
||||
_debug _system_ns "$_system_ns"
|
||||
|
||||
_info "Delete TXT record"
|
||||
|
||||
autodns_response="$(_autodns_zone_cleanup "$_zone" "$_sub_domain" "$txtvalue" "$_system_ns")"
|
||||
|
||||
if [ "$?" -eq "0" ]; then
|
||||
_info "Deleted, OK"
|
||||
return 0
|
||||
fi
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
#################### Private functions below ##################################
|
||||
|
||||
# Arguments:
|
||||
# fulldomain
|
||||
# Returns:
|
||||
# _sub_domain=_acme-challenge.www
|
||||
# _zone=domain.com
|
||||
# _system_ns
|
||||
_get_autodns_zone() {
|
||||
domain="$1"
|
||||
|
||||
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
|
||||
|
||||
autodns_response="$(_autodns_zone_inquire "$h")"
|
||||
|
||||
if [ "$?" -ne "0" ]; then
|
||||
_err "invalid domain"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if _contains "$autodns_response" "<summary>1</summary>" >/dev/null; then
|
||||
_zone="$(echo "$autodns_response" | _egrep_o '<name>[^<]*</name>' | cut -d '>' -f 2 | cut -d '<' -f 1)"
|
||||
_system_ns="$(echo "$autodns_response" | _egrep_o '<system_ns>[^<]*</system_ns>' | cut -d '>' -f 2 | cut -d '<' -f 1)"
|
||||
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
|
||||
return 0
|
||||
fi
|
||||
|
||||
p=$i
|
||||
i=$(_math "$i" + 1)
|
||||
done
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
_build_request_auth_xml() {
|
||||
printf "<auth>
|
||||
<user>%s</user>
|
||||
<password>%s</password>
|
||||
<context>10</context>
|
||||
</auth>" "$SCHLUNDTECH_USER" "$SCHLUNDTECH_PASSWORD"
|
||||
}
|
||||
|
||||
# Arguments:
|
||||
# zone
|
||||
_build_zone_inquire_xml() {
|
||||
printf "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
|
||||
<request>
|
||||
%s
|
||||
<task>
|
||||
<code>0205</code>
|
||||
<view>
|
||||
<children>1</children>
|
||||
<limit>1</limit>
|
||||
</view>
|
||||
<where>
|
||||
<key>name</key>
|
||||
<operator>eq</operator>
|
||||
<value>%s</value>
|
||||
</where>
|
||||
</task>
|
||||
</request>" "$(_build_request_auth_xml)" "$1"
|
||||
}
|
||||
|
||||
# Arguments:
|
||||
# zone
|
||||
# subdomain
|
||||
# txtvalue
|
||||
# system_ns
|
||||
_build_zone_update_xml() {
|
||||
printf "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
|
||||
<request>
|
||||
%s
|
||||
<task>
|
||||
<code>0202001</code>
|
||||
<default>
|
||||
<rr_add>
|
||||
<name>%s</name>
|
||||
<ttl>600</ttl>
|
||||
<type>TXT</type>
|
||||
<value>%s</value>
|
||||
</rr_add>
|
||||
</default>
|
||||
<zone>
|
||||
<name>%s</name>
|
||||
<system_ns>%s</system_ns>
|
||||
</zone>
|
||||
</task>
|
||||
</request>" "$(_build_request_auth_xml)" "$2" "$3" "$1" "$4"
|
||||
}
|
||||
|
||||
# Arguments:
|
||||
# zone
|
||||
_autodns_zone_inquire() {
|
||||
request_data="$(_build_zone_inquire_xml "$1")"
|
||||
autodns_response="$(_autodns_api_call "$request_data")"
|
||||
ret="$?"
|
||||
|
||||
printf "%s" "$autodns_response"
|
||||
return "$ret"
|
||||
}
|
||||
|
||||
# Arguments:
|
||||
# zone
|
||||
# subdomain
|
||||
# txtvalue
|
||||
# system_ns
|
||||
_autodns_zone_update() {
|
||||
request_data="$(_build_zone_update_xml "$1" "$2" "$3" "$4")"
|
||||
autodns_response="$(_autodns_api_call "$request_data")"
|
||||
ret="$?"
|
||||
|
||||
printf "%s" "$autodns_response"
|
||||
return "$ret"
|
||||
}
|
||||
|
||||
# Arguments:
|
||||
# zone
|
||||
# subdomain
|
||||
# txtvalue
|
||||
# system_ns
|
||||
_autodns_zone_cleanup() {
|
||||
request_data="$(_build_zone_update_xml "$1" "$2" "$3" "$4")"
|
||||
# replace 'rr_add>' with 'rr_rem>' in request_data
|
||||
request_data="$(printf -- "%s" "$request_data" | sed 's/rr_add>/rr_rem>/g')"
|
||||
autodns_response="$(_autodns_api_call "$request_data")"
|
||||
ret="$?"
|
||||
|
||||
printf "%s" "$autodns_response"
|
||||
return "$ret"
|
||||
}
|
||||
|
||||
# Arguments:
|
||||
# request_data
|
||||
_autodns_api_call() {
|
||||
request_data="$1"
|
||||
|
||||
_debug request_data "$request_data"
|
||||
|
||||
autodns_response="$(_post "$request_data" "$SCHLUNDTECH_API")"
|
||||
ret="$?"
|
||||
|
||||
_debug autodns_response "$autodns_response"
|
||||
|
||||
if [ "$ret" -ne "0" ]; then
|
||||
_err "error"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if _contains "$autodns_response" "<type>success</type>" >/dev/null; then
|
||||
_info "success"
|
||||
printf "%s" "$autodns_response"
|
||||
return 0
|
||||
fi
|
||||
|
||||
return 1
|
||||
}
|
@ -0,0 +1,120 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
#Support local mail app
|
||||
|
||||
#MAIL_BIN="sendmail"
|
||||
#MAIL_FROM="yyyy@gmail.com"
|
||||
#MAIL_TO="yyyy@gmail.com"
|
||||
|
||||
mail_send() {
|
||||
_subject="$1"
|
||||
_content="$2"
|
||||
_statusCode="$3" #0: success, 1: error 2($RENEW_SKIP): skipped
|
||||
_debug "_subject" "$_subject"
|
||||
_debug "_content" "$_content"
|
||||
_debug "_statusCode" "$_statusCode"
|
||||
|
||||
MAIL_BIN="${MAIL_BIN:-$(_readaccountconf_mutable MAIL_BIN)}"
|
||||
if [ -n "$MAIL_BIN" ] && ! _exists "$MAIL_BIN"; then
|
||||
_err "It seems that the command $MAIL_BIN is not in path."
|
||||
return 1
|
||||
fi
|
||||
_MAIL_CMD=$(_mail_cmnd)
|
||||
if [ -n "$MAIL_BIN" ]; then
|
||||
_saveaccountconf_mutable MAIL_BIN "$MAIL_BIN"
|
||||
else
|
||||
_clearaccountconf "MAIL_BIN"
|
||||
fi
|
||||
_MAIL_BODY=$(_mail_body)
|
||||
|
||||
MAIL_FROM="${MAIL_FROM:-$(_readaccountconf_mutable MAIL_FROM)}"
|
||||
if [ -n "$MAIL_FROM" ]; then
|
||||
if ! _contains "$MAIL_FROM" "@"; then
|
||||
_err "It seems that the MAIL_FROM=$MAIL_FROM is not a valid email address."
|
||||
return 1
|
||||
fi
|
||||
|
||||
_saveaccountconf_mutable MAIL_FROM "$MAIL_FROM"
|
||||
fi
|
||||
|
||||
MAIL_TO="${MAIL_TO:-$(_readaccountconf_mutable MAIL_TO)}"
|
||||
if [ -n "$MAIL_TO" ]; then
|
||||
if ! _contains "$MAIL_TO" "@"; then
|
||||
_err "It seems that the MAIL_TO=$MAIL_TO is not a valid email address."
|
||||
return 1
|
||||
fi
|
||||
|
||||
_saveaccountconf_mutable MAIL_TO "$MAIL_TO"
|
||||
else
|
||||
MAIL_TO="$(_readaccountconf ACCOUNT_EMAIL)"
|
||||
if [ -z "$MAIL_TO" ]; then
|
||||
_err "It seems that account email is empty."
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
|
||||
contenttype="text/plain; charset=utf-8"
|
||||
subject="=?UTF-8?B?$(echo "$_subject" | _base64)?="
|
||||
result=$({ echo "$_MAIL_BODY" | eval "$_MAIL_CMD"; } 2>&1)
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
_debug "mail send error."
|
||||
_err "$result"
|
||||
return 1
|
||||
fi
|
||||
|
||||
_debug "mail send success."
|
||||
return 0
|
||||
}
|
||||
|
||||
_mail_cmnd() {
|
||||
if [ -n "$MAIL_BIN" ]; then
|
||||
_MAIL_BIN="$MAIL_BIN"
|
||||
elif _exists "sendmail"; then
|
||||
_MAIL_BIN="sendmail"
|
||||
elif _exists "ssmtp"; then
|
||||
_MAIL_BIN="ssmtp"
|
||||
elif _exists "mutt"; then
|
||||
_MAIL_BIN="mutt"
|
||||
elif _exists "mail"; then
|
||||
_MAIL_BIN="mail"
|
||||
else
|
||||
_err "Please install sendmail, ssmtp, mutt or mail first."
|
||||
return 1
|
||||
fi
|
||||
|
||||
case $(basename "$_MAIL_BIN") in
|
||||
sendmail)
|
||||
if [ -n "$MAIL_FROM" ]; then
|
||||
echo "'$_MAIL_BIN' -f '$MAIL_FROM' '$MAIL_TO'"
|
||||
else
|
||||
echo "'$_MAIL_BIN' '$MAIL_TO'"
|
||||
fi
|
||||
;;
|
||||
ssmtp)
|
||||
echo "'$_MAIL_BIN' '$MAIL_TO'"
|
||||
;;
|
||||
mutt | mail)
|
||||
echo "'$_MAIL_BIN' -s '$_subject' '$MAIL_TO'"
|
||||
;;
|
||||
*)
|
||||
_err "Command $MAIL_BIN is not supported, use sendmail, ssmtp, mutt or mail."
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
_mail_body() {
|
||||
if [ "$_MAIL_BIN" = "sendmail" ] || [ "$_MAIL_BIN" = "ssmtp" ]; then
|
||||
if [ -n "$MAIL_FROM" ]; then
|
||||
echo "From: $MAIL_FROM"
|
||||
fi
|
||||
|
||||
echo "To: $MAIL_TO"
|
||||
echo "Subject: $subject"
|
||||
echo "Content-Type: $contenttype"
|
||||
echo
|
||||
fi
|
||||
|
||||
echo "$_content"
|
||||
}
|
@ -0,0 +1,131 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
#Support mailgun.com api
|
||||
|
||||
#MAILGUN_API_KEY="xxxx"
|
||||
#MAILGUN_TO="yyyy@gmail.com"
|
||||
|
||||
#MAILGUN_REGION="us|eu" #optional, use "us" as default
|
||||
#MAILGUN_API_DOMAIN="xxxxxx.com" #optional, use the default sandbox domain
|
||||
#MAILGUN_FROM="xxx@xxxxx.com" #optional, use the default sendbox account
|
||||
|
||||
_MAILGUN_BASE_US="https://api.mailgun.net/v3"
|
||||
_MAILGUN_BASE_EU="https://api.eu.mailgun.net/v3"
|
||||
|
||||
_MAILGUN_BASE="$_MAILGUN_BASE_US"
|
||||
|
||||
# subject content statusCode
|
||||
mailgun_send() {
|
||||
_subject="$1"
|
||||
_content="$2"
|
||||
_statusCode="$3" #0: success, 1: error 2($RENEW_SKIP): skipped
|
||||
_debug "_statusCode" "$_statusCode"
|
||||
|
||||
MAILGUN_API_KEY="${MAILGUN_API_KEY:-$(_readaccountconf_mutable MAILGUN_API_KEY)}"
|
||||
if [ -z "$MAILGUN_API_KEY" ]; then
|
||||
MAILGUN_API_KEY=""
|
||||
_err "You didn't specify a mailgun api key MAILGUN_API_KEY yet ."
|
||||
_err "You can get yours from here https://mailgun.com"
|
||||
return 1
|
||||
fi
|
||||
_saveaccountconf_mutable MAILGUN_API_KEY "$MAILGUN_API_KEY"
|
||||
|
||||
MAILGUN_REGION="${MAILGUN_REGION:-$(_readaccountconf_mutable MAILGUN_REGION)}"
|
||||
if [ -z "$MAILGUN_REGION" ]; then
|
||||
MAILGUN_REGION=""
|
||||
_debug "The MAILGUN_REGION is not set, so use the default us region."
|
||||
_MAILGUN_BASE="$_MAILGUN_BASE_US"
|
||||
else
|
||||
MAILGUN_REGION="$(echo "$MAILGUN_REGION" | _lower_case)"
|
||||
_saveaccountconf_mutable MAILGUN_REGION "$MAILGUN_REGION"
|
||||
if [ "$MAILGUN_REGION" = "us" ]; then
|
||||
_MAILGUN_BASE="$_MAILGUN_BASE_US"
|
||||
else
|
||||
_MAILGUN_BASE="$_MAILGUN_BASE_EU"
|
||||
fi
|
||||
fi
|
||||
_debug _MAILGUN_BASE "$_MAILGUN_BASE"
|
||||
MAILGUN_TO="${MAILGUN_TO:-$(_readaccountconf_mutable MAILGUN_TO)}"
|
||||
if [ -z "$MAILGUN_TO" ]; then
|
||||
MAILGUN_TO=""
|
||||
_err "You didn't specify an email to MAILGUN_TO receive messages."
|
||||
return 1
|
||||
fi
|
||||
_saveaccountconf_mutable MAILGUN_TO "$MAILGUN_TO"
|
||||
|
||||
MAILGUN_API_DOMAIN="${MAILGUN_API_DOMAIN:-$(_readaccountconf_mutable MAILGUN_API_DOMAIN)}"
|
||||
if [ -z "$MAILGUN_API_DOMAIN" ]; then
|
||||
_info "The MAILGUN_API_DOMAIN is not set, try to get the default sending sandbox domain for you."
|
||||
if ! _mailgun_rest GET "/domains"; then
|
||||
_err "Can not get sandbox domain."
|
||||
return 1
|
||||
fi
|
||||
_sendboxDomain="$(echo "$response" | _egrep_o '"name": *"sandbox.*.mailgun.org"' | cut -d : -f 2 | tr -d '" ')"
|
||||
_debug _sendboxDomain "$_sendboxDomain"
|
||||
MAILGUN_API_DOMAIN="$_sendboxDomain"
|
||||
if [ -z "$MAILGUN_API_DOMAIN" ]; then
|
||||
_err "Can not get sandbox domain for MAILGUN_API_DOMAIN"
|
||||
return 1
|
||||
fi
|
||||
|
||||
_info "$(__green "When using sandbox domain, you must verify your email first.")"
|
||||
#todo: add recepient
|
||||
fi
|
||||
if [ -z "$MAILGUN_API_DOMAIN" ]; then
|
||||
_err "Can not get MAILGUN_API_DOMAIN"
|
||||
return 1
|
||||
fi
|
||||
_saveaccountconf_mutable MAILGUN_API_DOMAIN "$MAILGUN_API_DOMAIN"
|
||||
|
||||
MAILGUN_FROM="${MAILGUN_FROM:-$(_readaccountconf_mutable MAILGUN_FROM)}"
|
||||
if [ -z "$MAILGUN_FROM" ]; then
|
||||
MAILGUN_FROM="$PROJECT_NAME@$MAILGUN_API_DOMAIN"
|
||||
_info "The MAILGUN_FROM is not set, so use the default value: $MAILGUN_FROM"
|
||||
else
|
||||
_debug MAILGUN_FROM "$MAILGUN_FROM"
|
||||
_saveaccountconf_mutable MAILGUN_FROM "$MAILGUN_FROM"
|
||||
fi
|
||||
|
||||
#send from url
|
||||
_msg="/$MAILGUN_API_DOMAIN/messages?from=$(printf "%s" "$MAILGUN_FROM" | _url_encode)&to=$(printf "%s" "$MAILGUN_TO" | _url_encode)&subject=$(printf "%s" "$_subject" | _url_encode)&text=$(printf "%s" "$_content" | _url_encode)"
|
||||
_debug "_msg" "$_msg"
|
||||
_mailgun_rest POST "$_msg"
|
||||
if _contains "$response" "Queued. Thank you."; then
|
||||
_debug "mailgun send success."
|
||||
return 0
|
||||
else
|
||||
_err "mailgun send error"
|
||||
_err "$response"
|
||||
return 1
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
# method uri data
|
||||
_mailgun_rest() {
|
||||
_method="$1"
|
||||
_mguri="$2"
|
||||
_mgdata="$3"
|
||||
_debug _mguri "$_mguri"
|
||||
_mgurl="$_MAILGUN_BASE$_mguri"
|
||||
_debug _mgurl "$_mgurl"
|
||||
|
||||
_auth="$(printf "%s" "api:$MAILGUN_API_KEY" | _base64)"
|
||||
export _H1="Authorization: Basic $_auth"
|
||||
export _H2="Content-Type: application/json"
|
||||
|
||||
if [ "$_method" = "GET" ]; then
|
||||
response="$(_get "$_mgurl")"
|
||||
else
|
||||
_debug _mgdata "$_mgdata"
|
||||
response="$(_post "$_mgdata" "$_mgurl" "" "$_method")"
|
||||
fi
|
||||
if [ "$?" != "0" ]; then
|
||||
_err "Error: $_mguri"
|
||||
_err "$response"
|
||||
return 1
|
||||
fi
|
||||
_debug2 response "$response"
|
||||
return 0
|
||||
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
# support pop
|
||||
|
||||
pop_send() {
|
||||
_subject="$1"
|
||||
_content="$2"
|
||||
_statusCode="$3" #0: success, 1: error 2($RENEW_SKIP): skipped
|
||||
_debug "_subject" "$_subject"
|
||||
_debug "_content" "$_content"
|
||||
_debug "_statusCode" "$_statusCode"
|
||||
|
||||
_err "Not implemented yet."
|
||||
return 1
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
#Support SENDGRID.com api
|
||||
|
||||
#SENDGRID_API_KEY=""
|
||||
#SENDGRID_TO="xxxx@xxx.com"
|
||||
#SENDGRID_FROM="xxxx@cccc.com"
|
||||
|
||||
sendgrid_send() {
|
||||
_subject="$1"
|
||||
_content="$2"
|
||||
_statusCode="$3" #0: success, 1: error 2($RENEW_SKIP): skipped
|
||||
_debug "_statusCode" "$_statusCode"
|
||||
|
||||
SENDGRID_API_KEY="${SENDGRID_API_KEY:-$(_readaccountconf_mutable SENDGRID_API_KEY)}"
|
||||
if [ -z "$SENDGRID_API_KEY" ]; then
|
||||
SENDGRID_API_KEY=""
|
||||
_err "You didn't specify a sendgrid api key SENDGRID_API_KEY yet ."
|
||||
_err "You can get yours from here https://sendgrid.com"
|
||||
return 1
|
||||
fi
|
||||
_saveaccountconf_mutable SENDGRID_API_KEY "$SENDGRID_API_KEY"
|
||||
|
||||
SENDGRID_TO="${SENDGRID_TO:-$(_readaccountconf_mutable SENDGRID_TO)}"
|
||||
if [ -z "$SENDGRID_TO" ]; then
|
||||
SENDGRID_TO=""
|
||||
_err "You didn't specify an email to SENDGRID_TO receive messages."
|
||||
return 1
|
||||
fi
|
||||
_saveaccountconf_mutable SENDGRID_TO "$SENDGRID_TO"
|
||||
|
||||
SENDGRID_FROM="${SENDGRID_FROM:-$(_readaccountconf_mutable SENDGRID_FROM)}"
|
||||
if [ -z "$SENDGRID_FROM" ]; then
|
||||
SENDGRID_FROM=""
|
||||
_err "You didn't specify an email to SENDGRID_FROM receive messages."
|
||||
return 1
|
||||
fi
|
||||
_saveaccountconf_mutable SENDGRID_FROM "$SENDGRID_FROM"
|
||||
|
||||
export _H1="Authorization: Bearer $SENDGRID_API_KEY"
|
||||
export _H2="Content-Type: application/json"
|
||||
|
||||
_content="$(echo "$_content" | _json_encode)"
|
||||
_data="{\"personalizations\": [{\"to\": [{\"email\": \"$SENDGRID_TO\"}]}],\"from\": {\"email\": \"$SENDGRID_FROM\"},\"subject\": \"$_subject\",\"content\": [{\"type\": \"text/plain\", \"value\": \"$_content\"}]}"
|
||||
response="" #just make shellcheck happy
|
||||
if _post "$_data" "https://api.sendgrid.com/v3/mail/send"; then
|
||||
if [ -z "$response" ]; then
|
||||
_info "sendgrid send sccess."
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
_err "sendgrid send error."
|
||||
_err "$response"
|
||||
return 1
|
||||
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
#Support Slack webhooks
|
||||
|
||||
#SLACK_WEBHOOK_URL=""
|
||||
#SLACK_CHANNEL=""
|
||||
#SLACK_USERNAME=""
|
||||
|
||||
slack_send() {
|
||||
_subject="$1"
|
||||
_content="$2"
|
||||
_statusCode="$3" #0: success, 1: error 2($RENEW_SKIP): skipped
|
||||
_debug "_statusCode" "$_statusCode"
|
||||
|
||||
SLACK_WEBHOOK_URL="${SLACK_WEBHOOK_URL:-$(_readaccountconf_mutable SLACK_WEBHOOK_URL)}"
|
||||
if [ -z "$SLACK_WEBHOOK_URL" ]; then
|
||||
SLACK_WEBHOOK_URL=""
|
||||
_err "You didn't specify a Slack webhook url SLACK_WEBHOOK_URL yet."
|
||||
return 1
|
||||
fi
|
||||
_saveaccountconf_mutable SLACK_WEBHOOK_URL "$SLACK_WEBHOOK_URL"
|
||||
|
||||
SLACK_CHANNEL="${SLACK_CHANNEL:-$(_readaccountconf_mutable SLACK_CHANNEL)}"
|
||||
if [ -n "$SLACK_CHANNEL" ]; then
|
||||
_saveaccountconf_mutable SLACK_CHANNEL "$SLACK_CHANNEL"
|
||||
fi
|
||||
|
||||
SLACK_USERNAME="${SLACK_USERNAME:-$(_readaccountconf_mutable SLACK_USERNAME)}"
|
||||
if [ -n "$SLACK_USERNAME" ]; then
|
||||
_saveaccountconf_mutable SLACK_USERNAME "$SLACK_USERNAME"
|
||||
fi
|
||||
|
||||
export _H1="Content-Type: application/json"
|
||||
|
||||
_content="$(printf "*%s*\n%s" "$_subject" "$_content" | _json_encode)"
|
||||
_data="{\"text\": \"$_content\", "
|
||||
if [ -n "$SLACK_CHANNEL" ]; then
|
||||
_data="$_data\"channel\": \"$SLACK_CHANNEL\", "
|
||||
fi
|
||||
if [ -n "$SLACK_USERNAME" ]; then
|
||||
_data="$_data\"username\": \"$SLACK_USERNAME\", "
|
||||
fi
|
||||
_data="$_data\"mrkdwn\": \"true\"}"
|
||||
|
||||
if _post "$_data" "$SLACK_WEBHOOK_URL"; then
|
||||
# shellcheck disable=SC2154
|
||||
if [ "$response" = "ok" ]; then
|
||||
_info "slack send success."
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
_err "slack send error."
|
||||
_err "$response"
|
||||
return 1
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
# support smtp
|
||||
|
||||
smtp_send() {
|
||||
_subject="$1"
|
||||
_content="$2"
|
||||
_statusCode="$3" #0: success, 1: error 2($RENEW_SKIP): skipped
|
||||
_debug "_subject" "$_subject"
|
||||
_debug "_content" "$_content"
|
||||
_debug "_statusCode" "$_statusCode"
|
||||
|
||||
_err "Not implemented yet."
|
||||
return 1
|
||||
}
|
Loading…
Reference in New Issue