From: Adam Tkac Date: Wed, 21 Jul 2010 09:19:00 +0000 (+0000) Subject: [Development] Rename SSecurityTLSBase source/class to SSecurityTLS. X-Git-Tag: v1.0.90~205 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=21b61a5c03d3f4ac72965e3ca28c710e2f54b35d;p=tigervnc.git [Development] Rename SSecurityTLSBase source/class to SSecurityTLS. git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@4108 3789f03b-4d11-0410-bbf8-ca57d06f2519 --- diff --git a/common/rfb/Makefile.am b/common/rfb/Makefile.am index 4aee2595..68b83b87 100644 --- a/common/rfb/Makefile.am +++ b/common/rfb/Makefile.am @@ -1,10 +1,10 @@ noinst_LTLIBRARIES = librfb.la VENCRYPT_HDRS = CSecurityTLS.h CSecurityTLSBase.h CSecurityX509.h \ - SSecurityTLSBase.h + SSecurityTLS.h VENCRYPT_SRCS = CSecurityTLS.cxx CSecurityTLSBase.cxx CSecurityX509.cxx \ - SSecurityTLSBase.cxx + SSecurityTLS.cxx HDRS = Blacklist.h CapsContainer.h CapsList.h CConnection.h \ CMsgHandler.h CMsgReader.h CMsgReaderV3.h CMsgWriter.h \ diff --git a/common/rfb/SSecurityTLS.cxx b/common/rfb/SSecurityTLS.cxx new file mode 100644 index 00000000..a268a512 --- /dev/null +++ b/common/rfb/SSecurityTLS.cxx @@ -0,0 +1,224 @@ +/* + * Copyright (C) 2004 Red Hat Inc. + * Copyright (C) 2005 Martin Koegler + * Copyright (C) 2010 TigerVNC Team + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#ifndef HAVE_GNUTLS +#error "This source should not be compiled without HAVE_GNUTLS defined" +#endif + +#include +#include +#include +#include +#include +#include + +#define DH_BITS 1024 /* XXX This should be configurable! */ +#define TLS_DEBUG + +using namespace rfb; + +StringParameter SSecurityTLS::X509_CertFile +("x509cert", "specifies path to the x509 certificate in PEM format", "", ConfServer); + +StringParameter SSecurityTLS::X509_KeyFile +("x509key", "specifies path to the key of the x509 certificate in PEM format", "", ConfServer); + +static LogWriter vlog("TLS"); + +#ifdef TLS_DEBUG +static void debug_log(int level, const char* str) +{ + vlog.debug(str); +} +#endif + +void SSecurityTLS::initGlobal() +{ + static bool globalInitDone = false; + + if (!globalInitDone) { + if (gnutls_global_init() != GNUTLS_E_SUCCESS) + throw AuthFailureException("gnutls_global_init failed"); + +#ifdef TLS_DEBUG + gnutls_global_set_log_level(10); + gnutls_global_set_log_function(debug_log); +#endif + + 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(); +} + +void SSecurityTLS::shutdown() +{ + if (session) { + if (gnutls_bye(session, GNUTLS_SHUT_RDWR) != GNUTLS_E_SUCCESS) { + /* FIXME: Treat as non-fatal error */ + vlog.error("TLS session wasn't terminated gracefully"); + } + } + + if (dh_params) { + gnutls_dh_params_deinit(dh_params); + dh_params = 0; + } + + if (anon_cred) { + gnutls_anon_free_server_credentials(anon_cred); + anon_cred = 0; + } + + if (cert_cred) { + gnutls_certificate_free_credentials(cert_cred); + cert_cred = 0; + } + + if (session) { + gnutls_deinit(session); + session = 0; + + gnutls_global_deinit(); + } +} + + +SSecurityTLS::~SSecurityTLS() +{ + shutdown(); + + if (fis) + delete fis; + if (fos) + delete fos; + + delete[] keyfile; + delete[] certfile; +} + +bool SSecurityTLS::processMsg(SConnection *sc) +{ + rdr::InStream* is = sc->getInStream(); + rdr::OutStream* os = sc->getOutStream(); + + 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"); + + if (gnutls_set_default_priority(session) != GNUTLS_E_SUCCESS) + throw AuthFailureException("gnutls_set_default_priority failed"); + + try { + setParams(session); + } + catch(...) { + os->writeU8(0); + throw; + } + + gnutls_transport_set_pull_function(session,rdr::gnutls_InStream_pull); + gnutls_transport_set_push_function(session,rdr::gnutls_OutStream_push); + gnutls_transport_set_ptr2(session, + (gnutls_transport_ptr)is, + (gnutls_transport_ptr)os); + os->writeU8(1); + os->flush(); + } + + int err; + if ((err = gnutls_handshake(session)) != GNUTLS_E_SUCCESS) { + if (!gnutls_error_is_fatal(err)) { + vlog.debug("Deferring completion of TLS handshake: %s", gnutls_strerror(err)); + return false; + } + vlog.error("TLS Handshake failed: %s", gnutls_strerror (err)); + shutdown(); + throw AuthFailureException("TLS Handshake failed"); + } + + vlog.debug("Handshake completed"); + + sc->setStreams(fis=new rdr::TLSInStream(is,session), + fos=new rdr::TLSOutStream(os,session)); + + return true; +} + +void SSecurityTLS::setParams(gnutls_session session) +{ + static const int kx_anon_priority[] = { GNUTLS_KX_ANON_DH, 0 }; + static const int kx_priority[] = { GNUTLS_KX_DHE_DSS, GNUTLS_KX_RSA, + GNUTLS_KX_DHE_RSA, GNUTLS_KX_SRP, 0 }; + + gnutls_kx_set_priority(session, anon ? kx_anon_priority : kx_priority); + + if (gnutls_dh_params_init(&dh_params) != GNUTLS_E_SUCCESS) + throw AuthFailureException("gnutls_dh_params_init failed"); + + if (gnutls_dh_params_generate2(dh_params, DH_BITS) != GNUTLS_E_SUCCESS) + throw AuthFailureException("gnutls_dh_params_generate2 failed"); + + if (anon) { + if (gnutls_anon_allocate_server_credentials(&anon_cred) != GNUTLS_E_SUCCESS) + throw AuthFailureException("gnutls_anon_allocate_server_credentials failed"); + + gnutls_anon_set_server_dh_params(anon_cred, dh_params); + + if (gnutls_credentials_set(session, GNUTLS_CRD_ANON, anon_cred) + != GNUTLS_E_SUCCESS) + throw AuthFailureException("gnutls_credentials_set failed"); + + vlog.debug("Anonymous session has been set"); + + } else { + if (gnutls_certificate_allocate_credentials(&cert_cred) != GNUTLS_E_SUCCESS) + throw AuthFailureException("gnutls_certificate_allocate_credentials failed"); + + gnutls_certificate_set_dh_params(cert_cred, dh_params); + + if (gnutls_certificate_set_x509_key_file(cert_cred, certfile, keyfile, + GNUTLS_X509_FMT_PEM) != GNUTLS_E_SUCCESS) + throw AuthFailureException("load of key failed"); + + if (gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, cert_cred) + != GNUTLS_E_SUCCESS) + throw AuthFailureException("gnutls_credentials_set failed"); + + vlog.debug("X509 session has been set"); + + } + +} diff --git a/common/rfb/SSecurityTLS.h b/common/rfb/SSecurityTLS.h new file mode 100644 index 00000000..4eebc7e0 --- /dev/null +++ b/common/rfb/SSecurityTLS.h @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2004 Red Hat Inc. + * Copyright (C) 2005 Martin Koegler + * Copyright (C) 2010 TigerVNC Team + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifndef __S_SECURITY_TLS_H__ +#define __S_SECURITY_TLS_H__ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#ifndef HAVE_GNUTLS +#error "This header should not be included without HAVE_GNUTLS defined" +#endif + +#include +#include +#include +#include +#include + +namespace rfb { + + class SSecurityTLS : public SSecurity { + public: + SSecurityTLS(bool _anon); + virtual ~SSecurityTLS(); + virtual bool processMsg(SConnection* sc); + virtual const char* getUserName() const {return 0;} + virtual int getType() const { return anon ? secTypeTLSNone : secTypeX509None;} + + static StringParameter X509_CertFile; + static StringParameter X509_KeyFile; + + protected: + void shutdown(); + void setParams(gnutls_session session); + + private: + static void initGlobal(); + + gnutls_session session; + gnutls_dh_params dh_params; + gnutls_anon_server_credentials anon_cred; + gnutls_certificate_credentials cert_cred; + char *keyfile, *certfile; + + int type; + bool anon; + + rdr::InStream* fis; + rdr::OutStream* fos; + }; + +} + +#endif diff --git a/common/rfb/SSecurityTLSBase.cxx b/common/rfb/SSecurityTLSBase.cxx deleted file mode 100644 index 8b9cae78..00000000 --- a/common/rfb/SSecurityTLSBase.cxx +++ /dev/null @@ -1,224 +0,0 @@ -/* - * Copyright (C) 2004 Red Hat Inc. - * Copyright (C) 2005 Martin Koegler - * Copyright (C) 2010 TigerVNC Team - * - * This is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this software; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - * USA. - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#ifndef HAVE_GNUTLS -#error "This source should not be compiled without HAVE_GNUTLS defined" -#endif - -#include -#include -#include -#include -#include -#include - -#define DH_BITS 1024 /* XXX This should be configurable! */ -#define TLS_DEBUG - -using namespace rfb; - -StringParameter SSecurityTLSBase::X509_CertFile -("x509cert", "specifies path to the x509 certificate in PEM format", "", ConfServer); - -StringParameter SSecurityTLSBase::X509_KeyFile -("x509key", "specifies path to the key of the x509 certificate in PEM format", "", ConfServer); - -static LogWriter vlog("TLS"); - -#ifdef TLS_DEBUG -static void debug_log(int level, const char* str) -{ - vlog.debug(str); -} -#endif - -void SSecurityTLSBase::initGlobal() -{ - static bool globalInitDone = false; - - if (!globalInitDone) { - if (gnutls_global_init() != GNUTLS_E_SUCCESS) - throw AuthFailureException("gnutls_global_init failed"); - -#ifdef TLS_DEBUG - gnutls_global_set_log_level(10); - gnutls_global_set_log_function(debug_log); -#endif - - globalInitDone = true; - } -} - -SSecurityTLSBase::SSecurityTLSBase(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(); -} - -void SSecurityTLSBase::shutdown() -{ - if (session) { - if (gnutls_bye(session, GNUTLS_SHUT_RDWR) != GNUTLS_E_SUCCESS) { - /* FIXME: Treat as non-fatal error */ - vlog.error("TLS session wasn't terminated gracefully"); - } - } - - if (dh_params) { - gnutls_dh_params_deinit(dh_params); - dh_params = 0; - } - - if (anon_cred) { - gnutls_anon_free_server_credentials(anon_cred); - anon_cred = 0; - } - - if (cert_cred) { - gnutls_certificate_free_credentials(cert_cred); - cert_cred = 0; - } - - if (session) { - gnutls_deinit(session); - session = 0; - - gnutls_global_deinit(); - } -} - - -SSecurityTLSBase::~SSecurityTLSBase() -{ - shutdown(); - - if (fis) - delete fis; - if (fos) - delete fos; - - delete[] keyfile; - delete[] certfile; -} - -bool SSecurityTLSBase::processMsg(SConnection *sc) -{ - rdr::InStream* is = sc->getInStream(); - rdr::OutStream* os = sc->getOutStream(); - - 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"); - - if (gnutls_set_default_priority(session) != GNUTLS_E_SUCCESS) - throw AuthFailureException("gnutls_set_default_priority failed"); - - try { - setParams(session); - } - catch(...) { - os->writeU8(0); - throw; - } - - gnutls_transport_set_pull_function(session,rdr::gnutls_InStream_pull); - gnutls_transport_set_push_function(session,rdr::gnutls_OutStream_push); - gnutls_transport_set_ptr2(session, - (gnutls_transport_ptr)is, - (gnutls_transport_ptr)os); - os->writeU8(1); - os->flush(); - } - - int err; - if ((err = gnutls_handshake(session)) != GNUTLS_E_SUCCESS) { - if (!gnutls_error_is_fatal(err)) { - vlog.debug("Deferring completion of TLS handshake: %s", gnutls_strerror(err)); - return false; - } - vlog.error("TLS Handshake failed: %s", gnutls_strerror (err)); - shutdown(); - throw AuthFailureException("TLS Handshake failed"); - } - - vlog.debug("Handshake completed"); - - sc->setStreams(fis=new rdr::TLSInStream(is,session), - fos=new rdr::TLSOutStream(os,session)); - - return true; -} - -void SSecurityTLSBase::setParams(gnutls_session session) -{ - static const int kx_anon_priority[] = { GNUTLS_KX_ANON_DH, 0 }; - static const int kx_priority[] = { GNUTLS_KX_DHE_DSS, GNUTLS_KX_RSA, - GNUTLS_KX_DHE_RSA, GNUTLS_KX_SRP, 0 }; - - gnutls_kx_set_priority(session, anon ? kx_anon_priority : kx_priority); - - if (gnutls_dh_params_init(&dh_params) != GNUTLS_E_SUCCESS) - throw AuthFailureException("gnutls_dh_params_init failed"); - - if (gnutls_dh_params_generate2(dh_params, DH_BITS) != GNUTLS_E_SUCCESS) - throw AuthFailureException("gnutls_dh_params_generate2 failed"); - - if (anon) { - if (gnutls_anon_allocate_server_credentials(&anon_cred) != GNUTLS_E_SUCCESS) - throw AuthFailureException("gnutls_anon_allocate_server_credentials failed"); - - gnutls_anon_set_server_dh_params(anon_cred, dh_params); - - if (gnutls_credentials_set(session, GNUTLS_CRD_ANON, anon_cred) - != GNUTLS_E_SUCCESS) - throw AuthFailureException("gnutls_credentials_set failed"); - - vlog.debug("Anonymous session has been set"); - - } else { - if (gnutls_certificate_allocate_credentials(&cert_cred) != GNUTLS_E_SUCCESS) - throw AuthFailureException("gnutls_certificate_allocate_credentials failed"); - - gnutls_certificate_set_dh_params(cert_cred, dh_params); - - if (gnutls_certificate_set_x509_key_file(cert_cred, certfile, keyfile, - GNUTLS_X509_FMT_PEM) != GNUTLS_E_SUCCESS) - throw AuthFailureException("load of key failed"); - - if (gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, cert_cred) - != GNUTLS_E_SUCCESS) - throw AuthFailureException("gnutls_credentials_set failed"); - - vlog.debug("X509 session has been set"); - - } - -} diff --git a/common/rfb/SSecurityTLSBase.h b/common/rfb/SSecurityTLSBase.h deleted file mode 100644 index d8f3adb9..00000000 --- a/common/rfb/SSecurityTLSBase.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (C) 2004 Red Hat Inc. - * Copyright (C) 2005 Martin Koegler - * Copyright (C) 2010 TigerVNC Team - * - * This is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this software; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - * USA. - */ - -#ifndef __S_SECURITY_TLSBASE_H__ -#define __S_SECURITY_TLSBASE_H__ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#ifndef HAVE_GNUTLS -#error "This header should not be included without HAVE_GNUTLS defined" -#endif - -#include -#include -#include -#include -#include - -namespace rfb { - - class SSecurityTLSBase : public SSecurity { - public: - SSecurityTLSBase(bool _anon); - virtual ~SSecurityTLSBase(); - virtual bool processMsg(SConnection* sc); - virtual const char* getUserName() const {return 0;} - virtual int getType() const { return anon ? secTypeTLSNone : secTypeX509None;} - - static StringParameter X509_CertFile; - static StringParameter X509_KeyFile; - - protected: - void shutdown(); - void setParams(gnutls_session session); - - private: - static void initGlobal(); - - gnutls_session session; - gnutls_dh_params dh_params; - gnutls_anon_server_credentials anon_cred; - gnutls_certificate_credentials cert_cred; - char *keyfile, *certfile; - - int type; - bool anon; - - rdr::InStream* fis; - rdr::OutStream* fos; - }; - -} - -#endif diff --git a/common/rfb/Security.cxx b/common/rfb/Security.cxx index 6462edcf..d2f40bec 100644 --- a/common/rfb/Security.cxx +++ b/common/rfb/Security.cxx @@ -41,7 +41,7 @@ #ifdef HAVE_GNUTLS #include #include -#include +#include #endif #include @@ -124,13 +124,13 @@ SSecurity* Security::GetSSecurity(U32 secType) case secTypeVeNCrypt: return new SSecurityVeNCrypt(this); #ifdef HAVE_GNUTLS case secTypeTLSNone: - return new SSecurityStack(secTypeTLSNone, new SSecurityTLSBase(true)); + return new SSecurityStack(secTypeTLSNone, new SSecurityTLS(true)); case secTypeTLSVnc: - return new SSecurityStack(secTypeTLSVnc, new SSecurityTLSBase(true), new SSecurityVncAuth()); + return new SSecurityStack(secTypeTLSVnc, new SSecurityTLS(true), new SSecurityVncAuth()); case secTypeX509None: - return new SSecurityStack(secTypeX509None, new SSecurityTLSBase(false)); + return new SSecurityStack(secTypeX509None, new SSecurityTLS(false)); case secTypeX509Vnc: - return new SSecurityStack(secTypeX509None, new SSecurityTLSBase(false), new SSecurityVncAuth()); + return new SSecurityStack(secTypeX509None, new SSecurityTLS(false), new SSecurityVncAuth()); #endif }