From 4f114f38178aeaffcc571aa42e2f930ca916f79d Mon Sep 17 00:00:00 2001 From: Ashley Whetter Date: Sun, 8 May 2016 17:28:28 +0100 Subject: libmakepkg: extract functions for integrity checking Signed-off-by: Ashley Whetter Signed-off-by: Allan McRae --- scripts/makepkg.sh.in | 428 -------------------------------------------------- 1 file changed, 428 deletions(-) (limited to 'scripts/makepkg.sh.in') diff --git a/scripts/makepkg.sh.in b/scripts/makepkg.sh.in index b87eb8a2..7b2ce511 100644 --- a/scripts/makepkg.sh.in +++ b/scripts/makepkg.sh.in @@ -204,18 +204,6 @@ missing_source_file() { exit 1 # $E_MISSING_FILE } -source_has_signatures() { - local file all_sources - - get_all_sources_for_arch 'all_sources' - for file in "${all_sources[@]}"; do - if [[ ${file%%::*} = *.@(sig?(n)|asc) ]]; then - return 0 - fi - done - return 1 -} - run_pacman() { local cmd if [[ $1 != -@(T|Qq) ]]; then @@ -332,399 +320,6 @@ remove_deps() { fi } -get_integlist() { - local integ - local integlist=() - - for integ in "${known_hash_algos[@]}"; do - local sumname="${integ}sums[@]" - if [[ -n ${!sumname} ]]; then - integlist+=("$integ") - fi - done - - if (( ${#integlist[@]} > 0 )); then - printf "%s\n" "${integlist[@]}" - else - printf "%s\n" "${INTEGRITY_CHECK[@]}" - fi -} - -generate_one_checksum() { - local integ=$1 arch=$2 sources numsrc indentsz idx - - if [[ $arch ]]; then - array_build sources "source_$arch" - else - array_build sources 'source' - fi - - numsrc=${#sources[*]} - if (( numsrc == 0 )); then - return - fi - - if [[ $arch ]]; then - printf "%ssums_%s=(%n" "$integ" "$arch" indentsz - else - printf "%ssums=(%n" "$integ" indentsz - fi - - for (( idx = 0; idx < numsrc; ++idx )); do - local netfile=${sources[idx]} - local proto sum - proto="$(get_protocol "$netfile")" - - case $proto in - bzr*|git*|hg*|svn*) - sum="SKIP" - ;; - *) - if [[ $netfile != *.@(sig?(n)|asc) ]]; then - local file - file="$(get_filepath "$netfile")" || missing_source_file "$netfile" - sum="$(openssl dgst -${integ} "$file")" - sum=${sum##* } - else - sum="SKIP" - fi - ;; - esac - - # indent checksum on lines after the first - printf "%*s%s" $(( idx ? indentsz : 0 )) '' "'$sum'" - - # print a newline on lines before the last - (( idx < (numsrc - 1) )) && echo - done - - echo ")" -} - -generate_checksums() { - msg "$(gettext "Generating checksums for source files...")" - - if ! type -p openssl >/dev/null; then - error "$(gettext "Cannot find the %s binary required for generating sourcefile checksums.")" "openssl" - exit 1 # $E_MISSING_PROGRAM - fi - - local integlist - if (( $# == 0 )); then - IFS=$'\n' read -rd '' -a integlist < <(get_integlist) - else - integlist=("$@") - fi - - local integ - for integ in "${integlist[@]}"; do - if ! in_array "$integ" "${known_hash_algos[@]}"; then - error "$(gettext "Invalid integrity algorithm '%s' specified.")" "$integ" - exit 1 # $E_CONFIG_ERROR - fi - - generate_one_checksum "$integ" - for a in "${arch[@]}"; do - generate_one_checksum "$integ" "$a" - done - done -} - -verify_integrity_one() { - local source_name=$1 integ=$2 expectedsum=$3 - - local file="$(get_filename "$source_name")" - printf ' %s ... ' "$file" >&2 - - if [[ $expectedsum = 'SKIP' ]]; then - printf '%s\n' "$(gettext "Skipped")" >&2 - return - fi - - if ! file="$(get_filepath "$file")"; then - printf '%s\n' "$(gettext "NOT FOUND")" >&2 - return 1 - fi - - local realsum="$(openssl dgst -${integ} "$file")" - realsum="${realsum##* }" - if [[ ${expectedsum,,} = "$realsum" ]]; then - printf '%s\n' "$(gettext "Passed")" >&2 - else - printf '%s\n' "$(gettext "FAILED")" >&2 - return 1 - fi - - return 0 -} - -verify_integrity_sums() { - local integ=$1 arch=$2 integrity_sums=() sources=() srcname - - if [[ $arch ]]; then - array_build integrity_sums "${integ}sums_$arch" - srcname=source_$arch - else - array_build integrity_sums "${integ}sums" - srcname=source - fi - - array_build sources "$srcname" - if (( ${#integrity_sums[@]} == 0 && ${#sources[@]} == 0 )); then - return 1 - fi - - if (( ${#integrity_sums[@]} == ${#sources[@]} )); then - msg "$(gettext "Validating %s files with %s...")" "$srcname" "${integ}sums" - local idx errors=0 - for (( idx = 0; idx < ${#sources[*]}; idx++ )); do - verify_integrity_one "${sources[idx]}" "$integ" "${integrity_sums[idx]}" || errors=1 - done - - if (( errors )); then - error "$(gettext "One or more files did not pass the validity check!")" - exit 1 # TODO: error code - fi - elif (( ${#integrity_sums[@]} )); then - error "$(gettext "Integrity checks (%s) differ in size from the source array.")" "$integ" - exit 1 # TODO: error code - else - return 1 - fi -} - -check_checksums() { - local integ a - declare -A correlation - (( SKIPCHECKSUMS )) && return 0 - - # Initialize a map which we'll use to verify that every source array has at - # least some kind of checksum array associated with it. - (( ${#source[*]} )) && correlation['source']=1 - case $1 in - all) - for a in "${arch[@]}"; do - array_build _ source_"$a" && correlation["source_$a"]=1 - done - ;; - *) - array_build _ source_"$CARCH" && correlation["source_$CARCH"]=1 - ;; - esac - - for integ in "${known_hash_algos[@]}"; do - verify_integrity_sums "$integ" && unset "correlation[source]" - - case $1 in - all) - for a in "${arch[@]}"; do - verify_integrity_sums "$integ" "$a" && unset "correlation[source_$a]" - done - ;; - *) - verify_integrity_sums "$integ" "$CARCH" && unset "correlation[source_$CARCH]" - ;; - esac - done - - if (( ${#correlation[*]} )); then - error "$(gettext "Integrity checks are missing for: %s")" "${!correlation[*]}" - exit 1 # TODO: error code - fi -} - -parse_gpg_statusfile() { - local type arg1 arg6 arg10 - - while read -r _ type arg1 _ _ _ _ arg6 _ _ _ arg10 _; do - case "$type" in - GOODSIG) - pubkey=$arg1 - success=1 - status="good" - ;; - EXPSIG) - pubkey=$arg1 - success=1 - status="expired" - ;; - EXPKEYSIG) - pubkey=$arg1 - success=1 - status="expiredkey" - ;; - REVKEYSIG) - pubkey=$arg1 - success=0 - status="revokedkey" - ;; - BADSIG) - pubkey=$arg1 - success=0 - status="bad" - ;; - ERRSIG) - pubkey=$arg1 - success=0 - if [[ $arg6 == 9 ]]; then - status="missingkey" - else - status="error" - fi - ;; - VALIDSIG) - if [[ $arg10 ]]; then - # If the file was signed with a subkey, arg10 contains - # the fingerprint of the primary key - fingerprint=$arg10 - else - fingerprint=$arg1 - fi - ;; - TRUST_UNDEFINED|TRUST_NEVER) - trusted=0 - ;; - TRUST_MARGINAL|TRUST_FULLY|TRUST_ULTIMATE) - trusted=1 - ;; - esac - done < "$1" -} - -check_pgpsigs() { - (( SKIPPGPCHECK )) && return 0 - ! source_has_signatures && return 0 - - msg "$(gettext "Verifying source file signatures with %s...")" "gpg" - - local file ext decompress found pubkey success status fingerprint trusted - local warning=0 - local errors=0 - local statusfile=$(mktemp) - local all_sources - - case $1 in - all) - get_all_sources 'all_sources' - ;; - *) - get_all_sources_for_arch 'all_sources' - ;; - esac - for file in "${all_sources[@]}"; do - file="$(get_filename "$file")" - if [[ $file != *.@(sig?(n)|asc) ]]; then - continue - fi - - printf " %s ... " "${file%.*}" >&2 - - if ! file="$(get_filepath "$file")"; then - printf '%s\n' "$(gettext "SIGNATURE NOT FOUND")" >&2 - errors=1 - continue - fi - - found=0 - for ext in "" gz bz2 xz lrz lzo Z; do - if sourcefile="$(get_filepath "${file%.*}${ext:+.$ext}")"; then - found=1 - break; - fi - done - if (( ! found )); then - printf '%s\n' "$(gettext "SOURCE FILE NOT FOUND")" >&2 - errors=1 - continue - fi - - case "$ext" in - gz) decompress="gzip -c -d -f" ;; - bz2) decompress="bzip2 -c -d -f" ;; - xz) decompress="xz -c -d" ;; - lrz) decompress="lrzip -q -d" ;; - lzo) decompress="lzop -c -d -q" ;; - Z) decompress="uncompress -c -f" ;; - "") decompress="cat" ;; - esac - - $decompress < "$sourcefile" | gpg --quiet --batch --status-file "$statusfile" --verify "$file" - 2> /dev/null - # these variables are assigned values in parse_gpg_statusfile - success=0 - status= - pubkey= - fingerprint= - trusted= - parse_gpg_statusfile "$statusfile" - if (( ! $success )); then - printf '%s' "$(gettext "FAILED")" >&2 - case "$status" in - "missingkey") - printf ' (%s)' "$(gettext "unknown public key") $pubkey" >&2 - ;; - "revokedkey") - printf " ($(gettext "public key %s has been revoked"))" "$pubkey" >&2 - ;; - "bad") - printf ' (%s)' "$(gettext "bad signature from public key") $pubkey" >&2 - ;; - "error") - printf ' (%s)' "$(gettext "error during signature verification")" >&2 - ;; - esac - errors=1 - else - if (( ${#validpgpkeys[@]} == 0 && !trusted )); then - printf "%s ($(gettext "the public key %s is not trusted"))" $(gettext "FAILED") "$fingerprint" >&2 - errors=1 - elif (( ${#validpgpkeys[@]} > 0 )) && ! in_array "$fingerprint" "${validpgpkeys[@]}"; then - printf "%s (%s %s)" "$(gettext "FAILED")" "$(gettext "invalid public key")" "$fingerprint" - errors=1 - else - printf '%s' "$(gettext "Passed")" >&2 - case "$status" in - "expired") - printf ' (%s)' "$(gettext "WARNING:") $(gettext "the signature has expired.")" >&2 - warnings=1 - ;; - "expiredkey") - printf ' (%s)' "$(gettext "WARNING:") $(gettext "the key has expired.")" >&2 - warnings=1 - ;; - esac - fi - fi - printf '\n' >&2 - done - - rm -f "$statusfile" - - if (( errors )); then - error "$(gettext "One or more PGP signatures could not be verified!")" - exit 1 - fi - - if (( warnings )); then - warning "$(gettext "Warnings have occurred while verifying the signatures.")" - plain "$(gettext "Please make sure you really trust them.")" - fi -} - -check_source_integrity() { - if (( SKIPCHECKSUMS && SKIPPGPCHECK )); then - warning "$(gettext "Skipping all source file integrity checks.")" - elif (( SKIPCHECKSUMS )); then - warning "$(gettext "Skipping verification of source file checksums.")" - check_pgpsigs "$@" - elif (( SKIPPGPCHECK )); then - warning "$(gettext "Skipping verification of source file PGP signatures.")" - check_checksums "$@" - else - check_checksums "$@" - check_pgpsigs "$@" - fi -} - error_function() { if [[ -p $logpipe ]]; then rm "$logpipe" @@ -1192,29 +787,6 @@ create_debug_package() { create_package } -create_signature() { - if [[ $SIGNPKG != 'y' ]]; then - return - fi - local ret=0 - local filename="$1" - msg "$(gettext "Signing package...")" - - local SIGNWITHKEY="" - if [[ -n $GPGKEY ]]; then - SIGNWITHKEY="-u ${GPGKEY}" - fi - - gpg --detach-sign --use-agent ${SIGNWITHKEY} --no-armor "$filename" &>/dev/null || ret=$? - - - if (( ! ret )); then - msg2 "$(gettext "Created signature file %s.")" "$filename.sig" - else - warning "$(gettext "Failed to sign package file.")" - fi -} - create_srcpackage() { local ret=0 msg "$(gettext "Creating source package...")" -- cgit v1.2.3