aboutsummaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
authorPierre Ossman <ossman@cendio.se>2021-06-10 16:34:15 +0200
committerPierre Ossman <ossman@cendio.se>2021-06-11 09:42:44 +0200
commit9c407d2a0bc11697ae8413a8e6bea21813fd6072 (patch)
tree570cb1cb4020c4935fa3f519d30f5da34e4cfe01 /common
parentd1ad6b5c250d0bc4c43b4d9983badf8ce01b5747 (diff)
downloadtigervnc-9c407d2a0bc11697ae8413a8e6bea21813fd6072.tar.gz
tigervnc-9c407d2a0bc11697ae8413a8e6bea21813fd6072.zip
Propagate exceptions from GnuTLS push/pull functions
Gives us a more meaningful error rather than just "Error in push/pull function".
Diffstat (limited to 'common')
-rw-r--r--common/rdr/TLSInStream.cxx15
-rw-r--r--common/rdr/TLSInStream.h2
-rw-r--r--common/rdr/TLSOutStream.cxx12
-rw-r--r--common/rdr/TLSOutStream.h2
4 files changed, 28 insertions, 3 deletions
diff --git a/common/rdr/TLSInStream.cxx b/common/rdr/TLSInStream.cxx
index 94e6109b..451855c7 100644
--- a/common/rdr/TLSInStream.cxx
+++ b/common/rdr/TLSInStream.cxx
@@ -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();
diff --git a/common/rdr/TLSInStream.h b/common/rdr/TLSInStream.h
index df5ebb48..8fe35d26 100644
--- a/common/rdr/TLSInStream.h
+++ b/common/rdr/TLSInStream.h
@@ -43,6 +43,8 @@ namespace rdr {
gnutls_session_t session;
InStream* in;
+
+ Exception* saved_exception;
};
};
diff --git a/common/rdr/TLSOutStream.cxx b/common/rdr/TLSOutStream.cxx
index 0fa14b39..dc6b55aa 100644
--- a/common/rdr/TLSOutStream.cxx
+++ b/common/rdr/TLSOutStream.cxx
@@ -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);
diff --git a/common/rdr/TLSOutStream.h b/common/rdr/TLSOutStream.h
index c9750463..c5579127 100644
--- a/common/rdr/TLSOutStream.h
+++ b/common/rdr/TLSOutStream.h
@@ -51,6 +51,8 @@ namespace rdr {
size_t bufSize;
U8* start;
size_t offset;
+
+ Exception* saved_exception;
};
};