#!/bin/bash # Copyright 2010-2015 Gentoo Authors; Distributed under the GPL v2 # might be earlier copyright, no history available # Keep this variable in sync in both sign-autobuilds.sh & sync-autobuilds.sh _ARCHES="alpha amd64 arm64 arm hppa ia64 loong m68k mips ppc riscv s390 sh sparc x86" #alpha amd64 arm64 arm hppa ia64 loong m68k mips ppc riscv s390 sh sparc x86 ARCHES=${ARCHES:-${_ARCHES}} RELEASES=/var/tmp/gmirror-releases/releases/ [[ $HOSTNAME == TODO ]] && RELEASES=/var/tmp/gmirror/releases/ : "${DEBUG:=}" : "${VERBOSE=}" GPG=(gpg --homedir /home/gmirror/.gnupg-releng/ --batch --no-tty) # Do not change DEBUGP= VERBOSEP=false [ -n "$DEBUG" ] && DEBUGP='echo' [ -n "$VERBOSE" ] && VERBOSEP='' [ -n "$DEBUG" ] && RSYNC_OPTS="${RSYNC_OPTS} -n" [ -n "$VERBOSE" ] && RSYNC_OPTS="${RSYNC_OPTS} -v" # needs more debugging # set -e warn() { echo "WARN: $*" 1>&2 } signone() { f="$1" $DEBUGP "${GPG[@]}" --armor --detach-sign "${f}" } signone_clearsign() { # only for text files! f="${1}" d="$(dirname "${f}")/.$(basename "${f}").asc.tmp" rm -f "${d}" # Clearsign aborts if the destfile exists $DEBUGP "${GPG[@]}" --armor --clearsign --output "$d" "${f}" $DEBUGP mv "${d}" "${f}" } cleanup() { # A sync mismatch means these seem like bad signatures due to different CDN # cache times. # [TXT] latest-install-alpha-minimal.txt 2023-10-09 03:00 116 # [TXT] latest-install-alpha-minimal.txt.asc 2023-10-09 00:21 488 # # Using a clearsign in a seperate file doesn't help here either, because it # can still be out of date compared to the underlying file. # It must be exactly 1 file, clearsigned. find autobuilds \ -type f \ -name 'latest*txt.asc' \ -exec grep -L -e '^-----BEGIN PGP SIGNED MESSAGE-----$' \{\} \+ \ | tr '\n' '\0' \ | xargs -0 --no-run-if-empty rm -f } gpgconf --kill all for a in $ARCHES ; do cd "$RELEASES/$a" >/dev/null || continue [[ -d autobuilds ]] || continue #echo "Release files:" # 2023/10/08: Unknown if the latest files are consumed by any machine-readable # process that would break if the changed into being clearsigned, so use a # detached signature for now. find_src_names=( '(' -false -or -name '*.tar.xz' -or -name '*.tar.zst' # future builds? -or -name '*.tar.zstd' # future builds? -or -name '*.iso' # iso images -or -name '*.qcow2' # disk images # hppa netboot -or -name '*.lif' # s390 netboot -or -name 'netboot*T[0-9][0-9][0-9][0-9][0-9][0-9]Z' ')' ) find_src_files_cmd=( find autobuilds -type f "${find_src_names[@]}" ) find_src_links_cmd=( find autobuilds -type l "${find_src_names[@]}" ) find_sig_names=( '(' -false -or -name '*.asc' ')' ) find_sig_files_cmd=( find autobuilds -type f "${find_sig_names[@]}" ) find_sig_links_cmd=( find autobuilds -type l "${find_sig_names[@]}" ) find_unsigned_helper_cmd=( find autobuilds -type f \( -false # Gentoo format digest files. -or -name '*.DIGESTS' # .sha256 files exist to support the OpenStack builder process -or -name '*.sha256' # marker files to declare latest builds. -or -name 'latest*txt' \) -exec grep -L -e '^-----BEGIN PGP SIGNED MESSAGE-----$' \{\} \+ ) src_files="$( "${find_src_files_cmd[@]}" )" src_links="$( "${find_src_links_cmd[@]}" )" sig_files="$( "${find_sig_files_cmd[@]}" )" sig_links="$( "${find_sig_links_cmd[@]}" )" unsigned_files="$(comm -23 <(echo "$src_files" |sort) <(echo "$sig_files" | sed -e 's,.asc$,,g' |sort))" unsigned_links="$(comm -23 <(echo "$src_links" |sort) <(echo "$sig_links" | sed -e 's,.asc$,,g' |sort))" #$VERBOSEP echo "=== ARCH: $a" for src in ${unsigned_files} ; do dgst=${src}.asc if [[ -f "${src}" ]]; then if [[ ! -e "${dgst}" ]]; then $VERBOSEP echo "Signing $src" signone "$src" fi # what if it existed but was NOT a file, this is an error if [[ -e "${dgst}" ]] && [[ ! -f "${dgst}" ]]; then warn "Unexpected link: $dgst" fi fi done for src in ${unsigned_links}; do dgst=${src}.asc if [[ -L "${src}" ]] && [[ ! -e "${dgst}" ]]; then link_rel=$(readlink "${src}") link_rel_sig=${link_rel}.asc link_abs=$(readlink -f "${src}") link_abs_sig=${link_abs}.asc if [[ -e "${link_rel_sig}" ]] || [[ -e "${link_abs_sig}" ]]; then ln -sf "${link_rel_sig}" "${dgst}" else warn "Link with no obvious signature: ${src} ; checked $link_rel_sig and $link_abs_sig" fi fi done for dgst in ${sig_files}; do src=${dgst%.asc} # If both the source & signature are files, not symlinks, and the source is # newer, then resign. Need to check both for being files, in case we are in # a symlink location. if [[ -f "${src}" ]] && [[ -f "${dgst}" ]] && [[ "${src}" -nt "${dgst}" ]]; then $VERBOSEP echo "Resigning $dgst" rm -f "${dgst}" signone "$src" fi done #echo "Text helper files:" unsigned="$( "${find_unsigned_helper_cmd[@]}" )" for src in $unsigned ; do $VERBOSEP echo "Signing (inline/cleartext) $src" signone_clearsign "$src" done cleanup done