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); }
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); }
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; }
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(); }
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); }
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(); }
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(); }
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(); }
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); }
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"); }
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); }
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; }
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); }
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; }
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); }
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; }
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); }
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)); }
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); }
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); }
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); } }
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); } }
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); }
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(); }
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"); }
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; }
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; }
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; }
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(); }
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(); }