X-Git-Url: https://git.saurik.com/apt.git/blobdiff_plain/0340069cc4709a18ba117090763d9f263de999a9..7a3b00b10b6a5a740e07fc1b68a4f3fb3bcdac23:/apt-pkg/acquire-worker.cc?ds=inline diff --git a/apt-pkg/acquire-worker.cc b/apt-pkg/acquire-worker.cc index c009f402e..7d6e6f79c 100644 --- a/apt-pkg/acquire-worker.cc +++ b/apt-pkg/acquire-worker.cc @@ -93,17 +93,38 @@ pkgAcquire::Worker::~Worker() bool pkgAcquire::Worker::Start() { // Get the method path - string Method = _config->FindDir("Dir::Bin::Methods") + Access; + constexpr char const * const methodsDir = "Dir::Bin::Methods"; + std::string const confItem = std::string(methodsDir) + "::" + Access; + std::string Method; + if (_config->Exists(confItem)) + Method = _config->FindFile(confItem.c_str()); + else + Method = _config->FindDir(methodsDir) + Access; if (FileExists(Method) == false) { + if (flNotDir(Method) == "false") + { + _error->Error(_("The method '%s' is explicitly disabled via configuration."), Access.c_str()); + if (Access == "http" || Access == "https") + _error->Notice(_("If you meant to use Tor remember to use %s instead of %s."), ("tor+" + Access).c_str(), Access.c_str()); + return false; + } _error->Error(_("The method driver %s could not be found."),Method.c_str()); - if (Access == "https") - _error->Notice(_("Is the package %s installed?"), "apt-transport-https"); + std::string const A(Access.cbegin(), std::find(Access.cbegin(), Access.cend(), '+')); + std::string pkg; + strprintf(pkg, "apt-transport-%s", A.c_str()); + _error->Notice(_("Is the package %s installed?"), pkg.c_str()); return false; } + std::string const Calling = _config->FindDir(methodsDir) + Access; if (Debug == true) - clog << "Starting method '" << Method << '\'' << endl; + { + std::clog << "Starting method '" << Calling << "'"; + if (Calling != Method) + std::clog << " ( via " << Method << " )"; + std::clog << endl; + } // Create the pipes int Pipes[4] = {-1,-1,-1,-1}; @@ -128,11 +149,9 @@ bool pkgAcquire::Worker::Start() SetCloseExec(STDIN_FILENO,false); SetCloseExec(STDERR_FILENO,false); - const char *Args[2]; - Args[0] = Method.c_str(); - Args[1] = 0; - execv(Args[0],(char **)Args); - cerr << "Failed to exec method " << Args[0] << endl; + const char * const Args[] = { Calling.c_str(), nullptr }; + execv(Method.c_str() ,const_cast(Args)); + std::cerr << "Failed to exec method " << Calling << " ( via " << Method << ")" << endl; _exit(100); } @@ -267,22 +286,35 @@ bool pkgAcquire::Worker::RunMessages() for (auto const &Owner: ItmOwners) { pkgAcquire::ItemDesc &desc = Owner->GetItemDesc(); + if (Owner->IsRedirectionLoop(NewURI)) + { + std::string msg = Message; + msg.append("\nFailReason: RedirectionLoop"); + Owner->Failed(msg, Config); + if (Log != nullptr) + Log->Fail(Owner->GetItemDesc()); + continue; + } + if (Log != nullptr) Log->Done(desc); // 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 +407,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 +425,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 +441,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); @@ -438,13 +464,20 @@ bool pkgAcquire::Worker::RunMessages() } else { + auto SavedDesc = Owner->GetItemDesc(); 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) - Log->Fail(Owner->GetItemDesc()); + Log->Fail(SavedDesc); } } ItemDone(); @@ -471,22 +504,32 @@ 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; + auto SavedDesc = Owner->GetItemDesc(); if (isDoomedItem(Owner) == false) Owner->Failed(Message,Config); if (Log != nullptr) - Log->Fail(Owner->GetItemDesc()); + Log->Fail(SavedDesc); } ItemDone(); @@ -618,6 +661,9 @@ bool pkgAcquire::Worker::QueueItem(pkgAcquire::Queue::QItem *Item) if (OutFd == -1) return false; + if (isDoomedItem(Item->Owner)) + return true; + string Message = "600 URI Acquire\n"; Message.reserve(300); Message += "URI: " + Item->URI; @@ -646,7 +692,7 @@ bool pkgAcquire::Worker::QueueItem(pkgAcquire::Queue::QItem *Item) { std::string const SandboxUser = _config->Find("APT::Sandbox::User"); ChangeOwnerAndPermissionOfFile("Item::QueueURI", Item->Owner->DestFile.c_str(), - SandboxUser.c_str(), "root", 0600); + SandboxUser.c_str(), ROOT_GROUP, 0600); } if (Debug == true) @@ -742,7 +788,7 @@ void pkgAcquire::Worker::PrepareFiles(char const * const caller, pkgAcquire::Que { if (RealFileExists(Itm->Owner->DestFile)) { - ChangeOwnerAndPermissionOfFile(caller, Itm->Owner->DestFile.c_str(), "root", "root", 0644); + ChangeOwnerAndPermissionOfFile(caller, Itm->Owner->DestFile.c_str(), "root", ROOT_GROUP, 0644); std::string const filename = Itm->Owner->DestFile; for (pkgAcquire::Queue::QItem::owner_iterator O = Itm->Owners.begin(); O != Itm->Owners.end(); ++O) {