Browse Source

Port required changes for TDE's krfb server from the old libvnc version embedded with krfb

pull/1/head
Timothy Pearson 7 years ago
parent
commit
366c7e7c21
  1. 1
      AUTHORS
  2. 125
      CMakeLists.txt
  3. 188
      libvncserver/main.c
  4. 11
      libvncserver/rfbserver.c
  5. 10
      rfb/rfb.h
  6. 8
      rfb/rfbproto.h

1
AUTHORS

@ -40,6 +40,7 @@ Rostislav Lisovy, Oliver Loch, Raphael Kubo da Costa, Amandeep Singh,
Brian Bidulock, Daniel Cohen Gindi, David Verbeiren, Luca Falavigna,
Matthias Treydte, Nicolas Ruff, Robbert Klarenbeek and Floris Bos.
Modified version for TDE's krfb/krdc applications created and maintained by Timothy Pearson.
Probably I forgot quite a few people sending a patch here and there, which
really made a difference. Without those, some obscure bugs still would

125
CMakeLists.txt

@ -104,11 +104,11 @@ if(GNUTLS_FOUND)
set(LIBVNCSERVER_WITH_CLIENT_TLS 1)
option(LIBVNCSERVER_WITH_WEBSOCKETS "Build with websockets support (gnutls)" ON)
set(WEBSOCKET_LIBRARIES ${RESOLV_LIB} ${GNUTLS_LIBRARIES})
set(WSSRCS ${LIBVNCSERVER_DIR}/rfbssl_gnutls ${LIBVNCSERVER_DIR}/rfbcrypto_gnutls)
set(WSSRCS ${LIBVNCSERVER_DIR}/rfbssl_gnutls.c ${LIBVNCSERVER_DIR}/rfbcrypto_gnutls.c)
elseif(OPENSSL_FOUND)
option(LIBVNCSERVER_WITH_WEBSOCKETS "Build with websockets support (openssl)" ON)
set(WEBSOCKET_LIBRARIES ${RESOLV_LIB} ${OPENSSL_LIBRARIES})
set(WSSRCS ${LIBVNCSERVER_DIR}/rfbssl_openssl ${LIBVNCSERVER_DIR}/rfbcrypto_openssl)
set(WSSRCS ${LIBVNCSERVER_DIR}/rfbssl_openssl.c ${LIBVNCSERVER_DIR}/rfbcrypto_openssl.c)
else()
option(LIBVNCSERVER_WITH_WEBSOCKETS "Build with websockets support (no ssl)" ON)
set(WEBSOCKET_LIBRARIES ${RESOLV_LIB})
@ -167,11 +167,11 @@ TEST_BIG_ENDIAN(LIBVNCSERVER_WORDS_BIGENDIAN)
# LIBVNCSERVER_ENOENT_WORKAROUND
# inline
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/rfb/rfbconfig.h.cmake ${CMAKE_BINARY_DIR}/rfb/rfbconfig.h)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/rfb/rfbint.h.cmake ${CMAKE_BINARY_DIR}/rfb/rfbint.h)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/rfb/rfbconfig.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/rfb/rfbconfig.h)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/rfb/rfbint.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/rfb/rfbint.h)
set(LIBVNCSERVER_SOURCES
${LIBVNCSERVER_DIR}/main.c
${LIBVNCSERVER_DIR}/main.cc
${LIBVNCSERVER_DIR}/rfbserver.c
${LIBVNCSERVER_DIR}/rfbregion.c
${LIBVNCSERVER_DIR}/auth.c
@ -269,111 +269,20 @@ if(LIBVNCSERVER_WITH_WEBSOCKETS)
)
endif(LIBVNCSERVER_WITH_WEBSOCKETS)
##### tdevncclient (static) ########################
add_library(vncclient SHARED ${LIBVNCCLIENT_SOURCES})
add_library(vncserver SHARED ${LIBVNCSERVER_SOURCES})
if(WIN32)
set(ADDITIONAL_LIBS ${ADDITIONAL_LIBS} ws2_32)
endif(WIN32)
target_link_libraries(vncclient
${ADDITIONAL_LIBS}
${ZLIB_LIBRARIES}
${JPEG_LIBRARIES}
${GNUTLS_LIBRARIES}
)
target_link_libraries(vncserver
${ADDITIONAL_LIBS}
${ZLIB_LIBRARIES}
${JPEG_LIBRARIES}
${PNG_LIBRARIES}
${WEBSOCKET_LIBRARIES}
)
SET_TARGET_PROPERTIES(vncclient vncserver
PROPERTIES SOVERSION "0.0.0"
)
# tests
set(LIBVNCSERVER_TESTS
backchannel
camera
colourmaptest
example
fontsel
pnmshow
pnmshow24
regiontest
rotate
simple
simple15
storepasswd
vncev
)
if(Threads_FOUND)
set(LIBVNCSERVER_TESTS
${LIBVNCSERVER_TESTS}
blooptest
)
endif(Threads_FOUND)
if(TIGHTVNC_FILETRANSFER)
set(LIBVNCSERVER_TESTS
${LIBVNCSERVER_TESTS}
filetransfer
)
endif(TIGHTVNC_FILETRANSFER)
if(MACOS)
set(LIBVNCSERVER_TESTS
${LIBVNCSERVER_TESTS}
mac
)
endif(MACOS)
set(LIBVNCCLIENT_TESTS
backchannel
ppmtest
tde_add_library( tdevncclient STATIC_PIC AUTOMOC
SOURCES
${LIBVNCCLIENT_SOURCES}
LINK
${ADDITIONAL_LIBS} ${ZLIB_LIBRARIES} ${JPEG_LIBRARIES} ${GNUTLS_LIBRARIES}
)
if(SDL_FOUND)
include_directories(${SDL_INCLUDE_DIR})
set(LIBVNCCLIENT_TESTS
${LIBVNCCLIENT_TESTS}
SDLvncviewer
)
set(SDLvncviewer_EXTRA_SOURCES scrap.c)
endif(SDL_FOUND)
##### tdevncserver (static) ########################
if(HAVE_FFMPEG)
set(LIBVNCCLIENT_TESTS
${LIBVNCCLIENT_TESTS}
vnc2mpg
)
endif(HAVE_FFMPEG)
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/examples)
foreach(test ${LIBVNCSERVER_TESTS})
add_executable(examples/${test} ${LIBVNCSRVTEST_DIR}/${test}.c)
target_link_libraries(examples/${test} vncserver ${CMAKE_THREAD_LIBS_INIT})
endforeach(test ${LIBVNCSERVER_TESTS})
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/client_examples)
foreach(test ${LIBVNCCLIENT_TESTS})
add_executable(client_examples/${test} ${LIBVNCCLITEST_DIR}/${test}.c ${LIBVNCCLITEST_DIR}/${${test}_EXTRA_SOURCES} )
target_link_libraries(client_examples/${test} vncclient ${CMAKE_THREAD_LIBS_INIT} ${X11_LIBRARIES} ${SDL_LIBRARY} ${FFMPEG_LIBRARIES})
endforeach(test ${LIBVNCCLIENT_TESTS})
install_targets(/lib vncserver)
install_targets(/lib vncclient)
install_files(/include/rfb FILES
rfb/keysym.h
rfb/rfb.h
rfb/rfbclient.h
rfb/rfbconfig.h
rfb/rfbint.h
rfb/rfbproto.h
rfb/rfbregion.h
tde_add_library( tdevncserver STATIC_PIC AUTOMOC
SOURCES
${LIBVNCSERVER_SOURCES}
LINK
${ADDITIONAL_LIBS} ${ZLIB_LIBRARIES} ${JPEG_LIBRARIES} ${PNG_LIBRARIES} ${WEBSOCKET_LIBRARIES}
)

188
libvncserver/main.c

@ -2,6 +2,7 @@
* This file is called main.c, because it contains most of the new functions
* for use with LibVNCServer.
*
* Copyright (C) 2015 Timothy Pearson <kb9vqf@pearsoncomputing.net>.
* LibVNCServer (C) 2001 Johannes E. Schindelin <Johannes.Schindelin@gmx.de>
* Original OSXvnc (C) 2001 Dan McGuirk <mcguirk@incompleteness.net>.
* Original Xvnc (C) 1999 AT&T Laboratories Cambridge.
@ -10,33 +11,56 @@
* see GPL (latest version) for full details
*/
#ifdef __STRICT_ANSI__
#define _BSD_SOURCE
#endif
#include <rfb/rfb.h>
#include <rfb/rfbregion.h>
#include "private.h"
extern "C" {
#ifdef __STRICT_ANSI__
#define _BSD_SOURCE
#endif
#include <rfb/rfb.h>
#include <rfb/rfbregion.h>
#include "private.h"
#include <stdarg.h>
#include <errno.h>
#ifndef false
#define false 0
#define true -1
#endif
#ifdef LIBVNCSERVER_HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifndef WIN32
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#endif
#include <signal.h>
#include <time.h>
}
#include <stdarg.h>
#include <errno.h>
#include <ntqobject.h>
#include <ntqvariant.h>
#include <ntqtimer.h>
#include <ntqthread.h>
#ifndef false
#define false 0
#define true -1
#endif
#include "main.h"
#ifdef LIBVNCSERVER_HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
ControlPipeHandlerObject* mControlPipeHandler = NULL;
TQEventLoopThread* mControlPipeHandlerThread = NULL;
#ifndef WIN32
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#endif
OnHoldClientHandlerObject* mOnHoldClientHandler = NULL;
TQEventLoopThread* mOnHoldClientHandlerThread = NULL;
#include <signal.h>
#include <time.h>
extern "C" {
/* from scale.c */
void rfbScaledScreenUpdate(rfbScreenInfoPtr screen, int x1, int y1, int x2, int y2);
/* from rfbserver.c */
rfbClientIteratorPtr rfbGetClientIteratorWithClosed(rfbScreenInfoPtr rfbScreen);
}
static int extMutex_initialized = 0;
static int logMutex_initialized = 0;
@ -169,7 +193,7 @@ rfbBool rfbEnableExtension(rfbClientPtr cl, rfbProtocolExtension* extension,
if(extData->extension == extension)
return FALSE;
extData = calloc(sizeof(rfbExtensionData),1);
extData = (rfbExtensionData*)calloc(sizeof(rfbExtensionData),1);
extData->extension = extension;
extData->data = data;
extData->next = cl->extensions;
@ -445,6 +469,7 @@ clientOutput(void *data)
rfbClientPtr cl = (rfbClientPtr)data;
rfbBool haveUpdate;
sraRegion* updateRegion;
cl->onHold = FALSE;
while (1) {
haveUpdate = false;
@ -453,7 +478,7 @@ clientOutput(void *data)
/* Client has disconnected. */
return NULL;
}
if (cl->state != RFB_NORMAL || cl->onHold) {
if (cl->state != _rfbClientRec::RFB_NORMAL || cl->onHold) {
/* just sleep until things get normal */
usleep(cl->screen->deferUpdateTime * 1000);
continue;
@ -509,8 +534,13 @@ static void *
clientInput(void *data)
{
rfbClientPtr cl = (rfbClientPtr)data;
pthread_t output_thread;
pthread_create(&output_thread, NULL, clientOutput, (void *)cl);
/* Start output thread */
TQEventLoopThread* clientOutputHandlerThread = new TQEventLoopThread();
ClientOutputHandlerObject* clientOutputHandler = new ClientOutputHandlerObject();
clientOutputHandler->d = cl;
clientOutputHandler->moveToThread(clientOutputHandlerThread);
TQTimer::singleShot(0, clientOutputHandler, SLOT(run()));
clientOutputHandlerThread->start();
while (1) {
fd_set rfds, wfds, efds;
@ -557,7 +587,11 @@ clientInput(void *data)
LOCK(cl->updateMutex);
TSIGNAL(cl->updateCond);
UNLOCK(cl->updateMutex);
IF_PTHREADS(pthread_join(output_thread, NULL));
clientOutputHandlerThread->wait();
delete clientOutputHandlerThread;
clientOutputHandlerThread = NULL;
delete clientOutputHandler;
clientOutputHandler = NULL;
rfbClientConnectionGone(cl);
@ -574,6 +608,15 @@ listenerRun(void *data)
socklen_t len;
fd_set listen_fds; /* temp file descriptor list for select() */
if (screen->inetdSock != -1) {
cl = rfbNewClient(screen, screen->inetdSock);
if (cl && !cl->onHold)
rfbStartOnHoldClient(cl);
else if (screen->inetdDisconnectHook && !cl)
screen->inetdDisconnectHook();
return NULL;
}
/* TODO: this thread wont die by restarting the server */
/* TODO: HTTP is not handled */
while (1) {
@ -607,7 +650,12 @@ listenerRun(void *data)
void
rfbStartOnHoldClient(rfbClientPtr cl)
{
pthread_create(&cl->client_thread, NULL, clientInput, (void *)cl);
mOnHoldClientHandlerThread = new TQEventLoopThread();
mOnHoldClientHandler = new OnHoldClientHandlerObject();
mOnHoldClientHandler->d = cl;
mOnHoldClientHandler->moveToThread(mOnHoldClientHandlerThread);
TQTimer::singleShot(0, mOnHoldClientHandler, SLOT(run()));
mOnHoldClientHandlerThread->start();
}
#else
@ -702,7 +750,7 @@ static rfbCursorPtr rfbDefaultGetCursorPtr(rfbClientPtr cl)
static rfbBool rfbDefaultPasswordCheck(rfbClientPtr cl,const char* response,int len)
{
int i;
char *passwd=rfbDecryptPasswdFromFile(cl->screen->authPasswdData);
char *passwd=rfbDecryptPasswdFromFile((char*)cl->screen->authPasswdData);
if(!passwd) {
rfbErr("Couldn't read password file: %s\n",cl->screen->authPasswdData);
@ -810,7 +858,7 @@ rfbScreenInfoPtr rfbGetScreen(int* argc,char** argv,
int width,int height,int bitsPerSample,int samplesPerPixel,
int bytesPerPixel)
{
rfbScreenInfoPtr screen=calloc(sizeof(rfbScreenInfo),1);
rfbScreenInfoPtr screen=(rfbScreenInfoPtr)calloc(sizeof(rfbScreenInfo),1);
if (! logMutex_initialized) {
INIT_MUTEX(logMutex);
@ -919,6 +967,7 @@ rfbScreenInfoPtr rfbGetScreen(int* argc,char** argv,
screen->setTranslateFunction = rfbSetTranslateFunction;
screen->newClientHook = rfbDefaultNewClientHook;
screen->displayHook = NULL;
screen->inetdDisconnectHook = NULL;
screen->displayFinishedHook = NULL;
screen->getKeyboardLedStateHook = NULL;
screen->xvpHook = NULL;
@ -1015,7 +1064,22 @@ void rfbScreenCleanup(rfbScreenInfoPtr screen)
cl1=cl;
}
rfbReleaseClientIterator(i);
if (mOnHoldClientHandlerThread) {
mOnHoldClientHandlerThread->exit();
delete mOnHoldClientHandlerThread;
mOnHoldClientHandlerThread = NULL;
delete mOnHoldClientHandler;
mOnHoldClientHandler = NULL;
}
if (mControlPipeHandlerThread) {
mControlPipeHandlerThread->exit();
delete mControlPipeHandlerThread;
mControlPipeHandlerThread = NULL;
delete mControlPipeHandler;
mControlPipeHandler = NULL;
}
#define FREE_IF(x) if(screen->x) free(screen->x)
FREE_IF(colourMap.data.bytes);
FREE_IF(underCursorBuffer);
@ -1180,12 +1244,15 @@ void rfbRunEventLoop(rfbScreenInfoPtr screen, long usec, rfbBool runInBackground
{
if(runInBackground) {
#ifdef LIBVNCSERVER_HAVE_LIBPTHREAD
pthread_t listener_thread;
screen->backgroundLoop = TRUE;
pthread_create(&listener_thread, NULL, listenerRun, screen);
return;
screen->backgroundLoop = TRUE;
mControlPipeHandlerThread = new TQEventLoopThread();
mControlPipeHandler = new ControlPipeHandlerObject();
mControlPipeHandler->d = screen;
mControlPipeHandler->moveToThread(mControlPipeHandlerThread);
TQTimer::singleShot(0, mControlPipeHandler, SLOT(run()));
mControlPipeHandlerThread->start();
return;
#else
rfbErr("Can't run in background, because I don't have PThreads!\n");
return;
@ -1198,3 +1265,50 @@ void rfbRunEventLoop(rfbScreenInfoPtr screen, long usec, rfbBool runInBackground
while(rfbIsActive(screen))
rfbProcessEvents(screen,usec);
}
ControlPipeHandlerObject::ControlPipeHandlerObject() : TQObject() {
//
}
ControlPipeHandlerObject::~ControlPipeHandlerObject() {
//
}
void ControlPipeHandlerObject::run(void) {
listenerRun(d);
// Terminate thread
TQThread::exit();
}
OnHoldClientHandlerObject::OnHoldClientHandlerObject() : TQObject() {
//
}
OnHoldClientHandlerObject::~OnHoldClientHandlerObject() {
//
}
void OnHoldClientHandlerObject::run(void) {
clientInput(d);
// Terminate thread
TQThread::exit();
}
ClientOutputHandlerObject::ClientOutputHandlerObject() : TQObject() {
//
}
ClientOutputHandlerObject::~ClientOutputHandlerObject() {
//
}
void ClientOutputHandlerObject::run(void) {
clientOutput(d);
// Terminate thread
TQThread::exit();
}
#include "main.moc"

11
libvncserver/rfbserver.c

@ -3,6 +3,7 @@
*/
/*
* Copyright (C) 2015 Timothy Pearson <kb9vqf@pearsoncomputing.net>.
* Copyright (C) 2011-2012 D. R. Commander
* Copyright (C) 2005 Rohit Kumar, Johannes E. Schindelin
* Copyright (C) 2002 RealVNC Ltd.
@ -328,6 +329,7 @@ rfbNewTCPOrUDPClient(rfbScreenInfoPtr rfbScreen,
cl->clientData = NULL;
cl->clientGoneHook = rfbDoNothingWithClient;
cl->negotiationFinishedHook = rfbDoNothingWithClient;
if(isUDP) {
rfbLog(" accepted UDP client\n");
@ -434,6 +436,7 @@ rfbNewTCPOrUDPClient(rfbScreenInfoPtr rfbScreen,
cl->enableCursorPosUpdates = FALSE;
cl->useRichCursorEncoding = FALSE;
cl->enableLastRectEncoding = FALSE;
cl->disableBackground = FALSE;
cl->enableKeyboardLedState = FALSE;
cl->enableSupportedMessages = FALSE;
cl->enableSupportedEncodings = FALSE;
@ -2093,6 +2096,7 @@ rfbProcessClientNormalMessage(rfbClientPtr cl)
cl->enableCursorShapeUpdates = FALSE;
cl->enableCursorShapeUpdates = FALSE;
cl->enableLastRectEncoding = FALSE;
cl->disableBackground = FALSE;
cl->enableKeyboardLedState = FALSE;
cl->enableSupportedMessages = FALSE;
cl->enableSupportedEncodings = FALSE;
@ -2181,6 +2185,11 @@ rfbProcessClientNormalMessage(rfbClientPtr cl)
cl->enableLastRectEncoding = TRUE;
}
break;
case rfbEncodingBackground:
rfbLog("Disabling background for client "
"%s\n", cl->host);
cl->disableBackground = TRUE;
break;
case rfbEncodingNewFBSize:
if (!cl->useNewFBSize) {
rfbLog("Enabling NewFBSize protocol extension for client "
@ -2335,6 +2344,8 @@ rfbProcessClientNormalMessage(rfbClientPtr cl)
cl->enableCursorPosUpdates = FALSE;
}
cl->negotiationFinishedHook(cl);
return;
}

10
rfb/rfb.h

@ -10,6 +10,7 @@
*/
/*
* Copyright (C) 2015 Timothy Pearson <kb9vqf@pearsoncomputing.net>.
* Copyright (C) 2005 Rohit Kumar <rokumar@novell.com>,
* Johannes E. Schindelin <johannes.schindelin@gmx.de>
* Copyright (C) 2002 RealVNC Ltd.
@ -149,6 +150,7 @@ typedef rfbBool (*rfbSetTranslateFunctionProcPtr)(struct _rfbClientRec* cl);
typedef rfbBool (*rfbPasswordCheckProcPtr)(struct _rfbClientRec* cl,const char* encryptedPassWord,int len);
typedef enum rfbNewClientAction (*rfbNewClientHookPtr)(struct _rfbClientRec* cl);
typedef void (*rfbDisplayHookPtr)(struct _rfbClientRec* cl);
typedef void (*rfbInetdDisconnectPtr)();
typedef void (*rfbDisplayFinishedHookPtr)(struct _rfbClientRec* cl, int result);
/** support the capability to view the caps/num/scroll states of the X server */
typedef int (*rfbGetKeyboardLedStateHookPtr)(struct _rfbScreenInfo* screen);
@ -340,6 +342,9 @@ typedef struct _rfbScreenInfo
rfbNewClientHookPtr newClientHook;
/** displayHook is called just before a frame buffer update */
rfbDisplayHookPtr displayHook;
/* inetdDisconnectHook is called when the connection has been
interrupted before a client could connect. */
rfbInetdDisconnectPtr inetdDisconnectHook;
/** These hooks are called to pass keyboard state back to the client */
rfbGetKeyboardLedStateHookPtr getKeyboardLedStateHook;
@ -413,6 +418,7 @@ typedef struct sraRegion* sraRegionPtr;
*/
typedef void (*ClientGoneHookPtr)(struct _rfbClientRec* cl);
typedef void (*NegotiationFinishedHookPtr)(struct _rfbClientRec* cl);
typedef struct _rfbFileTransferData {
int fd;
@ -458,6 +464,9 @@ typedef struct _rfbClientRec {
void* clientData;
ClientGoneHookPtr clientGoneHook;
/* negotiationFinishedHook is called when the negotiation phase has ended */
NegotiationFinishedHookPtr negotiationFinishedHook;
SOCKET sock;
char *host;
@ -623,6 +632,7 @@ typedef struct _rfbClientRec {
rfbBool enableServerIdentity; /**< client supports ServerIdentity encoding */
rfbBool enableKeyboardLedState; /**< client supports KeyboardState encoding */
rfbBool enableLastRectEncoding; /**< client supports LastRect encoding */
rfbBool disableBackground; /**< client wants to disable background */
rfbBool enableCursorShapeUpdates; /**< client supports cursor shape updates */
rfbBool enableCursorPosUpdates; /**< client supports cursor position updates */
rfbBool useRichCursorEncoding; /**< rfbEncodingRichCursor is preferred */

8
rfb/rfbproto.h

@ -13,6 +13,7 @@
*/
/*
* Copyright (C) 2015 Timothy Pearson <kb9vqf@pearsoncomputing.net>. All Rights Reserved.
* Copyright (C) 2009-2010 D. R. Commander. All Rights Reserved.
* Copyright (C) 2005 Rohit Kumar, Johannes E. Schindelin
* Copyright (C) 2004-2008 Sun Microsystems, Inc. All Rights Reserved.
@ -448,6 +449,13 @@ typedef struct {
#define rfbEncodingH264 0x48323634
/*
* Reserved range for TDE:
* 0xFFFE0100 - 0xFFFE01FF
*/
#define rfbEncodingBackground 0xFFFE0125
/* Cache & XOR-Zlib - rdv@2002 */
#define rfbEncodingCache 0xFFFF0000
#define rfbEncodingCacheEnable 0xFFFF0001

Loading…
Cancel
Save