Many projects provide signature files along with the source code archives. It's good to check these, too, when verifying the integrity of source code archives. Not everybody is using gpg so the verification can be disabled with --skippgpcheck. Additionally, only a warning is displayed when the key that signed the source file is unknown. Expired keys and signatures aren't considered an error, too. --- doc/makepkg.8.txt | 3 ++ scripts/makepkg.sh.in | 72 ++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 74 insertions(+), 1 deletions(-) diff --git a/doc/makepkg.8.txt b/doc/makepkg.8.txt index e11e9b3..255fbca 100644 --- a/doc/makepkg.8.txt +++ b/doc/makepkg.8.txt @@ -169,6 +169,9 @@ Options in linkman:makepkg.conf[5]. If not specified in either location, the default key from the keyring will be used. +*\--skippgpcheck*:: + Verify PGP signatures of the source files if provided in the build script. + *\--noconfirm*:: (Passed to pacman) Prevent pacman from waiting for user input before proceeding with operations. diff --git a/scripts/makepkg.sh.in b/scripts/makepkg.sh.in index 1b132a9..0b7bed6 100644 --- a/scripts/makepkg.sh.in +++ b/scripts/makepkg.sh.in @@ -57,6 +57,7 @@ FORCE=0 INFAKEROOT=0 GENINTEG=0 SKIPINTEG=0 +NOPGPSIGS=0 INSTALL=0 NOBUILD=0 NODEPS=0 @@ -674,6 +675,63 @@ check_checksums() { fi } +check_pgpsigs() { + (( NOPGPSIGS )) && return 0 + (( ! ${#source[@]} )) && return 0 + + msg "$(gettext "Verifying source file signatures with gpg...")" + + local file + local errors=0 + local statusfile=$(mktemp) + + for file in "${source[@]}"; do + local valid + local found=1 + + file="$(get_filename "$file")" + if [[ $file =~ .*(sig|asc) ]]; then + echo -n " $file ... " >&2 + + if ! file="$(get_filepath "$file")"; then + echo "$(gettext "NOT FOUND")" >&2 + errors=1 + found=0 + fi + + if (( found )); then + if ! gpg --quiet --batch --status-file "$statusfile" --verify "$file" 2> /dev/null; then + if grep "NO_PUBKEY" "$statusfile" > /dev/null; then + echo "" >&2 + warning "$(gettext "Unknown public key") $(awk '/NO_PUBKEY/ {print $3}' $statusfile)" >&2 + else + echo "$(gettext "Verification failed")" >&2 + errors=1 + fi + else + if grep "REVKEYSIG" "$statusfile" > /dev/null; then + errors=1 + echo "$(gettext "Verified, but the key that signed it has been revoked.")" >&2 + elif grep "EXPSIG" "$statusfile" > /dev/null; then + echo "$(gettext "Verified, but the signature is expired.")" >&2 + elif grep "EXPKEYSIG" "$statusfile" > /dev/null; then + echo "$(gettext "Verified, but the key that signed it is expired.")" >&2 + else + echo $(gettext "Verified") >&2 + fi + fi + fi + fi + done + + rm -f "$statusfile" + + if (( errors )); then + error "$(gettext "One or more PGP signatures could not be verified!")" + exit 1 + fi +} + extract_sources() { msg "$(gettext "Extracting Sources...")" local netfile @@ -1478,6 +1536,14 @@ check_software() { fi fi + # gpg - source verification + if [[ ! NOPGPSIGS ]]; then + if ! type -p gpg >/dev/null; then + error "$(gettext "Cannot find the %s binary required for verifying source files.")" "gpg" + ret=1 + fi + fi + # openssl - checksum operations if (( ! SKIPINTEG )); then if ! type -p openssl >/dev/null; then @@ -1712,6 +1778,7 @@ usage() { printf "$(gettext " --key <key> Specify a key to use for %s signing instead of the default")\n" "gpg" printf "$(gettext " --nocheck Do not run the %s function in the %s")\n" "check()" "$BUILDSCRIPT" echo "$(gettext " --nosign Do not create a signature for the package")" + echo "$(gettext " --skippgpcheck Disable verification of source files with pgp signatures")" echo "$(gettext " --pkg <list> Only build listed packages from a split package")" printf "$(gettext " --sign Sign the resulting package with %s")\n" "gpg" echo "$(gettext " --skipinteg Do not fail when integrity checks are missing")" @@ -1749,7 +1816,7 @@ ARGLIST=("$@") # Parse Command Line Options. OPT_SHORT="AcCdefFghiLmop:rRsV" OPT_LONG="allsource,asroot,ignorearch,check,clean,nodeps" -OPT_LONG+=",noextract,force,forcever:,geninteg,help,holdver" +OPT_LONG+=",noextract,force,forcever:,geninteg,help,holdver,skippgpcheck" OPT_LONG+=",install,key:,log,nocolor,nobuild,nocheck,nosign,pkg:,rmdeps" OPT_LONG+=",repackage,skipinteg,sign,source,syncdeps,version,config:" # Pacman Options @@ -1791,6 +1858,7 @@ while true; do --nosign) SIGNPKG='n' ;; -o|--nobuild) NOBUILD=1 ;; -p) shift; BUILDFILE=$1 ;; + --skippgpcheck) NOPGPSIGS=1;; --pkg) shift; PKGLIST=($1) ;; -r|--rmdeps) RMDEPS=1 ;; -R|--repackage) REPKG=1 ;; @@ -2122,6 +2190,7 @@ if (( SOURCEONLY )); then if (( ! SKIPINTEG )); then # We can only check checksums if we have all files. check_checksums + check_pgpsigs else warning "$(gettext "Skipping integrity checks.")" fi @@ -2200,6 +2269,7 @@ else download_sources if (( ! SKIPINTEG )); then check_checksums + check_pgpsigs else warning "$(gettext "Skipping integrity checks.")" fi -- 1.7.6