• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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