makepkg: Implement the verify function

Message ID 20220528141812.2355346-1-foxboron@archlinux.org
State New, archived
Headers show
Series makepkg: Implement the verify function | expand

Commit Message

Morten Linderud May 28, 2022, 2:18 p.m. UTC
From: Morten Linderud <morten@linderud.pw>

This patch implements a new verify function in makepkg. It allows us to
do arbitrary authentication on sources before extraction.

There are several new signing and validation methods being implemented
and it would be hard to have `makepkg` implement support for things such
as sequoia, cosign or minisign. This would allow us to distribute
generic validation functions.

This also implements a new `copy_` routine for our protocols as we need
to have a separation between extracting sources and copying sources.

Signed-off-by: Morten Linderud <morten@linderud.pw>
---
 doc/PKGBUILD.5.asciidoc              |  4 ++++
 doc/makepkg.8.asciidoc               |  3 +++
 scripts/libmakepkg/integrity.sh.in   |  3 +++
 scripts/libmakepkg/source.sh.in      | 15 +++++++++++++++
 scripts/libmakepkg/source/file.sh.in |  9 ++++++++-
 scripts/makepkg.sh.in                | 17 ++++++++++++++++-
 6 files changed, 49 insertions(+), 2 deletions(-)

Comments

Allan McRae June 25, 2022, 2:55 p.m. UTC | #1
On 29/5/22 00:18, Morten Linderud wrote:
> From: Morten Linderud <morten@linderud.pw>
> 
> This patch implements a new verify function in makepkg. It allows us to
> do arbitrary authentication on sources before extraction.
> 
> There are several new signing and validation methods being implemented
> and it would be hard to have `makepkg` implement support for things such
> as sequoia, cosign or minisign. This would allow us to distribute
> generic validation functions.
> 
> This also implements a new `copy_` routine for our protocols as we need
> to have a separation between extracting sources and copying sources.

I have looked at this patch and I have no idea what the copy_... is 
supposed to do here at all.  Why would anything need copied into $srcdir 
before verification?  This does not appear necessary for and of sequoia, 
cosign or minisign.

Allan
Morten Linderud June 25, 2022, 2:59 p.m. UTC | #2
On Sun, Jun 26, 2022 at 12:55:22AM +1000, Allan McRae wrote:
> On 29/5/22 00:18, Morten Linderud wrote:
> > From: Morten Linderud <morten@linderud.pw>
> > 
> > This patch implements a new verify function in makepkg. It allows us to
> > do arbitrary authentication on sources before extraction.
> > 
> > There are several new signing and validation methods being implemented
> > and it would be hard to have `makepkg` implement support for things such
> > as sequoia, cosign or minisign. This would allow us to distribute
> > generic validation functions.
> > 
> > This also implements a new `copy_` routine for our protocols as we need
> > to have a separation between extracting sources and copying sources.
> 
> I have looked at this patch and I have no idea what the copy_... is supposed
> to do here at all.  Why would anything need copied into $srcdir before
> verification?  This does not appear necessary for and of sequoia, cosign or
> minisign.
> 
> Allan

Currently makepkg does copying and extraction as one routine. Nothing is
currently available in `$srcdir` and there is no way to have files available in
`$srcdir` without actually extracting them as well.

How could sequioa/cosign/minisign verify files if there is no files in `$srcdir`?
Allan McRae June 25, 2022, 11:51 p.m. UTC | #3
On 26/6/22 00:59, Morten Linderud wrote:
> On Sun, Jun 26, 2022 at 12:55:22AM +1000, Allan McRae wrote:
>> On 29/5/22 00:18, Morten Linderud wrote:
>>> From: Morten Linderud <morten@linderud.pw>
>>>
>>> This patch implements a new verify function in makepkg. It allows us to
>>> do arbitrary authentication on sources before extraction.
>>>
>>> There are several new signing and validation methods being implemented
>>> and it would be hard to have `makepkg` implement support for things such
>>> as sequoia, cosign or minisign. This would allow us to distribute
>>> generic validation functions.
>>>
>>> This also implements a new `copy_` routine for our protocols as we need
>>> to have a separation between extracting sources and copying sources.
>>
>> I have looked at this patch and I have no idea what the copy_... is supposed
>> to do here at all.  Why would anything need copied into $srcdir before
>> verification?  This does not appear necessary for and of sequoia, cosign or
>> minisign.
>>
>> Allan
> 
> Currently makepkg does copying and extraction as one routine. Nothing is
> currently available in `$srcdir` and there is no way to have files available in
> `$srcdir` without actually extracting them as well.
> 
> How could sequioa/cosign/minisign verify files if there is no files in `$srcdir`?

All other verification happens in $startdir.  I don't see why a verify() 
function needs $srcdir.

Allan

Patch

diff --git a/doc/PKGBUILD.5.asciidoc b/doc/PKGBUILD.5.asciidoc
index 4ca8eb3b..e7743c88 100644
--- a/doc/PKGBUILD.5.asciidoc
+++ b/doc/PKGBUILD.5.asciidoc
@@ -344,6 +344,10 @@  function.
 	fakeroot to ensure correct file permissions in the resulting package.
 	All other functions will be run as the user calling makepkg.
 
+*verify() Function*::
+	An optional `verify()` function can be specified to implement arbiterary
+	source authentication. This function is run before sources are extracted.
+
 *prepare() Function*::
 	An optional `prepare()` function can be specified in which operations to
 	prepare the sources for building, such as patching, are performed. This
diff --git a/doc/makepkg.8.asciidoc b/doc/makepkg.8.asciidoc
index 38032e7b..75b2139f 100644
--- a/doc/makepkg.8.asciidoc
+++ b/doc/makepkg.8.asciidoc
@@ -168,6 +168,9 @@  Options
 *\--noprepare*::
 	Do not run the prepare() function in the PKGBUILD.
 
+*\--noverify*::
+	Do not run the verify() function in the PKGBUILD.
+
 *\--sign*::
 	Sign the resulting package with gpg, overriding the setting in
 	linkman:makepkg.conf[5].
diff --git a/scripts/libmakepkg/integrity.sh.in b/scripts/libmakepkg/integrity.sh.in
index 070392fa..81f935df 100644
--- a/scripts/libmakepkg/integrity.sh.in
+++ b/scripts/libmakepkg/integrity.sh.in
@@ -42,4 +42,7 @@  check_source_integrity() {
 		check_checksums "$@"
 		check_pgpsigs "$@"
 	fi
+	if (( VERIFYFUNC )); then
+		run_verify
+	fi
 }
diff --git a/scripts/libmakepkg/source.sh.in b/scripts/libmakepkg/source.sh.in
index e39dd16c..92dc71e4 100644
--- a/scripts/libmakepkg/source.sh.in
+++ b/scripts/libmakepkg/source.sh.in
@@ -69,6 +69,21 @@  download_sources() {
 	done
 }
 
+copy_sources(){
+	msg "$(gettext "Copying sources...")"
+	local netfile all_sources
+
+	get_all_sources_for_arch 'all_sources'
+	for netfile in "${all_sources[@]}"; do
+		local proto=$(get_protocol "$netfile")
+		if declare -f copy_$proto > /dev/null; then
+			copy_$proto "$netfile"
+		else
+			copy_file "$netfile"
+		fi
+	done
+}
+
 extract_sources() {
 	msg "$(gettext "Extracting sources...")"
 	local netfile all_sources
diff --git a/scripts/libmakepkg/source/file.sh.in b/scripts/libmakepkg/source/file.sh.in
index fa09d446..51452550 100644
--- a/scripts/libmakepkg/source/file.sh.in
+++ b/scripts/libmakepkg/source/file.sh.in
@@ -82,13 +82,20 @@  download_file() {
 	fi
 }
 
-extract_file() {
+copy_file(){
 	local netfile=$1
 
 	local file=$(get_filename "$netfile")
 	local filepath=$(get_filepath "$file")
 	rm -f "$srcdir/${file}"
 	ln -s "$filepath" "$srcdir/"
+}
+
+extract_file() {
+	local netfile=$1
+
+	local file=$(get_filename "$netfile")
+	local filepath=$(get_filepath "$file")
 
 	if in_array "$file" "${noextract[@]}"; then
 		# skip source files in the noextract=() array
diff --git a/scripts/makepkg.sh.in b/scripts/makepkg.sh.in
index 5aaabf63..b7b21af1 100644
--- a/scripts/makepkg.sh.in
+++ b/scripts/makepkg.sh.in
@@ -144,6 +144,9 @@  clean_up() {
 			if (( PKGVERFUNC )); then
 				rm -f "${pkgbase}-${fullver}-${CARCH}-pkgver.log"*
 			fi
+			if (( VERIFYFUNC )); then
+				rm -f "${pkgbase}-${fullver}-${CARCH}-verify.log"*
+			fi
 			if (( PREPAREFUNC )); then
 				rm -f "${pkgbase}-${fullver}-${CARCH}-prepare.log"*
 			fi
@@ -447,6 +450,10 @@  run_function() {
 	fi
 }
 
+run_verify() {
+	run_function_safe "verify"
+}
+
 run_prepare() {
 	run_function_safe "prepare"
 }
@@ -973,6 +980,7 @@  while true; do
 		-m|--nocolor)     USE_COLOR='n'; PACMAN_OPTS+=("--color" "never") ;;
 		--noarchive)      NOARCHIVE=1 ;;
 		--nocheck)        RUN_CHECK='n' ;;
+		--noverify)       RUN_VERIFY='n' ;;
 		--noprepare)      RUN_PREPARE='n' ;;
 		--nosign)         SIGNPKG='n' ;;
 		-o|--nobuild)     BUILDPKG=0 NOBUILD=1 ;;
@@ -1093,7 +1101,7 @@  fi
 
 unset pkgname "${pkgbuild_schema_strings[@]}" "${pkgbuild_schema_arrays[@]}"
 unset "${known_hash_algos[@]/%/sums}"
-unset -f pkgver prepare build check package "${!package_@}"
+unset -f pkgver verify prepare build check package "${!package_@}"
 unset "${!makedepends_@}" "${!depends_@}" "${!source_@}" "${!checkdepends_@}"
 unset "${!optdepends_@}" "${!conflicts_@}" "${!provides_@}" "${!replaces_@}"
 unset "${!cksums_@}" "${!md5sums_@}" "${!sha1sums_@}" "${!sha224sums_@}"
@@ -1165,6 +1173,12 @@  if (( ${#pkgname[@]} > 1 )) || have_function package_${pkgname}; then
 fi
 
 # test for available PKGBUILD functions
+if have_function verify; then
+	# "Hide" verify() function if not going to be run
+	if [[ $RUN_VERIFY != "n" ]]; then
+		VERIFYFUNC=1
+	fi
+fi
 if have_function prepare; then
 	# "Hide" prepare() function if not going to be run
 	if [[ $RUN_PREPARE != "n" ]]; then
@@ -1312,6 +1326,7 @@  if (( !REPKG )); then
 		warning "$(gettext "Using existing %s tree")" "\$srcdir/"
 	else
 		download_sources
+		copy_sources
 		check_source_integrity
 		(( VERIFYSOURCE )) && exit $E_OK