From e2fe1c8a6b2cb5f7e9f4d5e14e8ec0346a3a2261 Mon Sep 17 00:00:00 2001 From: Gunnar Beutner Date: Sat, 3 May 2014 19:56:47 +0200 Subject: [PATCH] Properly shut down TLS streams. Refs #6107 --- lib/base/tlsstream.cpp | 56 +++++++++++++++++++++++++++++++++--------- lib/remote/jsonrpc.cpp | 2 +- 2 files changed, 46 insertions(+), 12 deletions(-) diff --git a/lib/base/tlsstream.cpp b/lib/base/tlsstream.cpp index 7ec3216e6..b875a16cf 100644 --- a/lib/base/tlsstream.cpp +++ b/lib/base/tlsstream.cpp @@ -92,20 +92,19 @@ void TlsStream::Handshake(void) { ASSERT(!OwnsLock()); - int rc; - for (;;) { - int rc; + int rc, err; { ObjectLock olock(this); rc = SSL_do_handshake(m_SSL.get()); + + if (rc > 0) + break; + + err = SSL_get_error(m_SSL.get(), rc); } - if (rc > 0) - break; - - int err = SSL_get_error(m_SSL.get(), rc); switch (err) { case SSL_ERROR_WANT_READ: m_Socket->Poll(true, false); @@ -134,15 +133,17 @@ size_t TlsStream::Read(void *buffer, size_t count) size_t left = count; while (left > 0) { - int rc; + int rc, err; { ObjectLock olock(this); rc = SSL_read(m_SSL.get(), ((char *)buffer) + (count - left), left); + + if (rc <= 0) + err = SSL_get_error(m_SSL.get(), rc); } if (rc <= 0) { - int err = SSL_get_error(m_SSL.get(), rc); switch (err) { case SSL_ERROR_WANT_READ: m_Socket->Poll(true, false); @@ -173,15 +174,17 @@ void TlsStream::Write(const void *buffer, size_t count) size_t left = count; while (left > 0) { - int rc; + int rc, err; { ObjectLock olock(this); rc = SSL_write(m_SSL.get(), ((const char *)buffer) + (count - left), left); + + if (rc <= 0) + err = SSL_get_error(m_SSL.get(), rc); } if (rc <= 0) { - int err = SSL_get_error(m_SSL.get(), rc); switch (err) { case SSL_ERROR_WANT_READ: m_Socket->Poll(true, false); @@ -208,6 +211,37 @@ void TlsStream::Write(const void *buffer, size_t count) */ void TlsStream::Close(void) { + ASSERT(!OwnsLock()); + + for (;;) { + int rc, err; + + { + ObjectLock olock(this); + + do { + rc = SSL_shutdown(m_SSL.get()); + } while (rc == 0); + + if (rc > 0) + break; + + err = SSL_get_error(m_SSL.get(), rc); + } + + switch (err) { + case SSL_ERROR_WANT_READ: + m_Socket->Poll(true, false); + continue; + case SSL_ERROR_WANT_WRITE: + m_Socket->Poll(false, true); + continue; + default: + goto close_socket; + } + } + +close_socket: m_Socket->Close(); } diff --git a/lib/remote/jsonrpc.cpp b/lib/remote/jsonrpc.cpp index 628209d06..16f097b7c 100644 --- a/lib/remote/jsonrpc.cpp +++ b/lib/remote/jsonrpc.cpp @@ -42,7 +42,7 @@ Dictionary::Ptr JsonRpc::ReadMessage(const Stream::Ptr& stream) { String jsonString; if (!NetString::ReadStringFromStream(stream, &jsonString)) - BOOST_THROW_EXCEPTION(std::runtime_error("ReadStringFromStream signalled EOF.")); + return Dictionary::Ptr(); //std::cerr << "<< " << jsonString << std::endl; Value value = JsonDeserialize(jsonString);