]> git.saurik.com Git - apt.git/blobdiff - apt-pkg/acquire-item.cc
use 'best' hash for source authentication
[apt.git] / apt-pkg / acquire-item.cc
index 22b77cbda310eda13c6d4f01eca272c5114c8318..913764f64ce04fdc91238a0f3066a4b29209bf50 100644 (file)
@@ -55,7 +55,8 @@ using namespace std;
 /* */
 pkgAcquire::Item::Item(pkgAcquire *Owner) : Owner(Owner), FileSize(0),
                        PartialSize(0), Mode(0), ID(0), Complete(false), 
-                       Local(false), QueueCounter(0)
+                       Local(false), QueueCounter(0), 
+                       ExpectedAdditionalItems(0)
 {
    Owner->Add(this);
    Status = StatIdle;
@@ -342,21 +343,24 @@ bool pkgAcqSubIndex::ParseIndex(string const &IndexFile)          /*{{{*/
  * the original packages file
  */
 pkgAcqDiffIndex::pkgAcqDiffIndex(pkgAcquire *Owner,
-                                string URI,string URIDesc,string ShortDesc,
-                                HashString ExpectedHash)
-   : Item(Owner), RealURI(URI), ExpectedHash(ExpectedHash),
-     Description(URIDesc)
+                                 IndexTarget const *Target,
+                                HashString ExpectedHash,
+                                 indexRecords *MetaIndexParser)
+   : Item(Owner), ExpectedHash(ExpectedHash), Target(Target),
+     MetaIndexParser(MetaIndexParser)
+     
 {
    
    Debug = _config->FindB("Debug::pkgAcquire::Diffs",false);
 
-   Desc.Description = URIDesc + "/DiffIndex";
+   RealURI = Target->URI;
    Desc.Owner = this;
-   Desc.ShortDesc = ShortDesc;
-   Desc.URI = URI + ".diff/Index";
+   Desc.Description = Target->Description + "/DiffIndex";
+   Desc.ShortDesc = Target->ShortDesc;
+   Desc.URI = Target->URI + ".diff/Index";
 
    DestFile = _config->FindDir("Dir::State::lists") + "partial/";
-   DestFile += URItoFileName(URI) + string(".DiffIndex");
+   DestFile += URItoFileName(Target->URI) + string(".DiffIndex");
 
    if(Debug)
       std::clog << "pkgAcqDiffIndex: " << Desc.URI << std::endl;
@@ -559,8 +563,7 @@ void pkgAcqDiffIndex::Failed(string Message,pkgAcquire::MethodConfig * /*Cnf*/)/
       std::clog << "pkgAcqDiffIndex failed: " << Desc.URI << " with " << Message << std::endl
                << "Falling back to normal index file acquire" << std::endl;
 
-   new pkgAcqIndex(Owner, RealURI, Description, Desc.ShortDesc, 
-                  ExpectedHash);
+   new pkgAcqIndex(Owner, Target, ExpectedHash, MetaIndexParser);
 
    Complete = false;
    Status = StatDone;
@@ -919,7 +922,8 @@ void pkgAcqIndexMergeDiffs::Done(string Message,unsigned long long Size,string M
 pkgAcqIndex::pkgAcqIndex(pkgAcquire *Owner,
                         string URI,string URIDesc,string ShortDesc,
                         HashString ExpectedHash, string comprExt)
-   : Item(Owner), RealURI(URI), ExpectedHash(ExpectedHash)
+   : Item(Owner), RealURI(URI), ExpectedHash(ExpectedHash), Target(0),
+     MetaIndexParser(0)
 {
    if(comprExt.empty() == true)
    {
@@ -932,10 +936,12 @@ pkgAcqIndex::pkgAcqIndex(pkgAcquire *Owner,
    }
    CompressionExtension = comprExt;
 
+   Verify = true;
+
    Init(URI, URIDesc, ShortDesc);
 }
 pkgAcqIndex::pkgAcqIndex(pkgAcquire *Owner, IndexTarget const *Target,
-                        HashString const &ExpectedHash, indexRecords const *MetaIndexParser)
+                        HashString const &ExpectedHash, indexRecords *MetaIndexParser)
    : Item(Owner), RealURI(Target->URI), ExpectedHash(ExpectedHash)
 {
    // autoselect the compression method
@@ -962,6 +968,10 @@ pkgAcqIndex::pkgAcqIndex(pkgAcquire *Owner, IndexTarget const *Target,
    else
      Verify = true;
 
+   // we need this in Init()
+   this->Target = Target;
+   this->MetaIndexParser = MetaIndexParser;
+
    Init(Target->URI, Target->Description, Target->ShortDesc);
 }
                                                                        /*}}}*/
@@ -974,10 +984,27 @@ void pkgAcqIndex::Init(string const &URI, string const &URIDesc, string const &S
    DestFile += URItoFileName(URI);
 
    std::string const comprExt = CompressionExtension.substr(0, CompressionExtension.find(' '));
+   std::string MetaKey;
    if (comprExt == "uncompressed")
+   {
       Desc.URI = URI;
+      if(Target)
+         MetaKey = string(Target->MetaKey);
+   }
    else
+   {
       Desc.URI = URI + '.' + comprExt;
+      if(Target)
+         MetaKey = string(Target->MetaKey) + '.' + comprExt;
+   }
+
+   // load the filesize
+   if(MetaIndexParser)
+   {
+      indexRecords::checkSum *Record = MetaIndexParser->Lookup(MetaKey);
+      if(Record)
+         FileSize = Record->Size;
+   }
 
    Desc.Description = URIDesc;
    Desc.Owner = this;
@@ -1079,7 +1106,7 @@ void pkgAcqIndex::Done(string Message,unsigned long long Size,string Hash,
       FinalFile += URItoFileName(RealURI);
       Rename(DestFile,FinalFile);
       chmod(FinalFile.c_str(),0644);
-      
+
       /* We restore the original name to DestFile so that the clean operation
          will work OK */
       DestFile = _config->FindDir("Dir::State::lists") + "partial/";
@@ -1088,6 +1115,7 @@ void pkgAcqIndex::Done(string Message,unsigned long long Size,string Hash,
       // Remove the compressed version.
       if (Erase == true)
         unlink(DestFile.c_str());
+
       return;
    }
 
@@ -1175,9 +1203,13 @@ pkgAcqIndexTrans::pkgAcqIndexTrans(pkgAcquire *Owner,
 {
 }
 pkgAcqIndexTrans::pkgAcqIndexTrans(pkgAcquire *Owner, IndexTarget const *Target,
-                        HashString const &ExpectedHash, indexRecords const *MetaIndexParser)
+                        HashString const &ExpectedHash, indexRecords *MetaIndexParser)
   : pkgAcqIndex(Owner, Target, ExpectedHash, MetaIndexParser)
 {
+   // load the filesize
+   indexRecords::checkSum *Record = MetaIndexParser->Lookup(string(Target->MetaKey));
+   if(Record)
+      FileSize = Record->Size;
 }
                                                                        /*}}}*/
 // AcqIndexTrans::Custom600Headers - Insert custom request headers     /*{{{*/
@@ -1257,6 +1289,9 @@ pkgAcqMetaSig::pkgAcqMetaSig(pkgAcquire *Owner,                           /*{{{*/
       Rename(Final,LastGoodSig);
    }
 
+   // we expect the indextargets + one additional Release file
+   ExpectedAdditionalItems = IndexTargets->size() + 1;
+
    QueueURI(Desc);
 }
                                                                        /*}}}*/
@@ -1309,6 +1344,9 @@ void pkgAcqMetaSig::Done(string Message,unsigned long long Size,string MD5,
 
    Complete = true;
 
+   // at this point pkgAcqMetaIndex takes over
+   ExpectedAdditionalItems = 0;
+
    // put the last known good file back on i-m-s hit (it will
    // be re-verified again)
    // Else do nothing, we have the new file in DestFile then
@@ -1326,6 +1364,9 @@ void pkgAcqMetaSig::Failed(string Message,pkgAcquire::MethodConfig *Cnf)/*{{{*/
 {
    string Final = _config->FindDir("Dir::State::lists") + URItoFileName(RealURI);
 
+   // at this point pkgAcqMetaIndex takes over
+   ExpectedAdditionalItems = 0;
+
    // if we get a network error we fail gracefully
    if(Status == StatTransientNetworkError)
    {
@@ -1376,6 +1417,9 @@ pkgAcqMetaIndex::pkgAcqMetaIndex(pkgAcquire *Owner,                       /*{{{*/
    Desc.ShortDesc = ShortDesc;
    Desc.URI = URI;
 
+   // we expect more item
+   ExpectedAdditionalItems = IndexTargets->size();
+
    QueueURI(Desc);
 }
                                                                        /*}}}*/
@@ -1426,9 +1470,20 @@ void pkgAcqMetaIndex::Done(string Message,unsigned long long Size,string Hash,   /
       }
       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";
@@ -1554,12 +1609,15 @@ void pkgAcqMetaIndex::QueueIndexes(bool verify)                         /*{{{*/
         }
    }
 
+   // at this point the real Items are loaded in the fetcher
+   ExpectedAdditionalItems = 0;
+
    for (vector <struct IndexTarget*>::const_iterator Target = IndexTargets->begin();
         Target != IndexTargets->end();
         ++Target)
    {
       HashString ExpectedIndexHash;
-      const indexRecords::checkSum *Record = MetaIndexParser->Lookup((*Target)->MetaKey);
+      indexRecords::checkSum *Record = MetaIndexParser->Lookup((*Target)->MetaKey);
       bool compressedAvailable = false;
       if (Record == NULL)
       {
@@ -1606,8 +1664,7 @@ void pkgAcqMetaIndex::QueueIndexes(bool verify)                           /*{{{*/
         {
            if (_config->FindB("Acquire::PDiffs",true) == true && transInRelease == true &&
                MetaIndexParser->Exists((*Target)->MetaKey + ".diff/Index") == true)
-              new pkgAcqDiffIndex(Owner, (*Target)->URI, (*Target)->Description,
-                                  (*Target)->ShortDesc, ExpectedIndexHash);
+              new pkgAcqDiffIndex(Owner, *Target, ExpectedIndexHash, MetaIndexParser);
            else
               new pkgAcqIndexTrans(Owner, *Target, ExpectedIndexHash, MetaIndexParser);
         }
@@ -1620,8 +1677,7 @@ void pkgAcqMetaIndex::QueueIndexes(bool verify)                           /*{{{*/
          instead, but passing the required info to it is to much hassle */
       if(_config->FindB("Acquire::PDiffs",true) == true && (verify == false ||
          MetaIndexParser->Exists((*Target)->MetaKey + ".diff/Index") == true))
-        new pkgAcqDiffIndex(Owner, (*Target)->URI, (*Target)->Description,
-                            (*Target)->ShortDesc, ExpectedIndexHash);
+        new pkgAcqDiffIndex(Owner, *Target, ExpectedIndexHash, MetaIndexParser);
       else
         new pkgAcqIndex(Owner, *Target, ExpectedIndexHash, MetaIndexParser);
    }
@@ -1784,6 +1840,10 @@ pkgAcqMetaClearSig::pkgAcqMetaClearSig(pkgAcquire *Owner,                /*{{{*/
 {
    SigFile = DestFile;
 
+   // index targets + (worst case:) Release/Release.gpg
+   ExpectedAdditionalItems = IndexTargets->size() + 2;
+
+
    // keep the old InRelease around in case of transistent network errors
    string const Final = _config->FindDir("Dir::State::lists") + URItoFileName(RealURI);
    if (RealFileExists(Final) == true)
@@ -1826,6 +1886,9 @@ string pkgAcqMetaClearSig::Custom600Headers()
                                                                        /*}}}*/
 void pkgAcqMetaClearSig::Failed(string Message,pkgAcquire::MethodConfig *Cnf) /*{{{*/
 {
+   // we failed, we will not get additional items from this method
+   ExpectedAdditionalItems = 0;
+
    if (AuthPass == false)
    {
       // Remove the 'old' InRelease file if we try Release.gpg now as otherwise