implement AptAuthenticationReliabtlity spec
authorMichael Vogt <michael.vogt@ubuntu.com>
Fri, 21 Dec 2007 12:56:19 +0000 (13:56 +0100)
committerMichael Vogt <michael.vogt@ubuntu.com>
Fri, 21 Dec 2007 12:56:19 +0000 (13:56 +0100)
12 files changed:
apt-pkg/acquire-item.cc
apt-pkg/acquire-item.h
apt-pkg/algorithms.cc
po/apt-all.pot
test/authReliability/lists/people.ubuntu.com_%7emvo_apt_auth-test-suit_gpg-package-broken_Packages [new file with mode: 0644]
test/authReliability/lists/people.ubuntu.com_%7emvo_apt_auth-test-suit_gpg-package-broken_Release [new file with mode: 0644]
test/authReliability/lists/people.ubuntu.com_%7emvo_apt_auth-test-suit_gpg-package-broken_Release.gpg [new file with mode: 0644]
test/authReliability/lists/people.ubuntu.com_%7emvo_apt_auth-test-suit_gpg-package-ok_Packages [new file with mode: 0644]
test/authReliability/lists/people.ubuntu.com_%7emvo_apt_auth-test-suit_gpg-package-ok_Release [new file with mode: 0644]
test/authReliability/lists/people.ubuntu.com_%7emvo_apt_auth-test-suit_gpg-package-ok_Release.gpg [new file with mode: 0644]
test/authReliability/sources.list.failure [new file with mode: 0644]
test/pre-upload-check.py

index 7cae6c8..54526ab 100644 (file)
@@ -831,8 +831,9 @@ void pkgAcqMetaSig::Done(string Message,unsigned long Size,string MD5,
       Rename(LastGoodSig, DestFile);
 
    // queue a pkgAcqMetaIndex to be verified against the sig we just retrieved
-   new pkgAcqMetaIndex(Owner, MetaIndexURI, MetaIndexURIDesc, MetaIndexShortDesc,
-                      DestFile, IndexTargets, MetaIndexParser);
+   new pkgAcqMetaIndex(Owner, MetaIndexURI, MetaIndexURIDesc, 
+                      MetaIndexShortDesc,  DestFile, IndexTargets, 
+                      MetaIndexParser);
 
 }
                                                                        /*}}}*/
@@ -921,13 +922,19 @@ void pkgAcqMetaIndex::Done(string Message,unsigned long Size,string Hash,
    if (AuthPass == true)
    {
       AuthDone(Message);
+
+      // all cool, move Release file into place
+      Complete = true;
+
+      string FinalFile = _config->FindDir("Dir::State::lists");
+      FinalFile += URItoFileName(RealURI);
+      Rename(DestFile,FinalFile);
+      chmod(FinalFile.c_str(),0644);
+      DestFile = FinalFile;
    }
    else
    {
       RetrievalDone(Message);
-      if (!Complete)
-         // Still more retrieving to do
-         return;
 
       if (SigFile == "")
       {
@@ -972,22 +979,14 @@ void pkgAcqMetaIndex::RetrievalDone(string Message)
       return;
    }
 
-   // see if the download was a IMSHit
+   // make sure to verify against the right file on I-M-S hit
    IMSHit = StringToBool(LookupTag(Message,"IMS-Hit"),false);
-   Complete = true;
-
-   string FinalFile = _config->FindDir("Dir::State::lists");
-   FinalFile += URItoFileName(RealURI);
-
-   // If we get a IMS hit we can remove the empty file in partial
-   // othersie we move the file in place
-   if (IMSHit)
-      unlink(DestFile.c_str());
-   else
-      Rename(DestFile,FinalFile);
-
-   chmod(FinalFile.c_str(),0644);
-   DestFile = FinalFile;
+   if(IMSHit)
+   {
+      string FinalFile = _config->FindDir("Dir::State::lists");
+      FinalFile += URItoFileName(RealURI);
+      DestFile = FinalFile;
+   }
 }
 
 void pkgAcqMetaIndex::AuthDone(string Message)
@@ -1017,7 +1016,6 @@ void pkgAcqMetaIndex::AuthDone(string Message)
    QueueIndexes(true);
 
    // Done, move signature file into position
-
    string VerifiedSigFile = _config->FindDir("Dir::State::lists") +
       URItoFileName(RealURI) + ".gpg";
    Rename(SigFile,VerifiedSigFile);
@@ -1162,30 +1160,27 @@ void pkgAcqMetaIndex::Failed(string Message,pkgAcquire::MethodConfig *Cnf)
 {
    if (AuthPass == true)
    {
-      // if we fail the authentication but got the file via a IMS-Hit 
-      // this means that the file wasn't downloaded and that it might be
-      // just stale (server problem, proxy etc). we delete what we have
-      // queue it again without i-m-s 
-      // alternatively we could just unlink the file and let the user try again
-      if (IMSHit)
+      // gpgv method failed, if we have a good signature 
+      string LastGoodSigFile = _config->FindDir("Dir::State::lists") +
+        "partial/" + URItoFileName(RealURI) + ".gpg.reverify";
+      if(FileExists(LastGoodSigFile))
       {
-        Complete = false;
-        Local = false;
-        AuthPass = false;
-        unlink(DestFile.c_str());
-
-        DestFile = _config->FindDir("Dir::State::lists") + "partial/";
-        DestFile += URItoFileName(RealURI);
-        Desc.URI = RealURI;
-        QueueURI(Desc);
+        string VerifiedSigFile = _config->FindDir("Dir::State::lists") +
+           URItoFileName(RealURI) + ".gpg";
+        Rename(LastGoodSigFile,VerifiedSigFile);
+        Status = StatTransientNetworkError;
+        _error->Warning(_("A error occurred during the signature "
+                          "verification. The repository is not updated "
+                          "and the previous index files will be used."
+                          "GPG error: %s: %s\n"
+                        Desc.Description.c_str(),
+                        LookupTag(Message,"Message").c_str());
         return;
+      } else {
+        _error->Warning(_("GPG error: %s: %s"),
+                        Desc.Description.c_str(),
+                        LookupTag(Message,"Message").c_str());
       }
-
-      // gpgv method failed 
-      _error->Warning("GPG error: %s: %s",
-                      Desc.Description.c_str(),
-                      LookupTag(Message,"Message").c_str());
-
    }
 
    // No Release file was present, or verification failed, so fall
index a48f7f7..7ecbf57 100644 (file)
@@ -612,7 +612,6 @@ class pkgAcqMetaSig : public pkgAcquire::Item
    /** \brief The last good signature file */
    string LastGoodSig;
 
-
    /** \brief The fetch request that is currently being processed. */
    pkgAcquire::ItemDesc Desc;
 
index 158f9c2..c5e3c7b 100644 (file)
@@ -1107,8 +1107,7 @@ bool pkgProblemResolver::Resolve(bool BrokenFix)
       return _error->Error(_("Unable to correct problems, you have held broken packages."));
    }
    
-   // set the auto-flags (mvo: I'm not sure if we _really_ need this, but
-   // I didn't managed 
+   // set the auto-flags (mvo: I'm not sure if we _really_ need this)
    pkgCache::PkgIterator I = Cache.PkgBegin();
    for (;I.end() != true; I++) {
       if (Cache[I].NewInstall() && !(Flags[I->ID] & PreInstalled)) {
index a89f349..be99f59 100644 (file)
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2007-12-17 10:36+0530\n"
+"POT-Creation-Date: 2007-12-21 13:30+0100\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -2441,35 +2441,47 @@ msgstr ""
 msgid "MD5Sum mismatch"
 msgstr ""
 
-#: apt-pkg/acquire-item.cc:647 apt-pkg/acquire-item.cc:1408
+#: apt-pkg/acquire-item.cc:647 apt-pkg/acquire-item.cc:1401
 msgid "Hash Sum mismatch"
 msgstr ""
 
-#: apt-pkg/acquire-item.cc:1100
+#: apt-pkg/acquire-item.cc:1098
 msgid "There is no public key available for the following key IDs:\n"
 msgstr ""
 
-#: apt-pkg/acquire-item.cc:1213
+#: apt-pkg/acquire-item.cc:1172
+#, c-format
+msgid ""
+"GPG error: %s: %s\n"
+"The last good index will be used."
+msgstr ""
+
+#: apt-pkg/acquire-item.cc:1178
+#, c-format
+msgid "GPG error: %s: %s"
+msgstr ""
+
+#: apt-pkg/acquire-item.cc:1206
 #, c-format
 msgid ""
 "I wasn't able to locate a file for the %s package. This might mean you need "
 "to manually fix this package. (due to missing arch)"
 msgstr ""
 
-#: apt-pkg/acquire-item.cc:1272
+#: apt-pkg/acquire-item.cc:1265
 #, c-format
 msgid ""
 "I wasn't able to locate file for the %s package. This might mean you need to "
 "manually fix this package."
 msgstr ""
 
-#: apt-pkg/acquire-item.cc:1313
+#: apt-pkg/acquire-item.cc:1306
 #, c-format
 msgid ""
 "The package index files are corrupted. No Filename: field for package %s."
 msgstr ""
 
-#: apt-pkg/acquire-item.cc:1400
+#: apt-pkg/acquire-item.cc:1393
 msgid "Size mismatch"
 msgstr ""
 
diff --git a/test/authReliability/lists/people.ubuntu.com_%7emvo_apt_auth-test-suit_gpg-package-broken_Packages b/test/authReliability/lists/people.ubuntu.com_%7emvo_apt_auth-test-suit_gpg-package-broken_Packages
new file mode 100644 (file)
index 0000000..3e72654
--- /dev/null
@@ -0,0 +1,25 @@
+Package: libglib2.0-data
+Priority: optional
+Section: misc
+Installed-Size: 2288
+Maintainer: Ubuntu Desktop Team <ubuntu-desktop@lists.ubuntu.com>
+Original-Maintainer: Loic Minier <lool@dooz.org>
+Architecture: all
+Source: glib2.0
+Version: 2.13.6-1ubuntu1
+Replaces: libglib1.3, libglib1.3-data
+Depends: libglib2.0-0 (>= 2.13.6-1ubuntu1)
+Conflicts: libglib1.3-data
+Filename: ./libglib2.0-data_2.13.6-1ubuntu1_all.deb
+Size: 958
+MD5sum: 803fc5e2e31a4345b3e9c771e1eae49f
+SHA1: 75b2c62b21bae60c58e694dd40ed6d4df946e304
+SHA256: 142d8466eac252f06bc957d76fe1bb87f86f2d3512b99c8d4b08c1ad79fbe59e
+Description: Common files for GLib library
+ GLib is a library containing many useful C routines for things such
+ as trees, hashes, lists, and strings.  It is a useful general-purpose
+ C library used by projects such as GTK+, GIMP, and GNOME.
+ .
+ This package is needed for the runtime libraries to display messages in
+ languages other than English.
+
diff --git a/test/authReliability/lists/people.ubuntu.com_%7emvo_apt_auth-test-suit_gpg-package-broken_Release b/test/authReliability/lists/people.ubuntu.com_%7emvo_apt_auth-test-suit_gpg-package-broken_Release
new file mode 100644 (file)
index 0000000..7ecd4cd
--- /dev/null
@@ -0,0 +1,13 @@
+Date: Fri, 27 Jul 2007 14:39:41 UTC
+MD5Sum:
+ 4672dadea6a144839f823c9f3d5fd44b              934 Packages
+ 82ebcf09a8d78a2b9cf7759349da4936              603 Packages.gz
+ d41d8cd98f00b204e9800998ecf8427e                0 Release
+SHA1:
+ fa0f294aa30789529371066b10e9497be1284d26              934 Packages
+ f4032808663b2810d87b4a4dab6f5ae4a1e8fa8e              603 Packages.gz
+ da39a3ee5e6b4b0d3255bfef95601890afd80709                0 Release
+SHA256:
+ 92c9b605480dc74e6be79c0ddc24738bfcbd6dd3148af531acd68717de528049              934 Packages
+ 659ccc0d07ff21f0247f9fa5abe149221c90d5e17da52c7afddb035b93c23d39              603 Packages.gz
+ e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855                0 Release
diff --git a/test/authReliability/lists/people.ubuntu.com_%7emvo_apt_auth-test-suit_gpg-package-broken_Release.gpg b/test/authReliability/lists/people.ubuntu.com_%7emvo_apt_auth-test-suit_gpg-package-broken_Release.gpg
new file mode 100644 (file)
index 0000000..85c356e
--- /dev/null
@@ -0,0 +1,7 @@
+-----BEGIN PGP SIGNATURE-----
+Version: GnuPG v1.4.6 (GNU/Linux)
+
+iD8DBQBGqgOwliSD4VZixzQRAs6jAJ9p7Aiob9gzkUNCtoW8UPrBo0E/YwCdEaz0
+CQJszU6fRYX5jGWXSWzfc5c=
+=ugH0
+-----END PGP SIGNATURE-----
diff --git a/test/authReliability/lists/people.ubuntu.com_%7emvo_apt_auth-test-suit_gpg-package-ok_Packages b/test/authReliability/lists/people.ubuntu.com_%7emvo_apt_auth-test-suit_gpg-package-ok_Packages
new file mode 100644 (file)
index 0000000..3e72654
--- /dev/null
@@ -0,0 +1,25 @@
+Package: libglib2.0-data
+Priority: optional
+Section: misc
+Installed-Size: 2288
+Maintainer: Ubuntu Desktop Team <ubuntu-desktop@lists.ubuntu.com>
+Original-Maintainer: Loic Minier <lool@dooz.org>
+Architecture: all
+Source: glib2.0
+Version: 2.13.6-1ubuntu1
+Replaces: libglib1.3, libglib1.3-data
+Depends: libglib2.0-0 (>= 2.13.6-1ubuntu1)
+Conflicts: libglib1.3-data
+Filename: ./libglib2.0-data_2.13.6-1ubuntu1_all.deb
+Size: 958
+MD5sum: 803fc5e2e31a4345b3e9c771e1eae49f
+SHA1: 75b2c62b21bae60c58e694dd40ed6d4df946e304
+SHA256: 142d8466eac252f06bc957d76fe1bb87f86f2d3512b99c8d4b08c1ad79fbe59e
+Description: Common files for GLib library
+ GLib is a library containing many useful C routines for things such
+ as trees, hashes, lists, and strings.  It is a useful general-purpose
+ C library used by projects such as GTK+, GIMP, and GNOME.
+ .
+ This package is needed for the runtime libraries to display messages in
+ languages other than English.
+
diff --git a/test/authReliability/lists/people.ubuntu.com_%7emvo_apt_auth-test-suit_gpg-package-ok_Release b/test/authReliability/lists/people.ubuntu.com_%7emvo_apt_auth-test-suit_gpg-package-ok_Release
new file mode 100644 (file)
index 0000000..7ecd4cd
--- /dev/null
@@ -0,0 +1,13 @@
+Date: Fri, 27 Jul 2007 14:39:41 UTC
+MD5Sum:
+ 4672dadea6a144839f823c9f3d5fd44b              934 Packages
+ 82ebcf09a8d78a2b9cf7759349da4936              603 Packages.gz
+ d41d8cd98f00b204e9800998ecf8427e                0 Release
+SHA1:
+ fa0f294aa30789529371066b10e9497be1284d26              934 Packages
+ f4032808663b2810d87b4a4dab6f5ae4a1e8fa8e              603 Packages.gz
+ da39a3ee5e6b4b0d3255bfef95601890afd80709                0 Release
+SHA256:
+ 92c9b605480dc74e6be79c0ddc24738bfcbd6dd3148af531acd68717de528049              934 Packages
+ 659ccc0d07ff21f0247f9fa5abe149221c90d5e17da52c7afddb035b93c23d39              603 Packages.gz
+ e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855                0 Release
diff --git a/test/authReliability/lists/people.ubuntu.com_%7emvo_apt_auth-test-suit_gpg-package-ok_Release.gpg b/test/authReliability/lists/people.ubuntu.com_%7emvo_apt_auth-test-suit_gpg-package-ok_Release.gpg
new file mode 100644 (file)
index 0000000..85c356e
--- /dev/null
@@ -0,0 +1,7 @@
+-----BEGIN PGP SIGNATURE-----
+Version: GnuPG v1.4.6 (GNU/Linux)
+
+iD8DBQBGqgOwliSD4VZixzQRAs6jAJ9p7Aiob9gzkUNCtoW8UPrBo0E/YwCdEaz0
+CQJszU6fRYX5jGWXSWzfc5c=
+=ugH0
+-----END PGP SIGNATURE-----
diff --git a/test/authReliability/sources.list.failure b/test/authReliability/sources.list.failure
new file mode 100644 (file)
index 0000000..110f318
--- /dev/null
@@ -0,0 +1,2 @@
+deb http://people.ubuntu.com/~mvo/apt/auth-test-suit/gpg-package-broken/ /
+
index 268b3d6..75a7268 100755 (executable)
@@ -4,6 +4,8 @@ import sys
 import os
 import glob
 import os.path
+import shutil
+import time
 from subprocess import call, PIPE
 
 import unittest
@@ -11,7 +13,92 @@ import unittest
 stdout = os.open("/dev/null",0) #sys.stdout
 stderr = os.open("/dev/null",0) # sys.stderr
 
-apt_args = []  # ["-o","Debug::pkgAcquire::Auth=true"]
+apt_args = [] 
+#apt_args = ["-o","Debug::pkgAcquire::Auth=true"]
+
+class testAptAuthenticationReliability(unittest.TestCase):
+    """
+    test if the spec https://wiki.ubuntu.com/AptAuthenticationReliability 
+    is properly implemented
+    """
+    apt = "../bin/apt-get"
+
+    def setUp(self):
+        pass
+    def testRepositorySigFailure(self):
+        """
+        test if a repository that used to be authenticated and fails on
+        apt-get update refuses to update and uses the old state
+        """
+        # copy valid signatures into lists (those are ok, even
+        # if the name is "-broken-" ...
+        for f in glob.glob("./authReliability/lists/*"):
+            shutil.copy(f,"/var/lib/apt/lists")
+            # ensure we do *not* get a I-M-S hit
+            os.utime("/var/lib/apt/lists/%s" % os.path.basename(f), (0,0))
+        res = call([self.apt,
+                    "update",
+                    "-o","Dir::Etc::sourcelist=./authReliability/sources.list.failure"
+                   ] + apt_args,
+                   stdout=stdout, stderr=stderr)
+        self.assert_(os.path.exists("/var/lib/apt/lists/people.ubuntu.com_%7emvo_apt_auth-test-suit_gpg-package-broken_Release.gpg"),
+                     "The gpg file disappeared, this should not happen")
+        self.assert_(os.path.exists("/var/lib/apt/lists/people.ubuntu.com_%7emvo_apt_auth-test-suit_gpg-package-broken_Packages"),
+                     "The Packages file disappeared, this should not happen")
+        # the same with i-m-s hit this time
+        for f in glob.glob("./authReliability/lists/*"):
+            shutil.copy(f,"/var/lib/apt/lists")
+            os.utime("/var/lib/apt/lists/%s" % os.path.basename(f), (time.time(),time.time()))
+        res = call([self.apt,
+                    "update",
+                    "-o","Dir::Etc::sourcelist=./authReliability/sources.list.failure"
+                   ] + apt_args,
+                   stdout=stdout, stderr=stderr)
+        self.assert_(os.path.exists("/var/lib/apt/lists/people.ubuntu.com_%7emvo_apt_auth-test-suit_gpg-package-broken_Release.gpg"),
+                     "The gpg file disappeared, this should not happen")
+        self.assert_(os.path.exists("/var/lib/apt/lists/people.ubuntu.com_%7emvo_apt_auth-test-suit_gpg-package-broken_Packages"),
+                     "The Packages file disappeared, this should not happen")
+    def testRepositorySigGood(self):
+        """
+        test that a regular repository with good data stays good
+        """
+        res = call([self.apt,
+                    "update",
+                    "-o","Dir::Etc::sourcelist=./authReliability/sources.list.good"
+                   ] + apt_args,
+                   stdout=stdout, stderr=stderr)
+        self.assert_(os.path.exists("/var/lib/apt/lists/people.ubuntu.com_%7emvo_apt_auth-test-suit_gpg-package-ok_Release.gpg"),
+                     "The gpg file disappeared, this should not happen")
+        self.assert_(os.path.exists("/var/lib/apt/lists/people.ubuntu.com_%7emvo_apt_auth-test-suit_gpg-package-ok_Packages"),
+                     "The Packages file disappeared, this should not happen")
+        # test good is still good after non I-M-S hit and a previous files in lists/
+        for f in glob.glob("./authReliability/lists/*"):
+            shutil.copy(f,"/var/lib/apt/lists")
+            # ensure we do *not* get a I-M-S hit
+            os.utime("/var/lib/apt/lists/%s" % os.path.basename(f), (0,0))
+        res = call([self.apt,
+                    "update",
+                    "-o","Dir::Etc::sourcelist=./authReliability/sources.list.good"
+                   ] + apt_args,
+                   stdout=stdout, stderr=stderr)
+        self.assert_(os.path.exists("/var/lib/apt/lists/people.ubuntu.com_%7emvo_apt_auth-test-suit_gpg-package-ok_Release.gpg"),
+                     "The gpg file disappeared, this should not happen")
+        self.assert_(os.path.exists("/var/lib/apt/lists/people.ubuntu.com_%7emvo_apt_auth-test-suit_gpg-package-ok_Packages"),
+                     "The Packages file disappeared, this should not happen")
+        # test good is still good after I-M-S hit
+        for f in glob.glob("./authReliability/lists/*"):
+            shutil.copy(f,"/var/lib/apt/lists")
+            # ensure we do get a I-M-S hit
+            os.utime("/var/lib/apt/lists/%s" % os.path.basename(f), (time.time(),time.time()))
+        res = call([self.apt,
+                    "update",
+                    "-o","Dir::Etc::sourcelist=./authReliability/sources.list.good"
+                   ] + apt_args,
+                   stdout=stdout, stderr=stderr)
+        self.assert_(os.path.exists("/var/lib/apt/lists/people.ubuntu.com_%7emvo_apt_auth-test-suit_gpg-package-ok_Release.gpg"),
+                     "The gpg file disappeared, this should not happen")
+        self.assert_(os.path.exists("/var/lib/apt/lists/people.ubuntu.com_%7emvo_apt_auth-test-suit_gpg-package-ok_Packages"),
+                     "The Packages file disappeared, this should not happen")
 
 
 class testAuthentication(unittest.TestCase):
@@ -149,6 +236,7 @@ if __name__ == "__main__":
     if len(sys.argv) > 1 and sys.argv[1] == "-v":
         stdout = sys.stdout
         stderr = sys.stderr
+    
+    # run only one for now
+    #unittest.main(defaultTest="testAptAuthenticationReliability")
     unittest.main()
-
-