From 3e2729fdca18a3df8e9f1d95fb791c49e0538b49 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Sun, 10 Jul 2016 14:17:37 -0700 Subject: [PATCH 1/7] Add a rustls backend --- Cargo.lock | 38 +++ src/download/Cargo.toml | 4 + src/download/src/lib.rs | 431 ++++++++++++++++++-------- src/rustup-utils/Cargo.toml | 2 +- src/rustup-utils/src/notifications.rs | 6 +- src/rustup-utils/src/utils.rs | 7 +- 6 files changed, 358 insertions(+), 130 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index aefc5645bd..85bf427711 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -178,6 +178,7 @@ dependencies = [ "hyper 0.9.9 (registry+https://github.com/rust-lang/crates.io-index)", "native-tls 0.1.0 (git+https://github.com/sfackler/rust-native-tls.git)", "openssl-sys 0.7.14 (registry+https://github.com/rust-lang/crates.io-index)", + "rustls 0.1.0", "url 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -491,6 +492,15 @@ name = "regex-syntax" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "ring" +version = "0.1.0" +source = "git+https://github.com/ctz/ring#9a468a7ac60268f4ec64b569c32bbc12d1554f6e" +dependencies = [ + "lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "untrusted 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "rustc-serialize" version = "0.3.19" @@ -504,6 +514,18 @@ dependencies = [ "semver 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "rustls" +version = "0.1.0" +dependencies = [ + "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "ring 0.1.0 (git+https://github.com/ctz/ring)", + "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", + "untrusted 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "webpki 0.1.0 (git+https://github.com/ctz/webpki)", +] + [[package]] name = "rustup-dist" version = "0.2.0" @@ -750,6 +772,11 @@ name = "unicode-width" version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "untrusted" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "url" version = "1.1.0" @@ -805,6 +832,17 @@ dependencies = [ "winapi 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "webpki" +version = "0.1.0" +source = "git+https://github.com/ctz/webpki#c257d386d974ad5c1585984f7772ecbe3cff429f" +dependencies = [ + "ring 0.1.0 (git+https://github.com/ctz/ring)", + "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", + "untrusted 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "winapi" version = "0.2.7" diff --git a/src/download/Cargo.toml b/src/download/Cargo.toml index f8efc5fb33..debc5f3480 100644 --- a/src/download/Cargo.toml +++ b/src/download/Cargo.toml @@ -12,6 +12,7 @@ default = ["hyper-mode", "curl-mode"] curl-mode = ["curl"] hyper-mode = ["hyper", "native-tls", "openssl-sys"] +rustls-mode = ["hyper", "rustls"] [dependencies] error-chain = "0.2.1" @@ -33,3 +34,6 @@ optional = true [target.'cfg(not(any(target_os = "windows", target_os = "macos")))'.dependencies] openssl-sys = { version = "0.7.11", optional = true } +[dependencies.rustls] +path = "../../../rustls" +optional = true diff --git a/src/download/src/lib.rs b/src/download/src/lib.rs index 8367c2ad24..c9e17aa0c0 100644 --- a/src/download/src/lib.rs +++ b/src/download/src/lib.rs @@ -131,157 +131,306 @@ pub mod hyper { extern crate native_tls; use super::Event; - use std::fs; use std::io; use std::time::Duration; use url::Url; use errors::*; + use hyper_base; + use self::hyper::error::Result as HyperResult; + use self::hyper::net::{SslClient, NetworkStream}; + use std::io::Result as IoResult; + use std::io::{Read, Write}; + use std::net::{SocketAddr, Shutdown}; + use std::sync::{Arc, Mutex}; - fn proxy_from_env(url: &Url) -> Option<(String, u16)> { - use std::env::var_os; + pub fn download(url: &Url, + callback: &Fn(Event) -> Result<()>) + -> Result<()> { + hyper_base::download::(url, callback) + } - let mut maybe_https_proxy = var_os("https_proxy").map(|ref v| v.to_str().unwrap_or("").to_string()); - if maybe_https_proxy.is_none() { - maybe_https_proxy = var_os("HTTPS_PROXY").map(|ref v| v.to_str().unwrap_or("").to_string()); + struct NativeSslClient; + + impl hyper_base::NewSslClient for NativeSslClient { + fn new() -> Self { NativeSslClient } + fn maybe_init_certs() { maybe_init_certs() } + } + + impl SslClient for NativeSslClient { + type Stream = NativeSslStream; + + fn wrap_client(&self, stream: T, host: &str) -> HyperResult { + use self::native_tls::ClientBuilder as TlsClientBuilder; + use self::hyper::error::Error as HyperError; + + let mut ssl_builder = try!(TlsClientBuilder::new() + .map_err(|e| HyperError::Ssl(Box::new(e)))); + let ssl_stream = try!(ssl_builder.handshake(host, stream) + .map_err(|e| HyperError::Ssl(Box::new(e)))); + + Ok(NativeSslStream(Arc::new(Mutex::new(ssl_stream)))) } - let maybe_http_proxy = var_os("http_proxy").map(|ref v| v.to_str().unwrap_or("").to_string()); - let mut maybe_all_proxy = var_os("all_proxy").map(|ref v| v.to_str().unwrap_or("").to_string()); - if maybe_all_proxy.is_none() { - maybe_all_proxy = var_os("ALL_PROXY").map(|ref v| v.to_str().unwrap_or("").to_string()); + } + + #[derive(Clone)] + struct NativeSslStream(Arc>>); + + #[derive(Debug)] + struct NativeSslPoisonError; + + impl ::std::error::Error for NativeSslPoisonError { + fn description(&self) -> &str { "mutex poisoned during TLS operation" } + } + + impl ::std::fmt::Display for NativeSslPoisonError { + fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::result::Result<(), ::std::fmt::Error> { + f.write_str(::std::error::Error::description(self)) } - if let Some(url_value) = match url.scheme() { - "https" => maybe_https_proxy.or(maybe_http_proxy.or(maybe_all_proxy)), - "http" => maybe_http_proxy.or(maybe_all_proxy), - _ => maybe_all_proxy, - } { - if let Ok(proxy_url) = Url::parse(&url_value) { - if let Some(host) = proxy_url.host_str() { - let port = proxy_url.port().unwrap_or(8080); - return Some((host.to_string(), port)); - } - } + } + + impl NetworkStream for NativeSslStream + where T: NetworkStream + { + fn peer_addr(&mut self) -> IoResult { + self.0.lock() + .map_err(|_| io::Error::new(io::ErrorKind::Other, NativeSslPoisonError)) + .and_then(|mut t| t.get_mut().peer_addr()) + } + fn set_read_timeout(&self, dur: Option) -> IoResult<()> { + self.0.lock() + .map_err(|_| io::Error::new(io::ErrorKind::Other, NativeSslPoisonError)) + .and_then(|t| t.get_ref().set_read_timeout(dur)) + } + fn set_write_timeout(&self, dur: Option) -> IoResult<()> { + self.0.lock() + .map_err(|_| io::Error::new(io::ErrorKind::Other, NativeSslPoisonError)) + .and_then(|t| t.get_ref().set_write_timeout(dur)) + } + fn close(&mut self, how: Shutdown) -> IoResult<()> { + self.0.lock() + .map_err(|_| io::Error::new(io::ErrorKind::Other, NativeSslPoisonError)) + .and_then(|mut t| t.get_mut().close(how)) + } + } + + impl Read for NativeSslStream + where T: Read + Write + { + fn read(&mut self, buf: &mut [u8]) -> IoResult { + self.0.lock() + .map_err(|_| io::Error::new(io::ErrorKind::Other, NativeSslPoisonError)) + .and_then(|mut t| t.read(buf)) } - None } + impl Write for NativeSslStream + where T: Read + Write + { + fn write(&mut self, buf: &[u8]) -> IoResult { + self.0.lock() + .map_err(|_| io::Error::new(io::ErrorKind::Other, NativeSslPoisonError)) + .and_then(|mut t| t.write(buf)) + } + fn flush(&mut self) -> IoResult<()> { + self.0.lock() + .map_err(|_| io::Error::new(io::ErrorKind::Other, NativeSslPoisonError)) + .and_then(|mut t| t.flush()) + } + } + + // Tell our statically-linked OpenSSL where to find root certs + // cc https://github.com/alexcrichton/git2-rs/blob/master/libgit2-sys/lib.rs#L1267 + #[cfg(not(any(target_os = "windows", target_os = "macos")))] + fn maybe_init_certs() { + use std::sync::{Once, ONCE_INIT}; + static INIT: Once = ONCE_INIT; + INIT.call_once(|| { + openssl_sys::probe::init_ssl_cert_env_vars(); + }); + } + + #[cfg(any(target_os = "windows", target_os = "macos"))] + fn maybe_init_certs() { } +} + +/// Download via hyper; encrypt with rustls +#[cfg(feature = "rustls-mode")] +pub mod rustls { + + extern crate hyper; + extern crate rustls; + + use super::Event; + use std::io; + use std::time::Duration; + use url::Url; + use errors::*; + use hyper_base; + use self::hyper::error::Result as HyperResult; + use self::hyper::net::{SslClient, NetworkStream}; + use std::io::Result as IoResult; + use std::io::{Read, Write}; + use std::net::{SocketAddr, Shutdown}; + use std::sync::{Arc, Mutex}; + pub fn download(url: &Url, callback: &Fn(Event) -> Result<()>) -> Result<()> { + hyper_base::download::(url, callback) + } - // Short-circuit hyper for the "file:" URL scheme - if try!(download_from_file_url(url, callback)) { - return Ok(()); + struct NativeSslClient; + + impl hyper_base::NewSslClient for NativeSslClient { + fn new() -> Self { NativeSslClient } + fn maybe_init_certs() { } + } + + impl SslClient for NativeSslClient { + type Stream = NativeSslStream; + + fn wrap_client(&self, stream: T, host: &str) -> HyperResult { + let config = rustls::ClientConfig::new(); + // todo init certs + let config = Arc::new(config); + let tls_client = rustls::ClientSession::new(&config, host); + + Ok(NativeSslStream(Arc::new(Mutex::new((stream, tls_client))))) } + } - use self::hyper::client::{Client, ProxyConfig}; - use self::hyper::error::Result as HyperResult; - use self::hyper::header::ContentLength; - use self::hyper::net::{SslClient, NetworkStream, HttpsConnector}; - use std::io::Result as IoResult; - use std::io::{Read, Write}; - use std::net::{SocketAddr, Shutdown}; - use std::sync::{Arc, Mutex}; + #[derive(Clone)] + struct NativeSslStream(Arc>); - // The Hyper HTTP client - let client; + #[derive(Debug)] + struct NativeSslPoisonError; - let maybe_proxy = proxy_from_env(url); - if url.scheme() == "https" { + impl ::std::error::Error for NativeSslPoisonError { + fn description(&self) -> &str { "mutex poisoned during TLS operation" } + } + + impl ::std::fmt::Display for NativeSslPoisonError { + fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::result::Result<(), ::std::fmt::Error> { + f.write_str(::std::error::Error::description(self)) + } + } + + impl NetworkStream for NativeSslStream + where T: NetworkStream + { + fn peer_addr(&mut self) -> IoResult { + self.0.lock() + .map_err(|_| io::Error::new(io::ErrorKind::Other, NativeSslPoisonError)) + .and_then(|mut t| t.0.peer_addr()) + } + fn set_read_timeout(&self, dur: Option) -> IoResult<()> { + self.0.lock() + .map_err(|_| io::Error::new(io::ErrorKind::Other, NativeSslPoisonError)) + .and_then(|t| t.0.set_read_timeout(dur)) + } + fn set_write_timeout(&self, dur: Option) -> IoResult<()> { + self.0.lock() + .map_err(|_| io::Error::new(io::ErrorKind::Other, NativeSslPoisonError)) + .and_then(|t| t.0.set_write_timeout(dur)) + } + fn close(&mut self, how: Shutdown) -> IoResult<()> { + self.0.lock() + .map_err(|_| io::Error::new(io::ErrorKind::Other, NativeSslPoisonError)) + .and_then(|mut t| t.0.close(how)) + } + } - // All the following is adapter code to use native_tls with hyper. + impl Read for NativeSslStream + where T: Read + Write + { + fn read(&mut self, buf: &mut [u8]) -> IoResult { + self.0.lock() + .map_err(|_| io::Error::new(io::ErrorKind::Other, NativeSslPoisonError)) + .and_then(|mut t| { + let (ref mut stream, ref mut tls) = *t; + while tls.wants_read() { + tls.read_tls(stream).unwrap(); // FIXME + tls.process_new_packets().unwrap(); // FIXME + } - struct NativeSslClient; + tls.read(buf) + }) + } + } - impl SslClient for NativeSslClient { - type Stream = NativeSslStream; + impl Write for NativeSslStream + where T: Read + Write + { + fn write(&mut self, buf: &[u8]) -> IoResult { + self.0.lock() + .map_err(|_| io::Error::new(io::ErrorKind::Other, NativeSslPoisonError)) + .and_then(|mut t| { + let (ref mut stream, ref mut tls) = *t; - fn wrap_client(&self, stream: T, host: &str) -> HyperResult { - use self::native_tls::ClientBuilder as TlsClientBuilder; - use self::hyper::error::Error as HyperError; + let res = tls.write(buf); - let mut ssl_builder = try!(TlsClientBuilder::new() - .map_err(|e| HyperError::Ssl(Box::new(e)))); - let ssl_stream = try!(ssl_builder.handshake(host, stream) - .map_err(|e| HyperError::Ssl(Box::new(e)))); + while tls.wants_write() { + tls.write_tls(stream).unwrap(); // FIXME + } - Ok(NativeSslStream(Arc::new(Mutex::new(ssl_stream)))) - } - } + res + }) + } + fn flush(&mut self) -> IoResult<()> { + self.0.lock() + .map_err(|_| io::Error::new(io::ErrorKind::Other, NativeSslPoisonError)) + .and_then(|mut t| { + t.0.flush() + }) + } + } - #[derive(Clone)] - struct NativeSslStream(Arc>>); +} - #[derive(Debug)] - struct NativeSslPoisonError; +#[cfg(feature = "hyper")] +pub mod hyper_base { - impl ::std::error::Error for NativeSslPoisonError { - fn description(&self) -> &str { "mutex poisoned during TLS operation" } - } + extern crate hyper; - impl ::std::fmt::Display for NativeSslPoisonError { - fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::result::Result<(), ::std::fmt::Error> { - f.write_str(::std::error::Error::description(self)) - } - } + use super::Event; + use std::io; + use url::Url; + use errors::*; + use self::hyper::net::{SslClient, HttpStream}; - impl NetworkStream for NativeSslStream - where T: NetworkStream - { - fn peer_addr(&mut self) -> IoResult { - self.0.lock() - .map_err(|_| io::Error::new(io::ErrorKind::Other, NativeSslPoisonError)) - .and_then(|mut t| t.get_mut().peer_addr()) - } - fn set_read_timeout(&self, dur: Option) -> IoResult<()> { - self.0.lock() - .map_err(|_| io::Error::new(io::ErrorKind::Other, NativeSslPoisonError)) - .and_then(|t| t.get_ref().set_read_timeout(dur)) - } - fn set_write_timeout(&self, dur: Option) -> IoResult<()> { - self.0.lock() - .map_err(|_| io::Error::new(io::ErrorKind::Other, NativeSslPoisonError)) - .and_then(|t| t.get_ref().set_write_timeout(dur)) - } - fn close(&mut self, how: Shutdown) -> IoResult<()> { - self.0.lock() - .map_err(|_| io::Error::new(io::ErrorKind::Other, NativeSslPoisonError)) - .and_then(|mut t| t.get_mut().close(how)) - } - } + pub trait NewSslClient { + fn new() -> Self; + fn maybe_init_certs(); + } - impl Read for NativeSslStream - where T: Read + Write - { - fn read(&mut self, buf: &mut [u8]) -> IoResult { - self.0.lock() - .map_err(|_| io::Error::new(io::ErrorKind::Other, NativeSslPoisonError)) - .and_then(|mut t| t.read(buf)) - } - } + pub fn download(url: &Url, + callback: &Fn(Event) -> Result<()>) + -> Result<()> + where S: SslClient + NewSslClient + Send + Sync + 'static, + { - impl Write for NativeSslStream - where T: Read + Write - { - fn write(&mut self, buf: &[u8]) -> IoResult { - self.0.lock() - .map_err(|_| io::Error::new(io::ErrorKind::Other, NativeSslPoisonError)) - .and_then(|mut t| t.write(buf)) - } - fn flush(&mut self) -> IoResult<()> { - self.0.lock() - .map_err(|_| io::Error::new(io::ErrorKind::Other, NativeSslPoisonError)) - .and_then(|mut t| t.flush()) - } - } + // Short-circuit hyper for the "file:" URL scheme + if try!(download_from_file_url(url, callback)) { + return Ok(()); + } - maybe_init_certs(); + use self::hyper::client::{Client, ProxyConfig}; + use self::hyper::header::ContentLength; + use self::hyper::net::{HttpsConnector}; + // The Hyper HTTP client + let client; + + S::maybe_init_certs(); + + let maybe_proxy = proxy_from_env(url); + if url.scheme() == "https" { if maybe_proxy.is_none() { // Connect with hyper + native_tls - client = Client::with_connector(HttpsConnector::new(NativeSslClient)); + client = Client::with_connector(HttpsConnector::new(S::new())); } else { let proxy_host_port = maybe_proxy.unwrap(); - client = Client::with_proxy_config(ProxyConfig(proxy_host_port.0, proxy_host_port.1, NativeSslClient)); + client = Client::with_proxy_config(ProxyConfig(proxy_host_port.0, proxy_host_port.1, S::new())); } } else if url.scheme() == "http" { if maybe_proxy.is_none() { @@ -319,23 +468,40 @@ pub mod hyper { } } - // Tell our statically-linked OpenSSL where to find root certs - // cc https://github.com/alexcrichton/git2-rs/blob/master/libgit2-sys/lib.rs#L1267 - #[cfg(not(any(target_os = "windows", target_os = "macos")))] - fn maybe_init_certs() { - use std::sync::{Once, ONCE_INIT}; - static INIT: Once = ONCE_INIT; - INIT.call_once(|| { - openssl_sys::probe::init_ssl_cert_env_vars(); - }); - } + fn proxy_from_env(url: &Url) -> Option<(String, u16)> { + use std::env::var_os; - #[cfg(any(target_os = "windows", target_os = "macos"))] - fn maybe_init_certs() { } + let mut maybe_https_proxy = var_os("https_proxy").map(|ref v| v.to_str().unwrap_or("").to_string()); + if maybe_https_proxy.is_none() { + maybe_https_proxy = var_os("HTTPS_PROXY").map(|ref v| v.to_str().unwrap_or("").to_string()); + } + let maybe_http_proxy = var_os("http_proxy").map(|ref v| v.to_str().unwrap_or("").to_string()); + let mut maybe_all_proxy = var_os("all_proxy").map(|ref v| v.to_str().unwrap_or("").to_string()); + if maybe_all_proxy.is_none() { + maybe_all_proxy = var_os("ALL_PROXY").map(|ref v| v.to_str().unwrap_or("").to_string()); + } + if let Some(url_value) = match url.scheme() { + "https" => maybe_https_proxy.or(maybe_http_proxy.or(maybe_all_proxy)), + "http" => maybe_http_proxy.or(maybe_all_proxy), + _ => maybe_all_proxy, + } { + if let Ok(proxy_url) = Url::parse(&url_value) { + if let Some(host) = proxy_url.host_str() { + let port = proxy_url.port().unwrap_or(8080); + return Some((host.to_string(), port)); + } + } + } + None + } fn download_from_file_url(url: &Url, callback: &Fn(Event) -> Result<()>) -> Result { + + use std::fs; + use std::io; + // The file scheme is mostly for use by tests to mock the dist server if url.scheme() == "file" { let src = try!(url.to_file_path() @@ -364,6 +530,7 @@ pub mod hyper { Ok(false) } } + } #[cfg(not(feature = "curl-mode"))] @@ -393,3 +560,17 @@ pub mod hyper { Err(ErrorKind::BackendUnavailable("hyper").into()) } } + +#[cfg(not(feature = "rustls-mode"))] +pub mod rustls { + + use errors::*; + use url::Url; + use super::Event; + + pub fn download(_url: &Url, + _callback: &Fn(Event) -> Result<()> ) + -> Result<()> { + Err(ErrorKind::BackendUnavailable("rustls").into()) + } +} diff --git a/src/rustup-utils/Cargo.toml b/src/rustup-utils/Cargo.toml index 1adc1098c7..1f958ed291 100644 --- a/src/rustup-utils/Cargo.toml +++ b/src/rustup-utils/Cargo.toml @@ -20,7 +20,7 @@ rustc-serialize = "0.3.19" sha2 = "0.1.2" url = "1.1" toml = "0.1.27" -download = { path = "../download" } +download = { path = "../download", features = ["rustls-mode"] } [target."cfg(windows)".dependencies] winapi = "0.2.4" diff --git a/src/rustup-utils/src/notifications.rs b/src/rustup-utils/src/notifications.rs index 08f4a5016d..ec1d3820a5 100644 --- a/src/rustup-utils/src/notifications.rs +++ b/src/rustup-utils/src/notifications.rs @@ -21,6 +21,7 @@ pub enum Notification<'a> { NoCanonicalPath(&'a Path), UsingCurl, UsingHyper, + UsingRustls, } impl<'a> Notification<'a> { @@ -34,7 +35,7 @@ impl<'a> Notification<'a> { DownloadContentLengthReceived(_) | DownloadDataReceived(_) | DownloadFinished | - UsingCurl | UsingHyper => NotificationLevel::Verbose, + UsingCurl | UsingHyper | UsingRustls => NotificationLevel::Verbose, NoCanonicalPath(_) => NotificationLevel::Warn, } } @@ -58,7 +59,8 @@ impl<'a> Display for Notification<'a> { DownloadFinished => write!(f, "download finished"), NoCanonicalPath(path) => write!(f, "could not canonicalize path: '{}'", path.display()), UsingCurl => write!(f, "downloading with curl"), - UsingHyper => write!(f, "downloading with hyper"), + UsingHyper => write!(f, "downloading with hyper + native_tls"), + UsingRustls => write!(f, "downloading with hyper + rustls"), } } } diff --git a/src/rustup-utils/src/utils.rs b/src/rustup-utils/src/utils.rs index dbb46dccb1..1fe9fb8f42 100644 --- a/src/rustup-utils/src/utils.rs +++ b/src/rustup-utils/src/utils.rs @@ -176,7 +176,7 @@ fn download_file_(url: &Url, use sha2::Digest; use std::cell::RefCell; - use download::{self, Event, hyper, curl}; + use download::{self, Event, hyper, curl, rustls}; notify_handler(Notification::DownloadingFile(url, path)); @@ -216,7 +216,10 @@ fn download_file_(url: &Url, // Download the file if env::var_os("RUSTUP_USE_HYPER").is_some() { notify_handler(Notification::UsingHyper); - try!(hyper::download(url, callback)); + try!(hyper::download(url, callback)); + } else if env::var_os("RUSTUP_USE_RUSTLS").is_some() { + notify_handler(Notification::UsingRustls); + try!(rustls::download(url, callback)); } else { notify_handler(Notification::UsingCurl); try!(curl::download(url, callback)); From 3bee384031ec8498ad4ac4aecd67c7169a7bb7f8 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Sun, 10 Jul 2016 14:38:27 -0700 Subject: [PATCH 2/7] Move rustls to my branch --- Cargo.lock | 3 ++- src/download/Cargo.toml | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 85bf427711..9c850dda90 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -178,7 +178,7 @@ dependencies = [ "hyper 0.9.9 (registry+https://github.com/rust-lang/crates.io-index)", "native-tls 0.1.0 (git+https://github.com/sfackler/rust-native-tls.git)", "openssl-sys 0.7.14 (registry+https://github.com/rust-lang/crates.io-index)", - "rustls 0.1.0", + "rustls 0.1.0 (git+https://github.com/brson/rustls.git?branch=next)", "url 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -517,6 +517,7 @@ dependencies = [ [[package]] name = "rustls" version = "0.1.0" +source = "git+https://github.com/brson/rustls.git?branch=next#b386cbf92f458837df2256460f2100d4f84f514a" dependencies = [ "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "ring 0.1.0 (git+https://github.com/ctz/ring)", diff --git a/src/download/Cargo.toml b/src/download/Cargo.toml index debc5f3480..2c981d7a4f 100644 --- a/src/download/Cargo.toml +++ b/src/download/Cargo.toml @@ -35,5 +35,6 @@ optional = true openssl-sys = { version = "0.7.11", optional = true } [dependencies.rustls] -path = "../../../rustls" +git = "https://github.com/brson/rustls.git" +branch = "next" optional = true From a39d8fdcb29bbac7142a1f4c4526353b2233b94f Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Sun, 10 Jul 2016 14:55:45 -0700 Subject: [PATCH 3/7] Turn rustls off by default --- Cargo.lock | 1 + Cargo.toml | 9 +++++++++ src/download/Cargo.toml | 8 ++++---- src/download/src/lib.rs | 28 ++++++++++++++++++++++------ src/rustup-utils/Cargo.toml | 2 +- src/rustup-utils/src/utils.rs | 8 ++++---- 6 files changed, 41 insertions(+), 15 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9c850dda90..5eeef1f7f1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3,6 +3,7 @@ name = "rustup" version = "0.2.0" dependencies = [ "clap 2.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "download 0.2.0", "error-chain 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.4.15 (registry+https://github.com/rust-lang/crates.io-index)", "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index 2887ed2caf..d61e710b17 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,9 +17,18 @@ license = "MIT OR Apache-2.0" build = "build.rs" +[features] + +default = ["curl-backend", "hyper-backend"] + +curl-backend = ["download/curl-backend"] +hyper-backend = ["download/hyper-backend"] +rustls-backend = ["download/rustls-backend"] + [dependencies] rustup-dist = { path = "src/rustup-dist", version = "0.2.0" } rustup-utils = { path = "src/rustup-utils", version = "0.2.0" } +download = { path = "src/download" } error-chain = "0.2.1" clap = "2.2.4" regex = "0.1.41" diff --git a/src/download/Cargo.toml b/src/download/Cargo.toml index 2c981d7a4f..e50a4f2320 100644 --- a/src/download/Cargo.toml +++ b/src/download/Cargo.toml @@ -8,11 +8,11 @@ license = "MIT/Apache-2.0" [features] -default = ["hyper-mode", "curl-mode"] +default = ["hyper-backend"] -curl-mode = ["curl"] -hyper-mode = ["hyper", "native-tls", "openssl-sys"] -rustls-mode = ["hyper", "rustls"] +curl-backend = ["curl"] +hyper-backend = ["hyper", "native-tls", "openssl-sys"] +rustls-backend = ["hyper", "rustls"] [dependencies] error-chain = "0.2.1" diff --git a/src/download/src/lib.rs b/src/download/src/lib.rs index c9e17aa0c0..ff062c90d1 100644 --- a/src/download/src/lib.rs +++ b/src/download/src/lib.rs @@ -4,9 +4,14 @@ extern crate error_chain; extern crate url; +use url::Url; + mod errors; pub use errors::*; +#[derive(Debug)] +pub enum Backend { Curl, Hyper, Rustls } + #[derive(Debug)] pub enum Event<'a> { /// Received the Content-Length of the to-be downloaded data. @@ -15,9 +20,20 @@ pub enum Event<'a> { DownloadDataReceived(&'a [u8]), } +pub fn download_with_backend(url: &Url, + backend: Backend, + callback: &Fn(Event) -> Result<()>) + -> Result<()> { + match backend { + Backend::Curl => curl::download(url, callback), + Backend::Hyper => hyper::download(url, callback), + Backend::Rustls => rustls::download(url, callback), + } +} + /// Download via libcurl; encrypt with the native (or OpenSSl) TLS /// stack via libcurl -#[cfg(feature = "curl-mode")] +#[cfg(feature = "curl-backend")] pub mod curl { extern crate curl; @@ -122,7 +138,7 @@ pub mod curl { /// Download via hyper; encrypt with the native (or OpenSSl) TLS /// stack via native-tls -#[cfg(feature = "hyper-mode")] +#[cfg(feature = "hyper-backend")] pub mod hyper { extern crate hyper; @@ -254,7 +270,7 @@ pub mod hyper { } /// Download via hyper; encrypt with rustls -#[cfg(feature = "rustls-mode")] +#[cfg(feature = "rustls-backend")] pub mod rustls { extern crate hyper; @@ -533,7 +549,7 @@ pub mod hyper_base { } -#[cfg(not(feature = "curl-mode"))] +#[cfg(not(feature = "curl-backend"))] pub mod curl { use errors::*; @@ -547,7 +563,7 @@ pub mod curl { } } -#[cfg(not(feature = "hyper-mode"))] +#[cfg(not(feature = "hyper-backend"))] pub mod hyper { use errors::*; @@ -561,7 +577,7 @@ pub mod hyper { } } -#[cfg(not(feature = "rustls-mode"))] +#[cfg(not(feature = "rustls-backend"))] pub mod rustls { use errors::*; diff --git a/src/rustup-utils/Cargo.toml b/src/rustup-utils/Cargo.toml index 1f958ed291..1adc1098c7 100644 --- a/src/rustup-utils/Cargo.toml +++ b/src/rustup-utils/Cargo.toml @@ -20,7 +20,7 @@ rustc-serialize = "0.3.19" sha2 = "0.1.2" url = "1.1" toml = "0.1.27" -download = { path = "../download", features = ["rustls-mode"] } +download = { path = "../download" } [target."cfg(windows)".dependencies] winapi = "0.2.4" diff --git a/src/rustup-utils/src/utils.rs b/src/rustup-utils/src/utils.rs index 1fe9fb8f42..538d7a358e 100644 --- a/src/rustup-utils/src/utils.rs +++ b/src/rustup-utils/src/utils.rs @@ -176,7 +176,7 @@ fn download_file_(url: &Url, use sha2::Digest; use std::cell::RefCell; - use download::{self, Event, hyper, curl, rustls}; + use download::{self, download_with_backend, Event, Backend}; notify_handler(Notification::DownloadingFile(url, path)); @@ -216,13 +216,13 @@ fn download_file_(url: &Url, // Download the file if env::var_os("RUSTUP_USE_HYPER").is_some() { notify_handler(Notification::UsingHyper); - try!(hyper::download(url, callback)); + try!(download_with_backend(url, Backend::Hyper, callback)); } else if env::var_os("RUSTUP_USE_RUSTLS").is_some() { notify_handler(Notification::UsingRustls); - try!(rustls::download(url, callback)); + try!(download_with_backend(url, Backend::Rustls, callback)); } else { notify_handler(Notification::UsingCurl); - try!(curl::download(url, callback)); + try!(download_with_backend(url, Backend::Curl, callback)); } try!(file.borrow_mut().sync_data().chain_err(|| "unable to sync download to disk")); From 4b9266fcfeb954e73abd010aec86d54faf577cc7 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Sun, 10 Jul 2016 15:31:23 -0700 Subject: [PATCH 4/7] Begin loading the root cert store for rustls --- Cargo.lock | 1 + src/download/Cargo.toml | 8 +++----- src/download/src/lib.rs | 33 ++++++++++++++++++++++++++++++--- 3 files changed, 34 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5eeef1f7f1..ebbfa6cf7d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -177,6 +177,7 @@ dependencies = [ "curl 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "error-chain 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.9.9 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "native-tls 0.1.0 (git+https://github.com/sfackler/rust-native-tls.git)", "openssl-sys 0.7.14 (registry+https://github.com/rust-lang/crates.io-index)", "rustls 0.1.0 (git+https://github.com/brson/rustls.git?branch=next)", diff --git a/src/download/Cargo.toml b/src/download/Cargo.toml index e50a4f2320..85a2762cc9 100644 --- a/src/download/Cargo.toml +++ b/src/download/Cargo.toml @@ -12,15 +12,13 @@ default = ["hyper-backend"] curl-backend = ["curl"] hyper-backend = ["hyper", "native-tls", "openssl-sys"] -rustls-backend = ["hyper", "rustls"] +rustls-backend = ["hyper", "rustls", "lazy_static"] [dependencies] error-chain = "0.2.1" url = "1.1" - -[dependencies.curl] -version = "0.3" -optional = true +curl = { version = "0.3", optional = true } +lazy_static = { version = "0.2", optional = true } [dependencies.hyper] version = "0.9.8" diff --git a/src/download/src/lib.rs b/src/download/src/lib.rs index ff062c90d1..f6bcbf902a 100644 --- a/src/download/src/lib.rs +++ b/src/download/src/lib.rs @@ -4,6 +4,10 @@ extern crate error_chain; extern crate url; +#[cfg(feature = "rustls-backend")] +#[macro_use] +extern crate lazy_static; + use url::Url; mod errors; @@ -306,15 +310,38 @@ pub mod rustls { type Stream = NativeSslStream; fn wrap_client(&self, stream: T, host: &str) -> HyperResult { - let config = rustls::ClientConfig::new(); - // todo init certs - let config = Arc::new(config); + let config = global_config(); let tls_client = rustls::ClientSession::new(&config, host); Ok(NativeSslStream(Arc::new(Mutex::new((stream, tls_client))))) } } + fn global_config() -> Arc { + use std::fs::File; + use std::io::BufReader; + + lazy_static! { + static ref CONFIG: Arc = init(); + } + + fn init() -> Arc { + let mut config = rustls::ClientConfig::new(); + for cert in find_root_cert_paths() { + let certfile = File::open(cert).unwrap(); // FIXME + let mut reader = BufReader::new(certfile); + config.root_store.add_pem_file(&mut reader).unwrap(); // FIXME + } + Arc::new(config) + } + + CONFIG.clone() + } + + fn find_root_cert_paths() -> Vec { + panic!("FIXME: load root certs") + } + #[derive(Clone)] struct NativeSslStream(Arc>); From d41c90f314234a970a333d6cf70bf48b7d7ea085 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Sun, 10 Jul 2016 18:28:30 -0700 Subject: [PATCH 5/7] Add a `download_to_path` function to the `download` crate --- src/download/src/lib.rs | 84 +++++++++++++++++++++++++++++++++-- src/rustup-utils/src/utils.rs | 31 +++++-------- 2 files changed, 92 insertions(+), 23 deletions(-) diff --git a/src/download/src/lib.rs b/src/download/src/lib.rs index f6bcbf902a..098bd2631a 100644 --- a/src/download/src/lib.rs +++ b/src/download/src/lib.rs @@ -9,14 +9,15 @@ extern crate url; extern crate lazy_static; use url::Url; +use std::path::Path; mod errors; pub use errors::*; -#[derive(Debug)] +#[derive(Debug, Copy, Clone)] pub enum Backend { Curl, Hyper, Rustls } -#[derive(Debug)] +#[derive(Debug, Copy, Clone)] pub enum Event<'a> { /// Received the Content-Length of the to-be downloaded data. DownloadContentLengthReceived(u64), @@ -24,8 +25,43 @@ pub enum Event<'a> { DownloadDataReceived(&'a [u8]), } -pub fn download_with_backend(url: &Url, - backend: Backend, +const BACKENDS: &'static [Backend] = &[ + Backend::Curl, + Backend::Hyper, + Backend::Rustls +]; + +pub fn download(url: &Url, + callback: &Fn(Event) -> Result<()>) + -> Result<()> { + for &backend in BACKENDS { + match download_with_backend(backend, url, callback) { + Err(Error(ErrorKind::BackendUnavailable(_), _)) => (), + Err(e) => return Err(e), + Ok(()) => return Ok(()), + } + } + + Err("no working backends".into()) +} + +pub fn download_to_path(url: &Url, + path: &Path, + callback: Option<&Fn(Event) -> Result<()>>) + -> Result<()> { + for &backend in BACKENDS { + match download_to_path_with_backend(backend, url, path, callback) { + Err(Error(ErrorKind::BackendUnavailable(_), _)) => (), + Err(e) => return Err(e), + Ok(()) => return Ok(()), + } + } + + Err("no working backends".into()) +} + +pub fn download_with_backend(backend: Backend, + url: &Url, callback: &Fn(Event) -> Result<()>) -> Result<()> { match backend { @@ -35,6 +71,46 @@ pub fn download_with_backend(url: &Url, } } +pub fn download_to_path_with_backend( + backend: Backend, + url: &Url, + path: &Path, + callback: Option<&Fn(Event) -> Result<()>>) + -> Result<()> +{ + use std::cell::RefCell; + use std::fs::{self, File}; + use std::io::Write; + + || -> Result<()> { + let file = RefCell::new(try!(File::create(&path).chain_err( + || "error creating file for download"))); + + try!(download_with_backend(backend, url, &|event| { + if let Event::DownloadDataReceived(data) = event { + try!(file.borrow_mut().write_all(data) + .chain_err(|| "unable to write download to disk")); + } + match callback { + Some(cb) => cb(event), + None => Ok(()) + } + })); + + try!(file.borrow_mut().sync_data() + .chain_err(|| "unable to sync download to disk")); + + Ok(()) + }().map_err(|e| { + if path.is_file() { + // FIXME ignoring compound errors + let _ = fs::remove_file(path); + } + + e + }) +} + /// Download via libcurl; encrypt with the native (or OpenSSl) TLS /// stack via libcurl #[cfg(feature = "curl-backend")] diff --git a/src/rustup-utils/src/utils.rs b/src/rustup-utils/src/utils.rs index 538d7a358e..8df0b1bd14 100644 --- a/src/rustup-utils/src/utils.rs +++ b/src/rustup-utils/src/utils.rs @@ -176,24 +176,18 @@ fn download_file_(url: &Url, use sha2::Digest; use std::cell::RefCell; - use download::{self, download_with_backend, Event, Backend}; + use download::download_to_path_with_backend; + use download::{self, Event, Backend}; notify_handler(Notification::DownloadingFile(url, path)); - let file = RefCell::new(try!(fs::File::create(&path).chain_err( - || "error creating file for download"))); let hasher = RefCell::new(hasher); // This callback will write the download to disk and optionally // hash the contents, then forward the notification up the stack let callback: &Fn(Event) -> download::Result<()> = &|msg| { - use download::ChainErr; - match msg { Event::DownloadDataReceived(data) => { - try!(ChainErr::chain_err( - io::Write::write_all(&mut *file.borrow_mut(), data), - || "unable to write download to disk")); if let Some(ref mut h) = *hasher.borrow_mut() { h.input(data); } @@ -214,18 +208,17 @@ fn download_file_(url: &Url, }; // Download the file - if env::var_os("RUSTUP_USE_HYPER").is_some() { - notify_handler(Notification::UsingHyper); - try!(download_with_backend(url, Backend::Hyper, callback)); - } else if env::var_os("RUSTUP_USE_RUSTLS").is_some() { - notify_handler(Notification::UsingRustls); - try!(download_with_backend(url, Backend::Rustls, callback)); + let use_hyper_backend = env::var_os("RUSTUP_USE_HYPER").is_some(); + let use_rustls_backend = env::var_os("RUSTUP_USE_RUSTLS").is_some(); + let (backend, notification) = if use_hyper_backend { + (Backend::Hyper, Notification::UsingHyper) + } else if use_rustls_backend { + (Backend::Rustls, Notification::UsingRustls) } else { - notify_handler(Notification::UsingCurl); - try!(download_with_backend(url, Backend::Curl, callback)); - } - - try!(file.borrow_mut().sync_data().chain_err(|| "unable to sync download to disk")); + (Backend::Curl, Notification::UsingCurl) + }; + notify_handler(notification); + try!(download_to_path_with_backend(backend, url, path, Some(callback))); notify_handler(Notification::DownloadFinished); From a6e4e4ef79a27f6935552ab5e6e5c586856621f8 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Mon, 11 Jul 2016 13:31:44 -0700 Subject: [PATCH 6/7] Factor out lock poisoning boilerplate --- src/download/src/lib.rs | 60 ++++++++++++++++++++--------------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/src/download/src/lib.rs b/src/download/src/lib.rs index 098bd2631a..e172a5d1f0 100644 --- a/src/download/src/lib.rs +++ b/src/download/src/lib.rs @@ -237,7 +237,7 @@ pub mod hyper { use std::io::Result as IoResult; use std::io::{Read, Write}; use std::net::{SocketAddr, Shutdown}; - use std::sync::{Arc, Mutex}; + use std::sync::{Arc, Mutex, MutexGuard}; pub fn download(url: &Url, callback: &Fn(Event) -> Result<()>) @@ -284,27 +284,30 @@ pub mod hyper { } } + impl NativeSslStream { + fn lock<'a>(&'a self) -> IoResult>> { + self.0.lock() + .map_err(|_| io::Error::new(io::ErrorKind::Other, NativeSslPoisonError)) + } + } + impl NetworkStream for NativeSslStream where T: NetworkStream { fn peer_addr(&mut self) -> IoResult { - self.0.lock() - .map_err(|_| io::Error::new(io::ErrorKind::Other, NativeSslPoisonError)) + self.lock() .and_then(|mut t| t.get_mut().peer_addr()) } fn set_read_timeout(&self, dur: Option) -> IoResult<()> { - self.0.lock() - .map_err(|_| io::Error::new(io::ErrorKind::Other, NativeSslPoisonError)) + self.lock() .and_then(|t| t.get_ref().set_read_timeout(dur)) } fn set_write_timeout(&self, dur: Option) -> IoResult<()> { - self.0.lock() - .map_err(|_| io::Error::new(io::ErrorKind::Other, NativeSslPoisonError)) + self.lock() .and_then(|t| t.get_ref().set_write_timeout(dur)) } fn close(&mut self, how: Shutdown) -> IoResult<()> { - self.0.lock() - .map_err(|_| io::Error::new(io::ErrorKind::Other, NativeSslPoisonError)) + self.lock() .and_then(|mut t| t.get_mut().close(how)) } } @@ -313,8 +316,7 @@ pub mod hyper { where T: Read + Write { fn read(&mut self, buf: &mut [u8]) -> IoResult { - self.0.lock() - .map_err(|_| io::Error::new(io::ErrorKind::Other, NativeSslPoisonError)) + self.lock() .and_then(|mut t| t.read(buf)) } } @@ -323,13 +325,11 @@ pub mod hyper { where T: Read + Write { fn write(&mut self, buf: &[u8]) -> IoResult { - self.0.lock() - .map_err(|_| io::Error::new(io::ErrorKind::Other, NativeSslPoisonError)) + self.lock() .and_then(|mut t| t.write(buf)) } fn flush(&mut self) -> IoResult<()> { - self.0.lock() - .map_err(|_| io::Error::new(io::ErrorKind::Other, NativeSslPoisonError)) + self.lock() .and_then(|mut t| t.flush()) } } @@ -367,7 +367,7 @@ pub mod rustls { use std::io::Result as IoResult; use std::io::{Read, Write}; use std::net::{SocketAddr, Shutdown}; - use std::sync::{Arc, Mutex}; + use std::sync::{Arc, Mutex, MutexGuard}; pub fn download(url: &Url, callback: &Fn(Event) -> Result<()>) @@ -434,27 +434,30 @@ pub mod rustls { } } + impl NativeSslStream { + fn lock<'a>(&'a self) -> IoResult> { + self.0.lock() + .map_err(|_| io::Error::new(io::ErrorKind::Other, NativeSslPoisonError)) + } + } + impl NetworkStream for NativeSslStream where T: NetworkStream { fn peer_addr(&mut self) -> IoResult { - self.0.lock() - .map_err(|_| io::Error::new(io::ErrorKind::Other, NativeSslPoisonError)) + self.lock() .and_then(|mut t| t.0.peer_addr()) } fn set_read_timeout(&self, dur: Option) -> IoResult<()> { - self.0.lock() - .map_err(|_| io::Error::new(io::ErrorKind::Other, NativeSslPoisonError)) + self.lock() .and_then(|t| t.0.set_read_timeout(dur)) } fn set_write_timeout(&self, dur: Option) -> IoResult<()> { - self.0.lock() - .map_err(|_| io::Error::new(io::ErrorKind::Other, NativeSslPoisonError)) + self.lock() .and_then(|t| t.0.set_write_timeout(dur)) } fn close(&mut self, how: Shutdown) -> IoResult<()> { - self.0.lock() - .map_err(|_| io::Error::new(io::ErrorKind::Other, NativeSslPoisonError)) + self.lock() .and_then(|mut t| t.0.close(how)) } } @@ -463,8 +466,7 @@ pub mod rustls { where T: Read + Write { fn read(&mut self, buf: &mut [u8]) -> IoResult { - self.0.lock() - .map_err(|_| io::Error::new(io::ErrorKind::Other, NativeSslPoisonError)) + self.lock() .and_then(|mut t| { let (ref mut stream, ref mut tls) = *t; while tls.wants_read() { @@ -481,8 +483,7 @@ pub mod rustls { where T: Read + Write { fn write(&mut self, buf: &[u8]) -> IoResult { - self.0.lock() - .map_err(|_| io::Error::new(io::ErrorKind::Other, NativeSslPoisonError)) + self.lock() .and_then(|mut t| { let (ref mut stream, ref mut tls) = *t; @@ -496,8 +497,7 @@ pub mod rustls { }) } fn flush(&mut self) -> IoResult<()> { - self.0.lock() - .map_err(|_| io::Error::new(io::ErrorKind::Other, NativeSslPoisonError)) + self.lock() .and_then(|mut t| { t.0.flush() }) From ff66ed4fb4b75893f931b3071df11510d3efd137 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Mon, 11 Jul 2016 13:35:41 -0700 Subject: [PATCH 7/7] Upse ctz's rustls repo again --- Cargo.lock | 4 ++-- src/download/Cargo.toml | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ebbfa6cf7d..a552d2ad1a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -180,7 +180,7 @@ dependencies = [ "lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "native-tls 0.1.0 (git+https://github.com/sfackler/rust-native-tls.git)", "openssl-sys 0.7.14 (registry+https://github.com/rust-lang/crates.io-index)", - "rustls 0.1.0 (git+https://github.com/brson/rustls.git?branch=next)", + "rustls 0.1.0 (git+https://github.com/ctz/rustls.git)", "url 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -519,7 +519,7 @@ dependencies = [ [[package]] name = "rustls" version = "0.1.0" -source = "git+https://github.com/brson/rustls.git?branch=next#b386cbf92f458837df2256460f2100d4f84f514a" +source = "git+https://github.com/ctz/rustls.git#622dce5fdbd3b644e4e79d5d6e3dc891590121dc" dependencies = [ "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "ring 0.1.0 (git+https://github.com/ctz/ring)", diff --git a/src/download/Cargo.toml b/src/download/Cargo.toml index 85a2762cc9..259d8321c0 100644 --- a/src/download/Cargo.toml +++ b/src/download/Cargo.toml @@ -33,6 +33,5 @@ optional = true openssl-sys = { version = "0.7.11", optional = true } [dependencies.rustls] -git = "https://github.com/brson/rustls.git" -branch = "next" +git = "https://github.com/ctz/rustls.git" optional = true