示例#1
0
	def testCopy(self):
		sha1 = manifest.get_algorithm('sha1')
		sha1new = manifest.get_algorithm('sha1new')
		source = os.path.join(self.tmp, 'badname')
		os.mkdir(source)

		self.populate_sample(source)

		lines = list(sha1new.generate_manifest(source))
		self.assertEqual(['F f7ff9e8b7bb2e09b70935a5d785e0cc5d9d0abf0 2 5 MyFile',
				   'S 570b0ce957ab43e774c82fca0ea3873fc452278b 19 a symlink',
				   'D /My Dir',
				   'F 0236ef92e1e37c57f0eb161e7e2f8b6a8face705 2 10 !a file!',
				   'X b4ab02f2c791596a980fd35f51f5d92ee0b4705c 2 10 !a file!.exe'],
				lines)
		digest = sha1.getID(manifest.add_manifest_file(source, sha1))

		copy = tempfile.mktemp()
		os.mkdir(copy)
		try:
			# Source must be in the form alg=value
			try:
				cli.do_copy([source, copy])
				assert 0
			except BadDigest as ex:
				assert 'badname' in str(ex)
			source, badname = os.path.join(self.tmp, digest), source
			os.chmod(badname, 0o755)		# can't rename RO directories on MacOS X
			os.rename(badname, source)
			os.chmod(source, 0o555)

			# Can't copy sha1 implementations (unsafe)
			try:
				cli.do_copy([source, copy])
			except SafeException as ex:
				assert 'sha1' in str(ex)

			# Already have a .manifest
			try:
				manifest.add_manifest_file(source, sha1new)
				assert 0
			except SafeException as ex:
				assert '.manifest' in str(ex)

			os.chmod(source, 0o700)
			os.unlink(os.path.join(source, '.manifest'))

			# Switch to sha1new
			digest = sha1new.getID(manifest.add_manifest_file(source, sha1new))
			source, badname = os.path.join(self.tmp, digest), source
			os.chmod(badname, 0o755)
			os.rename(badname, source)
			os.chmod(source, 0o555)

			cli.do_copy([source, copy])

			with open(os.path.join(copy, digest, 'MyFile'), 'rt') as stream:
				self.assertEqual('Hello', stream.read())
		finally:
			support.ro_rmtree(copy)
示例#2
0
    def testCopy(self):
        sha1 = manifest.get_algorithm('sha1')
        sha1new = manifest.get_algorithm('sha1new')
        source = os.path.join(self.tmp, 'badname')
        os.mkdir(source)

        self.populate_sample(source)

        lines = list(sha1new.generate_manifest(source))
        self.assertEquals([
            'F f7ff9e8b7bb2e09b70935a5d785e0cc5d9d0abf0 2 5 MyFile',
            'S 570b0ce957ab43e774c82fca0ea3873fc452278b 19 a symlink',
            'D /My Dir',
            'F 0236ef92e1e37c57f0eb161e7e2f8b6a8face705 2 10 !a file!',
            'X b4ab02f2c791596a980fd35f51f5d92ee0b4705c 2 10 !a file!.exe'
        ], lines)
        digest = sha1.getID(manifest.add_manifest_file(source, sha1))

        copy = tempfile.mktemp()
        os.mkdir(copy)
        try:
            # Source must be in the form alg=value
            try:
                cli.do_copy([source, copy])
                assert 0
            except BadDigest as ex:
                assert 'badname' in str(ex)
            source, badname = os.path.join(self.tmp, digest), source
            os.rename(badname, source)

            # Can't copy sha1 implementations (unsafe)
            try:
                cli.do_copy([source, copy])
            except SafeException as ex:
                assert 'sha1' in str(ex)

            # Already have a .manifest
            try:
                manifest.add_manifest_file(source, sha1new)
                assert 0
            except SafeException as ex:
                assert '.manifest' in str(ex)

            os.chmod(source, 0o700)
            os.unlink(os.path.join(source, '.manifest'))

            # Switch to sha1new
            digest = sha1new.getID(manifest.add_manifest_file(source, sha1new))
            source, badname = os.path.join(self.tmp, digest), source
            os.rename(badname, source)

            cli.do_copy([source, copy])

            self.assertEquals(
                'Hello',
                file(os.path.join(copy, digest, 'MyFile')).read())
        finally:
            support.ro_rmtree(copy)
示例#3
0
def get_digest(unpack_dir, alg_name):
	alg = manifest.get_algorithm(alg_name)

	digest = alg.new_digest()
	for line in alg.generate_manifest(unpack_dir):
		digest.update((line + '\n').encode('utf-8'))
	
	return alg.getID(digest)
示例#4
0
def do_manifest(args):
	"""manifest DIRECTORY [ALGORITHM]"""
	if len(args) < 1 or len(args) > 2: raise UsageError(_("Wrong number of arguments"))
	if len(args) == 2:
		alg = get_algorithm(args[1])
	else:
		# If no algorithm was given, guess from the directory name
		name = os.path.basename(args[0])
		try:
			alg, unused = manifest.splitID(name)
		except zerostore.BadDigest:
			alg = get_algorithm('sha1new')
	digest = alg.new_digest()
	for line in alg.generate_manifest(args[0]):
		print(line)
		digest.update((line + '\n').encode('utf-8'))
	print(alg.getID(digest))
	sys.exit(0)
示例#5
0
def do_manifest(args):
	"""manifest DIRECTORY [ALGORITHM]"""
	if len(args) < 1 or len(args) > 2: raise UsageError(_("Wrong number of arguments"))
	if len(args) == 2:
		alg = get_algorithm(args[1])
	else:
		# If no algorithm was given, guess from the directory name
		name = os.path.basename(args[0])
		if '=' in name:
			alg = get_algorithm(name.split('=', 1)[0])
		else:
			alg = get_algorithm('sha1new')
	digest = alg.new_digest()
	for line in alg.generate_manifest(args[0]):
		print line
		digest.update(line + '\n')
	print alg.getID(digest)
	sys.exit(0)
示例#6
0
def do_manifest(args):
	"""manifest DIRECTORY [ALGORITHM]"""
	if len(args) < 1 or len(args) > 2: raise UsageError(_("Wrong number of arguments"))
	if len(args) == 2:
		alg = get_algorithm(args[1])
	else:
		# If no algorithm was given, guess from the directory name
		name = os.path.basename(args[0])
		try:
			alg, unused = manifest.splitID(name)
		except zerostore.BadDigest:
			alg = get_algorithm('sha1new')
	digest = alg.new_digest()
	for line in alg.generate_manifest(args[0]):
		print(line)
		digest.update((line + '\n').encode('utf-8'))
	print(alg.getID(digest))
	sys.exit(0)
示例#7
0
def do_manifest(args):
    """manifest DIRECTORY [ALGORITHM]"""
    if len(args) < 1 or len(args) > 2:
        raise UsageError(_("Wrong number of arguments"))
    if len(args) == 2:
        alg = get_algorithm(args[1])
    else:
        # If no algorithm was given, guess from the directory name
        name = os.path.basename(args[0])
        if '=' in name:
            alg = get_algorithm(name.split('=', 1)[0])
        else:
            alg = get_algorithm('sha1new')
    digest = alg.new_digest()
    for line in alg.generate_manifest(args[0]):
        print line
        digest.update(line + '\n')
    print alg.getID(digest)
    sys.exit(0)
示例#8
0
	def assert_manifest(self, required):
		alg_name = required.split('=', 1)[0]
		manifest.fixup_permissions(self.tmpdir)
		sha1 = alg_name + '=' + manifest.add_manifest_file(self.tmpdir, manifest.get_algorithm(alg_name)).hexdigest()
		self.assertEqual(sha1, required)

		# Check permissions are sensible
		for root, dirs, files in os.walk(self.tmpdir):
			for f in files + dirs:
				full = os.path.join(root, f)
				if os.path.islink(full): continue
				full_mode = os.stat(full).st_mode
				self.assertEqual(0o444, full_mode & 0o666)	# Must be r-?r-?r-?
示例#9
0
    def testCopy(self):
        sha1 = manifest.get_algorithm("sha1")
        sha1new = manifest.get_algorithm("sha1new")
        source = os.path.join(self.tmp, "badname")
        os.mkdir(source)

        self.populate_sample(source)

        lines = list(sha1new.generate_manifest(source))
        self.assertEquals(
            [
                "F f7ff9e8b7bb2e09b70935a5d785e0cc5d9d0abf0 2 5 MyFile",
                "S 570b0ce957ab43e774c82fca0ea3873fc452278b 19 a symlink",
                "D /My Dir",
                "F 0236ef92e1e37c57f0eb161e7e2f8b6a8face705 2 10 !a file!",
                "X b4ab02f2c791596a980fd35f51f5d92ee0b4705c 2 10 !a file!.exe",
            ],
            lines,
        )
        digest = sha1.getID(manifest.add_manifest_file(source, sha1))

        copy = tempfile.mktemp()
        os.mkdir(copy)
        try:
            # Source must be in the form alg=value
            try:
                cli.do_copy([source, copy])
                assert 0
            except BadDigest, ex:
                assert "badname" in str(ex)
            source, badname = os.path.join(self.tmp, digest), source
            os.rename(badname, source)

            # Can't copy sha1 implementations (unsafe)
            try:
                cli.do_copy([source, copy])
            except SafeException, ex:
                assert "sha1" in str(ex)
示例#10
0
    def assert_manifest(self, required):
        alg_name = required.split('=', 1)[0]
        manifest.fixup_permissions(self.tmpdir)
        sha1 = alg_name + '=' + manifest.add_manifest_file(
            self.tmpdir, manifest.get_algorithm(alg_name)).hexdigest()
        self.assertEqual(sha1, required)

        # Check permissions are sensible
        for root, dirs, files in os.walk(self.tmpdir):
            for f in files + dirs:
                full = os.path.join(root, f)
                if os.path.islink(full): continue
                full_mode = os.stat(full).st_mode
                self.assertEqual(0o444, full_mode & 0o666)  # Must be r-?r-?r-?
示例#11
0
 def testVerify(self):
     path = os.path.join(self.tmp, "MyLink")
     os.symlink("Hello", path)
     mfile = os.path.join(self.tmp, ".manifest")
     for alg_name in ["sha1", "sha256", "sha1new"]:
         try:
             alg = manifest.get_algorithm(alg_name)
             added_digest = alg.getID(manifest.add_manifest_file(self.tmp, alg))
             digest = alg.new_digest()
             digest.update("Hello")
             self.assertEquals("S %s 5 MyLink\n" % digest.hexdigest(), file(mfile, "rb").read())
             manifest.verify(self.tmp, added_digest)
             os.chmod(self.tmp, 0700)
             os.unlink(mfile)
         except BadDigest, ex:
             raise Exception("%s: %s\n%s" % (alg_name, ex, ex.detail))
示例#12
0
	def testVerify(self):
		path = os.path.join(self.tmp, 'MyLink')
		os.symlink('Hello', path)
		mfile = os.path.join(self.tmp, '.manifest')
		for alg_name in ['sha1', 'sha256', 'sha1new']:
			try:
				alg = manifest.get_algorithm(alg_name)
				added_digest = alg.getID(manifest.add_manifest_file(self.tmp, alg))
				digest = alg.new_digest()
				digest.update('Hello')
				self.assertEquals("S %s 5 MyLink\n" % digest.hexdigest(),
						file(mfile, 'rb').read())
				manifest.verify(self.tmp, added_digest)
				os.chmod(self.tmp, 0o700)
				os.unlink(mfile)
			except BadDigest as ex:
				raise Exception("%s: %s\n%s" % (alg_name, ex, ex.detail))
示例#13
0
	def testImplementationGenerateMissingId(self):
                old_out = sys.stdout
		try:
			sys.stdout = StringIO()
			self.child = server.handle_requests(('HelloWorld.tgz'))

                        from zeroinstall.zerostore import manifest
                        alg = manifest.get_algorithm('sha1')
                        assert alg

                        from zeroinstall.injector.reader import load_feed
			feed = load_feed(os.path.abspath('ImplementationNoId.xml'), True, False, False, alg, self.config)

                        expected_id = 'sha1=3ce644dc725f1d21cfcf02562c76f375944b266a'
                        assert feed.implementations[expected_id]
                        assert feed.implementations[expected_id].id == expected_id
		finally:
			sys.stdout = old_out
示例#14
0
 def testVerify(self):
     path = os.path.join(self.tmp, 'MyLink')
     os.symlink('Hello', path)
     mfile = os.path.join(self.tmp, '.manifest')
     for alg_name in ['sha1', 'sha256', 'sha1new']:
         try:
             alg = manifest.get_algorithm(alg_name)
             added_digest = alg.getID(
                 manifest.add_manifest_file(self.tmp, alg))
             digest = alg.new_digest()
             digest.update('Hello')
             self.assertEquals("S %s 5 MyLink\n" % digest.hexdigest(),
                               file(mfile, 'rb').read())
             manifest.verify(self.tmp, added_digest)
             os.chmod(self.tmp, 0o700)
             os.unlink(mfile)
         except BadDigest as ex:
             raise Exception("%s: %s\n%s" % (alg_name, ex, ex.detail))
示例#15
0
def add_digest(impl, alg_name):
    alg = manifest.get_algorithm(alg_name)

    # Scan through the existing digests
    # - If we've already got the one we need, return
    # - Otherwise, find a cached implementation we can use
    existing_path = None
    for a, value in digests(impl):
        if a in ('sha1', 'sha1new', 'sha256'):
            digest = '%s=%s' % (a, value)
        else:
            digest = '%s_%s' % (a, value)
        if a == alg_name:
            return False  # Already signed with this algorithm
        if not existing_path:
            try:
                existing_path = stores.lookup(digest)
                if existing_path:
                    existing_digest = digest
            except NotStored:
                pass  # OK

    if existing_path is None:
        print("No implementations of %s cached; can't calculate new digest" %
              get_version(impl))
        return False

    info("Verifying %s", existing_path)
    manifest.verify(existing_path, existing_digest)

    print("Adding new digest to version %s" % get_version(impl))

    new_digest = alg.new_digest()
    for line in alg.generate_manifest(existing_path):
        new_digest.update((line + '\n').encode())

    for md in xmltools.children(impl, 'manifest-digest'):
        break
    else:
        md = xmltools.create_element(impl, 'manifest-digest')
    _, digest_value = manifest.splitID(alg.getID(new_digest))
    md.setAttribute(alg_name, digest_value)

    return True
示例#16
0
    def testImplementationGenerateMissingId(self):
        old_out = sys.stdout
        try:
            sys.stdout = StringIO()
            self.child = server.handle_requests(('HelloWorld.tgz'))

            from zeroinstall.zerostore import manifest
            alg = manifest.get_algorithm('sha1')
            assert alg

            from zeroinstall.injector.reader import load_feed
            feed = load_feed(os.path.abspath('ImplementationNoId.xml'), True,
                             False, False, alg, self.config)

            expected_id = 'sha1=3ce644dc725f1d21cfcf02562c76f375944b266a'
            assert feed.implementations[expected_id]
            assert feed.implementations[expected_id].id == expected_id
        finally:
            sys.stdout = old_out
示例#17
0
	def check_manifest_and_rename(self, required_digest, unpack_dir, dry_run = False):
		implementation = self.impl

		sha1new = get_digest(unpack_dir, 'sha1new')
		if not implementation.getAttribute('id'):
			implementation.setAttribute('id', sha1new)
		digests = [sha1new]

		def add_digest(alg_name):
			digest_id = get_digest(unpack_dir, alg_name)
			digests.append(digest_id)
			name, value = zerostore.parse_algorithm_digest_pair(digest_id)
			elem.setAttribute(alg_name, value)

		have_manifest_elem = False
		for elem in implementation.getElementsByTagNameNS(namespaces.XMLNS_IFACE, 'manifest-digest'):
			have_manifest_elem = True
			have_digests = False
			for attr_name, value in elem.attributes.items():
				if value: continue
				add_digest(attr_name)
				have_digests = True
			if not have_digests:
				add_digest('sha256new')
		if not have_manifest_elem:
			print("WARNING: no <manifest-digest> element found")

		best_rating = -1
		best_digest = None
		for digest_id in digests:
			alg_name, value = zerostore.parse_algorithm_digest_pair(digest_id)
			alg = manifest.get_algorithm(alg_name)
			if alg.rating > best_rating:
				best_rating = alg.rating
				best_digest = digest_id

		# Cache if necessary (saves downloading it again later)
		stores = self.real_stores
		if stores.lookup_maybe(digests) is None:
			stores.add_dir_to_cache(best_digest, unpack_dir)
示例#18
0
def add_digest(impl, alg_name):
	alg = manifest.get_algorithm(alg_name)
	
	# Scan through the existing digests
	# - If we've already got the one we need, return
	# - Otherwise, find a cached implementation we can use
	existing_path = None
	for a, value in digests(impl):
		digest = '%s=%s' % (a, value)
		if a == alg_name:
			return False			# Already signed with this algorithm
		if not existing_path:
			try:
				existing_path = stores.lookup(digest)
				if existing_path:
					existing_digest = digest
			except NotStored:
				pass		# OK

	if existing_path is None:
		print "No implementations of %s cached; can't calculate new digest" % get_version(impl)
		return False

	info("Verifying %s", existing_path)
	manifest.verify(existing_path, existing_digest)

	print "Adding new digest to version %s" % get_version(impl)

	new_digest = alg.new_digest()
	for line in alg.generate_manifest(existing_path):
		new_digest.update(line + '\n')

	for md in xmltools.children(impl, 'manifest-digest'):
		break
	else:
		md = xmltools.create_element(impl, 'manifest-digest')
	md.setAttribute(alg_name, new_digest.hexdigest())

	return True
	def testUnknownAlgorithm(self):
		try:
			manifest.get_algorithm('unknown')
			assert False
		except BadDigest:
			pass
示例#20
0
	def create_archive_element(self, url, mime_type, root, extract, size, start_offset):
		alg = manifest.get_algorithm('sha1new')
		digest = alg.new_digest()
		for line in alg.generate_manifest(root):
			digest.update(line + '\n')
		id = alg.getID(digest)

		# Add it to the cache if missing
		# Helps with setting 'main' attribute later
		try:
			main.stores.lookup(id)
		except NotStored:
			main.stores.add_dir_to_cache(id, root)

		# Do we already have an implementation with this digest?
		impl_element = self.feed_editor.find_implementation(id)

		if impl_element is None:
			# No. Create a new implementation. Guess the details...

			leaf = url.split('/')[-1]
			version = None
			for m in re.finditer(version_regexp, leaf):
				match = m.group()[1:]
				if version is None or len(version) < len(match):
					version = match

			existing_versions = self.feed_editor.list_versions()
			older_versions = []
			if existing_versions and version:
				parsed_version = try_parse_version(version)
				if parsed_version:
					older_versions = [(v, elem) for v, elem in existing_versions if v < parsed_version]

			impl_element = self.feed_editor.doc.createElementNS(XMLNS_INTERFACE, 'implementation')

			if older_versions:
				# Try to add it just after the previous version's element in the XML document
				insert_after(impl_element, max(older_versions)[1])
			elif existing_versions:
				# Else add it before the first
				insert_before(impl_element, min(existing_versions)[1])
			else:
				# Put it in the root
				insert_element(impl_element, self.feed_editor.doc.documentElement)

			impl_element.setAttribute('id', id)
			impl_element.setAttribute('released', time.strftime('%Y-%m-%d'))
			if version: impl_element.setAttribute('version', version)
			created_impl = True
		else:
			created_impl = False

		archive_element = create_element(impl_element, 'archive')
		archive_element.setAttribute('size', str(size))
		archive_element.setAttribute('href', url)
		if extract: archive_element.setAttribute('extract', extract)
		if mime_type: archive_element.setAttribute('type', mime_type)
		if start_offset: archive_element.setAttribute('start-offset', str(start_offset))

		self.feed_editor.update_version_model()

		if created_impl:
			self.feed_editor.edit_properties(element = impl_element)
示例#21
0
 def testUnknownAlgorithm(self):
     try:
         manifest.get_algorithm('unknown')
         assert False
     except BadDigest:
         pass