[pacman-dev] [PATCH 2/3] makepkg: command line options for signing packages

Denis A. Altoé Falqueto denisfalqueto at gmail.com
Mon Feb 21 21:33:35 EST 2011


Three new command line options were added:

-n, --sign: forces the generation of a signature for
the resulting package, even if not configured in makepkg.conf.
The command line has precedence over the option in
makepkg.conf. So, even if makepkg.conf has !sign in
BUILDENV, passing --sign to makepkg will make it
sign the package.

--nosign: doesn't sign the resulting package, even
if option sign is present in $BUILDENV

--signwithkey <key>: there is a possibility of another key
being used, instead of the user's default. For exemple,
pacman-keyring package could be signed by a master key,
because it needs to be trusted explicitly by the user
before the installation of that package. So, this parameter
will be used to supply an id for a key to be used to sign
the package.

The verification of validity of key is made just after
check_sanity, because if there is a problem, the script
will die as soon as possible.

Signed-off-by: Denis A. Altoé Falqueto <denisfalqueto at gmail.com>
---
 scripts/makepkg.sh.in |   56 ++++++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 51 insertions(+), 5 deletions(-)

diff --git a/scripts/makepkg.sh.in b/scripts/makepkg.sh.in
index 8381a78..c7612cd 100644
--- a/scripts/makepkg.sh.in
+++ b/scripts/makepkg.sh.in
@@ -28,7 +28,7 @@
 # makepkg uses quite a few external programs during its execution. You
 # need to have at least the following installed for makepkg to function:
 #   awk, bsdtar (libarchive), bzip2, coreutils, fakeroot, file, find (findutils),
-#   gettext, grep, gzip, openssl, sed, tput (ncurses), xz
+#   gettext, gpg, grep, gzip, openssl, sed, tput (ncurses), xz
 
 # gettext initialization
 export TEXTDOMAIN='pacman'
@@ -74,6 +74,8 @@ BUILDFUNC=0
 CHECKFUNC=0
 PKGFUNC=0
 SPLITPKG=0
+RUN_SIGN='?'
+SIGNKEY=""
 PKGLIST=()
 
 # Forces the pkgver of the current PKGBUILD. Used by the fakeroot call
@@ -280,6 +282,23 @@ check_buildenv() {
 
 
 ##
+# Check if a signature must be made.
+#
+#  usage : must_sign
+# return : y - must sign
+#          n - must not
+##
+must_sign() {
+	if [[ $RUN_SIGN = 'n' || ( $RUN_SIGN != 'y' && $(check_buildenv sign) != 'y' ) ]]; then
+		echo 'n'
+		return
+	fi
+
+	echo 'y'
+}
+
+
+##
 #  usage : in_opt_array( $needle, $haystack )
 # return : y - enabled
 #          n - disabled
@@ -1106,7 +1125,7 @@ create_package() {
 }
 
 create_signature() {
-	if [[ $(check_buildenv sign) != "y" ]]; then
+	if [[ $(must_sign) = 'n' ]]; then
 		return
 	fi
 	local ret=0
@@ -1116,7 +1135,14 @@ create_signature() {
 		error "$(gettext "Cannot find the gpg binary! Is gnupg installed?")"
 		exit 1 # $E_MISSING_PROGRAM
 	fi
-	gpg --detach-sign --use-agent "$filename" || ret=$?
+
+	# Check if SIGNKEY is valid.
+	local SIGNWITHKEY=""
+	if [[ "${SIGNKEY}" ]]; then
+		SIGNWITHKEY="-u ${SIGNKEY}"
+	fi
+	# The signature will be generated directly in ascii-friendly format
+	gpg --detach-sign --use-agent ${SIGNWITHKEY} "$filename" &>/dev/null || ret=$?
 	if (( ! ret )); then
 		msg2 "$(gettext "Created signature file %s.")" "$filename.sig"
 	else
@@ -1614,6 +1640,10 @@ usage() {
 	echo "$(gettext "  --pkg <list>     Only build listed packages from a split package")"
 	echo "$(gettext "  --skipinteg      Do not fail when integrity checks are missing")"
 	echo "$(gettext "  --source         Generate a source-only tarball without downloaded sources")"
+	echo "$(gettext "  -n, --sign       Sign the resulting package with gpg")"
+	echo "$(gettext "  --nosign         Do not sign the package")"
+	printf "$(gettext "  --signwithkey <key>\n\
+                   Selects an specific key to use for signing, instead of user's default")"
 	echo
 	echo "$(gettext "These options can be passed to pacman:")"
 	echo
@@ -1645,11 +1675,12 @@ fi
 ARGLIST=("$@")
 
 # Parse Command Line Options.
-OPT_SHORT="AcCdefFghiLmop:rRsV"
+OPT_SHORT="AcCdefFghiLmnop:rRsV"
 OPT_LONG="allsource,asroot,ignorearch,check,clean,cleancache,nodeps"
 OPT_LONG+=",noextract,force,forcever:,geninteg,help,holdver"
 OPT_LONG+=",install,log,nocolor,nobuild,nocheck,pkg:,rmdeps"
-OPT_LONG+=",repackage,skipinteg,source,syncdeps,version,config:"
+OPT_LONG+=",repackage,sign,nosign,signwithkey:,skipinteg,"
+OPT_LONG+="source,syncdeps,version,config:"
 # Pacman Options
 OPT_LONG+=",noconfirm,noprogressbar"
 OPT_TEMP="$(parse_options $OPT_SHORT $OPT_LONG "$@" || echo 'PARSE_OPTIONS FAILED')"
@@ -1693,6 +1724,9 @@ while true; do
 		-R|--repackage)   REPKG=1 ;;
 		--skipinteg)      SKIPINTEG=1 ;;
 		--source)         SOURCEONLY=1 ;;
+		--sign)           RUN_SIGN='y' ;;
+		--nosign)         RUN_SIGN='n' ;;
+		--signwithkey)    shift; SIGNKEY=$1 ;;
 		-s|--syncdeps)    DEP_BIN=1 ;;
 
 		-h|--help)        usage; exit 0 ;; # E_OK
@@ -1889,6 +1923,18 @@ epoch=${epoch:-0}
 # check the PKGBUILD for some basic requirements
 check_sanity || exit 1
 
+# If the package must be signed, verify if the key is valid
+if [[ $(must_sign) = 'y' ]]; then
+	if ! gpg --list-key "${SIGNKEY}" &>/dev/null; then
+		if [[ ! -z $SIGNKEY ]]; then
+			error "$(gettext "The key ${SIGNKEY} doesn\'t exist in your keyring.")"
+		else
+			error "$(gettext "There is no key in your keyring.")"
+		fi
+		exit 1
+	fi
+fi
+
 # We need to run devel_update regardless of whether we are in the fakeroot
 # build process so that if the user runs makepkg --forcever manually, we
 # 1) output the correct pkgver, and 2) use the correct filename when
-- 
1.7.4.1



More information about the pacman-dev mailing list