| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2015-09-17 13:41:26 -04:00
										 |  |  |  *  Copyright (C) 2015 Cisco Systems, Inc. and/or its affiliates. All rights reserved. | 
					
						
							| 
									
										
										
										
											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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  | #ifdef HAVE_SYS_PARAM_H
 | 
					
						
							|  |  |  | #include <sys/param.h> /* for NAME_MAX */
 | 
					
						
							| 
									
										
										
										
											2006-07-25 15:09:45 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2004-08-22 10:37:32 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05: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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  | #ifdef HAVE_UNISTD_H
 | 
					
						
							| 
									
										
										
										
											2006-10-15 14:42:39 +00:00
										 |  |  | #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>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-21 15:00:59 -05:00
										 |  |  | /* Scheduled for rewrite in 0.94 (bb#804). Disabling for now */ | 
					
						
							| 
									
										
										
										
											2008-02-11 20:19:20 +00:00
										 |  |  | /* #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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  | static const char *blobGetFilename(const blob *b); | 
					
						
							| 
									
										
										
										
											2007-04-21 22:59:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  | blob * | 
					
						
							|  |  |  | blobCreate(void) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  | #ifdef CL_DEBUG
 | 
					
						
							|  |  |  |     blob *b = (blob *)cli_calloc(1, sizeof(blob)); | 
					
						
							|  |  |  |     if (b) | 
					
						
							|  |  |  |         b->magic = BLOBCLASS; | 
					
						
							|  |  |  |     cli_dbgmsg("blobCreate\n"); | 
					
						
							|  |  |  |     return b; | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  |     return (blob *)cli_calloc(1, sizeof(blob)); | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  | void blobDestroy(blob *b) | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  | #ifdef CL_DEBUG
 | 
					
						
							|  |  |  |     cli_dbgmsg("blobDestroy %d\n", b->magic); | 
					
						
							| 
									
										
										
										
											2003-08-30 19:20:04 +00:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  |     cli_dbgmsg("blobDestroy\n"); | 
					
						
							| 
									
										
										
										
											2003-08-30 19:20:04 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  |     assert(b != NULL); | 
					
						
							|  |  |  |     assert(b->magic == BLOBCLASS); | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  |     if (b->name) | 
					
						
							|  |  |  |         free(b->name); | 
					
						
							|  |  |  |     if (b->data) | 
					
						
							|  |  |  |         free(b->data); | 
					
						
							|  |  |  | #ifdef CL_DEBUG
 | 
					
						
							|  |  |  |     b->magic = INVALIDCLASS; | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  |     free(b); | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  | void blobArrayDestroy(blob *blobList[], int n) | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  |     assert(blobList != NULL); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     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) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  |     void *ret; | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  |     assert(b != NULL); | 
					
						
							|  |  |  |     assert(b->magic == BLOBCLASS); | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  |     if (!b->isClosed) | 
					
						
							|  |  |  |         blobClose(b); | 
					
						
							|  |  |  |     if (b->name) | 
					
						
							|  |  |  |         free(b->name); | 
					
						
							|  |  |  | #ifdef CL_DEBUG
 | 
					
						
							|  |  |  |     b->magic = INVALIDCLASS; | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  |     ret = (void *)b->data; | 
					
						
							|  |  |  |     free(b); | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  |     return ret; | 
					
						
							| 
									
										
										
										
											2007-12-13 16:18:18 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-08-22 15:10:32 +00:00
										 |  |  | /*ARGSUSED*/ | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  | void blobSetFilename(blob *b, const char *dir, const char *filename) | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  |     assert(b != NULL); | 
					
						
							|  |  |  |     assert(b->magic == BLOBCLASS); | 
					
						
							|  |  |  |     assert(filename != NULL); | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-10 18:11:49 -04:00
										 |  |  |     UNUSEDPARAM(dir); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  |     cli_dbgmsg("blobSetFilename: %s\n", filename); | 
					
						
							| 
									
										
										
										
											2004-09-06 08:34:47 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  |     if (b->name) | 
					
						
							|  |  |  |         free(b->name); | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  |     b->name = cli_strdup(filename); | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  |     if (b->name) | 
					
						
							|  |  |  |         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) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  |     assert(b != NULL); | 
					
						
							|  |  |  |     assert(b->magic == BLOBCLASS); | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  |     return b->name; | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-07 14:05:23 +00:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * Returns <0 for failure | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  | int blobAddData(blob *b, const unsigned char *data, size_t len) | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  | #if HAVE_CLI_GETPAGESIZE
 | 
					
						
							|  |  |  |     static int pagesize; | 
					
						
							|  |  |  |     int growth; | 
					
						
							| 
									
										
										
										
											2004-09-18 15:03:15 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  |     assert(b != NULL); | 
					
						
							|  |  |  |     assert(b->magic == BLOBCLASS); | 
					
						
							|  |  |  |     assert(data != NULL); | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  |     if (len == 0) | 
					
						
							|  |  |  |         return 0; | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  |     if (b->isClosed) { | 
					
						
							|  |  |  |         /*
 | 
					
						
							| 
									
										
										
										
											2004-02-15 08:49:05 +00:00
										 |  |  | 		 * Should be cli_dbgmsg, but I want to see them for now, | 
					
						
							|  |  |  | 		 * and cli_dbgmsg doesn't support debug levels | 
					
						
							|  |  |  | 		 */ | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  |         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 | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  | #if HAVE_CLI_GETPAGESIZE
 | 
					
						
							|  |  |  |     if (pagesize == 0) { | 
					
						
							|  |  |  |         pagesize = cli_getpagesize(); | 
					
						
							|  |  |  |         if (pagesize == 0) | 
					
						
							|  |  |  |             pagesize = 4096; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     growth = pagesize; | 
					
						
							|  |  |  |     if (len >= (size_t)pagesize) | 
					
						
							|  |  |  |         growth = ((len / pagesize) + 1) * pagesize; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /*cli_dbgmsg("blobGrow: b->size %lu, b->len %lu, len %lu, growth = %u\n",
 | 
					
						
							| 
									
										
										
										
											2006-07-01 16:21:03 +00:00
										 |  |  | 		b->size, b->len, len, growth);*/ | 
					
						
							| 
									
										
										
										
											2004-12-16 15:29:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  |     if (b->data == NULL) { | 
					
						
							|  |  |  |         assert(b->len == 0); | 
					
						
							|  |  |  |         assert(b->size == 0); | 
					
						
							| 
									
										
										
										
											2004-09-18 15:03:15 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  |         b->size = growth; | 
					
						
							|  |  |  |         b->data = cli_malloc(growth); | 
					
						
							|  |  |  |     } else if (b->size < b->len + (off_t)len) { | 
					
						
							|  |  |  |         unsigned char *p = cli_realloc(b->data, b->size + growth); | 
					
						
							| 
									
										
										
										
											2004-09-18 15:03:15 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  |         if (p == NULL) | 
					
						
							|  |  |  |             return -1; | 
					
						
							| 
									
										
										
										
											2004-09-18 15:03:15 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  |         b->size += growth; | 
					
						
							|  |  |  |         b->data = p; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2004-09-18 15:03:15 +00:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  |     if (b->data == NULL) { | 
					
						
							|  |  |  |         assert(b->len == 0); | 
					
						
							|  |  |  |         assert(b->size == 0); | 
					
						
							| 
									
										
										
										
											2004-03-25 22:42:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  |         b->size = (off_t)len * 4; | 
					
						
							|  |  |  |         b->data = cli_malloc(b->size); | 
					
						
							|  |  |  |     } else if (b->size < b->len + (off_t)len) { | 
					
						
							|  |  |  |         unsigned char *p = cli_realloc(b->data, b->size + (len * 4)); | 
					
						
							| 
									
										
										
										
											2004-08-01 08:22:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  |         if (p == NULL) | 
					
						
							|  |  |  |             return -1; | 
					
						
							| 
									
										
										
										
											2004-08-01 08:22:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  |         b->size += (off_t)len * 4; | 
					
						
							|  |  |  |         b->data = p; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2004-09-18 15:03:15 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  |     if (b->data) { | 
					
						
							|  |  |  |         memcpy(&b->data[b->len], data, len); | 
					
						
							|  |  |  |         b->len += (off_t)len; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     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) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  |     assert(b != NULL); | 
					
						
							|  |  |  |     assert(b->magic == BLOBCLASS); | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  |     if (b->len == 0) | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     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) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  |     assert(b != NULL); | 
					
						
							|  |  |  |     assert(b->magic == BLOBCLASS); | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  |     return b->len; | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2004-02-15 08:49:05 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  | void blobClose(blob *b) | 
					
						
							| 
									
										
										
										
											2004-02-15 08:49:05 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  |     assert(b != NULL); | 
					
						
							|  |  |  |     assert(b->magic == BLOBCLASS); | 
					
						
							| 
									
										
										
										
											2004-09-21 09:28:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  |     if (b->isClosed) { | 
					
						
							|  |  |  |         cli_warnmsg("Attempt to close a previously closed blob\n"); | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2004-09-18 15:03:15 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05: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 | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  |     if ((b->size - b->len) >= 64) { | 
					
						
							|  |  |  |         if (b->len == 0) { /* Not likely */ | 
					
						
							|  |  |  |             free(b->data); | 
					
						
							|  |  |  |             b->data = NULL; | 
					
						
							|  |  |  |             cli_dbgmsg("blobClose: recovered all %lu bytes\n", | 
					
						
							|  |  |  |                        (unsigned long)b->size); | 
					
						
							|  |  |  |             b->size = 0; | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             unsigned char *ptr = cli_realloc(b->data, b->len); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (ptr == NULL) | 
					
						
							|  |  |  |                 return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             cli_dbgmsg("blobClose: recovered %lu bytes from %lu\n", | 
					
						
							|  |  |  |                        (unsigned long)(b->size - b->len), | 
					
						
							|  |  |  |                        (unsigned long)b->size); | 
					
						
							|  |  |  |             b->size = b->len; | 
					
						
							|  |  |  |             b->data = ptr; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     b->isClosed = 1; | 
					
						
							| 
									
										
										
										
											2004-02-15 08:49:05 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * Returns 0 if the blobs are the same | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  | int blobcmp(const blob *b1, const blob *b2) | 
					
						
							| 
									
										
										
										
											2004-02-15 08:49:05 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  |     size_t s1, s2; | 
					
						
							| 
									
										
										
										
											2004-02-15 08:49:05 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  |     assert(b1 != NULL); | 
					
						
							|  |  |  |     assert(b2 != NULL); | 
					
						
							| 
									
										
										
										
											2004-02-15 08:49:05 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  |     if (b1 == b2) | 
					
						
							|  |  |  |         return 0; | 
					
						
							| 
									
										
										
										
											2004-02-15 08:49:05 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  |     s1 = blobGetDataSize(b1); | 
					
						
							|  |  |  |     s2 = blobGetDataSize(b2); | 
					
						
							| 
									
										
										
										
											2004-02-15 08:49:05 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  |     if (s1 != s2) | 
					
						
							|  |  |  |         return 1; | 
					
						
							| 
									
										
										
										
											2004-02-15 08:49:05 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  |     if ((s1 == 0) && (s2 == 0)) | 
					
						
							|  |  |  |         return 0; | 
					
						
							| 
									
										
										
										
											2004-09-18 15:03:15 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  |     return memcmp(blobGetData(b1), blobGetData(b2), s1); | 
					
						
							| 
									
										
										
										
											2004-02-15 08:49:05 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2004-03-25 22:42:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-07-01 03:51:03 +00:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * Return clamav return code | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  | int blobGrow(blob *b, size_t len) | 
					
						
							| 
									
										
										
										
											2004-03-25 22:42:00 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  |     assert(b != NULL); | 
					
						
							|  |  |  |     assert(b->magic == BLOBCLASS); | 
					
						
							| 
									
										
										
										
											2004-03-25 22:42:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  |     if (len == 0) | 
					
						
							|  |  |  |         return CL_SUCCESS; | 
					
						
							| 
									
										
										
										
											2004-03-25 22:42:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  |     if (b->isClosed) { | 
					
						
							|  |  |  |         /*
 | 
					
						
							| 
									
										
										
										
											2004-03-25 22:42:00 +00:00
										 |  |  | 		 * Should be cli_dbgmsg, but I want to see them for now, | 
					
						
							|  |  |  | 		 * and cli_dbgmsg doesn't support debug levels | 
					
						
							|  |  |  | 		 */ | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  |         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); | 
					
						
							|  |  |  |         if (b->data) | 
					
						
							|  |  |  |             b->size = (off_t)len; | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |         unsigned char *ptr = cli_realloc(b->data, b->size + len); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (ptr) { | 
					
						
							|  |  |  |             b->size += (off_t)len; | 
					
						
							|  |  |  |             b->data = ptr; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     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) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  | #ifdef CL_DEBUG
 | 
					
						
							|  |  |  |     fileblob *fb = (fileblob *)cli_calloc(1, sizeof(fileblob)); | 
					
						
							|  |  |  |     if (fb) | 
					
						
							|  |  |  |         fb->b.magic = BLOBCLASS; | 
					
						
							|  |  |  |     cli_dbgmsg("blobCreate\n"); | 
					
						
							|  |  |  |     return fb; | 
					
						
							| 
									
										
										
										
											2004-08-22 10:37:32 +00:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  |     return (fileblob *)cli_calloc(1, sizeof(fileblob)); | 
					
						
							| 
									
										
										
										
											2004-08-22 10:37:32 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-08-29 18:21:39 +00:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * Returns CL_CLEAN or CL_VIRUS. Destroys the fileblob and removes the file | 
					
						
							|  |  |  |  * if possible | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  | int fileblobScanAndDestroy(fileblob *fb) | 
					
						
							| 
									
										
										
										
											2007-08-29 18:21:39 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  |     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; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2007-08-29 18:21:39 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * Destroy the fileblob, and remove the file associated with it | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  | void fileblobDestructiveDestroy(fileblob *fb) | 
					
						
							| 
									
										
										
										
											2007-08-29 18:21:39 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  |     if (fb->fp && fb->fullname) { | 
					
						
							|  |  |  |         fclose(fb->fp); | 
					
						
							|  |  |  |         cli_dbgmsg("fileblobDestructiveDestroy: %s\n", fb->fullname); | 
					
						
							|  |  |  |         if (!fb->ctx || !fb->ctx->engine->keeptmp) | 
					
						
							|  |  |  |             cli_unlink(fb->fullname); | 
					
						
							|  |  |  |         free(fb->fullname); | 
					
						
							|  |  |  |         fb->fp       = NULL; | 
					
						
							|  |  |  |         fb->fullname = NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (fb->b.name) { | 
					
						
							|  |  |  |         free(fb->b.name); | 
					
						
							|  |  |  |         fb->b.name = NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     fileblobDestroy(fb); | 
					
						
							| 
									
										
										
										
											2007-08-29 18:21:39 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * Destroy the fileblob, and remove the file associated with it if that file is | 
					
						
							|  |  |  |  * empty | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  | void fileblobDestroy(fileblob *fb) | 
					
						
							| 
									
										
										
										
											2004-08-22 10:37:32 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  |     assert(fb != NULL); | 
					
						
							|  |  |  |     assert(fb->b.magic == BLOBCLASS); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (fb->b.name && fb->fp) { | 
					
						
							|  |  |  |         fclose(fb->fp); | 
					
						
							|  |  |  |         if (fb->fullname) { | 
					
						
							|  |  |  |             cli_dbgmsg("fileblobDestroy: %s\n", fb->fullname); | 
					
						
							|  |  |  |             if (!fb->isNotEmpty) { | 
					
						
							|  |  |  |                 cli_dbgmsg("fileblobDestroy: not saving empty file\n"); | 
					
						
							|  |  |  |                 cli_unlink(fb->fullname); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         free(fb->b.name); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         assert(fb->b.data == NULL); | 
					
						
							|  |  |  |     } else if (fb->b.data) { | 
					
						
							|  |  |  |         free(fb->b.data); | 
					
						
							|  |  |  |         if (fb->b.name) { | 
					
						
							|  |  |  |             cli_errmsg("fileblobDestroy: %s not saved: report to https://bugzilla.clamav.net\n", | 
					
						
							|  |  |  |                        (fb->fullname) ? fb->fullname : fb->b.name); | 
					
						
							|  |  |  |             free(fb->b.name); | 
					
						
							|  |  |  |         } else | 
					
						
							|  |  |  |             cli_errmsg("fileblobDestroy: file not saved (%lu bytes): report to https://bugzilla.clamav.net\n", | 
					
						
							|  |  |  |                        (unsigned long)fb->b.len); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (fb->fullname) | 
					
						
							|  |  |  |         free(fb->fullname); | 
					
						
							|  |  |  | #ifdef CL_DEBUG
 | 
					
						
							|  |  |  |     fb->b.magic = INVALIDCLASS; | 
					
						
							| 
									
										
										
										
											2005-03-16 14:47:26 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  |     free(fb); | 
					
						
							| 
									
										
										
										
											2004-08-22 10:37:32 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  | void fileblobPartialSet(fileblob *fb, const char *fullname, const char *arg) | 
					
						
							| 
									
										
										
										
											2008-07-30 13:54:34 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2014-07-10 18:11:49 -04:00
										 |  |  |     UNUSEDPARAM(arg); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  |     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) { | 
					
						
							|  |  |  |         cli_errmsg("fileblobSetFilename: fdopen failed\n"); | 
					
						
							|  |  |  |         close(fb->fd); | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     blobSetFilename(&fb->b, fb->ctx ? fb->ctx->engine->tmpdir : NULL, fullname); | 
					
						
							|  |  |  |     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); | 
					
						
							| 
									
										
										
										
											2008-07-30 13:54:34 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  | void fileblobSetFilename(fileblob *fb, const char *dir, const char *filename) | 
					
						
							| 
									
										
										
										
											2004-08-22 10:37:32 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  |     char *fullname; | 
					
						
							| 
									
										
										
										
											2004-08-22 10:37:32 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  |     if (fb->b.name) | 
					
						
							|  |  |  |         return; | 
					
						
							| 
									
										
										
										
											2004-08-22 10:37:32 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  |     assert(filename != NULL); | 
					
						
							|  |  |  |     assert(dir != NULL); | 
					
						
							| 
									
										
										
										
											2005-03-03 09:28:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  |     blobSetFilename(&fb->b, dir, filename); | 
					
						
							| 
									
										
										
										
											2004-08-22 10:37:32 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  |     /*
 | 
					
						
							| 
									
										
										
										
											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 | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  |     filename = blobGetFilename(&fb->b); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     assert(filename != NULL); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (cli_gentempfd(dir, &fullname, &fb->fd) != CL_SUCCESS) return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     cli_dbgmsg("fileblobSetFilename: file %s saved to %s\n", filename, fullname); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     fb->fp = fdopen(fb->fd, "wb"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (fb->fp == NULL) { | 
					
						
							|  |  |  |         cli_errmsg("fileblobSetFilename: fdopen failed\n"); | 
					
						
							|  |  |  |         close(fb->fd); | 
					
						
							|  |  |  |         free(fullname); | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     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 = fullname; | 
					
						
							| 
									
										
										
										
											2004-08-22 10:37:32 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  | int fileblobAddData(fileblob *fb, const unsigned char *data, size_t len) | 
					
						
							| 
									
										
										
										
											2004-08-22 10:37:32 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  |     if (len == 0) | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     assert(data != NULL); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (fb->fp) { | 
					
						
							|  |  |  | #if defined(MAX_SCAN_SIZE) && (MAX_SCAN_SIZE > 0)
 | 
					
						
							|  |  |  |         const cli_ctx *ctx = fb->ctx; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (fb->isInfected) /* pretend all was written */ | 
					
						
							|  |  |  |             return 0; | 
					
						
							|  |  |  |         if (ctx) { | 
					
						
							|  |  |  |             int do_scan = 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (cli_checklimits("fileblobAddData", ctx, fb->bytes_scanned, 0, 0) != CL_CLEAN) | 
					
						
							|  |  |  |                 do_scan = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             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; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 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)) { | 
					
						
							|  |  |  |                     cli_dbgmsg("fileblobAddData: found %s\n", cli_get_last_virus_str(ctx->virname)); | 
					
						
							|  |  |  |                     fb->isInfected = 1; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2006-12-13 13:52:39 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2006-05-03 09:36:40 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  |         if (fwrite(data, len, 1, fb->fp) != 1) { | 
					
						
							|  |  |  |             cli_errmsg("fileblobAddData: Can't write %lu bytes to temporary file %s\n", | 
					
						
							|  |  |  |                        (unsigned long)len, fb->b.name); | 
					
						
							|  |  |  |             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) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  |     return blobGetFilename(&(fb->b)); | 
					
						
							| 
									
										
										
										
											2004-08-22 10:37:32 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2004-09-06 08:34:47 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  | void fileblobSetCTX(fileblob *fb, cli_ctx *ctx) | 
					
						
							| 
									
										
										
										
											2006-05-03 15:41:44 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  |     fb->ctx = ctx; | 
					
						
							| 
									
										
										
										
											2006-05-03 15:41:44 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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 | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  | int fileblobScan(const fileblob *fb) | 
					
						
							| 
									
										
										
										
											2007-08-29 18:21:39 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  |     int rc; | 
					
						
							|  |  |  |     cli_ctx *ctx = fb->ctx; | 
					
						
							|  |  |  |     STATBUF sb; | 
					
						
							|  |  |  |     int virus_found = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (fb->isInfected) | 
					
						
							|  |  |  |         return CL_VIRUS; | 
					
						
							|  |  |  |     if (fb->fp == NULL || fb->fullname == NULL) { | 
					
						
							|  |  |  |         /* shouldn't happen, scan called before fileblobSetFilename */ | 
					
						
							|  |  |  |         cli_warnmsg("fileblobScan, fullname == NULL\n"); | 
					
						
							|  |  |  |         return CL_ENULLARG; /* there is no CL_UNKNOWN */ | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (fb->ctx == NULL) { | 
					
						
							|  |  |  |         /* fileblobSetCTX hasn't been called */ | 
					
						
							|  |  |  |         cli_dbgmsg("fileblobScan, ctx == NULL\n"); | 
					
						
							|  |  |  |         return CL_CLEAN; /* there is no CL_UNKNOWN */ | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     fflush(fb->fp); | 
					
						
							|  |  |  |     lseek(fb->fd, 0, SEEK_SET); | 
					
						
							|  |  |  |     FSTAT(fb->fd, &sb); | 
					
						
							|  |  |  |     if (cli_matchmeta(fb->ctx, fb->b.name, sb.st_size, sb.st_size, 0, 0, 0, NULL) == CL_VIRUS) { | 
					
						
							|  |  |  |         if (!SCAN_ALLMATCHES) | 
					
						
							|  |  |  |             return CL_VIRUS; | 
					
						
							|  |  |  |         virus_found = 1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     rc = cli_magic_scandesc(fb->fd, fb->fullname, fb->ctx); | 
					
						
							|  |  |  |     if (rc == CL_VIRUS || virus_found != 0) { | 
					
						
							|  |  |  |         cli_dbgmsg("%s is infected\n", fb->fullname); | 
					
						
							|  |  |  |         return CL_VIRUS; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     cli_dbgmsg("%s is clean\n", fb->fullname); | 
					
						
							|  |  |  |     return CL_BREAK; | 
					
						
							| 
									
										
										
										
											2007-08-29 18:21:39 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * Doesn't perform a full scan just lets the caller know if something suspicious has | 
					
						
							|  |  |  |  * been seen yet | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  | int fileblobInfected(const fileblob *fb) | 
					
						
							| 
									
										
										
										
											2006-05-03 15:41:44 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05: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 | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  | void sanitiseName(char *name) | 
					
						
							| 
									
										
										
										
											2007-04-02 17:49:01 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-12-03 12:40:13 -05:00
										 |  |  |     char c; | 
					
						
							|  |  |  |     while ((c = *name)) { | 
					
						
							|  |  |  |         if (c != '.' && c != '_' && (c > 'z' || c < '0' || (c > '9' && c < 'A') || (c > 'Z' && c < 'a'))) | 
					
						
							|  |  |  |             *name = '_'; | 
					
						
							|  |  |  |         name++; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2007-04-02 17:49:01 +00:00
										 |  |  | } |