Commit 0a909fde authored by dscho's avatar dscho

This monster commit contains support for TightVNC's file transfer protocol.

Thank you very much, Rohit!
parent 93be927b
......@@ -19,6 +19,9 @@ original proof-of-concept. It really deserves to replace the old version,
as it is a state-of-the-art, fast and usable program by now! However, he
maintains it and improves it still in amazing ways!
The file transfer protocol from TightVNC was implemented by Rohit Kumar.
This includes an implementation of RFB protocol version 3.7t.
Occasional important patches were sent by (in order I found the names in my
archives and please don't beat me, if I forgot you, but just send me an
email!): Akira Hatakeyama, Karl J. Runge, Justin "Zippy" Dearing,
......
2005-09-28 Rohit Kumar <rokumar@novell.com>
* examples/filetransfer.c, rfb/rfb.h, configure.ac,
libvncserver/{auth,cargs,main,rfbserver,sockets}.c,
libvncserver/tightvnc-extension/*:
Implement TightVNC's file transfer protocol.
2005-09-27 Rohit Kumar <rokumar@novell.com>
* libvncserver/{cargs,sockets,main,rfbserver}.c,
rfb/rfb.h: Provide a generic means to extend the RFB
......
......@@ -17,6 +17,14 @@ AC_PATH_PROG([AR], [ar], [/usr/bin/ar],
[$PATH:/usr/ccs/bin])
# Options
AH_TEMPLATE(WITH_TIGHTVNC_FILETRANSFER, [Disable TightVNCFileTransfer protocol])
AC_ARG_WITH(tightvnc-filetransfer,
[ --without-filetransfer disable TightVNC file transfer protocol],
, [ with_tightvnc_filetransfer=yes ])
if test "x$with_tightvnc_filetransfer" == "xyes"; then
AC_DEFINE(WITH_TIGHTVNC_FILETRANSFER)
fi
AM_CONDITIONAL(WITH_TIGHTVNC_FILETRANSFER, test "$with_tightvnc_filetransfer" == "yes")
AH_TEMPLATE(BACKCHANNEL, [Enable BackChannel communication])
AC_ARG_WITH(backchannel,
[ --without-backchannel disable backchannel method],
......
......@@ -13,4 +13,5 @@ simple15
colourmaptest
regiontest
mac
filetransfer
......@@ -6,9 +6,14 @@ MAC=mac
mac_LDFLAGS=-framework ApplicationServices -framework Carbon -framework IOKit
endif
if WITH_TIGHTVNC_FILETRANSFER
FILETRANSFER=filetransfer
endif
noinst_HEADERS=radon.h
noinst_PROGRAMS=example pnmshow regiontest pnmshow24 fontsel \
vncev storepasswd colourmaptest simple simple15 $(MAC)
vncev storepasswd colourmaptest simple simple15 $(MAC) \
$(FILETRANSFER)
#include <rfb/rfb.h>
int main(int argc,char** argv)
{
rfbScreenInfoPtr server=rfbGetScreen(&argc,argv,400,300,8,3,4);
server->frameBuffer=(char*)malloc(400*300*4);
rfbRegisterTightVNCFileTransferExtension();
rfbInitServer(server);
rfbRunEventLoop(server,-1,FALSE);
return(0);
}
.deps
Makefile
Makefile.in
client_test
libvncclient.a
.deps
Makefile
Makefile.in
libvncserver.a
DEFINES=-g -Wall
AM_CFLAGS=-g -Wall
#if WITH_TIGHTVNC_FILETRANSFER
TIGHTVNCFILETRANSFERHDRS=tightvnc-filetransfer/filelistinfo.h \
tightvnc-filetransfer/filetransfermsg.h \
tightvnc-filetransfer/handlefiletransferrequest.h \
tightvnc-filetransfer/rfbtightproto.h
TIGHTVNCFILETRANSFERSRCS = tightvnc-filetransfer/rfbtightserver.c \
tightvnc-filetransfer/handlefiletransferrequest.c \
tightvnc-filetransfer/filetransfermsg.c \
tightvnc-filetransfer/filelistinfo.c
#endif
includedir=$(prefix)/include/rfb
#include_HEADERS=rfb.h rfbconfig.h rfbint.h rfbproto.h keysym.h rfbregion.h
......@@ -7,7 +19,8 @@ include_HEADERS=../rfb/rfb.h ../rfb/rfbconfig.h ../rfb/rfbint.h \
../rfb/rfbproto.h ../rfb/keysym.h ../rfb/rfbregion.h ../rfb/rfbclient.h
noinst_HEADERS=d3des.h ../rfb/default8x16.h zrleoutstream.h \
zrlepalettehelper.h zrletypes.h private.h
zrlepalettehelper.h zrletypes.h private.h \
$(TIGHTVNCFILETRANSFERHDRS)
EXTRA_DIST=tableinit24.c tableinittctemplate.c tabletranstemplate.c \
tableinitcmtemplate.c tabletrans24template.c \
......@@ -24,7 +37,7 @@ LIB_SRCS = main.c rfbserver.c rfbregion.c auth.c sockets.c \
stats.c corre.c hextile.c rre.c translate.c cutpaste.c \
httpd.c cursor.c font.c \
draw.c selbox.c d3des.c vncauth.c cargs.c \
$(ZLIBSRCS) $(JPEGSRCS)
$(ZLIBSRCS) $(JPEGSRCS) $(TIGHTVNCFILETRANSFERSRCS)
libvncserver_a_SOURCES=$(LIB_SRCS)
......
......@@ -207,7 +207,7 @@ rfbAuthNewClient(rfbClientPtr cl)
void
rfbProcessClientSecurityType(rfbClientPtr cl)
{
int n, i;
int n;
uint8_t chosenType;
rfbSecurityHandler* handler;
......
......@@ -151,7 +151,7 @@ rfbProcessArguments(rfbScreenInfoPtr rfbScreen,int* argc, char *argv[])
for(extension=rfbGetExtensionIterator();handled==0 && extension;
extension=extension->next)
if(extension->processArgument)
handled = extension->processArgument(argv + i);
handled = extension->processArgument(*argc - i, argv + i);
rfbReleaseExtensionIterator();
if(handled==0) {
......
......@@ -84,6 +84,46 @@ void rfbReleaseExtensionIterator()
UNLOCK(extMutex);
}
rfbBool rfbEnableExtension(rfbClientPtr cl, rfbProtocolExtension* extension,
void* data)
{
rfbExtensionData* extData;
/* make sure extension is not yet enabled. */
for(extData = cl->extensions; extData; extData = extData->next)
if(extData->extension == extension)
return FALSE;
extData = calloc(sizeof(rfbExtensionData),1);
extData->extension = extension;
extData->data = data;
extData->next = cl->extensions;
cl->extensions = extData;
return TRUE;
}
rfbBool rfbDisableExtension(rfbClientPtr cl, rfbProtocolExtension* extension)
{
rfbExtensionData* extData;
rfbExtensionData* prevData = NULL;
for(extData = cl->extensions; extData; extData = extData->next) {
if(extData->extension == extension) {
if(extData->data)
free(extData->data);
if(prevData == NULL)
cl->extensions = extData->next;
else
prevData->next = extData->next;
return TRUE;
}
prevData = extData;
}
return FALSE;
}
/*
* Logging
*/
......
......@@ -229,6 +229,7 @@ rfbNewTCPOrUDPClient(rfbScreenInfoPtr rfbScreen,
rfbClientPtr cl,cl_;
struct sockaddr_in addr;
socklen_t addrlen = sizeof(struct sockaddr_in);
rfbProtocolExtension* extension;
cl = (rfbClientPtr)calloc(sizeof(rfbClientRec),1);
......@@ -361,6 +362,16 @@ rfbNewTCPOrUDPClient(rfbScreenInfoPtr rfbScreen,
}
}
for(extension = rfbGetExtensionIterator(); extension;
extension=extension->next) {
void* data = NULL;
/* if the extension does not have a newClient method, it wants
* to be initialized later. */
if(extension->newClient && extension->newClient(cl, &data))
rfbEnableExtension(cl, extension, data);
}
rfbReleaseExtensionIterator();
switch (cl->screen->newClientHook(cl)) {
case RFB_CLIENT_ON_HOLD:
cl->onHold = TRUE;
......@@ -606,7 +617,7 @@ rfbProcessClientInitMessage(rfbClientPtr cl)
int len, n;
rfbClientIteratorPtr iterator;
rfbClientPtr otherCl;
rfbProtocolExtension* extension;
rfbExtensionData* extension;
if ((n = rfbReadExact(cl, (char *)&ci,sz_rfbClientInitMsg)) <= 0) {
if (n == 0)
......@@ -636,18 +647,14 @@ rfbProcessClientInitMessage(rfbClientPtr cl)
return;
}
for(extension=rfbGetExtensionIterator();extension;extension=extension->next)
if(extension->init) {
void* data;
if(extension->init(cl, &data)) {
rfbExtensionData* extensionData=calloc(sizeof(rfbExtensionData),1);
extensionData->extension=extension;
extensionData->data=data;
extensionData->next=cl->extensions;
cl->extensions=extensionData;
for(extension = cl->extensions; extension;) {
rfbExtensionData* next = extension->next;
if(extension->extension->init &&
!extension->extension->init(cl, extension->data))
/* extension requested that it be removed */
rfbDisableExtension(cl, extension->extension);
extension = next;
}
}
rfbReleaseExtensionIterator();
cl->state = RFB_NORMAL;
......@@ -1068,7 +1075,7 @@ rfbProcessClientNormalMessage(rfbClientPtr cl)
for(extension=cl->extensions; extension; extension=extension->next)
if(extension->extension->handleMessage &&
extension->extension->handleMessage(cl, extension->data, msg))
extension->extension->handleMessage(cl, extension->data, &msg))
return;
if(cl->screen->processCustomClientMessage(cl,msg.type)) {
......
......@@ -466,6 +466,14 @@ rfbReadExactTimeout(rfbClientPtr cl, char* buf, int len, int timeout)
}
}
}
#undef DEBUG_READ_EXACT
#ifdef DEBUG_READ_EXACT
rfbLog("ReadExact %d bytes\n",len);
for(n=0;n<len;n++)
fprintf(stderr,"%02x ",(unsigned char)buf[n]);
fprintf(stderr,"\n");
#endif
return 1;
}
......
DEFINES=-g -Wall
includedir=$(prefix)/include/rfb
noinst_HEADERS=filelistinfo.h filetransfermsg.h \
handlefiletransferrequest.h rfbtightproto.h
LIB_SRCS = rfbtightserver.c handlefiletransferrequest.c filetransfermsg.c \
filelistinfo.c
tightvnc_filetransfer_a_SOURCES=$(LIB_SRCS)
lib_LIBRARIES=tightvnc-filetransfer.a
/*
* Copyright (c) 2005 Novell, Inc.
* All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program 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 program; if not, contact Novell, Inc.
*
* To contact Novell about this file by physical or electronic mail,
* you may find current contact information at www.novell.com
*
* Author : Rohit Kumar
* Email ID : rokumar@novell.com
* Date : 14th July 2005
*/
#include <stdio.h>
#include "rfb/rfb.h"
#include "filelistinfo.h"
/* This method is used for debugging purpose */
void
DisplayFileList(FileListInfo fli)
{
int i = 0;
if((fli.pEntries == NULL) || (fli.numEntries == 0)) return;
rfbLog("DISPLAYING FILE NAMES IN THE LIST ...START\n\n");
rfbLog("Numer of entries:: %d\n", fli.numEntries);
for(i = 0; i < fli.numEntries; i++)
rfbLog("file[%d]\t<%s>\n", i, fli.pEntries[i].name);
rfbLog("DISPLAYING FILE NAMES IN THE LIST ...END\n\n");
}
int
AddFileListItemInfo(FileListInfoPtr fileListInfoPtr, char* name,
unsigned int size, unsigned int data)
{
FileListItemInfoPtr fileListItemInfoPtr = (FileListItemInfoPtr)
calloc((fileListInfoPtr->numEntries + 1),
sizeof(FileListItemInfo));
if(fileListItemInfoPtr == NULL) {
rfbLog("File [%s]: Method [%s]: fileListItemInfoPtr is NULL\n",
__FILE__, __FUNCTION__);
return FAILURE;
}
if(fileListInfoPtr->numEntries != 0) {
memcpy(fileListItemInfoPtr, fileListInfoPtr->pEntries,
fileListInfoPtr->numEntries * sizeof(FileListItemInfo));
}
strcpy(fileListItemInfoPtr[fileListInfoPtr->numEntries].name, name);
fileListItemInfoPtr[fileListInfoPtr->numEntries].size = size;
fileListItemInfoPtr[fileListInfoPtr->numEntries].data = data;
if(fileListInfoPtr->pEntries != NULL) {
free(fileListInfoPtr->pEntries);
fileListInfoPtr->pEntries = NULL;
}
fileListInfoPtr->pEntries = fileListItemInfoPtr;
fileListItemInfoPtr = NULL;
fileListInfoPtr->numEntries++;
return SUCCESS;
}
char*
GetFileNameAt(FileListInfo fileListInfo, int number)
{
char* name = NULL;
if(number >= 0 && number < fileListInfo.numEntries)
name = fileListInfo.pEntries[number].name;
return name;
}
unsigned int
GetFileSizeAt(FileListInfo fileListInfo, int number)
{
unsigned int size = 0;
if(number >= 0 && number < fileListInfo.numEntries)
size = fileListInfo.pEntries[number].size;
return size;
}
unsigned int
GetFileDataAt(FileListInfo fileListInfo, int number)
{
unsigned int data = 0;
if(number >= 0 && number < fileListInfo.numEntries)
data = fileListInfo.pEntries[number].data;
return data;
}
unsigned int
GetSumOfFileNamesLength(FileListInfo fileListInfo)
{
int i = 0, sumLen = 0;
for(i = 0; i < fileListInfo.numEntries; i++)
sumLen += strlen(fileListInfo.pEntries[i].name);
return sumLen;
}
void
FreeFileListInfo(FileListInfo fileListInfo)
{
if(fileListInfo.pEntries != NULL) {
free(fileListInfo.pEntries);
fileListInfo.pEntries = NULL;
}
fileListInfo.numEntries = 0;
}
/*
* Copyright (c) 2005 Novell, Inc.
* All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program 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 program; if not, contact Novell, Inc.
*
* To contact Novell about this file by physical or electronic mail,
* you may find current contact information at www.novell.com
*
* Author : Rohit Kumar
* Email ID : rokumar@novell.com
* Date : 14th July 2005
*/
#ifndef FILE_LIST_INFO_H
#define FILE_LIST_INFO_H
#include <limits.h>
#define SUCCESS 1
#define FAILURE 0
typedef struct _FileListItemInfo {
char name[NAME_MAX];
unsigned int size;
unsigned int data;
} FileListItemInfo, *FileListItemInfoPtr;
typedef struct _FileListItemSize {
unsigned int size;
unsigned int data;
} FileListItemSize, *FileListItemSizePtr;
typedef struct _FileListInfo {
FileListItemInfoPtr pEntries;
int numEntries;
} FileListInfo, *FileListInfoPtr;
int AddFileListItemInfo(FileListInfoPtr fileListInfoPtr, char* name, unsigned int size, unsigned int data);
char* GetFileNameAt(FileListInfo fileListInfo, int number);
unsigned int GetFileSizeAt(FileListInfo fileListInfo, int number);
unsigned int GetFileDataAt(FileListInfo fileListInfo, int number);
unsigned int GetSumOfFileNamesLength(FileListInfo fileListInfo);
void FreeFileListInfo(FileListInfo fileListInfo);
void DisplayFileList(FileListInfo fli);
#endif
This diff is collapsed.
/*
* Copyright (c) 2005 Novell, Inc.
* All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program 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 program; if not, contact Novell, Inc.
*
* To contact Novell about this file by physical or electronic mail,
* you may find current contact information at www.novell.com
*
* Author : Rohit Kumar
* Email ID : rokumar@novell.com
* Date : 14th July 2005
*/
#ifndef FILE_TRANSFER_MSG_H
#define FILE_TRANSFER_MSG_H
typedef struct _FileTransferMsg {
char* data;
unsigned int length;
} FileTransferMsg;
FileTransferMsg GetFileListResponseMsg(char* path, char flag);
FileTransferMsg GetFileDownloadResponseMsg(char* path);
FileTransferMsg GetFileDownloadLengthErrResponseMsg();
FileTransferMsg GetFileDownLoadErrMsg();
FileTransferMsg GetFileDownloadResponseMsgInBlocks(rfbClientPtr cl, rfbTightClientPtr data);
FileTransferMsg ChkFileDownloadErr(rfbClientPtr cl, rfbTightClientPtr data);
FileTransferMsg GetFileUploadLengthErrResponseMsg();
FileTransferMsg GetFileUploadCompressedLevelErrMsg();
FileTransferMsg ChkFileUploadErr(rfbClientPtr cl, rfbTightClientPtr data);
FileTransferMsg ChkFileUploadWriteErr(rfbClientPtr cl, rfbTightClientPtr data, char* pBuf);
void CreateDirectory(char* dirName);
void FileUpdateComplete(rfbClientPtr cl, rfbTightClientPtr data);
void CloseUndoneFileTransfer(rfbClientPtr cl, rfbTightClientPtr data);
void FreeFileTransferMsg(FileTransferMsg ftm);
#endif
This diff is collapsed.
/*
* Copyright (c) 2005 Novell, Inc.
* All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program 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 program; if not, contact Novell, Inc.
*
* To contact Novell about this file by physical or electronic mail,
* you may find current contact information at www.novell.com
*
* Author : Rohit Kumar
* Email ID : rokumar@novell.com
* Date : 14th July 2005
*/
#ifndef HANDLE_FILE_TRANSFER_REQUEST_H
#define HANDLE_FILE_TRANSFER_REQUEST_H
#include <rfb/rfb.h>
void InitFileTransfer();
int SetFtpRoot(char* path);
void EnableFileTransfer(rfbBool enable);
rfbBool IsFileTransferEnabled();
char* GetFtpRoot();
void HandleFileListRequest(rfbClientPtr cl, rfbTightClientRec* data);
void HandleFileDownloadRequest(rfbClientPtr cl, rfbTightClientRec* data);
void HandleFileDownloadCancelRequest(rfbClientPtr cl, rfbTightClientRec* data);
void HandleFileUploadRequest(rfbClientPtr cl, rfbTightClientRec* data);
void HandleFileUploadDataRequest(rfbClientPtr cl, rfbTightClientRec* data);
void HandleFileUploadFailedRequest(rfbClientPtr cl, rfbTightClientRec* data);
void HandleFileCreateDirRequest(rfbClientPtr cl, rfbTightClientRec* data);
#endif
This diff is collapsed.
This diff is collapsed.
......@@ -159,16 +159,20 @@ typedef struct _rfbSecurity {
*/
typedef struct _rfbProtocolExtension {
/* returns TRUE if extension should be activated */
rfbBool (*init)(struct _rfbClientRec* client, void** data);
/* returns FALSE if extension should be deactivated for client.
if newClient == NULL, it is always deactivated. */
rfbBool (*newClient)(struct _rfbClientRec* client, void** data);
/* returns FALSE if extension should be deactivated for client.
if init == NULL, it stays activated. */
rfbBool (*init)(struct _rfbClientRec* client, void* data);
/* returns TRUE if message was handled */
rfbBool (*handleMessage)(struct _rfbClientRec* client,
void* data,
rfbClientToServerMsg message);
const rfbClientToServerMsg* message);
void (*close)(struct _rfbClientRec* client, void* data);
void (*usage)(void);
/* processArguments returns the number of handled arguments */
int (*processArgument)(char *argv[]);
int (*processArgument)(int argc, char *argv[]);
struct _rfbProtocolExtension* next;
} rfbProtocolExtension;
......@@ -623,6 +627,7 @@ extern void rfbHttpCheckFds(rfbScreenInfoPtr rfbScreen);
/* auth.c */
extern void rfbAuthNewClient(rfbClientPtr cl);
extern void rfbProcessClientSecurityType(rfbClientPtr cl);
extern void rfbAuthProcessClientMessage(rfbClientPtr cl);
extern void rfbRegisterSecurityHandler(rfbSecurityHandler* handler);
......@@ -788,7 +793,9 @@ enum rfbNewClientAction defaultNewClientHook(rfbClientPtr cl);
void rfbRegisterProtocolExtension(rfbProtocolExtension* extension);
struct _rfbProtocolExtension* rfbGetExtensionIterator();
void rfbReleaseExtensionIterator();
rfbBool rfbEnableExtension(rfbClientPtr cl, rfbProtocolExtension* extension);
rfbBool rfbEnableExtension(rfbClientPtr cl, rfbProtocolExtension* extension,
void* data);
rfbBool rfbDisableExtension(rfbClientPtr cl, rfbProtocolExtension* extension);
/* to check against plain passwords */
rfbBool rfbCheckPasswordByList(rfbClientPtr cl,const char* response,int len);
......@@ -821,6 +828,9 @@ extern void rfbRunEventLoop(rfbScreenInfoPtr screenInfo, long usec, rfbBool runI
extern rfbBool rfbProcessEvents(rfbScreenInfoPtr screenInfo,long usec);
extern rfbBool rfbIsActive(rfbScreenInfoPtr screenInfo);
/* TightVNC file transfer extension */
void rfbRegisterTightVNCFileTransferExtension();
#endif
#if(defined __cplusplus)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment