Proper global init/deinit of GnuTLS
These are reference counted so it is important to retain symmetry
between the calls. Failure to do so will result in bad memory access
and crashes.
diff --git a/common/rfb/CSecurityTLS.cxx b/common/rfb/CSecurityTLS.cxx
index 3dceded..8a053e3 100644
--- a/common/rfb/CSecurityTLS.cxx
+++ b/common/rfb/CSecurityTLS.cxx
@@ -67,21 +67,14 @@
static LogWriter vlog("TLS");
-void CSecurityTLS::initGlobal()
-{
- static bool globalInitDone = false;
-
- if (!globalInitDone) {
- gnutls_global_init();
- globalInitDone = true;
- }
-}
-
CSecurityTLS::CSecurityTLS(bool _anon) : session(0), anon_cred(0),
anon(_anon), fis(0), fos(0)
{
cafile = X509CA.getData();
crlfile = X509CRL.getData();
+
+ if (gnutls_global_init() != GNUTLS_E_SUCCESS)
+ throw AuthFailureException("gnutls_global_init failed");
}
void CSecurityTLS::setDefaults()
@@ -125,8 +118,6 @@
if (session) {
gnutls_deinit(session);
session = 0;
-
- gnutls_global_deinit();
}
}
@@ -142,6 +133,8 @@
delete[] cafile;
delete[] crlfile;
+
+ gnutls_global_deinit();
}
bool CSecurityTLS::processMsg(CConnection* cc)
@@ -150,8 +143,6 @@
rdr::OutStream* os = cc->getOutStream();
client = cc;
- initGlobal();
-
if (!session) {
if (!is->checkNoWait(1))
return false;