diff --git a/Cargo.toml b/Cargo.toml index 1634f4be98..19b4d3cbf9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,21 +25,9 @@ unicase = "1.0" url = "1.0" [dependencies.cookie] -version = "0.2" +version = "0.5" default-features = false -[dependencies.openssl] -version = "0.7" -optional = true - -[dependencies.openssl-verify] -version = "0.1" -optional = true - -[dependencies.security-framework] -version = "0.1.4" -optional = true - [dependencies.solicit] version = "0.4" default-features = false @@ -52,7 +40,5 @@ optional = true env_logger = "0.3" [features] -default = ["ssl"] -ssl = ["openssl", "openssl-verify", "cookie/secure"] serde-serialization = ["serde", "mime/serde"] nightly = [] diff --git a/src/client/proxy.rs b/src/client/proxy.rs index 7d4f9722d2..db7bc1eaf0 100644 --- a/src/client/proxy.rs +++ b/src/client/proxy.rs @@ -7,25 +7,6 @@ use client::scheme::Scheme; use method::Method; use net::{NetworkConnector, HttpConnector, NetworkStream, SslClient}; -#[cfg(all(feature = "openssl", not(feature = "security-framework")))] -pub fn tunnel(proxy: (Scheme, Cow<'static, str>, u16)) -> Proxy { - Proxy { - connector: HttpConnector, - proxy: proxy, - ssl: Default::default() - } -} - -#[cfg(feature = "security-framework")] -pub fn tunnel(proxy: (Scheme, Cow<'static, str>, u16)) -> Proxy { - Proxy { - connector: HttpConnector, - proxy: proxy, - ssl: Default::default() - } -} - -#[cfg(not(any(feature = "openssl", feature = "security-framework")))] pub fn tunnel(proxy: (Scheme, Cow<'static, str>, u16)) -> Proxy { Proxy { connector: HttpConnector, diff --git a/src/lib.rs b/src/lib.rs index 72e96e22e7..b580906768 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -131,12 +131,6 @@ extern crate rustc_serialize as serialize; extern crate time; #[macro_use] extern crate url; -#[cfg(feature = "openssl")] -extern crate openssl; -#[cfg(feature = "openssl-verify")] -extern crate openssl_verify; -#[cfg(feature = "security-framework")] -extern crate security_framework; #[cfg(feature = "serde-serialization")] extern crate serde; extern crate cookie; diff --git a/src/net.rs b/src/net.rs index 25b09b7463..94d4dc6216 100644 --- a/src/net.rs +++ b/src/net.rs @@ -5,12 +5,6 @@ use std::io::{self, ErrorKind, Read, Write}; use std::net::{SocketAddr, ToSocketAddrs, TcpStream, TcpListener, Shutdown}; use std::mem; -#[cfg(feature = "openssl")] -pub use self::openssl::{Openssl, OpensslClient}; - -#[cfg(feature = "security-framework")] -pub use self::security_framework::ClientWrapper; - use std::time::Duration; use typeable::Typeable; @@ -413,18 +407,6 @@ impl NetworkConnector for F where F: Fn(&str, u16, &str) -> io::Result ::Result; - /// Wrap a server stream with SSL. - fn wrap_server(&self, stream: HttpStream) -> ::Result; -} - /// An abstraction to allow any SSL implementation to be used with client-side HttpsStreams. pub trait SslClient { /// The protected stream. @@ -441,22 +423,6 @@ pub trait SslServer { fn wrap_server(&self, stream: T) -> ::Result; } -impl SslClient for S { - type Stream = ::Stream; - - fn wrap_client(&self, stream: HttpStream, host: &str) -> ::Result { - Ssl::wrap_client(self, stream, host) - } -} - -impl SslServer for S { - type Stream = ::Stream; - - fn wrap_server(&self, stream: HttpStream) -> ::Result { - Ssl::wrap_server(self, stream) - } -} - /// A stream over the HTTP protocol, possibly protected by SSL. #[derive(Debug, Clone)] pub enum HttpsStream { @@ -603,272 +569,9 @@ impl> NetworkConnector for } -#[cfg(all(not(feature = "openssl"), not(feature = "security-framework")))] #[doc(hidden)] pub type DefaultConnector = HttpConnector; -#[cfg(feature = "openssl")] -#[doc(hidden)] -pub type DefaultConnector = HttpsConnector; - -#[cfg(all(feature = "security-framework", not(feature = "openssl")))] -pub type DefaultConnector = HttpsConnector; - -#[cfg(feature = "openssl")] -mod openssl { - use std::io; - use std::net::{SocketAddr, Shutdown}; - use std::path::Path; - use std::sync::Arc; - use std::time::Duration; - - use openssl::ssl::{Ssl, SslContext, SslStream, SslMethod, SSL_VERIFY_NONE, SSL_VERIFY_PEER, SSL_OP_NO_SSLV2, SSL_OP_NO_SSLV3, SSL_OP_NO_COMPRESSION}; - use openssl::ssl::error::StreamError as SslIoError; - use openssl::ssl::error::SslError; - use openssl::x509::X509FileType; - use super::{NetworkStream, HttpStream}; - - /// An implementation of `Ssl` for OpenSSL. - /// - /// # Example - /// - /// ```no_run - /// use hyper::Server; - /// use hyper::net::Openssl; - /// - /// let ssl = Openssl::with_cert_and_key("/home/foo/cert", "/home/foo/key").unwrap(); - /// Server::https("0.0.0.0:443", ssl).unwrap(); - /// ``` - /// - /// For complete control, create a `SslContext` with the options you desire - /// and then create `Openssl { context: ctx } - #[derive(Debug, Clone)] - pub struct Openssl { - /// The `SslContext` from openssl crate. - pub context: Arc - } - - /// A client-specific implementation of OpenSSL. - #[derive(Debug, Clone)] - pub struct OpensslClient(SslContext); - - impl Default for OpensslClient { - fn default() -> OpensslClient { - let mut ctx = SslContext::new(SslMethod::Sslv23).unwrap(); - ctx.set_default_verify_paths().unwrap(); - ctx.set_options(SSL_OP_NO_SSLV2 | SSL_OP_NO_SSLV3 | SSL_OP_NO_COMPRESSION); - // cipher list taken from curl: - // https://github.com/curl/curl/blob/5bf5f6ebfcede78ef7c2b16daa41c4b7ba266087/lib/vtls/openssl.h#L120 - ctx.set_cipher_list("ALL!EXPORT!EXPORT40!EXPORT56!aNULL!LOW!RC4@STRENGTH").unwrap(); - OpensslClient::new(ctx) - } - } - - impl OpensslClient { - /// Creates a new OpensslClient with a custom SslContext - pub fn new(ctx: SslContext) -> OpensslClient { - OpensslClient(ctx) - } - } - - impl super::SslClient for OpensslClient { - type Stream = SslStream; - - #[cfg(not(windows))] - fn wrap_client(&self, stream: T, host: &str) -> ::Result { - let mut ssl = try!(Ssl::new(&self.0)); - try!(ssl.set_hostname(host)); - let host = host.to_owned(); - ssl.set_verify_callback(SSL_VERIFY_PEER, move |p, x| ::openssl_verify::verify_callback(&host, p, x)); - SslStream::connect(ssl, stream).map_err(From::from) - } - - - #[cfg(windows)] - fn wrap_client(&self, stream: T, host: &str) -> ::Result { - let mut ssl = try!(Ssl::new(&self.0)); - try!(ssl.set_hostname(host)); - SslStream::connect(ssl, stream).map_err(From::from) - } - } - - impl Default for Openssl { - fn default() -> Openssl { - Openssl { - context: Arc::new(SslContext::new(SslMethod::Sslv23).unwrap_or_else(|e| { - // if we cannot create a SslContext, that's because of a - // serious problem. just crash. - panic!("{}", e) - })) - } - } - } - - impl Openssl { - /// Ease creating an `Openssl` with a certificate and key. - pub fn with_cert_and_key(cert: C, key: K) -> Result - where C: AsRef, K: AsRef { - let mut ctx = try!(SslContext::new(SslMethod::Sslv23)); - try!(ctx.set_cipher_list("DEFAULT")); - try!(ctx.set_certificate_chain_file(cert.as_ref(), X509FileType::PEM)); - try!(ctx.set_private_key_file(key.as_ref(), X509FileType::PEM)); - ctx.set_verify(SSL_VERIFY_NONE, None); - Ok(Openssl { context: Arc::new(ctx) }) - } - } - - impl super::Ssl for Openssl { - type Stream = SslStream; - - fn wrap_client(&self, stream: HttpStream, host: &str) -> ::Result { - let ssl = try!(Ssl::new(&self.context)); - try!(ssl.set_hostname(host)); - SslStream::connect(ssl, stream).map_err(From::from) - } - - fn wrap_server(&self, stream: HttpStream) -> ::Result { - match SslStream::accept(&*self.context, stream) { - Ok(ssl_stream) => Ok(ssl_stream), - Err(SslIoError(e)) => { - Err(io::Error::new(io::ErrorKind::ConnectionAborted, e).into()) - }, - Err(e) => Err(e.into()) - } - } - } - - impl NetworkStream for SslStream { - #[inline] - fn peer_addr(&mut self) -> io::Result { - self.get_mut().peer_addr() - } - - #[inline] - fn set_read_timeout(&self, dur: Option) -> io::Result<()> { - self.get_ref().set_read_timeout(dur) - } - - #[inline] - fn set_write_timeout(&self, dur: Option) -> io::Result<()> { - self.get_ref().set_write_timeout(dur) - } - - fn close(&mut self, how: Shutdown) -> io::Result<()> { - self.get_mut().close(how) - } - } -} - -#[cfg(feature = "security-framework")] -pub mod security_framework { - use std::io; - use std::fmt; - use std::sync::{Arc, Mutex}; - use std::net::{Shutdown, SocketAddr}; - use std::time::Duration; - use security_framework::secure_transport::{SslStream, ClientBuilder, ServerBuilder}; - - use error::Error; - use net::{SslClient, SslServer, HttpStream, NetworkStream}; - - #[derive(Default)] - pub struct ClientWrapper(ClientBuilder); - - impl ClientWrapper { - pub fn new(builder: ClientBuilder) -> ClientWrapper { - ClientWrapper(builder) - } - } - - impl SslClient for ClientWrapper { - type Stream = Stream; - - fn wrap_client(&self, stream: HttpStream, host: &str) -> ::Result { - match self.0.handshake(host, stream) { - Ok(s) => Ok(Stream(Arc::new(Mutex::new(s)))), - Err(e) => Err(Error::Ssl(e.into())), - } - } - } - - #[derive(Clone)] - pub struct ServerWrapper(Arc); - - impl ServerWrapper { - pub fn new(builder: ServerBuilder) -> ServerWrapper { - ServerWrapper(Arc::new(builder)) - } - } - - impl SslServer for ServerWrapper { - type Stream = Stream; - - fn wrap_server(&self, stream: HttpStream) -> ::Result { - match self.0.handshake(stream) { - Ok(s) => Ok(Stream(Arc::new(Mutex::new(s)))), - Err(e) => Err(Error::Ssl(e.into())), - } - } - } - - #[derive(Clone)] - pub struct Stream(Arc>>); - - impl io::Read for Stream { - fn read(&mut self, buf: &mut [u8]) -> io::Result { - self.0.lock().unwrap_or_else(|e| e.into_inner()).read(buf) - } - - fn read_to_end(&mut self, buf: &mut Vec) -> io::Result { - self.0.lock().unwrap_or_else(|e| e.into_inner()).read_to_end(buf) - } - - fn read_to_string(&mut self, buf: &mut String) -> io::Result { - self.0.lock().unwrap_or_else(|e| e.into_inner()).read_to_string(buf) - } - - fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> { - self.0.lock().unwrap_or_else(|e| e.into_inner()).read_exact(buf) - } - } - - impl io::Write for Stream { - fn write(&mut self, buf: &[u8]) -> io::Result { - self.0.lock().unwrap_or_else(|e| e.into_inner()).write(buf) - } - - fn flush(&mut self) -> io::Result<()> { - self.0.lock().unwrap_or_else(|e| e.into_inner()).flush() - } - - fn write_all(&mut self, buf: &[u8]) -> io::Result<()> { - self.0.lock().unwrap_or_else(|e| e.into_inner()).write_all(buf) - } - - fn write_fmt(&mut self, fmt: fmt::Arguments) -> io::Result<()> { - self.0.lock().unwrap_or_else(|e| e.into_inner()).write_fmt(fmt) - } - } - - impl NetworkStream for Stream { - fn peer_addr(&mut self) -> io::Result { - self.0.lock().unwrap_or_else(|e| e.into_inner()).get_mut().peer_addr() - } - - fn set_read_timeout(&self, dur: Option) -> io::Result<()> { - self.0.lock().unwrap_or_else(|e| e.into_inner()).get_mut().set_read_timeout(dur) - } - - fn set_write_timeout(&self, dur: Option) -> io::Result<()> { - self.0.lock().unwrap_or_else(|e| e.into_inner()).get_mut().set_write_timeout(dur) - } - - fn close(&mut self, how: Shutdown) -> io::Result<()> { - self.0.lock().unwrap_or_else(|e| e.into_inner()).get_mut().close(how) - } - } -} - #[cfg(test)] mod tests { use mock::MockStream;