Przeglądaj źródła

show a more descriptive error for weak Release files

If we can't work with the hashes we parsed from the Release file we
display now an error message if the Release file includes only weak
hashes instead of downloading the indexes and failing to verify them
with "Hash Sum mismatch" even through the hashes didn't mismatch (they
were just weak).

If for some (unlikely) reason we have got weak hashes only for
individual targets we will show a warning to this effect (again, befor
downloading and failing the index itself).

Closes: 806459
David Kalnischkies 10 lat temu
rodzic
commit
bd4a8f5164

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

@@ -1075,6 +1075,16 @@ void pkgAcqMetaBase::QueueIndexes(bool const verify)			/*{{{*/
 	    strprintf(ErrorText, _("Unable to find expected entry '%s' in Release file (Wrong sources.list entry or malformed file)"), Target->MetaKey.c_str());
 	    return;
 	 }
+	 else
+	 {
+	    auto const hashes = GetExpectedHashesFor(Target->MetaKey);
+	    if (hashes.usable() == false && hashes.empty() == false)
+	    {
+	       _error->Warning(_("Skipping acquire of configured file '%s' as repository '%s' provides only weak security information for it"),
+			Target->MetaKey.c_str(), TransactionManager->Target.Description.c_str());
+	       continue;
+	    }
+	 }
 
 	 // autoselect the compression method
 	 std::vector<std::string> types = VectorizeString(Target->Option(IndexTarget::COMPRESSIONTYPES), ' ');

+ 15 - 4
apt-pkg/deb/debmetaindex.cc

@@ -348,9 +348,11 @@ bool debReleaseIndex::Load(std::string const &Filename, std::string * const Erro
    }
 
    bool FoundHashSum = false;
-   for (int i=0;HashString::SupportedHashes()[i] != NULL; i++)
+   bool FoundStrongHashSum = false;
+   auto const SupportedHashes = HashString::SupportedHashes();
+   for (int i=0; SupportedHashes[i] != NULL; i++)
    {
-      if (!Section.Find(HashString::SupportedHashes()[i], Start, End))
+      if (!Section.Find(SupportedHashes[i], Start, End))
 	 continue;
 
       std::string Name;
@@ -361,17 +363,20 @@ bool debReleaseIndex::Load(std::string const &Filename, std::string * const Erro
 	 if (!parseSumData(Start, End, Name, Hash, Size))
 	    return false;
 
+	 HashString const hs(SupportedHashes[i], Hash);
          if (Entries.find(Name) == Entries.end())
          {
             metaIndex::checkSum *Sum = new metaIndex::checkSum;
             Sum->MetaKeyFilename = Name;
             Sum->Size = Size;
 	    Sum->Hashes.FileSize(Size);
-            APT_IGNORE_DEPRECATED(Sum->Hash = HashString(HashString::SupportedHashes()[i],Hash);)
+            APT_IGNORE_DEPRECATED(Sum->Hash = hs;)
             Entries[Name] = Sum;
          }
-         Entries[Name]->Hashes.push_back(HashString(HashString::SupportedHashes()[i],Hash));
+         Entries[Name]->Hashes.push_back(hs);
          FoundHashSum = true;
+	 if (FoundStrongHashSum == false && hs.usable() == true)
+	    FoundStrongHashSum = true;
       }
    }
 
@@ -381,6 +386,12 @@ bool debReleaseIndex::Load(std::string const &Filename, std::string * const Erro
 	 strprintf(*ErrorText, _("No Hash entry in Release file %s"), Filename.c_str());
       return false;
    }
+   if(FoundStrongHashSum == false)
+   {
+      if (ErrorText != NULL)
+	 strprintf(*ErrorText, _("No Hash entry in Release file %s, which is considered strong enough for security purposes"), Filename.c_str());
+      return false;
+   }
 
    std::string const StrDate = Section.FindS("Date");
    if (RFC1123StrToTime(StrDate.c_str(), Date) == false)

+ 13 - 0
test/integration/framework

@@ -1420,6 +1420,19 @@ testnopackage() {
 	fi
 	msggroup
 }
+testnosrcpackage() {
+	msggroup 'testnosrcpackage'
+	msgtest "Test for non-existent source packages" "apt-cache showsrc $*"
+	local SHOWPKG="$(aptcache showsrc "$@" 2>&1 | grep '^Package: ')"
+	if [ -n "$SHOWPKG" ]; then
+		local OUTPUT="${TMPWORKINGDIRECTORY}/rootdir/tmp/testnosrcpackage.output"
+		echo "$SHOWPKG" >"$OUTPUT"
+		msgfailoutput '' "$OUTPUT"
+	else
+		msgpass
+	fi
+	msggroup
+}
 
 testdpkgstatus() {
 	msggroup 'testdpkgstatus'

+ 40 - 0
test/integration/test-apt-update-weak-hashes

@@ -0,0 +1,40 @@
+#!/bin/sh
+set -e
+
+TESTDIR="$(readlink -f "$(dirname "$0")")"
+. "$TESTDIR/framework"
+
+setupenvironment
+configarchitecture 'i386'
+confighashes 'MD5'
+
+insertpackage 'unstable' 'foo' 'i386' '1.0'
+insertsource 'unstable' 'foo' 'any' '1.0'
+
+setupaptarchive --no-update
+APTARCHIVE="$(readlink -f ./aptarchive)"
+
+msgmsg 'Release contains only weak hashes'
+FILENAME="${APTARCHIVE}/dists/unstable/InRelease"
+MANGLED="$(readlink -f ./rootdir)/var/lib/apt/lists/partial/$(echo "$FILENAME" | sed 's#/#_#g')"
+testfailuremsg "W: Failed to fetch file:${FILENAME}  No Hash entry in Release file ${MANGLED}, which is considered strong enough for security purposes
+E: Some index files failed to download. They have been ignored, or old ones used instead." apt update
+testnopackage foo
+testnosrcpackage foo
+
+msgmsg 'Release contains no hashes'
+sed -i -e '/^ / d' -e '/^MD5Sum:/ d' "$APTARCHIVE/dists/unstable/Release"
+signreleasefiles
+testfailuremsg "W: Failed to fetch file:${FILENAME}  No Hash entry in Release file ${MANGLED}
+E: Some index files failed to download. They have been ignored, or old ones used instead." apt update
+testnopackage foo
+testnosrcpackage foo
+
+msgmsg 'Release contains only weak hashes for some files'
+confighashes 'MD5' 'SHA256'
+generatereleasefiles
+sed -i '/^ [0-9a-fA-Z]\{64\} .*Sources$/d' "$APTARCHIVE/dists/unstable/Release"
+signreleasefiles
+testwarningmsg "W: Skipping acquire of configured file 'main/source/Sources' as repository 'file:${APTARCHIVE} unstable InRelease' provides only weak security information for it" apt update
+testsuccess apt show foo
+testnosrcpackage foo