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.
This commit is contained in:
Mikko Perttunen
2015-02-11 19:11:21 +02:00
parent 3e951c9723
commit 55f1266089

View File

@@ -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::<TcpStream>::new_server(&**ssl_context, stream).
map_err(lift_ssl_error));
HttpStream::Https(ssl_stream)
match SslStream::<TcpStream>::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))
}
}
})
}