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