git-svn-id: file:///var/lib/svn/clamav-devel/trunk/clamav-devel@644 77e5149b-7576-45b1-b177-96237e5ba77b
Trog authored on 2004/06/30 21:28:17... | ... |
@@ -1,3 +1,9 @@ |
1 |
+Wed Jun 30 13:24:56 BST 2004 (trog) |
|
2 |
+----------------------------------- |
|
3 |
+ * libclamav/vba_extract.c: dumb down the PowerPoint parser to Microsofts level. |
|
4 |
+ |
|
5 |
+ * libclamav/ole2_extract.c: check against recursion limits |
|
6 |
+ |
|
1 | 7 |
Tue Jun 29 23:24:44 CEST 2004 (tk) |
2 | 8 |
---------------------------------- |
3 | 9 |
* doc: update |
... | ... |
@@ -469,11 +469,16 @@ static void ole2_walk_property_tree(int fd, ole2_header_t *hdr, const char *dir, |
469 | 469 |
return; |
470 | 470 |
} |
471 | 471 |
|
472 |
- if(limits && limits->maxfiles && (*file_count > limits->maxfiles)) { |
|
472 |
+ if (limits && limits->maxfiles && (*file_count > limits->maxfiles)) { |
|
473 | 473 |
cli_dbgmsg("OLE2: File limit reached (max: %d)\n", limits->maxfiles); |
474 | 474 |
return; |
475 | 475 |
} |
476 | 476 |
|
477 |
+ if (limits && limits->maxreclevel && (rec_level > limits->maxreclevel)) { |
|
478 |
+ cli_dbgmsg("OLE2: Recursion limit reached (max: %d)\n", limits->maxreclevel); |
|
479 |
+ return; |
|
480 |
+ } |
|
481 |
+ |
|
477 | 482 |
index = prop_index / 4; |
478 | 483 |
for (i=0 ; i < index ; i++) { |
479 | 484 |
current_block = ole2_get_next_block_number(fd, hdr, current_block); |
... | ... |
@@ -975,8 +975,93 @@ static int ppt_unlzw(const char *dir, int fd, uint32_t length) |
975 | 975 |
return TRUE; |
976 | 976 |
} |
977 | 977 |
|
978 |
+static char *ppt_stream_iter(int fd) |
|
979 |
+{ |
|
980 |
+ atom_header_t atom_header; |
|
981 |
+ uint32_t ole_id; |
|
982 |
+ char *tmpdir, *out_dir; |
|
983 |
+ |
|
984 |
+ /* Create a directory to store the extracted OLE2 objects */ |
|
985 |
+ tmpdir = getenv("TMPDIR"); |
|
986 |
+ |
|
987 |
+ if(tmpdir == NULL) |
|
988 |
+#ifdef P_tmpdir |
|
989 |
+ tmpdir = P_tmpdir; |
|
990 |
+#else |
|
991 |
+ tmpdir = "/tmp"; |
|
992 |
+#endif |
|
993 |
+ |
|
994 |
+ /* generate the temporary directory */ |
|
995 |
+ out_dir = cl_gentemp(tmpdir); |
|
996 |
+ if(mkdir(out_dir, 0700)) { |
|
997 |
+ printf("ScanOLE2 -> Can't create temporary directory %s\n", out_dir); |
|
998 |
+ close(fd); |
|
999 |
+ return NULL; |
|
1000 |
+ } |
|
1001 |
+ |
|
1002 |
+ while (1) { |
|
1003 |
+ if (!ppt_read_atom_header(fd, &atom_header)) { |
|
1004 |
+ break; |
|
1005 |
+ } |
|
1006 |
+ ppt_print_atom_header(&atom_header); |
|
1007 |
+ |
|
1008 |
+ if (atom_header.type == 0x1011) { |
|
1009 |
+ if (cli_readn(fd, &ole_id, 4) != 4) { |
|
1010 |
+ cli_dbgmsg("read ole_id failed\n"); |
|
1011 |
+ cli_rmdirs(out_dir); |
|
1012 |
+ free(out_dir); |
|
1013 |
+ return NULL; |
|
1014 |
+ } |
|
1015 |
+ ole_id = vba_endian_convert_32(ole_id, FALSE); |
|
1016 |
+ cli_dbgmsg("OleID: %d, length: %d\n", |
|
1017 |
+ ole_id, atom_header.length-4); |
|
1018 |
+ if (!ppt_unlzw(out_dir, fd, atom_header.length-4)) { |
|
1019 |
+ cli_dbgmsg("ppt_unlzw failed\n"); |
|
1020 |
+ cli_rmdirs(out_dir); |
|
1021 |
+ free(out_dir); |
|
1022 |
+ return NULL; |
|
1023 |
+ } |
|
1024 |
+ |
|
1025 |
+ } else { |
|
1026 |
+ if (lseek(fd, atom_header.length, SEEK_CUR) == -1 ) { |
|
1027 |
+ break; |
|
1028 |
+ } |
|
1029 |
+ } |
|
1030 |
+ } |
|
1031 |
+ return out_dir; |
|
1032 |
+} |
|
1033 |
+ |
|
978 | 1034 |
char *ppt_vba_read(const char *dir) |
979 | 1035 |
{ |
1036 |
+ char *fullname, *out_dir; |
|
1037 |
+ int fd; |
|
1038 |
+ atom_header_t atom_header; |
|
1039 |
+ uint32_t ole_id; |
|
1040 |
+ |
|
1041 |
+ fullname = (char *) cli_malloc(strlen(dir) + 21); |
|
1042 |
+ if (!fullname) { |
|
1043 |
+ return NULL; |
|
1044 |
+ } |
|
1045 |
+ sprintf(fullname, "%s/PowerPoint Document", dir); |
|
1046 |
+ fd = open(fullname, O_RDONLY); |
|
1047 |
+ free(fullname); |
|
1048 |
+ if (fd == -1) { |
|
1049 |
+ cli_dbgmsg("Open PowerPoint Document failed\n"); |
|
1050 |
+ return NULL; |
|
1051 |
+ } |
|
1052 |
+ |
|
1053 |
+ out_dir = ppt_stream_iter(fd); |
|
1054 |
+ close(fd); |
|
1055 |
+ return out_dir; |
|
1056 |
+} |
|
1057 |
+ |
|
1058 |
+ |
|
1059 |
+/* Strictly speaking, the method below is the correct way to access the |
|
1060 |
+ componenets of a PowerPoint file. However, it appears Microsoft |
|
1061 |
+ don't do it that way. |
|
1062 |
+ |
|
1063 |
+char *ppt_vba_read_strict(const char *dir) |
|
1064 |
+{ |
|
980 | 1065 |
ppt_currentuser_t ppt_current_user; |
981 | 1066 |
ppt_useredit_t ppt_useredit; |
982 | 1067 |
uint32_t *persist_dir; |
... | ... |
@@ -1014,9 +1099,10 @@ char *ppt_vba_read(const char *dir) |
1014 | 1014 |
fd = open(fullname, O_RDONLY); |
1015 | 1015 |
free(fullname); |
1016 | 1016 |
if (fd == -1) { |
1017 |
- cli_dbgmsg("Open Current User failed\n"); |
|
1017 |
+ cli_dbgmsg("Open PowerPoint Document failed\n"); |
|
1018 | 1018 |
return NULL; |
1019 | 1019 |
} |
1020 |
+ |
|
1020 | 1021 |
if (lseek(fd, ppt_current_user.current_edit_offset, SEEK_SET) != |
1021 | 1022 |
ppt_current_user.current_edit_offset) { |
1022 | 1023 |
cli_dbgmsg("lseek cli_ppt_vbaread failed\n"); |
... | ... |
@@ -1024,7 +1110,6 @@ char *ppt_vba_read(const char *dir) |
1024 | 1024 |
return FALSE; |
1025 | 1025 |
} |
1026 | 1026 |
|
1027 |
- /* Create a directory to store the extracted OLE2 objects */ |
|
1028 | 1027 |
tmpdir = getenv("TMPDIR"); |
1029 | 1028 |
|
1030 | 1029 |
if(tmpdir == NULL) |
... | ... |
@@ -1034,7 +1119,6 @@ char *ppt_vba_read(const char *dir) |
1034 | 1034 |
tmpdir = "/tmp"; |
1035 | 1035 |
#endif |
1036 | 1036 |
|
1037 |
- /* generate the temporary directory */ |
|
1038 | 1037 |
out_dir = cl_gentemp(tmpdir); |
1039 | 1038 |
if(mkdir(out_dir, 0700)) { |
1040 | 1039 |
printf("ScanOLE2 -> Can't create temporary directory %s\n", dir); |
... | ... |
@@ -1107,6 +1191,8 @@ char *ppt_vba_read(const char *dir) |
1107 | 1107 |
close(fd); |
1108 | 1108 |
return out_dir; |
1109 | 1109 |
} |
1110 |
+*/ |
|
1111 |
+ |
|
1110 | 1112 |
|
1111 | 1113 |
/* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ |
1112 | 1114 |
/* Code to extract Word6 macros |