From 55f12660891812d13a59e799b0ab5b185926479a Mon Sep 17 00:00:00 2001 From: Mikko Perttunen Date: Wed, 11 Feb 2015 19:11:21 +0200 Subject: [PATCH] fix(net): don't stop the server when an SSL handshake fails with EOF HttpAcceptor::accept()'s HTTPS logic passes IO errors from the underlying SSL stream directly to the caller. Furthermore, the caller uses the EndOfFile error code to detect that the server should stop accepting connections. This means that if the TCP connection was succesfully accepted, but an EOF condition was detected during the handshake, the server will stop accepting connections and quit. This allows for a trivial denial of service attack and can happen accidentally as well. Change HttpAcceptor::accept such that if the TCP stream underlying the SSL stream returns an IoError error, a ConnectionAborted IoError is returned instead. This allows distinguishing between IoErrors from the acceptor and the stream. The original error reason is stored in the detail field. --- src/net.rs | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/net.rs b/src/net.rs index 09c189dd..b11abfa3 100644 --- a/src/net.rs +++ b/src/net.rs @@ -237,9 +237,17 @@ impl NetworkAcceptor for HttpAcceptor { HttpAcceptor::Http(ref mut tcp, _) => HttpStream::Http(try!(tcp.accept())), HttpAcceptor::Https(ref mut tcp, _, ref ssl_context) => { let stream = try!(tcp.accept()); - let ssl_stream = try!(SslStream::::new_server(&**ssl_context, stream). - map_err(lift_ssl_error)); - HttpStream::Https(ssl_stream) + match SslStream::::new_server(&**ssl_context, stream) { + Ok(ssl_stream) => HttpStream::Https(ssl_stream), + Err(StreamError(ref e)) => { + return Err(IoError { + kind: ConnectionAborted, + desc: "SSL Handshake Interrupted", + detail: Some(e.desc.to_string()) + }); + }, + Err(e) => return Err(lift_ssl_error(e)) + } } }) }