Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
L
libvncserver
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
rasky
libvncserver
Commits
0a909fde
Commit
0a909fde
authored
Sep 28, 2005
by
dscho
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
This monster commit contains support for TightVNC's file transfer protocol.
Thank you very much, Rohit!
parent
93be927b
Changes
25
Show whitespace changes
Inline
Side-by-side
Showing
25 changed files
with
3025 additions
and
26 deletions
+3025
-26
AUTHORS
AUTHORS
+3
-0
ChangeLog
ChangeLog
+6
-0
configure.ac
configure.ac
+8
-0
.cvsignore
examples/.cvsignore
+1
-0
Makefile.am
examples/Makefile.am
+6
-1
filetransfer.c
examples/filetransfer.c
+11
-0
.cvsignore
libvncclient/.cvsignore
+1
-1
.cvsignore
libvncserver/.cvsignore
+1
-0
Makefile.am
libvncserver/Makefile.am
+16
-3
auth.c
libvncserver/auth.c
+1
-1
cargs.c
libvncserver/cargs.c
+1
-1
main.c
libvncserver/main.c
+40
-0
rfbserver.c
libvncserver/rfbserver.c
+21
-14
sockets.c
libvncserver/sockets.c
+8
-0
.cvsignore
libvncserver/tightvnc-filetransfer/.cvsignore
+3
-0
Makefile.am
libvncserver/tightvnc-filetransfer/Makefile.am
+15
-0
filelistinfo.c
libvncserver/tightvnc-filetransfer/filelistinfo.c
+130
-0
filelistinfo.h
libvncserver/tightvnc-filetransfer/filelistinfo.h
+61
-0
filetransfermsg.c
libvncserver/tightvnc-filetransfer/filetransfermsg.c
+632
-0
filetransfermsg.h
libvncserver/tightvnc-filetransfer/filetransfermsg.h
+54
-0
handlefiletransferrequest.c
...cserver/tightvnc-filetransfer/handlefiletransferrequest.c
+988
-0
handlefiletransferrequest.h
...cserver/tightvnc-filetransfer/handlefiletransferrequest.h
+47
-0
rfbtightproto.h
libvncserver/tightvnc-filetransfer/rfbtightproto.h
+450
-0
rfbtightserver.c
libvncserver/tightvnc-filetransfer/rfbtightserver.c
+506
-0
rfb.h
rfb/rfb.h
+15
-5
No files found.
AUTHORS
View file @
0a909fde
...
@@ -19,6 +19,9 @@ original proof-of-concept. It really deserves to replace the old version,
...
@@ -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
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!
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
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
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,
email!): Akira Hatakeyama, Karl J. Runge, Justin "Zippy" Dearing,
...
...
ChangeLog
View file @
0a909fde
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>
2005-09-27 Rohit Kumar <rokumar@novell.com>
* libvncserver/{cargs,sockets,main,rfbserver}.c,
* libvncserver/{cargs,sockets,main,rfbserver}.c,
rfb/rfb.h: Provide a generic means to extend the RFB
rfb/rfb.h: Provide a generic means to extend the RFB
...
...
configure.ac
View file @
0a909fde
...
@@ -17,6 +17,14 @@ AC_PATH_PROG([AR], [ar], [/usr/bin/ar],
...
@@ -17,6 +17,14 @@ AC_PATH_PROG([AR], [ar], [/usr/bin/ar],
[$PATH:/usr/ccs/bin])
[$PATH:/usr/ccs/bin])
# Options
# 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])
AH_TEMPLATE(BACKCHANNEL, [Enable BackChannel communication])
AC_ARG_WITH(backchannel,
AC_ARG_WITH(backchannel,
[ --without-backchannel disable backchannel method],
[ --without-backchannel disable backchannel method],
...
...
examples/.cvsignore
View file @
0a909fde
...
@@ -13,4 +13,5 @@ simple15
...
@@ -13,4 +13,5 @@ simple15
colourmaptest
colourmaptest
regiontest
regiontest
mac
mac
filetransfer
examples/Makefile.am
View file @
0a909fde
...
@@ -6,9 +6,14 @@ MAC=mac
...
@@ -6,9 +6,14 @@ MAC=mac
mac_LDFLAGS
=
-framework
ApplicationServices
-framework
Carbon
-framework
IOKit
mac_LDFLAGS
=
-framework
ApplicationServices
-framework
Carbon
-framework
IOKit
endif
endif
if
WITH_TIGHTVNC_FILETRANSFER
FILETRANSFER
=
filetransfer
endif
noinst_HEADERS
=
radon.h
noinst_HEADERS
=
radon.h
noinst_PROGRAMS
=
example pnmshow regiontest pnmshow24 fontsel
\
noinst_PROGRAMS
=
example pnmshow regiontest pnmshow24 fontsel
\
vncev storepasswd colourmaptest simple simple15
$(MAC)
vncev storepasswd colourmaptest simple simple15
$(MAC)
\
$(FILETRANSFER)
examples/filetransfer.c
0 → 100644
View file @
0a909fde
#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
);
}
libvncclient/.cvsignore
View file @
0a909fde
.deps
.deps
Makefile
Makefile
Makefile.in
Makefile.in
client_test
libvncclient.a
libvncserver/.cvsignore
View file @
0a909fde
.deps
.deps
Makefile
Makefile
Makefile.in
Makefile.in
libvncserver.a
libvncserver/Makefile.am
View file @
0a909fde
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
includedir
=
$(prefix)
/include/rfb
#include_HEADERS=rfb.h rfbconfig.h rfbint.h rfbproto.h keysym.h rfbregion.h
#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 \
...
@@ -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
../rfb/rfbproto.h ../rfb/keysym.h ../rfb/rfbregion.h ../rfb/rfbclient.h
noinst_HEADERS
=
d3des.h ../rfb/default8x16.h zrleoutstream.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
\
EXTRA_DIST
=
tableinit24.c tableinittctemplate.c tabletranstemplate.c
\
tableinitcmtemplate.c tabletrans24template.c
\
tableinitcmtemplate.c tabletrans24template.c
\
...
@@ -24,7 +37,7 @@ LIB_SRCS = main.c rfbserver.c rfbregion.c auth.c sockets.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
\
stats.c corre.c hextile.c rre.c translate.c cutpaste.c
\
httpd.c cursor.c font.c
\
httpd.c cursor.c font.c
\
draw.c selbox.c d3des.c vncauth.c cargs.c
\
draw.c selbox.c d3des.c vncauth.c cargs.c
\
$(ZLIBSRCS)
$(JPEGSRCS)
$(ZLIBSRCS)
$(JPEGSRCS)
$(TIGHTVNCFILETRANSFERSRCS)
libvncserver_a_SOURCES
=
$(LIB_SRCS)
libvncserver_a_SOURCES
=
$(LIB_SRCS)
...
...
libvncserver/auth.c
View file @
0a909fde
...
@@ -207,7 +207,7 @@ rfbAuthNewClient(rfbClientPtr cl)
...
@@ -207,7 +207,7 @@ rfbAuthNewClient(rfbClientPtr cl)
void
void
rfbProcessClientSecurityType
(
rfbClientPtr
cl
)
rfbProcessClientSecurityType
(
rfbClientPtr
cl
)
{
{
int
n
,
i
;
int
n
;
uint8_t
chosenType
;
uint8_t
chosenType
;
rfbSecurityHandler
*
handler
;
rfbSecurityHandler
*
handler
;
...
...
libvncserver/cargs.c
View file @
0a909fde
...
@@ -151,7 +151,7 @@ rfbProcessArguments(rfbScreenInfoPtr rfbScreen,int* argc, char *argv[])
...
@@ -151,7 +151,7 @@ rfbProcessArguments(rfbScreenInfoPtr rfbScreen,int* argc, char *argv[])
for
(
extension
=
rfbGetExtensionIterator
();
handled
==
0
&&
extension
;
for
(
extension
=
rfbGetExtensionIterator
();
handled
==
0
&&
extension
;
extension
=
extension
->
next
)
extension
=
extension
->
next
)
if
(
extension
->
processArgument
)
if
(
extension
->
processArgument
)
handled
=
extension
->
processArgument
(
argv
+
i
);
handled
=
extension
->
processArgument
(
*
argc
-
i
,
argv
+
i
);
rfbReleaseExtensionIterator
();
rfbReleaseExtensionIterator
();
if
(
handled
==
0
)
{
if
(
handled
==
0
)
{
...
...
libvncserver/main.c
View file @
0a909fde
...
@@ -84,6 +84,46 @@ void rfbReleaseExtensionIterator()
...
@@ -84,6 +84,46 @@ void rfbReleaseExtensionIterator()
UNLOCK
(
extMutex
);
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
* Logging
*/
*/
...
...
libvncserver/rfbserver.c
View file @
0a909fde
...
@@ -229,6 +229,7 @@ rfbNewTCPOrUDPClient(rfbScreenInfoPtr rfbScreen,
...
@@ -229,6 +229,7 @@ rfbNewTCPOrUDPClient(rfbScreenInfoPtr rfbScreen,
rfbClientPtr
cl
,
cl_
;
rfbClientPtr
cl
,
cl_
;
struct
sockaddr_in
addr
;
struct
sockaddr_in
addr
;
socklen_t
addrlen
=
sizeof
(
struct
sockaddr_in
);
socklen_t
addrlen
=
sizeof
(
struct
sockaddr_in
);
rfbProtocolExtension
*
extension
;
cl
=
(
rfbClientPtr
)
calloc
(
sizeof
(
rfbClientRec
),
1
);
cl
=
(
rfbClientPtr
)
calloc
(
sizeof
(
rfbClientRec
),
1
);
...
@@ -361,6 +362,16 @@ rfbNewTCPOrUDPClient(rfbScreenInfoPtr rfbScreen,
...
@@ -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
))
{
switch
(
cl
->
screen
->
newClientHook
(
cl
))
{
case
RFB_CLIENT_ON_HOLD
:
case
RFB_CLIENT_ON_HOLD
:
cl
->
onHold
=
TRUE
;
cl
->
onHold
=
TRUE
;
...
@@ -606,7 +617,7 @@ rfbProcessClientInitMessage(rfbClientPtr cl)
...
@@ -606,7 +617,7 @@ rfbProcessClientInitMessage(rfbClientPtr cl)
int
len
,
n
;
int
len
,
n
;
rfbClientIteratorPtr
iterator
;
rfbClientIteratorPtr
iterator
;
rfbClientPtr
otherCl
;
rfbClientPtr
otherCl
;
rfb
ProtocolExtension
*
extension
;
rfb
ExtensionData
*
extension
;
if
((
n
=
rfbReadExact
(
cl
,
(
char
*
)
&
ci
,
sz_rfbClientInitMsg
))
<=
0
)
{
if
((
n
=
rfbReadExact
(
cl
,
(
char
*
)
&
ci
,
sz_rfbClientInitMsg
))
<=
0
)
{
if
(
n
==
0
)
if
(
n
==
0
)
...
@@ -636,18 +647,14 @@ rfbProcessClientInitMessage(rfbClientPtr cl)
...
@@ -636,18 +647,14 @@ rfbProcessClientInitMessage(rfbClientPtr cl)
return
;
return
;
}
}
for
(
extension
=
rfbGetExtensionIterator
();
extension
;
extension
=
extension
->
next
)
for
(
extension
=
cl
->
extensions
;
extension
;)
{
if
(
extension
->
init
)
{
rfbExtensionData
*
next
=
extension
->
next
;
void
*
data
;
if
(
extension
->
extension
->
init
&&
if
(
extension
->
init
(
cl
,
&
data
))
{
!
extension
->
extension
->
init
(
cl
,
extension
->
data
))
rfbExtensionData
*
extensionData
=
calloc
(
sizeof
(
rfbExtensionData
),
1
);
/* extension requested that it be removed */
extensionData
->
extension
=
extension
;
rfbDisableExtension
(
cl
,
extension
->
extension
);
extensionData
->
data
=
data
;
extension
=
next
;
extensionData
->
next
=
cl
->
extensions
;
cl
->
extensions
=
extensionData
;
}
}
}
rfbReleaseExtensionIterator
();
cl
->
state
=
RFB_NORMAL
;
cl
->
state
=
RFB_NORMAL
;
...
@@ -1068,7 +1075,7 @@ rfbProcessClientNormalMessage(rfbClientPtr cl)
...
@@ -1068,7 +1075,7 @@ rfbProcessClientNormalMessage(rfbClientPtr cl)
for
(
extension
=
cl
->
extensions
;
extension
;
extension
=
extension
->
next
)
for
(
extension
=
cl
->
extensions
;
extension
;
extension
=
extension
->
next
)
if
(
extension
->
extension
->
handleMessage
&&
if
(
extension
->
extension
->
handleMessage
&&
extension
->
extension
->
handleMessage
(
cl
,
extension
->
data
,
msg
))
extension
->
extension
->
handleMessage
(
cl
,
extension
->
data
,
&
msg
))
return
;
return
;
if
(
cl
->
screen
->
processCustomClientMessage
(
cl
,
msg
.
type
))
{
if
(
cl
->
screen
->
processCustomClientMessage
(
cl
,
msg
.
type
))
{
...
...
libvncserver/sockets.c
View file @
0a909fde
...
@@ -466,6 +466,14 @@ rfbReadExactTimeout(rfbClientPtr cl, char* buf, int len, int timeout)
...
@@ -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
;
return
1
;
}
}
...
...
libvncserver/tightvnc-filetransfer/.cvsignore
0 → 100644
View file @
0a909fde
Makefile
Makefile.in
libvncserver/tightvnc-filetransfer/Makefile.am
0 → 100644
View file @
0a909fde
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
libvncserver/tightvnc-filetransfer/filelistinfo.c
0 → 100644
View file @
0a909fde
/*
* 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
;
}
libvncserver/tightvnc-filetransfer/filelistinfo.h
0 → 100644
View file @
0a909fde
/*
* 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
libvncserver/tightvnc-filetransfer/filetransfermsg.c
0 → 100644
View file @
0a909fde
/*
* 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 <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <dirent.h>
#include <utime.h>
#include <errno.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <rfb/rfb.h>
#include "rfbtightproto.h"
#include "filelistinfo.h"
#include "filetransfermsg.h"
#include "handlefiletransferrequest.h"
#define SZ_RFBBLOCKSIZE 8192
void
FreeFileTransferMsg
(
FileTransferMsg
ftm
)
{
if
(
ftm
.
data
!=
NULL
)
{
free
(
ftm
.
data
);
ftm
.
data
=
NULL
;
}
ftm
.
length
=
0
;
}
/******************************************************************************
* Methods to handle file list request.
******************************************************************************/
int
CreateFileListInfo
(
FileListInfoPtr
pFileListInfo
,
char
*
path
,
int
flag
);
FileTransferMsg
CreateFileListErrMsg
(
char
flags
);
FileTransferMsg
CreateFileListMsg
(
FileListInfo
fileListInfo
,
char
flags
);
/*
* This is the method called by HandleFileListRequest to get the file list
*/
FileTransferMsg
GetFileListResponseMsg
(
char
*
path
,
char
flags
)
{
FileTransferMsg
fileListMsg
;
FileListInfo
fileListInfo
;
int
status
=
-
1
;
memset
(
&
fileListMsg
,
0
,
sizeof
(
FileTransferMsg
));
memset
(
&
fileListInfo
,
0
,
sizeof
(
FileListInfo
));
/* fileListInfo can have null data if the folder is Empty
or if some error condition has occured.
The return value is 'failure' only if some error condition has occured.
*/
status
=
CreateFileListInfo
(
&
fileListInfo
,
path
,
!
(
flags
&
0x10
));
if
(
status
==
FAILURE
)
{
fileListMsg
=
CreateFileListErrMsg
(
flags
);
}
else
{
/* DisplayFileList(fileListInfo); For Debugging */
fileListMsg
=
CreateFileListMsg
(
fileListInfo
,
flags
);
FreeFileListInfo
(
fileListInfo
);
}
return
fileListMsg
;
}
int
CreateFileListInfo
(
FileListInfoPtr
pFileListInfo
,
char
*
path
,
int
flag
)
{
DIR
*
pDir
=
NULL
;
struct
dirent
*
pDirent
=
NULL
;
if
((
path
==
NULL
)
||
(
strlen
(
path
)
==
0
))
{
/* In this case we will send the list of entries in ftp root*/
sprintf
(
path
,
"%s%s"
,
GetFtpRoot
(),
"/"
);
}
if
((
pDir
=
opendir
(
path
))
==
NULL
)
{
rfbLog
(
"File [%s]: Method [%s]: not able to open the dir
\n
"
,
__FILE__
,
__FUNCTION__
);
return
FAILURE
;
}
while
((
pDirent
=
readdir
(
pDir
)))
{
if
(
strcmp
(
pDirent
->
d_name
,
"."
)
&&
strcmp
(
pDirent
->
d_name
,
".."
))
{
struct
stat
stat_buf
;
/*
int fpLen = sizeof(char)*(strlen(pDirent->d_name)+strlen(path)+2);
*/
char
fullpath
[
PATH_MAX
];
memset
(
fullpath
,
0
,
PATH_MAX
);
strcpy
(
fullpath
,
path
);
if
(
path
[
strlen
(
path
)
-
1
]
!=
'/'
)
strcat
(
fullpath
,
"/"
);
strcat
(
fullpath
,
pDirent
->
d_name
);
if
(
stat
(
fullpath
,
&
stat_buf
)
<
0
)
{
rfbLog
(
"File [%s]: Method [%s]: Reading stat for file %s failed
\n
"
,
__FILE__
,
__FUNCTION__
,
fullpath
);
continue
;
}
if
(
S_ISDIR
(
stat_buf
.
st_mode
))
{
if
(
AddFileListItemInfo
(
pFileListInfo
,
pDirent
->
d_name
,
-
1
,
0
)
==
0
)
{
rfbLog
(
"File [%s]: Method [%s]: Add directory %s in the"
" list failed
\n
"
,
__FILE__
,
__FUNCTION__
,
fullpath
);
continue
;
}
}
else
{
if
(
flag
)
{
if
(
AddFileListItemInfo
(
pFileListInfo
,
pDirent
->
d_name
,
stat_buf
.
st_size
,
stat_buf
.
st_mtime
)
==
0
)
{
rfbLog
(
"File [%s]: Method [%s]: Add file %s in the "
"list failed
\n
"
,
__FILE__
,
__FUNCTION__
,
fullpath
);
continue
;
}
}
}
}
}
if
(
closedir
(
pDir
)
<
0
)
{
rfbLog
(
"File [%s]: Method [%s]: ERROR Couldn't close dir
\n
"
,
__FILE__
,
__FUNCTION__
);
}
return
SUCCESS
;
}
FileTransferMsg
CreateFileListErrMsg
(
char
flags
)
{
FileTransferMsg
fileListMsg
;
rfbFileListDataMsg
*
pFLD
=
NULL
;
char
*
data
=
NULL
;
unsigned
int
length
=
0
;
memset
(
&
fileListMsg
,
0
,
sizeof
(
FileTransferMsg
));
data
=
(
char
*
)
calloc
(
sizeof
(
rfbFileListDataMsg
),
sizeof
(
char
));
if
(
data
==
NULL
)
{
return
fileListMsg
;
}
length
=
sizeof
(
rfbFileListDataMsg
)
*
sizeof
(
char
);
pFLD
=
(
rfbFileListDataMsg
*
)
data
;
pFLD
->
type
=
rfbFileListData
;
pFLD
->
numFiles
=
Swap16IfLE
(
0
);
pFLD
->
dataSize
=
Swap16IfLE
(
0
);
pFLD
->
compressedSize
=
Swap16IfLE
(
0
);
pFLD
->
flags
=
flags
|
0x80
;
fileListMsg
.
data
=
data
;
fileListMsg
.
length
=
length
;
return
fileListMsg
;
}
FileTransferMsg
CreateFileListMsg
(
FileListInfo
fileListInfo
,
char
flags
)
{
FileTransferMsg
fileListMsg
;
rfbFileListDataMsg
*
pFLD
=
NULL
;
char
*
data
=
NULL
,
*
pFileNames
=
NULL
;
unsigned
int
length
=
0
,
dsSize
=
0
,
i
=
0
;
FileListItemSizePtr
pFileListItemSize
=
NULL
;
memset
(
&
fileListMsg
,
0
,
sizeof
(
FileTransferMsg
));
dsSize
=
fileListInfo
.
numEntries
*
8
;
length
=
sz_rfbFileListDataMsg
+
dsSize
+
GetSumOfFileNamesLength
(
fileListInfo
)
+
fileListInfo
.
numEntries
;
data
=
(
char
*
)
calloc
(
length
,
sizeof
(
char
));
if
(
data
==
NULL
)
{
return
fileListMsg
;
}
pFLD
=
(
rfbFileListDataMsg
*
)
data
;
pFileListItemSize
=
(
FileListItemSizePtr
)
&
data
[
sz_rfbFileListDataMsg
];
pFileNames
=
&
data
[
sz_rfbFileListDataMsg
+
dsSize
];
pFLD
->
type
=
rfbFileListData
;
pFLD
->
flags
=
flags
&
0xF0
;
pFLD
->
numFiles
=
Swap16IfLE
(
fileListInfo
.
numEntries
);
pFLD
->
dataSize
=
Swap16IfLE
(
GetSumOfFileNamesLength
(
fileListInfo
)
+
fileListInfo
.
numEntries
);
pFLD
->
compressedSize
=
pFLD
->
dataSize
;
for
(
i
=
0
;
i
<
fileListInfo
.
numEntries
;
i
++
)
{
pFileListItemSize
[
i
].
size
=
Swap32IfLE
(
GetFileSizeAt
(
fileListInfo
,
i
));
pFileListItemSize
[
i
].
data
=
Swap32IfLE
(
GetFileDataAt
(
fileListInfo
,
i
));
strcpy
(
pFileNames
,
GetFileNameAt
(
fileListInfo
,
i
));
if
(
i
+
1
<
fileListInfo
.
numEntries
)
pFileNames
+=
strlen
(
pFileNames
)
+
1
;
}
fileListMsg
.
data
=
data
;
fileListMsg
.
length
=
length
;
return
fileListMsg
;
}
/******************************************************************************
* Methods to handle File Download Request.
******************************************************************************/
FileTransferMsg
CreateFileDownloadErrMsg
(
char
*
reason
,
unsigned
int
reasonLen
);
FileTransferMsg
CreateFileDownloadZeroSizeDataMsg
(
unsigned
long
mTime
);
FileTransferMsg
CreateFileDownloadBlockSizeDataMsg
(
unsigned
short
sizeFile
,
char
*
pFile
);
FileTransferMsg
GetFileDownLoadErrMsg
()
{
FileTransferMsg
fileDownloadErrMsg
;
char
reason
[]
=
"An internal error on the server caused download failure"
;
int
reasonLen
=
strlen
(
reason
);
memset
(
&
fileDownloadErrMsg
,
0
,
sizeof
(
FileTransferMsg
));
fileDownloadErrMsg
=
CreateFileDownloadErrMsg
(
reason
,
reasonLen
);
return
fileDownloadErrMsg
;
}
FileTransferMsg
GetFileDownloadReadDataErrMsg
()
{
char
reason
[]
=
"Cannot open file, perhaps it is absent or is a directory"
;
int
reasonLen
=
strlen
(
reason
);
return
CreateFileDownloadErrMsg
(
reason
,
reasonLen
);
}
FileTransferMsg
GetFileDownloadLengthErrResponseMsg
()
{
char
reason
[]
=
"Path length exceeds PATH_MAX (4096) bytes"
;
int
reasonLen
=
strlen
(
reason
);
return
CreateFileDownloadErrMsg
(
reason
,
reasonLen
);
}
FileTransferMsg
GetFileDownloadResponseMsgInBlocks
(
rfbClientPtr
cl
,
rfbTightClientPtr
rtcp
)
{
//const unsigned int sz_rfbBlockSize = SZ_RFBBLOCKSIZE;
int
numOfBytesRead
=
0
;
char
pBuf
[
SZ_RFBBLOCKSIZE
];
char
*
path
=
rtcp
->
rcft
.
rcfd
.
fName
;
memset
(
pBuf
,
0
,
SZ_RFBBLOCKSIZE
);
if
((
rtcp
->
rcft
.
rcfd
.
downloadInProgress
==
FALSE
)
&&
(
rtcp
->
rcft
.
rcfd
.
downloadFD
==
-
1
))
{
if
((
rtcp
->
rcft
.
rcfd
.
downloadFD
=
open
(
path
,
O_RDONLY
))
==
-
1
)
{
rfbLog
(
"File [%s]: Method [%s]: Error: Couldn't open file
\n
"
,
__FILE__
,
__FUNCTION__
);
return
GetFileDownloadReadDataErrMsg
();
}
rtcp
->
rcft
.
rcfd
.
downloadInProgress
=
TRUE
;
}
if
((
rtcp
->
rcft
.
rcfd
.
downloadInProgress
==
TRUE
)
&&
(
rtcp
->
rcft
.
rcfd
.
downloadFD
!=
-
1
))
{
if
(
(
numOfBytesRead
=
read
(
rtcp
->
rcft
.
rcfd
.
downloadFD
,
pBuf
,
SZ_RFBBLOCKSIZE
))
<=
0
)
{
close
(
rtcp
->
rcft
.
rcfd
.
downloadFD
);
rtcp
->
rcft
.
rcfd
.
downloadFD
=
-
1
;
rtcp
->
rcft
.
rcfd
.
downloadInProgress
=
FALSE
;
if
(
numOfBytesRead
==
0
)
{
return
CreateFileDownloadZeroSizeDataMsg
(
rtcp
->
rcft
.
rcfd
.
mTime
);
}
return
GetFileDownloadReadDataErrMsg
();
}
return
CreateFileDownloadBlockSizeDataMsg
(
numOfBytesRead
,
pBuf
);
}
}
FileTransferMsg
ChkFileDownloadErr
(
rfbClientPtr
cl
,
rfbTightClientPtr
rtcp
)
{
FileTransferMsg
fileDownloadMsg
;
struct
stat
stat_buf
;
int
sz_rfbFileSize
=
0
;
char
*
path
=
rtcp
->
rcft
.
rcfd
.
fName
;
memset
(
&
fileDownloadMsg
,
0
,
sizeof
(
FileTransferMsg
));
if
(
(
path
==
NULL
)
||
(
strlen
(
path
)
==
0
)
||
(
stat
(
path
,
&
stat_buf
)
<
0
)
||
(
!
(
S_ISREG
(
stat_buf
.
st_mode
)))
)
{
char
reason
[]
=
"Cannot open file, perhaps it is absent or is not a regular file"
;
int
reasonLen
=
strlen
(
reason
);
rfbLog
(
"File [%s]: Method [%s]: Reading stat for path %s failed
\n
"
,
__FILE__
,
__FUNCTION__
,
path
);
fileDownloadMsg
=
CreateFileDownloadErrMsg
(
reason
,
reasonLen
);
}
else
{
rtcp
->
rcft
.
rcfd
.
mTime
=
stat_buf
.
st_mtime
;
sz_rfbFileSize
=
stat_buf
.
st_size
;
if
(
sz_rfbFileSize
<=
0
)
{
fileDownloadMsg
=
CreateFileDownloadZeroSizeDataMsg
(
stat_buf
.
st_mtime
);
}
}
return
fileDownloadMsg
;
}
FileTransferMsg
CreateFileDownloadErrMsg
(
char
*
reason
,
unsigned
int
reasonLen
)
{
FileTransferMsg
fileDownloadErrMsg
;
int
length
=
sz_rfbFileDownloadFailedMsg
+
reasonLen
+
1
;
rfbFileDownloadFailedMsg
*
pFDF
=
NULL
;
char
*
pFollow
=
NULL
;
char
*
pData
=
(
char
*
)
calloc
(
length
,
sizeof
(
char
));
memset
(
&
fileDownloadErrMsg
,
0
,
sizeof
(
FileTransferMsg
));
if
(
pData
==
NULL
)
{
rfbLog
(
"File [%s]: Method [%s]: pData is NULL
\n
"
,
__FILE__
,
__FUNCTION__
);
return
fileDownloadErrMsg
;
}
pFDF
=
(
rfbFileDownloadFailedMsg
*
)
pData
;
pFollow
=
&
pData
[
sz_rfbFileDownloadFailedMsg
];
pFDF
->
type
=
rfbFileDownloadFailed
;
pFDF
->
reasonLen
=
Swap16IfLE
(
reasonLen
);
memcpy
(
pFollow
,
reason
,
reasonLen
);
fileDownloadErrMsg
.
data
=
pData
;
fileDownloadErrMsg
.
length
=
length
;
return
fileDownloadErrMsg
;
}
FileTransferMsg
CreateFileDownloadZeroSizeDataMsg
(
unsigned
long
mTime
)
{
FileTransferMsg
fileDownloadZeroSizeDataMsg
;
int
length
=
sz_rfbFileDownloadDataMsg
+
sizeof
(
int
);
rfbFileDownloadDataMsg
*
pFDD
=
NULL
;
char
*
pFollow
=
NULL
;
char
*
pData
=
(
char
*
)
calloc
(
length
,
sizeof
(
char
));
memset
(
&
fileDownloadZeroSizeDataMsg
,
0
,
sizeof
(
FileTransferMsg
));
if
(
pData
==
NULL
)
{
rfbLog
(
"File [%s]: Method [%s]: pData is NULL
\n
"
,
__FILE__
,
__FUNCTION__
);
return
fileDownloadZeroSizeDataMsg
;
}
pFDD
=
(
rfbFileDownloadDataMsg
*
)
pData
;
pFollow
=
&
pData
[
sz_rfbFileDownloadDataMsg
];
pFDD
->
type
=
rfbFileDownloadData
;
pFDD
->
compressLevel
=
0
;
pFDD
->
compressedSize
=
Swap16IfLE
(
0
);
pFDD
->
realSize
=
Swap16IfLE
(
0
);
memcpy
(
pFollow
,
&
mTime
,
sizeof
(
unsigned
long
));
fileDownloadZeroSizeDataMsg
.
data
=
pData
;
fileDownloadZeroSizeDataMsg
.
length
=
length
;
return
fileDownloadZeroSizeDataMsg
;
}
FileTransferMsg
CreateFileDownloadBlockSizeDataMsg
(
unsigned
short
sizeFile
,
char
*
pFile
)
{
FileTransferMsg
fileDownloadBlockSizeDataMsg
;
int
length
=
sz_rfbFileDownloadDataMsg
+
sizeFile
;
rfbFileDownloadDataMsg
*
pFDD
=
NULL
;
char
*
pFollow
=
NULL
;
char
*
pData
=
(
char
*
)
calloc
(
length
,
sizeof
(
char
));
memset
(
&
fileDownloadBlockSizeDataMsg
,
0
,
sizeof
(
FileTransferMsg
));
if
(
NULL
==
pData
)
{
rfbLog
(
"File [%s]: Method [%s]: pData is NULL
\n
"
,
__FILE__
,
__FUNCTION__
);
return
fileDownloadBlockSizeDataMsg
;
}
pFDD
=
(
rfbFileDownloadDataMsg
*
)
pData
;
pFollow
=
&
pData
[
sz_rfbFileDownloadDataMsg
];
pFDD
->
type
=
rfbFileDownloadData
;
pFDD
->
compressLevel
=
0
;
pFDD
->
compressedSize
=
Swap16IfLE
(
sizeFile
);
pFDD
->
realSize
=
Swap16IfLE
(
sizeFile
);
memcpy
(
pFollow
,
pFile
,
sizeFile
);
fileDownloadBlockSizeDataMsg
.
data
=
pData
;
fileDownloadBlockSizeDataMsg
.
length
=
length
;
return
fileDownloadBlockSizeDataMsg
;
}
/******************************************************************************
* Methods to handle file upload request
******************************************************************************/
FileTransferMsg
CreateFileUploadErrMsg
(
char
*
reason
,
unsigned
int
reasonLen
);
FileTransferMsg
GetFileUploadLengthErrResponseMsg
()
{
char
reason
[]
=
"Path length exceeds PATH_MAX (4096) bytes"
;
int
reasonLen
=
strlen
(
reason
);
return
CreateFileUploadErrMsg
(
reason
,
reasonLen
);
}
FileTransferMsg
ChkFileUploadErr
(
rfbClientPtr
cl
,
rfbTightClientPtr
rtcp
)
{
FileTransferMsg
fileUploadErrMsg
;
memset
(
&
fileUploadErrMsg
,
0
,
sizeof
(
FileTransferMsg
));
if
(
(
rtcp
->
rcft
.
rcfu
.
fName
==
NULL
)
||
(
strlen
(
rtcp
->
rcft
.
rcfu
.
fName
)
==
0
)
||
((
rtcp
->
rcft
.
rcfu
.
uploadFD
=
creat
(
rtcp
->
rcft
.
rcfu
.
fName
,
S_IRUSR
|
S_IWUSR
|
S_IRGRP
|
S_IWGRP
|
S_IROTH
|
S_IWOTH
))
==
-
1
))
{
char
reason
[]
=
"Could not create file"
;
int
reasonLen
=
strlen
(
reason
);
fileUploadErrMsg
=
CreateFileUploadErrMsg
(
reason
,
reasonLen
);
}
else
rtcp
->
rcft
.
rcfu
.
uploadInProgress
=
TRUE
;
return
fileUploadErrMsg
;
}
FileTransferMsg
GetFileUploadCompressedLevelErrMsg
()
{
char
reason
[]
=
"Server does not support data compression on upload"
;
int
reasonLen
=
strlen
(
reason
);
return
CreateFileUploadErrMsg
(
reason
,
reasonLen
);
}
FileTransferMsg
ChkFileUploadWriteErr
(
rfbClientPtr
cl
,
rfbTightClientPtr
rtcp
,
char
*
pBuf
)
{
FileTransferMsg
ftm
;
unsigned
long
numOfBytesWritten
=
0
;
memset
(
&
ftm
,
0
,
sizeof
(
FileTransferMsg
));
numOfBytesWritten
=
write
(
rtcp
->
rcft
.
rcfu
.
uploadFD
,
pBuf
,
rtcp
->
rcft
.
rcfu
.
fSize
);
if
(
numOfBytesWritten
!=
rtcp
->
rcft
.
rcfu
.
fSize
)
{
char
reason
[]
=
"Error writing file data"
;
int
reasonLen
=
strlen
(
reason
);
ftm
=
CreateFileUploadErrMsg
(
reason
,
reasonLen
);
CloseUndoneFileTransfer
(
cl
,
rtcp
);
}
return
ftm
;
}
void
FileUpdateComplete
(
rfbClientPtr
cl
,
rfbTightClientPtr
rtcp
)
{
/* Here we are settimg the modification and access time of the file */
/* Windows code stes mod/access/creation time of the file */
struct
utimbuf
utb
;
utb
.
actime
=
utb
.
modtime
=
rtcp
->
rcft
.
rcfu
.
mTime
;
if
(
utime
(
rtcp
->
rcft
.
rcfu
.
fName
,
&
utb
)
==
-
1
)
{
rfbLog
(
"File [%s]: Method [%s]: Setting the modification/access"
" time for the file <%s> failed
\n
"
,
__FILE__
,
__FUNCTION__
,
rtcp
->
rcft
.
rcfu
.
fName
);
}
if
(
rtcp
->
rcft
.
rcfu
.
uploadFD
!=
-
1
)
{
close
(
rtcp
->
rcft
.
rcfu
.
uploadFD
);
rtcp
->
rcft
.
rcfu
.
uploadFD
=
-
1
;
rtcp
->
rcft
.
rcfu
.
uploadInProgress
=
FALSE
;
}
}
FileTransferMsg
CreateFileUploadErrMsg
(
char
*
reason
,
unsigned
int
reasonLen
)
{
FileTransferMsg
fileUploadErrMsg
;
int
length
=
sz_rfbFileUploadCancelMsg
+
reasonLen
;
rfbFileUploadCancelMsg
*
pFDF
=
NULL
;
char
*
pFollow
=
NULL
;
char
*
pData
=
(
char
*
)
calloc
(
length
,
sizeof
(
char
));
memset
(
&
fileUploadErrMsg
,
0
,
sizeof
(
FileTransferMsg
));
if
(
pData
==
NULL
)
{
rfbLog
(
"File [%s]: Method [%s]: pData is NULL
\n
"
,
__FILE__
,
__FUNCTION__
);
return
fileUploadErrMsg
;
}
pFDF
=
(
rfbFileUploadCancelMsg
*
)
pData
;
pFollow
=
&
pData
[
sz_rfbFileUploadCancelMsg
];
pFDF
->
type
=
rfbFileUploadCancel
;
pFDF
->
reasonLen
=
Swap16IfLE
(
reasonLen
);
memcpy
(
pFollow
,
reason
,
reasonLen
);
fileUploadErrMsg
.
data
=
pData
;
fileUploadErrMsg
.
length
=
length
;
return
fileUploadErrMsg
;
}
/******************************************************************************
* Method to cancel File Transfer operation.
******************************************************************************/
void
CloseUndoneFileTransfer
(
rfbClientPtr
cl
,
rfbTightClientPtr
rtcp
)
{
/* TODO :: File Upload case is not handled currently */
/* TODO :: In case of concurrency we need to use Critical Section */
if
(
cl
==
NULL
)
return
;
if
(
rtcp
->
rcft
.
rcfu
.
uploadInProgress
==
TRUE
)
{
rtcp
->
rcft
.
rcfu
.
uploadInProgress
=
FALSE
;
if
(
rtcp
->
rcft
.
rcfu
.
uploadFD
!=
-
1
)
{
close
(
rtcp
->
rcft
.
rcfu
.
uploadFD
);
rtcp
->
rcft
.
rcfu
.
uploadFD
=
-
1
;
}
if
(
unlink
(
rtcp
->
rcft
.
rcfu
.
fName
)
==
-
1
)
{
rfbLog
(
"File [%s]: Method [%s]: Delete operation on file <%s> failed
\n
"
,
__FILE__
,
__FUNCTION__
,
rtcp
->
rcft
.
rcfu
.
fName
);
}
memset
(
rtcp
->
rcft
.
rcfu
.
fName
,
0
,
PATH_MAX
);
}
if
(
rtcp
->
rcft
.
rcfd
.
downloadInProgress
==
TRUE
)
{
rtcp
->
rcft
.
rcfd
.
downloadInProgress
=
FALSE
;
if
(
rtcp
->
rcft
.
rcfd
.
downloadFD
!=
-
1
)
{
close
(
rtcp
->
rcft
.
rcfd
.
downloadFD
);
rtcp
->
rcft
.
rcfd
.
downloadFD
=
-
1
;
}
memset
(
rtcp
->
rcft
.
rcfd
.
fName
,
0
,
PATH_MAX
);
}
}
/******************************************************************************
* Method to handle create directory request.
******************************************************************************/
void
CreateDirectory
(
char
*
dirName
)
{
if
(
dirName
==
NULL
)
return
;
if
(
mkdir
(
dirName
,
0700
)
==
-
1
)
{
rfbLog
(
"File [%s]: Method [%s]: Create operation for directory <%s> failed
\n
"
,
__FILE__
,
__FUNCTION__
,
dirName
);
}
}
libvncserver/tightvnc-filetransfer/filetransfermsg.h
0 → 100644
View file @
0a909fde
/*
* 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
libvncserver/tightvnc-filetransfer/handlefiletransferrequest.c
0 → 100644
View file @
0a909fde
/*
* 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 <pwd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <dirent.h>
#include <pthread.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <limits.h>
#include <rfb/rfb.h>
#include "rfbtightproto.h"
#include "filetransfermsg.h"
#include "handlefiletransferrequest.h"
pthread_mutex_t
fileDownloadMutex
=
PTHREAD_MUTEX_INITIALIZER
;
rfbBool
fileTransferEnabled
=
TRUE
;
rfbBool
fileTransferInitted
=
FALSE
;
char
ftproot
[
PATH_MAX
];
/******************************************************************************
* File Transfer Init methods. These methods are called for initializating
* File Transfer and setting ftproot.
******************************************************************************/
void
InitFileTransfer
();
int
SetFtpRoot
(
char
*
path
);
char
*
GetHomeDir
(
uid_t
uid
);
void
FreeHomeDir
(
char
*
homedir
);
/*
* InitFileTransfer method is called before parsing the command-line options
* for Xvnc. This sets the ftproot to the Home dir of the user running the Xvnc
* server. In case of error ftproot is set to '\0' char.
*/
void
InitFileTransfer
()
{
char
*
userHome
=
NULL
;
uid_t
uid
=
geteuid
();
if
(
fileTransferInitted
)
return
;
memset
(
ftproot
,
0
,
sizeof
(
ftproot
));
userHome
=
GetHomeDir
(
uid
);
if
((
userHome
!=
NULL
)
&&
(
strlen
(
userHome
)
!=
0
))
{
SetFtpRoot
(
userHome
);
FreeHomeDir
(
userHome
);
}
fileTransferEnabled
=
TRUE
;
fileTransferInitted
=
TRUE
;
}
/*
* This method is called from InitFileTransfer method and
* if the command line option for ftproot is provided.
*/
int
SetFtpRoot
(
char
*
path
)
{
struct
stat
stat_buf
;
DIR
*
dir
=
NULL
;
if
((
path
==
NULL
)
||
(
strlen
(
path
)
==
0
)
||
(
strlen
(
path
)
>
(
PATH_MAX
-
1
)))
{
rfbLog
(
"File [%s]: Method [%s]: parameter passed is improper, ftproot"
" not changed
\n
"
,
__FILE__
,
__FUNCTION__
);
return
FALSE
;
}
if
(
stat
(
path
,
&
stat_buf
)
<
0
)
{
rfbLog
(
"File [%s]: Method [%s]: Reading stat for file %s failed
\n
"
,
__FILE__
,
__FUNCTION__
,
path
);
return
FALSE
;
}
if
(
S_ISDIR
(
stat_buf
.
st_mode
)
==
0
)
{
rfbLog
(
"File [%s]: Method [%s]: path specified is not a directory
\n
"
,
__FILE__
,
__FUNCTION__
);
return
FALSE
;
}
if
((
dir
=
opendir
(
path
))
==
NULL
)
{
rfbLog
(
"File [%s]: Method [%s]: Not able to open the directory
\n
"
,
__FILE__
,
__FUNCTION__
);
return
FALSE
;
}
else
{
closedir
(
dir
);
dir
=
NULL
;
}
memset
(
ftproot
,
0
,
PATH_MAX
);
if
(
path
[
strlen
(
path
)
-
1
]
==
'/'
)
{
memcpy
(
ftproot
,
path
,
strlen
(
path
)
-
1
);
}
else
memcpy
(
ftproot
,
path
,
strlen
(
path
));
return
TRUE
;
}
/*
* Get the home directory for the user name
* param: username - name of the user for whom the home directory is required.
* returns: returns the home directory for the user, or null in case the entry
* is not found or any error. The returned string must be freed by calling the
* freehomedir function.
*/
char
*
GetHomeDir
(
uid_t
uid
)
{
struct
passwd
*
pwEnt
=
NULL
;
char
*
homedir
=
NULL
;
pwEnt
=
getpwuid
(
uid
);
if
(
pwEnt
==
NULL
)
return
NULL
;
if
(
pwEnt
->
pw_dir
!=
NULL
)
{
homedir
=
strdup
(
pwEnt
->
pw_dir
);
}
return
homedir
;
}
/*
* Free the home directory allocated by a previous call to retrieve the home
* directory. param: homedir - the string returned by a previous call to
* retrieve home directory for a user.
*/
void
FreeHomeDir
(
char
*
homedir
)
{
free
(
homedir
);
}
/******************************************************************************
* General methods.
******************************************************************************/
/*
* When the console sends the File Transfer Request, it sends the file path with
* ftproot as "/". So on Agent, to get the absolute file path we need to prepend
* the ftproot to it.
*/
char
*
ConvertPath
(
char
*
path
)
{
char
p
[
PATH_MAX
];
memset
(
p
,
0
,
PATH_MAX
);
if
(
(
path
==
NULL
)
||
(
strlen
(
path
)
==
0
)
||
(
strlen
(
path
)
+
strlen
(
ftproot
)
>
PATH_MAX
-
1
)
)
{
rfbLog
(
"File [%s]: Method [%s]: cannot create path for file transfer
\n
"
,
__FILE__
,
__FUNCTION__
);
return
NULL
;
}
memcpy
(
p
,
path
,
strlen
(
path
));
memset
(
path
,
0
,
PATH_MAX
);
sprintf
(
path
,
"%s%s"
,
ftproot
,
p
);
return
path
;
}
void
EnableFileTransfer
(
rfbBool
enable
)
{
fileTransferEnabled
=
enable
;
}
rfbBool
IsFileTransferEnabled
()
{
return
fileTransferEnabled
;
}
char
*
GetFtpRoot
()
{
return
ftproot
;
}
/******************************************************************************
* Methods to Handle File List Request.
******************************************************************************/
/*
* HandleFileListRequest method is called when the server receives
* FileListRequest. In case of success a file list is sent to the client.
* For File List Request there is no failure reason sent.So here in case of any
* "unexpected" error no information will be sent. As these conditions should
* never come. Lets hope it never arrives :)
* In case of dir open failure an empty list will be sent, just the header of
* the message filled up. So on console you will get an Empty listing.
*/
void
HandleFileListRequest
(
rfbClientPtr
cl
,
rfbTightClientRec
*
data
)
{
rfbClientToServerTightMsg
msg
;
int
n
=
0
;
char
path
[
PATH_MAX
];
/* PATH_MAX has the value 4096 and is defined in limits.h */
FileTransferMsg
fileListMsg
;
memset
(
&
msg
,
0
,
sizeof
(
rfbClientToServerTightMsg
));
memset
(
path
,
0
,
PATH_MAX
);
memset
(
&
fileListMsg
,
0
,
sizeof
(
FileTransferMsg
));
if
(
cl
==
NULL
)
{
rfbLog
(
"File [%s]: Method [%s]: Unexpected error: rfbClientPtr is null
\n
"
,
__FILE__
,
__FUNCTION__
);
return
;
}
if
((
n
=
rfbReadExact
(
cl
,
((
char
*
)
&
msg
)
+
1
,
sz_rfbFileListRequestMsg
-
1
))
<=
0
)
{
if
(
n
<
0
)
rfbLog
(
"File [%s]: Method [%s]: Socket error while reading dir name"
" length
\n
"
,
__FILE__
,
__FUNCTION__
);
rfbCloseClient
(
cl
);
return
;
}
msg
.
flr
.
dirNameSize
=
Swap16IfLE
(
msg
.
flr
.
dirNameSize
);
if
((
msg
.
flr
.
dirNameSize
==
0
)
||
(
msg
.
flr
.
dirNameSize
>
(
PATH_MAX
-
1
)))
{
rfbLog
(
"File [%s]: Method [%s]: Unexpected error:: path length is "
"greater that PATH_MAX
\n
"
,
__FILE__
,
__FUNCTION__
);
return
;
}
if
((
n
=
rfbReadExact
(
cl
,
path
,
msg
.
flr
.
dirNameSize
))
<=
0
)
{
if
(
n
<
0
)
rfbLog
(
"File [%s]: Method [%s]: Socket error while reading dir name
\n
"
,
__FILE__
,
__FUNCTION__
);
rfbCloseClient
(
cl
);
return
;
}
if
(
ConvertPath
(
path
)
==
NULL
)
{
/* The execution should never reach here */
rfbLog
(
"File [%s]: Method [%s]: Unexpected error: path is NULL"
,
__FILE__
,
__FUNCTION__
);
return
;
}
fileListMsg
=
GetFileListResponseMsg
(
path
,
(
char
)
(
msg
.
flr
.
flags
));
if
((
fileListMsg
.
data
==
NULL
)
||
(
fileListMsg
.
length
==
0
))
{
rfbLog
(
"File [%s]: Method [%s]: Unexpected error:: Data to be sent is "
"of Zero length
\n
"
,
__FILE__
,
__FUNCTION__
);
return
;
}
rfbWriteExact
(
cl
,
fileListMsg
.
data
,
fileListMsg
.
length
);
FreeFileTransferMsg
(
fileListMsg
);
}
/******************************************************************************
* Methods to Handle File Download Request.
******************************************************************************/
void
HandleFileDownloadLengthError
(
rfbClientPtr
cl
,
short
fNameSize
);
void
SendFileDownloadLengthErrMsg
(
rfbClientPtr
cl
);
void
HandleFileDownload
(
rfbClientPtr
cl
,
rfbTightClientPtr
data
);
#ifdef TODO
void
HandleFileDownloadRequest
(
rfbClientPtr
cl
);
void
SendFileDownloadErrMsg
(
rfbClientPtr
cl
);
void
*
RunFileDownloadThread
(
void
*
client
);
#endif
/*
* HandleFileDownloadRequest method is called when the server receives
* rfbFileDownload request message.
*/
void
HandleFileDownloadRequest
(
rfbClientPtr
cl
,
rfbTightClientPtr
rtcp
)
{
int
n
=
0
;
char
path
[
PATH_MAX
];
/* PATH_MAX has the value 4096 and is defined in limits.h */
rfbClientToServerTightMsg
msg
;
memset
(
path
,
0
,
sizeof
(
path
));
memset
(
&
msg
,
0
,
sizeof
(
rfbClientToServerTightMsg
));
if
(
cl
==
NULL
)
{
rfbLog
(
"File [%s]: Method [%s]: Unexpected error:: rfbClientPtr is null
\n
"
,
__FILE__
,
__FUNCTION__
);
return
;
}
if
((
n
=
rfbReadExact
(
cl
,
((
char
*
)
&
msg
)
+
1
,
sz_rfbFileDownloadRequestMsg
-
1
))
<=
0
)
{
if
(
n
<
0
)
rfbLog
(
"File [%s]: Method [%s]: Error while reading dir name length
\n
"
,
__FILE__
,
__FUNCTION__
);
rfbCloseClient
(
cl
);
return
;
}
msg
.
fdr
.
fNameSize
=
Swap16IfLE
(
msg
.
fdr
.
fNameSize
);
msg
.
fdr
.
position
=
Swap16IfLE
(
msg
.
fdr
.
position
);
if
((
msg
.
fdr
.
fNameSize
==
0
)
||
(
msg
.
fdr
.
fNameSize
>
(
PATH_MAX
-
1
)))
{
rfbLog
(
"File [%s]: Method [%s]: Error: path length is greater than"
" PATH_MAX
\n
"
,
__FILE__
,
__FUNCTION__
);
HandleFileDownloadLengthError
(
cl
,
msg
.
fdr
.
fNameSize
);
return
;
}
if
((
n
=
rfbReadExact
(
cl
,
rtcp
->
rcft
.
rcfd
.
fName
,
msg
.
fdr
.
fNameSize
))
<=
0
)
{
if
(
n
<
0
)
rfbLog
(
"File [%s]: Method [%s]: Error while reading dir name length
\n
"
,
__FILE__
,
__FUNCTION__
);
rfbCloseClient
(
cl
);
return
;
}
rtcp
->
rcft
.
rcfd
.
fName
[
msg
.
fdr
.
fNameSize
]
=
'\0'
;
if
(
ConvertPath
(
rtcp
->
rcft
.
rcfd
.
fName
)
==
NULL
)
{
rfbLog
(
"File [%s]: Method [%s]: Unexpected error: path is NULL"
,
__FILE__
,
__FUNCTION__
);
/* This condition can come only if the file path is greater than
PATH_MAX. So sending file path length error msg back to client.
*/
SendFileDownloadLengthErrMsg
(
cl
);
return
;
}
HandleFileDownload
(
cl
,
rtcp
);
}
void
HandleFileDownloadLengthError
(
rfbClientPtr
cl
,
short
fNameSize
)
{
char
*
path
=
NULL
;
int
n
=
0
;
if
((
path
=
(
char
*
)
calloc
(
fNameSize
,
sizeof
(
char
)))
==
NULL
)
{
rfbLog
(
"File [%s]: Method [%s]: Fatal Error: Alloc failed
\n
"
,
__FILE__
,
__FUNCTION__
);
return
;
}
if
((
n
=
rfbReadExact
(
cl
,
path
,
fNameSize
))
<=
0
)
{
if
(
n
<
0
)
rfbLog
(
"File [%s]: Method [%s]: Error while reading dir name
\n
"
,
__FILE__
,
__FUNCTION__
);
rfbCloseClient
(
cl
);
if
(
path
!=
NULL
)
{
free
(
path
);
path
=
NULL
;
}
return
;
}
if
(
path
!=
NULL
)
{
free
(
path
);
path
=
NULL
;
}
SendFileDownloadLengthErrMsg
(
cl
);
}
void
SendFileDownloadLengthErrMsg
(
rfbClientPtr
cl
)
{
FileTransferMsg
fileDownloadErrMsg
;
memset
(
&
fileDownloadErrMsg
,
0
,
sizeof
(
FileTransferMsg
));
fileDownloadErrMsg
=
GetFileDownloadLengthErrResponseMsg
();
if
((
fileDownloadErrMsg
.
data
==
NULL
)
||
(
fileDownloadErrMsg
.
length
==
0
))
{
rfbLog
(
"File [%s]: Method [%s]: Unexpected error: fileDownloadErrMsg "
"is null
\n
"
,
__FILE__
,
__FUNCTION__
);
return
;
}
rfbWriteExact
(
cl
,
fileDownloadErrMsg
.
data
,
fileDownloadErrMsg
.
length
);
FreeFileTransferMsg
(
fileDownloadErrMsg
);
}
extern
rfbTightClientPtr
rfbGetTightClientData
(
rfbClientPtr
cl
);
void
*
RunFileDownloadThread
(
void
*
client
)
{
rfbClientPtr
cl
=
(
rfbClientPtr
)
client
;
rfbTightClientPtr
rtcp
=
rfbGetTightClientData
(
cl
);
FileTransferMsg
fileDownloadMsg
;
if
(
rtcp
==
NULL
)
return
NULL
;
memset
(
&
fileDownloadMsg
,
0
,
sizeof
(
FileTransferMsg
));
do
{
pthread_mutex_lock
(
&
fileDownloadMutex
);
fileDownloadMsg
=
GetFileDownloadResponseMsgInBlocks
(
cl
,
rtcp
);
pthread_mutex_unlock
(
&
fileDownloadMutex
);
if
((
fileDownloadMsg
.
data
!=
NULL
)
&&
(
fileDownloadMsg
.
length
!=
0
))
{
if
(
rfbWriteExact
(
cl
,
fileDownloadMsg
.
data
,
fileDownloadMsg
.
length
)
<
0
)
{
rfbLog
(
"File [%s]: Method [%s]: Error while writing to socket
\n
"
,
__FILE__
,
__FUNCTION__
);
if
(
cl
!=
NULL
)
{
rfbCloseClient
(
cl
);
CloseUndoneFileTransfer
(
cl
,
rtcp
);
}
FreeFileTransferMsg
(
fileDownloadMsg
);
return
NULL
;
}
FreeFileTransferMsg
(
fileDownloadMsg
);
}
}
while
(
rtcp
->
rcft
.
rcfd
.
downloadInProgress
==
TRUE
);
return
NULL
;
}
void
HandleFileDownload
(
rfbClientPtr
cl
,
rfbTightClientPtr
rtcp
)
{
pthread_t
fileDownloadThread
;
FileTransferMsg
fileDownloadMsg
;
memset
(
&
fileDownloadMsg
,
0
,
sizeof
(
FileTransferMsg
));
fileDownloadMsg
=
ChkFileDownloadErr
(
cl
,
rtcp
);
if
((
fileDownloadMsg
.
data
!=
NULL
)
&&
(
fileDownloadMsg
.
length
!=
0
))
{
rfbWriteExact
(
cl
,
fileDownloadMsg
.
data
,
fileDownloadMsg
.
length
);
FreeFileTransferMsg
(
fileDownloadMsg
);
return
;
}
rtcp
->
rcft
.
rcfd
.
downloadInProgress
=
FALSE
;
rtcp
->
rcft
.
rcfd
.
downloadFD
=
-
1
;
if
(
pthread_create
(
&
fileDownloadThread
,
NULL
,
RunFileDownloadThread
,
(
void
*
)
cl
)
!=
0
)
{
FileTransferMsg
ftm
=
GetFileDownLoadErrMsg
();
rfbLog
(
"File [%s]: Method [%s]: Download thread creation failed
\n
"
,
__FILE__
,
__FUNCTION__
);
if
((
ftm
.
data
!=
NULL
)
&&
(
ftm
.
length
!=
0
))
{
rfbWriteExact
(
cl
,
ftm
.
data
,
ftm
.
length
);
FreeFileTransferMsg
(
ftm
);
return
;
}
}
}
/******************************************************************************
* Methods to Handle File Download Cancel Request.
******************************************************************************/
void
HandleFileDownloadCancelRequest
(
rfbClientPtr
cl
,
rfbTightClientPtr
rtcp
)
{
int
n
=
0
;
char
*
reason
=
NULL
;
rfbClientToServerTightMsg
msg
;
memset
(
&
msg
,
0
,
sizeof
(
rfbClientToServerTightMsg
));
if
((
n
=
rfbReadExact
(
cl
,
((
char
*
)
&
msg
)
+
1
,
sz_rfbFileDownloadCancelMsg
-
1
))
<=
0
)
{
if
(
n
<
0
)
rfbLog
(
"File [%s]: Method [%s]: Error while reading "
"FileDownloadCancelMsg
\n
"
,
__FILE__
,
__FUNCTION__
);
rfbCloseClient
(
cl
);
return
;
}
msg
.
fdc
.
reasonLen
=
Swap16IfLE
(
msg
.
fdc
.
reasonLen
);
if
(
msg
.
fdc
.
reasonLen
==
0
)
{
rfbLog
(
"File [%s]: Method [%s]: reason length received is Zero
\n
"
,
__FILE__
,
__FUNCTION__
);
return
;
}
reason
=
(
char
*
)
calloc
(
msg
.
fdc
.
reasonLen
+
1
,
sizeof
(
char
));
if
(
reason
==
NULL
)
{
rfbLog
(
"File [%s]: Method [%s]: Fatal Error: Memory alloc failed
\n
"
,
__FILE__
,
__FUNCTION__
);
return
;
}
if
((
n
=
rfbReadExact
(
cl
,
reason
,
msg
.
fdc
.
reasonLen
))
<=
0
)
{
if
(
n
<
0
)
rfbLog
(
"File [%s]: Method [%s]: Error while reading "
"FileDownloadCancelMsg
\n
"
,
__FILE__
,
__FUNCTION__
);
rfbCloseClient
(
cl
);
}
rfbLog
(
"File [%s]: Method [%s]: File Download Cancel Request received:"
" reason <%s>
\n
"
,
__FILE__
,
__FUNCTION__
,
reason
);
pthread_mutex_lock
(
&
fileDownloadMutex
);
CloseUndoneFileTransfer
(
cl
,
rtcp
);
pthread_mutex_unlock
(
&
fileDownloadMutex
);
if
(
reason
!=
NULL
)
{
free
(
reason
);
reason
=
NULL
;
}
}
/******************************************************************************
* Methods to Handle File upload request
******************************************************************************/
#ifdef TODO
void
HandleFileUploadRequest
(
rfbClientPtr
cl
);
#endif
void
HandleFileUpload
(
rfbClientPtr
cl
,
rfbTightClientPtr
data
);
void
HandleFileUploadLengthError
(
rfbClientPtr
cl
,
short
fNameSize
);
void
SendFileUploadLengthErrMsg
(
rfbClientPtr
cl
);
void
HandleFileUploadRequest
(
rfbClientPtr
cl
,
rfbTightClientPtr
rtcp
)
{
int
n
=
0
;
char
path
[
PATH_MAX
];
/* PATH_MAX has the value 4096 and is defined in limits.h */
rfbClientToServerTightMsg
msg
;
memset
(
path
,
0
,
PATH_MAX
);
memset
(
&
msg
,
0
,
sizeof
(
rfbClientToServerTightMsg
));
if
(
cl
==
NULL
)
{
rfbLog
(
"File [%s]: Method [%s]: Unexpected error: rfbClientPtr is null
\n
"
,
__FILE__
,
__FUNCTION__
);
return
;
}
if
((
n
=
rfbReadExact
(
cl
,
((
char
*
)
&
msg
)
+
1
,
sz_rfbFileUploadRequestMsg
-
1
))
<=
0
)
{
if
(
n
<
0
)
rfbLog
(
"File [%s]: Method [%s]: Error while reading FileUploadRequestMsg
\n
"
,
__FILE__
,
__FUNCTION__
);
rfbCloseClient
(
cl
);
return
;
}
msg
.
fupr
.
fNameSize
=
Swap16IfLE
(
msg
.
fupr
.
fNameSize
);
msg
.
fupr
.
position
=
Swap16IfLE
(
msg
.
fupr
.
position
);
if
((
msg
.
fupr
.
fNameSize
==
0
)
||
(
msg
.
fupr
.
fNameSize
>
(
PATH_MAX
-
1
)))
{
rfbLog
(
"File [%s]: Method [%s]: error: path length is greater than PATH_MAX
\n
"
,
__FILE__
,
__FUNCTION__
);
HandleFileUploadLengthError
(
cl
,
msg
.
fupr
.
fNameSize
);
return
;
}
if
((
n
=
rfbReadExact
(
cl
,
rtcp
->
rcft
.
rcfu
.
fName
,
msg
.
fupr
.
fNameSize
))
<=
0
)
{
if
(
n
<
0
)
rfbLog
(
"File [%s]: Method [%s]: Error while reading FileUploadRequestMsg
\n
"
__FILE__
,
__FUNCTION__
);
rfbCloseClient
(
cl
);
return
;
}
rtcp
->
rcft
.
rcfu
.
fName
[
msg
.
fupr
.
fNameSize
]
=
'\0'
;
if
(
ConvertPath
(
rtcp
->
rcft
.
rcfu
.
fName
)
==
NULL
)
{
rfbLog
(
"File [%s]: Method [%s]: Unexpected error: path is NULL
\n
"
,
__FILE__
,
__FUNCTION__
);
/* This may come if the path length exceeds PATH_MAX.
So sending path length error to client
*/
SendFileUploadLengthErrMsg
(
cl
);
return
;
}
HandleFileUpload
(
cl
,
rtcp
);
}
void
HandleFileUploadLengthError
(
rfbClientPtr
cl
,
short
fNameSize
)
{
char
*
path
=
NULL
;
int
n
=
0
;
if
((
path
=
(
char
*
)
calloc
(
fNameSize
,
sizeof
(
char
)))
==
NULL
)
{
rfbLog
(
"File [%s]: Method [%s]: Fatal Error: Alloc failed
\n
"
,
__FILE__
,
__FUNCTION__
);
return
;
}
if
((
n
=
rfbReadExact
(
cl
,
path
,
fNameSize
))
<=
0
)
{
if
(
n
<
0
)
rfbLog
(
"File [%s]: Method [%s]: Error while reading dir name
\n
"
,
__FILE__
,
__FUNCTION__
);
rfbCloseClient
(
cl
);
if
(
path
!=
NULL
)
{
free
(
path
);
path
=
NULL
;
}
return
;
}
rfbLog
(
"File [%s]: Method [%s]: File Upload Length Error occured"
"file path requested is <%s>
\n
"
,
__FILE__
,
__FUNCTION__
,
path
);
if
(
path
!=
NULL
)
{
free
(
path
);
path
=
NULL
;
}
SendFileUploadLengthErrMsg
(
cl
);
}
void
SendFileUploadLengthErrMsg
(
rfbClientPtr
cl
)
{
FileTransferMsg
fileUploadErrMsg
;
memset
(
&
fileUploadErrMsg
,
0
,
sizeof
(
FileTransferMsg
));
fileUploadErrMsg
=
GetFileUploadLengthErrResponseMsg
();
if
((
fileUploadErrMsg
.
data
==
NULL
)
||
(
fileUploadErrMsg
.
length
==
0
))
{
rfbLog
(
"File [%s]: Method [%s]: Unexpected error: fileUploadErrMsg is null
\n
"
,
__FILE__
,
__FUNCTION__
);
return
;
}
rfbWriteExact
(
cl
,
fileUploadErrMsg
.
data
,
fileUploadErrMsg
.
length
);
FreeFileTransferMsg
(
fileUploadErrMsg
);
}
void
HandleFileUpload
(
rfbClientPtr
cl
,
rfbTightClientPtr
rtcp
)
{
FileTransferMsg
fileUploadErrMsg
;
memset
(
&
fileUploadErrMsg
,
0
,
sizeof
(
FileTransferMsg
));
rtcp
->
rcft
.
rcfu
.
uploadInProgress
=
FALSE
;
rtcp
->
rcft
.
rcfu
.
uploadFD
=
-
1
;
fileUploadErrMsg
=
ChkFileUploadErr
(
cl
,
rtcp
);
if
((
fileUploadErrMsg
.
data
!=
NULL
)
&&
(
fileUploadErrMsg
.
length
!=
0
))
{
rfbWriteExact
(
cl
,
fileUploadErrMsg
.
data
,
fileUploadErrMsg
.
length
);
FreeFileTransferMsg
(
fileUploadErrMsg
);
}
}
/******************************************************************************
* Methods to Handle File Upload Data Request
*****************************************************************************/
void
HandleFileUploadWrite
(
rfbClientPtr
cl
,
rfbTightClientPtr
rtcp
,
char
*
pBuf
);
void
HandleFileUploadDataRequest
(
rfbClientPtr
cl
,
rfbTightClientPtr
rtcp
)
{
int
n
=
0
;
char
*
pBuf
=
NULL
;
rfbClientToServerTightMsg
msg
;
memset
(
&
msg
,
0
,
sizeof
(
rfbClientToServerTightMsg
));
if
(
cl
==
NULL
)
{
rfbLog
(
"File [%s]: Method [%s]: Unexpected error: rfbClientPtr is null
\n
"
,
__FILE__
,
__FUNCTION__
);
return
;
}
if
((
n
=
rfbReadExact
(
cl
,
((
char
*
)
&
msg
)
+
1
,
sz_rfbFileUploadDataMsg
-
1
))
<=
0
)
{
if
(
n
<
0
)
rfbLog
(
"File [%s]: Method [%s]: Error while reading FileUploadRequestMsg
\n
"
,
__FILE__
,
__FUNCTION__
);
rfbCloseClient
(
cl
);
return
;
}
msg
.
fud
.
realSize
=
Swap16IfLE
(
msg
.
fud
.
realSize
);
msg
.
fud
.
compressedSize
=
Swap16IfLE
(
msg
.
fud
.
compressedSize
);
if
((
msg
.
fud
.
realSize
==
0
)
&&
(
msg
.
fud
.
compressedSize
==
0
))
{
if
((
n
=
rfbReadExact
(
cl
,
(
char
*
)
&
(
rtcp
->
rcft
.
rcfu
.
mTime
),
sizeof
(
unsigned
long
)))
<=
0
)
{
if
(
n
<
0
)
rfbLog
(
"File [%s]: Method [%s]: Error while reading FileUploadRequestMsg
\n
"
,
__FILE__
,
__FUNCTION__
);
rfbCloseClient
(
cl
);
return
;
}
FileUpdateComplete
(
cl
,
rtcp
);
return
;
}
pBuf
=
(
char
*
)
calloc
(
msg
.
fud
.
compressedSize
,
sizeof
(
char
));
if
(
pBuf
==
NULL
)
{
rfbLog
(
"File [%s]: Method [%s]: Memory alloc failed
\n
"
,
__FILE__
,
__FUNCTION__
);
return
;
}
if
((
n
=
rfbReadExact
(
cl
,
pBuf
,
msg
.
fud
.
compressedSize
))
<=
0
)
{
if
(
n
<
0
)
rfbLog
(
"File [%s]: Method [%s]: Error while reading FileUploadRequestMsg
\n
"
,
__FILE__
,
__FUNCTION__
);
rfbCloseClient
(
cl
);
if
(
pBuf
!=
NULL
)
{
free
(
pBuf
);
pBuf
=
NULL
;
}
return
;
}
if
(
msg
.
fud
.
compressedLevel
!=
0
)
{
FileTransferMsg
ftm
;
memset
(
&
ftm
,
0
,
sizeof
(
FileTransferMsg
));
ftm
=
GetFileUploadCompressedLevelErrMsg
();
if
((
ftm
.
data
!=
NULL
)
&&
(
ftm
.
length
!=
0
))
{
rfbWriteExact
(
cl
,
ftm
.
data
,
ftm
.
length
);
FreeFileTransferMsg
(
ftm
);
}
CloseUndoneFileTransfer
(
cl
,
rtcp
);
if
(
pBuf
!=
NULL
)
{
free
(
pBuf
);
pBuf
=
NULL
;
}
return
;
}
rtcp
->
rcft
.
rcfu
.
fSize
=
msg
.
fud
.
compressedSize
;
HandleFileUploadWrite
(
cl
,
rtcp
,
pBuf
);
if
(
pBuf
!=
NULL
)
{
free
(
pBuf
);
pBuf
=
NULL
;
}
}
void
HandleFileUploadWrite
(
rfbClientPtr
cl
,
rfbTightClientPtr
rtcp
,
char
*
pBuf
)
{
FileTransferMsg
ftm
;
memset
(
&
ftm
,
0
,
sizeof
(
FileTransferMsg
));
ftm
=
ChkFileUploadWriteErr
(
cl
,
rtcp
,
pBuf
);
if
((
ftm
.
data
!=
NULL
)
&&
(
ftm
.
length
!=
0
))
{
rfbWriteExact
(
cl
,
ftm
.
data
,
ftm
.
length
);
FreeFileTransferMsg
(
ftm
);
}
}
/******************************************************************************
* Methods to Handle File Upload Failed Request.
******************************************************************************/
void
HandleFileUploadFailedRequest
(
rfbClientPtr
cl
,
rfbTightClientPtr
rtcp
)
{
int
n
=
0
;
char
*
reason
=
NULL
;
rfbClientToServerTightMsg
msg
;
memset
(
&
msg
,
0
,
sizeof
(
rfbClientToServerTightMsg
));
if
(
cl
==
NULL
)
{
rfbLog
(
"File [%s]: Method [%s]: Unexpected error: rfbClientPtr is null
\n
"
,
__FILE__
,
__FUNCTION__
);
return
;
}
if
((
n
=
rfbReadExact
(
cl
,
((
char
*
)
&
msg
)
+
1
,
sz_rfbFileUploadFailedMsg
-
1
))
<=
0
)
{
if
(
n
<
0
)
rfbLog
(
"File [%s]: Method [%s]: Error while reading FileUploadFailedMsg
\n
"
,
__FILE__
,
__FUNCTION__
);
rfbCloseClient
(
cl
);
return
;
}
msg
.
fuf
.
reasonLen
=
Swap16IfLE
(
msg
.
fuf
.
reasonLen
);
if
(
msg
.
fuf
.
reasonLen
==
0
)
{
rfbLog
(
"File [%s]: Method [%s]: reason length received is Zero
\n
"
,
__FILE__
,
__FUNCTION__
);
return
;
}
reason
=
(
char
*
)
calloc
(
msg
.
fuf
.
reasonLen
+
1
,
sizeof
(
char
));
if
(
reason
==
NULL
)
{
rfbLog
(
"File [%s]: Method [%s]: Memory alloc failed
\n
"
,
__FILE__
,
__FUNCTION__
);
return
;
}
if
((
n
=
rfbReadExact
(
cl
,
reason
,
msg
.
fuf
.
reasonLen
))
<=
0
)
{
if
(
n
<
0
)
rfbLog
(
"File [%s]: Method [%s]: Error while reading FileUploadFailedMsg
\n
"
,
__FILE__
,
__FUNCTION__
);
rfbCloseClient
(
cl
);
if
(
reason
!=
NULL
)
{
free
(
reason
);
reason
=
NULL
;
}
return
;
}
rfbLog
(
"File [%s]: Method [%s]: File Upload Failed Request received:"
" reason <%s>
\n
"
,
__FILE__
,
__FUNCTION__
,
reason
);
CloseUndoneFileTransfer
(
cl
,
rtcp
);
if
(
reason
!=
NULL
)
{
free
(
reason
);
reason
=
NULL
;
}
}
/******************************************************************************
* Methods to Handle File Create Request.
******************************************************************************/
void
HandleFileCreateDirRequest
(
rfbClientPtr
cl
,
rfbTightClientPtr
rtcp
)
{
int
n
=
0
;
char
dirName
[
PATH_MAX
];
rfbClientToServerTightMsg
msg
;
memset
(
dirName
,
0
,
PATH_MAX
);
memset
(
&
msg
,
0
,
sizeof
(
rfbClientToServerTightMsg
));
if
(
cl
==
NULL
)
{
rfbLog
(
"File [%s]: Method [%s]: Unexpected error: rfbClientPtr is null
\n
"
,
__FILE__
,
__FUNCTION__
);
return
;
}
if
((
n
=
rfbReadExact
(
cl
,
((
char
*
)
&
msg
)
+
1
,
sz_rfbFileCreateDirRequestMsg
-
1
))
<=
0
)
{
if
(
n
<
0
)
rfbLog
(
"File [%s]: Method [%s]: Error while reading FileCreateDirRequestMsg
\n
"
,
__FILE__
,
__FUNCTION__
);
rfbCloseClient
(
cl
);
return
;
}
msg
.
fcdr
.
dNameLen
=
Swap16IfLE
(
msg
.
fcdr
.
dNameLen
);
/* TODO :: chk if the dNameLen is greater than PATH_MAX */
if
((
n
=
rfbReadExact
(
cl
,
dirName
,
msg
.
fcdr
.
dNameLen
))
<=
0
)
{
if
(
n
<
0
)
rfbLog
(
"File [%s]: Method [%s]: Error while reading FileUploadFailedMsg
\n
"
,
__FILE__
,
__FUNCTION__
);
rfbCloseClient
(
cl
);
return
;
}
if
(
ConvertPath
(
dirName
)
==
NULL
)
{
rfbLog
(
"File [%s]: Method [%s]: Unexpected error: path is NULL
\n
"
,
__FILE__
,
__FUNCTION__
);
return
;
}
CreateDirectory
(
dirName
);
}
libvncserver/tightvnc-filetransfer/handlefiletransferrequest.h
0 → 100644
View file @
0a909fde
/*
* 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
libvncserver/tightvnc-filetransfer/rfbtightproto.h
0 → 100644
View file @
0a909fde
/*
* 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 : 25th August 2005
*/
#ifndef RFBTIGHTPROTO_H
#define RFBTIGHTPROTO_H
#include <rfb/rfb.h>
#include <limits.h>
#define rfbSecTypeTight 16
void
rfbTightUsage
(
void
);
int
rfbTightProcessArgs
(
int
argc
,
char
*
argv
[]);
/*-----------------------------------------------------------------------------
* Negotiation of Tunneling Capabilities (protocol version 3.7t)
*
* If the chosen security type is rfbSecTypeTight, the server sends a list of
* supported tunneling methods ("tunneling" refers to any additional layer of
* data transformation, such as encryption or external compression.)
*
* nTunnelTypes specifies the number of following rfbCapabilityInfo structures
* that list all supported tunneling methods in the order of preference.
*
* NOTE: If nTunnelTypes is 0, that tells the client that no tunneling can be
* used, and the client should not send a response requesting a tunneling
* method.
*/
typedef
struct
_rfbTunnelingCapsMsg
{
uint32_t
nTunnelTypes
;
/* followed by nTunnelTypes * rfbCapabilityInfo structures */
}
rfbTunnelingCapsMsg
;
#define sz_rfbTunnelingCapsMsg 4
/*-----------------------------------------------------------------------------
* Tunneling Method Request (protocol version 3.7t)
*
* If the list of tunneling capabilities sent by the server was not empty, the
* client should reply with a 32-bit code specifying a particular tunneling
* method. The following code should be used for no tunneling.
*/
#define rfbNoTunneling 0
#define sig_rfbNoTunneling "NOTUNNEL"
/*-----------------------------------------------------------------------------
* Negotiation of Authentication Capabilities (protocol version 3.7t)
*
* After setting up tunneling, the server sends a list of supported
* authentication schemes.
*
* nAuthTypes specifies the number of following rfbCapabilityInfo structures
* that list all supported authentication schemes in the order of preference.
*
* NOTE: If nAuthTypes is 0, that tells the client that no authentication is
* necessary, and the client should not send a response requesting an
* authentication scheme.
*/
typedef
struct
_rfbAuthenticationCapsMsg
{
uint32_t
nAuthTypes
;
/* followed by nAuthTypes * rfbCapabilityInfo structures */
}
rfbAuthenticationCapsMsg
;
#define sz_rfbAuthenticationCapsMsg 4
/*-----------------------------------------------------------------------------
* Authentication Scheme Request (protocol version 3.7t)
*
* If the list of authentication capabilities sent by the server was not empty,
* the client should reply with a 32-bit code specifying a particular
* authentication scheme. The following codes are supported.
*/
#define rfbAuthNone 1
#define rfbAuthVNC 2
#define rfbAuthUnixLogin 129
#define rfbAuthExternal 130
#define sig_rfbAuthNone "NOAUTH__"
#define sig_rfbAuthVNC "VNCAUTH_"
#define sig_rfbAuthUnixLogin "ULGNAUTH"
#define sig_rfbAuthExternal "XTRNAUTH"
/*-----------------------------------------------------------------------------
* Structure used to describe protocol options such as tunneling methods,
* authentication schemes and message types (protocol version 3.7t).
*/
typedef
struct
_rfbCapabilityInfo
{
uint32_t
code
;
/* numeric identifier */
uint8_t
vendorSignature
[
4
];
/* vendor identification */
uint8_t
nameSignature
[
8
];
/* abbreviated option name */
}
rfbCapabilityInfo
;
#define sz_rfbCapabilityInfoVendor 4
#define sz_rfbCapabilityInfoName 8
#define sz_rfbCapabilityInfo 16
/*
* Vendors known by TightVNC: standard VNC/RealVNC, TridiaVNC, and TightVNC.
*/
#define rfbStandardVendor "STDV"
#define rfbTridiaVncVendor "TRDV"
#define rfbTightVncVendor "TGHT"
/* It's a good idea to keep these values a bit greater than required. */
#define MAX_TIGHT_ENCODINGS 10
#define MAX_TUNNELING_CAPS 16
#define MAX_AUTH_CAPS 16
typedef
struct
_rfbClientFileDownload
{
char
fName
[
PATH_MAX
];
int
downloadInProgress
;
unsigned
long
mTime
;
int
downloadFD
;
}
rfbClientFileDownload
;
typedef
struct
_rfbClientFileUpload
{
char
fName
[
PATH_MAX
];
int
uploadInProgress
;
unsigned
long
mTime
;
unsigned
long
fSize
;
int
uploadFD
;
}
rfbClientFileUpload
;
typedef
struct
_rfbClientFileTransfer
{
rfbClientFileDownload
rcfd
;
rfbClientFileUpload
rcfu
;
}
rfbClientFileTransfer
;
typedef
struct
_rfbTightClientRec
{
/* Lists of capability codes sent to clients. We remember these
lists to restrict clients from choosing those tunneling and
authentication types that were not advertised. */
int
nAuthCaps
;
uint32_t
authCaps
[
MAX_AUTH_CAPS
];
/* This is not useful while we don't support tunneling:
int nTunnelingCaps;
uint32_t tunnelingCaps[MAX_TUNNELING_CAPS]; */
rfbClientFileTransfer
rcft
;
}
rfbTightClientRec
,
*
rfbTightClientPtr
;
/*
* Macro to fill in an rfbCapabilityInfo structure (protocol 3.7t).
* Normally, using macros is no good, but this macro saves us from
* writing constants twice -- it constructs signature names from codes.
* Note that "code_sym" argument should be a single symbol, not an expression.
*/
#define SetCapInfo(cap_ptr, code_sym, vendor) \
{ \
rfbCapabilityInfo *pcap; \
pcap = (cap_ptr); \
pcap->code = Swap32IfLE(code_sym); \
memcpy(pcap->vendorSignature, (vendor), \
sz_rfbCapabilityInfoVendor); \
memcpy(pcap->nameSignature, sig_##code_sym, \
sz_rfbCapabilityInfoName); \
}
void
rfbHandleSecTypeTight
(
rfbClientPtr
cl
);
/*-----------------------------------------------------------------------------
* Server Interaction Capabilities Message (protocol version 3.7t)
*
* In the protocol version 3.7t, the server informs the client what message
* types it supports in addition to ones defined in the protocol version 3.7.
* Also, the server sends the list of all supported encodings (note that it's
* not necessary to advertise the "raw" encoding sinse it MUST be supported in
* RFB 3.x protocols).
*
* This data immediately follows the server initialisation message.
*/
typedef
struct
_rfbInteractionCapsMsg
{
uint16_t
nServerMessageTypes
;
uint16_t
nClientMessageTypes
;
uint16_t
nEncodingTypes
;
uint16_t
pad
;
/* reserved, must be 0 */
/* followed by nServerMessageTypes * rfbCapabilityInfo structures */
/* followed by nClientMessageTypes * rfbCapabilityInfo structures */
}
rfbInteractionCapsMsg
;
#define sz_rfbInteractionCapsMsg 8
#define rfbFileListData 130
#define rfbFileDownloadData 131
#define rfbFileUploadCancel 132
#define rfbFileDownloadFailed 133
/* signatures for non-standard messages */
#define sig_rfbFileListData "FTS_LSDT"
#define sig_rfbFileDownloadData "FTS_DNDT"
#define sig_rfbFileUploadCancel "FTS_UPCN"
#define sig_rfbFileDownloadFailed "FTS_DNFL"
#define rfbFileListRequest 130
#define rfbFileDownloadRequest 131
#define rfbFileUploadRequest 132
#define rfbFileUploadData 133
#define rfbFileDownloadCancel 134
#define rfbFileUploadFailed 135
#define rfbFileCreateDirRequest 136
/* signatures for non-standard messages */
#define sig_rfbFileListRequest "FTC_LSRQ"
#define sig_rfbFileDownloadRequest "FTC_DNRQ"
#define sig_rfbFileUploadRequest "FTC_UPRQ"
#define sig_rfbFileUploadData "FTC_UPDT"
#define sig_rfbFileDownloadCancel "FTC_DNCN"
#define sig_rfbFileUploadFailed "FTC_UPFL"
#define sig_rfbFileCreateDirRequest "FTC_FCDR"
/* signatures for basic encoding types */
#define sig_rfbEncodingRaw "RAW_____"
#define sig_rfbEncodingCopyRect "COPYRECT"
#define sig_rfbEncodingRRE "RRE_____"
#define sig_rfbEncodingCoRRE "CORRE___"
#define sig_rfbEncodingHextile "HEXTILE_"
#define sig_rfbEncodingZlib "ZLIB____"
#define sig_rfbEncodingTight "TIGHT___"
#define sig_rfbEncodingZlibHex "ZLIBHEX_"
/* signatures for "fake" encoding types */
#define sig_rfbEncodingCompressLevel0 "COMPRLVL"
#define sig_rfbEncodingXCursor "X11CURSR"
#define sig_rfbEncodingRichCursor "RCHCURSR"
#define sig_rfbEncodingPointerPos "POINTPOS"
#define sig_rfbEncodingLastRect "LASTRECT"
#define sig_rfbEncodingNewFBSize "NEWFBSIZ"
#define sig_rfbEncodingQualityLevel0 "JPEGQLVL"
/*-----------------------------------------------------------------------------
* FileListRequest
*/
typedef
struct
_rfbFileListRequestMsg
{
uint8_t
type
;
uint8_t
flags
;
uint16_t
dirNameSize
;
/* Followed by char Dirname[dirNameSize] */
}
rfbFileListRequestMsg
;
#define sz_rfbFileListRequestMsg 4
/*-----------------------------------------------------------------------------
* FileDownloadRequest
*/
typedef
struct
_rfbFileDownloadRequestMsg
{
uint8_t
type
;
uint8_t
compressedLevel
;
uint16_t
fNameSize
;
uint32_t
position
;
/* Followed by char Filename[fNameSize] */
}
rfbFileDownloadRequestMsg
;
#define sz_rfbFileDownloadRequestMsg 8
/*-----------------------------------------------------------------------------
* FileUploadRequest
*/
typedef
struct
_rfbFileUploadRequestMsg
{
uint8_t
type
;
uint8_t
compressedLevel
;
uint16_t
fNameSize
;
uint32_t
position
;
/* Followed by char Filename[fNameSize] */
}
rfbFileUploadRequestMsg
;
#define sz_rfbFileUploadRequestMsg 8
/*-----------------------------------------------------------------------------
* FileUploadData
*/
typedef
struct
_rfbFileUploadDataMsg
{
uint8_t
type
;
uint8_t
compressedLevel
;
uint16_t
realSize
;
uint16_t
compressedSize
;
/* Followed by File[compressedSize],
but if (realSize = compressedSize = 0) followed by uint32_t modTime */
}
rfbFileUploadDataMsg
;
#define sz_rfbFileUploadDataMsg 6
/*-----------------------------------------------------------------------------
* FileDownloadCancel
*/
typedef
struct
_rfbFileDownloadCancelMsg
{
uint8_t
type
;
uint8_t
unused
;
uint16_t
reasonLen
;
/* Followed by reason[reasonLen] */
}
rfbFileDownloadCancelMsg
;
#define sz_rfbFileDownloadCancelMsg 4
/*-----------------------------------------------------------------------------
* FileUploadFailed
*/
typedef
struct
_rfbFileUploadFailedMsg
{
uint8_t
type
;
uint8_t
unused
;
uint16_t
reasonLen
;
/* Followed by reason[reasonLen] */
}
rfbFileUploadFailedMsg
;
#define sz_rfbFileUploadFailedMsg 4
/*-----------------------------------------------------------------------------
* FileCreateDirRequest
*/
typedef
struct
_rfbFileCreateDirRequestMsg
{
uint8_t
type
;
uint8_t
unused
;
uint16_t
dNameLen
;
/* Followed by dName[dNameLen] */
}
rfbFileCreateDirRequestMsg
;
#define sz_rfbFileCreateDirRequestMsg 4
/*-----------------------------------------------------------------------------
* Union of all client->server messages.
*/
typedef
union
_rfbClientToServerTightMsg
{
rfbFileListRequestMsg
flr
;
rfbFileDownloadRequestMsg
fdr
;
rfbFileUploadRequestMsg
fupr
;
rfbFileUploadDataMsg
fud
;
rfbFileDownloadCancelMsg
fdc
;
rfbFileUploadFailedMsg
fuf
;
rfbFileCreateDirRequestMsg
fcdr
;
}
rfbClientToServerTightMsg
;
/*-----------------------------------------------------------------------------
* FileListData
*/
typedef
struct
_rfbFileListDataMsg
{
uint8_t
type
;
uint8_t
flags
;
uint16_t
numFiles
;
uint16_t
dataSize
;
uint16_t
compressedSize
;
/* Followed by SizeData[numFiles] */
/* Followed by Filenames[compressedSize] */
}
rfbFileListDataMsg
;
#define sz_rfbFileListDataMsg 8
/*-----------------------------------------------------------------------------
* FileDownloadData
*/
typedef
struct
_rfbFileDownloadDataMsg
{
uint8_t
type
;
uint8_t
compressLevel
;
uint16_t
realSize
;
uint16_t
compressedSize
;
/* Followed by File[copressedSize],
but if (realSize = compressedSize = 0) followed by uint32_t modTime */
}
rfbFileDownloadDataMsg
;
#define sz_rfbFileDownloadDataMsg 6
/*-----------------------------------------------------------------------------
* FileUploadCancel
*/
typedef
struct
_rfbFileUploadCancelMsg
{
uint8_t
type
;
uint8_t
unused
;
uint16_t
reasonLen
;
/* Followed by reason[reasonLen] */
}
rfbFileUploadCancelMsg
;
#define sz_rfbFileUploadCancelMsg 4
/*-----------------------------------------------------------------------------
* FileDownloadFailed
*/
typedef
struct
_rfbFileDownloadFailedMsg
{
uint8_t
type
;
uint8_t
unused
;
uint16_t
reasonLen
;
/* Followed by reason[reasonLen] */
}
rfbFileDownloadFailedMsg
;
#define sz_rfbFileDownloadFailedMsg 4
#endif
libvncserver/tightvnc-filetransfer/rfbtightserver.c
0 → 100644
View file @
0a909fde
/*
* 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 : 25th August 2005
*/
#include <rfb/rfb.h>
#include "rfbtightproto.h"
#include "handlefiletransferrequest.h"
/*
* Get my data!
*
* This gets the extension specific data from the client structure. If
* the data is not found, the client connection is closed, a complaint
* is logged, and NULL is returned.
*/
extern
rfbProtocolExtension
tightVncFileTransferExtension
;
rfbTightClientPtr
rfbGetTightClientData
(
rfbClientPtr
cl
)
{
rfbExtensionData
*
data
=
cl
->
extensions
;
while
(
data
&&
data
->
extension
!=
&
tightVncFileTransferExtension
)
data
=
data
->
next
;
if
(
data
==
NULL
)
{
rfbLog
(
"TightVNC enabled, but client data missing?!
\n
"
);
rfbCloseClient
(
cl
);
return
NULL
;
}
return
(
rfbTightClientPtr
)
data
->
data
;
}
/*
* Send the authentication challenge.
*/
static
void
rfbVncAuthSendChallenge
(
cl
)
rfbClientPtr
cl
;
{
// 4 byte header is alreay sent. Which is rfbSecTypeVncAuth (same as rfbVncAuth). Just send the challenge.
rfbRandomBytes
(
cl
->
authChallenge
);
if
(
rfbWriteExact
(
cl
,
(
char
*
)
cl
->
authChallenge
,
CHALLENGESIZE
)
<
0
)
{
rfbLogPerror
(
"rfbAuthNewClient: write"
);
rfbCloseClient
(
cl
);
return
;
}
/* Dispatch client input to rfbVncAuthProcessResponse. */
/* This methos is defined in auth.c file */
rfbAuthProcessClientMessage
(
cl
);
}
/*
* Read client's preferred authentication type (protocol 3.7t).
*/
void
rfbProcessClientAuthType
(
cl
)
rfbClientPtr
cl
;
{
uint32_t
auth_type
;
int
n
,
i
;
rfbTightClientPtr
rtcp
=
rfbGetTightClientData
(
cl
);
if
(
rtcp
==
NULL
)
return
;
/* Read authentication type selected by the client. */
n
=
rfbReadExact
(
cl
,
(
char
*
)
&
auth_type
,
sizeof
(
auth_type
));
if
(
n
<=
0
)
{
if
(
n
==
0
)
rfbLog
(
"rfbProcessClientAuthType: client gone
\n
"
);
else
rfbLogPerror
(
"rfbProcessClientAuthType: read"
);
rfbCloseClient
(
cl
);
return
;
}
auth_type
=
Swap32IfLE
(
auth_type
);
/* Make sure it was present in the list sent by the server. */
for
(
i
=
0
;
i
<
rtcp
->
nAuthCaps
;
i
++
)
{
if
(
auth_type
==
rtcp
->
authCaps
[
i
])
break
;
}
if
(
i
>=
rtcp
->
nAuthCaps
)
{
rfbLog
(
"rfbProcessClientAuthType: "
"wrong authentication type requested
\n
"
);
rfbCloseClient
(
cl
);
return
;
}
switch
(
auth_type
)
{
case
rfbAuthNone
:
/* Dispatch client input to rfbProcessClientInitMessage. */
cl
->
state
=
RFB_INITIALISATION
;
break
;
case
rfbAuthVNC
:
rfbVncAuthSendChallenge
(
cl
);
break
;
default
:
rfbLog
(
"rfbProcessClientAuthType: unknown authentication scheme
\n
"
);
rfbCloseClient
(
cl
);
}
}
/*
* Read tunneling type requested by the client (protocol 3.7t).
* NOTE: Currently, we don't support tunneling, and this function
* can never be called.
*/
void
rfbProcessClientTunnelingType
(
cl
)
rfbClientPtr
cl
;
{
/* If we were called, then something's really wrong. */
rfbLog
(
"rfbProcessClientTunnelingType: not implemented
\n
"
);
rfbCloseClient
(
cl
);
return
;
}
/*
* Send the list of our authentication capabilities to the client
* (protocol 3.7t).
*/
static
void
rfbSendAuthCaps
(
cl
)
rfbClientPtr
cl
;
{
rfbBool
authRequired
;
rfbAuthenticationCapsMsg
caps
;
rfbCapabilityInfo
caplist
[
MAX_AUTH_CAPS
];
int
count
=
0
;
rfbTightClientPtr
rtcp
=
rfbGetTightClientData
(
cl
);
if
(
rtcp
==
NULL
)
return
;
if
(
cl
->
screen
->
authPasswdData
&&
!
cl
->
reverseConnection
)
{
// chk if this condition is valid or not.
SetCapInfo
(
&
caplist
[
count
],
rfbAuthVNC
,
rfbStandardVendor
);
rtcp
->
authCaps
[
count
++
]
=
rfbAuthVNC
;
}
rtcp
->
nAuthCaps
=
count
;
caps
.
nAuthTypes
=
Swap32IfLE
((
uint32_t
)
count
);
if
(
rfbWriteExact
(
cl
,
(
char
*
)
&
caps
,
sz_rfbAuthenticationCapsMsg
)
<
0
)
{
rfbLogPerror
(
"rfbSendAuthCaps: write"
);
rfbCloseClient
(
cl
);
return
;
}
if
(
count
)
{
if
(
rfbWriteExact
(
cl
,
(
char
*
)
&
caplist
[
0
],
count
*
sz_rfbCapabilityInfo
)
<
0
)
{
rfbLogPerror
(
"rfbSendAuthCaps: write"
);
rfbCloseClient
(
cl
);
return
;
}
/* Dispatch client input to rfbProcessClientAuthType. */
/* Call the function for authentication from here */
rfbProcessClientAuthType
(
cl
);
}
else
{
/* Dispatch client input to rfbProcessClientInitMessage. */
cl
->
state
=
RFB_INITIALISATION
;
}
}
/*
* Send the list of our tunneling capabilities (protocol 3.7t).
*/
static
void
rfbSendTunnelingCaps
(
cl
)
rfbClientPtr
cl
;
{
rfbTunnelingCapsMsg
caps
;
uint32_t
nTypes
=
0
;
/* we don't support tunneling yet */
caps
.
nTunnelTypes
=
Swap32IfLE
(
nTypes
);
if
(
rfbWriteExact
(
cl
,
(
char
*
)
&
caps
,
sz_rfbTunnelingCapsMsg
)
<
0
)
{
rfbLogPerror
(
"rfbSendTunnelingCaps: write"
);
rfbCloseClient
(
cl
);
return
;
}
if
(
nTypes
)
{
/* Dispatch client input to rfbProcessClientTunnelingType(). */
/* The flow should not reach here as tunneling is not implemented. */
rfbProcessClientTunnelingType
(
cl
);
}
else
{
rfbSendAuthCaps
(
cl
);
}
}
/*
* rfbSendInteractionCaps is called after sending the server
* initialisation message, only if TightVNC protocol extensions were
* enabled (protocol 3.7t). In this function, we send the lists of
* supported protocol messages and encodings.
*/
/* Update these constants on changing capability lists below! */
/* Values updated for FTP */
#define N_SMSG_CAPS 4
#define N_CMSG_CAPS 6
#define N_ENC_CAPS 12
void
rfbSendInteractionCaps
(
cl
)
rfbClientPtr
cl
;
{
rfbInteractionCapsMsg
intr_caps
;
rfbCapabilityInfo
smsg_list
[
N_SMSG_CAPS
];
rfbCapabilityInfo
cmsg_list
[
N_CMSG_CAPS
];
rfbCapabilityInfo
enc_list
[
N_ENC_CAPS
];
int
i
;
/* Fill in the header structure sent prior to capability lists. */
intr_caps
.
nServerMessageTypes
=
Swap16IfLE
(
N_SMSG_CAPS
);
intr_caps
.
nClientMessageTypes
=
Swap16IfLE
(
N_CMSG_CAPS
);
intr_caps
.
nEncodingTypes
=
Swap16IfLE
(
N_ENC_CAPS
);
intr_caps
.
pad
=
0
;
/* Supported server->client message types. */
/* For file transfer support: */
i
=
0
;
if
((
IsFileTransferEnabled
()
==
TRUE
)
&&
(
cl
->
viewOnly
==
FALSE
))
{
SetCapInfo
(
&
smsg_list
[
i
++
],
rfbFileListData
,
rfbTightVncVendor
);
SetCapInfo
(
&
smsg_list
[
i
++
],
rfbFileDownloadData
,
rfbTightVncVendor
);
SetCapInfo
(
&
smsg_list
[
i
++
],
rfbFileUploadCancel
,
rfbTightVncVendor
);
SetCapInfo
(
&
smsg_list
[
i
++
],
rfbFileDownloadFailed
,
rfbTightVncVendor
);
if
(
i
!=
N_SMSG_CAPS
)
{
rfbLog
(
"rfbSendInteractionCaps: assertion failed, i != N_SMSG_CAPS
\n
"
);
rfbCloseClient
(
cl
);
return
;
}
}
/* Supported client->server message types. */
/* For file transfer support: */
i
=
0
;
if
((
IsFileTransferEnabled
()
==
TRUE
)
&&
(
cl
->
viewOnly
==
FALSE
))
{
SetCapInfo
(
&
cmsg_list
[
i
++
],
rfbFileListRequest
,
rfbTightVncVendor
);
SetCapInfo
(
&
cmsg_list
[
i
++
],
rfbFileDownloadRequest
,
rfbTightVncVendor
);
SetCapInfo
(
&
cmsg_list
[
i
++
],
rfbFileUploadRequest
,
rfbTightVncVendor
);
SetCapInfo
(
&
cmsg_list
[
i
++
],
rfbFileUploadData
,
rfbTightVncVendor
);
SetCapInfo
(
&
cmsg_list
[
i
++
],
rfbFileDownloadCancel
,
rfbTightVncVendor
);
SetCapInfo
(
&
cmsg_list
[
i
++
],
rfbFileUploadFailed
,
rfbTightVncVendor
);
if
(
i
!=
N_CMSG_CAPS
)
{
rfbLog
(
"rfbSendInteractionCaps: assertion failed, i != N_CMSG_CAPS
\n
"
);
rfbCloseClient
(
cl
);
return
;
}
}
/* Encoding types. */
i
=
0
;
SetCapInfo
(
&
enc_list
[
i
++
],
rfbEncodingCopyRect
,
rfbStandardVendor
);
SetCapInfo
(
&
enc_list
[
i
++
],
rfbEncodingRRE
,
rfbStandardVendor
);
SetCapInfo
(
&
enc_list
[
i
++
],
rfbEncodingCoRRE
,
rfbStandardVendor
);
SetCapInfo
(
&
enc_list
[
i
++
],
rfbEncodingHextile
,
rfbStandardVendor
);
SetCapInfo
(
&
enc_list
[
i
++
],
rfbEncodingZlib
,
rfbTridiaVncVendor
);
SetCapInfo
(
&
enc_list
[
i
++
],
rfbEncodingTight
,
rfbTightVncVendor
);
SetCapInfo
(
&
enc_list
[
i
++
],
rfbEncodingCompressLevel0
,
rfbTightVncVendor
);
SetCapInfo
(
&
enc_list
[
i
++
],
rfbEncodingQualityLevel0
,
rfbTightVncVendor
);
SetCapInfo
(
&
enc_list
[
i
++
],
rfbEncodingXCursor
,
rfbTightVncVendor
);
SetCapInfo
(
&
enc_list
[
i
++
],
rfbEncodingRichCursor
,
rfbTightVncVendor
);
SetCapInfo
(
&
enc_list
[
i
++
],
rfbEncodingPointerPos
,
rfbTightVncVendor
);
SetCapInfo
(
&
enc_list
[
i
++
],
rfbEncodingLastRect
,
rfbTightVncVendor
);
if
(
i
!=
N_ENC_CAPS
)
{
rfbLog
(
"rfbSendInteractionCaps: assertion failed, i != N_ENC_CAPS
\n
"
);
rfbCloseClient
(
cl
);
return
;
}
/* Send header and capability lists */
if
(
rfbWriteExact
(
cl
,
(
char
*
)
&
intr_caps
,
sz_rfbInteractionCapsMsg
)
<
0
||
rfbWriteExact
(
cl
,
(
char
*
)
&
smsg_list
[
0
],
sz_rfbCapabilityInfo
*
N_SMSG_CAPS
)
<
0
||
rfbWriteExact
(
cl
,
(
char
*
)
&
cmsg_list
[
0
],
sz_rfbCapabilityInfo
*
N_CMSG_CAPS
)
<
0
||
rfbWriteExact
(
cl
,
(
char
*
)
&
enc_list
[
0
],
sz_rfbCapabilityInfo
*
N_ENC_CAPS
)
<
0
)
{
rfbLogPerror
(
"rfbSendInteractionCaps: write"
);
rfbCloseClient
(
cl
);
return
;
}
/* Dispatch client input to rfbProcessClientNormalMessage(). */
cl
->
state
=
RFB_NORMAL
;
}
rfbBool
rfbTightExtensionInit
(
cl
,
data
)
rfbClientPtr
cl
;
void
**
data
;
{
rfbSendInteractionCaps
(
cl
);
return
TRUE
;
}
static
rfbBool
handleMessage
(
rfbClientPtr
cl
,
const
char
*
messageName
,
void
(
*
handler
)(
rfbClientPtr
cl
,
rfbTightClientPtr
data
))
{
rfbTightClientPtr
data
;
rfbLog
(
"%s message received
\n
"
,
messageName
);
if
((
IsFileTransferEnabled
()
==
FALSE
)
||
(
cl
->
viewOnly
==
TRUE
))
{
rfbCloseClient
(
cl
);
return
FALSE
;
}
data
=
rfbGetTightClientData
(
cl
);
if
(
data
==
NULL
)
return
FALSE
;
handler
(
cl
,
data
);
return
TRUE
;
}
rfbBool
rfbTightExtensionMsgHandler
(
cl
,
data
,
msg
)
struct
_rfbClientRec
*
cl
;
void
*
data
;
const
rfbClientToServerMsg
*
msg
;
{
switch
(
msg
->
type
)
{
case
rfbFileListRequest
:
return
handleMessage
(
cl
,
"rfbFileListRequest"
,
HandleFileListRequest
);
case
rfbFileDownloadRequest
:
return
handleMessage
(
cl
,
"rfbFileDownloadRequest"
,
HandleFileDownloadRequest
);
case
rfbFileUploadRequest
:
return
handleMessage
(
cl
,
"rfbFileUploadRequest"
,
HandleFileUploadRequest
);
case
rfbFileUploadData
:
return
handleMessage
(
cl
,
"rfbFileUploadDataRequest"
,
HandleFileUploadDataRequest
);
case
rfbFileDownloadCancel
:
return
handleMessage
(
cl
,
"rfbFileDownloadCancelRequest"
,
HandleFileDownloadCancelRequest
);
case
rfbFileUploadFailed
:
return
handleMessage
(
cl
,
"rfbFileUploadFailedRequest"
,
HandleFileUploadFailedRequest
);
case
rfbFileCreateDirRequest
:
return
handleMessage
(
cl
,
"rfbFileCreateDirRequest"
,
HandleFileCreateDirRequest
);
default
:
rfbLog
(
"rfbProcessClientNormalMessage: unknown message type %d
\n
"
,
msg
->
type
);
/*
// We shouldn't close the connection here for unhandled msg, it should be left to libvncserver.
rfbLog(" ... closing connection\n");
rfbCloseClient(cl);
*/
return
FALSE
;
}
}
void
rfbTightExtensionClientClose
(
rfbClientPtr
cl
,
void
*
data
)
{
if
(
data
!=
NULL
)
free
(
data
);
}
void
rfbTightUsage
(
void
)
{
fprintf
(
stderr
,
"
\n
libvncserver-tight-extension options:
\n
"
);
fprintf
(
stderr
,
"-disablefiletransfer disable file transfer
\n
"
);
fprintf
(
stderr
,
"-ftproot string set ftp root
\n
"
);
fprintf
(
stderr
,
"
\n
"
);
}
int
rfbTightProcessArg
(
int
argc
,
char
*
argv
[])
{
InitFileTransfer
();
if
(
argc
<
1
)
return
0
;
if
(
strcmp
(
argv
[
0
],
"-ftproot"
)
==
0
)
{
/* -ftproot string */
if
(
2
>
argc
)
{
return
0
;
}
rfbLog
(
"ftproot is set to <%s>
\n
"
,
argv
[
1
]);
if
(
SetFtpRoot
(
argv
[
1
])
==
FALSE
)
{
rfbLog
(
"ERROR:: Path specified for ftproot in invalid
\n
"
);
return
0
;
}
return
2
;
}
else
if
(
strcmp
(
argv
[
0
],
"-disablefiletransfer"
)
==
0
)
{
EnableFileTransfer
(
FALSE
);
return
1
;
}
return
0
;
}
/*
* This method should be registered to libvncserver to handle rfbSecTypeTight security type.
*/
void
rfbHandleSecTypeTight
(
rfbClientPtr
cl
)
{
rfbTightClientPtr
rtcp
=
(
rfbTightClientPtr
)
malloc
(
sizeof
(
rfbTightClientRec
));
if
(
rtcp
==
NULL
)
{
// Error condition close socket
rfbLog
(
"Memory error has occured while handling Tight security type... closing connection.
\n
"
);
rfbCloseClient
(
cl
);
return
;
}
memset
(
rtcp
,
0
,
sizeof
(
rfbTightClientRec
));
rtcp
->
rcft
.
rcfd
.
downloadFD
=
-
1
;
rtcp
->
rcft
.
rcfu
.
uploadFD
=
-
1
;
rfbEnableExtension
(
cl
,
&
tightVncFileTransferExtension
,
rtcp
);
rfbSendTunnelingCaps
(
cl
);
}
rfbProtocolExtension
tightVncFileTransferExtension
=
{
NULL
,
rfbTightExtensionInit
,
rfbTightExtensionMsgHandler
,
rfbTightExtensionClientClose
,
rfbTightUsage
,
rfbTightProcessArg
,
NULL
};
static
rfbSecurityHandler
tightVncSecurityHandler
=
{
rfbSecTypeTight
,
rfbHandleSecTypeTight
,
NULL
};
void
rfbRegisterTightVNCFileTransferExtension
()
{
rfbRegisterProtocolExtension
(
&
tightVncFileTransferExtension
);
rfbRegisterSecurityHandler
(
&
tightVncSecurityHandler
);
}
rfb/rfb.h
View file @
0a909fde
...
@@ -159,16 +159,20 @@ typedef struct _rfbSecurity {
...
@@ -159,16 +159,20 @@ typedef struct _rfbSecurity {
*/
*/
typedef
struct
_rfbProtocolExtension
{
typedef
struct
_rfbProtocolExtension
{
/* returns TRUE if extension should be activated */
/* returns FALSE if extension should be deactivated for client.
rfbBool
(
*
init
)(
struct
_rfbClientRec
*
client
,
void
**
data
);
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 */
/* returns TRUE if message was handled */
rfbBool
(
*
handleMessage
)(
struct
_rfbClientRec
*
client
,
rfbBool
(
*
handleMessage
)(
struct
_rfbClientRec
*
client
,
void
*
data
,
void
*
data
,
rfbClientToServerMsg
message
);
const
rfbClientToServerMsg
*
message
);
void
(
*
close
)(
struct
_rfbClientRec
*
client
,
void
*
data
);
void
(
*
close
)(
struct
_rfbClientRec
*
client
,
void
*
data
);
void
(
*
usage
)(
void
);
void
(
*
usage
)(
void
);
/* processArguments returns the number of handled arguments */
/* processArguments returns the number of handled arguments */
int
(
*
processArgument
)(
char
*
argv
[]);
int
(
*
processArgument
)(
int
argc
,
char
*
argv
[]);
struct
_rfbProtocolExtension
*
next
;
struct
_rfbProtocolExtension
*
next
;
}
rfbProtocolExtension
;
}
rfbProtocolExtension
;
...
@@ -623,6 +627,7 @@ extern void rfbHttpCheckFds(rfbScreenInfoPtr rfbScreen);
...
@@ -623,6 +627,7 @@ extern void rfbHttpCheckFds(rfbScreenInfoPtr rfbScreen);
/* auth.c */
/* auth.c */
extern
void
rfbAuthNewClient
(
rfbClientPtr
cl
);
extern
void
rfbAuthNewClient
(
rfbClientPtr
cl
);
extern
void
rfbProcessClientSecurityType
(
rfbClientPtr
cl
);
extern
void
rfbAuthProcessClientMessage
(
rfbClientPtr
cl
);
extern
void
rfbAuthProcessClientMessage
(
rfbClientPtr
cl
);
extern
void
rfbRegisterSecurityHandler
(
rfbSecurityHandler
*
handler
);
extern
void
rfbRegisterSecurityHandler
(
rfbSecurityHandler
*
handler
);
...
@@ -788,7 +793,9 @@ enum rfbNewClientAction defaultNewClientHook(rfbClientPtr cl);
...
@@ -788,7 +793,9 @@ enum rfbNewClientAction defaultNewClientHook(rfbClientPtr cl);
void
rfbRegisterProtocolExtension
(
rfbProtocolExtension
*
extension
);
void
rfbRegisterProtocolExtension
(
rfbProtocolExtension
*
extension
);
struct
_rfbProtocolExtension
*
rfbGetExtensionIterator
();
struct
_rfbProtocolExtension
*
rfbGetExtensionIterator
();
void
rfbReleaseExtensionIterator
();
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 */
/* to check against plain passwords */
rfbBool
rfbCheckPasswordByList
(
rfbClientPtr
cl
,
const
char
*
response
,
int
len
);
rfbBool
rfbCheckPasswordByList
(
rfbClientPtr
cl
,
const
char
*
response
,
int
len
);
...
@@ -821,6 +828,9 @@ extern void rfbRunEventLoop(rfbScreenInfoPtr screenInfo, long usec, rfbBool runI
...
@@ -821,6 +828,9 @@ extern void rfbRunEventLoop(rfbScreenInfoPtr screenInfo, long usec, rfbBool runI
extern
rfbBool
rfbProcessEvents
(
rfbScreenInfoPtr
screenInfo
,
long
usec
);
extern
rfbBool
rfbProcessEvents
(
rfbScreenInfoPtr
screenInfo
,
long
usec
);
extern
rfbBool
rfbIsActive
(
rfbScreenInfoPtr
screenInfo
);
extern
rfbBool
rfbIsActive
(
rfbScreenInfoPtr
screenInfo
);
/* TightVNC file transfer extension */
void
rfbRegisterTightVNCFileTransferExtension
();
#endif
#endif
#if(defined __cplusplus)
#if(defined __cplusplus)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment