diff options
author | Dan McGee <dan@archlinux.org> | 2011-10-04 13:37:12 -0500 |
---|---|---|
committer | Dan McGee <dan@archlinux.org> | 2011-10-04 13:37:12 -0500 |
commit | 8c621a75efc11f5c0c1876e44e6c0f849ce3e77d (patch) | |
tree | e7bd40762cf1dc7fc0bb63497c4174d8b47684c2 | |
parent | 03b579ee7e5c98d121da937be536a336d1120c43 (diff) | |
download | pacman-signing2.tar.gz pacman-signing2.zip |
WIP: pacman-key revoked and trusted interactive worksigning2
-rw-r--r-- | scripts/pacman-key.sh.in | 144 |
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() { |