about summary refs log tree commit diff
path: root/src/bootstrap
diff options
context:
space:
mode:
authorManish Goregaokar <manishsmail@gmail.com>2016-04-16 01:16:43 +0530
committerManish Goregaokar <manishsmail@gmail.com>2016-04-16 01:18:01 +0530
commit70601b8da249c789883725950ddf046070909095 (patch)
tree6d5d2e6c8fdcac432daffab3ea7c71330e473f36 /src/bootstrap
parent6a0cfbcac294faab2b8bcd95a04cda042101a2d8 (diff)
parente0f997d3477fe28c2c5d99229bd1cd0de81604b4 (diff)
Rollup merge of #32926 - caipre:rustbuild-verify-download, r=alexcrichton
rustbuild: Verify sha256 of downloaded tarballs

Here's a quick first pass at this.

I don't use Python often enough to claim that this is totally Pythonic. I've left off some (almost certainly unnecessary) error handling regarding opening and processing files. The whole tarball is read into memory to calculate the hash, but the file isn't *so* large so that should be fine. I don't care for the output from `raise RuntimeError`, but that's how `run()` does it so I'm following precedent.

Tested by manually changing the value of `expected`, and by modifying the tarball then forcing `rustc_out_of_date()`. Both cases tripped the error.

Closes https://github.com/rust-lang/rust/issues/32902
Diffstat (limited to 'src/bootstrap')
-rw-r--r--src/bootstrap/bootstrap.py53
1 files changed, 40 insertions, 13 deletions
diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py
index 5de7e6957c6..84b8ad333c1 100644
--- a/src/bootstrap/bootstrap.py
+++ b/src/bootstrap/bootstrap.py
@@ -10,6 +10,7 @@
 
 import argparse
 import contextlib
+import hashlib
 import os
 import shutil
 import subprocess
@@ -18,13 +19,29 @@ import tarfile
 
 def get(url, path, verbose=False):
     print("downloading " + url)
-    # see http://serverfault.com/questions/301128/how-to-download
-    if sys.platform == 'win32':
-        run(["PowerShell.exe", "/nologo", "-Command",
-             "(New-Object System.Net.WebClient).DownloadFile('" + url +
-                "', '" + path + "')"], verbose=verbose)
-    else:
-        run(["curl", "-o", path, url], verbose=verbose)
+    sha_url = url + ".sha256"
+    sha_path = path + ".sha256"
+    for _url, _path in ((url, path), (sha_url, sha_path)):
+        # see http://serverfault.com/questions/301128/how-to-download
+        if sys.platform == 'win32':
+            run(["PowerShell.exe", "/nologo", "-Command",
+                 "(New-Object System.Net.WebClient)"
+                 ".DownloadFile('{}', '{}')".format(_url, _path)],
+                verbose=verbose)
+        else:
+            run(["curl", "-o", _path, _url], verbose=verbose)
+    print("verifying " + path)
+    with open(path, "rb") as f:
+        found = hashlib.sha256(f.read()).hexdigest()
+    with open(sha_path, "r") as f:
+        expected, _ = f.readline().split()
+    if found != expected:
+        err = ("invalid checksum:\n"
+               "    found:    {}\n"
+               "    expected: {}".format(found, expected))
+        if verbose:
+            raise RuntimeError(err)
+        sys.exit(err)
 
 def unpack(tarball, dst, verbose=False, match=None):
     print("extracting " + tarball)
@@ -57,9 +74,10 @@ def run(args, verbose=False):
     ret = subprocess.Popen(args)
     code = ret.wait()
     if code != 0:
-        if not verbose:
-            print("failed to run: " + ' '.join(args))
-        raise RuntimeError("failed to run command")
+        err = "failed to run: " + ' '.join(args)
+        if verbose:
+            raise RuntimeError(err)
+        sys.exit(err)
 
 class RustBuild:
     def download_rust_nightly(self):
@@ -210,7 +228,10 @@ class RustBuild:
             if sys.platform == 'win32':
                 return 'x86_64-pc-windows-msvc'
             else:
-                raise
+                err = "uname not found"
+                if self.verbose:
+                    raise Exception(err)
+                sys.exit(err)
 
         # Darwin's `uname -s` lies and always returns i386. We have to use
         # sysctl instead.
@@ -253,7 +274,10 @@ class RustBuild:
                 cputype = 'x86_64'
             ostype = 'pc-windows-gnu'
         else:
-            raise ValueError("unknown OS type: " + ostype)
+            err = "unknown OS type: " + ostype
+            if self.verbose:
+                raise ValueError(err)
+            sys.exit(err)
 
         if cputype in {'i386', 'i486', 'i686', 'i786', 'x86'}:
             cputype = 'i686'
@@ -269,7 +293,10 @@ class RustBuild:
         elif cputype in {'amd64', 'x86_64', 'x86-64', 'x64'}:
             cputype = 'x86_64'
         else:
-            raise ValueError("unknown cpu type: " + cputype)
+            err = "unknown cpu type: " + cputype
+            if self.verbose:
+                raise ValueError(err)
+            sys.exit(err)
 
         return cputype + '-' + ostype