Index: pym/portage/dbapi/porttree.py =================================================================== --- pym/portage/dbapi/porttree.py (revision 11034) +++ pym/portage/dbapi/porttree.py (working copy) @@ -12,7 +12,7 @@ from portage.exception import OperationNotPermitted, PortageException, \ UntrustedSignature, SecurityViolation, InvalidSignature, MissingSignature, \ FileNotFound, InvalidDependString -from portage.manifest import Manifest +from portage.manifest import Manifest, MetaManifest from portage.output import red from portage.util import ensure_dirs, writemsg, apply_recursive_permissions from portage.versions import pkgcmp, pkgsplit, catpkgsplit, best, ver_regexp @@ -147,7 +147,38 @@ self._aux_cache_slot_dict = None self._aux_cache = {} self._broken_ebuilds = set() + self._metamanifests = {} + def verifyEbuild(self, repo_path, ebuild_path): + """ + Use the MetaManifest to verify the Manifest of an ebuild. This raises + an instance of SignatureException if something is wrong. + + @type repo_path: String + @param repo_path: The canonical path of the repository root. + @type ebuild_path: String + @param ebuild_path: The full path of the ebuild to verify, which must + start with the repo_path. + """ + + if "strict" not in self.mysettings.features: + return + + metamanifest = self._metamanifests.get(repo_path) + if metamanifest is None: + metamanifest = MetaManifest(repo_path, self.mysettings["DISTDIR"]) + self._metamanifests[repo_path] = metamanifest + + manifest_path = os.path.join( + os.path.dirname(ebuild_path), "Manifest") + relative_path = manifest_path[1+len(repo_path):] + try: + metamanifest.checkFileHashes("MISC", relative_path) + except KeyError: + raise MissingSignature(ebuild_path) + except FileNotFound: + raise MissingSignature(ebuild_path) + def _init_cache_dirs(self): """Create /var/cache/edb/dep and adjust permissions for the portage group.""" Index: pym/portage/__init__.py =================================================================== --- pym/portage/__init__.py (revision 11034) +++ pym/portage/__init__.py (working copy) @@ -4944,6 +4944,9 @@ global _doebuild_manifest_exempt_depend + repo_path = os.path.dirname(os.path.dirname( + os.path.dirname(myebuild))) + if "strict" in features and \ "digest" not in features and \ tree == "porttree" and \ @@ -4963,6 +4966,15 @@ noiselevel=-1) _doebuild_broken_manifests.add(manifest_path) return 1 + + try: + mydbapi.verifyEbuild(repo_path, myebuild) + except portage.exception.SignatureException, e: + writemsg("!!! Signature Exception: '%s'\n" % (e,), + noiselevel=-1) + _doebuild_broken_manifests.add(manifest_path) + return 1 + mf = Manifest(pkgdir, mysettings["DISTDIR"]) try: mf.checkTypeHashes("EBUILD") @@ -5408,9 +5420,15 @@ return 1 # See above comment about fetching only when needed - if not emerge_skip_distfiles and \ - not digestcheck(checkme, mysettings, "strict" in features): - return 1 + if not emerge_skip_distfiles: + try: + mydbapi.verifyEbuild(repo_path, myebuild) + except portage.exception.SignatureException, e: + writemsg("!!! Signature Exception: '%s'\n" % (e,), + noiselevel=-1) + return 1 + if not digestcheck(checkme, mysettings, "strict" in features): + return 1 if mydo == "fetch": return 0 Index: pym/portage/manifest.py =================================================================== --- pym/portage/manifest.py (revision 11034) +++ pym/portage/manifest.py (working copy) @@ -489,3 +489,19 @@ """Split a category and package, returning a list of [cat, pkg]. This is compatible with portage.catsplit()""" return pkg_key.split("/", 1) + +class MetaManifest(Manifest): + + def getFullname(self): + return os.path.join(self.pkgdir, "MetaManifest") + + def sign(self): + try: + ts = os.path.join(mysettings["PORTDIR"],'metadata','timestamp.x') + ts = open(ts,'r') + ts = ts.read().rstrip('\n').strip() + except EnvironmentError: + ts = 'File not available' + f = open(self.getFullname(), "a") + f.write("Timestamp: metadata/timestamp.x: "+ts+"\n") + f.close() Index: pym/_emerge/__init__.py =================================================================== --- pym/_emerge/__init__.py (revision 11035) +++ pym/_emerge/__init__.py (working copy) @@ -8525,6 +8525,14 @@ root_config = x.root_config portdb = root_config.trees["porttree"].dbapi + ebuild_path, repo_path = portdb.findname2(x.cpv) + try: + portdb.verifyEbuild(repo_path, ebuild_path) + except portage.exception.SignatureException, e: + writemsg("!!! Signature Exception: '%s'\n" % (e,), + noiselevel=-1) + return 1 + quiet_config = quiet_settings[root_config.root] quiet_config["O"] = os.path.dirname(portdb.findname(x.cpv)) if not portage.digestcheck([], quiet_config, strict=True):