Mercurial > libpst
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, ¤t_attach->size); | 1119 current_attach->data = lzfu_decompress(item->email->rtf_compressed, item->email->rtf_compressed_size, ¤t_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(); |