static void htmlnorm_setup(void) { cl_init(CL_INIT_DEFAULT); dconf_setup(); dir = cli_gentemp(NULL); fail_unless(!!dir, "cli_gentemp failed"); }
static int clamav_load_database() { int ret = 0; /* return value */ int reload = 0; /* libclamav initialization */ if (CLAMAV_G(cl_initcalled) == 0){ if((ret = cl_init(CL_INIT_DEFAULT)) != CL_SUCCESS) { php_error(E_WARNING, "cl_init: failed : error code %i (%s)\n", ret, cl_strerror(ret)); return FAILURE; } else { CLAMAV_G(cl_initcalled) = 1; } } /* database reload */ if (CLAMAV_G(dbstat.dir) != NULL && cl_statchkdir(&CLAMAV_G(dbstat)) == 1) { reload = 1; cl_statfree(&CLAMAV_G(dbstat)); } /* load engine */ if (!(CLAMAV_G(dbengine) = cl_engine_new())){ php_error(E_WARNING, "Can’t create new engine\n"); return FAILURE; } if (CLAMAV_G(dbpath) == NULL) CLAMAV_G(dbpath) = (char *) cl_retdbdir(); /* database loading */ if ((ret = cl_load(CLAMAV_G(dbpath), CLAMAV_G(dbengine), &CLAMAV_G(sig_num), CL_DB_STDOPT)) != CL_SUCCESS) { php_error(E_WARNING, "cl_load: failed : error code %i (%s)\n", ret, cl_strerror(ret)); return FAILURE; } /* compile signature database */ if ((ret = cl_engine_compile(CLAMAV_G(dbengine))) != CL_SUCCESS) { php_error(E_WARNING, "cl_engine_compile : error code %i (%s\n", ret, cl_strerror(ret)); return FAILURE; } /* allocate cl_stat */ if (!reload) memset(&CLAMAV_G(dbstat), 0, sizeof(struct cl_stat)); /* database stats */ if ((ret = cl_statinidir(CLAMAV_G(dbpath), &CLAMAV_G(dbstat))) != CL_SUCCESS) { php_error(E_WARNING, "cl_statinidir : error code %i (%s\n", ret, cl_strerror(ret)); return FAILURE; } /* set engine parameters */ cl_engine_set_num(CLAMAV_G(dbengine), CL_ENGINE_MAX_FILES, CLAMAV_G(maxfiles)); cl_engine_set_num(CLAMAV_G(dbengine), CL_ENGINE_MAX_FILESIZE, CLAMAV_G(maxfilesize)); cl_engine_set_num(CLAMAV_G(dbengine), CL_ENGINE_MAX_SCANSIZE, CLAMAV_G(maxscansize)); cl_engine_set_num(CLAMAV_G(dbengine), CL_ENGINE_MAX_RECURSION, CLAMAV_G(maxreclevel)); cl_engine_set_num(CLAMAV_G(dbengine), CL_ENGINE_KEEPTMP, CLAMAV_G(keeptmp)); cl_engine_set_str(CLAMAV_G(dbengine), CL_ENGINE_TMPDIR, CLAMAV_G(tmpdir)); return ret; }
CWHandle CWInit(void) { CWHandle cwh = malloc(sizeof(struct CWHandle_T)); cl_init(CL_INIT_DEFAULT); cwh->engine = cl_engine_new(); cwh->dboptions = CL_DB_CVDNOTMP; return cwh; }
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)); }
int main(int argc, const char *argv[]) { unsigned int width = 2048, height = 2048; float * __restrict__ input; float * __restrict__ output; struct Stats bw_buffer, bw_image2d; cl_init(); bandwidth_cl_prepare(); posix_memalign((void **) &input , 32, width * height * 4 * sizeof(float)); posix_memalign((void **) &output, 32, width * height * 4 * sizeof(float)); /* run usual */ for(int k=0; k<NTRIES; k++) { TIME_START(bw_buffer) { CL_WRITE_BUFFER buffer_cl (input_tex, output_tex, width, height); CL_READ_BUFFER } TIME_END(bw_buffer, k) } for(int k=0; k<NTRIES; k++) { TIME_START(bw_image2d) { CL_WRITE_IMAGE2D image2d_cl (input_tex, output_tex, width, height); CL_READ_IMAGE2D } TIME_END(bw_image2d, k) } printf("[Results]\n"); printf("- Global memory: %lf GB/s\n", (width * height) / (1024 * 1024 * bw_buffer.min) ); printf("- Texture Memory: %lf GB/s\n", (width * height) / (1024 * 1024 * bw_image2d.min) ); return 0; }
int scanmanager() { struct cl_engine *engine; char *file, cwd[1024]; const char *filename; struct stat sb; cl_init(); engine = cl_engine_new(); return 0; }
int main(int argc, char** argv) { Vector* v = (Vector*) malloc(sizeof(Vector)); v_init(v, 0); int i; printf("[test-1] push 10 closures to bottom\n"); for (i = 0; i < 10; i++) { Closure* c = (Closure*) malloc(sizeof(Closure)); cl_init(c); c->level = i; v_push_closure(v, c); } v_print(v); printf("[test-2] push 10 closures next to their roots\n"); for (i = 0; i < 10; i++) { Closure* c = (Closure*) malloc(sizeof(Closure)); cl_init(c); c->level = i; v_push_closure(v, c); } v_print(v); printf("[test-3] pop 10 closures from top\n"); for (i = 0; i < 10; i++) { Closure* c = v_pop_top(v); cl_free(c); } v_print(v); printf("[test-4] pop 10 closures from bot\n"); for (i = 0; i < 10; i++) { Closure* c = v_pop_bottom(v); cl_free(c); } v_print(v); v_free(v); return 0; }
VirusScan::VirusScan(TrayNotify *tn) { numSignatures = 0; fTypes[0] = ".EXE"; fTypes[1] = ".BAT"; fTypes[2] = ".BIN"; fTypes[3] = ".DLL"; fTypes[4] = ".COM"; fTypes[5] = ".INF"; fTypes[6] = ".INI"; fTypes[7] = ".PDF"; fTypes[8] = ".DOC"; fTypes[9] = ".DOCX"; fTypes[10] = ".PPT"; fTypes[11] = ".PPTX"; fTypes[12] = ".SYS"; fTypes[13] = ".VBS"; /* Init AV engine */ int res = cl_init(0); cl = cl_engine_new(); if (res != CL_SUCCESS) { ErrorLog::logErrorToFile("*CRITICAL*", "Unable to initialize AV engine: ", (char*)cl_strerror(res)); std::cout << cl_strerror(res); return; } res = cl_load(cl_retdbdir(), cl, &numSignatures, CL_DB_STDOPT); if (res != CL_SUCCESS) { ErrorLog::logErrorToFile("*CRITICAL*", "Unable to load AV engine signatures. Check for db folder?: ", (char*)cl_strerror(res)); std::cout << cl_strerror(res); return; } res = cl_engine_compile(cl); if (res != CL_SUCCESS) { ErrorLog::logErrorToFile("*CRITICAL*", "Unable to compile AV engine rules: ", (char*)cl_strerror(res)); std::cout << cl_strerror(res); return; } char msgStr[100]; sprintf(msgStr, "ClamAV engine initialized. %d signatures loaded.", numSignatures); ErrorLog::logErrorToFile("*INFO*", msgStr); tn->sendMessage(msgStr, "ClamAV"); tn->setHoverMessage("UsbNinja Daemon\nClamAV Loaded"); }
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"); }
int main(int argc, char **argv) { (void)argc; (void)argv; if (init_events_init()) return 1; start_logging(); if (init_rand_seed()) return 1; if (ensure_single_instance()) return 1; if (conf_load()) return 1; if (cl_init()) return 1; if (start_task_queue()) return 1; if (start_state_manager()) return 1; if (start_debug_console()) return 1; if (enqueue_task(main2, NULL)) return 1; if (start_rpc_svc()) return 1; return 0; }
void Engine::InitOpenCL() { cl_init(m_device, m_context, m_queue); std::string clDC(clDreamcaster_Source[0]); cl::Program::Sources clDCSrc = cl::Program::Sources(1, std::make_pair(clDC.c_str(), clDC.size() ) ); cl::Program clDCProg(m_context, clDCSrc); cl_int error; std::vector<cl::Device> devices; devices.push_back(m_device); error = clDCProg.build(devices);//, clOptions); if (error != CL_SUCCESS) { cl_int error2; std::string str = clDCProg.getBuildInfo<CL_PROGRAM_BUILD_LOG>(m_device, &error2); itk_clSafeCall( error2 ); itk_clThrowBuildLog( str ); } itk_clSafeCall(error); // create cl kernels K_raycast_batch = cl::Kernel(clDCProg, "raycast_batch", &error); itk_clSafeCall(error); }
// executive entrypoint int main(int argc, char** argv) { // init libclamav if (cl_init(CL_INIT_DEFAULT) != CL_SUCCESS) { printf("could not init clamAV.\n"); return 1; } // load virus db and compile the av engine struct cl_engine* engine = cl_engine_new(); const char* db_dir = cl_retdbdir(); unsigned int signature_count = 0; printf("loading from database at %s\n", db_dir); if (cl_load(db_dir, engine, &signature_count, CL_DB_STDOPT) != CL_SUCCESS || cl_engine_compile(engine) != CL_SUCCESS) { printf("failed to load db/compile AV engine.\n"); return 1; } printf("%d virus signatures loaded.\n", signature_count); // create a socket to listen on int s = socket(AF_INET, SOCK_STREAM, 0); if (s == -1) { printf("could not create socket. reason: %s\n", strerror(errno)); return 1; } // setup socket options such that the port can be reused quickly after // program termination struct sockaddr_in local_sockaddr; local_sockaddr.sin_family = AF_INET; local_sockaddr.sin_addr.s_addr = htonl(INADDR_ANY); local_sockaddr.sin_port = htons(PROXY_PORT); int one = 1; if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)) == -1) { printf("could not set socket options. reason: %s\n", strerror(errno)); return 1; } // bind socket to the sockaddr_in structure if (bind(s, (struct sockaddr*) &local_sockaddr, sizeof(local_sockaddr)) == -1) { printf("could not bind to socket. reason: %s\n", strerror(errno)); return 1; } // set socket to listening mode if (listen(s, QUEUE_SIZE) == -1) { printf("could not listen on socket. reason: %s\n", strerror(errno)); } while (1) { // wait for a TCP connection. the accept() function will block until the // TCP handshake is complete. struct sockaddr_in remote_sockaddr; socklen_t address_len = sizeof(remote_sockaddr); int client; // client socket client = accept(s, (struct sockaddr*) &remote_sockaddr, &address_len); if (client == -1) continue; // setup thread parameters pthread_t tid; thread_params_t* params = (thread_params_t*) malloc(sizeof(thread_params_t)); if (params == NULL) { printf("error allocating memory.\n"); return 1; } params->socket_id = client; params->cl_engine = engine; // create the thread and pass the parameters over if (pthread_create(&tid, NULL, proxy_thread, params) != 0) { printf("error creating thread.\n"); return 1; } } // free up scan engine (do this once you no longer need to scan files) cl_engine_free(engine); return 0; }
int main(int argc, char *argv[]) { if (!vstr_init()) errno = ENOMEM, err(EXIT_FAILURE, "%s", __func__); vstr_cntl_conf(NULL, VSTR_CNTL_CONF_SET_FMT_CHAR_ESC, '$'); vstr_sc_fmt_add_all(NULL); if (!(io_r = vstr_make_base(NULL))) /* used in cmd line */ errno = ENOMEM, err(EXIT_FAILURE, "%s", __func__); if (!(io_w = vstr_make_base(NULL))) errno = ENOMEM, err(EXIT_FAILURE, "%s", __func__); if (!socket_poll_init(0, SOCKET_POLL_TYPE_MAP_DIRECT)) errno = ENOMEM, err(EXIT_FAILURE, "%s", __func__); srand(getpid() ^ time(NULL)); /* doesn't need to be secure... just different * for different runs */ cl_signals(); cl_init(); cl_cmd_line(argc, argv); cl_beg(); while (io_ind_w && (io_w->len || evnt_waiting() || io_ind_r || io_r->len)) { int ready = evnt_poll(); struct timeval tv; if ((ready == -1) && (errno != EINTR)) err(EXIT_FAILURE, "%s", __func__); if (ready == -1) continue; evnt_out_dbg3("1"); ready = cl_scan_io_fds(ready); evnt_out_dbg3("2"); evnt_scan_fds(ready, CL_MAX_WAIT_SEND); evnt_out_dbg3("3"); evnt_scan_send_fds(); evnt_out_dbg3("4"); gettimeofday(&tv, NULL); timer_q_run_norm(&tv); evnt_out_dbg3("5"); evnt_scan_send_fds(); evnt_out_dbg3("6"); } evnt_out_dbg3("E"); vstr_free_base(io_r); vstr_free_base(io_w); timer_q_del_base(cl_timeout_base); timer_q_del_base(cl_timer_connect_base); evnt_close_all(); vlg_free(vlg); vlg_exit(); vstr_exit(); MALLOC_CHECK_EMPTY(); exit (EXIT_SUCCESS); }
int main(int argc, char *argv[]) { FILE *f; struct cli_bc *bc; struct cli_bc_ctx *ctx; int rc, dbgargc, bc_stats=0; struct optstruct *opts; const struct optstruct *opt; unsigned funcid=0, i; struct cli_all_bc bcs; int fd = -1; unsigned tracelevel; if(check_flevel()) exit(1); opts = optparse(NULL, argc, argv, 1, OPT_CLAMBC, 0, NULL); if (!opts) { fprintf(stderr, "ERROR: Can't parse command line options\n"); exit(1); } if(optget(opts, "version")->enabled) { printf("Clam AntiVirus Bytecode Testing Tool %s\n", get_version()); cl_init(CL_INIT_DEFAULT); cli_bytecode_printversion(); optfree(opts); exit(0); } if(optget(opts, "help")->enabled || !opts->filename) { optfree(opts); help(); exit(0); } f = fopen(opts->filename[0], "r"); if (!f) { fprintf(stderr, "Unable to load %s\n", argv[1]); optfree(opts); exit(2); } bc = malloc(sizeof(*bc)); if (!bc) { fprintf(stderr, "Out of memory\n"); optfree(opts); exit(3); } if (optget(opts,"debug")->enabled) { cl_debug(); debug_flag=1; } rc = cl_init(CL_INIT_DEFAULT); if (rc != CL_SUCCESS) { fprintf(stderr,"Unable to init libclamav: %s\n", cl_strerror(rc)); optfree(opts); exit(4); } dbgargc=1; while (opts->filename[dbgargc]) dbgargc++; if (dbgargc > 1) cli_bytecode_debug(dbgargc, opts->filename); if (optget(opts, "force-interpreter")->enabled) { bcs.engine = NULL; } else { rc = cli_bytecode_init(&bcs); if (rc != CL_SUCCESS) { fprintf(stderr,"Unable to init bytecode engine: %s\n", cl_strerror(rc)); optfree(opts); exit(4); } } bcs.all_bcs = bc; bcs.count = 1; if((opt = optget(opts, "statistics"))->enabled) { while(opt) { if (!strcasecmp(opt->strarg, "bytecode")) bc_stats=1; opt = opt->nextarg; } } rc = cli_bytecode_load(bc, f, NULL, optget(opts, "trust-bytecode")->enabled, bc_stats); if (rc != CL_SUCCESS) { fprintf(stderr,"Unable to load bytecode: %s\n", cl_strerror(rc)); optfree(opts); exit(4); } fclose(f); if (bc->state == bc_skip) { fprintf(stderr,"bytecode load skipped\n"); exit(0); } if (debug_flag) printf("[clambc] Bytecode loaded\n"); if (optget(opts, "info")->enabled) { cli_bytecode_describe(bc); } else if (optget(opts, "printsrc")->enabled) { print_src(opts->filename[0]); } else if (optget(opts, "printbcir")->enabled) { cli_bytetype_describe(bc); cli_bytevalue_describe(bc, 0); cli_bytefunc_describe(bc, 0); } else { cli_ctx cctx; struct cl_engine *engine = cl_engine_new(); fmap_t *map = NULL; memset(&cctx, 0, sizeof(cctx)); if (!engine) { fprintf(stderr,"Unable to create engine\n"); optfree(opts); exit(3); } rc = cl_engine_compile(engine); if (rc) { fprintf(stderr,"Unable to compile engine: %s\n", cl_strerror(rc)); optfree(opts); exit(4); } rc = cli_bytecode_prepare2(engine, &bcs, BYTECODE_ENGINE_MASK); if (rc != CL_SUCCESS) { fprintf(stderr,"Unable to prepare bytecode: %s\n", cl_strerror(rc)); optfree(opts); exit(4); } if (debug_flag) printf("[clambc] Bytecode prepared\n"); ctx = cli_bytecode_context_alloc(); if (!ctx) { fprintf(stderr,"Out of memory\n"); exit(3); } ctx->ctx = &cctx; cctx.engine = engine; cctx.fmap = cli_calloc(sizeof(fmap_t*), engine->maxreclevel+2); if (!cctx.fmap) { fprintf(stderr,"Out of memory\n"); exit(3); } memset(&dbg_state, 0, sizeof(dbg_state)); dbg_state.file = "<libclamav>"; dbg_state.line = 0; dbg_state.col = 0; dbg_state.showline = !optget(opts, "no-trace-showsource")->enabled; tracelevel = optget(opts, "trace")->numarg; cli_bytecode_context_set_trace(ctx, tracelevel, tracehook, tracehook_op, tracehook_val, tracehook_ptr); if (opts->filename[1]) { funcid = atoi(opts->filename[1]); } cli_bytecode_context_setfuncid(ctx, bc, funcid); if (debug_flag) printf("[clambc] Running bytecode function :%u\n", funcid); if (opts->filename[1]) { i=2; while (opts->filename[i]) { rc = cli_bytecode_context_setparam_int(ctx, i-2, atoi(opts->filename[i])); if (rc != CL_SUCCESS) { fprintf(stderr,"Unable to set param %u: %s\n", i-2, cl_strerror(rc)); } i++; } } if ((opt = optget(opts,"input"))->enabled) { fd = open(opt->strarg, O_RDONLY); if (fd == -1) { fprintf(stderr, "Unable to open input file %s: %s\n", opt->strarg, strerror(errno)); optfree(opts); exit(5); } map = fmap(fd, 0, 0); if (!map) { fprintf(stderr, "Unable to map input file %s\n", opt->strarg); exit(5); } rc = cli_bytecode_context_setfile(ctx, map); if (rc != CL_SUCCESS) { fprintf(stderr, "Unable to set file %s: %s\n", opt->strarg, cl_strerror(rc)); optfree(opts); exit(5); } } /* for testing */ ctx->hooks.match_counts = deadbeefcounts; ctx->hooks.match_offsets = deadbeefcounts; rc = cli_bytecode_run(&bcs, bc, ctx); if (rc != CL_SUCCESS) { fprintf(stderr,"Unable to run bytecode: %s\n", cl_strerror(rc)); } else { uint64_t v; if (debug_flag) printf("[clambc] Bytecode run finished\n"); v = cli_bytecode_context_getresult_int(ctx); if (debug_flag) printf("[clambc] Bytecode returned: 0x%llx\n", (long long)v); } cli_bytecode_context_destroy(ctx); if (map) funmap(map); cl_engine_free(engine); free(cctx.fmap); } cli_bytecode_destroy(bc); cli_bytecode_done(&bcs); free(bc); optfree(opts); if (fd != -1) close(fd); if (debug_flag) printf("[clambc] Exiting\n"); cl_cleanup_crypto(); return 0; }
int init_virusdb() { int ret; unsigned int no = 0; virusdb = malloc(sizeof(struct virus_db)); memset(virusdb, 0, sizeof(struct virus_db)); if (!virusdb) return 0; #ifdef HAVE_LIBCLAMAV_095 if((ret = cl_init(CL_INIT_DEFAULT))) { ci_debug_printf(1, "!Can't initialize libclamav: %s\n", cl_strerror(ret)); return 0; } if(!(virusdb->db = cl_engine_new())) { ci_debug_printf(1, "Clamav DB load: Cannot create new clamav engine\n"); return 0; } if ((ret = cl_load(cl_retdbdir(), virusdb->db, &no, CL_DB_STDOPT))) { ci_debug_printf(1, "Clamav DB load: cl_load failed: %s\n", cl_strerror(ret)); #elif defined(HAVE_LIBCLAMAV_09X) if ((ret = cl_load(cl_retdbdir(), &(virusdb->db), &no, CL_DB_STDOPT))) { ci_debug_printf(1, "Clamav DB load: cl_load failed: %s\n", cl_strerror(ret)); #else if ((ret = cl_loaddbdir(cl_retdbdir(), &(virusdb->db), &no))) { ci_debug_printf(1, "cl_loaddbdir: %s\n", cl_perror(ret)); #endif return 0; } #ifdef HAVE_LIBCLAMAV_095 if ((ret = cl_engine_compile(virusdb->db))) { #else if ((ret = cl_build(virusdb->db))) { #endif ci_debug_printf(1, "Database initialization error: %s\n", cl_strerror(ret)); #ifdef HAVE_LIBCLAMAV_095 cl_engine_free(virusdb->db); #else cl_free(virusdb->db); #endif free(virusdb); virusdb = NULL; return 0; } ci_thread_mutex_init(&db_mutex); virusdb->refcount = 1; old_virusdb = NULL; return 1; } /* Instead of using struct virus_db and refcount's someone can use the cl_dup function of clamav library, but it is undocumented so I did not use it. The following implementation we are starting to reload clamav db while threads are scanning for virus but we are not allow any child to start a new scan until we are loading DB. */ /*#define DB_NO_FULL_LOCK 1*/ #undef DB_NO_FULL_LOCK int reload_virusdb() { struct virus_db *vdb = NULL; int ret; unsigned int no = 0; ci_thread_mutex_lock(&db_mutex); if (old_virusdb) { ci_debug_printf(1, "Clamav DB reload pending, cancelling.\n"); ci_thread_mutex_unlock(&db_mutex); return 0; } #ifdef DB_NO_FULL_LOCK ci_thread_mutex_unlock(&db_mutex); #endif vdb = malloc(sizeof(struct virus_db)); if (!vdb) return 0; memset(vdb, 0, sizeof(struct virus_db)); ci_debug_printf(9, "db_reload going to load db\n"); #ifdef HAVE_LIBCLAMAV_095 if(!(vdb->db = cl_engine_new())) { ci_debug_printf(1, "Clamav DB load: Cannot create new clamav engine\n"); return 0; } if ((ret = cl_load(cl_retdbdir(), vdb->db, &no, CL_DB_STDOPT))) { ci_debug_printf(1, "Clamav DB reload: cl_load failed: %s\n", cl_strerror(ret)); #elif defined(HAVE_LIBCLAMAV_09X) if ((ret = cl_load(cl_retdbdir(), &(vdb->db), &no, CL_DB_STDOPT))) { ci_debug_printf(1, "Clamav DB reload: cl_load failed: %s\n", cl_strerror(ret)); #else if ((ret = cl_loaddbdir(cl_retdbdir(), &(vdb->db), &no))) { ci_debug_printf(1, "Clamav DB reload: cl_loaddbdir failed: %s\n", cl_perror(ret)); #endif return 0; } ci_debug_printf(9, "loaded. Going to build\n"); #ifdef HAVE_LIBCLAMAV_095 if ((ret = cl_engine_compile(vdb->db))) { #else if ((ret = cl_build(vdb->db))) { #endif ci_debug_printf(1, "Clamav DB reload: Database initialization error: %s\n", cl_strerror(ret)); #ifdef HAVE_LIBCLAMAV_095 cl_engine_free(vdb->db); #else cl_free(vdb->db); #endif free(vdb); vdb = NULL; #ifdef DB_NO_FULL_LOCK /*no lock needed */ #else ci_thread_mutex_unlock(&db_mutex); #endif return 0; } ci_debug_printf(9, "Done releasing.....\n"); #ifdef DB_NO_FULL_LOCK ci_thread_mutex_lock(&db_mutex); #endif old_virusdb = virusdb; old_virusdb->refcount--; ci_debug_printf(9, "Old VirusDB refcount:%d\n", old_virusdb->refcount); if (old_virusdb->refcount <= 0) { #ifdef HAVE_LIBCLAMAV_095 cl_engine_free(old_virusdb->db); #else cl_free(old_virusdb->db); #endif free(old_virusdb); old_virusdb = NULL; } virusdb = vdb; virusdb->refcount = 1; ci_thread_mutex_unlock(&db_mutex); return 1; } CL_ENGINE *get_virusdb() { struct virus_db *vdb; ci_thread_mutex_lock(&db_mutex); vdb = virusdb; vdb->refcount++; ci_thread_mutex_unlock(&db_mutex); return vdb->db; } void release_virusdb(CL_ENGINE * db) { ci_thread_mutex_lock(&db_mutex); if (virusdb && db == virusdb->db) virusdb->refcount--; else if (old_virusdb && (db == old_virusdb->db)) { old_virusdb->refcount--; ci_debug_printf(9, "Old VirusDB refcount: %d\n", old_virusdb->refcount); if (old_virusdb->refcount <= 0) { #ifdef HAVE_LIBCLAMAV_095 cl_engine_free(old_virusdb->db); #else cl_free(old_virusdb->db); #endif free(old_virusdb); old_virusdb = NULL; } } else { ci_debug_printf(1, "BUG in srv_clamav service! please contact the author\n"); } ci_thread_mutex_unlock(&db_mutex); } void destroy_virusdb() { if (virusdb) { #ifdef HAVE_LIBCLAMAV_095 cl_engine_free(virusdb->db); #else cl_free(virusdb->db); #endif free(virusdb); virusdb = NULL; } if (old_virusdb) { #ifdef HAVE_LIBCLAMAV_095 cl_engine_free(old_virusdb->db); #else cl_free(old_virusdb->db); #endif free(old_virusdb); old_virusdb = NULL; } } void set_istag(ci_service_xdata_t * srv_xdata) { char istag[SERVICE_ISTAG_SIZE + 1]; char str_version[64]; char *daily_path; char *s1, *s2; struct cl_cvd *d1; int version = 0, cfg_version = 0; struct stat daily_stat; /*instead of 128 should be strlen("/daily.inc/daily.info")+1*/ daily_path = malloc(strlen(cl_retdbdir()) + 128); if (!daily_path) /*???????? */ return; sprintf(daily_path, "%s/daily.cvd", cl_retdbdir()); if(stat(daily_path,&daily_stat) != 0){ /* if the clamav_lib_path/daily.cvd does not exists */ sprintf(daily_path, "%s/daily.cld", cl_retdbdir()); if(stat(daily_path,&daily_stat) != 0){ /* else try to use the clamav_lib_path/daily.inc/daly.info file instead" */ sprintf(daily_path, "%s/daily.inc/daily.info", cl_retdbdir()); } } if ((d1 = cl_cvdhead(daily_path))) { version = d1->version; free(d1); } free(daily_path); s1 = (char *) cl_retver(); s2 = str_version; while (*s1 != '\0' && s2 - str_version < 64) { if (*s1 != '.') { *s2 = *s1; s2++; } s1++; } *s2 = '\0'; /*cfg_version maybe must set by user when he is changing the srv_clamav configuration.... */ snprintf(istag, SERVICE_ISTAG_SIZE, "-%.3d-%s-%d%d", cfg_version, str_version, cl_retflevel(), version); istag[SERVICE_ISTAG_SIZE] = '\0'; ci_service_set_istag(srv_xdata, istag); }
int main(int argc, char **argv) { static struct cl_engine *engine = NULL; const struct optstruct *opt; #ifndef _WIN32 struct passwd *user = NULL; struct sigaction sa; struct rlimit rlim; #endif time_t currtime; const char *dbdir, *cfgfile; char *pua_cats = NULL, *pt; int ret, tcpsock = 0, localsock = 0, i, min_port, max_port; unsigned int sigs = 0; int lsockets[2], nlsockets = 0; unsigned int dboptions = 0; #ifdef C_LINUX STATBUF sb; #endif if(check_flevel()) exit(1); #ifndef _WIN32 memset(&sa, 0, sizeof(sa)); sa.sa_handler = SIG_IGN; sigaction(SIGHUP, &sa, NULL); sigaction(SIGUSR2, &sa, NULL); #endif if((opts = optparse(NULL, argc, argv, 1, OPT_CLAMD, 0, NULL)) == NULL) { mprintf("!Can't parse command line options\n"); return 1; } if(optget(opts, "help")->enabled) { help(); optfree(opts); return 0; } if(optget(opts, "debug")->enabled) { #if defined(C_LINUX) /* [email protected]: create a dump if needed */ rlim.rlim_cur = rlim.rlim_max = RLIM_INFINITY; if(setrlimit(RLIMIT_CORE, &rlim) < 0) perror("setrlimit"); #endif debug_mode = 1; } /* parse the config file */ cfgfile = optget(opts, "config-file")->strarg; pt = strdup(cfgfile); if((opts = optparse(cfgfile, 0, NULL, 1, OPT_CLAMD, 0, opts)) == NULL) { fprintf(stderr, "ERROR: Can't open/parse the config file %s\n", pt); free(pt); return 1; } free(pt); if(optget(opts, "version")->enabled) { print_version(optget(opts, "DatabaseDirectory")->strarg); optfree(opts); return 0; } /* drop privileges */ #ifndef _WIN32 if(geteuid() == 0 && (opt = optget(opts, "User"))->enabled) { if((user = getpwnam(opt->strarg)) == NULL) { fprintf(stderr, "ERROR: Can't get information about user %s.\n", opt->strarg); optfree(opts); return 1; } if(optget(opts, "AllowSupplementaryGroups")->enabled) { #ifdef HAVE_INITGROUPS if(initgroups(opt->strarg, user->pw_gid)) { fprintf(stderr, "ERROR: initgroups() failed.\n"); optfree(opts); return 1; } #else mprintf("!AllowSupplementaryGroups: initgroups() is not available, please disable AllowSupplementaryGroups in %s\n", cfgfile); optfree(opts); return 1; #endif } else { #ifdef HAVE_SETGROUPS if(setgroups(1, &user->pw_gid)) { fprintf(stderr, "ERROR: setgroups() failed.\n"); optfree(opts); return 1; } #endif } if(setgid(user->pw_gid)) { fprintf(stderr, "ERROR: setgid(%d) failed.\n", (int) user->pw_gid); optfree(opts); return 1; } if(setuid(user->pw_uid)) { fprintf(stderr, "ERROR: setuid(%d) failed.\n", (int) user->pw_uid); optfree(opts); return 1; } } #endif /* initialize logger */ logg_lock = !optget(opts, "LogFileUnlock")->enabled; logg_time = optget(opts, "LogTime")->enabled; logok = optget(opts, "LogClean")->enabled; logg_size = optget(opts, "LogFileMaxSize")->numarg; logg_verbose = mprintf_verbose = optget(opts, "LogVerbose")->enabled; if (logg_size) logg_rotate = optget(opts, "LogRotate")->enabled; mprintf_send_timeout = optget(opts, "SendBufTimeout")->numarg; do { /* logger initialized */ if((opt = optget(opts, "LogFile"))->enabled) { char timestr[32]; logg_file = opt->strarg; if(!cli_is_abspath(logg_file)) { fprintf(stderr, "ERROR: LogFile requires full path.\n"); ret = 1; break; } time(&currtime); if(logg("#+++ Started at %s", cli_ctime(&currtime, timestr, sizeof(timestr)))) { fprintf(stderr, "ERROR: Can't initialize the internal logger\n"); ret = 1; break; } } else logg_file = NULL; if (optget(opts,"DevLiblog")->enabled) cl_set_clcb_msg(msg_callback); if((ret = cl_init(CL_INIT_DEFAULT))) { logg("!Can't initialize libclamav: %s\n", cl_strerror(ret)); ret = 1; break; } if(optget(opts, "Debug")->enabled) /* enable debug messages in libclamav */ { cl_debug(); logg_verbose = 2; } #if defined(USE_SYSLOG) && !defined(C_AIX) if(optget(opts, "LogSyslog")->enabled) { int fac = LOG_LOCAL6; opt = optget(opts, "LogFacility"); if((fac = logg_facility(opt->strarg)) == -1) { logg("!LogFacility: %s: No such facility.\n", opt->strarg); ret = 1; break; } openlog("clamd", LOG_PID, fac); logg_syslog = 1; } #endif #ifdef C_LINUX procdev = 0; if(CLAMSTAT("/proc", &sb) != -1 && !sb.st_size) procdev = sb.st_dev; #endif /* check socket type */ if(optget(opts, "TCPSocket")->enabled) tcpsock = 1; if(optget(opts, "LocalSocket")->enabled) localsock = 1; if(!tcpsock && !localsock) { logg("!Please define server type (local and/or TCP).\n"); ret = 1; break; } logg("#clamd daemon %s (OS: "TARGET_OS_TYPE", ARCH: "TARGET_ARCH_TYPE", CPU: "TARGET_CPU_TYPE")\n", get_version()); #ifndef _WIN32 if(user) logg("#Running as user %s (UID %u, GID %u)\n", user->pw_name, user->pw_uid, user->pw_gid); #endif #if defined(RLIMIT_DATA) && defined(C_BSD) if (getrlimit(RLIMIT_DATA, &rlim) == 0) { /* bb #1941. * On 32-bit FreeBSD if you set ulimit -d to >2GB then mmap() will fail * too soon (after ~120 MB). * Set limit lower than 2G if on 32-bit */ uint64_t lim = rlim.rlim_cur; if (sizeof(void*) == 4 && lim > (1ULL << 31)) { rlim.rlim_cur = 1ULL << 31; if (setrlimit(RLIMIT_DATA, &rlim) < 0) logg("!setrlimit(RLIMIT_DATA) failed: %s\n", strerror(errno)); else logg("Running on 32-bit system, and RLIMIT_DATA > 2GB, lowering to 2GB!\n"); } } #endif if(logg_size) logg("#Log file size limited to %u bytes.\n", logg_size); else logg("#Log file size limit disabled.\n"); min_port = optget(opts, "StreamMinPort")->numarg; max_port = optget(opts, "StreamMaxPort")->numarg; if (min_port < 1024 || min_port > max_port || max_port > 65535) { logg("!Invalid StreamMinPort/StreamMaxPort: %d, %d\n", min_port, max_port); ret = 1; break; } if(!(engine = cl_engine_new())) { logg("!Can't initialize antivirus engine\n"); ret = 1; break; } /* load the database(s) */ dbdir = optget(opts, "DatabaseDirectory")->strarg; logg("#Reading databases from %s\n", dbdir); if(optget(opts, "DetectPUA")->enabled) { dboptions |= CL_DB_PUA; if((opt = optget(opts, "ExcludePUA"))->enabled) { dboptions |= CL_DB_PUA_EXCLUDE; i = 0; logg("#Excluded PUA categories:"); while(opt) { if(!(pua_cats = realloc(pua_cats, i + strlen(opt->strarg) + 3))) { logg("!Can't allocate memory for pua_cats\n"); cl_engine_free(engine); ret = 1; break; } logg("# %s", opt->strarg); sprintf(pua_cats + i, ".%s", opt->strarg); i += strlen(opt->strarg) + 1; pua_cats[i] = 0; opt = opt->nextarg; } if (ret) break; logg("#\n"); pua_cats[i] = '.'; pua_cats[i + 1] = 0; } if((opt = optget(opts, "IncludePUA"))->enabled) { if(pua_cats) { logg("!ExcludePUA and IncludePUA cannot be used at the same time\n"); free(pua_cats); ret = 1; break; } dboptions |= CL_DB_PUA_INCLUDE; i = 0; logg("#Included PUA categories:"); while(opt) { if(!(pua_cats = realloc(pua_cats, i + strlen(opt->strarg) + 3))) { logg("!Can't allocate memory for pua_cats\n"); ret = 1; break; } logg("# %s", opt->strarg); sprintf(pua_cats + i, ".%s", opt->strarg); i += strlen(opt->strarg) + 1; pua_cats[i] = 0; opt = opt->nextarg; } if (ret) break; logg("#\n"); pua_cats[i] = '.'; pua_cats[i + 1] = 0; } if(pua_cats) { if((ret = cl_engine_set_str(engine, CL_ENGINE_PUA_CATEGORIES, pua_cats))) { logg("!cli_engine_set_str(CL_ENGINE_PUA_CATEGORIES) failed: %s\n", cl_strerror(ret)); free(pua_cats); ret = 1; break; } free(pua_cats); } } else { logg("#Not loading PUA signatures.\n"); } if(optget(opts, "OfficialDatabaseOnly")->enabled) { dboptions |= CL_DB_OFFICIAL_ONLY; logg("#Only loading official signatures.\n"); } /* set the temporary dir */ if((opt = optget(opts, "TemporaryDirectory"))->enabled) { if((ret = cl_engine_set_str(engine, CL_ENGINE_TMPDIR, opt->strarg))) { logg("!cli_engine_set_str(CL_ENGINE_TMPDIR) failed: %s\n", cl_strerror(ret)); ret = 1; break; } } cl_engine_set_clcb_hash(engine, hash_callback); detstats_clear(); if(optget(opts, "LeaveTemporaryFiles")->enabled) cl_engine_set_num(engine, CL_ENGINE_KEEPTMP, 1); if(optget(opts, "PhishingSignatures")->enabled) dboptions |= CL_DB_PHISHING; else logg("#Not loading phishing signatures.\n"); if(optget(opts,"Bytecode")->enabled) { dboptions |= CL_DB_BYTECODE; if((opt = optget(opts,"BytecodeSecurity"))->enabled) { enum bytecode_security s; if (!strcmp(opt->strarg, "TrustSigned")) { s = CL_BYTECODE_TRUST_SIGNED; logg("#Bytecode: Security mode set to \"TrustSigned\".\n"); } else if (!strcmp(opt->strarg, "Paranoid")) { s = CL_BYTECODE_TRUST_NOTHING; logg("#Bytecode: Security mode set to \"Paranoid\".\n"); } else { logg("!Unable to parse bytecode security setting:%s\n", opt->strarg); ret = 1; break; } if ((ret = cl_engine_set_num(engine, CL_ENGINE_BYTECODE_SECURITY, s))) { logg("^Invalid bytecode security setting %s: %s\n", opt->strarg, cl_strerror(ret)); ret = 1; break; } } if((opt = optget(opts,"BytecodeUnsigned"))->enabled) { dboptions |= CL_DB_BYTECODE_UNSIGNED; logg("#Bytecode: Enabled support for unsigned bytecode.\n"); } if((opt = optget(opts,"BytecodeMode"))->enabled) { enum bytecode_mode mode; if (!strcmp(opt->strarg, "ForceJIT")) mode = CL_BYTECODE_MODE_JIT; else if(!strcmp(opt->strarg, "ForceInterpreter")) mode = CL_BYTECODE_MODE_INTERPRETER; else if(!strcmp(opt->strarg, "Test")) mode = CL_BYTECODE_MODE_TEST; else mode = CL_BYTECODE_MODE_AUTO; cl_engine_set_num(engine, CL_ENGINE_BYTECODE_MODE, mode); } if((opt = optget(opts,"BytecodeTimeout"))->enabled) { cl_engine_set_num(engine, CL_ENGINE_BYTECODE_TIMEOUT, opt->numarg); } } else logg("#Bytecode support disabled.\n"); if(optget(opts,"PhishingScanURLs")->enabled) dboptions |= CL_DB_PHISHING_URLS; else logg("#Disabling URL based phishing detection.\n"); if(optget(opts,"DevACOnly")->enabled) { logg("#Only using the A-C matcher.\n"); cl_engine_set_num(engine, CL_ENGINE_AC_ONLY, 1); } if((opt = optget(opts, "DevACDepth"))->enabled) { cl_engine_set_num(engine, CL_ENGINE_AC_MAXDEPTH, opt->numarg); logg("#Max A-C depth set to %u\n", (unsigned int) opt->numarg); } if((ret = cl_load(dbdir, engine, &sigs, dboptions))) { logg("!%s\n", cl_strerror(ret)); ret = 1; break; } if (optget(opts, "DisableCertCheck")->enabled) engine->dconf->pe |= PE_CONF_DISABLECERT; logg("#Loaded %u signatures.\n", sigs); if((ret = cl_engine_compile(engine)) != 0) { logg("!Database initialization error: %s\n", cl_strerror(ret)); ret = 1; break; } if(tcpsock) { if ((lsockets[nlsockets] = tcpserver(opts)) == -1) { ret = 1; break; } nlsockets++; } #ifndef _WIN32 if(localsock) { mode_t sock_mode, umsk = umask(0777); /* socket is created with 000 to avoid races */ if ((lsockets[nlsockets] = localserver(opts)) == -1) { ret = 1; umask(umsk); break; } umask(umsk); /* restore umask */ if(optget(opts, "LocalSocketGroup")->enabled) { char *gname = optget(opts, "LocalSocketGroup")->strarg, *end; gid_t sock_gid = strtol(gname, &end, 10); if(*end) { struct group *pgrp = getgrnam(gname); if(!pgrp) { logg("!Unknown group %s\n", gname); ret = 1; break; } sock_gid = pgrp->gr_gid; } if(chown(optget(opts, "LocalSocket")->strarg, -1, sock_gid)) { logg("!Failed to change socket ownership to group %s\n", gname); ret = 1; break; } } if(optget(opts, "LocalSocketMode")->enabled) { char *end; sock_mode = strtol(optget(opts, "LocalSocketMode")->strarg, &end, 8); if(*end) { logg("!Invalid LocalSocketMode %s\n", optget(opts, "LocalSocketMode")->strarg); ret = 1; break; } } else sock_mode = 0777 /* & ~umsk*/; /* conservative default: umask was 0 in clamd < 0.96 */ if(chmod(optget(opts, "LocalSocket")->strarg, sock_mode & 0666)) { logg("!Cannot set socket permission to %s\n", optget(opts, "LocalSocketMode")->strarg); ret = 1; break; } nlsockets++; } /* fork into background */ if(!optget(opts, "Foreground")->enabled) { #ifdef C_BSD /* workaround for OpenBSD bug, see https://wwws.clamav.net/bugzilla/show_bug.cgi?id=885 */ for(ret=0;ret<nlsockets;ret++) { if (fcntl(lsockets[ret], F_SETFL, fcntl(lsockets[ret], F_GETFL) | O_NONBLOCK) == -1) { logg("!fcntl for lsockets[] failed\n"); close(lsockets[ret]); ret = 1; break; } } #endif gengine = engine; atexit(free_engine); if(daemonize() == -1) { logg("!daemonize() failed: %s\n", strerror(errno)); ret = 1; break; } gengine = NULL; #ifdef C_BSD for(ret=0;ret<nlsockets;ret++) { if (fcntl(lsockets[ret], F_SETFL, fcntl(lsockets[ret], F_GETFL) & ~O_NONBLOCK) == -1) { logg("!fcntl for lsockets[] failed\n"); close(lsockets[ret]); ret = 1; break; } } #endif if(!debug_mode) if(chdir("/") == -1) logg("^Can't change current working directory to root\n"); } else foreground = 1; #endif ret = recvloop_th(lsockets, nlsockets, engine, dboptions, opts); } while (0); logg("*Closing the main socket%s.\n", (nlsockets > 1) ? "s" : ""); for (i = 0; i < nlsockets; i++) { closesocket(lsockets[i]); } #ifndef _WIN32 if(nlsockets && localsock) { opt = optget(opts, "LocalSocket"); if(unlink(opt->strarg) == -1) logg("!Can't unlink the socket file %s\n", opt->strarg); else logg("Socket file removed.\n"); } #endif logg_close(); optfree(opts); return ret; }
/* * main -- * This is the main loop for the standalone curses editor. */ int main(int argc, char **argv) { static int reenter; CL_PRIVATE *clp; GS *gp; WIN *wp; size_t rows, cols; int rval; char **p_av, **t_av; const char *ttype; /* If loaded at 0 and jumping through a NULL pointer, stop. */ if (reenter++) abort(); /* Create and initialize the global structure. */ __global_list = gp = gs_init(argv[0]); /* * Strip out any arguments that vi isn't going to understand. There's * no way to portably call getopt twice, so arguments parsed here must * be removed from the argument list. */ for (p_av = t_av = argv;;) { if (*t_av == NULL) { *p_av = NULL; break; } if (!strcmp(*t_av, "--")) { while ((*p_av++ = *t_av++) != NULL); break; } *p_av++ = *t_av++; } /* Create new window */ wp = gs_new_win(gp); /* Create and initialize the CL_PRIVATE structure. */ clp = cl_init(wp); /* * Initialize the terminal information. * * We have to know what terminal it is from the start, since we may * have to use termcap/terminfo to find out how big the screen is. */ if ((ttype = getenv("TERM")) == NULL) { if (isatty(STDIN_FILENO)) fprintf(stderr, "%s: warning: TERM is not set\n", gp->progname); ttype = "unknown"; } term_init(gp->progname, ttype); /* Add the terminal type to the global structure. */ if ((OG_D_STR(gp, GO_TERM) = OG_STR(gp, GO_TERM) = strdup(ttype)) == NULL) perr(gp->progname, NULL); /* Figure out how big the screen is. */ if (cl_ssize(NULL, 0, &rows, &cols, NULL)) exit (1); /* Add the rows and columns to the global structure. */ OG_VAL(gp, GO_LINES) = OG_D_VAL(gp, GO_LINES) = rows; OG_VAL(gp, GO_COLUMNS) = OG_D_VAL(gp, GO_COLUMNS) = cols; /* Ex wants stdout to be buffered. */ (void)setvbuf(stdout, NULL, _IOFBF, 0); /* Start catching signals. */ if (sig_init(gp, NULL)) exit (1); /* Run ex/vi. */ rval = editor(wp, argc, argv); /* Clean out the global structure. */ gs_end(gp); /* Clean up signals. */ sig_end(gp); /* Clean up the terminal. */ (void)cl_quit(gp); /* * XXX * Reset the O_MESG option. */ if (clp->tgw != TGW_UNKNOWN) (void)cl_omesg(NULL, clp, clp->tgw == TGW_SET); /* * XXX * Reset the X11 xterm icon/window name. */ if (F_ISSET(clp, CL_RENAME)) cl_setname(gp, clp->oname); /* If a killer signal arrived, pretend we just got it. */ if (clp->killersig) { (void)signal(clp->killersig, SIG_DFL); (void)kill(getpid(), clp->killersig); /* NOTREACHED */ } /* Free the global and CL private areas. */ #if defined(DEBUG) || defined(PURIFY) || defined(LIBRARY) cl_end(clp); free(gp); #endif exit (rval); }
/* FIXME: No it doesn't! pcAddress is not ever referenced in this * function. * CreepLord: Fixed much better way (will accept dns hostnames) */ int dbs_server_init(void) { int sd; struct sockaddr_in sinInterface; int val; t_addr * servaddr; dbs_server_connection_list=list_create(); if (d2dbs_d2ladder_init()==-1) { eventlog(eventlog_level_error,__FUNCTION__,"d2ladder_init() failed"); return -1; } if (cl_init(DEFAULT_HASHTBL_LEN, DEFAULT_GS_MAX)==-1) { eventlog(eventlog_level_error,__FUNCTION__,"cl_init() failed"); return -1; } if (psock_init()<0) { eventlog(eventlog_level_error,__FUNCTION__,"psock_init() failed"); return -1; } sd = psock_socket(PSOCK_PF_INET, PSOCK_SOCK_STREAM, PSOCK_IPPROTO_TCP); if (sd==-1) { eventlog(eventlog_level_error,__FUNCTION__,"psock_socket() failed : %s",strerror(psock_errno())); return -1; } val = 1; if (psock_setsockopt(sd, PSOCK_SOL_SOCKET, PSOCK_SO_REUSEADDR, &val, sizeof(val)) < 0) { eventlog(eventlog_level_error,__FUNCTION__,"psock_setsockopt() failed : %s",strerror(psock_errno())); } if (!(servaddr=addr_create_str(d2dbs_prefs_get_servaddrs(),INADDR_ANY,DEFAULT_LISTEN_PORT))) { eventlog(eventlog_level_error,__FUNCTION__,"could not get servaddr"); return -1; } sinInterface.sin_family = PSOCK_AF_INET; sinInterface.sin_addr.s_addr = htonl(addr_get_ip(servaddr)); sinInterface.sin_port = htons(addr_get_port(servaddr)); if (psock_bind(sd, (struct sockaddr*)&sinInterface, (psock_t_socklen)sizeof(struct sockaddr_in)) < 0) { eventlog(eventlog_level_error,__FUNCTION__,"psock_bind() failed : %s",strerror(psock_errno())); return -1; } if (psock_listen(sd, LISTEN_QUEUE) < 0) { eventlog(eventlog_level_error,__FUNCTION__,"psock_listen() failed : %s",strerror(psock_errno())); return -1; } addr_destroy(servaddr); return sd; }
/* * main -- * This is the main loop for the standalone curses editor. */ int main(int argc, char *argv[]) { CL_PRIVATE *clp; GS *gp; size_t rows, cols; int rval; char *ttype; /* Create and initialize the global structure. */ __global_list = gp = gs_init(); /* Create and initialize the CL_PRIVATE structure. */ clp = cl_init(gp); /* * Initialize the terminal information. * * We have to know what terminal it is from the start, since we may * have to use termcap/terminfo to find out how big the screen is. */ if ((ttype = getenv("TERM")) == NULL) ttype = "unknown"; term_init(ttype); /* Add the terminal type to the global structure. */ if ((OG_D_STR(gp, GO_TERM) = OG_STR(gp, GO_TERM) = strdup(ttype)) == NULL) err(1, NULL); /* Figure out how big the screen is. */ if (cl_ssize(NULL, 0, &rows, &cols, NULL)) exit (1); /* Add the rows and columns to the global structure. */ OG_VAL(gp, GO_LINES) = OG_D_VAL(gp, GO_LINES) = rows; OG_VAL(gp, GO_COLUMNS) = OG_D_VAL(gp, GO_COLUMNS) = cols; /* Ex wants stdout to be buffered. */ (void)setvbuf(stdout, NULL, _IOFBF, 0); /* Start catching signals. */ if (sig_init(gp, NULL)) exit (1); /* Run ex/vi. */ rval = editor(gp, argc, argv); /* Clean up signals. */ sig_end(gp); /* Clean up the terminal. */ (void)cl_quit(gp); /* * XXX * Reset the O_MESG option. */ if (clp->tgw != TGW_UNKNOWN) (void)cl_omesg(NULL, clp, clp->tgw == TGW_SET); /* * XXX * Reset the X11 xterm icon/window name. */ if (F_ISSET(clp, CL_RENAME)) { (void)printf(XTERM_RENAME, ttype); (void)fflush(stdout); } /* If a killer signal arrived, pretend we just got it. */ if (clp->killersig) { (void)signal(clp->killersig, SIG_DFL); (void)kill(getpid(), clp->killersig); /* NOTREACHED */ } /* Free the global and CL private areas. */ #if defined(DEBUG) || defined(PURIFY) free(clp); free(gp); #endif exit (rval); }
BOOL init() { char whereami[PATH_MAX], *slash; int ret; ret = GetModuleFileName((HINSTANCE)&__ImageBase, whereami, sizeof(whereami) -1); if(!ret || ret == sizeof(whereami) -1) { printf("ERROR: GetModuleFileName failed\n"); return FALSE; } whereami[sizeof(whereami)-1] = '\0'; slash = strrchr(whereami, '\\'); if(!slash) { printf("ERROR: No slash found in path %s\n", whereami); return FALSE; } slash++; *slash='\0'; SetDllDirectory(whereami); __try { cl_set_clcb_msg(msg_callback); ret = cl_init(CL_INIT_DEFAULT); } __except(EXCEPTION_EXECUTE_HANDLER) { ret = -1; } SetDllDirectory(NULL); if(ret) { printf("ERROR: Failed cl_init() returned %d\n", ret); return FALSE; } strncpy(slash, "clamav_log_verbose", sizeof(whereami) - (slash - whereami)); whereami[sizeof(whereami)-1] = '\0'; logg_verbose = access(whereami, 0) == -1 ? 0 : 1; strncpy(slash, "clamav.log", sizeof(whereami) - (slash - whereami)); whereami[sizeof(whereami)-1] = '\0'; logg_nowarn = 0; logg_lock = 0; logg_time = 1; // bb #5659: force log rotation at 100 MB logg_size = 104857600; logg_rotate = 1; logg_file = strdup(whereami); if(!logg_file) { printf("ERROR: failed to duplicate log filename\n"); return FALSE; } strncpy(slash, "clamav.old.log", sizeof(whereami) - (slash - whereami)); whereami[sizeof(whereami)-1] = '\0'; if(!MoveFileEx(logg_file, whereami, MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH)) DeleteFile(logg_file); logg_noflush = 1;/* only flush on errors and warnings */ if(logg("ClamAV core initialized (version %s, flevel %d)\n", cl_retver(), cl_retflevel())<0) { printf("ERROR: logg failed\n"); return FALSE; } if(init_errors()) { logg("!Failed to initialize errors\n"); return FALSE; } ret = interface_setup(); logg("ClamAV module initialization %s\n", ret == TRUE ? "succeeded" : "failed! Aborting..."); return ret; }
int main(int argc, char **argv) { int fd, ret; unsigned long int size = 0; unsigned int sigs = 0; long double mb; const char *virname; struct cl_engine *engine; if(argc != 2) { printf("Usage: %s file\n", argv[0]); return 2; } if((fd = open(argv[1], O_RDONLY)) == -1) { printf("Can't open file %s\n", argv[1]); return 2; } if((ret = cl_init(CL_INIT_DEFAULT)) != CL_SUCCESS) { printf("Can't initialize libclamav: %s\n", cl_strerror(ret)); return 2; } if(!(engine = cl_engine_new())) { printf("Can't create new engine\n"); return 2; } /* load all available databases from default directory */ if((ret = cl_load(cl_retdbdir(), engine, &sigs, CL_DB_STDOPT)) != CL_SUCCESS) { printf("cl_load: %s\n", cl_strerror(ret)); close(fd); cl_engine_free(engine); return 2; } printf("Loaded %u signatures.\n", sigs); /* build engine */ if((ret = cl_engine_compile(engine)) != CL_SUCCESS) { printf("Database initialization error: %s\n", cl_strerror(ret));; cl_engine_free(engine); close(fd); return 2; } /* scan file descriptor */ if((ret = cl_scandesc(fd, &virname, &size, engine, CL_SCAN_STDOPT)) == CL_VIRUS) { printf("Virus detected: %s\n", virname); } else { if(ret == CL_CLEAN) { printf("No virus detected.\n"); } else { printf("Error: %s\n", cl_strerror(ret)); cl_engine_free(engine); close(fd); return 2; } } close(fd); /* free memory */ cl_engine_free(engine); /* calculate size of scanned data */ mb = size * (CL_COUNT_PRECISION / 1024) / 1024.0; printf("Data scanned: %2.2Lf MB\n", mb); return ret == CL_VIRUS ? 1 : 0; }
/* * main -- * This is the main loop for the standalone curses editor. */ int main(int argc, char *argv[]) { static int reenter; CL_PRIVATE *clp; GS *gp; size_t rows, cols; int rval; char *ttype; #ifdef RUNNING_IP char *ip_arg; char **p_av, **t_av; #endif /* If loaded at 0 and jumping through a NULL pointer, stop. */ if (reenter++) abort(); /* Create and initialize the global structure. */ __global_list = gp = gs_init(argv[0]); /* * Strip out any arguments that vi isn't going to understand. There's * no way to portably call getopt twice, so arguments parsed here must * be removed from the argument list. */ #ifdef RUNNING_IP ip_arg = NULL; for (p_av = t_av = argv;;) { if (*t_av == NULL) { *p_av = NULL; break; } if (!strcmp(*t_av, "--")) { while ((*p_av++ = *t_av++) != NULL); break; } if (!memcmp(*t_av, "-I", sizeof("-I") - 1)) { if (t_av[0][2] != '\0') { ip_arg = t_av[0] + 2; ++t_av; --argc; continue; } if (t_av[1] != NULL) { ip_arg = t_av[1]; t_av += 2; argc -= 2; continue; } } *p_av++ = *t_av++; } /* * If we're being called as an editor library, we're done here, we * get loaded with the curses screen, we don't share much code. */ if (ip_arg != NULL) exit (ip_main(argc, argv, gp, ip_arg)); #endif /* Create and initialize the CL_PRIVATE structure. */ clp = cl_init(gp); /* * Initialize the terminal information. * * We have to know what terminal it is from the start, since we may * have to use termcap/terminfo to find out how big the screen is. */ if ((ttype = getenv("TERM")) == NULL) ttype = "unknown"; term_init(gp->progname, ttype); /* Add the terminal type to the global structure. */ if ((OG_D_STR(gp, GO_TERM) = OG_STR(gp, GO_TERM) = strdup(ttype)) == NULL) perr(gp->progname, NULL); /* Figure out how big the screen is. */ if (cl_ssize(NULL, 0, &rows, &cols, NULL)) exit (1); /* Add the rows and columns to the global structure. */ OG_VAL(gp, GO_LINES) = OG_D_VAL(gp, GO_LINES) = rows; OG_VAL(gp, GO_COLUMNS) = OG_D_VAL(gp, GO_COLUMNS) = cols; /* Ex wants stdout to be buffered. */ (void)setvbuf(stdout, NULL, _IOFBF, 0); /* Start catching signals. */ if (sig_init(gp, NULL)) exit (1); /* Run ex/vi. */ rval = editor(gp, argc, argv); /* Clean up signals. */ sig_end(gp); /* Clean up the terminal. */ (void)cl_quit(gp); /* * XXX * Reset the O_MESG option. */ if (clp->tgw != TGW_UNKNOWN) (void)cl_omesg(NULL, clp, clp->tgw == TGW_SET); /* * XXX * Reset the X11 xterm icon/window name. */ if (F_ISSET(clp, CL_RENAME)) { (void)printf(XTERM_RENAME, ttype); (void)fflush(stdout); } /* If a killer signal arrived, pretend we just got it. */ if (clp->killersig) { (void)signal(clp->killersig, SIG_DFL); (void)kill(getpid(), clp->killersig); /* NOTREACHED */ } /* Free the global and CL private areas. */ #if defined(DEBUG) || defined(PURIFY) || defined(LIBRARY) free(clp); free(gp); #endif exit (rval); }
int main(int argc, char **argv) { const struct optstruct *opt; #ifndef C_WINDOWS struct passwd *user = NULL; #endif time_t currtime; const char *dbdir, *cfgfile; char *pua_cats = NULL, *pt; int ret, tcpsock = 0, localsock = 0, i, min_port, max_port; unsigned int sigs = 0; int lsockets[2], nlsockets = 0; unsigned int dboptions = 0; #ifdef C_LINUX struct stat sb; #endif #ifdef C_WINDOWS if(!pthread_win32_process_attach_np()) { mprintf("!Can't start the win32 pthreads layer\n"); return 1; } #endif if((opts = optparse(NULL, argc, argv, 1, OPT_CLAMD, 0, NULL)) == NULL) { mprintf("!Can't parse command line options\n"); return 1; } if(optget(opts, "help")->enabled) { help(); optfree(opts); return 0; } if(optget(opts, "debug")->enabled) { #if defined(C_LINUX) /* [email protected]: create a dump if needed */ struct rlimit rlim; rlim.rlim_cur = rlim.rlim_max = RLIM_INFINITY; if(setrlimit(RLIMIT_CORE, &rlim) < 0) perror("setrlimit"); #endif debug_mode = 1; } /* parse the config file */ cfgfile = optget(opts, "config-file")->strarg; pt = strdup(cfgfile); if((opts = optparse(cfgfile, 0, NULL, 1, OPT_CLAMD, 0, opts)) == NULL) { fprintf(stderr, "ERROR: Can't open/parse the config file %s\n", pt); free(pt); return 1; } free(pt); if(optget(opts, "version")->enabled) { print_version(optget(opts, "DatabaseDirectory")->strarg); optfree(opts); return 0; } umask(0); /* drop privileges */ #if (!defined(C_OS2)) && (!defined(C_WINDOWS)) if(geteuid() == 0 && (opt = optget(opts, "User"))->enabled) { if((user = getpwnam(opt->strarg)) == NULL) { fprintf(stderr, "ERROR: Can't get information about user %s.\n", opt->strarg); optfree(opts); return 1; } if(optget(opts, "AllowSupplementaryGroups")->enabled) { #ifdef HAVE_INITGROUPS if(initgroups(opt->strarg, user->pw_gid)) { fprintf(stderr, "ERROR: initgroups() failed.\n"); optfree(opts); return 1; } #else mprintf("!AllowSupplementaryGroups: initgroups() is not available, please disable AllowSupplementaryGroups in %s\n", cfgfile); optfree(opts); return 1; #endif } else { #ifdef HAVE_SETGROUPS if(setgroups(1, &user->pw_gid)) { fprintf(stderr, "ERROR: setgroups() failed.\n"); optfree(opts); return 1; } #endif } if(setgid(user->pw_gid)) { fprintf(stderr, "ERROR: setgid(%d) failed.\n", (int) user->pw_gid); optfree(opts); return 1; } if(setuid(user->pw_uid)) { fprintf(stderr, "ERROR: setuid(%d) failed.\n", (int) user->pw_uid); optfree(opts); return 1; } } #endif /* initialize logger */ logg_lock = !optget(opts, "LogFileUnlock")->enabled; logg_time = optget(opts, "LogTime")->enabled; logok = optget(opts, "LogClean")->enabled; logg_size = optget(opts, "LogFileMaxSize")->numarg; logg_verbose = mprintf_verbose = optget(opts, "LogVerbose")->enabled; mprintf_send_timeout = optget(opts, "SendBufTimeout")->numarg; do { /* logger initialized */ if((opt = optget(opts, "LogFile"))->enabled) { char timestr[32]; logg_file = opt->strarg; if(strlen(logg_file) < 2 || (logg_file[0] != '/' && logg_file[0] != '\\' && logg_file[1] != ':')) { fprintf(stderr, "ERROR: LogFile requires full path.\n"); ret = 1; break; } time(&currtime); if(logg("#+++ Started at %s", cli_ctime(&currtime, timestr, sizeof(timestr)))) { fprintf(stderr, "ERROR: Can't initialize the internal logger\n"); ret = 1; break; } } else logg_file = NULL; if((ret = cl_init(CL_INIT_DEFAULT))) { logg("!Can't initialize libclamav: %s\n", cl_strerror(ret)); ret = 1; break; } if(optget(opts, "Debug")->enabled) /* enable debug messages in libclamav */ { cl_debug(); logg_verbose = 2; } #if defined(USE_SYSLOG) && !defined(C_AIX) if(optget(opts, "LogSyslog")->enabled) { int fac = LOG_LOCAL6; opt = optget(opts, "LogFacility"); if((fac = logg_facility(opt->strarg)) == -1) { logg("!LogFacility: %s: No such facility.\n", opt->strarg); ret = 1; break; } openlog("clamd", LOG_PID, fac); logg_syslog = 1; } #endif #ifdef C_LINUX procdev = 0; if(stat("/proc", &sb) != -1 && !sb.st_size) procdev = sb.st_dev; #endif /* check socket type */ if(optget(opts, "TCPSocket")->enabled) tcpsock = 1; if(optget(opts, "LocalSocket")->enabled) localsock = 1; if(!tcpsock && !localsock) { logg("!Please define server type (local and/or TCP).\n"); ret = 1; break; } logg("#clamd daemon %s (OS: "TARGET_OS_TYPE", ARCH: "TARGET_ARCH_TYPE", CPU: "TARGET_CPU_TYPE")\n", get_version()); #ifndef C_WINDOWS if(user) logg("#Running as user %s (UID %u, GID %u)\n", user->pw_name, user->pw_uid, user->pw_gid); #endif if(logg_size) logg("#Log file size limited to %d bytes.\n", logg_size); else logg("#Log file size limit disabled.\n"); min_port = optget(opts, "StreamMinPort")->numarg; max_port = optget(opts, "StreamMaxPort")->numarg; if (min_port < 1024 || min_port > max_port || max_port > 65535) { logg("!Invalid StreamMinPort/StreamMaxPort: %d, %d\n", min_port, max_port); ret = 1; break; } if(!(engine = cl_engine_new())) { logg("!Can't initialize antivirus engine\n"); ret = 1; break; } /* load the database(s) */ dbdir = optget(opts, "DatabaseDirectory")->strarg; logg("#Reading databases from %s\n", dbdir); if(optget(opts, "DetectPUA")->enabled) { dboptions |= CL_DB_PUA; if((opt = optget(opts, "ExcludePUA"))->enabled) { dboptions |= CL_DB_PUA_EXCLUDE; i = 0; logg("#Excluded PUA categories:"); while(opt) { if(!(pua_cats = realloc(pua_cats, i + strlen(opt->strarg) + 3))) { logg("!Can't allocate memory for pua_cats\n"); cl_engine_free(engine); ret = 1; break; } logg("# %s", opt->strarg); sprintf(pua_cats + i, ".%s", opt->strarg); i += strlen(opt->strarg) + 1; pua_cats[i] = 0; opt = opt->nextarg; } if (ret) break; logg("#\n"); pua_cats[i] = '.'; pua_cats[i + 1] = 0; } if((opt = optget(opts, "IncludePUA"))->enabled) { if(pua_cats) { logg("!ExcludePUA and IncludePUA cannot be used at the same time\n"); free(pua_cats); ret = 1; break; } dboptions |= CL_DB_PUA_INCLUDE; i = 0; logg("#Included PUA categories:"); while(opt) { if(!(pua_cats = realloc(pua_cats, i + strlen(opt->strarg) + 3))) { logg("!Can't allocate memory for pua_cats\n"); ret = 1; break; } logg("# %s", opt->strarg); sprintf(pua_cats + i, ".%s", opt->strarg); i += strlen(opt->strarg) + 1; pua_cats[i] = 0; opt = opt->nextarg; } if (ret) break; logg("#\n"); pua_cats[i] = '.'; pua_cats[i + 1] = 0; } if(pua_cats) { if((ret = cl_engine_set_str(engine, CL_ENGINE_PUA_CATEGORIES, pua_cats))) { logg("!cli_engine_set_str(CL_ENGINE_PUA_CATEGORIES) failed: %s\n", cl_strerror(ret)); free(pua_cats); ret = 1; break; } free(pua_cats); } } else { logg("#Not loading PUA signatures.\n"); } /* set the temporary dir */ if((opt = optget(opts, "TemporaryDirectory"))->enabled) { if((ret = cl_engine_set_str(engine, CL_ENGINE_TMPDIR, opt->strarg))) { logg("!cli_engine_set_str(CL_ENGINE_TMPDIR) failed: %s\n", cl_strerror(ret)); ret = 1; break; } } if(optget(opts, "LeaveTemporaryFiles")->enabled) cl_engine_set_num(engine, CL_ENGINE_KEEPTMP, 1); if(optget(opts, "PhishingSignatures")->enabled) dboptions |= CL_DB_PHISHING; else logg("#Not loading phishing signatures.\n"); if(optget(opts,"PhishingScanURLs")->enabled) dboptions |= CL_DB_PHISHING_URLS; else logg("#Disabling URL based phishing detection.\n"); if(optget(opts,"DevACOnly")->enabled) { logg("#Only using the A-C matcher.\n"); cl_engine_set_num(engine, CL_ENGINE_AC_ONLY, 1); } if((opt = optget(opts, "DevACDepth"))->enabled) { cl_engine_set_num(engine, CL_ENGINE_AC_MAXDEPTH, opt->numarg); logg("#Max A-C depth set to %u\n", (unsigned int) opt->numarg); } if((ret = cl_load(dbdir, engine, &sigs, dboptions))) { logg("!%s\n", cl_strerror(ret)); ret = 1; break; } logg("#Loaded %u signatures.\n", sigs); if((ret = cl_engine_compile(engine)) != 0) { logg("!Database initialization error: %s\n", cl_strerror(ret)); ret = 1; break; } if(tcpsock) { #ifdef C_WINDOWS WSADATA wsaData; if(WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) { logg("!Error at WSAStartup(): %d\n", WSAGetLastError()); ret = 1; break; } #endif if ((lsockets[nlsockets] = tcpserver(opts)) == -1) { ret = 1; break; } nlsockets++; } if(localsock) { if ((lsockets[nlsockets] = localserver(opts)) == -1) { ret = 1; break; } nlsockets++; } /* fork into background */ if(!optget(opts, "Foreground")->enabled) { #ifdef C_BSD /* workaround for OpenBSD bug, see https://wwws.clamav.net/bugzilla/show_bug.cgi?id=885 */ for(ret=0;ret<nlsockets;ret++) { fcntl(lsockets[ret], F_SETFL, fcntl(lsockets[ret], F_GETFL) | O_NONBLOCK); } #endif if(daemonize() == -1) { logg("!daemonize() failed\n"); ret = 1; break; } #ifdef C_BSD for(ret=0;ret<nlsockets;ret++) { fcntl(lsockets[ret], F_SETFL, fcntl(lsockets[ret], F_GETFL) & ~O_NONBLOCK); } #endif if(!debug_mode) if(chdir("/") == -1) logg("^Can't change current working directory to root\n"); } else foreground = 1; ret = recvloop_th(lsockets, nlsockets, engine, dboptions, opts); } while (0); logg("*Closing the main socket%s.\n", (nlsockets > 1) ? "s" : ""); for (i = 0; i < nlsockets; i++) { closesocket(lsockets[i]); } #ifndef C_OS2 if(nlsockets && localsock) { opt = optget(opts, "LocalSocket"); if(unlink(opt->strarg) == -1) logg("!Can't unlink the socket file %s\n", opt->strarg); else logg("Socket file removed.\n"); } #endif #ifdef C_WINDOWS if(tcpsock) WSACleanup(); if(!pthread_win32_process_detach_np()) { logg("!Can't stop the win32 pthreads layer\n"); logg_close(); optfree(opts); return 1; } #endif logg_close(); optfree(opts); return ret; }
int scanmanager(const struct optstruct *opts) { int ret = 0, i; unsigned int options = 0, dboptions = 0, dirlnk = 1, filelnk = 1; struct cl_engine *engine; STATBUF sb; char *file, cwd[1024], *pua_cats = NULL; const char *filename; const struct optstruct *opt; #ifndef _WIN32 struct rlimit rlim; #endif dirlnk = optget(opts, "follow-dir-symlinks")->numarg; if(dirlnk > 2) { logg("!--follow-dir-symlinks: Invalid argument\n"); return 2; } filelnk = optget(opts, "follow-file-symlinks")->numarg; if(filelnk > 2) { logg("!--follow-file-symlinks: Invalid argument\n"); return 2; } if(optget(opts, "yara-rules")->enabled) { char *p = optget(opts, "yara-rules")->strarg; if(strcmp(p, "yes")) { if(!strcmp(p, "only")) dboptions |= CL_DB_YARA_ONLY; else if (!strcmp(p, "no")) dboptions |= CL_DB_YARA_EXCLUDE; } } if(optget(opts, "phishing-sigs")->enabled) dboptions |= CL_DB_PHISHING; if(optget(opts, "official-db-only")->enabled) dboptions |= CL_DB_OFFICIAL_ONLY; if(optget(opts,"phishing-scan-urls")->enabled) dboptions |= CL_DB_PHISHING_URLS; if(optget(opts,"bytecode")->enabled) dboptions |= CL_DB_BYTECODE; if((ret = cl_init(CL_INIT_DEFAULT))) { logg("!Can't initialize libclamav: %s\n", cl_strerror(ret)); return 2; } if(!(engine = cl_engine_new())) { logg("!Can't initialize antivirus engine\n"); return 2; } cl_engine_set_clcb_virus_found(engine, clamscan_virus_found_cb); if (optget(opts, "disable-cache")->enabled) cl_engine_set_num(engine, CL_ENGINE_DISABLE_CACHE, 1); if (optget(opts, "disable-pe-stats")->enabled) { cl_engine_set_num(engine, CL_ENGINE_DISABLE_PE_STATS, 1); } if (optget(opts, "enable-stats")->enabled) { cl_engine_stats_enable(engine); } if (optget(opts, "stats-timeout")->enabled) { cl_engine_set_num(engine, CL_ENGINE_STATS_TIMEOUT, optget(opts, "StatsTimeout")->numarg); } if (optget(opts, "stats-host-id")->enabled) { char *p = optget(opts, "stats-host-id")->strarg; if (strcmp(p, "default")) { if (!strcmp(p, "none")) { cl_engine_set_clcb_stats_get_hostid(engine, NULL); } else if (!strcmp(p, "anonymous")) { strcpy(hostid, STATS_ANON_UUID); } else { if (strlen(p) > 36) { logg("!Invalid HostID\n"); cl_engine_set_clcb_stats_submit(engine, NULL); cl_engine_free(engine); return 2; } strcpy(hostid, p); } cl_engine_set_clcb_stats_get_hostid(engine, get_hostid); } } if(optget(opts, "detect-pua")->enabled) { dboptions |= CL_DB_PUA; if((opt = optget(opts, "exclude-pua"))->enabled) { dboptions |= CL_DB_PUA_EXCLUDE; i = 0; while(opt) { if(!(pua_cats = realloc(pua_cats, i + strlen(opt->strarg) + 3))) { logg("!Can't allocate memory for pua_cats\n"); cl_engine_free(engine); return 2; } sprintf(pua_cats + i, ".%s", opt->strarg); i += strlen(opt->strarg) + 1; pua_cats[i] = 0; opt = opt->nextarg; } pua_cats[i] = '.'; pua_cats[i + 1] = 0; } if((opt = optget(opts, "include-pua"))->enabled) { if(pua_cats) { logg("!--exclude-pua and --include-pua cannot be used at the same time\n"); cl_engine_free(engine); free(pua_cats); return 2; } dboptions |= CL_DB_PUA_INCLUDE; i = 0; while(opt) { if(!(pua_cats = realloc(pua_cats, i + strlen(opt->strarg) + 3))) { logg("!Can't allocate memory for pua_cats\n"); cl_engine_free(engine); return 2; } sprintf(pua_cats + i, ".%s", opt->strarg); i += strlen(opt->strarg) + 1; pua_cats[i] = 0; opt = opt->nextarg; } pua_cats[i] = '.'; pua_cats[i + 1] = 0; } if(pua_cats) { if((ret = cl_engine_set_str(engine, CL_ENGINE_PUA_CATEGORIES, pua_cats))) { logg("!cli_engine_set_str(CL_ENGINE_PUA_CATEGORIES) failed: %s\n", cl_strerror(ret)); free(pua_cats); cl_engine_free(engine); return 2; } free(pua_cats); } } if(optget(opts, "dev-ac-only")->enabled) cl_engine_set_num(engine, CL_ENGINE_AC_ONLY, 1); if(optget(opts, "dev-ac-depth")->enabled) cl_engine_set_num(engine, CL_ENGINE_AC_MAXDEPTH, optget(opts, "dev-ac-depth")->numarg); if(optget(opts, "leave-temps")->enabled) cl_engine_set_num(engine, CL_ENGINE_KEEPTMP, 1); if(optget(opts, "force-to-disk")->enabled) cl_engine_set_num(engine, CL_ENGINE_FORCETODISK, 1); if(optget(opts, "bytecode-unsigned")->enabled) dboptions |= CL_DB_BYTECODE_UNSIGNED; if((opt = optget(opts,"bytecode-timeout"))->enabled) cl_engine_set_num(engine, CL_ENGINE_BYTECODE_TIMEOUT, opt->numarg); if (optget(opts, "nocerts")->enabled) cl_engine_set_num(engine, CL_ENGINE_DISABLE_PE_CERTS, 1); if (optget(opts, "dumpcerts")->enabled) cl_engine_set_num(engine, CL_ENGINE_PE_DUMPCERTS, 1); if((opt = optget(opts,"bytecode-mode"))->enabled) { enum bytecode_mode mode; if (!strcmp(opt->strarg, "ForceJIT")) mode = CL_BYTECODE_MODE_JIT; else if(!strcmp(opt->strarg, "ForceInterpreter")) mode = CL_BYTECODE_MODE_INTERPRETER; else if(!strcmp(opt->strarg, "Test")) mode = CL_BYTECODE_MODE_TEST; else mode = CL_BYTECODE_MODE_AUTO; cl_engine_set_num(engine, CL_ENGINE_BYTECODE_MODE, mode); } if((opt = optget(opts, "statistics"))->enabled) { while(opt) { if (!strcasecmp(opt->strarg, "bytecode")) { dboptions |= CL_DB_BYTECODE_STATS; } else if (!strcasecmp(opt->strarg, "pcre")) { dboptions |= CL_DB_PCRE_STATS; } opt = opt->nextarg; } } if((opt = optget(opts, "tempdir"))->enabled) { if((ret = cl_engine_set_str(engine, CL_ENGINE_TMPDIR, opt->strarg))) { logg("!cli_engine_set_str(CL_ENGINE_TMPDIR) failed: %s\n", cl_strerror(ret)); cl_engine_free(engine); return 2; } } if((opt = optget(opts, "database"))->active) { while(opt) { if((ret = cl_load(opt->strarg, engine, &info.sigs, dboptions))) { logg("!%s\n", cl_strerror(ret)); cl_engine_free(engine); return 2; } opt = opt->nextarg; } } else { char *dbdir = freshdbdir(); if((ret = cl_load(dbdir, engine, &info.sigs, dboptions))) { logg("!%s\n", cl_strerror(ret)); free(dbdir); cl_engine_free(engine); return 2; } free(dbdir); } /* pcre engine limits - required for cl_engine_compile */ if ((opt = optget(opts, "pcre-match-limit"))->active) { if ((ret = cl_engine_set_num(engine, CL_ENGINE_PCRE_MATCH_LIMIT, opt->numarg))) { logg("!cli_engine_set_num(CL_ENGINE_PCRE_MATCH_LIMIT) failed: %s\n", cl_strerror(ret)); cl_engine_free(engine); return 2; } } if ((opt = optget(opts, "pcre-recmatch-limit"))->active) { if ((ret = cl_engine_set_num(engine, CL_ENGINE_PCRE_RECMATCH_LIMIT, opt->numarg))) { logg("!cli_engine_set_num(CL_ENGINE_PCRE_RECMATCH_LIMIT) failed: %s\n", cl_strerror(ret)); cl_engine_free(engine); return 2; } } if((ret = cl_engine_compile(engine)) != 0) { logg("!Database initialization error: %s\n", cl_strerror(ret));; cl_engine_free(engine); return 2; } if(optget(opts, "archive-verbose")->enabled) { cl_engine_set_clcb_meta(engine, meta); cl_engine_set_clcb_pre_cache(engine, pre); cl_engine_set_clcb_post_scan(engine, post); } /* set limits */ if((opt = optget(opts, "max-scansize"))->active) { if((ret = cl_engine_set_num(engine, CL_ENGINE_MAX_SCANSIZE, opt->numarg))) { logg("!cli_engine_set_num(CL_ENGINE_MAX_SCANSIZE) failed: %s\n", cl_strerror(ret)); cl_engine_free(engine); return 2; } } if((opt = optget(opts, "max-filesize"))->active) { if((ret = cl_engine_set_num(engine, CL_ENGINE_MAX_FILESIZE, opt->numarg))) { logg("!cli_engine_set_num(CL_ENGINE_MAX_FILESIZE) failed: %s\n", cl_strerror(ret)); cl_engine_free(engine); return 2; } } #ifndef _WIN32 if(getrlimit(RLIMIT_FSIZE, &rlim) == 0) { if(rlim.rlim_cur < (rlim_t) cl_engine_get_num(engine, CL_ENGINE_MAX_FILESIZE, NULL)) logg("^System limit for file size is lower than engine->maxfilesize\n"); if(rlim.rlim_cur < (rlim_t) cl_engine_get_num(engine, CL_ENGINE_MAX_SCANSIZE, NULL)) logg("^System limit for file size is lower than engine->maxscansize\n"); } else { logg("^Cannot obtain resource limits for file size\n"); } #endif if((opt = optget(opts, "max-files"))->active) { if((ret = cl_engine_set_num(engine, CL_ENGINE_MAX_FILES, opt->numarg))) { logg("!cli_engine_set_num(CL_ENGINE_MAX_FILES) failed: %s\n", cl_strerror(ret)); cl_engine_free(engine); return 2; } } if((opt = optget(opts, "max-recursion"))->active) { if((ret = cl_engine_set_num(engine, CL_ENGINE_MAX_RECURSION, opt->numarg))) { logg("!cli_engine_set_num(CL_ENGINE_MAX_RECURSION) failed: %s\n", cl_strerror(ret)); cl_engine_free(engine); return 2; } } /* Engine max sizes */ if((opt = optget(opts, "max-embeddedpe"))->active) { if((ret = cl_engine_set_num(engine, CL_ENGINE_MAX_EMBEDDEDPE, opt->numarg))) { logg("!cli_engine_set_num(CL_ENGINE_MAX_EMBEDDEDPE) failed: %s\n", cl_strerror(ret)); cl_engine_free(engine); return 2; } } if((opt = optget(opts, "max-htmlnormalize"))->active) { if((ret = cl_engine_set_num(engine, CL_ENGINE_MAX_HTMLNORMALIZE, opt->numarg))) { logg("!cli_engine_set_num(CL_ENGINE_MAX_HTMLNORMALIZE) failed: %s\n", cl_strerror(ret)); cl_engine_free(engine); return 2; } } if((opt = optget(opts, "max-htmlnotags"))->active) { if((ret = cl_engine_set_num(engine, CL_ENGINE_MAX_HTMLNOTAGS, opt->numarg))) { logg("!cli_engine_set_num(CL_ENGINE_MAX_HTMLNOTAGS) failed: %s\n", cl_strerror(ret)); cl_engine_free(engine); return 2; } } if((opt = optget(opts, "max-scriptnormalize"))->active) { if((ret = cl_engine_set_num(engine, CL_ENGINE_MAX_SCRIPTNORMALIZE, opt->numarg))) { logg("!cli_engine_set_num(CL_ENGINE_MAX_SCRIPTNORMALIZE) failed: %s\n", cl_strerror(ret)); cl_engine_free(engine); return 2; } } if((opt = optget(opts, "max-ziptypercg"))->active) { if((ret = cl_engine_set_num(engine, CL_ENGINE_MAX_ZIPTYPERCG, opt->numarg))) { logg("!cli_engine_set_num(CL_ENGINE_MAX_ZIPTYPERCG) failed: %s\n", cl_strerror(ret)); cl_engine_free(engine); return 2; } } if((opt = optget(opts, "max-partitions"))->active) { if((ret = cl_engine_set_num(engine, CL_ENGINE_MAX_PARTITIONS, opt->numarg))) { logg("!cli_engine_set_num(CL_ENGINE_MAX_PARTITIONS) failed: %s\n", cl_strerror(ret)); cl_engine_free(engine); return 2; } } if((opt = optget(opts, "max-iconspe"))->active) { if((ret = cl_engine_set_num(engine, CL_ENGINE_MAX_ICONSPE, opt->numarg))) { logg("!cli_engine_set_num(CL_ENGINE_MAX_ICONSPE) failed: %s\n", cl_strerror(ret)); cl_engine_free(engine); return 2; } } if((opt = optget(opts, "max-rechwp3"))->active) { if((ret = cl_engine_set_num(engine, CL_ENGINE_MAX_RECHWP3, opt->numarg))) { logg("!cli_engine_set_num(CL_ENGINE_MAX_RECHWP3) failed: %s\n", cl_strerror(ret)); cl_engine_free(engine); return 2; } } if ((opt = optget(opts, "timelimit"))->active) { if ((ret = cl_engine_set_num(engine, CL_ENGINE_TIME_LIMIT, opt->numarg))) { logg("!cli_engine_set_num(CL_ENGINE_TIME_LIMIT) failed: %s\n", cl_strerror(ret)); cl_engine_free(engine); return 2; } } if ((opt = optget(opts, "pcre-max-filesize"))->active) { if ((ret = cl_engine_set_num(engine, CL_ENGINE_PCRE_MAX_FILESIZE, opt->numarg))) { logg("!cli_engine_set_num(CL_ENGINE_PCRE_MAX_FILESIZE) failed: %s\n", cl_strerror(ret)); cl_engine_free(engine); return 2; } } /* set scan options */ if(optget(opts, "allmatch")->enabled) { options |= CL_SCAN_ALLMATCHES; } if(optget(opts,"phishing-ssl")->enabled) options |= CL_SCAN_PHISHING_BLOCKSSL; if(optget(opts,"phishing-cloak")->enabled) options |= CL_SCAN_PHISHING_BLOCKCLOAK; if(optget(opts,"partition-intersection")->enabled) options |= CL_SCAN_PARTITION_INTXN; if(optget(opts,"heuristic-scan-precedence")->enabled) options |= CL_SCAN_HEURISTIC_PRECEDENCE; if(optget(opts, "scan-archive")->enabled) options |= CL_SCAN_ARCHIVE; if(optget(opts, "detect-broken")->enabled) options |= CL_SCAN_BLOCKBROKEN; if(optget(opts, "block-encrypted")->enabled) options |= CL_SCAN_BLOCKENCRYPTED; if(optget(opts, "block-macros")->enabled) options |= CL_SCAN_BLOCKMACROS; if(optget(opts, "scan-pe")->enabled) options |= CL_SCAN_PE; if(optget(opts, "scan-elf")->enabled) options |= CL_SCAN_ELF; if(optget(opts, "scan-ole2")->enabled) options |= CL_SCAN_OLE2; if(optget(opts, "scan-pdf")->enabled) options |= CL_SCAN_PDF; if(optget(opts, "scan-swf")->enabled) options |= CL_SCAN_SWF; if(optget(opts, "scan-html")->enabled && optget(opts, "normalize")->enabled) options |= CL_SCAN_HTML; if(optget(opts, "scan-mail")->enabled) options |= CL_SCAN_MAIL; if(optget(opts, "scan-xmldocs")->enabled) options |= CL_SCAN_XMLDOCS; if(optget(opts, "scan-hwp3")->enabled) options |= CL_SCAN_HWP3; if(optget(opts, "algorithmic-detection")->enabled) options |= CL_SCAN_ALGORITHMIC; if(optget(opts, "block-max")->enabled) { options |= CL_SCAN_BLOCKMAX; } #ifdef HAVE__INTERNAL__SHA_COLLECT if(optget(opts, "dev-collect-hashes")->enabled) options |= CL_SCAN_INTERNAL_COLLECT_SHA; #endif if(optget(opts, "dev-performance")->enabled) options |= CL_SCAN_PERFORMANCE_INFO; if(optget(opts, "detect-structured")->enabled) { options |= CL_SCAN_STRUCTURED; if((opt = optget(opts, "structured-ssn-format"))->enabled) { switch(opt->numarg) { case 0: options |= CL_SCAN_STRUCTURED_SSN_NORMAL; break; case 1: options |= CL_SCAN_STRUCTURED_SSN_STRIPPED; break; case 2: options |= (CL_SCAN_STRUCTURED_SSN_NORMAL | CL_SCAN_STRUCTURED_SSN_STRIPPED); break; default: logg("!Invalid argument for --structured-ssn-format\n"); return 2; } } else { options |= CL_SCAN_STRUCTURED_SSN_NORMAL; } if((opt = optget(opts, "structured-ssn-count"))->active) { if((ret = cl_engine_set_num(engine, CL_ENGINE_MIN_SSN_COUNT, opt->numarg))) { logg("!cli_engine_set_num(CL_ENGINE_MIN_SSN_COUNT) failed: %s\n", cl_strerror(ret)); cl_engine_free(engine); return 2; } } if((opt = optget(opts, "structured-cc-count"))->active) { if((ret = cl_engine_set_num(engine, CL_ENGINE_MIN_CC_COUNT, opt->numarg))) { logg("!cli_engine_set_num(CL_ENGINE_MIN_CC_COUNT) failed: %s\n", cl_strerror(ret)); cl_engine_free(engine); return 2; } } } else { options &= ~CL_SCAN_STRUCTURED; } #ifdef C_LINUX procdev = (dev_t) 0; if(CLAMSTAT("/proc", &sb) != -1 && !sb.st_size) procdev = sb.st_dev; #endif #if HAVE_JSON if (optget(opts, "gen-json")->enabled) options |= CL_SCAN_FILE_PROPERTIES; #endif /* check filetype */ if(!opts->filename && !optget(opts, "file-list")->enabled) { /* we need full path for some reasons (eg. archive handling) */ if(!getcwd(cwd, sizeof(cwd))) { logg("!Can't get absolute pathname of current working directory\n"); ret = 2; } else { CLAMSTAT(cwd, &sb); scandirs(cwd, engine, opts, options, 1, sb.st_dev); } } else if(opts->filename && !optget(opts, "file-list")->enabled && !strcmp(opts->filename[0], "-")) { /* read data from stdin */ ret = scanstdin(engine, opts, options); } else { if(opts->filename && optget(opts, "file-list")->enabled) logg("^Only scanning files from --file-list (files passed at cmdline are ignored)\n"); while((filename = filelist(opts, &ret)) && (file = strdup(filename))) { if(LSTAT(file, &sb) == -1) { perror(file); logg("^%s: Can't access file\n", file); ret = 2; } else { for(i = strlen(file) - 1; i > 0; i--) { if(file[i] == *PATHSEP) file[i] = 0; else break; } if(S_ISLNK(sb.st_mode)) { if(dirlnk == 0 && filelnk == 0) { if(!printinfected) logg("%s: Symbolic link\n", file); } else if(CLAMSTAT(file, &sb) != -1) { if(S_ISREG(sb.st_mode) && filelnk) { scanfile(file, engine, opts, options); } else if(S_ISDIR(sb.st_mode) && dirlnk) { scandirs(file, engine, opts, options, 1, sb.st_dev); } else { if(!printinfected) logg("%s: Symbolic link\n", file); } } } else if(S_ISREG(sb.st_mode)) { scanfile(file, engine, opts, options); } else if(S_ISDIR(sb.st_mode)) { scandirs(file, engine, opts, options, 1, sb.st_dev); } else { logg("^%s: Not supported file type\n", file); ret = 2; } } free(file); } } if((opt = optget(opts, "statistics"))->enabled) { while(opt) { if (!strcasecmp(opt->strarg, "bytecode")) { cli_sigperf_print(); cli_sigperf_events_destroy(); } #if HAVE_PCRE else if (!strcasecmp(opt->strarg, "pcre")) { cli_pcre_perf_print(); cli_pcre_perf_events_destroy(); } #endif opt = opt->nextarg; } } /* free the engine */ cl_engine_free(engine); /* overwrite return code - infection takes priority */ if(info.ifiles) ret = 1; else if(info.errors) ret = 2; return ret; }