瀏覽代碼

Merge pull request #4061 from acmesh-official/dev

Dev
neil 3 年之前
父節點
當前提交
8be3465f94
共有 9 個文件被更改,包括 226 次插入242 次删除
  1. 2 1
      Dockerfile
  2. 37 27
      acme.sh
  3. 16 12
      deploy/mailcow.sh
  4. 7 7
      dnsapi/dns_1984hosting.sh
  5. 146 0
      dnsapi/dns_fornex.sh
  6. 0 177
      dnsapi/dns_gdnsdk.sh
  7. 4 4
      dnsapi/dns_loopia.sh
  8. 3 1
      dnsapi/dns_mydevil.sh
  9. 11 13
      dnsapi/dns_world4you.sh

+ 2 - 1
Dockerfile

@@ -65,7 +65,8 @@ RUN for verb in help \
 RUN printf "%b" '#!'"/usr/bin/env sh\n \
 if [ \"\$1\" = \"daemon\" ];  then \n \
  trap \"echo stop && killall crond && exit 0\" SIGTERM SIGINT \n \
- crond && while true; do sleep 1; done;\n \
+ crond && sleep infinity &\n \
+ wait \n \
 else \n \
  exec -- \"\$@\"\n \
 fi" >/entry.sh && chmod +x /entry.sh

+ 37 - 27
acme.sh

@@ -983,9 +983,9 @@ _base64() {
 #Usage: multiline
 _dbase64() {
   if [ "$1" ]; then
-    ${ACME_OPENSSL_BIN:-openssl} base64 -d -A
-  else
     ${ACME_OPENSSL_BIN:-openssl} base64 -d
+  else
+    ${ACME_OPENSSL_BIN:-openssl} base64 -d -A
   fi
 }
 
@@ -4530,7 +4530,7 @@ issue() {
 
       response="$(echo "$response" | _normalizeJson)"
       _debug2 response "$response"
-      _d="$(echo "$response" | _egrep_o '"value" *: *"[^"]*"' | cut -d : -f 2 | tr -d ' "')"
+      _d="$(echo "$response" | _egrep_o '"value" *: *"[^"]*"' | cut -d : -f 2- | tr -d ' "')"
       if _contains "$response" "\"wildcard\" *: *true"; then
         _d="*.$_d"
       fi
@@ -4680,6 +4680,7 @@ $_authorizations_map"
           _dns_root_d="$(echo "$_dns_root_d" | sed 's/*.//')"
         fi
         _d_alias="$(_getfield "$_challenge_alias" "$_alias_index")"
+        test "$_d_alias" = "$NO_VALUE" && _d_alias=""
         _alias_index="$(_math "$_alias_index" + 1)"
         _debug "_d_alias" "$_d_alias"
         if [ "$_d_alias" ]; then
@@ -4974,7 +4975,7 @@ $_authorizations_map"
         return 1
       fi
       _debug "sleep 2 secs to verify again"
-      sleep 2
+      _sleep 2
       _debug "checking"
 
       _send_signed_request "$uri"
@@ -5151,7 +5152,7 @@ $_authorizations_map"
   Le_CertCreateTime=$(_time)
   _savedomainconf "Le_CertCreateTime" "$Le_CertCreateTime"
 
-  Le_CertCreateTimeStr=$(date -u)
+  Le_CertCreateTimeStr=$(_time2str "$Le_CertCreateTime")
   _savedomainconf "Le_CertCreateTimeStr" "$Le_CertCreateTimeStr"
 
   if [ -z "$Le_RenewalDays" ] || [ "$Le_RenewalDays" -lt "0" ]; then
@@ -5249,7 +5250,8 @@ renew() {
   fi
 
   _isEcc="$2"
-
+  #the server specified from commandline
+  _acme_server_back="$ACME_DIRECTORY"
   _initpath "$Le_Domain" "$_isEcc"
   _set_level=${NOTIFY_LEVEL:-$NOTIFY_LEVEL_DEFAULT}
   _info "$(__green "Renew: '$Le_Domain'")"
@@ -5270,35 +5272,36 @@ renew() {
     Le_API="$CA_LETSENCRYPT_V2"
   fi
 
-  #revert from staging CAs back to production CAs
-  if [ -z "$ACME_DIRECTORY" ]; then
-    case "$Le_API" in
-
-    "$CA_LETSENCRYPT_V2_TEST")
-      _info "Switching back to $CA_LETSENCRYPT_V2"
-      Le_API="$CA_LETSENCRYPT_V2"
-      ;;
-    "$CA_BUYPASS_TEST")
-      _info "Switching back to $CA_BUYPASS"
-      Le_API="$CA_BUYPASS"
-      ;;
-    "$CA_GOOGLE_TEST")
-      _info "Switching back to $CA_GOOGLE"
-      Le_API="$CA_GOOGLE"
-      ;;
-    esac
+  if [ "$_acme_server_back" ]; then
+    export ACME_DIRECTORY="$_acme_server_back"
+  else
+    export ACME_DIRECTORY="$Le_API"
   fi
 
-  if [ "$Le_API" ]; then
+  case "$Le_API" in
+  "$CA_LETSENCRYPT_V2_TEST")
+    _info "Switching back to $CA_LETSENCRYPT_V2"
+    Le_API="$CA_LETSENCRYPT_V2"
+    ;;
+  "$CA_BUYPASS_TEST")
+    _info "Switching back to $CA_BUYPASS"
+    Le_API="$CA_BUYPASS"
+    ;;
+  "$CA_GOOGLE_TEST")
+    _info "Switching back to $CA_GOOGLE"
+    Le_API="$CA_GOOGLE"
+    ;;
+  esac
+
+  if [ "$Le_API" ] && [ "$ACME_DIRECTORY" ]; then
     if [ "$Le_API" != "$ACME_DIRECTORY" ]; then
       _clearAPI
     fi
-    export ACME_DIRECTORY="$Le_API"
     #reload ca configs
     ACCOUNT_KEY_PATH=""
     ACCOUNT_JSON_PATH=""
     CA_CONF=""
-    _debug3 "initpath again."
+    _debug2 "initpath again."
     _initpath "$Le_Domain" "$_isEcc"
   fi
 
@@ -5544,10 +5547,13 @@ showcsr() {
   _initpath
 
   _csrsubj=$(_readSubjectFromCSR "$_csrfile")
-  if [ "$?" != "0" ] || [ -z "$_csrsubj" ]; then
+  if [ "$?" != "0" ]; then
     _err "Can not read subject from csr: $_csrfile"
     return 1
   fi
+  if [ -z "$_csrsubj" ]; then
+    _info "The Subject is empty"
+  fi
 
   _info "Subject=$_csrsubj"
 
@@ -6956,6 +6962,10 @@ _processAccountConf() {
 }
 
 _checkSudo() {
+  if [ -z "__INTERACTIVE" ]; then
+    #don't check if it's not in an interactive shell
+    return 0
+  fi
   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

+ 16 - 12
deploy/mailcow.sh

@@ -20,18 +20,23 @@ mailcow_deploy() {
   _debug _cca "$_cca"
   _debug _cfullchain "$_cfullchain"
 
-  _mailcow_path="${DEPLOY_MAILCOW_PATH}"
+  _getdeployconf DEPLOY_MAILCOW_PATH
+  _getdeployconf DEPLOY_MAILCOW_RELOAD
 
-  if [ -z "$_mailcow_path" ]; then
+  _debug DEPLOY_MAILCOW_PATH "$DEPLOY_MAILCOW_PATH"
+  _debug DEPLOY_MAILCOW_RELOAD "$DEPLOY_MAILCOW_RELOAD"
+
+  if [ -z "$DEPLOY_MAILCOW_PATH" ]; then
     _err "Mailcow path is not found, please define DEPLOY_MAILCOW_PATH."
     return 1
   fi
 
-  #Tests if _ssl_path is the mailcow root directory.
-  if [ -f "${_mailcow_path}/generate_config.sh" ]; then
-    _ssl_path="${_mailcow_path}/data/assets/ssl/"
-  else
-    _ssl_path="${_mailcow_path}"
+  _savedeployconf DEPLOY_MAILCOW_PATH "$DEPLOY_MAILCOW_PATH"
+  [ -n "$DEPLOY_MAILCOW_RELOAD" ] && _savedeployconf DEPLOY_MAILCOW_RELOAD "$DEPLOY_MAILCOW_RELOAD"
+
+  _ssl_path="$DEPLOY_MAILCOW_PATH"
+  if [ -f "$DEPLOY_MAILCOW_PATH/generate_config.sh" ]; then
+    _ssl_path="$DEPLOY_MAILCOW_PATH/data/assets/ssl/"
   fi
 
   if [ ! -d "$_ssl_path" ]; then
@@ -40,16 +45,15 @@ mailcow_deploy() {
   fi
 
   # ECC or RSA
-  if [ -z "${Le_Keylength}" ]; then
-    Le_Keylength=""
-  fi
-  if _isEccKey "${Le_Keylength}"; then
+  length=$(_readdomainconf Le_Keylength)
+  if _isEccKey "$length"; then
     _info "ECC key type detected"
     _cert_name_prefix="ecdsa-"
   else
     _info "RSA key type detected"
     _cert_name_prefix=""
   fi
+
   _info "Copying key and cert"
   _real_key="$_ssl_path/${_cert_name_prefix}key.pem"
   if ! cat "$_ckey" >"$_real_key"; then
@@ -63,7 +67,7 @@ mailcow_deploy() {
     return 1
   fi
 
-  DEFAULT_MAILCOW_RELOAD="docker restart $(docker ps -qaf name=postfix-mailcow); docker restart $(docker ps -qaf name=nginx-mailcow); docker restart $(docker ps -qaf name=dovecot-mailcow)"
+  DEFAULT_MAILCOW_RELOAD="docker restart \$(docker ps --quiet --filter name=nginx-mailcow --filter name=dovecot-mailcow)"
   _reload="${DEPLOY_MAILCOW_RELOAD:-$DEFAULT_MAILCOW_RELOAD}"
 
   _info "Run reload: $_reload"

+ 7 - 7
dnsapi/dns_1984hosting.sh

@@ -42,7 +42,7 @@ dns_1984hosting_add() {
 
   _debug "Add TXT record $fulldomain with value '$txtvalue'"
   value="$(printf '%s' "$txtvalue" | _url_encode)"
-  url="https://management.1984hosting.com/domains/entry/"
+  url="https://1984.hosting/domains/entry/"
 
   postdata="entry=new"
   postdata="$postdata&type=TXT"
@@ -95,7 +95,7 @@ dns_1984hosting_rm() {
   _debug _domain "$_domain"
   _debug "Delete $fulldomain TXT record"
 
-  url="https://management.1984hosting.com/domains"
+  url="https://1984.hosting/domains"
   if ! _get_zone_id "$url" "$_domain"; then
     _err "invalid zone" "$_domain"
     return 1
@@ -138,7 +138,7 @@ _1984hosting_login() {
   _debug "Login to 1984Hosting as user $One984HOSTING_Username"
   username=$(printf '%s' "$One984HOSTING_Username" | _url_encode)
   password=$(printf '%s' "$One984HOSTING_Password" | _url_encode)
-  url="https://management.1984hosting.com/accounts/checkuserauth/"
+  url="https://1984.hosting/accounts/checkuserauth/"
 
   response="$(_post "username=$username&password=$password&otpkey=" $url)"
   response="$(echo "$response" | _normalizeJson)"
@@ -175,7 +175,7 @@ _check_cookies() {
     return 1
   fi
 
-  _authget "https://management.1984hosting.com/accounts/loginstatus/"
+  _authget "https://1984.hosting/accounts/loginstatus/"
   if _contains "$response" '"ok": true'; then
     _debug "Cached cookies still valid"
     return 0
@@ -204,7 +204,7 @@ _get_root() {
       return 1
     fi
 
-    _authget "https://management.1984hosting.com/domains/soacheck/?zone=$h&nameserver=ns0.1984.is."
+    _authget "https://1984.hosting/domains/soacheck/?zone=$h&nameserver=ns0.1984.is."
     if _contains "$_response" "serial" && ! _contains "$_response" "null"; then
       _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
       _domain="$h"
@@ -251,11 +251,11 @@ _htmlget() {
 
 # add extra headers to request
 _authpost() {
-  url="https://management.1984hosting.com/domains"
+  url="https://1984.hosting/domains"
   _get_zone_id "$url" "$_domain"
   csrf_header="$(echo "$One984HOSTING_CSRFTOKEN_COOKIE" | _egrep_o "=[^=][0-9a-zA-Z]*" | tr -d "=")"
   export _H1="Cookie: $One984HOSTING_CSRFTOKEN_COOKIE;$One984HOSTING_SESSIONID_COOKIE"
-  export _H2="Referer: https://management.1984hosting.com/domains/$_zone_id"
+  export _H2="Referer: https://1984.hosting/domains/$_zone_id"
   export _H3="X-CSRFToken: $csrf_header"
   _response=$(_post "$1" "$2")
 }

+ 146 - 0
dnsapi/dns_fornex.sh

@@ -0,0 +1,146 @@
+#!/usr/bin/env sh
+
+#Author: Timur Umarov <[email protected]>
+
+FORNEX_API_URL="https://fornex.com/api/dns/v0.1"
+
+########  Public functions #####################
+
+#Usage: dns_fornex_add   _acme-challenge.www.domain.com   "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
+dns_fornex_add() {
+  fulldomain=$1
+  txtvalue=$2
+
+  if ! _Fornex_API; then
+    return 1
+  fi
+
+  if ! _get_root "$fulldomain"; then
+    _err "Unable to determine root domain"
+    return 1
+  else
+    _debug _domain "$_domain"
+  fi
+
+  _info "Adding record"
+  if _rest POST "$_domain/entry_set/add/" "host=$fulldomain&type=TXT&value=$txtvalue&apikey=$FORNEX_API_KEY"; then
+    _debug _response "$response"
+    if _contains "$response" '"ok": true' || _contains "$response" 'Такая запись уже существует.'; then
+      _info "Added, OK"
+      return 0
+    fi
+  fi
+  _err "Add txt record error."
+  return 1
+}
+
+#Usage: dns_fornex_rm   _acme-challenge.www.domain.com
+dns_fornex_rm() {
+  fulldomain=$1
+  txtvalue=$2
+
+  if ! _Fornex_API; then
+    return 1
+  fi
+
+  if ! _get_root "$fulldomain"; then
+    _err "Unable to determine root domain"
+    return 1
+  else
+    _debug _domain "$_domain"
+  fi
+
+  _debug "Getting txt records"
+  _rest GET "$_domain/entry_set.json?apikey=$FORNEX_API_KEY"
+
+  if ! _contains "$response" "$txtvalue"; then
+    _err "Txt record not found"
+    return 1
+  fi
+
+  _record_id="$(echo "$response" | _egrep_o "{[^{]*\"value\"*:*\"$txtvalue\"[^}]*}" | sed -n -e 's#.*"id": \([0-9]*\).*#\1#p')"
+  _debug "_record_id" "$_record_id"
+  if [ -z "$_record_id" ]; then
+    _err "can not find _record_id"
+    return 1
+  fi
+
+  if ! _rest POST "$_domain/entry_set/$_record_id/delete/" "apikey=$FORNEX_API_KEY"; then
+    _err "Delete record error."
+    return 1
+  fi
+  return 0
+}
+
+####################  Private functions below ##################################
+
+#_acme-challenge.www.domain.com
+#returns
+# _sub_domain=_acme-challenge.www
+# _domain=domain.com
+_get_root() {
+  domain=$1
+
+  i=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 ! _rest GET "domain_list.json?q=$h&apikey=$FORNEX_API_KEY"; 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
+}
+
+_Fornex_API() {
+  FORNEX_API_KEY="${FORNEX_API_KEY:-$(_readaccountconf_mutable FORNEX_API_KEY)}"
+  if [ -z "$FORNEX_API_KEY" ]; then
+    FORNEX_API_KEY=""
+
+    _err "You didn't specify the Fornex API key yet."
+    _err "Please create your key and try again."
+
+    return 1
+  fi
+
+  _saveaccountconf_mutable FORNEX_API_KEY "$FORNEX_API_KEY"
+}
+
+#method method action data
+_rest() {
+  m=$1
+  ep="$2"
+  data="$3"
+  _debug "$ep"
+
+  export _H1="Accept: application/json"
+
+  if [ "$m" != "GET" ]; then
+    _debug data "$data"
+    response="$(_post "$data" "$FORNEX_API_URL/$ep" "" "$m")"
+  else
+    response="$(_get "$FORNEX_API_URL/$ep" | _normalizeJson)"
+  fi
+
+  _ret="$?"
+  if [ "$_ret" != "0" ]; then
+    _err "error $ep"
+    return 1
+  fi
+  _debug2 response "$response"
+  return 0
+}

+ 0 - 177
dnsapi/dns_gdnsdk.sh

@@ -1,177 +0,0 @@
-#!/usr/bin/env sh
-#Author: Herman Sletteng
-#Report Bugs here: https://github.com/loial/acme.sh
-#
-#
-# Note, gratisdns requires a login first, so the script needs to handle
-# temporary cookies. Since acme.sh _get/_post currently don't directly support
-# cookies, I've defined wrapper functions _myget/_mypost to set the headers
-
-GDNSDK_API="https://admin.gratisdns.com"
-########  Public functions #####################
-#Usage: dns_gdnsdk_add   _acme-challenge.www.domain.com   "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
-dns_gdnsdk_add() {
-  fulldomain=$1
-  txtvalue=$2
-  _info "Using gratisdns.dk"
-  _debug fulldomain "$fulldomain"
-  _debug txtvalue "$txtvalue"
-  if ! _gratisdns_login; then
-    _err "Login failed!"
-    return 1
-  fi
-  #finding domain zone
-  if ! _get_domain; then
-    _err "No matching root domain for $fulldomain found"
-    return 1
-  fi
-  # adding entry
-  _info "Adding the entry"
-  _mypost "action=dns_primary_record_added_txt&user_domain=$_domain&name=$fulldomain&txtdata=$txtvalue&ttl=1"
-  if _successful_update; then return 0; fi
-  _err "Couldn't create entry!"
-  return 1
-}
-
-#Usage: fulldomain txtvalue
-#Remove the txt record after validation.
-dns_gdnsdk_rm() {
-  fulldomain=$1
-  txtvalue=$2
-  _info "Using gratisdns.dk"
-  _debug fulldomain "$fulldomain"
-  _debug txtvalue "$txtvalue"
-  if ! _gratisdns_login; then
-    _err "Login failed!"
-    return 1
-  fi
-  if ! _get_domain; then
-    _err "No matching root domain for $fulldomain found"
-    return 1
-  fi
-  _findentry "$fulldomain" "$txtvalue"
-  if [ -z "$_id" ]; then
-    _info "Entry doesn't exist, nothing to delete"
-    return 0
-  fi
-  _debug "Deleting record..."
-  _mypost "action=dns_primary_delete_txt&user_domain=$_domain&id=$_id"
-  # removing entry
-
-  if _successful_update; then return 0; fi
-  _err "Couldn't delete entry!"
-  return 1
-}
-
-####################  Private functions below ##################################
-
-_checkcredentials() {
-  GDNSDK_Username="${GDNSDK_Username:-$(_readaccountconf_mutable GDNSDK_Username)}"
-  GDNSDK_Password="${GDNSDK_Password:-$(_readaccountconf_mutable GDNSDK_Password)}"
-
-  if [ -z "$GDNSDK_Username" ] || [ -z "$GDNSDK_Password" ]; then
-    GDNSDK_Username=""
-    GDNSDK_Password=""
-    _err "You haven't specified gratisdns.dk username and password yet."
-    _err "Please add credentials and try again."
-    return 1
-  fi
-  #save the credentials to the account conf file.
-  _saveaccountconf_mutable GDNSDK_Username "$GDNSDK_Username"
-  _saveaccountconf_mutable GDNSDK_Password "$GDNSDK_Password"
-  return 0
-}
-
-_checkcookie() {
-  GDNSDK_Cookie="${GDNSDK_Cookie:-$(_readaccountconf_mutable GDNSDK_Cookie)}"
-  if [ -z "$GDNSDK_Cookie" ]; then
-    _debug "No cached cookie found"
-    return 1
-  fi
-  _myget "action="
-  if (echo "$_result" | grep -q "logmeout"); then
-    _debug "Cached cookie still valid"
-    return 0
-  fi
-  _debug "Cached cookie no longer valid"
-  GDNSDK_Cookie=""
-  _saveaccountconf_mutable GDNSDK_Cookie "$GDNSDK_Cookie"
-  return 1
-}
-
-_gratisdns_login() {
-  if ! _checkcredentials; then return 1; fi
-
-  if _checkcookie; then
-    _debug "Already logged in"
-    return 0
-  fi
-  _debug "Logging into GratisDNS with user $GDNSDK_Username"
-
-  if ! _mypost "login=$GDNSDK_Username&password=$GDNSDK_Password&action=logmein"; then
-    _err "GratisDNS login failed for user $GDNSDK_Username bad RC from _post"
-    return 1
-  fi
-
-  GDNSDK_Cookie="$(grep -A 15 '302 Found' "$HTTP_HEADER" | _egrep_o 'Cookie: [^;]*' | _head_n 1 | cut -d ' ' -f2)"
-
-  if [ -z "$GDNSDK_Cookie" ]; then
-    _err "GratisDNS login failed for user $GDNSDK_Username. Check $HTTP_HEADER file"
-    return 1
-  fi
-  export GDNSDK_Cookie
-  _saveaccountconf_mutable GDNSDK_Cookie "$GDNSDK_Cookie"
-  return 0
-}
-
-_myget() {
-  #Adds cookie to request
-  export _H1="Cookie: $GDNSDK_Cookie"
-  _result=$(_get "$GDNSDK_API?$1")
-}
-_mypost() {
-  #Adds cookie to request
-  export _H1="Cookie: $GDNSDK_Cookie"
-  _result=$(_post "$1" "$GDNSDK_API")
-}
-
-_get_domain() {
-  _myget 'action=dns_primarydns'
-  _domains=$(echo "$_result" | _egrep_o ' domain="[[:alnum:]._-]+' | sed 's/^.*"//')
-  if [ -z "$_domains" ]; then
-    _err "Primary domain list not found!"
-    return 1
-  fi
-  for _domain in $_domains; do
-    if (_endswith "$fulldomain" "$_domain"); then
-      _debug "Root domain: $_domain"
-      return 0
-    fi
-  done
-  return 1
-}
-
-_successful_update() {
-  if (echo "$_result" | grep -q 'table-success'); then return 0; fi
-  return 1
-}
-
-_findentry() {
-  #args    $1: fulldomain, $2: txtvalue
-  #returns id of dns entry, if it exists
-  _myget "action=dns_primary_changeDNSsetup&user_domain=$_domain"
-  _debug3 "_result: $_result"
-
-  _tmp_result=$(echo "$_result" | tr -d '\n\r' | _egrep_o "<td>$1</td>\s*<td>$2</td>[^?]*[^&]*&id=[^&]*")
-  _debug _tmp_result "$_tmp_result"
-  if [ -z "${_tmp_result:-}" ]; then
-    _debug "The variable is _tmp_result is not supposed to be empty, there may be something wrong with the script"
-  fi
-
-  _id=$(echo "$_tmp_result" | sed 's/^.*=//')
-  if [ -n "$_id" ]; then
-    _debug "Entry found with _id=$_id"
-    return 0
-  fi
-  return 1
-}

+ 4 - 4
dnsapi/dns_loopia.sh

@@ -79,7 +79,7 @@ dns_loopia_rm() {
   response="$(_post "$xml_content" "$LOOPIA_Api" "" "POST")"
 
   if ! _contains "$response" "OK"; then
-    err_response=$(echo "$response" | grep -oPm1 "(?<=<string>)[^<]+")
+    err_response=$(echo "$response" | sed 's/.*<string>\(.*\)<\/string>.*/\1/')
     _err "Error could not get txt records: $err_response"
     return 1
   fi
@@ -148,7 +148,7 @@ _loopia_get_records() {
 
   response="$(_post "$xml_content" "$LOOPIA_Api" "" "POST")"
   if ! _contains "$response" "<array>"; then
-    err_response=$(echo "$response" | grep -oPm1 "(?<=<string>)[^<]+")
+    err_response=$(echo "$response" | sed 's/.*<string>\(.*\)<\/string>.*/\1/')
     _err "Error: $err_response"
     return 1
   fi
@@ -245,7 +245,7 @@ _loopia_add_record() {
   response="$(_post "$xml_content" "$LOOPIA_Api" "" "POST")"
 
   if ! _contains "$response" "OK"; then
-    err_response=$(echo "$response" | grep -oPm1 "(?<=<string>)[^<]+")
+    err_response=$(echo "$response" | sed 's/.*<string>\(.*\)<\/string>.*/\1/')
     _err "Error: $err_response"
     return 1
   fi
@@ -310,7 +310,7 @@ _loopia_add_sub_domain() {
   response="$(_post "$xml_content" "$LOOPIA_Api" "" "POST")"
 
   if ! _contains "$response" "OK"; then
-    err_response=$(echo "$response" | grep -oPm1 "(?<=<string>)[^<]+")
+    err_response=$(echo "$response" | sed 's/.*<string>\(.*\)<\/string>.*/\1/')
     _err "Error: $err_response"
     return 1
   fi

+ 3 - 1
dnsapi/dns_mydevil.sh

@@ -74,7 +74,7 @@ dns_mydevil_rm() {
   validRecords="^${num}${w}${fulldomain}${w}TXT${w}${any}${txtvalue}$"
   for id in $(devil dns list "$domain" | tail -n+2 | grep "${validRecords}" | cut -w -s -f 1); do
     _info "Removing record $id from domain $domain"
-    devil dns del "$domain" "$id" || _err "Could not remove DNS record."
+    echo "y" | devil dns del "$domain" "$id" || _err "Could not remove DNS record."
   done
 }
 
@@ -87,7 +87,9 @@ mydevil_get_domain() {
   domain=""
 
   for domain in $(devil dns list | cut -w -s -f 1 | tail -n+2); do
+    _debug "Checking domain: $domain"
     if _endswith "$fulldomain" "$domain"; then
+      _debug "Fulldomain '$fulldomain' matches '$domain'"
       printf -- "%s" "$domain"
       return 0
     fi

+ 11 - 13
dnsapi/dns_world4you.sh

@@ -54,15 +54,14 @@ dns_world4you_add() {
     if _contains "$res" "successfully"; then
       return 0
     else
-      msg=$(echo "$res" | tr '\n' '\t' | sed 's/.*<h3 class="mb-5">[^\t]*\t *\([^\t]*\)\t.*/\1/')
-      if _contains "$msg" '^<\!DOCTYPE html>'; then
-        msg='Unknown error'
-      fi
-      _err "Unable to add record: $msg"
-      if _contains "$msg" '^<\!DOCTYPE html>'; then
+      msg=$(echo "$res" | grep -A 15 'data-type="danger"' | grep "<h3[^>]*>[^<]" | sed 's/<[^>]*>\|^\s*//g')
+      if [ "$msg" = '' ]; then
+        _err "Unable to add record: Unknown error"
         echo "$ret" >'error-01.html'
         echo "$res" >'error-02.html'
         _err "View error-01.html and error-02.html for debugging"
+      else
+        _err "Unable to add record: my.world4you.com: $msg"
       fi
       return 1
     fi
@@ -119,15 +118,14 @@ dns_world4you_rm() {
     if _contains "$res" "successfully"; then
       return 0
     else
-      msg=$(echo "$res" | tr '\n' '\t' | sed 's/.*<h3 class="mb-5">[^\t]*\t *\([^\t]*\)\t.*/\1/')
-      if _contains "$msg" '^<\!DOCTYPE html>'; then
-        msg='Unknown error'
-      fi
-      _err "Unable to remove record: $msg"
-      if _contains "$msg" '^<\!DOCTYPE html>'; then
+      msg=$(echo "$res" | grep -A 15 'data-type="danger"' | grep "<h3[^>]*>[^<]" | sed 's/<[^>]*>\|^\s*//g')
+      if [ "$msg" = '' ]; then
+        _err "Unable to remove record: Unknown error"
         echo "$ret" >'error-01.html'
         echo "$res" >'error-02.html'
         _err "View error-01.html and error-02.html for debugging"
+      else
+        _err "Unable to remove record: my.world4you.com: $msg"
       fi
       return 1
     fi
@@ -199,6 +197,6 @@ _get_paketnr() {
   TLD="$domain"
   _debug domain "$domain"
   RECORD=$(echo "$fqdn" | cut -c"1-$((${#fqdn} - ${#TLD} - 1))")
-  PAKETNR=$(echo "$form" | grep "data-textfilter=\".* $domain " | _head_n 1 | sed 's/^.* \([0-9]*\) .*$/\1/')
+  PAKETNR=$(echo "$form" | grep "data-textfilter=\".* $domain " | _tail_n 1 | sed "s|.*$WORLD4YOU_API/\\([0-9]*\\)/.*|\\1|")
   return 0
 }