void hs_free_config(hs_config* cfg) { free(cfg->run_path); cfg->run_path = NULL; free(cfg->load_path); cfg->load_path = NULL; free(cfg->output_path); cfg->output_path = NULL; free(cfg->io_lua_path); cfg->io_lua_path = NULL; free(cfg->io_lua_cpath); cfg->io_lua_cpath = NULL; free(cfg->analysis_lua_path); cfg->analysis_lua_path = NULL; free(cfg->analysis_lua_cpath); cfg->analysis_lua_cpath = NULL; free(cfg->hostname); cfg->hostname = NULL; hs_free_sandbox_config(&cfg->ipd); hs_free_sandbox_config(&cfg->apd); hs_free_sandbox_config(&cfg->opd); hs_free_checkpoint_reader(&cfg->cp_reader); }
static char* test_sandbox_filename_config() { hs_sandbox_config cfg; bool ret = hs_load_sandbox_config("sandbox", "path_in_fn.cfg", &cfg, NULL, HS_SB_TYPE_INPUT); mu_assert(!ret, "accepted a filename with a path"); hs_free_sandbox_config(&cfg); ret = hs_load_sandbox_config("sandbox", "invalid_fn_ext.cfg", &cfg, NULL, HS_SB_TYPE_INPUT); mu_assert(!ret, "accepted a filename with a invalid extension"); hs_free_sandbox_config(&cfg); return NULL; }
static char* test_sandbox_analysis_config() { hs_sandbox_config cfg; bool ret = hs_load_sandbox_config("sandbox", "analysis.cfg", &cfg, NULL, HS_SB_TYPE_ANALYSIS); mu_assert(ret, "hs_load_sandbox_config failed"); mu_assert(strcmp(cfg.filename, "analysis.lua") == 0, "received %s", cfg.filename); mu_assert(strcmp(cfg.cfg_name, "analysis") == 0, "received %s", cfg.cfg_name); mu_assert(cfg.output_limit == 77777, "received %d", cfg.output_limit); mu_assert(cfg.memory_limit == 88888, "received %d", cfg.memory_limit); mu_assert(cfg.instruction_limit == 99999, "received %d", cfg.instruction_limit); mu_assert(cfg.ticker_interval == 17, "received %d", cfg.ticker_interval); mu_assert(cfg.preserve_data == true, "received %s", cfg.preserve_data ? "true" : "false"); mu_assert(strcmp(cfg.message_matcher, "TRUE") == 0, "received %s", cfg.message_matcher); mu_assert(cfg.thread == 1, "received %d", cfg.thread); mu_assert(cfg.async_buffer_size == 0, "received %d", cfg.async_buffer_size); hs_free_sandbox_config(&cfg); return NULL; }
void hs_load_analysis_plugins(hs_analysis_plugins* plugins, const hs_config* cfg, const char* path) { char dir[HS_MAX_PATH]; if (!hs_get_fqfn(path, hs_analysis_dir, dir, sizeof(dir))) { hs_log(g_module, 0, "load path too long"); exit(EXIT_FAILURE); } struct dirent* entry; DIR* dp = opendir(dir); if (dp == NULL) { exit(EXIT_FAILURE); } while ((entry = readdir(dp))) { hs_sandbox_config sbc; if (hs_load_sandbox_config(dir, entry->d_name, &sbc, &cfg->apd, HS_SB_TYPE_ANALYSIS)) { hs_analysis_plugin* p = create_analysis_plugin(cfg, &sbc); if (p) { p->sb->mm = hs_create_message_matcher(plugins->mmb, sbc.message_matcher); int ret = hs_init_analysis_sandbox(p->sb, &inject_message); if (!p->sb->mm || ret) { if (!p->sb->mm) { hs_log(g_module, 3, "%s invalid message_matcher: %s", p->sb->name, sbc.message_matcher); } else { hs_log(g_module, 3, "lsb_init: %s received: %d %s", p->sb->name, ret, lsb_get_error(p->sb->lsb)); } free_analysis_plugin(p); free(p); p = NULL; hs_free_sandbox_config(&sbc); continue; } add_to_analysis_plugins(&sbc, plugins, p); } } hs_free_sandbox_config(&sbc); } closedir(dp); }
void hs_load_output_plugins(hs_output_plugins *plugins, const hs_config *cfg, bool dynamic) { char lpath[HS_MAX_PATH]; char rpath[HS_MAX_PATH]; if (!hs_get_fqfn(cfg->load_path, hs_output_dir, lpath, sizeof(lpath))) { hs_log(NULL, g_module, 0, "load path too long"); exit(EXIT_FAILURE); } if (!hs_get_fqfn(cfg->run_path, hs_output_dir, rpath, sizeof(rpath))) { hs_log(NULL, g_module, 0, "run path too long"); exit(EXIT_FAILURE); } const char *dir = dynamic ? lpath : rpath; DIR *dp = opendir(dir); if (dp == NULL) { hs_log(NULL, g_module, 0, "%s: %s", dir, strerror(errno)); exit(EXIT_FAILURE); } if (dynamic) process_lua(plugins, lpath, rpath, dp); struct dirent *entry; while ((entry = readdir(dp))) { if (dynamic) { int ret = hs_process_load_cfg(lpath, rpath, entry->d_name); switch (ret) { case 0: remove_from_output_plugins(plugins, entry->d_name); break; case 1: // proceed to load break; default: // ignore continue; } } hs_sandbox_config sbc; if (hs_load_sandbox_config(rpath, entry->d_name, &sbc, &cfg->opd, 'o')) { hs_output_plugin *p = create_output_plugin(plugins->mmb, cfg, &sbc); if (p) { p->plugins = plugins; hs_init_input(&p->input, cfg->max_message_size, cfg->output_path, p->name); hs_init_input(&p->analysis, cfg->max_message_size, cfg->output_path, p->name); add_to_output_plugins(plugins, p); } else { hs_log(NULL, g_module, 3, "%s create_output_plugin failed", sbc.cfg_name); } hs_free_sandbox_config(&sbc); } } closedir(dp); }
static char* test_sandbox_output_config() { hs_sandbox_config cfg; bool ret = hs_load_sandbox_config("sandbox", "output.cfg", &cfg, NULL, HS_SB_TYPE_OUTPUT); mu_assert(ret, "hs_load_sandbox_config failed"); mu_assert(strcmp(cfg.filename, "output.lua") == 0, "received %s", cfg.filename); mu_assert(cfg.async_buffer_size == 999, "received %d", cfg.async_buffer_size); mu_assert(cfg.thread == 0, "received %d", cfg.thread); hs_free_sandbox_config(&cfg); return NULL; }
void hs_load_output_plugins(hs_output_plugins* plugins, const hs_config* cfg, bool dynamic) { char lpath[HS_MAX_PATH]; char rpath[HS_MAX_PATH]; if (!hs_get_fqfn(cfg->load_path, hs_output_dir, lpath, sizeof(lpath))) { hs_log(g_module, 0, "load path too long"); exit(EXIT_FAILURE); } if (!hs_get_fqfn(cfg->run_path, hs_output_dir, rpath, sizeof(rpath))) { hs_log(g_module, 0, "run path too long"); exit(EXIT_FAILURE); } const char* dir = dynamic ? lpath : rpath; DIR* dp = opendir(dir); if (dp == NULL) { hs_log(g_module, 0, "%s: %s", dir, strerror(errno)); exit(EXIT_FAILURE); } if (dynamic) process_lua(plugins, lpath, rpath, dp); struct dirent* entry; while ((entry = readdir(dp))) { if (dynamic) { int ret = hs_process_load_cfg(lpath, rpath, entry->d_name); switch (ret) { case 0: remove_from_output_plugins(plugins, entry->d_name); break; case 1: // proceed to load break; default: // ignore continue; } } hs_sandbox_config sbc; if (hs_load_sandbox_config(rpath, entry->d_name, &sbc, &cfg->opd, HS_SB_TYPE_OUTPUT)) { hs_output_plugin* p = create_output_plugin(cfg, &sbc); if (p) { p->plugins = plugins; hs_init_input(&p->input, cfg->max_message_size, cfg->output_path, p->sb->name); hs_init_input(&p->analysis, cfg->max_message_size, cfg->output_path, p->sb->name); p->sb->mm = hs_create_message_matcher(plugins->mmb, sbc.message_matcher); int ret = hs_init_output_sandbox(p->sb); if (!p->sb->mm || ret) { if (!p->sb->mm) { hs_log(g_module, 3, "file: %s invalid message_matcher: %s", p->sb->name, sbc.message_matcher); } else { hs_log(g_module, 3, "lsb_init() file: %s received: %d %s", p->sb->name, ret, lsb_get_error(p->sb->lsb)); } free_output_plugin(p); free(p); p = NULL; hs_free_sandbox_config(&sbc); continue; } add_to_output_plugins(plugins, p); } hs_free_sandbox_config(&sbc); } } closedir(dp); }
bool hs_load_sandbox_config(const char* dir, const char* fn, hs_sandbox_config* cfg, const hs_sandbox_config* dflt, hs_sb_type mode) { if (!cfg) return false; init_sandbox_config(cfg); char fqfn[HS_MAX_PATH]; if (!hs_get_config_fqfn(dir, fn, fqfn, sizeof(fqfn))) return false; if (!hs_file_exists(fqfn)) return false; lua_State* L = luaL_newstate(); if (!L) { hs_log(g_module, 3, "luaL_newstate failed: %s", fn); return false; } if (dflt) { cfg->output_limit = dflt->output_limit; cfg->memory_limit = dflt->memory_limit; cfg->instruction_limit = dflt->instruction_limit; cfg->ticker_interval = dflt->ticker_interval; cfg->preserve_data = dflt->preserve_data; } int ret = luaL_dofile(L, fqfn); if (ret) goto cleanup; size_t len = strlen(dir) + 1; cfg->dir = malloc(len); memcpy(cfg->dir, dir, len); // remove the extension and leave room for the NUL len = strlen(fn) - HS_EXT_LEN + 1; cfg->cfg_name = malloc(len); memcpy(cfg->cfg_name, fn, len); cfg->cfg_name[len - 1] = 0; ret = get_numeric_item(L, LUA_GLOBALSINDEX, cfg_sb_output, &cfg->output_limit); if (ret) goto cleanup; ret = get_numeric_item(L, LUA_GLOBALSINDEX, cfg_sb_memory, &cfg->memory_limit); if (ret) goto cleanup; ret = get_numeric_item(L, LUA_GLOBALSINDEX, cfg_sb_instruction, &cfg->instruction_limit); if (ret) goto cleanup; ret = get_numeric_item(L, LUA_GLOBALSINDEX, cfg_sb_ticker_interval, &cfg->ticker_interval); if (ret) goto cleanup; ret = get_string_item(L, LUA_GLOBALSINDEX, cfg_sb_filename, &cfg->filename, NULL); if (!ret) { if (strpbrk(cfg->filename, "/\\")) { lua_pushfstring(L, "%s must be not contain a path component", cfg_sb_filename); ret = 1; } else if (!hs_has_ext(cfg->filename, hs_lua_ext)) { lua_pushfstring(L, "%s must have a %s extension", hs_lua_ext, cfg_sb_filename); ret = 1; } } if (ret) goto cleanup; ret = get_bool_item(L, LUA_GLOBALSINDEX, cfg_sb_preserve, &cfg->preserve_data); if (ret) goto cleanup; if (mode == HS_SB_TYPE_ANALYSIS || mode == HS_SB_TYPE_OUTPUT) { ret = get_string_item(L, LUA_GLOBALSINDEX, cfg_sb_matcher, &cfg->message_matcher, NULL); if (ret) goto cleanup; } if (mode == HS_SB_TYPE_ANALYSIS) { ret = get_numeric_item(L, LUA_GLOBALSINDEX, cfg_sb_thread, &cfg->thread); if (ret) goto cleanup; } if (mode == HS_SB_TYPE_OUTPUT) { ret = get_numeric_item(L, LUA_GLOBALSINDEX, cfg_sb_async_buffer, &cfg->async_buffer_size); if (ret) goto cleanup; } cleanup: if (ret) { hs_log(g_module, 3, "loading %s failed: %s", fn, lua_tostring(L, -1)); lua_close(L); hs_free_sandbox_config(cfg); return false; } cfg->type = mode; cfg->custom_config = L; return true; }