X-Git-Url: https://git.saurik.com/apt.git/blobdiff_plain/73da43e90be945d3be9b4f3b6e5016fb7bacb59d..d4273c55e34cdf5a355b4edd92df61a83cfab318:/apt-pkg/acquire-item.cc diff --git a/apt-pkg/acquire-item.cc b/apt-pkg/acquire-item.cc index a6698b367..665dd427e 100644 --- a/apt-pkg/acquire-item.cc +++ b/apt-pkg/acquire-item.cc @@ -13,6 +13,8 @@ ##################################################################### */ /*}}}*/ // Include Files /*{{{*/ +#include + #include #include #include @@ -23,9 +25,9 @@ #include #include #include +#include +#include -#include - #include #include #include @@ -33,6 +35,8 @@ #include #include #include + +#include /*}}}*/ using namespace std; @@ -185,14 +189,14 @@ void pkgAcquire::Item::ReportMirrorFailure(string FailCode) /*}}}*/ // AcqSubIndex::AcqSubIndex - Constructor /*{{{*/ // --------------------------------------------------------------------- -/* Get the Index file first and see if there are languages available - * If so, create a pkgAcqIndexTrans for the found language(s). - */ +/* Get a sub-index file based on checksums from a 'master' file and + possibly query additional files */ pkgAcqSubIndex::pkgAcqSubIndex(pkgAcquire *Owner, string const &URI, string const &URIDesc, string const &ShortDesc, HashString const &ExpectedHash) : Item(Owner), ExpectedHash(ExpectedHash) { + /* XXX: Beware: Currently this class does nothing (of value) anymore ! */ Debug = _config->FindB("Debug::pkgAcquire::SubIndex",false); DestFile = _config->FindDir("Dir::State::lists") + "partial/"; @@ -232,17 +236,7 @@ void pkgAcqSubIndex::Failed(string Message,pkgAcquire::MethodConfig *Cnf) /*{{{* Status = StatDone; Dequeue(); - // No good Index is provided, so try guessing - std::vector langs = APT::Configuration::getLanguages(true); - for (std::vector::const_iterator l = langs.begin(); - l != langs.end(); ++l) - { - if (*l == "none") continue; - string const file = "Translation-" + *l; - new pkgAcqIndexTrans(Owner, Desc.URI.substr(0, Desc.URI.rfind('/')+1).append(file), - Desc.Description.erase(Desc.Description.rfind(' ')+1).append(file), - file); - } + // No good Index is provided } /*}}}*/ void pkgAcqSubIndex::Done(string Message,unsigned long long Size,string Md5Hash, /*{{{*/ @@ -301,38 +295,7 @@ bool pkgAcqSubIndex::ParseIndex(string const &IndexFile) /*{{{*/ indexRecords SubIndexParser; if (FileExists(IndexFile) == false || SubIndexParser.Load(IndexFile) == false) return false; - - std::vector lang = APT::Configuration::getLanguages(true); - for (std::vector::const_iterator l = lang.begin(); - l != lang.end(); ++l) - { - if (*l == "none") - continue; - - string file = "Translation-" + *l; - indexRecords::checkSum const *Record = SubIndexParser.Lookup(file); - HashString expected; - if (Record == NULL) - { - // FIXME: the Index file provided by debian currently only includes bz2 records - Record = SubIndexParser.Lookup(file + ".bz2"); - if (Record == NULL) - continue; - } - else - { - expected = Record->Hash; - if (expected.empty() == true) - continue; - } - - IndexTarget target; - target.Description = Desc.Description.erase(Desc.Description.rfind(' ')+1).append(file); - target.MetaKey = file; - target.ShortDesc = file; - target.URI = Desc.URI.substr(0, Desc.URI.rfind('/')+1).append(file); - new pkgAcqIndexTrans(Owner, &target, expected, &SubIndexParser); - } + // so something with the downloaded index return true; } /*}}}*/ @@ -434,7 +397,7 @@ bool pkgAcqDiffIndex::ParseDiffIndex(string IndexDiffFile) /*{{{*/ FileFd fd(CurrentPackagesFile, FileFd::ReadOnly); SHA1Summation SHA1; - SHA1.AddFD(fd.Fd(), fd.Size()); + SHA1.AddFD(fd); string const local_sha1 = SHA1.Result(); if(local_sha1 == ServerSha1) @@ -665,7 +628,7 @@ bool pkgAcqIndexDiffs::QueueNextDiff() /*{{{*/ FileFd fd(FinalFile, FileFd::ReadOnly); SHA1Summation SHA1; - SHA1.AddFD(fd.Fd(), fd.Size()); + SHA1.AddFD(fd); string local_sha1 = string(SHA1.Result()); if(Debug) std::clog << "QueueNextDiff: " @@ -681,17 +644,17 @@ bool pkgAcqIndexDiffs::QueueNextDiff() /*{{{*/ // remove all patches until the next matching patch is found // this requires the Index file to be ordered for(vector::iterator I=available_patches.begin(); - available_patches.size() > 0 && + available_patches.empty() == false && I != available_patches.end() && - (*I).sha1 != local_sha1; - I++) + I->sha1 != local_sha1; + ++I) { available_patches.erase(I); } // error checking and falling back if no patch was found - if(available_patches.size() == 0) - { + if(available_patches.empty() == true) + { Failed("", NULL); return false; } @@ -756,7 +719,7 @@ void pkgAcqIndexDiffs::Done(string Message,unsigned long long Size,string Md5Has chmod(FinalFile.c_str(),0644); // see if there is more to download - if(available_patches.size() > 0) { + if(available_patches.empty() == false) { new pkgAcqIndexDiffs(Owner, RealURI, Description, Desc.ShortDesc, ExpectedHash, ServerSha1, available_patches); return Finish(); @@ -808,6 +771,13 @@ pkgAcqIndex::pkgAcqIndex(pkgAcquire *Owner, IndexTarget const *Target, if (CompressionExtension.empty() == false) CompressionExtension.erase(CompressionExtension.end()-1); + // only verify non-optional targets, see acquire-item.h for a FIXME + // to make this more flexible + if (Target->IsOptional()) + Verify = false; + else + Verify = true; + Init(Target->URI, Target->Description, Target->ShortDesc); } /*}}}*/ @@ -905,6 +875,7 @@ void pkgAcqIndex::Done(string Message,unsigned long long Size,string Hash, /* Verify the index file for correctness (all indexes must * have a Package field) (LP: #346386) (Closes: #627642) */ + if (Verify == true) { FileFd fd(DestFile, FileFd::ReadOnly); pkgTagSection sec; @@ -1258,14 +1229,26 @@ void pkgAcqMetaIndex::Done(string Message,unsigned long long Size,string Hash, / if (SigFile == "") { // There was no signature file, so we are finished. Download - // the indexes without verification. + // the indexes and do only hashsum verification if possible + MetaIndexParser->Load(DestFile); QueueIndexes(false); } else { + // FIXME: move this into pkgAcqMetaClearSig::Done on the next + // ABI break + + // if we expect a ClearTextSignature (InRelase), ensure that + // this is what we get and if not fail to queue a + // Release/Release.gpg, see #346386 + if (SigFile == DestFile && !StartsWithGPGClearTextSignature(DestFile)) + { + Failed(Message, Cfg); + return; + } + // There was a signature file, so pass it to gpgv for // verification - if (_config->FindB("Debug::pkgAcquire::Auth", false)) std::cerr << "Metaindex acquired, queueing gpg verification (" << SigFile << "," << DestFile << ")\n"; @@ -1372,37 +1355,47 @@ void pkgAcqMetaIndex::QueueIndexes(bool verify) /*{{{*/ return; } #endif + bool transInRelease = false; + { + std::vector const keys = MetaIndexParser->MetaKeys(); + for (std::vector::const_iterator k = keys.begin(); k != keys.end(); ++k) + // FIXME: Feels wrong to check for hardcoded string here, but what should we do else… + if (k->find("Translation-") != std::string::npos) + { + transInRelease = true; + break; + } + } + for (vector ::const_iterator Target = IndexTargets->begin(); Target != IndexTargets->end(); - Target++) + ++Target) { HashString ExpectedIndexHash; - if (verify) + const indexRecords::checkSum *Record = MetaIndexParser->Lookup((*Target)->MetaKey); + if (Record == NULL) { - const indexRecords::checkSum *Record = MetaIndexParser->Lookup((*Target)->MetaKey); - if (Record == NULL) + if (verify == true && (*Target)->IsOptional() == false) { - if ((*Target)->IsOptional() == false) - { - Status = StatAuthError; - strprintf(ErrorText, _("Unable to find expected entry '%s' in Release file (Wrong sources.list entry or malformed file)"), (*Target)->MetaKey.c_str()); - return; - } + Status = StatAuthError; + strprintf(ErrorText, _("Unable to find expected entry '%s' in Release file (Wrong sources.list entry or malformed file)"), (*Target)->MetaKey.c_str()); + return; } - else + } + else + { + ExpectedIndexHash = Record->Hash; + if (_config->FindB("Debug::pkgAcquire::Auth", false)) { - ExpectedIndexHash = Record->Hash; - if (_config->FindB("Debug::pkgAcquire::Auth", false)) - { - std::cerr << "Queueing: " << (*Target)->URI << std::endl; - std::cerr << "Expected Hash: " << ExpectedIndexHash.toStr() << std::endl; - } - if (ExpectedIndexHash.empty() == true && (*Target)->IsOptional() == false) - { - Status = StatAuthError; - strprintf(ErrorText, _("Unable to find hash sum for '%s' in Release file"), (*Target)->MetaKey.c_str()); - return; - } + std::cerr << "Queueing: " << (*Target)->URI << std::endl; + std::cerr << "Expected Hash: " << ExpectedIndexHash.toStr() << std::endl; + std::cerr << "For: " << Record->MetaKeyFilename << std::endl; + } + if (verify == true && ExpectedIndexHash.empty() == true && (*Target)->IsOptional() == false) + { + Status = StatAuthError; + strprintf(ErrorText, _("Unable to find hash sum for '%s' in Release file"), (*Target)->MetaKey.c_str()); + return; } } @@ -1411,8 +1404,15 @@ void pkgAcqMetaIndex::QueueIndexes(bool verify) /*{{{*/ if ((*Target)->IsSubIndex() == true) new pkgAcqSubIndex(Owner, (*Target)->URI, (*Target)->Description, (*Target)->ShortDesc, ExpectedIndexHash); - else - new pkgAcqIndexTrans(Owner, *Target, ExpectedIndexHash, MetaIndexParser); + else if (transInRelease == false || MetaIndexParser->Exists((*Target)->MetaKey) == true) + { + if (_config->FindB("Acquire::PDiffs",true) == true && transInRelease == true && + MetaIndexParser->Exists(string((*Target)->MetaKey).append(".diff/Index")) == true) + new pkgAcqDiffIndex(Owner, (*Target)->URI, (*Target)->Description, + (*Target)->ShortDesc, ExpectedIndexHash); + else + new pkgAcqIndexTrans(Owner, *Target, ExpectedIndexHash, MetaIndexParser); + } continue; } @@ -1473,8 +1473,10 @@ bool pkgAcqMetaIndex::VerifyVendor(string Message) /*{{{*/ // TRANSLATOR: The first %s is the URL of the bad Release file, the second is // the time since then the file is invalid - formated in the same way as in // the download progress display (e.g. 7d 3h 42min 1s) - return _error->Error(_("Release file expired, ignoring %s (invalid since %s)"), - RealURI.c_str(), TimeToStr(invalid_since).c_str()); + return _error->Error( + _("Release file for %s is expired (invalid since %s). " + "Updates for this repository will not be applied."), + RealURI.c_str(), TimeToStr(invalid_since).c_str()); } if (_config->FindB("Debug::pkgAcquire::Auth", false)) @@ -1607,6 +1609,13 @@ void pkgAcqMetaClearSig::Failed(string Message,pkgAcquire::MethodConfig *Cnf) /* { if (AuthPass == false) { + // Remove the 'old' InRelease file if we try Release.gpg now as otherwise + // the file will stay around and gives a false-auth impression (CVE-2012-0214) + string FinalFile = _config->FindDir("Dir::State::lists"); + FinalFile.append(URItoFileName(RealURI)); + if (FileExists(FinalFile)) + unlink(FinalFile.c_str()); + new pkgAcqMetaSig(Owner, MetaSigURI, MetaSigURIDesc, MetaSigShortDesc, MetaIndexURI, MetaIndexURIDesc, MetaIndexShortDesc, @@ -1669,7 +1678,7 @@ pkgAcqArchive::pkgAcqArchive(pkgAcquire *Owner,pkgSourceList *Sources, // check if we have one trusted source for the package. if so, switch // to "TrustedOnly" mode - for (pkgCache::VerFileIterator i = Version.FileList(); i.end() == false; i++) + for (pkgCache::VerFileIterator i = Version.FileList(); i.end() == false; ++i) { pkgIndexFile *Index; if (Sources->FindIndex(i.File(),Index) == false) @@ -1706,7 +1715,7 @@ pkgAcqArchive::pkgAcqArchive(pkgAcquire *Owner,pkgSourceList *Sources, bool pkgAcqArchive::QueueNext() { string const ForceHash = _config->Find("Acquire::ForceHash"); - for (; Vf.end() == false; Vf++) + for (; Vf.end() == false; ++Vf) { // Ignore not source sources if ((Vf.File()->Flags & pkgCache::Flag::NotSource) != 0) @@ -1812,7 +1821,18 @@ bool pkgAcqArchive::QueueNext() else PartialSize = Buf.st_size; } - + + // Disables download of archives - useful if no real installation follows, + // e.g. if we are just interested in proposed installation order + if (_config->FindB("Debug::pkgAcqArchive::NoQueue", false) == true) + { + Complete = true; + Local = true; + Status = StatDone; + StoreFilename = DestFile = FinalFile; + return true; + } + // Create the item Local = false; Desc.URI = Index->ArchiveURI(PkgFile); @@ -1821,7 +1841,7 @@ bool pkgAcqArchive::QueueNext() Desc.ShortDesc = Version.ParentPkg().Name(); QueueURI(Desc); - Vf++; + ++Vf; return true; } return false; @@ -1895,7 +1915,7 @@ void pkgAcqArchive::Failed(string Message,pkgAcquire::MethodConfig *Cnf) StringToBool(LookupTag(Message,"Transient-Failure"),false) == true) { // Vf = Version.FileList(); - while (Vf.end() == false) Vf++; + while (Vf.end() == false) ++Vf; StoreFilename = string(); Item::Failed(Message,Cnf); return; @@ -2069,13 +2089,3 @@ string pkgAcqFile::Custom600Headers() return ""; } /*}}}*/ -bool IndexTarget::IsOptional() const { - if (strncmp(ShortDesc.c_str(), "Translation", 11) != 0) - return false; - return true; -} -bool IndexTarget::IsSubIndex() const { - if (ShortDesc != "TranslationIndex") - return false; - return true; -}