/** * Handle on/off directives. * * @param[in] cp Config parser * @param[in] name Directive name * @param[in] onoff on/off flag * @param[in] cbdata Callback data (ignored) * * @returns Status code */ static ib_status_t handle_directive_onoff(ib_cfgparser_t *cp, const char *name, int onoff, void *cbdata) { assert(cp != NULL); assert(name != NULL); assert(cp->ib != NULL); ib_engine_t *ib = cp->ib; ib_status_t rc; ib_module_t *module = NULL; modpcre_cfg_t *config = NULL; ib_context_t *ctx = cp->cur_ctx ? cp->cur_ctx : ib_context_main(ib); const char *pname; /* Get my module object */ rc = ib_engine_module_get(cp->ib, MODULE_NAME_STR, &module); if (rc != IB_OK) { ib_cfg_log_error(cp, "Failed to get %s module object: %s", MODULE_NAME_STR, ib_status_to_string(rc)); return rc; } /* Get my module configuration */ rc = ib_context_module_config(ctx, module, (void *)&config); if (rc != IB_OK) { ib_cfg_log_error(cp, "Failed to get %s module configuration: %s", MODULE_NAME_STR, ib_status_to_string(rc)); return rc; } if (strcasecmp("PcreStudy", name) == 0) { pname = MODULE_NAME_STR ".study"; } else if (strcasecmp("PcreUseJit", name) == 0) { pname = MODULE_NAME_STR ".use_jit"; } else { ib_cfg_log_error(cp, "Unhandled directive \"%s\"", name); return IB_EINVAL; } rc = ib_context_set_num(ctx, pname, onoff); if (rc != IB_OK) { ib_cfg_log_error(cp, "Failed to set \"%s\" to %s for \"%s\": %s", pname, onoff ? "true" : "false", name, ib_status_to_string(rc)); } return IB_OK; }
/** * Handle a GeoIPDatabaseFile directive. * * @param[in] cp Configuration parser * @param[in] name The directive name. * @param[in] p1 The directive parameter. * @param[in] cbdata User data (module configuration) */ static ib_status_t geoip_database_file_dir_param1(ib_cfgparser_t *cp, const char *name, const char *p1, void *cbdata) { assert(cp != NULL); assert(name != NULL); assert(p1 != NULL); assert(cbdata != NULL); ib_status_t rc; size_t p1_len = strlen(p1); size_t p1_unescaped_len; char *p1_unescaped = malloc(p1_len+1); module_data_t *mod_data = (module_data_t *)cbdata; if (p1_unescaped == NULL) { return IB_EALLOC; } rc = ib_util_unescape_string(p1_unescaped, &p1_unescaped_len, p1, p1_len, IB_UTIL_UNESCAPE_NULTERMINATE | IB_UTIL_UNESCAPE_NONULL); if (rc != IB_OK ) { const char *msg = ( rc == IB_EBADVAL )? "GeoIP Database File \"%s\" contains nulls." : "GeoIP Database File \"%s\" is an invalid string."; ib_cfg_log_debug(cp, msg, p1); free(p1_unescaped); return rc; } if (mod_data->geoip_db != NULL) { GeoIP_delete(mod_data->geoip_db); mod_data->geoip_db = NULL; } mod_data->geoip_db = GeoIP_open(p1_unescaped, GEOIP_MMAP_CACHE); if (mod_data->geoip_db == NULL) { int status = access(p1_unescaped, R_OK); if (status != 0) { ib_cfg_log_error(cp, "Unable to read GeoIP database file \"%s\"", p1_unescaped); rc = IB_ENOENT; } else { ib_cfg_log_error(cp, "Unknown error opening GeoIP database file \"%s\"", p1_unescaped); rc = IB_EUNKNOWN; } } free(p1_unescaped); return rc; }
/** * Handle single parameter directives. * * @param cp Config parser * @param name Directive name * @param p1 First parameter * @param cbdata Callback data (from directive registration) * * @returns Status code */ static ib_status_t handle_directive_param(ib_cfgparser_t *cp, const char *name, const char *p1, void *cbdata) { assert(cp != NULL); assert(name != NULL); assert(p1 != NULL); assert(cp->ib != NULL); ib_engine_t *ib = cp->ib; ib_status_t rc; ib_module_t *module = NULL; modpcre_cfg_t *config = NULL; ib_context_t *ctx = cp->cur_ctx ? cp->cur_ctx : ib_context_main(ib); const char *pname; ib_num_t value; /* Get my module object */ rc = ib_engine_module_get(cp->ib, MODULE_NAME_STR, &module); if (rc != IB_OK) { ib_cfg_log_error(cp, "Failed to get %s module object: %s", MODULE_NAME_STR, ib_status_to_string(rc)); return rc; } /* Get my module configuration */ rc = ib_context_module_config(ctx, module, (void *)&config); if (rc != IB_OK) { ib_cfg_log_error(cp, "Failed to get %s module configuration: %s", MODULE_NAME_STR, ib_status_to_string(rc)); return rc; } /* p1 should be a number */ rc = ib_string_to_num(p1, 0, &value); if (rc != IB_OK) { ib_cfg_log_error(cp, "Failed to convert \"%s\" to a number for \"%s\": %s", p1, name, ib_status_to_string(rc)); return rc; } if (strcasecmp("PcreMatchLimit", name) == 0) { pname = "pcre.match_limit"; } else if (strcasecmp("PcreMatchLimitRecursion", name) == 0) { pname = "pcre.match_limit_recursion"; } else if (strcasecmp("PcreJitStackStart", name) == 0) { pname = "pcre.jit_stack_start"; } else if (strcasecmp("PcreJitStackMax", name) == 0) { pname = "pcre.jit_stack_max"; } else if (strcasecmp("PcreDfaWorkspaceSize", name) == 0) { pname = "pcre.dfa_workspace_size"; } else { ib_cfg_log_error(cp, "Unhandled directive \"%s\"", name); return IB_EINVAL; } rc = ib_context_set_num(ctx, pname, value); if (rc != IB_OK) { ib_cfg_log_error(cp, "Failed to set \"%s\" to %ld for \"%s\": %s", pname, (long int)value, name, ib_status_to_string(rc)); } return IB_OK; }
/** * Called by RuleExt lua:. * * @param[in] cp Configuration parser. * @param[in] rule Rule under construction. * @param[in] tag Should be "lua". * @param[in] location What comes after "lua:". * @param[in] cbdata Callback data; unused. * @return * - IB_OK on success. * - IB_EINVAL if Lua not available or not called for "lua" tag. * - Other error code if loading or registration fails. */ static ib_status_t modlua_rule_driver( ib_cfgparser_t *cp, ib_rule_t *rule, const char *tag, const char *location, void *cbdata ) { assert(cp != NULL); assert(cp->ib != NULL); assert(tag != NULL); assert(location != NULL); ib_status_t rc; const char *slash; const char *name; ib_operator_t *op; ib_operator_inst_t *opinst; ib_engine_t *ib = cp->ib; modlua_cfg_t *cfg = NULL; ib_context_t *ctx = NULL; modlua_rules_cbdata_t *modlua_rules_cbdata = (modlua_rules_cbdata_t *)cbdata; /* This cbdata is passed on to the implementation. Validate it here. */ assert(modlua_rules_cbdata != NULL); assert(modlua_rules_cbdata->module != NULL); if (strncmp(tag, "lua", 3) != 0) { ib_cfg_log_error(cp, "Lua rule driver called for non-lua tag."); return IB_EINVAL; } rc = ib_cfgparser_context_current(cp, &ctx); if (rc != IB_OK) { ib_cfg_log_error(cp, "Failed to retrieve current context."); return rc; } rc = modlua_cfg_get(ib, ctx, &cfg); if (rc != IB_OK) { return rc; } rc = ib_lua_load_func( cp->ib, cfg->L, location, ib_rule_id(rule)); if (rc != IB_OK) { ib_cfg_log_error(cp, "Failed to load lua file \"%s\"", location); return rc; } /* Record that we need to reload this rule in each TX. */ rc = modlua_record_reload( cp->ib, cfg, MODLUA_RELOAD_RULE, NULL, ib_rule_id(rule), location); if (rc != IB_OK) { ib_cfg_log_error( cp, "Failed to record lua file \"%s\" to reload", location); return rc; } slash = strrchr(location, '/'); if (slash == NULL) { name = location; } else { name = slash + 1; } rc = ib_operator_create_and_register( &op, cp->ib, name, IB_OP_CAPABILITY_NONE, &lua_operator_create, modlua_rules_cbdata, NULL, NULL, &lua_operator_execute, modlua_rules_cbdata ); if (rc != IB_OK) { ib_cfg_log_error(cp, "Error registering lua operator \"%s\": %s", name, ib_status_to_string(rc)); return rc; } rc = ib_operator_inst_create(&opinst, ib_engine_mm_main_get(cp->ib), ctx, op, ib_rule_required_op_flags(rule), ib_rule_id(rule)); /* becomes instance_data */ if (rc != IB_OK) { ib_cfg_log_error(cp, "Error instantiating lua operator " "for rule \"%s\": %s", name, ib_status_to_string(rc)); return rc; } rc = ib_rule_set_operator(cp->ib, rule, opinst); if (rc != IB_OK) { ib_cfg_log_error(cp, "Error associating lua operator \"%s\" " "with rule \"%s\": %s", name, ib_rule_id(rule), ib_status_to_string(rc)); return rc; } return IB_OK; }
static ib_status_t sqli_dir_fingerprint_set( ib_cfgparser_t *cp, const char *directive_name, const char *set_name, const char *set_path, void *cbdata ) { assert(cp != NULL); assert(directive_name != NULL); assert(set_name != NULL); assert(set_path != NULL); ib_status_t rc; ib_context_t *ctx = NULL; ib_module_t *m = NULL; sqli_module_config_t *cfg = NULL; sqli_fingerprint_set_t *ps = NULL; ib_mm_t mm; char *abs_set_path = NULL; rc = ib_cfgparser_context_current(cp, &ctx); assert(rc == IB_OK); assert(ctx != NULL); if (ctx != ib_context_main(cp->ib)) { ib_cfg_log_error(cp, "%s: Only valid at main context.", directive_name ); return IB_EINVAL; } if (strcmp("default", set_name) == 0) { ib_cfg_log_error(cp, "%s: default is a reserved set name.", directive_name ); return IB_EINVAL; } mm = ib_engine_mm_main_get(cp->ib); rc = ib_engine_module_get( ib_context_get_engine(ctx), MODULE_NAME_STR, &m ); assert(rc == IB_OK); rc = ib_context_module_config(ctx, m, &cfg); assert(rc == IB_OK); if (cfg->fingerprint_sets == NULL) { rc = ib_hash_create(&cfg->fingerprint_sets, mm); assert(rc == IB_OK); } assert(cfg->fingerprint_sets != NULL); rc = ib_hash_get(cfg->fingerprint_sets, NULL, set_name); if (rc == IB_OK) { ib_cfg_log_error(cp, "%s: Duplicate fingerprint set definition: %s", directive_name, set_name ); return IB_EINVAL; } assert(rc == IB_ENOENT); abs_set_path = ib_util_relative_file( ib_engine_mm_config_get(cp->ib), ib_cfgparser_curr_file(cp), set_path ); if (abs_set_path == NULL) { return IB_EALLOC; } rc = sqli_create_fingerprint_set_from_file(&ps, abs_set_path, mm); if (rc != IB_OK) { ib_cfg_log_error(cp, "%s: Failure to load fingerprint set from file: %s", directive_name, abs_set_path ); return IB_EINVAL; } assert(ps != NULL); rc = ib_hash_set(cfg->fingerprint_sets, ib_mm_strdup(mm, set_name), ps); assert(rc == IB_OK); return IB_OK; }