cros_sdk: check for certificate errors, give appropriate message

Also, provides a --no-check-certificate option that allows overriding
the behaviour.

Note that this also silences the stderr from the first 'probe' curl
run, eliminating the first and useless curl output.

BUG=chromium-os:25517
TEST=cros_sdk --chroot x --replace (and see it work)
TEST=manually provide an incorrect command and check its handling

Change-Id: Icf048366ade67dde003723c374e5207a8b2ce7a6
Reviewed-on: https://gerrit.chromium.org/gerrit/19643
Tested-by: Zdenek Behan <zbehan@chromium.org>
Reviewed-by: Mike Frysinger <vapier@chromium.org>
Commit-Ready: Zdenek Behan <zbehan@chromium.org>
diff --git a/scripts/cros_sdk.py b/scripts/cros_sdk.py
index 29ae320..848058a 100644
--- a/scripts/cros_sdk.py
+++ b/scripts/cros_sdk.py
@@ -83,6 +83,23 @@
 
 def FetchRemoteTarball(url):
   """Fetches a tarball given by url, and place it in sdk/."""
+
+  def RunCurl(args, **kwargs):
+    """Runs curl and wraps around all necessary hacks."""
+    cmd = ['curl']
+    cmd.extend(args)
+
+    result = cros_build_lib.RunCommand(cmd, error_ok=True, **kwargs)
+    if result.returncode > 0:
+      # These are the return codes of failing certs as per 'man curl'.
+      if result.returncode in (51, 58, 60):
+        print 'Download failed with certificate error? Try "sudo c_rehash".'
+      else:
+        print 'Curl failed!'
+      sys.exit(1)
+
+    return result
+
   tarball_name = os.path.basename(urlparse.urlparse(url).path)
   tarball_dest = os.path.join(SDK_DIR, tarball_name)
 
@@ -96,23 +113,25 @@
       if os.path.isfile(f_path) and os.stat(f_path).st_uid == os.getuid():
         os.remove(f_path)
 
+  curl_opts = ['-f', '--retry', '5', '-L', '-y', '30',
+               '--output', tarball_dest]
   print 'Downloading sdk: "%s"' % url
-  cmd = ['curl', '-f', '--retry', '5', '-L', '-y', '30',
-         '--output', tarball_dest]
-
   if not url.startswith('file://') and os.path.exists(tarball_dest):
     # Only resume for remote URLs. If the file is local, there's no
     # real speedup, and using the same filename for different files
     # locally will cause issues.
-    cmd.extend(['-C', '-'])
+    curl_opts.extend(['-C', '-'])
 
     # Additionally, certain versions of curl incorrectly fail if
     # told to resume a file that is fully downloaded, thus do a
     # check on our own.
     # see:
     # https://sourceforge.net/tracker/?func=detail&atid=100976&aid=3482927&group_id=976
-    result = cros_build_lib.RunCommand(['curl', '-I', url],
-                                       redirect_stdout=True, print_cmd=False)
+    result = RunCurl(['-I', url],
+                     redirect_stdout=True,
+                     redirect_stderr=True,
+                     print_cmd=False)
+
     for x in result.output.splitlines():
       if x.lower().startswith("content-length:"):
         length = int(x.split(":", 1)[-1].strip())
@@ -121,10 +140,8 @@
           # of this (>=7.21.4 and up).
           return tarball_dest
         break
-
-  cmd.append(url)
-
-  cros_build_lib.RunCommand(cmd)
+  curl_opts.append(url)
+  RunCurl(curl_opts)
   return tarball_dest