From 631a7dc7906a10ccd5f14dcfe42224e6107e11f6 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Fri, 26 Sep 2014 20:59:31 +0200 Subject: Do not allow going from authenticated to unauthenticated repo Also rework the way we load the Release file, so it only after Release.gpg verified the Release file. The rational is that we never want to load untrusted data into our parsers. Only stuff verified with gpg or by its hashes get loaded. To load untrusted data you now need to use apt-get update --allow-unauthenticated. --- test/integration/test-apt-update-nofallback | 207 ++++++++++++++++++++++++++++ 1 file changed, 207 insertions(+) create mode 100755 test/integration/test-apt-update-nofallback (limited to 'test/integration/test-apt-update-nofallback') diff --git a/test/integration/test-apt-update-nofallback b/test/integration/test-apt-update-nofallback new file mode 100755 index 000000000..4e8ea9916 --- /dev/null +++ b/test/integration/test-apt-update-nofallback @@ -0,0 +1,207 @@ +#!/bin/sh +# +# ensure we never fallback from a signed to a unsigned repo +# +# hash checks are done in +# +set -e + +simulate_mitm_and_inject_evil_package() +{ + rm -f $APTARCHIVE/dists/unstable/InRelease + rm -f $APTARCHIVE/dists/unstable/Release.gpg + inject_evil_package +} + +inject_evil_package() +{ + cat > $APTARCHIVE/dists/unstable/main/binary-i386/Packages < +Architecture: all +Version: 1.0 +Filename: pool/evil_1.0_all.deb +Size: 1270 +Description: an autogenerated evil package +EOF + # avoid ims hit + touch -d '+1hour' aptarchive/dists/unstable/main/binary-i386/Packages +} + +assert_update_is_refused_and_last_good_state_used() +{ + testequal "E: The repository 'file: unstable Release.gpg' is no longer signed." aptget update -qq + + assert_repo_is_intact +} + +assert_repo_is_intact() +{ + testequal "foo/unstable 2.0 all" apt list -q + testsuccess "" aptget install -y -s foo + testfailure "" aptget install -y evil + + LISTDIR=rootdir/var/lib/apt/lists + if ! ( ls $LISTDIR/*InRelease >/dev/null 2>&1 || + ls $LISTDIR/*Release.gpg >/dev/null 2>&1 ); then + echo "Can not find InRelease/Release.gpg in $(ls $LISTDIR)" + msgfail + fi +} + +setupaptarchive_with_lists_clean() +{ + setupaptarchive --no-update + rm -f rootdir/var/lib/apt/lists/_* + #rm -rf rootdir/var/lib/apt/lists +} + +test_from_inrelease_to_unsigned() +{ + # setup archive with InRelease file + setupaptarchive_with_lists_clean + testsuccess aptget update + + simulate_mitm_and_inject_evil_package + assert_update_is_refused_and_last_good_state_used +} + +test_from_release_gpg_to_unsigned() +{ + # setup archive with Release/Release.gpg (but no InRelease) + setupaptarchive_with_lists_clean + rm $APTARCHIVE/dists/unstable/InRelease + testsuccess aptget update + + simulate_mitm_and_inject_evil_package + assert_update_is_refused_and_last_good_state_used +} + +test_cve_2012_0214() +{ + # see https://bugs.launchpad.net/ubuntu/+source/apt/+bug/947108 + # + # it was possible to MITM the download so that InRelease/Release.gpg + # are not delivered (404) and a altered Release file was send + # + # apt left the old InRelease file in /var/lib/apt/lists and downloaded + # the unauthenticated Release file too giving the false impression that + # Release was authenticated + # + # Note that this is pretty much impossible nowdays because: + # a) InRelease is left as is, not split to InRelease/Release as it was + # in the old days + # b) we refuse to go from signed->unsigned + # + # Still worth having a regression test the simulates the condition + + # setup archive with InRelease + setupaptarchive_with_lists_clean + testsuccess aptget update + + # do what CVE-2012-0214 did + rm $APTARCHIVE/dists/unstable/InRelease + rm $APTARCHIVE/dists/unstable/Release.gpg + inject_evil_package + # build valid Release file + aptftparchive -qq release ./aptarchive > aptarchive/dists/unstable/Release + + assert_update_is_refused_and_last_good_state_used + + # ensure there is no _Release file downloaded + testfailure ls rootdir/var/lib/apt/lists/*_Release +} + +test_subvert_inrelease() +{ + # setup archive with InRelease + setupaptarchive_with_lists_clean + testsuccess aptget update + + # replace InRelease with something else + mv $APTARCHIVE/dists/unstable/Release $APTARCHIVE/dists/unstable/InRelease + + testequal "W: Failed to fetch file:${APTARCHIVE}/dists/unstable/InRelease Does not start with a cleartext signature + +E: Some index files failed to download. They have been ignored, or old ones used instead." aptget update -qq + + # ensure we keep the repo + assert_repo_is_intact +} + +test_inrelease_to_invalid_inrelease() +{ + # setup archive with InRelease + setupaptarchive_with_lists_clean + testsuccess aptget update + + # now remove InRelease and subvert Release do no longer verify + sed -i 's/Codename.*/Codename: evil!'/ $APTARCHIVE/dists/unstable/InRelease + inject_evil_package + + testequal "W: An error occurred during the signature verification. The repository is not updated and the previous index files will be used. GPG error: file: unstable InRelease: The following signatures were invalid: BADSIG 5A90D141DBAC8DAE Joe Sixpack (APT Testcases Dummy) + +W: Failed to fetch file:${APTARCHIVE}/dists/unstable/InRelease + +W: Some index files failed to download. They have been ignored, or old ones used instead." aptget update -qq + + # ensure we keep the repo + assert_repo_is_intact + testfailure grep "evil" rootdir/var/lib/apt/lists/*InRelease +} + +test_release_gpg_to_invalid_release_release_gpg() +{ + # setup archive with InRelease + setupaptarchive_with_lists_clean + rm $APTARCHIVE/dists/unstable/InRelease + testsuccess aptget update + + # now subvert Release do no longer verify + echo "Some evil data" >> $APTARCHIVE/dists/unstable/Release + inject_evil_package + + testequal "E: The repository 'file: unstable Release.gpg' is no longer signed." aptget update -qq + + assert_repo_is_intact + testfailure grep "evil" rootdir/var/lib/apt/lists/*Release +} + + +TESTDIR=$(readlink -f $(dirname $0)) +. $TESTDIR/framework + +setupenvironment +configarchitecture "i386" + +# a "normal" package with source and binary +buildsimplenativepackage 'foo' 'all' '2.0' + +# setup the archive and ensure we have a single package that installs fine +setupaptarchive +APTARCHIVE=$(readlink -f ./aptarchive) +assert_repo_is_intact + +# test the various cases where a repo may go from signed->unsigned +msgmsg "test_from_inrelease_to_unsigned" +test_from_inrelease_to_unsigned + +msgmsg "test_from_release_gpg_to_unsigned" +test_from_release_gpg_to_unsigned + +# ensure we do not regress on CVE-2012-0214 +msgmsg "test_cve_2012_0214" +test_cve_2012_0214 + +# ensure InRelase can not be subverted +msgmsg "test_subvert_inrelease" +test_subvert_inrelease + +# ensure we revert to last good state if InRelease does not verify +msgmsg "test_inrelease_to_invalid_inrelease" +test_inrelease_to_invalid_inrelease + +# ensure we revert to last good state if Release/Release.gpg does not verify +msgmsg "test_release_gpg_to_invalid_release_release_gpg" +test_release_gpg_to_invalid_release_release_gpg -- cgit v1.2.3 From c99fe2e169243fc6e1a3278ce3768f0f521e260b Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Wed, 1 Oct 2014 12:21:55 +0200 Subject: Use Acquire::Allow{InsecureRepositories,DowngradeToInsecureRepositories} The configuration key Acquire::AllowInsecureRepositories controls if apt allows loading of unsigned repositories at all. The configuration Acquire::AllowDowngradeToInsecureRepositories controls if a signed repository can ever become unsigned. This should really never be needed but we provide it to avoid having to mess around in /var/lib/apt/lists if there is a use-case for this (which I can't think of right now). --- test/integration/test-apt-update-nofallback | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'test/integration/test-apt-update-nofallback') diff --git a/test/integration/test-apt-update-nofallback b/test/integration/test-apt-update-nofallback index 4e8ea9916..a53226e18 100755 --- a/test/integration/test-apt-update-nofallback +++ b/test/integration/test-apt-update-nofallback @@ -78,6 +78,25 @@ test_from_release_gpg_to_unsigned() assert_update_is_refused_and_last_good_state_used } +test_from_inrelease_to_unsigned_with_override() +{ + # setup archive with InRelease file + setupaptarchive_with_lists_clean + testsuccess aptget update + + # simulate moving to a unsigned but otherwise valid repo + simulate_mitm_and_inject_evil_package + generatereleasefiles + + # and ensure we can update to it (with enough force) + testsuccess aptget update --allow-insecure-repositories \ + -o Acquire::AllowDowngradeToInsecureRepositories=1 + # but that the individual packages are still considered untrusted + testequal "WARNING: The following packages cannot be authenticated! + evil +E: There are problems and -y was used without --force-yes" aptget install -qq -y evil +} + test_cve_2012_0214() { # see https://bugs.launchpad.net/ubuntu/+source/apt/+bug/947108 @@ -205,3 +224,7 @@ test_inrelease_to_invalid_inrelease # ensure we revert to last good state if Release/Release.gpg does not verify msgmsg "test_release_gpg_to_invalid_release_release_gpg" test_release_gpg_to_invalid_release_release_gpg + +# ensure we can ovveride the downgrade error +msgmsg "test_from_inrelease_to_unsigned" +test_from_inrelease_to_unsigned_with_override -- cgit v1.2.3 From 8beef749860d99fd21ea15852aad7716dd7b741b Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Wed, 1 Oct 2014 14:22:46 +0200 Subject: fix test-apt-update-nofallback test --- test/integration/test-apt-update-nofallback | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'test/integration/test-apt-update-nofallback') diff --git a/test/integration/test-apt-update-nofallback b/test/integration/test-apt-update-nofallback index a53226e18..c400dcc36 100755 --- a/test/integration/test-apt-update-nofallback +++ b/test/integration/test-apt-update-nofallback @@ -181,7 +181,11 @@ test_release_gpg_to_invalid_release_release_gpg() echo "Some evil data" >> $APTARCHIVE/dists/unstable/Release inject_evil_package - testequal "E: The repository 'file: unstable Release.gpg' is no longer signed." aptget update -qq + testequal "W: An error occurred during the signature verification. The repository is not updated and the previous index files will be used. GPG error: file: unstable Release.gpg: The following signatures were invalid: BADSIG 5A90D141DBAC8DAE Joe Sixpack (APT Testcases Dummy) + +W: Failed to fetch file:${APTARCHIVE}/dists/unstable/Release.gpg + +W: Some index files failed to download. They have been ignored, or old ones used instead." aptget update -qq assert_repo_is_intact testfailure grep "evil" rootdir/var/lib/apt/lists/*Release -- cgit v1.2.3 From 4dbfe436c60880f2625e4d3a9d0127a83dd6276e Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Tue, 7 Oct 2014 01:46:30 +0200 Subject: display errortext for all Err as well as Ign logs consistently using Item::Failed in all specializec classes helps setting up some information bits otherwise unset, so some errors had an empty reason as an error. Ign is upgraded to display the error message we ignored to further help in understanding what happens. --- test/integration/test-apt-update-nofallback | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'test/integration/test-apt-update-nofallback') diff --git a/test/integration/test-apt-update-nofallback b/test/integration/test-apt-update-nofallback index c400dcc36..321472c2e 100755 --- a/test/integration/test-apt-update-nofallback +++ b/test/integration/test-apt-update-nofallback @@ -161,7 +161,7 @@ test_inrelease_to_invalid_inrelease() testequal "W: An error occurred during the signature verification. The repository is not updated and the previous index files will be used. GPG error: file: unstable InRelease: The following signatures were invalid: BADSIG 5A90D141DBAC8DAE Joe Sixpack (APT Testcases Dummy) -W: Failed to fetch file:${APTARCHIVE}/dists/unstable/InRelease +W: Failed to fetch file:${APTARCHIVE}/dists/unstable/InRelease The following signatures were invalid: BADSIG 5A90D141DBAC8DAE Joe Sixpack (APT Testcases Dummy) W: Some index files failed to download. They have been ignored, or old ones used instead." aptget update -qq -- cgit v1.2.3