upgrade to native-tls 0.2 + invalid certs (#325)

- Bumps `native-tls` dependency to 0.2 and adapt code accordingly
- Import code used from `tokio-tls` into `connect_async` and adapt dependencies accordinlgy
- Add an option for using `danger_accept_invalid_certs` inside the `Config` struct
This commit is contained in:
Yannick Heinrich
2018-08-08 22:14:36 +02:00
committed by Sean McArthur
parent a25f62f4cb
commit 11f8588989
7 changed files with 212 additions and 47 deletions

View File

@@ -45,6 +45,7 @@ struct Config {
gzip: bool,
headers: HeaderMap,
hostname_verification: bool,
certs_verification: bool,
proxies: Vec<Proxy>,
redirect_policy: RedirectPolicy,
referer: bool,
@@ -56,31 +57,24 @@ struct Config {
impl ClientBuilder {
/// Constructs a new `ClientBuilder`
pub fn new() -> ClientBuilder {
match TlsConnector::builder() {
Ok(tls_connector_builder) => {
let mut headers: HeaderMap<HeaderValue> = HeaderMap::with_capacity(2);
headers.insert(USER_AGENT, HeaderValue::from_static(DEFAULT_USER_AGENT));
headers.insert(ACCEPT, HeaderValue::from_str(mime::STAR_STAR.as_ref()).expect("unable to parse mime"));
let mut headers: HeaderMap<HeaderValue> = HeaderMap::with_capacity(2);
headers.insert(USER_AGENT, HeaderValue::from_static(DEFAULT_USER_AGENT));
headers.insert(ACCEPT, HeaderValue::from_str(mime::STAR_STAR.as_ref()).expect("unable to parse mime"));
ClientBuilder {
config: Some(Config {
gzip: true,
headers: headers,
hostname_verification: true,
proxies: Vec::new(),
redirect_policy: RedirectPolicy::default(),
referer: true,
timeout: None,
tls: tls_connector_builder,
dns_threads: 4,
}),
err: None,
}
},
Err(e) => ClientBuilder {
config: None,
err: Some(::error::from(e)),
}
ClientBuilder {
config: Some(Config {
gzip: true,
headers: headers,
hostname_verification: true,
certs_verification: true,
proxies: Vec::new(),
redirect_policy: RedirectPolicy::default(),
referer: true,
timeout: None,
tls: TlsConnector::builder(),
dns_threads: 4,
}),
err: None,
}
}
@@ -98,19 +92,19 @@ impl ClientBuilder {
if let Some(err) = self.err.take() {
return Err(err);
}
let config = self.config
let mut config = self.config
.take()
.expect("ClientBuilder cannot be reused after building a Client");
config.tls.danger_accept_invalid_hostnames(!config.hostname_verification);
config.tls.danger_accept_invalid_certs(!config.certs_verification);
let tls = try_!(config.tls.build());
let proxies = Arc::new(config.proxies);
let mut connector = Connector::new(config.dns_threads, tls, proxies.clone());
if !config.hostname_verification {
connector.danger_disable_hostname_verification();
}
let hyper_client = ::hyper::Client::builder()
.build(connector);
@@ -133,9 +127,7 @@ impl ClientBuilder {
pub fn add_root_certificate(&mut self, cert: Certificate) -> &mut ClientBuilder {
if let Some(config) = config_mut(&mut self.config, &self.err) {
let cert = ::tls::cert(cert);
if let Err(e) = config.tls.add_root_certificate(cert) {
self.err = Some(::error::from(e));
}
config.tls.add_root_certificate(cert);
}
self
}
@@ -144,9 +136,7 @@ impl ClientBuilder {
pub fn identity(&mut self, identity: Identity) -> &mut ClientBuilder {
if let Some(config) = config_mut(&mut self.config, &self.err) {
let pkcs12 = ::tls::pkcs12(identity);
if let Err(e) = config.tls.identity(pkcs12) {
self.err = Some(::error::from(e));
}
config.tls.identity(pkcs12);
}
self
}
@@ -177,6 +167,31 @@ impl ClientBuilder {
self
}
/// Disable certs verification.
///
/// # Warning
///
/// You should think very carefully before you use this method. If
/// hostname verification is not used, any valid certificate for any
/// site will be trusted for use from any other. This introduces a
/// significant vulnerability to man-in-the-middle attacks.
#[inline]
pub fn danger_disable_certs_verification(&mut self) -> &mut ClientBuilder {
if let Some(config) = config_mut(&mut self.config, &self.err) {
config.certs_verification = false;
}
self
}
/// Enable certs verification.
#[inline]
pub fn enable_certs_verification(&mut self) -> &mut ClientBuilder {
if let Some(config) = config_mut(&mut self.config, &self.err) {
config.certs_verification = true;
}
self
}
/// Sets the default headers for every request.
#[inline]
pub fn default_headers(&mut self, headers: HeaderMap) -> &mut ClientBuilder {