From 77006d8a254f9a724c33d03cfc247c93e99bc5a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filipe=20La=C3=ADns?= Date: Thu, 28 May 2020 20:11:17 +0100 Subject: [PATCH] install: validate checksums MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Filipe LaĆ­ns --- README.md | 9 +++++---- install/__init__.py | 17 +++++++++++++++++ 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 13845aa..1ee258c 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,6 @@ optional arguments: ``` Missing components: - - Checksum verification - Custom data installation: - `headers` - `data` @@ -32,6 +31,8 @@ Missing components: ### Bootstraping `install` has a dependency on `installer`, which is used for entrypoint script -generation. As we don't install entrypoint scripts, this dependency is not needed -to install a `install` wheel, making `install` bootstrapable without any -dependencies. +generation and checksum validation. As we don't install entrypoint scripts, +this dependency is not needed to install a `install` wheel, making `install` +bootstrapable without any dependencies. The only thing is that you won't get the +checksum validation, but if you are building from source that shouldn't be a +problem. diff --git a/install/__init__.py b/install/__init__.py index 1a5ce2f..626f5a2 100644 --- a/install/__init__.py +++ b/install/__init__.py @@ -92,6 +92,21 @@ def _copy_dir(src, dst, ignore=[]): # type: (str, str, List[str]) -> None shutil.copy2(path, root) +def _validate_checksums(dist_info, dir): # type: (str, str) -> None + try: + import installer.records + + with open(os.path.join(dist_info, 'RECORD'), 'r') as f: + lines = [line.strip() for line in f] + + for record in installer.records.parse_record_file(lines): + with open(os.path.join(dir, record.path.as_posix()), 'rb') as fr: + if not record.validate(fr.read()): + raise InstallException('Invalid checksum: {}'.format(record)) + except ImportError: + warnings.warn("'installer' package missing, skipping checksum verification", RuntimeWarning) + + def _generate_entrypoint_scripts(file, dir): # type: (str, str) -> None entrypoints = configparser.ConfigParser() entrypoints.read(file) @@ -228,6 +243,8 @@ def build(wheel, cache_dir, optimize=[0, 1, 2], verify_dependencies=False): # t elif optimize: compileall.compile_dir(pkg_cache_dir) + _validate_checksums(dist_info, pkg_cache_dir) + if os.path.isfile(entrypoints_file): _generate_entrypoint_scripts(entrypoints_file, scripts_cache_dir)