diff options
author | David Kalnischkies <kalnischkies@gmail.com> | 2011-06-06 21:29:16 +0200 |
---|---|---|
committer | David Kalnischkies <kalnischkies@gmail.com> | 2011-06-06 21:29:16 +0200 |
commit | 2e3c9d6452e69dcb5c83732fbda27b747bc997f4 (patch) | |
tree | bc5e845c507f605f956964e45519ed4e73d7d341 | |
parent | 89a1aa5dd55a3469c92720c7fcb90779f90b61f0 (diff) |
* apt-pkg/indexcopy.cc:
- Verify that the first line of an InRelease file is a PGP header
for a signed message. Otherwise a man-in-the-middle can prefix
a valid InRelease file with his own data! (CVE-2011-1829)
-rw-r--r-- | apt-pkg/indexcopy.cc | 21 | ||||
-rw-r--r-- | debian/changelog | 6 | ||||
-rw-r--r-- | methods/gpgv.cc | 13 | ||||
-rwxr-xr-x | test/integration/test-ubuntu-bug-784473-InRelease-one-message-only | 31 |
4 files changed, 64 insertions, 7 deletions
diff --git a/apt-pkg/indexcopy.cc b/apt-pkg/indexcopy.cc index 064fb007c..31c577705 100644 --- a/apt-pkg/indexcopy.cc +++ b/apt-pkg/indexcopy.cc @@ -664,6 +664,21 @@ bool SigVerify::CopyAndVerify(string CDROM,string Name,vector<string> &SigList, bool SigVerify::RunGPGV(std::string const &File, std::string const &FileGPG, int const &statusfd, int fd[2]) { + if (File == FileGPG) + { + #define SIGMSG "-----BEGIN PGP SIGNED MESSAGE-----\n" + char buffer[sizeof(SIGMSG)]; + FILE* gpg = fopen(File.c_str(), "r"); + if (gpg == NULL) + return _error->Errno("RunGPGV", _("Could not open file %s"), File.c_str()); + char const * const test = fgets(buffer, sizeof(buffer), gpg); + fclose(gpg); + if (test == NULL || strcmp(buffer, SIGMSG) != 0) + return _error->Error(_("File %s doesn't start with a clearsigned message"), File.c_str()); + #undef SIGMSG + } + + string const gpgvpath = _config->Find("Dir::Bin::gpg", "/usr/bin/gpgv"); // FIXME: remove support for deprecated APT::GPGV setting string const trustedFile = _config->Find("APT::GPGV::TrustedKeyring", _config->FindFile("Dir::Etc::Trusted")); @@ -688,7 +703,11 @@ bool SigVerify::RunGPGV(std::string const &File, std::string const &FileGPG, Args.reserve(30); if (keyrings.empty() == true) - return false; + { + // TRANSLATOR: %s is the trusted keyring parts directory + return _error->Error(_("No keyring installed in %s."), + _config->FindDir("Dir::Etc::TrustedParts").c_str()); + } Args.push_back(gpgvpath.c_str()); Args.push_back("--ignore-time-conflict"); diff --git a/debian/changelog b/debian/changelog index 971cf53b7..c2cf8257e 100644 --- a/debian/changelog +++ b/debian/changelog @@ -16,6 +16,10 @@ apt (0.8.14.2) UNRELEASED; urgency=low * Galician translation update (Miguel Anxo Bouzada). Closes: #626505 [ David Kalnischkies ] + * apt-pkg/indexcopy.cc: + - Verify that the first line of an InRelease file is a PGP header + for a signed message. Otherwise a man-in-the-middle can prefix + a valid InRelease file with his own data! (CVE-2011-1829) * fix a bunch of cppcheck warnings/errors based on a patch by Niels Thykier, thanks! (Closes: #622805) * apt-pkg/depcache.cc: @@ -78,7 +82,7 @@ apt (0.8.14.2) UNRELEASED; urgency=low - show Acquire::Languages and APT::Architectures settings in 'dump' (Closes: 626739) - -- David Kalnischkies <kalnischkies@gmail.com> Sat, 28 May 2011 10:54:23 +0200 + -- David Kalnischkies <kalnischkies@gmail.com> Mon, 06 Jun 2011 21:24:28 +0200 apt (0.8.14.1) unstable; urgency=low diff --git a/methods/gpgv.cc b/methods/gpgv.cc index efe1f73f7..960c06180 100644 --- a/methods/gpgv.cc +++ b/methods/gpgv.cc @@ -65,13 +65,16 @@ string GPGVMethod::VerifyGetSigners(const char *file, const char *outfile, return string("Couldn't spawn new process") + strerror(errno); else if (pid == 0) { - if (SigVerify::RunGPGV(outfile, file, 3, fd) == false) + _error->PushToStack(); + bool const success = SigVerify::RunGPGV(outfile, file, 3, fd); + if (success == false) { - // TRANSLATOR: %s is the trusted keyring parts directory - ioprintf(ret, _("No keyring installed in %s."), - _config->FindDir("Dir::Etc::TrustedParts").c_str()); - return ret.str(); + string errmsg; + _error->PopMessage(errmsg); + _error->RevertToStack(); + return errmsg; } + _error->RevertToStack(); exit(111); } close(fd[1]); diff --git a/test/integration/test-ubuntu-bug-784473-InRelease-one-message-only b/test/integration/test-ubuntu-bug-784473-InRelease-one-message-only new file mode 100755 index 000000000..d97011914 --- /dev/null +++ b/test/integration/test-ubuntu-bug-784473-InRelease-one-message-only @@ -0,0 +1,31 @@ +#!/bin/sh +set -e + +TESTDIR=$(readlink -f $(dirname $0)) +. $TESTDIR/framework +setupenvironment +configarchitecture 'i386' + +insertpackage 'unstable' 'apt' 'i386' '0.8.11' + +setupaptarchive + +rm -rf rootdir/var/lib/apt/lists + +find aptarchive/ -name 'Release.gpg' -delete +find aptarchive/ -name 'InRelease' -exec cp {} {}.old \; + +for RELEASE in $(find aptarchive/ -name 'InRelease'); do + (echo 'Origin: Marvin +Label: Marvin +Suite: experimental +Codename: experimental +MD5Sum: + 65fd410587b6978de2277f2912523f09 9360 Packages + d27b294ed172a1fa9dd5a53949914c5d 4076 Packages.bz2 + 2182897e0a2a0c09e760beaae117a015 2023 Packages.diff/Index + 1b895931853981ad8204d2439821b999 4144 Packages.gz'; echo; cat ${RELEASE}.old;) > ${RELEASE} +done +aptget update -qq > /dev/null 2> starts-with-unsigned.msg +sed -i 's#File .*InRelease#File InRelease#' starts-with-unsigned.msg +testfileequal starts-with-unsigned.msg "W: GPG error: file: unstable InRelease: File InRelease doesn't start with a clearsigned message" |