From b9769d5af5e4be7a1c285ccf06df8a608d9d5825 Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Sun, 31 May 2015 13:28:57 -0600 Subject: librefetch: Don't try to use makepkg to create .sig files. --- src/librefetch/librefetch | 76 +++++++++++++++++++++++++++++++++----- src/librefetch/librefetch.8.ronn | 8 +++- test/librefetch-test.sh | 28 ++++++++++++++ test/librefetch.d/PKGBUILD | 2 +- test/librefetch.d/PKGBUILD-recurse | 18 +++++++++ 5 files changed, 120 insertions(+), 12 deletions(-) create mode 100644 test/librefetch.d/PKGBUILD-recurse diff --git a/src/librefetch/librefetch b/src/librefetch/librefetch index 49a8565..ea90e5b 100755 --- a/src/librefetch/librefetch +++ b/src/librefetch/librefetch @@ -3,6 +3,15 @@ # # Copyright (C) 2013-2015 Luke Shumaker # +# For just the create_signature() function: +# Copyright (C) 2006-2013 Pacman Development Team +# Copyright (C) 2002-2006 Judd Vinet +# Copyright (C) 2005 Aurelien Foret +# Copyright (C) 2006 Miklos Vajna +# Copyright (C) 2005 Christian Hamar +# Copyright (C) 2006 Alex Smith +# Copyright (C) 2006 Andras Voroskoi +# # License: GNU GPLv3+ # # This file is part of Parabola. @@ -20,6 +29,9 @@ # You should have received a copy of the GNU General Public License # along with Parabola. If not, see . +# create_signature() is taken from pacman:makepkg, which is GPLv2+, +# so we take the '+' to combine it with our GPLv3+. + . "$(librelib conf)" . "$(librelib messages)" setup_traps @@ -46,9 +58,14 @@ usage() { beginning of a URL, 'libre://' expands to the first configured mirror." echo - prose "In create mode, it looks at a build script, and uses that to - create the source tarball. SOURCE_URL is ignored, except that it - is used to set the default value of OUTPUT_FILE." + prose "In create mode, it either looks at a build script and uses that + to create the source tarball, or it uses GPG to create a + signature (if OUTPUT_FILE ends with \`.sig\` or \`.sig.part\`). + If it is using GPG to create a signature, but the file that it is + trying to sign doesn't exist yet, it recurses on itself to first + create that file. SOURCE_URL is ignored, except that it is used + to set the default value of OUTPUT_FILE, and that it may be used + when recursing." echo prose "The default build script is 'PKGBUILD', or 'SRCBUILD' if it exists." @@ -83,6 +100,10 @@ main() { exit 1 fi + doit +} + +doit() { # Mode: help ########################################################### if [[ $mode =~ help ]]; then @@ -183,13 +204,26 @@ main() { # Mode: create ######################################################### if [[ $mode =~ create ]]; then - PKGEXT=${dst##*/} - export PKGEXT=${PKGEXT%.part} - export PKGDEST=${dst%/*} - export pkg_file=$dst + local base_dst=${dst%.part} + local suffix=${dst#"$base_dst"} - cd "$BUILDFILEDIR" - "$makepkg" "${makepkg_opts[@]}" -p "$srcbuild" >&2 || exit $? + if [[ $base_dst == *.sig ]]; then + if ! [[ -e $base_dst ]]; then + extra_opts=("${src%.sig}" "${base_dst%.sig}") + doit || exit $? + fi + create_signature "${base_dst%.sig}" || exit $? + if [[ -n $suffix ]]; then + mv -f "$base_dst" "$dst" + fi + else + export PKGEXT=${base_dst##*/} + export PKGDEST=${dst%/*} + export pkg_file=$dst + + cd "$BUILDFILEDIR" + "$makepkg" "${makepkg_opts[@]}" -p "$srcbuild" >&2 || exit $? + fi fi } @@ -393,4 +427,28 @@ modified_srcbuild() { printf '%s\n' "$new" } +################################################################################ + +# This function is taken almost verbatim from makepkg +create_signature() { + local ret=0 + local filename="$1" + msg "Signing package..." + + local SIGNWITHKEY=() + if [[ -n $GPGKEY ]]; then + SIGNWITHKEY=(-u "${GPGKEY}") + fi + # The signature will be generated directly in ascii-friendly format + gpg --detach-sign --use-agent "${SIGNWITHKEY[@]}" "$filename" || ret=$? + + + if (( ! ret )); then + msg2 "Created signature file %s." "$filename.sig" + else + error "Failed to sign package file." + return $ret + fi +} + main "$@" diff --git a/src/librefetch/librefetch.8.ronn b/src/librefetch/librefetch.8.ronn index da5ea60..7d3550f 100644 --- a/src/librefetch/librefetch.8.ronn +++ b/src/librefetch/librefetch.8.ronn @@ -85,8 +85,12 @@ ensure that as long as the same directory contents go in, an identical tarball will come out--the checksum of the file should not change based on when it is built or who builds it. -The `SRCBUILD` is either created, or sanitized if it already exists, -then fed to a modified version of `makepkg(8)`. +The `SRCBUILD` is either created, or sanitized if it already exists. +If the output filename does not end with `.sig` or `.sig.part`, then +the `SRCBUILD` is fed to a modified version of `makepkg(8)`. If the +output filename does end with `.sig` or `.sig.part`, then it uses GPG +to create a signature. If the file it is trying to sign does not +exist yet, librefetch recurses on itself to create it. The reason `makepkg` must be modified is that we need the resulting tarball to be deterministic (as well as not containing package diff --git a/test/librefetch-test.sh b/test/librefetch-test.sh index 8dd957a..f10ee7f 100644 --- a/test/librefetch-test.sh +++ b/test/librefetch-test.sh @@ -4,6 +4,9 @@ describe librefetch . ./test-common.sh +KEYSERVER=hkp://pool.sks-keyservers.net +GPG="gpg --quiet --batch --no-tty --no-permission-warning --keyserver ${KEYSERVER}" + before() { _before @@ -28,6 +31,17 @@ EOF 'MIRRORS=("phony://example.com/dir/")' \ 'DOWNLOADER=/usr/bin/false' \ > "$XDG_CONFIG_HOME/libretools/librefetch.conf" + + printf '%s\n' \ + 'Key-Type: RSA' \ + 'Key-Length: 1024' \ + 'Key-Usage: sign' \ + 'Name-Real: Temporary LibreTools testsuite key' \ + 'Name-Email: libretools-test@localhost' \ + 'Expire-Date: 0' \ + '%no-protection' \ + '%commit' \ + | $GPG --gen-key 2>/dev/null } after() { @@ -68,4 +82,18 @@ it_runs() { # unfortunately). bsdtar tf "$tmpdir/srcdest/$srcball" > list-pkg.txt diff -u list.txt list-pkg.txt + # Verify that the signature was created and matches + gpg --quiet --verify "$tmpdir/srcdest/$srcball"{.sig,} 2>/dev/null +} + +it_recurses() { + local srcball=testpkg-1.0.tar.gz + cp librefetch.d/* "$tmpdir/" + cd "$tmpdir" + mv PKGBUILD{-recurse,} + + makepkg -g + bsdtar tf "$tmpdir/srcdest/$srcball" > list-pkg.txt + diff -u list.txt list-pkg.txt + gpg --quiet --verify "$tmpdir/srcdest/$srcball"{.sig,} 2>/dev/null } diff --git a/test/librefetch.d/PKGBUILD b/test/librefetch.d/PKGBUILD index db80db3..6547e25 100644 --- a/test/librefetch.d/PKGBUILD +++ b/test/librefetch.d/PKGBUILD @@ -3,7 +3,7 @@ pkgver=1.0 pkgrel=1 pkgdesc=foo arch=(any) -source=("libre://$pkgname-$pkgver.tar.gz") +source=("libre://$pkgname-$pkgver.tar.gz"{,.sig}) mksource() { mkdir "$srcdir/bar" diff --git a/test/librefetch.d/PKGBUILD-recurse b/test/librefetch.d/PKGBUILD-recurse new file mode 100644 index 0000000..fad5976 --- /dev/null +++ b/test/librefetch.d/PKGBUILD-recurse @@ -0,0 +1,18 @@ +pkgname=testpkg +pkgver=1.0 +pkgrel=1 +pkgdesc=foo +arch=(any) +source=("libre://$pkgname-$pkgver.tar.gz.sig") + +mksource() { + mkdir "$srcdir/bar" + local file + for file in '~foo' '~a' a A; do + touch "$srcdir/bar/$file" + done +} + +package() { + :; +} -- cgit v1.2.2