- backport forgotten Valid-Until patch from the obsolete experimental
authorDavid Kalnischkies <kalnischkies@gmail.com>
Wed, 9 Jun 2010 08:52:45 +0000 (10:52 +0200)
committerDavid Kalnischkies <kalnischkies@gmail.com>
Wed, 9 Jun 2010 08:52:45 +0000 (10:52 +0200)
    branch to prevent replay attacks better, thanks to Thomas Viehmann
    for the initial patch! (Closes: #499897)
* doc/apt.conf.5.xml:
  - document the new Valid-Until related options
* apt-pkg/contrib/strutl.cc:
  - split StrToTime() into HTTP1.1 and FTP date parser methods and
    use strptime() instead of some self-made scanf mangling
  - use the portable timegm shown in his manpage instead of a strange
    looking code copycat from wget
* ftparchive/writer.cc:
  - add ValidTime option to generate a Valid-Until header in Release file

1  2 
apt-pkg/acquire-item.cc
apt-pkg/indexrecords.cc
apt-pkg/indexrecords.h
debian/changelog
doc/examples/configure-index

diff --combined apt-pkg/acquire-item.cc
@@@ -33,6 -33,7 +33,7 @@@
  #include <string>
  #include <sstream>
  #include <stdio.h>
+ #include <ctime>
                                                                        /*}}}*/
  
  using namespace std;
@@@ -1105,16 -1106,13 +1106,16 @@@ void pkgAcqMetaIndex::QueueIndexes(boo
              return;
           }
        }
 -      
 -      // Queue Packages file (either diff or full packages files, depending
 -      // on the users option)
 -      if(_config->FindB("Acquire::PDiffs",true) == true) 
 +
 +      /* Queue Packages file (either diff or full packages files, depending
 +         on the users option) - we also check if the PDiff Index file is listed
 +         in the Meta-Index file. Ideal would be if pkgAcqDiffIndex would test this
 +         instead, but passing the required info to it is to much hassle */
 +      if(_config->FindB("Acquire::PDiffs",true) == true && (verify == false ||
 +        MetaIndexParser->Exists(string((*Target)->MetaKey).append(".diff/Index")) == true))
         new pkgAcqDiffIndex(Owner, (*Target)->URI, (*Target)->Description,
                             (*Target)->ShortDesc, ExpectedIndexHash);
 -      else 
 +      else
         new pkgAcqIndex(Owner, (*Target)->URI, (*Target)->Description,
                            (*Target)->ShortDesc, ExpectedIndexHash);
     }
@@@ -1180,6 -1178,17 +1181,17 @@@ bool pkgAcqMetaIndex::VerifyVendor(stri
        Transformed = "";
     }
  
+    if (_config->FindB("Acquire::Check-Valid-Until", true) == true &&
+        MetaIndexParser->GetValidUntil() > 0) {
+       time_t const invalid_since = time(NULL) - MetaIndexParser->GetValidUntil();
+       if (invalid_since > 0)
+        // 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());
+    }
     if (_config->FindB("Debug::pkgAcquire::Auth", false)) 
     {
        std::cerr << "Got Codename: " << MetaIndexParser->GetDist() << std::endl;
  //       return false;
        if (!Transformed.empty())
        {
-          _error->Warning("Conflicting distribution: %s (expected %s but got %s)",
+          _error->Warning(_("Conflicting distribution: %s (expected %s but got %s)"),
                           Desc.Description.c_str(),
                           Transformed.c_str(),
                           MetaIndexParser->GetDist().c_str());
diff --combined apt-pkg/indexrecords.cc
@@@ -7,8 -7,11 +7,11 @@@
  #include <apt-pkg/tagfile.h>
  #include <apt-pkg/error.h>
  #include <apt-pkg/strutl.h>
+ #include <apt-pkg/configuration.h>
  #include <apti18n.h>
  #include <sys/stat.h>
+ #include <clocale>
                                                                        /*}}}*/
  string indexRecords::GetDist() const
  {
@@@ -26,16 -29,16 +29,21 @@@ string indexRecords::GetExpectedDist() 
     return this->ExpectedDist;
  }
  
+ time_t indexRecords::GetValidUntil() const
+ {
+    return this->ValidUntil;
+ }
  const indexRecords::checkSum *indexRecords::Lookup(const string MetaKey)
  {
     return Entries[MetaKey];
  }
  
 +bool indexRecords::Exists(string const &MetaKey) const
 +{
 +   return Entries.count(MetaKey) == 1;
 +}
 +
  bool indexRecords::Load(const string Filename)                                /*{{{*/
  {
     FileFd Fd(Filename, FileFd::ReadOnly);
     {
        strprintf(ErrorText, _("No Hash entry in Release file %s"), Filename.c_str());
        return false;
-    }  
+    }
+    string Label = Section.FindS("Label");
+    string StrDate = Section.FindS("Date");
+    string StrValidUntil = Section.FindS("Valid-Until");
+    // if we have a Valid-Until header in the Release file, use it as default
+    if (StrValidUntil.empty() == false)
+    {
+       if(RFC1123StrToTime(StrValidUntil.c_str(), ValidUntil) == false)
+       {
+        strprintf(ErrorText, _("Invalid 'Valid-Until' entry in Release file %s"), Filename.c_str());
+        return false;
+       }
+    }
+    // get the user settings for this archive and use what expires earlier
+    int MaxAge = _config->FindI("Acquire::Max-ValidTime", 0);
+    if (Label.empty() == true)
+       MaxAge = _config->FindI(string("Acquire::Max-ValidTime::" + Label).c_str(), MaxAge);
+    if(MaxAge == 0) // No user settings, use the one from the Release file
+       return true;
+    time_t date;
+    if (RFC1123StrToTime(StrDate.c_str(), date) == false)
+    {
+       strprintf(ErrorText, _("Invalid 'Date' entry in Release file %s"), Filename.c_str());
+       return false;
+    }
+    date += 24*60*60*MaxAge;
+    if (ValidUntil == 0 || ValidUntil > date)
+       ValidUntil = date;
  
-    string Strdate = Section.FindS("Date"); // FIXME: verify this somehow?
     return true;
  }
                                                                        /*}}}*/
@@@ -165,6 -199,6 +204,6 @@@ indexRecords::indexRecords(
  }
  
  indexRecords::indexRecords(const string ExpectedDist) :
-    ExpectedDist(ExpectedDist)
+    ExpectedDist(ExpectedDist), ValidUntil(0)
  {
  }
diff --combined apt-pkg/indexrecords.h
@@@ -12,6 -12,7 +12,7 @@@
  
  #include <map>
  #include <vector>
+ #include <ctime>
  
  class indexRecords
  {
@@@ -25,6 -26,8 +26,8 @@@
     string Dist;
     string Suite;
     string ExpectedDist;
+    time_t ValidUntil;
     std::map<string,checkSum *> Entries;
  
     public:
  
     // Lookup function
     virtual const checkSum *Lookup(const string MetaKey);
 +   /** \brief tests if a checksum for this file is available */
 +   bool Exists(string const &MetaKey) const;
     std::vector<std::string> MetaKeys();
  
     virtual bool Load(string Filename);
     string GetDist() const;
+    time_t GetValidUntil() const;
     virtual bool CheckDist(const string MaybeDist) const;
     string GetExpectedDist() const;
     virtual ~indexRecords(){};
diff --combined debian/changelog
@@@ -1,55 -1,21 +1,67 @@@
  apt (0.7.26~exp6) UNRELEASED; urgency=low
  
    [ David Kalnischkies ]
 -  * doc/apt.conf.5.xml:
 -    - document the new Valid-Until related options
 -  * apt-pkg/indexrecords.cc:
 +  * apt-pkg/deb/dpkgpm.cc:
 +    - write Disappeared also to the history.log
 +    - forward manual-installed bit on package disappearance
 +  * apt-pkg/deb/debsystem.cc:
 +    - add better config item for extended_states file
 +  * apt-pkg/pkgcache.h:
 +    - switch {,Install-}Size to unsigned long long
 +  * apt-pkg/depcache.cc:
 +    - do the autoremove mark process also for required packages to handle
 +      these illegally depending on lower priority packages (Closes: #583517)
 +    - try harder to find the other pseudo versions for autoremove multiarch
 +    - correct "Dangerous iterator usage" pointed out by cppcheck
 +    - deal with long long, not with int to remove 2GB Limit (LP: #250909)
 +    - deprecate AddSize with Multiplier as it is unused and switch to
 +      boolean instead to handle the sizes more gracefully.
 +    - switch i{Download,Usr}Size from double to (un)signed long long
 +  * apt-pkg/aptconfiguration.cc:
 +    - remove duplicate architectures in getArchitectures()
 +  * apt-pkg/indexrecords.{cc,h}:
+     - backport forgotten Valid-Until patch from the obsolete experimental
+       branch to prevent replay attacks better, thanks to Thomas Viehmann
+       for the initial patch! (Closes: #499897)
 +    - add a constant Exists check for MetaKeys
 +  * apt-pkg/acquire-item.cc:
 +    - do not try PDiff if it is not listed in the Meta file
 +  * apt-pkg/cacheiterator.h:
 +    - let pkgCache::Iterator inherent std::iterator
 +  * ftparchive/writer.h:
 +    - add a virtual destructor to FTWScanner class (for cppcheck)
 +  * apt-pkg/cacheset.{cc,h}:
 +    - add simple wrapper around std::set for cache structures
 +    - move regex magic from apt-get to new FromRegEx method
 +    - move cmdline parsing from apt-cache to new FromCommandLine method
 +    - support special release-modifier 'installed' and 'candidate'
 +  * apt-pkg/contrib/cmdline.cc:
 +    - fix segfault in SaveInConfig caused by writing over char[] sizes
 +  * apt-pkg/pkgcache.cc:
 +    - get the best matching arch package from a group with FindPreferredPkg
 +  * cmdline/apt-cache.cc:
 +    - make the search multiarch compatible by using GrpIterator instead
 +    - use pkgCacheFile and the new CacheSets all over the place
 +    - add --target-release option (Closes: #115520)
 +    - accept pkg/release and pkg=version in show and co. (Closes: #236270)
 +    - accept package versions in the unmet command
 +  * cmdline/apt-get.cc:
 +    - use unsigned long long instead of double to store values it gets
 +  * apt-pkg/cachefile.{cc,h}:
 +    - split Open() into submethods to be able to build only parts
 +    - make the OpProgress optional in the Cache buildprocess
 +    - store also the SourceList we use internally for export
++  * doc/apt.conf.5.xml:
++    - document the new Valid-Until related options
+   * apt-pkg/contrib/strutl.cc:
+     - split StrToTime() into HTTP1.1 and FTP date parser methods and
+       use strptime() instead of some self-made scanf mangling
+     - use the portable timegm shown in his manpage instead of a strange
+       looking code copycat from wget
+   * ftparchive/writer.cc:
+     - add ValidTime option to generate a Valid-Until header in Release file
  
-  -- David Kalnischkies <kalnischkies@gmail.com>  Wed, 09 Jun 2010 10:50:12 +0200
 - -- David Kalnischkies <kalnischkies@gmail.com>  Wed, 09 Jun 2010 10:43:58 +0200
++ -- David Kalnischkies <kalnischkies@gmail.com>  Wed, 09 Jun 2010 10:52:31 +0200
  
  apt (0.7.26~exp5) experimental; urgency=low
  
@@@ -176,6 -176,10 +176,10 @@@ Acquir
    PDiffs::SizeLimit "50"; // don't use diffs if size of all patches excess
                          // 50% of the size of the original file
  
+   Check-Valid-Until "true";
+   Max-ValidTime "864000"; // 10 days
+   Max-ValidTime::Debian-Security "604800"; // 7 days, label specific configuration
    // HTTP method configuration
    http 
    {
@@@ -294,8 -298,9 +298,8 @@@ Dir "/
    State "var/lib/apt/" 
    {
       Lists "lists/";
 -     xstatus "xstatus";
 -     userstatus "status.user";
       status "/var/lib/dpkg/status";
 +     extended_states "extended_states";
       cdroms "cdroms.list";
    };