]> granicus.if.org Git - icinga2/commitdiff
Properly shut down TLS streams.
authorGunnar Beutner <gunnar@beutner.name>
Sat, 3 May 2014 17:56:47 +0000 (19:56 +0200)
committerGunnar Beutner <gunnar.beutner@netways.de>
Tue, 6 May 2014 08:40:36 +0000 (10:40 +0200)
Refs #6107

lib/base/tlsstream.cpp
lib/remote/jsonrpc.cpp

index 7ec3216e6523eb19e2e7794422c1ba2d7d2b669d..b875a16cf0665c68db187ae28c3827d78408e7d7 100644 (file)
@@ -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;
+                       if (rc > 0)
+                               break;
+
+                       err = SSL_get_error(m_SSL.get(), rc);
+               }
 
-               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();
 }
 
index 628209d060764e3f9dea08651f52ed2e915f3aca..16f097b7ceca571835e2a6f7b410eb9a89d04917 100644 (file)
@@ -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);