summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xsrc/librefetch/librefetch76
-rw-r--r--src/librefetch/librefetch.8.ronn8
-rw-r--r--test/librefetch-test.sh28
-rw-r--r--test/librefetch.d/PKGBUILD2
-rw-r--r--test/librefetch.d/PKGBUILD-recurse18
5 files changed, 120 insertions, 12 deletions
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 <lukeshu@sbcglobal.net>
#
+# For just the create_signature() function:
+# Copyright (C) 2006-2013 Pacman Development Team <pacman-dev@archlinux.org>
+# Copyright (C) 2002-2006 Judd Vinet <jvinet@zeroflux.org>
+# Copyright (C) 2005 Aurelien Foret <orelien@chez.com>
+# Copyright (C) 2006 Miklos Vajna <vmiklos@frugalware.org>
+# Copyright (C) 2005 Christian Hamar <krics@linuxforum.hu>
+# Copyright (C) 2006 Alex Smith <alex@alex-smith.me.uk>
+# Copyright (C) 2006 Andras Voroskoi <voroskoi@frugalware.org>
+#
# 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 <http://www.gnu.org/licenses/>.
+# 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() {
+ :;
+}