summaryrefslogtreecommitdiffstats
path: root/test/integration/test-apt-update-rollback
diff options
context:
space:
mode:
Diffstat (limited to 'test/integration/test-apt-update-rollback')
-rwxr-xr-xtest/integration/test-apt-update-rollback219
1 files changed, 219 insertions, 0 deletions
diff --git a/test/integration/test-apt-update-rollback b/test/integration/test-apt-update-rollback
new file mode 100755
index 0000000..ea431c8
--- /dev/null
+++ b/test/integration/test-apt-update-rollback
@@ -0,0 +1,219 @@
+#!/bin/sh
+#
+# test that apt-get update is transactional
+#
+set -e
+
+avoid_ims_hit() {
+ touch -d '+1hour' aptarchive/dists/unstable/main/binary-i386/Packages*
+ touch -d '+1hour' aptarchive/dists/unstable/main/source/Sources*
+ touch -d '+1hour' aptarchive/dists/unstable/*Release*
+
+ touch -d '-1hour' rootdir/var/lib/apt/lists/*
+}
+
+create_fresh_archive()
+{
+ rm -rf aptarchive/*
+ rm -f rootdir/var/lib/apt/lists/_* rootdir/var/lib/apt/lists/partial/*
+
+ insertpackage 'unstable' 'old' 'all' '1.0'
+
+ setupaptarchive --no-update
+}
+
+add_new_package() {
+ insertpackage 'unstable' 'new' 'all' '1.0'
+ insertsource 'unstable' 'new' 'all' '1.0'
+
+ setupaptarchive --no-update "$@"
+}
+
+break_repository_sources_index() {
+ mv "$APTARCHIVE/dists/unstable/main/source/Sources.gz" "$APTARCHIVE/dists/unstable/main/source/Sources.gz.orig"
+ printf 'xxx' > "$APTARCHIVE/dists/unstable/main/source/Sources"
+ compressfile "$APTARCHIVE/dists/unstable/main/source/Sources" "$@"
+}
+
+start_with_good_inrelease() {
+ create_fresh_archive
+ testsuccess aptget update
+ listcurrentlistsdirectory > lists.before
+ testsuccessequal 'dpkg/now 1.16.2+fake all [installed,local]
+old/unstable 1.0 all' apt list -qq
+}
+
+test_inrelease_to_new_inrelease() {
+ msgmsg 'Test InRelease to new InRelease works fine'
+ start_with_good_inrelease
+
+ add_new_package '+1hour'
+ testsuccess aptget update -o Debug::Acquire::Transaction=1
+ testsuccessequal 'dpkg/now 1.16.2+fake all [installed,local]
+new/unstable 1.0 all
+old/unstable 1.0 all' apt list -qq
+}
+
+test_inrelease_to_broken_hash_reverts_all() {
+ msgmsg 'Test InRelease to broken InRelease reverts everything'
+ start_with_good_inrelease
+
+ add_new_package '+1hour'
+ # break the Sources file
+ break_repository_sources_index '+1hour'
+
+ # test the error condition
+ testfailureequal "E: Failed to fetch file:${APTARCHIVE}/dists/unstable/main/source/Sources.gz Hash Sum mismatch
+ Hashes of expected file:
+ - Filesize:$(stat -c '%s' 'aptarchive/dists/unstable/main/source/Sources.gz.orig') [weak]
+ - SHA256:$(sha256sum 'aptarchive/dists/unstable/main/source/Sources.gz.orig' | cut -d' ' -f 1)
+ Hashes of received file:
+ - SHA256:$(sha256sum 'aptarchive/dists/unstable/main/source/Sources.gz' | cut -d' ' -f 1)
+ - Filesize:$(stat -c '%s' 'aptarchive/dists/unstable/main/source/Sources.gz') [weak]
+ Last modification reported: $(lastmodification 'aptarchive/dists/unstable/main/source/Sources.gz')
+ Release file created at: $(releasefiledate 'aptarchive/dists/unstable/InRelease')
+E: Some index files failed to download. They have been ignored, or old ones used instead." aptget update -qq
+ # ensure that the Packages file is also rolled back
+ testfileequal lists.before "$(listcurrentlistsdirectory)"
+ testfailureequal "E: Unable to locate package new" aptget install new -s -qq
+}
+
+test_inrelease_to_valid_release() {
+ msgmsg 'Test InRelease to valid Release'
+ start_with_good_inrelease
+
+ add_new_package '+1hour'
+ # switch to a unsigned repo now
+ rm -f "$APTARCHIVE/dists/unstable/InRelease" "$APTARCHIVE/dists/unstable/Release.gpg"
+
+ # update fails
+ testfailureequal "E: The repository 'file:${APTARCHIVE} unstable Release' is no longer signed." aptget update -qq
+
+ # test that security downgrade was not successful
+ testfileequal lists.before "$(listcurrentlistsdirectory)"
+ testsuccess aptget install old -s
+ testfailure aptget install new -s
+ testnotempty find "${ROOTDIR}/var/lib/apt/lists" -name '*_InRelease'
+ testempty find "${ROOTDIR}/var/lib/apt/lists" -name '*_Release'
+}
+
+test_inrelease_to_release_reverts_all() {
+ msgmsg 'Test InRelease to broken Release reverts everything'
+ start_with_good_inrelease
+
+ # switch to a unsigned repo now
+ add_new_package '+1hour'
+ rm -f "$APTARCHIVE/dists/unstable/InRelease" "$APTARCHIVE/dists/unstable/Release.gpg"
+
+ # break it
+ break_repository_sources_index '+1hour'
+
+ # ensure error
+ testfailureequal "E: The repository 'file:${APTARCHIVE} unstable Release' is no longer signed." aptget update -qq # -o Debug::acquire::transaction=1
+
+ # ensure that the Packages file is also rolled back
+ testfileequal lists.before "$(listcurrentlistsdirectory)"
+ testsuccess aptget install old -s
+ testfailure aptget install new -s
+ testnotempty find "${ROOTDIR}/var/lib/apt/lists" -name '*_InRelease'
+ testempty find "${ROOTDIR}/var/lib/apt/lists" -name '*_Release'
+}
+
+test_unauthenticated_to_invalid_inrelease() {
+ msgmsg 'Test UnAuthenticated to invalid InRelease reverts everything'
+ create_fresh_archive
+ rm -f "$APTARCHIVE/dists/unstable/InRelease" "$APTARCHIVE/dists/unstable/Release.gpg"
+
+ testwarning aptget update --allow-insecure-repositories
+ listcurrentlistsdirectory > lists.before
+ testfailureequal "WARNING: The following packages cannot be authenticated!
+ old
+E: There were unauthenticated packages and -y was used without --allow-unauthenticated" aptget install -qq -y old
+
+ # go to authenticated but not correct
+ add_new_package '+1hour'
+ break_repository_sources_index '+1hour'
+
+ testfailureequal "E: Failed to fetch file:$APTARCHIVE/dists/unstable/main/source/Sources.gz Hash Sum mismatch
+ Hashes of expected file:
+ - Filesize:$(stat -c '%s' 'aptarchive/dists/unstable/main/source/Sources.gz.orig') [weak]
+ - SHA256:$(sha256sum 'aptarchive/dists/unstable/main/source/Sources.gz.orig' | cut -d' ' -f 1)
+ Hashes of received file:
+ - SHA256:$(sha256sum 'aptarchive/dists/unstable/main/source/Sources.gz' | cut -d' ' -f 1)
+ - Filesize:$(stat -c '%s' 'aptarchive/dists/unstable/main/source/Sources.gz') [weak]
+ Last modification reported: $(lastmodification 'aptarchive/dists/unstable/main/source/Sources.gz')
+ Release file created at: $(releasefiledate 'aptarchive/dists/unstable/InRelease')
+E: Some index files failed to download. They have been ignored, or old ones used instead." aptget update -qq
+
+ testfileequal lists.before "$(listcurrentlistsdirectory)"
+ testempty find "${ROOTDIR}/var/lib/apt/lists" -maxdepth 1 -name '*_InRelease'
+ testfailureequal "WARNING: The following packages cannot be authenticated!
+ old
+E: There were unauthenticated packages and -y was used without --allow-unauthenticated" aptget install -qq -y old
+}
+
+test_inrelease_to_unauth_inrelease() {
+ msgmsg 'Test InRelease to InRelease without good sig'
+ start_with_good_inrelease
+
+ signreleasefiles 'Marvin Paranoid'
+
+ testwarningequal "W: An error occurred during the signature verification. The repository is not updated and the previous index files will be used. GPG error: file:${APTARCHIVE} unstable InRelease: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY E8525D47528144E2
+W: Failed to fetch file:$APTARCHIVE/dists/unstable/InRelease The following signatures couldn't be verified because the public key is not available: NO_PUBKEY E8525D47528144E2
+W: Some index files failed to download. They have been ignored, or old ones used instead." aptget update -qq
+
+ testfileequal lists.before "$(listcurrentlistsdirectory)"
+ testnotempty find "${ROOTDIR}/var/lib/apt/lists" -name '*_InRelease'
+}
+
+test_inrelease_to_broken_gzip() {
+ msgmsg "Test InRelease to broken gzip"
+ start_with_good_inrelease
+
+ break_repository_sources_index '+1hour'
+ generatereleasefiles '+2hours'
+ signreleasefiles
+
+ # append junk at the end of the compressed file
+ echo "lala" >> "$APTARCHIVE/dists/unstable/main/source/Sources.gz"
+ touch -d '+2min' "$APTARCHIVE/dists/unstable/main/source/Sources.gz"
+ # remove uncompressed file to avoid fallback
+ rm "$APTARCHIVE/dists/unstable/main/source/Sources"
+
+ testfailure aptget update
+ testsuccess grep 'Hash Sum mismatch' rootdir/tmp/testfailure.output
+ testfileequal lists.before "$(listcurrentlistsdirectory)"
+}
+
+TESTDIR="$(readlink -f "$(dirname "$0")")"
+. "$TESTDIR/framework"
+
+setupenvironment
+configarchitecture "i386"
+export APT_DONT_SIGN='Release.gpg'
+
+APTARCHIVE="$(readlink -f ./aptarchive)"
+ROOTDIR="${TMPWORKINGDIRECTORY}/rootdir"
+APTARCHIVE_LISTS="$(echo "$APTARCHIVE" | tr "/" "_" )"
+
+# test the following cases:
+# - InRelease -> broken InRelease revert to previous state
+# - empty lists dir and broken remote leaves nothing on the system
+# - InRelease -> hashsum mismatch for one file reverts all files to previous state
+# - Release/Release.gpg -> hashsum mismatch
+# - InRelease -> Release with hashsum mismatch revert entire state and kills Release
+# - Release -> InRelease with broken Sig/Hash removes InRelease
+# going from Release/Release.gpg -> InRelease and vice versa
+# - unauthenticated -> invalid InRelease
+
+# stuff to do:
+# - ims-hit
+# - gzip-index tests
+
+test_inrelease_to_new_inrelease
+test_inrelease_to_broken_hash_reverts_all
+test_inrelease_to_valid_release
+test_inrelease_to_release_reverts_all
+test_unauthenticated_to_invalid_inrelease
+test_inrelease_to_unauth_inrelease
+test_inrelease_to_broken_gzip