summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan McGee <dan@archlinux.org>2011-10-04 13:37:12 -0500
committerDan McGee <dan@archlinux.org>2011-10-04 13:37:12 -0500
commit8c621a75efc11f5c0c1876e44e6c0f849ce3e77d (patch)
treee7bd40762cf1dc7fc0bb63497c4174d8b47684c2
parent03b579ee7e5c98d121da937be536a336d1120c43 (diff)
downloadpacman-signing2.tar.gz
pacman-signing2.zip
WIP: pacman-key revoked and trusted interactive worksigning2
-rw-r--r--scripts/pacman-key.sh.in144
1 files changed, 86 insertions, 58 deletions
diff --git a/scripts/pacman-key.sh.in b/scripts/pacman-key.sh.in
index 482e0468..7cf85dde 100644
--- a/scripts/pacman-key.sh.in
+++ b/scripts/pacman-key.sh.in
@@ -49,6 +49,22 @@ DEFAULT_KEYSERVER='hkp://keys.gnupg.net'
m4_include(library/output_format.sh)
+question() {
+ local mesg=$1; shift
+ local default=$1; shift
+ local yesno answer
+ [[ $default == "y" ]] && yesno=$(gettext "[Y/n]") || yesno=$(gettext "[y/N]")
+ printf "==> ${mesg} ${yesno} " "$@" >&1
+ read answer
+ answer=$(tr '[:lower:]' '[:upper:]' <<< "$answer")
+ if [[ $answer = $(gettext YES) || $answer = $(gettext Y) ]]; then
+ return 0
+ elif [[ $default = "y" && -z $answer ]]; then
+ return 0
+ fi
+ return 1
+}
+
m4_include(library/parse_options.sh)
usage() {
@@ -215,19 +231,14 @@ verify_keyring_input() {
local ret=0;
local KEYRING_IMPORT_DIR='@pkgdatadir@/keyrings'
- # Verify signatures of keyring files and trusted/revoked files if they exist
+ # Verify signatures of keyring files and trust files if they exist
msg "$(gettext "Verifying keyring file signatures...")"
local keyring keyfile
for keyring in "${KEYRINGIDS[@]}"; do
keyfile="${KEYRING_IMPORT_DIR}/${keyring}.gpg"
validate_with_gpg "${keyfile}" || ret=1
- keyfile="${KEYRING_IMPORT_DIR}/${keyring}-trusted"
- if [[ -f "${keyfile}" ]]; then
- validate_with_gpg "${keyfile}" || ret=1
- fi
-
- keyfile="${KEYRING_IMPORT_DIR}/${keyring}-revoked"
+ keyfile="${KEYRING_IMPORT_DIR}/${keyring}-trust"
if [[ -f "${keyfile}" ]]; then
validate_with_gpg "${keyfile}" || ret=1
fi
@@ -269,72 +280,89 @@ populate_keyring() {
verify_keyring_input || exit 1
# Variable used for iterating on keyrings
- local key
- local key_id
+ local keyfile keycount
+ local -a keyrings
# Add keys from requested keyrings
for keyring in "${KEYRINGIDS[@]}"; do
- msg "$(gettext "Appending keys from %s.gpg...")" "$keyring"
- "${GPG_PACMAN[@]}" --import "${KEYRING_IMPORT_DIR}/${keyring}.gpg"
+ keyfile="${KEYRING_IMPORT_DIR}/${keyring}.gpg"
+ keycount=$("${GPG_PACMAN[@]}" --no-default-keyring --keyring "${keyfile}" --list-keys --with-colons | grep -c "^pub:")
+ if question "$(gettext "Do you wish to import %s keys from %s?")" "y" "${keycount}" "${keyring}.gpg"; then
+ msg "$(gettext "Importing keys from %s...")" "${keyring}.gpg"
+ "${GPG_PACMAN[@]}" --import "${keyfile}"
+ # later steps depend on knowing if we imported keys here
+ keyrings+=("${keyring}")
+ fi
done
- # Read the trusted key IDs to an array. Because this is an ownertrust
- # file, we know we have the full 40 hex digit fingerprint values.
- # Format of ownertrust dump file:
+
+ # Read the owner trust key IDs and locally sign and/or import owner trust.
+ # Because this is an ownertrust file, we know we have the full 40 hex digit
+ # fingerprint values. Format of ownertrust dump file:
# 40CHARFINGERPRINTXXXXXXXXXXXXXXXXXXXXXXX:6:
# 40CHARFINGERPRINTXXXXXXXXXXXXXXXXXXXXXXX:5:
- local -A trusted_ids
- for keyring in "${KEYRINGIDS[@]}"; do
- if [[ -f "${KEYRING_IMPORT_DIR}/${keyring}-trusted" ]]; then
+ local -a trustvals
+ # Possible ownertrust values are in range 0-6, corresponding to:
+ trustvals=('Unknown' 'Expired' 'Undefined' 'Never' 'Marginal' 'Fully' 'Ultimate')
+ # and the not so normal one
+ trustvals[128]='Disabled'
+ declare -r trustvals
+
+ local first_key=1 key key_id key_trust
+ local -A existing_trust
+ while read key; do
+ # skip comments; these are valid in this file
+ [[ $key = \#* ]] && continue
+ if [[ -n ${key} ]]; then
+ key_id="${key%%:*}"
+ key_trust="${key#*:}"
+ key_trust="${key_trust%:}"
+ existing_trust[$key_id]=${key_trust}
+ fi
+ done < <("${GPG_PACMAN[@]}" --export-ownertrust)
+
+ for keyring in "${keyrings[@]}"; do
+ keyfile="${KEYRING_IMPORT_DIR}/${keyring}-trust"
+ if [[ -f ${keyfile} ]]; then
+ local -a trusted_ids
while read key; do
# skip comments; these are valid in this file
[[ $key = \#* ]] && continue
+ if [[ -n ${key} ]]; then
+ trusted_ids+=("${key}")
+ fi
+ done < "${keyfile}"
+
+ for key in "${trusted_ids[@]}"; do
+ if (( first_key )); then
+ msg "$(gettext "\
+You will be asked to locally sign each trusted key if it is not already\n\
+ signed. Additionally you will be prompted to set the owner trust level.\n\
+ For more information on why this is necessary, please consult the\n\
+ pacman-key(8) manpage.")"
+ first_key=0
+ fi
key_id="${key%%:*}"
- if [[ -n ${key_id} ]]; then
- # Mark this key to be lsigned
- trusted_ids[$key_id]="${keyring}"
+ key_trust="${key#*:}"
+ key_trust="${key_trust%:}"
+ if (( !(key_trust & 128) )); then
+ msg2 "$(gettext "Signing key %s...")" "${key_id}"
+ "${GPG_PACMAN[@]}" --quiet --lsign-key "${key_id}"
+ else
+ msg2 "$(gettext "Disabling key %s...")" "${key_id}"
+ "${GPG_PACMAN[@]}" --quiet --list-key "${key_id}"
fi
- done < "${KEYRING_IMPORT_DIR}/${keyring}-trusted"
- fi
- done
-
- if (( ${#trusted_ids[@]} > 0 )); then
- msg "$(gettext "Locally signing trusted keys in keyring...")"
- for key_id in "${!trusted_ids[@]}"; do
- msg2 "$(gettext "Locally signing key %s...")" "${key_id}"
- "${GPG_PACMAN[@]}" --quiet --lsign-key "${key_id}"
- done
- msg "$(gettext "Importing owner trust values...")"
- for keyring in "${KEYRINGIDS[@]}"; do
- if [[ -f "${KEYRING_IMPORT_DIR}/${keyring}-trusted" ]]; then
- "${GPG_PACMAN[@]}" --import-ownertrust "${KEYRING_IMPORT_DIR}/${keyring}-trusted"
- fi
- done
- fi
-
- # Read the revoked key IDs to an array. The conversion from whatever is
- # inside the file to key ids is important, because key ids are the only
- # guarantee of identification for the keys.
- local -A revoked_ids
- for keyring in "${KEYRINGIDS[@]}"; do
- if [[ -f "${KEYRING_IMPORT_DIR}/${keyring}-revoked" ]]; then
- while read key; do
- key_id="$("${GPG_PACMAN[@]}" --quiet --with-colons --list-key "${key}" 2>/dev/null | grep ^pub | cut -d: -f5)"
- if [[ -n ${key_id} ]]; then
- # Mark this key to be disabled
- revoked_ids[$key_id]="${keyring}"
+ # TODO: only ask if different than stored value
+ if [[ ${existing_trust[$key_id]} != ${key_trust} ]]; then
+ if question "$(gettext "Do you wish to apply owner trust '%s' to this key?")" \
+ "y" "${trustvals[$key_trust]}"; then
+ echo "${key_id}:${key_trust}:" | "${GPG_PACMAN[@]}" --import-ownertrust
+ fi
fi
- done < "${KEYRING_IMPORT_DIR}/${keyring}-revoked"
+ done
+ unset trusted_ids
fi
done
-
- if (( ${#revoked_ids[@]} > 0 )); then
- msg "$(gettext "Disabling revoked keys in keyring...")"
- for key_id in "${!revoked_ids[@]}"; do
- msg2 "$(gettext "Disabling key %s...")" "${key_id}"
- printf 'disable\nquit\n' | LANG=C "${GPG_PACMAN[@]}" --command-fd 0 --quiet --batch --edit-key "${key_id}" 2>/dev/null
- done
- fi
}
edit_keys() {