summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Kalnischkies <david@kalnischkies.de>2016-08-25 12:42:36 +0200
committerDavid Kalnischkies <david@kalnischkies.de>2016-08-25 12:42:36 +0200
commit105503b4b470c124bc0c271bd8a50e25ecbe9133 (patch)
tree49e22d13d56a4555150214e59542160af2cc4f03
parent70ff288b98a7aae2c2808112015d34f76f2d5114 (diff)
downloadapt-105503b4b470c124bc0c271bd8a50e25ecbe9133.tar.gz
apt-key: warn instead of fail on unreadable keyrings
apt-key has inconsistent behaviour if it can't read a keyring file: Commands like 'list' skipped silently over such keyrings while 'verify' failed hard resulting in apt to report cconfusing gpg errors (#834973). As a first step we teach apt-key to be more consistent here skipping in all commands over unreadable keyrings, but issuing a warning in the process, which is as usual for apt commands displayed at the end of the run.
-rw-r--r--cmdline/apt-key.in57
-rwxr-xr-xtest/integration/test-apt-key24
2 files changed, 55 insertions, 26 deletions
diff --git a/cmdline/apt-key.in b/cmdline/apt-key.in
index 81314c7f5..d34f59497 100644
--- a/cmdline/apt-key.in
+++ b/cmdline/apt-key.in
@@ -232,6 +232,17 @@ remove_key_from_keyring() {
done
}
+accessible_file_exists() {
+ if ! test -s "$1"; then
+ return 1
+ fi
+ if test -r "$1"; then
+ return 0
+ fi
+ warn "The key(s) in the keyring $1 are ignored as the file is not readable by user '$USER' executing apt-key."
+ return 1
+}
+
foreach_keyring_do() {
local ACTION="$1"
shift
@@ -240,7 +251,7 @@ foreach_keyring_do() {
$ACTION "$FORCED_KEYRING" "$@"
else
# otherwise all known keyrings are up for inspection
- if [ -s "$TRUSTEDFILE" ]; then
+ if accessible_file_exists "$TRUSTEDFILE"; then
$ACTION "$TRUSTEDFILE" "$@"
fi
local TRUSTEDPARTS="/etc/apt/trusted.gpg.d"
@@ -249,7 +260,7 @@ foreach_keyring_do() {
TRUSTEDPARTS="$(readlink -f "$TRUSTEDPARTS")"
local TRUSTEDPARTSLIST="$(cd /; find "$TRUSTEDPARTS" -mindepth 1 -maxdepth 1 -name '*.gpg')"
for trusted in $(echo "$TRUSTEDPARTSLIST" | sort); do
- if [ -s "$trusted" ]; then
+ if accessible_file_exists "$trusted"; then
$ACTION "$trusted" "$@"
fi
done
@@ -302,35 +313,18 @@ import_keyring_into_keyring() {
fi
}
+catfile() {
+ cat "$1" >> "$2"
+}
+
merge_all_trusted_keyrings_into_pubring() {
# does the same as:
# foreach_keyring_do 'import_keys_from_keyring' "${GPGHOMEDIR}/pubring.gpg"
# but without using gpg, just cat and find
local PUBRING="$(readlink -f "${GPGHOMEDIR}/pubring.gpg")"
- # if a --keyring was given, just use this one
- if [ -n "$FORCED_KEYRING" ]; then
- if [ -s "$FORCED_KEYRING" ]; then
- cp --dereference "$FORCED_KEYRING" "$PUBRING"
- fi
- else
- # otherwise all known keyrings are merged
- local TRUSTEDPARTS="/etc/apt/trusted.gpg.d"
- eval $(apt-config shell TRUSTEDPARTS Dir::Etc::TrustedParts/d)
- if [ -d "$TRUSTEDPARTS" ]; then
- rm -f "$PUBRING"
- if [ -s "$TRUSTEDFILE" ]; then
- cat "$TRUSTEDFILE" > "$PUBRING"
- fi
- TRUSTEDPARTS="$(readlink -f "$TRUSTEDPARTS")"
- (cd /; find "$TRUSTEDPARTS" -mindepth 1 -maxdepth 1 -name '*.gpg' -exec cat {} + >> "$PUBRING";)
- elif [ -s "$TRUSTEDFILE" ]; then
- cp --dereference "$TRUSTEDFILE" "$PUBRING"
- fi
- fi
-
- if [ ! -s "$PUBRING" ]; then
- touch "$PUBRING"
- fi
+ rm -f "$PUBRING"
+ touch "$PUBRING"
+ foreach_keyring_do 'catfile' "$PUBRING"
}
import_keys_from_keyring() {
@@ -480,8 +474,19 @@ if [ -z "$command" ]; then
fi
shift
+warn() {
+ if [ -z "$GPGHOMEDIR" ]; then
+ echo >&2 'W:' "$@"
+ else
+ echo 'W:' "$@" > "${GPGHOMEDIR}/aptwarnings.log"
+ fi
+}
+
cleanup_gpg_home() {
if [ -z "$GPGHOMEDIR" ]; then return; fi
+ if [ -s "$GPGHOMEDIR/aptwarnings.log" ]; then
+ cat >&2 "$GPGHOMEDIR/aptwarnings.log"
+ fi
if command_available 'gpgconf'; then
GNUPGHOME="${GPGHOMEDIR}" gpgconf --kill gpg-agent >/dev/null 2>&1 || true
fi
diff --git a/test/integration/test-apt-key b/test/integration/test-apt-key
index 759ce1487..96cfe41fa 100755
--- a/test/integration/test-apt-key
+++ b/test/integration/test-apt-key
@@ -81,6 +81,20 @@ gpg: unchanged: 1' aptkey --fakeroot update
testsuccess --nomsg aptkey --fakeroot del d141dbac8dae
testempty aptkey list
+ if [ "$(id -u)" != '0' ]; then
+ msgtest 'Test key removal with' 'unreadable key'
+ cleanplate
+ cp -a "${KEYDIR}/joesixpack.pub" "${ROOTDIR}/etc/apt/trusted.gpg.d/joesixpack.gpg"
+ echo 'foobar' > "${ROOTDIR}/etc/apt/trusted.gpg.d/unreadablekey.gpg"
+ chmod 000 "${ROOTDIR}/etc/apt/trusted.gpg.d/unreadablekey.gpg"
+ testwarning --nomsg aptkey --fakeroot del d141dbac8dae
+ testwarning aptkey list
+ chmod 644 "${ROOTDIR}/etc/apt/trusted.gpg.d/unreadablekey.gpg"
+ rm -f "${ROOTDIR}/etc/apt/trusted.gpg.d/unreadablekey.gpg"
+ grep -v '^W: ' "${ROOTDIR}/tmp/testwarning.output" > "${ROOTDIR}/aptkeylist.output" || true
+ testempty cat "${ROOTDIR}/aptkeylist.output"
+ fi
+
msgtest 'Test key removal with' 'single key in real file'
cleanplate
cp -a "${KEYDIR}/joesixpack.pub" "${ROOTDIR}/etc/apt/trusted.gpg.d/joesixpack.gpg"
@@ -202,6 +216,16 @@ gpg: unchanged: 1' aptkey --fakeroot update
msgtest 'Test verify a file' 'with all keys'
testsuccess --nomsg aptkey --quiet --readonly verify "${SIGNATURE}.gpg" "${SIGNATURE}"
+ if [ "$(id -u)" != '0' ]; then
+ msgtest 'Test verify a file' 'with unreadable key'
+ echo 'foobar' > "${ROOTDIR}/etc/apt/trusted.gpg.d/unreadablekey.gpg"
+ chmod 000 "${ROOTDIR}/etc/apt/trusted.gpg.d/unreadablekey.gpg"
+ testwarning --nomsg aptkey --quiet --readonly verify "${SIGNATURE}.gpg" "${SIGNATURE}"
+ testwarning aptkey list
+ chmod 644 "${ROOTDIR}/etc/apt/trusted.gpg.d/unreadablekey.gpg"
+ rm -f "${ROOTDIR}/etc/apt/trusted.gpg.d/unreadablekey.gpg"
+ fi
+
msgtest 'Test verify a file' 'with good keyring'
testsuccess --nomsg aptkey --quiet --readonly --keyring "${KEYDIR}/testcase-multikey.pub" verify "${SIGNATURE}.gpg" "${SIGNATURE}"