Exemple #1
0
/**
 * Handle request_header events for user agent extraction.
 *
 * Extract the "request_headers" field (a list) from the transactions's
 * data provider instance, then loop through the list, looking for the
 * "User-Agent"  field.  If found, the value is parsed and used to update the
 * connection object fields.
 *
 * @param[in] ib IronBee object
 * @param[in,out] tx Transaction.
 * @param[in] event Event type
 * @param[in] data Callback data (not used)
 *
 * @returns Status code
 */
static ib_status_t modua_user_agent(ib_engine_t *ib,
                                    ib_tx_t *tx,
                                    ib_state_event_type_t event,
                                    void *data)
{
    assert(ib != NULL);
    assert(tx != NULL);
    assert(tx->data != NULL);
    assert(event == request_header_finished_event);

    ib_field_t         *req_agent = NULL;
    ib_status_t         rc = IB_OK;
    const ib_list_t *bs_list;
    const ib_bytestr_t *bs;

    /* Extract the User-Agent header field from the provider instance */
    rc = ib_data_get(tx->data, "request_headers:User-Agent", &req_agent);
    if ( (req_agent == NULL) || (rc != IB_OK) ) {
        ib_log_debug_tx(tx, "request_header_finished_event: No user agent");
        return IB_OK;
    }

    if (req_agent->type != IB_FTYPE_LIST) {
        ib_log_error_tx(tx,
                        "Expected request_headers:User-Agent to "
                        "return list of values.");
        return IB_EINVAL;
    }

    rc = ib_field_value_type(req_agent,
                             ib_ftype_list_out(&bs_list),
                             IB_FTYPE_LIST);
    if (rc != IB_OK) {
        ib_log_error_tx(tx,
                        "Cannot retrieve request_headers:User-Agent: %d",
                        rc);
        return rc;
    }

    if (IB_LIST_ELEMENTS(bs_list) == 0) {
        ib_log_debug_tx(tx, "request_header_finished_event: No user agent");
        return IB_OK;
    }

    req_agent = (ib_field_t *)IB_LIST_NODE_DATA(IB_LIST_LAST(bs_list));

    /* Found it: copy the data into a newly allocated string buffer */
    rc = ib_field_value_type(req_agent,
                             ib_ftype_bytestr_out(&bs),
                             IB_FTYPE_BYTESTR);
    if (rc != IB_OK) {
        ib_log_error_tx(tx, "Request user agent is not a BYTESTR: %s",
                        ib_status_to_string(rc));
        return rc;
    }

    /* Finally, split it up & store the components */
    rc = modua_agent_fields(ib, tx, bs);
    return rc;
}
Exemple #2
0
 //! Iterator just past end of list.
 iterator end() const
 {
     if (IB_LIST_ELEMENTS(ib()) == 0) {
         return begin();
     }
     else {
         return boost::next(iterator(IB_LIST_LAST(ib())));
     }
 }
// 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);
}
Exemple #4
0
ib_status_t ib_stream_push_sdata(ib_stream_t *s,
                                 ib_sdata_t *sdata)
{
    IB_FTRACE_INIT();

    s->slen += sdata->dlen;

    if (IB_LIST_ELEMENTS(s) == 0) {
        IB_LIST_NODE_INSERT_INITIAL(s, sdata);
        IB_FTRACE_RET_STATUS(IB_OK);
    }

    IB_LIST_NODE_INSERT_LAST(s, sdata, ib_sdata_t);

    IB_FTRACE_RET_STATUS(IB_OK);
}
Exemple #5
0
const char *ib_field_format(
    const ib_field_t  *field,
    bool               quote,
    bool               escape,
    const char       **type_name,
    char              *buf,
    size_t             bufsize
)
{
    ib_status_t rc;
    const char *tname = NULL;

    assert(buf != NULL);
    assert(bufsize > 0);

    *buf = '\0';
    if (field == NULL) {
        tname = "NULL";
        if (quote) {
            strncpy(buf, "\"\"", bufsize-1);
            *(buf+bufsize) = '\0';
        }
        else {
            *buf = '\0';
        }
    }
    else {
        switch (field->type) {

        case IB_FTYPE_NULSTR :
        {
            const char *s;
            tname = "NULSTR";
            rc = ib_field_value(field, ib_ftype_nulstr_out(&s));
            if (rc != IB_OK) {
                break;
            }
            if (escape) {
                ib_string_escape_json_buf(s, quote, buf, bufsize, NULL, NULL);
            }
            else if (quote) {
                snprintf(buf, bufsize, "\"%s\"", (s?s:""));
            }
            else {
                strncpy(buf, s, bufsize-1);
                *(buf+bufsize-1) = '\0';
            }
            break;
        }

        case IB_FTYPE_BYTESTR:
        {
            const ib_bytestr_t *bs;

            tname = "BYTESTR";
            rc = ib_field_value(field, ib_ftype_bytestr_out(&bs));
            if (rc != IB_OK) {
                break;
            }

            if (escape) {
                ib_string_escape_json_buf_ex(ib_bytestr_const_ptr(bs),
                                             ib_bytestr_length(bs),
                                             true,
                                             quote,
                                             buf, bufsize, NULL,
                                             NULL);
            }
            else if (quote) {
                snprintf(buf, bufsize, "\"%.*s\"",
                         (int)ib_bytestr_length(bs),
                         (const char *)ib_bytestr_const_ptr(bs));
            }
            else {
                size_t len = ib_bytestr_length(bs);
                if (len > (bufsize - 1) ) {
                    len = bufsize - 1;
                }
                strncpy(buf, (const char *)ib_bytestr_const_ptr(bs), len);
                *(buf+len) = '\0';
            }
            break;
        }

        case IB_FTYPE_NUM :          /**< Numeric value */
        {
            ib_num_t n;
            tname = "NUM";
            rc = ib_field_value(field, ib_ftype_num_out(&n));
            if (rc != IB_OK) {
                break;
            }
            snprintf(buf, bufsize, "%"PRId64, n);
            break;
        }

        case IB_FTYPE_FLOAT :        /**< Float numeric value */
        {
            ib_float_t f;
            tname = "FLOAT";
            rc = ib_field_value(field, ib_ftype_float_out(&f));
            if (rc != IB_OK) {
                break;
            }
            snprintf(buf, bufsize, "%Lf", f);
            break;
        }

        case IB_FTYPE_LIST :         /**< List */
        {
            const ib_list_t *lst;
            size_t len;

            tname = "LIST";
            rc = ib_field_value(field, ib_ftype_list_out(&lst));
            if (rc != IB_OK) {
                break;
            }
            len = IB_LIST_ELEMENTS(lst);
            if (len == 0) {
                snprintf(buf, bufsize, "list[%zd]", len);
            }
            else {
                const ib_list_node_t *node;
                node = ib_list_last_const(lst);
                if (node == NULL) {
                    snprintf(buf, bufsize, "list[%zd]", len);
                }
                else {
                    ib_field_format((const ib_field_t *)node->data,
                                    quote, escape,
                                    &tname, buf, bufsize);
                }
            }
            break;
        }

        default:
            tname = buf;
            snprintf(buf, bufsize, "type = %d", field->type);
            break;
        }
    }

    /* Store the type name */
    if (type_name != NULL) {
        *type_name = tname;
    }

    /* Return the buffer */
    return buf;
}
Exemple #6
0
/**
 * Handle request_header events for user agent extraction.
 *
 * Extract the "request_headers" field (a list) from the transactions's
 * data provider instance, then loop through the list, looking for the
 * "User-Agent"  field.  If found, the value is parsed and used to update the
 * connection object fields.
 *
 * @param[in] ib IronBee object
 * @param[in,out] tx Transaction.
 * @param[in] event Event type
 * @param[in] data Callback data (module)
 *
 * @returns Status code
 */
static ib_status_t modua_user_agent(ib_engine_t *ib,
                                    ib_tx_t *tx,
                                    ib_state_event_type_t event,
                                    void *data)
{
    assert(ib != NULL);
    assert(tx != NULL);
    assert(tx->var_store != NULL);
    assert(event == request_header_finished_event);
    assert(data != NULL);

    const ib_module_t *m = (const ib_module_t *)data;
    const ib_field_t  *req_agent = NULL;
    ib_status_t         rc = IB_OK;
    const ib_list_t *bs_list;
    const ib_bytestr_t *bs;
    const modua_config_t *cfg;

    rc = ib_context_module_config(ib_context_main(ib), m, &cfg);
    if (rc != IB_OK) {
        ib_log_error_tx(tx, "Can't fetch configuration: %s",
                        ib_status_to_string(rc));
        return rc;
    }

    /* Extract the User-Agent header field */
    rc = ib_var_target_get_const(
        cfg->user_agent,
        &bs_list,
        tx->mp,
        tx->var_store
    );
    if (rc == IB_ENOENT || ib_list_elements(bs_list) == 0) {
        ib_log_debug_tx(tx, "request_header_finished_event: No user agent");
        return IB_OK;
    }
    if (rc != IB_OK) {
        ib_log_error_tx(tx,
                        "Cannot retrieve request_headers:User-Agent: %d",
                        rc);
        return rc;
    }

    if (IB_LIST_ELEMENTS(bs_list) == 0) {
        ib_log_debug_tx(tx, "request_header_finished_event: No user agent");
        return IB_OK;
    }

    req_agent = (ib_field_t *)IB_LIST_NODE_DATA(IB_LIST_LAST(bs_list));

    /* Found it: copy the data into a newly allocated string buffer */
    rc = ib_field_value_type(req_agent,
                             ib_ftype_bytestr_out(&bs),
                             IB_FTYPE_BYTESTR);
    if (rc != IB_OK) {
        ib_log_error_tx(tx, "Request user agent is not a BYTESTR: %s",
                        ib_status_to_string(rc));
        return rc;
    }

    /* Finally, split it up & store the components */
    rc = modua_agent_fields(ib, tx, bs);
    return rc;
}