[pacman-dev] [PATCH v2] makepkg: Add support for verifying pgp signatures

Wieland Hoffmann themineo at googlemail.com
Mon Jul 4 08:13:52 EDT 2011


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



More information about the pacman-dev mailing list