Просмотр исходного кода

randomize acquire order for same type index files

Without randomizing the order in which we download the index files we
leak needlessly information to the mirrors of which architecture is
native or foreign on this system. More importantly, we leak the order in
which description translations will be used which in most cases will e.g.
have the native tongue first.

Note that the leak effect in practice is limited as apt detects if a file
it wants to download is already available in the latest version from a
previous download and does not query the server in such cases. Combined
with the fact that Translation files are usually updated infrequently
and not all at the same time, so a mirror can never be sure if it got asked
about all files the user wants.
David Kalnischkies лет назад: 10
Родитель
Сommit
4ff5e237d5
3 измененных файлов с 41 добавлено и 3 удалено
  1. 18 0
      apt-pkg/acquire-item.cc
  2. 2 0
      test/integration/framework
  3. 21 3
      test/integration/test-apt-update-simple

+ 18 - 0
apt-pkg/acquire-item.cc

@@ -46,6 +46,7 @@
 #include <ctime>
 #include <ctime>
 #include <sstream>
 #include <sstream>
 #include <numeric>
 #include <numeric>
+#include <random>
 
 
 #include <apti18n.h>
 #include <apti18n.h>
 									/*}}}*/
 									/*}}}*/
@@ -1340,6 +1341,23 @@ void pkgAcqMetaClearSig::QueueIndexes(bool const verify)			/*{{{*/
    if (hasReleaseFile && verify == false)
    if (hasReleaseFile && verify == false)
       hasHashes = std::any_of(IndexTargets.begin(), IndexTargets.end(),
       hasHashes = std::any_of(IndexTargets.begin(), IndexTargets.end(),
 	    [&](IndexTarget const &Target) { return TransactionManager->MetaIndexParser->Exists(Target.MetaKey); });
 	    [&](IndexTarget const &Target) { return TransactionManager->MetaIndexParser->Exists(Target.MetaKey); });
+   if (_config->FindB("Acquire::IndexTargets::Randomized", true) && likely(IndexTargets.empty() == false))
+   {
+      /* For fallback handling and to have some reasonable progress information
+	 we can't randomize everything, but at least the order in the same type
+	 can be as we shouldn't be telling the mirrors (and everyone else watching)
+	 which is native/foreign arch, specific order of preference of translations, … */
+      auto range_start = IndexTargets.begin();
+      std::random_device rd;
+      std::default_random_engine g(rd());
+      do {
+	 auto const type = range_start->Option(IndexTarget::CREATED_BY);
+	 auto const range_end = std::find_if_not(range_start, IndexTargets.end(),
+	       [&type](IndexTarget const &T) { return type == T.Option(IndexTarget::CREATED_BY); });
+	 std::shuffle(range_start, range_end, g);
+	 range_start = range_end;
+      } while (range_start != IndexTargets.end());
+   }
    for (auto&& Target: IndexTargets)
    for (auto&& Target: IndexTargets)
    {
    {
       // if we have seen a target which is created-by a target this one here is declared a
       // if we have seen a target which is created-by a target this one here is declared a

+ 2 - 0
test/integration/framework

@@ -436,6 +436,8 @@ EOF
 		# in testcases, it can appear as if localhost has a rotation setup,
 		# in testcases, it can appear as if localhost has a rotation setup,
 		# hide this as we can't really deal with it properly
 		# hide this as we can't really deal with it properly
 		echo 'Acquire::Failure::ShowIP "false";'
 		echo 'Acquire::Failure::ShowIP "false";'
+		# randomess and tests don't play well together
+		echo 'Acquire::IndexTargets::Randomized "false";'
 		# fakeroot can't fake everything, so disabled in production but good for tests
 		# fakeroot can't fake everything, so disabled in production but good for tests
 		echo 'APT::Sandbox::Verify "true";'
 		echo 'APT::Sandbox::Verify "true";'
 	} >> aptconfig.conf
 	} >> aptconfig.conf

+ 21 - 3
test/integration/test-apt-update-simple

@@ -6,10 +6,28 @@ TESTDIR="$(readlink -f "$(dirname "$0")")"
 setupenvironment
 setupenvironment
 configarchitecture 'amd64'
 configarchitecture 'amd64'
 
 
-insertpackage 'unstable' 'unrelated' 'all' '0.5~squeeze1'
-insertsource 'unstable' 'unrelated' 'all' '0.5~squeeze1'
+insertpackage 'unstable' 'foo' 'all' '1'
+insertpackage 'unstable' 'bar' 'amd64' '1'
+insertpackage 'unstable' 'bar' 'i386' '1'
+insertsource 'unstable' 'foo' 'all' '1'
+
+sed -e 's#^Description-en:#Description-de:#' \
+	aptarchive/dists/unstable/main/i18n/Translation-en > aptarchive/dists/unstable/main/i18n/Translation-de
 
 
 setupaptarchive --no-update
 setupaptarchive --no-update
 changetowebserver
 changetowebserver
 
 
-testsuccess aptget update -o Debug::Acquire::Auth=1
+# the framework modifies some configs to ensure testability,
+# at the expense of creating an environment which doesn't always
+# reflect apts "normal" behavior on a "normal" system
+echo 'Acquire::IndexTargets::Randomized "true";
+Acquire::Languages { "environment"; "en"; "de"; };
+' > rootdir/etc/apt/apt.conf.d/restore-simplicity
+
+testempty aptget indextargets
+testsuccess aptget update
+testequal 'main/source/Sources
+main/binary-amd64/Packages
+main/binary-all/Packages
+main/i18n/Translation-en
+main/i18n/Translation-de' aptget indextargets --format '$(METAKEY)'