From bd0c0c60bd5aed184a2b915dfb0d4a85f8a09cd1 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Thu, 20 Oct 2016 20:57:53 -0700 Subject: [PATCH] Store a MidHandshakeSslStream in fatal errors This in particular allows the X509 verification error to be retrieved, as well as the stream itself. --- openssl/src/ssl/mod.rs | 55 ++++++++++++++++++++++++++++++------------ 1 file changed, 39 insertions(+), 16 deletions(-) diff --git a/openssl/src/ssl/mod.rs b/openssl/src/ssl/mod.rs index 3e05a5c9..83c7b7a1 100644 --- a/openssl/src/ssl/mod.rs +++ b/openssl/src/ssl/mod.rs @@ -761,9 +761,12 @@ unsafe impl<'a> Sync for SslRef<'a> {} impl<'a> fmt::Debug for SslRef<'a> { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - fmt.debug_struct("SslRef") - .field("state", &self.state_string_long()) - .finish() + let mut builder = fmt.debug_struct("SslRef"); + builder.field("state", &self.state_string_long()); + if let Some(err) = self.verify_result() { + builder.field("verify_result", &err); + } + builder.finish() } } @@ -1008,9 +1011,12 @@ pub struct Ssl(SslRef<'static>); impl fmt::Debug for Ssl { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - fmt.debug_struct("Ssl") - .field("state", &self.state_string_long()) - .finish() + let mut builder = fmt.debug_struct("Ssl"); + builder.field("state", &self.state_string_long()); + if let Some(err) = self.verify_result() { + builder.field("verify_result", &err); + } + builder.finish() } } @@ -1063,7 +1069,12 @@ impl Ssl { error: e, })) } - err => Err(HandshakeError::Failure(err)), + err => { + Err(HandshakeError::Failure(MidHandshakeSslStream { + stream: stream, + error: err, + })) + } } } } @@ -1085,7 +1096,12 @@ impl Ssl { error: e, })) } - err => Err(HandshakeError::Failure(err)), + err => { + Err(HandshakeError::Failure(MidHandshakeSslStream { + stream: stream, + error: err, + })) + } } } } @@ -1156,7 +1172,7 @@ impl SslStream { #[derive(Debug)] pub enum HandshakeError { /// The handshake failed. - Failure(Error), + Failure(MidHandshakeSslStream), /// The handshake was interrupted midway through. Interrupted(MidHandshakeSslStream), } @@ -1164,15 +1180,14 @@ pub enum HandshakeError { impl stderror::Error for HandshakeError { fn description(&self) -> &str { match *self { - HandshakeError::Failure(ref e) => e.description(), - HandshakeError::Interrupted(ref e) => e.error.description(), + HandshakeError::Failure(_) => "the handshake failed", + HandshakeError::Interrupted(_) => "the handshake was interrupted", } } fn cause(&self) -> Option<&stderror::Error> { match *self { - HandshakeError::Failure(ref e) => Some(e), - HandshakeError::Interrupted(ref e) => Some(&e.error), + HandshakeError::Failure(ref s) | HandshakeError::Interrupted(ref s) => Some(s.error()), } } } @@ -1180,8 +1195,13 @@ impl stderror::Error for HandshakeError { impl fmt::Display for HandshakeError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { try!(f.write_str(stderror::Error::description(self))); - if let Some(e) = stderror::Error::cause(self) { - try!(write!(f, ": {}", e)); + match *self { + HandshakeError::Failure(ref s) | HandshakeError::Interrupted(ref s) => { + try!(write!(f, ": {}", s.error())); + if let Some(err) = s.ssl().verify_result() { + try!(write!(f, ": {}", err)); + } + } } Ok(()) } @@ -1227,7 +1247,10 @@ impl MidHandshakeSslStream { self.error = e; Err(HandshakeError::Interrupted(self)) } - err => Err(HandshakeError::Failure(err)), + err => { + self.error = err; + Err(HandshakeError::Failure(self)) + } } } }