| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2008-04-02 15:24:51 +00:00
										 |  |  |  *  Copyright (C) 2007-2008 Sourcefire, Inc. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  Authors: Nigel Horne | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  |  * | 
					
						
							|  |  |  |  *  This program is free software; you can redistribute it and/or modify | 
					
						
							| 
									
										
										
										
											2008-04-02 15:24:51 +00:00
										 |  |  |  *  it under the terms of the GNU General Public License version 2 as | 
					
						
							|  |  |  |  *  published by the Free Software Foundation. | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  |  * | 
					
						
							|  |  |  |  *  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. | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2008-04-02 15:24:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-02-12 22:26:08 +00:00
										 |  |  | static	char	const	rcsid[] = "$Id: blob.c,v 1.64 2007/02/12 22:25:14 njh Exp $"; | 
					
						
							| 
									
										
										
										
											2004-02-06 13:46:08 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #if HAVE_CONFIG_H
 | 
					
						
							|  |  |  | #include "clamav-config.h"
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-08-22 10:37:32 +00:00
										 |  |  | #include <stdio.h>
 | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  | #include <stdlib.h>
 | 
					
						
							|  |  |  | #include <string.h>
 | 
					
						
							| 
									
										
										
										
											2004-08-22 10:37:32 +00:00
										 |  |  | #include <errno.h>
 | 
					
						
							| 
									
										
										
										
											2004-08-30 11:37:47 +00:00
										 |  |  | #include <fcntl.h>
 | 
					
						
							| 
									
										
										
										
											2010-01-15 16:24:16 +01:00
										 |  |  | #include <sys/types.h>
 | 
					
						
							|  |  |  | #include <sys/stat.h>
 | 
					
						
							| 
									
										
										
										
											2004-08-22 10:37:32 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-08-27 09:54:47 +00:00
										 |  |  | #ifdef	HAVE_SYS_PARAM_H
 | 
					
						
							| 
									
										
										
										
											2004-10-01 13:50:47 +00:00
										 |  |  | #include <sys/param.h>	/* for NAME_MAX */
 | 
					
						
							| 
									
										
										
										
											2006-07-25 15:09:45 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2004-08-22 10:37:32 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-12-04 17:05:56 +00:00
										 |  |  | #ifdef	C_DARWIN
 | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  | #include <sys/types.h>
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2004-08-22 10:37:32 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-15 14:42:39 +00:00
										 |  |  | #ifdef	HAVE_UNISTD_H
 | 
					
						
							|  |  |  | #include <unistd.h>
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-05-03 09:36:40 +00:00
										 |  |  | #include "others.h"
 | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  | #include "mbox.h"
 | 
					
						
							| 
									
										
										
										
											2006-05-03 09:36:40 +00:00
										 |  |  | #include "matcher.h"
 | 
					
						
							| 
									
										
										
										
											2007-08-29 18:21:39 +00:00
										 |  |  | #include "scanners.h"
 | 
					
						
							| 
									
										
										
										
											2008-02-11 18:34:28 +00:00
										 |  |  | #include "filetypes.h"
 | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include <assert.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-11 20:19:20 +00:00
										 |  |  | /* Scehduled for rewite in 0.94 (bb#804). Disabling for now */ | 
					
						
							|  |  |  | /* #define	MAX_SCAN_SIZE	20*1024	/\* */ | 
					
						
							|  |  |  | /* 				 * The performance benefit of scanning */ | 
					
						
							|  |  |  | /* 				 * early disappears on medium and */ | 
					
						
							|  |  |  | /* 				 * large sized files */ | 
					
						
							|  |  |  | /* 				 *\/ */ | 
					
						
							| 
									
										
										
										
											2006-12-13 13:52:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-04-21 22:59:28 +00:00
										 |  |  | static	const	char	*blobGetFilename(const blob *b); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  | blob * | 
					
						
							|  |  |  | blobCreate(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | #ifdef	CL_DEBUG
 | 
					
						
							|  |  |  | 	blob *b = (blob *)cli_calloc(1, sizeof(blob)); | 
					
						
							| 
									
										
										
										
											2004-03-23 10:58:52 +00:00
										 |  |  | 	if(b) | 
					
						
							| 
									
										
										
										
											2005-02-16 22:25:53 +00:00
										 |  |  | 		b->magic = BLOBCLASS; | 
					
						
							| 
									
										
										
										
											2003-08-30 19:20:04 +00:00
										 |  |  | 	cli_dbgmsg("blobCreate\n"); | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  | 	return b; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 	return (blob *)cli_calloc(1, sizeof(blob)); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void | 
					
						
							|  |  |  | blobDestroy(blob *b) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2003-08-30 19:20:04 +00:00
										 |  |  | #ifdef	CL_DEBUG
 | 
					
						
							|  |  |  | 	cli_dbgmsg("blobDestroy %d\n", b->magic); | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 	cli_dbgmsg("blobDestroy\n"); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  | 	assert(b != NULL); | 
					
						
							| 
									
										
										
										
											2005-02-16 22:25:53 +00:00
										 |  |  | 	assert(b->magic == BLOBCLASS); | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if(b->name) | 
					
						
							|  |  |  | 		free(b->name); | 
					
						
							|  |  |  | 	if(b->data) | 
					
						
							|  |  |  | 		free(b->data); | 
					
						
							|  |  |  | #ifdef	CL_DEBUG
 | 
					
						
							| 
									
										
										
										
											2005-02-16 22:25:53 +00:00
										 |  |  | 	b->magic = INVALIDCLASS; | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 	free(b); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void | 
					
						
							|  |  |  | blobArrayDestroy(blob *blobList[], int n) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2004-09-18 15:03:15 +00:00
										 |  |  | 	assert(blobList != NULL); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-08-30 19:20:04 +00:00
										 |  |  | 	while(--n >= 0) { | 
					
						
							|  |  |  | 		cli_dbgmsg("blobArrayDestroy: %d\n", n); | 
					
						
							|  |  |  | 		if(blobList[n]) { | 
					
						
							|  |  |  | 			blobDestroy(blobList[n]); | 
					
						
							|  |  |  | 			blobList[n] = NULL; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * No longer needed to be growable, so turn into a normal memory area which | 
					
						
							|  |  |  |  * the caller must free. The passed blob is destroyed | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | void * | 
					
						
							|  |  |  | blobToMem(blob *b) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	void *ret; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	assert(b != NULL); | 
					
						
							|  |  |  | 	assert(b->magic == BLOBCLASS); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if(!b->isClosed) | 
					
						
							|  |  |  | 		blobClose(b); | 
					
						
							|  |  |  | 	if(b->name) | 
					
						
							|  |  |  | 		free(b->name); | 
					
						
							|  |  |  | #ifdef	CL_DEBUG
 | 
					
						
							|  |  |  | 	b->magic = INVALIDCLASS; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 	ret = (void *)b->data; | 
					
						
							|  |  |  | 	free(b); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return ret; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-08-22 15:10:32 +00:00
										 |  |  | /*ARGSUSED*/ | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  | void | 
					
						
							| 
									
										
										
										
											2004-08-22 15:10:32 +00:00
										 |  |  | blobSetFilename(blob *b, const char *dir, const char *filename) | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	assert(b != NULL); | 
					
						
							| 
									
										
										
										
											2005-02-16 22:25:53 +00:00
										 |  |  | 	assert(b->magic == BLOBCLASS); | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  | 	assert(filename != NULL); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-09-06 08:34:47 +00:00
										 |  |  | 	cli_dbgmsg("blobSetFilename: %s\n", filename); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  | 	if(b->name) | 
					
						
							|  |  |  | 		free(b->name); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-02-22 17:30:00 +00:00
										 |  |  | 	b->name = cli_strdup(filename); | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-09-06 08:34:47 +00:00
										 |  |  | 	if(b->name) | 
					
						
							| 
									
										
										
										
											2007-04-02 17:49:01 +00:00
										 |  |  | 		sanitiseName(b->name); | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-04-21 22:59:28 +00:00
										 |  |  | static const char * | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  | blobGetFilename(const blob *b) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	assert(b != NULL); | 
					
						
							| 
									
										
										
										
											2005-02-16 22:25:53 +00:00
										 |  |  | 	assert(b->magic == BLOBCLASS); | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-08-22 10:37:32 +00:00
										 |  |  | 	return b->name; | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-07 14:05:23 +00:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * Returns <0 for failure | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2005-04-04 13:52:46 +00:00
										 |  |  | int | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  | blobAddData(blob *b, const unsigned char *data, size_t len) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2009-07-16 13:22:28 +02:00
										 |  |  | #if	HAVE_CLI_GETPAGESIZE
 | 
					
						
							| 
									
										
										
										
											2004-12-16 15:29:51 +00:00
										 |  |  | 	static int pagesize; | 
					
						
							|  |  |  | 	int growth; | 
					
						
							| 
									
										
										
										
											2004-09-18 15:03:15 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  | 	assert(b != NULL); | 
					
						
							| 
									
										
										
										
											2005-02-16 22:25:53 +00:00
										 |  |  | 	assert(b->magic == BLOBCLASS); | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  | 	assert(data != NULL); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if(len == 0) | 
					
						
							| 
									
										
										
										
											2005-04-04 13:52:46 +00:00
										 |  |  | 		return 0; | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-02-15 08:49:05 +00:00
										 |  |  | 	if(b->isClosed) { | 
					
						
							|  |  |  | 		/*
 | 
					
						
							|  |  |  | 		 * Should be cli_dbgmsg, but I want to see them for now, | 
					
						
							|  |  |  | 		 * and cli_dbgmsg doesn't support debug levels | 
					
						
							|  |  |  | 		 */ | 
					
						
							|  |  |  | 		cli_warnmsg("Reopening closed blob\n"); | 
					
						
							|  |  |  | 		b->isClosed = 0; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2004-09-18 15:03:15 +00:00
										 |  |  | 	/*
 | 
					
						
							|  |  |  | 	 * The payoff here is between reducing the number of calls to | 
					
						
							|  |  |  | 	 * malloc/realloc and not overallocating memory. A lot of machines | 
					
						
							|  |  |  | 	 * are more tight with memory than one may imagine which is why | 
					
						
							|  |  |  | 	 * we don't just allocate a *huge* amount and be done with it. Closing | 
					
						
							|  |  |  | 	 * the blob helps because that reclaims memory. If you know the maximum | 
					
						
							|  |  |  | 	 * size of a blob before you start adding data, use blobGrow() that's | 
					
						
							|  |  |  | 	 * the most optimum | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2009-07-16 13:22:28 +02:00
										 |  |  | #if	HAVE_CLI_GETPAGESIZE
 | 
					
						
							| 
									
										
										
										
											2004-12-16 15:29:51 +00:00
										 |  |  | 	if(pagesize == 0) { | 
					
						
							| 
									
										
										
										
											2009-07-16 13:22:28 +02:00
										 |  |  | 		pagesize = cli_getpagesize(); | 
					
						
							| 
									
										
										
										
											2004-12-16 15:29:51 +00:00
										 |  |  | 		if(pagesize == 0) | 
					
						
							|  |  |  | 			pagesize = 4096; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	growth = pagesize; | 
					
						
							| 
									
										
										
										
											2005-03-18 08:34:35 +00:00
										 |  |  | 	if(len >= (size_t)pagesize) | 
					
						
							| 
									
										
										
										
											2004-12-16 15:29:51 +00:00
										 |  |  | 		growth = ((len / pagesize) + 1) * pagesize; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-01 16:21:03 +00:00
										 |  |  | 	/*cli_dbgmsg("blobGrow: b->size %lu, b->len %lu, len %lu, growth = %u\n",
 | 
					
						
							|  |  |  | 		b->size, b->len, len, growth);*/ | 
					
						
							| 
									
										
										
										
											2004-12-16 15:29:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-09-18 15:03:15 +00:00
										 |  |  | 	if(b->data == NULL) { | 
					
						
							|  |  |  | 		assert(b->len == 0); | 
					
						
							|  |  |  | 		assert(b->size == 0); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-12-16 15:29:51 +00:00
										 |  |  | 		b->size = growth; | 
					
						
							|  |  |  | 		b->data = cli_malloc(growth); | 
					
						
							| 
									
										
										
										
											2007-02-10 14:23:52 +00:00
										 |  |  | 	} else if(b->size < b->len + (off_t)len) { | 
					
						
							| 
									
										
										
										
											2004-12-16 15:29:51 +00:00
										 |  |  | 		unsigned char *p = cli_realloc(b->data, b->size + growth); | 
					
						
							| 
									
										
										
										
											2004-09-18 15:03:15 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		if(p == NULL) | 
					
						
							| 
									
										
										
										
											2005-04-04 13:52:46 +00:00
										 |  |  | 			return -1; | 
					
						
							| 
									
										
										
										
											2004-09-18 15:03:15 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-12-16 15:29:51 +00:00
										 |  |  | 		b->size += growth; | 
					
						
							| 
									
										
										
										
											2004-09-18 15:03:15 +00:00
										 |  |  | 		b->data = p; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  | 	if(b->data == NULL) { | 
					
						
							|  |  |  | 		assert(b->len == 0); | 
					
						
							| 
									
										
										
										
											2004-03-25 22:42:00 +00:00
										 |  |  | 		assert(b->size == 0); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-08-29 18:21:39 +00:00
										 |  |  | 		b->size = (off_t)len * 4; | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  | 		b->data = cli_malloc(b->size); | 
					
						
							| 
									
										
										
										
											2007-08-27 23:05:16 +00:00
										 |  |  | 	} else if(b->size < b->len + (off_t)len) { | 
					
						
							| 
									
										
										
										
											2004-08-01 08:22:58 +00:00
										 |  |  | 		unsigned char *p = cli_realloc(b->data, b->size + (len * 4)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if(p == NULL) | 
					
						
							| 
									
										
										
										
											2005-04-04 13:52:46 +00:00
										 |  |  | 			return -1; | 
					
						
							| 
									
										
										
										
											2004-08-01 08:22:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-08-29 18:21:39 +00:00
										 |  |  | 		b->size += (off_t)len * 4; | 
					
						
							| 
									
										
										
										
											2004-08-01 08:22:58 +00:00
										 |  |  | 		b->data = p; | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2004-09-18 15:03:15 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-03-23 10:58:52 +00:00
										 |  |  | 	if(b->data) { | 
					
						
							|  |  |  | 		memcpy(&b->data[b->len], data, len); | 
					
						
							| 
									
										
										
										
											2007-08-29 18:21:39 +00:00
										 |  |  | 		b->len += (off_t)len; | 
					
						
							| 
									
										
										
										
											2004-03-23 10:58:52 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2005-04-04 13:52:46 +00:00
										 |  |  | 	return 0; | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-01-14 10:09:59 +00:00
										 |  |  | unsigned char * | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  | blobGetData(const blob *b) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	assert(b != NULL); | 
					
						
							| 
									
										
										
										
											2005-02-16 22:25:53 +00:00
										 |  |  | 	assert(b->magic == BLOBCLASS); | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-01-19 05:30:50 +00:00
										 |  |  | 	if(b->len == 0) | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							| 
									
										
										
										
											2007-05-25 10:10:30 +00:00
										 |  |  | 	return b->data; | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-25 15:09:45 +00:00
										 |  |  | size_t | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  | blobGetDataSize(const blob *b) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	assert(b != NULL); | 
					
						
							| 
									
										
										
										
											2005-02-16 22:25:53 +00:00
										 |  |  | 	assert(b->magic == BLOBCLASS); | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-05-25 10:10:30 +00:00
										 |  |  | 	return b->len; | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2004-02-15 08:49:05 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | void | 
					
						
							|  |  |  | blobClose(blob *b) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2004-09-18 15:03:15 +00:00
										 |  |  | 	assert(b != NULL); | 
					
						
							| 
									
										
										
										
											2005-02-16 22:25:53 +00:00
										 |  |  | 	assert(b->magic == BLOBCLASS); | 
					
						
							| 
									
										
										
										
											2004-09-21 09:28:28 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if(b->isClosed) { | 
					
						
							| 
									
										
										
										
											2006-09-20 10:24:17 +00:00
										 |  |  | 		cli_warnmsg("Attempt to close a previously closed blob\n"); | 
					
						
							| 
									
										
										
										
											2004-09-21 09:28:28 +00:00
										 |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2004-09-18 15:03:15 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-06-16 08:07:39 +00:00
										 |  |  | 	/*
 | 
					
						
							|  |  |  | 	 * Nothing more is going to be added to this blob. If it'll save more | 
					
						
							|  |  |  | 	 * than a trivial amount (say 64 bytes) of memory, shrink the allocation | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	if((b->size - b->len) >= 64) { | 
					
						
							| 
									
										
										
										
											2004-09-18 15:03:15 +00:00
										 |  |  | 		if(b->len == 0) {	/* Not likely */ | 
					
						
							|  |  |  | 			free(b->data); | 
					
						
							|  |  |  | 			b->data = NULL; | 
					
						
							| 
									
										
										
										
											2007-02-10 14:23:52 +00:00
										 |  |  | 			cli_dbgmsg("blobClose: recovered all %lu bytes\n", | 
					
						
							| 
									
										
										
										
											2007-02-12 20:47:28 +00:00
										 |  |  | 				(unsigned long)b->size); | 
					
						
							| 
									
										
										
										
											2004-09-18 15:03:15 +00:00
										 |  |  | 			b->size = 0; | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			unsigned char *ptr = cli_realloc(b->data, b->len); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if(ptr == NULL) | 
					
						
							|  |  |  | 				return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-02-10 14:23:52 +00:00
										 |  |  | 			cli_dbgmsg("blobClose: recovered %lu bytes from %lu\n", | 
					
						
							| 
									
										
										
										
											2007-02-12 20:47:28 +00:00
										 |  |  | 				(unsigned long)(b->size - b->len), | 
					
						
							|  |  |  | 				(unsigned long)b->size); | 
					
						
							| 
									
										
										
										
											2004-09-18 15:03:15 +00:00
										 |  |  | 			b->size = b->len; | 
					
						
							|  |  |  | 			b->data = ptr; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2004-02-15 08:49:05 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2004-05-21 11:33:43 +00:00
										 |  |  | 	b->isClosed = 1; | 
					
						
							| 
									
										
										
										
											2004-02-15 08:49:05 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * Returns 0 if the blobs are the same | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | int | 
					
						
							|  |  |  | blobcmp(const blob *b1, const blob *b2) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2006-07-25 15:09:45 +00:00
										 |  |  | 	size_t s1, s2; | 
					
						
							| 
									
										
										
										
											2004-02-15 08:49:05 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	assert(b1 != NULL); | 
					
						
							|  |  |  | 	assert(b2 != NULL); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if(b1 == b2) | 
					
						
							|  |  |  | 		return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	s1 = blobGetDataSize(b1); | 
					
						
							|  |  |  | 	s2 = blobGetDataSize(b2); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if(s1 != s2) | 
					
						
							|  |  |  | 		return 1; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-09-18 15:03:15 +00:00
										 |  |  | 	if((s1 == 0) && (s2 == 0)) | 
					
						
							|  |  |  | 		return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-02-15 08:49:05 +00:00
										 |  |  | 	return memcmp(blobGetData(b1), blobGetData(b2), s1); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2004-03-25 22:42:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-01 03:51:03 +00:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * Return clamav return code | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | int | 
					
						
							| 
									
										
										
										
											2004-03-25 22:42:00 +00:00
										 |  |  | blobGrow(blob *b, size_t len) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	assert(b != NULL); | 
					
						
							| 
									
										
										
										
											2005-02-16 22:25:53 +00:00
										 |  |  | 	assert(b->magic == BLOBCLASS); | 
					
						
							| 
									
										
										
										
											2004-03-25 22:42:00 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if(len == 0) | 
					
						
							| 
									
										
										
										
											2006-07-01 03:51:03 +00:00
										 |  |  | 		return CL_SUCCESS; | 
					
						
							| 
									
										
										
										
											2004-03-25 22:42:00 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if(b->isClosed) { | 
					
						
							|  |  |  | 		/*
 | 
					
						
							|  |  |  | 		 * Should be cli_dbgmsg, but I want to see them for now, | 
					
						
							|  |  |  | 		 * and cli_dbgmsg doesn't support debug levels | 
					
						
							|  |  |  | 		 */ | 
					
						
							|  |  |  | 		cli_warnmsg("Growing closed blob\n"); | 
					
						
							|  |  |  | 		b->isClosed = 0; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if(b->data == NULL) { | 
					
						
							|  |  |  | 		assert(b->len == 0); | 
					
						
							|  |  |  | 		assert(b->size == 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		b->data = cli_malloc(len); | 
					
						
							| 
									
										
										
										
											2004-05-21 11:33:43 +00:00
										 |  |  | 		if(b->data) | 
					
						
							| 
									
										
										
										
											2007-08-29 18:21:39 +00:00
										 |  |  | 			b->size = (off_t)len; | 
					
						
							| 
									
										
										
										
											2004-03-25 22:42:00 +00:00
										 |  |  | 	} else { | 
					
						
							| 
									
										
										
										
											2004-05-21 11:33:43 +00:00
										 |  |  | 		unsigned char *ptr = cli_realloc(b->data, b->size + len); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if(ptr) { | 
					
						
							| 
									
										
										
										
											2007-08-29 18:21:39 +00:00
										 |  |  | 			b->size += (off_t)len; | 
					
						
							| 
									
										
										
										
											2004-05-21 11:33:43 +00:00
										 |  |  | 			b->data = ptr; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2004-03-25 22:42:00 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2006-07-01 03:51:03 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return (b->data) ? CL_SUCCESS : CL_EMEM; | 
					
						
							| 
									
										
										
										
											2004-03-25 22:42:00 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2004-08-22 10:37:32 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | fileblob * | 
					
						
							|  |  |  | fileblobCreate(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | #ifdef	CL_DEBUG
 | 
					
						
							|  |  |  | 	fileblob *fb = (fileblob *)cli_calloc(1, sizeof(fileblob)); | 
					
						
							|  |  |  | 	if(fb) | 
					
						
							| 
									
										
										
										
											2005-02-16 22:25:53 +00:00
										 |  |  | 		fb->b.magic = BLOBCLASS; | 
					
						
							| 
									
										
										
										
											2004-08-22 10:37:32 +00:00
										 |  |  | 	cli_dbgmsg("blobCreate\n"); | 
					
						
							|  |  |  | 	return fb; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 	return (fileblob *)cli_calloc(1, sizeof(fileblob)); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-08-29 18:21:39 +00:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * Returns CL_CLEAN or CL_VIRUS. Destroys the fileblob and removes the file | 
					
						
							|  |  |  |  * if possible | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | int | 
					
						
							|  |  |  | fileblobScanAndDestroy(fileblob *fb) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	switch(fileblobScan(fb)) { | 
					
						
							|  |  |  | 		case CL_VIRUS: | 
					
						
							|  |  |  | 			fileblobDestructiveDestroy(fb); | 
					
						
							|  |  |  | 			return CL_VIRUS; | 
					
						
							|  |  |  | 		case CL_BREAK: | 
					
						
							|  |  |  | 			fileblobDestructiveDestroy(fb); | 
					
						
							|  |  |  | 			return CL_CLEAN; | 
					
						
							|  |  |  | 		default: | 
					
						
							|  |  |  | 			fileblobDestroy(fb); | 
					
						
							|  |  |  | 			return CL_CLEAN; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * Destroy the fileblob, and remove the file associated with it | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | void | 
					
						
							|  |  |  | fileblobDestructiveDestroy(fileblob *fb) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if(fb->fp && fb->fullname) { | 
					
						
							|  |  |  | 		fclose(fb->fp); | 
					
						
							|  |  |  | 		cli_dbgmsg("fileblobDestructiveDestroy: %s\n", fb->fullname); | 
					
						
							| 
									
										
										
										
											2010-12-28 13:05:00 +01:00
										 |  |  | 		if(!fb->ctx || !fb->ctx->engine->keeptmp) | 
					
						
							|  |  |  | 			cli_unlink(fb->fullname); | 
					
						
							| 
									
										
										
										
											2007-08-29 18:21:39 +00:00
										 |  |  | 		free(fb->fullname); | 
					
						
							|  |  |  | 		fb->fp = NULL; | 
					
						
							|  |  |  | 		fb->fullname = NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if(fb->b.name) { | 
					
						
							|  |  |  | 		free(fb->b.name); | 
					
						
							|  |  |  | 		fb->b.name = NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	fileblobDestroy(fb); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * Destroy the fileblob, and remove the file associated with it if that file is | 
					
						
							|  |  |  |  * empty | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2004-08-22 10:37:32 +00:00
										 |  |  | void | 
					
						
							|  |  |  | fileblobDestroy(fileblob *fb) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	assert(fb != NULL); | 
					
						
							| 
									
										
										
										
											2005-03-16 14:47:26 +00:00
										 |  |  | 	assert(fb->b.magic == BLOBCLASS); | 
					
						
							| 
									
										
										
										
											2004-08-22 10:37:32 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-11-29 13:15:41 +00:00
										 |  |  | 	if(fb->b.name && fb->fp) { | 
					
						
							| 
									
										
										
										
											2005-03-16 14:47:26 +00:00
										 |  |  | 		fclose(fb->fp); | 
					
						
							| 
									
										
										
										
											2007-08-27 23:05:16 +00:00
										 |  |  | 		if(fb->fullname) { | 
					
						
							|  |  |  | 			cli_dbgmsg("fileblobDestroy: %s\n", fb->fullname); | 
					
						
							|  |  |  | 			if(!fb->isNotEmpty) { | 
					
						
							|  |  |  | 				cli_dbgmsg("fileblobDestroy: not saving empty file\n"); | 
					
						
							| 
									
										
										
										
											2008-04-02 15:53:10 +00:00
										 |  |  | 				cli_unlink(fb->fullname);  | 
					
						
							| 
									
										
										
										
											2007-08-27 23:05:16 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2004-09-18 15:03:15 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2004-08-22 10:37:32 +00:00
										 |  |  | 		free(fb->b.name); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		assert(fb->b.data == NULL); | 
					
						
							|  |  |  | 	} else if(fb->b.data) { | 
					
						
							|  |  |  | 		free(fb->b.data); | 
					
						
							| 
									
										
										
										
											2005-05-18 20:34:14 +00:00
										 |  |  | 		if(fb->b.name) { | 
					
						
							| 
									
										
										
										
											2007-09-06 12:22:16 +00:00
										 |  |  | 			cli_errmsg("fileblobDestroy: %s not saved: report to http://bugs.clamav.net\n", | 
					
						
							|  |  |  | 				(fb->fullname) ? fb->fullname : fb->b.name); | 
					
						
							| 
									
										
										
										
											2004-11-29 13:15:41 +00:00
										 |  |  | 			free(fb->b.name); | 
					
						
							| 
									
										
										
										
											2005-05-18 20:34:14 +00:00
										 |  |  | 		} else | 
					
						
							| 
									
										
										
										
											2007-02-12 20:47:28 +00:00
										 |  |  | 			cli_errmsg("fileblobDestroy: file not saved (%lu bytes): report to http://bugs.clamav.net\n", | 
					
						
							|  |  |  | 				(unsigned long)fb->b.len); | 
					
						
							| 
									
										
										
										
											2004-08-22 10:37:32 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2007-08-27 23:05:16 +00:00
										 |  |  | 	if(fb->fullname) | 
					
						
							|  |  |  | 		free(fb->fullname); | 
					
						
							| 
									
										
										
										
											2005-03-16 14:47:26 +00:00
										 |  |  | #ifdef	CL_DEBUG
 | 
					
						
							|  |  |  | 	fb->b.magic = INVALIDCLASS; | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2004-08-22 10:37:32 +00:00
										 |  |  | 	free(fb); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-07-30 13:54:34 +00:00
										 |  |  | void | 
					
						
							|  |  |  | fileblobPartialSet(fileblob *fb, const char *fullname, const char *arg) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if(fb->b.name) | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	assert(fullname != NULL); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	cli_dbgmsg("fileblobPartialSet: saving to %s\n", fullname); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	fb->fd = open(fullname, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY|O_EXCL, 0600); | 
					
						
							|  |  |  | 	if(fb->fd < 0) { | 
					
						
							|  |  |  | 		cli_errmsg("fileblobPartialSet: unable to create file: %s\n",fullname); | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	fb->fp = fdopen(fb->fd, "wb"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if(fb->fp == NULL) { | 
					
						
							| 
									
										
										
										
											2009-03-11 18:04:01 +00:00
										 |  |  | 		cli_errmsg("fileblobSetFilename: fdopen failed\n"); | 
					
						
							| 
									
										
										
										
											2008-07-30 13:54:34 +00:00
										 |  |  | 		close(fb->fd); | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2008-11-14 22:23:39 +00:00
										 |  |  | 	blobSetFilename(&fb->b, fb->ctx ? fb->ctx->engine->tmpdir : NULL, fullname); | 
					
						
							| 
									
										
										
										
											2008-07-30 13:54:34 +00:00
										 |  |  | 	if(fb->b.data) | 
					
						
							|  |  |  | 		if(fileblobAddData(fb, fb->b.data, fb->b.len) == 0) { | 
					
						
							|  |  |  | 			free(fb->b.data); | 
					
						
							|  |  |  | 			fb->b.data = NULL; | 
					
						
							|  |  |  | 			fb->b.len = fb->b.size = 0; | 
					
						
							|  |  |  | 			fb->isNotEmpty = 1; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	fb->fullname = cli_strdup(fullname); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-08-22 10:37:32 +00:00
										 |  |  | void | 
					
						
							|  |  |  | fileblobSetFilename(fileblob *fb, const char *dir, const char *filename) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2008-03-20 21:02:17 +00:00
										 |  |  | 	char *fullname; | 
					
						
							| 
									
										
										
										
											2004-08-22 10:37:32 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if(fb->b.name) | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-03-03 09:28:19 +00:00
										 |  |  | 	assert(filename != NULL); | 
					
						
							|  |  |  | 	assert(dir != NULL); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-08-22 15:10:32 +00:00
										 |  |  | 	blobSetFilename(&fb->b, dir, filename); | 
					
						
							| 
									
										
										
										
											2004-08-22 10:37:32 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/*
 | 
					
						
							|  |  |  | 	 * Reload the filename, it may be different from the one we've | 
					
						
							|  |  |  | 	 * asked for, e.g. '/'s taken out | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	filename = blobGetFilename(&fb->b); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-03-03 09:28:19 +00:00
										 |  |  | 	assert(filename != NULL); | 
					
						
							| 
									
										
										
										
											2008-03-20 21:02:17 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	if (cli_gentempfd(dir, &fullname, &fb->fd)!=CL_SUCCESS) return; | 
					
						
							| 
									
										
										
										
											2005-03-03 09:28:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-20 21:02:17 +00:00
										 |  |  | 	cli_dbgmsg("fileblobSetFilename: file %s saved to %s\n", filename, fullname); | 
					
						
							| 
									
										
										
										
											2004-08-22 10:37:32 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-20 21:02:17 +00:00
										 |  |  | 	fb->fp = fdopen(fb->fd, "wb"); | 
					
						
							| 
									
										
										
										
											2004-08-22 10:37:32 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if(fb->fp == NULL) { | 
					
						
							| 
									
										
										
										
											2009-03-11 18:04:01 +00:00
										 |  |  | 		cli_errmsg("fileblobSetFilename: fdopen failed\n"); | 
					
						
							| 
									
										
										
										
											2008-03-20 21:02:17 +00:00
										 |  |  | 		close(fb->fd); | 
					
						
							|  |  |  | 		free(fullname); | 
					
						
							| 
									
										
										
										
											2004-08-22 10:37:32 +00:00
										 |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2005-04-23 10:33:44 +00:00
										 |  |  | 	if(fb->b.data) | 
					
						
							|  |  |  | 		if(fileblobAddData(fb, fb->b.data, fb->b.len) == 0) { | 
					
						
							|  |  |  | 			free(fb->b.data); | 
					
						
							|  |  |  | 			fb->b.data = NULL; | 
					
						
							|  |  |  | 			fb->b.len = fb->b.size = 0; | 
					
						
							| 
									
										
										
										
											2007-08-27 23:05:16 +00:00
										 |  |  | 			fb->isNotEmpty = 1; | 
					
						
							| 
									
										
										
										
											2005-04-23 10:33:44 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2008-03-20 21:02:17 +00:00
										 |  |  | 	fb->fullname = fullname; | 
					
						
							| 
									
										
										
										
											2004-08-22 10:37:32 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-04-04 13:52:46 +00:00
										 |  |  | int | 
					
						
							| 
									
										
										
										
											2004-08-22 10:37:32 +00:00
										 |  |  | fileblobAddData(fileblob *fb, const unsigned char *data, size_t len) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if(len == 0) | 
					
						
							| 
									
										
										
										
											2005-04-04 13:52:46 +00:00
										 |  |  | 		return 0; | 
					
						
							| 
									
										
										
										
											2004-08-22 10:37:32 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-03-16 14:47:26 +00:00
										 |  |  | 	assert(data != NULL); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-08-22 10:37:32 +00:00
										 |  |  | 	if(fb->fp) { | 
					
						
							| 
									
										
										
										
											2006-12-13 13:52:39 +00:00
										 |  |  | #if	defined(MAX_SCAN_SIZE) && (MAX_SCAN_SIZE > 0)
 | 
					
						
							|  |  |  | 		const cli_ctx *ctx = fb->ctx; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-05-03 15:41:44 +00:00
										 |  |  | 		if(fb->isInfected)	/* pretend all was written */ | 
					
						
							|  |  |  | 			return 0; | 
					
						
							| 
									
										
										
										
											2006-12-13 13:52:39 +00:00
										 |  |  | 		if(ctx) { | 
					
						
							|  |  |  | 			int do_scan = 1; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-11 20:19:20 +00:00
										 |  |  | 			if(cli_checklimits("fileblobAddData", ctx, fb->bytes_scanned, 0, 0)!=CL_CLEAN) | 
					
						
							|  |  |  | 			        do_scan = 0; | 
					
						
							| 
									
										
										
										
											2006-12-13 13:52:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			if(fb->bytes_scanned > MAX_SCAN_SIZE) | 
					
						
							|  |  |  | 				do_scan = 0; | 
					
						
							|  |  |  | 			if(do_scan) { | 
					
						
							|  |  |  | 				if(ctx->scanned) | 
					
						
							|  |  |  | 					*ctx->scanned += (unsigned long)len / CL_COUNT_PRECISION; | 
					
						
							|  |  |  | 				fb->bytes_scanned += (unsigned long)len; | 
					
						
							| 
									
										
										
										
											2008-02-14 18:34:20 +00:00
										 |  |  | 				 | 
					
						
							| 
									
										
										
										
											2009-04-06 20:01:09 +00:00
										 |  |  | 				if((len > 5) && cli_updatelimits(ctx, len)==CL_CLEAN && (cli_scanbuff(data, (unsigned int)len, 0, ctx->virname, ctx->engine, CL_TYPE_BINARY_DATA, NULL) == CL_VIRUS)) { | 
					
						
							| 
									
										
										
										
											2006-12-13 13:52:39 +00:00
										 |  |  | 					cli_dbgmsg("fileblobAddData: found %s\n", *ctx->virname); | 
					
						
							|  |  |  | 					fb->isInfected = 1; | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2006-05-03 09:36:40 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2006-12-13 13:52:39 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2006-05-03 09:36:40 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-04-04 13:52:46 +00:00
										 |  |  | 		if(fwrite(data, len, 1, fb->fp) != 1) { | 
					
						
							| 
									
										
										
										
											2009-03-11 18:04:01 +00:00
										 |  |  | 			cli_errmsg("fileblobAddData: Can't write %lu bytes to temporary file %s\n", | 
					
						
							|  |  |  | 				(unsigned long)len, fb->b.name); | 
					
						
							| 
									
										
										
										
											2005-04-04 13:52:46 +00:00
										 |  |  | 			return -1; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		fb->isNotEmpty = 1; | 
					
						
							|  |  |  | 		return 0; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return blobAddData(&(fb->b), data, len); | 
					
						
							| 
									
										
										
										
											2004-08-22 10:37:32 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const char * | 
					
						
							|  |  |  | fileblobGetFilename(const fileblob *fb) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return blobGetFilename(&(fb->b)); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2004-09-06 08:34:47 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-05-03 15:41:44 +00:00
										 |  |  | void | 
					
						
							|  |  |  | fileblobSetCTX(fileblob *fb, cli_ctx *ctx) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	fb->ctx = ctx; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-08-29 18:21:39 +00:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * Performs a full scan on the fileblob, returning ClamAV status: | 
					
						
							|  |  |  |  *	CL_BREAK means clean | 
					
						
							|  |  |  |  *	CL_CLEAN means unknown | 
					
						
							|  |  |  |  *	CL_VIRUS means infected | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | int | 
					
						
							|  |  |  | fileblobScan(const fileblob *fb) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2008-03-20 21:02:17 +00:00
										 |  |  | 	int rc; | 
					
						
							| 
									
										
										
										
											2012-07-16 15:36:49 -04:00
										 |  |  | 	STATBUF sb; | 
					
						
							| 
									
										
										
										
											2007-08-29 18:21:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if(fb->isInfected) | 
					
						
							|  |  |  | 		return CL_VIRUS; | 
					
						
							| 
									
										
										
										
											2008-03-20 21:02:17 +00:00
										 |  |  | 	if(fb->fp == NULL || fb->fullname == NULL) { | 
					
						
							| 
									
										
										
										
											2007-08-29 18:21:39 +00:00
										 |  |  | 		/* shouldn't happen, scan called before fileblobSetFilename */ | 
					
						
							|  |  |  | 		cli_warnmsg("fileblobScan, fullname == NULL\n"); | 
					
						
							| 
									
										
										
										
											2007-09-06 12:22:16 +00:00
										 |  |  | 		return CL_ENULLARG;	/* there is no CL_UNKNOWN */ | 
					
						
							| 
									
										
										
										
											2007-08-29 18:21:39 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	if(fb->ctx == NULL) { | 
					
						
							|  |  |  | 		/* fileblobSetCTX hasn't been called */ | 
					
						
							|  |  |  | 		cli_dbgmsg("fileblobScan, ctx == NULL\n"); | 
					
						
							|  |  |  | 		return CL_CLEAN;	/* there is no CL_UNKNOWN */ | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-20 21:02:17 +00:00
										 |  |  | 	fflush(fb->fp); | 
					
						
							|  |  |  | 	lseek(fb->fd, 0, SEEK_SET); | 
					
						
							| 
									
										
										
										
											2012-07-16 15:36:49 -04:00
										 |  |  | 	FSTAT(fb->fd, &sb); | 
					
						
							| 
									
										
										
										
											2010-01-15 16:24:16 +01:00
										 |  |  | 	if(cli_matchmeta(fb->ctx, fb->b.name, sb.st_size, sb.st_size, 0, 0, 0, NULL) == CL_VIRUS) | 
					
						
							|  |  |  | 	    return CL_VIRUS; | 
					
						
							| 
									
										
										
										
											2008-02-11 18:34:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-30 19:46:26 +02:00
										 |  |  | 	rc = cli_magic_scandesc(fb->fd, fb->ctx); | 
					
						
							| 
									
										
										
										
											2007-08-29 18:21:39 +00:00
										 |  |  | 	if(rc == CL_VIRUS) { | 
					
						
							|  |  |  | 		cli_dbgmsg("%s is infected\n", fb->fullname); | 
					
						
							|  |  |  | 		return CL_VIRUS; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	cli_dbgmsg("%s is clean\n", fb->fullname); | 
					
						
							|  |  |  | 	return CL_BREAK; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * Doesn't perform a full scan just lets the caller know if something suspicious has | 
					
						
							|  |  |  |  * been seen yet | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2006-05-03 15:41:44 +00:00
										 |  |  | int | 
					
						
							| 
									
										
										
										
											2007-08-29 18:21:39 +00:00
										 |  |  | fileblobInfected(const fileblob *fb) | 
					
						
							| 
									
										
										
										
											2006-05-03 15:41:44 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2007-08-29 18:21:39 +00:00
										 |  |  | 	return fb->isInfected; | 
					
						
							| 
									
										
										
										
											2006-05-03 15:41:44 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2007-04-02 17:49:01 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * Different operating systems allow different characters in their filenames | 
					
						
							|  |  |  |  * FIXME: What does QNX want? There is no #ifdef C_QNX, but if there were | 
					
						
							|  |  |  |  * it may be best to treat it like MSDOS | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | void | 
					
						
							|  |  |  | sanitiseName(char *name) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2009-09-24 19:07:39 +02:00
										 |  |  | 	char c; | 
					
						
							|  |  |  | 	while((c = *name)) { | 
					
						
							|  |  |  | 		if(c!='.' && c!='_' && (c>'z' || c<'0' || (c>'9' && c<'A') || (c>'Z' && c<'a'))) | 
					
						
							| 
									
										
										
										
											2007-04-02 17:49:01 +00:00
										 |  |  | 			*name = '_'; | 
					
						
							|  |  |  | 		name++; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } |