Browse code

maintain internal OLE2 directory structure when unpacking OLE2 archive files (not yet activated)

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
Showing 2 changed files
... ...
@@ -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
 }