git-svn-id: file:///var/lib/svn/clamav-devel/trunk/clamav-devel@506 77e5149b-7576-45b1-b177-96237e5ba77b
Trog authored on 2004/04/19 21:41:03... | ... |
@@ -1,3 +1,8 @@ |
1 |
+Mon Apr 19 13:39:23 BST 2004 (trog) |
|
2 |
+----------------------------------- |
|
3 |
+ * libclamav/ole2_extract: maintain internal OLE2 directory structure |
|
4 |
+ when unpacking OLE2 archive files (not yet activated) |
|
5 |
+ |
|
1 | 6 |
Sat Apr 17 21:40:19 BST 2004 (njh) |
2 | 7 |
---------------------------------- |
3 | 8 |
* clamav-milter: Include the virus name in the 550 rejection if |
... | ... |
@@ -437,6 +437,96 @@ static void ole2_read_property_tree(int fd, ole2_header_t *hdr, const char *dir, |
437 | 437 |
return; |
438 | 438 |
} |
439 | 439 |
|
440 |
+static void ole2_walk_property_tree(int fd, ole2_header_t *hdr, const char *dir, int32_t prop_index, |
|
441 |
+ int (*handler)(int fd, ole2_header_t *hdr, property_t *prop, const char *dir), |
|
442 |
+ int rec_level, int file_count) |
|
443 |
+{ |
|
444 |
+ property_t prop_block[4]; |
|
445 |
+ int32_t index, current_block, count=0, i; |
|
446 |
+ unsigned char *dirname; |
|
447 |
+ current_block = hdr->prop_start; |
|
448 |
+ |
|
449 |
+ if ((prop_index < 0) || (rec_level > 100) || (file_count > 100000)) { |
|
450 |
+ return; |
|
451 |
+ } |
|
452 |
+ |
|
453 |
+ index = prop_index / 4; |
|
454 |
+ for (i=0 ; i < index ; i++) { |
|
455 |
+ current_block = ole2_get_next_block_number(fd, hdr, current_block); |
|
456 |
+ if (current_block < 0) { |
|
457 |
+ return; |
|
458 |
+ } |
|
459 |
+ } |
|
460 |
+ index = prop_index % 4; |
|
461 |
+ if (!ole2_read_block(fd, hdr, prop_block, |
|
462 |
+ current_block)) { |
|
463 |
+ return; |
|
464 |
+ } |
|
465 |
+ if (prop_block[index].type <= 0) { |
|
466 |
+ return; |
|
467 |
+ } |
|
468 |
+ prop_block[index].name_size = ole2_endian_convert_16(prop_block[index].name_size); |
|
469 |
+ prop_block[index].prev = ole2_endian_convert_32(prop_block[index].prev); |
|
470 |
+ prop_block[index].next = ole2_endian_convert_32(prop_block[index].next); |
|
471 |
+ prop_block[index].child = ole2_endian_convert_32(prop_block[index].child); |
|
472 |
+ prop_block[index].user_flags = ole2_endian_convert_32(prop_block[index].user_flags); |
|
473 |
+ prop_block[index].create_lowdate = ole2_endian_convert_32(prop_block[index].create_lowdate); |
|
474 |
+ prop_block[index].create_highdate = ole2_endian_convert_32(prop_block[index].create_highdate); |
|
475 |
+ prop_block[index].mod_lowdate = ole2_endian_convert_32(prop_block[index].mod_lowdate); |
|
476 |
+ prop_block[index].mod_highdate = ole2_endian_convert_32(prop_block[index].mod_highdate); |
|
477 |
+ prop_block[index].start_block = ole2_endian_convert_32(prop_block[index].start_block); |
|
478 |
+ prop_block[index].size = ole2_endian_convert_32(prop_block[index].size); |
|
479 |
+ |
|
480 |
+ print_ole2_property(&prop_block[index]); |
|
481 |
+ switch (prop_block[index].type) { |
|
482 |
+ case 5: /* Root Entry */ |
|
483 |
+ if (prop_index != 0) { |
|
484 |
+ /* Can only have RootEntry as the top */ |
|
485 |
+ cli_dbgmsg("ERROR: illegal Root Entry\n"); |
|
486 |
+ return; |
|
487 |
+ } |
|
488 |
+ hdr->sbat_root_start = prop_block[index].start_block; |
|
489 |
+ ole2_walk_property_tree(fd, hdr, dir, |
|
490 |
+ prop_block[index].prev, handler, rec_level+1, file_count); |
|
491 |
+ ole2_walk_property_tree(fd, hdr, dir, |
|
492 |
+ prop_block[index].next, handler, rec_level+1, file_count); |
|
493 |
+ ole2_walk_property_tree(fd, hdr, dir, |
|
494 |
+ prop_block[index].child, handler, rec_level+1, file_count); |
|
495 |
+ break; |
|
496 |
+ case 2: /* File */ |
|
497 |
+ if (!handler(fd, hdr, &prop_block[index], dir)) { |
|
498 |
+ cli_dbgmsg("ERROR: handler failed\n"); |
|
499 |
+ return; |
|
500 |
+ } |
|
501 |
+ ole2_walk_property_tree(fd, hdr, dir, |
|
502 |
+ prop_block[index].prev, handler, rec_level, file_count+1); |
|
503 |
+ ole2_walk_property_tree(fd, hdr, dir, |
|
504 |
+ prop_block[index].next, handler, rec_level, file_count+1); |
|
505 |
+ ole2_walk_property_tree(fd, hdr, dir, |
|
506 |
+ prop_block[index].child, handler, rec_level, file_count+1); |
|
507 |
+ break; |
|
508 |
+ case 1: /* Directory */ |
|
509 |
+ dirname = (char *) cli_malloc(strlen(dir)+8); |
|
510 |
+ if (!dirname) { |
|
511 |
+ return; |
|
512 |
+ } |
|
513 |
+ snprintf(dirname, strlen(dir)+8, "%s/%.6d", dir, prop_index); |
|
514 |
+ mkdir(dirname, 0700); |
|
515 |
+ cli_dbgmsg("OLE2 dir entry: %s\n",dirname); |
|
516 |
+ ole2_walk_property_tree(fd, hdr, dirname, |
|
517 |
+ prop_block[index].prev, handler, rec_level+1, file_count); |
|
518 |
+ ole2_walk_property_tree(fd, hdr, dirname, |
|
519 |
+ prop_block[index].next, handler, rec_level+1, file_count); |
|
520 |
+ ole2_walk_property_tree(fd, hdr, dirname, |
|
521 |
+ prop_block[index].child, handler, rec_level+1, file_count); |
|
522 |
+ free(dirname); |
|
523 |
+ break; |
|
524 |
+ default: |
|
525 |
+ cli_errmsg("ERROR: unknown OLE2 entry type: %d\n", prop_block[index].type); |
|
526 |
+ break; |
|
527 |
+ } |
|
528 |
+ return; |
|
529 |
+} |
|
440 | 530 |
/* Write file Handler - write the contents of the entry to a file */ |
441 | 531 |
static int handler_writefile(int fd, ole2_header_t *hdr, property_t *prop, const char *dir) |
442 | 532 |
{ |
... | ... |
@@ -627,7 +717,13 @@ int cli_ole2_extract(int fd, const char *dirname) |
627 | 627 |
|
628 | 628 |
print_ole2_header(&hdr); |
629 | 629 |
|
630 |
+ /* NOTE: Select only ONE of the following two methods */ |
|
631 |
+ |
|
630 | 632 |
ole2_read_property_tree(fd, &hdr, dirname, handler_writefile); |
631 |
- |
|
633 |
+ |
|
634 |
+ /* OR */ |
|
635 |
+ |
|
636 |
+ /* ole2_walk_property_tree(fd, &hdr, dirname, 0, handler_writefile, 0, 0); */ |
|
637 |
+ |
|
632 | 638 |
return 0; |
633 | 639 |
} |