diff options
author | Adam Tkac <atkac@redhat.com> | 2010-04-23 14:12:18 +0000 |
---|---|---|
committer | Adam Tkac <atkac@redhat.com> | 2010-04-23 14:12:18 +0000 |
commit | 35e6d4c554e6f9fd9c1446db647fbaf3dbc6c087 (patch) | |
tree | a2e046e2b4d8802406380728d8cb20cc3a71f55d /common/rdr | |
parent | 29da2d89339689ef95da1bb1a3e538efd4cf788a (diff) | |
download | tigervnc-35e6d4c554e6f9fd9c1446db647fbaf3dbc6c087.tar.gz tigervnc-35e6d4c554e6f9fd9c1446db647fbaf3dbc6c087.zip |
[Development] Implement secure TLS streams.
git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@4044 3789f03b-4d11-0410-bbf8-ca57d06f2519
Diffstat (limited to 'common/rdr')
-rw-r--r-- | common/rdr/Exception.cxx | 13 | ||||
-rw-r--r-- | common/rdr/Exception.h | 3 | ||||
-rw-r--r-- | common/rdr/Makefile.am | 8 | ||||
-rw-r--r-- | common/rdr/TLSException.cxx | 48 | ||||
-rw-r--r-- | common/rdr/TLSException.h | 35 | ||||
-rw-r--r-- | common/rdr/TLSInStream.cxx | 111 | ||||
-rw-r--r-- | common/rdr/TLSInStream.h | 57 | ||||
-rw-r--r-- | common/rdr/TLSOutStream.cxx | 106 | ||||
-rw-r--r-- | common/rdr/TLSOutStream.h | 58 |
9 files changed, 436 insertions, 3 deletions
diff --git a/common/rdr/Exception.cxx b/common/rdr/Exception.cxx index 72a03e11..fd40582f 100644 --- a/common/rdr/Exception.cxx +++ b/common/rdr/Exception.cxx @@ -1,4 +1,6 @@ /* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. + * Copyright (C) 2004 Red Hat Inc. + * 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 @@ -15,7 +17,13 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, * USA. */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + #include <rdr/Exception.h> +#include <rdr/TLSException.h> #ifdef _WIN32 #include <tchar.h> #include <winsock2.h> @@ -26,6 +34,10 @@ #include <string.h> +#ifdef HAVE_GNUTLS +#include <gnutls/gnutls.h> +#endif + using namespace rdr; Exception::Exception(const char *format, ...) { @@ -83,3 +95,4 @@ SystemException::SystemException(const char* s, int err_) strncat(str_, buf, len-1-strlen(str_)); strncat(str_, ")", len-1-strlen(str_)); } + diff --git a/common/rdr/Exception.h b/common/rdr/Exception.h index ef6b3689..ea10f9d7 100644 --- a/common/rdr/Exception.h +++ b/common/rdr/Exception.h @@ -1,4 +1,6 @@ /* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. + * Copyright (C) 2004 Red Hat Inc. + * 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 @@ -45,6 +47,7 @@ namespace rdr { struct FrameException : public Exception { FrameException(const char* s="Frame exception") : Exception(s) {} }; + } #endif diff --git a/common/rdr/Makefile.am b/common/rdr/Makefile.am index d25f77ce..bd23cbfe 100644 --- a/common/rdr/Makefile.am +++ b/common/rdr/Makefile.am @@ -3,11 +3,13 @@ noinst_LTLIBRARIES = librdr.la HDRS = Exception.h FdInStream.h FdOutStream.h FixedMemOutStream.h \ HexInStream.h HexOutStream.h InStream.h MemInStream.h \ MemOutStream.h msvcwarning.h OutStream.h RandomStream.h \ - SubstitutingInStream.h types.h ZlibInStream.h ZlibOutStream.h + SubstitutingInStream.h types.h TLSException.h TLSInStream.h \ + TLSOutStream.h ZlibInStream.h ZlibOutStream.h librdr_la_SOURCES = $(HDRS) Exception.cxx FdInStream.cxx FdOutStream.cxx \ - InStream.cxx RandomStream.cxx ZlibInStream.cxx ZlibOutStream.cxx \ - HexInStream.cxx HexOutStream.cxx + HexInStream.cxx HexOutStream.cxx InStream.cxx RandomStream.cxx \ + TLSException.cxx TLSInStream.cxx TLSOutStream.cxx ZlibInStream.cxx \ + ZlibOutStream.cxx librdr_la_CPPFLAGS = -I$(top_srcdir)/common librdr_la_LIBADD = diff --git a/common/rdr/TLSException.cxx b/common/rdr/TLSException.cxx new file mode 100644 index 00000000..3d39d790 --- /dev/null +++ b/common/rdr/TLSException.cxx @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2004 Red Hat Inc. + * 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 + +#include <rdr/TLSException.h> + +#include <string.h> +#include <stdio.h> +#ifdef HAVE_GNUTLS +#include <gnutls/gnutls.h> +#endif + +using namespace rdr; + +#ifdef HAVE_GNUTLS +TLSException::TLSException(const char* s, int err_) + : Exception(s), err(err_) +{ + strncat(str_, ": ", len-1-strlen(str_)); + strncat(str_, gnutls_strerror(err), len-1-strlen(str_)); + strncat(str_, " (", len-1-strlen(str_)); + char buf[20]; + sprintf(buf,"%d",err); + strncat(str_, buf, len-1-strlen(str_)); + strncat(str_, ")", len-1-strlen(str_)); +} +#endif /* HAVE_GNUTLS */ + diff --git a/common/rdr/TLSException.h b/common/rdr/TLSException.h new file mode 100644 index 00000000..b519bfef --- /dev/null +++ b/common/rdr/TLSException.h @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2004 Red Hat Inc. + * 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 __RDR_TLSEXCEPTION_H__ +#define __RDR_TLSEXCEPTION_H__ + +#include <rdr/Exception.h> + +namespace rdr { + + struct TLSException : public Exception { + int err; + TLSException(const char* s, int err_); + }; + +} + +#endif diff --git a/common/rdr/TLSInStream.cxx b/common/rdr/TLSInStream.cxx new file mode 100644 index 00000000..f6bf334c --- /dev/null +++ b/common/rdr/TLSInStream.cxx @@ -0,0 +1,111 @@ +/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. + * 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 + +#include <rdr/Exception.h> +#include <rdr/TLSException.h> +#include <rdr/TLSInStream.h> +#include <errno.h> + +#ifdef HAVE_GNUTLS +using namespace rdr; + +enum { DEFAULT_BUF_SIZE = 16384 }; + +ssize_t rdr::gnutls_InStream_pull(gnutls_transport_ptr str, void* data, + size_t size) +{ + InStream* in= (InStream*) str; + + if (!in->check(1, 1, false)) { + errno=EAGAIN; + return -1; + } + + if (in->getend() - in->getptr() < size) + size = in->getend() - in->getptr(); + + in->readBytes(data, size); + + return size; +} + +TLSInStream::TLSInStream(InStream* _in, gnutls_session _session) + : session(_session), in(_in), bufSize(DEFAULT_BUF_SIZE), offset(0) +{ + ptr = end = start = new U8[bufSize]; +} + +TLSInStream::~TLSInStream() +{ + delete[] start; +} + +int TLSInStream::pos() +{ + return offset + ptr - start; +} + +int TLSInStream::overrun(int itemSize, int nItems, bool wait) +{ + if (itemSize > bufSize) + throw Exception("TLSInStream overrun: max itemSize exceeded"); + + if (end - ptr != 0) + memmove(start, ptr, end - ptr); + + offset += ptr - start; + end -= ptr - start; + ptr = start; + + while (end < start + itemSize) { + int n = readTLS((U8*) end, start + bufSize - end, wait); + if (!wait && n == 0) + return 0; + end += n; + } + + if (itemSize * nItems > end - ptr) + nItems = (end - ptr) / itemSize; + + return nItems; +} + +int TLSInStream::readTLS(U8* buf, int len, bool wait) +{ + int n; + + n = in->check(1, 1, wait); + if (n == 0) + return 0; + + n = gnutls_record_recv(session, (void *) buf, len); + if (n == GNUTLS_E_INTERRUPTED || n == GNUTLS_E_AGAIN) + return 0; + + if (n < 0) throw TLSException("readTLS", n); + + return n; +} + +#endif diff --git a/common/rdr/TLSInStream.h b/common/rdr/TLSInStream.h new file mode 100644 index 00000000..7fad6fa5 --- /dev/null +++ b/common/rdr/TLSInStream.h @@ -0,0 +1,57 @@ +/* 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 __RDR_TLSINSTREAM_H__ +#define __RDR_TLSINSTREAM_H__ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#ifdef HAVE_GNUTLS + +#include <gnutls/gnutls.h> +#include <rdr/InStream.h> + +namespace rdr { + + class TLSInStream : public InStream { + public: + TLSInStream(InStream* in, gnutls_session session); + virtual ~TLSInStream(); + + int pos(); + + private: + int overrun(int itemSize, int nItems, bool wait); + int readTLS(U8* buf, int len, bool wait); + + gnutls_session session; + InStream* in; + int bufSize; + int offset; + U8* start; + }; + + ssize_t gnutls_InStream_pull(gnutls_transport_ptr,void*, size_t); + +}; + +#endif +#endif diff --git a/common/rdr/TLSOutStream.cxx b/common/rdr/TLSOutStream.cxx new file mode 100644 index 00000000..59edf150 --- /dev/null +++ b/common/rdr/TLSOutStream.cxx @@ -0,0 +1,106 @@ +/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. + * 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 + +#include <rdr/Exception.h> +#include <rdr/TLSException.h> +#include <rdr/TLSOutStream.h> + +#ifdef HAVE_GNUTLS +using namespace rdr; + +enum { DEFAULT_BUF_SIZE = 16384 }; + +ssize_t rdr::gnutls_OutStream_push(gnutls_transport_ptr str, const void* data, + size_t size) +{ + OutStream* out = (OutStream*) str; + out->writeBytes(data, size); + out->flush(); + return size; +} + +TLSOutStream::TLSOutStream(OutStream* _out, gnutls_session _session) + : session(_session), out(_out), bufSize(DEFAULT_BUF_SIZE), offset(0) +{ + ptr = start = new U8[bufSize]; + end = start + bufSize; +} + +TLSOutStream::~TLSOutStream() +{ +#if 0 + try { +// flush(); + } catch (Exception&) { + } +#endif + delete [] start; +} + +int TLSOutStream::length() +{ + return offset + ptr - start; +} + +void TLSOutStream::flush() +{ + U8* sentUpTo = start; + while (sentUpTo < ptr) { + int n = writeTLS(sentUpTo, ptr - sentUpTo); + sentUpTo += n; + offset += n; + } + + ptr = start; + out->flush(); +} + +int TLSOutStream::overrun(int itemSize, int nItems) +{ + if (itemSize > bufSize) + throw Exception("TLSOutStream overrun: max itemSize exceeded"); + + flush(); + + if (itemSize * nItems > end - ptr) + nItems = (end - ptr) / itemSize; + + return nItems; +} + +int TLSOutStream::writeTLS(const U8* data, int length) +{ + int n; + + n = gnutls_record_send(session, data, length); + if (n == GNUTLS_E_INTERRUPTED || n == GNUTLS_E_AGAIN) + return 0; + + if (n < 0) + throw TLSException("writeTLS", n); + + return n; +} + +#endif diff --git a/common/rdr/TLSOutStream.h b/common/rdr/TLSOutStream.h new file mode 100644 index 00000000..5eb512ec --- /dev/null +++ b/common/rdr/TLSOutStream.h @@ -0,0 +1,58 @@ +/* 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 __RDR_TLSOUTSTREAM_H__ +#define __RDR_TLSOUTSTREAM_H__ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#ifdef HAVE_GNUTLS +#include <gnutls/gnutls.h> +#include <rdr/OutStream.h> + +namespace rdr { + + class TLSOutStream : public OutStream { + public: + TLSOutStream(OutStream* out, gnutls_session session); + virtual ~TLSOutStream(); + + void flush(); + int length(); + + protected: + int overrun(int itemSize, int nItems); + + private: + int writeTLS(const U8* data, int length); + + gnutls_session session; + OutStream* out; + int bufSize; + U8* start; + int offset; + }; + + ssize_t gnutls_OutStream_push(gnutls_transport_ptr, const void*, size_t); +}; + +#endif +#endif |