]> source.dussan.org Git - tigervnc.git/commitdiff
Propagate exceptions from GnuTLS push/pull functions
authorPierre Ossman <ossman@cendio.se>
Thu, 10 Jun 2021 14:34:15 +0000 (16:34 +0200)
committerPierre Ossman <ossman@cendio.se>
Fri, 11 Jun 2021 07:42:44 +0000 (09:42 +0200)
Gives us a more meaningful error rather than just "Error in push/pull
function".

common/rdr/TLSInStream.cxx
common/rdr/TLSInStream.h
common/rdr/TLSOutStream.cxx
common/rdr/TLSOutStream.h

index 94e6109b38a0a0f16ad3de63c4f02caa00e02dde..451855c730ca6889770a624a5ccf0aa7eeb344e6 100644 (file)
@@ -39,6 +39,9 @@ ssize_t TLSInStream::pull(gnutls_transport_ptr_t str, void* data, size_t size)
   TLSInStream* self= (TLSInStream*) str;
   InStream *in = self->in;
 
+  delete self->saved_exception;
+  self->saved_exception = NULL;
+
   try {
     if (!in->hasData(1)) {
       gnutls_transport_set_errno(self->session, EAGAIN);
@@ -54,10 +57,12 @@ ssize_t TLSInStream::pull(gnutls_transport_ptr_t str, void* data, size_t size)
   } catch (SystemException &e) {
     vlog.error("Failure reading TLS data: %s", e.str());
     gnutls_transport_set_errno(self->session, e.err);
+    self->saved_exception = new SystemException(e);
     return -1;
   } catch (Exception& e) {
     vlog.error("Failure reading TLS data: %s", e.str());
     gnutls_transport_set_errno(self->session, EINVAL);
+    self->saved_exception = new Exception(e);
     return -1;
   }
 
@@ -65,7 +70,7 @@ ssize_t TLSInStream::pull(gnutls_transport_ptr_t str, void* data, size_t size)
 }
 
 TLSInStream::TLSInStream(InStream* _in, gnutls_session_t _session)
-  : session(_session), in(_in)
+  : session(_session), in(_in), saved_exception(NULL)
 {
   gnutls_transport_ptr_t recv, send;
 
@@ -77,6 +82,8 @@ TLSInStream::TLSInStream(InStream* _in, gnutls_session_t _session)
 TLSInStream::~TLSInStream()
 {
   gnutls_transport_set_pull_function(session, NULL);
+
+  delete saved_exception;
 }
 
 bool TLSInStream::fillBuffer(size_t maxSize)
@@ -97,7 +104,11 @@ size_t TLSInStream::readTLS(U8* buf, size_t len)
   if (n == GNUTLS_E_INTERRUPTED || n == GNUTLS_E_AGAIN)
     return 0;
 
-  if (n < 0) throw TLSException("readTLS", n);
+  if (n == GNUTLS_E_PULL_ERROR)
+    throw *saved_exception;
+
+  if (n < 0)
+    throw TLSException("readTLS", n);
 
   if (n == 0)
     throw EndOfStream();
index df5ebb4883af92c4a2997e4e0ddbb76a66087b02..8fe35d263e87cff536cd4fe19290d9f5d1c85964 100644 (file)
@@ -43,6 +43,8 @@ namespace rdr {
 
     gnutls_session_t session;
     InStream* in;
+
+    Exception* saved_exception;
   };
 };
 
index 0fa14b39e31db42d5de56970053ddccf0292d664..dc6b55aad77e2394333c06c8a7f71dfc0c5ea9b8 100644 (file)
@@ -42,16 +42,21 @@ ssize_t TLSOutStream::push(gnutls_transport_ptr_t str, const void* data,
   TLSOutStream* self= (TLSOutStream*) str;
   OutStream *out = self->out;
 
+  delete self->saved_exception;
+  self->saved_exception = NULL;
+
   try {
     out->writeBytes(data, size);
     out->flush();
   } catch (SystemException &e) {
     vlog.error("Failure sending TLS data: %s", e.str());
     gnutls_transport_set_errno(self->session, e.err);
+    self->saved_exception = new SystemException(e);
     return -1;
   } catch (Exception& e) {
     vlog.error("Failure sending TLS data: %s", e.str());
     gnutls_transport_set_errno(self->session, EINVAL);
+    self->saved_exception = new Exception(e);
     return -1;
   }
 
@@ -59,7 +64,8 @@ ssize_t TLSOutStream::push(gnutls_transport_ptr_t str, const void* data,
 }
 
 TLSOutStream::TLSOutStream(OutStream* _out, gnutls_session_t _session)
-  : session(_session), out(_out), bufSize(DEFAULT_BUF_SIZE), offset(0)
+  : session(_session), out(_out), bufSize(DEFAULT_BUF_SIZE), offset(0),
+    saved_exception(NULL)
 {
   gnutls_transport_ptr_t recv, send;
 
@@ -82,6 +88,7 @@ TLSOutStream::~TLSOutStream()
   gnutls_transport_set_push_function(session, NULL);
 
   delete [] start;
+  delete saved_exception;
 }
 
 size_t TLSOutStream::length()
@@ -134,6 +141,9 @@ size_t TLSOutStream::writeTLS(const U8* data, size_t length)
   if (n == GNUTLS_E_INTERRUPTED || n == GNUTLS_E_AGAIN)
     return 0;
 
+  if (n == GNUTLS_E_PUSH_ERROR)
+    throw *saved_exception;
+
   if (n < 0)
     throw TLSException("writeTLS", n);
 
index c97504635bbb6deb32fe108e1f7aff25dac8118d..c557912768bea7d8a3744100ce2bca702e92ded3 100644 (file)
@@ -51,6 +51,8 @@ namespace rdr {
     size_t bufSize;
     U8* start;
     size_t offset;
+
+    Exception* saved_exception;
   };
 };