From 45bc96908474c373408216a640dbf117b4a17acf Mon Sep 17 00:00:00 2001 From: Lucky Baar Date: Fri, 13 May 2022 10:43:50 -0500 Subject: [PATCH 1/6] fix: use temporary directory when downloading updater --- cmd/updater/update.sh | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/cmd/updater/update.sh b/cmd/updater/update.sh index 60fbe05617..77aaf1bcef 100755 --- a/cmd/updater/update.sh +++ b/cmd/updater/update.sh @@ -214,26 +214,36 @@ function check_for_updater() { exit 1 fi - CURL_OUT=$(curl -LJO --silent ${UPDATER_URL}) + # intitialize temporary directory for updater + local updater_tempdir="" \ + updater_archive="${updater_tempdir}/${UPDATER_FILENAME}" + + # create temporary directory for updater archive + updater_tempdir=$(mktemp -d 2>/dev/null || mktemp -d -t "tmp") + + CURL_OUT=$(curl -sSL ${UPDATER_URL} -o "$updater_archive") if [ "$?" != "0" ]; then echo "failed to download updater binary from ${UPDATER_URL} using curl." echo "${CURL_OUT}" exit 1 fi - if [ ! -f "${SCRIPTPATH}/${UPDATER_FILENAME}" ]; then - echo "downloaded file ${SCRIPTPATH}/${UPDATER_FILENAME} is missing." + if [ ! -f "${updater_archive}" ]; then + echo "downloaded file ${updater_archive} is missing." exit fi - tar -zxvf "${SCRIPTPATH}/${UPDATER_FILENAME}" updater + # extract and install updater + tar -zxf "$updater_archive" -C "$updater_tempdir" updater + mv "${updater_tempdir}/updater" "${SCRIPTPATH}" if [ "$?" != "0" ]; then - echo "failed to extract updater binary from ${SCRIPTPATH}/${UPDATER_FILENAME}" + echo "failed to extract updater binary from ${updater_archive}" exit 1 fi - rm -f "${SCRIPTPATH}/${UPDATER_FILENAME}" - echo "updater binary was downloaded" + # clean up temp directory + rm -rf "$updater_tempdir" + echo "updater binary was installed at ${SCRIPTPATH}/updater" } function check_for_update() { From 75bc8b834d8f16de97362f922238d2928a9b9713 Mon Sep 17 00:00:00 2001 From: Lucky Baar Date: Mon, 16 May 2022 15:32:45 -0500 Subject: [PATCH 2/6] fix: update UPDATER_URL --- cmd/updater/update.sh | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/cmd/updater/update.sh b/cmd/updater/update.sh index 77aaf1bcef..628b21ca79 100755 --- a/cmd/updater/update.sh +++ b/cmd/updater/update.sh @@ -190,8 +190,8 @@ function get_updater_url() { echo "This operation system ${UNAME} is not supported by updater." exit 1 fi - UPDATER_FILENAME="install_master_${OS}-${ARCH}.tar.gz" - UPDATER_URL="https://github.com/algorand/go-algorand-doc/raw/master/downloads/installers/${OS}_${ARCH}/${UPDATER_FILENAME}" + UPDATER_FILENAME="install_stable_${OS}-${ARCH}_3.6.2.tar.gz" + UPDATER_URL="https://github.com/algorand/go-algorand/releases/download/v3.6.2-stable/install_stable_${OS}-${ARCH}_3.6.2.tar.gz" } # check to see if the binary updater exists. if not, it will automatically the correct updater binary for the current platform @@ -214,35 +214,34 @@ function check_for_updater() { exit 1 fi - # intitialize temporary directory for updater - local updater_tempdir="" \ - updater_archive="${updater_tempdir}/${UPDATER_FILENAME}" + # create temporary directory for updater archive + local UPDATER_TEMPDIR="" + UPDATER_TEMPDIR="$(mktemp -d 2>/dev/null || mktemp -d -t "tmp")" - # create temporary directory for updater archive - updater_tempdir=$(mktemp -d 2>/dev/null || mktemp -d -t "tmp") + local UPDATER_ARCHIVE="${UPDATER_TEMPDIR}/${UPDATER_FILENAME}" - CURL_OUT=$(curl -sSL ${UPDATER_URL} -o "$updater_archive") + CURL_OUT=$(curl -sSL ${UPDATER_URL} -o "$UPDATER_ARCHIVE") if [ "$?" != "0" ]; then echo "failed to download updater binary from ${UPDATER_URL} using curl." echo "${CURL_OUT}" exit 1 fi - if [ ! -f "${updater_archive}" ]; then - echo "downloaded file ${updater_archive} is missing." + if [ ! -f "${UPDATER_ARCHIVE}" ]; then + echo "downloaded file ${UPDATER_ARCHIVE} is missing." exit fi - # extract and install updater - tar -zxf "$updater_archive" -C "$updater_tempdir" updater - mv "${updater_tempdir}/updater" "${SCRIPTPATH}" + # extract and install updater + tar -zxf "$UPDATER_ARCHIVE" -C "$UPDATER_TEMPDIR" updater + mv "${UPDATER_TEMPDIR}/updater" "${SCRIPTPATH}" if [ "$?" != "0" ]; then - echo "failed to extract updater binary from ${updater_archive}" + echo "failed to extract updater binary from ${UPDATER_ARCHIVE}" exit 1 fi # clean up temp directory - rm -rf "$updater_tempdir" + rm -rf "$UPDATER_TEMPDIR" echo "updater binary was installed at ${SCRIPTPATH}/updater" } From e4638ef42500758565d8d1ac2916f7fe0986c552 Mon Sep 17 00:00:00 2001 From: Lucky Baar Date: Wed, 18 May 2022 10:43:42 -0500 Subject: [PATCH 3/6] fix: add comment about hard-coded version --- cmd/updater/update.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cmd/updater/update.sh b/cmd/updater/update.sh index 628b21ca79..19a9dc5657 100755 --- a/cmd/updater/update.sh +++ b/cmd/updater/update.sh @@ -190,6 +190,8 @@ function get_updater_url() { echo "This operation system ${UNAME} is not supported by updater." exit 1 fi + # the updater will auto-update itself to the latest version, this means that the version of updater that is downloaded + # can be arbitrary as long as the self-updating functionality is working, hence the hard-coded version UPDATER_FILENAME="install_stable_${OS}-${ARCH}_3.6.2.tar.gz" UPDATER_URL="https://github.com/algorand/go-algorand/releases/download/v3.6.2-stable/install_stable_${OS}-${ARCH}_3.6.2.tar.gz" } From 23f00c3449fec4d78f3287876a9c103fb531a4c2 Mon Sep 17 00:00:00 2001 From: Lucky Baar Date: Thu, 19 May 2022 04:19:46 -0500 Subject: [PATCH 4/6] update.sh: add gpg and checksum validation to linux updater --- cmd/updater/update.sh | 99 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 83 insertions(+), 16 deletions(-) diff --git a/cmd/updater/update.sh b/cmd/updater/update.sh index 19a9dc5657..d8179c8e53 100755 --- a/cmd/updater/update.sh +++ b/cmd/updater/update.sh @@ -190,26 +190,39 @@ function get_updater_url() { echo "This operation system ${UNAME} is not supported by updater." exit 1 fi + # the updater will auto-update itself to the latest version, this means that the version of updater that is downloaded # can be arbitrary as long as the self-updating functionality is working, hence the hard-coded version + UPDATER_URL="http://algorand-dev-deb-repo.s3-website-us-east-1.amazonaws.com/releases/stable/f9d842778_3.6.2/install_stable_${OS}-${ARCH}_3.6.2.tar.gz" UPDATER_FILENAME="install_stable_${OS}-${ARCH}_3.6.2.tar.gz" - UPDATER_URL="https://github.com/algorand/go-algorand/releases/download/v3.6.2-stable/install_stable_${OS}-${ARCH}_3.6.2.tar.gz" + + # if on linux, also set variables for signature and checksum validation + if [ "$OS" = "linux" ]; then + UPDATER_PUBKEYURL="https://releases.algorand.com/key.pub" + UPDATER_SIGURL="http://algorand-dev-deb-repo.s3-website-us-east-1.amazonaws.com/releases/stable/f9d842778_3.6.2/install_stable_${OS}-${ARCH}_3.6.2.tar.gz.sig" + UPDATER_CHECKSUMURL="https://algorand-releases.s3.amazonaws.com/channel/stable/hashes_stable_${OS}_${ARCH}_3.6.2" + fi } # check to see if the binary updater exists. if not, it will automatically the correct updater binary for the current platform function check_for_updater() { + local UNAME + UNAME="$(uname)" + # check if the updater binary exist and is not empty. if [[ -s "${SCRIPTPATH}/updater" && -f "${SCRIPTPATH}/updater" ]]; then return 0 fi + + # set UPDATER_URL and UPDATER_ARCHIVE as a global that can be referenced here + # if linux, UPDATER_PUBKEYURL, UPDATER_SIGURL, UPDATER_CHECKSUMURL will be set to try verification get_updater_url - # check the curl is available. - CURL_VER=$(curl -V 2>/dev/null || true) - if [ "${CURL_VER}" = "" ]; then + # check if curl is available + if ! type curl &>/dev/null; then # no curl is installed. echo "updater binary is missing and cannot be downloaded since curl is missing." - if [[ "$(uname)" = "Linux" ]]; then + if [ "$UNAME" = "Linux" ]; then echo "To install curl, run the following command:" echo "apt-get update; apt-get install -y curl" fi @@ -217,29 +230,83 @@ function check_for_updater() { fi # create temporary directory for updater archive - local UPDATER_TEMPDIR="" + local UPDATER_TEMPDIR="" UPDATER_ARCHIVE="" UPDATER_TEMPDIR="$(mktemp -d 2>/dev/null || mktemp -d -t "tmp")" + UPDATER_ARCHIVE="${UPDATER_TEMPDIR}/${UPDATER_FILENAME}" - local UPDATER_ARCHIVE="${UPDATER_TEMPDIR}/${UPDATER_FILENAME}" - - CURL_OUT=$(curl -sSL ${UPDATER_URL} -o "$UPDATER_ARCHIVE") - if [ "$?" != "0" ]; then - echo "failed to download updater binary from ${UPDATER_URL} using curl." - echo "${CURL_OUT}" + # download updater archive + if ! curl -sSL "$UPDATER_URL" -o "$UPDATER_ARCHIVE"; then + echo "failed to download updater archive from ${UPDATER_URL} using curl." exit 1 fi - if [ ! -f "${UPDATER_ARCHIVE}" ]; then + if [ ! -f "$UPDATER_ARCHIVE" ]; then echo "downloaded file ${UPDATER_ARCHIVE} is missing." exit fi + # if linux, check for checksum and signature validation dependencies + local GPG_VERIFY="0" CHECKSUM_VERIFY="0" + if [ "$UNAME" = "Linux" ]; then + if type gpg >&/dev/null; then + GPG_VERIFY="1" + else + echo "gpg is not available to perform signature validation." + fi + + if type sha256sum &>/dev/null; then + CHECKSUM_VERIFY="1" + else + echo "sha256sum is not available to perform checksum validation." + fi + fi + + # try signature validation + if [ "$GPG_VERIFY" = "1" ]; then + local UPDATER_SIGFILE="$UPDATER_TEMPDIR/updater.sig" UPDATER_PUBKEYFILE="key.pub" + # try downloading public key + if curl -sSL "$UPDATER_PUBKEYURL" -o "$UPDATER_PUBKEYFILE"; then + if gpg --import "$UPDATER_PUBKEYFILE"; then + if curl -sSL "$UPDATER_SIGURL" -o "$UPDATER_SIGFILE"; then + if ! gpg --verify "$UPDATER_SIGFILE" "$UPDATER_ARCHIVE"; then + echo "failed to verify signature of updater archive." + exit 1 + fi + else + echo "failed download signature file, cannot perform signature validation." + fi + else + echo "failed importing GPG public key, cannot perform signature validation." + fi + else + echo "failed downloading GPG public key, cannot perform signature validation." + fi + fi + + # try checksum validation + if [ "$CHECKSUM_VERIFY" = "1" ]; then + local UPDATER_CHECKSUMFILE="$UPDATER_TEMPDIR/updater.checksum" + # try downloading checksum file + if curl -sSL "$UPDATER_CHECKSUMURL" -o "$UPDATER_CHECKSUMFILE"; then + # have to be in same directory as archive + pushd "$UPDATER_TEMPDIR" + if ! sha256sum --quiet --ignore-missing -c "$UPDATER_CHECKSUMFILE"; then + echo "failed to verify checksum of updater archive." + popd + exit 1 + fi + popd + else + echo "failed downloading checksum file, cannot perform checksum validation." + fi + fi + # extract and install updater - tar -zxf "$UPDATER_ARCHIVE" -C "$UPDATER_TEMPDIR" updater - mv "${UPDATER_TEMPDIR}/updater" "${SCRIPTPATH}" - if [ "$?" != "0" ]; then + if ! tar -zxf "$UPDATER_ARCHIVE" -C "$UPDATER_TEMPDIR" updater; then echo "failed to extract updater binary from ${UPDATER_ARCHIVE}" exit 1 + else + mv "${UPDATER_TEMPDIR}/updater" "$SCRIPTPATH" fi # clean up temp directory From bbd56bcc1d68e05f666061294ef8070fab144fa5 Mon Sep 17 00:00:00 2001 From: Lucky Baar Date: Thu, 19 May 2022 13:12:11 -0500 Subject: [PATCH 5/6] update.sh: make gpg use separate directory for keyring --- cmd/updater/update.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cmd/updater/update.sh b/cmd/updater/update.sh index d8179c8e53..f62e84e0fd 100755 --- a/cmd/updater/update.sh +++ b/cmd/updater/update.sh @@ -266,6 +266,7 @@ function check_for_updater() { local UPDATER_SIGFILE="$UPDATER_TEMPDIR/updater.sig" UPDATER_PUBKEYFILE="key.pub" # try downloading public key if curl -sSL "$UPDATER_PUBKEYURL" -o "$UPDATER_PUBKEYFILE"; then + GNUPGHOME="$(mktemp -d)"; export GNUPGHOME if gpg --import "$UPDATER_PUBKEYFILE"; then if curl -sSL "$UPDATER_SIGURL" -o "$UPDATER_SIGFILE"; then if ! gpg --verify "$UPDATER_SIGFILE" "$UPDATER_ARCHIVE"; then @@ -278,6 +279,8 @@ function check_for_updater() { else echo "failed importing GPG public key, cannot perform signature validation." fi + # clean up temporary directory used for signature validation + rm -rf "$GNUPGHOME"; unset GNUPGHOME else echo "failed downloading GPG public key, cannot perform signature validation." fi From 3563b5d8c77ac1bcbfa59312632ec08fb4fbb6c1 Mon Sep 17 00:00:00 2001 From: Lucky Baar Date: Fri, 20 May 2022 15:25:58 -0500 Subject: [PATCH 6/6] update.sh: add -verify CLI flag and default to false --- cmd/updater/update.sh | 98 +++++++++++++++++++++++-------------------- 1 file changed, 53 insertions(+), 45 deletions(-) diff --git a/cmd/updater/update.sh b/cmd/updater/update.sh index f62e84e0fd..3ed4622bad 100755 --- a/cmd/updater/update.sh +++ b/cmd/updater/update.sh @@ -22,6 +22,7 @@ GENESIS_NETWORK_DIR_SPEC="" SKIP_UPDATE=0 TOOLS_OUTPUT_DIR="" DRYRUN=false +VERIFY_UPDATER_ARCHIVE="0" IS_ROOT=false if [ $EUID -eq 0 ]; then IS_ROOT=true @@ -100,6 +101,10 @@ while [ "$1" != "" ]; do shift TOOLS_OUTPUT_DIR=$1 ;; + -verify) + shift + VERIFY_UPDATER_ARCHIVE="1" + ;; -z) DRYRUN=true ;; @@ -197,7 +202,7 @@ function get_updater_url() { UPDATER_FILENAME="install_stable_${OS}-${ARCH}_3.6.2.tar.gz" # if on linux, also set variables for signature and checksum validation - if [ "$OS" = "linux" ]; then + if [ "$OS" = "linux" ] && [ "$VERIFY_UPDATER_ARCHIVE" = "1" ]; then UPDATER_PUBKEYURL="https://releases.algorand.com/key.pub" UPDATER_SIGURL="http://algorand-dev-deb-repo.s3-website-us-east-1.amazonaws.com/releases/stable/f9d842778_3.6.2/install_stable_${OS}-${ARCH}_3.6.2.tar.gz.sig" UPDATER_CHECKSUMURL="https://algorand-releases.s3.amazonaws.com/channel/stable/hashes_stable_${OS}_${ARCH}_3.6.2" @@ -245,62 +250,65 @@ function check_for_updater() { exit fi - # if linux, check for checksum and signature validation dependencies - local GPG_VERIFY="0" CHECKSUM_VERIFY="0" - if [ "$UNAME" = "Linux" ]; then - if type gpg >&/dev/null; then - GPG_VERIFY="1" - else - echo "gpg is not available to perform signature validation." - fi + # if -verify command line flag is set, try verifying updater archive + if [ "$VERIFY_UPDATER_ARCHIVE" = "1" ]; then + # if linux, check for checksum and signature validation dependencies + local GPG_VERIFY="0" CHECKSUM_VERIFY="0" + if [ "$UNAME" = "Linux" ]; then + if type gpg >&/dev/null; then + GPG_VERIFY="1" + else + echo "gpg is not available to perform signature validation." + fi - if type sha256sum &>/dev/null; then - CHECKSUM_VERIFY="1" - else - echo "sha256sum is not available to perform checksum validation." + if type sha256sum &>/dev/null; then + CHECKSUM_VERIFY="1" + else + echo "sha256sum is not available to perform checksum validation." + fi fi - fi - # try signature validation - if [ "$GPG_VERIFY" = "1" ]; then - local UPDATER_SIGFILE="$UPDATER_TEMPDIR/updater.sig" UPDATER_PUBKEYFILE="key.pub" - # try downloading public key - if curl -sSL "$UPDATER_PUBKEYURL" -o "$UPDATER_PUBKEYFILE"; then - GNUPGHOME="$(mktemp -d)"; export GNUPGHOME - if gpg --import "$UPDATER_PUBKEYFILE"; then - if curl -sSL "$UPDATER_SIGURL" -o "$UPDATER_SIGFILE"; then - if ! gpg --verify "$UPDATER_SIGFILE" "$UPDATER_ARCHIVE"; then - echo "failed to verify signature of updater archive." - exit 1 + # try signature validation + if [ "$GPG_VERIFY" = "1" ]; then + local UPDATER_SIGFILE="$UPDATER_TEMPDIR/updater.sig" UPDATER_PUBKEYFILE="key.pub" + # try downloading public key + if curl -sSL "$UPDATER_PUBKEYURL" -o "$UPDATER_PUBKEYFILE"; then + GNUPGHOME="$(mktemp -d)"; export GNUPGHOME + if gpg --import "$UPDATER_PUBKEYFILE"; then + if curl -sSL "$UPDATER_SIGURL" -o "$UPDATER_SIGFILE"; then + if ! gpg --verify "$UPDATER_SIGFILE" "$UPDATER_ARCHIVE"; then + echo "failed to verify signature of updater archive." + exit 1 + fi + else + echo "failed download signature file, cannot perform signature validation." fi else - echo "failed download signature file, cannot perform signature validation." + echo "failed importing GPG public key, cannot perform signature validation." fi + # clean up temporary directory used for signature validation + rm -rf "$GNUPGHOME"; unset GNUPGHOME else - echo "failed importing GPG public key, cannot perform signature validation." + echo "failed downloading GPG public key, cannot perform signature validation." fi - # clean up temporary directory used for signature validation - rm -rf "$GNUPGHOME"; unset GNUPGHOME - else - echo "failed downloading GPG public key, cannot perform signature validation." fi - fi - # try checksum validation - if [ "$CHECKSUM_VERIFY" = "1" ]; then - local UPDATER_CHECKSUMFILE="$UPDATER_TEMPDIR/updater.checksum" - # try downloading checksum file - if curl -sSL "$UPDATER_CHECKSUMURL" -o "$UPDATER_CHECKSUMFILE"; then - # have to be in same directory as archive - pushd "$UPDATER_TEMPDIR" - if ! sha256sum --quiet --ignore-missing -c "$UPDATER_CHECKSUMFILE"; then - echo "failed to verify checksum of updater archive." + # try checksum validation + if [ "$CHECKSUM_VERIFY" = "1" ]; then + local UPDATER_CHECKSUMFILE="$UPDATER_TEMPDIR/updater.checksum" + # try downloading checksum file + if curl -sSL "$UPDATER_CHECKSUMURL" -o "$UPDATER_CHECKSUMFILE"; then + # have to be in same directory as archive + pushd "$UPDATER_TEMPDIR" + if ! sha256sum --quiet --ignore-missing -c "$UPDATER_CHECKSUMFILE"; then + echo "failed to verify checksum of updater archive." + popd + exit 1 + fi popd - exit 1 + else + echo "failed downloading checksum file, cannot perform checksum validation." fi - popd - else - echo "failed downloading checksum file, cannot perform checksum validation." fi fi