* apt-pkg/indexrecords.cc:
authorDavid Kalnischkies <kalnischkies@gmail.com>
Tue, 8 Jun 2010 17:27:49 +0000 (19:27 +0200)
committerDavid Kalnischkies <kalnischkies@gmail.com>
Tue, 8 Jun 2010 17:27:49 +0000 (19:27 +0200)
  - 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)

apt-pkg/acquire-item.cc
apt-pkg/indexrecords.cc
apt-pkg/indexrecords.h
debian/changelog
test/pre-upload-check.py
test/testsources.list/sources.list.all-validuntil-broken [new file with mode: 0644]

index c035b91..4a84680 100644 (file)
@@ -33,6 +33,7 @@
 #include <string>
 #include <sstream>
 #include <stdio.h>
+#include <ctime>
                                                                        /*}}}*/
 
 using namespace std;
@@ -1177,6 +1178,15 @@ bool pkgAcqMetaIndex::VerifyVendor(string Message)                       /*{{{*/
       Transformed = "";
    }
 
+   if (_config->FindB("Acquire::Check-Valid-Until", true)) {
+      if (MetaIndexParser->GetValidUntil() > 0 &&
+          time(NULL) > MetaIndexParser->GetValidUntil()) {
+        return _error->Error(_("Release file expired, ignoring %s (valid until %s)"),
+                             RealURI.c_str(), 
+                             TimeRFC1123(MetaIndexParser->GetValidUntil()).c_str());
+      }
+   }
+
    if (_config->FindB("Debug::pkgAcquire::Auth", false)) 
    {
       std::cerr << "Got Codename: " << MetaIndexParser->GetDist() << std::endl;
@@ -1194,7 +1204,7 @@ bool pkgAcqMetaIndex::VerifyVendor(string Message)                        /*{{{*/
 //       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());
index 1fc27b1..24ed02b 100644 (file)
@@ -7,8 +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,6 +29,11 @@ string indexRecords::GetExpectedDist() const
    return this->ExpectedDist;
 }
 
+time_t indexRecords::GetValidUntil() const
+{
+   return this->ValidUntil;
+}
+
 const indexRecords::checkSum *indexRecords::Lookup(const string MetaKey)
 {
    return Entries[MetaKey];
@@ -82,7 +90,33 @@ bool indexRecords::Load(const string Filename)                               /*{{{*/
       return false;
    }  
 
-   string Strdate = Section.FindS("Date"); // FIXME: verify this somehow?
+   string Label = Section.FindS("Label");
+   string StrDate = Section.FindS("Date"); 
+   string StrValidUntil = Section.FindS("Valid-Until");
+
+   // if we have a Valid-Until header, use it
+   if (!StrValidUntil.empty())
+   {
+      // set ValidUntil based on the information in the Release file
+      if(!StrToTime(StrValidUntil, ValidUntil))
+      {
+        ErrorText = _(("Invalid 'Valid-Until' entry in Release file " + Filename).c_str());
+        return false;
+      }
+   } else {
+      // if we don't have a valid-until string, check if we have a default
+      if (!Label.empty())
+      {
+        int MaxAge = _config->FindI(string("apt::acquire::max-default-age::"+Label).c_str(),0);
+        if(MaxAge > 0 && !StrToTime(StrDate, ValidUntil))
+        {
+           ErrorText = _(("Invalid 'Date' entry in Release file " + Filename).c_str());
+           return false;
+        }
+        ValidUntil += 24*60*60*MaxAge;      
+      }
+   }
+
    return true;
 }
                                                                        /*}}}*/
@@ -160,6 +194,6 @@ indexRecords::indexRecords()
 }
 
 indexRecords::indexRecords(const string ExpectedDist) :
-   ExpectedDist(ExpectedDist)
+   ExpectedDist(ExpectedDist), ValidUntil(0)
 {
 }
index 468d2bd..500cf23 100644 (file)
@@ -12,6 +12,7 @@
 
 #include <map>
 #include <vector>
+#include <ctime>
 
 class indexRecords
 {
@@ -25,6 +26,8 @@ class indexRecords
    string Dist;
    string Suite;
    string ExpectedDist;
+   time_t ValidUntil;
+
    std::map<string,checkSum *> Entries;
 
    public:
@@ -38,6 +41,7 @@ class indexRecords
 
    virtual bool Load(string Filename);
    string GetDist() const;
+   time_t GetValidUntil() const;
    virtual bool CheckDist(const string MaybeDist) const;
    string GetExpectedDist() const;
    virtual ~indexRecords(){};
index 3771ca4..d8fb577 100644 (file)
@@ -1,6 +1,10 @@
 apt (0.7.26~exp5) experimental; urgency=low
 
   [ David Kalnischkies ]
+  * apt-pkg/indexrecords.cc:
+    - 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)
   * cmdline/apt-get.cc:
     - rerun dpkg-source in source if --fix-broken is given (Closes: #576752)
     - don't suggest held packages as they are installed (Closes: #578135)
index 268b3d6..e2dfecb 100755 (executable)
@@ -95,6 +95,20 @@ class testAuthentication(unittest.TestCase):
                 self.assert_(len(glob.glob("/var/lib/apt/lists/partial/*")) == 0,
                              "partial/ dir has leftover files: %s" % glob.glob("/var/lib/apt/lists/partial/*"))
 
+    def testValid(self):
+        for f in glob.glob("testsources.list/sources.list*validuntil*"):
+            self._cleanup()
+            (prefix, testtype, result) = f.split("-")
+            expected_res = self._expectedRes(result)
+            cmd = ["update"]
+            res = call([self.apt,"-o","Dir::Etc::sourcelist=./%s" % f]+cmd+apt_args,
+                       stdout=stdout, stderr=stderr)
+            self.assert_(res == expected_res,
+                         "test '%s' failed (got %s expected %s" % (f,res,expected_res))
+            if expected_res == 0:
+                self.assert_(len(glob.glob("/var/lib/apt/lists/partial/*")) == 0,
+                             "partial/ dir has leftover files: %s" % glob.glob("/var/lib/apt/lists/partial/*"))
+
 
 class testLocalRepositories(unittest.TestCase):
     " test local repository regressions "
diff --git a/test/testsources.list/sources.list.all-validuntil-broken b/test/testsources.list/sources.list.all-validuntil-broken
new file mode 100644 (file)
index 0000000..bab59bb
--- /dev/null
@@ -0,0 +1 @@
+deb http://people.ubuntu.com/~mvo/apt/auth-test-suit/all-validuntil-broken/ /