diff --git a/cf_remote/commands.py b/cf_remote/commands.py index 3d3f90b..7712d74 100644 --- a/cf_remote/commands.py +++ b/cf_remote/commands.py @@ -296,7 +296,7 @@ def _iterate_over_packages(tags=None, version=None, edition=None, download=False else: for artifact in artifacts: if download: - download_package(artifact.url) + download_package(artifact.url, checksum=artifact.data.get("SHA256")) else: print(artifact.url) return 0 diff --git a/cf_remote/web.py b/cf_remote/web.py index 6d060f7..35878ec 100644 --- a/cf_remote/web.py +++ b/cf_remote/web.py @@ -1,12 +1,15 @@ +import hashlib import os import fcntl +import re import urllib.request import json from collections import OrderedDict -from cf_remote.utils import write_json, mkdir, parse_json +from cf_remote.utils import file_sha256, user_error, write_json, mkdir, parse_json from cf_remote import log from cf_remote.paths import cf_remote_dir, cf_remote_packages_dir +SHA256_RE = re.compile(r"^[0-9a-f]{64}$") def get_json(url): with urllib.request.urlopen(url) as r: @@ -22,7 +25,14 @@ def get_json(url): return data -def download_package(url, path=None): +def download_package(url, path=None, checksum=None): + + if not checksum : + user_error("No checksum found") + + if not SHA256_RE.match(checksum): + user_error("Invalid checksum or unsupported checksum algorithm: '%s'" % checksum) + if not path: filename = os.path.basename(url) directory = cf_remote_packages_dir() @@ -40,8 +50,16 @@ def download_package(url, path=None): log.debug("Package '{}' already downloaded".format(path)) else: print("Downloading package: '{}'".format(path)) - f.write(urllib.request.urlopen(url).read()) - f.flush() + + answer = urllib.request.urlopen(url).read() + digest = hashlib.sha256(answer).digest().hex() + + if checksum == digest : + f.write(answer) + f.flush() + else : + user_error("Mismatching checksums") + fcntl.flock(f.fileno(), fcntl.LOCK_UN) return path