test-apt-update-rollback 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. #!/bin/sh
  2. #
  3. # test that apt-get update is transactional
  4. #
  5. set -e
  6. avoid_ims_hit() {
  7. touch -d '+1hour' aptarchive/dists/unstable/main/binary-i386/Packages*
  8. touch -d '+1hour' aptarchive/dists/unstable/main/source/Sources*
  9. touch -d '+1hour' aptarchive/dists/unstable/*Release*
  10. touch -d '-1hour' rootdir/var/lib/apt/lists/*
  11. }
  12. create_fresh_archive()
  13. {
  14. rm -rf aptarchive/*
  15. rm -f rootdir/var/lib/apt/lists/_* rootdir/var/lib/apt/lists/partial/*
  16. insertpackage 'unstable' 'old' 'all' '1.0'
  17. setupaptarchive --no-update
  18. }
  19. add_new_package() {
  20. insertpackage 'unstable' 'new' 'all' '1.0'
  21. insertsource 'unstable' 'new' 'all' '1.0'
  22. setupaptarchive --no-update "$@"
  23. }
  24. break_repository_sources_index() {
  25. mv "$APTARCHIVE/dists/unstable/main/source/Sources.gz" "$APTARCHIVE/dists/unstable/main/source/Sources.gz.orig"
  26. printf 'xxx' > "$APTARCHIVE/dists/unstable/main/source/Sources"
  27. compressfile "$APTARCHIVE/dists/unstable/main/source/Sources" "$@"
  28. }
  29. start_with_good_inrelease() {
  30. create_fresh_archive
  31. testsuccess aptget update
  32. listcurrentlistsdirectory > lists.before
  33. testsuccessequal 'dpkg/now 1.16.2+fake all [installed,local]
  34. old/unstable 1.0 all' apt list -qq
  35. }
  36. test_inrelease_to_new_inrelease() {
  37. msgmsg 'Test InRelease to new InRelease works fine'
  38. start_with_good_inrelease
  39. add_new_package '+1hour'
  40. testsuccess aptget update -o Debug::Acquire::Transaction=1
  41. testsuccessequal 'dpkg/now 1.16.2+fake all [installed,local]
  42. new/unstable 1.0 all
  43. old/unstable 1.0 all' apt list -qq
  44. }
  45. test_inrelease_to_broken_hash_reverts_all() {
  46. msgmsg 'Test InRelease to broken InRelease reverts everything'
  47. start_with_good_inrelease
  48. add_new_package '+1hour'
  49. # break the Sources file
  50. break_repository_sources_index '+1hour'
  51. # test the error condition
  52. testfailureequal "E: Failed to fetch file:${APTARCHIVE}/dists/unstable/main/source/Sources.gz Hash Sum mismatch
  53. Hashes of expected file:
  54. - Filesize:$(stat -c '%s' 'aptarchive/dists/unstable/main/source/Sources.gz.orig') [weak]
  55. - SHA256:$(sha256sum 'aptarchive/dists/unstable/main/source/Sources.gz.orig' | cut -d' ' -f 1)
  56. Hashes of received file:
  57. - SHA256:$(sha256sum 'aptarchive/dists/unstable/main/source/Sources.gz' | cut -d' ' -f 1)
  58. - Filesize:$(stat -c '%s' 'aptarchive/dists/unstable/main/source/Sources.gz') [weak]
  59. Last modification reported: $(lastmodification 'aptarchive/dists/unstable/main/source/Sources.gz')
  60. Release file created at: $(releasefiledate 'aptarchive/dists/unstable/InRelease')
  61. E: Some index files failed to download. They have been ignored, or old ones used instead." aptget update -qq
  62. # ensure that the Packages file is also rolled back
  63. testfileequal lists.before "$(listcurrentlistsdirectory)"
  64. testfailureequal "E: Unable to locate package new" aptget install new -s -qq
  65. }
  66. test_inrelease_to_valid_release() {
  67. msgmsg 'Test InRelease to valid Release'
  68. start_with_good_inrelease
  69. add_new_package '+1hour'
  70. # switch to a unsigned repo now
  71. rm -f "$APTARCHIVE/dists/unstable/InRelease" "$APTARCHIVE/dists/unstable/Release.gpg"
  72. # update fails
  73. testfailureequal "E: The repository 'file:${APTARCHIVE} unstable Release' is no longer signed." aptget update -qq
  74. # test that security downgrade was not successful
  75. testfileequal lists.before "$(listcurrentlistsdirectory)"
  76. testsuccess aptget install old -s
  77. testfailure aptget install new -s
  78. testnotempty find "${ROOTDIR}/var/lib/apt/lists" -name '*_InRelease'
  79. testempty find "${ROOTDIR}/var/lib/apt/lists" -name '*_Release'
  80. }
  81. test_inrelease_to_release_reverts_all() {
  82. msgmsg 'Test InRelease to broken Release reverts everything'
  83. start_with_good_inrelease
  84. # switch to a unsigned repo now
  85. add_new_package '+1hour'
  86. rm -f "$APTARCHIVE/dists/unstable/InRelease" "$APTARCHIVE/dists/unstable/Release.gpg"
  87. # break it
  88. break_repository_sources_index '+1hour'
  89. # ensure error
  90. testfailureequal "E: The repository 'file:${APTARCHIVE} unstable Release' is no longer signed." aptget update -qq # -o Debug::acquire::transaction=1
  91. # ensure that the Packages file is also rolled back
  92. testfileequal lists.before "$(listcurrentlistsdirectory)"
  93. testsuccess aptget install old -s
  94. testfailure aptget install new -s
  95. testnotempty find "${ROOTDIR}/var/lib/apt/lists" -name '*_InRelease'
  96. testempty find "${ROOTDIR}/var/lib/apt/lists" -name '*_Release'
  97. }
  98. test_unauthenticated_to_invalid_inrelease() {
  99. msgmsg 'Test UnAuthenticated to invalid InRelease reverts everything'
  100. create_fresh_archive
  101. rm -f "$APTARCHIVE/dists/unstable/InRelease" "$APTARCHIVE/dists/unstable/Release.gpg"
  102. testwarning aptget update --allow-insecure-repositories
  103. listcurrentlistsdirectory > lists.before
  104. testfailureequal "WARNING: The following packages cannot be authenticated!
  105. old
  106. E: There were unauthenticated packages and -y was used without --allow-unauthenticated" aptget install -qq -y old
  107. # go to authenticated but not correct
  108. add_new_package '+1hour'
  109. break_repository_sources_index '+1hour'
  110. testfailureequal "E: Failed to fetch file:$APTARCHIVE/dists/unstable/main/source/Sources.gz Hash Sum mismatch
  111. Hashes of expected file:
  112. - Filesize:$(stat -c '%s' 'aptarchive/dists/unstable/main/source/Sources.gz.orig') [weak]
  113. - SHA256:$(sha256sum 'aptarchive/dists/unstable/main/source/Sources.gz.orig' | cut -d' ' -f 1)
  114. Hashes of received file:
  115. - SHA256:$(sha256sum 'aptarchive/dists/unstable/main/source/Sources.gz' | cut -d' ' -f 1)
  116. - Filesize:$(stat -c '%s' 'aptarchive/dists/unstable/main/source/Sources.gz') [weak]
  117. Last modification reported: $(lastmodification 'aptarchive/dists/unstable/main/source/Sources.gz')
  118. Release file created at: $(releasefiledate 'aptarchive/dists/unstable/InRelease')
  119. E: Some index files failed to download. They have been ignored, or old ones used instead." aptget update -qq
  120. testfileequal lists.before "$(listcurrentlistsdirectory)"
  121. testempty find "${ROOTDIR}/var/lib/apt/lists" -maxdepth 1 -name '*_InRelease'
  122. testfailureequal "WARNING: The following packages cannot be authenticated!
  123. old
  124. E: There were unauthenticated packages and -y was used without --allow-unauthenticated" aptget install -qq -y old
  125. }
  126. test_inrelease_to_unauth_inrelease() {
  127. msgmsg 'Test InRelease to InRelease without good sig'
  128. start_with_good_inrelease
  129. signreleasefiles 'Marvin Paranoid'
  130. 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
  131. 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
  132. W: Some index files failed to download. They have been ignored, or old ones used instead." aptget update -qq
  133. testfileequal lists.before "$(listcurrentlistsdirectory)"
  134. testnotempty find "${ROOTDIR}/var/lib/apt/lists" -name '*_InRelease'
  135. }
  136. test_inrelease_to_broken_gzip() {
  137. msgmsg "Test InRelease to broken gzip"
  138. start_with_good_inrelease
  139. break_repository_sources_index '+1hour'
  140. generatereleasefiles '+2hours'
  141. signreleasefiles
  142. # append junk at the end of the compressed file
  143. echo "lala" >> "$APTARCHIVE/dists/unstable/main/source/Sources.gz"
  144. touch -d '+2min' "$APTARCHIVE/dists/unstable/main/source/Sources.gz"
  145. # remove uncompressed file to avoid fallback
  146. rm "$APTARCHIVE/dists/unstable/main/source/Sources"
  147. testfailure aptget update
  148. testsuccess grep 'Hash Sum mismatch' rootdir/tmp/testfailure.output
  149. testfileequal lists.before "$(listcurrentlistsdirectory)"
  150. }
  151. TESTDIR="$(readlink -f "$(dirname "$0")")"
  152. . "$TESTDIR/framework"
  153. setupenvironment
  154. configarchitecture "i386"
  155. export APT_DONT_SIGN='Release.gpg'
  156. APTARCHIVE="$(readlink -f ./aptarchive)"
  157. ROOTDIR="${TMPWORKINGDIRECTORY}/rootdir"
  158. APTARCHIVE_LISTS="$(echo "$APTARCHIVE" | tr "/" "_" )"
  159. # test the following cases:
  160. # - InRelease -> broken InRelease revert to previous state
  161. # - empty lists dir and broken remote leaves nothing on the system
  162. # - InRelease -> hashsum mismatch for one file reverts all files to previous state
  163. # - Release/Release.gpg -> hashsum mismatch
  164. # - InRelease -> Release with hashsum mismatch revert entire state and kills Release
  165. # - Release -> InRelease with broken Sig/Hash removes InRelease
  166. # going from Release/Release.gpg -> InRelease and vice versa
  167. # - unauthenticated -> invalid InRelease
  168. # stuff to do:
  169. # - ims-hit
  170. # - gzip-index tests
  171. test_inrelease_to_new_inrelease
  172. test_inrelease_to_broken_hash_reverts_all
  173. test_inrelease_to_valid_release
  174. test_inrelease_to_release_reverts_all
  175. test_unauthenticated_to_invalid_inrelease
  176. test_inrelease_to_unauth_inrelease
  177. test_inrelease_to_broken_gzip