comparison src/readpst.c @ 41:183ae993b9ad

security fix for potential buffer overrun in lz decompress
author carl
date Tue, 02 Oct 2007 15:49:44 -0700
parents 2ad7ef0a3c4f
children f6db1f060a95
comparison
equal deleted inserted replaced
40:be6d5329cc01 41:183ae993b9ad
73 int32_t close_recurse_dir(); 73 int32_t close_recurse_dir();
74 char* mk_seperate_dir(char *dir); 74 char* mk_seperate_dir(char *dir);
75 int32_t close_seperate_dir(); 75 int32_t close_seperate_dir();
76 int32_t mk_seperate_file(struct file_ll *f); 76 int32_t mk_seperate_file(struct file_ll *f);
77 char* my_stristr(char *haystack, char *needle); 77 char* my_stristr(char *haystack, char *needle);
78 char* check_filename(char *fname); 78 void check_filename(char *fname);
79 char* rfc2426_escape(char *str); 79 char* rfc2426_escape(char *str);
80 int32_t chr_count(char *str, char x); 80 int32_t chr_count(char *str, char x);
81 char* rfc2425_datetime_format(FILETIME *ft); 81 char* rfc2425_datetime_format(FILETIME *ft);
82 char* rfc2445_datetime_format(FILETIME *ft); 82 char* rfc2445_datetime_format(FILETIME *ft);
83 char* skip_header_prologue(char *headers); 83 char* skip_header_prologue(char *headers);
476 x = errno; 476 x = errno;
477 DIE(("mk_kmail_dir: Cannot change to directory %s: %s\n", kmail_chdir, strerror(x))); 477 DIE(("mk_kmail_dir: Cannot change to directory %s: %s\n", kmail_chdir, strerror(x)));
478 } 478 }
479 dir = malloc(strlen(fname)+strlen(OUTPUT_KMAIL_DIR_TEMPLATE)+1); 479 dir = malloc(strlen(fname)+strlen(OUTPUT_KMAIL_DIR_TEMPLATE)+1);
480 sprintf(dir, OUTPUT_KMAIL_DIR_TEMPLATE, fname); 480 sprintf(dir, OUTPUT_KMAIL_DIR_TEMPLATE, fname);
481 dir = check_filename(dir); 481 check_filename(dir);
482 if (D_MKDIR(dir)) { 482 if (D_MKDIR(dir)) {
483 //error occured 483 //error occured
484 if (errno != EEXIST) { 484 if (errno != EEXIST) {
485 x = errno; 485 x = errno;
486 DIE(("mk_kmail_dir: Cannot create directory %s: %s\n", dir, strerror(x))); 486 DIE(("mk_kmail_dir: Cannot create directory %s: %s\n", dir, strerror(x)));
526 // contain mbox files 526 // contain mbox files
527 char *mk_recurse_dir(char *dir) { 527 char *mk_recurse_dir(char *dir) {
528 int x; 528 int x;
529 char *out_name; 529 char *out_name;
530 DEBUG_ENT("mk_recurse_dir"); 530 DEBUG_ENT("mk_recurse_dir");
531 dir = check_filename(dir); 531 check_filename(dir);
532 if (D_MKDIR (dir)) { 532 if (D_MKDIR (dir)) {
533 if (errno != EEXIST) { // not an error because it exists 533 if (errno != EEXIST) { // not an error because it exists
534 x = errno; 534 x = errno;
535 DIE(("mk_recurse_dir: Cannot create directory %s: %s\n", dir, strerror(x))); 535 DIE(("mk_recurse_dir: Cannot create directory %s: %s\n", dir, strerror(x)));
536 } 536 }
558 } 558 }
559 559
560 560
561 char *mk_seperate_dir(char *dir) { 561 char *mk_seperate_dir(char *dir) {
562 DEBUG_ENT("mk_seperate_dir"); 562 DEBUG_ENT("mk_seperate_dir");
563 #if !defined(WIN32) && !defined(__CYGWIN__) 563
564 DIR * sdir = NULL; 564 size_t dirsize = strlen(dir) + 10;
565 struct dirent *dirent = NULL; 565 char dir_name[dirsize];
566 struct stat *filestat = xmalloc(sizeof(struct stat));
567 #endif
568
569 char *dir_name = NULL;
570 int x = 0, y = 0; 566 int x = 0, y = 0;
571
572 dir_name = xmalloc(strlen(dir)+10);
573 567
574 do { 568 do {
575 if (y == 0) 569 if (y == 0)
576 sprintf(dir_name, "%s", dir); 570 snprintf(dir_name, dirsize, "%s", dir);
577 else 571 else
578 sprintf(dir_name, "%s" SEP_MAIL_FILE_TEMPLATE, dir, y); // enough for 9 digits allocated above 572 snprintf(dir_name, dirsize, "%s" SEP_MAIL_FILE_TEMPLATE, dir, y); // enough for 9 digits allocated above
579 573
580 dir_name = check_filename(dir_name); 574 check_filename(dir_name);
581 DEBUG_MAIN(("about to try creating %s\n", dir_name)); 575 DEBUG_MAIN(("about to try creating %s\n", dir_name));
582 if (D_MKDIR(dir_name)) { 576 if (D_MKDIR(dir_name)) {
583 if (errno != EEXIST) { // if there is an error, and it doesn't already exist 577 if (errno != EEXIST) { // if there is an error, and it doesn't already exist
584 x = errno; 578 x = errno;
585 DIE(("mk_seperate_dir: Cannot create directory %s: %s\n", dir, strerror(x))); 579 DIE(("mk_seperate_dir: Cannot create directory %s: %s\n", dir, strerror(x)));
588 break; 582 break;
589 } 583 }
590 y++; 584 y++;
591 } while (overwrite == 0); 585 } while (overwrite == 0);
592 586
593 if (chdir (dir_name)) { 587 if (chdir(dir_name)) {
594 x = errno; 588 x = errno;
595 DIE(("mk_recurse_dir: Cannot change to directory %s: %s\n", dir, strerror(x))); 589 DIE(("mk_recurse_dir: Cannot change to directory %s: %s\n", dir, strerror(x)));
596 } 590 }
597 591
598 if (overwrite) { 592 if (overwrite) {
599 // we should probably delete all files from this directory 593 // we should probably delete all files from this directory
600 #if !defined(WIN32) && !defined(__CYGWIN__) 594 #if !defined(WIN32) && !defined(__CYGWIN__)
595 DIR * sdir = NULL;
596 struct dirent *dirent = NULL;
597 struct stat filestat;
601 if (!(sdir = opendir("./"))) { 598 if (!(sdir = opendir("./"))) {
602 WARN(("mk_seperate_dir: Cannot open dir \"%s\" for deletion of old contents\n", "./")); 599 WARN(("mk_seperate_dir: Cannot open dir \"%s\" for deletion of old contents\n", "./"));
603 } else { 600 } else {
604 while ((dirent = readdir(sdir))) { 601 while ((dirent = readdir(sdir))) {
605 if (lstat(dirent->d_name, filestat) != -1) 602 if (lstat(dirent->d_name, &filestat) != -1)
606 if (S_ISREG(filestat->st_mode)) { 603 if (S_ISREG(filestat.st_mode)) {
607 if (unlink(dirent->d_name)) { 604 if (unlink(dirent->d_name)) {
608 y = errno; 605 y = errno;
609 DIE(("mk_seperate_dir: unlink returned error on file %s: %s\n", dirent->d_name, strerror(y))); 606 DIE(("mk_seperate_dir: unlink returned error on file %s: %s\n", dirent->d_name, strerror(y)));
610 } 607 }
611 } 608 }
640 DIE(("mk_seperate_file: The number of emails in this folder has become too high to handle")); 637 DIE(("mk_seperate_file: The number of emails in this folder has become too high to handle"));
641 } 638 }
642 sprintf(f->name, SEP_MAIL_FILE_TEMPLATE, f->email_count + name_offset); 639 sprintf(f->name, SEP_MAIL_FILE_TEMPLATE, f->email_count + name_offset);
643 if (f->output) fclose(f->output); 640 if (f->output) fclose(f->output);
644 f->output = NULL; 641 f->output = NULL;
645 f->name = check_filename(f->name); 642 check_filename(f->name);
646 if (!(f->output = fopen(f->name, "w"))) { 643 if (!(f->output = fopen(f->name, "w"))) {
647 DIE(("mk_seperate_file: Cannot open file to save email \"%s\"\n", f->name)); 644 DIE(("mk_seperate_file: Cannot open file to save email \"%s\"\n", f->name));
648 } 645 }
649 DEBUG_RET(); 646 DEBUG_RET();
650 return 0; 647 return 0;
673 DEBUG_RET(); 670 DEBUG_RET();
674 return z; 671 return z;
675 } 672 }
676 673
677 674
678 char *check_filename(char *fname) { 675 void check_filename(char *fname) {
679 char *t = fname; 676 char *t = fname;
680 DEBUG_ENT("check_filename"); 677 DEBUG_ENT("check_filename");
681 if (!t) { 678 if (!t) {
682 DEBUG_RET(); 679 DEBUG_RET();
683 return fname; 680 return fname;
1117 DEBUG_EMAIL(("Adding RTF body as attachment\n")); 1114 DEBUG_EMAIL(("Adding RTF body as attachment\n"));
1118 current_attach = (pst_item_attach*)xmalloc(sizeof(pst_item_attach)); 1115 current_attach = (pst_item_attach*)xmalloc(sizeof(pst_item_attach));
1119 memset(current_attach, 0, sizeof(pst_item_attach)); 1116 memset(current_attach, 0, sizeof(pst_item_attach));
1120 current_attach->next = item->attach; 1117 current_attach->next = item->attach;
1121 item->attach = current_attach; 1118 item->attach = current_attach;
1122 current_attach->data = lzfu_decompress(item->email->rtf_compressed, &current_attach->size); 1119 current_attach->data = lzfu_decompress(item->email->rtf_compressed, item->email->rtf_compressed_size, &current_attach->size);
1123 current_attach->filename2 = xmalloc(strlen(RTF_ATTACH_NAME)+2); 1120 current_attach->filename2 = xmalloc(strlen(RTF_ATTACH_NAME)+2);
1124 strcpy(current_attach->filename2, RTF_ATTACH_NAME); 1121 strcpy(current_attach->filename2, RTF_ATTACH_NAME);
1125 current_attach->mimetype = xmalloc(strlen(RTF_ATTACH_TYPE)+2); 1122 current_attach->mimetype = xmalloc(strlen(RTF_ATTACH_TYPE)+2);
1126 strcpy(current_attach->mimetype, RTF_ATTACH_TYPE); 1123 strcpy(current_attach->mimetype, RTF_ATTACH_TYPE);
1127 //memcpy(&tester, item->email->rtf_compressed+sizeof(int32_t), sizeof(int32_t)); 1124 //memcpy(&tester, item->email->rtf_compressed+sizeof(int32_t), sizeof(int32_t));
1380 if (overwrite != 1) { 1377 if (overwrite != 1) {
1381 int x = 0; 1378 int x = 0;
1382 char *temp = (char*) xmalloc (strlen(f->name)+10); //enough room for 10 digits 1379 char *temp = (char*) xmalloc (strlen(f->name)+10); //enough room for 10 digits
1383 1380
1384 sprintf(temp, "%s", f->name); 1381 sprintf(temp, "%s", f->name);
1385 temp = check_filename(temp); 1382 check_filename(temp);
1386 while ((f->output = fopen(temp, "r"))) { 1383 while ((f->output = fopen(temp, "r"))) {
1387 DEBUG_MAIN(("need to increase filename because one already exists with that name\n")); 1384 DEBUG_MAIN(("need to increase filename because one already exists with that name\n"));
1388 DEBUG_MAIN(("- increasing it to %s%d\n", f->name, x)); 1385 DEBUG_MAIN(("- increasing it to %s%d\n", f->name, x));
1389 x++; 1386 x++;
1390 sprintf(temp, "%s%08d", f->name, x); 1387 sprintf(temp, "%s%08d", f->name, x);
1402 } 1399 }
1403 } 1400 }
1404 1401
1405 DEBUG_MAIN(("f->name = %s\nitem->folder_name = %s\n", f->name, item->file_as)); 1402 DEBUG_MAIN(("f->name = %s\nitem->folder_name = %s\n", f->name, item->file_as));
1406 if (mode != MODE_SEPERATE) { 1403 if (mode != MODE_SEPERATE) {
1407 f->name = check_filename(f->name); 1404 check_filename(f->name);
1408 if (!(f->output = fopen(f->name, "w"))) { 1405 if (!(f->output = fopen(f->name, "w"))) {
1409 DIE(("create_enter_dir: Could not open file \"%s\" for write\n", f->name)); 1406 DIE(("create_enter_dir: Could not open file \"%s\" for write\n", f->name));
1410 } 1407 }
1411 } 1408 }
1412 DEBUG_RET(); 1409 DEBUG_RET();