From f8af13dd93e6723385811798c35d12da70d3641b Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Tue, 23 Aug 2016 17:02:58 +0200 Subject: [PATCH] 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. (cherry picked from commit 8aa4bc53206c2430bbf0c8f4b642f59a379ee649) --- common/rfb/CSecurityTLS.cxx | 19 +++++-------------- common/rfb/CSecurityTLS.h | 2 -- common/rfb/SSecurityTLS.cxx | 20 +++++--------------- common/rfb/SSecurityTLS.h | 2 -- 4 files changed, 10 insertions(+), 33 deletions(-) diff --git a/common/rfb/CSecurityTLS.cxx b/common/rfb/CSecurityTLS.cxx index 3dcededb..8a053e3d 100644 --- a/common/rfb/CSecurityTLS.cxx +++ b/common/rfb/CSecurityTLS.cxx @@ -67,21 +67,14 @@ StringParameter CSecurityTLS::X509CRL("X509CRL", "X509 CRL file", "", ConfViewer 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 @@ void CSecurityTLS::shutdown(bool needbye) if (session) { gnutls_deinit(session); session = 0; - - gnutls_global_deinit(); } } @@ -142,6 +133,8 @@ CSecurityTLS::~CSecurityTLS() delete[] cafile; delete[] crlfile; + + gnutls_global_deinit(); } bool CSecurityTLS::processMsg(CConnection* cc) @@ -150,8 +143,6 @@ bool CSecurityTLS::processMsg(CConnection* cc) rdr::OutStream* os = cc->getOutStream(); client = cc; - initGlobal(); - if (!session) { if (!is->checkNoWait(1)) return false; diff --git a/common/rfb/CSecurityTLS.h b/common/rfb/CSecurityTLS.h index b147d802..57d964d7 100644 --- a/common/rfb/CSecurityTLS.h +++ b/common/rfb/CSecurityTLS.h @@ -62,8 +62,6 @@ namespace rfb { CConnection *client; private: - static void initGlobal(); - gnutls_session_t session; gnutls_anon_client_credentials_t anon_cred; gnutls_certificate_credentials_t cert_cred; diff --git a/common/rfb/SSecurityTLS.cxx b/common/rfb/SSecurityTLS.cxx index 0f52d34b..b9460223 100644 --- a/common/rfb/SSecurityTLS.cxx +++ b/common/rfb/SSecurityTLS.cxx @@ -48,23 +48,15 @@ StringParameter SSecurityTLS::X509_KeyFile static LogWriter vlog("TLS"); -void SSecurityTLS::initGlobal() -{ - static bool globalInitDone = false; - - if (!globalInitDone) { - if (gnutls_global_init() != GNUTLS_E_SUCCESS) - throw AuthFailureException("gnutls_global_init failed"); - globalInitDone = true; - } -} - SSecurityTLS::SSecurityTLS(bool _anon) : session(0), dh_params(0), anon_cred(0), cert_cred(0), anon(_anon), fis(0), fos(0) { certfile = X509_CertFile.getData(); keyfile = X509_KeyFile.getData(); + + if (gnutls_global_init() != GNUTLS_E_SUCCESS) + throw AuthFailureException("gnutls_global_init failed"); } void SSecurityTLS::shutdown() @@ -94,8 +86,6 @@ void SSecurityTLS::shutdown() if (session) { gnutls_deinit(session); session = 0; - - gnutls_global_deinit(); } } @@ -111,6 +101,8 @@ SSecurityTLS::~SSecurityTLS() delete[] keyfile; delete[] certfile; + + gnutls_global_deinit(); } bool SSecurityTLS::processMsg(SConnection *sc) @@ -121,8 +113,6 @@ bool SSecurityTLS::processMsg(SConnection *sc) vlog.debug("Process security message (session %p)", session); if (!session) { - initGlobal(); - if (gnutls_init(&session, GNUTLS_SERVER) != GNUTLS_E_SUCCESS) throw AuthFailureException("gnutls_init failed"); diff --git a/common/rfb/SSecurityTLS.h b/common/rfb/SSecurityTLS.h index a7932054..30242a24 100644 --- a/common/rfb/SSecurityTLS.h +++ b/common/rfb/SSecurityTLS.h @@ -54,8 +54,6 @@ namespace rfb { void setParams(gnutls_session_t session); private: - static void initGlobal(); - gnutls_session_t session; gnutls_dh_params_t dh_params; gnutls_anon_server_credentials_t anon_cred; -- 2.39.5