From 7d205a70a26f1c3d283e995ec590b6838eb8283d Mon Sep 17 00:00:00 2001 From: Allan McRae Date: Wed, 6 Jul 2011 03:05:08 +1000 Subject: pacman-key: use our option parser MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The pacman-key script is complicated enough to warrent usage of the parse_options script. This is especially helpful in dealing with all the configuration file override flags as the no longer need to be specified first. It also allows us to do the right thing early with --help/--version and no option cases cleanly. This change also makde the check for root privileges only occur on operations where they are needed. This patch is inspired by and supercedes some patches submitted by Denis A. Altoé Falqueto and Ivan Kanakarakis who were altering the previous option handling in an attempt to deal with the above issues. Signed-off-by: Allan McRae --- scripts/pacman-key.sh.in | 191 ++++++++++++++++++++++++----------------------- 1 file changed, 98 insertions(+), 93 deletions(-) diff --git a/scripts/pacman-key.sh.in b/scripts/pacman-key.sh.in index 833943cb..4056451f 100644 --- a/scripts/pacman-key.sh.in +++ b/scripts/pacman-key.sh.in @@ -26,20 +26,30 @@ export TEXTDOMAINDIR='@localedir@' myver="@PACKAGE_VERSION@" +# Options +ADD=0 +ADVANCED=0 +DELETE=0 +EXPORT=0 +FINGER=0 +LIST=0 +RECEIVE=0 +RELOAD=0 +TRUST=0 +UPDATEDB=0 + m4_include(library/output_format.sh) +m4_include(library/parse_options.sh) + usage() { printf "pacman-key (pacman) %s\n" ${myver} echo - printf "$(gettext "Usage: %s [options] [arguments]")\n" $(basename $0) + printf "$(gettext "Usage: %s [options]")\n" $(basename $0) echo printf "$(gettext "Manage pacman\'s list of trusted keys")\n" echo - echo "$(gettext "Options must be placed before commands. The available options are:")" - printf "$(gettext " --config Use an alternate config file (instead of '%s')")\n" "$CONFIG" - printf "$(gettext " --gpgdir Set an alternate directory for gnupg (instead of '%s')")\n" "$PACMAN_KEYRING_DIR" - echo - echo "$(gettext "The available commands are:")" + echo "$(gettext "Options:")" echo "$(gettext " -a, --add [] Add the specified keys (empty for stdin)")" echo "$(gettext " -d, --del Remove the specified keyids")" echo "$(gettext " -e, --export Export the specified keyids")" @@ -51,8 +61,11 @@ usage() { echo "$(gettext " -u, --updatedb Update the trustdb of pacman")" echo "$(gettext " -V, --version Show program version")" echo "$(gettext " --adv Use pacman's keyring with advanced gpg commands")" - printf "$(gettext " --reload Reload the default keys")" - echo + echo "$(gettext " --config Use an alternate config file")" + printf "$(gettext " (instead of '%s')")\n" "@sysconfdir@/pacman.conf" + echo "$(gettext " --gpgdir Set an alternate directory for gnupg")" + printf "$(gettext " (instead of '%s')")\n" "@sysconfdir@/pacman.d/gnupg" + echo "$(gettext " --reload Reload the default keys")" } version() { @@ -198,116 +211,108 @@ if ! type gettext &>/dev/null; then } fi -if [[ $1 != "--version" && $1 != "-V" && $1 != "--help" && $1 != "-h" && $1 != "" ]]; then - if type -p gpg >/dev/null 2>&1 = 1; then - error "$(gettext "gnupg does not seem to be installed.")" - msg2 "$(gettext "pacman-key requires gnupg for most operations.")" - exit 1 - elif (( EUID != 0 )); then - error "$(gettext "pacman-key needs to be run as root.")" - exit 1 - fi +OPT_SHORT="a::d:e:f::hlr:t:uV" +OPT_LONG="add::,adv:,config:,del:,export:,finger::,gpgdir:,help,list" +OPT_LONG+=",receive:,reload,trust:,updatedb,version" +if ! OPT_TEMP="$(parse_options $OPT_SHORT $OPT_LONG "$@")"; then + echo; usage; exit 1 # E_INVALID_OPTION; +fi +eval set -- "$OPT_TEMP" +unset OPT_SHORT OPT_LONG OPT_TEMP + +if [[ $1 == "--" ]]; then + usage; + exit 0; fi -# Parse global options -CONFIG="@sysconfdir@/pacman.conf" -PACMAN_KEYRING_DIR="@sysconfdir@/pacman.d/gnupg" -while [[ $1 =~ ^--(config|gpgdir)$ ]]; do +while true; do case "$1" in - --config) shift; CONFIG="$1" ;; - --gpgdir) shift; PACMAN_KEYRING_DIR="$1" ;; + -a|--add) ADD=1; [[ -n $2 && ${2:0:1} != "-" ]] && shift && KEYFILES=($1) ;; + --adv) ADVANCED=1; shift; ARGUMENTS=($1) ;; + --config) shift; CONFIG=$1 ;; + -d|--del) DELETE=1; shift; KEYIDS=($1) ;; + -e|--export) EXPORT=1; shift; KEYIDS=($1) ;; + -f|--finger) FINGER=1; [[ -n $2 && ${2:0:1} != "-" ]] && shift && KEYIDS=($1) ;; + --gpgdir) shift; PACMAN_KEYRING_DIR=$1 ;; + -l|--list) LIST=1 ;; + -r|--receive) RECEIVE=1; shift; KEYSERVER="${1[0]}"; KEYIDS=("${1[@]:1}") ;; + --reload) RELOAD=1 ;; + -t|--trust) TRUST=1; shift; KEYIDS=($1) ;; + -u|--updatedb) UPDATEDB=1 ;; + + -h|--help) usage; exit 0 ;; + -V|--version) version; exit 0 ;; + + --) OPT_IND=0; shift; break;; + *) usage; exit 1 ;; esac shift done + +if ! type -p gpg >/dev/null; then + error "$(gettext "Cannot find the %s binary required for all %s operations.")" "gpg" "pacman-key" + exit 1 +fi + +if (( (ADD || ADVANCED || DELETE || RECEIVE || RELOAD || TRUST || UPDATEDB) && EUID != 0 )); then + error "$(gettext "%s needs to be run as root for this operation.")" "pacman-key" + exit 1 +fi + +CONFIG=${CONFIG:-@sysconfdir@/pacman.conf} if [[ ! -r "${CONFIG}" ]]; then - error "$(gettext "%s not found.")" "$CONFIG" + error "$(gettext "%s configuation file '%s' not found.")" "pacman" "$CONFIG" exit 1 fi -# Read GPGDIR from $CONFIG. -if [[ GPGDIR=$(get_from "$CONFIG" "GPGDir") == 0 ]]; then +# Get GPGDIR from pacman.conf iff not specified on command line +if [[ -z PACMAN_KEYRING_DIR && GPGDIR=$(get_from "$CONFIG" "GPGDir") == 0 ]]; then PACMAN_KEYRING_DIR="${GPGDIR}" fi -GPG_PACMAN="gpg --homedir ${PACMAN_KEYRING_DIR} --no-permission-warning" +PACMAN_KEYRING_DIR=${PACMAN_KEYRING_DIR:-@sysconfdir@/pacman.d/gnupg} # Try to create $PACMAN_KEYRING_DIR if non-existent # Check for simple existence rather than for a directory as someone may want # to use a symlink here [[ -e ${PACMAN_KEYRING_DIR} ]] || mkdir -p -m 755 "${PACMAN_KEYRING_DIR}" -# Parse and execute command -command="$1" -if [[ -z "${command}" ]]; then - usage - exit 1 +GPG_PACMAN="gpg --homedir ${PACMAN_KEYRING_DIR} --no-permission-warning" + + +(( ADD )) && ${GPG_PACMAN} --quiet --batch --import "${KEYFILES[@]}" +(( DELETE )) && ${GPG_PACMAN} --quiet --batch --delete-key --yes "${KEYIDS[@]}" +(( EXPORT )) && ${GPG_PACMAN} --armor --export "${KEYIDS[@]}" +(( FINGER )) && ${GPG_PACMAN} --batch --fingerprint "${KEYIDS[@]}" +(( LIST )) && ${GPG_PACMAN} --batch --list-sigs "${KEYIDS[@]}" +(( RELOAD )) && reload_keyring +(( UPDATEDB )) && ${GPG_PACMAN} --batch --check-trustdb + +if (( ADVANCED )); then + msg "$(gettext "Executing: %s %s")" "${GPG_PACMAN}" "${ARGUMENTS[@]}" + ${GPG_PACMAN} "${ARGUMENTS[@]}" || ret=$? + exit $ret fi -shift - -case "${command}" in - -a|--add) - # If there is no extra parameter, gpg will read stdin - ${GPG_PACMAN} --quiet --batch --import "$@" - ;; - -d|--del) - if (( $# == 0 )); then - error "$(gettext "You need to specify at least one key identifier")" - exit 1 - fi - ${GPG_PACMAN} --quiet --batch --delete-key --yes "$@" - ;; - -u|--updatedb) - ${GPG_PACMAN} --batch --check-trustdb - ;; - --reload) - reload_keyring - ;; - -l|--list) - ${GPG_PACMAN} --batch --list-sigs "$@" - ;; - -f|--finger) - ${GPG_PACMAN} --batch --fingerprint "$@" - ;; - -e|--export) - ${GPG_PACMAN} --armor --export "$@" - ;; - -r|--receive) - if (( $# < 2 )); then - error "$(gettext "You need to specify the keyserver and at least one key identifier")" - exit 1 - fi - keyserver="$1" - shift - ${GPG_PACMAN} --keyserver "${keyserver}" --recv-keys "$@" - ;; - -t|--trust) - if (( $# == 0 )); then - error "$(gettext "You need to specify at least one key identifier")" - exit 1 - fi - while (( $# > 0 )); do + +if (( RECEIVE )); then + if [[ -z ${KEYIDS[@]} ]]; then + error "$(gettext "You need to specify the keyserver and at least one key identifier")" + exit 1 + fi + ${GPG_PACMAN} --keyserver "$KEYSERVER" --recv-keys "${KEYIDS[@]}" +fi + +if (( TRUST )); then + for key in ${KEYIDS[@]}; do # Verify if the key exists in pacman's keyring - if ${GPG_PACMAN} --list-keys "$1" > /dev/null 2>&1; then - ${GPG_PACMAN} --edit-key "$1" + if ${GPG_PACMAN} --list-keys "$key" > /dev/null 2>&1; then + ${GPG_PACMAN} --edit-key "$key" else - error "$(gettext "The key identified by %s doesn't exist")" "$1" + error "$(gettext "The key identified by %s does not exist")" "$key" exit 1 fi shift done - ;; - --adv) - msg "$(gettext "Executing: %s ")$*" "${GPG_PACMAN}" - ${GPG_PACMAN} "$@" || ret=$? - exit $ret - ;; - -h|--help) - usage; exit 0 ;; - -V|--version) - version; exit 0 ;; - *) - error "$(gettext "Unknown command:") $command" - usage; exit 1 ;; -esac +fi # vim: set ts=2 sw=2 noet: -- cgit v1.2.3-2-g168b From 95d7e1616361ab2b2be38ba5283328f6f9312012 Mon Sep 17 00:00:00 2001 From: Allan McRae Date: Wed, 6 Jul 2011 03:27:23 +1000 Subject: pacman-key: remove the --adv option The conversion to using parse_options causes this option to break. It is preferable to remove the option rather than fix it as it is simply a wrapper for "gpg --homedir @sysconfdir@/pacman.d/gnupg". Any user using more advanced keyring management than provided by pacman-key can manage to point gpg at the right place themselves... How to manually edit the keyring with gpg will instead be documented in the man page in a later commit. Signed-off-by: Allan McRae --- scripts/pacman-key.sh.in | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/scripts/pacman-key.sh.in b/scripts/pacman-key.sh.in index 4056451f..a55cd7ef 100644 --- a/scripts/pacman-key.sh.in +++ b/scripts/pacman-key.sh.in @@ -28,7 +28,6 @@ myver="@PACKAGE_VERSION@" # Options ADD=0 -ADVANCED=0 DELETE=0 EXPORT=0 FINGER=0 @@ -60,7 +59,6 @@ usage() { echo "$(gettext " -t, --trust Set the trust level of the given keyids")" echo "$(gettext " -u, --updatedb Update the trustdb of pacman")" echo "$(gettext " -V, --version Show program version")" - echo "$(gettext " --adv Use pacman's keyring with advanced gpg commands")" echo "$(gettext " --config Use an alternate config file")" printf "$(gettext " (instead of '%s')")\n" "@sysconfdir@/pacman.conf" echo "$(gettext " --gpgdir Set an alternate directory for gnupg")" @@ -212,7 +210,7 @@ if ! type gettext &>/dev/null; then fi OPT_SHORT="a::d:e:f::hlr:t:uV" -OPT_LONG="add::,adv:,config:,del:,export:,finger::,gpgdir:,help,list" +OPT_LONG="add::,config:,del:,export:,finger::,gpgdir:,help,list" OPT_LONG+=",receive:,reload,trust:,updatedb,version" if ! OPT_TEMP="$(parse_options $OPT_SHORT $OPT_LONG "$@")"; then echo; usage; exit 1 # E_INVALID_OPTION; @@ -228,7 +226,6 @@ fi while true; do case "$1" in -a|--add) ADD=1; [[ -n $2 && ${2:0:1} != "-" ]] && shift && KEYFILES=($1) ;; - --adv) ADVANCED=1; shift; ARGUMENTS=($1) ;; --config) shift; CONFIG=$1 ;; -d|--del) DELETE=1; shift; KEYIDS=($1) ;; -e|--export) EXPORT=1; shift; KEYIDS=($1) ;; @@ -255,7 +252,7 @@ if ! type -p gpg >/dev/null; then exit 1 fi -if (( (ADD || ADVANCED || DELETE || RECEIVE || RELOAD || TRUST || UPDATEDB) && EUID != 0 )); then +if (( (ADD || DELETE || RECEIVE || RELOAD || TRUST || UPDATEDB) && EUID != 0 )); then error "$(gettext "%s needs to be run as root for this operation.")" "pacman-key" exit 1 fi @@ -288,12 +285,6 @@ GPG_PACMAN="gpg --homedir ${PACMAN_KEYRING_DIR} --no-permission-warning" (( RELOAD )) && reload_keyring (( UPDATEDB )) && ${GPG_PACMAN} --batch --check-trustdb -if (( ADVANCED )); then - msg "$(gettext "Executing: %s %s")" "${GPG_PACMAN}" "${ARGUMENTS[@]}" - ${GPG_PACMAN} "${ARGUMENTS[@]}" || ret=$? - exit $ret -fi - if (( RECEIVE )); then if [[ -z ${KEYIDS[@]} ]]; then error "$(gettext "You need to specify the keyserver and at least one key identifier")" -- cgit v1.2.3-2-g168b From 8ee0724558a33e224c06dddd63d6560d6e41cb44 Mon Sep 17 00:00:00 2001 From: Allan McRae Date: Wed, 6 Jul 2011 03:34:04 +1000 Subject: pacman-key: rename --del to --delete There is already the short -d alias provided, so stay verbose with the longer option name. Signed-off-by: Allan McRae --- scripts/pacman-key.sh.in | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/pacman-key.sh.in b/scripts/pacman-key.sh.in index a55cd7ef..2561f91c 100644 --- a/scripts/pacman-key.sh.in +++ b/scripts/pacman-key.sh.in @@ -50,7 +50,7 @@ usage() { echo echo "$(gettext "Options:")" echo "$(gettext " -a, --add [] Add the specified keys (empty for stdin)")" - echo "$(gettext " -d, --del Remove the specified keyids")" + echo "$(gettext " -d, --delete Remove the specified keyids")" echo "$(gettext " -e, --export Export the specified keyids")" echo "$(gettext " -f, --finger [] List fingerprint for specified or all keyids")" echo "$(gettext " -h, --help Show this help message and exit")" @@ -210,7 +210,7 @@ if ! type gettext &>/dev/null; then fi OPT_SHORT="a::d:e:f::hlr:t:uV" -OPT_LONG="add::,config:,del:,export:,finger::,gpgdir:,help,list" +OPT_LONG="add::,config:,delete:,export:,finger::,gpgdir:,help,list" OPT_LONG+=",receive:,reload,trust:,updatedb,version" if ! OPT_TEMP="$(parse_options $OPT_SHORT $OPT_LONG "$@")"; then echo; usage; exit 1 # E_INVALID_OPTION; @@ -227,7 +227,7 @@ while true; do case "$1" in -a|--add) ADD=1; [[ -n $2 && ${2:0:1} != "-" ]] && shift && KEYFILES=($1) ;; --config) shift; CONFIG=$1 ;; - -d|--del) DELETE=1; shift; KEYIDS=($1) ;; + -d|--delete) DELETE=1; shift; KEYIDS=($1) ;; -e|--export) EXPORT=1; shift; KEYIDS=($1) ;; -f|--finger) FINGER=1; [[ -n $2 && ${2:0:1} != "-" ]] && shift && KEYIDS=($1) ;; --gpgdir) shift; PACMAN_KEYRING_DIR=$1 ;; -- cgit v1.2.3-2-g168b From b300b991a7c489731f7e30117be169f69ffb8745 Mon Sep 17 00:00:00 2001 From: Allan McRae Date: Wed, 6 Jul 2011 03:41:52 +1000 Subject: pacman-key: allow the export of all key ids The gpg --export will exprt all keys if none are specified. Replicate this behavior in pacman-key. Signed-off-by: Allan McRae --- scripts/pacman-key.sh.in | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/pacman-key.sh.in b/scripts/pacman-key.sh.in index 2561f91c..cf8c840e 100644 --- a/scripts/pacman-key.sh.in +++ b/scripts/pacman-key.sh.in @@ -51,7 +51,7 @@ usage() { echo "$(gettext "Options:")" echo "$(gettext " -a, --add [] Add the specified keys (empty for stdin)")" echo "$(gettext " -d, --delete Remove the specified keyids")" - echo "$(gettext " -e, --export Export the specified keyids")" + echo "$(gettext " -e, --export [] Export the specified or all keyids")" echo "$(gettext " -f, --finger [] List fingerprint for specified or all keyids")" echo "$(gettext " -h, --help Show this help message and exit")" echo "$(gettext " -l, --list List keys")" @@ -210,7 +210,7 @@ if ! type gettext &>/dev/null; then fi OPT_SHORT="a::d:e:f::hlr:t:uV" -OPT_LONG="add::,config:,delete:,export:,finger::,gpgdir:,help,list" +OPT_LONG="add::,config:,delete:,export::,finger::,gpgdir:,help,list" OPT_LONG+=",receive:,reload,trust:,updatedb,version" if ! OPT_TEMP="$(parse_options $OPT_SHORT $OPT_LONG "$@")"; then echo; usage; exit 1 # E_INVALID_OPTION; @@ -228,7 +228,7 @@ while true; do -a|--add) ADD=1; [[ -n $2 && ${2:0:1} != "-" ]] && shift && KEYFILES=($1) ;; --config) shift; CONFIG=$1 ;; -d|--delete) DELETE=1; shift; KEYIDS=($1) ;; - -e|--export) EXPORT=1; shift; KEYIDS=($1) ;; + -e|--export) EXPORT=1; [[ -n $2 && ${2:0:1} != "-" ]] && shift && KEYIDS=($1) ;; -f|--finger) FINGER=1; [[ -n $2 && ${2:0:1} != "-" ]] && shift && KEYIDS=($1) ;; --gpgdir) shift; PACMAN_KEYRING_DIR=$1 ;; -l|--list) LIST=1 ;; -- cgit v1.2.3-2-g168b From 15ca6dca5c7be3253f650d615756f3bff1149d35 Mon Sep 17 00:00:00 2001 From: Ivan Kanakarakis Date: Thu, 21 Apr 2011 16:59:08 +0300 Subject: pacman-key: fix quotation on several variable assignments This commit adds quotes to several variable assignments. Unquoted values can cause problems on several occasions if the value is empty. It is safer to have every assignment quoted. Signed-off-by: Ivan Kanakarakis --- scripts/pacman-key.sh.in | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/scripts/pacman-key.sh.in b/scripts/pacman-key.sh.in index cf8c840e..473f87fc 100644 --- a/scripts/pacman-key.sh.in +++ b/scripts/pacman-key.sh.in @@ -137,12 +137,12 @@ reload_keyring() { if [[ -r "${REMOVED_KEYS}" ]]; then while read key; do local key_values name - key_values=$(${GPG_PACMAN} --quiet --with-colons --list-key "${key}" | grep ^pub | cut -d: -f5,10 --output-delimiter=' ') + key_values="$(${GPG_PACMAN} --quiet --with-colons --list-key "${key}" | grep ^pub | cut -d: -f5,10 --output-delimiter=' ')" if [[ -n $key_values ]]; then # The first word is the key_id - key_id=${key_values%% *} + key_id="${key_values%% *}" # the rest if the name of the owner - name=${key_values#* } + name="${key_values#* }" if [[ -n ${key_id} ]]; then # Mark this key to be deleted removed_ids[$key_id]="$name" @@ -152,12 +152,12 @@ reload_keyring() { fi # 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") + local HOLD_KEYS="$(get_from "$CONFIG" "HoldKeys")" # Remove the keys that must be kept from the set of keys that should be removed if [[ -n ${HOLD_KEYS} ]]; then for key in ${HOLD_KEYS}; do - key_id=$(${GPG_PACMAN} --quiet --with-colons --list-key "${key}" | grep ^pub | cut -d: -f5) + key_id="$(${GPG_PACMAN} --quiet --with-colons --list-key "${key}" | grep ^pub | cut -d: -f5)" if [[ -n "${removed_ids[$key_id]}" ]]; then unset removed_ids[$key_id] fi @@ -168,7 +168,7 @@ reload_keyring() { # be updated automatically. if [[ -r "${ADDED_KEYS}" ]]; then msg "$(gettext "Appending official keys...")" - local add_keys=$(${GPG_NOKEYRING} --keyring "${ADDED_KEYS}" --with-colons --list-keys | grep ^pub | cut -d: -f5) + local add_keys="$(${GPG_NOKEYRING} --keyring "${ADDED_KEYS}" --with-colons --list-keys | grep ^pub | cut -d: -f5)" for key_id in ${add_keys}; do # There is no point in adding a key that will be deleted right after if [[ -z "${removed_ids[$key_id]}" ]]; then @@ -179,7 +179,7 @@ reload_keyring() { if [[ -r "${DEPRECATED_KEYS}" ]]; then msg "$(gettext "Appending deprecated keys...")" - local add_keys=$(${GPG_NOKEYRING} --keyring "${DEPRECATED_KEYS}" --with-colons --list-keys | grep ^pub | cut -d: -f5) + local add_keys="$(${GPG_NOKEYRING} --keyring "${DEPRECATED_KEYS}" --with-colons --list-keys | grep ^pub | cut -d: -f5)" for key_id in ${add_keys}; do # There is no point in adding a key that will be deleted right after if [[ -z "${removed_ids[$key_id]}" ]]; then @@ -264,7 +264,7 @@ if [[ ! -r "${CONFIG}" ]]; then fi # Get GPGDIR from pacman.conf iff not specified on command line -if [[ -z PACMAN_KEYRING_DIR && GPGDIR=$(get_from "$CONFIG" "GPGDir") == 0 ]]; then +if [[ -z PACMAN_KEYRING_DIR && GPGDIR="$(get_from "$CONFIG" "GPGDir")" == 0 ]]; then PACMAN_KEYRING_DIR="${GPGDIR}" fi PACMAN_KEYRING_DIR=${PACMAN_KEYRING_DIR:-@sysconfdir@/pacman.d/gnupg} -- cgit v1.2.3-2-g168b From e458606ad2fce01e973eb02fb44f0a3f27baafa9 Mon Sep 17 00:00:00 2001 From: Allan McRae Date: Fri, 8 Jul 2011 21:14:53 +1000 Subject: pacman-key: rename --trust to --edit-key MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This keeps the naming of the option more consistent with what is actually being called by gpg. Original-patch-by: Denis A. Altoé Falqueto Signed-off-by: Allan McRae --- scripts/pacman-key.sh.in | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/scripts/pacman-key.sh.in b/scripts/pacman-key.sh.in index 473f87fc..161281f4 100644 --- a/scripts/pacman-key.sh.in +++ b/scripts/pacman-key.sh.in @@ -29,12 +29,12 @@ myver="@PACKAGE_VERSION@" # Options ADD=0 DELETE=0 +EDITKEY=0 EXPORT=0 FINGER=0 LIST=0 RECEIVE=0 RELOAD=0 -TRUST=0 UPDATEDB=0 m4_include(library/output_format.sh) @@ -56,11 +56,11 @@ usage() { echo "$(gettext " -h, --help Show this help message and exit")" echo "$(gettext " -l, --list List keys")" echo "$(gettext " -r, --receive Fetch the specified keyids")" - echo "$(gettext " -t, --trust Set the trust level of the given keyids")" echo "$(gettext " -u, --updatedb Update the trustdb of pacman")" echo "$(gettext " -V, --version Show program version")" echo "$(gettext " --config Use an alternate config file")" printf "$(gettext " (instead of '%s')")\n" "@sysconfdir@/pacman.conf" + echo "$(gettext " --edit-key Present a menu for key management task on keyids")" echo "$(gettext " --gpgdir Set an alternate directory for gnupg")" printf "$(gettext " (instead of '%s')")\n" "@sysconfdir@/pacman.d/gnupg" echo "$(gettext " --reload Reload the default keys")" @@ -209,9 +209,9 @@ if ! type gettext &>/dev/null; then } fi -OPT_SHORT="a::d:e:f::hlr:t:uV" -OPT_LONG="add::,config:,delete:,export::,finger::,gpgdir:,help,list" -OPT_LONG+=",receive:,reload,trust:,updatedb,version" +OPT_SHORT="a::d:e:f::hlr:uV" +OPT_LONG="add::,config:,delete:,edit-key:,export::,finger::,gpgdir:" +OPT_LONG+=",help,list,receive:,reload,updatedb,version" if ! OPT_TEMP="$(parse_options $OPT_SHORT $OPT_LONG "$@")"; then echo; usage; exit 1 # E_INVALID_OPTION; fi @@ -228,13 +228,13 @@ while true; do -a|--add) ADD=1; [[ -n $2 && ${2:0:1} != "-" ]] && shift && KEYFILES=($1) ;; --config) shift; CONFIG=$1 ;; -d|--delete) DELETE=1; shift; KEYIDS=($1) ;; + --edit-key) EDITKEY=1; shift; KEYIDS=($1) ;; -e|--export) EXPORT=1; [[ -n $2 && ${2:0:1} != "-" ]] && shift && KEYIDS=($1) ;; -f|--finger) FINGER=1; [[ -n $2 && ${2:0:1} != "-" ]] && shift && KEYIDS=($1) ;; --gpgdir) shift; PACMAN_KEYRING_DIR=$1 ;; -l|--list) LIST=1 ;; -r|--receive) RECEIVE=1; shift; KEYSERVER="${1[0]}"; KEYIDS=("${1[@]:1}") ;; --reload) RELOAD=1 ;; - -t|--trust) TRUST=1; shift; KEYIDS=($1) ;; -u|--updatedb) UPDATEDB=1 ;; -h|--help) usage; exit 0 ;; @@ -252,7 +252,7 @@ if ! type -p gpg >/dev/null; then exit 1 fi -if (( (ADD || DELETE || RECEIVE || RELOAD || TRUST || UPDATEDB) && EUID != 0 )); then +if (( (ADD || DELETE || EDITKEY || RECEIVE || RELOAD || UPDATEDB) && EUID != 0 )); then error "$(gettext "%s needs to be run as root for this operation.")" "pacman-key" exit 1 fi @@ -293,7 +293,7 @@ if (( RECEIVE )); then ${GPG_PACMAN} --keyserver "$KEYSERVER" --recv-keys "${KEYIDS[@]}" fi -if (( TRUST )); then +if (( EDITKEY )); then for key in ${KEYIDS[@]}; do # Verify if the key exists in pacman's keyring if ${GPG_PACMAN} --list-keys "$key" > /dev/null 2>&1; then -- cgit v1.2.3-2-g168b From e37adcd66427acecac934fd97fcf8428080c62e4 Mon Sep 17 00:00:00 2001 From: Ivan Kanakarakis Date: Thu, 21 Apr 2011 16:59:09 +0300 Subject: pacman-key: hide output of executed commands on logic checks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit correctly redirects to /dev/null the output of several commands that get executed on logic checks. Original-patch-by: Denis A. Altoé Falqueto Signed-off-by: Ivan Kanakarakis Signed-off-by: Allan McRae --- scripts/pacman-key.sh.in | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/pacman-key.sh.in b/scripts/pacman-key.sh.in index 161281f4..f48e9c03 100644 --- a/scripts/pacman-key.sh.in +++ b/scripts/pacman-key.sh.in @@ -108,7 +108,7 @@ reload_keyring() { # Verify signatures of related files, if they exist if [[ -r "${ADDED_KEYS}" ]]; then msg "$(gettext "Verifying official keys file signature...")" - if ! ${GPG_PACMAN} --quiet --batch --verify "${ADDED_KEYS}.sig" 1>/dev/null; then + if ! ${GPG_PACMAN} --verify "${ADDED_KEYS}.sig" &>/dev/null; then error "$(gettext "The signature of file %s is not valid.")" "${ADDED_KEYS}" exit 1 fi @@ -116,7 +116,7 @@ reload_keyring() { if [[ -r "${DEPRECATED_KEYS}" ]]; then msg "$(gettext "Verifying deprecated keys file signature...")" - if ! ${GPG_PACMAN} --quiet --batch --verify "${DEPRECATED_KEYS}.sig" 1>/dev/null; then + if ! ${GPG_PACMAN} --verify "${DEPRECATED_KEYS}.sig" &>/dev/null; then error "$(gettext "The signature of file %s is not valid.")" "${DEPRECATED_KEYS}" exit 1 fi @@ -124,7 +124,7 @@ reload_keyring() { if [[ -r "${REMOVED_KEYS}" ]]; then msg "$(gettext "Verifying deleted keys file signature...")" - if ! ${GPG_PACMAN} --quiet --batch --verify "${REMOVED_KEYS}.sig"; then + if ! ${GPG_PACMAN} --verify "${REMOVED_KEYS}.sig" &>/dev/null; then error "$(gettext "The signature of file %s is not valid.")" "${REMOVED_KEYS}" exit 1 fi @@ -296,7 +296,7 @@ fi if (( EDITKEY )); then for key in ${KEYIDS[@]}; do # Verify if the key exists in pacman's keyring - if ${GPG_PACMAN} --list-keys "$key" > /dev/null 2>&1; then + if ${GPG_PACMAN} --list-keys "$key" &>/dev/null; then ${GPG_PACMAN} --edit-key "$key" else error "$(gettext "The key identified by %s does not exist")" "$key" -- cgit v1.2.3-2-g168b From 7963c5d0000a9dc6fe895e0b321cd6f978168c34 Mon Sep 17 00:00:00 2001 From: Allan McRae Date: Fri, 8 Jul 2011 22:30:09 +1000 Subject: pacman-key: update man page Update man page to reflect current options. Also add a description on how to manually interact with the pacman keyring with gpg. Signed-off-by: Allan McRae --- doc/pacman-key.8.txt | 58 +++++++++++++++++++++++++--------------------------- 1 file changed, 28 insertions(+), 30 deletions(-) diff --git a/doc/pacman-key.8.txt b/doc/pacman-key.8.txt index 892f14df..f961bc2e 100644 --- a/doc/pacman-key.8.txt +++ b/doc/pacman-key.8.txt @@ -12,65 +12,63 @@ pacman-key - manage pacman's list of trusted keys Synopsis -------- -'pacman-key' [options] [arguments] +'pacman-key' [options] Description ----------- -'pacman-key' is a script used to manage pacman's keyring, which is the collection -of GnuPG keys used to check signed packages. It provides the ability to import -and export keys, fetch keys from keyservers and update the key trust database. +'pacman-key' is a wrapper script for GnuPG used to manage pacman's keyring, which +is the collection of PGP keys used to check signed packages and databases. It +provides the ability to import and export keys, fetch keys from keyservers and +update the key trust database. - -Options -------- -*\--config* :: - Use an alternate config file instead of the +{sysconfdir}/pacman.conf+ - default. - -*\--gpgdir* :: - Set an alternate home directory for GnuPG. If unspecified, the value is - read from +{sysconfdir}/pacman.conf+. +More complex keyring management can be achieved using GnuPG directly combined with +the `--homedir` option pointing at the pacman keyring (located in ++{sysconfdir}/pacman.d/gnupg+ by default). -Commands +Options ------- -*-a, \--add* file ...:: +*-a, \--add* [file(s)]:: Add the key(s) contained in the specified file or files to pacman's keyring. If a key already exists, update it. -*\--adv* param ...:: - Use this option to issue particular GnuPG actions to pacman's keyring. This - option should be used with care as it can modify pacman's trust in - packages' signatures. +*\--config* :: + Use an alternate config file instead of the +{sysconfdir}/pacman.conf+ + default. -*-d, \--del* keyid ...:: - Remove the key(s) identified by the specified keyid or keyids from pacman's +*-d, \--delete* :: + Remove the key(s) identified by the specified keyid(s) from pacman's keyring. -*-e, \--export* [keyid ...]:: - Export key(s) identified by the specified keyid to 'stdout'. If no keyid is - specified, all keys will be exported. +*-e, \--export* [keyid(s)]:: + Export key(s) identified by the specified keyid(s) to 'stdout'. If no keyid + is specified, all keys will be exported. + +*\--edit-key * :: + Present a menu for key management task on the specified keyids. Useful for + adjusting a keys trust level. -*-f, \--finger* [keyid ...]:: +*-f, \--finger* [keyid(s)]:: List a fingerprint for each specified keyid, or for all known keys if no keyids are specified. +*\--gpgdir* :: + Set an alternate home directory for GnuPG. If unspecified, the value is + read from +{sysconfdir}/pacman.conf+. + *-h, \--help*:: Output syntax and command line options. *-l, \--list*:: Equivalent to --list-sigs from GnuPG. -*-r, \--receive* keyserver keyid ...:: +*-r, \--receive* :: Fetch the specified keyids from the specified key server URL. *\--reload*:: Reloads the keys from the keyring package. -*-t, \--trust* keyid:: - Set the trust level of the given key. - *-u, \--updatedb*:: Equivalent to \--check-trustdb in GnuPG. -- cgit v1.2.3-2-g168b From 74e5a494b0cfea7a987fd2b253b765ca4362b456 Mon Sep 17 00:00:00 2001 From: Allan McRae Date: Sat, 9 Jul 2011 11:07:29 +1000 Subject: pacman-key: move --edit-key and --receive processing to functions This moves the processing of the --edit-key and --receive options to functions, keeping the final option processing to be all single line statements. Also rework the --edit-key option to validate all input before processing. Signed-off-by: Allan McRae --- scripts/pacman-key.sh.in | 47 ++++++++++++++++++++++++++--------------------- 1 file changed, 26 insertions(+), 21 deletions(-) diff --git a/scripts/pacman-key.sh.in b/scripts/pacman-key.sh.in index f48e9c03..fd52359b 100644 --- a/scripts/pacman-key.sh.in +++ b/scripts/pacman-key.sh.in @@ -202,6 +202,30 @@ reload_keyring() { ${GPG_PACMAN} --batch --check-trustdb } +receive_keys() { + if [[ -z ${KEYIDS[@]} ]]; then + error "$(gettext "You need to specify the keyserver and at least one key identifier")" + exit 1 + fi + ${GPG_PACMAN} --keyserver "$KEYSERVER" --recv-keys "${KEYIDS[@]}" +} + +edit_keys() { + local errors=0; + for key in ${KEYIDS[@]}; do + # Verify if the key exists in pacman's keyring + if ! ${GPG_PACMAN} --list-keys "$key" &>/dev/null; then + error "$(gettext "The key identified by %s does not exist")" "$key" + errors=1; + fi + done + (( errors )) && exit 1; + + for key in ${KEYIDS[@]}; do + ${GPG_PACMAN} --edit-key "$key" + done +} + # PROGRAM START if ! type gettext &>/dev/null; then gettext() { @@ -279,31 +303,12 @@ GPG_PACMAN="gpg --homedir ${PACMAN_KEYRING_DIR} --no-permission-warning" (( ADD )) && ${GPG_PACMAN} --quiet --batch --import "${KEYFILES[@]}" (( DELETE )) && ${GPG_PACMAN} --quiet --batch --delete-key --yes "${KEYIDS[@]}" +(( EDITKEY )) && edit_keys (( EXPORT )) && ${GPG_PACMAN} --armor --export "${KEYIDS[@]}" (( FINGER )) && ${GPG_PACMAN} --batch --fingerprint "${KEYIDS[@]}" (( LIST )) && ${GPG_PACMAN} --batch --list-sigs "${KEYIDS[@]}" +(( RECEIVE )) && receive_keys (( RELOAD )) && reload_keyring (( UPDATEDB )) && ${GPG_PACMAN} --batch --check-trustdb -if (( RECEIVE )); then - if [[ -z ${KEYIDS[@]} ]]; then - error "$(gettext "You need to specify the keyserver and at least one key identifier")" - exit 1 - fi - ${GPG_PACMAN} --keyserver "$KEYSERVER" --recv-keys "${KEYIDS[@]}" -fi - -if (( EDITKEY )); then - for key in ${KEYIDS[@]}; do - # Verify if the key exists in pacman's keyring - if ${GPG_PACMAN} --list-keys "$key" &>/dev/null; then - ${GPG_PACMAN} --edit-key "$key" - else - error "$(gettext "The key identified by %s does not exist")" "$key" - exit 1 - fi - shift - done -fi - # vim: set ts=2 sw=2 noet: -- cgit v1.2.3-2-g168b From 74f6d717a3e25957ca5f3cf80897b218b990eea8 Mon Sep 17 00:00:00 2001 From: Allan McRae Date: Sat, 9 Jul 2011 11:16:12 +1000 Subject: pacman-key: move verifying keyring files to own function Also check all files before bailing on errors. Signed-off-by: Allan McRae --- scripts/pacman-key.sh.in | 48 ++++++++++++++++++++++++++++-------------------- 1 file changed, 28 insertions(+), 20 deletions(-) diff --git a/scripts/pacman-key.sh.in b/scripts/pacman-key.sh.in index fd52359b..4366ca45 100644 --- a/scripts/pacman-key.sh.in +++ b/scripts/pacman-key.sh.in @@ -87,30 +87,15 @@ get_from() { done < "$1" } -reload_keyring() { - local PACMAN_SHARE_DIR='@prefix@/share/pacman' - local GPG_NOKEYRING="gpg --batch --quiet --ignore-time-conflict --no-options --no-default-keyring --homedir ${PACMAN_KEYRING_DIR}" - - # Variable used for iterating on keyrings - local key - local key_id - - # Keyring with keys to be added to the keyring - local ADDED_KEYS="${PACMAN_SHARE_DIR}/addedkeys.gpg" - - # Keyring with keys that were deprecated and will eventually be deleted - local DEPRECATED_KEYS="${PACMAN_SHARE_DIR}/deprecatedkeys.gpg" - - # List of keys removed from the keyring. This file is not a keyring, unlike the others. - # It is a textual list of values that gpg recogniezes as identifiers for keys. - local REMOVED_KEYS="${PACMAN_SHARE_DIR}/removedkeys" +verify_keyring_input() { + local ret=0; # 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 error "$(gettext "The signature of file %s is not valid.")" "${ADDED_KEYS}" - exit 1 + ret=1 fi fi @@ -118,7 +103,7 @@ reload_keyring() { msg "$(gettext "Verifying deprecated keys file signature...")" if ! ${GPG_PACMAN} --verify "${DEPRECATED_KEYS}.sig" &>/dev/null; then error "$(gettext "The signature of file %s is not valid.")" "${DEPRECATED_KEYS}" - exit 1 + ret=1 fi fi @@ -126,10 +111,33 @@ reload_keyring() { msg "$(gettext "Verifying deleted keys file signature...")" if ! ${GPG_PACMAN} --verify "${REMOVED_KEYS}.sig" &>/dev/null; then error "$(gettext "The signature of file %s is not valid.")" "${REMOVED_KEYS}" - exit 1 + ret=1 fi fi + return errors +} + +reload_keyring() { + local PACMAN_SHARE_DIR='@prefix@/share/pacman' + local GPG_NOKEYRING="gpg --batch --quiet --ignore-time-conflict --no-options --no-default-keyring --homedir ${PACMAN_KEYRING_DIR}" + + # Variable used for iterating on keyrings + local key + local key_id + + # Keyring with keys to be added to the keyring + local ADDED_KEYS="${PACMAN_SHARE_DIR}/addedkeys.gpg" + + # Keyring with keys that were deprecated and will eventually be deleted + local DEPRECATED_KEYS="${PACMAN_SHARE_DIR}/deprecatedkeys.gpg" + + # List of keys removed from the keyring. This file is not a keyring, unlike the others. + # It is a textual list of values that gpg recogniezes as identifiers for keys. + local REMOVED_KEYS="${PACMAN_SHARE_DIR}/removedkeys" + + verify_keyring_input || exit 1 + # Read the 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. -- cgit v1.2.3-2-g168b From fec10d4a65ebfdcac1f0e3dec9e24c1fe67bb52a Mon Sep 17 00:00:00 2001 From: Allan McRae Date: Sat, 9 Jul 2011 11:28:57 +1000 Subject: pacman-key: check only a single operation has been specified Follow the example of gpg and only allow a single operation to be specified each time. Prevents having to deal with conflicting variable names and potential issues due to the order in which the operations are run. Signed-off-by: Allan McRae --- scripts/pacman-key.sh.in | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/scripts/pacman-key.sh.in b/scripts/pacman-key.sh.in index 4366ca45..776fc0e9 100644 --- a/scripts/pacman-key.sh.in +++ b/scripts/pacman-key.sh.in @@ -308,6 +308,22 @@ PACMAN_KEYRING_DIR=${PACMAN_KEYRING_DIR:-@sysconfdir@/pacman.d/gnupg} GPG_PACMAN="gpg --homedir ${PACMAN_KEYRING_DIR} --no-permission-warning" +# check only a single operation has been given +numopt=$(( ADD + DELETE + EDITKEY + EXPORT + FINGER + LIST + RECEIVE + RELOAD + UPDATEBD )) + +if (( ! numopt )); then + error "$(gettext "No operations specified")" + echo + usage + exit 1 +fi + +if (( numopt != 1 )); then + error "$(gettext "Multiple operations specified")" + printf "$(gettext "Please run %s with each operation separately\n")" "pacman-key" + exit 1 +fi + (( ADD )) && ${GPG_PACMAN} --quiet --batch --import "${KEYFILES[@]}" (( DELETE )) && ${GPG_PACMAN} --quiet --batch --delete-key --yes "${KEYIDS[@]}" -- cgit v1.2.3-2-g168b From 0e85c4989b7a7a20978ba0dcc7b56f0f1853b974 Mon Sep 17 00:00:00 2001 From: Allan McRae Date: Sat, 9 Jul 2011 11:41:04 +1000 Subject: pacman-key: add --verify option Signed-off-by: Allan McRae --- doc/pacman-key.8.txt | 5 ++++- scripts/pacman-key.sh.in | 10 +++++++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/doc/pacman-key.8.txt b/doc/pacman-key.8.txt index f961bc2e..2771ece4 100644 --- a/doc/pacman-key.8.txt +++ b/doc/pacman-key.8.txt @@ -72,7 +72,10 @@ Options *-u, \--updatedb*:: Equivalent to \--check-trustdb in GnuPG. -*-v, \--version*:: +* -v, \--verify* :: + Verify the given signature file. + +*-V, \--version*:: Displays the program version. diff --git a/scripts/pacman-key.sh.in b/scripts/pacman-key.sh.in index 776fc0e9..937dcad5 100644 --- a/scripts/pacman-key.sh.in +++ b/scripts/pacman-key.sh.in @@ -36,6 +36,7 @@ LIST=0 RECEIVE=0 RELOAD=0 UPDATEDB=0 +VERIFY=0 m4_include(library/output_format.sh) @@ -57,6 +58,7 @@ usage() { echo "$(gettext " -l, --list List keys")" echo "$(gettext " -r, --receive Fetch the specified keyids")" echo "$(gettext " -u, --updatedb Update the trustdb of pacman")" + echo "$(gettext " -v, --verify Verify the file specified by the signature")" echo "$(gettext " -V, --version Show program version")" echo "$(gettext " --config Use an alternate config file")" printf "$(gettext " (instead of '%s')")\n" "@sysconfdir@/pacman.conf" @@ -241,9 +243,9 @@ if ! type gettext &>/dev/null; then } fi -OPT_SHORT="a::d:e:f::hlr:uV" +OPT_SHORT="a::d:e:f::hlr:uv:V" OPT_LONG="add::,config:,delete:,edit-key:,export::,finger::,gpgdir:" -OPT_LONG+=",help,list,receive:,reload,updatedb,version" +OPT_LONG+=",help,list,receive:,reload,updatedb,verify:,version" if ! OPT_TEMP="$(parse_options $OPT_SHORT $OPT_LONG "$@")"; then echo; usage; exit 1 # E_INVALID_OPTION; fi @@ -268,6 +270,7 @@ while true; do -r|--receive) RECEIVE=1; shift; KEYSERVER="${1[0]}"; KEYIDS=("${1[@]:1}") ;; --reload) RELOAD=1 ;; -u|--updatedb) UPDATEDB=1 ;; + -v|--verify) VERIFY=1; shift; SIGNATURE=$1 ;; -h|--help) usage; exit 0 ;; -V|--version) version; exit 0 ;; @@ -309,7 +312,7 @@ PACMAN_KEYRING_DIR=${PACMAN_KEYRING_DIR:-@sysconfdir@/pacman.d/gnupg} GPG_PACMAN="gpg --homedir ${PACMAN_KEYRING_DIR} --no-permission-warning" # check only a single operation has been given -numopt=$(( ADD + DELETE + EDITKEY + EXPORT + FINGER + LIST + RECEIVE + RELOAD + UPDATEBD )) +numopt=$(( ADD + DELETE + EDITKEY + EXPORT + FINGER + LIST + RECEIVE + RELOAD + UPDATEBD + VERIFY )) if (( ! numopt )); then error "$(gettext "No operations specified")" @@ -334,5 +337,6 @@ fi (( RECEIVE )) && receive_keys (( RELOAD )) && reload_keyring (( UPDATEDB )) && ${GPG_PACMAN} --batch --check-trustdb +(( VERIFY )) && ${GPG_PACMAN} --verify $SIGNATURE # vim: set ts=2 sw=2 noet: -- cgit v1.2.3-2-g168b From df7b390514efa0ae6b84e8404806dee63d3524ad Mon Sep 17 00:00:00 2001 From: Dave Reisner Date: Fri, 8 Jul 2011 22:40:25 -0400 Subject: pacman-key: refactor get_from This function had a variety of pitfalls, including the inability to successfully find a key=value pair where no whitespace surrounded the equals sign. Make it more robust by splitting the line on the equals itself, and performing whitespace trimming on the resulting key/value pair. Signed-off-by: Dave Reisner Signed-off-by: Allan McRae --- scripts/pacman-key.sh.in | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/scripts/pacman-key.sh.in b/scripts/pacman-key.sh.in index 937dcad5..0ce0ea24 100644 --- a/scripts/pacman-key.sh.in +++ b/scripts/pacman-key.sh.in @@ -76,17 +76,19 @@ This is free software; see the source for copying conditions.\n\ There is NO WARRANTY, to the extent permitted by law.\n")" } -# Read provided file and search for values matching the given key -# The contents of the file are expected to be in this format: key = value -# 'key', 'equal sign' and 'value' can be surrounded by random whitespace -# Usage: get_from "$file" "$key" # returns the value for the first matching key in the file +# read the config file "$1" which has key=value pairs, and return the key which +# matches "$2". the equals sign between pairs may be surrounded by any amount +# of whitespace. get_from() { - while read key _ value; do - if [[ $key = $2 ]]; then - echo "$value" - break + while IFS='=' read -r key value; do + [[ -z $key || ${key:0:1} = '#' ]] && continue + + if [[ ${key%% *} = "$2" && -n ${value##* } ]]; then + echo "${value##* }" + return 0 fi done < "$1" + return 1 } verify_keyring_input() { -- cgit v1.2.3-2-g168b From 0be9e4a4cd2c6a5d5c5246c8dc269931e883c1fe Mon Sep 17 00:00:00 2001 From: Dave Reisner Date: Sat, 9 Jul 2011 12:48:41 +1000 Subject: pacman-key: tidy up logic for finding pacman keyring directory Signed-off-by: Allan McRae --- scripts/pacman-key.sh.in | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/scripts/pacman-key.sh.in b/scripts/pacman-key.sh.in index 0ce0ea24..79bf41a8 100644 --- a/scripts/pacman-key.sh.in +++ b/scripts/pacman-key.sh.in @@ -300,11 +300,9 @@ if [[ ! -r "${CONFIG}" ]]; then exit 1 fi -# Get GPGDIR from pacman.conf iff not specified on command line -if [[ -z PACMAN_KEYRING_DIR && GPGDIR="$(get_from "$CONFIG" "GPGDir")" == 0 ]]; then - PACMAN_KEYRING_DIR="${GPGDIR}" -fi -PACMAN_KEYRING_DIR=${PACMAN_KEYRING_DIR:-@sysconfdir@/pacman.d/gnupg} +# if PACMAN_KEYRING_DIR isn't assigned, try to get it from the config +# file, falling back on a hard default +PACMAN_KEYRING_DIR=${PACMAN_KEYRING_DIR:-$(get_from "$CONFIG" "GPGDir" || echo "@sysconfdir@/pacman.d/gnupg")} # Try to create $PACMAN_KEYRING_DIR if non-existent # Check for simple existence rather than for a directory as someone may want -- cgit v1.2.3-2-g168b From 0c9e86bab17691bf17c4251b2e16d65f517b88c8 Mon Sep 17 00:00:00 2001 From: Allan McRae Date: Sat, 9 Jul 2011 17:26:17 +1000 Subject: pacman-key: add --init option Add an --init option that ensures that the pacman keyring has all the necessary files and they have the correct permissions for being read as a user. Signed-off-by: Allan McRae --- doc/pacman-key.8.txt | 4 ++++ scripts/pacman-key.sh.in | 34 ++++++++++++++++++++++++++-------- 2 files changed, 30 insertions(+), 8 deletions(-) diff --git a/doc/pacman-key.8.txt b/doc/pacman-key.8.txt index 2771ece4..cf72b83c 100644 --- a/doc/pacman-key.8.txt +++ b/doc/pacman-key.8.txt @@ -60,6 +60,10 @@ Options *-h, \--help*:: Output syntax and command line options. +*--init*:: + Ensure the keyring is properly initialized and has the required access + permissions. + *-l, \--list*:: Equivalent to --list-sigs from GnuPG. diff --git a/scripts/pacman-key.sh.in b/scripts/pacman-key.sh.in index 79bf41a8..d7129e53 100644 --- a/scripts/pacman-key.sh.in +++ b/scripts/pacman-key.sh.in @@ -32,6 +32,7 @@ DELETE=0 EDITKEY=0 EXPORT=0 FINGER=0 +INIT=0 LIST=0 RECEIVE=0 RELOAD=0 @@ -65,6 +66,7 @@ usage() { echo "$(gettext " --edit-key Present a menu for key management task on keyids")" echo "$(gettext " --gpgdir Set an alternate directory for gnupg")" printf "$(gettext " (instead of '%s')")\n" "@sysconfdir@/pacman.d/gnupg" + echo "$(gettest " --init Ensure the keyring is properly initialized")" echo "$(gettext " --reload Reload the default keys")" } @@ -91,6 +93,25 @@ get_from() { return 1 } +initialize() { + # Check for simple existence rather than for a directory as someone + # may want to use a symlink here + [[ -e ${PACMAN_KEYRING_DIR} ]] || mkdir -p -m 755 "${PACMAN_KEYRING_DIR}" + + # keyring files + [[ -f ${PACMAN_KEYRING_DIR}/pubring.gpg ]] || touch ${PACMAN_KEYRING_DIR}/pubring.gpg + [[ -f ${PACMAN_KEYRING_DIR}/secring.gpg ]] || touch ${PACMAN_KEYRING_DIR}/secring.gpg + [[ -f ${PACMAN_KEYRING_DIR}/trustdb.gpg ]] || ${GPG_PACMAN} --update-trustdb + chmod 644 ${PACMAN_KEYRING_DIR}/{{pub,sec}ring,trustdb}.gpg + + # gpg.conf + [[ ! -f ${PACMAN_KEYRING_DIR}/gpg.conf ]] || touch ${PACMAN_KEYRING_DIR}/gpg.conf + chmod 644 ${PACMAN_KEYRING_DIR}/gpg.conf + if ! grep -w -q "lock-never" ${PACMAN_KEYRING_DIR}/gpg.conf &>/dev/null; then + echo "lock-never" >> ${PACMAN_KEYRING_DIR}/gpg.conf + fi +} + verify_keyring_input() { local ret=0; @@ -247,7 +268,7 @@ fi OPT_SHORT="a::d:e:f::hlr:uv:V" OPT_LONG="add::,config:,delete:,edit-key:,export::,finger::,gpgdir:" -OPT_LONG+=",help,list,receive:,reload,updatedb,verify:,version" +OPT_LONG+=",help,init,list,receive:,reload,updatedb,verify:,version" if ! OPT_TEMP="$(parse_options $OPT_SHORT $OPT_LONG "$@")"; then echo; usage; exit 1 # E_INVALID_OPTION; fi @@ -268,6 +289,7 @@ while true; do -e|--export) EXPORT=1; [[ -n $2 && ${2:0:1} != "-" ]] && shift && KEYIDS=($1) ;; -f|--finger) FINGER=1; [[ -n $2 && ${2:0:1} != "-" ]] && shift && KEYIDS=($1) ;; --gpgdir) shift; PACMAN_KEYRING_DIR=$1 ;; + --init) INIT=1 ;; -l|--list) LIST=1 ;; -r|--receive) RECEIVE=1; shift; KEYSERVER="${1[0]}"; KEYIDS=("${1[@]:1}") ;; --reload) RELOAD=1 ;; @@ -289,7 +311,7 @@ if ! type -p gpg >/dev/null; then exit 1 fi -if (( (ADD || DELETE || EDITKEY || RECEIVE || RELOAD || UPDATEDB) && EUID != 0 )); then +if (( (ADD || DELETE || EDITKEY || INIT || RECEIVE || RELOAD || UPDATEDB) && EUID != 0 )); then error "$(gettext "%s needs to be run as root for this operation.")" "pacman-key" exit 1 fi @@ -304,15 +326,10 @@ fi # file, falling back on a hard default PACMAN_KEYRING_DIR=${PACMAN_KEYRING_DIR:-$(get_from "$CONFIG" "GPGDir" || echo "@sysconfdir@/pacman.d/gnupg")} -# Try to create $PACMAN_KEYRING_DIR if non-existent -# Check for simple existence rather than for a directory as someone may want -# to use a symlink here -[[ -e ${PACMAN_KEYRING_DIR} ]] || mkdir -p -m 755 "${PACMAN_KEYRING_DIR}" - GPG_PACMAN="gpg --homedir ${PACMAN_KEYRING_DIR} --no-permission-warning" # check only a single operation has been given -numopt=$(( ADD + DELETE + EDITKEY + EXPORT + FINGER + LIST + RECEIVE + RELOAD + UPDATEBD + VERIFY )) +numopt=$(( ADD + DELETE + EDITKEY + EXPORT + FINGER + INIT + LIST + RECEIVE + RELOAD + UPDATEBD + VERIFY )) if (( ! numopt )); then error "$(gettext "No operations specified")" @@ -333,6 +350,7 @@ fi (( EDITKEY )) && edit_keys (( EXPORT )) && ${GPG_PACMAN} --armor --export "${KEYIDS[@]}" (( FINGER )) && ${GPG_PACMAN} --batch --fingerprint "${KEYIDS[@]}" +(( INIT )) && initialize (( LIST )) && ${GPG_PACMAN} --batch --list-sigs "${KEYIDS[@]}" (( RECEIVE )) && receive_keys (( RELOAD )) && reload_keyring -- cgit v1.2.3-2-g168b From 31c9a521b47a84ae01f3f9c9e25980694e1c472d Mon Sep 17 00:00:00 2001 From: Allan McRae Date: Sat, 9 Jul 2011 21:51:01 +1000 Subject: pacman-key: check required permissions on keyring Makes sure that the pacman keyring is readable and that the user has permissions to create a lock file if lock-never is not specified in the gpg.conf file. Signed-off-by: Allan McRae --- scripts/pacman-key.sh.in | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/scripts/pacman-key.sh.in b/scripts/pacman-key.sh.in index d7129e53..972749f2 100644 --- a/scripts/pacman-key.sh.in +++ b/scripts/pacman-key.sh.in @@ -112,6 +112,25 @@ initialize() { fi } +check_keyring() { + if [[ ! -r ${PACMAN_KEYRING_DIR}/pubring.gpg || \ + ! -r ${PACMAN_KEYRING_DIR}/secring.gpg || \ + ! -r ${PACMAN_KEYRING_DIR}/trustdb.gpg ]]; then + error "$(gettext "You do not have sufficient permissions to read the %s keyring...")" "pacman" + msg "$(gettext "Use '%s' to correct the keyring permissions.")" "pacman-key --init" + exit 1 + fi + + if (( (EXPORT || FINGER || LIST || VERIFY) && EUID != 0 )); then + if ! grep -w -q "lock-never" ${PACMAN_KEYRING_DIR}/gpg.conf &>/dev/null; then + error "$(gettext "You do not have sufficient permissions to run this command...")" + msg "$(gettext "Use '%s' to correct the keyring permissions.")" "pacman-key --init" + exit 1 + fi + fi + +} + verify_keyring_input() { local ret=0; @@ -344,6 +363,7 @@ if (( numopt != 1 )); then exit 1 fi +(( ! INIT )) && check_keyring (( ADD )) && ${GPG_PACMAN} --quiet --batch --import "${KEYFILES[@]}" (( DELETE )) && ${GPG_PACMAN} --quiet --batch --delete-key --yes "${KEYIDS[@]}" -- cgit v1.2.3-2-g168b From 7e5dea5d329a84293fe363ee098aede5aa1825af Mon Sep 17 00:00:00 2001 From: Allan McRae Date: Sun, 10 Jul 2011 16:53:03 +1000 Subject: pacman-key: add dependency on parse_options to Makefile Signed-off-by: Allan McRae --- scripts/Makefile.am | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/Makefile.am b/scripts/Makefile.am index 8491b743..adb259a7 100644 --- a/scripts/Makefile.am +++ b/scripts/Makefile.am @@ -80,7 +80,8 @@ pacman-db-upgrade: \ pacman-key: \ $(srcdir)/pacman-key.sh.in \ - $(srcdir)/library/output_format.sh + $(srcdir)/library/output_format.sh \ + $(srcdir)/library/parse_options.sh pacman-optimize: \ $(srcdir)/pacman-optimize.sh.in \ -- cgit v1.2.3-2-g168b From fa3aaa41e3563e8d4632c12cda989a471627aa20 Mon Sep 17 00:00:00 2001 From: Pang Yan Han Date: Sun, 10 Jul 2011 12:23:47 +0800 Subject: pacman-key: correct spelling mistake Signed-off-by: Pang Yan Han Signed-off-by: Allan McRae --- scripts/pacman-key.sh.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/pacman-key.sh.in b/scripts/pacman-key.sh.in index 972749f2..3ed42e68 100644 --- a/scripts/pacman-key.sh.in +++ b/scripts/pacman-key.sh.in @@ -66,7 +66,7 @@ usage() { echo "$(gettext " --edit-key Present a menu for key management task on keyids")" echo "$(gettext " --gpgdir Set an alternate directory for gnupg")" printf "$(gettext " (instead of '%s')")\n" "@sysconfdir@/pacman.d/gnupg" - echo "$(gettest " --init Ensure the keyring is properly initialized")" + echo "$(gettext " --init Ensure the keyring is properly initialized")" echo "$(gettext " --reload Reload the default keys")" } -- cgit v1.2.3-2-g168b From 333269482a08e02d4e730dd739fc9e8625efde32 Mon Sep 17 00:00:00 2001 From: Pang Yan Han Date: Sun, 10 Jul 2011 12:26:42 +0800 Subject: pacman-key: --init: correct creation of gpg.conf Signed-off-by: Pang Yan Han Signed-off-by: Allan McRae --- scripts/pacman-key.sh.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/pacman-key.sh.in b/scripts/pacman-key.sh.in index 3ed42e68..cb108acc 100644 --- a/scripts/pacman-key.sh.in +++ b/scripts/pacman-key.sh.in @@ -105,7 +105,7 @@ initialize() { chmod 644 ${PACMAN_KEYRING_DIR}/{{pub,sec}ring,trustdb}.gpg # gpg.conf - [[ ! -f ${PACMAN_KEYRING_DIR}/gpg.conf ]] || touch ${PACMAN_KEYRING_DIR}/gpg.conf + [[ -f ${PACMAN_KEYRING_DIR}/gpg.conf ]] || touch ${PACMAN_KEYRING_DIR}/gpg.conf chmod 644 ${PACMAN_KEYRING_DIR}/gpg.conf if ! grep -w -q "lock-never" ${PACMAN_KEYRING_DIR}/gpg.conf &>/dev/null; then echo "lock-never" >> ${PACMAN_KEYRING_DIR}/gpg.conf -- cgit v1.2.3-2-g168b