bool hs_get_config_fqfn(const char* path, const char* name, char* fqfn, size_t fqfn_len) { if (!hs_has_ext(name, hs_cfg_ext)) return false; int ret = snprintf(fqfn, fqfn_len, "%s/%s", path, name); if (ret < 0 || ret > (int)fqfn_len - 1) { return false; } return true; }
static void process_lua(hs_output_plugins* plugins, const char* lpath, const char* rpath, DIR* dp) { char lua_lpath[HS_MAX_PATH]; char lua_rpath[HS_MAX_PATH]; char cfg_lpath[HS_MAX_PATH]; char cfg_rpath[HS_MAX_PATH]; size_t tlen = strlen(hs_output_dir) + 1; struct dirent* entry; while ((entry = readdir(dp))) { if (hs_has_ext(entry->d_name, hs_lua_ext)) { // move the Lua to the run directory if (!hs_get_fqfn(lpath, entry->d_name, lua_lpath, sizeof(lua_lpath))) { hs_log(g_module, 0, "load lua path too long"); exit(EXIT_FAILURE); } if (!hs_get_fqfn(rpath, entry->d_name, lua_rpath, sizeof(lua_rpath))) { hs_log(g_module, 0, "run lua path too long"); exit(EXIT_FAILURE); } if (rename(lua_lpath, lua_rpath)) { hs_log(g_module, 3, "failed to move: %s to %s errno: %d", lua_lpath, lua_rpath, errno); continue; } // restart any plugins using this Lua code pthread_mutex_lock(&plugins->list_lock); for (int i = 0; i < plugins->list_cap; ++i) { if (!plugins->list[i]) continue; hs_output_plugin* p = plugins->list[i]; if (strcmp(lua_rpath, lsb_get_lua_file(p->sb->lsb)) == 0) { int ret = snprintf(cfg_lpath, HS_MAX_PATH, "%s/%s%s", lpath, p->sb->name + tlen, hs_cfg_ext); if (ret < 0 || ret > HS_MAX_PATH - 1) { hs_log(g_module, 0, "load cfg path too long"); exit(EXIT_FAILURE); } ret = snprintf(cfg_rpath, HS_MAX_PATH, "%s/%s%s", rpath, p->sb->name + tlen, hs_cfg_ext); if (ret < 0 || ret > HS_MAX_PATH - 1) { hs_log(g_module, 0, "run cfg path too long"); exit(EXIT_FAILURE); } // if no new cfg was provided, move the existing cfg to the load // directory if (!hs_file_exists(cfg_lpath)) { if (rename(cfg_rpath, cfg_lpath)) { hs_log(g_module, 3, "failed to move: %s to %s errno: %d", cfg_rpath, cfg_lpath, errno); } } } } pthread_mutex_unlock(&plugins->list_lock); } } rewinddir(dp); }
int hs_process_load_cfg(const char* lpath, const char* rpath, const char* name) { if (hs_has_ext(name, hs_cfg_ext)) { char cfg_lpath[HS_MAX_PATH]; if (!hs_get_fqfn(lpath, name, cfg_lpath, sizeof(cfg_lpath))) { hs_log(g_module, 0, "load cfg path too long"); exit(EXIT_FAILURE); } char cfg_rpath[HS_MAX_PATH]; if (!hs_get_fqfn(rpath, name, cfg_rpath, sizeof(cfg_rpath))) { hs_log(g_module, 0, "run cfg path too long"); exit(EXIT_FAILURE); } // if the plugin was off clear the flag and prepare for restart char off_rpath[HS_MAX_PATH]; strcpy(off_rpath, cfg_rpath); strcpy(off_rpath + strlen(off_rpath) - HS_EXT_LEN, hs_off_ext); if (hs_file_exists(off_rpath)) { if (unlink(off_rpath)) { hs_log(g_module, 3, "failed to delete: %s errno: %d", off_rpath, errno); return -1; } } // move the cfg to the run directory and prepare for start/restart if (rename(cfg_lpath, cfg_rpath)) { hs_log(g_module, 3, "failed to move: %s to %s errno: %d", cfg_lpath, cfg_rpath, errno); return -1; } return 1; } else if (hs_has_ext(name, hs_off_ext)) { char off_lpath[HS_MAX_PATH]; if (!hs_get_fqfn(lpath, name, off_lpath, sizeof(off_lpath))) { hs_log(g_module, 0, "load off path too long"); exit(EXIT_FAILURE); } if (unlink(off_lpath)) { hs_log(g_module, 3, "failed to delete: %s errno: %d", off_lpath, errno); return -1; } // move the current cfg to .off and shutdown the plugin char off_rpath[HS_MAX_PATH]; if (!hs_get_fqfn(rpath, name, off_rpath, sizeof(off_rpath))) { hs_log(g_module, 0, "run off path too long"); exit(EXIT_FAILURE); } char cfg_rpath[HS_MAX_PATH]; strcpy(cfg_rpath, off_rpath); strcpy(cfg_rpath + strlen(cfg_rpath) - HS_EXT_LEN, hs_cfg_ext); if (rename(cfg_rpath, off_rpath)) { hs_log(g_module, 4, "failed to move: %s to %s errno: %d", cfg_rpath, off_rpath, errno); return -1; } return 0; } return -1; }
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; }