aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason R. Coombs <jaraco@jaraco.com>2013-08-10 10:14:22 -0400
committerJason R. Coombs <jaraco@jaraco.com>2013-08-10 10:14:22 -0400
commite29ad44c0a1e8025c154c9afb4418f143019379f (patch)
tree51b54caf2fa8eea2acc1088ee8c71edffc6afdd8
parent8f7b0128ebb408b980162863eb865bf9e6e3ce22 (diff)
downloadexternal_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.py75
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)