Browse Source

Merge branch 'dev' into feature/hosting.de-plugin

Oliver Dick 6 years ago
parent
commit
ee258f1425
7 changed files with 252 additions and 23 deletions
  1. 1 0
      README.md
  2. 16 16
      acme.sh
  3. 19 3
      dnsapi/README.md
  4. 1 1
      dnsapi/dns_azure.sh
  5. 2 2
      dnsapi/dns_cx.sh
  6. 3 1
      dnsapi/dns_he.sh
  7. 210 0
      dnsapi/dns_mydnsjp.sh

+ 1 - 0
README.md

@@ -327,6 +327,7 @@ You don't have to do anything manually!
 1. netcup DNS API (https://www.netcup.de)
 1. GratisDNS.dk (https://gratisdns.dk)
 1. Namecheap API (https://www.namecheap.com/)
+1. MyDNS.JP API (https://www.mydns.jp/)
 1. hosting.de (https://www.hosting.de)
 
 And: 

+ 16 - 16
acme.sh

@@ -124,23 +124,19 @@ if [ -t 1 ]; then
 fi
 
 __green() {
-  if [ "$__INTERACTIVE${ACME_NO_COLOR}" = "1" -o "${ACME_FORCE_COLOR}" = "1" ]; then
-    printf '\033[1;31;32m'
+  if [ "${__INTERACTIVE}${ACME_NO_COLOR:-0}" = "10" -o "${ACME_FORCE_COLOR}" = "1" ]; then
+    printf '\033[1;31;32m%b\033[0m' "$1"
+    return
   fi
   printf -- "%b" "$1"
-  if [ "$__INTERACTIVE${ACME_NO_COLOR}" = "1" -o "${ACME_FORCE_COLOR}" = "1" ]; then
-    printf '\033[0m'
-  fi
 }
 
 __red() {
-  if [ "$__INTERACTIVE${ACME_NO_COLOR}" = "1" -o "${ACME_FORCE_COLOR}" = "1" ]; then
-    printf '\033[1;31;40m'
+  if [ "${__INTERACTIVE}${ACME_NO_COLOR:-0}" = "10" -o "${ACME_FORCE_COLOR}" = "1" ]; then
+    printf '\033[1;31;40m%b\033[0m' "$1"
+    return
   fi
   printf -- "%b" "$1"
-  if [ "$__INTERACTIVE${ACME_NO_COLOR}" = "1" -o "${ACME_FORCE_COLOR}" = "1" ]; then
-    printf '\033[0m'
-  fi
 }
 
 _printargs() {
@@ -1810,14 +1806,14 @@ _send_signed_request() {
     if [ -z "$_CACHED_NONCE" ]; then
       _headers=""
       if [ "$ACME_NEW_NONCE" ]; then
-        _debug2 "Get nonce. ACME_NEW_NONCE" "$ACME_NEW_NONCE"
+        _debug2 "Get nonce with HEAD. ACME_NEW_NONCE" "$ACME_NEW_NONCE"
         nonceurl="$ACME_NEW_NONCE"
         if _post "" "$nonceurl" "" "HEAD" "$__request_conent_type"; then
           _headers="$(cat "$HTTP_HEADER")"
         fi
       fi
       if [ -z "$_headers" ]; then
-        _debug2 "Get nonce. ACME_DIRECTORY" "$ACME_DIRECTORY"
+        _debug2 "Get nonce with GET. ACME_DIRECTORY" "$ACME_DIRECTORY"
         nonceurl="$ACME_DIRECTORY"
         _headers="$(_get "$nonceurl" "onlyheader")"
       fi
@@ -2925,6 +2921,7 @@ _clearupdns() {
     _debug txt "$txt"
     if [ "$keyauthorization" = "$STATE_VERIFIED" ]; then
       _debug "$d is already verified, skip $vtype."
+      _alias_index="$(_math "$_alias_index" + 1)"
       continue
     fi
 
@@ -3775,6 +3772,7 @@ $_authorizations_map"
       _debug d "$d"
       if [ "$keyauthorization" = "$STATE_VERIFIED" ]; then
         _debug "$d is already verified, skip $vtype."
+        _alias_index="$(_math "$_alias_index" + 1)"
         continue
       fi
 
@@ -4602,7 +4600,8 @@ deploy() {
 
   _initpath "$_d" "$_isEcc"
   if [ ! -d "$DOMAIN_PATH" ]; then
-    _err "Domain is not valid:'$_d'"
+    _err "The domain '$_d' is not a cert name. You must use the cert name to specify the cert to install."
+    _err "Can not find path:'$DOMAIN_PATH'"
     return 1
   fi
 
@@ -4629,7 +4628,8 @@ installcert() {
 
   _initpath "$_main_domain" "$_isEcc"
   if [ ! -d "$DOMAIN_PATH" ]; then
-    _err "Domain is not valid:'$_main_domain'"
+    _err "The domain '$_main_domain' is not a cert name. You must use the cert name to specify the cert to install."
+    _err "Can not find path:'$DOMAIN_PATH'"
     return 1
   fi
 
@@ -5474,7 +5474,7 @@ Parameters:
   --log-level 1|2                   Specifies the log level, default is 1.
   --syslog [0|3|6|7]                Syslog level, 0: disable syslog, 3: error, 6: info, 7: debug.
 
-  These parameters are to install the cert to nginx/apache or anyother server after issue/renew a cert:
+  These parameters are to install the cert to nginx/apache or any other server after issue/renew a cert:
 
   --cert-file                       After issue/renew, the cert will be copied to this path.
   --key-file                        After issue/renew, the key will be copied to this path.
@@ -5485,7 +5485,7 @@ Parameters:
 
   --server SERVER                   ACME Directory Resource URI. (default: https://acme-v01.api.letsencrypt.org/directory)
   --accountconf                     Specifies a customized account config file.
-  --home                            Specifies the home dir for $PROJECT_NAME .
+  --home                            Specifies the home dir for $PROJECT_NAME.
   --cert-home                       Specifies the home dir to save all the certs, only valid for '--install' command.
   --config-home                     Specifies the home dir to save all the configurations.
   --useragent                       Specifies the user agent string. it will be saved for future use too.

+ 19 - 3
dnsapi/README.md

@@ -6,7 +6,7 @@ https://github.com/Neilpang/acme.sh/wiki/DNS-alias-mode
 
 ## 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](https://dash.cloudflare.com/profile). 
 
 ```
 export CF_Key="sdfsdfsdfljlbjkljlkjsdfoiwje"
@@ -454,7 +454,7 @@ The `Infoblox_Creds` and `Infoblox_Server` will be saved in `~/.acme.sh/account.
 First you need to create/obtain API tokens on your [settings panel](https://vscale.io/panel/settings/tokens/).
 
 ```
-VSCALE_API_KEY="sdfsdfsdfljlbjkljlkjsdfoiwje"
+export VSCALE_API_KEY="sdfsdfsdfljlbjkljlkjsdfoiwje"
 ```
 
 Ok, let's issue a cert now:
@@ -1014,7 +1014,23 @@ Now you can issue a certificate.
 acme.sh --issue --dns dns_namecheap -d example.com -d *.example.com
 ```
 
-## 54. Use hosting.de API
+## 54. Use MyDNS.JP API
+
+First, register to MyDNS.JP and get MasterID and Password.
+
+```
+export MYDNSJP_MasterID=MasterID
+export MYDNSJP_Password=Password
+```
+
+To issue a certificate:
+
+```
+acme.sh --issue --dns dns_mydnsjp -d example.com -d www.example.com
+```
+The `MYDNSJP_MasterID` and `MYDNSJP_Password` will be saved in `~/.acme.sh/account.conf` and will be reused when needed.
+
+## 55. Use hosting.de API
 
 Create an API key in your hosting.de account here: https://secure.hosting.de
 

+ 1 - 1
dnsapi/dns_azure.sh

@@ -316,7 +316,7 @@ _get_root() {
   ## (ZoneListResult with  continuation token for the next page of results)
   ## Per https://docs.microsoft.com/en-us/azure/azure-subscription-service-limits#dns-limits you are limited to 100 Zone/subscriptions anyways
   ##
-  _azure_rest GET "https://management.azure.com/subscriptions/$subscriptionId/providers/Microsoft.Network/dnszones?api-version=2017-09-01" "" "$accesstoken"
+  _azure_rest GET "https://management.azure.com/subscriptions/$subscriptionId/providers/Microsoft.Network/dnszones?\$top=500&api-version=2017-09-01" "" "$accesstoken"
   # Find matching domain name is Json response
   while true; do
     h=$(printf "%s" "$domain" | cut -d . -f $i-100)

+ 2 - 2
dnsapi/dns_cx.sh

@@ -1,6 +1,6 @@
 #!/usr/bin/env sh
 
-# Cloudxns.com Domain api
+# CloudXNS Domain api
 #
 #CX_Key="1234"
 #
@@ -19,7 +19,7 @@ dns_cx_add() {
   if [ -z "$CX_Key" ] || [ -z "$CX_Secret" ]; then
     CX_Key=""
     CX_Secret=""
-    _err "You don't specify cloudxns.com  api key or secret yet."
+    _err "You don't specify cloudxns.net  api key or secret yet."
     _err "Please create you key and try again."
     return 1
   fi

+ 3 - 1
dnsapi/dns_he.sh

@@ -92,7 +92,9 @@ dns_he_rm() {
     return 1
   fi
   # Remove the record
-  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&menu=edit_zone"
   body="$body&hosted_dns_zoneid=$_zone_id"
   body="$body&hosted_dns_recordid=$_record_id"

+ 210 - 0
dnsapi/dns_mydnsjp.sh

@@ -0,0 +1,210 @@
+#!/usr/bin/env sh
+
+#Here is a api script for MyDNS.JP.
+#This file name is "dns_mydnsjp.sh"
+#So, here must be a method   dns_mydnsjp_add()
+#Which will be called by acme.sh to add the txt record to your api system.
+#returns 0 means success, otherwise error.
+#
+#Author: epgdatacapbon
+#Report Bugs here: https://github.com/epgdatacapbon/acme.sh
+#
+########  Public functions #####################
+
+# Export MyDNS.JP MasterID and Password in following variables...
+#  MYDNSJP_MasterID=MasterID
+#  MYDNSJP_Password=Password
+
+MYDNSJP_API="https://www.mydns.jp"
+
+#Usage: dns_mydnsjp_add   _acme-challenge.www.domain.com   "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
+dns_mydnsjp_add() {
+  fulldomain=$1
+  txtvalue=$2
+
+  _info "Using mydnsjp"
+  _debug fulldomain "$fulldomain"
+  _debug txtvalue "$txtvalue"
+
+  # Load the credentials from the account conf file
+  MYDNSJP_MasterID="${MYDNSJP_MasterID:-$(_readaccountconf_mutable MYDNSJP_MasterID)}"
+  MYDNSJP_Password="${MYDNSJP_Password:-$(_readaccountconf_mutable MYDNSJP_Password)}"
+  if [ -z "$MYDNSJP_MasterID" ] || [ -z "$MYDNSJP_Password" ]; then
+    MYDNSJP_MasterID=""
+    MYDNSJP_Password=""
+    _err "You don't specify mydnsjp api MasterID and Password yet."
+    _err "Please export as MYDNSJP_MasterID / MYDNSJP_Password and try again."
+    return 1
+  fi
+
+  # Save the credentials to the account conf file
+  _saveaccountconf_mutable MYDNSJP_MasterID "$MYDNSJP_MasterID"
+  _saveaccountconf_mutable MYDNSJP_Password "$MYDNSJP_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"
+
+  if _mydnsjp_api "REGIST" "$_domain" "$txtvalue"; then
+    if printf -- "%s" "$response" | grep "OK." >/dev/null; then
+      _info "Added, OK"
+      return 0
+    else
+      _err "Add txt record error."
+      return 1
+    fi
+  fi
+  _err "Add txt record error."
+
+  return 1
+}
+
+#Usage: fulldomain txtvalue
+#Remove the txt record after validation.
+dns_mydnsjp_rm() {
+  fulldomain=$1
+  txtvalue=$2
+
+  _info "Removing TXT record"
+  _debug fulldomain "$fulldomain"
+  _debug txtvalue "$txtvalue"
+
+  # Load the credentials from the account conf file
+  MYDNSJP_MasterID="${MYDNSJP_MasterID:-$(_readaccountconf_mutable MYDNSJP_MasterID)}"
+  MYDNSJP_Password="${MYDNSJP_Password:-$(_readaccountconf_mutable MYDNSJP_Password)}"
+  if [ -z "$MYDNSJP_MasterID" ] || [ -z "$MYDNSJP_Password" ]; then
+    MYDNSJP_MasterID=""
+    MYDNSJP_Password=""
+    _err "You don't specify mydnsjp api MasterID and Password yet."
+    _err "Please export as MYDNSJP_MasterID / MYDNSJP_Password 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"
+
+  if _mydnsjp_api "DELETE" "$_domain" "$txtvalue"; then
+    if printf -- "%s" "$response" | grep "OK." >/dev/null; then
+      _info "Deleted, OK"
+      return 0
+    else
+      _err "Delete txt record error."
+      return 1
+    fi
+  fi
+  _err "Delete txt record error."
+
+  return 1
+}
+
+####################  Private functions below ##################################
+# _acme-challenge.www.domain.com
+# returns
+#  _sub_domain=_acme-challenge.www
+#  _domain=domain.com
+_get_root() {
+  fulldomain=$1
+  i=2
+  p=1
+
+  # Get the root domain
+  _mydnsjp_retrieve_domain
+  if [ "$?" != "0" ]; then
+    # not valid
+    return 1
+  fi
+
+  while true; do
+    _domain=$(printf "%s" "$fulldomain" | cut -d . -f $i-100)
+
+    if [ -z "$_domain" ]; then
+      # not valid
+      return 1
+    fi
+
+    if [ "$_domain" = "$_root_domain" ]; then
+      _sub_domain=$(printf "%s" "$fulldomain" | cut -d . -f 1-$p)
+      return 0
+    fi
+
+    p=$i
+    i=$(_math "$i" + 1)
+  done
+
+  return 1
+}
+
+# Retrieve the root domain
+# returns 0 success
+_mydnsjp_retrieve_domain() {
+  _debug "Login to MyDNS.JP"
+
+  response="$(_post "masterid=$MYDNSJP_MasterID&masterpwd=$MYDNSJP_Password" "$MYDNSJP_API/?MENU=100")"
+  cookie="$(grep -i '^set-cookie:' "$HTTP_HEADER" | _head_n 1 | cut -d " " -f 2)"
+
+  # If cookies is not empty then logon successful
+  if [ -z "$cookie" ]; then
+    _err "Fail to get a cookie."
+    return 1
+  fi
+
+  _debug "Retrieve DOMAIN INFO page"
+
+  export _H1="Cookie:${cookie}"
+
+  response="$(_get "$MYDNSJP_API/?MENU=300")"
+
+  if [ "$?" != "0" ]; then
+    _err "Fail to retrieve DOMAIN INFO."
+    return 1
+  fi
+
+  _root_domain=$(echo "$response" | grep "DNSINFO\[domainname\]" | sed 's/^.*value="\([^"]*\)".*/\1/')
+
+  # Logout
+  response="$(_get "$MYDNSJP_API/?MENU=090")"
+
+  _debug _root_domain "$_root_domain"
+
+  if [ -z "$_root_domain" ]; then
+    _err "Fail to get the root domain."
+    return 1
+  fi
+
+  return 0
+}
+
+_mydnsjp_api() {
+  cmd=$1
+  domain=$2
+  txtvalue=$3
+
+  # Base64 encode the credentials
+  credentials=$(printf "%s:%s" "$MYDNSJP_MasterID" "$MYDNSJP_Password" | _base64)
+
+  # Construct the HTTP Authorization header
+  export _H1="Content-Type: application/x-www-form-urlencoded"
+  export _H2="Authorization: Basic ${credentials}"
+
+  response="$(_post "CERTBOT_DOMAIN=$domain&CERTBOT_VALIDATION=$txtvalue&EDIT_CMD=$cmd" "$MYDNSJP_API/directedit.html")"
+
+  if [ "$?" != "0" ]; then
+    _err "error $domain"
+    return 1
+  fi
+
+  _debug2 response "$response"
+
+  return 0
+}