2003-07-29 15:48:06 +00:00
/*
2010-01-20 22:10:56 +01:00
* Copyright ( C ) 2007 - 2010 Sourcefire , Inc .
2008-02-01 00:17:44 +00:00
*
2008-04-02 15:24:51 +00:00
* Authors : Tomasz Kojm
2003-07-29 15:48:06 +00:00
*
* This program is free software ; you can redistribute it and / or modify
2007-03-31 20:31:04 +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
*/
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
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# include <ctype.h>
2006-10-09 15:23:50 +00:00
# ifdef HAVE_UNISTD_H
2003-07-29 15:48:06 +00:00
# include <unistd.h>
2006-10-09 15:23:50 +00:00
# endif
2003-07-29 15:48:06 +00:00
# include <dirent.h>
# include <sys/types.h>
# include <sys/stat.h>
2006-10-09 15:23:50 +00:00
# ifdef HAVE_SYS_PARAM_H
2004-11-13 14:47:20 +00:00
# include <sys/param.h>
2006-10-09 15:23:50 +00:00
# endif
2003-07-29 15:48:06 +00:00
# include <fcntl.h>
2007-12-18 19:23:56 +00:00
# include <zlib.h>
2009-08-04 15:14:22 +02:00
# include <errno.h>
2003-07-29 15:48:06 +00:00
# include "clamav.h"
2003-10-26 06:01:03 +00:00
# include "cvd.h"
2006-10-09 15:23:50 +00:00
# ifdef HAVE_STRINGS_H
# include <strings.h>
# endif
2004-07-19 17:54:40 +00:00
# include "matcher-ac.h"
# include "matcher-bm.h"
2007-03-28 21:38:07 +00:00
# include "matcher.h"
2003-07-29 15:48:06 +00:00
# include "others.h"
# include "str.h"
2007-01-09 20:06:51 +00:00
# include "dconf.h"
2007-12-14 22:39:37 +00:00
# include "filetypes.h"
# include "filetypes_int.h"
2007-02-11 00:41:13 +00:00
# include "readdb.h"
2008-07-25 19:00:25 +00:00
# include "cltypes.h"
2009-02-16 16:29:44 +00:00
# include "default.h"
2009-09-28 19:33:59 +02:00
# include "md5.h"
2010-01-25 13:28:19 +01:00
# include "sha256.h"
# include "dsig.h"
2003-07-29 15:48:06 +00:00
2007-02-11 00:41:13 +00:00
# include "phishcheck.h"
2006-09-12 17:50:04 +00:00
# include "phish_whitelist.h"
# include "phish_domaincheck_db.h"
2006-10-07 11:00:46 +00:00
# include "regex_list.h"
2008-02-06 18:53:23 +00:00
# include "hashtab.h"
2006-09-12 17:50:04 +00:00
2004-10-20 20:20:20 +00:00
# if defined(HAVE_READDIR_R_3) || defined(HAVE_READDIR_R_2)
# include <limits.h>
2004-11-02 04:08:09 +00:00
# include <stddef.h>
2004-10-20 20:20:20 +00:00
# endif
2008-10-17 17:00:13 +00:00
# include "mpool.h"
2009-09-21 19:24:16 +03:00
# include "bytecode.h"
2009-10-02 17:33:11 +03:00
# include "bytecode_api.h"
2009-09-21 19:24:16 +03:00
# include "bytecode_priv.h"
2010-01-15 10:23:25 +02:00
# include "cache.h"
2006-04-07 19:22:21 +00:00
# ifdef CL_THREAD_SAFE
# include <pthread.h>
static pthread_mutex_t cli_ref_mutex = PTHREAD_MUTEX_INITIALIZER ;
# endif
2008-11-04 19:18:27 +00:00
char * cli_virname ( char * virname , unsigned int official )
2008-07-03 11:19:21 +00:00
{
char * newname , * pt ;
if ( ! virname )
return NULL ;
if ( ( pt = strstr ( virname , " (Clam) " ) ) )
2008-11-04 19:18:27 +00:00
* pt = ' \0 ' ;
2008-07-03 11:19:21 +00:00
2008-11-04 19:18:27 +00:00
if ( ! virname [ 0 ] ) {
2008-07-03 11:19:21 +00:00
cli_errmsg ( " cli_virname: Empty virus name \n " ) ;
return NULL ;
}
2008-11-04 19:18:27 +00:00
if ( official )
return cli_strdup ( virname ) ;
2008-07-03 11:19:21 +00:00
2008-11-04 19:18:27 +00:00
newname = ( char * ) cli_malloc ( strlen ( virname ) + 11 + 1 ) ;
if ( ! newname ) {
cli_errmsg ( " cli_virname: Can't allocate memory for newname \n " ) ;
return NULL ;
2008-07-03 11:19:21 +00:00
}
2008-11-04 19:18:27 +00:00
sprintf ( newname , " %s.UNOFFICIAL " , virname ) ;
return newname ;
2008-07-03 11:19:21 +00:00
}
2008-08-07 12:40:41 +00:00
int cli_parse_add ( struct cli_matcher * root , const char * virname , const char * hexsig , uint16_t rtype , uint16_t type , const char * offset , uint8_t target , const uint32_t * lsigid , unsigned int options )
2004-07-02 23:00:58 +00:00
{
2004-07-19 17:54:40 +00:00
struct cli_bm_patt * bm_new ;
2004-07-08 13:48:58 +00:00
char * pt , * hexcpy , * start , * n ;
2008-07-03 11:19:21 +00:00
int ret , asterisk = 0 ;
2009-08-14 14:38:13 +02:00
unsigned int i , j , hexlen , parts = 0 ;
2004-07-08 13:48:58 +00:00
int mindist = 0 , maxdist = 0 , error = 0 ;
2004-07-02 23:00:58 +00:00
2009-08-14 14:38:13 +02:00
hexlen = strlen ( hexsig ) ;
2010-02-08 13:45:03 +02:00
if ( hexsig [ 0 ] = = ' $ ' ) {
/* macro */
unsigned smin , smax , tid ;
2010-02-19 16:10:37 +01:00
struct cli_ac_patt * patt ;
2010-02-08 13:45:03 +02:00
if ( hexsig [ hexlen - 1 ] ! = ' $ ' ) {
cli_errmsg ( " cli_parseadd(): missing terminator $ \n " ) ;
return CL_EMALFDB ;
}
if ( ! lsigid ) {
cli_errmsg ( " cli_parseadd(): macro signatures only valid inside logical signatures \n " ) ;
return CL_EMALFDB ;
}
if ( sscanf ( hexsig , " ${%u-%u}%u$ " ,
& smin , & smax , & tid ) ! = 3 ) {
cli_errmsg ( " cli_parseadd(): invalid macro signature format \n " ) ;
return CL_EMALFDB ;
}
if ( tid > = 32 ) {
cli_errmsg ( " cli_parseadd(): only 32 macro groups are supported \n " ) ;
return CL_EMALFDB ;
}
2010-02-19 16:10:37 +01:00
patt = mpool_calloc ( root - > mempool , 1 , sizeof ( * patt ) ) ;
if ( ! patt )
2010-02-08 13:45:03 +02:00
return CL_EMEM ;
/* this is not a pattern that will be matched by AC itself, rather it is a
* pattern checked by the lsig code */
2010-02-19 16:10:37 +01:00
patt - > ch_mindist [ 0 ] = smin ;
patt - > ch_maxdist [ 0 ] = smax ;
patt - > sigid = tid ;
patt - > length = root - > ac_mindepth ;
2010-02-08 13:45:03 +02:00
/* dummy */
2010-02-19 16:10:37 +01:00
patt - > pattern = mpool_calloc ( root - > mempool , patt - > length , sizeof ( * patt - > pattern ) ) ;
if ( patt - > pattern ) {
free ( patt ) ;
2010-02-13 18:13:39 +02:00
return CL_EMEM ;
}
2010-02-19 16:10:37 +01:00
if ( ( ret = cli_ac_addpatt ( root , patt ) ) ) {
mpool_free ( root - > mempool , patt - > pattern ) ;
free ( patt ) ;
2010-02-08 13:45:03 +02:00
return ret ;
}
return CL_SUCCESS ;
}
2004-07-08 13:48:58 +00:00
if ( strchr ( hexsig , ' { ' ) ) {
2004-07-02 23:00:58 +00:00
2004-07-19 17:54:40 +00:00
root - > ac_partsigs + + ;
2004-07-08 13:48:58 +00:00
2007-01-31 18:13:17 +00:00
if ( ! ( hexcpy = cli_strdup ( hexsig ) ) )
2004-07-08 13:48:58 +00:00
return CL_EMEM ;
2009-08-14 14:38:13 +02:00
for ( i = 0 ; i < hexlen ; i + + )
2004-10-09 01:10:29 +00:00
if ( hexsig [ i ] = = ' { ' | | hexsig [ i ] = = ' * ' )
2004-07-08 13:48:58 +00:00
parts + + ;
if ( parts )
parts + + ;
start = pt = hexcpy ;
for ( i = 1 ; i < = parts ; i + + ) {
if ( i ! = parts ) {
2004-10-09 01:10:29 +00:00
for ( j = 0 ; j < strlen ( start ) ; j + + ) {
if ( start [ j ] = = ' { ' ) {
asterisk = 0 ;
pt = start + j ;
break ;
}
if ( start [ j ] = = ' * ' ) {
asterisk = 1 ;
pt = start + j ;
break ;
}
}
2004-07-08 13:48:58 +00:00
* pt + + = 0 ;
}
2008-08-25 14:07:18 +00:00
if ( ( ret = cli_ac_addsig ( root , virname , start , root - > ac_partsigs , parts , i , rtype , type , mindist , maxdist , offset , lsigid , options ) ) ) {
2004-10-09 01:10:29 +00:00
cli_errmsg ( " cli_parse_add(): Problem adding signature (1). \n " ) ;
2004-07-08 13:48:58 +00:00
error = 1 ;
break ;
}
if ( i = = parts )
break ;
2004-10-09 01:10:29 +00:00
mindist = maxdist = 0 ;
if ( asterisk ) {
start = pt ;
continue ;
}
2004-07-08 13:48:58 +00:00
if ( ! ( start = strchr ( pt , ' } ' ) ) ) {
error = 1 ;
break ;
}
* start + + = 0 ;
if ( ! pt ) {
error = 1 ;
break ;
}
if ( ! strchr ( pt , ' - ' ) ) {
2008-01-30 20:04:02 +00:00
if ( ! cli_isnumber ( pt ) | | ( mindist = maxdist = atoi ( pt ) ) < 0 ) {
2004-07-08 13:48:58 +00:00
error = 1 ;
break ;
}
} else {
2004-09-14 01:33:32 +00:00
if ( ( n = cli_strtok ( pt , 0 , " - " ) ) ) {
2008-01-30 20:04:02 +00:00
if ( ! cli_isnumber ( n ) | | ( mindist = atoi ( n ) ) < 0 ) {
2004-07-08 13:48:58 +00:00
error = 1 ;
free ( n ) ;
break ;
}
free ( n ) ;
}
2004-09-14 01:33:32 +00:00
if ( ( n = cli_strtok ( pt , 1 , " - " ) ) ) {
2008-01-30 20:04:02 +00:00
if ( ! cli_isnumber ( n ) | | ( maxdist = atoi ( n ) ) < 0 ) {
2004-07-08 13:48:58 +00:00
error = 1 ;
free ( n ) ;
break ;
}
free ( n ) ;
}
2008-01-30 20:04:02 +00:00
if ( ( n = cli_strtok ( pt , 2 , " - " ) ) ) { /* strict check */
error = 1 ;
free ( n ) ;
2008-01-30 20:06:39 +00:00
break ;
2008-01-30 20:04:02 +00:00
}
2004-07-08 13:48:58 +00:00
}
}
free ( hexcpy ) ;
if ( error )
return CL_EMALFDB ;
} else if ( strchr ( hexsig , ' * ' ) ) {
2004-07-19 17:54:40 +00:00
root - > ac_partsigs + + ;
2004-07-02 23:00:58 +00:00
2009-08-14 14:38:13 +02:00
for ( i = 0 ; i < hexlen ; i + + )
2004-07-02 23:00:58 +00:00
if ( hexsig [ i ] = = ' * ' )
parts + + ;
2004-07-19 17:54:40 +00:00
if ( parts )
2004-07-02 23:00:58 +00:00
parts + + ;
for ( i = 1 ; i < = parts ; i + + ) {
if ( ( pt = cli_strtok ( hexsig , i - 1 , " * " ) ) = = NULL ) {
2006-07-28 17:51:14 +00:00
cli_errmsg ( " Can't extract part %d of partial signature. \n " , i ) ;
2004-07-02 23:00:58 +00:00
return CL_EMALFDB ;
}
2008-08-25 14:07:18 +00:00
if ( ( ret = cli_ac_addsig ( root , virname , pt , root - > ac_partsigs , parts , i , rtype , type , 0 , 0 , offset , lsigid , options ) ) ) {
2004-10-09 01:10:29 +00:00
cli_errmsg ( " cli_parse_add(): Problem adding signature (2). \n " ) ;
2004-07-02 23:00:58 +00:00
free ( pt ) ;
return ret ;
}
free ( pt ) ;
}
2010-02-08 13:45:03 +02:00
} else if ( root - > ac_only | | type | | lsigid | | strpbrk ( hexsig , " ?([ " ) | | ( root - > bm_offmode & & ( ! strcmp ( offset , " * " ) | | strchr ( offset , ' , ' ) ) ) | | strstr ( offset , " VI " ) | | strchr ( offset , ' $ ' ) ) {
2008-08-25 14:07:18 +00:00
if ( ( ret = cli_ac_addsig ( root , virname , hexsig , 0 , 0 , 0 , rtype , type , 0 , 0 , offset , lsigid , options ) ) ) {
2004-10-09 01:10:29 +00:00
cli_errmsg ( " cli_parse_add(): Problem adding signature (3). \n " ) ;
2004-07-19 17:54:40 +00:00
return ret ;
}
} else {
2009-01-26 19:47:02 +00:00
bm_new = ( struct cli_bm_patt * ) mpool_calloc ( root - > mempool , 1 , sizeof ( struct cli_bm_patt ) ) ;
2004-07-19 17:54:40 +00:00
if ( ! bm_new )
return CL_EMEM ;
2009-01-26 19:47:02 +00:00
bm_new - > pattern = ( unsigned char * ) cli_mpool_hex2str ( root - > mempool , hexsig ) ;
2008-10-17 20:33:15 +00:00
if ( ! bm_new - > pattern ) {
2009-01-26 19:47:02 +00:00
mpool_free ( root - > mempool , bm_new ) ;
2004-07-19 17:54:40 +00:00
return CL_EMALFDB ;
2004-07-30 17:07:31 +00:00
}
2009-08-14 14:38:13 +02:00
bm_new - > length = hexlen / 2 ;
2004-07-19 17:54:40 +00:00
2010-01-12 16:16:08 +01:00
bm_new - > virname = cli_mpool_virname ( root - > mempool , virname , options & CL_DB_OFFICIAL ) ;
2008-07-03 11:19:21 +00:00
if ( ! bm_new - > virname ) {
2009-01-26 19:47:02 +00:00
mpool_free ( root - > mempool , bm_new - > pattern ) ;
mpool_free ( root - > mempool , bm_new ) ;
2004-07-19 17:54:40 +00:00
return CL_EMEM ;
}
2009-08-27 18:12:39 +03:00
if ( bm_new - > length > root - > maxpatlen ) {
2004-07-19 17:54:40 +00:00
root - > maxpatlen = bm_new - > length ;
2009-08-27 18:12:39 +03:00
}
2004-07-19 17:54:40 +00:00
2009-08-14 14:38:13 +02:00
if ( ( ret = cli_bm_addpatt ( root , bm_new , offset ) ) ) {
2004-10-09 01:10:29 +00:00
cli_errmsg ( " cli_parse_add(): Problem adding signature (4). \n " ) ;
2009-01-26 19:47:02 +00:00
mpool_free ( root - > mempool , bm_new - > pattern ) ;
mpool_free ( root - > mempool , bm_new - > virname ) ;
mpool_free ( root - > mempool , bm_new ) ;
2004-07-02 23:00:58 +00:00
return ret ;
}
}
2006-05-18 11:29:24 +00:00
return CL_SUCCESS ;
2004-07-02 23:00:58 +00:00
}
2003-07-29 15:48:06 +00:00
2009-12-09 23:32:34 +01:00
int cli_initroots ( struct cl_engine * engine , unsigned int options )
2005-09-23 02:23:36 +00:00
{
int i , ret ;
struct cli_matcher * root ;
2008-02-01 00:17:44 +00:00
for ( i = 0 ; i < CLI_MTARGETS ; i + + ) {
2005-09-23 02:23:36 +00:00
if ( ! engine - > root [ i ] ) {
cli_dbgmsg ( " Initializing engine->root[%d] \n " , i ) ;
2009-01-26 19:47:02 +00:00
root = engine - > root [ i ] = ( struct cli_matcher * ) mpool_calloc ( engine - > mempool , 1 , sizeof ( struct cli_matcher ) ) ;
2005-09-23 02:23:36 +00:00
if ( ! root ) {
2007-04-30 14:12:38 +00:00
cli_errmsg ( " cli_initroots: Can't allocate memory for cli_matcher \n " ) ;
2005-09-23 02:23:36 +00:00
return CL_EMEM ;
}
2009-08-14 14:38:13 +02:00
# ifdef USE_MPOOL
root - > mempool = engine - > mempool ;
# endif
root - > type = i ;
2008-11-13 19:06:42 +00:00
if ( cli_mtargets [ i ] . ac_only | | engine - > ac_only )
2005-12-12 21:05:26 +00:00
root - > ac_only = 1 ;
2005-09-23 02:23:36 +00:00
cli_dbgmsg ( " Initialising AC pattern matcher of root[%d] \n " , i ) ;
2010-02-15 15:01:37 +02:00
if ( ( ret = cli_ac_init ( root , engine - > ac_mindepth , engine - > ac_maxdepth , engine - > dconf - > other & OTHER_CONF_PREFILTERING ) ) ) {
2005-09-23 02:23:36 +00:00
/* no need to free previously allocated memory here */
2007-04-30 14:12:38 +00:00
cli_errmsg ( " cli_initroots: Can't initialise AC pattern matcher \n " ) ;
2007-04-28 18:40:59 +00:00
return ret ;
2005-09-23 02:23:36 +00:00
}
2005-12-12 21:05:26 +00:00
if ( ! root - > ac_only ) {
2007-04-30 14:12:38 +00:00
cli_dbgmsg ( " cli_initroots: Initializing BM tables of root[%d] \n " , i ) ;
2005-12-12 21:05:26 +00:00
if ( ( ret = cli_bm_init ( root ) ) ) {
2007-04-30 14:12:38 +00:00
cli_errmsg ( " cli_initroots: Can't initialise BM pattern matcher \n " ) ;
2005-12-12 21:05:26 +00:00
return ret ;
}
2005-09-23 02:23:36 +00:00
}
2004-07-19 17:54:40 +00:00
}
}
2009-09-01 19:44:42 +02:00
engine - > root [ 1 ] - > bm_offmode = 1 ; /* BM offset mode for PE files */
2006-05-18 11:29:24 +00:00
return CL_SUCCESS ;
2005-09-23 02:23:36 +00:00
}
2008-05-18 21:32:27 +00:00
char * cli_dbgets ( char * buff , unsigned int size , FILE * fs , struct cli_dbio * dbio )
2007-12-18 19:23:56 +00:00
{
2009-07-28 20:23:31 +02:00
if ( fs )
2007-12-18 19:23:56 +00:00
return fgets ( buff , size , fs ) ;
2009-07-28 20:23:31 +02:00
if ( dbio - > usebuf ) {
int bread ;
char * nl ;
while ( 1 ) {
if ( ! dbio - > bufpt ) {
if ( ! dbio - > size )
return NULL ;
if ( dbio - > gzs ) {
bread = gzread ( dbio - > gzs , dbio - > readpt , dbio - > readsize ) ;
if ( bread = = - 1 ) {
cli_errmsg ( " cli_dbgets: gzread() failed \n " ) ;
return NULL ;
}
} else {
bread = fread ( dbio - > readpt , 1 , dbio - > readsize , dbio - > fs ) ;
if ( ! bread & & ferror ( dbio - > fs ) ) {
cli_errmsg ( " cli_dbgets: gzread() failed \n " ) ;
return NULL ;
}
}
if ( ! bread )
return NULL ;
dbio - > readpt [ bread ] = 0 ;
dbio - > bufpt = dbio - > buf ;
dbio - > size - = bread ;
2010-01-20 22:10:56 +01:00
dbio - > bread + = bread ;
2010-01-25 13:28:19 +01:00
sha256_update ( & dbio - > sha256ctx , dbio - > readpt , bread ) ;
2009-07-28 20:23:31 +02:00
}
nl = strchr ( dbio - > bufpt , ' \n ' ) ;
if ( nl ) {
if ( nl - dbio - > bufpt > = size ) {
cli_errmsg ( " cli_dbgets: Line too long for provided buffer \n " ) ;
return NULL ;
}
strncpy ( buff , dbio - > bufpt , nl - dbio - > bufpt ) ;
buff [ nl - dbio - > bufpt ] = 0 ;
if ( nl < dbio - > buf + dbio - > bufsize ) {
dbio - > bufpt = + + nl ;
} else {
dbio - > bufpt = NULL ;
dbio - > readpt = dbio - > buf ;
dbio - > readsize = dbio - > size < dbio - > bufsize ? dbio - > size : dbio - > bufsize - 1 ;
}
return buff ;
} else {
unsigned int remain = dbio - > buf + dbio - > bufsize - 1 - dbio - > bufpt ;
if ( dbio - > bufpt = = dbio - > buf ) {
cli_errmsg ( " cli_dbgets: Invalid data or internal buffer too small \n " ) ;
return NULL ;
}
memmove ( dbio - > buf , dbio - > bufpt , remain ) ;
dbio - > readpt = dbio - > buf + remain ;
dbio - > readsize = dbio - > bufsize - remain ;
dbio - > readsize = dbio - > size < dbio - > bufsize - remain ? dbio - > size : dbio - > bufsize - remain - 1 ;
dbio - > bufpt = NULL ;
}
}
} else { /* use gzgets/fgets */
2007-12-18 19:23:56 +00:00
char * pt ;
unsigned int bs ;
2008-05-18 21:32:27 +00:00
if ( ! dbio - > size )
2007-12-18 19:23:56 +00:00
return NULL ;
2008-05-18 21:32:27 +00:00
bs = dbio - > size < size ? dbio - > size + 1 : size ;
if ( dbio - > gzs )
pt = gzgets ( dbio - > gzs , buff , bs ) ;
else
pt = fgets ( buff , bs , dbio - > fs ) ;
2010-01-20 22:10:56 +01:00
if ( ! pt ) {
2007-12-18 19:23:56 +00:00
cli_errmsg ( " cli_dbgets: Preliminary end of data \n " ) ;
2010-01-20 22:10:56 +01:00
return pt ;
}
bs = strlen ( buff ) ;
dbio - > size - = bs ;
dbio - > bread + = bs ;
2010-01-25 13:28:19 +01:00
sha256_update ( & dbio - > sha256ctx , buff , bs ) ;
2007-12-18 19:23:56 +00:00
return pt ;
}
}
2009-09-28 19:33:59 +02:00
static int cli_chkign ( const struct cli_matcher * ignored , const char * signame , const char * entry )
2008-02-08 19:32:45 +00:00
{
2009-09-28 19:33:59 +02:00
const char * md5_expected = NULL ;
cli_md5_ctx md5ctx ;
unsigned char digest [ 16 ] ;
2008-02-08 19:32:45 +00:00
2009-09-28 19:33:59 +02:00
if ( ! ignored | | ! signame | | ! entry )
2008-02-08 19:32:45 +00:00
return 0 ;
2010-01-12 16:16:08 +01:00
if ( cli_bm_scanbuff ( ( const unsigned char * ) signame , strlen ( signame ) , & md5_expected , NULL , ignored , 0 , NULL , NULL ) = = CL_VIRUS ) {
2009-09-28 19:33:59 +02:00
if ( md5_expected ) {
cli_md5_init ( & md5ctx ) ;
cli_md5_update ( & md5ctx , entry , strlen ( entry ) ) ;
cli_md5_final ( digest , & md5ctx ) ;
if ( memcmp ( digest , ( const unsigned char * ) md5_expected , 16 ) )
return 0 ;
2008-02-08 19:32:45 +00:00
}
2009-09-28 19:33:59 +02:00
cli_dbgmsg ( " Ignoring signature %s \n " , signame ) ;
return 1 ;
2008-02-08 19:32:45 +00:00
}
return 0 ;
}
2008-07-31 16:26:50 +00:00
static int cli_chkpua ( const char * signame , const char * pua_cats , unsigned int options )
{
char cat [ 32 ] , * pt ;
const char * sig ;
int ret ;
if ( strncmp ( signame , " PUA. " , 4 ) ) {
cli_dbgmsg ( " Skipping signature %s - no PUA prefix \n " , signame ) ;
return 1 ;
}
sig = signame + 3 ;
if ( ! ( pt = strchr ( sig + 1 , ' . ' ) ) ) {
cli_dbgmsg ( " Skipping signature %s - bad syntax \n " , signame ) ;
return 1 ;
}
2008-08-08 14:00:17 +00:00
if ( ( unsigned int ) ( pt - sig + 2 ) > sizeof ( cat ) ) {
2008-07-31 16:26:50 +00:00
cli_dbgmsg ( " Skipping signature %s - too long category name \n " , signame ) ;
return 1 ;
}
strncpy ( cat , sig , pt - signame + 1 ) ;
cat [ pt - sig + 1 ] = 0 ;
pt = strstr ( pua_cats , cat ) ;
if ( options & CL_DB_PUA_INCLUDE )
ret = pt ? 0 : 1 ;
else
ret = pt ? 1 : 0 ;
if ( ret )
cli_dbgmsg ( " Skipping PUA signature %s - excluded category \n " , signame ) ;
return ret ;
}
2008-11-11 21:23:34 +00:00
static int cli_loaddb ( FILE * fs , struct cl_engine * engine , unsigned int * signo , unsigned int options , struct cli_dbio * dbio , const char * dbname )
2005-09-23 02:23:36 +00:00
{
2010-01-12 16:16:08 +01:00
char buffer [ FILEBUFF ] , * buffer_cpy = NULL , * pt , * start ;
2008-02-08 19:32:45 +00:00
unsigned int line = 0 , sigs = 0 ;
int ret = 0 ;
2005-09-23 02:23:36 +00:00
struct cli_matcher * root ;
2008-11-11 21:23:34 +00:00
if ( ( ret = cli_initroots ( engine , options ) ) )
2005-09-23 02:23:36 +00:00
return ret ;
2008-11-11 21:23:34 +00:00
root = engine - > root [ 0 ] ;
2005-09-23 02:23:36 +00:00
2009-09-28 19:33:59 +02:00
if ( engine - > ignored )
if ( ! ( buffer_cpy = cli_malloc ( FILEBUFF ) ) )
return CL_EMEM ;
2008-05-18 21:32:27 +00:00
while ( cli_dbgets ( buffer , FILEBUFF , fs , dbio ) ) {
2004-07-13 03:30:49 +00:00
line + + ;
cli_chomp ( buffer ) ;
2009-09-28 19:33:59 +02:00
if ( engine - > ignored )
strcpy ( buffer_cpy , buffer ) ;
2004-07-13 03:30:49 +00:00
pt = strchr ( buffer , ' = ' ) ;
if ( ! pt ) {
cli_errmsg ( " Malformed pattern line %d \n " , line ) ;
ret = CL_EMALFDB ;
break ;
}
start = buffer ;
* pt + + = 0 ;
2004-02-01 01:18:57 +00:00
2009-09-28 19:33:59 +02:00
if ( engine - > ignored & & cli_chkign ( engine - > ignored , start , buffer_cpy ) )
2008-02-08 19:32:45 +00:00
continue ;
2004-07-13 03:30:49 +00:00
if ( * pt = = ' = ' ) continue ;
2004-02-01 01:18:57 +00:00
2009-08-14 14:38:13 +02:00
if ( ( ret = cli_parse_add ( root , start , pt , 0 , 0 , " * " , 0 , NULL , options ) ) ) {
2004-09-14 01:33:32 +00:00
ret = CL_EMALFDB ;
break ;
}
2008-02-08 19:32:45 +00:00
sigs + + ;
2004-09-14 01:33:32 +00:00
}
2009-09-28 19:33:59 +02:00
if ( engine - > ignored )
free ( buffer_cpy ) ;
2004-09-14 01:33:32 +00:00
if ( ! line ) {
cli_errmsg ( " Empty database file \n " ) ;
return CL_EMALFDB ;
}
if ( ret ) {
cli_errmsg ( " Problem parsing database at line %d \n " , line ) ;
return ret ;
}
if ( signo )
2008-02-08 19:32:45 +00:00
* signo + = sigs ;
2004-09-14 01:33:32 +00:00
2006-05-18 11:29:24 +00:00
return CL_SUCCESS ;
2004-09-14 01:33:32 +00:00
}
2009-12-11 00:52:16 +01:00
# define ICO_TOKENS 4
2009-12-07 19:10:34 +01:00
static int cli_loadidb ( FILE * fs , struct cl_engine * engine , unsigned int * signo , unsigned int options , struct cli_dbio * dbio )
2009-12-07 18:54:09 +01:00
{
const char * tokens [ ICO_TOKENS + 1 ] ;
2010-01-12 16:16:08 +01:00
char buffer [ FILEBUFF ] , * buffer_cpy = NULL ;
2009-12-07 19:10:34 +01:00
uint8_t * hash ;
2009-12-07 18:54:09 +01:00
int ret = CL_SUCCESS ;
2009-12-07 19:10:34 +01:00
unsigned int line = 0 , sigs = 0 , tokens_count , i , size , enginesize ;
2009-12-07 18:54:09 +01:00
struct icomtr * metric ;
2009-12-11 00:52:16 +01:00
struct icon_matcher * matcher ;
2009-12-07 18:54:09 +01:00
2009-12-11 00:52:16 +01:00
if ( ! ( matcher = ( struct icon_matcher * ) mpool_calloc ( engine - > mempool , sizeof ( * matcher ) , 1 ) ) )
return CL_EMEM ;
2009-12-07 18:54:09 +01:00
if ( engine - > ignored )
if ( ! ( buffer_cpy = cli_malloc ( FILEBUFF ) ) )
return CL_EMEM ;
while ( cli_dbgets ( buffer , FILEBUFF , fs , dbio ) ) {
line + + ;
2009-12-10 03:10:58 +01:00
if ( buffer [ 0 ] = = ' # ' )
continue ;
2009-12-07 18:54:09 +01:00
cli_chomp ( buffer ) ;
if ( engine - > ignored )
strcpy ( buffer_cpy , buffer ) ;
tokens_count = cli_strtokenize ( buffer , ' : ' , ICO_TOKENS + 1 , tokens ) ;
if ( tokens_count ! = ICO_TOKENS ) {
2009-12-11 23:04:18 +01:00
cli_errmsg ( " cli_loadidb: Malformed hash at line %u (wrong token count) \n " , line ) ;
2009-12-07 18:54:09 +01:00
ret = CL_EMALFDB ;
break ;
}
2009-12-11 00:52:16 +01:00
if ( strlen ( tokens [ 3 ] ) ! = 124 ) {
2009-12-11 23:04:18 +01:00
cli_errmsg ( " cli_loadidb: Malformed hash at line %u (wrong length) \n " , line ) ;
2009-12-07 18:54:09 +01:00
ret = CL_EMALFDB ;
break ;
}
if ( engine - > ignored & & cli_chkign ( engine - > ignored , tokens [ 0 ] , buffer_cpy ) )
continue ;
2009-12-11 00:52:16 +01:00
hash = ( uint8_t * ) tokens [ 3 ] ;
2009-12-07 20:06:07 +01:00
if ( cli_hexnibbles ( ( char * ) hash , 124 ) ) {
2009-12-07 18:54:09 +01:00
cli_errmsg ( " cli_loadidb: Malformed hash at line %u (bad chars) \n " , line ) ;
ret = CL_EMALFDB ;
break ;
}
size = ( hash [ 0 ] < < 4 ) + hash [ 1 ] ;
if ( size ! = 32 & & size ! = 24 & & size ! = 16 ) {
cli_errmsg ( " cli_loadidb: Malformed hash at line %u (bad size) \n " , line ) ;
ret = CL_EMALFDB ;
break ;
}
2009-12-07 19:10:34 +01:00
enginesize = ( size > > 3 ) - 2 ;
2009-12-07 18:54:09 +01:00
hash + = 2 ;
2009-12-11 00:52:16 +01:00
metric = ( struct icomtr * ) mpool_realloc ( engine - > mempool , matcher - > icons [ enginesize ] , sizeof ( struct icomtr ) * ( matcher - > icon_counts [ enginesize ] + 1 ) ) ;
2009-12-07 18:54:09 +01:00
if ( ! metric ) {
ret = CL_EMEM ;
break ;
}
2009-12-11 00:52:16 +01:00
matcher - > icons [ enginesize ] = metric ;
metric + = matcher - > icon_counts [ enginesize ] ;
matcher - > icon_counts [ enginesize ] + + ;
2009-12-07 18:54:09 +01:00
for ( i = 0 ; i < 3 ; i + + ) {
if ( ( metric - > color_avg [ i ] = ( hash [ 0 ] < < 8 ) | ( hash [ 1 ] < < 4 ) | hash [ 2 ] ) > 4072 )
break ;
if ( ( metric - > color_x [ i ] = ( hash [ 3 ] < < 4 ) | hash [ 4 ] ) > size - size / 8 )
break ;
if ( ( metric - > color_y [ i ] = ( hash [ 5 ] < < 4 ) | hash [ 6 ] ) > size - size / 8 )
break ;
hash + = 7 ;
}
if ( i ! = 3 ) {
cli_errmsg ( " cli_loadidb: Malformed hash at line %u (bad color data) \n " , line ) ;
ret = CL_EMALFDB ;
break ;
}
for ( i = 0 ; i < 3 ; i + + ) {
if ( ( metric - > gray_avg [ i ] = ( hash [ 0 ] < < 8 ) | ( hash [ 1 ] < < 4 ) | hash [ 2 ] ) > 4072 )
break ;
if ( ( metric - > gray_x [ i ] = ( hash [ 3 ] < < 4 ) | hash [ 4 ] ) > size - size / 8 )
break ;
if ( ( metric - > gray_y [ i ] = ( hash [ 5 ] < < 4 ) | hash [ 6 ] ) > size - size / 8 )
break ;
hash + = 7 ;
}
if ( i ! = 3 ) {
cli_errmsg ( " cli_loadidb: Malformed hash at line %u (bad gray data) \n " , line ) ;
ret = CL_EMALFDB ;
break ;
}
for ( i = 0 ; i < 3 ; i + + ) {
metric - > bright_avg [ i ] = ( hash [ 0 ] < < 4 ) | hash [ 1 ] ;
if ( ( metric - > bright_x [ i ] = ( hash [ 2 ] < < 4 ) | hash [ 3 ] ) > size - size / 8 )
break ;
2009-12-07 19:10:34 +01:00
if ( ( metric - > bright_y [ i ] = ( hash [ 4 ] < < 4 ) | hash [ 5 ] ) > size - size / 8 )
2009-12-07 18:54:09 +01:00
break ;
hash + = 6 ;
}
if ( i ! = 3 ) {
cli_errmsg ( " cli_loadidb: Malformed hash at line %u (bad bright data) \n " , line ) ;
ret = CL_EMALFDB ;
break ;
}
for ( i = 0 ; i < 3 ; i + + ) {
metric - > dark_avg [ i ] = ( hash [ 0 ] < < 4 ) | hash [ 1 ] ;
if ( ( metric - > dark_x [ i ] = ( hash [ 2 ] < < 4 ) | hash [ 3 ] ) > size - size / 8 )
break ;
2009-12-07 19:10:34 +01:00
if ( ( metric - > dark_y [ i ] = ( hash [ 4 ] < < 4 ) | hash [ 5 ] ) > size - size / 8 )
2009-12-07 18:54:09 +01:00
break ;
hash + = 6 ;
}
if ( i ! = 3 ) {
cli_errmsg ( " cli_loadidb: Malformed hash at line %u (bad dark data) \n " , line ) ;
ret = CL_EMALFDB ;
break ;
}
for ( i = 0 ; i < 3 ; i + + ) {
metric - > edge_avg [ i ] = ( hash [ 0 ] < < 4 ) | hash [ 1 ] ;
if ( ( metric - > edge_x [ i ] = ( hash [ 2 ] < < 4 ) | hash [ 3 ] ) > size - size / 8 )
break ;
2009-12-07 19:10:34 +01:00
if ( ( metric - > edge_y [ i ] = ( hash [ 4 ] < < 4 ) | hash [ 5 ] ) > size - size / 8 )
2009-12-07 18:54:09 +01:00
break ;
hash + = 6 ;
}
if ( i ! = 3 ) {
cli_errmsg ( " cli_loadidb: Malformed hash at line %u (bad edge data) \n " , line ) ;
ret = CL_EMALFDB ;
break ;
}
for ( i = 0 ; i < 3 ; i + + ) {
metric - > noedge_avg [ i ] = ( hash [ 0 ] < < 4 ) | hash [ 1 ] ;
if ( ( metric - > noedge_x [ i ] = ( hash [ 2 ] < < 4 ) | hash [ 3 ] ) > size - size / 8 )
break ;
2009-12-07 19:10:34 +01:00
if ( ( metric - > noedge_y [ i ] = ( hash [ 4 ] < < 4 ) | hash [ 5 ] ) > size - size / 8 )
2009-12-07 18:54:09 +01:00
break ;
hash + = 6 ;
}
if ( i ! = 3 ) {
cli_errmsg ( " cli_loadidb: Malformed hash at line %u (bad noedge data) \n " , line ) ;
ret = CL_EMALFDB ;
break ;
}
metric - > rsum = ( hash [ 0 ] < < 4 ) | hash [ 1 ] ;
metric - > gsum = ( hash [ 2 ] < < 4 ) | hash [ 3 ] ;
metric - > bsum = ( hash [ 4 ] < < 4 ) | hash [ 5 ] ;
metric - > ccount = ( hash [ 6 ] < < 4 ) | hash [ 7 ] ;
2009-12-08 17:34:14 +01:00
if ( metric - > rsum + metric - > gsum + metric - > bsum > 103 | | metric - > ccount > 100 ) {
2009-12-07 18:54:09 +01:00
cli_errmsg ( " cli_loadidb: Malformed hash at line %u (bad spread data) \n " , line ) ;
ret = CL_EMALFDB ;
break ;
}
if ( ! ( metric - > name = cli_mpool_strdup ( engine - > mempool , tokens [ 0 ] ) ) ) {
ret = CL_EMEM ;
break ;
}
2009-12-11 00:52:16 +01:00
for ( i = 0 ; i < matcher - > group_counts [ 0 ] ; i + + ) {
if ( ! strcmp ( tokens [ 1 ] , matcher - > group_names [ 0 ] [ i ] ) )
break ;
}
if ( i = = matcher - > group_counts [ 0 ] ) {
if ( ! ( matcher - > group_names [ 0 ] = mpool_realloc ( engine - > mempool , matcher - > group_names [ 0 ] , sizeof ( char * ) * ( i + 1 ) ) ) | |
! ( matcher - > group_names [ 0 ] [ i ] = cli_mpool_strdup ( engine - > mempool , tokens [ 1 ] ) ) ) {
ret = CL_EMEM ;
break ;
}
matcher - > group_counts [ 0 ] + + ;
}
metric - > group [ 0 ] = i ;
for ( i = 0 ; i < matcher - > group_counts [ 1 ] ; i + + ) {
if ( ! strcmp ( tokens [ 2 ] , matcher - > group_names [ 1 ] [ i ] ) )
break ;
}
if ( i = = matcher - > group_counts [ 1 ] ) {
if ( ! ( matcher - > group_names [ 1 ] = mpool_realloc ( engine - > mempool , matcher - > group_names [ 1 ] , sizeof ( char * ) * ( i + 1 ) ) ) | |
! ( matcher - > group_names [ 1 ] [ i ] = cli_mpool_strdup ( engine - > mempool , tokens [ 2 ] ) ) ) {
2009-12-11 23:04:18 +01:00
ret = CL_EMEM ;
2009-12-11 00:52:16 +01:00
break ;
}
matcher - > group_counts [ 1 ] + + ;
}
metric - > group [ 1 ] = i ;
2009-12-11 23:04:18 +01:00
if ( matcher - > group_counts [ 0 ] > 256 | | matcher - > group_counts [ 1 ] > 256 ) {
cli_errmsg ( " cli_loadidb: too many icon groups! \n " ) ;
ret = CL_EMALFDB ;
break ;
}
2009-12-11 00:52:16 +01:00
2009-12-07 18:54:09 +01:00
sigs + + ;
}
if ( engine - > ignored )
free ( buffer_cpy ) ;
if ( ! line ) {
2009-12-07 19:10:34 +01:00
cli_errmsg ( " cli_loadidb: Empty database file \n " ) ;
2009-12-07 18:54:09 +01:00
return CL_EMALFDB ;
}
if ( ret ) {
2009-12-07 19:10:34 +01:00
cli_errmsg ( " cli_loadidb: Problem parsing database at line %u \n " , line ) ;
2009-12-07 18:54:09 +01:00
return ret ;
}
if ( signo )
* signo + = sigs ;
2009-12-11 00:52:16 +01:00
engine - > iconcheck = matcher ;
2009-12-07 18:54:09 +01:00
return CL_SUCCESS ;
}
2009-12-06 19:49:40 +01:00
2008-11-11 21:23:34 +00:00
static int cli_loadwdb ( FILE * fs , struct cl_engine * engine , unsigned int options , struct cli_dbio * dbio )
2006-10-07 11:00:46 +00:00
{
int ret = 0 ;
2006-10-10 23:51:49 +00:00
2008-11-11 21:23:34 +00:00
if ( ! ( engine - > dconf - > phishing & PHISHING_CONF_ENGINE ) )
2007-05-01 16:08:57 +00:00
return CL_SUCCESS ;
2008-11-11 21:23:34 +00:00
if ( ! engine - > whitelist_matcher ) {
if ( ( ret = init_whitelist ( engine ) ) ) {
2006-10-10 23:51:49 +00:00
return ret ;
2006-10-07 11:00:46 +00:00
}
2006-10-10 23:51:49 +00:00
}
2006-10-07 11:00:46 +00:00
2010-02-15 15:01:37 +02:00
if ( ( ret = load_regex_matcher ( engine - > whitelist_matcher , fs , NULL , options , 1 , dbio , engine - > dconf - > other & OTHER_CONF_PREFILTERING ) ) ) {
2006-10-10 23:51:49 +00:00
return ret ;
}
2006-10-07 11:00:46 +00:00
2006-10-10 23:51:49 +00:00
return CL_SUCCESS ;
2006-10-07 11:00:46 +00:00
}
2009-03-05 19:09:54 +00:00
static int cli_loadpdb ( FILE * fs , struct cl_engine * engine , unsigned int * signo , unsigned int options , struct cli_dbio * dbio )
2006-10-07 11:00:46 +00:00
{
int ret = 0 ;
2006-10-10 23:51:49 +00:00
2008-11-11 21:23:34 +00:00
if ( ! ( engine - > dconf - > phishing & PHISHING_CONF_ENGINE ) )
2007-05-01 16:08:57 +00:00
return CL_SUCCESS ;
2008-11-11 21:23:34 +00:00
if ( ! engine - > domainlist_matcher ) {
if ( ( ret = init_domainlist ( engine ) ) ) {
2006-10-10 23:51:49 +00:00
return ret ;
2006-10-07 11:00:46 +00:00
}
2006-10-10 23:51:49 +00:00
}
2006-10-07 11:00:46 +00:00
2010-02-15 15:01:37 +02:00
if ( ( ret = load_regex_matcher ( engine - > domainlist_matcher , fs , signo , options , 0 , dbio , engine - > dconf - > other & OTHER_CONF_PREFILTERING ) ) ) {
2006-10-10 23:51:49 +00:00
return ret ;
}
return CL_SUCCESS ;
2006-10-07 11:00:46 +00:00
}
2006-10-10 23:51:49 +00:00
2007-03-26 12:57:02 +00:00
# define NDB_TOKENS 6
2008-11-11 21:23:34 +00:00
static int cli_loadndb ( FILE * fs , struct cl_engine * engine , unsigned int * signo , unsigned short sdb , unsigned int options , struct cli_dbio * dbio , const char * dbname )
2004-09-14 01:33:32 +00:00
{
2009-01-05 19:57:47 +00:00
const char * tokens [ NDB_TOKENS + 1 ] ;
2010-01-12 16:16:08 +01:00
char buffer [ FILEBUFF ] , * buffer_cpy = NULL ;
2007-03-26 12:57:02 +00:00
const char * sig , * virname , * offset , * pt ;
2005-09-23 02:23:36 +00:00
struct cli_matcher * root ;
2009-01-05 19:57:47 +00:00
int line = 0 , sigs = 0 , ret = 0 , tokens_count ;
2004-09-14 01:33:32 +00:00
unsigned short target ;
2006-12-20 01:23:50 +00:00
unsigned int phish = options & CL_DB_PHISHING ;
2004-09-14 01:33:32 +00:00
2008-11-11 21:23:34 +00:00
if ( ( ret = cli_initroots ( engine , options ) ) )
2005-09-23 02:23:36 +00:00
return ret ;
2004-09-14 01:33:32 +00:00
2009-09-28 19:33:59 +02:00
if ( engine - > ignored )
if ( ! ( buffer_cpy = cli_malloc ( FILEBUFF ) ) )
return CL_EMEM ;
2008-05-18 21:32:27 +00:00
while ( cli_dbgets ( buffer , FILEBUFF , fs , dbio ) ) {
2004-09-14 01:33:32 +00:00
line + + ;
2005-03-19 00:02:47 +00:00
2006-12-20 01:23:50 +00:00
if ( ! phish )
2005-11-13 23:38:41 +00:00
if ( ! strncmp ( buffer , " HTML.Phishing " , 13 ) | | ! strncmp ( buffer , " Email.Phishing " , 14 ) )
continue ;
2004-09-14 01:33:32 +00:00
cli_chomp ( buffer ) ;
2009-09-28 19:33:59 +02:00
if ( engine - > ignored )
strcpy ( buffer_cpy , buffer ) ;
2004-09-14 01:33:32 +00:00
2009-01-05 19:57:47 +00:00
tokens_count = cli_strtokenize ( buffer , ' : ' , NDB_TOKENS + 1 , tokens ) ;
2010-02-17 16:25:56 +01:00
if ( tokens_count < 4 | | tokens_count > 6 ) {
2004-09-14 01:33:32 +00:00
ret = CL_EMALFDB ;
break ;
}
2009-01-05 19:57:47 +00:00
virname = tokens [ 0 ] ;
2008-11-11 21:23:34 +00:00
if ( engine - > pua_cats & & ( options & CL_DB_PUA_MODE ) & & ( options & ( CL_DB_PUA_INCLUDE | CL_DB_PUA_EXCLUDE ) ) )
if ( cli_chkpua ( virname , engine - > pua_cats , options ) )
2008-07-31 16:26:50 +00:00
continue ;
2009-09-28 19:33:59 +02:00
if ( engine - > ignored & & cli_chkign ( engine - > ignored , virname , buffer_cpy ) )
2008-02-08 19:32:45 +00:00
continue ;
2009-01-05 19:57:47 +00:00
if ( tokens_count > 4 ) { /* min version */
pt = tokens [ 4 ] ;
2009-08-04 20:22:03 +02:00
if ( ! cli_isnumber ( pt ) ) {
2004-10-15 21:00:20 +00:00
ret = CL_EMALFDB ;
break ;
}
2006-12-02 00:09:02 +00:00
if ( ( unsigned int ) atoi ( pt ) > cl_retflevel ( ) ) {
2006-11-17 23:53:44 +00:00
cli_dbgmsg ( " Signature for %s not loaded (required f-level: %d) \n " , virname , atoi ( pt ) ) ;
2004-10-15 21:00:20 +00:00
continue ;
}
2009-01-05 19:57:47 +00:00
if ( tokens_count = = 6 ) { /* max version */
pt = tokens [ 5 ] ;
2009-08-04 20:22:03 +02:00
if ( ! cli_isnumber ( pt ) ) {
2006-01-25 12:11:31 +00:00
ret = CL_EMALFDB ;
break ;
}
2006-12-02 00:09:02 +00:00
if ( ( unsigned int ) atoi ( pt ) < cl_retflevel ( ) ) {
2006-01-25 12:11:31 +00:00
continue ;
}
}
2004-10-15 21:00:20 +00:00
}
2009-08-04 20:22:03 +02:00
if ( ! ( pt = tokens [ 1 ] ) | | ( strcmp ( pt , " * " ) & & ! cli_isnumber ( pt ) ) ) {
2004-09-14 01:33:32 +00:00
ret = CL_EMALFDB ;
break ;
}
target = ( unsigned short ) atoi ( pt ) ;
2008-02-01 00:17:44 +00:00
if ( target > = CLI_MTARGETS ) {
2005-09-23 02:23:36 +00:00
cli_dbgmsg ( " Not supported target type in signature for %s \n " , virname ) ;
continue ;
}
2008-11-11 21:23:34 +00:00
root = engine - > root [ target ] ;
2005-09-23 02:23:36 +00:00
2009-01-05 19:57:47 +00:00
offset = tokens [ 2 ] ;
sig = tokens [ 3 ] ;
2004-09-14 01:33:32 +00:00
2008-07-25 19:00:25 +00:00
if ( ( ret = cli_parse_add ( root , virname , sig , 0 , 0 , offset , target , NULL , options ) ) ) {
2004-07-13 03:30:49 +00:00
ret = CL_EMALFDB ;
break ;
}
2008-02-08 19:32:45 +00:00
sigs + + ;
2004-02-01 01:18:57 +00:00
}
2009-09-28 19:33:59 +02:00
if ( engine - > ignored )
free ( buffer_cpy ) ;
2004-02-01 01:18:57 +00:00
2004-07-13 03:30:49 +00:00
if ( ! line ) {
cli_errmsg ( " Empty database file \n " ) ;
return CL_EMALFDB ;
}
2003-09-29 11:44:52 +00:00
2004-07-13 03:30:49 +00:00
if ( ret ) {
2004-09-14 01:33:32 +00:00
cli_errmsg ( " Problem parsing database at line %d \n " , line ) ;
2003-09-29 11:44:52 +00:00
return ret ;
}
2004-09-13 16:44:01 +00:00
if ( signo )
2004-10-15 21:00:20 +00:00
* signo + = sigs ;
2004-07-13 03:30:49 +00:00
2008-11-11 21:23:34 +00:00
if ( sdb & & sigs & & ! engine - > sdb ) {
engine - > sdb = 1 ;
2006-01-25 12:11:31 +00:00
cli_dbgmsg ( " *** Self protection mechanism activated. \n " ) ;
}
2006-05-18 11:29:24 +00:00
return CL_SUCCESS ;
2004-07-13 03:30:49 +00:00
}
2008-07-25 19:00:25 +00:00
struct lsig_attrib {
const char * name ;
unsigned int type ;
void * * pt ;
} ;
/* TODO: rework this */
static int lsigattribs ( char * attribs , struct cli_lsig_tdb * tdb )
{
struct lsig_attrib attrtab [ ] = {
2010-01-12 14:41:44 +01:00
# define ATTRIB_TOKENS 8
2009-12-30 00:20:02 +01:00
{ " Target " , CLI_TDB_UINT , ( void * * ) & tdb - > target } ,
{ " Engine " , CLI_TDB_RANGE , ( void * * ) & tdb - > engine } ,
2009-12-14 17:16:46 +01:00
2009-12-30 00:20:02 +01:00
{ " FileSize " , CLI_TDB_RANGE , ( void * * ) & tdb - > filesize } ,
{ " EntryPoint " , CLI_TDB_RANGE , ( void * * ) & tdb - > ep } ,
{ " NumberOfSections " , CLI_TDB_RANGE , ( void * * ) & tdb - > nos } ,
{ " IconGroup1 " , CLI_TDB_STR , ( void * * ) & tdb - > icongrp1 } ,
{ " IconGroup2 " , CLI_TDB_STR , ( void * * ) & tdb - > icongrp2 } ,
2009-12-14 17:16:46 +01:00
2010-01-12 14:41:44 +01:00
{ " Container " , CLI_TDB_FTYPE , ( void * * ) & tdb - > container } ,
2008-07-25 19:00:25 +00:00
/*
{ " SectOff " , CLI_TDB_RANGE2 , ( void * * ) & tdb - > sectoff } ,
{ " SectRVA " , CLI_TDB_RANGE2 , ( void * * ) & tdb - > sectrva } ,
{ " SectVSZ " , CLI_TDB_RANGE2 , ( void * * ) & tdb - > sectvsz } ,
{ " SectRAW " , CLI_TDB_RANGE2 , ( void * * ) & tdb - > sectraw } ,
{ " SectRSZ " , CLI_TDB_RANGE2 , ( void * * ) & tdb - > sectrsz } ,
{ " SectURVA " , CLI_TDB_RANGE2 , ( void * * ) & tdb - > secturva } ,
{ " SectUVSZ " , CLI_TDB_RANGE2 , ( void * * ) & tdb - > sectuvsz } ,
{ " SectURAW " , CLI_TDB_RANGE2 , ( void * * ) & tdb - > secturaw } ,
{ " SectURSZ " , CLI_TDB_RANGE2 , ( void * * ) & tdb - > sectursz } ,
*/
{ NULL , 0 , NULL , }
} ;
struct lsig_attrib * apt ;
char * tokens [ ATTRIB_TOKENS ] , * pt , * pt2 ;
2010-05-07 15:47:03 +02:00
unsigned int v1 , v2 , v3 , i , j , tokens_count , have_newext = 0 ;
2008-07-25 19:00:25 +00:00
uint32_t cnt , off [ ATTRIB_TOKENS ] ;
2009-01-05 19:57:47 +00:00
tokens_count = cli_strtokenize ( attribs , ' , ' , ATTRIB_TOKENS , ( const char * * ) tokens ) ;
2008-07-25 19:00:25 +00:00
2009-01-05 19:57:47 +00:00
for ( i = 0 ; i < tokens_count ; i + + ) {
2008-07-25 19:00:25 +00:00
if ( ! ( pt = strchr ( tokens [ i ] , ' : ' ) ) ) {
cli_errmsg ( " lsigattribs: Incorrect format of attribute '%s' \n " , tokens [ i ] ) ;
return - 1 ;
}
* pt + + = 0 ;
apt = NULL ;
for ( j = 0 ; attrtab [ j ] . name ; j + + ) {
if ( ! strcmp ( attrtab [ j ] . name , tokens [ i ] ) ) {
apt = & attrtab [ j ] ;
break ;
}
}
if ( ! apt ) {
cli_dbgmsg ( " lsigattribs: Unknown attribute name '%s' \n " , tokens [ i ] ) ;
2010-01-12 12:16:13 +01:00
return 1 ;
2008-07-25 19:00:25 +00:00
}
2010-05-07 15:47:03 +02:00
if ( ! strcmp ( apt - > name , " Engine " ) ) {
if ( i ) {
cli_errmsg ( " lsigattribs: For backward compatibility the Engine attribute must be on the first position \n " ) ;
return - 1 ;
}
} else if ( strcmp ( apt - > name , " Target " ) )
have_newext = 1 ;
2008-07-25 19:00:25 +00:00
switch ( apt - > type ) {
case CLI_TDB_UINT :
2009-08-04 20:22:03 +02:00
if ( ! cli_isnumber ( pt ) ) {
cli_errmsg ( " lsigattribs: Invalid argument for %s \n " , tokens [ i ] ) ;
return - 1 ;
}
2008-07-25 19:00:25 +00:00
off [ i ] = cnt = tdb - > cnt [ CLI_TDB_UINT ] + + ;
2009-01-26 19:47:02 +00:00
tdb - > val = ( uint32_t * ) mpool_realloc2 ( tdb - > mempool , tdb - > val , tdb - > cnt [ CLI_TDB_UINT ] * sizeof ( uint32_t ) ) ;
2008-07-25 19:00:25 +00:00
if ( ! tdb - > val ) {
tdb - > cnt [ CLI_TDB_UINT ] = 0 ;
return - 1 ;
}
tdb - > val [ cnt ] = atoi ( pt ) ;
break ;
2010-01-12 14:41:44 +01:00
case CLI_TDB_FTYPE :
if ( ( v1 = cli_ftcode ( pt ) ) = = CL_TYPE_ERROR ) {
cli_dbgmsg ( " lsigattribs: Unknown file type in %s \n " , tokens [ i ] ) ;
return 1 ; /* skip */
}
off [ i ] = cnt = tdb - > cnt [ CLI_TDB_UINT ] + + ;
tdb - > val = ( uint32_t * ) mpool_realloc2 ( tdb - > mempool , tdb - > val , tdb - > cnt [ CLI_TDB_UINT ] * sizeof ( uint32_t ) ) ;
if ( ! tdb - > val ) {
tdb - > cnt [ CLI_TDB_UINT ] = 0 ;
return - 1 ;
}
tdb - > val [ cnt ] = v1 ;
break ;
2008-07-25 19:00:25 +00:00
case CLI_TDB_RANGE :
if ( ! ( pt2 = strchr ( pt , ' - ' ) ) ) {
cli_errmsg ( " lsigattribs: Incorrect parameters in '%s' \n " , tokens [ i ] ) ;
return - 1 ;
}
* pt2 + + = 0 ;
off [ i ] = cnt = tdb - > cnt [ CLI_TDB_RANGE ] ;
tdb - > cnt [ CLI_TDB_RANGE ] + = 2 ;
2009-01-26 19:47:02 +00:00
tdb - > range = ( uint32_t * ) mpool_realloc2 ( tdb - > mempool , tdb - > range , tdb - > cnt [ CLI_TDB_RANGE ] * sizeof ( uint32_t ) ) ;
2008-07-25 19:00:25 +00:00
if ( ! tdb - > range ) {
tdb - > cnt [ CLI_TDB_RANGE ] = 0 ;
return - 1 ;
}
2009-08-04 20:22:03 +02:00
if ( ! cli_isnumber ( pt ) | | ! cli_isnumber ( pt2 ) ) {
cli_errmsg ( " lsigattribs: Invalid argument for %s \n " , tokens [ i ] ) ;
return - 1 ;
}
2008-07-25 19:00:25 +00:00
tdb - > range [ cnt ] = atoi ( pt ) ;
tdb - > range [ cnt + 1 ] = atoi ( pt2 ) ;
break ;
case CLI_TDB_RANGE2 :
if ( ! strchr ( pt , ' - ' ) | | ! strchr ( pt , ' . ' ) ) {
cli_errmsg ( " lsigattribs: Incorrect parameters in '%s' \n " , tokens [ i ] ) ;
return - 1 ;
}
off [ i ] = cnt = tdb - > cnt [ CLI_TDB_RANGE ] ;
tdb - > cnt [ CLI_TDB_RANGE ] + = 3 ;
2009-01-26 19:47:02 +00:00
tdb - > range = ( uint32_t * ) mpool_realloc2 ( tdb - > mempool , tdb - > range , tdb - > cnt [ CLI_TDB_RANGE ] * sizeof ( uint32_t ) ) ;
2008-07-25 19:00:25 +00:00
if ( ! tdb - > range ) {
tdb - > cnt [ CLI_TDB_RANGE ] = 0 ;
return - 1 ;
}
if ( sscanf ( pt , " %u.%u-%u " , & v1 , & v2 , & v3 ) ! = 3 ) {
cli_errmsg ( " lsigattribs: Can't parse parameters in '%s' \n " , tokens [ i ] ) ;
return - 1 ;
}
tdb - > range [ cnt ] = ( uint32_t ) v1 ;
tdb - > range [ cnt + 1 ] = ( uint32_t ) v2 ;
tdb - > range [ cnt + 2 ] = ( uint32_t ) v3 ;
break ;
case CLI_TDB_STR :
off [ i ] = cnt = tdb - > cnt [ CLI_TDB_STR ] ;
tdb - > cnt [ CLI_TDB_STR ] + = strlen ( pt ) + 1 ;
2009-01-26 19:47:02 +00:00
tdb - > str = ( char * ) mpool_realloc2 ( tdb - > mempool , tdb - > str , tdb - > cnt [ CLI_TDB_STR ] * sizeof ( char ) ) ;
2008-07-25 19:00:25 +00:00
if ( ! tdb - > str ) {
cli_errmsg ( " lsigattribs: Can't allocate memory for tdb->str \n " ) ;
return - 1 ;
}
memcpy ( & tdb - > str [ cnt ] , pt , strlen ( pt ) ) ;
tdb - > str [ tdb - > cnt [ CLI_TDB_STR ] - 1 ] = 0 ;
break ;
}
}
if ( ! i ) {
cli_errmsg ( " lsigattribs: Empty TDB \n " ) ;
return - 1 ;
}
2009-01-05 19:57:47 +00:00
for ( i = 0 ; i < tokens_count ; i + + ) {
2008-07-25 19:00:25 +00:00
for ( j = 0 ; attrtab [ j ] . name ; j + + ) {
if ( ! strcmp ( attrtab [ j ] . name , tokens [ i ] ) ) {
apt = & attrtab [ j ] ;
break ;
}
}
2008-11-18 19:21:11 +00:00
if ( ! apt )
continue ;
2008-07-25 19:00:25 +00:00
switch ( apt - > type ) {
case CLI_TDB_UINT :
2010-01-12 14:41:44 +01:00
case CLI_TDB_FTYPE :
2008-07-25 19:00:25 +00:00
* apt - > pt = ( uint32_t * ) & tdb - > val [ off [ i ] ] ;
break ;
case CLI_TDB_RANGE :
case CLI_TDB_RANGE2 :
* apt - > pt = ( uint32_t * ) & tdb - > range [ off [ i ] ] ;
break ;
case CLI_TDB_STR :
* apt - > pt = ( char * ) & tdb - > str [ off [ i ] ] ;
break ;
}
}
2010-05-07 15:47:03 +02:00
if ( have_newext & & ( ! tdb - > engine | | tdb - > engine [ 0 ] < 51 ) ) {
cli_errmsg ( " lsigattribs: For backward compatibility all signatures using new attributes must have the Engine attribute present and set to min_level of at least 51 (0.96) \n " ) ;
return - 1 ;
}
2008-07-25 19:00:25 +00:00
return 0 ;
}
2008-10-19 16:16:49 +00:00
# define FREE_TDB(x) do { \
if ( x . cnt [ CLI_TDB_UINT ] ) \
2009-01-26 19:47:02 +00:00
mpool_free ( x . mempool , x . val ) ; \
2008-10-19 16:16:49 +00:00
if ( x . cnt [ CLI_TDB_RANGE ] ) \
2009-01-26 19:47:02 +00:00
mpool_free ( x . mempool , x . range ) ; \
2008-10-19 16:16:49 +00:00
if ( x . cnt [ CLI_TDB_STR ] ) \
2009-01-26 19:47:02 +00:00
mpool_free ( x . mempool , x . str ) ; \
2010-02-08 13:45:03 +02:00
if ( x . macro_ptids ) \
mpool_free ( x . mempool , x . macro_ptids ) ; \
2008-10-19 16:16:49 +00:00
} while ( 0 ) ;
2008-07-25 19:00:25 +00:00
# define LDB_TOKENS 67
2010-02-02 15:29:02 +02:00
static int load_oneldb ( char * buffer , int chkpua , int chkign , struct cl_engine * engine , unsigned int options , const char * dbname , unsigned int line , unsigned int * sigs , unsigned bc_idx , const char * buffer_cpy )
2008-07-25 19:00:25 +00:00
{
2009-09-21 20:28:15 +03:00
const char * sig , * virname , * offset , * logic ;
struct cli_ac_lsig * * newtable , * lsig ;
2010-01-12 16:57:22 +02:00
char * tokens [ LDB_TOKENS + 1 ] , * pt ;
2009-09-21 20:28:15 +03:00
int i , subsigs , tokens_count ;
unsigned short target = 0 ;
struct cli_matcher * root ;
struct cli_lsig_tdb tdb ;
uint32_t lsigid [ 2 ] ;
int ret ;
2008-07-25 19:00:25 +00:00
2010-01-12 12:16:13 +01:00
tokens_count = cli_strtokenize ( buffer , ' ; ' , LDB_TOKENS + 1 , ( const char * * ) tokens ) ;
2009-09-21 20:28:15 +03:00
if ( tokens_count < 4 ) {
return CL_EMALFDB ;
}
virname = tokens [ 0 ] ;
logic = tokens [ 2 ] ;
2008-07-25 19:00:25 +00:00
2009-09-21 20:28:15 +03:00
if ( chkpua & & cli_chkpua ( virname , engine - > pua_cats , options ) )
return CL_SUCCESS ;
2009-09-28 19:33:59 +02:00
2009-10-02 10:04:37 +03:00
if ( chkign & & cli_chkign ( engine - > ignored , virname , buffer_cpy ) )
2009-09-21 20:28:15 +03:00
return CL_SUCCESS ;
2008-07-25 19:00:25 +00:00
2009-09-21 20:28:15 +03:00
subsigs = cli_ac_chklsig ( logic , logic + strlen ( logic ) , NULL , NULL , NULL , 1 ) ;
if ( subsigs = = - 1 ) {
return CL_EMALFDB ;
}
subsigs + + ;
if ( subsigs > 64 ) {
cli_errmsg ( " cli_loadldb: Broken logical expression or too many subsignatures \n " ) ;
return CL_EMALFDB ;
}
2009-09-22 11:03:17 +03:00
if ( ! line ) {
/* This is a logical signature from the bytecode, we need all
* subsignatures , even if not referenced from the logical expression */
if ( subsigs > tokens_count - 3 ) {
cli_errmsg ( " load_oneldb: Too many subsignatures: %u (max %u) \n " ,
subsigs , tokens_count - 3 ) ;
return CL_EMALFDB ;
2008-07-25 19:00:25 +00:00
}
2009-09-22 11:03:17 +03:00
subsigs = tokens_count - 3 ;
2009-12-03 11:37:38 +02:00
} else if ( subsigs ! = tokens_count - 3 ) {
cli_errmsg ( " cli_loadldb: The number of subsignatures (== %u) doesn't match the IDs in the logical expression (== %u) \n " , tokens_count - 3 , subsigs ) ;
return CL_EMALFDB ;
2009-09-22 11:03:17 +03:00
}
2008-07-25 19:00:25 +00:00
2009-09-21 20:28:15 +03:00
/* TDB */
memset ( & tdb , 0 , sizeof ( tdb ) ) ;
# ifdef USE_MPOOL
tdb . mempool = engine - > mempool ;
# endif
2010-01-12 12:16:13 +01:00
if ( ( ret = lsigattribs ( tokens [ 1 ] , & tdb ) ) ) {
2009-09-21 20:28:15 +03:00
FREE_TDB ( tdb ) ;
2010-01-12 12:16:13 +01:00
if ( ret = = 1 ) {
cli_dbgmsg ( " cli_loadldb: Not supported attribute(s) in logical signature for %s, skipping \n " , virname ) ;
2010-01-12 16:16:08 +01:00
( * sigs ) - - ;
2010-01-12 12:16:13 +01:00
return CL_SUCCESS ;
}
2009-09-21 20:28:15 +03:00
return CL_EMALFDB ;
}
2010-01-12 12:16:13 +01:00
2009-09-21 20:28:15 +03:00
if ( ! tdb . target ) {
cli_errmsg ( " cli_loadldb: No target specified in TDB \n " ) ;
FREE_TDB ( tdb ) ;
return CL_EMALFDB ;
} else if ( tdb . target [ 0 ] > = CLI_MTARGETS ) {
2010-01-12 12:16:13 +01:00
cli_dbgmsg ( " cli_loadldb: Not supported target type in logical signature for %s, skipping \n " , virname ) ;
2009-09-21 20:28:15 +03:00
FREE_TDB ( tdb ) ;
2010-01-12 16:16:08 +01:00
( * sigs ) - - ;
2009-09-21 20:28:15 +03:00
return CL_SUCCESS ;
}
2009-01-05 19:57:47 +00:00
2009-12-14 17:16:46 +01:00
if ( ( tdb . icongrp1 | | tdb . icongrp2 ) & & tdb . target [ 0 ] ! = 1 ) {
cli_errmsg ( " cli_loadldb: IconGroup is only supported in PE (target 1) signatures \n " ) ;
FREE_TDB ( tdb ) ;
return CL_EMALFDB ;
}
2009-12-30 00:20:02 +01:00
if ( ( tdb . ep | | tdb . nos ) & & tdb . target [ 0 ] ! = 1 & & tdb . target [ 0 ] ! = 6 & & tdb . target [ 0 ] ! = 9 ) {
2009-12-30 00:24:06 +01:00
cli_errmsg ( " cli_loadldb: EntryPoint/NumberOfSections is only supported in PE/ELF/Mach-O signatures \n " ) ;
2009-12-30 00:20:02 +01:00
FREE_TDB ( tdb ) ;
return CL_EMALFDB ;
}
2009-09-21 20:28:15 +03:00
root = engine - > root [ tdb . target [ 0 ] ] ;
2008-07-31 16:26:50 +00:00
2009-09-21 20:28:15 +03:00
lsig = ( struct cli_ac_lsig * ) mpool_calloc ( engine - > mempool , 1 , sizeof ( struct cli_ac_lsig ) ) ;
if ( ! lsig ) {
cli_errmsg ( " cli_loadldb: Can't allocate memory for lsig \n " ) ;
FREE_TDB ( tdb ) ;
return CL_EMEM ;
}
2008-07-25 19:00:25 +00:00
2009-09-21 20:28:15 +03:00
lsig - > logic = cli_mpool_strdup ( engine - > mempool , logic ) ;
if ( ! lsig - > logic ) {
cli_errmsg ( " cli_loadldb: Can't allocate memory for lsig->logic \n " ) ;
FREE_TDB ( tdb ) ;
mpool_free ( engine - > mempool , lsig ) ;
return CL_EMEM ;
}
2008-07-25 19:00:25 +00:00
2009-09-21 20:28:15 +03:00
lsigid [ 0 ] = lsig - > id = root - > ac_lsigs ;
2008-07-25 19:00:25 +00:00
2009-09-21 20:28:15 +03:00
root - > ac_lsigs + + ;
newtable = ( struct cli_ac_lsig * * ) mpool_realloc ( engine - > mempool , root - > ac_lsigtable , root - > ac_lsigs * sizeof ( struct cli_ac_lsig * ) ) ;
if ( ! newtable ) {
root - > ac_lsigs - - ;
cli_errmsg ( " cli_loadldb: Can't realloc root->ac_lsigtable \n " ) ;
FREE_TDB ( tdb ) ;
mpool_free ( engine - > mempool , lsig ) ;
return CL_EMEM ;
}
2010-02-02 15:29:02 +02:00
/* 0 marks no bc, we can't use a pointer to bc, since that is
* realloced / moved during load */
lsig - > bc_idx = bc_idx ;
2009-09-21 20:28:15 +03:00
newtable [ root - > ac_lsigs - 1 ] = lsig ;
root - > ac_lsigtable = newtable ;
2010-02-08 13:45:03 +02:00
tdb . subsigs = subsigs ;
2009-11-03 15:19:43 +01:00
2009-09-21 20:28:15 +03:00
for ( i = 0 ; i < subsigs ; i + + ) {
lsigid [ 1 ] = i ;
sig = tokens [ 3 + i ] ;
2008-07-25 19:00:25 +00:00
2009-09-21 20:28:15 +03:00
if ( ( pt = strchr ( tokens [ 3 + i ] , ' : ' ) ) ) {
* pt = 0 ;
sig = + + pt ;
offset = tokens [ 3 + i ] ;
} else {
offset = " * " ;
sig = tokens [ 3 + i ] ;
}
2008-07-25 19:00:25 +00:00
2010-01-12 12:16:13 +01:00
if ( ( ret = cli_parse_add ( root , virname , sig , 0 , 0 , offset , target , lsigid , options ) ) )
return ret ;
2010-02-08 13:45:03 +02:00
if ( sig [ 0 ] = = ' $ ' & & i ) {
/* allow mapping from lsig back to pattern for macros */
if ( ! tdb . macro_ptids )
tdb . macro_ptids = mpool_calloc ( root - > mempool , subsigs , sizeof ( * tdb . macro_ptids ) ) ;
if ( ! tdb . macro_ptids )
return CL_EMEM ;
tdb . macro_ptids [ i - 1 ] = root - > ac_patterns - 1 ;
}
2008-07-25 19:00:25 +00:00
if ( tdb . engine ) {
if ( tdb . engine [ 0 ] > cl_retflevel ( ) ) {
cli_dbgmsg ( " cli_loadldb: Signature for %s not loaded (required f-level: %u) \n " , virname , tdb . engine [ 0 ] ) ;
FREE_TDB ( tdb ) ;
2010-01-12 16:16:08 +01:00
( * sigs ) - - ;
2009-09-21 20:28:15 +03:00
return CL_SUCCESS ;
2008-07-25 19:00:25 +00:00
} else if ( tdb . engine [ 1 ] < cl_retflevel ( ) ) {
FREE_TDB ( tdb ) ;
2010-01-12 16:16:08 +01:00
( * sigs ) - - ;
2009-09-21 20:28:15 +03:00
return CL_SUCCESS ;
2008-07-25 19:00:25 +00:00
}
}
2009-09-21 20:28:15 +03:00
}
2010-02-08 13:45:03 +02:00
memcpy ( & lsig - > tdb , & tdb , sizeof ( tdb ) ) ;
2009-09-21 20:28:15 +03:00
return CL_SUCCESS ;
}
2008-07-25 19:00:25 +00:00
2009-09-21 20:28:15 +03:00
static int cli_loadldb ( FILE * fs , struct cl_engine * engine , unsigned int * signo , unsigned int options , struct cli_dbio * dbio , const char * dbname )
{
2010-01-12 16:16:08 +01:00
char buffer [ CLI_DEFAULT_LSIG_BUFSIZE + 1 ] , * buffer_cpy = NULL ;
2009-09-21 20:28:15 +03:00
unsigned int line = 0 , sigs = 0 ;
int ret ;
2008-07-25 19:00:25 +00:00
2009-09-21 20:28:15 +03:00
if ( ( ret = cli_initroots ( engine , options ) ) )
return ret ;
2008-07-25 19:00:25 +00:00
2009-10-02 10:04:37 +03:00
if ( engine - > ignored )
if ( ! ( buffer_cpy = cli_malloc ( sizeof ( buffer ) ) ) )
return CL_EMEM ;
2009-09-21 20:28:15 +03:00
while ( cli_dbgets ( buffer , sizeof ( buffer ) , fs , dbio ) ) {
line + + ;
sigs + + ;
cli_chomp ( buffer ) ;
2008-07-25 19:00:25 +00:00
2009-10-02 10:04:37 +03:00
if ( engine - > ignored )
strcpy ( buffer_cpy , buffer ) ;
2009-09-21 20:28:15 +03:00
ret = load_oneldb ( buffer ,
engine - > pua_cats & & ( options & CL_DB_PUA_MODE ) & & ( options & ( CL_DB_PUA_INCLUDE | CL_DB_PUA_EXCLUDE ) ) ,
! ! engine - > ignored ,
2010-02-02 15:29:02 +02:00
engine , options , dbname , line , & sigs , 0 , buffer_cpy ) ;
2009-09-21 20:28:15 +03:00
if ( ret )
2008-07-25 19:00:25 +00:00
break ;
}
2009-09-28 19:33:59 +02:00
if ( engine - > ignored )
free ( buffer_cpy ) ;
2008-07-25 19:00:25 +00:00
if ( ! line ) {
cli_errmsg ( " Empty database file \n " ) ;
return CL_EMALFDB ;
}
if ( ret ) {
cli_errmsg ( " Problem parsing database at line %u \n " , line ) ;
return ret ;
}
if ( signo )
* signo + = sigs ;
return CL_SUCCESS ;
}
2009-09-21 19:24:16 +03:00
static int cli_loadcbc ( FILE * fs , struct cl_engine * engine , unsigned int * signo , unsigned int options , struct cli_dbio * dbio , const char * dbname )
{
int rc ;
struct cli_all_bc * bcs = & engine - > bcs ;
struct cli_bc * bc ;
2009-09-21 23:44:32 +03:00
unsigned sigs = 0 ;
2010-01-22 14:36:56 +02:00
unsigned security_trust = 0 ;
2009-09-21 23:44:32 +03:00
2009-10-02 17:33:11 +03:00
/* TODO: virusname have a common prefix, and whitelist by that */
2009-09-21 23:44:32 +03:00
if ( ( rc = cli_initroots ( engine , options ) ) )
return rc ;
2009-09-21 19:24:16 +03:00
if ( ! ( engine - > dconf - > bytecode & BYTECODE_ENGINE_MASK ) ) {
return CL_SUCCESS ;
}
2010-03-22 17:28:38 +02:00
# ifndef CL_BCUNSIGNED
2010-03-10 15:58:42 +02:00
if ( ! ( options & CL_DB_SIGNED ) ) {
cli_warnmsg ( " Only loading signed bytecode, skipping load of unsigned bytecode! \n " ) ;
return CL_SUCCESS ;
}
# endif
2009-09-21 19:24:16 +03:00
bcs - > all_bcs = cli_realloc2 ( bcs - > all_bcs , sizeof ( * bcs - > all_bcs ) * ( bcs - > count + 1 ) ) ;
if ( ! bcs - > all_bcs ) {
cli_errmsg ( " cli_loadcbc: Can't allocate memory for bytecode entry \n " ) ;
return CL_EMEM ;
}
bcs - > count + + ;
bc = & bcs - > all_bcs [ bcs - > count - 1 ] ;
2010-01-22 14:36:56 +02:00
switch ( engine - > bytecode_security ) {
case CL_BYTECODE_TRUST_ALL :
security_trust = 1 ;
cli_dbgmsg ( " bytecode: trusting all bytecode! \n " ) ;
break ;
case CL_BYTECODE_TRUST_SIGNED :
2010-01-25 13:28:19 +01:00
security_trust = ! ! ( options & CL_DB_SIGNED ) ;
2010-01-22 14:36:56 +02:00
break ;
default :
security_trust = 0 ;
}
rc = cli_bytecode_load ( bc , fs , dbio , security_trust ) ;
2009-09-21 19:24:16 +03:00
if ( rc ! = CL_SUCCESS ) {
2009-10-02 17:33:11 +03:00
cli_errmsg ( " Unable to load %s bytecode: %s \n " , dbname , cl_strerror ( rc ) ) ;
2009-09-21 19:24:16 +03:00
return rc ;
}
2010-02-13 18:21:33 +02:00
if ( bc - > state = = bc_skip ) {
cli_bytecode_destroy ( bc ) ;
bcs - > count - - ;
return CL_SUCCESS ;
}
2010-02-02 15:29:02 +02:00
bc - > id = bcs - > count ; /* must set after _load, since load zeroes */
2010-02-02 17:13:44 +01:00
sigs + + ;
2010-01-19 16:38:12 +02:00
if ( bc - > kind = = BC_LOGICAL | | bc - > lsig ) {
2010-04-26 18:19:28 +03:00
unsigned oldsigs = sigs ;
2009-10-02 17:33:11 +03:00
if ( ! bc - > lsig ) {
cli_errmsg ( " Bytecode %s has logical kind, but missing logical signature! \n " , dbname ) ;
return CL_EMALFDB ;
}
2010-01-22 16:50:16 +02:00
cli_dbgmsg ( " Bytecode %s(%u) has logical signature: %s \n " , dbname , bc - > id , bc - > lsig ) ;
2010-02-02 15:29:02 +02:00
rc = load_oneldb ( bc - > lsig , 0 , 0 , engine , options , dbname , 0 , & sigs , bcs - > count , NULL ) ;
2009-09-21 23:44:32 +03:00
if ( rc ! = CL_SUCCESS ) {
2009-10-02 17:33:11 +03:00
cli_errmsg ( " Problem parsing logical signature %s for bytecode %s: %s \n " ,
bc - > lsig , dbname , cl_strerror ( rc ) ) ;
2009-09-21 23:44:32 +03:00
return rc ;
}
2010-04-26 18:19:28 +03:00
if ( sigs ! = oldsigs ) {
/* compiler ensures Engine field in lsig matches the one in bytecode,
* so this should never happen . */
cli_errmsg ( " Bytecode logical signature skipped, but bytecode itself not? " ) ;
return CL_EMALFDB ;
}
2010-01-19 16:38:12 +02:00
}
if ( bc - > kind ! = BC_LOGICAL ) {
2009-10-02 17:33:11 +03:00
if ( bc - > lsig ) {
2010-01-19 16:38:12 +02:00
/* runlsig will only flip a status bit, not report a match,
* when the hooks are executed we only execute the hook if its
* status bit is on */
bc - > hook_lsig_id = + + engine - > hook_lsig_ids ;
2009-10-02 17:33:11 +03:00
}
if ( bc - > kind > = _BC_START_HOOKS & & bc - > kind < _BC_LAST_HOOK ) {
unsigned hook = bc - > kind - _BC_START_HOOKS ;
unsigned cnt = + + engine - > hooks_cnt [ hook ] ;
engine - > hooks [ hook ] = cli_realloc2 ( engine - > hooks [ hook ] ,
sizeof ( * engine - > hooks [ 0 ] ) * cnt ) ;
if ( ! engine - > hooks [ hook ] ) {
cli_errmsg ( " Out of memory allocating memory for hook %u " , hook ) ;
return CL_EMEM ;
}
engine - > hooks [ hook ] [ cnt - 1 ] = bcs - > count - 1 ;
} else switch ( bc - > kind ) {
default :
cli_errmsg ( " Bytecode: unhandled bytecode kind %u \n " , bc - > kind ) ;
return CL_EMALFDB ;
}
2009-09-21 20:28:15 +03:00
}
2009-09-21 23:44:32 +03:00
if ( signo )
* signo + = sigs ;
2009-09-21 19:24:16 +03:00
return CL_SUCCESS ;
}
2009-01-05 19:57:47 +00:00
# define FTM_TOKENS 8
2008-11-11 21:23:34 +00:00
static int cli_loadftm ( FILE * fs , struct cl_engine * engine , unsigned int options , unsigned int internal , struct cli_dbio * dbio )
2007-12-14 22:39:37 +00:00
{
2009-01-05 19:57:47 +00:00
const char * tokens [ FTM_TOKENS + 1 ] , * pt ;
2007-12-14 22:39:37 +00:00
char buffer [ FILEBUFF ] ;
2009-01-05 19:57:47 +00:00
unsigned int line = 0 , sigs = 0 , tokens_count ;
2007-12-14 22:39:37 +00:00
struct cli_ftype * new ;
2008-02-20 22:04:48 +00:00
cli_file_t rtype , type ;
2007-12-14 22:39:37 +00:00
int ret ;
2008-11-11 21:23:34 +00:00
if ( ( ret = cli_initroots ( engine , options ) ) )
2007-12-14 22:39:37 +00:00
return ret ;
while ( 1 ) {
if ( internal ) {
2010-03-01 18:35:09 +01:00
options | = CL_DB_OFFICIAL ;
2007-12-14 22:39:37 +00:00
if ( ! ftypes_int [ line ] )
break ;
strncpy ( buffer , ftypes_int [ line ] , sizeof ( buffer ) ) ;
2008-05-27 16:30:47 +00:00
buffer [ sizeof ( buffer ) - 1 ] = ' \0 ' ;
2007-12-14 22:39:37 +00:00
} else {
2008-05-18 21:32:27 +00:00
if ( ! cli_dbgets ( buffer , FILEBUFF , fs , dbio ) )
2007-12-14 22:39:37 +00:00
break ;
cli_chomp ( buffer ) ;
}
line + + ;
2009-01-05 19:57:47 +00:00
tokens_count = cli_strtokenize ( buffer , ' : ' , FTM_TOKENS + 1 , tokens ) ;
2007-12-14 22:39:37 +00:00
2009-01-05 19:57:47 +00:00
if ( tokens_count < 6 | | tokens_count > 8 ) {
2007-12-14 22:39:37 +00:00
ret = CL_EMALFDB ;
break ;
}
2009-01-05 19:57:47 +00:00
if ( tokens_count > 6 ) { /* min version */
pt = tokens [ 6 ] ;
2008-02-20 22:04:48 +00:00
if ( ! cli_isnumber ( pt ) ) {
ret = CL_EMALFDB ;
break ;
}
if ( ( unsigned int ) atoi ( pt ) > cl_retflevel ( ) ) {
cli_dbgmsg ( " cli_loadftm: File type signature for %s not loaded (required f-level: %u) \n " , tokens [ 3 ] , atoi ( pt ) ) ;
continue ;
}
2009-01-05 19:57:47 +00:00
if ( tokens_count = = 8 ) { /* max version */
pt = tokens [ 7 ] ;
2008-02-20 22:04:48 +00:00
if ( ! cli_isnumber ( pt ) ) {
ret = CL_EMALFDB ;
break ;
}
if ( ( unsigned int ) atoi ( pt ) < cl_retflevel ( ) )
continue ;
}
}
rtype = cli_ftcode ( tokens [ 4 ] ) ;
type = cli_ftcode ( tokens [ 5 ] ) ;
if ( rtype = = CL_TYPE_ERROR | | type = = CL_TYPE_ERROR ) {
2007-12-14 22:39:37 +00:00
ret = CL_EMALFDB ;
break ;
}
2009-08-04 20:22:03 +02:00
if ( ! cli_isnumber ( tokens [ 0 ] ) ) {
cli_errmsg ( " cli_loadftm: Invalid value for the first field \n " ) ;
ret = CL_EMALFDB ;
break ;
}
2008-02-20 22:04:48 +00:00
if ( atoi ( tokens [ 0 ] ) = = 1 ) { /* A-C */
2009-08-14 14:38:13 +02:00
if ( ( ret = cli_parse_add ( engine - > root [ 0 ] , tokens [ 3 ] , tokens [ 2 ] , rtype , type , tokens [ 1 ] , 0 , NULL , options ) ) )
2007-12-14 22:39:37 +00:00
break ;
2008-02-20 22:04:48 +00:00
} else if ( atoi ( tokens [ 0 ] ) = = 0 ) { /* memcmp() */
2009-08-04 20:22:03 +02:00
if ( ! cli_isnumber ( tokens [ 1 ] ) ) {
cli_errmsg ( " cli_loadftm: Invalid offset \n " ) ;
ret = CL_EMALFDB ;
break ;
}
2009-01-26 19:47:02 +00:00
new = ( struct cli_ftype * ) mpool_malloc ( engine - > mempool , sizeof ( struct cli_ftype ) ) ;
2007-12-14 22:39:37 +00:00
if ( ! new ) {
ret = CL_EMEM ;
break ;
}
new - > type = type ;
2008-02-20 22:04:48 +00:00
new - > offset = atoi ( tokens [ 1 ] ) ;
2009-01-26 19:47:02 +00:00
new - > magic = ( unsigned char * ) cli_mpool_hex2str ( engine - > mempool , tokens [ 2 ] ) ;
2007-12-14 22:39:37 +00:00
if ( ! new - > magic ) {
2008-02-20 22:04:48 +00:00
cli_errmsg ( " cli_loadftm: Can't decode the hex string \n " ) ;
2007-12-14 22:39:37 +00:00
ret = CL_EMALFDB ;
2009-01-26 19:47:02 +00:00
mpool_free ( engine - > mempool , new ) ;
2007-12-14 22:39:37 +00:00
break ;
}
2008-02-20 22:04:48 +00:00
new - > length = strlen ( tokens [ 2 ] ) / 2 ;
2009-01-26 19:47:02 +00:00
new - > tname = cli_mpool_strdup ( engine - > mempool , tokens [ 3 ] ) ;
2007-12-14 22:39:37 +00:00
if ( ! new - > tname ) {
2009-01-26 19:47:02 +00:00
mpool_free ( engine - > mempool , new - > magic ) ;
mpool_free ( engine - > mempool , new ) ;
2007-12-14 22:39:37 +00:00
ret = CL_EMEM ;
break ;
}
2008-11-11 21:23:34 +00:00
new - > next = engine - > ftypes ;
engine - > ftypes = new ;
2008-02-20 22:04:48 +00:00
} else {
cli_dbgmsg ( " cli_loadftm: Unsupported mode %u \n " , atoi ( tokens [ 0 ] ) ) ;
continue ;
2007-12-14 22:39:37 +00:00
}
2008-02-20 22:04:48 +00:00
sigs + + ;
2007-12-14 22:39:37 +00:00
}
2008-02-20 22:04:48 +00:00
if ( ret ) {
cli_errmsg ( " Problem parsing %s filetype database at line %u \n " , internal ? " built-in " : " external " , line ) ;
return ret ;
2007-12-14 22:39:37 +00:00
}
2008-02-20 22:04:48 +00:00
if ( ! sigs ) {
cli_errmsg ( " Empty %s filetype database \n " , internal ? " built-in " : " external " ) ;
return CL_EMALFDB ;
2007-12-14 22:39:37 +00:00
}
2008-02-20 22:04:48 +00:00
cli_dbgmsg ( " Loaded %u filetype definitions \n " , sigs ) ;
2007-12-14 22:39:37 +00:00
return CL_SUCCESS ;
}
2010-01-25 13:28:19 +01:00
# define INFO_NSTR "11088894983048545473659556106627194923928941791795047620591658697413581043322715912172496806525381055880964520618400224333320534660299233983755341740679502866829909679955734391392668378361221524205396631090105151641270857277080310734320951653700508941717419168723942507890702904702707587451621691050754307850383399865346487203798464178537392211402786481359824461197231102895415093770394216666324484593935762408468516826633192140826667923494822045805347809932848454845886971706424360558667862775876072059437703365380209101697738577515476935085469455279994113145977994084618328482151013142393373316337519977244732747977"
# define INFO_ESTR "100002049"
# define INFO_TOKENS 3
2010-01-20 22:10:56 +01:00
static int cli_loadinfo ( FILE * fs , struct cl_engine * engine , unsigned int options , struct cli_dbio * dbio )
{
2010-01-25 13:28:19 +01:00
const char * tokens [ INFO_TOKENS + 1 ] ;
2010-01-20 22:10:56 +01:00
char buffer [ FILEBUFF ] ;
2010-01-25 13:28:19 +01:00
unsigned int line = 0 , tokens_count , len ;
unsigned char hash [ 32 ] ;
2010-01-20 22:10:56 +01:00
struct cli_dbinfo * last = NULL , * new ;
2010-01-25 13:28:19 +01:00
int ret = CL_SUCCESS , dsig = 0 ;
SHA256_CTX ctx ;
2010-01-20 22:10:56 +01:00
2010-01-25 13:28:19 +01:00
sha256_init ( & ctx ) ;
2010-01-20 22:10:56 +01:00
while ( cli_dbgets ( buffer , FILEBUFF , fs , dbio ) ) {
line + + ;
2010-01-25 13:28:19 +01:00
if ( ! strncmp ( buffer , " DSIG: " , 5 ) ) {
dsig = 1 ;
sha256_final ( & ctx , hash ) ;
if ( cli_versig2 ( hash , buffer + 5 , INFO_NSTR , INFO_ESTR ) ! = CL_SUCCESS ) {
cli_errmsg ( " cli_loadinfo: Incorrect digital signature \n " ) ;
ret = CL_EMALFDB ;
}
break ;
}
len = strlen ( buffer ) ;
if ( dbio - > usebuf & & buffer [ len - 1 ] ! = ' \n ' & & len + 1 < FILEBUFF ) {
/* cli_dbgets in buffered mode strips \n */
buffer [ len ] = ' \n ' ;
buffer [ len + 1 ] = 0 ;
}
sha256_update ( & ctx , buffer , strlen ( buffer ) ) ;
2010-01-20 22:10:56 +01:00
cli_chomp ( buffer ) ;
if ( ! strncmp ( " ClamAV-VDB: " , buffer , 11 ) ) {
if ( engine - > dbinfo ) { /* shouldn't be initialized at this point */
cli_errmsg ( " cli_loadinfo: engine->dbinfo already initialized \n " ) ;
ret = CL_EMALFDB ;
break ;
}
last = engine - > dbinfo = ( struct cli_dbinfo * ) mpool_calloc ( engine - > mempool , 1 , sizeof ( struct cli_bm_patt ) ) ;
if ( ! engine - > dbinfo ) {
ret = CL_EMEM ;
break ;
}
engine - > dbinfo - > cvd = cl_cvdparse ( buffer ) ;
if ( ! engine - > dbinfo - > cvd ) {
cli_errmsg ( " cli_loadinfo: Can't parse header entry \n " ) ;
ret = CL_EMALFDB ;
break ;
}
continue ;
}
if ( ! last ) {
cli_errmsg ( " cli_loadinfo: Incorrect file format \n " ) ;
ret = CL_EMALFDB ;
break ;
}
2010-01-25 13:28:19 +01:00
tokens_count = cli_strtokenize ( buffer , ' : ' , INFO_TOKENS + 1 , tokens ) ;
if ( tokens_count ! = INFO_TOKENS ) {
2010-01-20 22:10:56 +01:00
ret = CL_EMALFDB ;
break ;
}
new = ( struct cli_dbinfo * ) mpool_calloc ( engine - > mempool , 1 , sizeof ( struct cli_dbinfo ) ) ;
if ( ! new ) {
ret = CL_EMEM ;
break ;
}
2010-04-13 16:19:47 +03:00
new - > name = cli_mpool_strdup ( engine - > mempool , tokens [ 0 ] ) ;
2010-01-20 22:10:56 +01:00
if ( ! new - > name ) {
mpool_free ( engine - > mempool , new ) ;
ret = CL_EMEM ;
break ;
}
2010-01-25 13:28:19 +01:00
if ( ! cli_isnumber ( tokens [ 1 ] ) ) {
cli_errmsg ( " cli_loadinfo: Invalid value in the size field \n " ) ;
2010-01-20 22:10:56 +01:00
mpool_free ( engine - > mempool , new - > name ) ;
mpool_free ( engine - > mempool , new ) ;
ret = CL_EMALFDB ;
break ;
}
2010-01-25 13:28:19 +01:00
new - > size = atoi ( tokens [ 1 ] ) ;
2010-01-20 22:10:56 +01:00
2010-01-25 13:28:19 +01:00
if ( strlen ( tokens [ 2 ] ) ! = 64 | | ! ( new - > hash = cli_mpool_hex2str ( engine - > mempool , tokens [ 2 ] ) ) ) {
cli_errmsg ( " cli_loadinfo: Malformed SHA256 string at line %u \n " , line ) ;
mpool_free ( engine - > mempool , new - > name ) ;
mpool_free ( engine - > mempool , new ) ;
ret = CL_EMALFDB ;
break ;
}
2010-01-20 22:10:56 +01:00
last - > next = new ;
last = new ;
}
2010-01-25 13:28:19 +01:00
if ( ! dsig ) {
cli_errmsg ( " cli_loadinfo: Digital signature not found \n " ) ;
return CL_EMALFDB ;
}
2010-01-20 22:10:56 +01:00
if ( ret ) {
cli_errmsg ( " cli_loadinfo: Problem parsing database at line %u \n " , line ) ;
return ret ;
}
return CL_SUCCESS ;
}
2009-09-28 19:33:59 +02:00
# define IGN_MAX_TOKENS 3
2008-11-11 21:23:34 +00:00
static int cli_loadign ( FILE * fs , struct cl_engine * engine , unsigned int options , struct cli_dbio * dbio )
2008-02-08 19:32:45 +00:00
{
2009-09-28 19:33:59 +02:00
const char * tokens [ IGN_MAX_TOKENS + 1 ] , * signame , * hash = NULL ;
2008-11-06 14:27:43 +00:00
char buffer [ FILEBUFF ] ;
2010-01-12 16:16:08 +01:00
unsigned int line = 0 , tokens_count , len ;
2009-09-28 19:33:59 +02:00
struct cli_bm_patt * new ;
2008-11-04 18:45:48 +00:00
int ret = CL_SUCCESS ;
2008-02-08 19:32:45 +00:00
2008-11-11 21:23:34 +00:00
if ( ! engine - > ignored ) {
2009-09-28 19:33:59 +02:00
engine - > ignored = ( struct cli_matcher * ) mpool_calloc ( engine - > mempool , 1 , sizeof ( struct cli_matcher ) ) ;
if ( ! engine - > ignored )
2008-02-08 19:32:45 +00:00
return CL_EMEM ;
2009-09-28 19:33:59 +02:00
# ifdef USE_MPOOL
engine - > ignored - > mempool = engine - > mempool ;
# endif
if ( ( ret = cli_bm_init ( engine - > ignored ) ) ) {
cli_errmsg ( " cli_loadign: Can't initialise AC pattern matcher \n " ) ;
return ret ;
}
2008-02-08 19:32:45 +00:00
}
2008-05-18 21:32:27 +00:00
while ( cli_dbgets ( buffer , FILEBUFF , fs , dbio ) ) {
2008-02-08 19:32:45 +00:00
line + + ;
cli_chomp ( buffer ) ;
2009-09-28 19:33:59 +02:00
tokens_count = cli_strtokenize ( buffer , ' : ' , IGN_MAX_TOKENS + 1 , tokens ) ;
if ( tokens_count > IGN_MAX_TOKENS ) {
2009-01-05 19:57:47 +00:00
ret = CL_EMALFDB ;
break ;
}
2008-11-04 19:18:27 +00:00
2009-09-28 19:33:59 +02:00
if ( tokens_count = = 1 ) {
signame = buffer ;
} else if ( tokens_count = = 2 ) {
signame = tokens [ 0 ] ;
hash = tokens [ 1 ] ;
} else { /* old mode */
signame = tokens [ 2 ] ;
}
if ( ! ( len = strlen ( signame ) ) ) {
cli_errmsg ( " cli_loadign: No signature name provided \n " ) ;
2009-08-04 20:22:03 +02:00
ret = CL_EMALFDB ;
break ;
}
2009-09-28 19:33:59 +02:00
new = ( struct cli_bm_patt * ) mpool_calloc ( engine - > mempool , 1 , sizeof ( struct cli_bm_patt ) ) ;
2008-02-08 19:32:45 +00:00
if ( ! new ) {
ret = CL_EMEM ;
break ;
}
2010-01-12 16:16:08 +01:00
new - > pattern = ( unsigned char * ) cli_mpool_strdup ( engine - > mempool , signame ) ;
2009-09-28 19:33:59 +02:00
if ( ! new - > pattern ) {
2009-01-26 19:47:02 +00:00
mpool_free ( engine - > mempool , new ) ;
2009-09-28 19:33:59 +02:00
ret = CL_EMEM ;
2008-02-08 19:32:45 +00:00
break ;
}
2009-09-28 19:33:59 +02:00
if ( hash ) {
2010-01-12 16:16:08 +01:00
if ( strlen ( hash ) ! = 32 | | ! ( new - > virname = ( char * ) cli_mpool_hex2str ( engine - > mempool , hash ) ) ) {
2009-09-28 19:33:59 +02:00
cli_errmsg ( " cli_loadign: Malformed MD5 string at line %u \n " , line ) ;
mpool_free ( engine - > mempool , new - > pattern ) ;
mpool_free ( engine - > mempool , new ) ;
ret = CL_EMALFDB ;
break ;
}
}
new - > length = len ;
new - > boundary | = BM_BOUNDARY_EOL ;
2008-02-08 19:32:45 +00:00
2009-09-28 19:33:59 +02:00
if ( ( ret = cli_bm_addpatt ( engine - > ignored , new , " 0 " ) ) ) {
if ( hash )
mpool_free ( engine - > mempool , new - > virname ) ;
mpool_free ( engine - > mempool , new - > pattern ) ;
2009-01-26 19:47:02 +00:00
mpool_free ( engine - > mempool , new ) ;
2008-02-08 19:32:45 +00:00
break ;
}
}
if ( ret ) {
cli_errmsg ( " cli_loadign: Problem parsing database at line %u \n " , line ) ;
return ret ;
}
return CL_SUCCESS ;
}
2007-10-05 13:29:59 +00:00
# define MD5_HDB 0
# define MD5_MDB 1
# define MD5_FP 2
2007-12-15 20:34:31 +00:00
2008-11-11 21:23:34 +00:00
static int cli_md5db_init ( struct cl_engine * engine , unsigned int mode )
2007-12-15 20:34:31 +00:00
{
struct cli_matcher * bm = NULL ;
int ret ;
if ( mode = = MD5_HDB ) {
2009-01-26 19:47:02 +00:00
bm = engine - > md5_hdb = ( struct cli_matcher * ) mpool_calloc ( engine - > mempool , sizeof ( struct cli_matcher ) , 1 ) ;
2007-12-15 20:34:31 +00:00
} else if ( mode = = MD5_MDB ) {
2009-01-26 19:47:02 +00:00
bm = engine - > md5_mdb = ( struct cli_matcher * ) mpool_calloc ( engine - > mempool , sizeof ( struct cli_matcher ) , 1 ) ;
2007-12-15 20:34:31 +00:00
} else {
2009-01-26 19:47:02 +00:00
bm = engine - > md5_fp = ( struct cli_matcher * ) mpool_calloc ( engine - > mempool , sizeof ( struct cli_matcher ) , 1 ) ;
2007-12-15 20:34:31 +00:00
}
if ( ! bm )
return CL_EMEM ;
2008-10-18 00:16:23 +00:00
# ifdef USE_MPOOL
2008-11-11 21:23:34 +00:00
bm - > mempool = engine - > mempool ;
2008-10-18 00:16:23 +00:00
# endif
2007-12-15 20:34:31 +00:00
if ( ( ret = cli_bm_init ( bm ) ) ) {
cli_errmsg ( " cli_md5db_init: Failed to initialize B-M \n " ) ;
return ret ;
}
return CL_SUCCESS ;
}
# define MD5_DB \
if ( mode = = MD5_HDB ) \
2008-11-11 21:23:34 +00:00
db = engine - > md5_hdb ; \
2007-12-15 20:34:31 +00:00
else if ( mode = = MD5_MDB ) \
2008-11-11 21:23:34 +00:00
db = engine - > md5_mdb ; \
2007-12-15 20:34:31 +00:00
else \
2008-11-11 21:23:34 +00:00
db = engine - > md5_fp ;
2007-12-15 20:34:31 +00:00
2008-05-16 08:15:26 +00:00
# define MD5_TOKENS 3
2008-11-11 21:23:34 +00:00
static int cli_loadmd5 ( FILE * fs , struct cl_engine * engine , unsigned int * signo , unsigned int mode , unsigned int options , struct cli_dbio * dbio , const char * dbname )
2004-07-13 03:30:49 +00:00
{
2009-01-05 19:57:47 +00:00
const char * tokens [ MD5_TOKENS + 1 ] ;
2010-01-12 16:16:08 +01:00
char buffer [ FILEBUFF ] , * buffer_cpy = NULL ;
2008-05-16 08:15:26 +00:00
const char * pt ;
2007-04-30 14:12:38 +00:00
int ret = CL_SUCCESS ;
2009-01-05 19:57:47 +00:00
unsigned int size_field = 1 , md5_field = 0 , line = 0 , sigs = 0 , tokens_count ;
2007-12-15 20:34:31 +00:00
struct cli_bm_patt * new ;
struct cli_matcher * db = NULL ;
2003-07-29 15:48:06 +00:00
2004-07-13 03:30:49 +00:00
2007-10-05 13:29:59 +00:00
if ( mode = = MD5_MDB ) {
size_field = 0 ;
md5_field = 1 ;
2006-10-15 23:14:42 +00:00
}
2009-09-28 19:33:59 +02:00
if ( engine - > ignored )
if ( ! ( buffer_cpy = cli_malloc ( FILEBUFF ) ) )
return CL_EMEM ;
2008-05-18 21:32:27 +00:00
while ( cli_dbgets ( buffer , FILEBUFF , fs , dbio ) ) {
2003-07-29 15:48:06 +00:00
line + + ;
cli_chomp ( buffer ) ;
2009-09-28 19:33:59 +02:00
if ( engine - > ignored )
strcpy ( buffer_cpy , buffer ) ;
2009-01-05 19:57:47 +00:00
tokens_count = cli_strtokenize ( buffer , ' : ' , MD5_TOKENS + 1 , tokens ) ;
if ( tokens_count ! = MD5_TOKENS ) {
2008-07-31 16:26:50 +00:00
ret = CL_EMALFDB ;
break ;
}
2009-08-04 20:22:03 +02:00
if ( ! cli_isnumber ( tokens [ size_field ] ) ) {
cli_errmsg ( " cli_loadmd5: Invalid value for the size field \n " ) ;
ret = CL_EMALFDB ;
break ;
}
2008-07-31 16:26:50 +00:00
2009-01-05 19:57:47 +00:00
pt = tokens [ 2 ] ; /* virname */
2008-11-11 21:23:34 +00:00
if ( engine - > pua_cats & & ( options & CL_DB_PUA_MODE ) & & ( options & ( CL_DB_PUA_INCLUDE | CL_DB_PUA_EXCLUDE ) ) )
if ( cli_chkpua ( pt , engine - > pua_cats , options ) )
2008-07-31 16:26:50 +00:00
continue ;
2009-09-28 19:33:59 +02:00
if ( engine - > ignored & & cli_chkign ( engine - > ignored , pt , buffer_cpy ) )
2008-07-31 16:26:50 +00:00
continue ;
2009-01-26 19:47:02 +00:00
new = ( struct cli_bm_patt * ) mpool_calloc ( engine - > mempool , 1 , sizeof ( struct cli_bm_patt ) ) ;
2004-07-13 03:30:49 +00:00
if ( ! new ) {
ret = CL_EMEM ;
break ;
2003-07-29 15:48:06 +00:00
}
2009-01-05 19:57:47 +00:00
pt = tokens [ md5_field ] ; /* md5 */
2009-01-26 19:47:02 +00:00
if ( strlen ( pt ) ! = 32 | | ! ( new - > pattern = ( unsigned char * ) cli_mpool_hex2str ( engine - > mempool , pt ) ) ) {
2008-10-18 00:16:23 +00:00
cli_errmsg ( " cli_loadmd5: Malformed MD5 string at line %u \n " , line ) ;
2009-01-26 19:47:02 +00:00
mpool_free ( engine - > mempool , new ) ;
2008-10-18 00:16:23 +00:00
ret = CL_EMALFDB ;
break ;
}
2007-12-15 20:34:31 +00:00
new - > length = 16 ;
2003-07-29 15:48:06 +00:00
2009-10-02 21:03:26 +02:00
new - > filesize = atoi ( tokens [ size_field ] ) ;
2004-07-27 23:22:44 +00:00
2010-01-12 16:16:08 +01:00
new - > virname = cli_mpool_virname ( engine - > mempool , tokens [ 2 ] , options & CL_DB_OFFICIAL ) ;
2008-10-18 00:16:23 +00:00
if ( ! new - > virname ) {
2009-01-26 19:47:02 +00:00
mpool_free ( engine - > mempool , new - > pattern ) ;
mpool_free ( engine - > mempool , new ) ;
2004-07-13 03:30:49 +00:00
ret = CL_EMALFDB ;
break ;
2003-07-29 15:48:06 +00:00
}
2004-07-13 03:30:49 +00:00
2007-12-15 20:34:31 +00:00
MD5_DB ;
if ( ! db & & ( ret = cli_md5db_init ( engine , mode ) ) ) {
2009-01-26 19:47:02 +00:00
mpool_free ( engine - > mempool , new - > pattern ) ;
mpool_free ( engine - > mempool , new - > virname ) ;
mpool_free ( engine - > mempool , new ) ;
2007-12-15 20:34:31 +00:00
break ;
} else {
MD5_DB ;
}
2007-04-30 14:12:38 +00:00
2009-08-14 14:38:13 +02:00
if ( ( ret = cli_bm_addpatt ( db , new , " 0 " ) ) ) {
2007-12-15 20:34:31 +00:00
cli_errmsg ( " cli_loadmd5: Error adding BM pattern \n " ) ;
2009-01-26 19:47:02 +00:00
mpool_free ( engine - > mempool , new - > pattern ) ;
mpool_free ( engine - > mempool , new - > virname ) ;
mpool_free ( engine - > mempool , new ) ;
2007-12-15 20:34:31 +00:00
break ;
}
2007-04-30 14:12:38 +00:00
2007-12-15 20:34:31 +00:00
if ( mode = = MD5_MDB ) { /* section MD5 */
2008-02-06 18:53:23 +00:00
if ( ! db - > md5_sizes_hs . capacity ) {
2009-08-04 23:17:28 +02:00
cli_hashset_init ( & db - > md5_sizes_hs , 65536 , 80 ) ;
2004-07-19 17:54:40 +00:00
}
2009-10-02 21:03:26 +02:00
cli_hashset_addkey ( & db - > md5_sizes_hs , new - > filesize ) ;
2006-09-27 00:36:11 +00:00
}
2008-02-08 19:32:45 +00:00
sigs + + ;
2003-07-29 15:48:06 +00:00
}
2009-09-28 19:33:59 +02:00
if ( engine - > ignored )
free ( buffer_cpy ) ;
2003-07-29 15:48:06 +00:00
2004-07-13 03:30:49 +00:00
if ( ! line ) {
2007-10-05 13:29:59 +00:00
cli_errmsg ( " cli_loadmd5: Empty database file \n " ) ;
2004-07-13 03:30:49 +00:00
return CL_EMALFDB ;
}
2003-07-29 15:48:06 +00:00
2004-07-13 03:30:49 +00:00
if ( ret ) {
2007-10-05 13:29:59 +00:00
cli_errmsg ( " cli_loadmd5: Problem parsing database at line %u \n " , line ) ;
2004-07-13 03:30:49 +00:00
return ret ;
}
2004-02-01 01:18:57 +00:00
2004-09-13 16:44:01 +00:00
if ( signo )
2008-02-08 19:32:45 +00:00
* signo + = sigs ;
2004-08-31 18:46:00 +00:00
2006-05-18 11:29:24 +00:00
return CL_SUCCESS ;
2003-07-29 15:48:06 +00:00
}
2008-11-04 19:18:27 +00:00
# define MD_TOKENS 9
2008-11-11 21:23:34 +00:00
static int cli_loadmd ( FILE * fs , struct cl_engine * engine , unsigned int * signo , int type , unsigned int options , struct cli_dbio * dbio , const char * dbname )
2005-02-20 04:14:06 +00:00
{
2009-01-05 19:57:47 +00:00
const char * tokens [ MD_TOKENS + 1 ] ;
2010-01-12 16:16:08 +01:00
char buffer [ FILEBUFF ] , * buffer_cpy = NULL ;
2009-01-05 19:57:47 +00:00
unsigned int line = 0 , sigs = 0 , tokens_count ;
2010-01-12 16:16:08 +01:00
int ret = CL_SUCCESS ;
2010-01-08 15:20:33 +01:00
struct cli_cdb * new ;
2005-02-20 04:14:06 +00:00
2009-09-28 19:33:59 +02:00
if ( engine - > ignored )
if ( ! ( buffer_cpy = cli_malloc ( FILEBUFF ) ) )
return CL_EMEM ;
2008-05-18 21:32:27 +00:00
while ( cli_dbgets ( buffer , FILEBUFF , fs , dbio ) ) {
2005-02-20 04:14:06 +00:00
line + + ;
2008-02-08 19:32:45 +00:00
if ( buffer [ 0 ] = = ' # ' )
2005-02-20 04:14:06 +00:00
continue ;
cli_chomp ( buffer ) ;
2009-09-28 19:33:59 +02:00
if ( engine - > ignored )
strcpy ( buffer_cpy , buffer ) ;
2009-01-05 19:57:47 +00:00
tokens_count = cli_strtokenize ( buffer , ' : ' , MD_TOKENS + 1 , tokens ) ;
if ( tokens_count ! = MD_TOKENS ) {
ret = CL_EMALFDB ;
break ;
}
2005-02-20 04:14:06 +00:00
2009-08-04 20:22:03 +02:00
if ( strcmp ( tokens [ 1 ] , " * " ) & & ! cli_isnumber ( tokens [ 1 ] ) ) {
cli_errmsg ( " cli_loadmd: Invalid value for the 'encrypted' field \n " ) ;
ret = CL_EMALFDB ;
break ;
}
if ( strcmp ( tokens [ 3 ] , " * " ) & & ! cli_isnumber ( tokens [ 3 ] ) ) {
cli_errmsg ( " cli_loadmd: Invalid value for the 'original size' field \n " ) ;
ret = CL_EMALFDB ;
break ;
}
if ( strcmp ( tokens [ 4 ] , " * " ) & & ! cli_isnumber ( tokens [ 4 ] ) ) {
cli_errmsg ( " cli_loadmd: Invalid value for the 'compressed size' field \n " ) ;
ret = CL_EMALFDB ;
break ;
}
if ( strcmp ( tokens [ 6 ] , " * " ) & & ! cli_isnumber ( tokens [ 6 ] ) ) {
cli_errmsg ( " cli_loadmd: Invalid value for the 'compression method' field \n " ) ;
ret = CL_EMALFDB ;
break ;
}
if ( strcmp ( tokens [ 7 ] , " * " ) & & ! cli_isnumber ( tokens [ 7 ] ) ) {
cli_errmsg ( " cli_loadmd: Invalid value for the 'file number' field \n " ) ;
ret = CL_EMALFDB ;
break ;
}
if ( strcmp ( tokens [ 8 ] , " * " ) & & ! cli_isnumber ( tokens [ 8 ] ) ) {
cli_errmsg ( " cli_loadmd: Invalid value for the 'max depth' field \n " ) ;
ret = CL_EMALFDB ;
break ;
}
2010-01-08 15:20:33 +01:00
new = ( struct cli_cdb * ) mpool_calloc ( engine - > mempool , 1 , sizeof ( struct cli_cdb ) ) ;
2005-02-20 04:14:06 +00:00
if ( ! new ) {
ret = CL_EMEM ;
break ;
}
2010-01-12 16:16:08 +01:00
new - > virname = cli_mpool_virname ( engine - > mempool , tokens [ 0 ] , options & CL_DB_OFFICIAL ) ;
2008-10-18 00:16:23 +00:00
if ( ! new - > virname ) {
2009-01-26 19:47:02 +00:00
mpool_free ( engine - > mempool , new ) ;
2008-07-03 11:19:21 +00:00
ret = CL_EMEM ;
2005-02-20 04:14:06 +00:00
break ;
}
2010-01-08 15:20:33 +01:00
new - > ctype = ( type = = 1 ) ? CL_TYPE_ZIP : CL_TYPE_RAR ;
2005-02-20 04:14:06 +00:00
2009-09-28 19:33:59 +02:00
if ( engine - > ignored & & cli_chkign ( engine - > ignored , new - > virname , buffer /*_cpy*/ ) ) {
2009-01-26 19:47:02 +00:00
mpool_free ( engine - > mempool , new - > virname ) ;
mpool_free ( engine - > mempool , new ) ;
2008-02-08 19:32:45 +00:00
continue ;
}
2010-01-14 19:44:56 +01:00
new - > encrypted = strcmp ( tokens [ 1 ] , " * " ) ? atoi ( tokens [ 1 ] ) : 2 ;
2010-01-08 15:20:33 +01:00
if ( strcmp ( tokens [ 2 ] , " * " ) & & cli_regcomp ( & new - > name , tokens [ 2 ] , REG_EXTENDED | REG_NOSUB ) ) {
cli_errmsg ( " cli_loadmd: Can't compile regular expression %s in signature for %s \n " , tokens [ 2 ] , tokens [ 0 ] ) ;
2009-01-26 19:47:02 +00:00
mpool_free ( engine - > mempool , new - > virname ) ;
mpool_free ( engine - > mempool , new ) ;
2010-01-08 15:20:33 +01:00
ret = CL_EMEM ;
2005-02-20 04:14:06 +00:00
break ;
}
2010-01-08 15:20:33 +01:00
new - > csize [ 0 ] = new - > csize [ 1 ] = CLI_OFF_ANY ;
2005-02-20 04:14:06 +00:00
2008-11-04 19:18:27 +00:00
if ( ! strcmp ( tokens [ 3 ] , " * " ) )
2010-01-08 15:20:33 +01:00
new - > fsizer [ 0 ] = new - > fsizer [ 1 ] = CLI_OFF_ANY ;
2008-11-04 19:18:27 +00:00
else
2010-01-08 15:20:33 +01:00
new - > fsizer [ 0 ] = new - > fsizer [ 1 ] = atoi ( tokens [ 3 ] ) ;
2005-02-20 04:14:06 +00:00
2008-11-04 19:18:27 +00:00
if ( ! strcmp ( tokens [ 4 ] , " * " ) )
2010-01-08 15:20:33 +01:00
new - > fsizec [ 0 ] = new - > fsizec [ 1 ] = CLI_OFF_ANY ;
2008-11-04 19:18:27 +00:00
else
2010-01-08 15:20:33 +01:00
new - > fsizec [ 0 ] = new - > fsizec [ 1 ] = atoi ( tokens [ 4 ] ) ;
2005-02-20 04:14:06 +00:00
2010-01-08 15:20:33 +01:00
if ( strcmp ( tokens [ 5 ] , " * " ) ) {
new - > res1 = cli_hex2num ( tokens [ 5 ] ) ;
if ( new - > res1 = = - 1 ) {
mpool_free ( engine - > mempool , new - > virname ) ;
mpool_free ( engine - > mempool , new ) ;
if ( new - > name . re_magic )
cli_regfree ( & new - > name ) ;
2008-11-04 19:18:27 +00:00
ret = CL_EMALFDB ;
break ;
2005-02-20 04:14:06 +00:00
}
}
2010-01-08 15:20:33 +01:00
/* tokens[6] - not used */
2005-02-20 04:14:06 +00:00
2010-01-27 16:06:12 +01:00
new - > filepos [ 0 ] = new - > filepos [ 1 ] = strcmp ( tokens [ 7 ] , " * " ) ? atoi ( tokens [ 7 ] ) : ( int ) CLI_OFF_ANY ;
2005-02-27 01:31:02 +00:00
2010-01-08 15:20:33 +01:00
/* tokens[8] - not used */
2008-02-08 19:32:45 +00:00
2010-01-08 15:20:33 +01:00
new - > next = engine - > cdb ;
engine - > cdb = new ;
2008-02-08 19:32:45 +00:00
sigs + + ;
2005-02-20 04:14:06 +00:00
}
2009-09-28 19:33:59 +02:00
if ( engine - > ignored )
free ( buffer_cpy ) ;
2005-02-20 04:14:06 +00:00
if ( ! line ) {
cli_errmsg ( " Empty database file \n " ) ;
return CL_EMALFDB ;
}
if ( ret ) {
cli_errmsg ( " Problem parsing database at line %d \n " , line ) ;
return ret ;
}
if ( signo )
2008-02-08 19:32:45 +00:00
* signo + = sigs ;
2005-02-20 04:14:06 +00:00
2006-05-18 11:29:24 +00:00
return CL_SUCCESS ;
2005-02-20 04:14:06 +00:00
}
2010-01-14 23:32:35 +01:00
/* 0 1 2 3 4 5 6 7 8 9 10 11
* VirusName : ContainerType : ContainerSize : FileNameREGEX : FileSizeInContainer : FileSizeReal : IsEncrypted : FilePos : Res1 : Res2 [ : MinFL [ : MaxFL ] ]
2010-01-07 18:26:12 +01:00
*/
2010-01-14 23:32:35 +01:00
# define CDB_TOKENS 12
2010-01-07 18:26:12 +01:00
static int cli_loadcdb ( FILE * fs , struct cl_engine * engine , unsigned int * signo , unsigned int options , struct cli_dbio * dbio )
{
2010-01-07 23:22:34 +01:00
const char * tokens [ CDB_TOKENS + 1 ] ;
2010-01-12 16:16:08 +01:00
char buffer [ FILEBUFF ] , * buffer_cpy = NULL ;
2010-01-07 18:26:12 +01:00
unsigned int line = 0 , sigs = 0 , tokens_count , n0 , n1 ;
int ret = CL_SUCCESS ;
struct cli_cdb * new ;
if ( engine - > ignored )
if ( ! ( buffer_cpy = cli_malloc ( FILEBUFF ) ) )
return CL_EMEM ;
while ( cli_dbgets ( buffer , FILEBUFF , fs , dbio ) ) {
line + + ;
if ( buffer [ 0 ] = = ' # ' )
continue ;
cli_chomp ( buffer ) ;
if ( engine - > ignored )
strcpy ( buffer_cpy , buffer ) ;
tokens_count = cli_strtokenize ( buffer , ' : ' , CDB_TOKENS + 1 , tokens ) ;
2010-01-08 15:20:33 +01:00
if ( tokens_count > CDB_TOKENS | | tokens_count < CDB_TOKENS - 2 ) {
2010-01-07 18:26:12 +01:00
ret = CL_EMALFDB ;
break ;
}
2010-01-14 23:32:35 +01:00
if ( tokens_count > 10 ) { /* min version */
if ( ! cli_isnumber ( tokens [ 10 ] ) ) {
2010-01-07 18:26:12 +01:00
ret = CL_EMALFDB ;
break ;
}
2010-01-14 23:32:35 +01:00
if ( ( unsigned int ) atoi ( tokens [ 10 ] ) > cl_retflevel ( ) ) {
2010-01-07 18:26:12 +01:00
cli_dbgmsg ( " cli_loadcdb: Container signature for %s not loaded (required f-level: %u) \n " , tokens [ 0 ] , atoi ( tokens [ 10 ] ) ) ;
continue ;
}
2010-01-14 23:32:35 +01:00
if ( tokens_count = = CDB_TOKENS ) { /* max version */
if ( ! cli_isnumber ( tokens [ 11 ] ) ) {
2010-01-07 18:26:12 +01:00
ret = CL_EMALFDB ;
break ;
}
2010-01-14 23:32:35 +01:00
if ( ( unsigned int ) atoi ( tokens [ 11 ] ) < cl_retflevel ( ) )
2010-01-07 18:26:12 +01:00
continue ;
}
}
new = ( struct cli_cdb * ) mpool_calloc ( engine - > mempool , 1 , sizeof ( struct cli_cdb ) ) ;
if ( ! new ) {
ret = CL_EMEM ;
break ;
}
2010-01-12 16:16:08 +01:00
new - > virname = cli_mpool_virname ( engine - > mempool , tokens [ 0 ] , options & CL_DB_OFFICIAL ) ;
2010-01-07 18:26:12 +01:00
if ( ! new - > virname ) {
mpool_free ( engine - > mempool , new ) ;
ret = CL_EMEM ;
break ;
}
if ( engine - > ignored & & cli_chkign ( engine - > ignored , new - > virname , buffer /*_cpy*/ ) ) {
mpool_free ( engine - > mempool , new - > virname ) ;
mpool_free ( engine - > mempool , new ) ;
continue ;
}
if ( ! strcmp ( tokens [ 1 ] , " * " ) ) {
new - > ctype = CL_TYPE_ANY ;
} else if ( ( new - > ctype = cli_ftcode ( tokens [ 1 ] ) ) = = CL_TYPE_ERROR ) {
2010-01-08 15:20:33 +01:00
cli_dbgmsg ( " cli_loadcdb: Unknown container type %s in signature for %s, skipping \n " , tokens [ 1 ] , tokens [ 0 ] ) ;
2010-01-07 18:26:12 +01:00
mpool_free ( engine - > mempool , new - > virname ) ;
mpool_free ( engine - > mempool , new ) ;
continue ;
}
if ( strcmp ( tokens [ 3 ] , " * " ) & & cli_regcomp ( & new - > name , tokens [ 3 ] , REG_EXTENDED | REG_NOSUB ) ) {
2010-01-08 15:20:33 +01:00
cli_errmsg ( " cli_loadcdb: Can't compile regular expression %s in signature for %s \n " , tokens [ 3 ] , tokens [ 0 ] ) ;
2010-01-07 18:26:12 +01:00
mpool_free ( engine - > mempool , new - > virname ) ;
mpool_free ( engine - > mempool , new ) ;
ret = CL_EMEM ;
break ;
}
# define CDBRANGE(token_str, dest) \
if ( strcmp ( token_str , " * " ) ) { \
if ( strchr ( token_str , ' - ' ) ) { \
if ( sscanf ( token_str , " %u-%u " , & n0 , & n1 ) ! = 2 ) { \
ret = CL_EMALFDB ; \
} else { \
dest [ 0 ] = n0 ; \
dest [ 1 ] = n1 ; \
} \
} else { \
if ( ! cli_isnumber ( token_str ) ) \
ret = CL_EMALFDB ; \
else \
dest [ 0 ] = dest [ 1 ] = atoi ( token_str ) ; \
} \
if ( ret ! = CL_SUCCESS ) { \
2010-01-08 15:20:33 +01:00
cli_errmsg ( " cli_loadcdb: Invalid value %s in signature for %s \n " , \
2010-01-07 18:26:12 +01:00
token_str , tokens [ 0 ] ) ; \
if ( new - > name . re_magic ) \
cli_regfree ( & new - > name ) ; \
mpool_free ( engine - > mempool , new - > virname ) ; \
mpool_free ( engine - > mempool , new ) ; \
ret = CL_EMEM ; \
break ; \
} \
} else { \
dest [ 0 ] = dest [ 1 ] = CLI_OFF_ANY ; \
}
2010-01-14 23:32:35 +01:00
CDBRANGE ( tokens [ 2 ] , new - > csize ) ;
CDBRANGE ( tokens [ 4 ] , new - > fsizec ) ;
CDBRANGE ( tokens [ 5 ] , new - > fsizer ) ;
CDBRANGE ( tokens [ 7 ] , new - > filepos ) ;
2010-01-07 18:26:12 +01:00
2010-01-14 23:32:35 +01:00
if ( ! strcmp ( tokens [ 6 ] , " * " ) ) {
2010-01-07 18:26:12 +01:00
new - > encrypted = 2 ;
} else {
2010-01-14 23:32:35 +01:00
if ( strcmp ( tokens [ 6 ] , " 0 " ) & & strcmp ( tokens [ 6 ] , " 1 " ) ) {
2010-01-08 15:20:33 +01:00
cli_errmsg ( " cli_loadcdb: Invalid encryption flag value in signature for %s \n " , tokens [ 0 ] ) ;
2010-01-07 18:26:12 +01:00
if ( new - > name . re_magic )
cli_regfree ( & new - > name ) ;
mpool_free ( engine - > mempool , new - > virname ) ;
mpool_free ( engine - > mempool , new ) ;
ret = CL_EMEM ;
break ;
}
2010-01-14 23:32:35 +01:00
new - > encrypted = * tokens [ 6 ] - 0x30 ;
2010-01-07 18:26:12 +01:00
}
2010-01-14 23:32:35 +01:00
if ( strcmp ( tokens [ 9 ] , " * " ) ) {
new - > res2 = cli_mpool_strdup ( engine - > mempool , tokens [ 9 ] ) ;
2010-01-07 18:26:12 +01:00
if ( ! new - > res2 ) {
2010-01-08 15:20:33 +01:00
cli_errmsg ( " cli_loadcdb: Can't allocate memory for res2 in signature for %s \n " , tokens [ 0 ] ) ;
2010-01-07 18:26:12 +01:00
if ( new - > name . re_magic )
cli_regfree ( & new - > name ) ;
mpool_free ( engine - > mempool , new - > virname ) ;
mpool_free ( engine - > mempool , new ) ;
ret = CL_EMEM ;
break ;
}
}
new - > next = engine - > cdb ;
engine - > cdb = new ;
sigs + + ;
}
if ( engine - > ignored )
free ( buffer_cpy ) ;
if ( ! line ) {
cli_errmsg ( " Empty database file \n " ) ;
return CL_EMALFDB ;
}
if ( ret ) {
cli_errmsg ( " Problem parsing database at line %u \n " , line ) ;
return ret ;
}
if ( signo )
* signo + = sigs ;
return CL_SUCCESS ;
}
2008-11-11 21:23:34 +00:00
static int cli_loaddbdir ( const char * dirname , struct cl_engine * engine , unsigned int * signo , unsigned int options ) ;
2006-07-26 15:02:22 +00:00
2008-11-11 21:23:34 +00:00
int cli_load ( const char * filename , struct cl_engine * engine , unsigned int * signo , unsigned int options , struct cli_dbio * dbio )
2003-07-29 15:48:06 +00:00
{
2007-12-18 19:23:56 +00:00
FILE * fs = NULL ;
2006-04-07 19:22:21 +00:00
int ret = CL_SUCCESS ;
2006-04-21 12:34:19 +00:00
uint8_t skipped = 0 ;
2008-02-08 19:32:45 +00:00
const char * dbname ;
2006-04-07 19:22:21 +00:00
2004-07-13 03:30:49 +00:00
2008-05-18 21:32:27 +00:00
if ( ! dbio & & ( fs = fopen ( filename , " rb " ) ) = = NULL ) {
2009-08-04 15:14:22 +02:00
if ( options & CL_DB_DIRECTORY ) { /* bb#1624 */
if ( access ( filename , R_OK ) ) {
if ( errno = = ENOENT ) {
cli_dbgmsg ( " Detected race condition, ignoring old file %s \n " , filename ) ;
return CL_SUCCESS ;
}
}
}
2006-04-07 19:22:21 +00:00
cli_errmsg ( " cli_load(): Can't open file %s \n " , filename ) ;
2004-07-13 03:30:49 +00:00
return CL_EOPEN ;
}
2009-09-24 19:07:39 +02:00
if ( ( dbname = strrchr ( filename , * PATHSEP ) ) )
2008-02-08 19:32:45 +00:00
dbname + + ;
else
dbname = filename ;
2004-07-13 03:30:49 +00:00
2008-02-08 19:32:45 +00:00
if ( cli_strbcasestr ( dbname , " .db " ) ) {
2008-05-18 21:32:27 +00:00
ret = cli_loaddb ( fs , engine , signo , options , dbio , dbname ) ;
2008-02-08 19:32:45 +00:00
} else if ( cli_strbcasestr ( dbname , " .cvd " ) ) {
2010-04-22 18:04:01 +02:00
ret = cli_cvdload ( fs , engine , signo , options , 0 , filename ) ;
2007-12-19 22:06:32 +00:00
2008-02-08 19:32:45 +00:00
} else if ( cli_strbcasestr ( dbname , " .cld " ) ) {
2010-04-22 18:04:01 +02:00
ret = cli_cvdload ( fs , engine , signo , options , 1 , filename ) ;
2004-07-13 03:30:49 +00:00
2008-02-08 19:32:45 +00:00
} else if ( cli_strbcasestr ( dbname , " .hdb " ) ) {
2008-05-18 21:32:27 +00:00
ret = cli_loadmd5 ( fs , engine , signo , MD5_HDB , options , dbio , dbname ) ;
2005-03-06 23:40:57 +00:00
2008-02-08 19:32:45 +00:00
} else if ( cli_strbcasestr ( dbname , " .hdu " ) ) {
2007-08-13 18:10:35 +00:00
if ( options & CL_DB_PUA )
2008-07-31 16:26:50 +00:00
ret = cli_loadmd5 ( fs , engine , signo , MD5_HDB , options | CL_DB_PUA_MODE , dbio , dbname ) ;
2007-08-13 18:10:35 +00:00
else
skipped = 1 ;
2008-02-08 19:32:45 +00:00
} else if ( cli_strbcasestr ( dbname , " .fp " ) ) {
2008-05-18 21:32:27 +00:00
ret = cli_loadmd5 ( fs , engine , signo , MD5_FP , options , dbio , dbname ) ;
2004-07-13 03:30:49 +00:00
2008-02-08 19:32:45 +00:00
} else if ( cli_strbcasestr ( dbname , " .mdb " ) ) {
2008-05-18 21:32:27 +00:00
ret = cli_loadmd5 ( fs , engine , signo , MD5_MDB , options , dbio , dbname ) ;
2006-09-27 00:36:11 +00:00
2008-02-08 19:32:45 +00:00
} else if ( cli_strbcasestr ( dbname , " .mdu " ) ) {
2007-08-13 18:10:35 +00:00
if ( options & CL_DB_PUA )
2008-07-31 16:26:50 +00:00
ret = cli_loadmd5 ( fs , engine , signo , MD5_MDB , options | CL_DB_PUA_MODE , dbio , dbname ) ;
2007-08-13 18:10:35 +00:00
else
skipped = 1 ;
2008-02-08 19:32:45 +00:00
} else if ( cli_strbcasestr ( dbname , " .ndb " ) ) {
2008-05-18 21:32:27 +00:00
ret = cli_loadndb ( fs , engine , signo , 0 , options , dbio , dbname ) ;
2006-01-25 12:11:31 +00:00
2008-02-08 19:32:45 +00:00
} else if ( cli_strbcasestr ( dbname , " .ndu " ) ) {
2007-09-07 14:22:10 +00:00
if ( ! ( options & CL_DB_PUA ) )
2007-08-13 18:10:35 +00:00
skipped = 1 ;
else
2008-07-31 16:26:50 +00:00
ret = cli_loadndb ( fs , engine , signo , 0 , options | CL_DB_PUA_MODE , dbio , dbname ) ;
2007-08-13 18:10:35 +00:00
2008-07-25 19:00:25 +00:00
} else if ( cli_strbcasestr ( filename , " .ldb " ) ) {
ret = cli_loadldb ( fs , engine , signo , options , dbio , dbname ) ;
} else if ( cli_strbcasestr ( filename , " .ldu " ) ) {
if ( options & CL_DB_PUA )
2008-07-31 16:26:50 +00:00
ret = cli_loadldb ( fs , engine , signo , options | CL_DB_PUA_MODE , dbio , dbname ) ;
2008-07-25 19:00:25 +00:00
else
skipped = 1 ;
2009-09-21 19:24:16 +03:00
} else if ( cli_strbcasestr ( filename , " .cbc " ) ) {
if ( options & CL_DB_BYTECODE )
ret = cli_loadcbc ( fs , engine , signo , options , dbio , dbname ) ;
else
skipped = 1 ;
2008-02-08 19:32:45 +00:00
} else if ( cli_strbcasestr ( dbname , " .sdb " ) ) {
2008-05-18 21:32:27 +00:00
ret = cli_loadndb ( fs , engine , signo , 1 , options , dbio , dbname ) ;
2004-09-14 01:33:32 +00:00
2008-02-08 19:32:45 +00:00
} else if ( cli_strbcasestr ( dbname , " .zmd " ) ) {
2008-05-18 21:32:27 +00:00
ret = cli_loadmd ( fs , engine , signo , 1 , options , dbio , dbname ) ;
2005-03-18 01:27:45 +00:00
2008-02-08 19:32:45 +00:00
} else if ( cli_strbcasestr ( dbname , " .rmd " ) ) {
2008-05-18 21:32:27 +00:00
ret = cli_loadmd ( fs , engine , signo , 2 , options , dbio , dbname ) ;
2005-02-20 04:14:06 +00:00
2008-02-08 19:32:45 +00:00
} else if ( cli_strbcasestr ( dbname , " .cfg " ) ) {
2008-05-18 21:32:27 +00:00
ret = cli_dconf_load ( fs , engine , options , dbio ) ;
2007-01-09 20:06:51 +00:00
2010-01-20 22:10:56 +01:00
} else if ( cli_strbcasestr ( dbname , " .info " ) ) {
ret = cli_loadinfo ( fs , engine , options , dbio ) ;
2008-02-08 19:32:45 +00:00
} else if ( cli_strbcasestr ( dbname , " .wdb " ) ) {
2007-12-18 19:23:56 +00:00
if ( options & CL_DB_PHISHING_URLS ) {
2008-05-18 21:32:27 +00:00
ret = cli_loadwdb ( fs , engine , options , dbio ) ;
2007-12-18 19:23:56 +00:00
} else
2006-09-12 17:50:04 +00:00
skipped = 1 ;
2009-03-06 16:39:04 +00:00
} else if ( cli_strbcasestr ( dbname , " .pdb " ) | | cli_strbcasestr ( dbname , " .gdb " ) ) {
2007-12-18 19:23:56 +00:00
if ( options & CL_DB_PHISHING_URLS ) {
2009-03-05 19:09:54 +00:00
ret = cli_loadpdb ( fs , engine , signo , options , dbio ) ;
2007-12-18 19:23:56 +00:00
} else
2006-09-12 17:50:04 +00:00
skipped = 1 ;
2008-02-20 22:04:48 +00:00
} else if ( cli_strbcasestr ( dbname , " .ftm " ) ) {
2008-05-18 21:32:27 +00:00
ret = cli_loadftm ( fs , engine , options , 0 , dbio ) ;
2007-12-14 22:39:37 +00:00
2009-09-28 19:33:59 +02:00
} else if ( cli_strbcasestr ( dbname , " .ign " ) | | cli_strbcasestr ( dbname , " .ign2 " ) ) {
2008-05-18 21:32:27 +00:00
ret = cli_loadign ( fs , engine , options , dbio ) ;
2008-02-08 19:32:45 +00:00
2009-12-07 19:10:34 +01:00
} else if ( cli_strbcasestr ( dbname , " .idb " ) ) {
ret = cli_loadidb ( fs , engine , signo , options , dbio ) ;
2009-12-06 19:49:40 +01:00
2010-01-07 18:26:12 +01:00
} else if ( cli_strbcasestr ( dbname , " .cdb " ) ) {
ret = cli_loadcdb ( fs , engine , signo , options , dbio ) ;
2004-07-13 03:30:49 +00:00
} else {
2006-04-07 19:22:21 +00:00
cli_dbgmsg ( " cli_load: unknown extension - assuming old database format \n " ) ;
2008-05-18 21:32:27 +00:00
ret = cli_loaddb ( fs , engine , signo , options , dbio , dbname ) ;
2004-07-13 03:30:49 +00:00
}
2006-04-21 12:34:19 +00:00
if ( ret ) {
2005-02-01 02:49:07 +00:00
cli_errmsg ( " Can't load %s: %s \n " , filename , cl_strerror ( ret ) ) ;
2006-04-21 12:34:19 +00:00
} else {
if ( skipped )
cli_dbgmsg ( " %s skipped \n " , filename ) ;
else
cli_dbgmsg ( " %s loaded \n " , filename ) ;
}
2004-07-13 03:30:49 +00:00
2007-12-18 19:23:56 +00:00
if ( fs )
fclose ( fs ) ;
2004-07-13 03:30:49 +00:00
return ret ;
2003-07-29 15:48:06 +00:00
}
2008-11-11 21:23:34 +00:00
static int cli_loaddbdir ( const char * dirname , struct cl_engine * engine , unsigned int * signo , unsigned int options )
2003-07-29 15:48:06 +00:00
{
DIR * dd ;
struct dirent * dent ;
2004-10-03 15:12:13 +00:00
# if defined(HAVE_READDIR_R_3) || defined(HAVE_READDIR_R_2)
2004-11-02 04:08:09 +00:00
union {
struct dirent d ;
char b [ offsetof ( struct dirent , d_name ) + NAME_MAX + 1 ] ;
} result ;
2004-10-03 15:12:13 +00:00
# endif
2003-07-29 15:48:06 +00:00
char * dbfile ;
2009-11-03 22:54:10 +01:00
int ret = CL_EOPEN , have_cld ;
struct cl_cvd * daily_cld , * daily_cvd ;
2003-07-29 15:48:06 +00:00
2007-03-06 23:24:28 +00:00
cli_dbgmsg ( " Loading databases from %s \n " , dirname ) ;
2009-09-28 19:33:59 +02:00
if ( ( dd = opendir ( dirname ) ) = = NULL ) {
cli_errmsg ( " cli_loaddbdir(): Can't open directory %s \n " , dirname ) ;
return CL_EOPEN ;
}
/* first round - load .ign and .ign2 files */
# ifdef HAVE_READDIR_R_3
while ( ! readdir_r ( dd , & result . d , & dent ) & & dent ) {
# elif defined(HAVE_READDIR_R_2)
while ( ( dent = ( struct dirent * ) readdir_r ( dd , & result . d ) ) ) {
# else
while ( ( dent = readdir ( dd ) ) ) {
# endif
if ( dent - > d_ino )
{
if ( cli_strbcasestr ( dent - > d_name , " .ign " ) | | cli_strbcasestr ( dent - > d_name , " .ign2 " ) ) {
dbfile = ( char * ) cli_malloc ( strlen ( dent - > d_name ) + strlen ( dirname ) + 2 ) ;
if ( ! dbfile ) {
cli_dbgmsg ( " cli_loaddbdir(): dbfile == NULL \n " ) ;
closedir ( dd ) ;
return CL_EMEM ;
}
sprintf ( dbfile , " %s " PATHSEP " %s " , dirname , dent - > d_name ) ;
ret = cli_load ( dbfile , engine , signo , options , NULL ) ;
if ( ret ) {
cli_dbgmsg ( " cli_loaddbdir(): error loading database %s \n " , dbfile ) ;
free ( dbfile ) ;
closedir ( dd ) ;
return ret ;
}
free ( dbfile ) ;
}
}
}
/* the daily db must be loaded before main */
2008-02-08 19:32:45 +00:00
dbfile = ( char * ) cli_malloc ( strlen ( dirname ) + 20 ) ;
2009-09-28 19:33:59 +02:00
if ( ! dbfile ) {
closedir ( dd ) ;
2007-03-06 23:24:28 +00:00
return CL_EMEM ;
2008-02-08 19:32:45 +00:00
}
2009-09-24 19:07:39 +02:00
sprintf ( dbfile , " %s " PATHSEP " daily.cld " , dirname ) ;
2009-11-03 22:54:10 +01:00
have_cld = ! access ( dbfile , R_OK ) ;
if ( have_cld ) {
daily_cld = cl_cvdhead ( dbfile ) ;
if ( ! daily_cld ) {
cli_errmsg ( " cli_loaddbdir(): error parsing header of %s \n " , dbfile ) ;
free ( dbfile ) ;
closedir ( dd ) ;
return CL_EMALFDB ;
}
}
sprintf ( dbfile , " %s " PATHSEP " daily.cvd " , dirname ) ;
if ( ! access ( dbfile , R_OK ) ) {
if ( have_cld ) {
daily_cvd = cl_cvdhead ( dbfile ) ;
if ( ! daily_cvd ) {
cli_errmsg ( " cli_loaddbdir(): error parsing header of %s \n " , dbfile ) ;
free ( dbfile ) ;
2010-02-19 16:10:37 +01:00
cl_cvdfree ( daily_cld ) ;
2009-11-03 22:54:10 +01:00
closedir ( dd ) ;
return CL_EMALFDB ;
}
if ( daily_cld - > version > daily_cvd - > version )
sprintf ( dbfile , " %s " PATHSEP " daily.cld " , dirname ) ;
cl_cvdfree ( daily_cvd ) ;
}
} else {
sprintf ( dbfile , " %s " PATHSEP " daily.cld " , dirname ) ;
}
if ( have_cld )
cl_cvdfree ( daily_cld ) ;
2008-05-18 21:32:27 +00:00
if ( ! access ( dbfile , R_OK ) & & ( ret = cli_load ( dbfile , engine , signo , options , NULL ) ) ) {
2008-02-08 19:32:45 +00:00
free ( dbfile ) ;
2009-09-28 19:33:59 +02:00
closedir ( dd ) ;
2008-02-08 19:32:45 +00:00
return ret ;
}
2009-04-02 20:36:27 +00:00
/* try to load local.gdb next */
2009-09-24 19:07:39 +02:00
sprintf ( dbfile , " %s " PATHSEP " local.gdb " , dirname ) ;
2009-04-02 20:36:27 +00:00
if ( ! access ( dbfile , R_OK ) & & ( ret = cli_load ( dbfile , engine , signo , options , NULL ) ) ) {
free ( dbfile ) ;
2009-09-28 19:33:59 +02:00
closedir ( dd ) ;
2009-04-02 20:36:27 +00:00
return ret ;
}
2008-02-08 19:32:45 +00:00
/* check for and load daily.cfg */
2009-09-24 19:07:39 +02:00
sprintf ( dbfile , " %s " PATHSEP " daily.cfg " , dirname ) ;
2008-05-18 21:32:27 +00:00
if ( ! access ( dbfile , R_OK ) & & ( ret = cli_load ( dbfile , engine , signo , options , NULL ) ) ) {
2008-02-08 19:32:45 +00:00
free ( dbfile ) ;
2009-09-28 19:33:59 +02:00
closedir ( dd ) ;
2008-02-08 19:32:45 +00:00
return ret ;
2007-03-06 23:24:28 +00:00
}
free ( dbfile ) ;
2009-09-28 19:33:59 +02:00
/* second round - load everything else */
rewinddir ( dd ) ;
2004-10-03 15:12:13 +00:00
# ifdef HAVE_READDIR_R_3
2004-11-02 04:08:09 +00:00
while ( ! readdir_r ( dd , & result . d , & dent ) & & dent ) {
2004-10-03 15:12:13 +00:00
# elif defined(HAVE_READDIR_R_2)
2004-11-02 04:08:09 +00:00
while ( ( dent = ( struct dirent * ) readdir_r ( dd , & result . d ) ) ) {
2004-10-03 15:12:13 +00:00
# else
2003-07-29 15:48:06 +00:00
while ( ( dent = readdir ( dd ) ) ) {
2004-10-03 15:12:13 +00:00
# endif
2004-06-27 07:22:19 +00:00
if ( dent - > d_ino )
{
2009-09-28 19:33:59 +02:00
if ( strcmp ( dent - > d_name , " . " ) & & strcmp ( dent - > d_name , " .. " ) & & strcmp ( dent - > d_name , " daily.cvd " ) & & strcmp ( dent - > d_name , " daily.cld " ) & & strcmp ( dent - > d_name , " daily.cfg " ) & & CLI_DBEXT ( dent - > d_name ) ) {
2009-11-10 19:30:33 +01:00
if ( ( options & CL_DB_OFFICIAL_ONLY ) & & ! strstr ( dirname , " clamav- " ) & & ! cli_strbcasestr ( dent - > d_name , " .cld " ) & & ! cli_strbcasestr ( dent - > d_name , " .cvd " ) ) {
cli_dbgmsg ( " Skipping unofficial database %s \n " , dent - > d_name ) ;
continue ;
}
2007-03-06 23:24:28 +00:00
dbfile = ( char * ) cli_malloc ( strlen ( dent - > d_name ) + strlen ( dirname ) + 2 ) ;
2003-07-29 15:48:06 +00:00
if ( ! dbfile ) {
2005-11-13 16:48:38 +00:00
cli_dbgmsg ( " cli_loaddbdir(): dbfile == NULL \n " ) ;
2003-07-29 15:48:06 +00:00
closedir ( dd ) ;
return CL_EMEM ;
}
2009-09-24 19:07:39 +02:00
sprintf ( dbfile , " %s " PATHSEP " %s " , dirname , dent - > d_name ) ;
2008-05-18 21:32:27 +00:00
ret = cli_load ( dbfile , engine , signo , options , NULL ) ;
2007-10-05 13:29:59 +00:00
if ( ret ) {
2005-11-13 16:48:38 +00:00
cli_dbgmsg ( " cli_loaddbdir(): error loading database %s \n " , dbfile ) ;
2003-07-29 15:48:06 +00:00
free ( dbfile ) ;
closedir ( dd ) ;
return ret ;
}
free ( dbfile ) ;
}
}
}
closedir ( dd ) ;
2009-02-12 13:53:23 +00:00
if ( ret = = CL_EOPEN )
2007-01-14 23:46:50 +00:00
cli_errmsg ( " cli_loaddb(): No supported database files found in %s \n " , dirname ) ;
return ret ;
2003-07-29 15:48:06 +00:00
}
2009-03-12 15:21:36 +00:00
int cl_load ( const char * path , struct cl_engine * engine , unsigned int * signo , unsigned int dboptions )
2005-11-12 01:29:51 +00:00
{
struct stat sb ;
2005-11-13 02:08:28 +00:00
int ret ;
2005-11-12 01:29:51 +00:00
2008-11-11 21:23:34 +00:00
if ( ! engine ) {
2008-11-10 17:39:58 +00:00
cli_errmsg ( " cl_load: engine == NULL \n " ) ;
return CL_ENULLARG ;
}
2005-11-12 01:29:51 +00:00
2009-03-22 14:18:19 +00:00
if ( engine - > dboptions & CL_DB_COMPILED ) {
cli_errmsg ( " cl_load(): can't load new databases when engine is already compiled \n " ) ;
return CL_EARG ;
}
2005-11-12 01:29:51 +00:00
if ( stat ( path , & sb ) = = - 1 ) {
2008-11-04 18:45:48 +00:00
cli_errmsg ( " cl_load(): Can't get status of %s \n " , path ) ;
2009-02-12 13:53:23 +00:00
return CL_ESTAT ;
2005-11-12 01:29:51 +00:00
}
2009-03-12 15:21:36 +00:00
if ( ( dboptions & CL_DB_PHISHING_URLS ) & & ! engine - > phishcheck & & ( engine - > dconf - > phishing & PHISHING_CONF_ENGINE ) )
2008-11-11 21:23:34 +00:00
if ( ( ret = phishing_init ( engine ) ) )
2008-11-10 17:39:58 +00:00
return ret ;
2005-11-13 02:08:28 +00:00
2009-09-21 19:24:16 +03:00
if ( ( dboptions & CL_DB_BYTECODE ) & & ! engine - > bcs . engine & & ( engine - > dconf - > bytecode & BYTECODE_ENGINE_MASK ) ) {
2010-02-15 14:37:09 +02:00
if ( ( ret = cli_bytecode_init ( & engine - > bcs , engine - > dconf - > bytecode ) ) )
2009-09-21 19:24:16 +03:00
return ret ;
} else {
cli_dbgmsg ( " Bytecode engine disabled \n " ) ;
}
2010-01-14 18:54:53 +01:00
if ( cli_cache_init ( engine ) )
return CL_EMEM ;
2009-03-22 14:18:19 +00:00
engine - > dboptions | = dboptions ;
2006-11-23 00:07:58 +00:00
2006-04-07 19:22:21 +00:00
switch ( sb . st_mode & S_IFMT ) {
2009-09-21 19:24:16 +03:00
case S_IFREG :
2009-03-12 15:21:36 +00:00
ret = cli_load ( path , engine , signo , dboptions , NULL ) ;
2007-01-09 20:06:51 +00:00
break ;
2005-11-12 01:29:51 +00:00
case S_IFDIR :
2009-08-04 15:14:22 +02:00
ret = cli_loaddbdir ( path , engine , signo , dboptions | CL_DB_DIRECTORY ) ;
2007-01-09 20:06:51 +00:00
break ;
2005-11-12 01:29:51 +00:00
default :
2007-01-09 20:06:51 +00:00
cli_errmsg ( " cl_load(%s): Not supported database file type \n " , path ) ;
2005-11-12 01:29:51 +00:00
return CL_EOPEN ;
}
2007-01-09 20:06:51 +00:00
return ret ;
2005-11-12 01:29:51 +00:00
}
2004-07-13 03:30:49 +00:00
const char * cl_retdbdir ( void )
{
return DATADIR ;
}
2003-07-29 15:48:06 +00:00
int cl_statinidir ( const char * dirname , struct cl_stat * dbstat )
{
DIR * dd ;
2004-10-20 20:20:20 +00:00
const struct dirent * dent ;
2004-10-03 15:12:13 +00:00
# if defined(HAVE_READDIR_R_3) || defined(HAVE_READDIR_R_2)
2004-11-02 04:08:09 +00:00
union {
struct dirent d ;
char b [ offsetof ( struct dirent , d_name ) + NAME_MAX + 1 ] ;
} result ;
2004-10-03 15:12:13 +00:00
# endif
2003-07-29 15:48:06 +00:00
char * fname ;
if ( dbstat ) {
2006-11-01 16:04:54 +00:00
dbstat - > entries = 0 ;
2003-07-29 15:48:06 +00:00
dbstat - > stattab = NULL ;
2004-12-20 01:37:36 +00:00
dbstat - > statdname = NULL ;
2007-01-31 18:13:17 +00:00
dbstat - > dir = cli_strdup ( dirname ) ;
2003-07-29 15:48:06 +00:00
} else {
cli_errmsg ( " cl_statdbdir(): Null argument passed. \n " ) ;
return CL_ENULLARG ;
}
if ( ( dd = opendir ( dirname ) ) = = NULL ) {
cli_errmsg ( " cl_statdbdir(): Can't open directory %s \n " , dirname ) ;
2007-02-08 13:50:23 +00:00
cl_statfree ( dbstat ) ;
2003-07-29 15:48:06 +00:00
return CL_EOPEN ;
}
cli_dbgmsg ( " Stat()ing files in %s \n " , dirname ) ;
2004-10-03 15:12:13 +00:00
# ifdef HAVE_READDIR_R_3
2004-11-02 04:08:09 +00:00
while ( ! readdir_r ( dd , & result . d , & dent ) & & dent ) {
2004-10-03 15:12:13 +00:00
# elif defined(HAVE_READDIR_R_2)
2004-11-02 04:08:09 +00:00
while ( ( dent = ( struct dirent * ) readdir_r ( dd , & result . d ) ) ) {
2004-10-03 15:12:13 +00:00
# else
2003-07-29 15:48:06 +00:00
while ( ( dent = readdir ( dd ) ) ) {
2004-10-03 15:12:13 +00:00
# endif
2004-06-27 07:22:19 +00:00
if ( dent - > d_ino )
{
2007-10-05 13:29:59 +00:00
if ( strcmp ( dent - > d_name , " . " ) & & strcmp ( dent - > d_name , " .. " ) & & CLI_DBEXT ( dent - > d_name ) ) {
2006-11-01 16:04:54 +00:00
dbstat - > entries + + ;
2007-05-25 23:10:58 +00:00
dbstat - > stattab = ( struct stat * ) cli_realloc2 ( dbstat - > stattab , dbstat - > entries * sizeof ( struct stat ) ) ;
2007-02-08 13:50:23 +00:00
if ( ! dbstat - > stattab ) {
cl_statfree ( dbstat ) ;
closedir ( dd ) ;
return CL_EMEM ;
}
2009-09-24 19:10:27 +02:00
# ifdef _WIN32
2007-05-25 23:10:58 +00:00
dbstat - > statdname = ( char * * ) cli_realloc2 ( dbstat - > statdname , dbstat - > entries * sizeof ( char * ) ) ;
2007-02-08 13:50:23 +00:00
if ( ! dbstat - > statdname ) {
cl_statfree ( dbstat ) ;
closedir ( dd ) ;
return CL_EMEM ;
}
2004-12-20 01:37:36 +00:00
# endif
2007-03-06 23:24:28 +00:00
fname = cli_malloc ( strlen ( dirname ) + strlen ( dent - > d_name ) + 32 ) ;
2007-02-08 13:50:23 +00:00
if ( ! fname ) {
cl_statfree ( dbstat ) ;
closedir ( dd ) ;
return CL_EMEM ;
}
2009-09-24 19:07:39 +02:00
sprintf ( fname , " %s " PATHSEP " %s " , dirname , dent - > d_name ) ;
2009-09-24 19:10:27 +02:00
# ifdef _WIN32
2007-03-06 23:24:28 +00:00
dbstat - > statdname [ dbstat - > entries - 1 ] = ( char * ) cli_malloc ( strlen ( dent - > d_name ) + 1 ) ;
2007-02-08 13:50:23 +00:00
if ( ! dbstat - > statdname [ dbstat - > entries - 1 ] ) {
cl_statfree ( dbstat ) ;
closedir ( dd ) ;
return CL_EMEM ;
}
2006-11-01 16:04:54 +00:00
strcpy ( dbstat - > statdname [ dbstat - > entries - 1 ] , dent - > d_name ) ;
2004-12-20 01:37:36 +00:00
# endif
2006-11-01 16:04:54 +00:00
stat ( fname , & dbstat - > stattab [ dbstat - > entries - 1 ] ) ;
2003-07-29 15:48:06 +00:00
free ( fname ) ;
}
}
}
closedir ( dd ) ;
2006-05-18 11:29:24 +00:00
return CL_SUCCESS ;
2003-07-29 15:48:06 +00:00
}
int cl_statchkdir ( const struct cl_stat * dbstat )
{
DIR * dd ;
struct dirent * dent ;
2004-10-03 15:12:13 +00:00
# if defined(HAVE_READDIR_R_3) || defined(HAVE_READDIR_R_2)
2004-11-02 04:08:09 +00:00
union {
struct dirent d ;
char b [ offsetof ( struct dirent , d_name ) + NAME_MAX + 1 ] ;
} result ;
2004-10-03 15:12:13 +00:00
# endif
2003-07-29 15:48:06 +00:00
struct stat sb ;
2006-12-02 00:09:02 +00:00
unsigned int i , found ;
2003-07-29 15:48:06 +00:00
char * fname ;
if ( ! dbstat | | ! dbstat - > dir ) {
cli_errmsg ( " cl_statdbdir(): Null argument passed. \n " ) ;
return CL_ENULLARG ;
}
if ( ( dd = opendir ( dbstat - > dir ) ) = = NULL ) {
cli_errmsg ( " cl_statdbdir(): Can't open directory %s \n " , dbstat - > dir ) ;
return CL_EOPEN ;
}
cli_dbgmsg ( " Stat()ing files in %s \n " , dbstat - > dir ) ;
2004-10-03 15:12:13 +00:00
# ifdef HAVE_READDIR_R_3
2004-11-02 04:08:09 +00:00
while ( ! readdir_r ( dd , & result . d , & dent ) & & dent ) {
2004-10-03 15:12:13 +00:00
# elif defined(HAVE_READDIR_R_2)
2004-11-02 04:08:09 +00:00
while ( ( dent = ( struct dirent * ) readdir_r ( dd , & result . d ) ) ) {
2004-10-03 15:12:13 +00:00
# else
2003-07-29 15:48:06 +00:00
while ( ( dent = readdir ( dd ) ) ) {
2004-10-03 15:12:13 +00:00
# endif
2004-06-27 07:22:19 +00:00
if ( dent - > d_ino )
{
2007-10-05 13:29:59 +00:00
if ( strcmp ( dent - > d_name , " . " ) & & strcmp ( dent - > d_name , " .. " ) & & CLI_DBEXT ( dent - > d_name ) ) {
2007-03-06 23:24:28 +00:00
fname = cli_malloc ( strlen ( dbstat - > dir ) + strlen ( dent - > d_name ) + 32 ) ;
2007-02-08 13:50:23 +00:00
if ( ! fname ) {
closedir ( dd ) ;
return CL_EMEM ;
}
2009-09-24 19:07:39 +02:00
sprintf ( fname , " %s " PATHSEP " %s " , dbstat - > dir , dent - > d_name ) ;
2003-07-29 15:48:06 +00:00
stat ( fname , & sb ) ;
free ( fname ) ;
found = 0 ;
2006-11-01 16:04:54 +00:00
for ( i = 0 ; i < dbstat - > entries ; i + + )
2009-09-24 19:10:27 +02:00
# ifdef _WIN32
2004-12-20 01:37:36 +00:00
if ( ! strcmp ( dbstat - > statdname [ i ] , dent - > d_name ) ) {
# else
2003-07-29 15:48:06 +00:00
if ( dbstat - > stattab [ i ] . st_ino = = sb . st_ino ) {
2004-12-20 01:37:36 +00:00
# endif
2003-07-29 15:48:06 +00:00
found = 1 ;
2004-02-26 10:58:17 +00:00
if ( dbstat - > stattab [ i ] . st_mtime ! = sb . st_mtime ) {
closedir ( dd ) ;
2003-07-29 15:48:06 +00:00
return 1 ;
2004-02-26 10:58:17 +00:00
}
2003-07-29 15:48:06 +00:00
}
2004-02-26 10:58:17 +00:00
if ( ! found ) {
closedir ( dd ) ;
2003-07-29 15:48:06 +00:00
return 1 ;
2004-02-26 10:58:17 +00:00
}
2003-07-29 15:48:06 +00:00
}
}
}
closedir ( dd ) ;
2006-05-18 11:29:24 +00:00
return CL_SUCCESS ;
2003-07-29 15:48:06 +00:00
}
int cl_statfree ( struct cl_stat * dbstat )
{
if ( dbstat ) {
2004-12-20 01:37:36 +00:00
2009-09-24 19:10:27 +02:00
# ifdef _WIN32
2004-12-20 01:37:36 +00:00
int i ;
2007-02-08 13:50:23 +00:00
if ( dbstat - > statdname ) {
for ( i = 0 ; i < dbstat - > entries ; i + + ) {
if ( dbstat - > statdname [ i ] )
free ( dbstat - > statdname [ i ] ) ;
dbstat - > statdname [ i ] = NULL ;
}
free ( dbstat - > statdname ) ;
dbstat - > statdname = NULL ;
2004-12-20 01:37:36 +00:00
}
# endif
2007-02-08 13:50:23 +00:00
if ( dbstat - > stattab ) {
free ( dbstat - > stattab ) ;
dbstat - > stattab = NULL ;
}
2006-11-01 16:04:54 +00:00
dbstat - > entries = 0 ;
2007-02-08 13:50:23 +00:00
2003-12-01 19:28:40 +00:00
if ( dbstat - > dir ) {
2003-07-29 15:48:06 +00:00
free ( dbstat - > dir ) ;
2003-12-01 19:28:40 +00:00
dbstat - > dir = NULL ;
}
2003-07-29 15:48:06 +00:00
} else {
2004-07-19 17:54:40 +00:00
cli_errmsg ( " cl_statfree(): Null argument passed \n " ) ;
2003-07-29 15:48:06 +00:00
return CL_ENULLARG ;
}
2006-05-18 11:29:24 +00:00
return CL_SUCCESS ;
2003-07-29 15:48:06 +00:00
}
2006-04-07 19:22:21 +00:00
2008-11-10 17:39:58 +00:00
int cl_engine_free ( struct cl_engine * engine )
2006-04-07 19:22:21 +00:00
{
2008-07-25 19:00:25 +00:00
unsigned int i , j ;
2006-04-07 19:22:21 +00:00
struct cli_matcher * root ;
2006-06-03 21:57:47 +00:00
2006-04-07 19:22:21 +00:00
if ( ! engine ) {
cli_errmsg ( " cl_free: engine == NULL \n " ) ;
2008-11-10 17:39:58 +00:00
return CL_ENULLARG ;
2006-04-07 19:22:21 +00:00
}
# ifdef CL_THREAD_SAFE
pthread_mutex_lock ( & cli_ref_mutex ) ;
# endif
2008-06-02 12:00:37 +00:00
if ( engine - > refcount )
engine - > refcount - - ;
2006-04-07 19:22:21 +00:00
if ( engine - > refcount ) {
# ifdef CL_THREAD_SAFE
pthread_mutex_unlock ( & cli_ref_mutex ) ;
# endif
2008-11-10 17:39:58 +00:00
return CL_SUCCESS ;
2006-04-07 19:22:21 +00:00
}
# ifdef CL_THREAD_SAFE
pthread_mutex_unlock ( & cli_ref_mutex ) ;
# endif
2007-01-09 20:06:51 +00:00
if ( engine - > root ) {
2008-02-01 00:17:44 +00:00
for ( i = 0 ; i < CLI_MTARGETS ; i + + ) {
2007-01-09 20:06:51 +00:00
if ( ( root = engine - > root [ i ] ) ) {
2007-03-28 21:38:07 +00:00
if ( ! root - > ac_only )
2007-01-09 20:06:51 +00:00
cli_bm_free ( root ) ;
2007-03-28 21:38:07 +00:00
cli_ac_free ( root ) ;
2008-07-25 19:00:25 +00:00
if ( root - > ac_lsigtable ) {
for ( j = 0 ; j < root - > ac_lsigs ; j + + ) {
2009-01-26 19:47:02 +00:00
mpool_free ( engine - > mempool , root - > ac_lsigtable [ j ] - > logic ) ;
2008-07-25 19:00:25 +00:00
FREE_TDB ( root - > ac_lsigtable [ j ] - > tdb ) ;
2009-01-26 19:47:02 +00:00
mpool_free ( engine - > mempool , root - > ac_lsigtable [ j ] ) ;
2008-07-25 19:00:25 +00:00
}
2009-01-26 19:47:02 +00:00
mpool_free ( engine - > mempool , root - > ac_lsigtable ) ;
2008-07-25 19:00:25 +00:00
}
2009-01-26 19:47:02 +00:00
mpool_free ( engine - > mempool , root ) ;
2007-01-09 20:06:51 +00:00
}
2006-04-07 19:22:21 +00:00
}
2009-01-26 19:47:02 +00:00
mpool_free ( engine - > mempool , engine - > root ) ;
2006-04-07 19:22:21 +00:00
}
2007-12-15 20:34:31 +00:00
if ( ( root = engine - > md5_hdb ) ) {
cli_bm_free ( root ) ;
2009-01-26 19:47:02 +00:00
mpool_free ( engine - > mempool , root ) ;
2006-04-07 19:22:21 +00:00
}
2007-12-15 20:34:31 +00:00
if ( ( root = engine - > md5_mdb ) ) {
2007-04-30 14:12:38 +00:00
cli_bm_free ( root ) ;
2009-01-26 19:47:02 +00:00
mpool_free ( engine - > mempool , root - > soff ) ;
2008-02-06 18:53:23 +00:00
if ( root - > md5_sizes_hs . capacity ) {
2009-08-04 23:17:28 +02:00
cli_hashset_destroy ( & root - > md5_sizes_hs ) ;
2008-02-06 18:53:23 +00:00
}
2009-01-26 19:47:02 +00:00
mpool_free ( engine - > mempool , root ) ;
2007-02-24 18:44:18 +00:00
}
2007-12-15 20:34:31 +00:00
if ( ( root = engine - > md5_fp ) ) {
cli_bm_free ( root ) ;
2009-01-26 19:47:02 +00:00
mpool_free ( engine - > mempool , root ) ;
2007-12-15 20:34:31 +00:00
}
2010-01-07 18:26:12 +01:00
while ( engine - > cdb ) {
struct cli_cdb * pt = engine - > cdb ;
engine - > cdb = pt - > next ;
if ( pt - > name . re_magic )
cli_regfree ( & pt - > name ) ;
mpool_free ( engine - > mempool , pt - > res2 ) ;
mpool_free ( engine - > mempool , pt - > virname ) ;
mpool_free ( engine - > mempool , pt ) ;
}
2010-01-20 22:10:56 +01:00
while ( engine - > dbinfo ) {
struct cli_dbinfo * pt = engine - > dbinfo ;
engine - > dbinfo = pt - > next ;
mpool_free ( engine - > mempool , pt - > name ) ;
mpool_free ( engine - > mempool , pt - > hash ) ;
2010-03-05 19:12:07 +01:00
if ( pt - > cvd )
cl_cvdfree ( pt - > cvd ) ;
2010-01-20 22:10:56 +01:00
mpool_free ( engine - > mempool , pt ) ;
}
2009-09-21 19:24:16 +03:00
if ( engine - > dconf - > bytecode & BYTECODE_ENGINE_MASK ) {
if ( engine - > bcs . all_bcs )
for ( i = 0 ; i < engine - > bcs . count ; i + + )
cli_bytecode_destroy ( & engine - > bcs . all_bcs [ i ] ) ;
cli_bytecode_done ( & engine - > bcs ) ;
free ( engine - > bcs . all_bcs ) ;
2009-10-02 17:33:11 +03:00
for ( i = 0 ; i < _BC_LAST_HOOK - _BC_START_HOOKS ; i + + ) {
free ( engine - > hooks [ i ] ) ;
}
2009-09-21 19:24:16 +03:00
}
2008-11-11 21:23:34 +00:00
if ( engine - > dconf - > phishing & PHISHING_CONF_ENGINE )
2007-05-01 16:08:57 +00:00
phishing_done ( engine ) ;
2007-01-09 20:06:51 +00:00
if ( engine - > dconf )
2009-01-26 19:47:02 +00:00
mpool_free ( engine - > mempool , engine - > dconf ) ;
2007-01-09 20:06:51 +00:00
2008-07-31 16:26:50 +00:00
if ( engine - > pua_cats )
2009-01-26 19:47:02 +00:00
mpool_free ( engine - > mempool , engine - > pua_cats ) ;
2008-07-31 16:26:50 +00:00
2009-12-11 00:52:16 +01:00
if ( engine - > iconcheck ) {
struct icon_matcher * iconcheck = engine - > iconcheck ;
for ( i = 0 ; i < 3 ; i + + ) {
if ( iconcheck - > icons [ i ] ) {
mpool_free ( engine - > mempool , iconcheck - > icons [ i ] - > name ) ;
mpool_free ( engine - > mempool , iconcheck - > icons [ i ] ) ;
}
2009-12-07 19:47:50 +01:00
}
2009-12-11 00:52:16 +01:00
if ( iconcheck - > group_names [ 0 ] ) {
for ( i = 0 ; i < iconcheck - > group_counts [ 0 ] ; i + + )
mpool_free ( engine - > mempool , iconcheck - > group_names [ 0 ] [ i ] ) ;
mpool_free ( engine - > mempool , iconcheck - > group_names [ 0 ] ) ;
}
if ( iconcheck - > group_names [ 1 ] ) {
for ( i = 0 ; i < iconcheck - > group_counts [ 1 ] ; i + + )
mpool_free ( engine - > mempool , iconcheck - > group_names [ 1 ] [ i ] ) ;
mpool_free ( engine - > mempool , iconcheck - > group_names [ 1 ] ) ;
}
mpool_free ( engine - > mempool , iconcheck ) ;
}
2009-12-07 19:38:06 +01:00
2008-11-14 22:23:39 +00:00
if ( engine - > tmpdir )
2009-01-26 19:47:02 +00:00
mpool_free ( engine - > mempool , engine - > tmpdir ) ;
2008-11-14 22:23:39 +00:00
2010-01-14 18:54:53 +01:00
if ( engine - > cache )
cli_cache_destroy ( engine ) ;
2008-10-19 16:16:49 +00:00
cli_ftfree ( engine ) ;
2009-09-28 19:33:59 +02:00
if ( engine - > ignored ) {
cli_bm_free ( engine - > ignored ) ;
mpool_free ( engine - > mempool , engine - > ignored ) ;
}
2008-10-19 16:16:49 +00:00
# ifdef USE_MPOOL
2009-01-26 19:47:02 +00:00
if ( engine - > mempool ) mpool_destroy ( engine - > mempool ) ;
2008-10-21 23:55:11 +00:00
# endif
2006-04-07 19:22:21 +00:00
free ( engine ) ;
2008-11-10 17:39:58 +00:00
return CL_SUCCESS ;
2006-04-07 19:22:21 +00:00
}
2008-02-06 18:53:23 +00:00
static void cli_md5db_build ( struct cli_matcher * root )
{
if ( root & & root - > md5_sizes_hs . capacity ) {
/* TODO: use hashset directly, instead of the array when matching*/
2009-02-19 08:50:04 +00:00
cli_dbgmsg ( " Converting hashset to array: %u entries \n " , root - > md5_sizes_hs . count ) ;
2008-10-19 17:27:37 +00:00
# ifdef USE_MPOOL
{
uint32_t * mpoolht ;
unsigned int mpoolhtsz = root - > md5_sizes_hs . count * sizeof ( * mpoolht ) ;
2009-01-26 19:47:02 +00:00
root - > soff = mpool_malloc ( root - > mempool , mpoolhtsz ) ;
2009-08-04 23:17:28 +02:00
root - > soff_len = cli_hashset_toarray ( & root - > md5_sizes_hs , & mpoolht ) ;
2008-10-19 17:27:37 +00:00
memcpy ( root - > soff , mpoolht , mpoolhtsz ) ;
free ( mpoolht ) ;
}
# else
2009-08-04 23:17:28 +02:00
root - > soff_len = cli_hashset_toarray ( & root - > md5_sizes_hs , & root - > soff ) ;
2008-10-19 17:27:37 +00:00
# endif
2009-08-04 23:17:28 +02:00
cli_hashset_destroy ( & root - > md5_sizes_hs ) ;
2009-11-16 19:27:35 +01:00
cli_qsort ( root - > soff , root - > soff_len , sizeof ( uint32_t ) , NULL ) ;
2008-02-06 18:53:23 +00:00
}
}
2008-11-10 17:39:58 +00:00
int cl_engine_compile ( struct cl_engine * engine )
2006-04-07 19:22:21 +00:00
{
2007-12-14 22:39:37 +00:00
unsigned int i ;
int ret ;
2006-04-07 19:22:21 +00:00
struct cli_matcher * root ;
2007-12-14 22:39:37 +00:00
if ( ! engine )
return CL_ENULLARG ;
if ( ! engine - > ftypes )
2008-11-11 21:23:34 +00:00
if ( ( ret = cli_loadftm ( NULL , engine , 0 , 1 , NULL ) ) )
2007-12-14 22:39:37 +00:00
return ret ;
2006-04-07 19:22:21 +00:00
2008-02-01 00:17:44 +00:00
for ( i = 0 ; i < CLI_MTARGETS ; i + + ) {
if ( ( root = engine - > root [ i ] ) ) {
if ( ( ret = cli_ac_buildtrie ( root ) ) )
return ret ;
2009-08-27 18:12:39 +03:00
cli_dbgmsg ( " matcher[%u]: %s: AC sigs: %u (reloff: %u, absoff: %u) BM sigs: %u (reloff: %u, absoff: %u) maxpatlen %u %s \n " , i , cli_mtargets [ i ] . name , root - > ac_patterns , root - > ac_reloff_num , root - > ac_absoff_num , root - > bm_patterns , root - > bm_reloff_num , root - > bm_absoff_num , root - > maxpatlen , root - > ac_only ? " (ac_only mode) " : " " ) ;
2008-02-01 00:17:44 +00:00
}
}
2006-04-07 19:22:21 +00:00
2008-07-23 13:51:57 +00:00
if ( ( ret = cli_build_regex_list ( engine - > whitelist_matcher ) ) ) {
return ret ;
}
if ( ( ret = cli_build_regex_list ( engine - > domainlist_matcher ) ) ) {
return ret ;
}
2008-02-06 18:53:23 +00:00
cli_md5db_build ( engine - > md5_mdb ) ;
2009-09-28 19:33:59 +02:00
if ( engine - > ignored ) {
cli_bm_free ( engine - > ignored ) ;
mpool_free ( engine - > mempool , engine - > ignored ) ;
engine - > ignored = NULL ;
}
2007-03-08 13:17:20 +00:00
cli_dconf_print ( engine - > dconf ) ;
2009-01-26 19:47:02 +00:00
mpool_flush ( engine - > mempool ) ;
2007-03-08 13:17:20 +00:00
2009-09-21 19:24:16 +03:00
/* Compile bytecode */
2010-02-15 14:37:09 +02:00
if ( ( ret = cli_bytecode_prepare ( & engine - > bcs , engine - > dconf - > bytecode ) ) ) {
2009-10-02 17:33:11 +03:00
cli_errmsg ( " Unable to compile/load bytecode: %s \n " , cl_strerror ( ret ) ) ;
2009-09-21 19:24:16 +03:00
return ret ;
}
2009-03-02 16:36:23 +00:00
engine - > dboptions | = CL_DB_COMPILED ;
2006-05-18 11:29:24 +00:00
return CL_SUCCESS ;
2006-04-07 19:22:21 +00:00
}
2008-11-13 15:55:35 +00:00
int cl_engine_addref ( struct cl_engine * engine )
2006-04-07 19:22:21 +00:00
{
if ( ! engine ) {
2008-11-13 15:55:35 +00:00
cli_errmsg ( " cl_engine_addref: engine == NULL \n " ) ;
return CL_ENULLARG ;
2006-04-07 19:22:21 +00:00
}
# ifdef CL_THREAD_SAFE
pthread_mutex_lock ( & cli_ref_mutex ) ;
# endif
engine - > refcount + + ;
# ifdef CL_THREAD_SAFE
pthread_mutex_unlock ( & cli_ref_mutex ) ;
# endif
2008-11-13 15:55:35 +00:00
return CL_SUCCESS ;
2006-04-07 19:22:21 +00:00
}
2010-02-12 15:52:19 +01:00
static int countentries ( const char * dbname , unsigned int * sigs )
{
char buffer [ CLI_DEFAULT_LSIG_BUFSIZE + 1 ] ;
FILE * fs ;
unsigned int entry = 0 ;
fs = fopen ( dbname , " r " ) ;
if ( ! fs ) {
cli_errmsg ( " countentries: Can't open file %s \n " , dbname ) ;
return CL_EOPEN ;
}
while ( fgets ( buffer , sizeof ( buffer ) , fs ) ) {
if ( buffer [ 0 ] = = ' # ' )
continue ;
entry + + ;
}
fclose ( fs ) ;
* sigs + = entry ;
return CL_SUCCESS ;
}
static int countsigs ( const char * dbname , unsigned int options , unsigned int * sigs )
{
if ( ( cli_strbcasestr ( dbname , " .cvd " ) | | cli_strbcasestr ( dbname , " .cld " ) ) ) {
if ( options & CL_COUNTSIGS_OFFICIAL ) {
struct cl_cvd * cvd = cl_cvdhead ( dbname ) ;
if ( ! cvd ) {
cli_errmsg ( " countsigs: Can't parse %s \n " , dbname ) ;
return CL_ECVD ;
}
* sigs + = cvd - > sigs ;
cl_cvdfree ( cvd ) ;
}
} else if ( cli_strbcasestr ( dbname , " .cbc " ) ) {
if ( options & CL_COUNTSIGS_UNOFFICIAL )
( * sigs ) + + ;
} else if ( cli_strbcasestr ( dbname , " .wdb " ) | | cli_strbcasestr ( dbname , " .fp " ) | | cli_strbcasestr ( dbname , " .ftm " ) | | cli_strbcasestr ( dbname , " .cfg " ) ) {
/* ignore */
} else if ( ( options & CL_COUNTSIGS_UNOFFICIAL ) & & CLI_DBEXT ( dbname ) ) {
return countentries ( dbname , sigs ) ;
}
return CL_SUCCESS ;
}
int cl_countsigs ( const char * path , unsigned int countoptions , unsigned int * sigs )
{
struct stat sb ;
char fname [ 1024 ] ;
struct dirent * dent ;
# if defined(HAVE_READDIR_R_3) || defined(HAVE_READDIR_R_2)
union {
struct dirent d ;
char b [ offsetof ( struct dirent , d_name ) + NAME_MAX + 1 ] ;
} result ;
# endif
DIR * dd ;
int ret ;
if ( ! sigs )
return CL_ENULLARG ;
if ( stat ( path , & sb ) = = - 1 ) {
cli_errmsg ( " cl_countsigs: Can't stat %s \n " , path ) ;
return CL_ESTAT ;
}
if ( ( sb . st_mode & S_IFMT ) = = S_IFREG ) {
return countsigs ( path , countoptions , sigs ) ;
} else if ( ( sb . st_mode & S_IFMT ) = = S_IFDIR ) {
if ( ( dd = opendir ( path ) ) = = NULL ) {
cli_errmsg ( " cl_countsigs: Can't open directory %s \n " , path ) ;
return CL_EOPEN ;
}
# ifdef HAVE_READDIR_R_3
while ( ! readdir_r ( dd , & result . d , & dent ) & & dent ) {
# elif defined(HAVE_READDIR_R_2)
while ( ( dent = ( struct dirent * ) readdir_r ( dd , & result . d ) ) ) {
# else
while ( ( dent = readdir ( dd ) ) ) {
# endif
if ( dent - > d_ino ) {
if ( strcmp ( dent - > d_name , " . " ) & & strcmp ( dent - > d_name , " .. " ) & & CLI_DBEXT ( dent - > d_name ) ) {
snprintf ( fname , sizeof ( fname ) , " %s " PATHSEP " %s " , path , dent - > d_name ) ;
fname [ sizeof ( fname ) - 1 ] = 0 ;
ret = countsigs ( fname , countoptions , sigs ) ;
if ( ret ! = CL_SUCCESS ) {
closedir ( dd ) ;
return ret ;
}
}
}
}
closedir ( dd ) ;
} else {
cli_errmsg ( " cl_countsigs: Unsupported file type \n " ) ;
return CL_EARG ;
}
return CL_SUCCESS ;
}