From 6ec20fb23ac82946e983af29c6805202b2b68ead Mon Sep 17 00:00:00 2001 From: Sergey Otpuschennikov Date: Mon, 20 Jun 2016 13:40:35 +0300 Subject: [PATCH] Implement Sigul for signing packages Signing rpm packages Signing deb packages Signing metadata of repositories Related Jira-ticket: https://mirantis.jira.com/browse/PROD-3854 Change-Id: I31cfe16bab67c003fa8687ac33a7fc6cc420cdf6 --- .../functions/publish-functions.sh | 55 +++++++++++++++++++ .../publisher.v5/publish-deb-binaries.sh | 22 ++++++-- .../publisher.v5/publish-rpm-binaries.sh | 36 +++++++++--- 3 files changed, 101 insertions(+), 12 deletions(-) diff --git a/perestroika/publisher.v5/functions/publish-functions.sh b/perestroika/publisher.v5/functions/publish-functions.sh index df4dc37..9fbbbfe 100644 --- a/perestroika/publisher.v5/functions/publish-functions.sh +++ b/perestroika/publisher.v5/functions/publish-functions.sh @@ -19,6 +19,12 @@ info () { echo } +_sigul () { + local PASSWD=$1 + shift + printf '%s\0' "$PASSWD" | sigul --batch $@ +} + check-gpg() { local RESULT=0 [ -z "$SIGKEYID" ] && echo "WARNING: No secret keys given" && RESULT=1 @@ -33,6 +39,55 @@ check-gpg() { return $RESULT } +check-sigul() { + local SIGKEYID=$1 + local SIGUL_USER=$2 + local SIGUL_ADMIN_PASSWD=$3 + local RESULT=0 + # Test of secret key and definiton of sigul + [ -z "$SIGKEYID" ] && echo "WARNING: No secret keys given" && RESULT=1 + [ -z "$SIGUL_USER" ] && echo "WARNING: No Sigul user given" && RESULT=1 + [ -z "$SIGUL_ADMIN_PASSWD" ] && echo "WARNING: No Sigul Administration's password given" && RESULT=1 + [ -z "$(which sigul)" ] && echo "WARNING: Sigul is not found" && RESULT=1 + # Test of sigul or secret key availability + if [ $RESULT -eq 0 ] ; then + retry -c4 -s1 _sigul "$SIGUL_ADMIN_PASSWD" -u "$SIGUL_USER" list-keys > keys_list.tmp + [ $? -ne 0 ] && echo "WARNING: Something went wrong" && RESULT=1 + fi + [ $RESULT -eq 0 ] && [ $(grep -c "$SIGKEYID" keys_list.tmp) -ne 1 ] && RESULT=1 + [ $RESULT -ne 0 ] && echo "WARNING:No secret keys found or Sigul is unavailable. Fall back to local signed" + return $RESULT +} + +retry() { + local count=3 + local sleep=5 + local optname + while getopts 'c:s:' optname + do + case $optname in + c) count=$OPTARG ;; + s) sleep=$OPTARG ;; + ?) return 1 ;; + esac + done + shift $((OPTIND - 1)) + local ec + while true + do + "$@" && true + ec=$? + (( count-- )) + if [[ $ec -eq 0 || $count -eq 0 ]] + then + break + else + sleep "$sleep" + fi + done + return "$ec" +} + sync-repo() { local LOCAL_DIR=$1 local REMOTE_DIR=$2 diff --git a/perestroika/publisher.v5/publish-deb-binaries.sh b/perestroika/publisher.v5/publish-deb-binaries.sh index dc0a4a0..678d50e 100755 --- a/perestroika/publisher.v5/publish-deb-binaries.sh +++ b/perestroika/publisher.v5/publish-deb-binaries.sh @@ -6,7 +6,12 @@ source $(dirname $(readlink -e $0))/functions/locking.sh main() { local SIGN_STRING="" - check-gpg && SIGN_STRING="true" + if check-sigul "$SIGKEYID" "$SIGUL_USER" "$SIGUL_ADMIN_PASSWD" ; then + USE_SIGUL="true" + SIGN_STRING="true" + else + check-gpg && SIGN_STRING="true" + fi ## Download sources from worker [ -d $TMP_DIR ] && rm -rf $TMP_DIR @@ -76,9 +81,13 @@ main() { -i ${release_file} rm -f ${release_file}.gpg # ReSign Release file - [ -n "${SIGN_STRING}" ] \ + if [ "${USE_SIGUL}" = "true" ] ; then + retry -c4 -s1 _sigul "$KEY_PASSPHRASE" -u "$SIGUL_USER" sign-data --armor -o "${release_file}.gpg" "${SIGKEYID}" "${release_file}" + else + [ -n "${SIGN_STRING}" ] \ && gpg --sign --local-user ${SIGKEYID} -ba \ -o ${release_file}.gpg ${release_file} + fi done job_lock ${CONFIGDIR}.lock unset fi @@ -183,9 +192,14 @@ main() { rm -f ${release_file}.gpg local pub_key_file="${LOCAL_REPO_PATH}/public/archive-${PROJECT_NAME}${PROJECT_VERSION}.key" if [ -n "${SIGN_STRING}" ] ; then - gpg --sign --local-user ${SIGKEYID} -ba -o ${release_file}.gpg ${release_file} [ ! -f "${pub_key_file}" ] && touch ${pub_key_file} - gpg -o ${pub_key_file}.tmp --armor --export ${SIGKEYID} + if [ "${USE_SIGUL}" = "true" ] ; then + retry -c4 -s1 _sigul "$KEY_PASSPHRASE" -u "$SIGUL_USER" sign-data --armor -o "${release_file}.gpg" "${SIGKEYID}" "${release_file}" + retry -c4 -s1 _sigul "$KEY_PASSPHRASE" -u "$SIGUL_ADMIN" get-public-key "${SIGKEYID}" > "${pub_key_file}.tmp" + else + gpg --sign --local-user ${SIGKEYID} -ba -o ${release_file}.gpg ${release_file} + gpg -o ${pub_key_file}.tmp --armor --export ${SIGKEYID} + fi if diff -q ${pub_key_file} ${pub_key_file}.tmp &>/dev/null ; then rm ${pub_key_file}.tmp else diff --git a/perestroika/publisher.v5/publish-rpm-binaries.sh b/perestroika/publisher.v5/publish-rpm-binaries.sh index b80d422..0d63820 100755 --- a/perestroika/publisher.v5/publish-rpm-binaries.sh +++ b/perestroika/publisher.v5/publish-rpm-binaries.sh @@ -8,10 +8,18 @@ source $(dirname $(readlink -e $0))/functions/locking.sh main() { if [ -n "${SIGKEYID}" ] ; then - check-gpg || : - gpg --export -a ${SIGKEYID} > RPM-GPG-KEY - if [ $(rpm -qa | grep gpg-pubkey | grep -ci ${SIGKEYID}) -eq 0 ]; then - rpm --import RPM-GPG-KEY + # Is sigul availble and signed key exist + [ -n "${SIGUL_USER}" ] && check-sigul "$SIGKEYID" "$SIGUL_USER" "$SIGUL_ADMIN_PASSWD" && USE_SIGUL=true + if [ "${USE_SIGUL}" = "true" ] ; then + # Use sigul for sign + retry -c4 -s1 _sigul "$SIGUL_ADMIN_PASSWD" -u "$SIGUL_ADMIN" get-public-key "$SIGKEYID" > RPM-GPG-KEY + else + # Use local sign + check-gpg || : + gpg --export -a ${SIGKEYID} > RPM-GPG-KEY + if [ $(rpm -qa | grep gpg-pubkey | grep -ci ${SIGKEYID}) -eq 0 ]; then + rpm --import RPM-GPG-KEY + fi fi fi @@ -183,7 +191,12 @@ main() { ## if [ -n "${SIGKEYID}" ] ; then # rpmsign requires pass phrase. use `expect` to skip it - LANG=C expect <