aboutsummaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
Diffstat (limited to 'common')
-rw-r--r--common/rfb/Makefile.am15
-rw-r--r--common/rfb/SSecurityPlain.cxx93
-rw-r--r--common/rfb/SSecurityPlain.h56
-rw-r--r--common/rfb/SSecurityStack.cxx67
-rw-r--r--common/rfb/SSecurityStack.h41
-rw-r--r--common/rfb/SSecurityTLS.cxx82
-rw-r--r--common/rfb/SSecurityTLS.h55
-rw-r--r--common/rfb/SSecurityTLSBase.cxx146
-rw-r--r--common/rfb/SSecurityTLSBase.h62
-rw-r--r--common/rfb/SSecurityVeNCrypt.cxx282
-rw-r--r--common/rfb/SSecurityVeNCrypt.h68
-rw-r--r--common/rfb/Security.cxx6
-rw-r--r--common/rfb/Security.h1
13 files changed, 967 insertions, 7 deletions
diff --git a/common/rfb/Makefile.am b/common/rfb/Makefile.am
index 138fec80..ee797a83 100644
--- a/common/rfb/Makefile.am
+++ b/common/rfb/Makefile.am
@@ -15,9 +15,10 @@ HDRS = Blacklist.h CapsContainer.h CapsList.h CConnection.h \
ScaledPixelBuffer.h ScaleFilters.h SConnection.h ScreenSet.h \
screenTypes.h SDesktop.h ServerCore.h SMsgHandler.h \
SMsgReader.h SMsgReaderV3.h SMsgWriter.h SMsgWriterV3.h \
- Security.h SSecurity.h SSecurityNone.h \
- SSecurityVncAuth.h Threading.h tightDecode.h TightDecoder.h \
- tightEncode.h TightEncoder.h TightPalette.h Timer.h \
+ Security.h SSecurity.h SSecurityNone.h SSecurityPlain.h \
+ SSecurityStack.h SSecurityTLS.h SSecurityTLSBase.h SSecurityVeNCrypt.h \
+ SSecurityVncAuth.h Threading.h tightDecode.h \
+ TightDecoder.h tightEncode.h TightEncoder.h TightPalette.h Timer.h \
TransImageGetter.h transInitTempl.h transTempl.h TrueColourMap.h \
UpdateTracker.h UserPasswdGetter.h util.h VNCSConnectionST.h \
VNCServer.h VNCServerST.h zrleDecode.h ZRLEDecoder.h zrleEncode.h \
@@ -34,15 +35,17 @@ librfb_la_SOURCES = $(HDRS) Blacklist.cxx CConnection.cxx CMsgHandler.cxx \
RREEncoder.cxx RREDecoder.cxx RawDecoder.cxx RawEncoder.cxx \
Region.cxx SConnection.cxx SMsgHandler.cxx \
SMsgReader.cxx SMsgReaderV3.cxx SMsgWriter.cxx SMsgWriterV3.cxx \
- ServerCore.cxx Security.cxx SSecurityVncAuth.cxx \
+ ServerCore.cxx Security.cxx SSecurityPlain.cxx SSecurityStack.cxx \
+ SSecurityTLS.cxx SSecurityTLSBase.cxx SSecurityVeNCrypt.cxx \
+ SSecurityVncAuth.cxx \
ScaledPixelBuffer.cxx ScaleFilters.cxx Timer.cxx TightDecoder.cxx \
TightEncoder.cxx TightPalette.cxx TransImageGetter.cxx \
UpdateTracker.cxx VNCSConnectionST.cxx \
VNCServerST.cxx ZRLEEncoder.cxx ZRLEDecoder.cxx encodings.cxx \
util.cxx
-librfb_la_CPPFLAGS = -I$(top_srcdir)/common -I$(top_srcdir)/win
-librfb_la_LIBADD =
+librfb_la_CPPFLAGS = -I$(top_srcdir)/common -I$(top_srcdir)/win @GNUTLS_CFLAGS@
+librfb_la_LIBADD = @GNUTLS_LIBS@
if INCLUDED_JPEG
librfb_la_CPPFLAGS += -I$(top_srcdir)/common/jpeg -I$(top_builddir)/common/jpeg
diff --git a/common/rfb/SSecurityPlain.cxx b/common/rfb/SSecurityPlain.cxx
new file mode 100644
index 00000000..d1f92646
--- /dev/null
+++ b/common/rfb/SSecurityPlain.cxx
@@ -0,0 +1,93 @@
+/* Copyright (C) 2005 Martin Koegler
+ * Copyright (C) 2006 OCCAM Financial Technology
+ *
+ * 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.
+ */
+
+#include <rfb/SSecurityPlain.h>
+#include <rfb/SConnection.h>
+#include <rfb/Exception.h>
+#include <rdr/InStream.h>
+
+using namespace rfb;
+
+StringParameter PasswordValidator::plainUsers
+("PlainUsers",
+ "Users permitted to access via Plain security type (including TLSPlain, X509Plain etc.)",
+ "");
+
+bool PasswordValidator::validUser(const char* username)
+{
+ CharArray users(strDup(plainUsers.getValueStr())), user;
+ while (users.buf) {
+ strSplit(users.buf, ',', &user.buf, &users.buf);
+#ifdef WIN32
+ if(0==stricmp(user.buf, "*"))
+ return true;
+ if(0==stricmp(user.buf, username))
+ return true;
+#else
+ if(!strcmp (user.buf, "*"))
+ return true;
+ if(!strcmp (user.buf, username))
+ return true;
+#endif
+ }
+ return false;
+}
+
+SSecurityPlain::SSecurityPlain(PasswordValidator* _valid)
+{
+ valid=_valid;
+ state=0;
+}
+
+bool SSecurityPlain::processMsg(SConnection* sc)
+{
+ rdr::InStream* is = sc->getInStream();
+ char* pw;
+ char *uname;
+ CharArray password;
+
+ if(state==0)
+ {
+ if(!is->checkNoWait(8))
+ return false;
+ ulen=is->readU32();
+ plen=is->readU32();
+ state=1;
+ }
+ if(state==1)
+ {
+ if(is->checkNoWait(ulen+plen+2))
+ return false;
+ state=2;
+ pw=new char[plen+1];
+ uname=new char[ulen+1];
+ username.replaceBuf(uname);
+ password.replaceBuf(pw);
+ is->readBytes(uname,ulen);
+ is->readBytes(pw,plen);
+ pw[plen]=0;
+ uname[ulen]=0;
+ plen=0;
+ if(!valid->validate(sc,uname,pw))
+ throw AuthFailureException("invalid password or username");
+ return true;
+ }
+ return true;
+}
+
diff --git a/common/rfb/SSecurityPlain.h b/common/rfb/SSecurityPlain.h
new file mode 100644
index 00000000..610ef5bd
--- /dev/null
+++ b/common/rfb/SSecurityPlain.h
@@ -0,0 +1,56 @@
+/* Copyright (C) 2005 Martin Koegler
+ * Copyright (C) 2006 OCCAM Financial Technology
+ * 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 __RFB_SSECURITYPLAIN_H__
+#define __RFB_SSECURITYPLAIN_H__
+
+#include <rfb/SConnection.h>
+#include <rfb/SSecurity.h>
+#include <rfb/SSecurityVeNCrypt.h>
+#include <rfb/util.h>
+#include <rfb/Configuration.h>
+
+namespace rfb {
+
+ class PasswordValidator {
+ public:
+ // validate username / password combination
+ bool validate(SConnection* sc, const char *username, const char *password) { return validUser(username) ? validateInternal(sc, username, password) : false; };
+ static StringParameter plainUsers;
+ protected:
+ virtual bool validateInternal(SConnection* sc, const char *username, const char *password)=0;
+ static bool validUser(const char* username);
+ };
+
+ class SSecurityPlain : public SSecurity {
+ public:
+ SSecurityPlain(PasswordValidator* valid);
+ virtual bool processMsg(SConnection* sc);
+ virtual int getType() const {return secTypePlain;};
+ virtual const char* getUserName() const { return username.buf; }
+
+ private:
+ PasswordValidator* valid;
+ unsigned int ulen,plen,state;
+ CharArray username;
+ };
+
+}
+#endif
+
diff --git a/common/rfb/SSecurityStack.cxx b/common/rfb/SSecurityStack.cxx
new file mode 100644
index 00000000..9ddc9f2f
--- /dev/null
+++ b/common/rfb/SSecurityStack.cxx
@@ -0,0 +1,67 @@
+/* Copyright (C) 2005 Martin Koegler
+ *
+ * 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.
+ */
+
+#include <rfb/SSecurityStack.h>
+
+using namespace rfb;
+
+SSecurityStack::SSecurityStack(int Type, SSecurity* s0, SSecurity* s1)
+ :state(0), state0(s0), state1(s1), type(Type) {}
+
+SSecurityStack::~SSecurityStack()
+{
+ if (state0)
+ delete state0;
+ if (state1)
+ delete state1;
+}
+
+bool SSecurityStack::processMsg(SConnection* cc)
+{
+ bool res = true;
+
+ if (state == 0) {
+ if (state0)
+ res = state0->processMsg(cc);
+ if (!res)
+ return res;
+ state++;
+ }
+
+ if (state == 1) {
+ if (state1)
+ res = state1->processMsg(cc);
+ if (!res)
+ return res;
+ state++;
+ }
+
+ return res;
+}
+
+const char* SSecurityStack::getUserName() const
+{
+ const char* c = 0;
+
+ if (state1 && !c)
+ c = state1->getUserName();
+ if (state0 && !c)
+ c = state0->getUserName();
+
+ return c;
+}
diff --git a/common/rfb/SSecurityStack.h b/common/rfb/SSecurityStack.h
new file mode 100644
index 00000000..0630dacd
--- /dev/null
+++ b/common/rfb/SSecurityStack.h
@@ -0,0 +1,41 @@
+/* Copyright (C) 2005 Martin Koegler
+ * Copyright (C) 2006 OCCAM Financial Technology
+ * 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 __RFB_SSECURITYSTACK_H__
+#define __RFB_SSECURITYSTACK_H__
+
+#include <rfb/SSecurity.h>
+
+namespace rfb {
+
+ class SSecurityStack : public SSecurity {
+ public:
+ SSecurityStack(int Type, SSecurity* s0 = 0, SSecurity* s1 = 0);
+ ~SSecurityStack();
+ virtual bool processMsg(SConnection* cc);
+ virtual int getType() const { return type; };
+ virtual const char* getUserName() const;
+ protected:
+ short state;
+ SSecurity* state0;
+ SSecurity* state1;
+ int type;
+ };
+}
+#endif
diff --git a/common/rfb/SSecurityTLS.cxx b/common/rfb/SSecurityTLS.cxx
new file mode 100644
index 00000000..f54158e7
--- /dev/null
+++ b/common/rfb/SSecurityTLS.cxx
@@ -0,0 +1,82 @@
+/*
+ * 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 <config.h>
+#endif
+
+#ifdef HAVE_GNUTLS
+
+#include <rfb/SSecurityTLS.h>
+#include <rfb/Exception.h>
+
+#define DH_BITS 1024
+
+#undef TLS_DEBUG
+
+using namespace rfb;
+
+SSecurityTLS::SSecurityTLS() : dh_params(0), anon_cred(0)
+{
+}
+
+SSecurityTLS::~SSecurityTLS()
+{
+ shutdown();
+ if (dh_params)
+ gnutls_dh_params_deinit(dh_params);
+ if (anon_cred)
+ gnutls_anon_free_server_credentials(anon_cred);
+}
+
+void SSecurityTLS::freeResources()
+{
+ 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;
+}
+
+void SSecurityTLS::setParams(gnutls_session session)
+{
+ static const int kx_priority[] = {GNUTLS_KX_ANON_DH, 0};
+ gnutls_kx_set_priority(session, kx_priority);
+
+ if (gnutls_anon_allocate_server_credentials(&anon_cred) != GNUTLS_E_SUCCESS)
+ throw AuthFailureException("gnutls_anon_allocate_server_credentials failed");
+
+ 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");
+
+ 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");
+
+}
+
+#endif /* HAVE_GNUTLS */
diff --git a/common/rfb/SSecurityTLS.h b/common/rfb/SSecurityTLS.h
new file mode 100644
index 00000000..f137f31b
--- /dev/null
+++ b/common/rfb/SSecurityTLS.h
@@ -0,0 +1,55 @@
+/*
+ * 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 <config.h>
+#endif
+
+#ifdef HAVE_GNUTLS
+
+#include <rfb/SSecurityTLSBase.h>
+#include <rfb/SSecurityVeNCrypt.h>
+
+namespace rfb {
+
+ class SSecurityTLS : public SSecurityTLSBase {
+ public:
+ SSecurityTLS();
+ virtual ~SSecurityTLS();
+ virtual int getType() const {return secTypeTLSNone;}
+ protected:
+ virtual void freeResources();
+ virtual void setParams(gnutls_session session);
+
+ private:
+ static void initGlobal();
+
+ gnutls_dh_params dh_params;
+ gnutls_anon_server_credentials anon_cred;
+ };
+
+}
+#endif /* HAVE_GNUTLS */
+
+#endif /* __S_SECURITY_TLS_H__ */
diff --git a/common/rfb/SSecurityTLSBase.cxx b/common/rfb/SSecurityTLSBase.cxx
new file mode 100644
index 00000000..2fec9bc1
--- /dev/null
+++ b/common/rfb/SSecurityTLSBase.cxx
@@ -0,0 +1,146 @@
+/*
+ * 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 <config.h>
+#endif
+
+#ifdef HAVE_GNUTLS
+
+#include <rfb/SSecurityTLSBase.h>
+#include <rfb/SConnection.h>
+#include <rfb/LogWriter.h>
+#include <rfb/Exception.h>
+#include <rdr/TLSInStream.h>
+#include <rdr/TLSOutStream.h>
+
+#define TLS_DEBUG
+
+using namespace rfb;
+
+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() : session(0)
+{
+ fis=0;
+ fos=0;
+}
+
+void SSecurityTLSBase::shutdown()
+{
+ if(session)
+ ;//gnutls_bye(session, GNUTLS_SHUT_RDWR);
+}
+
+
+SSecurityTLSBase::~SSecurityTLSBase()
+{
+ if (session) {
+ //gnutls_bye(session, GNUTLS_SHUT_RDWR);
+ gnutls_deinit(session);
+ }
+ if(fis)
+ delete fis;
+ if(fos)
+ delete fos;
+ /* FIXME: should be doing gnutls_global_deinit() at some point */
+}
+
+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));
+ gnutls_bye(session, GNUTLS_SHUT_RDWR);
+ freeResources();
+ gnutls_deinit(session);
+ session = 0;
+ 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;
+}
+
+#endif /* HAVE_GNUTLS */
diff --git a/common/rfb/SSecurityTLSBase.h b/common/rfb/SSecurityTLSBase.h
new file mode 100644
index 00000000..4daad217
--- /dev/null
+++ b/common/rfb/SSecurityTLSBase.h
@@ -0,0 +1,62 @@
+/*
+ * 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 <config.h>
+#endif
+
+#ifdef HAVE_GNUTLS
+
+#include <rfb/SSecurity.h>
+#include <rdr/InStream.h>
+#include <rdr/OutStream.h>
+#include <gnutls/gnutls.h>
+
+namespace rfb {
+
+ class SSecurityTLSBase : public SSecurity {
+ public:
+ SSecurityTLSBase();
+ virtual ~SSecurityTLSBase();
+ virtual bool processMsg(SConnection* sc);
+ virtual const char* getUserName() const {return 0;}
+
+ protected:
+ void shutdown();
+ virtual void freeResources()=0;
+ virtual void setParams(gnutls_session session)=0;
+
+ private:
+ static void initGlobal();
+
+ gnutls_session session;
+ rdr::InStream* fis;
+ rdr::OutStream* fos;
+ };
+
+}
+
+#endif /* HAVE_GNUTLS */
+
+#endif
diff --git a/common/rfb/SSecurityVeNCrypt.cxx b/common/rfb/SSecurityVeNCrypt.cxx
new file mode 100644
index 00000000..fc831482
--- /dev/null
+++ b/common/rfb/SSecurityVeNCrypt.cxx
@@ -0,0 +1,282 @@
+/*
+ * Copyright (C) 2005-2006 Martin Koegler
+ * Copyright (C) 2006 OCCAM Financial Technology
+ * 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.
+ */
+/*
+ * SSecurityVeNCrypt
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <rfb/SSecurityVeNCrypt.h>
+#include <rfb/Exception.h>
+#include <rfb/LogWriter.h>
+#include <rdr/InStream.h>
+#include <rdr/OutStream.h>
+#include <rfb/SSecurityVncAuth.h>
+#include <rfb/SSecurityTLS.h>
+
+using namespace rfb;
+using namespace rdr;
+using namespace std;
+
+static LogWriter vlog("SVeNCrypt");
+
+StringParameter SSecurityVeNCrypt::X509_CertFile
+("x509cert",
+ "specifies path to the x509 certificate in PEM format",
+ "", ConfServer);
+
+StringParameter SSecurityVeNCrypt::X509_KeyFile
+("x509key",
+ "specifies path to the key of the x509 certificate in PEM format",
+ "", ConfServer);
+
+StringParameter SSecurityVeNCrypt::secTypesStr
+("VeNCryptTypes",
+ "Specify which security scheme to use for VeNCrypt connections (TLSNone, "
+ "TLSVnc, TLSPlain, X509None, X509Vnc, X509Plain)",
+ "TLSVnc,TLSPlain,X509Vnc,X509Plain", ConfServer);
+
+SSecurityVeNCrypt::SSecurityVeNCrypt(void)
+{
+ ssecurityStack = NULL;
+ haveSentVersion = false;
+ haveRecvdMajorVersion = false;
+ haveRecvdMinorVersion = false;
+ majorVersion = 0;
+ minorVersion = 0;
+ haveSentTypes = false;
+ haveChosenType = false;
+ chosenType = secTypeVeNCrypt;
+ numTypes = 0;
+ subTypes = NULL;
+}
+
+SSecurityVeNCrypt::~SSecurityVeNCrypt()
+{
+ if (subTypes) {
+ delete [] subTypes;
+ subTypes = NULL;
+ }
+}
+
+bool SSecurityVeNCrypt::processMsg(SConnection* sc)
+{
+ rdr::InStream* is = sc->getInStream();
+ rdr::OutStream* os = sc->getOutStream();
+ rdr::U8 i;
+
+ /* VeNCrypt initialization */
+
+ /* Send the highest version we can support */
+ if (!haveSentVersion) {
+ os->writeU8(0);
+ os->writeU8(2);
+ haveSentVersion = true;
+ os->flush();
+
+ return false;
+ }
+
+ /* Receive back highest version that client can support (up to and including ours) */
+ if (!haveRecvdMajorVersion) {
+ majorVersion = is->readU8();
+ haveRecvdMajorVersion = true;
+
+ return false;
+ }
+
+ if (!haveRecvdMinorVersion) {
+ minorVersion = is->readU8();
+ haveRecvdMinorVersion = true;
+
+ /* WORD value with major version in upper 8 bits and minor version in lower 8 bits */
+ U16 Version = (((U16)majorVersion) << 8) | ((U16)minorVersion);
+
+ switch (Version) {
+ case 0x0000: /* 0.0 - The client cannot support us! */
+ case 0x0001: /* 0.1 Legacy VeNCrypt, not supported */
+ os->writeU8(0xFF); /* This is not OK */
+ os->flush();
+ throw AuthFailureException("The client cannot support the server's "
+ "VeNCrypt version");
+
+ case 0x0002: /* 0.2 */
+ os->writeU8(0); /* OK */
+ break;
+
+ default:
+ os->writeU8(0xFF); /* Not OK */
+ os->flush();
+ throw AuthFailureException("The client returned an unsupported VeNCrypt version");
+ }
+ }
+
+ /*
+ * send number of supported VeNCrypt authentication types (U8) followed
+ * by authentication types (U32s)
+ */
+ if (!haveSentTypes) {
+ list<U32> listSubTypes;
+ SSecurityVeNCrypt::getSecTypes(&listSubTypes);
+
+ numTypes = listSubTypes.size();
+ subTypes = new U32[numTypes];
+
+ for (i = 0; i < numTypes; i++) {
+ subTypes[i] = listSubTypes.front();
+ listSubTypes.pop_front();
+ }
+
+ if (numTypes) {
+ os->writeU8(numTypes);
+ for (i = 0; i < numTypes; i++)
+ os->writeU32(subTypes[i]);
+
+ os->flush();
+ haveSentTypes = true;
+ return false;
+ } else
+ throw AuthFailureException("There are no VeNCrypt sub-types to send to the client");
+ }
+
+ /* get type back from client (must be one of the ones we sent) */
+ if (!haveChosenType) {
+ is->check(4);
+ chosenType = is->readU32();
+
+ for (i = 0; i < numTypes; i++) {
+ if (chosenType == subTypes[i]) {
+ haveChosenType = true;
+ break;
+ }
+ }
+
+ if (!haveChosenType)
+ chosenType = secTypeInvalid;
+
+ /* Set up the stack according to the chosen type */
+ switch(chosenType) {
+ case secTypeTLSNone:
+ case secTypeTLSVnc:
+ case secTypeTLSPlain:
+ case secTypeX509None:
+ case secTypeX509Vnc:
+ case secTypeX509Plain:
+ ssecurityStack = SSecurityVeNCrypt::getSSecurityStack(chosenType);
+ break;
+ case secTypeInvalid:
+ case secTypeVeNCrypt: /* This would cause looping */
+ default:
+ throw AuthFailureException("No valid VeNCrypt sub-type");
+ }
+
+ }
+
+ /* continue processing the messages */
+ return ssecurityStack->processMsg(sc);
+}
+
+SSecurityStack* SSecurityVeNCrypt::getSSecurityStack(int secType)
+{
+ switch (secType) {
+ case secTypeTLSNone:
+ return new SSecurityStack(secTypeTLSNone, new SSecurityTLS());
+ case secTypeTLSVnc:
+ return new SSecurityStack(secTypeTLSVnc, new SSecurityTLS(), new SSecurityVncAuth());
+#if 0
+ /* Following types are not implemented, yet */
+ case secTypeTLSPlain:
+ case secTypeX509None:
+ case secTypeX509Vnc:
+ case secTypeX509Plain:
+#endif
+ default:
+ throw Exception("Bug in the SSecurityVeNCrypt::getSSecurityStack");
+ }
+}
+
+void SSecurityVeNCrypt::getSecTypes(list<U32>* secTypes)
+{
+ CharArray types;
+
+ types.buf = SSecurityVeNCrypt::secTypesStr.getData();
+ list<U32> configured = SSecurityVeNCrypt::parseSecTypes(types.buf);
+ list<U32>::iterator i;
+ for (i = configured.begin(); i != configured.end(); i++)
+ secTypes->push_back(*i);
+}
+
+U32 SSecurityVeNCrypt::secTypeNum(const char *name)
+{
+ if (strcasecmp(name, "TLSNone") == 0)
+ return secTypeTLSNone;
+ if (strcasecmp(name, "TLSVnc") == 0)
+ return secTypeTLSVnc;
+ if (strcasecmp(name, "TLSPlain") == 0)
+ return secTypeTLSPlain;
+ if (strcasecmp(name, "X509None") == 0)
+ return secTypeX509None;
+ if (strcasecmp(name, "X509Vnc") == 0)
+ return secTypeX509Vnc;
+ if (strcasecmp(name, "X509Plain") == 0)
+ return secTypeX509Plain;
+
+ return secTypeInvalid;
+}
+
+char* SSecurityVeNCrypt::secTypeName(U32 num)
+{
+ switch (num) {
+ case secTypePlain:
+ return "Plain";
+ case secTypeTLSNone:
+ return "TLSNone";
+ case secTypeTLSVnc:
+ return "TLSVnc";
+ case secTypeTLSPlain:
+ return "TLSPlain";
+ case secTypeX509None:
+ return "X509None";
+ case secTypeX509Vnc:
+ return "X509Vnc";
+ case secTypeX509Plain:
+ return "X509Plain";
+ default:
+ return "[unknown secType]";
+ }
+}
+
+list<U32> SSecurityVeNCrypt::parseSecTypes(const char *secTypes)
+{
+ list<U32> result;
+ CharArray types(strDup(secTypes)), type;
+ while (types.buf) {
+ strSplit(types.buf, ',', &type.buf, &types.buf);
+ int typeNum = SSecurityVeNCrypt::secTypeNum(type.buf);
+ if (typeNum != secTypeInvalid)
+ result.push_back(typeNum);
+ }
+ return result;
+}
+
+
diff --git a/common/rfb/SSecurityVeNCrypt.h b/common/rfb/SSecurityVeNCrypt.h
new file mode 100644
index 00000000..3d1e0e0a
--- /dev/null
+++ b/common/rfb/SSecurityVeNCrypt.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2005-2006 Martin Koegler
+ * Copyright (C) 2006 OCCAM Financial Technology
+ * 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.
+ */
+//
+// SSecurityVeNCrypt
+//
+
+#ifndef __SSECURITYVENCRYPT_H__
+#define __SSECURITYVENCRYPT_H__
+
+#include <rfb/SSecurityStack.h>
+#include <rfb/SConnection.h>
+
+namespace rfb {
+
+ /* VeNCrypt subtypes */
+ const int secTypePlain = 256;
+ const int secTypeTLSNone = 257;
+ const int secTypeTLSVnc = 258;
+ const int secTypeTLSPlain = 259;
+ const int secTypeX509None = 260;
+ const int secTypeX509Vnc = 261;
+ const int secTypeX509Plain = 262;
+
+ class SSecurityVeNCrypt : public SSecurity {
+ public:
+ SSecurityVeNCrypt(void);
+ ~SSecurityVeNCrypt();
+ virtual bool processMsg(SConnection* sc);// { return true; }
+ virtual int getType() const { return secTypeVeNCrypt; }
+ virtual const char* getUserName() const { return NULL; }
+
+ static StringParameter X509_CertFile, X509_KeyFile, secTypesStr;
+
+ protected:
+ static SSecurityStack* getSSecurityStack(int secType);
+
+ /* XXX Derive Security class and merge those functions appropriately ? */
+ static void getSecTypes(std::list<rdr::U32>* secTypes);
+ static rdr::U32 secTypeNum(const char *name);
+ static char* secTypeName(rdr::U32 num);
+ static std::list<rdr::U32> parseSecTypes(const char *types);
+
+ SSecurityStack *ssecurityStack;
+ bool haveSentVersion, haveRecvdMajorVersion, haveRecvdMinorVersion;
+ bool haveSentTypes, haveChosenType;
+ rdr::U8 majorVersion, minorVersion, numTypes;
+ rdr::U32 *subTypes, chosenType;
+ };
+}
+#endif
diff --git a/common/rfb/Security.cxx b/common/rfb/Security.cxx
index fac2d4bd..589eaa66 100644
--- a/common/rfb/Security.cxx
+++ b/common/rfb/Security.cxx
@@ -28,6 +28,7 @@
#include <rfb/Security.h>
#include <rfb/SSecurityNone.h>
#include <rfb/SSecurityVncAuth.h>
+#include <rfb/SSecurityVeNCrypt.h>
#include <rfb/util.h>
using namespace rdr;
@@ -80,6 +81,7 @@ SSecurity* Security::GetSSecurity(U8 secType)
switch (secType) {
case secTypeNone: return new SSecurityNone();
case secTypeVncAuth: return new SSecurityVncAuth();
+ case secTypeVeNCrypt: return new SSecurityVeNCrypt();
}
bail:
@@ -110,7 +112,8 @@ rdr::U8 rfb::secTypeNum(const char* name)
if (strcasecmp(name, "RA2") == 0) return secTypeRA2;
if (strcasecmp(name, "RA2ne") == 0) return secTypeRA2ne;
if (strcasecmp(name, "SSPI") == 0) return secTypeSSPI;
- if (strcasecmp(name, "SSPIne") == 0) return secTypeSSPIne;
+ if (strcasecmp(name, "SSPIne") == 0) return secTypeSSPIne;
+ if (strcasecmp(name, "VeNCrypt") == 0) return secTypeVeNCrypt;
return secTypeInvalid;
}
@@ -124,6 +127,7 @@ const char* rfb::secTypeName(rdr::U8 num)
case secTypeRA2ne: return "RA2ne";
case secTypeSSPI: return "SSPI";
case secTypeSSPIne: return "SSPIne";
+ case secTypeVeNCrypt: return "VeNCrypt";
default: return "[unknown secType]";
}
}
diff --git a/common/rfb/Security.h b/common/rfb/Security.h
index edbcd444..3231f1f5 100644
--- a/common/rfb/Security.h
+++ b/common/rfb/Security.h
@@ -44,6 +44,7 @@ namespace rfb {
const rdr::U8 secTypeTight = 16;
const rdr::U8 secTypeUltra = 17;
const rdr::U8 secTypeTLS = 18;
+ const rdr::U8 secTypeVeNCrypt= 19;
// result types