diff --git a/libclamav/Makefile.am b/libclamav/Makefile.am index a0736650e..47a4748e5 100644 --- a/libclamav/Makefile.am +++ b/libclamav/Makefile.am @@ -144,6 +144,8 @@ libclamav_la_SOURCES = \ matcher-bm.h \ matcher-md5.c \ matcher-md5.h \ + matcher-hash.c \ + matcher-hash.h \ matcher.c \ matcher.h \ others.c \ diff --git a/libclamav/Makefile.in b/libclamav/Makefile.in index d4b6ee8cd..ec781a2a9 100644 --- a/libclamav/Makefile.in +++ b/libclamav/Makefile.in @@ -115,21 +115,22 @@ LTLIBRARIES = $(lib_LTLIBRARIES) $(noinst_LTLIBRARIES) @ENABLE_LLVM_TRUE@am__DEPENDENCIES_2 = c++/libclamavcxx.la am__libclamav_la_SOURCES_DIST = clamav.h matcher-ac.c matcher-ac.h \ matcher-bm.c matcher-bm.h matcher-md5.c matcher-md5.h \ - matcher.c matcher.h others.c others.h readdb.c readdb.h cvd.c \ - cvd.h dsig.c dsig.h scanners.c scanners.h textdet.c textdet.h \ - filetypes.c filetypes.h filetypes_int.h rtf.c rtf.h blob.c \ - blob.h mbox.c mbox.h message.c message.h table.c table.h \ - text.c text.h ole2_extract.c ole2_extract.h vba_extract.c \ - vba_extract.h cltypes.h msexpand.c msexpand.h pe.c pe.h \ - pe_icons.c pe_icons.h disasm.c disasm.h disasm-common.h \ - disasmpriv.h upx.c upx.h htmlnorm.c htmlnorm.h chmunpack.c \ - chmunpack.h rebuildpe.c rebuildpe.h petite.c petite.h \ - wwunpack.c wwunpack.h unsp.c unsp.h aspack.c aspack.h \ - packlibs.c packlibs.h fsg.c fsg.h mew.c mew.h upack.c upack.h \ - line.c line.h untar.c untar.h unzip.c unzip.h inflate64.c \ - inflate64.h inffixed64.h inflate64_priv.h special.c special.h \ - binhex.c binhex.h is_tar.c is_tar.h tnef.c tnef.h autoit.c \ - autoit.h unarj.c unarj.h nsis/bzlib.c nsis/bzlib_private.h \ + matcher-hash.c matcher-hash.h matcher.c matcher.h others.c \ + others.h readdb.c readdb.h cvd.c cvd.h dsig.c dsig.h \ + scanners.c scanners.h textdet.c textdet.h filetypes.c \ + filetypes.h filetypes_int.h rtf.c rtf.h blob.c blob.h mbox.c \ + mbox.h message.c message.h table.c table.h text.c text.h \ + ole2_extract.c ole2_extract.h vba_extract.c vba_extract.h \ + cltypes.h msexpand.c msexpand.h pe.c pe.h pe_icons.c \ + pe_icons.h disasm.c disasm.h disasm-common.h disasmpriv.h \ + upx.c upx.h htmlnorm.c htmlnorm.h chmunpack.c chmunpack.h \ + rebuildpe.c rebuildpe.h petite.c petite.h wwunpack.c \ + wwunpack.h unsp.c unsp.h aspack.c aspack.h packlibs.c \ + packlibs.h fsg.c fsg.h mew.c mew.h upack.c upack.h line.c \ + line.h untar.c untar.h unzip.c unzip.h inflate64.c inflate64.h \ + inffixed64.h inflate64_priv.h special.c special.h binhex.c \ + binhex.h is_tar.c is_tar.h tnef.c tnef.h autoit.c autoit.h \ + unarj.c unarj.h nsis/bzlib.c nsis/bzlib_private.h \ nsis/nsis_bzlib.h nsis/nulsft.c nsis/nulsft.h nsis/infblock.c \ nsis/nsis_zconf.h nsis/nsis_zlib.h nsis/nsis_zutil.h pdf.c \ pdf.h spin.c spin.h yc.c yc.h elf.c elf.h execs.h sis.c sis.h \ @@ -162,11 +163,12 @@ am__libclamav_la_SOURCES_DIST = clamav.h matcher-ac.c matcher-ac.h \ @LINK_TOMMATH_FALSE@am__objects_1 = libclamav_la-bignum.lo am_libclamav_la_OBJECTS = libclamav_la-matcher-ac.lo \ libclamav_la-matcher-bm.lo libclamav_la-matcher-md5.lo \ - libclamav_la-matcher.lo libclamav_la-others.lo \ - libclamav_la-readdb.lo libclamav_la-cvd.lo \ - libclamav_la-dsig.lo libclamav_la-scanners.lo \ - libclamav_la-textdet.lo libclamav_la-filetypes.lo \ - libclamav_la-rtf.lo libclamav_la-blob.lo libclamav_la-mbox.lo \ + libclamav_la-matcher-hash.lo libclamav_la-matcher.lo \ + libclamav_la-others.lo libclamav_la-readdb.lo \ + libclamav_la-cvd.lo libclamav_la-dsig.lo \ + libclamav_la-scanners.lo libclamav_la-textdet.lo \ + libclamav_la-filetypes.lo libclamav_la-rtf.lo \ + libclamav_la-blob.lo libclamav_la-mbox.lo \ libclamav_la-message.lo libclamav_la-table.lo \ libclamav_la-text.lo libclamav_la-ole2_extract.lo \ libclamav_la-vba_extract.lo libclamav_la-msexpand.lo \ @@ -619,22 +621,22 @@ libclamav_la_LDFLAGS = @TH_SAFE@ -version-info @LIBCLAMAV_VERSION@ \ -no-undefined $(am__append_6) include_HEADERS = clamav.h libclamav_la_SOURCES = clamav.h matcher-ac.c matcher-ac.h matcher-bm.c \ - matcher-bm.h matcher-md5.c matcher-md5.h matcher.c matcher.h \ - others.c others.h readdb.c readdb.h cvd.c cvd.h dsig.c dsig.h \ - scanners.c scanners.h textdet.c textdet.h filetypes.c \ - filetypes.h filetypes_int.h rtf.c rtf.h blob.c blob.h mbox.c \ - mbox.h message.c message.h table.c table.h text.c text.h \ - ole2_extract.c ole2_extract.h vba_extract.c vba_extract.h \ - cltypes.h msexpand.c msexpand.h pe.c pe.h pe_icons.c \ - pe_icons.h disasm.c disasm.h disasm-common.h disasmpriv.h \ - upx.c upx.h htmlnorm.c htmlnorm.h chmunpack.c chmunpack.h \ - rebuildpe.c rebuildpe.h petite.c petite.h wwunpack.c \ - wwunpack.h unsp.c unsp.h aspack.c aspack.h packlibs.c \ - packlibs.h fsg.c fsg.h mew.c mew.h upack.c upack.h line.c \ - line.h untar.c untar.h unzip.c unzip.h inflate64.c inflate64.h \ - inffixed64.h inflate64_priv.h special.c special.h binhex.c \ - binhex.h is_tar.c is_tar.h tnef.c tnef.h autoit.c autoit.h \ - unarj.c unarj.h nsis/bzlib.c nsis/bzlib_private.h \ + matcher-bm.h matcher-md5.c matcher-md5.h matcher-hash.c \ + matcher-hash.h matcher.c matcher.h others.c others.h readdb.c \ + readdb.h cvd.c cvd.h dsig.c dsig.h scanners.c scanners.h \ + textdet.c textdet.h filetypes.c filetypes.h filetypes_int.h \ + rtf.c rtf.h blob.c blob.h mbox.c mbox.h message.c message.h \ + table.c table.h text.c text.h ole2_extract.c ole2_extract.h \ + vba_extract.c vba_extract.h cltypes.h msexpand.c msexpand.h \ + pe.c pe.h pe_icons.c pe_icons.h disasm.c disasm.h \ + disasm-common.h disasmpriv.h upx.c upx.h htmlnorm.c htmlnorm.h \ + chmunpack.c chmunpack.h rebuildpe.c rebuildpe.h petite.c \ + petite.h wwunpack.c wwunpack.h unsp.c unsp.h aspack.c aspack.h \ + packlibs.c packlibs.h fsg.c fsg.h mew.c mew.h upack.c upack.h \ + line.c line.h untar.c untar.h unzip.c unzip.h inflate64.c \ + inflate64.h inffixed64.h inflate64_priv.h special.c special.h \ + binhex.c binhex.h is_tar.c is_tar.h tnef.c tnef.h autoit.c \ + autoit.h unarj.c unarj.h nsis/bzlib.c nsis/bzlib_private.h \ nsis/nsis_bzlib.h nsis/nulsft.c nsis/nulsft.h nsis/infblock.c \ nsis/nsis_zconf.h nsis/nsis_zlib.h nsis/nsis_zutil.h pdf.c \ pdf.h spin.c spin.h yc.c yc.h elf.c elf.h execs.h sis.c sis.h \ @@ -837,6 +839,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_la-macho.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_la-matcher-ac.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_la-matcher-bm.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_la-matcher-hash.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_la-matcher-md5.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_la-matcher.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_la-mbox.Plo@am__quote@ @@ -943,6 +946,14 @@ libclamav_la-matcher-md5.lo: matcher-md5.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -c -o libclamav_la-matcher-md5.lo `test -f 'matcher-md5.c' || echo '$(srcdir)/'`matcher-md5.c +libclamav_la-matcher-hash.lo: matcher-hash.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -MT libclamav_la-matcher-hash.lo -MD -MP -MF $(DEPDIR)/libclamav_la-matcher-hash.Tpo -c -o libclamav_la-matcher-hash.lo `test -f 'matcher-hash.c' || echo '$(srcdir)/'`matcher-hash.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libclamav_la-matcher-hash.Tpo $(DEPDIR)/libclamav_la-matcher-hash.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='matcher-hash.c' object='libclamav_la-matcher-hash.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -c -o libclamav_la-matcher-hash.lo `test -f 'matcher-hash.c' || echo '$(srcdir)/'`matcher-hash.c + libclamav_la-matcher.lo: matcher.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -MT libclamav_la-matcher.lo -MD -MP -MF $(DEPDIR)/libclamav_la-matcher.Tpo -c -o libclamav_la-matcher.lo `test -f 'matcher.c' || echo '$(srcdir)/'`matcher.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libclamav_la-matcher.Tpo $(DEPDIR)/libclamav_la-matcher.Plo diff --git a/libclamav/hashtab.c b/libclamav/hashtab.c index 55d8978c6..a4b22f5d6 100644 --- a/libclamav/hashtab.c +++ b/libclamav/hashtab.c @@ -588,6 +588,11 @@ void cli_htu32_free(struct cli_htu32 *s, mpool_t *mempool) s->capacity = 0; } +size_t cli_htu32_numitems(struct cli_htu32 *s) { + if(!s) return 0; + return s->capacity; +} + int cli_hashtab_store(const struct cli_hashtable *s,FILE* out) { size_t i; diff --git a/libclamav/hashtab.h b/libclamav/hashtab.h index b56418f93..9a28a66bf 100644 --- a/libclamav/hashtab.h +++ b/libclamav/hashtab.h @@ -111,6 +111,7 @@ void cli_htu32_delete(struct cli_htu32 *s, uint32_t key); void cli_htu32_clear(struct cli_htu32 *s); void cli_htu32_free(struct cli_htu32 *s, mpool_t *mempool); const struct cli_htu32_element *cli_htu32_next(const struct cli_htu32 *s, const struct cli_htu32_element *current); +size_t cli_htu32_numitems(struct cli_htu32 *s); /* a hashtable that stores the values too */ diff --git a/libclamav/matcher-hash.c b/libclamav/matcher-hash.c new file mode 100644 index 000000000..87191dd78 --- /dev/null +++ b/libclamav/matcher-hash.c @@ -0,0 +1,115 @@ +/* + * Copyright (C) 2010 Sourcefire, Inc. + * + * Authors: aCaB + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#include "matcher.h" +#include "others.h" +#include "str.h" + +#include + +int hm_addhash(struct cli_matcher *root, const char *hash, uint32_t size, const char *virusname) { + const struct cli_htu32_element *item; + struct cli_sz_hash *szh; + struct cli_htu32 *ht; + enum CLI_HASH_TYPE type; + uint8_t binhash[64]; + int hashlen, i; + + if(!root || !hash) { + cli_errmsg("hm_addhash: NULL root or hash\n"); + return CL_ENULLARG; + } + + if(!size || size == (uint32_t)-1) { + cli_errmsg("hm_addhash: null or invalid size (%u)\n", size); + return CL_EARG; + } + + hashlen = strlen(hash); + switch(hashlen) { + case 32: + type = CLI_HASH_MD5; + break; + case 40: + type = CLI_HASH_SHA1; + break; + case 64: + type = CLI_HASH_SHA256; + break; + default: + cli_errmsg("hm_addhash: invalid hash %s -- FIXME!\n", hash); + return CL_EARG; + } + if(cli_hex2str_to(hash, (char *)binhash, hashlen)) { + cli_errmsg("hm_addhash: invalid hash %s\n", hash); + return CL_EARG; + } + + ht = &root->hm.sizehashes[type]; + if(!root->hm.htiint[type]) { + i = cli_htu32_init(ht, 5000, root->mempool); + if(i) return i; + } + + item = cli_htu32_find(ht, size); + if(!item) { + struct cli_htu32_element htitem; + szh = mpool_calloc(root->mempool, 1, sizeof(szh)); + if(!szh) { + cli_errmsg("hm_addhash: failed to allocate size hash\n"); + return CL_EMEM; + } + + htitem.key = size; + htitem.data.as_ptr = szh; + i = cli_htu32_insert(ht, &htitem, root->mempool); + if(i) { + cli_errmsg("ht_addhash: failed to add item to hashtab"); + mpool_free(root->mempool, szh); + return i; + } + } else + szh = (struct cli_sz_hash *)item->data.as_ptr; + + if(szh->items == szh->max) { + if(!szh->max) + szh->max = 1024; + else + szh->max = szh->max + szh->max / 2; + + szh->hash_array = mpool_realloc2(root->mempool, szh->hash_array, hashlen * szh->max); + if(!szh->hash_array) { + cli_errmsg("ht_add: failed to grow hash array to %u entries\n", szh->max); + return CL_EMEM; + } + + szh->virusnames = mpool_realloc2(root->mempool, szh->hash_array, sizeof(*szh->virusnames) * szh->max); + if(!szh->virusnames) { + cli_errmsg("ht_add: failed to grow virusname array to %u entries\n", szh->max); + return CL_EMEM; + } + } + + memcpy(&szh->hash_array[szh->items * hashlen], binhash, hashlen / 2); + szh->virusnames[szh->items] = virusname; + szh->items++; + + return 0; +} diff --git a/libclamav/matcher-hash.h b/libclamav/matcher-hash.h new file mode 100644 index 000000000..3632fe796 --- /dev/null +++ b/libclamav/matcher-hash.h @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2010 Sourcefire, Inc. + * + * Authors: aCaB + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#ifndef __MATCHER_HASH_H +#define __MATCHER_HASH_H + +#if HAVE_CONFIG_H +#include "clamav-config.h" +#endif + +#include "cltypes.h" +#include "hashtab.h" + +enum CLI_HASH_TYPE { + CLI_HASH_MD5, + CLI_HASH_SHA256, + CLI_HASH_SHA1, + + /* new hash types go above this line */ + CLI_HASH_AVAIL_TYPES +}; + +struct cli_sz_hash { + uint8_t *hash_array; /* FIXME: make 256 entries? */ + const char **virusnames; + uint32_t items; + uint32_t max; +}; + + +struct cli_hash_patt { + struct cli_htu32 sizehashes[CLI_HASH_AVAIL_TYPES]; + int htiint[CLI_HASH_AVAIL_TYPES]; +}; + + +int hm_addhash(struct cli_matcher *root, const char *hash, uint32_t size, const char *virusname); + +#endif diff --git a/libclamav/matcher.h b/libclamav/matcher.h index b4203d40b..d2d4ffd5b 100644 --- a/libclamav/matcher.h +++ b/libclamav/matcher.h @@ -38,6 +38,7 @@ struct cli_target_info { #include "matcher-ac.h" #include "matcher-bm.h" +#include "matcher-hash.h" #include "hashtab.h" #include "fmap.h" #include "mpool.h" @@ -97,6 +98,8 @@ struct cli_matcher { struct cli_md5m_patt **md5tab; uint32_t md5_patterns; + struct cli_hash_patt hm; + /* Extended Aho-Corasick */ uint32_t ac_partsigs, ac_nodes, ac_patterns, ac_lsigs; struct cli_ac_lsig **ac_lsigtable; diff --git a/libclamav/others.h b/libclamav/others.h index c260cf4c5..211d2f33d 100644 --- a/libclamav/others.h +++ b/libclamav/others.h @@ -217,6 +217,15 @@ struct cl_engine { /* B-M matcher for whitelist db */ struct cli_matcher *md5_fp; + + /* hash matcher for standard MD5 sigs */ + struct cli_matcher *hm_hdb; + /* hash matcher for MD5 sigs for PE sections */ + struct cli_matcher *hm_mdb; + /* hash matcher for whitelist db */ + struct cli_matcher *hm_fp; + + /* Container metadata */ struct cli_cdb *cdb; diff --git a/libclamav/readdb.c b/libclamav/readdb.c index 2dab42e96..1598ac5a6 100644 --- a/libclamav/readdb.c +++ b/libclamav/readdb.c @@ -47,6 +47,7 @@ #include "matcher-ac.h" #include "matcher-bm.h" #include "matcher-md5.h" +#include "matcher-hash.h" #include "matcher.h" #include "others.h" #include "str.h" @@ -2023,6 +2024,108 @@ static int cli_loadmd5(FILE *fs, struct cl_engine *engine, unsigned int *signo, return CL_SUCCESS; } + + +#define MD5_TOKENS 3 +static int cli_loadhash(FILE *fs, struct cl_engine *engine, unsigned int *signo, unsigned int mode, unsigned int options, struct cli_dbio *dbio, const char *dbname) +{ + const char *tokens[MD5_TOKENS + 1]; + char buffer[FILEBUFF], *buffer_cpy = NULL; + const char *pt, *virname; + int ret = CL_SUCCESS; + unsigned int size_field = 1, md5_field = 0, line = 0, sigs = 0, tokens_count; + struct cli_matcher *db = NULL; + unsigned long size; + + + if(mode == MD5_MDB) { + size_field = 0; + md5_field = 1; + } + + if(engine->ignored) + if(!(buffer_cpy = cli_malloc(FILEBUFF))) + return CL_EMEM; + + while(cli_dbgets(buffer, FILEBUFF, fs, dbio)) { + line++; + cli_chomp(buffer); + if(engine->ignored) + strcpy(buffer_cpy, buffer); + + tokens_count = cli_strtokenize(buffer, ':', MD5_TOKENS + 1, tokens); + if(tokens_count != MD5_TOKENS) { + ret = CL_EMALFDB; + break; + } + + size = strtol(tokens[size_field], (char **)&pt, 10); + if(*pt || !size || size >= 0xffffffff) { + cli_errmsg("cli_loadhash: Invalid value for the size field\n"); + ret = CL_EMALFDB; + break; + } + + pt = tokens[2]; /* virname */ + 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)) + continue; + + if(engine->ignored && cli_chkign(engine->ignored, pt, buffer_cpy)) + continue; + + if(engine->cb_sigload) { + const char *dot = strchr(dbname, '.'); + if(!dot) + dot = dbname; + else + dot++; + if(engine->cb_sigload(dot, pt, engine->cb_sigload_ctx)) { + cli_dbgmsg("cli_loadhash: skipping %s (%s) due to callback\n", pt, dot); + continue; + } + } + + virname = cli_mpool_virname(engine->mempool, pt, options & CL_DB_OFFICIAL); + if(!virname) { + ret = CL_EMALFDB; + break; + } + + if(mode == MD5_HDB) + db = engine->hm_hdb; + else if(mode == MD5_MDB) + db = engine->hm_mdb; + else + db = engine->hm_fp; + + if((ret = hm_addhash(db, tokens[md5_field], size, virname))) { + cli_errmsg("cli_loadmd5: Malformed MD5 string at line %u\n", line); + mpool_free(engine->mempool, (void *)virname); + break; + } + + sigs++; + } + if(engine->ignored) + free(buffer_cpy); + + if(!line) { + cli_errmsg("cli_loadmd5: Empty database file\n"); + return CL_EMALFDB; + } + + if(ret) { + cli_errmsg("cli_loadmd5: Problem parsing database at line %u\n", line); + return ret; + } + + if(signo) + *signo += sigs; + + return CL_SUCCESS; +} + #define MD_TOKENS 9 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) { @@ -2468,7 +2571,24 @@ int cli_load(const char *filename, struct cl_engine *engine, unsigned int *signo } else if(cli_strbcasestr(dbname, ".cdb")) { ret = cli_loadcdb(fs, engine, signo, options, dbio); + } else if(cli_strbcasestr(dbname, ".hsb")) { + ret = cli_loadhash(fs, engine, signo, MD5_HDB, options, dbio, dbname); + } else if(cli_strbcasestr(dbname, ".hsu")) { + if(options & CL_DB_PUA) + ret = cli_loadhash(fs, engine, signo, MD5_HDB, options | CL_DB_PUA_MODE, dbio, dbname); + else + skipped = 1; + } else if(cli_strbcasestr(dbname, ".sfp")) { + ret = cli_loadhash(fs, engine, signo, MD5_FP, options, dbio, dbname); + } else if(cli_strbcasestr(dbname, ".msb")) { + ret = cli_loadhash(fs, engine, signo, MD5_MDB, options, dbio, dbname); + + } else if(cli_strbcasestr(dbname, ".msu")) { + if(options & CL_DB_PUA) + ret = cli_loadhash(fs, engine, signo, MD5_MDB, options | CL_DB_PUA_MODE, dbio, dbname); + else + skipped = 1; } else { cli_dbgmsg("cli_load: unknown extension - assuming old database format\n"); ret = cli_loaddb(fs, engine, signo, options, dbio, dbname);