[pacman-dev] [PATCH] pacman-key: rework importing distro/repo provided keyrings
Allan McRae
allan at archlinux.org
Wed Aug 17 20:49:43 EDT 2011
On 18/08/11 08:48, Dan McGee wrote:
> On Mon, Aug 15, 2011 at 8:10 AM, Allan McRae<allan at archlinux.org> wrote:
>> The current --reload option, apart from being non-clear in its naming,
>> is very limited in that only one keyring can be provided. A distribution
>> may want to provide multiple keyrings for various subsets of its
>> organisation or custom repo providers may also want to provide a keyring.
> Interesting thought. What happens here if a key is marked as OK in
> foo.gpg, but "revoked" in bar-revoked, as might happen if someone
> changes organizations?
Yeah.. that could be interesting. At the moment I believe revoking
anywhere takes precedence, but I will need to double check that. I
think this is something that entirely undocmuented HoldKey option can be
used for.
> Keeping arch and the TU and Dev groups in mind, you could see such a
> situation. However, I don't believe we would ever put a key in the
> revoked keyring unless we had really good reason to- this wouldn't
> just happen if someone left the dev team for instance.
>
> Not that timestamps are trustable in signatures themselves if the key
> used to sign is trusted, but is there any way to say "this key is
> valid but not if sigs using it were created after X time"? Clearly we
> can get bogged down in this but something worth thinking about.
I have absolutely no idea if that is even possible with gpg...
>> This patch adds a --populate option that reads keyrings from (by default)
>> /usr/share/pacman/keyrings. A keyring is named foo.gpg, with optional
>> foo-revoked file providing a list of revoked key ids. These files are
>> required to be signed (detached) by a key trusted by pacman-key, in
>> practise probably by the key that signed the package providing these
> practice
>> files. The --populate flag either updates the pacman keyring using all
>> keyrings in the directory or individual keyrings can be specified.
>>
>> Signed-off-by: Allan McRae<allan at archlinux.org>
>> ---
>> doc/pacman-key.8.txt | 8 ++-
>> scripts/Makefile.am | 1 +
>> scripts/pacman-key.sh.in | 149 +++++++++++++++++++++++-----------------------
>> 3 files changed, 82 insertions(+), 76 deletions(-)
>>
>> diff --git a/doc/pacman-key.8.txt b/doc/pacman-key.8.txt
>> index c8ce026..98ee6f6 100644
>> --- a/doc/pacman-key.8.txt
>> +++ b/doc/pacman-key.8.txt
>> @@ -80,8 +80,12 @@ Options
>> *-r, \--receive*<keyserver> <keyid(s)>::
>> Fetch the specified keyids from the specified key server URL.
>>
>> -*\--reload*::
>> - Reloads the keys from the keyring package.
>> +*\--populate* [<keyring(s)>]::
>> + Reload the default keys from the (given) keyrings in +{pkgdatadir}/keyrings+.
> (optionally provided) ?
>
>> + Each keyring is provided in a file foo.gpg that contains the keys for the foo
> filenames in `foo.gpg` backticks usually is the convention.
>> + keyring. Optionally the file foo-revoked contains a list of revoked key ids
> Optionally,<comma>
> `foo-revoked.gpg` (forgot the extension here too). Or did I
> misunderstand and this is a text file with IDs rather than an actual
> keyring file with binary data? This might require some thought, it
> looks like I did misunderstand.
> "IDs" is the capitalization used in the gpg manpage.
Yes - the foo-revoked file is a list of key IDs rather than a keyring.
I just went with extending what was already implemented previously so I
guess this is how it is done in apt-key. When you say "requires more
thought" do you mean in the description or implementation?
>> + for that keyring. These files are required to be signed (detached) by a
>> + trusted PGP key.
>>
>> *-u, \--updatedb*::
>> Equivalent to \--check-trustdb in GnuPG.
>> diff --git a/scripts/Makefile.am b/scripts/Makefile.am
>> index adb259a..30b6ad8 100644
>> --- a/scripts/Makefile.am
>> +++ b/scripts/Makefile.am
>> @@ -46,6 +46,7 @@ edit = sed \
>> -e 's|@localedir[@]|$(localedir)|g' \
>> -e 's|@sysconfdir[@]|$(sysconfdir)|g' \
>> -e 's|@localstatedir[@]|$(localstatedir)|g' \
>> + -e 's|@pkgdatadir[@]|$(pkgdatadir)|g' \
>> -e 's|@prefix[@]|$(prefix)|g' \
>> -e '1s|!/bin/bash|!$(BASH_SHELL)|g' \
>> -e 's|@PACKAGE_VERSION[@]|$(REAL_PACKAGE_VERSION)|g' \
>> diff --git a/scripts/pacman-key.sh.in b/scripts/pacman-key.sh.in
>> index 74ecfcf..c14d9bb 100644
>> --- a/scripts/pacman-key.sh.in
>> +++ b/scripts/pacman-key.sh.in
>> @@ -37,8 +37,8 @@ IMPORT_TRUSTDB=0
>> INIT=0
>> LISTKEYS=0
>> LISTSIGS=0
>> +POPULATE=0
>> RECEIVE=0
>> -RELOAD=0
>> UPDATEDB=0
>> VERIFY=0
>>
>> @@ -73,7 +73,8 @@ usage() {
>> echo "$(gettext " --import-trustdb<dir(s)> Imports ownertrust values from trustdb.gpg in dir(s)")"
>> echo "$(gettext " --init Ensure the keyring is properly initialized")"
>> echo "$(gettext " --list-sigs [<keyid(s)>] List keys and their signatures")"
>> - echo "$(gettext " --reload Reload the default keys")"
>> + printf "$(gettext " --populate [<keyring(s)] Reload the default keys from the (given) keyrings\n\
>> + in '%s'")\n" "@pkgdatadir@/keyrings"
>> }
>>
>> version() {
>> @@ -139,75 +140,87 @@ check_keyring() {
>>
>> verify_keyring_input() {
>> local ret=0;
>> + local KEYRING_IMPORT_DIR='@pkgdatadir@/keyrings'
>>
>> - # Verify signatures of related files, if they exist
>> - if [[ -r "${ADDED_KEYS}" ]]; then
>> - msg "$(gettext "Verifying official keys file signature...")"
>> - if ! "${GPG_PACMAN[@]}" --verify "${ADDED_KEYS}.sig"&>/dev/null; then
>> + # Verify signatures of keyring files and association revocation files if they exist
>> + msg "$(gettext "Verifying keyring file signatures...")"
>> + local keyring
>> + for keyring in ${KEYRINGIDS[@]}; do
>> + if ! "${GPG_PACMAN[@]}" --verify "${KEYRING_IMPORT_DIR}/${keyring}.gpg.sig"&>/dev/null; then
> So how do we do the initial bootstrap? Maybe we need a way (e.g.
> command line option) to override the verification?
The initial bootstrap is going to require a user to manually add a
key(s) and give it some trust. That key(s) would then be used to sign
the keyring (and the package it is distributed in) for the rest of the
repo. I can not see any sane way around that step.
<snip>
>> + for keyring in ${KEYRINGIDS[@]}; do
>> + if [[ -f "${KEYRING_IMPORT_DIR}/${keyring}-revoked" ]]; then
>> + while read key; do
>> + local key_values name
>> + key_values="$("${GPG_PACMAN[@]}" --quiet --with-colons --list-key "${key}" 2>/dev/null | grep ^pub | cut -d: -f5,10 --output-delimiter=' ')"
> A comment describing this madness line would be nice.
Sure... note that is just an indent change so I will need to figure it
out too!
>> + if [[ -n $key_values ]]; then
>> + # The first word is the key_id
>> + key_id="${key_values%% *}"
>> + # the rest if the name of the owner
>> + name="${key_values#* }"
>> + if [[ -n ${key_id} ]]; then
>> + # Mark this key to be deleted
>> + removed_ids[$key_id]="$name"
>> + fi
>> fi
>> - fi
>> - done< "${REMOVED_KEYS}"
>> - fi
>> + done< "${KEYRING_IMPORT_DIR}/${keyring}-revoked"
>> + fi
>> + done
>>
>> # List of keys that must be kept installed, even if in the list of keys to be removed
>> local HOLD_KEYS="$(get_from "$CONFIG" "HoldKeys")"
> This is something I hadn't noticed before. How exactly does this hold
> keys stuff work? man pacman-key, /hold shows me nothing.
Looks like this was never documented anywhere... My understanding is
that you can provide a list of keys to never be removed from the keyring
in using "HoldKey = " in pacman.conf.
Thinking about this, I'm not sure that is really an option for
pacman.conf, but it does seem like something that is a useful feature.
Suggestions for how it should be adjusted?
Allan
More information about the pacman-dev
mailing list