diff --git a/images/linux/scripts/helpers/install.sh b/images/linux/scripts/helpers/install.sh index b90d1007..56356ebc 100644 --- a/images/linux/scripts/helpers/install.sh +++ b/images/linux/scripts/helpers/install.sh @@ -152,6 +152,42 @@ get_github_package_hash() { echo "$result" } +get_hash_from_remote_file() { + local url=$1 + local keywords=("$2" "$3") + local delimiter=${4:-' '} + local word_number=${5:-1} + + if [[ -z "${keywords[0]}" || -z "$url" ]]; then + echo "File name and/or URL is not specified." + exit 1 + fi + + matching_line=$(curl -fsSL "$url" | tr -d '`') + for keyword in "${keywords[@]}"; do + matching_line=$(echo "$matching_line" | grep "$keyword") + done + + if [[ "$(echo "$matching_line" | wc -l)" -gt 1 ]]; then + echo "Multiple lines found including the words: ${keywords[*]}. Please use a more specific filter." + exit 1 + fi + + if [[ -z "$matching_line" ]]; then + echo "Keywords (${keywords[*]}) not found in the file with hashes." + exit 1 + fi + + result=$(echo "$matching_line" | cut -d "$delimiter" -f "$word_number" | tr -d -c '[:alnum:]') + if [[ ${#result} -ne 64 && ${#result} -ne 128 ]]; then + echo "Invalid result length. Expected 64 or 128 characters. Please check delimiter and/or word_number parameters." + echo "Result: $result" + exit 1 + fi + + echo "$result" +} + use_checksum_comparison() { local file_path=$1 local checksum=$2 diff --git a/images/linux/scripts/installers/aliyun-cli.sh b/images/linux/scripts/installers/aliyun-cli.sh index 756b86d3..d5495085 100644 --- a/images/linux/scripts/installers/aliyun-cli.sh +++ b/images/linux/scripts/installers/aliyun-cli.sh @@ -2,6 +2,7 @@ ################################################################################ ## File: aliyun-cli.sh ## Desc: Installs Alibaba Cloud CLI +## Supply chain security: Alibaba Cloud CLI - checksum validation ################################################################################ # Source the helpers for use with the script @@ -11,14 +12,22 @@ source $HELPER_SCRIPTS/install.sh # Install Alibaba Cloud CLI # Pin tool version on ubuntu20 due to issues with GLIBC_2.32 not available if isUbuntu20; then - toolsetVersion=$(get_toolset_value '.aliyunCli.version') - downloadUrl="https://github.com/aliyun/aliyun-cli/releases/download/v$toolsetVersion/aliyun-cli-linux-$toolsetVersion-amd64.tgz" + toolset_version=$(get_toolset_value '.aliyunCli.version') + download_url="https://github.com/aliyun/aliyun-cli/releases/download/v$toolset_version/aliyun-cli-linux-$toolset_version-amd64.tgz" + hash_url="https://github.com/aliyun/aliyun-cli/releases/download/v$toolset_version/SHASUMS256.txt" else - downloadUrl="https://aliyuncli.alicdn.com/aliyun-cli-linux-latest-amd64.tgz" + download_url=$(get_github_package_download_url "aliyun/aliyun-cli" "contains(\"aliyun-cli-linux\") and endswith(\"amd64.tgz\")") + hash_url="https://github.com/aliyun/aliyun-cli/releases/latest/download/SHASUMS256.txt" fi -download_with_retries $downloadUrl "/tmp" -tar xzf /tmp/aliyun-cli-linux-*-amd64.tgz +package_name="aliyun-cli-linux-amd64.tgz" +download_with_retries "$download_url" "/tmp" "$package_name" + +# Supply chain security - Alibaba Cloud CLI +external_hash=$(get_hash_from_remote_file "$hash_url" "aliyun-cli-linux" "amd64.tgz") +use_checksum_comparison "/tmp/$package_name" "$external_hash" + +tar xzf "/tmp/$package_name" mv aliyun /usr/local/bin invoke_tests "CLI.Tools" "Aliyun CLI" diff --git a/images/linux/scripts/installers/cmake.sh b/images/linux/scripts/installers/cmake.sh index 4bf5ca81..588f9295 100644 --- a/images/linux/scripts/installers/cmake.sh +++ b/images/linux/scripts/installers/cmake.sh @@ -2,6 +2,7 @@ ################################################################################ ## File: cmake.sh ## Desc: Installs CMake +## Supply chain security: CMake - checksum validation ################################################################################ # Source the helpers for use with the script @@ -12,9 +13,15 @@ echo "Checking to see if the installer script has already been run" if command -v cmake; then echo "cmake is already installed" else - downloadUrl=$(get_github_package_download_url "Kitware/CMake" "endswith(\"inux-x86_64.sh\")") - curl -fsSL ${downloadUrl} -o cmakeinstall.sh \ - && chmod +x cmakeinstall.sh \ + # Download script to install CMake + download_url=$(get_github_package_download_url "Kitware/CMake" "endswith(\"inux-x86_64.sh\")") + curl -fsSL "${download_url}" -o cmakeinstall.sh + # Supply chain security - CMake + hash_url=$(get_github_package_download_url "Kitware/CMake" "endswith(\"SHA-256.txt\")") + external_hash=$(get_hash_from_remote_file "$hash_url" "linux-x86_64.sh") + use_checksum_comparison "cmakeinstall.sh" "$external_hash" + # Install CMake and remove the install script + chmod +x cmakeinstall.sh \ && ./cmakeinstall.sh --prefix=/usr/local --exclude-subdir \ && rm cmakeinstall.sh fi diff --git a/images/linux/scripts/installers/docker.sh b/images/linux/scripts/installers/docker.sh index 00370d15..4c8b2c15 100644 --- a/images/linux/scripts/installers/docker.sh +++ b/images/linux/scripts/installers/docker.sh @@ -2,6 +2,7 @@ ################################################################################ ## File: docker.sh ## Desc: Installs docker onto the image +## Supply chain security: Docker Compose v2 - checksum validation ################################################################################ # Source the helpers for use with the script @@ -19,8 +20,13 @@ apt-get install --no-install-recommends docker-ce docker-ce-cli containerd.io do # Install docker compose v2 from releases URL=$(get_github_package_download_url "docker/compose" "contains(\"compose-linux-x86_64\")") -curl -fsSL $URL -o /usr/libexec/docker/cli-plugins/docker-compose -chmod +x /usr/libexec/docker/cli-plugins/docker-compose +curl -fsSL "${URL}" -o /tmp/docker-compose +# Supply chain security - CMake +hash_url=$(get_github_package_download_url "docker/compose" "contains(\"checksums.txt\")") +external_hash=$(get_hash_from_remote_file "$hash_url" "compose-linux-x86_64") +use_checksum_comparison "/tmp/docker-compose" "$external_hash" +install /tmp/docker-compose /usr/libexec/docker/cli-plugins/docker-compose + # docker from official repo introduced different GID generation: https://github.com/actions/runner-images/issues/8157 gid=$(cut -d ":" -f 3 /etc/group | grep "^1..$" | sort -n | tail -n 1 | awk '{ print $1+1 }')