예제 #1
0
void diff_file_mem(int fd, const char *ref, size_t len)
{
	char c1,c2;
	size_t p, reflen = len;
	char *buf = cli_malloc(len);

	fail_unless_fmt(!!buf, "unable to malloc buffer: %d", len);
	p = read(fd, buf, len);
	fail_unless_fmt(p == len,  "file is smaller: %lu, expected: %lu", p, len);
	p = 0;
	while(len > 0) {
		c1 = ref[p];
		c2 = buf[p];
		if(c1 != c2)
			break;
		p++;
		len--;
	}
	if (len > 0)
		fail_unless_fmt(c1 == c2, "file contents mismatch at byte: %lu, was: %c, expected: %c", p, c2, c1);
	free(buf);
	p = lseek(fd, 0, SEEK_END);
        fail_unless_fmt(p == reflen, "trailing garbage, file size: %ld, expected: %ld", p, reflen);
	close(fd);
}
예제 #2
0
END_TEST

START_TEST (test_cl_scanmap_callback_mem_allscan)
{
    const char *virname = NULL;
    unsigned long int scanned = 0;
    cl_fmap_t *map;
    int ret;
    void *mem;
    unsigned long size;
    char file[256];

    int fd = get_test_file(_i, file, sizeof(file), &size);

    mem = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0);
    fail_unless(mem != MAP_FAILED, "mmap");

    /* intentionally use different way than scanners.c for testing */
    map = cl_fmap_open_memory(mem, size);
    fail_unless(!!map, "cl_fmap_open_mem %s");

    cli_dbgmsg("scanning (mem) allscan %s\n", file);
    ret = cl_scanmap_callback(map, &virname, &scanned, g_engine, CL_SCAN_ALLMATCHES+CL_SCAN_STDOPT, NULL);
    cli_dbgmsg("scan end (mem) allscan %s\n", file);
    if (!FALSE_NEGATIVE) {
      fail_unless_fmt(ret == CL_VIRUS, "cl_scanmap_callback failed for %s: %s", file, cl_strerror(ret));
      fail_unless_fmt(virname && !strcmp(virname, "ClamAV-Test-File.UNOFFICIAL"), "virusname: %s for %s", virname, file);
    }
    close(fd);
    cl_fmap_close(map);
    munmap(mem, size);
}
예제 #3
0
END_TEST

static size_t prepare_instream(char *buf, size_t off, size_t buflen)
{
    STATBUF stbuf;
    int fd, nread;
    uint32_t chunk;
    fail_unless_fmt(STAT(SCANFILE, &stbuf) != -1, "stat failed for %s: %s", SCANFILE, strerror(errno));

    fd = open(SCANFILE, O_RDONLY);
    fail_unless_fmt(fd != -1, "open failed: %s\n", strerror(errno));

    chunk = htonl(stbuf.st_size);
    memcpy(&buf[off], &chunk, sizeof(chunk));
    off += 4;
    nread = read(fd, &buf[off], buflen-off-4);
    fail_unless_fmt(nread == stbuf.st_size, "read failed: %d != %d, %s\n", nread, stbuf.st_size, strerror(errno));
    off += nread;
    buf[off++]=0;
    buf[off++]=0;
    buf[off++]=0;
    buf[off++]=0;
    close(fd);
    return off;
}
예제 #4
0
static void tst_fildes(const char *cmd, size_t len, int fd,
			const char *expect, size_t expect_len, int closefd, int singlemsg)
{
    char *recvdata, *p;
    int rc;

    conn_setup();
    fail_unless_fmt(sendmsg_fd(sockd, cmd, len, fd, singlemsg) != -1,
		     "Failed to sendmsg: %s\n", strerror(errno));

    if (closefd)
	close(fd);

    recvdata = recvfull(sockd, &len);
    p = strchr(recvdata, ':');

    fail_unless_fmt(!!p, "Reply doesn't contain ':' : %s\n", recvdata);
    *p++ = '\0';

    fail_unless_fmt(sscanf(recvdata, "fd[%u]", &rc) == 1, "Reply doesn't contain fd: %s\n", recvdata);

    len -= p - recvdata;
    fail_unless_fmt(len == expect_len, "Reply has wrong size: %lu, expected %lu, reply: %s, expected: %s\n",
		    len, expect_len, p, expect);

    rc = memcmp(p, expect, expect_len);
    fail_unless_fmt(!rc, "Wrong reply for command %s: |%s|, expected: |%s|\n", cmd, p, expect);
    free(recvdata);
    conn_teardown();
}
예제 #5
0
END_TEST

START_TEST (test_cl_scanmap_callback_handle_allscan)
{
    const char *virname = NULL;
    unsigned long int scanned = 0;
    cl_fmap_t *map;
    int ret;
    char file[256];
    unsigned long size;

    int fd = get_test_file(_i, file, sizeof(file), &size);
    /* intentionally use different way than scanners.c for testing */
    map = cl_fmap_open_handle(&fd, 0, size, pread_cb, 1);
    fail_unless(!!map, "cl_fmap_open_handle %s");

    cli_dbgmsg("scanning (handle) allscan %s\n", file);
    ret = cl_scanmap_callback(map, &virname, &scanned, g_engine, CL_SCAN_ALLMATCHES+CL_SCAN_STDOPT, NULL);
    cli_dbgmsg("scan end (handle) allscan %s\n", file);

    if (!FALSE_NEGATIVE) {
      fail_unless_fmt(ret == CL_VIRUS, "cl_scanmap_callback_allscan failed for %s: %s", file, cl_strerror(ret));
      fail_unless_fmt(virname && !strcmp(virname, "ClamAV-Test-File.UNOFFICIAL"), "virusname: %s", virname);
    }
    close(fd);
}
예제 #6
0
END_TEST
#endif

START_TEST (test_fildes_many)
{
    const char idsession[] = "zIDSESSION";
    int dummyfd, i, killed = 0;
    conn_setup();
    dummyfd = open(SCANFILE, O_RDONLY);
    fail_unless_fmt(dummyfd != -1, "failed to open %s: %s\n", SCANFILE, strerror(errno));

    fail_unless_fmt(send(sockd, idsession, sizeof(idsession), 0) == sizeof(idsession), "send IDSESSION failed\n");
    for (i=0;i<1024;i++) {
	if (sendmsg_fd(sockd, "zFILDES", sizeof("zFILDES"), dummyfd, 1) == -1) {
	    killed = 1;
	    break;
	}
    }
    close(dummyfd);
    if (send(sockd, "zEND", sizeof("zEND"), 0) == -1) {
	killed = 1;
    }
    conn_teardown();

    conn_setup();
    test_command("zPING", sizeof("zPING"), NULL, "PONG", 5);
    conn_teardown();
}
예제 #7
0
END_TEST

START_TEST (test_idsession_stress)
{
    char buf[BUFSIZ];
    size_t i;
    char *data, *p;
    size_t len;

    conn_setup();

    fail_unless_fmt(send(sockd, "zIDSESSION", sizeof("zIDSESSION"), 0) == sizeof("zIDSESSION"),
		    "send() failed: %s\n", strerror(errno));
    for (i=0;i < 1024; i++) {
	snprintf(buf, sizeof(buf), "%u", (unsigned)(i+1));
	fail_unless(send(sockd, "zVERSION", sizeof("zVERSION"), 0) == sizeof("zVERSION"),
		    "send failed: %s\n",strerror(errno));
	data = recvpartial(sockd, &len, 1);
	p = strchr(data, ':');
	fail_unless_fmt(!!p, "wrong VERSION reply (%u): %s\n", i, data);
	*p++ = '\0';
	fail_unless_fmt(*p == ' ', "wrong VERSION reply (%u): %s\n", i, p);
	*p++  = '\0';

	fail_unless_fmt(!strcmp(p, VERSION_REPLY), "wrong VERSION reply: %s\n", data);
	fail_unless_fmt(!strcmp(data, buf), "wrong IDSESSION id: %s\n", data);

	free(data);
    }

    conn_teardown();
}
예제 #8
0
END_TEST
#endif

#define EXPECT_INSTREAM "stream: ClamAV-Test-File.UNOFFICIAL FOUND\n"
#define EXPECT_INSTREAM0 "stream: ClamAV-Test-File.UNOFFICIAL FOUND"

#define STATS_REPLY "POOLS: 1\n\nSTATE: VALID PRIMARY\n"
START_TEST (test_stats)
{
    char *recvdata;
    size_t len = strlen("nSTATS\n");
    int rc;

    conn_setup();
    rc = send(sockd, "nSTATS\n", len, 0);
    fail_unless_fmt((size_t)rc == len, "Unable to send(): %s\n", strerror(errno));

    recvdata = recvfull(sockd, &len);

    fail_unless_fmt(len > strlen(STATS_REPLY), "Reply has wrong size: %lu, minimum %lu, reply: %s\n",
		    len, strlen(STATS_REPLY), recvdata);

    if (len > strlen(STATS_REPLY))
	len = strlen(STATS_REPLY);
    rc = strncmp(recvdata, STATS_REPLY, len);

    fail_unless_fmt(rc == 0, "Wrong reply: %s\n", recvdata);
    free(recvdata);
    conn_teardown();
}
예제 #9
0
END_TEST

START_TEST (test_cl_scandesc_callback_allscan)
{
    const char *virname = NULL;
    const char **virpp = &virname;
    char file[256];
    unsigned long size;
    unsigned long int scanned = 0;
    int ret;

    int fd = get_test_file(_i, file, sizeof(file), &size);

    cli_dbgmsg("scanning (scandesc_cb_allscan) %s\n", file);
    /* TODO: test callbacks */
    ret = cl_scandesc_callback(fd, virpp, &scanned, g_engine, CL_SCAN_ALLMATCHES+CL_SCAN_STDOPT, NULL);
    cli_dbgmsg("scan end (scandesc_cb_allscan) %s\n", file);

    if (!FALSE_NEGATIVE) {
        fail_unless_fmt(ret == CL_VIRUS, "cl_scanfile_allscan failed for %s: %s", file, cl_strerror(ret));
        virpp = (const char **)*virpp; /* allscan api hack */
        fail_unless_fmt(*virpp && !strcmp(*virpp, "ClamAV-Test-File.UNOFFICIAL"), "virusname: %s", *virpp);
        free((void *)virpp);
    }
    close(fd);
}
예제 #10
0
static void psetup_impl(int load2)
{
	FILE *f;
	int rc;
	unsigned signo=0;

	engine = cl_engine_new();
	fail_unless(!!engine , "cl_engine_new");

	phishing_init(engine);
	fail_unless(!!engine->phishcheck, "phishing_init");

	rc = init_domainlist(engine);
	fail_unless(rc == 0,"init_domainlist");

	f = fdopen(open_testfile("input/daily.pdb"),"r");
	fail_unless(!!f, "fopen daily.pdb");

	rc = load_regex_matcher(engine, engine->domainlist_matcher,  f, &signo, 0, 0, NULL, 1);
	fail_unless(rc == 0, "load_regex_matcher");
	fclose(f);

	fail_unless_fmt(signo == 201, "Incorrect number of signatures: %u, expected %u", signo, 201);

	if(load2) {
		f = fdopen(open_testfile("input/daily.gdb"),"r");
		fail_unless(!!f, "fopen daily.gdb");

		signo = 0;
		rc = load_regex_matcher(engine, engine->domainlist_matcher,  f, &signo, 0, 0, NULL, 1);
		fail_unless(rc == 0, "load_regex_matcher");
		fclose(f);

		fail_unless_fmt(signo == 4, "Incorrect number of signatures: %u, expected %u", signo, 4);
	}
	loaded_2 = load2;

	rc = init_whitelist(engine);
	fail_unless(rc == 0,"init_whitelist");

	f = fdopen(open_testfile("input/daily.wdb"),"r");
	signo = 0;
	rc = load_regex_matcher(engine, engine->whitelist_matcher, f, &signo, 0, 1, NULL, 1);
	fail_unless(rc == 0,"load_regex_matcher");
	fclose(f);

	fail_unless_fmt(signo == 31, "Incorrect number of signatures: %u, expected %u", signo, 31);

	rc = cli_build_regex_list(engine->whitelist_matcher);
	fail_unless(rc == 0,"cli_build_regex_list");

	rc = cli_build_regex_list(engine->domainlist_matcher);
	fail_unless(rc == 0,"cli_build_regex_list");

	fail_unless(is_regex_ok(engine->whitelist_matcher),"is_regex_ok");
	fail_unless(is_regex_ok(engine->domainlist_matcher),"is_regex_ok");
}
예제 #11
0
END_TEST

START_TEST (test_pcre_scanbuff_allscan) {
	struct cli_ac_data mdata;
	struct cli_matcher *root;
	char *hexsig;
	unsigned int i, hexlen;
	int ret;

    root = ctx.engine->root[0];
    fail_unless(root != NULL, "root == NULL");

#ifdef USE_MPOOL
    root->mempool = mpool_create();
#endif
    ret = cli_pcre_init();
    fail_unless(ret == CL_SUCCESS, "[pcre] cli_pcre_init() failed");

    for(i = 0; pcre_testdata[i].data; i++) {
	hexlen = strlen(PCRE_BYPASS) + strlen(pcre_testdata[i].hexsig) + 1;

	hexsig = cli_calloc(hexlen, sizeof(char));
	fail_unless(hexsig != NULL, "[pcre] failed to prepend bypass (out-of-memory)");

	strncat(hexsig, PCRE_BYPASS, hexlen);
	strncat(hexsig, pcre_testdata[i].hexsig, hexlen);

	ret = cli_parse_add(root, pcre_testdata[i].virname, hexsig, 0, 0, 0, pcre_testdata[i].offset, 0, NULL, 0);
	fail_unless(ret == CL_SUCCESS, "[pcre] cli_parse_add() failed");
	free(hexsig);
    }

    ret = cli_pcre_build(root, CLI_DEFAULT_PCRE_MATCH_LIMIT, CLI_DEFAULT_PCRE_RECMATCH_LIMIT, NULL);
    fail_unless(ret == CL_SUCCESS, "[pcre] cli_pcre_build() failed");

    // recomputate offsets

    ret = cli_ac_initdata(&mdata, root->ac_partsigs, root->ac_lsigs, root->ac_reloff_num, CLI_DEFAULT_AC_TRACKLEN);
    fail_unless(ret == CL_SUCCESS, "[pcre] cli_ac_initdata() failed");

    ctx.options |= CL_SCAN_ALLMATCHES;
    for(i = 0; pcre_testdata[i].data; i++) {
	ret = cli_pcre_scanbuf((const unsigned char*)pcre_testdata[i].data, strlen(pcre_testdata[i].data), &virname, NULL, root, NULL, NULL, NULL);
	fail_unless_fmt(ret == pcre_testdata[i].expected_result, "[pcre] cli_pcre_scanbuff() failed for %s (%d != %d)", pcre_testdata[i].virname, ret, pcre_testdata[i].expected_result);
	if (pcre_testdata[i].expected_result == CL_VIRUS)
	    fail_unless_fmt(!strncmp(virname, pcre_testdata[i].virname, strlen(pcre_testdata[i].virname)), "[pcre] Dataset %u matched with %s", i, virname);

	ret = cli_scanbuff((const unsigned char*)pcre_testdata[i].data, strlen(pcre_testdata[i].data), 0, &ctx, 0, NULL);
	fail_unless_fmt(ret == pcre_testdata[i].expected_result, "[pcre] cli_scanbuff() failed for %s", pcre_testdata[i].virname);
	/* num_virus field add to test case struct */
	if (ctx.num_viruses)
	    ctx.num_viruses = 0;
    }

    cli_ac_freedata(&mdata);
}
예제 #12
0
static int cb_expect_multi(void *cbdata, const char *suffix, size_t len, const struct regex_list *r)
{
	const char **exp = cbdata;
	fail_unless(!!exp, "expected data");
	exp++;
	fail_unless_fmt(!!*exp, "expected no suffix, got: %s\n",suffix);
	fail_unless_fmt(!!exp[cb_called], "expected less suffixes, but already got: %d\n", cb_called);
	fail_unless_fmt(strcmp(exp[cb_called], suffix) == 0,
			"suffix mismatch, was: %s, expected: %s\n",suffix, exp[cb_called]);
	fail_unless_fmt(strlen(suffix) == len, "incorrect suffix len, expected: %d, got: %d\n", strlen(suffix), len);
	cb_called++;
	return 0;
}
예제 #13
0
static void init_testfiles(void)
{
    struct dirent *dirent;
    unsigned i = 0;
    int expect = expected_testfiles;

    DIR *d = opendir(OBJDIR"/../test");
    fail_unless(!!d, "opendir");
    if (!d)
	return;
    testfiles = NULL;
    testfiles_n = 0;
    while ((dirent = readdir(d))) {
	if (strncmp(dirent->d_name, "clam", 4))
	    continue;
        i++;
	testfiles = cli_realloc(testfiles, i*sizeof(*testfiles));
	fail_unless(!!testfiles, "cli_realloc");
	testfiles[i-1] = strdup(dirent->d_name);
    }
    testfiles_n = i;
    if (get_fpu_endian() == FPU_ENDIAN_UNKNOWN)
        expect--;
    expect -= skip_files();
    fail_unless_fmt(testfiles_n == expect, "testfiles: %d != %d", testfiles_n, expect);

    closedir(d);
}
예제 #14
0
static int conn_tcp(int port)
{
    struct sockaddr_in server;
    int rc;
    int sd = socket(AF_INET, SOCK_STREAM, 0);
    fail_unless_fmt(sd != -1, "Unable to create socket: %s\n", strerror(errno));

    memset(&server, 0, sizeof(server));
    server.sin_family = AF_INET;
    server.sin_port = htons(port);
    server.sin_addr.s_addr = inet_addr("127.0.0.1");

    rc = connect(sd, (struct sockaddr *)&server, sizeof(server));
    fail_unless_fmt(rc != -1, "Unable to connect(): %s\n", strerror(errno));
    return sd;
}
예제 #15
0
void diff_files(int fd, int ref_fd)
{
	char *ref;
	ssize_t nread;
	off_t siz = lseek(ref_fd, 0, SEEK_END);
	fail_unless_fmt(siz != -1, "lseek failed");

	ref = cli_malloc(siz);
	fail_unless_fmt(!!ref, "unable to malloc buffer: %d", siz);

	fail_unless_fmt(lseek(ref_fd, 0, SEEK_SET) == 0,"lseek failed");
	nread = read(ref_fd, ref, siz);
        fail_unless_fmt(nread == siz, "short read, expected: %ld, was: %ld", siz, nread);
	close(ref_fd);
	diff_file_mem(fd, ref, siz);
	free(ref);
}
예제 #16
0
static int cb_expect_single(void *cbdata, const char *suffix, size_t len, const struct regex_list *regex)
{
	const char *expected = cbdata;
	cb_called++;
	fail_unless_fmt(suffix && strcmp(suffix, expected) == 0,
			"suffix mismatch, was: %s, expected: %s\n", suffix, expected);
	return 0;
}
예제 #17
0
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, "*", 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)
	    ctx.num_viruses = 0;
     }

    cli_ac_freedata(&mdata);
}
예제 #18
0
static void jstest_setup(void)
{
    cl_init(CL_INIT_DEFAULT);
    state = cli_js_init();
    fail_unless(!!state, "js init");
    tmpdir = cli_gentemp(NULL);
    fail_unless(!!tmpdir,"js tmp dir");
    fail_unless_fmt(mkdir(tmpdir, 0700) == 0, "tempdir mkdir of %s failed: %s", tmpdir, strerror(errno));
}
예제 #19
0
static void conn_setup_mayfail(int may)
{
    int rc;
    struct sockaddr_un nixsock;
    memset((void *)&nixsock, 0, sizeof(nixsock));
    nixsock.sun_family = AF_UNIX;
    strncpy(nixsock.sun_path, SOCKET, sizeof(nixsock.sun_path));

    sockd = socket(AF_UNIX, SOCK_STREAM, 0);
    if (sockd == -1 && (may && (errno == EMFILE || errno == ENFILE)))
	return;
    fail_unless_fmt(sockd != -1, "Unable to create socket: %s\n", strerror(errno));

    rc = connect(sockd, (struct sockaddr *)&nixsock, sizeof(nixsock));
    fail_unless_fmt(rc != -1, "Unable to connect(): %s\n", strerror(errno));

    signal(SIGPIPE, SIG_IGN);
}
예제 #20
0
END_TEST

START_TEST (test_ac_scanbuff_ex) {
	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, "[ac_ex] cli_ac_init() failed");

    for(i = 0; ac_sigopts_testdata[i].data; i++) {
	ret = cli_sigopts_handler(root, ac_sigopts_testdata[i].virname, ac_sigopts_testdata[i].hexsig, ac_sigopts_testdata[i].sigopts, 0, 0, ac_sigopts_testdata[i].offset, 0, NULL, 0);
	fail_unless(ret == CL_SUCCESS, "[ac_ex] cli_sigopts_handler() failed");
    }

    ret = cli_ac_buildtrie(root);
    fail_unless(ret == CL_SUCCESS, "[ac_ex] cli_ac_buildtrie() failed");

    ret = cli_ac_initdata(&mdata, root->ac_partsigs, 0, 0, CLI_DEFAULT_AC_TRACKLEN);
    fail_unless(ret == CL_SUCCESS, "[ac_ex] cli_ac_initdata() failed");

    for(i = 0; ac_sigopts_testdata[i].data; i++) {
	ret = cli_ac_scanbuff((const unsigned char*)ac_sigopts_testdata[i].data, ac_sigopts_testdata[i].dlength, &virname, NULL, NULL, root, &mdata, 0, 0, NULL, AC_SCAN_VIR, NULL);
	fail_unless_fmt(ret == ac_sigopts_testdata[i].expected_result, "[ac_ex] cli_ac_scanbuff() failed for %s (%d != %d)", ac_sigopts_testdata[i].virname, ret, ac_sigopts_testdata[i].expected_result);
	if (ac_sigopts_testdata[i].expected_result == CL_VIRUS)
	    fail_unless_fmt(!strncmp(virname, ac_sigopts_testdata[i].virname, strlen(ac_sigopts_testdata[i].virname)), "[ac_ex] Dataset %u matched with %s", i, virname);

	ret = cli_scanbuff((const unsigned char*)ac_sigopts_testdata[i].data, ac_sigopts_testdata[i].dlength, 0, &ctx, 0, NULL);
	fail_unless_fmt(ret == ac_sigopts_testdata[i].expected_result, "[ac_ex] cli_ac_scanbuff() failed for %s (%d != %d)", ac_sigopts_testdata[i].virname, ret, ac_sigopts_testdata[i].expected_result);
    }

    cli_ac_freedata(&mdata);
}
예제 #21
0
END_TEST

START_TEST (test_cl_scanfile_allscan)
{
    const char *virname = NULL;
    char file[256];
    unsigned long size;
    unsigned long int scanned = 0;
    int ret;

    int fd = get_test_file(_i, file, sizeof(file), &size);
    close(fd);

    cli_dbgmsg("scanning (scanfile_allscan) %s\n", file);
    ret = cl_scanfile(file, &virname, &scanned, g_engine, CL_SCAN_ALLMATCHES+CL_SCAN_STDOPT);
    cli_dbgmsg("scan end (scanfile_allscan) %s\n", file);

    if (!FALSE_NEGATIVE) {
      fail_unless_fmt(ret == CL_VIRUS, "cl_scanfile_allscan failed for %s: %s", file, cl_strerror(ret));
      fail_unless_fmt(virname && !strcmp(virname, "ClamAV-Test-File.UNOFFICIAL"), "virusname: %s", virname);
    }
}
예제 #22
0
END_TEST

//* int cl_scanfile(const char *filename, const char **virname, unsigned long int *scanned, const struct cl_engine *engine, const struct cl_limits *limits, unsigned int options) */
START_TEST (test_cl_scanfile)
{
    const char *virname = NULL;
    char file[256];
    unsigned long size;
    unsigned long int scanned = 0;
    int ret;

    int fd = get_test_file(_i, file, sizeof(file), &size);
    close(fd);

    cli_dbgmsg("scanning (scanfile) %s\n", file);
    ret = cl_scanfile(file, &virname, &scanned, g_engine, CL_SCAN_STDOPT);
    cli_dbgmsg("scan end (scanfile) %s\n", file);

    if (!FALSE_NEGATIVE) {
      fail_unless_fmt(ret == CL_VIRUS , "cl_scanfile failed for %s: %s", file, cl_strerror(ret));
      fail_unless_fmt(virname && !strcmp(virname, "ClamAV-Test-File.UNOFFICIAL"), "virusname: %s", virname);
    }
}
예제 #23
0
static void test_command(const char *cmd, size_t len, const char *extra, const char *expect, size_t expect_len)
{
    void *recvdata;
    ssize_t rc;

    rc = send(sockd, cmd, len, 0);
    fail_unless_fmt((size_t)rc == len, "Unable to send(): %s\n", strerror(errno));

    if (extra) {
	rc = send(sockd, extra, strlen(extra), 0);
	fail_unless_fmt((size_t)rc == strlen(extra), "Unable to send() extra for %s: %s\n", cmd, strerror(errno));
    }
    shutdown(sockd, SHUT_WR);
    recvdata = recvfull(sockd, &len);

    fail_unless_fmt(len == expect_len, "Reply has wrong size: %lu, expected %lu, reply: %s, expected: %s\n",
		    len, expect_len, recvdata, expect);

    rc = memcmp(recvdata, expect, expect_len);
    fail_unless_fmt(!rc, "Wrong reply for command %s: |%s|, expected: |%s|\n", cmd, recvdata, expect);
    free(recvdata);

}
예제 #24
0
END_TEST

START_TEST (test_fildes_unwanted)
{
    char *recvdata;
    size_t len;
    int dummyfd;
    conn_setup();
    dummyfd = open(SCANFILE, O_RDONLY);

    /* send a 'zVERSION\0' including the ancillary data.
     * The \0 is from the extra char needed when sending ancillary data */
    fail_unless_fmt(sendmsg_fd(sockd, "zIDSESSION", strlen("zIDSESSION"), dummyfd, 1) != -1,
		    "sendmsg failed: %s\n", strerror(errno));

    recvdata = recvfull(sockd, &len);

    fail_unless_fmt(!strcmp(recvdata,"1: PROTOCOL ERROR: ancillary data sent without FILDES. ERROR"),
		    "Wrong reply: %s\n", recvdata);

    free(recvdata);
    close(dummyfd);
    conn_teardown();
}
예제 #25
0
static void engine_setup(void)
{
    unsigned int sigs = 0;
    const char *hdb = OBJDIR"/clamav.hdb";

    init_testfiles();
    if (!inited)
	fail_unless(cl_init(CL_INIT_DEFAULT) == 0, "cl_init");
    inited = 1;
    g_engine = cl_engine_new();
    fail_unless(!!g_engine, "engine");
    fail_unless_fmt(cl_load(hdb, g_engine, &sigs, CL_DB_STDOPT) == 0, "cl_load %s", hdb);
    fail_unless(sigs == 1, "sigs");
    fail_unless(cl_engine_compile(g_engine) == 0, "cl_engine_compile");
}
예제 #26
0
static void commands_setup(void)
{
    const char *nonempty = "NONEMPTYFILE";
    int fd = open(NONEXISTENT, O_RDONLY);
    if (fd != -1) close(fd);
    fail_unless(fd == -1, "Nonexistent file exists!\n");

    fd = open(ACCDENIED, O_CREAT | O_WRONLY, S_IWUSR);
    fail_unless_fmt(fd != -1,
		    "Failed to create file for access denied tests: %s\n", strerror(errno));


    fail_unless_fmt(fchmod(fd,  S_IWUSR) != -1,
		    "Failed to chmod: %s\n", strerror(errno));
    /* must not be empty file */
    fail_unless_fmt((size_t)write(fd, nonempty, strlen(nonempty)) == strlen(nonempty),
		    "Failed to write into testfile: %s\n", strerror(errno));
    close(fd);

    /* skip access denied tests when run as root, as root will ignore
     * permissions */
    if (!geteuid())
	isroot = 1;
}
예제 #27
0
int open_testfile(const char *name)
{
	int fd;
	const char * srcdir = getenv("srcdir");
	char *str;

	if(!srcdir) {
		/* when run from automake srcdir is set, but if run manually then not */
		srcdir = SRCDIR;
	}

	str = cli_malloc(strlen(name)+strlen(srcdir)+2);
	fail_unless(!!str, "cli_malloc");
	sprintf(str, "%s/%s", srcdir, name);

	fd = open(str, O_RDONLY);
	fail_unless_fmt(fd >= 0, "open() failed: %s", str);
	free(str);
	return fd;
}
예제 #28
0
static void *recvpartial(int sd, size_t *len, int partial)
{
    char *buf = NULL;
    size_t off = 0;
    int rc;

    *len = 0;
    do {
       if (off + BUFSIZ > *len) {
	    *len += BUFSIZ+1;
	    buf = realloc(buf, *len);
	    fail_unless(!!buf, "Cannot realloc buffer\n");
	}
	rc = recv(sd, buf + off, BUFSIZ, 0);
	fail_unless_fmt(rc != -1, "recv() failed: %s\n", strerror(errno));
	off += rc;
    } while (rc && (!partial || !memchr(buf, '\0', off)));
    *len = off;
    buf[*len] = '\0';
    return buf;
}
예제 #29
0
END_TEST

START_TEST (test_stream)
{
    char buf[BUFSIZ];
    char *recvdata;
    size_t len;
    unsigned port;
    int streamsd, infd, nread;

    infd = open(SCANFILE, O_RDONLY);

    fail_unless_fmt(infd != -1, "open failed: %s\n", strerror(errno));
    conn_setup();
    fail_unless_fmt(
	send(sockd, "zSTREAM", sizeof("zSTREAM"), 0) == sizeof("zSTREAM"),
	"send failed: %s\n", strerror(errno));
    recvdata = recvpartial(sockd, &len, 1);
    fail_unless_fmt (sscanf(recvdata, "PORT %u\n", &port) == 1,
		     "Wrong stream reply: %s\n", recvdata);

    free(recvdata);
    streamsd = conn_tcp(port);

    do {
	nread = read(infd, buf, sizeof(buf));
	if (nread > 0)
	    fail_unless_fmt(send(streamsd, buf, nread, 0) == nread,
			    "send failed: %s\n", strerror(errno));
    } while (nread > 0 || (nread == -1 && errno == EINTR));
    fail_unless_fmt(nread != -1, "read failed: %s\n", strerror(errno));
    close(infd);
    close(streamsd);

    recvdata = recvfull(sockd, &len);
    fail_unless_fmt(!strcmp(recvdata,"stream: ClamAV-Test-File.UNOFFICIAL FOUND"),
		    "Wrong reply: %s\n", recvdata);
    free(recvdata);

    conn_teardown();
}
예제 #30
0
END_TEST

#define END_CMD "zEND"
#define INSTREAM_CMD "zINSTREAM"
static void test_idsession_commands(int split, int instream)
{
    char buf[20480];
    size_t i, len=0, j=0;
    char *recvdata;
    char *p = buf;
    const char *replies[2 + sizeof(basic_tests)/sizeof(basic_tests[0])];

    /* test all commands that must be accepted inside an IDSESSION */
    for (i=0;i < sizeof(basic_tests)/sizeof(basic_tests[0]); i++) {
	const struct basic_test *test = &basic_tests[i];
	if (test->skiproot && isroot)
	    continue;
	if (test->ids == IDS_OK) {
	    fail_unless(p+strlen(test->command)+2 < buf+sizeof(buf), "Buffer too small");
	    *p++ = 'z';
	    strcpy(p, test->command);
	    p += strlen(test->command);
	    *p++ = '\0';
	    if (test->extra) {
		fail_unless(p+strlen(test->extra) < buf+sizeof(buf), "Buffer too small");
		strcpy(p, test->extra);
		p += strlen(test->extra);
	    }
	    replies[j++] = test->reply;
	}
	if (instream && test->ids == IDS_END) {
	    uint32_t chunk;
	    /* IDS_END - in middle of other commands, perfect for inserting
	     * INSTREAM */
	    fail_unless(p+sizeof(INSTREAM_CMD)+544< buf+sizeof(buf), "Buffer too small");
	    memcpy(p, INSTREAM_CMD, sizeof(INSTREAM_CMD));
	    p += sizeof(INSTREAM_CMD);
	    p += prepare_instream(p, 0, 552);
	    replies[j++] = EXPECT_INSTREAM0;
	    fail_unless(p+sizeof(INSTREAM_CMD)+16388< buf+sizeof(buf), "Buffer too small");
	    memcpy(p, INSTREAM_CMD, sizeof(INSTREAM_CMD));
	    p += sizeof(INSTREAM_CMD);
	    chunk=htonl(16384);
	    memcpy(p, &chunk, 4);
	    p+=4;
	    memset(p, 0x5a, 16384);
	    p += 16384;
	    *p++='\0';
	    *p++='\0';
	    *p++='\0';
	    *p++='\0';
	    replies[j++] = "stream: OK";
	}
    }
    fail_unless(p+sizeof(END_CMD) < buf+sizeof(buf), "Buffer too small");
    memcpy(p, END_CMD, sizeof(END_CMD));
    p += sizeof(END_CMD);

    if (split) {
	/* test corner-cases: 1-byte sends */
	for (i=0;i<(size_t)(p-buf);i++)
	    fail_unless((size_t)send(sockd, &buf[i], 1, 0) == 1, "send() failed: %u, %s\n", i, strerror(errno));
    } else {
	fail_unless(send(sockd, buf, p-buf, 0) == p-buf,"send() failed: %s\n", strerror(errno));
    }
    recvdata = recvfull(sockd, &len);
    p = recvdata;
    for (i=0;i < sizeof(basic_tests)/sizeof(basic_tests[0]); i++) {
	const struct basic_test *test = &basic_tests[i];
	if (test->skiproot && isroot)
	    continue;
	if (test->ids == IDS_OK) {
	    unsigned id;
	    char *q = strchr(p, ':');
	    fail_unless_fmt(!!q, "No ID in reply: %s\n", p);
	    *q = '\0';
	    fail_unless_fmt(sscanf(p, "%u", &id) == 1,"Wrong ID in reply: %s\n", p);
	    fail_unless(id > 0, "ID cannot be zero");
	    fail_unless_fmt(id <= j, "ID too big: %u, max: %u\n", id, j);
	    q += 2;
	    fail_unless_fmt(!strcmp(q, replies[id-1]),
			    "Wrong ID reply for ID %u: %s, expected %s\n",
			    id,
			    q, replies[id-1]);
	    p = q + strlen(q)+1;
	}
    }
    free(recvdata);
    conn_teardown();
}