This is an automated email from the ASF dual-hosted git repository. chtompki pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/commons-release-plugin.git
commit 695a4e175dc5e025a993421d89395a317d24a346 Author: Rob Tompkins <chtom...@apache.org> AuthorDate: Fri Oct 2 11:29:52 2020 -0400 COMMONSSITE-138: create signature validation script for releases --- src/changes/changes.xml | 1 + src/main/resources/signature-validator.sh | 144 ++++++++++++++++++++++++++++++ 2 files changed, 145 insertions(+) diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 173642d..1511b34 100755 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -26,6 +26,7 @@ <body> <release version="1.8" date="2020-MM-DD" description="Version 1.8"> + <action issue="COMMONSSITE-138" type="add" dev="chtompki">Create signature validation script for releases</action> <action type="update" dev="kinow">Bump actions/setup-java from v1.4.0 to v1.4.3 #11 #19.</action> <action type="update" dev="kinow">Bump spotbugs from 4.1.1 to 4.1.3 #10 #20.</action> <action type="update" dev="sebb">Fail if commons.nexus.repo.id is not defined.</action> diff --git a/src/main/resources/signature-validator.sh b/src/main/resources/signature-validator.sh new file mode 100644 index 0000000..8a5421a --- /dev/null +++ b/src/main/resources/signature-validator.sh @@ -0,0 +1,144 @@ +#!/bin/bash +########### +# +# This script is to be placed in the root of the svn dist checkout. +# For example, my directory looks like: +# +# drwxr-xr-x@ 8 usr staff 256 Oct 1 11:22 .svn +# -rw-r--r--@ 1 usr staff 1230 Oct 1 11:22 HEADER.html +# -rw-r--r--@ 1 usr staff 2649 Oct 1 11:22 README.html +# -rw-r--r--@ 1 usr staff 5093 Oct 1 11:22 RELEASE-NOTES.txt +# drwxr-xr-x@ 10 usr staff 320 Oct 1 11:22 binaries +# -rw-r--r--@ 1 usr staff 3900 Oct 1 13:40 signature-validation.sh +# drwxr-xr-x@ 44 usr staff 1408 Oct 1 11:22 site +# drwxr-xr-x@ 10 usr staff 320 Oct 1 11:37 source +# +# From here you run ./signature-validation.sh and it will create a directory "artifacts-for-validation-deletable-post-validation +# in which all of the binaries generated by a release are copied and then it checks to see that all of the signatures and hashes +# are infact correct for the artifacts. +# +########### + +if test "$#" != "1" +then + echo "ERROR:" + echo "We expect the a url like https://repository.apache.org/content/repositories/orgapachecommons-1531/commons-net/commons-net/3.7.1/" + echo "to be passed in as a parameter to the script." +fi + + + +BASEDIR="$( cd "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )" +VALIDATION_DIR=${BASEDIR}/artifacts-for-validation-deletable-post-validation +BINARIES_DIR=${BASEDIR}/binaries +SOURCE_DIR=${BASEDIR}/source + +BASE_NEXUS_URL="$1" + +function clean_and_build_validation_dir() { + mkdir -p ${VALIDATION_DIR} +} + +function copy_in_checked_out_artifacts() { + cp ${BASEDIR}/binaries/commons* ${VALIDATION_DIR} + cp ${BASEDIR}/source/commons* ${VALIDATION_DIR} +} + +function download_nexus_artifacts_to_validation_directory() { + # Curls html page and does text modification to put artifacts in semicolon delimited list + # ...(ugly but works, debug by removing pipes one at a time) + echo "INFO: Downloading artifacts from nexus" + NEXUS_ARTIFACTS=$(curl ${BASE_NEXUS_URL} \ + | grep "${BASE_NEXUS_URL}" \ + | cut -d '>' -f3 \ + | sed "s|</a|;|g" \ + | sed ':a;N;$!ba;s/\n/ /g' \ + | sed 's/ //g' + ) + + IFS=';' read -r -a array <<< "${NEXUS_ARTIFACTS}" + + for element in "${array[@]}" + do + ARTIFACT_NAME=$(echo $element | cut -d '/' -f7) + echo $ARTIFACT_NAME + URL="${BASE_NEXUS_URL}${element}" + curl $URL -o ${VALIDATION_DIR}/$ARTIFACT_NAME + done +} + +function validate_signatures() { + echo "INFO: Validating Signatures in ${VALIDATION_DIR}" + ALL_ARTIFACTS=$(ls -Al ${VALIDATION_DIR} \ + | awk -F':[0-9]* ' '/:/{print $2}' \ + | sed ':a;N;$!ba;s/\n/;/g' + ) + + ARTIFACTS_FOR_VALIDATION=() + + IFS=';' read -r -a array <<< "${ALL_ARTIFACTS}" + + for element in "${array[@]}" + do + if [[ ! (${element} =~ ^.*asc$ || ${element} =~ ^.*sha512$ || ${element} =~ ^.*md5$ || ${element} =~ ^.*sha1$) ]]; + then + ARTIFACTS_FOR_VALIDATION=("${ARTIFACTS_FOR_VALIDATION[@]}" $element) + fi + done + + for element in "${ARTIFACTS_FOR_VALIDATION[@]}" + do + if [[ ${element} =~ ^.*tar.gz.*$ || ${element} =~ ^.*zip.*$ ]]; + then + ARTIFACT_SHA512=$(openssl sha512 ${VALIDATION_DIR}/$element | cut -d '=' -f2 | cut -d ' ' -f2) + FILE_SHA512=$(cut -d$'\r' -f1 ${VALIDATION_DIR}/$element.sha512) + if test "${ARTIFACT_SHA512}" != "${FILE_SHA512}" + then + echo "$element failed sha512 check" + echo "==${ARTIFACT_SHA512}==" + echo "==${FILE_SHA512}==" + exit 1; + fi + else + ARTIFACT_MD5=$(openssl md5 ${VALIDATION_DIR}/$element | cut -d '=' -f2 | cut -d ' ' -f2) + FILE_MD5=$(cut -d$'\r' -f1 ${VALIDATION_DIR}/$element.md5) + ARTIFACT_SHA1=$(openssl sha1 ${VALIDATION_DIR}/$element | cut -d '=' -f2 | cut -d ' ' -f2) + FILE_SHA1=$(cut -d$'\r' -f1 ${VALIDATION_DIR}/$element.sha1) + if test "${ARTIFACT_MD5}" != "${FILE_MD5}" + then + echo "$element failed md5 check" + echo "==${ARTIFACT_MD5}==" + echo "==${FILE_MD5}==" + exit 1; + fi + if test "${ARTIFACT_SHA1}" != "${FILE_SHA1}" + then + echo "$element failed sha1 check" + echo "==${ARTIFACT_SHA1}==" + echo "==${FILE_SHA1}==" + exit 1; + fi + + + gpg --verify ${VALIDATION_DIR}/$element.asc ${VALIDATION_DIR}/$element > /dev/null 2>&1 + if test "$?" != "0" + then + echo "$element failed gpg signature check" + exit 1; + fi + fi + done + + echo "SUCCESSFUL VALIDATION" +} + +function clean_up_afterwards() { + rm -rf ${VALIDATION_DIR} +} + + +echo $(clean_and_build_validation_dir) +echo $(copy_in_checked_out_artifacts) +echo $(download_nexus_artifacts_to_validation_directory) +echo $(validate_signatures) +#clean_up_afterwards \ No newline at end of file