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_no_signature_rejected(self): # An unsigned changes file is rejected. path = datadir('signatures/unsigned.changes') changesfile = ChangesFile(path, InsecureUploadPolicy(), BufferLogger()) errors = list(changesfile.parseChanges()) self.assertIsInstance(errors[0], UploadError) self.assertEqual(1, len(errors))
def testCheckParseUnterminatedSigRaises(self): """lp.archiveuploader.tagfiles.parse_changes should raise TagFileParseError on unterminated signatures """ self.assertRaises(TagFileParseError, parse_tagfile, datadir("unterminated-sig-changes"))
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 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 _getImportableFilesFromTarball(self): tarball = TarFile.open(mode="r:gz", fileobj=open( datadir("rosetta-translations/%s" % self.translations_file))) return [ relpath(file_, "./source/") for file_ in tarball.getnames() if ".po" in file_ ]
def uploadTestData(self, version): upload = NascentUpload.from_changesfile_path( datadir("dist-upgrader/dist-upgrader_%s_all.changes" % version), self.anything_policy, self.logger) upload.process() self.assertFalse(upload.is_rejected) self.assertTrue(upload.do_accept()) self.assertFalse(upload.rejection_message) return upload
def uploadTestData(self, version): upload = NascentUpload.from_changesfile_path( datadir("ddtp-tarball/translations-main_%s_all.changes" % version), self.anything_policy, self.logger ) upload.process() self.assertFalse(upload.is_rejected) self.assertTrue(upload.do_accept()) self.assertFalse(upload.rejection_message) return upload
def uploadToPPA(self): # Setup PPA owner and archive self.name16 = getUtility(IPersonSet).getByName('name16') name16_archive = self.factory.makeArchive( distribution=self.breezy_autotest.distribution, owner=self.name16, name="ppa") policy = self.absolutely_anything_policy policy.archive = name16_archive upload = NascentUpload.from_changesfile_path( datadir("rosetta-translations/%s" % self.source_changes_file), policy, self.logger) upload.process() self.assertFalse(upload.is_rejected) self.assertTrue(upload.do_accept()) self.assertEqual(upload.queue_root.status, PackageUploadStatus.DONE) spph = self.name16.archive.getPublishedSources(name="pmount").one() self.assertIsNotNone(spph) transaction.commit() policy.accepted_type = ArchiveUploadType.BINARY_ONLY bin_upload = NascentUpload.from_changesfile_path( datadir("rosetta-translations/%s" % self.bin_changes_file), policy, self.logger) bin_upload.process() self.assertFalse(bin_upload.is_rejected) self.assertTrue(bin_upload.do_accept()) self.assertEqual(bin_upload.queue_root.status, PackageUploadStatus.ACCEPTED) bin_upload.queue_root.realiseUpload() self.assertEqual(bin_upload.queue_root.status, PackageUploadStatus.DONE) self.assertEqual(bin_upload.queue_root.builds[0].build.status.name, "FULLYBUILT") transaction.commit() return upload, spph, bin_upload
def uploadTestData(self): upload = NascentUpload.from_changesfile_path( datadir("debian-installer/" "debian-installer_20070214ubuntu1_i386.changes"), self.anything_policy, self.logger) upload.process() self.assertFalse(upload.is_rejected) self.assertTrue(upload.do_accept()) self.assertFalse(upload.rejection_message) return upload
def test_simple(self): # unpack_source unpacks in a temporary directory and returns the # path. temp_dir = self.makeTemporaryDirectory() extract_dpkg_source( datadir(os.path.join('suite', 'bar_1.0-1', 'bar_1.0-1.dsc')), temp_dir) self.assertEquals(["bar-1.0"], os.listdir(temp_dir)) self.assertContentEqual( ["THIS_IS_BAR", "debian"], os.listdir(os.path.join(temp_dir, "bar-1.0")))
def test_simple(self): # unpack_source unpacks in a temporary directory and returns the # path. temp_dir = self.makeTemporaryDirectory() extract_dpkg_source( datadir(os.path.join('suite', 'bar_1.0-1', 'bar_1.0-1.dsc')), temp_dir) self.assertEqual(["bar-1.0"], os.listdir(temp_dir)) self.assertContentEqual( ["THIS_IS_BAR", "debian"], os.listdir(os.path.join(temp_dir, "bar-1.0")))
def uploadTestData(self): upload = NascentUpload.from_changesfile_path( datadir( "debian-installer/" "debian-installer_20070214ubuntu1_i386.changes"), self.anything_policy, self.logger) upload.process() self.assertFalse(upload.is_rejected) self.assertTrue(upload.do_accept()) self.assertFalse(upload.rejection_message) return upload
def test_valid_signature_accepted(self): # A correctly signed changes file is excepted, and all its # content is parsed. path = datadir('signatures/signed.changes') parsed = ChangesFile(path, InsecureUploadPolicy(), BufferLogger()) self.assertEqual( getUtility(IPersonSet).getByEmail('*****@*****.**'), parsed.signer) expected = "\AFormat: 1.7\n.*foo_1.0-1.diff.gz\Z" self.assertTextMatchesExpressionIgnoreWhitespace( expected, parsed.parsed_content)
def getDscFile(self, name): dsc_path = datadir(os.path.join('suite', name, name + '.dsc')) class Changes: architectures = ['source'] logger = BufferLogger() policy = BuildDaemonUploadPolicy() policy.distroseries = self.factory.makeDistroSeries() policy.archive = self.factory.makeArchive() policy.distro = policy.distroseries.distribution return DSCFile(dsc_path, {}, 0, 'main/editors', 'priority', 'package', 'version', Changes, policy, logger)
def test_unpack_source(self): # unpack_source unpacks in a temporary directory and returns the # path. unpacked_dir = unpack_source( datadir(os.path.join('suite', 'bar_1.0-1', 'bar_1.0-1.dsc'))) try: self.assertEquals(["bar-1.0"], os.listdir(unpacked_dir)) self.assertContentEqual(["THIS_IS_BAR", "debian"], os.listdir( os.path.join(unpacked_dir, "bar-1.0"))) finally: cleanup_unpacked_dir(unpacked_dir)
def test_unpack_source(self): # unpack_source unpacks in a temporary directory and returns the # path. unpacked_dir = unpack_source( datadir(os.path.join('suite', 'bar_1.0-1', 'bar_1.0-1.dsc'))) try: self.assertEquals(["bar-1.0"], os.listdir(unpacked_dir)) self.assertContentEqual( ["THIS_IS_BAR", "debian"], os.listdir(os.path.join(unpacked_dir, "bar-1.0"))) finally: cleanup_unpacked_dir(unpacked_dir)
def test_prefix_ignored(self): # A signed changes file with an unsigned prefix has only the # signed part parsed. path = datadir('signatures/prefixed.changes') parsed = ChangesFile(path, InsecureUploadPolicy(), BufferLogger()) self.assertEqual( getUtility(IPersonSet).getByEmail('*****@*****.**'), parsed.signer) expected = "\AFormat: 1.7\n.*foo_1.0-1.diff.gz\Z" self.assertTextMatchesExpressionIgnoreWhitespace( expected, parsed.parsed_content) self.assertEqual("breezy", parsed.suite_name) self.assertNotIn("evil", parsed.changes_comment)
def test_hash_mismatch_rejects(self): # A hash mismatch for any uploaded file will cause the upload to # be rejected. policy = getPolicy(name="sync", distro="ubuntu", distroseries="hoary") policy.accepted_type = ArchiveUploadType.BINARY_ONLY upload = NascentUpload.from_changesfile_path( datadir("suite/badhash_1.0-1/badhash_1.0-1_i386.changes"), policy, DevNullLogger()) upload.process() self.assertTrue(upload.is_rejected) self.assertEqual( 'File badhash_1.0-1_i386.deb mentioned in the changes has a SHA1 ' 'mismatch. 2ca33cf32a45852c62b465aaf9063fb7deb31725 != ' '91556113ad38eb35d2fe03d27ae646e0ed487a3d', upload.rejection_message)
def test_hash_mismatch_rejects(self): # A hash mismatch for any uploaded file will cause the upload to # be rejected. policy = getPolicy(name="sync", distro="ubuntu", distroseries="hoary") policy.accepted_type = ArchiveUploadType.BINARY_ONLY upload = NascentUpload.from_changesfile_path( datadir("suite/badhash_1.0-1/badhash_1.0-1_i386.changes"), policy, DevNullLogger() ) upload.process() self.assertTrue(upload.is_rejected) self.assertEqual( "File badhash_1.0-1_i386.deb mentioned in the changes has a SHA1 " "mismatch. 2ca33cf32a45852c62b465aaf9063fb7deb31725 != " "91556113ad38eb35d2fe03d27ae646e0ed487a3d", upload.rejection_message, )
def test_checkFiles_verifies_additional_hashes(self): """Test that checkFiles detects SHA1 and SHA256 mismatches.""" policy = getPolicy(name="sync", distro="ubuntu", distroseries="hoary") path = datadir( os.path.join('suite', 'badhash_1.0-1_broken_dsc', 'badhash_1.0-1.dsc')) dsc = DSCFile(path, {}, 426, 'main/editors', 'priority', 'badhash', '1.0-1', FakeChangesFile(), policy, DevNullLogger()) errors = [e[0] for e in dsc.verify()] self.assertEqual([ 'File badhash_1.0-1.tar.gz mentioned in the changes has a SHA256' ' mismatch. a29ec2370df83193c3fb2cc9e1287dbfe9feba04108ccfa490bb' 'e20ea66f3d08 != aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' 'aaaaaaaaaaaaaaaaa', 'Files specified in DSC are broken or missing, skipping package ' 'unpack verification.' ], errors)
def test_ppa_publishing_location(self): # A PPA dist-upgrader upload is published to the right place. archive = self.factory.makeArchive(distribution=self.ubuntutest) self.anything_policy.archive = archive ppa_upload = self.uploadTestData("20060302.0120") ppa_upload = NascentUpload.from_changesfile_path( datadir("dist-upgrader/dist-upgrader_20060302.0120_all.changes"), self.anything_policy, self.logger) ppa_upload.process() self.assertTrue(ppa_upload.do_accept()) transaction.commit() ppa_upload.queue_root.realiseUpload(self.logger) ppa_root = config.personalpackagearchive.root ppa_dir = os.path.join(ppa_root, archive.owner.name, archive.name) target_dir = os.path.join( ppa_dir, "ubuntutest/dists/breezy-autotest/main/dist-upgrader-all") self.assertContentEqual( ["20060302.0120", "current"], os.listdir(target_dir))
def test_ppa_publishing_location(self): # A PPA dist-upgrader upload is published to the right place. archive = self.factory.makeArchive(distribution=self.ubuntutest) self.anything_policy.archive = archive ppa_upload = self.uploadTestData("20060302.0120") ppa_upload = NascentUpload.from_changesfile_path( datadir("dist-upgrader/dist-upgrader_20060302.0120_all.changes"), self.anything_policy, self.logger) ppa_upload.process() self.assertTrue(ppa_upload.do_accept()) transaction.commit() ppa_upload.queue_root.realiseUpload(self.logger) ppa_root = config.personalpackagearchive.root ppa_dir = os.path.join(ppa_root, archive.owner.name, archive.name) target_dir = os.path.join( ppa_dir, "ubuntutest/dists/breezy-autotest/main/dist-upgrader-all") self.assertContentEqual(["20060302.0120", "current"], os.listdir(target_dir))
def test_checkFiles_verifies_additional_hashes(self): """Test that checkFiles detects SHA1 and SHA256 mismatches.""" policy = getPolicy( name="sync", distro="ubuntu", distroseries="hoary") path = datadir(os.path.join( 'suite', 'badhash_1.0-1_broken_dsc', 'badhash_1.0-1.dsc')) dsc = DSCFile( path, {}, 426, 'main/editors', 'priority', 'badhash', '1.0-1', FakeChangesFile(), policy, DevNullLogger()) errors = [e[0] for e in dsc.verify()] self.assertEqual( ['File badhash_1.0-1.tar.gz mentioned in the changes has a SHA256' ' mismatch. a29ec2370df83193c3fb2cc9e1287dbfe9feba04108ccfa490bb' 'e20ea66f3d08 != aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' 'aaaaaaaaaaaaaaaaa', 'Files specified in DSC are broken or missing, skipping package ' 'unpack verification.'], errors)
def uploadTestData(self, name=None, version=None): if name is None: name = self.package_name if version is None: version = self.version spph = self.getPubSource(sourcename=name, version=version, distroseries=self.breezy_autotest, status=PackagePublishingStatus.PUBLISHED) self.spr = spph.sourcepackagerelease upload = NascentUpload.from_changesfile_path( datadir("rosetta-translations/%s" % self.bin_changes_file), self.absolutely_anything_policy, self.logger) upload.process() self.assertFalse(upload.is_rejected) self.assertTrue(upload.do_accept()) self.assertFalse(upload.rejection_message) # Accepting the queue entry because there's no ancestry, so not # auto-accepted upload.queue_root.setAccepted() return upload
def test_rejects_misspelled_changesfile_name(self): upload = NascentUpload.from_changesfile_path( datadir("dist-upgrader/dist-upgrader_20060302.0120.changes"), self.absolutely_anything_policy, self.logger) self.assertRaises(EarlyReturnUploadError, upload.process)
def testCheckParseChangesOkay(self): """lp.archiveuploader.tagfiles.parse_tagfile should work on a good changes file """ parse_tagfile(datadir("good-signed-changes"))
def testCheckParseEmptyChangesRaises(self): """lp.archiveuploader.tagfiles.parse_chantges should raise TagFileParseError on empty """ self.assertRaises(TagFileParseError, parse_tagfile, datadir("empty-file"))
def test_rejects_misspelled_changesfile_name(self): upload = NascentUpload.from_changesfile_path( datadir("ddtp-tarball/translations-main_20060728.changes"), self.absolutely_anything_policy, self.logger ) self.assertRaises(EarlyReturnUploadError, upload.process)
def getUploadForBinary(upload_path): """Return a NascentUpload object for binaries.""" policy = getPolicy(name='sync', distro='ubuntu', distroseries='hoary') policy.accepted_type = ArchiveUploadType.BINARY_ONLY return NascentUpload.from_changesfile_path( datadir(upload_path), policy, DevNullLogger())
def getPPAUploadForSource(upload_path, ppa): """Return a NascentUpload object for a PPA source.""" policy = getPolicy(name='insecure', distro='ubuntu', distroseries='hoary') policy.archive = ppa return NascentUpload.from_changesfile_path( datadir(upload_path), policy, DevNullLogger())
def getUploadForSource(upload_path): """Return a NascentUpload object for a source.""" policy = getPolicy(name='sync', distro='ubuntu', distroseries='hoary') return NascentUpload.from_changesfile_path( datadir(upload_path), policy, DevNullLogger())
def test_no_signature_rejected(self): # An unsigned changes file is rejected. path = datadir('signatures/unsigned.changes') self.assertRaises(UploadError, ChangesFile, path, InsecureUploadPolicy(), BufferLogger())
def test_rejects_misspelled_changesfile_name(self): upload = NascentUpload.from_changesfile_path( datadir("ddtp-tarball/translations-main_20060728.changes"), self.absolutely_anything_policy, self.logger) self.assertRaises(EarlyReturnUploadError, upload.process)
def setUp(self): """Create two new uploads in the new state and a person with permission to upload to the partner archive.""" super(TestAcceptRejectQueueUploads, self).setUp() login('*****@*****.**') self.test_publisher = SoyuzTestPublisher() self.test_publisher.prepareBreezyAutotest() distribution = self.test_publisher.distroseries.distribution self.second_series = self.factory.makeDistroSeries( distribution=distribution) self.factory.makeComponentSelection(self.second_series, 'main') self.main_archive = distribution.getArchiveByComponent('main') self.partner_archive = distribution.getArchiveByComponent('partner') # Get some sample changes file content for the new uploads. with open(datadir('suite/bar_1.0-1/bar_1.0-1_source.changes')) as cf: changes_file_content = cf.read() self.partner_spr = self.makeSPR( 'partner-upload', 'partner', self.partner_archive, changes_file_content, distroseries=self.test_publisher.distroseries) self.main_spr = self.makeSPR( 'main-upload', 'main', self.main_archive, changes_file_content, distroseries=self.test_publisher.distroseries) self.proposed_spr = self.makeSPR( 'proposed-upload', 'main', self.main_archive, changes_file_content, pocket=PackagePublishingPocket.PROPOSED, distroseries=self.test_publisher.distroseries) self.proposed_series_spr = self.makeSPR( 'proposed-series-upload', 'main', self.main_archive, changes_file_content, pocket=PackagePublishingPocket.PROPOSED, distroseries=self.second_series) # Define the form that will be used to post to the view. self.form = { 'queue_state': PackageUploadStatus.NEW.value, 'Accept': 'Accept', } # Create a user with queue admin rights for main, and a separate # user with queue admin rights for partner (on the partner # archive). self.main_queue_admin = self.factory.makePerson() getUtility(IArchivePermissionSet).newQueueAdmin( distribution.getArchiveByComponent('main'), self.main_queue_admin, self.main_spr.component) self.partner_queue_admin = self.factory.makePerson() getUtility(IArchivePermissionSet).newQueueAdmin( distribution.getArchiveByComponent('partner'), self.partner_queue_admin, self.partner_spr.component) # Create users with various pocket queue admin rights. self.proposed_queue_admin = self.factory.makePerson() getUtility(IArchivePermissionSet).newPocketQueueAdmin( self.main_archive, self.proposed_queue_admin, PackagePublishingPocket.PROPOSED) self.proposed_series_queue_admin = self.factory.makePerson() getUtility(IArchivePermissionSet).newPocketQueueAdmin( self.main_archive, self.proposed_series_queue_admin, PackagePublishingPocket.PROPOSED, distroseries=self.second_series) # We need to commit to ensure the changes file exists in the # librarian. transaction.commit() logout()