TEST_F(XRulesTest, SetFlag) { ib_field_t *field; ib_num_t num; ib_var_target_t *target; const ib_list_t *list; std::string config = std::string( "LogLevel DEBUG\n" "LoadModule \"ibmod_persistence_framework.so\"\n" "LoadModule \"ibmod_init_collection.so\"\n" "LoadModule \"ibmod_xrules.so\"\n" "InitCollection GeoIP vars: country_code=US\n" "SensorId B9C1B52B-C24A-4309-B9F9-0EF4CD577A3E\n" "SensorName UnitTesting\n" "SensorHostname unit-testing.sensor.tld\n" /* Note that both rules should fire and result in a single entry. */ "XRulePath / EnableRequestParamInspection priority=1\n" "XRuleGeo US EnableRequestParamInspection priority=1\n" "<Site test-site>\n" " SiteId AAAABBBB-1111-2222-3333-000000000000\n" " Hostname somesite.com\n" "</Site>\n" ); configureIronBeeByString(config.c_str()); performTx(); ASSERT_TRUE(ib_tx); ASSERT_TRUE(ib_tx->flags & IB_TX_FINSPECT_REQPARAMS); ASSERT_EQ( IB_OK, ib_var_target_acquire_from_string( &target, ib_tx->mp, ib_var_store_config(ib_tx->var_store), "FLAGS:inspectRequestParams", strlen("FLAGS:inspectRequestParams"), NULL, NULL) ); ASSERT_EQ( IB_OK, ib_var_target_get_const( target, &list, ib_tx->mp, ib_tx->var_store) ); ASSERT_EQ(1U, ib_list_elements(list)); field = (ib_field_t *)ib_list_node_data_const(ib_list_first_const(list)); ASSERT_EQ(IB_FTYPE_NUM, field->type); ASSERT_EQ( IB_OK, ib_field_value(field, ib_ftype_num_out(&num)) ); ASSERT_EQ(1, num); }
static ib_status_t cpy_psntsfw_cfg( ib_engine_t *ib, ib_mpool_t *mp, ib_mpool_t *local_mp, const ib_persist_fw_cfg_t *persist_fw_src, ib_persist_fw_cfg_t **persist_fw_dst ) { assert(ib != NULL); assert(mp != NULL); assert(local_mp != NULL); assert(persist_fw_src != NULL); assert(persist_fw_dst != NULL); ib_list_t *list = NULL; ib_list_node_t *list_node; ib_status_t rc; ib_persist_fw_cfg_t *persist_fw_out; rc = ib_persist_fw_cfg_create(mp, &persist_fw_out); if (rc != IB_OK) { ib_log_error(ib, "Failed to create new persist_fw_cfg."); return rc; } rc = ib_list_create(&list, local_mp); if (rc != IB_OK) { return rc; } /* Copy the src store hash to the dst store hash. */ if (ib_hash_size(persist_fw_src->stores) > 0) { rc = ib_hash_get_all(persist_fw_src->stores, list); if (rc != IB_OK) { ib_log_error(ib, "Failed to get entries from hash."); return rc; } IB_LIST_LOOP(list, list_node) { ib_persist_fw_store_t *store = (ib_persist_fw_store_t *)ib_list_node_data_const(list_node); rc = ib_hash_set(persist_fw_out->stores, store->name, store); if (rc != IB_OK) { ib_log_error(ib, "Failed to set store %s", store->name); return rc; } }
ib_status_t ib_tfn_execute( ib_mpool_t *mp, const ib_tfn_t *tfn, const ib_field_t *fin, const ib_field_t **fout ) { assert(mp != NULL); assert(tfn != NULL); assert(fin != NULL); assert(fout != NULL); ib_status_t rc; const ib_field_t *out = NULL; if (fin->type == IB_FTYPE_LIST && ! ib_tfn_handle_list(tfn)) { /* Unroll list */ const ib_list_t *value_list; const ib_list_node_t *node; ib_list_t *out_list; ib_field_t *fnew; rc = ib_field_value(fin, ib_ftype_list_out(&value_list)); if (rc != IB_OK) { return rc; } rc = ib_list_create(&out_list, mp); if (rc != IB_OK) { return rc; } IB_LIST_LOOP_CONST(value_list, node) { const ib_field_t *in; const ib_field_t *tfn_out; in = (const ib_field_t *)ib_list_node_data_const(node); assert(in != NULL); rc = ib_tfn_execute(mp, tfn, in, &tfn_out); if (rc != IB_OK) { return rc; } if (tfn_out == NULL) { return IB_EINVAL; } rc = ib_list_push(out_list, (void *)tfn_out); if (rc != IB_OK) { return rc; } } /* Finally, create the output field (list) and return it */ rc = ib_field_create(&fnew, mp, fin->name, fin->nlen, IB_FTYPE_LIST, ib_ftype_list_in(out_list)); if (rc != IB_OK) { return rc; } out = fnew; } else {
/** * Join a field with strings before and after it * * @param[in] mp Memory pool * @param[in] f Field to join * @param[in] iptr Pointer to initial string * @param[in] ilen Length of @a iptr * @param[in] fptr Pointer to final string * @param[in] flen Length of @a fptr * @param[in] nul true if NUL byte should be tacked on, false if not * @param[out] out Pointer to output block * @param[out] olen Length of the output block * * @returns status code */ static ib_status_t join_parts(ib_mpool_t *mp, const ib_field_t *f, const char *iptr, size_t ilen, const char *fptr, size_t flen, bool nul, char **out, size_t *olen) { IB_FTRACE_INIT(); ib_status_t rc; char numbuf[NUM_BUF_LEN+1]; /* Buffer used to convert number to str */ assert(NUM_BUF_LEN <= 256); switch(f->type) { case IB_FTYPE_NULSTR: { /* Field is a NUL-terminated string */ const char *s; rc = ib_field_value(f, ib_ftype_nulstr_out(&s)); if (rc != IB_OK) { IB_FTRACE_RET_STATUS(rc); } size_t slen = strlen(s); rc = join3(mp, iptr, ilen, s, slen, fptr, flen, nul, out, olen); break; } case IB_FTYPE_BYTESTR: { /* Field is a byte string */ const ib_bytestr_t *bs; rc = ib_field_value(f, ib_ftype_bytestr_out(&bs)); if (rc != IB_OK) { IB_FTRACE_RET_STATUS(rc); } rc = join3(mp, iptr, ilen, (const char *)ib_bytestr_const_ptr(bs), ib_bytestr_length(bs), fptr, flen, nul, out, olen); break; } case IB_FTYPE_NUM: { /* Field is a number; convert it to a string */ ib_num_t n; rc = ib_field_value(f, ib_ftype_num_out(&n)); if (rc != IB_OK) { IB_FTRACE_RET_STATUS(rc); } snprintf(numbuf, NUM_BUF_LEN, "%"PRId64, n); rc = join3(mp, iptr, ilen, numbuf, strlen(numbuf), fptr, flen, nul, out, olen); break; } case IB_FTYPE_UNUM: { /* Field is an unsigned number; convert it to a string */ ib_unum_t n; rc = ib_field_value(f, ib_ftype_unum_out(&n)); if (rc != IB_OK) { IB_FTRACE_RET_STATUS(rc); } snprintf(numbuf, NUM_BUF_LEN, "%"PRIu64, n); rc = join3(mp, iptr, ilen, numbuf, strlen(numbuf), fptr, flen, nul, out, olen); break; } case IB_FTYPE_LIST: { /* Field is a list: use the first element in the list */ const ib_list_t *list; const ib_list_node_t *node; const ib_field_t *element; rc = ib_field_value(f, ib_ftype_list_out(&list)); if (rc != IB_OK) { IB_FTRACE_RET_STATUS(rc); } node = ib_list_first_const(list); if (node == NULL) { rc = join2(mp, iptr, ilen, fptr, flen, nul, out, olen); break; } element = (const ib_field_t *)ib_list_node_data_const(node); rc = join_parts(mp, element, iptr, ilen, fptr, flen, nul, out, olen); break; } default: /* Something else: replace with "" */ rc = join2(mp, iptr, ilen, fptr, flen, nul, out, olen); break; } IB_FTRACE_RET_STATUS(rc); }
ib_status_t ib_string_join( const char *join_string, ib_list_t *list, ib_mm_t mm, const char **pout, size_t *pout_len ) { assert(join_string != NULL); assert(list != NULL); assert(pout != NULL); assert(pout_len != NULL); const ib_list_node_t *node; char *end; /* Points to the \0 in out. */ const char *out; size_t out_len = 1; /* Size to hold an empty string, '\0' */ size_t *str_len; /* Array of lengths of char*s in list. */ size_t str_idx; /* Index into str_len. */ size_t join_string_len; join_string_len = strlen(join_string); /* Handle the base-case and avoid asking for size 0 memory segments. */ if (ib_list_elements(list) == 0) { *pout = ""; *pout_len = 0; return IB_OK; } /* First, build a place to cache string lengths. */ str_len = ib_mm_alloc(mm, sizeof(*str_len) * ib_list_elements(list)); if (str_len == NULL) { return IB_EALLOC; } /* Record each string length and sum those lengths into out_len. * Recall that out_len starts equal to 1 for the '\0'. */ str_idx = 0; IB_LIST_LOOP_CONST(list, node) { const size_t len = strlen((const char *)ib_list_node_data_const(node)); out_len += len; str_len[str_idx] = len; ++str_idx; } /* Increase out_len by the join string length * (n-1) elements. */ out_len += (ib_list_elements(list) - 1)* join_string_len; /* Allocate the final string. */ end = ib_mm_alloc(mm, out_len); if (end == NULL) { return IB_EALLOC; } /* Setup vars for joining the strings into out. */ out = end; str_idx = 0; node = ib_list_first(list); /* Copy the first string. We know the list is > 0 elements long. */ strcpy(end, (const char *)ib_list_node_data_const(node)); end += str_len[str_idx]; ++str_idx; /* Having copied the first string, now copy the join string, then the * the next string until the end of the list. */ for ( node = ib_list_node_next_const(node); node != NULL; node = ib_list_node_next_const(node) ) { /* Copy the join string first. */ strcpy(end, join_string); end += join_string_len; /* Copy the lagging string. */ strcpy(end, (const char *)ib_list_node_data_const(node)); end += str_len[str_idx]; ++str_idx; } /* Commit work back to the caller. */ *pout = out; *pout_len = out_len-1; return IB_OK; }
/** * Feed a collection of byte strings from an @ref ib_data_t to automata. * * @param[in] ib IronBee engine; used for logging. * @param[in] eudoxus Eudoxus engine; used for ia_eudoxus_error(). * @param[in] state Current Eudoxus execution state; updated. * @param[in] data Data source. * @param[in] collection Collection to feed. * @return * - IB_OK on success. * - IB_EINVAL on IronAutomata failure; will emit log message. * - IB_EOTHER on IronBee failure; will emit log message. */ static ib_status_t fast_feed_data_collection( const ib_engine_t *ib, const ia_eudoxus_t *eudoxus, ia_eudoxus_state_t *state, const ib_data_t *data, const fast_collection_spec_t *collection ) { assert(ib != NULL); assert(eudoxus != NULL); assert(state != NULL); assert(data != NULL); assert(collection != NULL); ib_field_t *field; const ib_list_t *subfields; const ib_list_node_t *node; const ib_field_t *subfield; const ib_bytestr_t *bs; ib_status_t rc; rc = ib_data_get(data, collection->name, &field); if (rc == IB_ENOENT) { ib_log_error( ib, "fast: No such data %s", collection->name ); return IB_EOTHER; } else if (rc != IB_OK) { ib_log_error( ib, "fast: Error fetching data %s: %s", collection->name, ib_status_to_string(rc) ); return IB_EOTHER; } rc = ib_field_value_type( field, ib_ftype_list_out(&subfields), IB_FTYPE_LIST ); if (rc != IB_OK) { ib_log_error( ib, "fast: Error loading data field %s: %s", collection->name, ib_status_to_string(rc) ); return IB_EOTHER; } IB_LIST_LOOP_CONST(subfields, node) { subfield = (const ib_field_t *)ib_list_node_data_const(node); assert(subfield != NULL); rc = ib_field_value_type( subfield, ib_ftype_bytestr_out(&bs), IB_FTYPE_BYTESTR ); if (rc != IB_OK) { ib_log_error( ib, "fast: Error loading data subfield %s of %s: %s", subfield->name, collection->name, ib_status_to_string(rc) ); return IB_EOTHER; } rc = fast_feed( ib, eudoxus, state, (const uint8_t *)subfield->name, subfield->nlen ); if (rc != IB_OK) { return rc; } rc = fast_feed( ib, eudoxus, state, (const uint8_t *)collection->separator, strlen(collection->separator) ); if (rc != IB_OK) { return rc; } if (ib_bytestr_const_ptr(bs) != NULL && ib_bytestr_size(bs) > 0) { rc = fast_feed( ib, eudoxus, state, ib_bytestr_const_ptr(bs), ib_bytestr_size(bs) ); if (rc != IB_OK) { return rc; } } rc = fast_feed( ib, eudoxus, state, (const uint8_t *)c_data_separator, strlen(c_data_separator) ); if (rc != IB_OK) { return rc; } }