mirror of
				https://github.com/acmesh-official/acme.sh
				synced 2025-11-04 13:55:56 +08:00 
			
		
		
		
	
							
								
								
									
										6
									
								
								.github/workflows/DNS.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								.github/workflows/DNS.yml
									
									
									
									
										vendored
									
									
								
							@@ -188,7 +188,7 @@ jobs:
 | 
			
		||||
    - uses: actions/checkout@v2
 | 
			
		||||
    - name: Clone acmetest
 | 
			
		||||
      run: cd .. && git clone https://github.com/acmesh-official/acmetest.git  && cp -r acme.sh acmetest/
 | 
			
		||||
    - uses: vmactions/freebsd-vm@v0.1.4
 | 
			
		||||
    - uses: vmactions/freebsd-vm@v0.1.8
 | 
			
		||||
      with:
 | 
			
		||||
        envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}'
 | 
			
		||||
        prepare: pkg install -y socat curl
 | 
			
		||||
@@ -270,7 +270,7 @@ jobs:
 | 
			
		||||
    - uses: actions/checkout@v2
 | 
			
		||||
    - name: Clone acmetest
 | 
			
		||||
      run: cd .. && git clone https://github.com/acmesh-official/acmetest.git  && cp -r acme.sh acmetest/
 | 
			
		||||
    - uses: vmactions/openbsd-vm@v0.0.1
 | 
			
		||||
    - uses: vmactions/openbsd-vm@v0.0.4
 | 
			
		||||
      with:
 | 
			
		||||
        envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}'
 | 
			
		||||
        prepare: pkg_add socat curl
 | 
			
		||||
@@ -310,7 +310,7 @@ jobs:
 | 
			
		||||
    - uses: actions/checkout@v2
 | 
			
		||||
    - name: Clone acmetest
 | 
			
		||||
      run: cd .. && git clone https://github.com/acmesh-official/acmetest.git  && cp -r acme.sh acmetest/
 | 
			
		||||
    - uses: vmactions/netbsd-vm@v0.0.1
 | 
			
		||||
    - uses: vmactions/netbsd-vm@v0.0.2
 | 
			
		||||
      with:
 | 
			
		||||
        envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}'
 | 
			
		||||
        prepare: |
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								.github/workflows/FreeBSD.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/FreeBSD.yml
									
									
									
									
										vendored
									
									
								
							@@ -49,7 +49,7 @@ jobs:
 | 
			
		||||
      run: echo "TestingDomain=${{steps.tunnel.outputs.server}}" >> $GITHUB_ENV
 | 
			
		||||
    - name: Clone acmetest
 | 
			
		||||
      run: cd .. && git clone https://github.com/acmesh-official/acmetest.git  && cp -r acme.sh acmetest/
 | 
			
		||||
    - uses: vmactions/freebsd-vm@v0.1.5
 | 
			
		||||
    - uses: vmactions/freebsd-vm@v0.1.8
 | 
			
		||||
      with:
 | 
			
		||||
        envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN'
 | 
			
		||||
        nat: |
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								.github/workflows/NetBSD.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/NetBSD.yml
									
									
									
									
										vendored
									
									
								
							@@ -49,7 +49,7 @@ jobs:
 | 
			
		||||
      run: echo "TestingDomain=${{steps.tunnel.outputs.server}}" >> $GITHUB_ENV
 | 
			
		||||
    - name: Clone acmetest
 | 
			
		||||
      run: cd .. && git clone https://github.com/acmesh-official/acmetest.git  && cp -r acme.sh acmetest/
 | 
			
		||||
    - uses: vmactions/netbsd-vm@v0.0.1
 | 
			
		||||
    - uses: vmactions/netbsd-vm@v0.0.2
 | 
			
		||||
      with:
 | 
			
		||||
        envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN'
 | 
			
		||||
        nat: |
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								.github/workflows/OpenBSD.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/OpenBSD.yml
									
									
									
									
										vendored
									
									
								
							@@ -49,7 +49,7 @@ jobs:
 | 
			
		||||
      run: echo "TestingDomain=${{steps.tunnel.outputs.server}}" >> $GITHUB_ENV
 | 
			
		||||
    - name: Clone acmetest
 | 
			
		||||
      run: cd .. && git clone https://github.com/acmesh-official/acmetest.git  && cp -r acme.sh acmetest/
 | 
			
		||||
    - uses: vmactions/openbsd-vm@v0.0.1
 | 
			
		||||
    - uses: vmactions/openbsd-vm@v0.0.4
 | 
			
		||||
      with:
 | 
			
		||||
        envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN'
 | 
			
		||||
        nat: |
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								acme.sh
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								acme.sh
									
									
									
									
									
								
							@@ -1196,7 +1196,7 @@ _createkey() {
 | 
			
		||||
_is_idn() {
 | 
			
		||||
  _is_idn_d="$1"
 | 
			
		||||
  _debug2 _is_idn_d "$_is_idn_d"
 | 
			
		||||
  _idn_temp=$(printf "%s" "$_is_idn_d" | tr -d '0-9' | tr -d 'a-z' | tr -d 'A-Z' | tr -d '*.,-_')
 | 
			
		||||
  _idn_temp=$(printf "%s" "$_is_idn_d" | tr -d [0-9] | tr -d [a-z] | tr -d [A-Z] | tr -d '*.,-_')
 | 
			
		||||
  _debug2 _idn_temp "$_idn_temp"
 | 
			
		||||
  [ "$_idn_temp" ]
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -44,30 +44,20 @@ mailcow_deploy() {
 | 
			
		||||
    return 1
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  # ECC or RSA
 | 
			
		||||
  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"
 | 
			
		||||
  _real_key="$_ssl_path/key.pem"
 | 
			
		||||
  if ! cat "$_ckey" >"$_real_key"; then
 | 
			
		||||
    _err "Error: write key file to: $_real_key"
 | 
			
		||||
    return 1
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  _real_fullchain="$_ssl_path/${_cert_name_prefix}cert.pem"
 | 
			
		||||
  _real_fullchain="$_ssl_path/cert.pem"
 | 
			
		||||
  if ! cat "$_cfullchain" >"$_real_fullchain"; then
 | 
			
		||||
    _err "Error: write cert file to: $_real_fullchain"
 | 
			
		||||
    return 1
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  DEFAULT_MAILCOW_RELOAD="docker restart \$(docker ps --quiet --filter name=nginx-mailcow --filter name=dovecot-mailcow)"
 | 
			
		||||
  DEFAULT_MAILCOW_RELOAD="docker restart \$(docker ps --quiet --filter name=nginx-mailcow --filter name=dovecot-mailcow --filter name=postfix-mailcow)"
 | 
			
		||||
  _reload="${DEPLOY_MAILCOW_RELOAD:-$DEFAULT_MAILCOW_RELOAD}"
 | 
			
		||||
 | 
			
		||||
  _info "Run reload: $_reload"
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										132
									
								
								deploy/proxmoxve.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										132
									
								
								deploy/proxmoxve.sh
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,132 @@
 | 
			
		||||
#!/usr/bin/env sh
 | 
			
		||||
 | 
			
		||||
# Deploy certificates to a proxmox virtual environment node using the API.
 | 
			
		||||
#
 | 
			
		||||
# Environment variables that can be set are:
 | 
			
		||||
# `DEPLOY_PROXMOXVE_SERVER`: The hostname of the proxmox ve node. Defaults to
 | 
			
		||||
#                            _cdomain.
 | 
			
		||||
# `DEPLOY_PROXMOXVE_SERVER_PORT`: The port number the management interface is on.
 | 
			
		||||
#                                 Defaults to 8006.
 | 
			
		||||
# `DEPLOY_PROXMOXVE_NODE_NAME`: The name of the node we'll be connecting to.
 | 
			
		||||
#                               Defaults to the host portion of the server
 | 
			
		||||
#                               domain name.
 | 
			
		||||
# `DEPLOY_PROXMOXVE_USER`: The user we'll connect as. Defaults to root.
 | 
			
		||||
# `DEPLOY_PROXMOXVE_USER_REALM`: The authentication realm the user authenticates
 | 
			
		||||
#                                with. Defaults to pam.
 | 
			
		||||
# `DEPLOY_PROXMOXVE_API_TOKEN_NAME`: The name of the API token created for the
 | 
			
		||||
#                                    user account. Defaults to acme.
 | 
			
		||||
# `DEPLOY_PROXMOXVE_API_TOKEN_KEY`: The API token. Required.
 | 
			
		||||
 | 
			
		||||
proxmoxve_deploy() {
 | 
			
		||||
  _cdomain="$1"
 | 
			
		||||
  _ckey="$2"
 | 
			
		||||
  _ccert="$3"
 | 
			
		||||
  _cca="$4"
 | 
			
		||||
  _cfullchain="$5"
 | 
			
		||||
 | 
			
		||||
  _debug _cdomain "$_cdomain"
 | 
			
		||||
  _debug2 _ckey "$_ckey"
 | 
			
		||||
  _debug _ccert "$_ccert"
 | 
			
		||||
  _debug _cca "$_cca"
 | 
			
		||||
  _debug _cfullchain "$_cfullchain"
 | 
			
		||||
 | 
			
		||||
  # "Sane" defaults.
 | 
			
		||||
  _getdeployconf DEPLOY_PROXMOXVE_SERVER
 | 
			
		||||
  if [ -z "$DEPLOY_PROXMOXVE_SERVER" ]; then
 | 
			
		||||
    _target_hostname="$_cdomain"
 | 
			
		||||
  else
 | 
			
		||||
    _target_hostname="$DEPLOY_PROXMOXVE_SERVER"
 | 
			
		||||
    _savedeployconf DEPLOY_PROXMOXVE_SERVER "$DEPLOY_PROXMOXVE_SERVER"
 | 
			
		||||
  fi
 | 
			
		||||
  _debug2 DEPLOY_PROXMOXVE_SERVER "$_target_hostname"
 | 
			
		||||
 | 
			
		||||
  _getdeployconf DEPLOY_PROXMOXVE_SERVER_PORT
 | 
			
		||||
  if [ -z "$DEPLOY_PROXMOXVE_SERVER_PORT" ]; then
 | 
			
		||||
    _target_port="8006"
 | 
			
		||||
  else
 | 
			
		||||
    _target_port="$DEPLOY_PROXMOXVE_SERVER_PORT"
 | 
			
		||||
    _savedeployconf DEPLOY_PROXMOXVE_SERVER_PORT "$DEPLOY_PROXMOXVE_SERVER_PORT"
 | 
			
		||||
  fi
 | 
			
		||||
  _debug2 DEPLOY_PROXMOXVE_SERVER_PORT "$_target_port"
 | 
			
		||||
 | 
			
		||||
  _getdeployconf DEPLOY_PROXMOXVE_NODE_NAME
 | 
			
		||||
  if [ -z "$DEPLOY_PROXMOXVE_NODE_NAME" ]; then
 | 
			
		||||
    _node_name=$(echo "$_target_hostname" | cut -d. -f1)
 | 
			
		||||
  else
 | 
			
		||||
    _node_name="$DEPLOY_PROXMOXVE_NODE_NAME"
 | 
			
		||||
    _savedeployconf DEPLOY_PROXMOXVE_NODE_NAME "$DEPLOY_PROXMOXVE_NODE_NAME"
 | 
			
		||||
  fi
 | 
			
		||||
  _debug2 DEPLOY_PROXMOXVE_NODE_NAME "$_node_name"
 | 
			
		||||
 | 
			
		||||
  # Complete URL.
 | 
			
		||||
  _target_url="https://${_target_hostname}:${_target_port}/api2/json/nodes/${_node_name}/certificates/custom"
 | 
			
		||||
  _debug TARGET_URL "$_target_url"
 | 
			
		||||
 | 
			
		||||
  # More "sane" defaults.
 | 
			
		||||
  _getdeployconf DEPLOY_PROXMOXVE_USER
 | 
			
		||||
  if [ -z "$DEPLOY_PROXMOXVE_USER" ]; then
 | 
			
		||||
    _proxmoxve_user="root"
 | 
			
		||||
  else
 | 
			
		||||
    _proxmoxve_user="$DEPLOY_PROXMOXVE_USER"
 | 
			
		||||
    _savedeployconf DEPLOY_PROXMOXVE_USER "$DEPLOY_PROXMOXVE_USER"
 | 
			
		||||
  fi
 | 
			
		||||
  _debug2 DEPLOY_PROXMOXVE_USER "$_proxmoxve_user"
 | 
			
		||||
 | 
			
		||||
  _getdeployconf DEPLOY_PROXMOXVE_USER_REALM
 | 
			
		||||
  if [ -z "$DEPLOY_PROXMOXVE_USER_REALM" ]; then
 | 
			
		||||
    _proxmoxve_user_realm="pam"
 | 
			
		||||
  else
 | 
			
		||||
    _proxmoxve_user_realm="$DEPLOY_PROXMOXVE_USER_REALM"
 | 
			
		||||
    _savedeployconf DEPLOY_PROXMOXVE_USER_REALM "$DEPLOY_PROXMOXVE_USER_REALM"
 | 
			
		||||
  fi
 | 
			
		||||
  _debug2 DEPLOY_PROXMOXVE_USER_REALM "$_proxmoxve_user_realm"
 | 
			
		||||
 | 
			
		||||
  _getdeployconf DEPLOY_PROXMOXVE_API_TOKEN_NAME
 | 
			
		||||
  if [ -z "$DEPLOY_PROXMOXVE_API_TOKEN_NAME" ]; then
 | 
			
		||||
    _proxmoxve_api_token_name="acme"
 | 
			
		||||
  else
 | 
			
		||||
    _proxmoxve_api_token_name="$DEPLOY_PROXMOXVE_API_TOKEN_NAME"
 | 
			
		||||
    _savedeployconf DEPLOY_PROXMOXVE_API_TOKEN_NAME "$DEPLOY_PROXMOXVE_API_TOKEN_NAME"
 | 
			
		||||
  fi
 | 
			
		||||
  _debug2 DEPLOY_PROXMOXVE_API_TOKEN_NAME "$_proxmoxve_api_token_name"
 | 
			
		||||
 | 
			
		||||
  # This is required.
 | 
			
		||||
  _getdeployconf DEPLOY_PROXMOXVE_API_TOKEN_KEY
 | 
			
		||||
  if [ -z "$DEPLOY_PROXMOXVE_API_TOKEN_KEY" ]; then
 | 
			
		||||
    _err "API key not provided."
 | 
			
		||||
    return 1
 | 
			
		||||
  else
 | 
			
		||||
    _proxmoxve_api_token_key="$DEPLOY_PROXMOXVE_API_TOKEN_KEY"
 | 
			
		||||
    _savedeployconf DEPLOY_PROXMOXVE_API_TOKEN_KEY "$DEPLOY_PROXMOXVE_API_TOKEN_KEY"
 | 
			
		||||
  fi
 | 
			
		||||
  _debug2 DEPLOY_PROXMOXVE_API_TOKEN_KEY _proxmoxve_api_token_key
 | 
			
		||||
 | 
			
		||||
  # PVE API Token header value. Used in "Authorization: PVEAPIToken".
 | 
			
		||||
  _proxmoxve_header_api_token="${_proxmoxve_user}@${_proxmoxve_user_realm}!${_proxmoxve_api_token_name}=${_proxmoxve_api_token_key}"
 | 
			
		||||
  _debug2 "Auth Header" _proxmoxve_header_api_token
 | 
			
		||||
 | 
			
		||||
  # Ugly. I hate putting heredocs inside functions because heredocs don't
 | 
			
		||||
  # account for whitespace correctly but it _does_ work and is several times
 | 
			
		||||
  # cleaner than anything else I had here.
 | 
			
		||||
  #
 | 
			
		||||
  # This dumps the json payload to a variable that should be passable to the
 | 
			
		||||
  # _psot function.
 | 
			
		||||
  _json_payload=$(
 | 
			
		||||
    cat <<HEREDOC
 | 
			
		||||
{
 | 
			
		||||
  "certificates": "$(tr '\n' ':' <"$_cfullchain" | sed 's/:/\\n/g')",
 | 
			
		||||
  "key": "$(tr '\n' ':' <"$_ckey" | sed 's/:/\\n/g')",
 | 
			
		||||
  "node":"$_node_name",
 | 
			
		||||
  "restart":"1",
 | 
			
		||||
  "force":"1"
 | 
			
		||||
}
 | 
			
		||||
HEREDOC
 | 
			
		||||
  )
 | 
			
		||||
  _debug2 Payload "$_json_payload"
 | 
			
		||||
 | 
			
		||||
  # Push certificates to server.
 | 
			
		||||
  export _HTTPS_INSECURE=1
 | 
			
		||||
  export _H1="Authorization: PVEAPIToken=${_proxmoxve_header_api_token}"
 | 
			
		||||
  _post "$_json_payload" "$_target_url" "" POST "application/json"
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										234
									
								
								dnsapi/dns_dnsservices.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										234
									
								
								dnsapi/dns_dnsservices.sh
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,234 @@
 | 
			
		||||
#!/usr/bin/env sh
 | 
			
		||||
 | 
			
		||||
#This file name is "dns_dnsservices.sh"
 | 
			
		||||
#Script for Danish DNS registra and DNS hosting provider https://dns.services
 | 
			
		||||
 | 
			
		||||
#Author: Bjarke Bruun <bbruun@gmail.com>
 | 
			
		||||
#Report Bugs here: https://github.com/acmesh-official/acme.sh/issues/4152
 | 
			
		||||
 | 
			
		||||
# Global variable to connect to the DNS.Services API
 | 
			
		||||
DNSServices_API=https://dns.services/api
 | 
			
		||||
 | 
			
		||||
########  Public functions #####################
 | 
			
		||||
 | 
			
		||||
#Usage: dns_dnsservices_add  _acme-challenge.www.domain.com   "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
 | 
			
		||||
dns_dnsservices_add() {
 | 
			
		||||
  fulldomain=$1
 | 
			
		||||
  txtvalue=$2
 | 
			
		||||
 | 
			
		||||
  _info "Using dns.services to create ACME DNS challenge"
 | 
			
		||||
  _debug2 add_fulldomain "$fulldomain"
 | 
			
		||||
  _debug2 add_txtvalue "$txtvalue"
 | 
			
		||||
 | 
			
		||||
  # Read username/password from environment or .acme.sh/accounts.conf
 | 
			
		||||
  DnsServices_Username="${DnsServices_Username:-$(_readaccountconf_mutable DnsServices_Username)}"
 | 
			
		||||
  DnsServices_Password="${DnsServices_Password:-$(_readaccountconf_mutable DnsServices_Password)}"
 | 
			
		||||
  if [ -z "$DnsServices_Username" ] || [ -z "$DnsServices_Password" ]; then
 | 
			
		||||
    DnsServices_Username=""
 | 
			
		||||
    DnsServices_Password=""
 | 
			
		||||
    _err "You didn't specify dns.services api username and password yet."
 | 
			
		||||
    _err "Set environment variables DnsServices_Username and DnsServices_Password"
 | 
			
		||||
    return 1
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  # Setup GET/POST/DELETE headers
 | 
			
		||||
  _setup_headers
 | 
			
		||||
 | 
			
		||||
  #save the credentials to the account conf file.
 | 
			
		||||
  _saveaccountconf_mutable DnsServices_Username "$DnsServices_Username"
 | 
			
		||||
  _saveaccountconf_mutable DnsServices_Password "$DnsServices_Password"
 | 
			
		||||
 | 
			
		||||
  if ! _contains "$DnsServices_Username" "@"; then
 | 
			
		||||
    _err "It seems that the username variable DnsServices_Username has not been set/left blank"
 | 
			
		||||
    _err "or is not a valid email. Please correct and try again."
 | 
			
		||||
    return 1
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  if ! _get_root "${fulldomain}"; then
 | 
			
		||||
    _err "Invalid domain ${fulldomain}"
 | 
			
		||||
    return 1
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  if ! createRecord "$fulldomain" "${txtvalue}"; then
 | 
			
		||||
    _err "Error creating TXT record in domain $fulldomain in $rootZoneName"
 | 
			
		||||
    return 1
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  _debug2 challenge-created "Created $fulldomain"
 | 
			
		||||
  return 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#Usage: fulldomain txtvalue
 | 
			
		||||
#Description: Remove the txt record after validation.
 | 
			
		||||
dns_dnsservices_rm() {
 | 
			
		||||
  fulldomain=$1
 | 
			
		||||
  txtvalue=$2
 | 
			
		||||
 | 
			
		||||
  _info "Using dns.services to remove DNS record $fulldomain TXT $txtvalue"
 | 
			
		||||
  _debug rm_fulldomain "$fulldomain"
 | 
			
		||||
  _debug rm_txtvalue "$txtvalue"
 | 
			
		||||
 | 
			
		||||
  # Read username/password from environment or .acme.sh/accounts.conf
 | 
			
		||||
  DnsServices_Username="${DnsServices_Username:-$(_readaccountconf_mutable DnsServices_Username)}"
 | 
			
		||||
  DnsServices_Password="${DnsServices_Password:-$(_readaccountconf_mutable DnsServices_Password)}"
 | 
			
		||||
  if [ -z "$DnsServices_Username" ] || [ -z "$DnsServices_Password" ]; then
 | 
			
		||||
    DnsServices_Username=""
 | 
			
		||||
    DnsServices_Password=""
 | 
			
		||||
    _err "You didn't specify dns.services api username and password yet."
 | 
			
		||||
    _err "Set environment variables DnsServices_Username and DnsServices_Password"
 | 
			
		||||
    return 1
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  # Setup GET/POST/DELETE headers
 | 
			
		||||
  _setup_headers
 | 
			
		||||
 | 
			
		||||
  if ! _get_root "${fulldomain}"; then
 | 
			
		||||
    _err "Invalid domain ${fulldomain}"
 | 
			
		||||
    return 1
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  _debug2 rm_rootDomainInfo "found root domain $rootZoneName for $fulldomain"
 | 
			
		||||
 | 
			
		||||
  if ! deleteRecord "${fulldomain}" "${txtvalue}"; then
 | 
			
		||||
    _err "Error removing record: $fulldomain TXT ${txtvalue}"
 | 
			
		||||
    return 1
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  return 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
####################  Private functions below ##################################
 | 
			
		||||
 | 
			
		||||
_setup_headers() {
 | 
			
		||||
  # Set up API Headers for _get() and _post()
 | 
			
		||||
  # The <function>_add or <function>_rm must have been called before to work
 | 
			
		||||
 | 
			
		||||
  if [ -z "$DnsServices_Username" ] || [ -z "$DnsServices_Password" ]; then
 | 
			
		||||
    _err "Could not setup BASIC authentication headers, they are missing"
 | 
			
		||||
    return 1
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  DnsServiceCredentials="$(printf "%s" "$DnsServices_Username:$DnsServices_Password" | _base64)"
 | 
			
		||||
  export _H1="Authorization: Basic $DnsServiceCredentials"
 | 
			
		||||
  export _H2="Content-Type: application/json"
 | 
			
		||||
 | 
			
		||||
  # Just return if headers are set
 | 
			
		||||
  return 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
_get_root() {
 | 
			
		||||
  domain=$1
 | 
			
		||||
  _debug2 _get_root "Get the root domain of ${domain} for DNS API"
 | 
			
		||||
 | 
			
		||||
  # Setup _get() and _post() headers
 | 
			
		||||
  #_setup_headers
 | 
			
		||||
 | 
			
		||||
  result=$(_H1="$_H1" _H2="$_H2" _get "$DNSServices_API/dns")
 | 
			
		||||
  _debug2 _get_root "Got the following root domain(s) $result"
 | 
			
		||||
  _debug2 _get_root "- JSON: $result"
 | 
			
		||||
 | 
			
		||||
  if [ "$(echo "$result" | grep -c '"name"')" -gt "1" ]; then
 | 
			
		||||
    checkMultiZones="true"
 | 
			
		||||
    _debug2 _get_root "- multiple zones found"
 | 
			
		||||
  else
 | 
			
		||||
    checkMultiZones="false"
 | 
			
		||||
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  # Find/isolate the root zone to work with in createRecord() and deleteRecord()
 | 
			
		||||
  rootZone=""
 | 
			
		||||
  if [ "$checkMultiZones" = "true" ]; then
 | 
			
		||||
    rootZone=$(for zone in $(echo "$result" | tr -d '\n' ' '); do
 | 
			
		||||
      if [ "$(echo "$domain" | grep "$zone")" != "" ]; then
 | 
			
		||||
        _debug2 _get_root "- trying to figure out if $zone is in $domain"
 | 
			
		||||
        echo "$zone"
 | 
			
		||||
        break
 | 
			
		||||
      fi
 | 
			
		||||
    done)
 | 
			
		||||
  else
 | 
			
		||||
    rootZone=$(echo "$result" | _egrep_o '"name":"[^"]*' | cut -d'"' -f4)
 | 
			
		||||
    _debug2 _get_root "- only found 1 domain in API: $rootZone"
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  if [ -z "$rootZone" ]; then
 | 
			
		||||
    _err "Could not find root domain for $domain - is it correctly typed?"
 | 
			
		||||
    return 1
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  # Setup variables used by other functions to communicate with DNS.Services API
 | 
			
		||||
  #zoneInfo=$(echo "$result" | sed "s,\"zones,\n&,g" | grep zones | cut -d'[' -f2 | cut -d']' -f1 | tr '}' '\n' | grep "\"$rootZone\"")
 | 
			
		||||
  zoneInfo=$(echo "$result" | sed -E 's,.*(zones)(.*),\1\2,g' | sed -E 's,^(.*"name":")([^"]*)"(.*)$,\2,g' | grep "\"$rootZone\"")
 | 
			
		||||
  rootZoneName="$rootZone"
 | 
			
		||||
  subDomainName="$(echo "$domain" | sed "s,\.$rootZone,,g")"
 | 
			
		||||
  subDomainNameClean="$(echo "$domain" | sed "s,_acme-challenge.,,g")"
 | 
			
		||||
  rootZoneDomainID=$(echo "$result" | sed -E 's,.*(zones)(.*),\1\2,g' | sed -E 's,^(.*"domain_id":")([^"]*)"(.*)$,\2,g')
 | 
			
		||||
  rootZoneServiceID=$(echo "$result" | sed -E 's,.*(zones)(.*),\1\2,g' | sed -E 's,^(.*"service_id":")([^"]*)"(.*)$,\2,g')
 | 
			
		||||
 | 
			
		||||
  _debug2 _zoneInfo "Zone info from API  : $zoneInfo"
 | 
			
		||||
  _debug2 _get_root "Root zone name      : $rootZoneName"
 | 
			
		||||
  _debug2 _get_root "Root zone domain ID : $rootZoneDomainID"
 | 
			
		||||
  _debug2 _get_root "Root zone service ID: $rootZoneServiceID"
 | 
			
		||||
  _debug2 _get_root "Sub domain          : $subDomainName"
 | 
			
		||||
 | 
			
		||||
  _debug _get_root "Found valid root domain $rootZone for $subDomainNameClean"
 | 
			
		||||
  return 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
createRecord() {
 | 
			
		||||
  fulldomain=$1
 | 
			
		||||
  txtvalue="$2"
 | 
			
		||||
 | 
			
		||||
  # Get root domain information - needed for DNS.Services API communication
 | 
			
		||||
  if [ -z "$rootZoneName" ] || [ -z "$rootZoneDomainID" ] || [ -z "$rootZoneServiceID" ]; then
 | 
			
		||||
    _get_root "$fulldomain"
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  _debug2 createRecord "CNAME TXT value is: $txtvalue"
 | 
			
		||||
 | 
			
		||||
  # Prepare data to send to API
 | 
			
		||||
  data="{\"name\":\"${fulldomain}\",\"type\":\"TXT\",\"content\":\"${txtvalue}\", \"ttl\":\"10\"}"
 | 
			
		||||
 | 
			
		||||
  _debug2 createRecord "data to API: $data"
 | 
			
		||||
  result=$(_post "$data" "$DNSServices_API/service/$rootZoneServiceID/dns/$rootZoneDomainID/records" "" "POST")
 | 
			
		||||
  _debug2 createRecord "result from API: $result"
 | 
			
		||||
 | 
			
		||||
  if [ "$(echo "$result" | _egrep_o "\"success\":true")" = "" ]; then
 | 
			
		||||
    _err "Failed to create TXT record $fulldomain with content $txtvalue in zone $rootZoneName"
 | 
			
		||||
    _err "$result"
 | 
			
		||||
    return 1
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  _info "Record \"$fulldomain TXT $txtvalue\" has been created"
 | 
			
		||||
  return 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
deleteRecord() {
 | 
			
		||||
  fulldomain=$1
 | 
			
		||||
  txtvalue=$2
 | 
			
		||||
 | 
			
		||||
  _log deleteRecord "Deleting $fulldomain TXT $txtvalue record"
 | 
			
		||||
 | 
			
		||||
  if [ -z "$rootZoneName" ] || [ -z "$rootZoneDomainID" ] || [ -z "$rootZoneServiceID" ]; then
 | 
			
		||||
    _get_root "$fulldomain"
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  result="$(_H1="$_H1" _H2="$_H2" _get "$DNSServices_API/service/$rootZoneServiceID/dns/$rootZoneDomainID")"
 | 
			
		||||
  recordInfo="$(echo "$result" | sed -e 's/:{/:{\n/g' -e 's/},/\n},\n/g' | grep "${txtvalue}")"
 | 
			
		||||
  recordID="$(echo "$recordInfo" | sed -e 's/:{/:{\n/g' -e 's/},/\n},\n/g' | grep "${txtvalue}" | sed -E 's,.*(zones)(.*),\1\2,g' | sed -E 's,^(.*"id":")([^"]*)"(.*)$,\2,g')"
 | 
			
		||||
 | 
			
		||||
  if [ -z "$recordID" ]; then
 | 
			
		||||
    _info "Record $fulldomain TXT $txtvalue not found or already deleted"
 | 
			
		||||
    return 0
 | 
			
		||||
  else
 | 
			
		||||
    _debug2 deleteRecord "Found recordID=$recordID"
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  _debug2 deleteRecord "DELETE request $DNSServices_API/service/$rootZoneServiceID/dns/$rootZoneDomainID/records/$recordID"
 | 
			
		||||
  _log "curl DELETE request $DNSServices_API/service/$rootZoneServiceID/dns/$rootZoneDomainID/records/$recordID"
 | 
			
		||||
  result="$(_H1="$_H1" _H2="$_H2" _post "" "$DNSServices_API/service/$rootZoneServiceID/dns/$rootZoneDomainID/records/$recordID" "" "DELETE")"
 | 
			
		||||
  _debug2 deleteRecord "API Delete result \"$result\""
 | 
			
		||||
  _log "curl API Delete result \"$result\""
 | 
			
		||||
 | 
			
		||||
  # Return OK regardless
 | 
			
		||||
  return 0
 | 
			
		||||
}
 | 
			
		||||
@@ -2,7 +2,7 @@
 | 
			
		||||
 | 
			
		||||
# HUAWEICLOUD_Username
 | 
			
		||||
# HUAWEICLOUD_Password
 | 
			
		||||
# HUAWEICLOUD_ProjectID
 | 
			
		||||
# HUAWEICLOUD_DomainName
 | 
			
		||||
 | 
			
		||||
iam_api="https://iam.myhuaweicloud.com"
 | 
			
		||||
dns_api="https://dns.ap-southeast-1.myhuaweicloud.com" # Should work
 | 
			
		||||
@@ -14,6 +14,8 @@ dns_api="https://dns.ap-southeast-1.myhuaweicloud.com" # Should work
 | 
			
		||||
#
 | 
			
		||||
# Ref: https://support.huaweicloud.com/intl/zh-cn/api-dns/zh-cn_topic_0132421999.html
 | 
			
		||||
#
 | 
			
		||||
# About "DomainName" parameters see: https://support.huaweicloud.com/api-iam/iam_01_0006.html
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
dns_huaweicloud_add() {
 | 
			
		||||
  fulldomain=$1
 | 
			
		||||
@@ -21,16 +23,16 @@ dns_huaweicloud_add() {
 | 
			
		||||
 | 
			
		||||
  HUAWEICLOUD_Username="${HUAWEICLOUD_Username:-$(_readaccountconf_mutable HUAWEICLOUD_Username)}"
 | 
			
		||||
  HUAWEICLOUD_Password="${HUAWEICLOUD_Password:-$(_readaccountconf_mutable HUAWEICLOUD_Password)}"
 | 
			
		||||
  HUAWEICLOUD_ProjectID="${HUAWEICLOUD_ProjectID:-$(_readaccountconf_mutable HUAWEICLOUD_ProjectID)}"
 | 
			
		||||
  HUAWEICLOUD_DomainName="${HUAWEICLOUD_DomainName:-$(_readaccountconf_mutable HUAWEICLOUD_Username)}"
 | 
			
		||||
 | 
			
		||||
  # Check information
 | 
			
		||||
  if [ -z "${HUAWEICLOUD_Username}" ] || [ -z "${HUAWEICLOUD_Password}" ] || [ -z "${HUAWEICLOUD_ProjectID}" ]; then
 | 
			
		||||
  if [ -z "${HUAWEICLOUD_Username}" ] || [ -z "${HUAWEICLOUD_Password}" ] || [ -z "${HUAWEICLOUD_DomainName}" ]; then
 | 
			
		||||
    _err "Not enough information provided to dns_huaweicloud!"
 | 
			
		||||
    return 1
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  unset token # Clear token
 | 
			
		||||
  token="$(_get_token "${HUAWEICLOUD_Username}" "${HUAWEICLOUD_Password}" "${HUAWEICLOUD_ProjectID}")"
 | 
			
		||||
  token="$(_get_token "${HUAWEICLOUD_Username}" "${HUAWEICLOUD_Password}" "${HUAWEICLOUD_DomainName}")"
 | 
			
		||||
  if [ -z "${token}" ]; then # Check token
 | 
			
		||||
    _err "dns_api(dns_huaweicloud): Error getting token."
 | 
			
		||||
    return 1
 | 
			
		||||
@@ -56,7 +58,7 @@ dns_huaweicloud_add() {
 | 
			
		||||
  # Do saving work if all succeeded
 | 
			
		||||
  _saveaccountconf_mutable HUAWEICLOUD_Username "${HUAWEICLOUD_Username}"
 | 
			
		||||
  _saveaccountconf_mutable HUAWEICLOUD_Password "${HUAWEICLOUD_Password}"
 | 
			
		||||
  _saveaccountconf_mutable HUAWEICLOUD_ProjectID "${HUAWEICLOUD_ProjectID}"
 | 
			
		||||
  _saveaccountconf_mutable HUAWEICLOUD_DomainName "${HUAWEICLOUD_DomainName}"
 | 
			
		||||
  return 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -72,16 +74,16 @@ dns_huaweicloud_rm() {
 | 
			
		||||
 | 
			
		||||
  HUAWEICLOUD_Username="${HUAWEICLOUD_Username:-$(_readaccountconf_mutable HUAWEICLOUD_Username)}"
 | 
			
		||||
  HUAWEICLOUD_Password="${HUAWEICLOUD_Password:-$(_readaccountconf_mutable HUAWEICLOUD_Password)}"
 | 
			
		||||
  HUAWEICLOUD_ProjectID="${HUAWEICLOUD_ProjectID:-$(_readaccountconf_mutable HUAWEICLOUD_ProjectID)}"
 | 
			
		||||
  HUAWEICLOUD_DomainName="${HUAWEICLOUD_DomainName:-$(_readaccountconf_mutable HUAWEICLOUD_Username)}"
 | 
			
		||||
 | 
			
		||||
  # Check information
 | 
			
		||||
  if [ -z "${HUAWEICLOUD_Username}" ] || [ -z "${HUAWEICLOUD_Password}" ] || [ -z "${HUAWEICLOUD_ProjectID}" ]; then
 | 
			
		||||
  if [ -z "${HUAWEICLOUD_Username}" ] || [ -z "${HUAWEICLOUD_Password}" ] || [ -z "${HUAWEICLOUD_DomainName}" ]; then
 | 
			
		||||
    _err "Not enough information provided to dns_huaweicloud!"
 | 
			
		||||
    return 1
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  unset token # Clear token
 | 
			
		||||
  token="$(_get_token "${HUAWEICLOUD_Username}" "${HUAWEICLOUD_Password}" "${HUAWEICLOUD_ProjectID}")"
 | 
			
		||||
  token="$(_get_token "${HUAWEICLOUD_Username}" "${HUAWEICLOUD_Password}" "${HUAWEICLOUD_DomainName}")"
 | 
			
		||||
  if [ -z "${token}" ]; then # Check token
 | 
			
		||||
    _err "dns_api(dns_huaweicloud): Error getting token."
 | 
			
		||||
    return 1
 | 
			
		||||
@@ -253,7 +255,7 @@ _rm_record() {
 | 
			
		||||
_get_token() {
 | 
			
		||||
  _username=$1
 | 
			
		||||
  _password=$2
 | 
			
		||||
  _project=$3
 | 
			
		||||
  _domain_name=$3
 | 
			
		||||
 | 
			
		||||
  _debug "Getting Token"
 | 
			
		||||
  body="{
 | 
			
		||||
@@ -267,14 +269,14 @@ _get_token() {
 | 
			
		||||
            \"name\": \"${_username}\",
 | 
			
		||||
            \"password\": \"${_password}\",
 | 
			
		||||
            \"domain\": {
 | 
			
		||||
              \"name\": \"${_username}\"
 | 
			
		||||
              \"name\": \"${_domain_name}\"
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      \"scope\": {
 | 
			
		||||
        \"project\": {
 | 
			
		||||
          \"id\": \"${_project}\"
 | 
			
		||||
          \"name\": \"ap-southeast-1\"
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -118,6 +118,7 @@ _initAuth() {
 | 
			
		||||
    #return and wait for retry.
 | 
			
		||||
    return 1
 | 
			
		||||
  fi
 | 
			
		||||
  _saveaccountconf OVH_CK "$OVH_CK"
 | 
			
		||||
 | 
			
		||||
  _info "Checking authentication"
 | 
			
		||||
 | 
			
		||||
@@ -235,7 +236,6 @@ _ovh_authentication() {
 | 
			
		||||
  _secure_debug consumerKey "$consumerKey"
 | 
			
		||||
 | 
			
		||||
  OVH_CK="$consumerKey"
 | 
			
		||||
  _saveaccountconf OVH_CK "$OVH_CK"
 | 
			
		||||
 | 
			
		||||
  _info "Please open this link to do authentication: $(__green "$validationUrl")"
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -3,10 +3,10 @@
 | 
			
		||||
#
 | 
			
		||||
#VULTR_API_KEY=000011112222333344445555666677778888
 | 
			
		||||
 | 
			
		||||
VULTR_Api="https://api.vultr.com/v1"
 | 
			
		||||
VULTR_Api="https://api.vultr.com/v2"
 | 
			
		||||
 | 
			
		||||
########  Public functions #####################
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
#Usage: add  _acme-challenge.www.domain.com   "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
 | 
			
		||||
dns_vultr_add() {
 | 
			
		||||
  fulldomain=$1
 | 
			
		||||
@@ -31,14 +31,14 @@ dns_vultr_add() {
 | 
			
		||||
  _debug _domain "$_domain"
 | 
			
		||||
 | 
			
		||||
  _debug 'Getting txt records'
 | 
			
		||||
  _vultr_rest GET "dns/records?domain=$_domain"
 | 
			
		||||
  _vultr_rest GET "domains/$_domain/records"
 | 
			
		||||
 | 
			
		||||
  if printf "%s\n" "$response" | grep -- "\"type\":\"TXT\",\"name\":\"$fulldomain\"" >/dev/null; then
 | 
			
		||||
    _err 'Error'
 | 
			
		||||
    return 1
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  if ! _vultr_rest POST 'dns/create_record' "domain=$_domain&name=$_sub_domain&data=\"$txtvalue\"&type=TXT"; then
 | 
			
		||||
  if ! _vultr_rest POST "domains/$_domain/records" "{\"name\":\"$_sub_domain\",\"data\":\"$txtvalue\",\"type\":\"TXT\"}"; then
 | 
			
		||||
    _err "$response"
 | 
			
		||||
    return 1
 | 
			
		||||
  fi
 | 
			
		||||
@@ -71,14 +71,14 @@ dns_vultr_rm() {
 | 
			
		||||
  _debug _domain "$_domain"
 | 
			
		||||
 | 
			
		||||
  _debug 'Getting txt records'
 | 
			
		||||
  _vultr_rest GET "dns/records?domain=$_domain"
 | 
			
		||||
  _vultr_rest GET "domains/$_domain/records"
 | 
			
		||||
 | 
			
		||||
  if printf "%s\n" "$response" | grep -- "\"type\":\"TXT\",\"name\":\"$fulldomain\"" >/dev/null; then
 | 
			
		||||
    _err 'Error'
 | 
			
		||||
    return 1
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  _record_id="$(echo "$response" | tr '{}' '\n' | grep '"TXT"' | grep -- "$txtvalue" | tr ',' '\n' | grep -i 'RECORDID' | cut -d : -f 2)"
 | 
			
		||||
  _record_id="$(echo "$response" | tr '{}' '\n' | grep '"TXT"' | grep -- "$txtvalue" | tr ',' '\n' | grep -i 'id' | cut -d : -f 2)"
 | 
			
		||||
  _debug _record_id "$_record_id"
 | 
			
		||||
  if [ "$_record_id" ]; then
 | 
			
		||||
    _info "Successfully retrieved the record id for ACME challenge."
 | 
			
		||||
@@ -87,7 +87,7 @@ dns_vultr_rm() {
 | 
			
		||||
    return 0
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  if ! _vultr_rest POST 'dns/delete_record' "domain=$_domain&RECORDID=$_record_id"; then
 | 
			
		||||
  if ! _vultr_rest DELETE "domains/$_domain/records/$_record_id"; then
 | 
			
		||||
    _err "$response"
 | 
			
		||||
    return 1
 | 
			
		||||
  fi
 | 
			
		||||
@@ -112,11 +112,11 @@ _get_root() {
 | 
			
		||||
      return 1
 | 
			
		||||
    fi
 | 
			
		||||
 | 
			
		||||
    if ! _vultr_rest GET "dns/list"; then
 | 
			
		||||
    if ! _vultr_rest GET "domains"; then
 | 
			
		||||
      return 1
 | 
			
		||||
    fi
 | 
			
		||||
 | 
			
		||||
    if printf "%s\n" "$response" | grep '^\[.*\]' >/dev/null; then
 | 
			
		||||
    if printf "%s\n" "$response" | grep '^\{.*\}' >/dev/null; then
 | 
			
		||||
      if _contains "$response" "\"domain\":\"$_domain\""; then
 | 
			
		||||
        _sub_domain="$(echo "$fulldomain" | sed "s/\\.$_domain\$//")"
 | 
			
		||||
        return 0
 | 
			
		||||
@@ -141,8 +141,8 @@ _vultr_rest() {
 | 
			
		||||
 | 
			
		||||
  api_key_trimmed=$(echo $VULTR_API_KEY | tr -d '"')
 | 
			
		||||
 | 
			
		||||
  export _H1="Api-Key: $api_key_trimmed"
 | 
			
		||||
  export _H2='Content-Type: application/x-www-form-urlencoded'
 | 
			
		||||
  export _H1="Authorization: Bearer $api_key_trimmed"
 | 
			
		||||
  export _H2='Content-Type: application/json'
 | 
			
		||||
 | 
			
		||||
  if [ "$m" != "GET" ]; then
 | 
			
		||||
    _debug data "$data"
 | 
			
		||||
 
 | 
			
		||||
@@ -12,7 +12,7 @@ RECORD=''
 | 
			
		||||
 | 
			
		||||
# Usage: dns_world4you_add <fqdn> <value>
 | 
			
		||||
dns_world4you_add() {
 | 
			
		||||
  fqdn="$1"
 | 
			
		||||
  fqdn=$(echo "$1" | _lower_case)
 | 
			
		||||
  value="$2"
 | 
			
		||||
  _info "Using world4you to add record"
 | 
			
		||||
  _debug fulldomain "$fqdn"
 | 
			
		||||
@@ -49,12 +49,12 @@ dns_world4you_add() {
 | 
			
		||||
  ret=$(_post "$body" "$WORLD4YOU_API/$paketnr/dns" '' POST 'application/x-www-form-urlencoded')
 | 
			
		||||
  _resethttp
 | 
			
		||||
 | 
			
		||||
  if _contains "$(_head_n 3 <"$HTTP_HEADER")" '302'; then
 | 
			
		||||
  if _contains "$(_head_n 1 <"$HTTP_HEADER")" '302'; then
 | 
			
		||||
    res=$(_get "$WORLD4YOU_API/$paketnr/dns")
 | 
			
		||||
    if _contains "$res" "successfully"; then
 | 
			
		||||
      return 0
 | 
			
		||||
    else
 | 
			
		||||
      msg=$(echo "$res" | grep -A 15 'data-type="danger"' | grep "<h3[^>]*>[^<]" | sed 's/<[^>]*>\|^\s*//g')
 | 
			
		||||
      msg=$(echo "$res" | grep -A 15 'data-type="danger"' | grep "<h3[^>]*>[^<]" | sed 's/<[^>]*>//g' | sed 's/^\s*//g')
 | 
			
		||||
      if [ "$msg" = '' ]; then
 | 
			
		||||
        _err "Unable to add record: Unknown error"
 | 
			
		||||
        echo "$ret" >'error-01.html'
 | 
			
		||||
@@ -66,15 +66,15 @@ dns_world4you_add() {
 | 
			
		||||
      return 1
 | 
			
		||||
    fi
 | 
			
		||||
  else
 | 
			
		||||
    _err "$(_head_n 3 <"$HTTP_HEADER")"
 | 
			
		||||
    _err "View $HTTP_HEADER for debugging"
 | 
			
		||||
    msg=$(echo "$ret" | grep '"form-error-message"' | sed 's/^.*<div class="form-error-message">\([^<]*\)<\/div>.*$/\1/')
 | 
			
		||||
    _err "Unable to add record: my.world4you.com: $msg"
 | 
			
		||||
    return 1
 | 
			
		||||
  fi
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# Usage: dns_world4you_rm <fqdn> <value>
 | 
			
		||||
dns_world4you_rm() {
 | 
			
		||||
  fqdn="$1"
 | 
			
		||||
  fqdn=$(echo "$1" | _lower_case)
 | 
			
		||||
  value="$2"
 | 
			
		||||
  _info "Using world4you to remove record"
 | 
			
		||||
  _debug fulldomain "$fqdn"
 | 
			
		||||
@@ -113,12 +113,12 @@ dns_world4you_rm() {
 | 
			
		||||
  ret=$(_post "$body" "$WORLD4YOU_API/$paketnr/dns/record/delete" '' POST 'application/x-www-form-urlencoded')
 | 
			
		||||
  _resethttp
 | 
			
		||||
 | 
			
		||||
  if _contains "$(_head_n 3 <"$HTTP_HEADER")" '302'; then
 | 
			
		||||
  if _contains "$(_head_n 1 <"$HTTP_HEADER")" '302'; then
 | 
			
		||||
    res=$(_get "$WORLD4YOU_API/$paketnr/dns")
 | 
			
		||||
    if _contains "$res" "successfully"; then
 | 
			
		||||
      return 0
 | 
			
		||||
    else
 | 
			
		||||
      msg=$(echo "$res" | grep -A 15 'data-type="danger"' | grep "<h3[^>]*>[^<]" | sed 's/<[^>]*>\|^\s*//g')
 | 
			
		||||
      msg=$(echo "$res" | grep -A 15 'data-type="danger"' | grep "<h3[^>]*>[^<]" | sed 's/<[^>]*>//g' | sed 's/^\s*//g')
 | 
			
		||||
      if [ "$msg" = '' ]; then
 | 
			
		||||
        _err "Unable to remove record: Unknown error"
 | 
			
		||||
        echo "$ret" >'error-01.html'
 | 
			
		||||
@@ -130,8 +130,8 @@ dns_world4you_rm() {
 | 
			
		||||
      return 1
 | 
			
		||||
    fi
 | 
			
		||||
  else
 | 
			
		||||
    _err "$(_head_n 3 <"$HTTP_HEADER")"
 | 
			
		||||
    _err "View $HTTP_HEADER for debugging"
 | 
			
		||||
    msg=$(echo "$ret" | grep "form-error-message" | sed 's/^.*<div class="form-error-message">\([^<]*\)<\/div>.*$/\1/')
 | 
			
		||||
    _err "Unable to remove record: my.world4you.com: $msg"
 | 
			
		||||
    return 1
 | 
			
		||||
  fi
 | 
			
		||||
}
 | 
			
		||||
@@ -155,29 +155,42 @@ _login() {
 | 
			
		||||
  _saveaccountconf_mutable WORLD4YOU_USERNAME "$WORLD4YOU_USERNAME"
 | 
			
		||||
  _saveaccountconf_mutable WORLD4YOU_PASSWORD "$WORLD4YOU_PASSWORD"
 | 
			
		||||
 | 
			
		||||
  _resethttp
 | 
			
		||||
  export ACME_HTTP_NO_REDIRECTS=1
 | 
			
		||||
  page=$(_get "$WORLD4YOU_API/login")
 | 
			
		||||
  _resethttp
 | 
			
		||||
 | 
			
		||||
  if _contains "$(_head_n 1 <"$HTTP_HEADER")" '302'; then
 | 
			
		||||
    _info "Already logged in"
 | 
			
		||||
    _parse_sessid
 | 
			
		||||
    return 0
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  _info "Logging in..."
 | 
			
		||||
 | 
			
		||||
  username="$WORLD4YOU_USERNAME"
 | 
			
		||||
  password="$WORLD4YOU_PASSWORD"
 | 
			
		||||
  csrf_token=$(_get "$WORLD4YOU_API/login" | grep '_csrf_token' | sed 's/^.*<input[^>]*value=\"\([^"]*\)\".*$/\1/')
 | 
			
		||||
  sessid=$(grep 'W4YSESSID' <"$HTTP_HEADER" | sed 's/^.*W4YSESSID=\([^;]*\);.*$/\1/')
 | 
			
		||||
  csrf_token=$(echo "$page" | grep '_csrf_token' | sed 's/^.*<input[^>]*value=\"\([^"]*\)\".*$/\1/')
 | 
			
		||||
  _parse_sessid
 | 
			
		||||
 | 
			
		||||
  export _H1="Cookie: W4YSESSID=$sessid"
 | 
			
		||||
  export _H2="X-Requested-With: XMLHttpRequest"
 | 
			
		||||
  body="_username=$username&_password=$password&_csrf_token=$csrf_token"
 | 
			
		||||
  ret=$(_post "$body" "$WORLD4YOU_API/login" '' POST 'application/x-www-form-urlencoded')
 | 
			
		||||
  unset _H2
 | 
			
		||||
 | 
			
		||||
  _debug ret "$ret"
 | 
			
		||||
  if _contains "$ret" "\"success\":true"; then
 | 
			
		||||
    _info "Successfully logged in"
 | 
			
		||||
    sessid=$(grep 'W4YSESSID' <"$HTTP_HEADER" | sed 's/^.*W4YSESSID=\([^;]*\);.*$/\1/')
 | 
			
		||||
    _parse_sessid
 | 
			
		||||
  else
 | 
			
		||||
    _err "Unable to log in: $(echo "$ret" | sed 's/^.*"message":"\([^\"]*\)".*$/\1/')"
 | 
			
		||||
    msg=$(echo "$ret" | sed 's/^.*"message":"\([^\"]*\)".*$/\1/')
 | 
			
		||||
    _err "Unable to log in: my.world4you.com: $msg"
 | 
			
		||||
    return 1
 | 
			
		||||
  fi
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# Usage _get_paketnr <fqdn> <form>
 | 
			
		||||
# Usage: _get_paketnr <fqdn> <form>
 | 
			
		||||
_get_paketnr() {
 | 
			
		||||
  fqdn="$1"
 | 
			
		||||
  form="$2"
 | 
			
		||||
@@ -200,3 +213,8 @@ _get_paketnr() {
 | 
			
		||||
  PAKETNR=$(echo "$form" | grep "data-textfilter=\".* $domain " | _tail_n 1 | sed "s|.*$WORLD4YOU_API/\\([0-9]*\\)/.*|\\1|")
 | 
			
		||||
  return 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# Usage: _parse_sessid
 | 
			
		||||
_parse_sessid() {
 | 
			
		||||
  sessid=$(grep 'W4YSESSID' <"$HTTP_HEADER" | _tail_n 1 | sed 's/^.*W4YSESSID=\([^;]*\);.*$/\1/')
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										45
									
								
								notify/slack_app.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										45
									
								
								notify/slack_app.sh
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,45 @@
 | 
			
		||||
#!/usr/bin/env sh
 | 
			
		||||
 | 
			
		||||
#Support Slack APP notifications
 | 
			
		||||
 | 
			
		||||
#SLACK_APP_CHANNEL=""
 | 
			
		||||
#SLACK_APP_TOKEN=""
 | 
			
		||||
 | 
			
		||||
slack_app_send() {
 | 
			
		||||
  _subject="$1"
 | 
			
		||||
  _content="$2"
 | 
			
		||||
  _statusCode="$3" #0: success, 1: error 2($RENEW_SKIP): skipped
 | 
			
		||||
  _debug "_statusCode" "$_statusCode"
 | 
			
		||||
 | 
			
		||||
  SLACK_APP_CHANNEL="${SLACK_APP_CHANNEL:-$(_readaccountconf_mutable SLACK_APP_CHANNEL)}"
 | 
			
		||||
  if [ -n "$SLACK_APP_CHANNEL" ]; then
 | 
			
		||||
    _saveaccountconf_mutable SLACK_APP_CHANNEL "$SLACK_APP_CHANNEL"
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  SLACK_APP_TOKEN="${SLACK_APP_TOKEN:-$(_readaccountconf_mutable SLACK_APP_TOKEN)}"
 | 
			
		||||
  if [ -n "$SLACK_APP_TOKEN" ]; then
 | 
			
		||||
    _saveaccountconf_mutable SLACK_APP_TOKEN "$SLACK_APP_TOKEN"
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  _content="$(printf "*%s*\n%s" "$_subject" "$_content" | _json_encode)"
 | 
			
		||||
  _data="{\"text\": \"$_content\", "
 | 
			
		||||
  if [ -n "$SLACK_APP_CHANNEL" ]; then
 | 
			
		||||
    _data="$_data\"channel\": \"$SLACK_APP_CHANNEL\", "
 | 
			
		||||
  fi
 | 
			
		||||
  _data="$_data\"mrkdwn\": \"true\"}"
 | 
			
		||||
 | 
			
		||||
  export _H1="Authorization: Bearer $SLACK_APP_TOKEN"
 | 
			
		||||
 | 
			
		||||
  SLACK_APP_API_URL="https://slack.com/api/chat.postMessage"
 | 
			
		||||
  if _post "$_data" "$SLACK_APP_API_URL" "" "POST" "application/json; charset=utf-8"; then
 | 
			
		||||
    # shellcheck disable=SC2154
 | 
			
		||||
    SLACK_APP_RESULT_OK=$(echo "$response" | _egrep_o 'ok" *: *true')
 | 
			
		||||
    if [ "$?" = "0" ] && [ "$SLACK_APP_RESULT_OK" ]; then
 | 
			
		||||
      _info "slack send success."
 | 
			
		||||
      return 0
 | 
			
		||||
    fi
 | 
			
		||||
  fi
 | 
			
		||||
  _err "slack send error."
 | 
			
		||||
  _err "$response"
 | 
			
		||||
  return 1
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user