Skip to content

Commit d676e52

Browse files
committed
install: validate checksums
Signed-off-by: Filipe Laíns <lains@archlinux.org>
1 parent fb7906f commit d676e52

File tree

2 files changed

+23
-5
lines changed

2 files changed

+23
-5
lines changed

README.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ Missing components:
2828
### Bootstraping
2929
3030
`install` has a dependency on `installer`, which is used for entrypoint script
31-
generation. As we don't install entrypoint scripts, this dependency is not needed
32-
to install a `install` wheel, making `install` bootstrapable without any
33-
dependencies.
31+
generation and checksum validation. As we don't install entrypoint scripts,
32+
this dependency is not needed to install a `install` wheel, making `install`
33+
bootstrapable without any dependencies. The only thing is that you won't get the
34+
checksum validation, but if you are building from source that shouldn't be a
35+
problem.

install/__init__.py

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,22 @@ def _copy_dir(src, dst, ignore=[]): # type: (str, str, List[str]) -> None
7979
_copy_dir_old(src, dst, ignore)
8080

8181

82+
def _validate_checksums(dist_info, dir): # type: (str, str) -> None
83+
try:
84+
import installer.records
85+
86+
with open(os.path.join(dist_info, 'RECORD'), 'r') as f:
87+
lines = [line.strip() for line in f]
88+
89+
for record in installer.records.parse_record_file(lines):
90+
with open(os.path.join(dir, record.path.as_posix()), 'rb') as f:
91+
if not record.validate(f.read()):
92+
raise InstallException('Invalid checksum: {}'.format(record))
93+
except ImportError:
94+
import warnings
95+
warnings.warn("'installer' package missing, skipping checksum verification", RuntimeWarning)
96+
97+
8298
def _generate_entrypoint_scripts(file, dir): # type: (str, str) -> None
8399
entrypoints = configparser.ConfigParser()
84100
entrypoints.read(file)
@@ -130,6 +146,8 @@ def build(wheel, cache_dir, optimize=[0, 1, 2]): # type: (str, str, List[int])
130146
elif optimize:
131147
compileall.compile_dir(pkg_cache_dir)
132148

149+
_validate_checksums(dist_info, pkg_cache_dir)
150+
133151
if os.path.isfile(entrypoints_file):
134152
_generate_entrypoint_scripts(entrypoints_file, scripts_cache_dir)
135153

@@ -138,8 +156,6 @@ def build(wheel, cache_dir, optimize=[0, 1, 2]): # type: (str, str, List[int])
138156
with open(os.path.join(cache_dir, 'metadata.pickle'), 'wb') as f:
139157
pickle.dump(metadata, f)
140158

141-
# TODO: verify checksums
142-
143159
# TODO: replace scripts shebang
144160
# TODO: validate platform/python tags to make sure it is compatible
145161

0 commit comments

Comments
 (0)