diff options
author | Jason R. Coombs <jaraco@jaraco.com> | 2013-08-10 10:14:22 -0400 |
---|---|---|
committer | Jason R. Coombs <jaraco@jaraco.com> | 2013-08-10 10:14:22 -0400 |
commit | e29ad44c0a1e8025c154c9afb4418f143019379f (patch) | |
tree | 51b54caf2fa8eea2acc1088ee8c71edffc6afdd8 | |
parent | 8f7b0128ebb408b980162863eb865bf9e6e3ce22 (diff) | |
download | external_python_setuptools-e29ad44c0a1e8025c154c9afb4418f143019379f.tar.gz external_python_setuptools-e29ad44c0a1e8025c154c9afb4418f143019379f.tar.bz2 external_python_setuptools-e29ad44c0a1e8025c154c9afb4418f143019379f.zip |
Issue #63: Initial implementation of a mechanism for securely bootstrapping setuptools, leveraging system tools for trust validation.
-rw-r--r-- | ez_setup.py | 75 |
1 files changed, 57 insertions, 18 deletions
diff --git a/ez_setup.py b/ez_setup.py index 5a5ff260..98d15f22 100644 --- a/ez_setup.py +++ b/ez_setup.py @@ -20,6 +20,7 @@ import tempfile import tarfile import optparse import subprocess +import platform from distutils import log @@ -141,6 +142,59 @@ def use_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL, return _do_download(version, download_base, to_dir, download_delay) +def download_file_powershell(url, target): + """ + Download the file at url to target using Powershell (which will validate + trust). Raise an exception if the command cannot complete. + """ + target = os.path.abspath(target) + cmd = [ + 'powershell', + '-Command', + "(new-object System.Net.WebClient).DownloadFile(%(url)r, %(target)r)" % vars(), + ] + subprocess.check_call(cmd) + +download_file_powershell.viable = ( + lambda: platform.name() == 'Windows' and platform.win32_ver()[1] >= '6' +) + +def download_file_insecure(url, target): + """ + Use Python to download the file, even though it cannot authenticate the + connection. + """ + try: + from urllib.request import urlopen + except ImportError: + from urllib2 import urlopen + src = dst = None + try: + src = urlopen(url) + # Read/write all in one block, so we don't create a corrupt file + # if the download is interrupted. + data = src.read() + dst = open(target, "wb") + dst.write(data) + finally: + if src: + src.close() + if dst: + dst.close() + +download_file_insecure.viable = lambda: True + +def get_best_downloader(): + downloaders = [ + download_file_powershell, + #download_file_curl, + #download_file_wget, + download_file_insecure, + ] + + for dl in downloaders: + if dl.viable(): + return dl def download_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir, delay=15): @@ -154,28 +208,13 @@ def download_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL, """ # making sure we use the absolute path to_dir = os.path.abspath(to_dir) - try: - from urllib.request import urlopen - except ImportError: - from urllib2 import urlopen tgz_name = "setuptools-%s.tar.gz" % version url = download_base + tgz_name saveto = os.path.join(to_dir, tgz_name) - src = dst = None if not os.path.exists(saveto): # Avoid repeated downloads - try: - log.warn("Downloading %s", url) - src = urlopen(url) - # Read/write all in one block, so we don't create a corrupt file - # if the download is interrupted. - data = src.read() - dst = open(saveto, "wb") - dst.write(data) - finally: - if src: - src.close() - if dst: - dst.close() + log.warn("Downloading %s", url) + downloader = get_best_downloader() + downloader(url, saveto) return os.path.realpath(saveto) |