Fix unclean SSL disconnection
authorHardening <rdp.effort@gmail.com>
Thu, 10 Jul 2014 21:35:11 +0000 (23:35 +0200)
committerHardening <rdp.effort@gmail.com>
Thu, 10 Jul 2014 21:35:11 +0000 (23:35 +0200)
This patch prevent an infinite loop when the remote peer disconnect
the socket without cleanly closing the SSL connection.

libfreerdp/core/tcp.c
libfreerdp/crypto/tls.c

index 245d3b1..3147049 100644 (file)
@@ -122,23 +122,28 @@ static int transport_bio_simple_read(BIO* bio, char* buf, int size)
        BIO_clear_flags(bio, BIO_FLAGS_READ);
 
        status = _recv((SOCKET) bio->num, buf, size, 0);
+       if (status > 0)
+               return status;
 
-       if (status <= 0)
+       if (status == 0)
        {
-               error = WSAGetLastError();
+               BIO_clear_flags(bio, BIO_FLAGS_SHOULD_RETRY);
+               return 0;
+       }
 
-               if ((error == WSAEWOULDBLOCK) || (error == WSAEINTR) ||
-                       (error == WSAEINPROGRESS) || (error == WSAEALREADY))
-               {
-                       BIO_set_flags(bio, (BIO_FLAGS_READ | BIO_FLAGS_SHOULD_RETRY));
-               }
-               else
-               {
-                       BIO_clear_flags(bio, BIO_FLAGS_SHOULD_RETRY);
-               }
+       error = WSAGetLastError();
+
+       if ((error == WSAEWOULDBLOCK) || (error == WSAEINTR) ||
+               (error == WSAEINPROGRESS) || (error == WSAEALREADY))
+       {
+               BIO_set_flags(bio, (BIO_FLAGS_READ | BIO_FLAGS_SHOULD_RETRY));
+       }
+       else
+       {
+               BIO_clear_flags(bio, BIO_FLAGS_SHOULD_RETRY);
        }
 
-       return status;
+       return -1;
 }
 
 static int transport_bio_simple_puts(BIO* bio, const char* str)
@@ -327,7 +332,6 @@ static int transport_bio_buffered_read(BIO* bio, char* buf, int size)
                if (!BIO_should_retry(bio->next_bio))
                {
                        BIO_clear_flags(bio, BIO_FLAGS_SHOULD_RETRY);
-                       status = -1;
                        goto out;
                }
 
index 9075f1e..da0a0cc 100644 (file)
@@ -152,7 +152,8 @@ static int bio_rdp_tls_read(BIO* bio, char* buf, int size)
                                break;
 
                        case SSL_ERROR_SYSCALL:
-                               status = 0;
+                               BIO_clear_flags(bio, BIO_FLAGS_SHOULD_RETRY);
+                               status = -1;
                                break;
                }
        }