1 /*
2 * Copyright (c) 2005 Novell, Inc.
3 * All Rights Reserved.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, contact Novell, Inc.
16 *
17 * To contact Novell about this file by physical or electronic mail,
18 * you may find current contact information at www.novell.com
19 *
20 * Author : Rohit Kumar
21 * Email ID : rokumar@novell.com
22 * Date : 14th July 2005
23 */
24
25 #ifndef _MSC_VER
26 #include <pwd.h>
27 #endif /* _MSC_VER */
28
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <unistd.h>
33 #ifndef _MSC_VER
34 #include <dirent.h>
35 #include <pthread.h>
36 #endif /* _MSC_VER */
37 #include <sys/stat.h>
38 #include <sys/types.h>
39 #include <limits.h>
40
41 #include <rfb/rfb.h>
42 #include "rfbtightproto.h"
43 #include "filetransfermsg.h"
44 #include "handlefiletransferrequest.h"
45
46
47 pthread_mutex_t fileDownloadMutex = PTHREAD_MUTEX_INITIALIZER;
48
49 rfbBool fileTransferEnabled = TRUE;
50 rfbBool fileTransferInitted = FALSE;
51 char ftproot[PATH_MAX];
52
53
54 /******************************************************************************
55 * File Transfer Init methods. These methods are called for initializating
56 * File Transfer and setting ftproot.
57 ******************************************************************************/
58
59 void InitFileTransfer();
60 int SetFtpRoot(char* path);
61 char* GetHomeDir(uid_t uid);
62 void FreeHomeDir(char *homedir);
63
64 /*
65 * InitFileTransfer method is called before parsing the command-line options
66 * for Xvnc. This sets the ftproot to the Home dir of the user running the Xvnc
67 * server. In case of error ftproot is set to '\0' char.
68 */
69
70 void
InitFileTransfer()71 InitFileTransfer()
72 {
73 char* userHome = NULL;
74 uid_t uid = geteuid();
75
76 if(fileTransferInitted)
77 return;
78
79 rfbLog("tightvnc-filetransfer/InitFileTransfer\n");
80
81 memset(ftproot, 0, sizeof(ftproot));
82
83 userHome = GetHomeDir(uid);
84
85 if((userHome != NULL) && (strlen(userHome) != 0)) {
86 SetFtpRoot(userHome);
87 FreeHomeDir(userHome);
88 }
89
90 fileTransferEnabled = TRUE;
91 fileTransferInitted = TRUE;
92 }
93
94 #ifndef __GNUC__
95 #define __FUNCTION__ "unknown"
96 #endif
97
98 /*
99 * This method is called from InitFileTransfer method and
100 * if the command line option for ftproot is provided.
101 */
102 int
SetFtpRoot(char * path)103 SetFtpRoot(char* path)
104 {
105 struct stat stat_buf;
106 DIR* dir = NULL;
107
108 rfbLog("tightvnc-filetransfer/SetFtpRoot\n");
109
110 if((path == NULL) || (strlen(path) == 0) || (strlen(path) > (PATH_MAX - 1))) {
111 rfbLog("File [%s]: Method [%s]: parameter passed is improper, ftproot"
112 " not changed\n", __FILE__, __FUNCTION__);
113 return FALSE;
114 }
115
116 if(stat(path, &stat_buf) < 0) {
117 rfbLog("File [%s]: Method [%s]: Reading stat for file %s failed\n",
118 __FILE__, __FUNCTION__, path);
119 return FALSE;
120 }
121
122 if(S_ISDIR(stat_buf.st_mode) == 0) {
123 rfbLog("File [%s]: Method [%s]: path specified is not a directory\n",
124 __FILE__, __FUNCTION__);
125 return FALSE;
126 }
127
128 if((dir = opendir(path)) == NULL) {
129 rfbLog("File [%s]: Method [%s]: Not able to open the directory\n",
130 __FILE__, __FUNCTION__);
131 return FALSE;
132 }
133 else {
134 closedir(dir);
135 dir = NULL;
136 }
137
138
139 memset(ftproot, 0, PATH_MAX);
140 if(path[strlen(path)-1] == '/') {
141 memcpy(ftproot, path, strlen(path)-1);
142 }
143 else
144 memcpy(ftproot, path, strlen(path));
145
146
147 return TRUE;
148 }
149
150
151 /*
152 * Get the home directory for the user name
153 * param: username - name of the user for whom the home directory is required.
154 * returns: returns the home directory for the user, or null in case the entry
155 * is not found or any error. The returned string must be freed by calling the
156 * freehomedir function.
157 */
158 char*
GetHomeDir(uid_t uid)159 GetHomeDir(uid_t uid)
160 {
161 struct passwd *pwEnt = NULL;
162 char *homedir = NULL;
163
164 pwEnt = getpwuid (uid);
165 if (pwEnt == NULL)
166 return NULL;
167
168 if(pwEnt->pw_dir != NULL) {
169 homedir = strdup (pwEnt->pw_dir);
170 }
171
172 return homedir;
173 }
174
175
176 /*
177 * Free the home directory allocated by a previous call to retrieve the home
178 * directory. param: homedir - the string returned by a previous call to
179 * retrieve home directory for a user.
180 */
181 void
FreeHomeDir(char * homedir)182 FreeHomeDir(char *homedir)
183 {
184 free (homedir);
185 }
186
187
188 /******************************************************************************
189 * General methods.
190 ******************************************************************************/
191
192 /*
193 * When the console sends the File Transfer Request, it sends the file path with
194 * ftproot as "/". So on Agent, to get the absolute file path we need to prepend
195 * the ftproot to it.
196 */
197 char*
ConvertPath(char * path)198 ConvertPath(char* path)
199 {
200 char p[PATH_MAX];
201 memset(p, 0, PATH_MAX);
202
203 if( (path == NULL) ||
204 (strlen(path) == 0) ||
205 (strlen(path)+strlen(ftproot) > PATH_MAX - 1) ) {
206
207 rfbLog("File [%s]: Method [%s]: cannot create path for file transfer\n",
208 __FILE__, __FUNCTION__);
209 return NULL;
210 }
211
212 memcpy(p, path, strlen(path));
213 memset(path, 0, PATH_MAX);
214 sprintf(path, "%s%s", ftproot, p);
215
216 return path;
217 }
218
219
220 void
EnableFileTransfer(rfbBool enable)221 EnableFileTransfer(rfbBool enable)
222 {
223 fileTransferEnabled = enable;
224 }
225
226
227 rfbBool
IsFileTransferEnabled()228 IsFileTransferEnabled()
229 {
230 return fileTransferEnabled;
231 }
232
233
234 char*
GetFtpRoot()235 GetFtpRoot()
236 {
237 return ftproot;
238 }
239
240
241 /******************************************************************************
242 * Methods to Handle File List Request.
243 ******************************************************************************/
244
245 /*
246 * HandleFileListRequest method is called when the server receives
247 * FileListRequest. In case of success a file list is sent to the client.
248 * For File List Request there is no failure reason sent.So here in case of any
249 * "unexpected" error no information will be sent. As these conditions should
250 * never come. Lets hope it never arrives :)
251 * In case of dir open failure an empty list will be sent, just the header of
252 * the message filled up. So on console you will get an Empty listing.
253 */
254 void
HandleFileListRequest(rfbClientPtr cl,rfbTightClientRec * data)255 HandleFileListRequest(rfbClientPtr cl, rfbTightClientRec* data)
256 {
257 rfbClientToServerTightMsg msg;
258 int n = 0;
259 char path[PATH_MAX]; /* PATH_MAX has the value 4096 and is defined in limits.h */
260 FileTransferMsg fileListMsg;
261
262 memset(&msg, 0, sizeof(rfbClientToServerTightMsg));
263 memset(path, 0, PATH_MAX);
264 memset(&fileListMsg, 0, sizeof(FileTransferMsg));
265
266 if(cl == NULL) {
267 rfbLog("File [%s]: Method [%s]: Unexpected error: rfbClientPtr is null\n",
268 __FILE__, __FUNCTION__);
269 return;
270 }
271
272 if((n = rfbReadExact(cl, ((char *)&msg)+1, sz_rfbFileListRequestMsg-1)) <= 0) {
273
274 if (n < 0)
275 rfbLog("File [%s]: Method [%s]: Socket error while reading dir name"
276 " length\n", __FILE__, __FUNCTION__);
277
278 rfbCloseClient(cl);
279 return;
280 }
281
282 msg.flr.dirNameSize = Swap16IfLE(msg.flr.dirNameSize);
283 if ((msg.flr.dirNameSize == 0) ||
284 (msg.flr.dirNameSize > (PATH_MAX - 1))) {
285
286 rfbLog("File [%s]: Method [%s]: Unexpected error:: path length is "
287 "greater that PATH_MAX\n", __FILE__, __FUNCTION__);
288
289 return;
290 }
291
292 if((n = rfbReadExact(cl, path, msg.flr.dirNameSize)) <= 0) {
293
294 if (n < 0)
295 rfbLog("File [%s]: Method [%s]: Socket error while reading dir name\n",
296 __FILE__, __FUNCTION__);
297
298 rfbCloseClient(cl);
299 return;
300 }
301
302 if(ConvertPath(path) == NULL) {
303
304 /* The execution should never reach here */
305 rfbLog("File [%s]: Method [%s]: Unexpected error: path is NULL",
306 __FILE__, __FUNCTION__);
307 return;
308 }
309
310 fileListMsg = GetFileListResponseMsg(path, (char) (msg.flr.flags));
311
312 if((fileListMsg.data == NULL) || (fileListMsg.length == 0)) {
313
314 rfbLog("File [%s]: Method [%s]: Unexpected error:: Data to be sent is "
315 "of Zero length\n", __FILE__, __FUNCTION__);
316 return;
317 }
318
319 rfbWriteExact(cl, fileListMsg.data, fileListMsg.length);
320
321 FreeFileTransferMsg(fileListMsg);
322 }
323
324
325 /******************************************************************************
326 * Methods to Handle File Download Request.
327 ******************************************************************************/
328
329 void HandleFileDownloadLengthError(rfbClientPtr cl, short fNameSize);
330 void SendFileDownloadLengthErrMsg(rfbClientPtr cl);
331 void HandleFileDownload(rfbClientPtr cl, rfbTightClientPtr data);
332 #ifdef TODO
333 void HandleFileDownloadRequest(rfbClientPtr cl);
334 void SendFileDownloadErrMsg(rfbClientPtr cl);
335 void* RunFileDownloadThread(void* client);
336 #endif
337
338 /*
339 * HandleFileDownloadRequest method is called when the server receives
340 * rfbFileDownload request message.
341 */
342 void
HandleFileDownloadRequest(rfbClientPtr cl,rfbTightClientPtr rtcp)343 HandleFileDownloadRequest(rfbClientPtr cl, rfbTightClientPtr rtcp)
344 {
345 int n = 0;
346 char path[PATH_MAX]; /* PATH_MAX has the value 4096 and is defined in limits.h */
347 rfbClientToServerTightMsg msg;
348
349 memset(path, 0, sizeof(path));
350 memset(&msg, 0, sizeof(rfbClientToServerTightMsg));
351
352 if(cl == NULL) {
353
354 rfbLog("File [%s]: Method [%s]: Unexpected error:: rfbClientPtr is null\n",
355 __FILE__, __FUNCTION__);
356 return;
357 }
358
359 if((n = rfbReadExact(cl, ((char *)&msg)+1, sz_rfbFileDownloadRequestMsg-1)) <= 0) {
360
361 if (n < 0)
362 rfbLog("File [%s]: Method [%s]: Error while reading dir name length\n",
363 __FILE__, __FUNCTION__);
364
365 rfbCloseClient(cl);
366 return;
367 }
368
369 msg.fdr.fNameSize = Swap16IfLE(msg.fdr.fNameSize);
370 msg.fdr.position = Swap16IfLE(msg.fdr.position);
371
372 if ((msg.fdr.fNameSize == 0) ||
373 (msg.fdr.fNameSize > (PATH_MAX - 1))) {
374
375 rfbLog("File [%s]: Method [%s]: Error: path length is greater than"
376 " PATH_MAX\n", __FILE__, __FUNCTION__);
377
378 HandleFileDownloadLengthError(cl, msg.fdr.fNameSize);
379 return;
380 }
381
382 if((n = rfbReadExact(cl, rtcp->rcft.rcfd.fName, msg.fdr.fNameSize)) <= 0) {
383
384 if (n < 0)
385 rfbLog("File [%s]: Method [%s]: Error while reading dir name length\n",
386 __FILE__, __FUNCTION__);
387
388 rfbCloseClient(cl);
389 return;
390 }
391 rtcp->rcft.rcfd.fName[msg.fdr.fNameSize] = '\0';
392
393 if(ConvertPath(rtcp->rcft.rcfd.fName) == NULL) {
394
395 rfbLog("File [%s]: Method [%s]: Unexpected error: path is NULL",
396 __FILE__, __FUNCTION__);
397
398
399 /* This condition can come only if the file path is greater than
400 PATH_MAX. So sending file path length error msg back to client.
401 */
402
403 SendFileDownloadLengthErrMsg(cl);
404 return;
405 }
406
407 HandleFileDownload(cl, rtcp);
408
409 }
410
411
412 void
HandleFileDownloadLengthError(rfbClientPtr cl,short fNameSize)413 HandleFileDownloadLengthError(rfbClientPtr cl, short fNameSize)
414 {
415 char *path = NULL;
416 int n = 0;
417
418 if((path = (char*) calloc(fNameSize, sizeof(char))) == NULL) {
419 rfbLog("File [%s]: Method [%s]: Fatal Error: Alloc failed\n",
420 __FILE__, __FUNCTION__);
421 return;
422 }
423 if((n = rfbReadExact(cl, path, fNameSize)) <= 0) {
424
425 if (n < 0)
426 rfbLog("File [%s]: Method [%s]: Error while reading dir name\n",
427 __FILE__, __FUNCTION__);
428
429 rfbCloseClient(cl);
430
431 if(path != NULL) {
432 free(path);
433 path = NULL;
434 }
435
436 return;
437 }
438
439 if(path != NULL) {
440 free(path);
441 path = NULL;
442 }
443
444 SendFileDownloadLengthErrMsg(cl);
445 }
446
447
448 void
SendFileDownloadLengthErrMsg(rfbClientPtr cl)449 SendFileDownloadLengthErrMsg(rfbClientPtr cl)
450 {
451 FileTransferMsg fileDownloadErrMsg;
452
453 memset(&fileDownloadErrMsg, 0 , sizeof(FileTransferMsg));
454
455 fileDownloadErrMsg = GetFileDownloadLengthErrResponseMsg();
456
457 if((fileDownloadErrMsg.data == NULL) || (fileDownloadErrMsg.length == 0)) {
458 rfbLog("File [%s]: Method [%s]: Unexpected error: fileDownloadErrMsg "
459 "is null\n", __FILE__, __FUNCTION__);
460 return;
461 }
462
463 rfbWriteExact(cl, fileDownloadErrMsg.data, fileDownloadErrMsg.length);
464
465 FreeFileTransferMsg(fileDownloadErrMsg);
466 }
467
468 extern rfbTightClientPtr rfbGetTightClientData(rfbClientPtr cl);
469
470 void*
RunFileDownloadThread(void * client)471 RunFileDownloadThread(void* client)
472 {
473 rfbClientPtr cl = (rfbClientPtr) client;
474 rfbTightClientPtr rtcp = rfbGetTightClientData(cl);
475 FileTransferMsg fileDownloadMsg;
476
477 if(rtcp == NULL)
478 return NULL;
479
480 memset(&fileDownloadMsg, 0, sizeof(FileTransferMsg));
481 do {
482 pthread_mutex_lock(&fileDownloadMutex);
483 fileDownloadMsg = GetFileDownloadResponseMsgInBlocks(cl, rtcp);
484 pthread_mutex_unlock(&fileDownloadMutex);
485
486 if((fileDownloadMsg.data != NULL) && (fileDownloadMsg.length != 0)) {
487 if(rfbWriteExact(cl, fileDownloadMsg.data, fileDownloadMsg.length) < 0) {
488 rfbLog("File [%s]: Method [%s]: Error while writing to socket \n"
489 , __FILE__, __FUNCTION__);
490
491 if(cl != NULL) {
492 rfbCloseClient(cl);
493 CloseUndoneFileTransfer(cl, rtcp);
494 }
495
496 FreeFileTransferMsg(fileDownloadMsg);
497 return NULL;
498 }
499 FreeFileTransferMsg(fileDownloadMsg);
500 }
501 } while(rtcp->rcft.rcfd.downloadInProgress == TRUE);
502 return NULL;
503 }
504
505
506 void
HandleFileDownload(rfbClientPtr cl,rfbTightClientPtr rtcp)507 HandleFileDownload(rfbClientPtr cl, rfbTightClientPtr rtcp)
508 {
509 pthread_t fileDownloadThread;
510 FileTransferMsg fileDownloadMsg;
511
512 memset(&fileDownloadMsg, 0, sizeof(FileTransferMsg));
513 fileDownloadMsg = ChkFileDownloadErr(cl, rtcp);
514 if((fileDownloadMsg.data != NULL) && (fileDownloadMsg.length != 0)) {
515 rfbWriteExact(cl, fileDownloadMsg.data, fileDownloadMsg.length);
516 FreeFileTransferMsg(fileDownloadMsg);
517 return;
518 }
519 rtcp->rcft.rcfd.downloadInProgress = FALSE;
520 rtcp->rcft.rcfd.downloadFD = -1;
521
522 if(pthread_create(&fileDownloadThread, NULL, RunFileDownloadThread, (void*)
523 cl) != 0) {
524 FileTransferMsg ftm = GetFileDownLoadErrMsg();
525
526 rfbLog("File [%s]: Method [%s]: Download thread creation failed\n",
527 __FILE__, __FUNCTION__);
528
529 if((ftm.data != NULL) && (ftm.length != 0)) {
530 rfbWriteExact(cl, ftm.data, ftm.length);
531 FreeFileTransferMsg(ftm);
532 return;
533 }
534
535 }
536
537 }
538
539
540 /******************************************************************************
541 * Methods to Handle File Download Cancel Request.
542 ******************************************************************************/
543
544
545 void
HandleFileDownloadCancelRequest(rfbClientPtr cl,rfbTightClientPtr rtcp)546 HandleFileDownloadCancelRequest(rfbClientPtr cl, rfbTightClientPtr rtcp)
547 {
548 int n = 0;
549 char *reason = NULL;
550 rfbClientToServerTightMsg msg;
551
552 memset(&msg, 0, sizeof(rfbClientToServerTightMsg));
553
554 if((n = rfbReadExact(cl, ((char *)&msg)+1, sz_rfbFileDownloadCancelMsg-1)) <= 0) {
555
556 if (n < 0)
557 rfbLog("File [%s]: Method [%s]: Error while reading "
558 "FileDownloadCancelMsg\n", __FILE__, __FUNCTION__);
559
560 rfbCloseClient(cl);
561 return;
562 }
563
564 msg.fdc.reasonLen = Swap16IfLE(msg.fdc.reasonLen);
565
566 if(msg.fdc.reasonLen == 0) {
567 rfbLog("File [%s]: Method [%s]: reason length received is Zero\n",
568 __FILE__, __FUNCTION__);
569 return;
570 }
571
572 reason = (char*) calloc(msg.fdc.reasonLen + 1, sizeof(char));
573 if(reason == NULL) {
574 rfbLog("File [%s]: Method [%s]: Fatal Error: Memory alloc failed\n",
575 __FILE__, __FUNCTION__);
576 return;
577 }
578
579 if((n = rfbReadExact(cl, reason, msg.fdc.reasonLen)) <= 0) {
580
581 if (n < 0)
582 rfbLog("File [%s]: Method [%s]: Error while reading "
583 "FileDownloadCancelMsg\n", __FILE__, __FUNCTION__);
584
585 rfbCloseClient(cl);
586 }
587
588 rfbLog("File [%s]: Method [%s]: File Download Cancel Request received:"
589 " reason <%s>\n", __FILE__, __FUNCTION__, reason);
590
591 pthread_mutex_lock(&fileDownloadMutex);
592 CloseUndoneFileTransfer(cl, rtcp);
593 pthread_mutex_unlock(&fileDownloadMutex);
594
595 if(reason != NULL) {
596 free(reason);
597 reason = NULL;
598 }
599
600 }
601
602
603 /******************************************************************************
604 * Methods to Handle File upload request
605 ******************************************************************************/
606
607 #ifdef TODO
608 void HandleFileUploadRequest(rfbClientPtr cl);
609 #endif
610 void HandleFileUpload(rfbClientPtr cl, rfbTightClientPtr data);
611 void HandleFileUploadLengthError(rfbClientPtr cl, short fNameSize);
612 void SendFileUploadLengthErrMsg(rfbClientPtr cl);
613
614
615 void
HandleFileUploadRequest(rfbClientPtr cl,rfbTightClientPtr rtcp)616 HandleFileUploadRequest(rfbClientPtr cl, rfbTightClientPtr rtcp)
617 {
618 int n = 0;
619 char path[PATH_MAX]; /* PATH_MAX has the value 4096 and is defined in limits.h */
620 rfbClientToServerTightMsg msg;
621
622 memset(path, 0, PATH_MAX);
623 memset(&msg, 0, sizeof(rfbClientToServerTightMsg));
624
625 if(cl == NULL) {
626 rfbLog("File [%s]: Method [%s]: Unexpected error: rfbClientPtr is null\n",
627 __FILE__, __FUNCTION__);
628 return;
629 }
630
631 if((n = rfbReadExact(cl, ((char *)&msg)+1, sz_rfbFileUploadRequestMsg-1)) <= 0) {
632
633 if (n < 0)
634 rfbLog("File [%s]: Method [%s]: Error while reading FileUploadRequestMsg\n",
635 __FILE__, __FUNCTION__);
636
637 rfbCloseClient(cl);
638 return;
639 }
640
641 msg.fupr.fNameSize = Swap16IfLE(msg.fupr.fNameSize);
642 msg.fupr.position = Swap16IfLE(msg.fupr.position);
643
644 if ((msg.fupr.fNameSize == 0) ||
645 (msg.fupr.fNameSize > (PATH_MAX - 1))) {
646
647 rfbLog("File [%s]: Method [%s]: error: path length is greater than PATH_MAX\n",
648 __FILE__, __FUNCTION__);
649 HandleFileUploadLengthError(cl, msg.fupr.fNameSize);
650 return;
651 }
652
653 if((n = rfbReadExact(cl, rtcp->rcft.rcfu.fName, msg.fupr.fNameSize)) <= 0) {
654
655 if (n < 0)
656 rfbLog("File [%s]: Method [%s]: Error while reading FileUploadRequestMsg\n"
657 __FILE__, __FUNCTION__);
658
659 rfbCloseClient(cl);
660 return;
661 }
662 rtcp->rcft.rcfu.fName[msg.fupr.fNameSize] = '\0';
663
664 if(ConvertPath(rtcp->rcft.rcfu.fName) == NULL) {
665 rfbLog("File [%s]: Method [%s]: Unexpected error: path is NULL\n",
666 __FILE__, __FUNCTION__);
667
668 /* This may come if the path length exceeds PATH_MAX.
669 So sending path length error to client
670 */
671 SendFileUploadLengthErrMsg(cl);
672 return;
673 }
674
675 HandleFileUpload(cl, rtcp);
676 }
677
678
679 void
HandleFileUploadLengthError(rfbClientPtr cl,short fNameSize)680 HandleFileUploadLengthError(rfbClientPtr cl, short fNameSize)
681 {
682 char *path = NULL;
683 int n = 0;
684
685 if((path = (char*) calloc(fNameSize, sizeof(char))) == NULL) {
686 rfbLog("File [%s]: Method [%s]: Fatal Error: Alloc failed\n",
687 __FILE__, __FUNCTION__);
688 return;
689 }
690 if((n = rfbReadExact(cl, path, fNameSize)) <= 0) {
691
692 if (n < 0)
693 rfbLog("File [%s]: Method [%s]: Error while reading dir name\n",
694 __FILE__, __FUNCTION__);
695
696 rfbCloseClient(cl);
697
698 if(path != NULL) {
699 free(path);
700 path = NULL;
701 }
702
703 return;
704 }
705
706 rfbLog("File [%s]: Method [%s]: File Upload Length Error occured"
707 "file path requested is <%s>\n", __FILE__, __FUNCTION__, path);
708
709 if(path != NULL) {
710 free(path);
711 path = NULL;
712 }
713
714 SendFileUploadLengthErrMsg(cl);
715 }
716
717 void
SendFileUploadLengthErrMsg(rfbClientPtr cl)718 SendFileUploadLengthErrMsg(rfbClientPtr cl)
719 {
720
721 FileTransferMsg fileUploadErrMsg;
722
723 memset(&fileUploadErrMsg, 0, sizeof(FileTransferMsg));
724 fileUploadErrMsg = GetFileUploadLengthErrResponseMsg();
725
726 if((fileUploadErrMsg.data == NULL) || (fileUploadErrMsg.length == 0)) {
727 rfbLog("File [%s]: Method [%s]: Unexpected error: fileUploadErrMsg is null\n",
728 __FILE__, __FUNCTION__);
729 return;
730 }
731
732 rfbWriteExact(cl, fileUploadErrMsg.data, fileUploadErrMsg.length);
733 FreeFileTransferMsg(fileUploadErrMsg);
734 }
735
736 void
HandleFileUpload(rfbClientPtr cl,rfbTightClientPtr rtcp)737 HandleFileUpload(rfbClientPtr cl, rfbTightClientPtr rtcp)
738 {
739 FileTransferMsg fileUploadErrMsg;
740
741 memset(&fileUploadErrMsg, 0, sizeof(FileTransferMsg));
742
743 rtcp->rcft.rcfu.uploadInProgress = FALSE;
744 rtcp->rcft.rcfu.uploadFD = -1;
745
746 fileUploadErrMsg = ChkFileUploadErr(cl, rtcp);
747 if((fileUploadErrMsg.data != NULL) && (fileUploadErrMsg.length != 0)) {
748 rfbWriteExact(cl, fileUploadErrMsg.data, fileUploadErrMsg.length);
749 FreeFileTransferMsg(fileUploadErrMsg);
750 }
751 }
752
753
754 /******************************************************************************
755 * Methods to Handle File Upload Data Request
756 *****************************************************************************/
757
758 void HandleFileUploadWrite(rfbClientPtr cl, rfbTightClientPtr rtcp, char* pBuf);
759
760
761 void
HandleFileUploadDataRequest(rfbClientPtr cl,rfbTightClientPtr rtcp)762 HandleFileUploadDataRequest(rfbClientPtr cl, rfbTightClientPtr rtcp)
763 {
764 int n = 0;
765 char* pBuf = NULL;
766 rfbClientToServerTightMsg msg;
767
768 memset(&msg, 0, sizeof(rfbClientToServerTightMsg));
769
770 if(cl == NULL) {
771 rfbLog("File [%s]: Method [%s]: Unexpected error: rfbClientPtr is null\n",
772 __FILE__, __FUNCTION__);
773 return;
774 }
775
776 if((n = rfbReadExact(cl, ((char *)&msg)+1, sz_rfbFileUploadDataMsg-1)) <= 0) {
777
778 if (n < 0)
779 rfbLog("File [%s]: Method [%s]: Error while reading FileUploadRequestMsg\n",
780 __FILE__, __FUNCTION__);
781
782 rfbCloseClient(cl);
783 return;
784 }
785
786 msg.fud.realSize = Swap16IfLE(msg.fud.realSize);
787 msg.fud.compressedSize = Swap16IfLE(msg.fud.compressedSize);
788 if((msg.fud.realSize == 0) && (msg.fud.compressedSize == 0)) {
789 if((n = rfbReadExact(cl, (char*)&(rtcp->rcft.rcfu.mTime), sizeof(unsigned
790 long))) <= 0) {
791
792 if (n < 0)
793 rfbLog("File [%s]: Method [%s]: Error while reading FileUploadRequestMsg\n",
794 __FILE__, __FUNCTION__);
795
796 rfbCloseClient(cl);
797 return;
798 }
799
800 FileUpdateComplete(cl, rtcp);
801 return;
802 }
803
804 pBuf = (char*) calloc(msg.fud.compressedSize, sizeof(char));
805 if(pBuf == NULL) {
806 rfbLog("File [%s]: Method [%s]: Memory alloc failed\n", __FILE__, __FUNCTION__);
807 return;
808 }
809 if((n = rfbReadExact(cl, pBuf, msg.fud.compressedSize)) <= 0) {
810
811 if (n < 0)
812 rfbLog("File [%s]: Method [%s]: Error while reading FileUploadRequestMsg\n",
813 __FILE__, __FUNCTION__);
814
815 rfbCloseClient(cl);
816
817 if(pBuf != NULL) {
818 free(pBuf);
819 pBuf = NULL;
820 }
821
822 return;
823 }
824 if(msg.fud.compressedLevel != 0) {
825 FileTransferMsg ftm;
826 memset(&ftm, 0, sizeof(FileTransferMsg));
827
828 ftm = GetFileUploadCompressedLevelErrMsg();
829
830 if((ftm.data != NULL) && (ftm.length != 0)) {
831 rfbWriteExact(cl, ftm.data, ftm.length);
832 FreeFileTransferMsg(ftm);
833 }
834
835 CloseUndoneFileTransfer(cl, rtcp);
836
837 if(pBuf != NULL) {
838 free(pBuf);
839 pBuf = NULL;
840 }
841
842 return;
843 }
844
845 rtcp->rcft.rcfu.fSize = msg.fud.compressedSize;
846
847 HandleFileUploadWrite(cl, rtcp, pBuf);
848
849 if(pBuf != NULL) {
850 free(pBuf);
851 pBuf = NULL;
852 }
853
854 }
855
856
857 void
HandleFileUploadWrite(rfbClientPtr cl,rfbTightClientPtr rtcp,char * pBuf)858 HandleFileUploadWrite(rfbClientPtr cl, rfbTightClientPtr rtcp, char* pBuf)
859 {
860 FileTransferMsg ftm;
861 memset(&ftm, 0, sizeof(FileTransferMsg));
862
863 ftm = ChkFileUploadWriteErr(cl, rtcp, pBuf);
864
865 if((ftm.data != NULL) && (ftm.length != 0)) {
866 rfbWriteExact(cl, ftm.data, ftm.length);
867 FreeFileTransferMsg(ftm);
868 }
869 }
870
871
872 /******************************************************************************
873 * Methods to Handle File Upload Failed Request.
874 ******************************************************************************/
875
876
877 void
HandleFileUploadFailedRequest(rfbClientPtr cl,rfbTightClientPtr rtcp)878 HandleFileUploadFailedRequest(rfbClientPtr cl, rfbTightClientPtr rtcp)
879 {
880 int n = 0;
881 char* reason = NULL;
882 rfbClientToServerTightMsg msg;
883
884 memset(&msg, 0, sizeof(rfbClientToServerTightMsg));
885
886 if(cl == NULL) {
887 rfbLog("File [%s]: Method [%s]: Unexpected error: rfbClientPtr is null\n",
888 __FILE__, __FUNCTION__);
889 return;
890 }
891
892 if((n = rfbReadExact(cl, ((char *)&msg)+1, sz_rfbFileUploadFailedMsg-1)) <= 0) {
893
894 if (n < 0)
895 rfbLog("File [%s]: Method [%s]: Error while reading FileUploadFailedMsg\n",
896 __FILE__, __FUNCTION__);
897
898 rfbCloseClient(cl);
899 return;
900 }
901
902 msg.fuf.reasonLen = Swap16IfLE(msg.fuf.reasonLen);
903 if(msg.fuf.reasonLen == 0) {
904 rfbLog("File [%s]: Method [%s]: reason length received is Zero\n",
905 __FILE__, __FUNCTION__);
906 return;
907 }
908
909
910 reason = (char*) calloc(msg.fuf.reasonLen + 1, sizeof(char));
911 if(reason == NULL) {
912 rfbLog("File [%s]: Method [%s]: Memory alloc failed\n", __FILE__, __FUNCTION__);
913 return;
914 }
915
916 if((n = rfbReadExact(cl, reason, msg.fuf.reasonLen)) <= 0) {
917
918 if (n < 0)
919 rfbLog("File [%s]: Method [%s]: Error while reading FileUploadFailedMsg\n",
920 __FILE__, __FUNCTION__);
921
922 rfbCloseClient(cl);
923
924 if(reason != NULL) {
925 free(reason);
926 reason = NULL;
927 }
928
929 return;
930 }
931
932 rfbLog("File [%s]: Method [%s]: File Upload Failed Request received:"
933 " reason <%s>\n", __FILE__, __FUNCTION__, reason);
934
935 CloseUndoneFileTransfer(cl, rtcp);
936
937 if(reason != NULL) {
938 free(reason);
939 reason = NULL;
940 }
941
942 }
943
944
945 /******************************************************************************
946 * Methods to Handle File Create Request.
947 ******************************************************************************/
948
949
950 void
HandleFileCreateDirRequest(rfbClientPtr cl,rfbTightClientPtr rtcp)951 HandleFileCreateDirRequest(rfbClientPtr cl, rfbTightClientPtr rtcp)
952 {
953 int n = 0;
954 char dirName[PATH_MAX];
955 rfbClientToServerTightMsg msg;
956
957 memset(dirName, 0, PATH_MAX);
958 memset(&msg, 0, sizeof(rfbClientToServerTightMsg));
959
960 if(cl == NULL) {
961 rfbLog("File [%s]: Method [%s]: Unexpected error: rfbClientPtr is null\n",
962 __FILE__, __FUNCTION__);
963 return;
964 }
965
966 if((n = rfbReadExact(cl, ((char *)&msg)+1, sz_rfbFileCreateDirRequestMsg-1)) <= 0) {
967
968 if (n < 0)
969 rfbLog("File [%s]: Method [%s]: Error while reading FileCreateDirRequestMsg\n",
970 __FILE__, __FUNCTION__);
971
972 rfbCloseClient(cl);
973 return;
974 }
975
976 msg.fcdr.dNameLen = Swap16IfLE(msg.fcdr.dNameLen);
977
978 /* TODO :: chk if the dNameLen is greater than PATH_MAX */
979
980 if((n = rfbReadExact(cl, dirName, msg.fcdr.dNameLen)) <= 0) {
981
982 if (n < 0)
983 rfbLog("File [%s]: Method [%s]: Error while reading FileUploadFailedMsg\n",
984 __FILE__, __FUNCTION__);
985
986 rfbCloseClient(cl);
987 return;
988 }
989
990 if(ConvertPath(dirName) == NULL) {
991 rfbLog("File [%s]: Method [%s]: Unexpected error: path is NULL\n",
992 __FILE__, __FUNCTION__);
993
994 return;
995 }
996
997 CreateDirectory(dirName);
998 }
999