def testParseChangesNotVulnerableToArchExploit(self): """lp.archiveuploader.tagfiles.parse_tagfile should not be vulnerable to tags outside of the signed portion """ tf = parse_tagfile(datadir("changes-with-exploit-top")) self.assertRaises(KeyError, tf.__getitem__, "you") tf = parse_tagfile(datadir("changes-with-exploit-bottom")) self.assertRaises(KeyError, tf.__getitem__, "you")
def test_unpack_dsc_with_vendor(self): # Some source packages unpack differently depending on dpkg's idea # of the "vendor", and in extreme cases may even fail with some # vendors. gina always sets the vendor to the target distribution # name to ensure that it unpacks packages as if unpacking on that # distribution. archive_root = self.useTempDir() pool_dir = os.path.join(archive_root, "pool/main/f/foo") os.makedirs(pool_dir) # Synthesise a package that can be unpacked with DEB_VENDOR=debian # but not with DEB_VENDOR=ubuntu. with open(os.path.join(pool_dir, "foo_1.0.orig.tar.gz"), "wb+") as buffer: orig_tar = LaunchpadWriteTarFile(buffer) orig_tar.add_directory("foo-1.0") orig_tar.close() buffer.seek(0) orig_tar_contents = buffer.read() with open(os.path.join(pool_dir, "foo_1.0-1.debian.tar.gz"), "wb+") as buffer: debian_tar = LaunchpadWriteTarFile(buffer) debian_tar.add_file("debian/source/format", "3.0 (quilt)\n") debian_tar.add_file("debian/patches/ubuntu.series", "--- corrupt patch\n") debian_tar.add_file("debian/rules", "") debian_tar.close() buffer.seek(0) debian_tar_contents = buffer.read() dsc_path = os.path.join(pool_dir, "foo_1.0-1.dsc") with open(dsc_path, "w") as dsc: dsc.write( dedent("""\ Format: 3.0 (quilt) Source: foo Binary: foo Architecture: all Version: 1.0-1 Maintainer: Foo Bar <*****@*****.**> Files: %s %s foo_1.0.orig.tar.gz %s %s foo_1.0-1.debian.tar.gz """ % (hashlib.md5(orig_tar_contents).hexdigest(), len(orig_tar_contents), hashlib.md5(debian_tar_contents).hexdigest(), len(debian_tar_contents)))) dsc_contents = parse_tagfile(dsc_path) dsc_contents["Directory"] = pool_dir dsc_contents["Package"] = "foo" dsc_contents["Component"] = "main" dsc_contents["Section"] = "misc" sp_data = SourcePackageData(**dsc_contents) # Unpacking this in an Ubuntu context fails. self.assertRaises(ExecutionError, sp_data.do_package, "ubuntu", archive_root) # But all is well in a Debian context. sp_data.do_package("debian", archive_root)
def testCheckParseBadChanges(self): """Malformed but somewhat readable files do not raise an exception. We let apt_pkg make of them what it can, and dpkg-source will reject them if it can't understand. """ parsed = parse_tagfile(datadir("bad-multiline-changes")) self.assertEqual('unstable', parsed['Distribution'])
def test_process_package_cleans_up_after_unpack_failure(self): archive_root = self.useTempDir() pool_dir = os.path.join(archive_root, "pool/main/f/foo") os.makedirs(pool_dir) with open(os.path.join( pool_dir, "foo_1.0.orig.tar.gz"), "wb+") as buffer: orig_tar = LaunchpadWriteTarFile(buffer) orig_tar.add_directory("foo-1.0") orig_tar.close() buffer.seek(0) orig_tar_contents = buffer.read() with open(os.path.join( pool_dir, "foo_1.0-1.debian.tar.gz"), "wb+") as buffer: debian_tar = LaunchpadWriteTarFile(buffer) debian_tar.add_file("debian/source/format", "3.0 (quilt)\n") debian_tar.add_file("debian/patches/series", "--- corrupt patch\n") debian_tar.add_file("debian/rules", "") debian_tar.close() buffer.seek(0) debian_tar_contents = buffer.read() dsc_path = os.path.join(pool_dir, "foo_1.0-1.dsc") with open(dsc_path, "w") as dsc: dsc.write(dedent("""\ Format: 3.0 (quilt) Source: foo Binary: foo Architecture: all Version: 1.0-1 Maintainer: Foo Bar <*****@*****.**> Files: %s %s foo_1.0.orig.tar.gz %s %s foo_1.0-1.debian.tar.gz """ % ( hashlib.md5(orig_tar_contents).hexdigest(), len(orig_tar_contents), hashlib.md5(debian_tar_contents).hexdigest(), len(debian_tar_contents)))) dsc_contents = parse_tagfile(dsc_path) dsc_contents["Directory"] = pool_dir dsc_contents["Package"] = "foo" dsc_contents["Component"] = "main" dsc_contents["Section"] = "misc" sp_data = SourcePackageData(**dsc_contents) unpack_tmpdir = self.makeTemporaryDirectory() with EnvironmentVariableFixture("TMPDIR", unpack_tmpdir): # Force tempfile to recheck TMPDIR. tempfile.tempdir = None try: self.assertRaises( ExecutionError, sp_data.process_package, "ubuntu", archive_root) finally: # Force tempfile to recheck TMPDIR for future tests. tempfile.tempdir = None self.assertEqual([], os.listdir(unpack_tmpdir))
def setUp(self): """Parse the test file using apt_pkg for comparison.""" tagfile_path = datadir("test436182_0.1_source.changes") tagfile = open(tagfile_path) self.apt_pkg_parsed_version = apt_pkg.TagFile(tagfile) self.apt_pkg_parsed_version.step() self.parse_tagfile_version = parse_tagfile(tagfile_path)
def _getSourcePackageDataFromDSC(self, sp_name, sp_version, sp_component, sp_section): try: dsc_name, dsc_path, sp_component = get_dsc_path(sp_name, sp_version, sp_component, self.archive_root) except PoolFileNotFound: # Aah well, no source package in archive either. return None log.debug("Found a source package for %s (%s) in %s" % (sp_name, sp_version, sp_component)) dsc_contents = parse_tagfile(dsc_path) dsc_contents = dict([ (name.lower(), value) for (name, value) in dsc_contents.iteritems()]) # Since the dsc doesn't know, we add in the directory, package # component and section dsc_contents['directory'] = os.path.join("pool", poolify(sp_name, sp_component)) dsc_contents['package'] = sp_name dsc_contents['component'] = sp_component dsc_contents['section'] = sp_section # the dsc doesn't list itself so add it ourselves if 'files' not in dsc_contents: log.error('DSC for %s didn\'t contain a files entry: %r' % (dsc_name, dsc_contents)) return None if not dsc_contents['files'].endswith("\n"): dsc_contents['files'] += "\n" # XXX kiko 2005-10-21: Why do we hack the md5sum and size of the DSC? # Should probably calculate it properly. dsc_contents['files'] += "xxx 000 %s" % dsc_name # SourcePackageData requires capitals capitalized_dsc = {} for k, v in dsc_contents.items(): capitalized_dsc[k.capitalize()] = v return SourcePackageData(**capitalized_dsc)
def _getSourcePackageDataFromDSC(self, sp_name, sp_version, sp_component, sp_section): try: dsc_name, dsc_path, sp_component = get_dsc_path( sp_name, sp_version, sp_component, self.archive_root) except PoolFileNotFound: # Aah well, no source package in archive either. return None log.debug("Found a source package for %s (%s) in %s" % (sp_name, sp_version, sp_component)) dsc_contents = parse_tagfile(dsc_path) dsc_contents = dict([(name.lower(), value) for (name, value) in dsc_contents.iteritems()]) # Since the dsc doesn't know, we add in the directory, package # component and section dsc_contents['directory'] = os.path.join( "pool", poolify(sp_name, sp_component)) dsc_contents['package'] = sp_name dsc_contents['component'] = sp_component dsc_contents['section'] = sp_section # the dsc doesn't list itself so add it ourselves if 'files' not in dsc_contents: log.error('DSC for %s didn\'t contain a files entry: %r' % (dsc_name, dsc_contents)) return None if not dsc_contents['files'].endswith("\n"): dsc_contents['files'] += "\n" # XXX kiko 2005-10-21: Why do we hack the md5sum and size of the DSC? # Should probably calculate it properly. dsc_contents['files'] += "xxx 000 %s" % dsc_name # SourcePackageData requires capitals capitalized_dsc = {} for k, v in dsc_contents.items(): capitalized_dsc[k.capitalize()] = v return SourcePackageData(**capitalized_dsc)
def test_unpack_dsc_with_vendor(self): # Some source packages unpack differently depending on dpkg's idea # of the "vendor", and in extreme cases may even fail with some # vendors. gina always sets the vendor to the target distribution # name to ensure that it unpacks packages as if unpacking on that # distribution. archive_root = self.useTempDir() pool_dir = os.path.join(archive_root, "pool/main/f/foo") os.makedirs(pool_dir) # Synthesise a package that can be unpacked with DEB_VENDOR=debian # but not with DEB_VENDOR=ubuntu. with open(os.path.join(pool_dir, "foo_1.0.orig.tar.gz"), "wb+") as buffer: orig_tar = LaunchpadWriteTarFile(buffer) orig_tar.add_directory("foo-1.0") orig_tar.close() buffer.seek(0) orig_tar_contents = buffer.read() with open(os.path.join(pool_dir, "foo_1.0-1.debian.tar.gz"), "wb+") as buffer: debian_tar = LaunchpadWriteTarFile(buffer) debian_tar.add_file("debian/source/format", "3.0 (quilt)\n") debian_tar.add_file("debian/patches/ubuntu.series", "--- corrupt patch\n") debian_tar.add_file("debian/rules", "") debian_tar.close() buffer.seek(0) debian_tar_contents = buffer.read() dsc_path = os.path.join(pool_dir, "foo_1.0-1.dsc") with open(dsc_path, "w") as dsc: dsc.write( dedent( """\ Format: 3.0 (quilt) Source: foo Binary: foo Architecture: all Version: 1.0-1 Maintainer: Foo Bar <*****@*****.**> Files: %s %s foo_1.0.orig.tar.gz %s %s foo_1.0-1.debian.tar.gz """ % ( hashlib.md5(orig_tar_contents).hexdigest(), len(orig_tar_contents), hashlib.md5(debian_tar_contents).hexdigest(), len(debian_tar_contents), ) ) ) dsc_contents = parse_tagfile(dsc_path) dsc_contents["Directory"] = pool_dir dsc_contents["Package"] = "foo" dsc_contents["Component"] = "main" dsc_contents["Section"] = "misc" sp_data = SourcePackageData(**dsc_contents) # Unpacking this in an Ubuntu context fails. self.assertRaises(ExecutionError, sp_data.do_package, "ubuntu", archive_root) # But all is well in a Debian context. sp_data.do_package("debian", archive_root)
def testCheckParseChangesOkay(self): """lp.archiveuploader.tagfiles.parse_tagfile should work on a good changes file """ parse_tagfile(datadir("good-signed-changes"))