Browse Source

* apt-pkg/deb/debindexfile.cc,

apt-pkg/deb/deblistparser.cc:
  - use OpenMaybeClearSignedFile to be free from detecting and
    skipping clearsigning metadata in dsc and Release files

We can't write a "clean" file to disk as not all acquire methods copy
Release files before checking them (e.g. cdrom), so this reverts recombining,
but uses the method we use for dsc files also in the two places we
deal with Release files
debian/1.8.y
David Kalnischkies 9 years ago
parent
commit
233b78083f
  1. 44
      apt-pkg/contrib/gpgv.cc
  2. 14
      apt-pkg/contrib/gpgv.h
  3. 8
      apt-pkg/deb/debindexfile.cc
  4. 12
      apt-pkg/deb/deblistparser.cc
  5. 6
      apt-pkg/indexrecords.cc
  6. 11
      debian/changelog
  7. 2
      test/integration/framework
  8. 2
      test/integration/test-apt-cdrom

44
apt-pkg/contrib/gpgv.cc

@ -215,7 +215,7 @@ void ExecGPGV(std::string const &File, std::string const &FileGPG,
UNLINK_EXIT(EINTERNAL);
}
#undef UNLINK_EXIT
// we don't need the files any longer as we have the filedescriptors still open
// we don't need the files any longer
unlink(sig);
unlink(data);
free(sig);
@ -235,52 +235,12 @@ void ExecGPGV(std::string const &File, std::string const &FileGPG,
exit(WEXITSTATUS(Status));
}
/* looks like its fine. Our caller will check the status fd,
but we construct a good-known clear-signed file without garbage
and other non-sense. In a perfect world, we get the same file,
but empty lines, trailing whitespaces and stuff makes it inperfect */
if (RecombineToClearSignedFile(File, dataFd, dataHeader, sigFd) == false)
{
_error->DumpErrors(std::cerr);
exit(EINTERNAL);
}
// everything fine, we have a clean file now!
// everything fine
exit(0);
}
exit(EINTERNAL); // unreachable safe-guard
}
/*}}}*/
// RecombineToClearSignedFile - combine data/signature to message /*{{{*/
bool RecombineToClearSignedFile(std::string const &OutFile, int const ContentFile,
std::vector<std::string> const &ContentHeader, int const SignatureFile)
{
FILE *clean_file = fopen(OutFile.c_str(), "w");
fputs("-----BEGIN PGP SIGNED MESSAGE-----\n", clean_file);
for (std::vector<std::string>::const_iterator h = ContentHeader.begin(); h != ContentHeader.end(); ++h)
fprintf(clean_file, "%s\n", h->c_str());
fputs("\n", clean_file);
FILE *data_file = fdopen(ContentFile, "r");
FILE *sig_file = fdopen(SignatureFile, "r");
if (data_file == NULL || sig_file == NULL)
{
fclose(clean_file);
return _error->Error("Couldn't open splitfiles to recombine them into %s", OutFile.c_str());
}
char *buf = NULL;
size_t buf_size = 0;
while (getline(&buf, &buf_size, data_file) != -1)
fputs(buf, clean_file);
fclose(data_file);
fputs("\n", clean_file);
while (getline(&buf, &buf_size, sig_file) != -1)
fputs(buf, clean_file);
fclose(sig_file);
fclose(clean_file);
return true;
}
/*}}}*/
// SplitClearSignedFile - split message into data/signature /*{{{*/
bool SplitClearSignedFile(std::string const &InFile, int const ContentFile,
std::vector<std::string> * const ContentHeader, int const SignatureFile)

14
apt-pkg/contrib/gpgv.h

@ -69,20 +69,6 @@ inline void ExecGPGV(std::string const &File, std::string const &FileSig,
bool SplitClearSignedFile(std::string const &InFile, int const ContentFile,
std::vector<std::string> * const ContentHeader, int const SignatureFile);
/** \brief recombines message and signature to an inline signature
*
* Reverses the splitting down by #SplitClearSignedFile by writing
* a well-formed clear-signed message without unsigned messages,
* additional signed messages or just trailing whitespaces
*
* @param OutFile will be clear-signed file
* @param ContentFile is the Fd the message will be read from
* @param ContentHeader is a list of all required Amored Headers for the message
* @param SignatureFile is the Fd all signatures will be read from
*/
bool RecombineToClearSignedFile(std::string const &OutFile, int const ContentFile,
std::vector<std::string> const &ContentHeader, int const SignatureFile);
/** \brief open a file which might be clear-signed
*
* This method tries to extract the (signed) message of a file.

8
apt-pkg/deb/debindexfile.cc

@ -22,6 +22,7 @@
#include <apt-pkg/strutl.h>
#include <apt-pkg/acquire-item.h>
#include <apt-pkg/debmetaindex.h>
#include <apt-pkg/gpgv.h>
#include <sys/stat.h>
/*}}}*/
@ -337,7 +338,12 @@ bool debPackagesIndex::Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const
if (releaseExists == true || FileExists(ReleaseFile) == true)
{
FileFd Rel(ReleaseFile,FileFd::ReadOnly);
FileFd Rel;
// Beware: The 'Release' file might be clearsigned in case the
// signature for an 'InRelease' file couldn't be checked
if (OpenMaybeClearSignedFile(ReleaseFile, Rel) == false)
return false;
if (_error->PendingError() == true)
return false;
Parser.LoadReleaseInfo(File,Rel,Section);

12
apt-pkg/deb/deblistparser.cc

@ -800,13 +800,12 @@ bool debListParser::LoadReleaseInfo(pkgCache::PkgFileIterator &FileI,
map_ptrloc const storage = WriteUniqString(component);
FileI->Component = storage;
// FIXME: Code depends on the fact that Release files aren't compressed
// FIXME: should use FileFd and TagSection
FILE* release = fdopen(dup(File.Fd()), "r");
if (release == NULL)
return false;
char buffer[101];
bool gpgClose = false;
while (fgets(buffer, sizeof(buffer), release) != NULL)
{
size_t len = 0;
@ -818,15 +817,6 @@ bool debListParser::LoadReleaseInfo(pkgCache::PkgFileIterator &FileI,
if (buffer[len] == '\0')
continue;
// only evalute the first GPG section
if (strncmp("-----", buffer, 5) == 0)
{
if (gpgClose == true)
break;
gpgClose = true;
continue;
}
// seperate the tag from the data
const char* dataStart = strchr(buffer + len, ':');
if (dataStart == NULL)

6
apt-pkg/indexrecords.cc

@ -12,6 +12,7 @@
#include <apt-pkg/configuration.h>
#include <apt-pkg/fileutl.h>
#include <apt-pkg/hashes.h>
#include <apt-pkg/gpgv.h>
#include <sys/stat.h>
#include <clocale>
@ -57,7 +58,10 @@ bool indexRecords::Exists(string const &MetaKey) const
bool indexRecords::Load(const string Filename) /*{{{*/
{
FileFd Fd(Filename, FileFd::ReadOnly);
FileFd Fd;
if (OpenMaybeClearSignedFile(Filename, Fd) == false)
return false;
pkgTagFile TagFile(&Fd, Fd.Size() + 256); // XXX
if (_error->PendingError() == true)
{

11
debian/changelog

@ -8,19 +8,18 @@ apt (0.9.7.9) UNRELEASED; urgency=low
and fix the inconsistency of returning in error cases
- don't close stdout/stderr if it is also the statusfd
- if ExecGPGV deals with a clear-signed file it will split this file
into data and signatures, pass it to gpgv for verification and
recombines it after that in a known-good way without unsigned blocks
and whitespaces resulting usually in more or less the same file as
before, but later code can be sure about the format
into data and signatures, pass it to gpgv for verification
- add method to open (maybe) clearsigned files transparently
* apt-pkg/acquire-item.cc:
- keep the last good InRelease file around just as we do it with
Release.gpg in case the new one we download isn't good for us
* apt-pkg/deb/debmetaindex.cc:
- reenable InRelease by default
* ftparchive/writer.cc:
* ftparchive/writer.cc,
apt-pkg/deb/debindexfile.cc,
apt-pkg/deb/deblistparser.cc:
- use OpenMaybeClearSignedFile to be free from detecting and
skipping clearsigning metadata in dsc files
skipping clearsigning metadata in dsc and Release files
[ Michael Vogt ]
* add regression test for CVE-2013-1051

2
test/integration/framework

@ -114,7 +114,7 @@ gdb() {
}
addtrap() {
CURRENTTRAP="$CURRENTTRAP $1"
CURRENTTRAP="$1 $CURRENTTRAP"
trap "$CURRENTTRAP exit;" 0 HUP INT QUIT ILL ABRT FPE SEGV PIPE TERM
}

2
test/integration/test-apt-cdrom

@ -24,6 +24,8 @@ cat Translation-de | xz --format=lzma > Translation-de.lzma
cat Translation-de | xz > Translation-de.xz
rm Translation-en Translation-de
cd - > /dev/null
addtrap "chmod -R +w $PWD/rootdir/media/cdrom/dists/;"
chmod -R -w rootdir/media/cdrom/dists
aptcdrom add -m -o quiet=1 > apt-cdrom.log 2>&1
sed -i -e '/^Using CD-ROM/ d' -e '/gpgv/ d' -e '/^Identifying/ d' -e '/Reading / d' apt-cdrom.log

Loading…
Cancel
Save