| 
									
										
										
										
											2004-01-23 11:17:16 +00:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2004-01-25 06:34:45 +00:00
										 |  |  |  *  Extract VBA source code for component MS Office Documents | 
					
						
							| 
									
										
										
										
											2004-01-23 11:17:16 +00:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2005-03-11 19:18:01 +00:00
										 |  |  |  *  Copyright (C) 2004-2005 trog@uncon.org | 
					
						
							| 
									
										
										
										
											2004-01-23 11:17:16 +00:00
										 |  |  |  * | 
					
						
							|  |  |  |  *  This code is based on the OpenOffice and libgsf sources. | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  |  *  Libgsf is available under the LGPL. | 
					
						
							| 
									
										
										
										
											2007-10-22 20:33:20 +00:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2004-01-23 11:17:16 +00:00
										 |  |  |  *  This program is free software; you can redistribute it and/or modify | 
					
						
							|  |  |  |  *  it under the terms of the GNU General Public License as published by | 
					
						
							|  |  |  |  *  the Free Software Foundation; either version 2 of the License, or | 
					
						
							|  |  |  |  *  (at your option) any later version. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  This program is distributed in the hope that it will be useful, | 
					
						
							|  |  |  |  *  but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  |  *  GNU General Public License for more details. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  You should have received a copy of the GNU General Public License | 
					
						
							|  |  |  |  *  along with this program; if not, write to the Free Software | 
					
						
							| 
									
										
										
										
											2006-04-09 19:59:28 +00:00
										 |  |  |  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | 
					
						
							|  |  |  |  *  MA 02110-1301, USA. | 
					
						
							| 
									
										
										
										
											2004-01-23 11:17:16 +00:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2007-10-22 20:33:20 +00:00
										 |  |  | #if HAVE_CONFIG_H
 | 
					
						
							|  |  |  | #include "clamav-config.h"
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2004-01-23 11:17:16 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include <stdio.h>
 | 
					
						
							|  |  |  | #include <string.h>
 | 
					
						
							| 
									
										
										
										
											2006-10-09 15:23:50 +00:00
										 |  |  | #ifdef	HAVE_UNISTD_H
 | 
					
						
							| 
									
										
										
										
											2004-01-23 11:17:16 +00:00
										 |  |  | #include <unistd.h>
 | 
					
						
							| 
									
										
										
										
											2006-10-09 15:23:50 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2004-01-23 11:17:16 +00:00
										 |  |  | #include <sys/types.h>
 | 
					
						
							|  |  |  | #include <sys/stat.h>
 | 
					
						
							|  |  |  | #include <fcntl.h>
 | 
					
						
							|  |  |  | #include <stdlib.h>
 | 
					
						
							|  |  |  | #include <ctype.h>
 | 
					
						
							| 
									
										
										
										
											2004-05-27 15:38:39 +00:00
										 |  |  | #include <zlib.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "clamav.h"
 | 
					
						
							| 
									
										
										
										
											2004-01-23 11:17:16 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-03-02 13:06:23 +00:00
										 |  |  | #include "others.h"
 | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | #include "vba_extract.h"
 | 
					
						
							|  |  |  | #ifdef	CL_DEBUG
 | 
					
						
							| 
									
										
										
										
											2007-12-12 23:27:39 +00:00
										 |  |  | #include "mbox.h"
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2007-10-22 20:33:20 +00:00
										 |  |  | #include "blob.h"
 | 
					
						
							| 
									
										
										
										
											2004-01-23 11:17:16 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-09 15:23:50 +00:00
										 |  |  | #ifndef	O_BINARY
 | 
					
						
							|  |  |  | #define	O_BINARY	0
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-12 18:42:44 +00:00
										 |  |  | #define PPT_LZW_BUFFSIZE 8192
 | 
					
						
							|  |  |  | #define VBA_COMPRESSION_WINDOW 4096
 | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | #define	MIDDLE_SIZE	20
 | 
					
						
							| 
									
										
										
										
											2007-11-12 18:42:44 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | #ifndef HAVE_ATTRIB_PACKED
 | 
					
						
							|  |  |  | #define __attribute__(x)
 | 
					
						
							| 
									
										
										
										
											2007-10-26 16:29:26 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * VBA (Visual Basic for Applications), versions 5 and 6 | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2007-10-26 16:29:26 +00:00
										 |  |  | struct vba56_header { | 
					
						
							|  |  |  | 	unsigned char magic[2]; | 
					
						
							|  |  |  | 	unsigned char version[4]; | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 	unsigned	char	ignore[28]; | 
					
						
							| 
									
										
										
										
											2007-10-26 16:29:26 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | typedef struct { | 
					
						
							| 
									
										
										
										
											2004-01-23 11:17:16 +00:00
										 |  |  | 	unsigned char signature[4]; | 
					
						
							|  |  |  | 	const char *name; | 
					
						
							|  |  |  | 	int is_mac; | 
					
						
							|  |  |  | } vba_version_t; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | static	int	skip_past_nul(int fd); | 
					
						
							|  |  |  | static	int	read_uint16(int fd, uint16_t *u, int is_mac); | 
					
						
							|  |  |  | static	int	read_uint32(int fd, uint32_t *u, int is_mac); | 
					
						
							|  |  |  | static	int	seekandread(int fd, off_t offset, int whence, void *data, size_t len); | 
					
						
							|  |  |  | static	vba_project_t	*create_vba_project(int record_count, const char *dir); | 
					
						
							|  |  |  | static	uint32_t	sigtouint32(const unsigned char *fourbytes); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-03-22 09:17:31 +00:00
										 |  |  | static uint16_t vba_endian_convert_16(uint16_t value, int is_mac) | 
					
						
							| 
									
										
										
										
											2004-03-17 09:26:29 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2006-04-07 23:31:41 +00:00
										 |  |  | 	if (is_mac) | 
					
						
							| 
									
										
										
										
											2007-10-26 16:29:26 +00:00
										 |  |  | 		return (uint16_t)be16_to_host(value); | 
					
						
							| 
									
										
										
										
											2006-04-07 23:31:41 +00:00
										 |  |  | 	else | 
					
						
							|  |  |  | 		return le16_to_host(value); | 
					
						
							| 
									
										
										
										
											2004-01-29 10:28:33 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2007-10-22 20:33:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | /* Seems to be a duplicate of riff_endian_convert_32() */ | 
					
						
							| 
									
										
										
										
											2004-03-22 09:17:31 +00:00
										 |  |  | static uint32_t vba_endian_convert_32(uint32_t value, int is_mac) | 
					
						
							| 
									
										
										
										
											2004-03-17 09:26:29 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2006-04-07 23:31:41 +00:00
										 |  |  | 	if (is_mac) | 
					
						
							|  |  |  | 		return be32_to_host(value); | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 		return le32_to_host(value); | 
					
						
							| 
									
										
										
										
											2004-03-17 09:26:29 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2004-01-29 10:28:33 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | /* from libgsf */ | 
					
						
							|  |  |  | static const vba_version_t vba_versions[] = { | 
					
						
							|  |  |  | 	{ { 0x5e, 0x00, 0x00, 0x01 }, "Office 97",              FALSE }, | 
					
						
							| 
									
										
										
										
											2007-11-12 18:42:44 +00:00
										 |  |  | 	{ { 0x5f, 0x00, 0x00, 0x01 }, "Office 97 SR1",          FALSE }, | 
					
						
							|  |  |  | 	{ { 0x65, 0x00, 0x00, 0x01 }, "Office 2000 alpha?",     FALSE }, | 
					
						
							|  |  |  | 	{ { 0x6b, 0x00, 0x00, 0x01 }, "Office 2000 beta?",      FALSE }, | 
					
						
							|  |  |  | 	{ { 0x6d, 0x00, 0x00, 0x01 }, "Office 2000",            FALSE }, | 
					
						
							|  |  |  | 	{ { 0x6f, 0x00, 0x00, 0x01 }, "Office 2000",            FALSE }, | 
					
						
							|  |  |  | 	{ { 0x70, 0x00, 0x00, 0x01 }, "Office XP beta 1/2",     FALSE }, | 
					
						
							|  |  |  | 	{ { 0x73, 0x00, 0x00, 0x01 }, "Office XP",              FALSE }, | 
					
						
							|  |  |  | 	{ { 0x76, 0x00, 0x00, 0x01 }, "Office 2003",            FALSE }, | 
					
						
							|  |  |  | 	{ { 0x79, 0x00, 0x00, 0x01 }, "Office 2003",            FALSE }, | 
					
						
							|  |  |  | 	{ { 0x60, 0x00, 0x00, 0x0e }, "MacOffice 98",           TRUE }, | 
					
						
							|  |  |  | 	{ { 0x62, 0x00, 0x00, 0x0e }, "MacOffice 2001",         TRUE }, | 
					
						
							|  |  |  | 	{ { 0x63, 0x00, 0x00, 0x0e }, "MacOffice X",		TRUE }, | 
					
						
							|  |  |  | 	{ { 0x64, 0x00, 0x00, 0x0e }, "MacOffice 2004",         TRUE }, | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 	{ { 0x00, 0x00, 0x00, 0x00 }, NULL,		        FALSE }, | 
					
						
							| 
									
										
										
										
											2004-01-23 11:17:16 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-10-22 20:33:20 +00:00
										 |  |  | static char * | 
					
						
							|  |  |  | get_unicode_name(const char *name, int size, int is_mac) | 
					
						
							| 
									
										
										
										
											2004-01-23 11:17:16 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 	int i, increment; | 
					
						
							|  |  |  | 	char *newname, *ret; | 
					
						
							| 
									
										
										
										
											2004-03-08 12:30:05 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-06 18:48:29 +00:00
										 |  |  | 	if((name == NULL) || (*name == '\0') || (size <= 0)) | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 		return NULL; | 
					
						
							| 
									
										
										
										
											2004-03-08 12:30:05 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 	newname = (char *)cli_malloc(size * 7); | 
					
						
							|  |  |  | 	if(newname == NULL) | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							| 
									
										
										
										
											2007-11-06 18:48:29 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if((!is_mac) && (size & 0x1)) { | 
					
						
							|  |  |  | 		cli_dbgmsg("get_unicode_name: odd number of bytes %d\n", size); | 
					
						
							|  |  |  | 		--size; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	increment = (is_mac) ? 1 : 2; | 
					
						
							|  |  |  | 	ret = newname; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 	for(i = 0; i < size; i += increment) { | 
					
						
							|  |  |  | 		if(isprint(name[i])) | 
					
						
							|  |  |  | 			*ret++ = name[i]; | 
					
						
							|  |  |  | 		else { | 
					
						
							|  |  |  | 			if((name[i] < 10) && (name[i] >= 0)) { | 
					
						
							| 
									
										
										
										
											2007-11-06 18:48:29 +00:00
										 |  |  | 				*ret++ = '_'; | 
					
						
							|  |  |  | 				*ret++ = (char)(name[i] + '0'); | 
					
						
							|  |  |  | 			} else { | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 				const uint16_t x = (uint16_t)((name[i] << 8) | name[i + 1]); | 
					
						
							| 
									
										
										
										
											2007-10-26 16:29:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-06 18:48:29 +00:00
										 |  |  | 				*ret++ = '_'; | 
					
						
							|  |  |  | 				*ret++ = (char)('a'+((x&0xF))); | 
					
						
							|  |  |  | 				*ret++ = (char)('a'+((x>>4)&0xF)); | 
					
						
							|  |  |  | 				*ret++ = (char)('a'+((x>>8)&0xF)); | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 				*ret++ = 'a'; | 
					
						
							|  |  |  | 				*ret++ = 'a'; | 
					
						
							| 
									
										
										
										
											2007-01-07 20:41:01 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2007-11-06 18:48:29 +00:00
										 |  |  | 			*ret++ = '_'; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 	*ret = '\0'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Saves a lot of memory */ | 
					
						
							|  |  |  | 	ret = cli_realloc(newname, (ret - newname) + 1); | 
					
						
							|  |  |  | 	return ret ? ret : newname; | 
					
						
							| 
									
										
										
										
											2004-01-23 11:17:16 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2004-01-26 16:03:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-01-26 16:03:45 +00:00
										 |  |  | static void vba56_test_middle(int fd) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 	char test_middle[MIDDLE_SIZE]; | 
					
						
							| 
									
										
										
										
											2004-04-05 09:03:53 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* MacOffice middle */ | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 	static const uint8_t middle1_str[MIDDLE_SIZE] = { | 
					
						
							| 
									
										
										
										
											2004-03-18 09:49:41 +00:00
										 |  |  | 		0x00, 0x01, 0x0d, 0x45, 0x2e, 0xe1, 0xe0, 0x8f, 0x10, 0x1a, | 
					
						
							|  |  |  | 		0x85, 0x2e, 0x02, 0x60, 0x8c, 0x4d, 0x0b, 0xb4, 0x00, 0x00 | 
					
						
							| 
									
										
										
										
											2004-01-26 16:03:45 +00:00
										 |  |  | 	}; | 
					
						
							| 
									
										
										
										
											2004-04-05 09:03:53 +00:00
										 |  |  | 	/* MS Office middle */ | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 	static const uint8_t middle2_str[MIDDLE_SIZE] = { | 
					
						
							| 
									
										
										
										
											2007-10-22 20:33:20 +00:00
										 |  |  | 		0x00, 0x00, 0xe1, 0x2e, 0x45, 0x0d, 0x8f, 0xe0, 0x1a, 0x10, | 
					
						
							| 
									
										
										
										
											2004-04-05 09:03:53 +00:00
										 |  |  | 		0x85, 0x2e, 0x02, 0x60, 0x8c, 0x4d, 0x0b, 0xb4, 0x00, 0x00 | 
					
						
							|  |  |  | 	}; | 
					
						
							| 
									
										
										
										
											2004-01-26 16:03:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 	if(cli_readn(fd, &test_middle, MIDDLE_SIZE) != MIDDLE_SIZE) | 
					
						
							| 
									
										
										
										
											2007-10-26 16:29:26 +00:00
										 |  |  | 		return; | 
					
						
							| 
									
										
										
										
											2004-03-08 12:30:05 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 	if((memcmp(test_middle, middle1_str, MIDDLE_SIZE) != 0) && | 
					
						
							|  |  |  | 	   (memcmp(test_middle, middle2_str, MIDDLE_SIZE) != 0)) { | 
					
						
							| 
									
										
										
										
											2004-03-18 09:49:41 +00:00
										 |  |  | 		cli_dbgmsg("middle not found\n"); | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 		lseek(fd, -MIDDLE_SIZE, SEEK_CUR); | 
					
						
							|  |  |  | 	} else | 
					
						
							| 
									
										
										
										
											2004-03-18 09:49:41 +00:00
										 |  |  | 		cli_dbgmsg("middle found\n"); | 
					
						
							| 
									
										
										
										
											2004-01-26 16:03:45 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-01 18:32:17 +00:00
										 |  |  | static int | 
					
						
							|  |  |  | vba_read_project_strings(int fd, int is_mac) | 
					
						
							| 
									
										
										
										
											2004-03-18 09:49:41 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 	unsigned char *buf = NULL; | 
					
						
							|  |  |  | 	uint16_t buflen = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for(;;) { | 
					
						
							|  |  |  | 		off_t offset; | 
					
						
							| 
									
										
										
										
											2007-10-31 18:36:02 +00:00
										 |  |  | 		uint16_t length; | 
					
						
							|  |  |  | 		char *name; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 		if(!read_uint16(fd, &length, is_mac)) { | 
					
						
							|  |  |  | 			if(buf) | 
					
						
							|  |  |  | 				free(buf); | 
					
						
							| 
									
										
										
										
											2004-03-18 09:49:41 +00:00
										 |  |  | 			return FALSE; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if (length < 6) { | 
					
						
							|  |  |  | 			lseek(fd, -2, SEEK_CUR); | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 		if(length > buflen) { | 
					
						
							|  |  |  | 			unsigned char *newbuf = (unsigned char *)cli_realloc(buf, length); | 
					
						
							|  |  |  | 			if(newbuf == NULL) { | 
					
						
							|  |  |  | 				if(buf) | 
					
						
							|  |  |  | 					free(buf); | 
					
						
							|  |  |  | 				return FALSE; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			buflen = length; | 
					
						
							|  |  |  | 			buf = newbuf; | 
					
						
							| 
									
										
										
										
											2004-03-18 09:49:41 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-03-18 09:49:41 +00:00
										 |  |  | 		offset = lseek(fd, 0, SEEK_CUR); | 
					
						
							| 
									
										
										
										
											2007-10-26 16:29:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 		if(cli_readn(fd, buf, length) != (int)length) { | 
					
						
							| 
									
										
										
										
											2004-03-18 09:49:41 +00:00
										 |  |  | 			cli_dbgmsg("read name failed - rewinding\n"); | 
					
						
							|  |  |  | 			lseek(fd, offset, SEEK_SET); | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 		name = get_unicode_name((const char *)buf, length, is_mac); | 
					
						
							|  |  |  | 		cli_dbgmsg("length: %d, name: %s\n", length, (name) ? name : "[null]"); | 
					
						
							| 
									
										
										
										
											2004-03-18 09:49:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-01 18:32:17 +00:00
										 |  |  | 		if((name == NULL) || (memcmp("*\\", name, 2) != 0) || | 
					
						
							|  |  |  | 		   (strchr("GCHD", name[2]) == NULL)) { | 
					
						
							| 
									
										
										
										
											2004-03-18 09:49:41 +00:00
										 |  |  | 			/* Unknown type - probably ran out of strings - rewind */ | 
					
						
							|  |  |  | 			lseek(fd, -(length+2), SEEK_CUR); | 
					
						
							| 
									
										
										
										
											2007-11-01 18:32:17 +00:00
										 |  |  | 			if(name) | 
					
						
							| 
									
										
										
										
											2004-04-16 18:48:16 +00:00
										 |  |  | 				free(name); | 
					
						
							| 
									
										
										
										
											2004-03-18 09:49:41 +00:00
										 |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		free(name); | 
					
						
							| 
									
										
										
										
											2007-11-01 18:32:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 		if(!read_uint16(fd, &length, is_mac)) { | 
					
						
							|  |  |  | 			if(buf) | 
					
						
							|  |  |  | 				free(buf); | 
					
						
							| 
									
										
										
										
											2007-11-01 18:32:17 +00:00
										 |  |  | 			return FALSE; | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2007-11-01 18:32:17 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		if ((length != 0) && (length != 65535)) { | 
					
						
							|  |  |  | 			lseek(fd, -2, SEEK_CUR); | 
					
						
							|  |  |  | 			continue; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		offset = lseek(fd, 10, SEEK_CUR); | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 		cli_dbgmsg("offset: %lu\n", (unsigned long)offset); | 
					
						
							| 
									
										
										
										
											2004-03-18 09:49:41 +00:00
										 |  |  | 		vba56_test_middle(fd); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 	if(buf) | 
					
						
							|  |  |  | 		free(buf); | 
					
						
							| 
									
										
										
										
											2004-03-18 09:49:41 +00:00
										 |  |  | 	return TRUE; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2004-01-26 16:03:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-18 14:32:47 +00:00
										 |  |  | vba_project_t * | 
					
						
							|  |  |  | cli_vba_readdir(const char *dir) | 
					
						
							| 
									
										
										
										
											2004-01-23 11:17:16 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 	unsigned char *buf; | 
					
						
							| 
									
										
										
										
											2007-10-26 16:29:26 +00:00
										 |  |  | 	const unsigned char vba56_signature[] = { 0xcc, 0x61 }; | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 	uint16_t record_count, buflen, ffff, byte_count; | 
					
						
							|  |  |  | 	uint32_t offset, sig; | 
					
						
							| 
									
										
										
										
											2007-10-26 16:29:26 +00:00
										 |  |  | 	int i, fd, is_mac; | 
					
						
							| 
									
										
										
										
											2004-01-23 11:17:16 +00:00
										 |  |  | 	vba_project_t *vba_project; | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 	const vba_version_t *v; | 
					
						
							| 
									
										
										
										
											2007-10-26 16:29:26 +00:00
										 |  |  | 	struct vba56_header v56h; | 
					
						
							| 
									
										
										
										
											2007-10-31 18:36:02 +00:00
										 |  |  | 	char fullname[NAME_MAX + 1]; | 
					
						
							| 
									
										
										
										
											2004-01-23 11:17:16 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-18 14:32:47 +00:00
										 |  |  | 	cli_dbgmsg("in cli_vba_readdir()\n"); | 
					
						
							| 
									
										
										
										
											2004-01-25 06:34:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-17 20:22:11 +00:00
										 |  |  | 	if(dir == NULL) | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 	/*
 | 
					
						
							|  |  |  | 	 * _VBA_PROJECT files are embedded within office documents (OLE2) | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2007-10-31 18:36:02 +00:00
										 |  |  | 	snprintf(fullname, sizeof(fullname) - 1, "%s/_VBA_PROJECT", dir); | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 	fd = open(fullname, O_RDONLY|O_BINARY); | 
					
						
							| 
									
										
										
										
											2004-01-23 11:17:16 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-17 20:22:11 +00:00
										 |  |  | 	if(fd == -1) { | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 		cli_dbgmsg("Can't open %s\n", fullname); | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2004-01-23 11:17:16 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-10-26 16:29:26 +00:00
										 |  |  | 	if(cli_readn(fd, &v56h, sizeof(struct vba56_header)) != sizeof(struct vba56_header)) { | 
					
						
							| 
									
										
										
										
											2004-02-19 16:00:05 +00:00
										 |  |  | 		close(fd); | 
					
						
							| 
									
										
										
										
											2004-01-23 11:17:16 +00:00
										 |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2007-10-26 16:29:26 +00:00
										 |  |  | 	if (memcmp(v56h.magic, vba56_signature, sizeof(v56h.magic)) != 0) { | 
					
						
							| 
									
										
										
										
											2004-02-19 16:00:05 +00:00
										 |  |  | 		close(fd); | 
					
						
							| 
									
										
										
										
											2004-01-23 11:17:16 +00:00
										 |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 	sig = sigtouint32(v56h.version); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for(v = vba_versions; v->name; v++) | 
					
						
							|  |  |  | 		if(sigtouint32(v->signature) == sig) | 
					
						
							| 
									
										
										
										
											2004-01-23 11:17:16 +00:00
										 |  |  | 			break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 	if(v->name == NULL) { | 
					
						
							| 
									
										
										
										
											2004-12-14 11:39:08 +00:00
										 |  |  | 		cli_warnmsg("Unknown VBA version signature %x %x %x %x\n", | 
					
						
							| 
									
										
										
										
											2007-10-26 16:29:26 +00:00
										 |  |  | 			v56h.version[0], v56h.version[1], | 
					
						
							|  |  |  | 			v56h.version[2], v56h.version[3]); | 
					
						
							|  |  |  | 		switch(v56h.version[3]) { | 
					
						
							|  |  |  | 			case 0x01: | 
					
						
							|  |  |  | 				cli_warnmsg("Guessing little-endian\n"); | 
					
						
							|  |  |  | 				is_mac = FALSE; | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			case 0x0E: | 
					
						
							|  |  |  | 				cli_warnmsg("Guessing big-endian\n"); | 
					
						
							|  |  |  | 				is_mac = TRUE; | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			default: | 
					
						
							|  |  |  | 				cli_warnmsg("Unable to guess VBA type\n"); | 
					
						
							|  |  |  | 				close(fd); | 
					
						
							|  |  |  | 				return NULL; | 
					
						
							| 
									
										
										
										
											2007-10-22 20:33:20 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2004-12-14 11:39:08 +00:00
										 |  |  | 	} else { | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 		cli_dbgmsg("VBA Project: %s\n", v->name); | 
					
						
							|  |  |  | 		is_mac = v->is_mac; | 
					
						
							| 
									
										
										
										
											2004-01-23 11:17:16 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-03-18 09:49:41 +00:00
										 |  |  | 	if (!vba_read_project_strings(fd, is_mac)) { | 
					
						
							| 
									
										
										
										
											2004-02-19 16:00:05 +00:00
										 |  |  | 		close(fd); | 
					
						
							| 
									
										
										
										
											2004-01-23 11:17:16 +00:00
										 |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2007-10-22 20:33:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-01-23 11:17:16 +00:00
										 |  |  | 	/* junk some more stuff */ | 
					
						
							|  |  |  | 	do { | 
					
						
							| 
									
										
										
										
											2007-10-26 16:29:26 +00:00
										 |  |  | 		if (cli_readn(fd, &ffff, 2) != 2) { | 
					
						
							| 
									
										
										
										
											2004-02-19 16:00:05 +00:00
										 |  |  | 			close(fd); | 
					
						
							| 
									
										
										
										
											2004-01-23 11:17:16 +00:00
										 |  |  | 			return NULL; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2007-10-26 16:29:26 +00:00
										 |  |  | 	} while(ffff != 0xFFFF); | 
					
						
							| 
									
										
										
										
											2004-03-17 11:45:15 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* check for alignment error */ | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 	if(!seekandread(fd, -3, SEEK_CUR, &ffff, sizeof(uint16_t))) { | 
					
						
							| 
									
										
										
										
											2007-10-22 20:33:20 +00:00
										 |  |  | 		close(fd); | 
					
						
							| 
									
										
										
										
											2004-03-17 11:45:15 +00:00
										 |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 	if (ffff != 0xFFFF) | 
					
						
							| 
									
										
										
										
											2004-03-17 11:45:15 +00:00
										 |  |  | 		lseek(fd, 1, SEEK_CUR); | 
					
						
							| 
									
										
										
										
											2007-10-22 20:33:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 	if(!read_uint16(fd, &ffff, is_mac)) { | 
					
						
							| 
									
										
										
										
											2004-02-19 16:00:05 +00:00
										 |  |  | 		close(fd); | 
					
						
							| 
									
										
										
										
											2004-01-23 11:17:16 +00:00
										 |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 	if(ffff != 0xFFFF) | 
					
						
							| 
									
										
										
										
											2007-10-26 16:29:26 +00:00
										 |  |  | 		lseek(fd, ffff, SEEK_CUR); | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if(!read_uint16(fd, &ffff, is_mac)) { | 
					
						
							| 
									
										
										
										
											2004-02-19 16:00:05 +00:00
										 |  |  | 		close(fd); | 
					
						
							| 
									
										
										
										
											2004-01-23 11:17:16 +00:00
										 |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 	if(ffff == 0xFFFF) | 
					
						
							|  |  |  | 		ffff = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	lseek(fd, ffff + 100, SEEK_CUR); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if(!read_uint16(fd, &record_count, is_mac)) { | 
					
						
							| 
									
										
										
										
											2004-02-19 16:00:05 +00:00
										 |  |  | 		close(fd); | 
					
						
							| 
									
										
										
										
											2004-01-23 11:17:16 +00:00
										 |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 	cli_dbgmsg("VBA Record count: %d\n", record_count); | 
					
						
							| 
									
										
										
										
											2005-08-03 08:58:25 +00:00
										 |  |  | 	if (record_count == 0) { | 
					
						
							|  |  |  | 		close(fd); | 
					
						
							| 
									
										
										
										
											2007-10-26 16:29:26 +00:00
										 |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2004-06-02 09:55:30 +00:00
										 |  |  | 	if (record_count > 1000) { | 
					
						
							|  |  |  | 		/* Almost certainly an error */ | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 		cli_dbgmsg("VBA Record count too big"); | 
					
						
							| 
									
										
										
										
											2004-06-02 09:55:30 +00:00
										 |  |  | 		close(fd); | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2007-10-22 20:33:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 	vba_project = create_vba_project(record_count, dir); | 
					
						
							|  |  |  | 	if(vba_project == NULL) { | 
					
						
							| 
									
										
										
										
											2004-05-20 10:23:40 +00:00
										 |  |  | 		close(fd); | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 	buf = NULL; | 
					
						
							|  |  |  | 	buflen = 0; | 
					
						
							| 
									
										
										
										
											2007-10-26 16:29:26 +00:00
										 |  |  | 	for(i = 0; i < record_count; i++) { | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 		uint16_t length; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if(!read_uint16(fd, &length, is_mac)) | 
					
						
							| 
									
										
										
										
											2007-10-26 16:29:26 +00:00
										 |  |  | 			break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-04-05 13:28:27 +00:00
										 |  |  | 		if (length == 0) { | 
					
						
							|  |  |  | 			cli_dbgmsg("zero name length\n"); | 
					
						
							| 
									
										
										
										
											2007-10-26 16:29:26 +00:00
										 |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 		if(length > buflen) { | 
					
						
							|  |  |  | 			unsigned char *newbuf = (unsigned char *)cli_realloc(buf, length); | 
					
						
							|  |  |  | 			if(newbuf == NULL) | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			buflen = length; | 
					
						
							|  |  |  | 			buf = newbuf; | 
					
						
							| 
									
										
										
										
											2004-01-23 11:17:16 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 		if (cli_readn(fd, buf, length) != length) { | 
					
						
							| 
									
										
										
										
											2004-01-23 11:17:16 +00:00
										 |  |  | 			cli_dbgmsg("read name failed\n"); | 
					
						
							| 
									
										
										
										
											2007-10-26 16:29:26 +00:00
										 |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2004-01-23 11:17:16 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 		vba_project->name[i] = get_unicode_name((const char *)buf, length, is_mac); | 
					
						
							| 
									
										
										
										
											2004-06-25 14:18:13 +00:00
										 |  |  | 		if (!vba_project->name[i]) { | 
					
						
							|  |  |  | 			offset = lseek(fd, 0, SEEK_CUR); | 
					
						
							|  |  |  | 			vba_project->name[i] = (char *) cli_malloc(18); | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 			if(vba_project->name[i] == NULL) | 
					
						
							| 
									
										
										
										
											2007-10-26 16:29:26 +00:00
										 |  |  | 				break; | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 			sprintf(vba_project->name[i], "clamav-%.10d", (int)offset); | 
					
						
							| 
									
										
										
										
											2004-06-25 14:18:13 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 		cli_dbgmsg("project name: %s\n", vba_project->name[i]); | 
					
						
							| 
									
										
										
										
											2004-01-23 11:17:16 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		/* some kind of string identifier ?? */ | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 		if(!read_uint16(fd, &length, is_mac)) { | 
					
						
							| 
									
										
										
										
											2004-02-19 16:00:05 +00:00
										 |  |  | 			free(vba_project->name[i]); | 
					
						
							| 
									
										
										
										
											2007-10-26 16:29:26 +00:00
										 |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2004-01-23 11:17:16 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		lseek(fd, length, SEEK_CUR); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/* unknown stuff */ | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 		if(!read_uint16(fd, &ffff, is_mac)) { | 
					
						
							| 
									
										
										
										
											2004-02-19 16:00:05 +00:00
										 |  |  | 			free(vba_project->name[i]); | 
					
						
							| 
									
										
										
										
											2007-10-26 16:29:26 +00:00
										 |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2004-01-23 11:17:16 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2007-10-26 16:29:26 +00:00
										 |  |  | 		if (ffff == 0xFFFF) { | 
					
						
							| 
									
										
										
										
											2004-01-23 11:17:16 +00:00
										 |  |  | 			lseek(fd, 2, SEEK_CUR); | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 			if(!read_uint16(fd, &ffff, is_mac)) { | 
					
						
							| 
									
										
										
										
											2004-02-19 16:00:05 +00:00
										 |  |  | 				free(vba_project->name[i]); | 
					
						
							| 
									
										
										
										
											2007-10-26 16:29:26 +00:00
										 |  |  | 				break; | 
					
						
							| 
									
										
										
										
											2004-01-23 11:17:16 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 			lseek(fd, ffff + 8, SEEK_CUR); | 
					
						
							|  |  |  | 		} else | 
					
						
							|  |  |  | 			lseek(fd, ffff + 10, SEEK_CUR); | 
					
						
							| 
									
										
										
										
											2004-01-23 11:17:16 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 		if(!read_uint16(fd, &byte_count, is_mac)) { | 
					
						
							| 
									
										
										
										
											2004-02-19 16:00:05 +00:00
										 |  |  | 			free(vba_project->name[i]); | 
					
						
							| 
									
										
										
										
											2007-10-26 16:29:26 +00:00
										 |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2004-01-23 11:17:16 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2007-10-26 16:29:26 +00:00
										 |  |  | 		lseek(fd, (8 * byte_count) + 5, SEEK_CUR); | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 		if(!read_uint32(fd, &offset, is_mac)) { | 
					
						
							| 
									
										
										
										
											2004-02-19 16:00:05 +00:00
										 |  |  | 			free(vba_project->name[i]); | 
					
						
							| 
									
										
										
										
											2007-10-26 16:29:26 +00:00
										 |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2004-01-23 11:17:16 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		vba_project->offset[i] = offset; | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 		cli_dbgmsg("offset: %u\n", (unsigned int)offset); | 
					
						
							| 
									
										
										
										
											2004-01-23 11:17:16 +00:00
										 |  |  | 		lseek(fd, 2, SEEK_CUR); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2007-10-22 20:33:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 	if(buf) | 
					
						
							|  |  |  | 		free(buf); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-10-26 16:29:26 +00:00
										 |  |  | 	close(fd); | 
					
						
							| 
									
										
										
										
											2007-10-22 20:33:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-10-26 16:29:26 +00:00
										 |  |  | 	if(i < record_count) { | 
					
						
							|  |  |  | 		/* above loop failed */ | 
					
						
							|  |  |  | 		while(--i >= 0) | 
					
						
							|  |  |  | 			free(vba_project->name[i]); | 
					
						
							| 
									
										
										
										
											2004-01-23 11:17:16 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-10-26 16:29:26 +00:00
										 |  |  | 		free(vba_project->name); | 
					
						
							|  |  |  | 		free(vba_project->dir); | 
					
						
							|  |  |  | 		free(vba_project->offset); | 
					
						
							|  |  |  | 		free(vba_project); | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							| 
									
										
										
										
											2004-01-23 11:17:16 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2004-02-19 16:00:05 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-10-26 16:29:26 +00:00
										 |  |  | 	return vba_project; | 
					
						
							| 
									
										
										
										
											2004-01-23 11:17:16 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-17 20:22:11 +00:00
										 |  |  | unsigned char * | 
					
						
							| 
									
										
										
										
											2007-12-18 14:32:47 +00:00
										 |  |  | cli_vba_inflate(int fd, off_t offset, int *size) | 
					
						
							| 
									
										
										
										
											2004-01-23 11:17:16 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2007-12-17 20:22:11 +00:00
										 |  |  | 	unsigned int pos, shift, mask, distance, clean; | 
					
						
							| 
									
										
										
										
											2004-01-23 11:17:16 +00:00
										 |  |  | 	uint8_t flag; | 
					
						
							| 
									
										
										
										
											2007-12-17 20:22:11 +00:00
										 |  |  | 	uint16_t token; | 
					
						
							| 
									
										
										
										
											2007-10-22 20:33:20 +00:00
										 |  |  | 	blob *b; | 
					
						
							| 
									
										
										
										
											2004-01-23 11:17:16 +00:00
										 |  |  | 	unsigned char buffer[VBA_COMPRESSION_WINDOW]; | 
					
						
							| 
									
										
										
										
											2007-10-22 20:33:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-17 20:22:11 +00:00
										 |  |  | 	if(fd < 0) | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-10-22 20:33:20 +00:00
										 |  |  | 	b = blobCreate(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if(b == NULL) | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	lseek(fd, offset+3, SEEK_SET); /* 1byte ?? , 2byte length ?? */ | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 	clean = TRUE; | 
					
						
							| 
									
										
										
										
											2007-12-17 20:22:11 +00:00
										 |  |  | 	pos = 0; | 
					
						
							| 
									
										
										
										
											2007-10-22 20:33:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-03-26 09:37:09 +00:00
										 |  |  | 	while (cli_readn(fd, &flag, 1) == 1) { | 
					
						
							| 
									
										
										
										
											2007-12-17 20:22:11 +00:00
										 |  |  | 		for(mask = 1; mask < 0x100; mask<<=1) { | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 			unsigned int winpos = pos % VBA_COMPRESSION_WINDOW; | 
					
						
							| 
									
										
										
										
											2004-01-23 11:17:16 +00:00
										 |  |  | 			if (flag & mask) { | 
					
						
							| 
									
										
										
										
											2007-12-17 20:22:11 +00:00
										 |  |  | 				uint16_t len; | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 				unsigned int srcpos; | 
					
						
							| 
									
										
										
										
											2007-12-17 20:22:11 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 				if(!read_uint16(fd, &token, FALSE)) { | 
					
						
							| 
									
										
										
										
											2007-10-22 20:33:20 +00:00
										 |  |  | 					blobDestroy(b); | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 					if(size) | 
					
						
							| 
									
										
										
										
											2004-02-20 14:51:46 +00:00
										 |  |  | 						*size = 0; | 
					
						
							| 
									
										
										
										
											2004-02-19 16:00:05 +00:00
										 |  |  | 					return NULL; | 
					
						
							| 
									
										
										
										
											2004-01-23 11:17:16 +00:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2007-12-17 20:22:11 +00:00
										 |  |  | 				shift = 12 - (winpos > 0x10) | 
					
						
							|  |  |  | 						- (winpos > 0x20) | 
					
						
							|  |  |  | 						- (winpos > 0x40) | 
					
						
							|  |  |  | 						- (winpos > 0x80) | 
					
						
							|  |  |  | 						- (winpos > 0x100) | 
					
						
							|  |  |  | 						- (winpos > 0x200) | 
					
						
							|  |  |  | 						- (winpos > 0x400) | 
					
						
							|  |  |  | 						- (winpos > 0x800); | 
					
						
							|  |  |  | 				len = (uint16_t)((token & ((1 << shift) - 1)) + 3); | 
					
						
							| 
									
										
										
										
											2004-01-23 11:17:16 +00:00
										 |  |  | 				distance = token >> shift; | 
					
						
							| 
									
										
										
										
											2007-10-22 20:33:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 				srcpos = pos - distance - 1; | 
					
						
							|  |  |  | 				if((((srcpos + len) % VBA_COMPRESSION_WINDOW) < winpos) && | 
					
						
							|  |  |  | 				   ((winpos + len) < VBA_COMPRESSION_WINDOW) && | 
					
						
							|  |  |  | 				   (((srcpos % VBA_COMPRESSION_WINDOW) + len) < VBA_COMPRESSION_WINDOW) && | 
					
						
							|  |  |  | 				   (len <= VBA_COMPRESSION_WINDOW)) { | 
					
						
							|  |  |  | 					srcpos %= VBA_COMPRESSION_WINDOW; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-17 20:22:11 +00:00
										 |  |  | 					cli_dbgmsg("memcpy(%u, %u, %d)\n", | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 						winpos, srcpos, len); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					memcpy(&buffer[winpos], &buffer[srcpos], | 
					
						
							|  |  |  | 						len); | 
					
						
							|  |  |  | 					pos += len; | 
					
						
							|  |  |  | 				} else | 
					
						
							| 
									
										
										
										
											2007-12-17 20:22:11 +00:00
										 |  |  | 					while(len-- > 0) { | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 						srcpos = (pos - distance - 1) % VBA_COMPRESSION_WINDOW; | 
					
						
							| 
									
										
										
										
											2007-12-17 20:22:11 +00:00
										 |  |  | 						cli_dbgmsg("Copying %u to %u\n", | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 							srcpos, pos % VBA_COMPRESSION_WINDOW); | 
					
						
							|  |  |  | 						buffer[pos++ % VBA_COMPRESSION_WINDOW] = buffer[srcpos]; | 
					
						
							|  |  |  | 					} | 
					
						
							| 
									
										
										
										
											2004-01-23 11:17:16 +00:00
										 |  |  | 			} else { | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 				if((pos != 0) && (winpos == 0) && clean) { | 
					
						
							| 
									
										
										
										
											2004-03-26 09:37:09 +00:00
										 |  |  | 					if (cli_readn(fd, &token, 2) != 2) { | 
					
						
							| 
									
										
										
										
											2007-10-22 20:33:20 +00:00
										 |  |  | 						blobDestroy(b); | 
					
						
							|  |  |  | 						if(size) | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 							*size = 0; | 
					
						
							| 
									
										
										
										
											2004-02-19 16:00:05 +00:00
										 |  |  | 						return NULL; | 
					
						
							| 
									
										
										
										
											2004-01-23 11:17:16 +00:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2007-10-22 20:33:20 +00:00
										 |  |  | 					(void)blobAddData(b, buffer, VBA_COMPRESSION_WINDOW); | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 					clean = FALSE; | 
					
						
							| 
									
										
										
										
											2004-01-23 11:17:16 +00:00
										 |  |  | 					break; | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 				if(cli_readn(fd, &buffer[winpos], 1) == 1) | 
					
						
							| 
									
										
										
										
											2004-01-23 11:17:16 +00:00
										 |  |  | 					pos++; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 			clean = TRUE; | 
					
						
							| 
									
										
										
										
											2004-01-23 11:17:16 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 	if(blobAddData(b, buffer, pos%VBA_COMPRESSION_WINDOW) < 0) { | 
					
						
							| 
									
										
										
										
											2007-10-22 20:33:20 +00:00
										 |  |  | 		blobDestroy(b); | 
					
						
							|  |  |  | 		if(size) | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 			*size = 0; | 
					
						
							| 
									
										
										
										
											2007-10-22 20:33:20 +00:00
										 |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-10-22 20:33:20 +00:00
										 |  |  | 	if(size) | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 		*size = (int)blobGetDataSize(b); | 
					
						
							|  |  |  | 	return (unsigned char *)blobToMem(b); | 
					
						
							| 
									
										
										
										
											2004-01-23 11:17:16 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2004-04-27 11:42:53 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * See also cli_filecopy() | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | ole_copy_file_data(int s, int d, uint32_t len) | 
					
						
							| 
									
										
										
										
											2005-04-14 18:42:13 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 	unsigned char data[FILEBUFF]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	while(len > 0) { | 
					
						
							|  |  |  | 		unsigned int todo = MIN(sizeof(data), len); | 
					
						
							|  |  |  | 		unsigned int count = cli_readn(s, data, todo); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if(count != todo) | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		if((unsigned int)cli_writen(d, data, count) != count) | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		len -= count; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2005-04-14 18:42:13 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-17 20:22:11 +00:00
										 |  |  | int | 
					
						
							|  |  |  | cli_decode_ole_object(int fd, const char *dir) | 
					
						
							| 
									
										
										
										
											2005-04-14 18:42:13 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	int ofd; | 
					
						
							|  |  |  | 	uint32_t object_size; | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 	struct stat statbuf; | 
					
						
							| 
									
										
										
										
											2007-11-08 15:26:14 +00:00
										 |  |  | 	char fullname[NAME_MAX + 1]; | 
					
						
							| 
									
										
										
										
											2005-04-14 18:42:13 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-17 20:22:11 +00:00
										 |  |  | 	if(dir == NULL) | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if(fd < 0) | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 	if(!read_uint32(fd, &object_size, FALSE)) | 
					
						
							| 
									
										
										
										
											2005-04-14 18:42:13 +00:00
										 |  |  | 		return -1; | 
					
						
							| 
									
										
										
										
											2007-10-22 20:33:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 	if(fstat(fd, &statbuf) == -1) | 
					
						
							| 
									
										
										
										
											2005-04-14 18:42:13 +00:00
										 |  |  | 		return -1; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 	if ((statbuf.st_size - object_size) >= 4) { | 
					
						
							| 
									
										
										
										
											2005-04-14 18:42:13 +00:00
										 |  |  | 		/* Probably the OLE type id */ | 
					
						
							|  |  |  | 		if (lseek(fd, 2, SEEK_CUR) == -1) { | 
					
						
							|  |  |  | 			return -1; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2007-10-22 20:33:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-04-14 18:42:13 +00:00
										 |  |  | 		/* Skip attachment name */ | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 		if(!skip_past_nul(fd)) | 
					
						
							|  |  |  | 			return -1; | 
					
						
							| 
									
										
										
										
											2007-10-22 20:33:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-04-14 18:42:13 +00:00
										 |  |  | 		/* Skip attachment full path */ | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 		if(!skip_past_nul(fd)) | 
					
						
							|  |  |  | 			return -1; | 
					
						
							| 
									
										
										
										
											2007-10-22 20:33:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-04-14 18:42:13 +00:00
										 |  |  | 		/* Skip unknown data */ | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 		if(lseek(fd, 8, SEEK_CUR) == -1) | 
					
						
							| 
									
										
										
										
											2005-04-14 18:42:13 +00:00
										 |  |  | 			return -1; | 
					
						
							| 
									
										
										
										
											2007-10-22 20:33:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-04-14 18:42:13 +00:00
										 |  |  | 		/* Skip attachment full path */ | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 		if(!skip_past_nul(fd)) | 
					
						
							|  |  |  | 			return -1; | 
					
						
							| 
									
										
										
										
											2007-10-22 20:33:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 		if(!read_uint32(fd, &object_size, FALSE)) | 
					
						
							| 
									
										
										
										
											2005-04-14 18:42:13 +00:00
										 |  |  | 			return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2007-11-08 15:26:14 +00:00
										 |  |  | 	snprintf(fullname, sizeof(fullname) - 1, "%s/_clam_ole_object", dir); | 
					
						
							| 
									
										
										
										
											2006-10-09 15:23:50 +00:00
										 |  |  | 	ofd = open(fullname, O_RDWR|O_CREAT|O_TRUNC|O_BINARY, 0600); | 
					
						
							| 
									
										
										
										
											2007-10-26 16:29:26 +00:00
										 |  |  | 	if (ofd < 0) { | 
					
						
							| 
									
										
										
										
											2005-04-14 18:42:13 +00:00
										 |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	ole_copy_file_data(fd, ofd, object_size); | 
					
						
							| 
									
										
										
										
											2006-12-04 00:17:54 +00:00
										 |  |  | 	lseek(ofd, 0, SEEK_SET); | 
					
						
							| 
									
										
										
										
											2005-04-14 18:42:13 +00:00
										 |  |  | 	return ofd; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * Powerpoint files | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | typedef struct { | 
					
						
							| 
									
										
										
										
											2004-05-27 15:38:39 +00:00
										 |  |  | 	uint16_t type; | 
					
						
							|  |  |  | 	uint32_t length; | 
					
						
							|  |  |  | } atom_header_t; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | static int | 
					
						
							|  |  |  | ppt_read_atom_header(int fd, atom_header_t *atom_header) | 
					
						
							| 
									
										
										
										
											2004-05-27 15:38:39 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 	uint16_t v; | 
					
						
							|  |  |  | 	struct ppt_header { | 
					
						
							|  |  |  | 		uint16_t ver; | 
					
						
							|  |  |  | 		uint16_t type; | 
					
						
							|  |  |  | 		uint32_t length; | 
					
						
							|  |  |  | 	} h; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	cli_dbgmsg("in ppt_read_atom_header\n"); | 
					
						
							|  |  |  | 	if(cli_readn(fd, &h, sizeof(struct ppt_header)) != sizeof(struct ppt_header)) { | 
					
						
							|  |  |  | 		cli_dbgmsg("read ppt_header failed\n"); | 
					
						
							| 
									
										
										
										
											2004-05-27 15:38:39 +00:00
										 |  |  | 		return FALSE; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 	v = vba_endian_convert_16(h.ver, FALSE); | 
					
						
							|  |  |  | 	cli_dbgmsg("\tversion: 0x%.2x\n", (uint8_t)(v & 0xF)); | 
					
						
							|  |  |  | 	cli_dbgmsg("\tinstance: 0x%.2x\n", (uint16_t)(v >> 4)); | 
					
						
							| 
									
										
										
										
											2004-05-27 15:38:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 	atom_header->type = vba_endian_convert_16(h.type, FALSE); | 
					
						
							|  |  |  | 	cli_dbgmsg("\ttype: 0x%.4x\n", atom_header->type); | 
					
						
							|  |  |  | 	atom_header->length = vba_endian_convert_32(h.length, FALSE); | 
					
						
							|  |  |  | 	cli_dbgmsg("\tlength: 0x%.8x\n", (int)atom_header->length); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return TRUE; | 
					
						
							| 
									
										
										
										
											2004-05-27 15:38:39 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * TODO: combine shared code with flatedecode() | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2004-05-27 15:38:39 +00:00
										 |  |  | static int ppt_unlzw(const char *dir, int fd, uint32_t length) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int ofd, retval; | 
					
						
							|  |  |  | 	uint32_t bufflen; | 
					
						
							|  |  |  | 	z_stream stream; | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 	unsigned char inbuff[PPT_LZW_BUFFSIZE], outbuff[PPT_LZW_BUFFSIZE]; | 
					
						
							| 
									
										
										
										
											2007-11-12 18:42:44 +00:00
										 |  |  | 	char fullname[NAME_MAX + 1]; | 
					
						
							| 
									
										
										
										
											2007-10-22 20:33:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-12 18:42:44 +00:00
										 |  |  | 	snprintf(fullname, sizeof(fullname) - 1, "%s/ppt%.8lx.doc", | 
					
						
							|  |  |  | 		dir, (long)lseek(fd, 0L, SEEK_CUR)); | 
					
						
							| 
									
										
										
										
											2007-10-22 20:33:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-09 15:23:50 +00:00
										 |  |  | 	ofd = open(fullname, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0600); | 
					
						
							| 
									
										
										
										
											2007-10-26 16:29:26 +00:00
										 |  |  | 	if (ofd == -1) { | 
					
						
							|  |  |  | 		cli_dbgmsg("ppt_unlzw Open outfile failed\n"); | 
					
						
							|  |  |  | 		return FALSE; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2007-10-22 20:33:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-05-27 15:38:39 +00:00
										 |  |  | 	stream.zalloc = Z_NULL; | 
					
						
							|  |  |  | 	stream.zfree = Z_NULL; | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 	stream.opaque = (void *)NULL; | 
					
						
							|  |  |  | 	stream.next_in = (Bytef *)inbuff; | 
					
						
							|  |  |  | 	stream.next_out = outbuff; | 
					
						
							|  |  |  | 	stream.avail_out = sizeof(outbuff); | 
					
						
							|  |  |  | 	stream.avail_in = MIN(length, PPT_LZW_BUFFSIZE); | 
					
						
							| 
									
										
										
										
											2007-10-22 20:33:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 	if(cli_readn(fd, inbuff, stream.avail_in) != (int)stream.avail_in) { | 
					
						
							| 
									
										
										
										
											2004-05-27 15:38:39 +00:00
										 |  |  | 		close(ofd); | 
					
						
							| 
									
										
										
										
											2007-11-01 18:32:17 +00:00
										 |  |  | 		unlink(fullname); | 
					
						
							| 
									
										
										
										
											2004-05-27 15:38:39 +00:00
										 |  |  | 		return FALSE; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	length -= stream.avail_in; | 
					
						
							| 
									
										
										
										
											2007-10-22 20:33:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-05-27 15:38:39 +00:00
										 |  |  | 	retval = inflateInit(&stream); | 
					
						
							|  |  |  | 	if (retval != Z_OK) { | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 		cli_dbgmsg("ppt_unlzw !Z_OK: %d\n", retval); | 
					
						
							| 
									
										
										
										
											2004-05-27 15:38:39 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2007-10-22 20:33:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 	bufflen = stream.avail_in; | 
					
						
							| 
									
										
										
										
											2007-10-22 20:33:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-05-27 15:38:39 +00:00
										 |  |  | 	do { | 
					
						
							|  |  |  | 		if (stream.avail_out == 0) { | 
					
						
							|  |  |  | 			if (cli_writen(ofd, outbuff, PPT_LZW_BUFFSIZE) | 
					
						
							|  |  |  | 						!= PPT_LZW_BUFFSIZE) { | 
					
						
							|  |  |  | 				close(ofd); | 
					
						
							|  |  |  | 				inflateEnd(&stream); | 
					
						
							|  |  |  | 				return FALSE; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			stream.next_out = outbuff; | 
					
						
							|  |  |  | 			stream.avail_out = PPT_LZW_BUFFSIZE; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if (stream.avail_in == 0) { | 
					
						
							|  |  |  | 			stream.next_in = inbuff; | 
					
						
							|  |  |  | 			bufflen = stream.avail_in = MIN(length, PPT_LZW_BUFFSIZE); | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 			if (cli_readn(fd, inbuff, stream.avail_in) != (int)stream.avail_in) { | 
					
						
							| 
									
										
										
										
											2004-05-27 15:38:39 +00:00
										 |  |  | 				close(ofd); | 
					
						
							|  |  |  | 				inflateEnd(&stream); | 
					
						
							|  |  |  | 				return FALSE; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			length -= stream.avail_in; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 	} while(inflate(&stream, Z_NO_FLUSH) == Z_OK); | 
					
						
							| 
									
										
										
										
											2007-10-22 20:33:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 	if (cli_writen(ofd, outbuff, bufflen) != (int)bufflen) { | 
					
						
							| 
									
										
										
										
											2004-05-27 15:38:39 +00:00
										 |  |  | 		close(ofd); | 
					
						
							|  |  |  | 		inflateEnd(&stream); | 
					
						
							|  |  |  | 		return FALSE; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 	close(ofd); | 
					
						
							|  |  |  | 	return inflateEnd(&stream) == Z_OK; | 
					
						
							| 
									
										
										
										
											2004-05-27 15:38:39 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | static const char * | 
					
						
							|  |  |  | ppt_stream_iter(int fd, const char *dir) | 
					
						
							| 
									
										
										
										
											2004-06-30 12:28:17 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2007-10-22 20:33:20 +00:00
										 |  |  | 	atom_header_t atom_header; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	while(ppt_read_atom_header(fd, &atom_header)) { | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 		if(atom_header.length == 0) | 
					
						
							| 
									
										
										
										
											2004-11-12 15:32:15 +00:00
										 |  |  | 			return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 		if(atom_header.type == 0x1011) { | 
					
						
							|  |  |  | 			uint32_t ole_id, length; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if(!read_uint32(fd, &ole_id, FALSE)) { | 
					
						
							| 
									
										
										
										
											2004-06-30 12:28:17 +00:00
										 |  |  | 				cli_dbgmsg("read ole_id failed\n"); | 
					
						
							|  |  |  | 				return NULL; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 			length = atom_header.length - 4; | 
					
						
							| 
									
										
										
										
											2004-06-30 12:28:17 +00:00
										 |  |  | 			cli_dbgmsg("OleID: %d, length: %d\n", | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 					(int)ole_id, (int)length); | 
					
						
							|  |  |  | 			if (!ppt_unlzw(dir, fd, length)) { | 
					
						
							| 
									
										
										
										
											2004-06-30 12:28:17 +00:00
										 |  |  | 				cli_dbgmsg("ppt_unlzw failed\n"); | 
					
						
							|  |  |  | 				return NULL; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} else { | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 			off_t offset = lseek(fd, 0, SEEK_CUR); | 
					
						
							| 
									
										
										
										
											2005-03-11 19:18:01 +00:00
										 |  |  | 			/* Check we don't wrap */ | 
					
						
							| 
									
										
										
										
											2005-03-18 13:52:06 +00:00
										 |  |  | 			if ((offset + (off_t)atom_header.length) < offset) { | 
					
						
							| 
									
										
										
										
											2005-03-11 19:18:01 +00:00
										 |  |  | 				break; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			offset += atom_header.length; | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 			if (lseek(fd, offset, SEEK_SET) != offset) { | 
					
						
							| 
									
										
										
										
											2004-06-30 12:28:17 +00:00
										 |  |  | 				break; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 	return dir; | 
					
						
							| 
									
										
										
										
											2004-06-30 12:28:17 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | char * | 
					
						
							| 
									
										
										
										
											2007-12-18 14:32:47 +00:00
										 |  |  | cli_ppt_vba_read(const char *filename) | 
					
						
							| 
									
										
										
										
											2004-06-30 12:28:17 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 	char *dir; | 
					
						
							|  |  |  | 	const char *ret; | 
					
						
							| 
									
										
										
										
											2004-06-30 12:28:17 +00:00
										 |  |  | 	int fd; | 
					
						
							| 
									
										
										
										
											2007-11-01 18:32:17 +00:00
										 |  |  | 	char fullname[NAME_MAX + 1]; | 
					
						
							| 
									
										
										
										
											2004-06-30 12:28:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-17 20:22:11 +00:00
										 |  |  | 	if(filename == NULL) | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 	snprintf(fullname, sizeof(fullname) - 1, "%s/PowerPoint Document", | 
					
						
							|  |  |  | 		filename); | 
					
						
							| 
									
										
										
										
											2006-10-09 15:23:50 +00:00
										 |  |  | 	fd = open(fullname, O_RDONLY|O_BINARY); | 
					
						
							| 
									
										
										
										
											2004-06-30 12:28:17 +00:00
										 |  |  | 	if (fd == -1) { | 
					
						
							| 
									
										
										
										
											2007-10-31 18:36:02 +00:00
										 |  |  | 		cli_dbgmsg("Open PowerPoint Document failed\n"); | 
					
						
							| 
									
										
										
										
											2004-06-30 12:28:17 +00:00
										 |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2007-10-22 20:33:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 	/* Create a directory to store the extracted OLE2 objects */ | 
					
						
							|  |  |  | 	dir = cli_gentemp(NULL); | 
					
						
							| 
									
										
										
										
											2007-12-18 14:32:47 +00:00
										 |  |  | 	if(dir == NULL) | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 	if(mkdir(dir, 0700)) { | 
					
						
							| 
									
										
										
										
											2007-12-18 14:32:47 +00:00
										 |  |  | 		cli_errmsg("cli_ppt_vba_read: Can't create temporary directory %s\n", dir); | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 		free(dir); | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	ret = ppt_stream_iter(fd, dir); | 
					
						
							| 
									
										
										
										
											2004-06-30 12:28:17 +00:00
										 |  |  | 	close(fd); | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 	if(ret == NULL) { | 
					
						
							|  |  |  | 		cli_rmdirs(dir); | 
					
						
							|  |  |  | 		free(dir); | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return dir; | 
					
						
							| 
									
										
										
										
											2004-06-30 12:28:17 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * Word 6 macros | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | typedef struct { | 
					
						
							|  |  |  | 	unsigned	char unused[12]; | 
					
						
							|  |  |  | 	uint32_t	macro_offset; | 
					
						
							|  |  |  | 	uint32_t	macro_len; | 
					
						
							| 
									
										
										
										
											2004-04-27 11:42:53 +00:00
										 |  |  | } mso_fib_t; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | typedef struct macro_entry_tag { | 
					
						
							|  |  |  | 	unsigned char key; | 
					
						
							|  |  |  | 	uint32_t len; | 
					
						
							|  |  |  | 	uint32_t offset; | 
					
						
							|  |  |  | } macro_entry_t; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | typedef struct macro_info_tag { | 
					
						
							|  |  |  | 	uint16_t count; | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 	struct macro_entry_tag *entries; | 
					
						
							| 
									
										
										
										
											2004-04-27 11:42:53 +00:00
										 |  |  | } macro_info_t; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | static int | 
					
						
							|  |  |  | word_read_fib(int fd, mso_fib_t *fib) | 
					
						
							| 
									
										
										
										
											2004-04-27 11:42:53 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 	struct { | 
					
						
							|  |  |  | 		uint32_t offset; | 
					
						
							|  |  |  | 		uint32_t len; | 
					
						
							|  |  |  | 	} macro_details; | 
					
						
							| 
									
										
										
										
											2007-10-22 20:33:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 	if(!seekandread(fd, 0x118, SEEK_SET, ¯o_details, sizeof(macro_details))) { | 
					
						
							|  |  |  | 		cli_dbgmsg("read word_fib failed\n"); | 
					
						
							| 
									
										
										
										
											2004-04-27 11:42:53 +00:00
										 |  |  | 		return FALSE; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 	fib->macro_offset = vba_endian_convert_32(macro_details.offset, FALSE); | 
					
						
							|  |  |  | 	fib->macro_len = vba_endian_convert_32(macro_details.len, FALSE); | 
					
						
							| 
									
										
										
										
											2007-10-22 20:33:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-04-27 11:42:53 +00:00
										 |  |  | 	return TRUE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | static int | 
					
						
							|  |  |  | word_read_macro_entry(int fd, macro_info_t *macro_info) | 
					
						
							| 
									
										
										
										
											2004-04-27 11:42:53 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2007-12-17 20:22:11 +00:00
										 |  |  | 	int msize; | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 	int count = macro_info->count; | 
					
						
							|  |  |  | 	macro_entry_t *macro_entry; | 
					
						
							|  |  |  | #ifdef HAVE_PRAGMA_PACK
 | 
					
						
							|  |  |  | #pragma pack(1)
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef HAVE_PRAGMA_PACK_HPPA
 | 
					
						
							|  |  |  | #pragma pack 1
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 	struct macro { | 
					
						
							|  |  |  | 		unsigned char version; | 
					
						
							|  |  |  | 		unsigned char key; | 
					
						
							|  |  |  | 		unsigned char ignore[10]; | 
					
						
							|  |  |  | 		uint32_t len	__attribute__ ((packed)); | 
					
						
							|  |  |  | 		uint32_t state	__attribute__ ((packed)); | 
					
						
							|  |  |  | 		uint32_t offset	__attribute__ ((packed)); | 
					
						
							|  |  |  | 	} *m; | 
					
						
							|  |  |  | 	const struct macro *n; | 
					
						
							|  |  |  | #ifdef HAVE_PRAGMA_PACK
 | 
					
						
							|  |  |  | #pragma pack()
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef HAVE_PRAGMA_PACK_HPPA
 | 
					
						
							|  |  |  | #pragma pack
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 	if(count == 0) | 
					
						
							|  |  |  | 		return TRUE; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	msize = count * sizeof(struct macro); | 
					
						
							|  |  |  | 	m = cli_malloc(msize); | 
					
						
							|  |  |  | 	if(m == NULL) | 
					
						
							| 
									
										
										
										
											2004-04-27 11:42:53 +00:00
										 |  |  | 		return FALSE; | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if(cli_readn(fd, m, msize) != msize) { | 
					
						
							|  |  |  | 		free(m); | 
					
						
							|  |  |  | 		cli_warnmsg("read %d macro_entries failed\n", count); | 
					
						
							| 
									
										
										
										
											2004-04-27 11:42:53 +00:00
										 |  |  | 		return FALSE; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 	macro_entry = macro_info->entries; | 
					
						
							|  |  |  | 	n = m; | 
					
						
							| 
									
										
										
										
											2007-12-17 20:22:11 +00:00
										 |  |  | 	do { | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 		macro_entry->key = n->key; | 
					
						
							|  |  |  | 		macro_entry->len = vba_endian_convert_32(n->len, FALSE); | 
					
						
							|  |  |  | 		macro_entry->offset = vba_endian_convert_32(n->offset, FALSE); | 
					
						
							|  |  |  | 		macro_entry++; | 
					
						
							|  |  |  | 		n++; | 
					
						
							| 
									
										
										
										
											2007-12-17 20:22:11 +00:00
										 |  |  | 	} while(--count > 0); | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 	free(m); | 
					
						
							| 
									
										
										
										
											2004-04-27 11:42:53 +00:00
										 |  |  | 	return TRUE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | static macro_info_t * | 
					
						
							|  |  |  | word_read_macro_info(int fd, macro_info_t *macro_info) | 
					
						
							| 
									
										
										
										
											2004-04-27 11:42:53 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 	if(!read_uint16(fd, ¯o_info->count, FALSE)) { | 
					
						
							| 
									
										
										
										
											2004-05-05 10:32:03 +00:00
										 |  |  | 		cli_dbgmsg("read macro_info failed\n"); | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 		macro_info->count = 0; | 
					
						
							| 
									
										
										
										
											2004-04-27 11:42:53 +00:00
										 |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	cli_dbgmsg("macro count: %d\n", macro_info->count); | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 	if(macro_info->count == 0) | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	macro_info->entries = (macro_entry_t *)cli_malloc(sizeof(macro_entry_t) * macro_info->count); | 
					
						
							|  |  |  | 	if(macro_info->entries == NULL) { | 
					
						
							|  |  |  | 		macro_info->count = 0; | 
					
						
							| 
									
										
										
										
											2004-04-27 11:42:53 +00:00
										 |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 	if(!word_read_macro_entry(fd, macro_info)) { | 
					
						
							|  |  |  | 		free(macro_info->entries); | 
					
						
							|  |  |  | 		macro_info->count = 0; | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							| 
									
										
										
										
											2004-04-27 11:42:53 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	return macro_info; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | static int | 
					
						
							|  |  |  | word_skip_oxo3(int fd) | 
					
						
							| 
									
										
										
										
											2004-04-27 11:42:53 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	uint8_t count; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (cli_readn(fd, &count, 1) != 1) { | 
					
						
							|  |  |  | 		cli_dbgmsg("read oxo3 record1 failed\n"); | 
					
						
							|  |  |  | 		return FALSE; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	cli_dbgmsg("oxo3 records1: %d\n", count); | 
					
						
							| 
									
										
										
										
											2007-10-22 20:33:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 	if(!seekandread(fd, count * 14, SEEK_CUR, &count, 1)) { | 
					
						
							| 
									
										
										
										
											2004-05-05 10:32:03 +00:00
										 |  |  | 		cli_dbgmsg("read oxo3 record2 failed\n"); | 
					
						
							| 
									
										
										
										
											2004-04-27 11:42:53 +00:00
										 |  |  | 		return FALSE; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if(count == 0) { | 
					
						
							|  |  |  | 		uint8_t twobytes[2]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if(cli_readn(fd, twobytes, 2) != 2) { | 
					
						
							| 
									
										
										
										
											2004-05-05 10:32:03 +00:00
										 |  |  | 			cli_dbgmsg("read oxo3 failed\n"); | 
					
						
							| 
									
										
										
										
											2004-04-27 11:42:53 +00:00
										 |  |  | 			return FALSE; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 		if(twobytes[0] != 2) { | 
					
						
							|  |  |  | 			lseek(fd, -2, SEEK_CUR); | 
					
						
							| 
									
										
										
										
											2004-04-27 11:42:53 +00:00
										 |  |  | 			return TRUE; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 		count = twobytes[1]; | 
					
						
							| 
									
										
										
										
											2004-04-27 11:42:53 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2007-12-17 20:22:11 +00:00
										 |  |  | 	if(count > 0) | 
					
						
							| 
									
										
										
										
											2004-04-27 11:42:53 +00:00
										 |  |  | 		if (lseek(fd, (count*4)+1, SEEK_CUR) == -1) { | 
					
						
							| 
									
										
										
										
											2004-05-05 10:32:03 +00:00
										 |  |  | 			cli_dbgmsg("lseek oxo3 failed\n"); | 
					
						
							| 
									
										
										
										
											2004-04-27 11:42:53 +00:00
										 |  |  | 			return FALSE; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2007-12-17 20:22:11 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-04-27 11:42:53 +00:00
										 |  |  | 	cli_dbgmsg("oxo3 records2: %d\n", count); | 
					
						
							|  |  |  | 	return TRUE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-01 18:32:17 +00:00
										 |  |  | static int | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | word_skip_menu_info(int fd) | 
					
						
							| 
									
										
										
										
											2004-04-27 11:42:53 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2007-11-01 18:32:17 +00:00
										 |  |  | 	uint16_t count; | 
					
						
							| 
									
										
										
										
											2007-10-22 20:33:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 	if(!read_uint16(fd, &count, FALSE)) { | 
					
						
							| 
									
										
										
										
											2004-05-05 10:32:03 +00:00
										 |  |  | 		cli_dbgmsg("read menu_info failed\n"); | 
					
						
							| 
									
										
										
										
											2007-11-01 18:32:17 +00:00
										 |  |  | 		return FALSE; | 
					
						
							| 
									
										
										
										
											2004-04-27 11:42:53 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2007-11-01 18:32:17 +00:00
										 |  |  | 	cli_dbgmsg("menu_info count: %d\n", count); | 
					
						
							| 
									
										
										
										
											2004-04-27 11:42:53 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-01 18:32:17 +00:00
										 |  |  | 	if(count) | 
					
						
							|  |  |  | 		if(lseek(fd, count * 12, SEEK_CUR) == -1) | 
					
						
							|  |  |  | 			return FALSE; | 
					
						
							|  |  |  | 	return TRUE; | 
					
						
							| 
									
										
										
										
											2004-04-27 11:42:53 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-05 18:14:59 +00:00
										 |  |  | static int | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | word_skip_macro_extnames(int fd) | 
					
						
							| 
									
										
										
										
											2004-04-27 11:42:53 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 	int is_unicode, nbytes; | 
					
						
							| 
									
										
										
										
											2004-04-27 11:42:53 +00:00
										 |  |  | 	int16_t size; | 
					
						
							| 
									
										
										
										
											2007-10-22 20:33:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 	if(!read_uint16(fd, (uint16_t *)&size, FALSE)) { | 
					
						
							| 
									
										
										
										
											2004-04-27 11:42:53 +00:00
										 |  |  | 		cli_dbgmsg("read macro_extnames failed\n"); | 
					
						
							| 
									
										
										
										
											2007-11-05 18:14:59 +00:00
										 |  |  | 		return FALSE; | 
					
						
							| 
									
										
										
										
											2004-04-27 11:42:53 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	if (size == -1) { /* Unicode flag */ | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 		if(!read_uint16(fd, (uint16_t *)&size, FALSE)) { | 
					
						
							| 
									
										
										
										
											2004-05-05 10:32:03 +00:00
										 |  |  | 			cli_dbgmsg("read macro_extnames failed\n"); | 
					
						
							| 
									
										
										
										
											2007-11-05 18:14:59 +00:00
										 |  |  | 			return FALSE; | 
					
						
							| 
									
										
										
										
											2004-04-27 11:42:53 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2007-11-05 18:14:59 +00:00
										 |  |  | 		is_unicode = 1; | 
					
						
							|  |  |  | 	} else | 
					
						
							|  |  |  | 		is_unicode = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-04-27 11:42:53 +00:00
										 |  |  | 	cli_dbgmsg("ext names size: 0x%x\n", size); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 	nbytes = size; | 
					
						
							|  |  |  | 	while(nbytes > 0) { | 
					
						
							| 
									
										
										
										
											2007-11-05 18:14:59 +00:00
										 |  |  | 		uint8_t length; | 
					
						
							| 
									
										
										
										
											2007-11-05 18:48:55 +00:00
										 |  |  | 		off_t offset; | 
					
						
							| 
									
										
										
										
											2007-11-05 18:14:59 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		if (cli_readn(fd, &length, 1) != 1) { | 
					
						
							| 
									
										
										
										
											2004-05-12 14:25:21 +00:00
										 |  |  | 			cli_dbgmsg("read macro_extnames failed\n"); | 
					
						
							| 
									
										
										
										
											2007-11-05 18:14:59 +00:00
										 |  |  | 			return FALSE; | 
					
						
							| 
									
										
										
										
											2004-04-27 11:42:53 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2004-05-12 14:25:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-05 18:48:55 +00:00
										 |  |  | 		if(is_unicode) | 
					
						
							| 
									
										
										
										
											2007-11-06 17:11:12 +00:00
										 |  |  | 			offset = (off_t)length * 2 + 1; | 
					
						
							| 
									
										
										
										
											2007-11-05 18:48:55 +00:00
										 |  |  | 		else | 
					
						
							| 
									
										
										
										
											2007-11-06 17:11:12 +00:00
										 |  |  | 			offset = (off_t)length; | 
					
						
							| 
									
										
										
										
											2007-11-05 18:48:55 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		offset += sizeof(uint16_t);	/* numref */ | 
					
						
							|  |  |  | 		if(lseek(fd, offset, SEEK_CUR) == -1) { | 
					
						
							|  |  |  | 			cli_dbgmsg("read macro_extnames failed to seek\n"); | 
					
						
							| 
									
										
										
										
											2007-11-05 18:14:59 +00:00
										 |  |  | 			return FALSE; | 
					
						
							| 
									
										
										
										
											2007-10-22 20:33:20 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 		nbytes -= size; | 
					
						
							| 
									
										
										
										
											2004-04-27 11:42:53 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2007-11-05 18:14:59 +00:00
										 |  |  | 	return TRUE; | 
					
						
							| 
									
										
										
										
											2004-04-27 11:42:53 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-06 17:11:12 +00:00
										 |  |  | static int | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | word_skip_macro_intnames(int fd) | 
					
						
							| 
									
										
										
										
											2004-04-27 11:42:53 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2007-12-17 20:22:11 +00:00
										 |  |  | 	uint16_t count; | 
					
						
							| 
									
										
										
										
											2007-10-22 20:33:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 	if(!read_uint16(fd, &count, FALSE)) { | 
					
						
							| 
									
										
										
										
											2004-05-05 10:32:03 +00:00
										 |  |  | 		cli_dbgmsg("read macro_intnames failed\n"); | 
					
						
							| 
									
										
										
										
											2007-11-06 17:11:12 +00:00
										 |  |  | 		return FALSE; | 
					
						
							| 
									
										
										
										
											2004-04-27 11:42:53 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 	cli_dbgmsg("int names count: %u\n", (unsigned int)count); | 
					
						
							| 
									
										
										
										
											2007-10-22 20:33:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-17 20:22:11 +00:00
										 |  |  | 	while(count-- > 0) { | 
					
						
							| 
									
										
										
										
											2007-11-06 17:11:12 +00:00
										 |  |  | 		uint8_t length; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/* id */ | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 		if(!seekandread(fd, sizeof(uint16_t), SEEK_CUR, &length, sizeof(uint8_t))) { | 
					
						
							| 
									
										
										
										
											2007-11-06 17:11:12 +00:00
										 |  |  | 			cli_dbgmsg("skip_macro_intnames failed\n"); | 
					
						
							|  |  |  | 			return FALSE; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2007-10-22 20:33:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-06 17:11:12 +00:00
										 |  |  | 		/* Internal name, plus one byte of unknown data */ | 
					
						
							|  |  |  | 		if(lseek(fd, length + 1, SEEK_CUR) == -1) { | 
					
						
							|  |  |  | 			cli_dbgmsg("skip_macro_intnames failed\n"); | 
					
						
							|  |  |  | 			return FALSE; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2004-04-27 11:42:53 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2007-11-06 17:11:12 +00:00
										 |  |  | 	return TRUE; | 
					
						
							| 
									
										
										
										
											2004-04-27 11:42:53 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-17 20:22:11 +00:00
										 |  |  | vba_project_t * | 
					
						
							| 
									
										
										
										
											2007-12-18 14:32:47 +00:00
										 |  |  | cli_wm_readdir(const char *dir) | 
					
						
							| 
									
										
										
										
											2004-04-27 11:42:53 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2007-11-08 15:26:14 +00:00
										 |  |  | 	int fd, done; | 
					
						
							| 
									
										
										
										
											2004-04-27 11:42:53 +00:00
										 |  |  | 	off_t end_offset; | 
					
						
							| 
									
										
										
										
											2007-11-01 18:32:17 +00:00
										 |  |  | 	unsigned char info_id; | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 	macro_info_t macro_info; | 
					
						
							| 
									
										
										
										
											2007-11-05 18:14:59 +00:00
										 |  |  | 	vba_project_t *vba_project; | 
					
						
							|  |  |  | 	mso_fib_t fib; | 
					
						
							| 
									
										
										
										
											2007-11-01 18:32:17 +00:00
										 |  |  | 	char fullname[NAME_MAX + 1]; | 
					
						
							| 
									
										
										
										
											2007-10-22 20:33:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-17 20:22:11 +00:00
										 |  |  | 	if(dir == NULL) | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-01 18:32:17 +00:00
										 |  |  | 	snprintf(fullname, sizeof(fullname) - 1, "%s/WordDocument", dir); | 
					
						
							| 
									
										
										
										
											2006-10-09 15:23:50 +00:00
										 |  |  | 	fd = open(fullname, O_RDONLY|O_BINARY); | 
					
						
							| 
									
										
										
										
											2004-04-27 11:42:53 +00:00
										 |  |  | 	if (fd == -1) { | 
					
						
							|  |  |  | 		cli_dbgmsg("Open WordDocument failed\n"); | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2007-10-22 20:33:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 	if (!word_read_fib(fd, &fib)) { | 
					
						
							| 
									
										
										
										
											2004-05-06 15:21:33 +00:00
										 |  |  | 		close(fd); | 
					
						
							| 
									
										
										
										
											2004-04-27 11:42:53 +00:00
										 |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2007-11-01 18:32:17 +00:00
										 |  |  | 	if(fib.macro_len == 0) { | 
					
						
							|  |  |  | 		cli_dbgmsg("No macros detected\n"); | 
					
						
							|  |  |  | 		/* Must be clean */ | 
					
						
							|  |  |  | 		close(fd); | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 	cli_dbgmsg("macro offset: 0x%.4x\n", (int)fib.macro_offset); | 
					
						
							|  |  |  | 	cli_dbgmsg("macro len: 0x%.4x\n\n", (int)fib.macro_len); | 
					
						
							| 
									
										
										
										
											2007-10-22 20:33:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-01 18:32:17 +00:00
										 |  |  | 	/* Go one past the start to ignore start_id */ | 
					
						
							|  |  |  | 	if (lseek(fd, fib.macro_offset + 1, SEEK_SET) != (off_t)(fib.macro_offset + 1)) { | 
					
						
							| 
									
										
										
										
											2004-04-27 11:42:53 +00:00
										 |  |  | 		cli_dbgmsg("lseek macro_offset failed\n"); | 
					
						
							| 
									
										
										
										
											2004-05-06 15:21:33 +00:00
										 |  |  | 		close(fd); | 
					
						
							| 
									
										
										
										
											2004-04-27 11:42:53 +00:00
										 |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2007-10-22 20:33:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-04-27 11:42:53 +00:00
										 |  |  | 	end_offset = fib.macro_offset + fib.macro_len; | 
					
						
							| 
									
										
										
										
											2007-11-05 18:14:59 +00:00
										 |  |  | 	done = FALSE; | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 	memset(¯o_info, '\0', sizeof(macro_info)); | 
					
						
							| 
									
										
										
										
											2007-10-22 20:33:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-04-27 11:42:53 +00:00
										 |  |  | 	while ((lseek(fd, 0, SEEK_CUR) < end_offset) && !done) { | 
					
						
							|  |  |  | 		if (cli_readn(fd, &info_id, 1) != 1) { | 
					
						
							| 
									
										
										
										
											2004-05-05 10:32:03 +00:00
										 |  |  | 			cli_dbgmsg("read macro_info failed\n"); | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2004-04-27 11:42:53 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		switch (info_id) { | 
					
						
							|  |  |  | 			case 0x01: | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 				if(macro_info.count) | 
					
						
							|  |  |  | 					free(macro_info.entries); | 
					
						
							|  |  |  | 				word_read_macro_info(fd, ¯o_info); | 
					
						
							|  |  |  | 				done = TRUE; | 
					
						
							| 
									
										
										
										
											2004-04-27 11:42:53 +00:00
										 |  |  | 				break; | 
					
						
							|  |  |  | 			case 0x03: | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 				if(!word_skip_oxo3(fd)) | 
					
						
							| 
									
										
										
										
											2004-04-27 11:42:53 +00:00
										 |  |  | 					done = TRUE; | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			case 0x05: | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 				if(!word_skip_menu_info(fd)) | 
					
						
							| 
									
										
										
										
											2004-04-27 11:42:53 +00:00
										 |  |  | 					done = TRUE; | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			case 0x10: | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 				if(!word_skip_macro_extnames(fd)) | 
					
						
							| 
									
										
										
										
											2004-04-27 11:42:53 +00:00
										 |  |  | 					done = TRUE; | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			case 0x11: | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 				if(!word_skip_macro_intnames(fd)) | 
					
						
							| 
									
										
										
										
											2004-04-27 11:42:53 +00:00
										 |  |  | 					done = TRUE; | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			case 0x12: | 
					
						
							|  |  |  | 				/* No sure about these, always seems to
 | 
					
						
							|  |  |  | 				come after the macros though, so finish | 
					
						
							|  |  |  | 				*/ | 
					
						
							| 
									
										
										
										
											2007-11-01 18:32:17 +00:00
										 |  |  | 				done = TRUE; | 
					
						
							| 
									
										
										
										
											2004-04-27 11:42:53 +00:00
										 |  |  | 				break; | 
					
						
							|  |  |  | 			case 0x40: | 
					
						
							|  |  |  | 				/* end marker */ | 
					
						
							| 
									
										
										
										
											2007-11-01 18:32:17 +00:00
										 |  |  | 				done = TRUE; | 
					
						
							| 
									
										
										
										
											2004-04-27 11:42:53 +00:00
										 |  |  | 				break; | 
					
						
							|  |  |  | 			default: | 
					
						
							| 
									
										
										
										
											2007-11-05 18:14:59 +00:00
										 |  |  | 				cli_dbgmsg("unknown type: 0x%x\n", info_id); | 
					
						
							| 
									
										
										
										
											2007-11-01 18:32:17 +00:00
										 |  |  | 				done = TRUE; | 
					
						
							| 
									
										
										
										
											2004-04-27 11:42:53 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2007-10-22 20:33:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-05 18:14:59 +00:00
										 |  |  | 	close(fd); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 	if(macro_info.count == 0) | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	vba_project = create_vba_project(macro_info.count, dir); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if(vba_project) { | 
					
						
							|  |  |  | 		vba_project->length = (uint32_t *)cli_malloc(sizeof(uint32_t) * | 
					
						
							|  |  |  | 				macro_info.count); | 
					
						
							|  |  |  | 		vba_project->key = (unsigned char *)cli_malloc(sizeof(unsigned char) * | 
					
						
							|  |  |  | 				macro_info.count); | 
					
						
							|  |  |  | 		if((vba_project->length != NULL) && | 
					
						
							|  |  |  | 		   (vba_project->key != NULL)) { | 
					
						
							|  |  |  | 			int i; | 
					
						
							|  |  |  | 			const macro_entry_t *m = macro_info.entries; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			for(i = 0; i < macro_info.count; i++) { | 
					
						
							|  |  |  | 				vba_project->name[i] = cli_strdup("WordDocument"); | 
					
						
							|  |  |  | 				vba_project->offset[i] = m->offset; | 
					
						
							|  |  |  | 				vba_project->length[i] = m->len; | 
					
						
							|  |  |  | 				vba_project->key[i] = m->key; | 
					
						
							|  |  |  | 				m++; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} else { | 
					
						
							| 
									
										
										
										
											2004-04-27 11:42:53 +00:00
										 |  |  | 			free(vba_project->name); | 
					
						
							|  |  |  | 			free(vba_project->dir); | 
					
						
							|  |  |  | 			free(vba_project->offset); | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 			if(vba_project->length) | 
					
						
							|  |  |  | 				free(vba_project->length); | 
					
						
							|  |  |  | 			if(vba_project->key) | 
					
						
							|  |  |  | 				free(vba_project->key); | 
					
						
							| 
									
										
										
										
											2004-04-27 11:42:53 +00:00
										 |  |  | 			free(vba_project); | 
					
						
							|  |  |  | 			vba_project = NULL; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	free(macro_info.entries); | 
					
						
							| 
									
										
										
										
											2007-11-05 18:14:59 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-04-27 11:42:53 +00:00
										 |  |  | 	return vba_project; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | unsigned char * | 
					
						
							| 
									
										
										
										
											2007-12-18 14:32:47 +00:00
										 |  |  | cli_wm_decrypt_macro(int fd, off_t offset, uint32_t len, unsigned char key) | 
					
						
							| 
									
										
										
										
											2004-04-27 11:42:53 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	unsigned char *buff; | 
					
						
							| 
									
										
										
										
											2007-10-22 20:33:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-17 20:22:11 +00:00
										 |  |  | 	if(len == 0) | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if(fd < 0) | 
					
						
							| 
									
										
										
										
											2007-12-15 20:34:31 +00:00
										 |  |  | 		return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 	buff = (unsigned char *)cli_malloc(len); | 
					
						
							|  |  |  | 	if(buff == NULL) | 
					
						
							| 
									
										
										
										
											2004-04-27 11:42:53 +00:00
										 |  |  | 		return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 	if(!seekandread(fd, offset, SEEK_SET, buff, len)) { | 
					
						
							| 
									
										
										
										
											2004-04-27 11:42:53 +00:00
										 |  |  | 		free(buff); | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 	if(key) { | 
					
						
							|  |  |  | 		unsigned char *p; | 
					
						
							| 
									
										
										
										
											2007-12-17 20:22:11 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 		for(p = buff; p < &buff[len]; p++) | 
					
						
							|  |  |  | 			*p ^= key; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2004-04-27 11:42:53 +00:00
										 |  |  | 	return buff; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * Keep reading bytes until we reach a NUL. Returns 0 if none is found | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | static int | 
					
						
							|  |  |  | skip_past_nul(int fd) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	char ch; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	do | 
					
						
							|  |  |  | 		if(cli_readn(fd, &ch, 1) != 1) | 
					
						
							|  |  |  | 			return FALSE; | 
					
						
							|  |  |  | 	while(ch); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return TRUE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * Read 2 bytes as a 16-bit number, host byte order. Return success or fail | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | static int | 
					
						
							|  |  |  | read_uint16(int fd, uint16_t *u, int is_mac) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if(cli_readn(fd, u, sizeof(uint16_t)) != sizeof(uint16_t)) | 
					
						
							|  |  |  | 		return FALSE; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	*u = vba_endian_convert_16(*u, is_mac); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return TRUE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * Read 4 bytes as a 32-bit number, host byte order. Return success or fail | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | static int | 
					
						
							|  |  |  | read_uint32(int fd, uint32_t *u, int is_mac) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if(cli_readn(fd, u, sizeof(uint32_t)) != sizeof(uint32_t)) | 
					
						
							|  |  |  | 		return FALSE; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	*u = vba_endian_convert_32(*u, is_mac); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return TRUE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * Miss some bytes then read a bit | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | static int | 
					
						
							|  |  |  | seekandread(int fd, off_t offset, int whence, void *data, size_t len) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if(lseek(fd, offset, whence) == (off_t)-1) { | 
					
						
							|  |  |  | 		cli_dbgmsg("lseek failed\n"); | 
					
						
							|  |  |  | 		return FALSE; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return cli_readn(fd, data, (unsigned int)len) == (int)len; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * Create and initialise a vba_project structure | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | static vba_project_t * | 
					
						
							|  |  |  | create_vba_project(int record_count, const char *dir) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	vba_project_t *ret; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ret = (vba_project_t *) cli_malloc(sizeof(struct vba_project_tag)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if(ret == NULL) | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ret->name = (char **)cli_malloc(sizeof(char *) * record_count); | 
					
						
							|  |  |  | 	ret->dir = cli_strdup(dir); | 
					
						
							|  |  |  | 	ret->offset = (uint32_t *)cli_malloc (sizeof(uint32_t) * record_count); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if((ret->name == NULL) || (ret->dir == NULL) || (ret->offset == NULL)) { | 
					
						
							|  |  |  | 		if(ret->dir) | 
					
						
							|  |  |  | 			free(ret->dir); | 
					
						
							|  |  |  | 		if(ret->name) | 
					
						
							|  |  |  | 			free(ret->name); | 
					
						
							|  |  |  | 		if(ret->offset) | 
					
						
							|  |  |  | 			free(ret->offset); | 
					
						
							|  |  |  | 		free(ret); | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	ret->count = record_count; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return ret; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static uint32_t | 
					
						
							|  |  |  | sigtouint32(const unsigned char *fourbytes) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return (uint32_t)((*fourbytes++ << 24) | (*fourbytes++ << 16) | (*fourbytes++ << 8) | *fourbytes); | 
					
						
							|  |  |  | } |