summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmdline/apt-key.in134
1 files changed, 77 insertions, 57 deletions
diff --git a/cmdline/apt-key.in b/cmdline/apt-key.in
index 9adbd6443..9d8e60ec0 100644
--- a/cmdline/apt-key.in
+++ b/cmdline/apt-key.in
@@ -23,7 +23,6 @@ GPG_CMD="$GPG_CMD --homedir $GPGHOMEDIR"
$GPG_CMD --quiet --check-trustdb --keyring $SECRETKEYRING >/dev/null 2>&1
# tell gpg that it shouldn't try to maintain a trustdb file
GPG_CMD="$GPG_CMD --no-auto-check-trustdb --trust-model always"
-
GPG="$GPG_CMD"
APT_DIR="/"
@@ -113,7 +112,6 @@ net_update() {
echo >&2 "ERROR: Your distribution is not supported in net-update as no uri for the archive-keyring is set"
exit 1
fi
- requires_root
# in theory we would need to depend on wget for this, but this feature
# isn't useable in debian anyway as we have no keyring uri nor a master key
if ! which wget >/dev/null 2>&1; then
@@ -145,7 +143,6 @@ update() {
echo >&2 "Is the &keyring-package; package installed?"
exit 1
fi
- requires_root
# add new keys from the package;
@@ -158,11 +155,8 @@ update() {
if [ -r "$REMOVED_KEYS" ]; then
# remove no-longer supported/used keys
- keys=`$GPG_CMD --keyring $REMOVED_KEYS --with-colons --list-keys | grep ^pub | cut -d: -f5`
- for key in $keys; do
- if $GPG --list-keys --with-colons | grep ^pub | cut -d: -f5 | grep -q $key; then
- $GPG --quiet --batch --delete-key --yes ${key}
- fi
+ $GPG_CMD --keyring $REMOVED_KEYS --with-colons --list-keys | grep ^pub | cut -d: -f5 | while read key; do
+ foreach_keyring_do 'remove_key_from_keyring' "$key"
done
else
echo >&2 "Warning: removed keys keyring $REMOVED_KEYS missing or not readable"
@@ -172,12 +166,17 @@ update() {
remove_key_from_keyring() {
local KEYRINGFILE="$1"
shift
+ # non-existent keyrings have by definition no keys
+ if [ ! -e "$KEYRINGFILE" ]; then
+ return
+ fi
+
local GPG="$GPG_CMD --keyring $KEYRINGFILE"
while [ -n "$1" ]; do
local KEY="$1"
shift
# check if the key is in this keyring: the key id is in the 5 column at the end
- if ! $GPG --with-colons --list-keys 2>&1 | grep -q "^pub:[^:]*:[^:]*:[^:]*:[0-9A-F]\+${KEY}:"; then
+ if ! $GPG --with-colons --list-keys 2>&1 | grep -q "^pub:[^:]*:[^:]*:[^:]*:[0-9A-F]*${KEY}:"; then
continue
fi
if [ ! -w "$KEYRINGFILE" ]; then
@@ -205,12 +204,6 @@ remove_key_from_keyring() {
done
}
-remove_key() {
- requires_root
- foreach_keyring_do 'remove_key_from_keyring' "$@"
- aptkey_echo "OK"
- }
-
foreach_keyring_do() {
local ACTION="$1"
shift
@@ -219,20 +212,62 @@ foreach_keyring_do() {
$ACTION "$FORCED_KEYRING" "$@"
else
# otherwise all known keyrings are up for inspection
- local TRUSTEDFILE="/etc/apt/trusted.gpg"
- eval $(apt-config shell TRUSTEDFILE Apt::GPGV::TrustedKeyring)
- eval $(apt-config shell TRUSTEDFILE Dir::Etc::Trusted/f)
- $ACTION "$TRUSTEDFILE" "$@"
+ if [ -s "$TRUSTEDFILE" ]; then
+ $ACTION "$TRUSTEDFILE" "$@"
+ fi
local TRUSTEDPARTS="/etc/apt/trusted.gpg.d"
eval $(apt-config shell TRUSTEDPARTS Dir::Etc::TrustedParts/d)
if [ -d "$TRUSTEDPARTS" ]; then
+ # strip / suffix as gpg will double-slash in that case (#665411)
+ local STRIPPED_TRUSTEDPARTS="${TRUSTEDPARTS%/}"
+ if [ "${STRIPPED_TRUSTEDPARTS}/" = "$TRUSTEDPARTS" ]; then
+ TRUSTEDPARTS="$STRIPPED_TRUSTEDPARTS"
+ fi
for trusted in $(run-parts --list "$TRUSTEDPARTS" --regex '^.*\.gpg$'); do
- $ACTION "$trusted" "$@"
+ if [ -s "$trusted" ]; then
+ $ACTION "$trusted" "$@"
+ fi
done
fi
fi
}
+list_keys_from_keyring() {
+ local KEYRINGFILE="$1"
+ shift
+ # don't show the error message if this keyring doesn't include the key
+ $GPG_CMD --keyring "$KEYRINGFILE" --batch --list-keys "$@" 2>/dev/null || true
+}
+
+fingerprint_keys_from_keyring() {
+ local KEYRINGFILE="$1"
+ shift
+ # don't show the error message if this keyring doesn't include the fingerprint
+ $GPG_CMD --keyring "$KEYRINGFILE" --batch --fingerprint "$@" 2>/dev/null || true
+}
+
+import_keys_from_keyring() {
+ local IMPORT="$1"
+ local KEYRINGFILE="$2"
+ $GPG_CMD --keyring "$KEYRINGFILE" --batch --import "$IMPORT" >/dev/null 2>&1
+}
+
+setup_merged_keyring() {
+ local TRUSTEDFILE_BAK="$TRUSTEDFILE"
+ TRUSTEDFILE='/dev/null'
+ foreach_keyring_do 'import_keys_from_keyring' "${GPGHOMEDIR}/trusted.gpg"
+ TRUSTEDFILE="$TRUSTEDFILE_BAK"
+ # mark it as non-writeable so users get errors if gnupg tries to modify it
+ if [ -s "${GPGHOMEDIR}/trusted.gpg" ]; then
+ chmod -w "${GPGHOMEDIR}/trusted.gpg"
+ GPG="$GPG --keyring ${GPGHOMEDIR}/trusted.gpg"
+ fi
+ if [ -r "$TRUSTEDFILE" ]; then
+ GPG="$GPG --keyring $TRUSTEDFILE --primary-keyring $TRUSTEDFILE"
+ fi
+}
+
+
usage() {
echo "Usage: apt-key [--keyring file] [command] [arguments]"
echo
@@ -257,12 +292,6 @@ while [ -n "$1" ]; do
shift
TRUSTEDFILE="$1"
FORCED_KEYRING="$1"
- if [ -r "$TRUSTEDFILE" ] || [ "$2" = 'add' ] || [ "$2" = 'adv' ]; then
- GPG="$GPG --keyring $TRUSTEDFILE --primary-keyring $TRUSTEDFILE"
- else
- echo >&2 "Error: The specified keyring »$TRUSTEDFILE« is missing or not readable"
- exit 1
- fi
shift
;;
--fakeroot)
@@ -286,22 +315,6 @@ if [ -z "$TRUSTEDFILE" ]; then
TRUSTEDFILE="/etc/apt/trusted.gpg"
eval $(apt-config shell TRUSTEDFILE Apt::GPGV::TrustedKeyring)
eval $(apt-config shell TRUSTEDFILE Dir::Etc::Trusted/f)
- if [ -r "$TRUSTEDFILE" ]; then
- GPG="$GPG --keyring $TRUSTEDFILE"
- GPG="$GPG --primary-keyring $TRUSTEDFILE"
- fi
- TRUSTEDPARTS="/etc/apt/trusted.gpg.d"
- eval $(apt-config shell TRUSTEDPARTS Dir::Etc::TrustedParts/d)
- if [ -d "$TRUSTEDPARTS" ]; then
- # strip / suffix as gpg will double-slash in that case (#665411)
- STRIPPED_TRUSTEDPARTS="${TRUSTEDPARTS%/}"
- if [ "${STRIPPED_TRUSTEDPARTS}/" = "$TRUSTEDPARTS" ]; then
- TRUSTEDPARTS="$STRIPPED_TRUSTEDPARTS"
- fi
- for trusted in $(run-parts --list "$TRUSTEDPARTS" --regex '^.*\.gpg$'); do
- GPG="$GPG --keyring $trusted"
- done
- fi
fi
command="$1"
@@ -323,40 +336,47 @@ if [ "$command" != "help" ]; then
if [ -w "$(dirname "$TRUSTEDFILE")" ]; then
touch -- "$TRUSTEDFILE"
chmod 0644 -- "$TRUSTEDFILE"
- GPG="$GPG --keyring $TRUSTEDFILE"
- GPG="$GPG --primary-keyring $TRUSTEDFILE"
fi
fi
fi
case "$command" in
add)
- requires_root
- $GPG --quiet --batch --import "$@"
- aptkey_echo "OK"
+ requires_root
+ setup_merged_keyring
+ $GPG --quiet --batch --import "$@"
+ aptkey_echo "OK"
;;
del|rm|remove)
- remove_key "$@"
+ requires_root
+ foreach_keyring_do 'remove_key_from_keyring' "$@"
+ aptkey_echo "OK"
;;
update)
+ requires_root
+ setup_merged_keyring
update
;;
net-update)
+ requires_root
+ setup_merged_keyring
net_update
;;
list)
- $GPG --batch --list-keys "$@"
- ;;
+ foreach_keyring_do 'list_keys_from_keyring' "$@"
+ ;;
finger*)
- $GPG --batch --fingerprint "$@"
- ;;
+ foreach_keyring_do 'fingerprint_keys_from_keyring' "$@"
+ ;;
export|exportall)
- $GPG --armor --export "$@"
- ;;
+ foreach_keyring_do 'import_keys_from_keyring' "${GPGHOMEDIR}/trusted.gpg"
+ $GPG_CMD --keyring "${GPGHOMEDIR}/trusted.gpg" --armor --export "$@"
+ ;;
adv*)
- aptkey_echo "Executing: $GPG $*"
- $GPG "$@"
- ;;
+ setup_merged_keyring
+ aptkey_echo "Executing: $GPG $*"
+ $GPG "$@"
+ ;;
help)
usage
;;