[pacman-dev] [PATCH 4/5] Parameter to select key to sign
Denis A. Altoé Falqueto
denisfalqueto at gmail.com
Mon Jul 26 16:26:04 EDT 2010
There is a possibility of another key being used, instead of
the user's default. For exemple, the pacman-keyring package
will be signed by a master key, because it needs to be trusted
explicitly by the user before the installation of that package.
So, the parameter --signwithkey will be used to supply an
id of a key that will be used to sign a database or package.
Signed-off-by: Denis A. Altoé Falqueto <denisfalqueto at gmail.com>
---
scripts/makepkg.sh.in | 38 ++++++++++++++++++++--------
scripts/repo-add.sh.in | 63 +++++++++++++++++++++++++++++++++++-------------
2 files changed, 73 insertions(+), 28 deletions(-)
diff --git a/scripts/makepkg.sh.in b/scripts/makepkg.sh.in
index 080e530..f6f9dfe 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:
# bsdtar (libarchive), bzip2, coreutils, fakeroot, find (findutils),
-# gettext, grep, gzip, openssl, sed, tput (ncurses), xz
+# gettext, grep, gzip, openssl, sed, tput (ncurses), xz, gpg
# gettext initialization
export TEXTDOMAIN='pacman'
@@ -43,6 +43,8 @@ BUILDSCRIPT='@BUILDSCRIPT@'
startdir="$PWD"
srcdir="$startdir/src"
pkgdir="$startdir/pkg"
+GPG="gpg2"
+SIG_EXT=".sig"
packaging_options=('strip' 'docs' 'libtool' 'emptydirs' 'zipman' 'purge')
other_options=('ccache' 'distcc' 'makeflags' 'force')
@@ -74,6 +76,7 @@ BUILDFUNC=0
PKGFUNC=0
SPLITPKG=0
PKGLIST=""
+SIGNKEY=""
# Forces the pkgver of the current PKGBUILD. Used by the fakeroot call
# when dealing with svn/cvs/etc PKGBUILDs.
@@ -391,8 +394,8 @@ check_deps() {
local ret=0
local pmout
pmout=$(run_pacman -T "$@") || ret=$?
- set -E
-
+ set -E
+
if (( ret == 127 )); then #unresolved deps
echo "$pmout"
elif (( ret )); then
@@ -1040,7 +1043,7 @@ create_package() {
local ret=0
[[ -f $pkg_file ]] && rm -f "$pkg_file"
- [[ -f $pkg_file.sig ]] && rm -f "$pkg_file.sig"
+ [[ -f ${pkg_file}${SIG_EXT} ]] && rm -f "${pkg_file}${SIG_EXT}"
# when fileglobbing, we want * in an empty directory to expand to
# the null string rather than itself
@@ -1067,7 +1070,7 @@ create_package() {
if (( ! ret )) && [[ "$PKGDEST" != "${startdir}" ]]; then
ln -sf "${pkg_file}" "${pkg_file/$PKGDEST/$startdir}"
ret=$?
- [[ -f $pkg_file.sig ]] && ln -sf "$pkg_file.sig" "${pkg_file/$PKGDEST/$startdir}.sig"
+ [[ -f ${pkg_file}${SIG_EXT} ]] && ln -sf "${pkg_file}${SIG_EXT}" "${pkg_file/$PKGDEST/$startdir}${SIG_EXT}"
fi
if (( ret )); then
@@ -1082,13 +1085,24 @@ create_signature() {
local ret=0
local filename="$1"
msg "$(gettext "Signing package...")"
- if [ ! $(type -p "gpg") ]; then
- error "$(gettext "Cannot find the gpg binary! Is gnupg installed?")"
+ if [[ ! $(type -p "${GPG}") ]]; then
+ 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
+ if ! ${GPG} --list-key "${SIGNKEY}" 1>/dev/null 2>&1; then
+ error "$(gettext "The key ${SIGNKEY} doesn\'t exist.")"
+ exit 1
+ fi
+ SIGNWITHKEY="-u ${SIGNKEY}"
+ fi
+ # The signature will be generated directly in ascii-friendly format
+ ${GPG} --detach-sign ${SIGNWITHKEY} "$filename" || ret=$?
if (( ! ret )); then
- msg2 "$(gettext "Created signature file %s.")" "$filename.sig"
+ msg2 "$(gettext "Created signature file %s.")" "${filename}${SIG_EXT}"
else
warning "$(gettext "Failed to sign package file.")"
fi
@@ -1269,7 +1283,7 @@ check_sanity() {
local i
for i in 'changelog' 'install'; do
- local filelist=$(sed -n "s/^[[:space:]]*$i=//p" "$BUILDFILE")
+ local filelist=$(sed -n "s/^[[:space:]]*$i=//p" "$BUILDFILE")
local file
for file in $filelist; do
# evaluate any bash variables used
@@ -1557,6 +1571,7 @@ 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 " --signwithkey Selects an specific key to use for signing")"
echo
echo "$(gettext "These options can be passed to pacman:")"
echo
@@ -1592,7 +1607,7 @@ OPT_SHORT="AcCdefFghiLmop:rRsV"
OPT_LONG="allsource,asroot,ignorearch,clean,cleancache,nodeps"
OPT_LONG+=",noextract,force,forcever:,geninteg,help,holdver"
OPT_LONG+=",install,log,nocolor,nobuild,pkg:,rmdeps,repackage,skipinteg"
-OPT_LONG+=",source,syncdeps,version,config:"
+OPT_LONG+=",source,syncdeps,version,config:,signwithkey"
# Pacman Options
OPT_LONG+=",noconfirm,noprogressbar"
OPT_TEMP="$(parse_options $OPT_SHORT $OPT_LONG "$@" || echo 'PARSE_OPTIONS FAILED')"
@@ -1635,6 +1650,7 @@ while true; do
--skipinteg) SKIPINTEG=1 ;;
--source) SOURCEONLY=1 ;;
-s|--syncdeps) DEP_BIN=1 ;;
+ --signwithkey) shift; SIGNKEY=$1 ;;
-h|--help) usage; exit 0 ;; # E_OK
-V|--version) version; exit 0 ;; # E_OK
diff --git a/scripts/repo-add.sh.in b/scripts/repo-add.sh.in
index 4ee63d8..ac734aa 100644
--- a/scripts/repo-add.sh.in
+++ b/scripts/repo-add.sh.in
@@ -26,6 +26,8 @@ export TEXTDOMAINDIR='@localedir@'
myver='@PACKAGE_VERSION@'
confdir='@sysconfdir@'
+GPG="gpg2"
+SIG_EXT=".sig"
QUIET=0
SIGN=0
@@ -62,8 +64,8 @@ error() {
# print usage instructions
usage() {
printf "repo-add, repo-remove (pacman) %s\n\n" "$myver"
- printf "$(gettext "Usage: repo-add [-q] [-s] [-v] <path-to-db> <package|delta> ...\n")"
- printf "$(gettext "Usage: repo-remove [-q] <path-to-db> <packagename|delta> ...\n\n")"
+ printf "$(gettext "Usage: repo-add [-q] [-s [-k|--signwithkey key]] [-v] <path-to-db> <package|delta> ...\n")"
+ printf "$(gettext "Usage: repo-remove [-q] [-s [-k|--signwithkey key]] <path-to-db> <packagename|delta> ...\n\n")"
printf "$(gettext "\
repo-add will update a package database by reading a package file.\n\
Multiple packages to add can be specified on the command line.\n\n")"
@@ -185,13 +187,24 @@ create_signature() {
local dbfile="$1"
local ret=0
msg "$(gettext "Signing database...")"
- if [ ! $(type -p "gpg") ]; then
- error "$(gettext "Cannot find the gpg binary! Is gnupg installed?")"
+ if [ ! $(type -p "${GPG}") ]; then
+ error "$(gettext "Cannot find the ${GPG} binary! Is gnupg installed?")"
exit 1 # $E_MISSING_PROGRAM
fi
- gpg --detach-sign --use-agent "$dbfile" || ret=$?
+
+ # Check if SIGNKEY is valid.
+ local SIGNWITHKEY=""
+ if [[ "${SIGNKEY}" ]]; then
+ if ! "${GPG}" --list-key "${SIGNKEY}" 1>/dev/null 2>&1; then
+ error "$(gettext "The key ${SIGNKEY} doesnn't exist.")"
+ exit 1
+ fi
+ SIGNWITHKEY="-u ${SIGNKEY}"
+ fi
+ echo "${GPG} --detach-sign ${SIGNWITHKEY} $dbfile"
+ ${GPG} --detach-sign ${SIGNWITHKEY} "$dbfile" || ret=$?
if (( ! ret )); then
- msg2 "$(gettext "Created signature file %s.")" "$dbfile.sig"
+ msg2 "$(gettext "Created signature file %s.")" "${dbfile}${SIG_EXT}"
else
warning "$(gettext "Failed to sign package database.")"
fi
@@ -203,15 +216,15 @@ verify_signature() {
local dbfile="$1"
local ret=0
msg "$(gettext "Verifying database signature...")"
- if [ ! $(type -p "gpg") ]; then
- error "$(gettext "Cannot find the gpg binary! Is gnupg installed?")"
+ if [ ! $(type -p "${GPG}") ]; then
+ error "$(gettext "Cannot find the ${GPG} binary! Is gnupg installed?")"
exit 1 # $E_MISSING_PROGRAM
fi
- if [[ ! -f $dbfile.sig ]]; then
+ if [[ ! -f ${dbfile}${SIG_EXT} ]]; then
warning "$(gettext "No existing signature found, skipping verification.")"
return
fi
- gpg --verify "$dbfile.sig" || ret=$?
+ ${GPG} --verify "${dbfile}${SIG_EXT}" || ret=$?
if (( ! ret )); then
msg2 "$(gettext "Database signature file verified.")"
else
@@ -298,9 +311,9 @@ db_write_entry()
echo -e "%MD5SUM%\n$md5sum\n" >>desc
# add base64'd PGP signature
- if [[ -f $startdir/$pkgfile.sig ]]; then
+ if [[ -f $startdir/$pkgfile${SIG_EXT} ]]; then
echo -e "%PGPSIG%" >>desc
- echo -e "$(openssl base64 -in "$startdir/$pkgfile.sig" | tr -d '\n')\n" >>desc
+ echo -e "$(openssl enc -base64 -in "$startdir/$pkgfile${SIG_EXT}")\n" >>desc
fi
[[ -n $url ]] && echo -e "%URL%\n$url\n" >>desc
@@ -492,10 +505,24 @@ trap 'trap_exit "$(gettext "An unknown error has occured. Exiting...")"' ERR
success=0
# parse arguments
-for arg in "$@"; do
+while [[ $# > 0 ]] ; do
+ arg="$1"
case "$arg" in
-q|--quiet) QUIET=1;;
- -s|--sign) SIGN=1;;
+ -s|--sign)
+ SIGN=1
+ # The signature will be made, even if there are no operations
+ success=1
+ ;;
+ -k|--signwithkey)
+ shift
+ SIGNKEY="$1"
+ # Check if key really exists
+ if ! ${GPG} --list-key ${SIGNKEY} 1> /dev/null 2>&1; then
+ error "$(gettext "Cannot find key $SIGNKEY.")"
+ exit 1
+ fi
+ ;;
-v|--verify) VERIFY=1;;
*)
if [[ -z $REPO_DB_FILE ]]; then
@@ -510,6 +537,7 @@ for arg in "$@"; do
fi
;;
esac
+ shift
done
# if at least one operation was a success, re-zip database
@@ -529,18 +557,19 @@ if (( success )); then
cd "$tmpdir"
if [[ -n $(ls) ]]; then
bsdtar -c${TAR_OPT}f "$filename" *
- create_signature "$filename"
else
# we have no packages remaining? zip up some emptyness
warning "$(gettext "No packages remain, creating empty database.")"
bsdtar -c${TAR_OPT}f "$filename" -T /dev/null
fi
+ # The signature must be dealt with in both cases, empty repo or not.
+ create_signature "$filename"
cd "$startdir"
[[ -f $REPO_DB_FILE ]] && mv -f "$REPO_DB_FILE" "${REPO_DB_FILE}.old"
- [[ -f $REPO_DB_FILE.sig ]] && rm -f "$REPO_DB_FILE.sig"
+ [[ -f $REPO_DB_FILE${SIG_EXT} ]] && rm -f "$REPO_DB_FILE${SIG_EXT}"
[[ -f $tmpdir/$filename ]] && mv "$tmpdir/$filename" "$REPO_DB_FILE"
- [[ -f $tmpdir/$filename.sig ]] && mv "$tmpdir/$filename.sig" "$REPO_DB_FILE.sig"
+ [[ -f $tmpdir/$filename${SIG_EXT} ]] && mv "$tmpdir/$filename${SIG_EXT}" "$REPO_DB_FILE${SIG_EXT}"
dblink="${REPO_DB_FILE%.tar.*}"
ln -sf "$REPO_DB_FILE" "$dblink" 2>/dev/null || \
ln -f "$REPO_DB_FILE" "$dblink" 2>/dev/null || \
--
1.7.1.1
More information about the pacman-dev
mailing list