]> git.saurik.com Git - apt.git/blobdiff - apt-pkg/acquire-worker.cc
close server if parsing of header field failed
[apt.git] / apt-pkg / acquire-worker.cc
index c009f402e11f170eba3f280af6020b960d0b0cdc..9ed7b5b28fb0d5cc3d42b09cdf14089134f5a63a 100644 (file)
@@ -273,16 +273,19 @@ bool pkgAcquire::Worker::RunMessages()
               // if we change site, treat it as a mirror change
               if (URI::SiteOnly(NewURI) != URI::SiteOnly(desc.URI))
               {
-                 std::string const OldSite = desc.Description.substr(0, desc.Description.find(" "));
-                 if (likely(APT::String::Startswith(desc.URI, OldSite)))
+                 auto const firstSpace = desc.Description.find(" ");
+                 if (firstSpace != std::string::npos)
                  {
-                    std::string const OldExtra = desc.URI.substr(OldSite.length() + 1);
-                    if (likely(APT::String::Endswith(NewURI, OldExtra)))
+                    std::string const OldSite = desc.Description.substr(0, firstSpace);
+                    if (likely(APT::String::Startswith(desc.URI, OldSite)))
                     {
-                       std::string const NewSite = NewURI.substr(0, NewURI.length() - OldExtra.length());
-                       Owner->UsedMirror = URI::ArchiveOnly(NewSite);
-                       if (desc.Description.find(" ") != string::npos)
-                          desc.Description.replace(0, desc.Description.find(" "), Owner->UsedMirror);
+                       std::string const OldExtra = desc.URI.substr(OldSite.length() + 1);
+                       if (likely(APT::String::Endswith(NewURI, OldExtra)))
+                       {
+                          std::string const NewSite = NewURI.substr(0, NewURI.length() - OldExtra.length());
+                          Owner->UsedMirror = URI::ArchiveOnly(NewSite);
+                          desc.Description.replace(0, firstSpace, Owner->UsedMirror);
+                       }
                     }
                  }
               }
@@ -375,6 +378,7 @@ bool pkgAcquire::Worker::RunMessages()
 
            bool const isIMSHit = StringToBool(LookupTag(Message,"IMS-Hit"),false) ||
               StringToBool(LookupTag(Message,"Alt-IMS-Hit"),false);
+           auto const forcedHash = _config->Find("Acquire::ForceHash");
            for (auto const Owner: ItmOwners)
            {
               HashStringList const ExpectedHashes = Owner->GetExpectedHashes();
@@ -392,9 +396,10 @@ bool pkgAcquire::Worker::RunMessages()
 
               // decide if what we got is what we expected
               bool consideredOkay = false;
-              if (ExpectedHashes.usable())
+              if ((forcedHash.empty() && ExpectedHashes.empty() == false) ||
+                    (forcedHash.empty() == false && ExpectedHashes.usable()))
               {
-                 if (ReceivedHashes.usable() == false)
+                 if (ReceivedHashes.empty())
                  {
                     /* IMS-Hits can't be checked here as we will have uncompressed file,
                        but the hashes for the compressed file. What we have was good through
@@ -407,16 +412,8 @@ bool pkgAcquire::Worker::RunMessages()
                     consideredOkay = false;
 
               }
-              else if (Owner->HashesRequired() == true)
-                 consideredOkay = false;
               else
-              {
-                 consideredOkay = true;
-                 // even if the hashes aren't usable to declare something secure
-                 // we can at least use them to declare it an integrity failure
-                 if (ExpectedHashes.empty() == false && ReceivedHashes != ExpectedHashes && _config->Find("Acquire::ForceHash").empty())
-                    consideredOkay = false;
-              }
+                 consideredOkay = !Owner->HashesRequired();
 
               if (consideredOkay == true)
                  consideredOkay = Owner->VerifyDone(Message, Config);
@@ -440,7 +437,13 @@ bool pkgAcquire::Worker::RunMessages()
               {
                  if (isDoomedItem(Owner) == false)
                  {
-                    Message.append("\nFailReason: HashSumMismatch");
+                    if (Message.find("\nFailReason:") == std::string::npos)
+                    {
+                       if (ReceivedHashes != ExpectedHashes)
+                          Message.append("\nFailReason: HashSumMismatch");
+                       else
+                          Message.append("\nFailReason: WeakHashSums");
+                    }
                     Owner->Failed(Message,Config);
                  }
                  if (Log != nullptr)
@@ -471,18 +474,28 @@ bool pkgAcquire::Worker::RunMessages()
            OwnerQ->ItemDone(Itm);
            Itm = nullptr;
 
-           bool errTransient;
+           bool errTransient = false, errAuthErr = false;
            {
               std::string const failReason = LookupTag(Message, "FailReason");
-              std::string const reasons[] = { "Timeout", "ConnectionRefused",
-                 "ConnectionTimedOut", "ResolveFailure", "TmpResolveFailure" };
-              errTransient = std::find(std::begin(reasons), std::end(reasons), failReason) != std::end(reasons);
+              {
+                 auto const reasons = { "Timeout", "ConnectionRefused",
+                    "ConnectionTimedOut", "ResolveFailure", "TmpResolveFailure" };
+                 errTransient = std::find(std::begin(reasons), std::end(reasons), failReason) != std::end(reasons);
+              }
+              if (errTransient == false)
+              {
+                 auto const reasons = { "HashSumMismatch", "WeakHashSums", "MaximumSizeExceeded" };
+                 errAuthErr = std::find(std::begin(reasons), std::end(reasons), failReason) != std::end(reasons);
+              }
            }
 
            for (auto const Owner: ItmOwners)
            {
-              if (errTransient)
+              if (errAuthErr && Owner->GetExpectedHashes().empty() == false)
+                 Owner->Status = pkgAcquire::Item::StatAuthError;
+              else if (errTransient)
                  Owner->Status = pkgAcquire::Item::StatTransientNetworkError;
+
               if (isDoomedItem(Owner) == false)
                  Owner->Failed(Message,Config);
               if (Log != nullptr)
@@ -618,12 +631,36 @@ bool pkgAcquire::Worker::QueueItem(pkgAcquire::Queue::QItem *Item)
    if (OutFd == -1)
       return false;
 
+   HashStringList const hsl = Item->GetExpectedHashes();
+
+   if (isDoomedItem(Item->Owner))
+      return true;
+
+   if (hsl.usable() == false && Item->Owner->HashesRequired() &&
+        _config->Exists("Acquire::ForceHash") == false)
+   {
+      std::string const Message = "400 URI Failure"
+        "\nURI: " + Item->URI +
+        "\nFilename: " + Item->Owner->DestFile +
+        "\nFailReason: WeakHashSums";
+
+      auto const ItmOwners = Item->Owners;
+      for (auto &O: ItmOwners)
+      {
+        O->Status = pkgAcquire::Item::StatAuthError;
+        O->Failed(Message, Config);
+        if (Log != nullptr)
+           Log->Fail(O->GetItemDesc());
+      }
+      // "queued" successfully, the item just instantly failed
+      return true;
+   }
+
    string Message = "600 URI Acquire\n";
    Message.reserve(300);
    Message += "URI: " + Item->URI;
    Message += "\nFilename: " + Item->Owner->DestFile;
 
-   HashStringList const hsl = Item->GetExpectedHashes();
    for (HashStringList::const_iterator hs = hsl.begin(); hs != hsl.end(); ++hs)
       Message += "\nExpected-" + hs->HashType() + ": " + hs->HashValue();