Пример #1
0
// Test pattern matching a field.
TEST(TestIronBee, test_data_pcre)
{
    ib_engine_t *ib;
    ib_data_config_t *dataconfig;
    ib_data_t *data;
    ib_field_t *list_field;
    ib_field_t *out_field;
    ib_list_t *list;
    ib_list_t *out_list;
    ib_field_t *field1;
    ib_field_t *field2;
    ib_field_t *field3;
    ib_num_t num1 = 1;
    ib_num_t num2 = 2;
    ib_num_t num3 = 3;

    ibtest_engine_create(&ib);

    ASSERT_EQ(IB_OK, ib_data_config_create(ib_engine_pool_main_get(ib), & dataconfig));
    ASSERT_EQ(IB_OK, ib_data_create(dataconfig, ib_engine_pool_main_get(ib), &data));
    ASSERT_TRUE(data);

    ASSERT_IB_OK(
        ib_field_create(&field1, ib_data_pool(data), "field1", 6, IB_FTYPE_NUM, &num1));
    ASSERT_IB_OK(
        ib_field_create(&field2, ib_data_pool(data), "field2", 6, IB_FTYPE_NUM, &num2));
    ASSERT_IB_OK(
        ib_field_create(&field3, ib_data_pool(data), "field3", 6, IB_FTYPE_NUM, &num3));
    ASSERT_IB_OK(ib_data_add_list(data, "ARGV", &list_field));
    ASSERT_IB_OK(ib_data_get(data, "ARGV", &out_field));

    ASSERT_IB_OK(ib_field_value(list_field, &list));
    ASSERT_IB_OK(ib_list_push(list, field1));
    ASSERT_IB_OK(ib_list_push(list, field2));
    ASSERT_IB_OK(ib_list_push(list, field3));

    ASSERT_IB_OK(ib_data_get(data, "ARGV:/.*(1|3)/", &out_field));

    ASSERT_IB_OK(ib_field_value(out_field, &out_list));
    ASSERT_NE(list, out_list); /* Make sure it's a different list. */

    ASSERT_EQ(2U, IB_LIST_ELEMENTS(out_list));

    out_field = (ib_field_t *) IB_LIST_FIRST(out_list)->data;
    ASSERT_FALSE(memcmp(out_field->name, field1->name, field1->nlen));

    out_field = (ib_field_t *) IB_LIST_LAST(out_list)->data;
    ASSERT_FALSE(memcmp(out_field->name, field3->name, field3->nlen));

    ibtest_engine_destroy(ib);
}
Пример #2
0
TEST(TestIronBee, test_data_name)
{
    ib_engine_t *ib = NULL;
    ib_data_t *data = NULL;
    ib_field_t *list_field = NULL;
    ib_field_t *out_field = NULL;

    ibtest_engine_create(&ib);

    ASSERT_EQ(IB_OK, ib_data_create(ib_engine_pool_main_get(ib), &data));
    ASSERT_TRUE(data);

    ASSERT_IB_OK(ib_data_add_list(data, "ARGV", &list_field));
    ASSERT_IB_OK(ib_data_get(data, "ARGV", &out_field));
    ASSERT_TRUE(out_field);
    out_field = NULL;
    ASSERT_IB_OK(ib_data_get_ex(data, "ARGV:/.*(1|3)/", 4, &out_field));
    ASSERT_TRUE(out_field);
    ibtest_engine_destroy(ib);
}
Пример #3
0
//! Ensure that the given field name exists in tx->dpi.
static ib_status_t ensure_field_exists(ib_engine_t *ib,
                                       ib_tx_t *tx,
                                       const char *field_name)
{
    IB_FTRACE_INIT();

    ib_status_t rc;

    assert(ib!=NULL);
    assert(tx!=NULL);
    assert(tx->dpi!=NULL);
    assert(field_name!=NULL);

    ib_field_t *ib_field;

    rc = ib_data_get(tx->dpi, field_name, &ib_field);

    if (rc == IB_ENOENT) {
        ib_data_add_list(tx->dpi, field_name, NULL);
    }

    IB_FTRACE_RET_STATUS(IB_OK);
}
Пример #4
0
/**
 * Parse the user agent header, splitting into component fields.
 *
 * Attempt to tokenize the user agent string passed in, storing the
 * result in the DPI associated with the transaction.
 *
 * @param[in] ib IronBee object
 * @param[in,out] tx Transaction object
 * @param[in] bs Byte string containing the agent string
 *
 * @returns Status code
 */
static ib_status_t modua_agent_fields(ib_engine_t *ib,
                                      ib_tx_t *tx,
                                      const ib_bytestr_t *bs)
{
    const modua_match_rule_t *rule = NULL;
    ib_field_t               *agent_list = NULL;
    char                     *product = NULL;
    char                     *platform = NULL;
    char                     *extra = NULL;
    char                     *agent;
    char                     *buf;
    size_t                    len;
    ib_status_t               rc;

    /* Get the length of the byte string */
    len = ib_bytestr_length(bs);

    /* Allocate memory for a copy of the string to split up below. */
    buf = (char *)ib_mpool_calloc(tx->mp, 1, len+1);
    if (buf == NULL) {
        ib_log_error_tx(tx,
                        "Failed to allocate %zd bytes for agent string",
                        len+1);
        return IB_EALLOC;
    }

    /* Copy the string out */
    memcpy(buf, ib_bytestr_const_ptr(bs), len);
    buf[len] = '\0';
    ib_log_debug_tx(tx, "Found user agent: '%s'", buf);

    /* Copy the agent string */
    agent = (char *)ib_mpool_strdup(tx->mp, buf);
    if (agent == NULL) {
        ib_log_error_tx(tx, "Failed to allocate copy of agent string");
        return IB_EALLOC;
    }

    /* Parse the user agent string */
    rc = modua_parse_uastring(buf, &product, &platform, &extra);
    if (rc != IB_OK) {
        ib_log_debug_tx(tx, "Failed to parse User Agent string '%s'", agent);
        return IB_OK;
    }

    /* Categorize the parsed string */
    rule = modua_match_cat_rules(product, platform, extra);
    if (rule == NULL) {
        ib_log_debug_tx(tx, "No rule matched" );
    }
    else {
        ib_log_debug_tx(tx, "Matched to rule #%d / category '%s'",
                        rule->rule_num, rule->category );
    }

    /* Build a new list. */
    rc = ib_data_add_list(tx->data, "UA", &agent_list);
    if (rc != IB_OK)
    {
        ib_log_alert_tx(tx, "Unable to add UserAgent list to DPI.");
        return rc;
    }

    /* Store Agent */
    rc = modua_store_field(ib, tx->mp, agent_list, "agent", agent);
    if (rc != IB_OK) {
        return rc;
    }

    /* Store product */
    rc = modua_store_field(ib, tx->mp, agent_list, "PRODUCT", product);
    if (rc != IB_OK) {
        return rc;
    }

    /* Store Platform */
    rc = modua_store_field(ib, tx->mp, agent_list, "OS", platform);
    if (rc != IB_OK) {
        return rc;
    }

    /* Store Extra */
    rc = modua_store_field(ib, tx->mp, agent_list, "extra", extra);
    if (rc != IB_OK) {
        return rc;
    }

    /* Store Extra */
    if (rule != NULL) {
        rc = modua_store_field(ib, tx->mp, agent_list,
                               "category", rule->category);
    }
    else {
        rc = modua_store_field(ib, tx->mp, agent_list, "category", NULL );
    }
    if (rc != IB_OK) {
        return rc;
    }

    /* Done */
    return IB_OK;
}
Пример #5
0
/**
 * Create an alias list collection.
 *
 * @param ib Engine.
 * @param tx Transaction.
 * @param name Collection name
 * @param header Header list to alias
 *
 * @returns Status code
 */
static ib_status_t create_header_alias_list(
    ib_engine_t *ib,
    ib_tx_t *tx,
    const char *name,
    ib_parsed_header_wrapper_t *header)
{
    ib_field_t *f;
    ib_list_t *header_list;
    ib_status_t rc;
    ib_parsed_name_value_pair_list_t *nvpair;

    assert(ib != NULL);
    assert(tx != NULL);
    assert(name != NULL);
    assert(header != NULL);

    /* Create the list */
    rc = ib_data_get(tx->data, name, &f);
    if (rc == IB_ENOENT) {
        rc = ib_data_add_list(tx->data, name, &f);
        if (rc != IB_OK) {
            return rc;
        }
    }
    else if (rc != IB_OK) {
        return rc;
    }
    rc = ib_field_mutable_value(f, ib_ftype_list_mutable_out(&header_list));
    if (rc != IB_OK) {
        return rc;
    }

    /* Loop through the list & alias everything */
    for(nvpair = header->head;  nvpair != NULL;  nvpair = nvpair->next) {
        assert(nvpair);
        assert(nvpair->value);
        ib_bytestr_t *bs = NULL;
        if (ib_bytestr_ptr(nvpair->value) != NULL) {
            rc = ib_bytestr_alias_mem(
                &bs,
                tx->mp,
                ib_bytestr_ptr(nvpair->value),
                ib_bytestr_length(nvpair->value)
            );
        }
        else {
            rc = ib_bytestr_dup_mem(&bs, tx->mp, (const uint8_t *)"", 0);
        }
        if (rc != IB_OK) {
            ib_log_error_tx(
                tx,
                "Error creating bytestring of '%.*s' for %s: %s",
                (int)ib_bytestr_length(nvpair->name),
                (const char *)ib_bytestr_ptr(nvpair->name),
                name,
                ib_status_to_string(rc)
            );
            return rc;
        }

        /* Create a byte string field */
        rc = ib_field_create(
            &f,
            tx->mp,
            (const char *)ib_bytestr_const_ptr(nvpair->name),
            ib_bytestr_length(nvpair->name),
            IB_FTYPE_BYTESTR,
            ib_ftype_bytestr_in(bs)
        );
        if (rc != IB_OK) {
            ib_log_error_tx(tx,
                            "Error creating field of '%.*s' for %s: %s",
                            (int)ib_bytestr_length(nvpair->name),
                            (const char *)ib_bytestr_ptr(nvpair->name),
                            name,
                            ib_status_to_string(rc));
            return rc;
        }

        /* Add the field to the list */
        rc = ib_list_push(header_list, f);
        if (rc != IB_OK) {
            ib_log_error_tx(tx, "Error adding alias of '%.*s' to %s list: %s",
                            (int)ib_bytestr_length(nvpair->name),
                            (const char *)ib_bytestr_ptr(nvpair->name),
                            name,
                            ib_status_to_string(rc));
            return rc;
        }
    }

    return IB_OK;
}
Пример #6
0
// FIXME: This needs to go away and be replaced with dynamic fields
static ib_status_t core_gen_placeholder_fields(ib_engine_t *ib,
                                               ib_tx_t *tx,
                                               ib_state_event_type_t event,
                                               void *cbdata)
{
    assert(ib != NULL);
    assert(tx != NULL);
    assert(tx->data != NULL);
    assert(event == tx_started_event);

    ib_status_t rc;
    ib_field_t *tmp;

    /* Core Request Fields */
    rc = core_field_placeholder_bytestr(tx->data, "request_line");
    if (rc != IB_OK) {
        return rc;
    }

    rc = core_field_placeholder_bytestr(tx->data, "request_method");
    if (rc != IB_OK) {
        return rc;
    }

    rc = core_field_placeholder_bytestr(tx->data, "request_protocol");
    if (rc != IB_OK) {
        return rc;
    }

    rc = core_field_placeholder_bytestr(tx->data, "request_uri");
    if (rc != IB_OK) {
        return rc;
    }

    rc = core_field_placeholder_bytestr(tx->data, "request_uri_raw");
    if (rc != IB_OK) {
        return rc;
    }

    rc = core_field_placeholder_bytestr(tx->data, "request_uri_scheme");
    if (rc != IB_OK) {
        return rc;
    }

    rc = core_field_placeholder_bytestr(tx->data, "request_uri_username");
    if (rc != IB_OK) {
        return rc;
    }

    rc = core_field_placeholder_bytestr(tx->data, "request_uri_password");
    if (rc != IB_OK) {
        return rc;
    }

    rc = core_field_placeholder_bytestr(tx->data, "request_uri_host");
    if (rc != IB_OK) {
        return rc;
    }

    rc = core_field_placeholder_bytestr(tx->data, "request_host");
    if (rc != IB_OK) {
        return rc;
    }

    rc = core_field_placeholder_bytestr(tx->data, "request_uri_port");
    if (rc != IB_OK) {
        return rc;
    }

    rc = core_field_placeholder_bytestr(tx->data, "request_uri_path");
    if (rc != IB_OK) {
        return rc;
    }

    rc = core_field_placeholder_bytestr(tx->data, "request_uri_path_raw");
    if (rc != IB_OK) {
        return rc;
    }

    rc = core_field_placeholder_bytestr(tx->data, "request_uri_query");
    if (rc != IB_OK) {
        return rc;
    }

    rc = core_field_placeholder_bytestr(tx->data, "request_uri_fragment");
    if (rc != IB_OK) {
        return rc;
    }

    rc = core_field_placeholder_bytestr(tx->data, "request_content_type");
    if (rc != IB_OK) {
        return rc;
    }

    rc = core_field_placeholder_bytestr(tx->data, "request_filename");
    if (rc != IB_OK) {
        return rc;
    }

    rc = core_field_placeholder_bytestr(tx->data, "auth_type");
    if (rc != IB_OK) {
        return rc;
    }

    rc = core_field_placeholder_bytestr(tx->data, "auth_username");
    if (rc != IB_OK) {
        return rc;
    }

    rc = core_field_placeholder_bytestr(tx->data, "auth_password");
    if (rc != IB_OK) {
        return rc;
    }

    /* Core Request Collections */
    rc = ib_data_add_list(tx->data, "request_headers", NULL);
    if (rc != IB_OK) {
        return rc;
    }

    rc = ib_data_add_list(tx->data, "request_cookies", NULL);
    if (rc != IB_OK) {
        return rc;
    }

    rc = ib_data_add_list(tx->data, "request_uri_params", NULL);
    if (rc != IB_OK) {
        return rc;
    }

    rc = ib_data_add_list(tx->data, "request_body_params", NULL);
    if (rc != IB_OK) {
        return rc;
    }

    /* ARGS collection */
    rc = ib_data_get(tx->data, "ARGS", &tmp);
    if (rc == IB_ENOENT) {
        rc = ib_data_add_list(tx->data, "ARGS", NULL);
        if (rc != IB_OK) {
            return rc;
        }
    }
    else if (rc != IB_OK) {
        return rc;
    }

    /* Flags collection */
    rc = ib_data_get(tx->data, "FLAGS", &tmp);
    if (rc == IB_ENOENT) {
        rc = ib_data_add_list(tx->data, "FLAGS", NULL);
        if (rc != IB_OK) {
            return rc;
        }
    }
    else if (rc != IB_OK) {
        return rc;
    }

    /* Initialize CAPTURE */
    {
        ib_field_t *capture;
        rc = ib_capture_acquire(tx, NULL, &capture);
        if (rc != IB_OK) {
            return rc;
        }
        assert(capture != NULL);
        rc = ib_capture_clear(capture);
        if (rc != IB_OK) {
            return rc;
        }
    }

    /* Core Response Fields */
    rc = core_field_placeholder_bytestr(tx->data, "response_line");
    if (rc != IB_OK) {
        return rc;
    }

    rc = core_field_placeholder_bytestr(tx->data, "response_protocol");
    if (rc != IB_OK) {
        return rc;
    }

    rc = core_field_placeholder_bytestr(tx->data, "response_status");
    if (rc != IB_OK) {
        return rc;
    }

    rc = core_field_placeholder_bytestr(tx->data, "response_message");
    if (rc != IB_OK) {
        return rc;
    }

    rc = core_field_placeholder_bytestr(tx->data, "response_content_type");
    if (rc != IB_OK) {
        return rc;
    }

    /* Core Response Collections */
    rc = ib_data_add_list(tx->data, "response_headers", NULL);
    if (rc != IB_OK) {
        return rc;
    }

    rc = core_field_placeholder_bytestr(tx->data, "FIELD_NAME");
    if (rc != IB_OK) {
        return rc;
    }
    rc = core_field_placeholder_bytestr(tx->data, "FIELD_NAME_FULL");
    if (rc != IB_OK) {
        return rc;
    }

    rc = ib_data_add_list(tx->data, "response_cookies", NULL);

    return rc;
}
Пример #7
0
static ib_status_t geoip_lookup(
    ib_engine_t *ib,
    ib_tx_t *tx,
    ib_state_event_type_t event,
    void *data
)
{
    const char *ip = tx->er_ipstr;

    if (ip == NULL) {
        ib_log_alert_tx(tx, "Trying to lookup NULL IP in GEOIP");
        return IB_EINVAL;
    }

#ifdef GEOIP_HAVE_VERSION
    /**
     * Some configurations exist as single characters and must be converted to
     * a string. This is simply a place to assemble that string before
     * it is passed into ip_data_add_nulstr.
     * This is only needed if we have support confidence items. WAM
     */
    char one_char_str[2] = { '\0', '\0' };
#endif /* GEOIP_HAVE_VERSION */

    ib_status_t rc;

    /* Declare and initialize the GeoIP property list.
     * Regardless of if we find a record or not, we want to create the list
     * artifact so that later modules know we ran and did [not] find a
     * record. */
    ib_field_t *geoip_lst = NULL;

    ib_field_t *tmp_field = NULL;

    /* Id of geo ip record to read. */
    int geoip_id;

    ib_log_debug_tx(tx, "GeoIP Lookup '%s'", ip);

    /* Build a new list. */
    rc = ib_data_add_list(tx->data, "GEOIP", &geoip_lst);

    /* NOTICE: Called before GeoIP_record_by_addr allocates a
     * GeoIPRecord. */
    if (rc != IB_OK)
    {
        ib_log_alert_tx(tx, "Unable to add GEOIP list to DPI.");
        return IB_EINVAL;
    }

    if (geoip_db == NULL) {
        ib_log_alert_tx(tx,
                        "GeoIP database was never opened. Perhaps the "
                        "configuration file needs a GeoIPDatabaseFile "
                        "\"/usr/share/geoip/GeoLite.dat\" line?");
        return IB_EINVAL;
    }

    geoip_id = GeoIP_id_by_addr(geoip_db, ip);

    if (geoip_id > 0)
    {
        const char *tmp_str;

        ib_log_debug_tx(tx, "GeoIP record found.");

        /* Add integers. */
        tmp_field = NULL;

        tmp_str = GeoIP_code_by_id(geoip_id);
        if (tmp_str)
        {
            ib_field_create(&tmp_field,
                            tx->mp,
                            IB_FIELD_NAME("country_code"),
                            IB_FTYPE_NULSTR,
                            ib_ftype_nulstr_in(tmp_str));
            ib_field_list_add(geoip_lst, tmp_field);
        }

        tmp_str = GeoIP_code3_by_id(geoip_id);
        if (tmp_str)
        {
            ib_field_create(&tmp_field,
                            tx->mp,
                            IB_FIELD_NAME("country_code3"),
                            IB_FTYPE_NULSTR,
                            ib_ftype_nulstr_in(tmp_str));
            ib_field_list_add(geoip_lst, tmp_field);
        }

        tmp_str = GeoIP_country_name_by_id(geoip_db, geoip_id);
        if (tmp_str)
        {
            ib_field_create(&tmp_field,
                            tx->mp,
                            IB_FIELD_NAME("country_name"),
                            IB_FTYPE_NULSTR,
                            ib_ftype_nulstr_in(tmp_str));
            ib_field_list_add(geoip_lst, tmp_field);
        }

        tmp_str = GeoIP_continent_by_id(geoip_id);
        if (tmp_str)
        {
            ib_field_create(&tmp_field,
                            tx->mp,
                            IB_FIELD_NAME("continent_code"),
                            IB_FTYPE_NULSTR,
                            ib_ftype_nulstr_in(tmp_str));
            ib_field_list_add(geoip_lst, tmp_field);
        }
    }
    else
    {
        ib_log_debug_tx(tx, "No GeoIP record found.");
        ib_field_create(&tmp_field,
                        tx->mp,
                        IB_FIELD_NAME("country_code"),
                        IB_FTYPE_NULSTR,
                        ib_ftype_nulstr_in("O1"));
        ib_field_list_add(geoip_lst, tmp_field);
        ib_field_create(&tmp_field,
                        tx->mp,
                        IB_FIELD_NAME("country_code3"),
                        IB_FTYPE_NULSTR,
                        ib_ftype_nulstr_in("O01"));
        ib_field_list_add(geoip_lst, tmp_field);
        ib_field_create(&tmp_field,
                        tx->mp,
                        IB_FIELD_NAME("country_name"),
                        IB_FTYPE_NULSTR,
                        ib_ftype_nulstr_in("Other Country"));
        ib_field_list_add(geoip_lst, tmp_field);
        ib_field_create(&tmp_field,
                        tx->mp,
                        IB_FIELD_NAME("continent_code"),
                        IB_FTYPE_NULSTR,
                        ib_ftype_nulstr_in("O1"));
        ib_field_list_add(geoip_lst, tmp_field);
    }

    return IB_OK;
}