ec285505 |
/*
* Copyright (C) 2008 Sourcefire, Inc.
*
* Authors: Tomasz Kojm
*
* 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.
*/
#if HAVE_CONFIG_H
#include "clamav-config.h"
#endif
#include <check.h>
#include <stdio.h> |
5cd3f734 |
#include <string.h> |
ec285505 |
|
b2e7c931 |
#include <openssl/ssl.h>
#include <openssl/err.h>
#include "libclamav/crypto.h"
|
ec285505 |
#include "../libclamav/clamav.h"
#include "../libclamav/readdb.h"
#include "../libclamav/matcher.h"
#include "../libclamav/matcher-ac.h"
#include "../libclamav/matcher-bm.h" |
e0ac80ab |
#include "../libclamav/others.h" |
589d8d8e |
#include "../libclamav/default.h" |
ec285505 |
#include "checks.h"
static const struct ac_testdata_s {
const char *data;
const char *hexsig;
const char *virname;
} ac_testdata[] = {
/* IMPORTANT: ac_testdata[i].hexsig should only match ac_testdata[i].data */
{ "daaaaaaaaddbbbbbcce", "64[4-4]61616161{2}6262[3-6]65", "Test_1" },
{ "ebbbbbbbbeecccccddf", "6262(6162|6364|6265|6465){2}6363", "Test_2" },
{ "aaaabbbbcccccdddddeeee", "616161*63636363*6565", "Test_3" },
{ "oprstuwxy","6f??727374????7879", "Test_4" },
{ "abdcabcddabccadbbdbacb", "6463{2-3}64646162(63|64|65)6361*6462????6261{-1}6362", "Test_5" },
{ "abcdefghijkabcdefghijk", "62????65666768*696a6b6162{2-3}656667[1-3]6b", "Test_6" },
{ "abcadbabcadbabcacb", "6?6164?26?62{3}?26162?361", "Test_7" }, |
e0ac80ab |
/* testcase for filter bug: it was checking only first 32 chars, and last
* maxpatlen */
{ "\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1dddddddddddddddddddd5\1\1\1\1\1\1\1\1\1\1\1\1\1","6464646464646464646464646464646464646464(35|36)","Test_8"}, |
ec285505 |
{ NULL, NULL, NULL}
};
|
e0ac80ab |
static cli_ctx ctx; |
8ef83e0b |
static fmap_t *thefmap = NULL; |
e0ac80ab |
static const char *virname = NULL;
static void setup(void)
{ |
ec285505 |
struct cli_matcher *root; |
e0ac80ab |
virname = NULL; |
8ef83e0b |
thefmap = NULL; |
e0ac80ab |
ctx.virname = &virname; |
8ef83e0b |
ctx.fmap = &thefmap; |
e0ac80ab |
ctx.engine = cl_engine_new();
fail_unless(!!ctx.engine, "cl_engine_new() failed");
root = (struct cli_matcher *) mpool_calloc(ctx.engine->mempool, 1, sizeof(struct cli_matcher));
fail_unless(root != NULL, "root == NULL");
#ifdef USE_MPOOL
root->mempool = ctx.engine->mempool;
#endif
ctx.engine->root[0] = root;
}
static void teardown(void)
{
cl_engine_free((struct cl_engine*)ctx.engine);
}
START_TEST (test_ac_scanbuff) { |
ec285505 |
struct cli_ac_data mdata; |
e0ac80ab |
struct cli_matcher *root; |
ec285505 |
unsigned int i;
int ret;
|
e0ac80ab |
root = ctx.engine->root[0]; |
ec285505 |
fail_unless(root != NULL, "root == NULL");
root->ac_only = 1;
|
7866b37c |
#ifdef USE_MPOOL |
47d40feb |
root->mempool = mpool_create(); |
563582a1 |
#endif |
5b74e89a |
ret = cli_ac_init(root, CLI_DEFAULT_AC_MINDEPTH, CLI_DEFAULT_AC_MAXDEPTH, 1); |
ec285505 |
fail_unless(ret == CL_SUCCESS, "cli_ac_init() failed");
|
e0ac80ab |
|
ec285505 |
for(i = 0; ac_testdata[i].data; i++) { |
33872a43 |
ret = cli_parse_add(root, ac_testdata[i].virname, ac_testdata[i].hexsig, 0, 0, "*", 0, NULL, 0); |
ec285505 |
fail_unless(ret == CL_SUCCESS, "cli_parse_add() failed");
}
ret = cli_ac_buildtrie(root);
fail_unless(ret == CL_SUCCESS, "cli_ac_buildtrie() failed");
|
aca9ea82 |
ret = cli_ac_initdata(&mdata, root->ac_partsigs, 0, 0, CLI_DEFAULT_AC_TRACKLEN); |
ec285505 |
fail_unless(ret == CL_SUCCESS, "cli_ac_initdata() failed");
for(i = 0; ac_testdata[i].data; i++) { |
e4a0f2c9 |
ret = cli_ac_scanbuff((const unsigned char*)ac_testdata[i].data, strlen(ac_testdata[i].data), &virname, NULL, NULL, root, &mdata, 0, 0, NULL, AC_SCAN_VIR, NULL); |
d5d06ecc |
fail_unless_fmt(ret == CL_VIRUS, "cli_ac_scanbuff() failed for %s", ac_testdata[i].virname);
fail_unless_fmt(!strncmp(virname, ac_testdata[i].virname, strlen(ac_testdata[i].virname)), "Dataset %u matched with %s", i, virname); |
e0ac80ab |
|
e4a0f2c9 |
ret = cli_scanbuff((const unsigned char*)ac_testdata[i].data, strlen(ac_testdata[i].data), 0, &ctx, 0, NULL); |
e0ac80ab |
fail_unless_fmt(ret == CL_VIRUS, "cli_scanbuff() failed for %s", ac_testdata[i].virname);
fail_unless_fmt(!strncmp(virname, ac_testdata[i].virname, strlen(ac_testdata[i].virname)), "Dataset %u matched with %s", i, virname); |
ec285505 |
}
cli_ac_freedata(&mdata);
}
END_TEST
START_TEST (test_bm_scanbuff) {
struct cli_matcher *root;
const char *virname = NULL;
int ret;
|
e0ac80ab |
root = ctx.engine->root[0]; |
ec285505 |
fail_unless(root != NULL, "root == NULL");
|
7866b37c |
#ifdef USE_MPOOL |
47d40feb |
root->mempool = mpool_create(); |
563582a1 |
#endif |
ec285505 |
ret = cli_bm_init(root);
fail_unless(ret == CL_SUCCESS, "cli_bm_init() failed");
|
33872a43 |
ret = cli_parse_add(root, "Sig1", "deadbabe", 0, 0, "*", 0, NULL, 0); |
ec285505 |
fail_unless(ret == CL_SUCCESS, "cli_parse_add() failed"); |
33872a43 |
ret = cli_parse_add(root, "Sig2", "deadbeef", 0, 0, "*", 0, NULL, 0); |
ec285505 |
fail_unless(ret == CL_SUCCESS, "cli_parse_add() failed"); |
33872a43 |
ret = cli_parse_add(root, "Sig3", "babedead", 0, 0, "*", 0, NULL, 0); |
ec285505 |
fail_unless(ret == CL_SUCCESS, "cli_parse_add() failed");
|
6ad45a29 |
ret = cli_bm_scanbuff((const unsigned char*)"blah\xde\xad\xbe\xef", 12, &virname, NULL, root, 0, NULL, NULL, NULL);
fail_unless(ret == CL_VIRUS, "cli_bm_scanbuff() failed");
fail_unless(!strncmp(virname, "Sig2", 4), "Incorrect signature matched in cli_bm_scanbuff()\n");
}
END_TEST
START_TEST (test_ac_scanbuff_allscan) {
struct cli_ac_data mdata;
struct cli_matcher *root;
unsigned int i;
int ret;
root = ctx.engine->root[0];
fail_unless(root != NULL, "root == NULL");
root->ac_only = 1;
#ifdef USE_MPOOL
root->mempool = mpool_create();
#endif
ret = cli_ac_init(root, CLI_DEFAULT_AC_MINDEPTH, CLI_DEFAULT_AC_MAXDEPTH, 1);
fail_unless(ret == CL_SUCCESS, "cli_ac_init() failed");
for(i = 0; ac_testdata[i].data; i++) {
ret = cli_parse_add(root, ac_testdata[i].virname, ac_testdata[i].hexsig, 0, 0, "*", 0, NULL, 0);
fail_unless(ret == CL_SUCCESS, "cli_parse_add() failed");
}
ret = cli_ac_buildtrie(root);
fail_unless(ret == CL_SUCCESS, "cli_ac_buildtrie() failed");
ret = cli_ac_initdata(&mdata, root->ac_partsigs, 0, 0, CLI_DEFAULT_AC_TRACKLEN);
fail_unless(ret == CL_SUCCESS, "cli_ac_initdata() failed");
ctx.options |= CL_SCAN_ALLMATCHES;
for(i = 0; ac_testdata[i].data; i++) {
ret = cli_ac_scanbuff((const unsigned char*)ac_testdata[i].data, strlen(ac_testdata[i].data), &virname, NULL, NULL, root, &mdata, 0, 0, NULL, AC_SCAN_VIR, NULL);
fail_unless_fmt(ret == CL_VIRUS, "cli_ac_scanbuff() failed for %s", ac_testdata[i].virname);
fail_unless_fmt(!strncmp(virname, ac_testdata[i].virname, strlen(ac_testdata[i].virname)), "Dataset %u matched with %s", i, virname);
ret = cli_scanbuff((const unsigned char*)ac_testdata[i].data, strlen(ac_testdata[i].data), 0, &ctx, 0, NULL);
fail_unless_fmt(ret == CL_VIRUS, "cli_scanbuff() failed for %s", ac_testdata[i].virname);
fail_unless_fmt(!strncmp(virname, ac_testdata[i].virname, strlen(ac_testdata[i].virname)), "Dataset %u matched with %s", i, virname);
if (ctx.num_viruses) {
free((void *)ctx.virname);
ctx.num_viruses = 0;
ctx.size_viruses = 0;
}
}
cli_ac_freedata(&mdata);
}
END_TEST
START_TEST (test_bm_scanbuff_allscan) {
struct cli_matcher *root;
const char *virname = NULL;
int ret;
root = ctx.engine->root[0];
fail_unless(root != NULL, "root == NULL");
#ifdef USE_MPOOL
root->mempool = mpool_create();
#endif
ret = cli_bm_init(root);
fail_unless(ret == CL_SUCCESS, "cli_bm_init() failed");
ret = cli_parse_add(root, "Sig1", "deadbabe", 0, 0, "*", 0, NULL, 0);
fail_unless(ret == CL_SUCCESS, "cli_parse_add() failed");
ret = cli_parse_add(root, "Sig2", "deadbeef", 0, 0, "*", 0, NULL, 0);
fail_unless(ret == CL_SUCCESS, "cli_parse_add() failed");
ret = cli_parse_add(root, "Sig3", "babedead", 0, 0, "*", 0, NULL, 0);
fail_unless(ret == CL_SUCCESS, "cli_parse_add() failed");
ret = cli_bm_scanbuff((const unsigned char*)"blah\xde\xad\xbe\xef", 12, &virname, NULL, root, 0, NULL, NULL, NULL); |
ec285505 |
fail_unless(ret == CL_VIRUS, "cli_bm_scanbuff() failed");
fail_unless(!strncmp(virname, "Sig2", 4), "Incorrect signature matched in cli_bm_scanbuff()\n");
}
END_TEST
Suite *test_matchers_suite(void)
{
Suite *s = suite_create("matchers");
TCase *tc_matchers;
tc_matchers = tcase_create("matchers");
suite_add_tcase(s, tc_matchers); |
e0ac80ab |
tcase_add_checked_fixture (tc_matchers, setup, teardown); |
ec285505 |
tcase_add_test(tc_matchers, test_ac_scanbuff);
tcase_add_test(tc_matchers, test_bm_scanbuff); |
6ad45a29 |
tcase_add_test(tc_matchers, test_ac_scanbuff_allscan);
tcase_add_test(tc_matchers, test_bm_scanbuff_allscan); |
ec285505 |
return s;
}
|