]> git.giorgioravera.it Git - scripts.git/commitdiff
Updated Fritz Scripts
authorGiorgio Ravera <giorgio.ravera@gmail.com>
Tue, 5 Aug 2025 17:25:02 +0000 (19:25 +0200)
committerGiorgio Ravera <giorgio.ravera@gmail.com>
Tue, 5 Aug 2025 17:43:11 +0000 (19:43 +0200)
update_certificate
update_certificate_fritz

index b9cf405852afdf4a27f2ea3f496b157af5442401..d216f136ca2f9c63ad3fdb64a520eba4b5b73371 100755 (executable)
@@ -19,6 +19,7 @@ DST_TMP_CHAIN="$DST_TMP_PATH/chain.pem"
 DST_TMP_FULLCHAIN="$DST_TMP_PATH/fullchain.pem"
 DST_TMP_SERVER="$DST_TMP_PATH/server.pem"
 PATH="$PATH:/usr/local/bin"
+SECRET_FILE=".secret"
 
 # Copy Certificate
 # Copy Certificate in $dst folder
@@ -142,7 +143,12 @@ function update_fritz () {
        USER="fritz5738"
        ALIVE=$(ping -c 1 $HOST |grep ttl)
        if [ ! -z "$ALIVE" ]; then
-               update_certificate_fritz $HOST $USER $SRC_FULLCHAIN $SRC_KEY
+               if [ -f "$SECRET_FILE" ]; then
+                       password=$(awk -F':' -v host="$HOST" '$1 == host {print $2}' "$SECRET_FILE")
+                       update_certificate_fritz -b $HOST -u $USER -p $password -c $SRC_FULLCHAIN -k $SRC_KEY
+               else
+                       echo "$SECRET_FILE not found"
+               fi
        else
                echo "Host $HOST not alive, skipped"
        fi
@@ -158,7 +164,12 @@ function update_ap1 () {
        USER="fritz9145"
        ALIVE=$(ping -c 1 $HOST |grep ttl)
        if [ ! -z "$ALIVE" ]; then
-               update_certificate_fritz $HOST $USER $SRC_FULLCHAIN $SRC_KEY
+               if [ -f "$SECRET_FILE" ]; then
+                       password=$(awk -F':' -v host="$HOST" '$1 == host {print $2}' "$SECRET_FILE")
+                       update_certificate_fritz -b $HOST -u $USER -p $password -c $SRC_FULLCHAIN -k $SRC_KEY
+               else
+                       echo "$SECRET_FILE not found"
+               fi
        else
                echo "Host $HOST not alive, skipped"
        fi
index 4f71d6ddc5e2a1791bee78af96305604053a92ae..8ac05919e19afa2b5520289b9d8f5805266a28c1 100755 (executable)
 #!/bin/bash
 
 # Parameters
-PASSWORD=""
-
-# check inputs:
-if [ $# -eq 0 ]; then
-    echo "Wrong parameters. Please use:"
-    echo "- host"
-    echo "- username"
-    echo "- certificate"
-    echo "- key"
-    exit
+CURL_CMD="curl"
+ICONV_CMD="iconv"
+OPENSSL_CMD="openssl"
+
+SUCCESS_MESSAGES="^ *(Das SSL-Zertifikat wurde erfolgreich importiert|Import of the SSL certificate was successful|El certificado SSL se ha importado correctamente|Le certificat SSL a été importé|Il certificato SSL è stato importato|Import certyfikatu SSL został pomyślnie zakończony)"
+
+DEBUG_OUTPUT=/tmp/fritzbox.debug
+
+function usage {
+  echo "Usage: $0 [-b baseurl] [-u username] [-p password] [-c fullchain certificate] [-k privkey]" >&2
+  exit 64
+}
+
+function error {
+  local msg=$1
+
+  [ "${msg}" ] && echo "${msg}" >&2
+  exit 1
+}
+
+md5cmd=
+
+for cmd in md5 md5sum; do
+  if which "${cmd}" >/dev/null 2>&1; then
+    md5cmd=${cmd}
+    break
+  fi
+done
+
+if [ -z "${md5cmd}" ]; then
+  error "Missing command for calculating MD5 hash"
+fi
+
+exit=0
+
+for cmd in ${CURL_CMD} ${ICONV_CMD} ${OPENSSL_CMD}; do
+  if ! which "${cmd}" >/dev/null 2>&1; then
+    error "Please install ${cmd}" >&2
+  fi
+done
+
+[ ${exit} -ne 0 ] && exit ${exit}
+
+while getopts ":b:p:u:c:k:dh" opt; do
+  case ${opt} in
+    b)
+      baseurl=$OPTARG
+      ;;
+    p)
+      password=$OPTARG
+      ;;
+    u)
+      username=$OPTARG
+      ;;
+    c)
+      fullchain=$OPTARG
+      ;;
+    k)
+      privkey=$OPTARG
+      ;;
+    d)
+      debug="true"
+      ;;
+    h)
+      usage
+      ;;
+    \?)
+      echo "Invalid option: $OPTARG" >&2
+      echo >&2
+      usage
+      ;;
+    :)
+      echo "Invalid option: $OPTARG requires an argument" >&2
+      echo >&2
+      usage
+      ;;
+  esac
+done
+
+shift $((OPTIND - 1))
+
+exit=0
+
+# strip trailing slash
+baseurl="${baseurl%/}"
+
+if [ ! -r "${fullchain}" ] || [ ! -r "${privkey}" ]; then
+  error "Certpath ${certpath} must contain fullchain.pem and privkey.pem"
 fi
 
-# save inputs
-HOST=$1
-USERNAME=$2
-CERT=$3
-KEY=$4
+if ! ${OPENSSL_CMD} rsa -in "${privkey}" -check -noout &>/dev/null; then
+  error "FRITZ!OS only supports RSA private keys."
+fi
+
+if [ -n "${debug}" ]; then
+  curl_opts="-v -s --stderr -"
+
+  function process_curl_output {
+    grep -v '^[*{}]' | sed -e '1i\
+' | tee -a ${DEBUG_OUTPUT}
+  }
 
-# make and secure a temporary file
-TMP="$(mktemp -t XXXXXX)"
-chmod 600 $TMP
+  echo "Debug output will be written to ${DEBUG_OUTPUT}"
+else
+  curl_opts="-sS"
+
+  function process_curl_output {
+    cat
+  }
+fi
+
+request_file="$(mktemp -t XXXXXX)"
+trap 'rm -f "${request_file}"' EXIT
+
+echo "----------------------------------------------------------------" >>${DEBUG_OUTPUT}
+date >>${DEBUG_OUTPUT}
 
 # login to the box and get a valid SID
-CHALLENGE=`wget -q -O - $HOST/login_sid.lua | sed -e 's/^.*<Challenge>//' -e 's/<\/Challenge>.*$//'`
-HASH="`echo -n $CHALLENGE-$PASSWORD | iconv -f ASCII -t UTF16LE |md5sum|awk '{print $1}'`"
-SID=`wget -q -O - "$HOST/login_sid.lua?sid=0000000000000000&username=$USERNAME&response=$CHALLENGE-$HASH"| sed -e 's/^.*<SID>//' -e 's/<\/SID>.*$//'`
+# shellcheck disable=SC2086
+challenge="$(${CURL_CMD} ${curl_opts} "${baseurl}/login_sid.lua" | process_curl_output | sed -ne 's/^.*<Challenge>\([0-9a-f][0-9a-f]*\)<\/Challenge>.*$/\1/p')"
+if [ -z "${challenge}" ]; then
+  error "Invalid challenge received."
+fi
+
+md5hash="$(echo -n "${challenge}-${password}" | ${ICONV_CMD} -f ASCII -t UTF-16LE | ${md5cmd} | awk '{print $1}')"
+
+# shellcheck disable=SC2086
+sid="$(${CURL_CMD} ${curl_opts} "${baseurl}/login_sid.lua?username=${username}&response=${challenge}-${md5hash}" | process_curl_output | sed -ne 's/^.*<SID>\([0-9a-f][0-9a-f]*\)<\/SID>.*$/\1/p')"
+if [ -z "${sid}" ] || [ "${sid}" = "0000000000000000" ]; then
+  error "Login failed."
+fi
+
+certbundle=$(cat "${fullchain}" "${privkey}" | grep -v '^$')
 
 # generate our upload request
-BOUNDARY="---------------------------"`date +%Y%m%d%H%M%S`
-printf -- "--$BOUNDARY\r\n" >> $TMP
-printf "Content-Disposition: form-data; name=\"sid\"\r\n\r\n$SID\r\n" >> $TMP
-#printf -- "--$BOUNDARY\r\n" >> $TMP
-#printf "Content-Disposition: form-data; name=\"BoxCertPassword\"\r\n\r\n$CERT_PASSWORD\r\n" >> $TMP
-printf -- "--$BOUNDARY\r\n" >> $TMP
-printf "Content-Disposition: form-data; name=\"BoxCertImportFile\"; filename=\"BoxCert.pem\"\r\n" >> $TMP
-printf "Content-Type: application/octet-stream\r\n\r\n" >> $TMP
-cat $KEY >> $TMP
-cat $CERT >> $TMP
-printf "\r\n" >> $TMP
-printf -- "--$BOUNDARY--" >> $TMP
+boundary="---------------------------$(date +%Y%m%d%H%M%S)"
 
-# upload the certificate to the box
-wget -q -O - $HOST/cgi-bin/firmwarecfg --header="Content-type: multipart/form-data boundary=$BOUNDARY" --post-file $TMP | grep SSL
+cat <<EOD >>"${request_file}"
+--${boundary}
+Content-Disposition: form-data; name="sid"
 
-# clean up
-rm -f $TMP
+${sid}
+--${boundary}
+Content-Disposition: form-data; name="BoxCertImportFile"; filename="BoxCert.pem"
+Content-Type: application/octet-stream
+
+${certbundle}
+--${boundary}--
+EOD
+
+# upload the certificate to the box
+# shellcheck disable=SC2086
+${CURL_CMD} ${curl_opts} -X POST "${baseurl}/cgi-bin/firmwarecfg" -H "Content-type: multipart/form-data boundary=${boundary}" --data-binary "@${request_file}" | process_curl_output | grep -qE "${SUCCESS_MESSAGES}"
+# shellcheck disable=SC2181
+if [ $? -ne 0 ]; then
+  error "Could not import certificate."
+else
+  echo "Import of the SSL certificate was successful"
+fi