/** * Handle event starts. * * Here we set start times and increment the call counter. * * \param[in] ib IronBee object. * \param[in] eventp Event info. * \param[in] perf_info Perf info. **/ static void mod_perf_stats_event_start( ib_engine_t *ib, event_info_t *eventp, perf_info_t *perf_info ) { IB_FTRACE_INIT(); int cevent = eventp->number; /* Current event number. */ perf_info_t *perfp; /* Perf data on current event. */ if (perf_info != NULL) { /* Set perfp to current event type. */ perfp = &perf_info[cevent]; /* Set the start time for event */ perfp->start_usec = ib_clock_get_time(); /* Increment the call counter */ perfp->call_cnt++; ib_log_debug(ib, "Start Callback: %s (%llu) (%llu) ", perfp->name, perfp->call_cnt, perfp->start_usec); } else { ib_log_debug(ib, "Connection based perf_info is NULL"); } IB_FTRACE_RET_VOID(); }
/** * Perf Event Start Event Callback. * * On a connection started event we register connection * counters for the connection. * * @param[in] ib IronBee object. * @param[in] event Event type. * @param[in] connp Connection object. * @param[in] cbdata Callback data: actually an perf_info_t describing the * event. */ static ib_status_t mod_perf_stats_reg_conn_counter( ib_engine_t *ib, ib_state_event_type_t event_type, ib_conn_t *connp, void *cbdata ) { IB_FTRACE_INIT(); perf_info_t *perf_info; event_info_t *eventp = (event_info_t *)cbdata; int cevent = eventp->number; int rc; int event; perf_info = ib_mpool_alloc(connp->mp, sizeof(*perf_info) * IB_STATE_EVENT_NUM); for (event = 0; event < IB_STATE_EVENT_NUM; ++event) { if ((eventp->cbdata_type == IB_CBDATA_NONE) || (eventp->cbdata_type == IB_CBDATA_CONN_DATA_T)) { ib_log_error(ib, "Cannot collect stats for:%d name:%s cbdata_type: %d", eventp->number, eventp->name, eventp->cbdata_type); } else { perf_info_t *perfp = &perf_info[event]; /* Does this event match conn_started_event? * If so we should init counters for this event. */ if (event == cevent) { perfp->call_cnt = 1; perfp->start_usec = ib_clock_get_time(); } else { perfp->call_cnt = 0; perfp->start_usec = 0; } /* Setup other defaults */ perfp->number = event; perfp->name = ib_state_event_name((ib_state_event_type_t)event); perfp->cbdata_type = ib_state_event_cbdata_type(event); perfp->max_usec = 0; perfp->total_usec = 0; perfp->stop_usec = 0; ib_log_debug(ib, "Perf callback registered %s (%d) (%d)", perfp->name, perfp->number, perfp->cbdata_type); } } rc = ib_hash_set(connp->data, "MOD_PERF_STATS" ,perf_info); if (rc != IB_OK) { ib_log_debug(ib, "Failed to store perf stats in connection data: %s", ib_status_to_string(rc)); IB_FTRACE_RET_STATUS(rc); } IB_FTRACE_RET_STATUS(IB_OK); }
static ib_status_t modbinradix_init(ib_engine_t *ib, ib_module_t *m, void *cbdata) { IB_FTRACE_INIT(); ib_status_t rc; /* Register as a matcher provider. */ rc = ib_provider_register(ib, IB_PROVIDER_TYPE_MATCHER, MODULE_NAME_STR, NULL, &modbinradix_matcher_iface, modbinradix_provider_instance_init); if (rc != IB_OK) { ib_log_error(ib, MODULE_NAME_STR ": Error registering ac matcher provider: " "%s", ib_status_to_string(rc)); IB_FTRACE_RET_STATUS(IB_OK); } ib_log_debug(ib, "AC Status: compiled=\"%d.%d %s\" BinRadix Matcher" " registered", AC_MAJOR, AC_MINOR, IB_XSTRINGIFY(AC_DATE)); IB_FTRACE_RET_STATUS(IB_OK); }
ib_status_t ibpp_caught_boost_exception( ib_engine_t* engine, const boost::exception& e ) { std::string message; int level = 1; message = "Unknown boost::exception thrown: "; if (boost::get_error_info<boost::throw_function>(e)) { message += *boost::get_error_info<boost::throw_function>(e); } else { message += "No information provided. Please report as bug."; } if (boost::get_error_info<errinfo_level>(e)) { level = *boost::get_error_info<errinfo_level>(e); } if (engine) { ib_log(engine, level, "%s", message.c_str()); ib_log_debug(engine, "%s", diagnostic_information(e).c_str() ); } else { ib_util_log_error("%s", message.c_str()); ib_util_log_debug("%s", diagnostic_information(e).c_str() ); } return IB_EUNKNOWN; }
ib_status_t ibpp_caught_ib_exception( ib_engine_t* engine, ib_status_t status, const error& e ) { std::string message; int level = 1; message = std::string(ib_status_to_string(status)) + ":"; if (boost::get_error_info<errinfo_what>(e)) { message += *boost::get_error_info<errinfo_what>(e); } else { message += "IronBee++ Exception but no explanation provided. " "Please report as bug."; } if (boost::get_error_info<errinfo_level>(e)) { level = *boost::get_error_info<errinfo_level>(e); } if (engine) { ib_log(engine, level, "%s", message.c_str()); ib_log_debug(engine, "%s", diagnostic_information(e).c_str() ); } else { ib_util_log_error("%s", message.c_str()); ib_util_log_debug("%s", diagnostic_information(e).c_str() ); } return status; }
ib_status_t ib_cfgparser_context_pop(ib_cfgparser_t *cp, ib_context_t **pctx) { IB_FTRACE_INIT(ib_cfgparser_context_pop); ib_engine_t *ib = cp->ib; ib_context_t *ctx; ib_status_t rc; if (pctx != NULL) { *pctx = NULL; } /* Remove the last item. */ rc = ib_list_pop(cp->stack, &ctx); if (rc != IB_OK) { ib_log_error(ib, 4, "Failed to pop context: %d", rc); IB_FTRACE_RET_STATUS(rc); } if (pctx != NULL) { *pctx = ctx; } /* The last in the list is now the current. */ ctx = (ib_context_t *)ib_list_node_data(ib_list_last(cp->stack)); cfgp_set_current(cp, ctx); ib_log_debug(ib, 9, "Stack: ctx=%p site=%p(%s) loc=%p(%s)", cp->cur_ctx, cp->cur_site, cp->cur_site?cp->cur_site->name:"NONE", cp->cur_loc, cp->cur_loc?cp->cur_loc->path:"/"); IB_FTRACE_RET_STATUS(IB_OK); }
/** * * Log to debug log * * Lua parameter stack: * 1) engine handle * 3) format * 4) ... * * @param L Lua state */ static int log_debug(lua_State *L) { ib_engine_t *ib = (ib_engine_t *)lua_topointer(L, 1); int nargs = lua_gettop(L); const char *msg; int ec; /* * Call string.format() to do the actual formatting. * * This is done as lua cannot bind a vararg C function. Instead, * this reorganizes the stack, replacing the "level" arg with the * format function, then calls string.format with the remaining args. * This allows string.format to do the formatting so that a single * string arg can be passed to the underlying ironbee log function. */ /// @todo Store the format function for faster access??? lua_getglobal(L, "string"); lua_getfield(L, -1, "format"); /* string.format() */ lua_pop(L, 1); /* cleanup the stack used to find string table */ ec = lua_pcall(L, (nargs - 2), 1, 0); /* format(fmt, ...) */ if (ec != 0) { ib_log_error(ib, "Failed to exec string.format - %s (%d)", lua_tostring(L, -1), ec); return 0; } msg = lua_tostring(L, -1); /* formatted string */ /* Call the ironbee API with the formatted message. */ ib_log_debug(ib, "%s", msg); return 1; }
static ib_status_t modpcre_init(ib_engine_t *ib, ib_module_t *m, void *cbdata) { IB_FTRACE_INIT(); ib_status_t rc; /* Register as a matcher provider. */ rc = ib_provider_register(ib, IB_PROVIDER_TYPE_MATCHER, MODULE_NAME_STR, NULL, &modpcre_matcher_iface, NULL); if (rc != IB_OK) { ib_log_error(ib, MODULE_NAME_STR ": Error registering pcre matcher provider: " "%s", ib_status_to_string(rc)); IB_FTRACE_RET_STATUS(IB_OK); } ib_log_debug(ib,"PCRE Status: compiled=\"%d.%d %s\" loaded=\"%s\"", PCRE_MAJOR, PCRE_MINOR, IB_XSTRINGIFY(PCRE_DATE), pcre_version()); /* Register operators. */ ib_operator_register(ib, "pcre", (IB_OP_FLAG_PHASE | IB_OP_FLAG_CAPTURE), pcre_operator_create, NULL, pcre_operator_destroy, NULL, pcre_operator_execute, NULL); /* An alias of pcre. The same callbacks are registered. */ ib_operator_register(ib, "rx", (IB_OP_FLAG_PHASE | IB_OP_FLAG_CAPTURE), pcre_operator_create, NULL, pcre_operator_destroy, NULL, pcre_operator_execute, NULL); /* Register a pcre operator that uses pcre_dfa_exec to match streams. */ ib_operator_register(ib, "dfa", (IB_OP_FLAG_PHASE | IB_OP_FLAG_STREAM), dfa_operator_create, NULL, dfa_operator_destroy, NULL, dfa_operator_execute, NULL); IB_FTRACE_RET_STATUS(IB_OK); }
/** * Match against the AC tree * * @param mpi provider instance * @param flags extra flags * @param data the data to search in * @param dlen length of the the data to search in * * @return status of the operation */ static ib_status_t modac_match(ib_provider_inst_t *mpi, ib_flags_t flags, const uint8_t *data, size_t dlen, void *ctx) { IB_FTRACE_INIT(modac_match); modac_provider_data_t *dt = mpi->data; if (dt == NULL) { IB_FTRACE_RET_STATUS(IB_EINVAL); } ib_log_debug(mpi->pr->ib, 4, "Matching AGAINST AC tree %x", dt->ac_tree); ib_ac_t *ac_tree = dt->ac_tree; ib_ac_context_t *ac_mctx = (ib_ac_context_t *)ctx; ib_ac_reset_ctx(ac_mctx, ac_tree); /* Let's perform the search. Content is consumed in just one call */ ib_status_t rc = ib_ac_consume(ac_mctx, (const char *)data, dlen, IB_AC_FLAG_CONSUME_DOLIST | IB_AC_FLAG_CONSUME_MATCHALL | IB_AC_FLAG_CONSUME_DOCALLBACK, mpi->mp); IB_FTRACE_RET_STATUS(rc); }
/* Called when module is unloaded. */ static ib_status_t perf_stats_fini(ib_engine_t *ib, ib_module_t *m, void *cbdata) { IB_FTRACE_INIT(); ib_log_debug(ib, "Perf stats module unloaded."); IB_FTRACE_RET_STATUS(IB_OK); }
/** * Create an instance of the @c ee_match_any operator. * * Looks up the automata name and adds the automata to the operator instance. * * @param[in] ctx Current context. * @param[in] parameters Automata name. * @param[out] instance_data Instance data. * @param[in] cbdata Callback data. */ static ib_status_t ee_match_any_operator_create( ib_context_t *ctx, const char *parameters, void *instance_data, void *cbdata ) { assert(ctx != NULL); assert(parameters != NULL); assert(instance_data != NULL); ib_status_t rc; ia_eudoxus_t* eudoxus; ee_operator_data_t *operator_data; ib_module_t *module; ib_engine_t *ib = ib_context_get_engine(ctx); ib_mpool_t *pool = ib_context_get_mpool(ctx); const ee_config_t *config = ee_get_config(ib); const ib_hash_t *eudoxus_pattern_hash; assert(config != NULL); assert(config->eudoxus_pattern_hash != NULL); /* Get my module object */ rc = ib_engine_module_get(ib, MODULE_NAME_STR, &module); if (rc != IB_OK) { ib_log_error(ib, "Failed to get eudoxus operator module object: %s", ib_status_to_string(rc)); return rc; } /* Allocate a rule data object, populate it */ operator_data = ib_mpool_alloc(pool, sizeof(*operator_data)); if (operator_data == NULL) { return IB_EALLOC; } eudoxus_pattern_hash = config->eudoxus_pattern_hash; rc = ib_hash_get(eudoxus_pattern_hash, &eudoxus, parameters); if (rc == IB_ENOENT ) { ib_log_error(ib, MODULE_NAME_STR ": No eudoxus automata named %s found.", parameters); return rc; } else if (rc != IB_OK) { ib_log_error(ib, MODULE_NAME_STR ": Error setting up eudoxus automata operator."); return rc; } operator_data->eudoxus = eudoxus; *(ee_operator_data_t **)instance_data = operator_data; ib_log_debug(ib, "Found compiled eudoxus pattern \"%s\"", parameters); return IB_OK; }
static ib_status_t geoip_database_file_dir_param1(ib_cfgparser_t *cp, const char *name, const char *p1, void *cbdata) { IB_FTRACE_INIT(); assert(cp!=NULL); assert(name!=NULL); assert(p1!=NULL); ib_status_t rc; size_t p1_len = strlen(p1); size_t p1_unescaped_len; char *p1_unescaped = malloc(p1_len+1); if ( p1_unescaped == NULL ) { IB_FTRACE_RET_STATUS(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_log_debug(cp->ib, msg, p1); free(p1_unescaped); IB_FTRACE_RET_STATUS(rc); } if (geoip_db != NULL) { GeoIP_delete(geoip_db); geoip_db = NULL; } IB_FTRACE_MSG("Initializing custom GeoIP database..."); IB_FTRACE_MSG(p1_unescaped); geoip_db = GeoIP_open(p1_unescaped, GEOIP_MMAP_CACHE); free(p1_unescaped); if (geoip_db == NULL) { IB_FTRACE_MSG("Failed to initialize GeoIP database."); IB_FTRACE_RET_STATUS(IB_EUNKNOWN); } IB_FTRACE_RET_STATUS(IB_OK); }
/* Called when module is unloaded. */ static ib_status_t geoip_fini(ib_engine_t *ib, ib_module_t *m, void *cbdata) { if (geoip_db!=NULL) { GeoIP_delete(geoip_db); } ib_log_debug(ib, "GeoIP module unloaded."); return IB_OK; }
/** * Use set_mode() to change this module into @ref STOPPING mode. * * @sa mode_t * * @param[in] ib IronBee Engine. * @param[in] event The shutdown event. */ void on_connection_opened( IronBee::Engine ib, IronBee::Connection conn) const { if (get_mode() != RUNNING) { ib_log_debug( ib.ib(), "New connection started after shutdown req."); } }
/* Called when module is unloaded. */ static ib_status_t geoip_fini(ib_engine_t *ib, ib_module_t *m, void *cbdata) { IB_FTRACE_INIT(); if (geoip_db!=NULL) { GeoIP_delete(geoip_db); } ib_log_debug(ib, "GeoIP module unloaded."); IB_FTRACE_RET_STATUS(IB_OK); }
/** * @brief Create the PCRE operator. * @param[in] ib The IronBee engine (unused) * @param[in] ctx The current IronBee context (unused) * @param[in,out] pool The memory pool into which @c op_inst->data * will be allocated. * @param[in] The regular expression to be built. * @param[out] op_inst The operator instance that will be populated by * parsing @a pattern. * @returns IB_OK on success or IB_EALLOC on any other type of error. */ static ib_status_t dfa_operator_create(ib_engine_t *ib, ib_context_t *ctx, const ib_rule_t *rule, ib_mpool_t *pool, const char *pattern, ib_operator_inst_t *op_inst) { IB_FTRACE_INIT(); const char* errptr; int erroffset; dfa_rule_data_t *rule_data = NULL; ib_status_t rc; rc = dfa_compile_internal(pool, &rule_data, pattern, &errptr, &erroffset); if (rc==IB_OK) { ib_log_debug(ib, "Compiled DFA operator pattern: %s", pattern); /* We compute the length of the string buffer as such: * +2 for the 0x prefix. * +1 for the \0 string terminations. * +16 for encoding 8 bytes (64 bits) as hex-pairs (2 chars / byte). */ size_t id_sz = 16 + 2 + 1; char *id; id = ib_mpool_alloc(pool, id_sz); snprintf(id, id_sz, "%p", op_inst); rule_data->id = id; ib_log_debug(ib, "Created DFA operator with ID %s.", id); op_inst->data = rule_data; } else { ib_log_error(ib, "Failed to parse DFA operator pattern: %s", pattern); } IB_FTRACE_RET_STATUS(IB_OK); }
/** * Block a transaction if get_mode() returns not @ref RUNNING. * * @sa mode_t * * @param[in] ib IronBee Engine. * @param[in] tx The transaction. */ void on_transaction_started( IronBee::Engine ib, IronBee::Transaction tx) const { if (get_mode() != RUNNING) { ib_log_debug( ib.ib(), "New transaction started after shutdown req."); } }
ib_status_t ib_cfgparser_create(ib_cfgparser_t **pcp, ib_engine_t *ib) { IB_FTRACE_INIT(ib_cfgparser_create); ib_mpool_t *pool; ib_status_t rc; /* Create parser memory pool */ rc = ib_mpool_create(&pool, ib->mp); if (rc != IB_OK) { rc = IB_EALLOC; goto failed; } /* Create the main structure in the memory pool */ *pcp = (ib_cfgparser_t *)ib_mpool_calloc(pool, 1, sizeof(**pcp)); if (*pcp == NULL) { rc = IB_EALLOC; goto failed; } (*pcp)->ib = ib; (*pcp)->mp = pool; /* Create the stack */ rc = ib_list_create(&((*pcp)->stack), pool); if (rc != IB_OK) { goto failed; } (*pcp)->cur_ctx = ib_context_main(ib); ib_list_push((*pcp)->stack, (*pcp)->cur_ctx); /* Create the block tracking list */ rc = ib_list_create(&((*pcp)->block), pool); if (rc != IB_OK) { goto failed; } /* Other fields are NULLed via calloc */ ib_log_debug(ib, 9, "Stack: ctx=%p site=%p(%s) loc=%p(%s)", (*pcp)->cur_ctx, (*pcp)->cur_site, (*pcp)->cur_site?(*pcp)->cur_site->name:"NONE", (*pcp)->cur_loc, (*pcp)->cur_loc?(*pcp)->cur_loc->path:"/"); IB_FTRACE_RET_STATUS(rc); failed: /* Make sure everything is cleaned up on failure */ if (pool != NULL) { ib_mpool_destroy(pool); } *pcp = NULL; IB_FTRACE_RET_STATUS(rc); }
/** * @internal * Handle event stops. * * Counters are updated and displayed. * * @param[in] ib IronBee object * \param[in] eventp Event info. * \param[in] perf_info Perf info. * event. */ static ib_status_t mod_perf_stats_event_stop( ib_engine_t *ib, event_info_t *eventp, perf_info_t *perf_info ) { IB_FTRACE_INIT(); int cevent = eventp->number; /* Current event number. */ perf_info_t *perfp; /* Perf data on current event. */ uint64_t time_taken; /* Temp storage for time the event took */ if (perf_info != NULL) { perfp = &perf_info[cevent]; /* Set the stop time for the event. */ perfp->stop_usec = ib_clock_get_time(); /* Get the msec the event took. */ time_taken = (perfp->stop_usec - perfp->start_usec); /* Update total time spent on event. */ perfp->total_usec += time_taken; /* Update max time taken for event if needed. */ if (time_taken > perfp->max_usec) { perfp->max_usec = time_taken; } ib_log_debug(ib, "Stop Callback: %s call_cnt:(%llu) start:(%llu) " "stop:(%llu) took:(%llu) conn total:(%llu) max:(%llu)", perfp->name, perfp->call_cnt, perfp->start_usec, perfp->stop_usec, time_taken, perfp->total_usec, perfp->max_usec); } else { ib_log_debug(ib, "Connection based perf_info is NULL"); } IB_FTRACE_RET_STATUS(IB_OK); }
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); ib_status_t rc; size_t p1_len = strlen(p1); size_t p1_unescaped_len; char *p1_unescaped = malloc(p1_len+1); 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_log_debug(cp->ib, msg, p1); free(p1_unescaped); return rc; } if (geoip_db != NULL) { GeoIP_delete(geoip_db); geoip_db = NULL; } geoip_db = GeoIP_open(p1_unescaped, GEOIP_MMAP_CACHE); free(p1_unescaped); if (geoip_db == NULL) { return IB_EUNKNOWN; } return IB_OK; }
/* Called to initialize a module (on load). */ static ib_status_t sqltfn_init(ib_engine_t *ib, ib_module_t *m, void *cbdata) { ib_status_t rc; ib_log_debug(ib, "Initializing %s module.", MODULE_NAME_STR); rc = ib_tfn_register(ib, "normalizeSqlPg", sqltfn_normalize_pg_tfn, IB_TFN_FLAG_NONE, NULL); if (rc != IB_OK) { return rc; } return IB_OK; }
/** * Match against the Radix tree * * @param mpi provider instance * @param flags extra flags * @param data the data to search in * @param dlen length of the the data to search in * @param ctx it will be used to return user data * * @return status of the operation */ static ib_status_t modradix_match(ib_provider_inst_t *mpi, ib_flags_t flags, const uint8_t *data, size_t dlen, void *ctx) { IB_FTRACE_INIT(modradix_match); ib_status_t rc; modradix_provider_data_t *dt = mpi->data; if (dt == NULL) { IB_FTRACE_RET_STATUS(IB_EINVAL); } ib_log_debug(mpi->pr->ib, 4, "Matching AGAINST Radix tree %x", dt->radix_tree); ib_radix_t *radix_tree = dt->radix_tree; ib_radix_prefix_t *pre = NULL; rc = ib_radix_ip_to_prefix((const char *)data, &pre, mpi->mp); if (rc != IB_OK) { IB_FTRACE_RET_STATUS(rc); } void *result = NULL; rc = ib_radix_match_closest(radix_tree, pre, &result); if (rc == IB_OK) { modradix_content_t *mrc = (modradix_content_t *)result; if (mrc->callback != NULL && mrc->data != NULL) { *(void **)ctx = result; IB_FTRACE_RET_STATUS(mrc->callback(mrc->data)); } else if (mrc->data != NULL) { if (ctx!= NULL) { *(void **)ctx = result; } IB_FTRACE_RET_STATUS(IB_OK); } else { IB_FTRACE_RET_STATUS(IB_ENOENT); } } IB_FTRACE_RET_STATUS(rc); }
/* Called when module is unloaded. */ static ib_status_t geoip_fini(ib_engine_t *ib, ib_module_t *m, void *cbdata) { assert(ib != NULL); assert(m != NULL); assert(m->data != NULL); module_data_t *mod_data = (module_data_t *)m->data; if (mod_data->geoip_db != NULL) { GeoIP_delete(mod_data->geoip_db); mod_data->geoip_db = NULL; } ib_log_debug(ib, "GeoIP module unloaded."); return IB_OK; }
/** * Match against the BinRadix tree considering data as a binary IP address * This is the main difference with the other radix matcher (where data is * considered ascii) * * @param mpi provider instance * @param flags extra flags * @param data the data to search in * @param dlen length of the the data to search in * * @return status of the operation */ static ib_status_t modbinradix_match(ib_provider_inst_t *mpi, ib_flags_t flags, const uint8_t *data, size_t dlen, void *ctx) { IB_FTRACE_INIT(); ib_status_t rc; modbinradix_provider_data_t *dt = mpi->data; if (dt == NULL) { IB_FTRACE_RET_STATUS(IB_EINVAL); } ib_log_debug(mpi->pr->ib, "Matching AGAINST BinRadix tree %x", dt->binradix_tree); ib_radix_t *binradix_tree = dt->binradix_tree; ib_radix_prefix_t *pre = NULL; /* Create the prefix directly. Data should be a binary ip address already */ rc = ib_radix_prefix_create(&pre, (uint8_t *)data, (uint8_t)dlen * 8, mpi->mp); if (rc != IB_OK) { IB_FTRACE_RET_STATUS(rc); } void *result = NULL; rc = ib_radix_match_closest(binradix_tree, pre, &result); if (rc == IB_OK) { modbinradix_content_t *mrc = (modbinradix_content_t *)result; if (mrc->callback != NULL && mrc->data != NULL) { *(void **)ctx = result; IB_FTRACE_RET_STATUS(mrc->callback(mrc->data)); } else if (mrc->data != NULL) { *(void **)ctx = result; IB_FTRACE_RET_STATUS(IB_OK); } else { IB_FTRACE_RET_STATUS(IB_ENOENT); } } IB_FTRACE_RET_STATUS(rc); }
/** * Add a prefix to the prefixes of the binradix, given a prefix and * callback + extra arg * * @param mpr matcher provider * @param prefixes pointer to the prefix container (i.e.: an BinRadix tree) * @param prefix the prefix to be added * @param callback the callback to register with the given prefix * @param arg the extra argument to pass to the callback * @param errptr a pointer reference to point where an error occurred * @param erroffset a pointer holding the offset of the error * * @return status of the operation */ static ib_status_t modbinradix_add_prefix_ex(ib_provider_inst_t *mpi, void *prefixes, const char *prefix, ib_void_fn_t callback, void *arg, const char **errptr, int *erroffset) { IB_FTRACE_INIT(); ib_status_t rc; ib_radix_t *binradix_tree = (ib_radix_t *)mpi->data; modbinradix_content_t *mrc = NULL; mrc = (modbinradix_content_t *)ib_mpool_calloc(mpi->pr->mp, 1, sizeof(modbinradix_content_t)); if (mrc == NULL) { ib_log_error(mpi->pr->ib, "Failed to allocate modbinradix_content_t" " for %s to the BinRadix tree %x", prefix, binradix_tree); IB_FTRACE_RET_STATUS(IB_EALLOC); } mrc->data = arg; mrc->callback = (modbinradix_callback_t)callback; ib_radix_prefix_t *pre = NULL; rc = ib_radix_ip_to_prefix(prefix, &pre, mpi->mp); if (rc != IB_OK) { ib_log_error(mpi->pr->ib, "Failed to create a binradix prefix for %s" " to the BinRadix tree %x", prefix, binradix_tree); IB_FTRACE_RET_STATUS(rc); } rc = ib_radix_insert_data(binradix_tree, pre, (void *) mrc); if (rc == IB_OK) { ib_log_debug(mpi->pr->ib, "prefix %s added to the BinRadix tree %x", prefix, binradix_tree); } else { ib_log_error(mpi->pr->ib, "Failed to load prefix %s to the BinRadix " "tree %x", prefix, binradix_tree); } IB_FTRACE_RET_STATUS(rc); }
/** * Called to initialize the user agent module (when the module is loaded). * * Registers a handler for the request_header_finished_event event. * * @param[in,out] ib IronBee object * @param[in] m Module object * @param[in] cbdata (unused) * * @returns Status code */ static ib_status_t modua_init(ib_engine_t *ib, ib_module_t *m, void *cbdata) { IB_FTRACE_INIT(); ib_status_t rc; modua_match_rule_t *failed_rule; unsigned int failed_frule_num; /* Register the user agent callback */ rc = ib_hook_tx_register(ib, request_header_finished_event, modua_user_agent, NULL); if (rc != IB_OK) { ib_log_error(ib, "Hook register returned %s", ib_status_to_string(rc)); } /* Register the remote address callback */ rc = ib_hook_tx_register(ib, request_header_finished_event, modua_remoteip, NULL); if (rc != IB_OK) { ib_log_error(ib, "Hook register returned %s", ib_status_to_string(rc)); } /* Initializations */ rc = modua_ruleset_init(&failed_rule, &failed_frule_num); if (rc != IB_OK) { ib_log_error(ib, "User agent rule initialization failed" " on rule %s field rule #%d: %s", failed_rule->label, failed_frule_num, ib_status_to_string(rc)); } /* Get the rules */ modua_match_ruleset = modua_ruleset_get( ); if (modua_match_ruleset == NULL) { ib_log_error(ib, "Failed to get user agent rule list: %s", ib_status_to_string(rc)); IB_FTRACE_RET_STATUS(rc); } ib_log_debug(ib, "Found %d match rules", modua_match_ruleset->num_rules); IB_FTRACE_RET_STATUS(IB_OK); }
ib_status_t ib_cfgparser_context_push(ib_cfgparser_t *cp, ib_context_t *ctx) { IB_FTRACE_INIT(ib_cfgparser_context_push); ib_engine_t *ib = cp->ib; ib_status_t rc; rc = ib_list_push(cp->stack, ctx); if (rc != IB_OK) { ib_log_error(ib, 4, "Failed to push context %p: %d", ctx, rc); IB_FTRACE_RET_STATUS(rc); } cfgp_set_current(cp, ctx); ib_log_debug(ib, 9, "Stack: ctx=%p site=%p(%s) loc=%p(%s)", cp->cur_ctx, cp->cur_site, cp->cur_site?cp->cur_site->name:"NONE", cp->cur_loc, cp->cur_loc?cp->cur_loc->path:"/"); IB_FTRACE_RET_STATUS(IB_OK); }
/** * @internal * Handle a PocSigTrace directive. * * @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 pocsig_dir_trace(ib_cfgparser_t *cp, const char *name, const char *p1, void *cbdata) { IB_FTRACE_INIT(pocsig_dir_trace); ib_engine_t *ib = cp->ib; ib_context_t *ctx = cp->cur_ctx ? cp->cur_ctx : ib_context_main(ib); ib_status_t rc; ib_log_debug(ib, 7, "%s: \"%s\" ctx=%p", name, p1, ctx); if (strcasecmp("On", p1) == 0) { rc = ib_context_set_num(ctx, MODULE_NAME_STR ".trace", 1); IB_FTRACE_RET_STATUS(rc); } else if (strcasecmp("Off", p1) == 0) { rc = ib_context_set_num(ctx, MODULE_NAME_STR ".trace", 0); IB_FTRACE_RET_STATUS(rc); } ib_log_error(ib, 1, "Failed to parse directive: %s \"%s\"", name, p1); IB_FTRACE_RET_STATUS(IB_EINVAL); }
/** * Add a pattern to the patterns of the matcher given a pattern and * callback + extra arg * * @param mpr matcher provider * @param patterns pointer to the pattern container (ie: an AC tree) * @param patt the pattern to be added * @param callback the callback to register with the given pattern * @param arg the extra argument to pass to the callback * @param errptr a pointer reference to point where an error ocur * @param erroffset a pointer holding the offset of the error * * @return status of the operation */ static ib_status_t modac_add_pattern_ex(ib_provider_inst_t *mpi, void *patterns, const char *patt, ib_void_fn_t callback, void *arg, const char **errptr, int *erroffset) { IB_FTRACE_INIT(modac_add_pattern_ex); ib_status_t rc; ib_ac_t *ac_tree = (ib_ac_t *)((modac_provider_data_t*)mpi->data)->ac_tree; /* If the ac_tree doesn't exist, create it before adding the pattern */ if (ac_tree == NULL) { rc = ib_ac_create(&ac_tree, 0, mpi->mp); if (rc != IB_OK || ac_tree == NULL) { ib_log_error(mpi->pr->ib, 4, "Unable to create the AC tree at modac"); IB_FTRACE_RET_STATUS(rc); } ((modac_provider_data_t*)mpi->data)->ac_tree = ac_tree; } rc = ib_ac_add_pattern(ac_tree, patt, (ib_ac_callback_t)callback, arg, 0); if (rc == IB_OK) { ib_log_debug(mpi->pr->ib, 4, "pattern %s added to the AC tree %x", patt, ac_tree); } else { ib_log_error(mpi->pr->ib, 4, "Failed to load pattern %s to the AC tree %x", patt, ac_tree); } IB_FTRACE_RET_STATUS(rc); }
/* Called when module is loaded. */ static ib_status_t geoip_init(ib_engine_t *ib, ib_module_t *m, void *cbdata) { IB_FTRACE_INIT(); ib_status_t rc; if (geoip_db == NULL) { ib_log_debug(ib, "Initializing default GeoIP database..."); geoip_db = GeoIP_new(GEOIP_MMAP_CACHE); } if (geoip_db == NULL) { ib_log_debug(ib, "Failed to initialize GeoIP database."); IB_FTRACE_RET_STATUS(IB_EUNKNOWN); } ib_log_debug(ib, "Initializing GeoIP database complete."); ib_log_debug(ib, "Registering handler..."); rc = ib_hook_tx_register(ib, handle_context_tx_event, geoip_lookup, NULL); ib_log_debug(ib, "Done registering handler."); if (rc != IB_OK) { ib_log_debug(ib, "Failed to load GeoIP module."); IB_FTRACE_RET_STATUS(rc); } ib_log_debug(ib, "GeoIP module loaded."); IB_FTRACE_RET_STATUS(IB_OK); }