diff --git a/acme.sh b/acme.sh index 2ca7fa97..798ba3f8 100755 --- a/acme.sh +++ b/acme.sh @@ -2455,8 +2455,13 @@ _apachePath() { if ! _exists apachectl; then if _exists apache2ctl; then _APACHECTL="apache2ctl" + elif _exists apache2; then #added + _APACHECTL="apache2" #added + elif _exists httpd; then #added + _APACHECTL="httpd" #added else - _err "'apachectl not found. It seems that apache is not installed, or you are not root user.'" + _err "'apachectl (or apache2 or httpd) not found. It seems that apache is not installed, or you are not root user.'" + #_err "'apachectl not found. It seems that apache is not installed, or you are not root user.'" _err "Please use webroot mode to try again." return 1 fi diff --git a/deploy/apache.sh b/deploy/apache.sh index 7b34bd5f..6d9c98d5 100644 --- a/deploy/apache.sh +++ b/deploy/apache.sh @@ -1,12 +1,218 @@ #!/usr/bin/env sh - +# TESTING!!! # #Here is a script to deploy cert to apache server. #returns 0 means success, otherwise error. - +#acme.sh --install-cert -d example.com \ +#--cert-file /path/to/certfile/in/apache/cert.pem \ +#--key-file /path/to/keyfile/in/apache/key.pem \ +#--fullchain-file /path/to/fullchain/certfile/apache/fullchain.pem \ +#--reloadcmd "service apache2 force-reload" ######## Public functions ##################### +set -x +# get rid of _APACHECTL, and _exec after testing +_APACHECTL='httpd' + +_exec() { + eval "$@" +} + +## $1 : new cert location $2: cp to location +_cpCert() { + #return 0 + if cp -f ${1} ${2} && chmod 600 ${2}; then + return 0 + fi + return 1 +} + +_vhostBackupConf() { + #return 0 + if cp -f "${1}" "${1}.bak"; then + return 0 + fi + return 1 +} + +_vhostRestoreConf() { + #return 0 + if cp -f "${1}.bak" "${1}"; then + return 0 + fi + return 1 +} + +_testConf() { + if ! _exec $_APACHECTL -t; then + return 1 + fi + return 0 +} + +## $1 : vhost config file to check and edit. $2: domain $3: port +_vhostConf() { + if ! _vhostBackupConf "$1"; then + # do something + testvar='' + fi + + serverName=$(awk '/ServerName/,/$/' "$1") + serverName=$(awk -F ' ' '{print $2}' <<< ${serverName}) + serverAlias=$(awk '/ServerAlias/,/$/' "$1") + serverAlias=$(awk -F ' ' '{print $2}' <<< ${serverAlias}) + docRoot=$(awk '/DocumentRoot/,/$/' "$1") + docRoot=$(awk -F ' ' '{print $2}' <<< ${docRoot}) + rootParent=$(dirname ${docRoot}) + pri=$rootParent/ssl/private + pub=$rootParent/ssl/public + mkdir -m 700 -p ${pri:1} + mkdir -m 700 -p ${pub:1} + sslEng=$(awk '/SSLEngine/,/$/' "$1") + sslEng=$(awk -F ' ' '{print $2}' <<< ${sslEng}) + sslPro=$(awk '/SSLProtocol/,/$/' "$1") + sslPro=$(awk -F ' ' '{print $2}' <<< ${sslPro}) + sslCiph=$(awk '/SSLCipherSuite/,/$/' "$1") + sslCiph=$(awk -F ' ' '{print $2}' <<< ${sslCiph}) + ciphOrd=$(awk '/SSLHonorCipherOrder/,/$/' "$1") + ciphOrd=$(awk -F ' ' '{print $2}' <<< ${ciphOrd}) + crtFile=$(awk '/SSLCertificateFile/,/$/' "$1") + crtFile=$(awk -F ' ' '{print $2}' <<< ${crtFile}) + keyFile=$(awk '/SSLCertificateKeyFile/,/$/' "$1") + keyFile=$(awk -F ' ' '{print $2}' <<< ${keyFile}) + chainFile=$(awk '/SSLCertificateChainFile/,/$/' "$1") + chainFile=$(awk -F ' ' '{print $2}' <<< ${chainFile}) + locSec1=' + RewriteEngine On + RewriteRule .* https://${matchServerName}/%{REQUEST_URI}/ [R=301,L,QSA] + +EOF +) + sed -i '/"${reWriteBlock}"/i ' "${confMatch}" + return 0 + fi + return 1 + fi + if grep -q 'SSLEngine' "$1"; then + sed -i '/SSLEngine /c\SSLEngine On' "$1" + sed -i '/SSLProtocol /c\SSLProtocol -all +TLSv1.2' "$1" + sed -i '/SSLCipherSuite /c\SSLCipherSuite ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:RSA+AESGCM:RSA+AES:!aNULL:!MD5:!DSS' "$1" + sed -i '/SSLHonorCipherOrder /c\SSLHonorCipherOrder on' "$1" + sed -i '/SSLCertificateFile /c\SSLCertificateFile ${rootParent}/ssl/public/${serverName}.crt' "$1" + sed -i '/SSLCertificateChainFile /c\SSLCertificateChainFile ${rootParent}/ssl/public/${serverName}.chain.crt' "$1" + sed -i '/SSLCertificateKeyFile /c\SSLCertificateKeyFile ${rootParent}/ssl/private/${serverName}.key' "$1" + testvar='' + else + sslBlock=$(cat < + ServerName ${serverName} + DocumentRoot ${docRoot} + SSLEngine On + SSLProtocol -all +TLSv1.2 + SSLCipherSuite ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:RSA+AESGCM:RSA+AES:!aNULL:!MD5:!DSS + SSLHonorCipherOrder on + SSLCertificateFile ${rootParent}/ssl/public/${serverName}.crt + SSLCertificateChainFile ${rootParent}/ssl/public/${serverName}.chain.crt + SSLCertificateKeyFile ${rootParent}/ssl/private/${serverName}.key + + ${locSec} + DirectorySlash On + + +EOF +) + echo "${sslBlock}" >> "$1" + fi + + #look for a location section eg. + + if grep -q ${locSec} "$1"; then + if grep -q ${dirSlash} "$1"; then + #set dir slash on + sed -i '/DirectorySlash /c\DirectorySlash On' "$1" + testvar='' + else + #append dir slash here + sed -i '/${locSec}/a DirectorySlash On' "$1" + testvar='' + fi + else + locBlock=$(cat < +EOF +) + # insert the new block here... + sed -i '/<\/virtualhost>/i ${locBlock}' "$1" + fi + + #look for mod_rewrite section + modReWrite='' + if grep -q ${modReWrite} "$1"; then + if grep -q "RewriteEngine On" "$1"; then + #set rewrite rules for ssl + # too many ways to redirect ssl for me to check.... + testvar='' + else + #append rewrite rules for ssl + sed -i '/${modReWrite}/a RewriteEngine On' "$1" + sed -i '/RewriteEngine On/a RewriteCond %{HTTPS} !on [OR]' "$1" + sed -i '/RewriteCond %{HTTPS} !on [OR]/a RewriteCond %{HTTP_HOST} ^www\. [NC] [OR]' "$1" + sed -i '/RewriteCond %{HTTP_HOST} ^www\. [NC] [OR]/a RewriteCond %{REQUEST_URI} !(.*)/$' "$1" + sed -i '/RewriteCond %{REQUEST_URI} !(.*)/$/a ${newRwRuleSsl}' "$1" + testvar='' + fi + else + reWriteBlock=$(cat < + RewriteEngine On + RewriteCond %{HTTPS} !on [OR] + RewriteCond %{HTTP_HOST} ^www\. [NC] [OR] + RewriteCond %{REQUEST_URI} !(.*)/$ + ${newRwRuleSsl} + +EOF +) + # insert the new block here... + sed -i '/<\/virtualhost>/i ${reWriteBlock}' "$1" + fi + return +} + -#domain keyfile certfile cafile fullchain apache_deploy() { _cdomain="$1" _ckey="$2" @@ -14,13 +220,39 @@ apache_deploy() { _cca="$4" _cfullchain="$5" - _debug _cdomain "$_cdomain" - _debug _ckey "$_ckey" - _debug _ccert "$_ccert" - _debug _cca "$_cca" - _debug _cfullchain "$_cfullchain" + all_hosts=$(eval "$_APACHECTL -S" | awk '/namevhost/,/\)/') + #echo "$all_hosts" + oldIFS=$IFS + IFS=' +' + loopLog='' + for h in $all_hosts; do + d=$(awk -F ' ' '{print $4}' <<< "${h}") + c=$(awk -F ' ' '{print $5}' <<< "${h}") + c=$(echo "$c" | awk -v FS="(\\\\(|\\\\:)" '{print $2}') + p=$(awk -F ' ' '{print $2}' <<< "${h}") + #echo "$d $p $c" + if echo ${d} | grep -q ${_cdomain}; then + if _vhostConf "$c" "$d" "$p"; then + c1='/ssl/public/' + c2='/ssl/private/' + k='.key' + k1=$rootParent$c2$d$k + c3='.crt' + c4='.chain.crt' + c5=$rootParent$c1$d$c3 + c6=$rootParent$c1$d$c4 + cp -f $_ckey ${k1:1} + cp -f $_ccert ${c5:1} + cp -f $_cfullchain ${c6:1} - _err "Deploy cert to apache server, Not implemented yet" - return 1 + fi + fi + done + IFS=$oldIFS } + +apache_deploy idragonfly.net /path/to/test.key /path/to/test.crt /path/to/test.cacert.crt /path/to/test.chain.crt +#echo "$testLog" >> test.log +set +x diff --git a/dnsapi/README.md b/dnsapi/README.md index 8c43806c..d1a8bfb8 100644 --- a/dnsapi/README.md +++ b/dnsapi/README.md @@ -92,6 +92,21 @@ acme.sh --issue --dns dns_pdns -d example.com -d www.example.com The `PDNS_Url`, `PDNS_ServerId`, `PDNS_Token` and `PDNS_Ttl` will be saved in `~/.acme.sh/account.conf` and will be reused when needed. +## 5a. Use PowerDNS mysql backend to automatically issue cert + +First you need to set your host:user:pass:database in the configuration. +Make sure the following are in your records table: +INSERT INTO `records` (`domain_id`, `name`, `type`, `content`, `ttl`, `prio`, `change_date`) +VALUES ({your domain_id}, 'example.com', 'SOA', 'ns1.example.com.net admin.example.com 1 10800 3600 604800 3600', 120, NULL, 0), +({your domain_id}, '_acme-challenge.example.com', 'A', '{ipv4 address}', 60, NULL, 0), +({your domain_id}, '_acme-challenge.example.com', 'AAAA', '{ipv6 address}', 60, NULL, NULL, 'N', 0, NULL, 0), +({your domain_id}, 'example.com', 'CAA', '0 issue "letsencrypt.org"', 60, NULL, 0); + +Ok, let's issue a cert now: +``` +acme.sh --issue --dns dns_pdnsMysql -d example.com -d *.example.com +``` + ## 6. Use OVH/kimsufi/soyoustart/runabove API to automatically issue cert diff --git a/dnsapi/dns_ad.sh b/dnsapi/dns_ad.sh deleted file mode 100755 index fc4a664b..00000000 --- a/dnsapi/dns_ad.sh +++ /dev/null @@ -1,147 +0,0 @@ -#!/usr/bin/env sh - -# -#AD_API_KEY="sdfsdfsdfljlbjkljlkjsdfoiwje" - -#This is the Alwaysdata api wrapper for acme.sh -# -#Author: Paul Koppen -#Report Bugs here: https://github.com/wpk-/acme.sh - -AD_API_URL="https://$AD_API_KEY:@api.alwaysdata.com/v1" - -######## Public functions ##################### - -#Usage: dns_myapi_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" -dns_ad_add() { - fulldomain=$1 - txtvalue=$2 - - if [ -z "$AD_API_KEY" ]; then - AD_API_KEY="" - _err "You didn't specify the AD api key yet." - _err "Please create you key and try again." - return 1 - fi - - _saveaccountconf AD_API_KEY "$AD_API_KEY" - - _debug "First detect the root zone" - if ! _get_root "$fulldomain"; then - _err "invalid domain" - return 1 - fi - _debug _domain_id "$_domain_id" - _debug _sub_domain "$_sub_domain" - _debug _domain "$_domain" - - _ad_tmpl_json="{\"domain\":$_domain_id,\"type\":\"TXT\",\"name\":\"$_sub_domain\",\"value\":\"$txtvalue\"}" - - if _ad_rest POST "record/" "$_ad_tmpl_json" && [ -z "$response" ]; then - _info "txt record updated success." - return 0 - fi - - return 1 -} - -#fulldomain txtvalue -dns_ad_rm() { - fulldomain=$1 - txtvalue=$2 - - _debug "First detect the root zone" - if ! _get_root "$fulldomain"; then - _err "invalid domain" - return 1 - fi - _debug _domain_id "$_domain_id" - _debug _sub_domain "$_sub_domain" - _debug _domain "$_domain" - - _debug "Getting txt records" - _ad_rest GET "record/?domain=$_domain_id&name=$_sub_domain" - - if [ -n "$response" ]; then - record_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":\s*[0-9]+" | cut -d : -f 2 | tr -d " " | _head_n 1) - _debug record_id "$record_id" - if [ -z "$record_id" ]; then - _err "Can not get record id to remove." - return 1 - fi - if _ad_rest DELETE "record/$record_id/" && [ -z "$response" ]; then - _info "txt record deleted success." - return 0 - fi - _debug response "$response" - return 1 - 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 - - if _ad_rest GET "domain/"; then - response="$(echo "$response" | tr -d "\n" | sed 's/{/\n&/g')" - while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) - _debug h "$h" - if [ -z "$h" ]; then - #not valid - return 1 - fi - - hostedzone="$(echo "$response" | _egrep_o "{.*\"name\":\s*\"$h\".*}")" - if [ "$hostedzone" ]; then - _domain_id=$(printf "%s\n" "$hostedzone" | _egrep_o "\"id\":\s*[0-9]+" | _head_n 1 | cut -d : -f 2 | tr -d \ ) - if [ "$_domain_id" ]; then - _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) - _domain=$h - return 0 - fi - return 1 - fi - p=$i - i=$(_math "$i" + 1) - done - fi - return 1 -} - -#method uri qstr data -_ad_rest() { - mtd="$1" - ep="$2" - data="$3" - - _debug mtd "$mtd" - _debug ep "$ep" - - export _H1="Accept: application/json" - export _H2="Content-Type: application/json" - - if [ "$mtd" != "GET" ]; then - # both POST and DELETE. - _debug data "$data" - response="$(_post "$data" "$AD_API_URL/$ep" "" "$mtd")" - else - response="$(_get "$AD_API_URL/$ep")" - fi - - if [ "$?" != "0" ]; then - _err "error $ep" - return 1 - fi - _debug2 response "$response" - return 0 -} diff --git a/dnsapi/dns_ali.sh b/dnsapi/dns_ali.sh deleted file mode 100755 index 543a0a54..00000000 --- a/dnsapi/dns_ali.sh +++ /dev/null @@ -1,202 +0,0 @@ -#!/usr/bin/env sh - -Ali_API="https://alidns.aliyuncs.com/" - -#Ali_Key="LTqIA87hOKdjevsf5" -#Ali_Secret="0p5EYueFNq501xnCPzKNbx6K51qPH2" - -#Usage: dns_ali_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" -dns_ali_add() { - fulldomain=$1 - txtvalue=$2 - - Ali_Key="${Ali_Key:-$(_readaccountconf_mutable Ali_Key)}" - Ali_Secret="${Ali_Secret:-$(_readaccountconf_mutable Ali_Secret)}" - if [ -z "$Ali_Key" ] || [ -z "$Ali_Secret" ]; then - Ali_Key="" - Ali_Secret="" - _err "You don't specify aliyun api key and secret yet." - return 1 - fi - - #save the api key and secret to the account conf file. - _saveaccountconf_mutable Ali_Key "$Ali_Key" - _saveaccountconf_mutable Ali_Secret "$Ali_Secret" - - _debug "First detect the root zone" - if ! _get_root "$fulldomain"; then - return 1 - fi - - _debug "Add record" - _add_record_query "$_domain" "$_sub_domain" "$txtvalue" && _ali_rest "Add record" -} - -dns_ali_rm() { - fulldomain=$1 - txtvalue=$2 - Ali_Key="${Ali_Key:-$(_readaccountconf_mutable Ali_Key)}" - Ali_Secret="${Ali_Secret:-$(_readaccountconf_mutable Ali_Secret)}" - - _debug "First detect the root zone" - if ! _get_root "$fulldomain"; then - return 1 - fi - - _clean -} - -#################### Private functions below ################################## - -_get_root() { - domain=$1 - i=2 - p=1 - while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) - if [ -z "$h" ]; then - #not valid - return 1 - fi - - _describe_records_query "$h" - if ! _ali_rest "Get root" "ignore"; then - return 1 - fi - - if _contains "$response" "PageNumber"; then - _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) - _debug _sub_domain "$_sub_domain" - _domain="$h" - _debug _domain "$_domain" - return 0 - fi - p="$i" - i=$(_math "$i" + 1) - done - return 1 -} - -_ali_rest() { - signature=$(printf "%s" "GET&%2F&$(_ali_urlencode "$query")" | _hmac "sha1" "$(printf "%s" "$Ali_Secret&" | _hex_dump | tr -d " ")" | _base64) - signature=$(_ali_urlencode "$signature") - url="$Ali_API?$query&Signature=$signature" - - if ! response="$(_get "$url")"; then - _err "Error <$1>" - return 1 - fi - - _debug2 response "$response" - if [ -z "$2" ]; then - message="$(echo "$response" | _egrep_o "\"Message\":\"[^\"]*\"" | cut -d : -f 2 | tr -d \")" - if [ "$message" ]; then - _err "$message" - return 1 - fi - fi -} - -_ali_urlencode() { - _str="$1" - _str_len=${#_str} - _u_i=1 - while [ "$_u_i" -le "$_str_len" ]; do - _str_c="$(printf "%s" "$_str" | cut -c "$_u_i")" - case $_str_c in [a-zA-Z0-9.~_-]) - printf "%s" "$_str_c" - ;; - *) - printf "%%%02X" "'$_str_c" - ;; - esac - _u_i="$(_math "$_u_i" + 1)" - done -} - -_ali_nonce() { - #_head_n 1 1" >/dev/null; then - _zone="$(echo "$autodns_response" | _egrep_o '[^<]*' | cut -d '>' -f 2 | cut -d '<' -f 1)" - _system_ns="$(echo "$autodns_response" | _egrep_o '[^<]*' | 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 " - %s - %s - %s - " "$AUTODNS_USER" "$AUTODNS_PASSWORD" "$AUTODNS_CONTEXT" -} - -# Arguments: -# zone -_build_zone_inquire_xml() { - printf " - - %s - - 0205 - - 1 - 1 - - - name - eq - %s - - - " "$(_build_request_auth_xml)" "$1" -} - -# Arguments: -# zone -# subdomain -# txtvalue -# system_ns -_build_zone_update_xml() { - printf " - - %s - - 0202001 - - - %s - 600 - TXT - %s - - - - %s - %s - - - " "$(_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" "$AUTODNS_API")" - ret="$?" - - _debug autodns_response "$autodns_response" - - if [ "$ret" -ne "0" ]; then - _err "error" - return 1 - fi - - if _contains "$autodns_response" "success" >/dev/null; then - _info "success" - printf "%s" "$autodns_response" - return 0 - fi - - return 1 -} diff --git a/dnsapi/dns_pdnsMysql.sh b/dnsapi/dns_pdnsMysql.sh new file mode 100644 index 00000000..b4e6ff49 --- /dev/null +++ b/dnsapi/dns_pdnsMysql.sh @@ -0,0 +1,172 @@ +#!/usr/bin/env sh + +#PowerDNS Mysql backend +# +# +PDNS_Host="example.com" +PDNS_Port=3306 +PDNS_User="username" +PDNS_Pass="password" +PDNS_Database="powerdns" +PDNS_Ttl=60 + +DEFAULT_PDNS_TTL=60 + +######## Public functions ##################### +#Usage: add _acme-challenge.www.domain.com "123456789ABCDEF0000000000000000000000000000000000000" +#fulldomain +#txtvalue +dns_pdnsMysql_add() { + fulldomain=$1 + txtvalue=$2 + + if [ -z "$PDNS_Host" ]; then + PDNS_Url="" + _err "You didn't specify PowerDNS Mysql address." + _err "Please set PDNS_Host and try again." + return 1 + fi + + if [ -z "$PDNS_Port" ]; then + PDNS_Url="" + _err "You didn't specify PowerDNS Mysql Port." + _err "Please set PDNS_Port and try again." + return 1 + fi + + if [ -z "$PDNS_User" ]; then + PDNS_User="" + _err "You didn't specify PowerDNS Mysql username." + _err "Please set PDNS_User and try again." + return 1 + fi + + if [ -z "$PDNS_Pass" ]; then + PDNS_Pass="" + _err "You didn't specify PowerDNS Mysql password." + _err "Please set PDNS_Pass and try again." + return 1 + fi + + if [ -z "$PDNS_Database" ]; then + PDNS_Database="" + _err "You didn't specify PowerDNS Mysql database." + _err "Please set PDNS_Database and try again." + return 1 + fi + + if [ -z "$PDNS_Ttl" ]; then + PDNS_Ttl="$DEFAULT_PDNS_TTL" + fi + + #save the api addr and key to the account conf file. + _saveaccountconf PDNS_Host "$PDNS_Host" + _saveaccountconf PDNS_Port "$PDNS_Port" + _saveaccountconf PDNS_User "$PDNS_User" + _saveaccountconf PDNS_Pass "$PDNS_Pass" + _saveaccountconf PDNS_Database "$PDNS_Database" + + if [ "$PDNS_Ttl" != "$DEFAULT_PDNS_TTL" ]; then + _saveaccountconf PDNS_Ttl "$PDNS_Ttl" + fi + + _debug "Detect root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + _debug _domain "$_domain" + + if ! set_record "$_domain" "$fulldomain" "$txtvalue"; then + return 1 + fi + + return 0 +} + +#fulldomain +dns_pdnsMysql_rm() { + fulldomain=$1 + + _debug "Detect root zone" + if ! _get_root "$fulldomain"; then + _err "invalid domain" + return 1 + fi + _debug _domain "$_domain" + + if ! rm_record "$_domain" "$fulldomain"; then + return 1 + fi + + return 0 +} + +set_record() { + _info "Adding record" + root=$1 + full=$2 + txtvalue=$3 + _domain_id=$(mysql -ss "-h${PDNS_Host}" "-P${PDNS_Port}" "-u${PDNS_User}" "-p${PDNS_Pass}" -e "SELECT id FROM ${PDNS_Database}.domains WHERE name='${root}'") + # insert challenge. + mysql -ss "-h${PDNS_Host}" "-P${PDNS_Port}" "-u${PDNS_User}" "-p${PDNS_Pass}" -e "INSERT INTO ${PDNS_Database}.records (domain_id,name, content, type,ttl,prio) VALUES \ + (${_domain_id},'${full}','${txtvalue}','TXT',60,NULL);" + + if ! notify_slaves "$root"; then + return 1 + fi + + return 0 +} + +rm_record() { + _info "Remove record" + root=$1 + full=$2 + + mysql -ss "-h${PDNS_Host}" "-P${PDNS_Port}" "-u${PDNS_User}" "-p${PDNS_Pass}" -e "DELETE FROM ${PDNS_Database}.records WHERE name='${full}' AND type='TXT';" + + if ! notify_slaves "$root"; then + return 1 + fi + + return 0 +} + +notify_slaves() { + root=$1 + # hack set last_check to null to force update. # + mysql -ss "-h${PDNS_Host}" "-P${PDNS_Port}" "-u${PDNS_User}" "-p${PDNS_Pass}" -e "UPDATE ${PDNS_Database}.domains SET last_check=NULL WHERE name='${root}';" + + return 0 +} + +#################### Private functions below ################################## +#_acme-challenge.www.domain.com +#returns +# _domain=domain.com +_get_root() { + domain=$1 + i=1 + _pdns_domains=$(mysql -ss "-h${PDNS_Host}" "-P${PDNS_Port}" "-u${PDNS_User}" "-p${PDNS_Pass}" -e "SELECT name FROM ${PDNS_Database}.domains") + if [ -z "$_pdns_domains" ]; then + return 1 + fi + + while true; do + h=$(printf "%s" "$domain" | cut -d . -f $i-100) + if [ -z "$h" ]; then + return 1 + fi + + if _contains "$_pdns_domains" "$h"; then + _domain="$h" + return 0 + fi + + i=$(_math $i + 1) + done + _debug "$domain not found" + + return 1 +}