From af5778510d1d8422fcb04873f7c726a67f15f5eb Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Wed, 14 Jan 2015 18:52:24 +0530 Subject: [PATCH 1/2] feat(net): Allow more generic SSL verification (fixes #244) --- src/client/mod.rs | 6 ++---- src/net.rs | 13 +++++++++---- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/client/mod.rs b/src/client/mod.rs index 2e77984e..5853c067 100644 --- a/src/client/mod.rs +++ b/src/client/mod.rs @@ -25,12 +25,10 @@ use std::iter::Extend; use url::UrlParser; use url::ParseError as UrlError; -use openssl::ssl::VerifyCallback; - use header::{Headers, Header, HeaderFormat}; use header::common::{ContentLength, Location}; use method::Method; -use net::{NetworkConnector, HttpConnector}; +use net::{NetworkConnector, HttpConnector, ContextVerifier}; use status::StatusClass::Redirection; use {Url, Port, HttpResult}; use HttpError::HttpUriError; @@ -57,7 +55,7 @@ impl Client { } /// Set the SSL verifier callback for use with OpenSSL. - pub fn set_ssl_verifier(&mut self, verifier: VerifyCallback) { + pub fn set_ssl_verifier(&mut self, verifier: ContextVerifier) { self.connector = HttpConnector(Some(verifier)); } diff --git a/src/net.rs b/src/net.rs index 0be3e8ed..97536134 100644 --- a/src/net.rs +++ b/src/net.rs @@ -11,8 +11,8 @@ use std::raw::{self, TraitObject}; use std::sync::Arc; use uany::UnsafeAnyExt; -use openssl::ssl::{Ssl, SslStream, SslContext, VerifyCallback}; -use openssl::ssl::SslVerifyMode::{SslVerifyPeer, SslVerifyNone}; +use openssl::ssl::{Ssl, SslStream, SslContext}; +use openssl::ssl::SslVerifyMode::SslVerifyNone; use openssl::ssl::SslMethod::Sslv23; use openssl::ssl::error::{SslError, StreamError, OpenSslErrors, SslSessionClosed}; use openssl::x509::X509FileType; @@ -309,7 +309,10 @@ impl NetworkStream for HttpStream { /// A connector that will produce HttpStreams. #[allow(missing_copy_implementations)] -pub struct HttpConnector(pub Option); +pub struct HttpConnector(pub Option); + +/// A method that can set verification methods on an SSL context +pub type ContextVerifier = for <'a> fn(&'a mut SslContext) -> (); impl NetworkConnector for HttpConnector { type Stream = HttpStream; @@ -325,7 +328,9 @@ impl NetworkConnector for HttpConnector { debug!("https scheme"); let stream = try!(TcpStream::connect(addr)); let mut context = try!(SslContext::new(Sslv23).map_err(lift_ssl_error)); - self.0.as_ref().map(|cb| context.set_verify(SslVerifyPeer, Some(*cb))); + if let Some(ref v) = self.0 { + v(&mut context); + } let ssl = try!(Ssl::new(&context).map_err(lift_ssl_error)); try!(ssl.set_hostname(host).map_err(lift_ssl_error)); let stream = try!(SslStream::new(&context, stream).map_err(lift_ssl_error)); From bca9a53c66c967affb8e245f26507494db39c35e Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Thu, 15 Jan 2015 22:22:20 +0530 Subject: [PATCH 2/2] feat(net): Move SSL verification to unboxed closures --- src/client/mod.rs | 6 +++--- src/net.rs | 10 +++++----- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/client/mod.rs b/src/client/mod.rs index 5853c067..43befdbc 100644 --- a/src/client/mod.rs +++ b/src/client/mod.rs @@ -47,15 +47,15 @@ pub struct Client { redirect_policy: RedirectPolicy, } -impl Client { +impl<'v> Client> { /// Create a new Client. - pub fn new() -> Client { + pub fn new() -> Client> { Client::with_connector(HttpConnector(None)) } /// Set the SSL verifier callback for use with OpenSSL. - pub fn set_ssl_verifier(&mut self, verifier: ContextVerifier) { + pub fn set_ssl_verifier(&mut self, verifier: ContextVerifier<'v>) { self.connector = HttpConnector(Some(verifier)); } diff --git a/src/net.rs b/src/net.rs index 97536134..8d4dea91 100644 --- a/src/net.rs +++ b/src/net.rs @@ -309,12 +309,12 @@ impl NetworkStream for HttpStream { /// A connector that will produce HttpStreams. #[allow(missing_copy_implementations)] -pub struct HttpConnector(pub Option); +pub struct HttpConnector<'v>(pub Option>); /// A method that can set verification methods on an SSL context -pub type ContextVerifier = for <'a> fn(&'a mut SslContext) -> (); +pub type ContextVerifier<'v> = Box ()+'v>; -impl NetworkConnector for HttpConnector { +impl<'v> NetworkConnector for HttpConnector<'v> { type Stream = HttpStream; fn connect(&mut self, host: &str, port: Port, scheme: &str) -> IoResult { @@ -328,8 +328,8 @@ impl NetworkConnector for HttpConnector { debug!("https scheme"); let stream = try!(TcpStream::connect(addr)); let mut context = try!(SslContext::new(Sslv23).map_err(lift_ssl_error)); - if let Some(ref v) = self.0 { - v(&mut context); + if let Some(ref mut verifier) = self.0 { + verifier(&mut context); } let ssl = try!(Ssl::new(&context).map_err(lift_ssl_error)); try!(ssl.set_hostname(host).map_err(lift_ssl_error));