From e2f73cbd583b3619a03d9700728c25b08f0a1089 Mon Sep 17 00:00:00 2001 From: Dirk Brenken Date: Thu, 13 Sep 2018 14:45:44 +0200 Subject: [PATCH] ddns-scripts: multiple fixes * replace shell based urlencoder with an awk variant * fix write_log function/syslog output in case of an error * protect answer string with double quotes in update_route53 * remove bogus set/IFS options in update_route53 * clean-up update_route53 a little bit This patchset finally fix #6977 Many thanks to @mark0n & @a-bali for testing & debugging Signed-off-by: Dirk Brenken --- net/ddns-scripts/Makefile | 2 +- .../files/dynamic_dns_functions.sh | 32 ++------- net/ddns-scripts/files/update_route53_v1.sh | 72 +++++++++---------- 3 files changed, 42 insertions(+), 64 deletions(-) diff --git a/net/ddns-scripts/Makefile b/net/ddns-scripts/Makefile index d72cab260..aa57c4fcb 100755 --- a/net/ddns-scripts/Makefile +++ b/net/ddns-scripts/Makefile @@ -12,7 +12,7 @@ PKG_NAME:=ddns-scripts PKG_VERSION:=2.7.8 # Release == build # increase on changes of services files or tld_names.dat -PKG_RELEASE:=4 +PKG_RELEASE:=5 PKG_LICENSE:=GPL-2.0 PKG_MAINTAINER:= diff --git a/net/ddns-scripts/files/dynamic_dns_functions.sh b/net/ddns-scripts/files/dynamic_dns_functions.sh index 31b6f1974..658334480 100755 --- a/net/ddns-scripts/files/dynamic_dns_functions.sh +++ b/net/ddns-scripts/files/dynamic_dns_functions.sh @@ -21,7 +21,7 @@ . /lib/functions/network.sh # GLOBAL VARIABLES # -VERSION="2.7.8-4" +VERSION="2.7.8-5" SECTION_ID="" # hold config's section name VERBOSE=0 # default mode is log to console, but easily changed with parameter MYPROG=$(basename $0) # my program call name @@ -282,11 +282,11 @@ write_log() { [ $__LEVEL -eq 7 ] && return # no syslog for debug messages __CMD=$(echo -e "$__CMD" | tr -d '\n' | tr '\t' ' ') # remove \n \t chars [ $__EXIT -eq 1 ] && { - $__CMD # force syslog before exit + eval "$__CMD" # force syslog before exit exit 1 } [ $use_syslog -eq 0 ] && return - [ $((use_syslog + __LEVEL)) -le 7 ] && $__CMD + [ $((use_syslog + __LEVEL)) -le 7 ] && eval "$__CMD" return } @@ -301,32 +301,12 @@ write_log() { urlencode() { # $1 Name of Variable to store encoded string to # $2 string to encode - local __STR __LEN __CHAR __OUT - local __ENC="" - local __POS=1 + local __ENC [ $# -ne 2 ] && write_log 12 "Error calling 'urlencode()' - wrong number of parameters" - __STR="$2" # read string to encode - __LEN=${#__STR} # get string length - - while [ $__POS -le $__LEN ]; do - # read one chat of the string - __CHAR=$(expr substr "$__STR" $__POS 1) - - case "$__CHAR" in - [-_.~a-zA-Z0-9] ) - # standard char - __OUT="${__CHAR}" - ;; - * ) - # special char get %hex code - __OUT=$(printf '%%%02x' "'$__CHAR" ) - ;; - esac - __ENC="${__ENC}${__OUT}" # append to encoded string - __POS=$(( $__POS + 1 )) # increment position - done + __ENC="$(awk -v str="$2" 'BEGIN{ORS="";for(i=32;i<=127;i++)lookup[sprintf("%c",i)]=i + for(k=1;k<=length(str);++k){enc=substr(str,k,1);if(enc!~"[-_.~a-zA-Z0-9]")enc=sprintf("%%%02x", lookup[enc]);print enc}}')" eval "$1=\"$__ENC\"" # transfer back to variable return 0 diff --git a/net/ddns-scripts/files/update_route53_v1.sh b/net/ddns-scripts/files/update_route53_v1.sh index 6b9b029e0..a7d4dfb64 100644 --- a/net/ddns-scripts/files/update_route53_v1.sh +++ b/net/ddns-scripts/files/update_route53_v1.sh @@ -1,46 +1,44 @@ #!/bin/sh -#.Distributed under the terms of the GNU General Public License (GPL) version 2.0 -#.based on Yuval Adam's route53.sh found at https://github.com/yuvadm/route53-ddns/blob/master/route53.sh -#.2017 Max Berger -[ -z "$CURL_SSL" ] && write_log 14 "Amazon AWS Route53 communication require cURL with SSL support. Please install" -[ -z "$username" ] && write_log 14 "Service section not configured correctly! Missing key as 'username'" -[ -z "$password" ] && write_log 14 "Service section not configured correctly! Missing secret as 'password'" -[ -z "$domain" ] && write_log 14 "Service section not configured correctly! Missing zone id as 'domain'" +# Distributed under the terms of the GNU General Public License (GPL) version 2.0 +# based on Yuval Adam's route53.sh found at https://github.com/yuvadm/route53-ddns/blob/master/route53.sh +# 2017 Max Berger -set -euo pipefail -IFS=$'\n\t' +[ -z "${CURL_SSL}" ] && write_log 14 "Amazon AWS Route53 communication require cURL with SSL support. Please install" +[ -z "{$username}" ] && write_log 14 "Service section not configured correctly! Missing key as 'username'" +[ -z "${password}" ] && write_log 14 "Service section not configured correctly! Missing secret as 'password'" +[ -z "${domain}" ] && write_log 14 "Service section not configured correctly! Missing zone id as 'domain'" ENDPOINT="route53.amazonaws.com" RECORD_TTL=300 -RECORD_NAME="$lookup_host". -[ $use_ipv6 -eq 0 ] && RECORD_TYPE="A" -[ $use_ipv6 -eq 1 ] && RECORD_TYPE="AAAA" -RECORD_VALUE="$LOCAL_IP" -HOSTED_ZONE_ID="$domain" +RECORD_NAME="${lookup_host}." +[ ${use_ipv6} -eq 0 ] && RECORD_TYPE="A" +[ ${use_ipv6} -eq 1 ] && RECORD_TYPE="AAAA" +RECORD_VALUE="${LOCAL_IP}" +HOSTED_ZONE_ID="${domain}" API_PATH="/2013-04-01/hostedzone/${HOSTED_ZONE_ID}/rrset/" -AWS_ACCESS_KEY_ID="$username" -AWS_SECRET_ACCESS_KEY="$password" +AWS_ACCESS_KEY_ID="${username}" +AWS_SECRET_ACCESS_KEY="${password}" AWS_REGION='us-east-1' AWS_SERVICE='route53' hash() { - msg=$1 - echo -en "$msg" | openssl dgst -sha256 | sed 's/^.* //' + msg="$1" + echo -en "${msg}" | openssl dgst -sha256 | sed 's/^.* //' } sign_plain() { # Sign message using a plaintext key - key=$1 - msg=$2 - echo -en "$msg" | openssl dgst -hex -sha256 -hmac "$key" | sed 's/^.* //' + key="$1" + msg="$2" + echo -en "${msg}" | openssl dgst -hex -sha256 -hmac "${key}" | sed 's/^.* //' } sign() { # Sign message using a hex formatted key - key=$1 - msg=$2 - echo -en "$msg" | openssl dgst -hex -sha256 -mac HMAC -macopt "hexkey:${key}" | sed 's/^.* //' + key="$1" + msg="$2" + echo -en "${msg}" | openssl dgst -hex -sha256 -mac HMAC -macopt "hexkey:${key}" | sed 's/^.* //' } request_body=" \ @@ -64,34 +62,34 @@ request_body=" \ \ " -fulldate=$(date --utc +%Y%m%dT%H%M%SZ) -shortdate=$(date --utc +%Y%m%d) +fulldate="$(date --utc +%Y%m%dT%H%M%SZ)" +shortdate="$(date --utc +%Y%m%d)" signed_headers="host;x-amz-date" -request_hash=$(hash "$request_body") +request_hash="$(hash "${request_body}")" canonical_request="POST\n${API_PATH}\n\nhost:route53.amazonaws.com\nx-amz-date:${fulldate}\n\n${signed_headers}\n${request_hash}" -date_key=$(sign_plain "AWS4${AWS_SECRET_ACCESS_KEY}" "${shortdate}") -region_key=$(sign "$date_key" $AWS_REGION) -service_key=$(sign "$region_key" $AWS_SERVICE) -signing_key=$(sign "$service_key" aws4_request) +date_key="$(sign_plain "AWS4${AWS_SECRET_ACCESS_KEY}" "${shortdate}")" +region_key="$(sign "${date_key}" ${AWS_REGION})" +service_key="$(sign "${region_key}" ${AWS_SERVICE})" +signing_key="$(sign "${service_key}" aws4_request)" credential="${shortdate}/${AWS_REGION}/${AWS_SERVICE}/aws4_request" -sigmsg="AWS4-HMAC-SHA256\n${fulldate}\n${credential}\n$(hash "$canonical_request")" +sigmsg="AWS4-HMAC-SHA256\n${fulldate}\n${credential}\n$(hash "${canonical_request}")" -signature=$(sign "$signing_key" "$sigmsg") +signature="$(sign "${signing_key}" "${sigmsg}")" authorization="AWS4-HMAC-SHA256 Credential=${AWS_ACCESS_KEY_ID}/${credential}, SignedHeaders=${signed_headers}, Signature=${signature}" -ANSWER=$(curl \ +ANSWER="$(curl \ -X "POST" \ -H "Host: route53.amazonaws.com" \ -H "X-Amz-Date: ${fulldate}" \ -H "Authorization: ${authorization}" \ -H "Content-Type: text/xml" \ -d "$request_body" \ - "https://${ENDPOINT}${API_PATH}") + "https://${ENDPOINT}${API_PATH}")" write_log 7 "${ANSWER}" -echo ${ANSWER} | grep Error >/dev/null && return 1 -echo ${ANSWER} | grep ChangeInfo >/dev/null && return 0 +echo "${ANSWER}" | grep -F "Error" >/dev/null && return 1 +echo "${ANSWER}" | grep -F "ChangeInfo" >/dev/null && return 0 return 2