From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from lists.gentoo.org (pigeon.gentoo.org [208.92.234.80]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by finch.gentoo.org (Postfix) with ESMTPS id 45E851581F3 for ; Thu, 28 Nov 2024 13:10:13 +0000 (UTC) Received: from pigeon.gentoo.org (localhost [127.0.0.1]) by pigeon.gentoo.org (Postfix) with SMTP id 9A4C1E08C0; Thu, 28 Nov 2024 13:10:07 +0000 (UTC) Received: from smtp.gentoo.org (woodpecker.gentoo.org [140.211.166.183]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by pigeon.gentoo.org (Postfix) with ESMTPS id A38B8E08A6 for ; Thu, 28 Nov 2024 13:10:06 +0000 (UTC) Message-ID: Subject: Re: [gentoo-dev] [PATCH v2 1/2] sec-keys.eclass: new eclass From: =?UTF-8?Q?Micha=C5=82_G=C3=B3rny?= To: gentoo-dev@lists.gentoo.org Date: Thu, 28 Nov 2024 14:10:01 +0100 In-Reply-To: <20241128043320.1562802-2-eschwartz@gentoo.org> References: <20241127203042.1503004-1-eschwartz@gentoo.org> <20241128043320.1562802-1-eschwartz@gentoo.org> <20241128043320.1562802-2-eschwartz@gentoo.org> Organization: Gentoo Content-Type: multipart/signed; micalg="pgp-sha512"; protocol="application/pgp-signature"; boundary="=-kw7BMtizzLdrpjp1lsHX" User-Agent: Evolution 3.52.4 Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-Id: Gentoo Linux mail X-BeenThere: gentoo-dev@lists.gentoo.org Reply-to: gentoo-dev@lists.gentoo.org X-Auto-Response-Suppress: DR, RN, NRN, OOF, AutoReply MIME-Version: 1.0 X-Archives-Salt: 773be6c5-3ff6-44f2-a7eb-67c2a3c69757 X-Archives-Hash: 28f087b8454a01d8edcc6e4d56077801 --=-kw7BMtizzLdrpjp1lsHX Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable On Wed, 2024-11-27 at 23:32 -0500, Eli Schwartz wrote: > +# @ECLASS_VARIABLE: SEC_KEYS_VALIDPGPKEYS > +# @PRE_INHERIT > +# @DEFAULT_UNSET > +# @DESCRIPTION: > +# Mapping of fingerprints, name, and optional location of PGP keys to in= clude, So "location" or "locations", plural? > +# separated by colons. The allowed values for a location are: > +# > +# - gentoo -- fetch key by fingerprint from https://keys.gentoo.org > +# > +# - github -- fetch key from github.com/${name}.pgp > +# > +# - openpgp -- fetch key by fingerprint from https://keys.openpgp.org > +# > +# - ubuntu -- fetch key by fingerprint from http://keyserver.ubuntu.com= (the default) I'd go without a default. Typing 6 more letters doesn't cost anything, and makes the contents more consistent. Also saves us from regretting having chosen a bad default in the future. > +# > +# - none -- do not add to SRC_URI, the ebuild will provide a custom dow= nload location Perhaps "manual"? "None" sounds like there would be no key at all. > +_sec_keys_set_globals() { > + if [[ ${SEC_KEYS_VALIDPGPKEYS[*]} ]]; then > + local key fingerprint name loc locations=3D() remote > + for key in "${SEC_KEYS_VALIDPGPKEYS[@]}"; do > + fingerprint=3D${key%%:*} > + name=3D${key#${fingerprint}:}; name=3D${name%%:*} > + IFS=3D, read -r -a locations <<<"${key##*:}" > + [[ ${locations[@]} ]] || locations=3D(ubuntu) > + for loc in "${locations[@]}"; do > + case ${loc} in > + gentoo) remote=3D"https://keys.gentoo.org/pks/lookup?op=3Dget&searc= h=3D0x${fingerprint}";; > + github) remote=3D"https://github.com/${name}.gpg";; > + openpgp) remote=3D"https://keys.openpgp.org/vks/v1/by-fingerprint/$= {fingerprint}";; > + ubuntu) remote=3D"https://keyserver.ubuntu.com/pks/lookup?op=3Dget&= search=3D0x${fingerprint}";; > + # provided via manual SRC_URI > + none) continue;; > + *) die "${ECLASS}: unknown PGP key remote: ${loc}";; > + Stray empty line. > + esac > + SRC_URI+=3D" > + ${remote} -> openpgp-keys-${name}-${loc}-${PV}.asc > + " > + done > + done > + fi > +} > +_sec_keys_set_globals > +unset -f _sec_keys_set_globals > + > +IUSE=3D"test" > +PROPERTIES=3D"test_network" > +RESTRICT=3D"test" > + > +BDEPEND=3D" > + app-crypt/gnupg > + test? ( app-crypt/pgpdump ) > +" > +S=3D${WORKDIR} > + > +LICENSE=3D"public-domain" > +SLOT=3D"0" Please keep ebuildy variables in the standard/skel order, or at least as close to it as you can get. > +# @FUNCTION: sec-keys_src_compile > +# @DESCRIPTION: > +# Default src_compile override that imports all public keys into a keyri= ng, > +# and validates that they are listed in SEC_KEYS_VALIDPGPKEYS. > +sec-keys_src_compile() { > + local -x GNUPGHOME=3D${WORKDIR}/gnupg > + mkdir -m700 -p "${GNUPGHOME}" || die > + > + pushd "${DISTDIR}" >/dev/null || die > + gpg --import ${A} || die > + popd >/dev/null || die > + > + local line imported_keys=3D() found=3D0 > + while IFS=3D: read -r -a line; do > + if [[ ${line[0]} =3D pub ]]; then Please use '=3D=3D' in ebuilds and eclasses. > + # new key > + found=3D0 > + elif [[ ${found} =3D 0 && ${line[0]} =3D fpr ]]; then > + # primary fingerprint > + imported_keys+=3D("${line[9]}") > + found=3D1 > + fi > + done < <(gpg --batch --list-keys --keyid-format=3Dlong --with-colons ||= die) Why do you need --keyid-format? You're using fingerprints only, aren't you? > + > + printf '%s\n' "${imported_keys[@]}" | sort > imported_keys.list || die > + printf '%s\n' "${SEC_KEYS_VALIDPGPKEYS[@]%%:*}" | sort > allowed_keys.l= ist || die > + > + local extra_keys=3D($(comm -23 imported_keys.list allowed_keys.list || = die)) > + local missing_keys=3D($(comm -13 imported_keys.list allowed_keys.list |= | die)) > + > + if [[ ${#extra_keys[@]} !=3D 0 ]]; then > + die "too many keys found. Suspicious keys: ${extra_keys[@]}" The first sentence is not capitalized. > + fi > + if [[ ${#missing_keys[@]} !=3D 0 ]]; then > + die "too few keys found. Unavailable keys: ${missing_keys[@]}" > + fi > +} > + > + > +sec-keys_src_test() { > + local -x GNUPGHOME=3D${WORKDIR}/gnupg > + local key fingerprint name server > + local gpg_command=3D(gpg --export-options export-minimal) > + > + for fingerprint in "${SEC_KEYS_VALIDPGPKEYS[@]%%:*}"; do > + "${gpg_command[@]}" --export "${fingerprint}" | pgpdump > "${fingerpri= nt}.pgpdump" || die > + done > + > + # Best-effort attempt to check for updates. keyservers can and usually = do > + # fail for weird reasons, (such as being unable to import a key without= a > + # uid) as well as normal reasons, like the key being exclusive to a > + # different keyserver. this isn't a reason to fail src_test. Well, I dare say that if refreshing against the server specified as the reference source fails, that would count as a reason to fail.=20 Consider the case of someone removing a compromised key instead of revoking it. > + for server in keys.gentoo.org keys.openpgp.org keyserver.ubuntu.com; do > + gpg --refresh-keys --keyserver "hkps://${server}" > + done > + for key in "${SEC_KEYS_VALIDPGPKEYS[@]}"; do > + if [[ ${key##*:} =3D *github* ]]; then > + name=3D${key#*:}; name=3D${name%%:*} > + wget -qO- https://github.com/${name}.gpg | gpg --import || die > + fi > + done > + > + for fingerprint in "${SEC_KEYS_VALIDPGPKEYS[@]%%:*}"; do > + "${gpg_command[@]}" --export "${fingerprint}" | pgpdump > "${fingerpri= nt}.pgpdump.new" || die > + diff -u "${fingerprint}.pgpdump" "${fingerprint}.pgpdump.new" || die "= updates available for PGP key: ${fingerprint}" > + done > + > +} > + > +# @FUNCTION: sec-keys_src_install > +# @DESCRIPTION: > +# Default src_install override that minifies and exports all PGP public = keys > +# into an ascii-armored keyfile installed to the standard /usr/share/ope= npgp-keys. > +sec-keys_src_install() { > + local -x GNUPGHOME=3D${WORKDIR}/gnupg > + local fingerprint > + local gpg_command=3D(gpg --no-permission-warning --export-options expor= t-minimal) > + > + for fingerprint in "${SEC_KEYS_VALIDPGPKEYS[@]%%:*}"; do > + local uids=3D() > + mapfile -t uids < <("${gpg_command[@]}" --list-key --with-colons ${fin= gerprint} | awk -F: '/^uid/{print $10}' || die) > + edo "${gpg_command[@]}" "${uids[@]/#/--comment=3D}" --export --armor "= ${fingerprint}" >> ${PN#openpgp-keys-}.asc > + done That looks like something you could do in src_compile() already. Also, I'm confused by the purpose of this whole logic. After all, you have already verified that there are no stray keys in the keyring, right? So why not just export the whole thing? --=20 Best regards, Micha=C5=82 G=C3=B3rny --=-kw7BMtizzLdrpjp1lsHX Content-Type: application/pgp-signature; name="signature.asc" Content-Description: This is a digitally signed message part -----BEGIN PGP SIGNATURE----- iQFGBAABCgAwFiEEx2qEUJQJjSjMiybFY5ra4jKeJA4FAmdIa6kSHG1nb3JueUBn ZW50b28ub3JnAAoJEGOa2uIyniQOVhgH/2j0WF3p7/pDuQtUXG1ZI8JnP1qfsqhK pQPN/f4iOh5QHc30IlC1lqEl80H5yZiSyDPxoJLABDWl99DcFuOuuKGEJD5nM1ZW 07VZEUMNYl9aMDA310AV7MidMUVqmpECYVTOfFLcHlLWHqpcsjisFQ7ryUJHztVP sfOyR1HEVYTSVqOaFOiGmatk1qTYylOkC0dEaTgCOsuVRThoe5G1Ac4HUVDAenTH YIDRFp3K/p9/h2teK3YxaTTAGp2ELYB/5koN9rszaXIhvEZ3iLAXndwzpwqDlk74 XnF13DneHclKR2sz23qJgLqd+le/AZ4jX+LTEV/Nu6FGfu+m6Qmvco0= =qLyG -----END PGP SIGNATURE----- --=-kw7BMtizzLdrpjp1lsHX--