From ee34869e8934fe55562a84c4eac055256b7c42f0 Mon Sep 17 00:00:00 2001 From: Geoffroy Carrier Date: Mon, 2 Jun 2008 10:27:00 +0200 Subject: Add GPG signature support to makepkg This is a rather simple patch to add signing support to makepkg. Add a create_signature() to makepkg, add a 'sign' BUILDENV option in makepkg.conf, and document the changes in the makepkg.conf manpage. Signed-off-by: Geoffroy Carrier Signed-off-by: Dan McGee --- doc/makepkg.conf.5.txt | 9 ++++++++- etc/makepkg.conf.in | 5 +++-- scripts/makepkg.sh.in | 21 +++++++++++++++++++++ 3 files changed, 32 insertions(+), 3 deletions(-) diff --git a/doc/makepkg.conf.5.txt b/doc/makepkg.conf.5.txt index 61302492..a9faa14d 100644 --- a/doc/makepkg.conf.5.txt +++ b/doc/makepkg.conf.5.txt @@ -70,7 +70,7 @@ Options This is often used to set the number of jobs used, for example, `-j2`. Other flags that make accepts can also be passed. -**BUILDENV=(**fakeroot !distcc color !ccache**)**:: +**BUILDENV=(**fakeroot !distcc color !ccache !sign**)**:: This array contains options that affect the build environment, the defaults are shown here. All options should always be left in the array; to enable or disable an option simply remove or place an ``!'' at the front of the @@ -98,6 +98,13 @@ Options enabled or disabled for individual packages through the use of makepkg's `--check` and `--nocheck` options respectively. + *sign*;; + Generate a PGP signature file using GnuPG. This will execute `gpg + --detach-sign --use-agent` on the built package to generate a detached + signature file, using the GPG agent if it is available. The signature + file will be the entire filename of the package with a ``.sig'' + extension. + **DISTCC_HOSTS=**"host1 ...":: If using DistCC, this is used to specify a space-delimited list of hosts running in the DistCC cluster. In addition, you will want to modify your diff --git a/etc/makepkg.conf.in b/etc/makepkg.conf.in index 81a11b1d..286e2a84 100644 --- a/etc/makepkg.conf.in +++ b/etc/makepkg.conf.in @@ -39,7 +39,7 @@ CXXFLAGS="@CARCHFLAGS@-mtune=generic -O2 -pipe" # BUILD ENVIRONMENT ######################################################################### # -# Defaults: BUILDENV=(fakeroot !distcc color !ccache check) +# Defaults: BUILDENV=(fakeroot !distcc color !ccache check !sign) # A negated environment option will do the opposite of the comments below. # #-- fakeroot: Allow building packages as a non-root user @@ -47,8 +47,9 @@ CXXFLAGS="@CARCHFLAGS@-mtune=generic -O2 -pipe" #-- color: Colorize output messages #-- ccache: Use ccache to cache compilation #-- check: Run the check() function if present in the PKGBUILD +#-- sign: Generate PGP signature file # -BUILDENV=(fakeroot !distcc color !ccache check) +BUILDENV=(fakeroot !distcc color !ccache check !sign) # #-- If using DistCC, your MAKEFLAGS will also need modification. In addition, #-- specify a space-delimited list of hosts running in the DistCC cluster. diff --git a/scripts/makepkg.sh.in b/scripts/makepkg.sh.in index bb7616cf..f28097f6 100644 --- a/scripts/makepkg.sh.in +++ b/scripts/makepkg.sh.in @@ -1099,6 +1099,25 @@ create_package() { fi } +create_signature() { + if [[ $(check_buildenv sign) != "y" ]]; then + return + fi + local ret=0 + local filename="$PKGDEST/${pkgname}-${pkgver}-${pkgrel}-${CARCH}${PKGEXT}" + msg "$(gettext "Signing package...")" + 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=$? + if (( ! ret )); then + msg2 "$(gettext "Created signature file %s.")" $filename.sig + else + warning "$(gettext "Failed to sign package file.")" + fi +} + create_srcpackage() { cd "$startdir" @@ -2115,6 +2134,8 @@ fi fullver=$(get_full_version $epoch $pkgver $pkgrel) msg "$(gettext "Finished making: %s")" "$pkgbase $fullver ($(date))" +create_signature + install_package exit 0 #E_OK -- cgit v1.2.3-24-g4f1b From 82e22596d8bfeac89e96d8b2d9eda8e13e14880c Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Mon, 24 Aug 2009 13:22:12 -0500 Subject: makepkg: allow signatures to work with split packages Signed-off-by: Dan McGee --- scripts/makepkg.sh.in | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/scripts/makepkg.sh.in b/scripts/makepkg.sh.in index f28097f6..5d6363f0 100644 --- a/scripts/makepkg.sh.in +++ b/scripts/makepkg.sh.in @@ -1068,6 +1068,9 @@ create_package() { local pkg_file="$PKGDEST/${nameofpkg}-${fullver}-${PKGARCH}${PKGEXT}" local ret=0 + [[ -f $pkg_file ]] && rm -f "$pkg_file" + [[ -f $pkg_file.sig ]] && rm -f "$pkg_file.sig" + # when fileglobbing, we want * in an empty directory to expand to # the null string rather than itself shopt -s nullglob @@ -1097,6 +1100,8 @@ create_package() { if (( ret )); then warning "$(gettext "Failed to create symlink to package file.")" fi + + create_signature "$pkg_file" } create_signature() { @@ -1104,15 +1109,15 @@ create_signature() { return fi local ret=0 - local filename="$PKGDEST/${pkgname}-${pkgver}-${pkgrel}-${CARCH}${PKGEXT}" + local filename="$1" msg "$(gettext "Signing package...")" 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=$? + gpg --detach-sign --use-agent "$filename" || ret=$? if (( ! ret )); then - msg2 "$(gettext "Created signature file %s.")" $filename.sig + msg2 "$(gettext "Created signature file %s.")" "$filename.sig" else warning "$(gettext "Failed to sign package file.")" fi @@ -2134,8 +2139,6 @@ fi fullver=$(get_full_version $epoch $pkgver $pkgrel) msg "$(gettext "Finished making: %s")" "$pkgbase $fullver ($(date))" -create_signature - install_package exit 0 #E_OK -- cgit v1.2.3-24-g4f1b From 2f2f53ddc9f05d00244a41a66eef9ed34bc87463 Mon Sep 17 00:00:00 2001 From: Allan McRae Date: Wed, 31 Mar 2010 15:00:33 +1000 Subject: makepkg: place signature symlink in build dir Be consistent in package and signature placements when using PKGDEST. Signed-off-by: Allan McRae --- scripts/makepkg.sh.in | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/scripts/makepkg.sh.in b/scripts/makepkg.sh.in index 5d6363f0..5742c492 100644 --- a/scripts/makepkg.sh.in +++ b/scripts/makepkg.sh.in @@ -1092,16 +1092,17 @@ create_package() { exit 1 # TODO: error code fi + create_signature "$pkg_file" + if (( ! ret )) && [[ ! "$PKGDEST" -ef "${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" fi if (( ret )); then warning "$(gettext "Failed to create symlink to package file.")" fi - - create_signature "$pkg_file" } create_signature() { -- cgit v1.2.3-24-g4f1b From 8fde399fe62c3a08310e1830bb15b6e93ed360f9 Mon Sep 17 00:00:00 2001 From: Geoffroy Carrier Date: Mon, 2 Jun 2008 10:27:01 +0200 Subject: Add PGPSIG field in repo-add Use base64 encoding to store the value in the database if a .sig file exists for the package being added. Signed-off-by: Geoffroy Carrier Signed-off-by: Dan McGee --- scripts/repo-add.sh.in | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/scripts/repo-add.sh.in b/scripts/repo-add.sh.in index dfc93974..70cfd63c 100644 --- a/scripts/repo-add.sh.in +++ b/scripts/repo-add.sh.in @@ -268,6 +268,12 @@ db_write_entry() msg2 "$(gettext "Computing md5 checksums...")" echo -e "%MD5SUM%\n$md5sum\n" >>desc + # add base64'd PGP signature + if [[ -f $startdir/$pkgfile.sig ]]; then + pgpsig=$(openssl base64 -in "$startdir/$pkgfile.sig" | tr -d '\n') + echo -e "%PGPSIG%\n$pgpsig\n" >>desc + fi + [[ -n $url ]] && echo -e "%URL%\n$url\n" >>desc write_list_entry "LICENSE" "$_licenses" "desc" [[ -n $arch ]] && echo -e "%ARCH%\n$arch\n" >>desc -- cgit v1.2.3-24-g4f1b From a4120f2015ae4d5880642e16c81acadbab77555d Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Mon, 24 Aug 2009 13:23:44 -0500 Subject: repo-add: allow signing of the package database In order to be fully secure, we can't only sign packages. We also need to sign our repository metadata to prevent database falsification, dependency injection, etc. Add an '-s/--sign' option that allows this functionality, and will generate a .sig file side-by-side with the package database. While at it, fix the issue where a signature file would never be found because of 'cd' madness (this needs fixing in another commit). Signed-off-by: Dan McGee --- doc/repo-add.8.txt | 7 +++++++ scripts/repo-add.sh.in | 23 +++++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/doc/repo-add.8.txt b/doc/repo-add.8.txt index 75f49ef5..26009f67 100644 --- a/doc/repo-add.8.txt +++ b/doc/repo-add.8.txt @@ -43,6 +43,13 @@ Options Force this program to keep quiet and run silent except for warning and error messages. +*-s, \--sign*:: + Generate a PGP signature file using GnuPG. This will execute `gpg + --detach-sign --use-agent` on the generated database to generate a detached + signature file, using the GPG agent if it is available. The signature file + will be the entire filename of the database with a ``.sig'' extension. + + See Also -------- linkman:makepkg[8], linkman:pacman[8] diff --git a/scripts/repo-add.sh.in b/scripts/repo-add.sh.in index 70cfd63c..ebe226a1 100644 --- a/scripts/repo-add.sh.in +++ b/scripts/repo-add.sh.in @@ -30,6 +30,7 @@ confdir='@sysconfdir@' QUIET=0 DELTA=0 WITHFILES=0 +SIGN=0 REPO_DB_FILE= LOCKFILE= CLEAN_LOCK=0 @@ -184,6 +185,24 @@ db_remove_delta() return 1 } # end db_remove_delta +# sign the package database once repackaged +create_signature() { + (( ! SIGN )) && return + 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?")" + exit 1 # $E_MISSING_PROGRAM + fi + gpg --detach-sign --use-agent "$dbfile" || ret=$? + if (( ! ret )); then + msg2 "$(gettext "Created signature file %s.")" "$dbfile.sig" + else + warning "$(gettext "Failed to sign package database.")" + fi +} + # write an entry to the pacman database # arg1 - path to package db_write_entry() @@ -488,6 +507,7 @@ for arg in "$@"; do -q|--quiet) QUIET=1;; -d|--delta) DELTA=1;; -f|--files) WITHFILES=1;; + -s|--sign) SIGN=1;; *) if [[ -z $REPO_DB_FILE ]]; then REPO_DB_FILE="$arg" @@ -520,6 +540,7 @@ if (( success )); then pushd "$tmpdir" >/dev/null 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.")" @@ -528,7 +549,9 @@ if (( success )); then popd >/dev/null [[ -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 $tmpdir/$filename ]] && mv "$tmpdir/$filename" "$REPO_DB_FILE" + [[ -f $tmpdir/$filename.sig ]] && mv "$tmpdir/$filename.sig" "$REPO_DB_FILE.sig" dblink="${REPO_DB_FILE%.tar.*}" target=${REPO_DB_FILE##*/} ln -sf "$target" "$dblink" 2>/dev/null || \ -- cgit v1.2.3-24-g4f1b From 38f94da47d71780fdaaf0f06e0bf4dd37456fc00 Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Mon, 24 Aug 2009 16:52:23 -0500 Subject: repo-add: add -v/--verify option This is intended to verify an existing signature on a database before making further changes to it and performing updates. Rarely would you use this without immediately resigning it via the -s/--sign option. Instead, it is intended as a "chain of trust" operation where the previous signature is verified to give you some sense that what you sign off on is also safe. Still todo: don't make changes unless the signature is not only good, but also in the accepted list of keys. Signed-off-by: Dan McGee --- scripts/repo-add.sh.in | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/scripts/repo-add.sh.in b/scripts/repo-add.sh.in index ebe226a1..8a738b4b 100644 --- a/scripts/repo-add.sh.in +++ b/scripts/repo-add.sh.in @@ -31,6 +31,7 @@ QUIET=0 DELTA=0 WITHFILES=0 SIGN=0 +VERIFY=0 REPO_DB_FILE= LOCKFILE= CLEAN_LOCK=0 @@ -203,6 +204,29 @@ create_signature() { fi } +# verify the existing package database signature +verify_signature() { + (( ! VERIFY )) && return + 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?")" + exit 1 # $E_MISSING_PROGRAM + fi + if [[ ! -f $dbfile.sig ]]; then + warning "$(gettext "No existing signature found, skipping verification.")" + return + fi + gpg --verify "$dbfile.sig" || ret=$? + if (( ! ret )); then + msg2 "$(gettext "Database signature file verified.")" + else + error "$(gettext "Database signature was NOT valid!")" + exit 1 + fi +} + # write an entry to the pacman database # arg1 - path to package db_write_entry() @@ -377,6 +401,7 @@ check_repo_db() exit 1 fi fi + verify_signature "$REPO_DB_FILE" msg "$(gettext "Extracting database to a temporary location...")" bsdtar -xf "$REPO_DB_FILE" -C "$tmpdir" else @@ -508,6 +533,7 @@ for arg in "$@"; do -d|--delta) DELTA=1;; -f|--files) WITHFILES=1;; -s|--sign) SIGN=1;; + -v|--verify) VERIFY=1;; *) if [[ -z $REPO_DB_FILE ]]; then REPO_DB_FILE="$arg" -- cgit v1.2.3-24-g4f1b From f0f83197694edb055b074a4b339e07c31627205c Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Thu, 29 Oct 2009 21:35:25 -0500 Subject: repo-add: Fix up usage with GPG options Signed-off-by: Dan McGee --- scripts/repo-add.sh.in | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/scripts/repo-add.sh.in b/scripts/repo-add.sh.in index 8a738b4b..c55eac3f 100644 --- a/scripts/repo-add.sh.in +++ b/scripts/repo-add.sh.in @@ -64,7 +64,7 @@ error() { # print usage instructions usage() { printf "repo-add, repo-remove (pacman) %s\n\n" "$myver" - printf "$(gettext "Usage: repo-add [-d] [-f] [-q] ...\n")" + printf "$(gettext "Usage: repo-add [-d] [-f] [-q] [-s] [-v] ...\n")" printf "$(gettext "Usage: repo-remove [-q] ...\n\n")" printf "$(gettext "\ repo-add will update a package database by reading a package file.\n\ @@ -81,7 +81,8 @@ Use the -d/--delta flag to automatically generate and add a delta file\n\ between the old entry and the new one, if the old package file is found\n\ next to the new one.\n\n")" printf "$(gettext "\ -Use the -f/--files flag to update a database including file entries.\n\n")" +Use the -f/--files flag to update a database including file entries.\n\n +See repo-add(8) for more details and descriptions of the available options.\n\n")" echo "$(gettext "Example: repo-add /path/to/repo.db.tar.gz pacman-3.0.0.pkg.tar.gz")" echo "$(gettext "Example: repo-remove /path/to/repo.db.tar.gz kernel26")" } -- cgit v1.2.3-24-g4f1b From 93591d428fa553a03fee1f63228311f92e85d1ed Mon Sep 17 00:00:00 2001 From: Allan McRae Date: Tue, 23 Nov 2010 14:57:58 +1000 Subject: repo-add: add symlink to signature file Signed-off-by: Allan McRae --- scripts/repo-add.sh.in | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/scripts/repo-add.sh.in b/scripts/repo-add.sh.in index c55eac3f..76005757 100644 --- a/scripts/repo-add.sh.in +++ b/scripts/repo-add.sh.in @@ -584,6 +584,11 @@ if (( success )); then ln -sf "$target" "$dblink" 2>/dev/null || \ ln -f "$target" "$dblink" 2>/dev/null || \ cp "$REPO_DB_FILE" "$dblink" + if [[ -f "$target.sig" ]]; then + ln -sf "$target.sig" "$dblink.sig" 2>/dev/null || \ + ln -f "$target.sig" "$dblink.sig" 2>/dev/null || \ + cp "$REPO_DB_FILE.sig" "$dblink.sig" + fi else msg "$(gettext "No packages modified, nothing to do.")" exit 1 -- cgit v1.2.3-24-g4f1b From a31d091fb3bd250416d419b30e99c900b1608efc Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Wed, 23 Mar 2011 00:10:36 -0500 Subject: repo-add: add sha256sum values to repo database Implements FS#23103. Also modify libalpm so it ignores this value without any warning as we know it is likely to exist. Signed-off-by: Dan McGee --- lib/libalpm/be_sync.c | 3 +++ scripts/repo-add.sh.in | 14 +++++++++----- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/lib/libalpm/be_sync.c b/lib/libalpm/be_sync.c index 4966ce6f..9ca52de3 100644 --- a/lib/libalpm/be_sync.c +++ b/lib/libalpm/be_sync.c @@ -418,6 +418,9 @@ static int sync_db_read(pmdb_t *db, struct archive *archive, pkg->isize = atol(line); } else if(strcmp(line, "%MD5SUM%") == 0) { READ_AND_STORE(pkg->md5sum); + } else if(strcmp(line, "%SHA256SUM%") == 0) { + /* we don't do anything with this value right now */ + READ_NEXT(line); } else if(strcmp(line, "%REPLACES%") == 0) { READ_AND_STORE_ALL(pkg->replaces); } else if(strcmp(line, "%DEPENDS%") == 0) { diff --git a/scripts/repo-add.sh.in b/scripts/repo-add.sh.in index 76005757..59e98cfe 100644 --- a/scripts/repo-add.sh.in +++ b/scripts/repo-add.sh.in @@ -263,9 +263,6 @@ db_write_entry() IFS=$OLDIFS - # get md5sum and compressed size of package - md5sum="$(openssl dgst -md5 "$pkgfile")" - md5sum="${md5sum##* }" csize=$(@SIZECMD@ "$pkgfile") # ensure $pkgname and $pkgver variables were found @@ -287,6 +284,13 @@ db_write_entry() fi fi + # compute checksums + msg2 "$(gettext "Computing checksums...")" + md5sum="$(openssl dgst -md5 "$pkgfile")" + md5sum="${md5sum##* }" + sha256sum="$(openssl dgst -sha256 "$pkgfile")" + sha256sum="${sha256sum##* }" + # remove an existing entry if it exists, ignore failures db_remove_entry "$pkgname" @@ -308,9 +312,9 @@ db_write_entry() [[ -n $csize ]] && echo -e "%CSIZE%\n$csize\n" >>desc [[ -n $size ]] && echo -e "%ISIZE%\n$size\n" >>desc - # compute checksums - msg2 "$(gettext "Computing md5 checksums...")" + # add checksums echo -e "%MD5SUM%\n$md5sum\n" >>desc + echo -e "%SHA256SUM%\n$sha256sum\n" >>desc # add base64'd PGP signature if [[ -f $startdir/$pkgfile.sig ]]; then -- cgit v1.2.3-24-g4f1b