Ejemplo n.º 1
0
ib_status_t ib_parsed_headers_add(
    ib_parsed_headers_t *headers,
    const char          *name,
    size_t               name_len,
    const char          *value,
    size_t               value_len
)
{
    ib_status_t rc;

    assert(headers        != NULL);
    assert(name           != NULL);
    assert(value          != NULL);

    ib_parsed_header_t *ele;

    ele = ib_mm_alloc(headers->mm, sizeof(*ele));
    if (ele == NULL) {
        return IB_EALLOC;
    }

    rc = ib_bytestr_dup_mem(
        &ele->name,
        headers->mm,
        (const uint8_t *)name, name_len
    );
    if (rc != IB_OK) {
        return rc;
    }

    rc = ib_bytestr_dup_mem(
        &ele->value,
        headers->mm,
        (const uint8_t *)value, value_len
    );
    if (rc != IB_OK) {
        return rc;
    }

    ele->next = NULL;

    /* List is empty. Add first element. */
    if (headers->head == NULL) {
        headers->head = ele;
        headers->tail = ele;
        headers->size = 1;
    }

    /* Normal append to a list with values in it already. */
    else {
        headers->tail->next = ele;
        headers->tail = ele;
        ++(headers->size);
    }

    return IB_OK;
}
Ejemplo n.º 2
0
ib_status_t ib_parsed_name_value_pair_list_add(
    ib_parsed_name_value_pair_list_wrapper_t *headers,
    const char *name,
    size_t name_len,
    const char *value,
    size_t value_len)
{
    IB_FTRACE_INIT();
    ib_status_t rc;

    assert(headers != NULL);
    assert(headers->mpool != NULL);
    assert(name != NULL);
    assert(value != NULL);

    ib_parsed_name_value_pair_list_t *ele;

    ele = ib_mpool_alloc(headers->mpool, sizeof(*ele));
    if (ele == NULL) {
        IB_FTRACE_RET_STATUS(IB_EALLOC);
    }

    rc = ib_bytestr_dup_mem(&ele->name,
                            headers->mpool,
                            (const uint8_t *)name,
                            name_len);
    if (rc != IB_OK) {
        IB_FTRACE_RET_STATUS(rc);
    }

    rc = ib_bytestr_dup_mem(&ele->value,
                            headers->mpool,
                            (const uint8_t *)value,
                            value_len);
    if (rc != IB_OK) {
        IB_FTRACE_RET_STATUS(rc);
    }

    ele->next = NULL;

    /* List is empty. Add first element. */
    if (headers->head == NULL) {
        headers->head = ele;
        headers->tail = ele;
        headers->size = 1;
    }

    /* Normal append to a list with values in it already. */
    else {
        headers->tail->next = ele;
        headers->tail = ele;
        ++(headers->size);
    }

    IB_FTRACE_RET_STATUS(IB_OK);
}
Ejemplo n.º 3
0
/// @test Test util field library - ib_field_create() ib_field_create()
TEST_F(TestIBUtilField, test_field_create)
{
    ib_field_t *f;
    ib_status_t rc;
    const char *nulstrval = "TestValue";
    ib_num_t numval = 5;
    ib_bytestr_t *bytestrval;
    const char *nulout;
    const char *nulcopy;

    nulcopy = ib_mm_strdup(MM(), nulstrval);
    ASSERT_STRNE(NULL, nulcopy);
    rc = ib_field_create(&f, MM(), IB_S2SL("test_nulstr"),
                         IB_FTYPE_NULSTR, ib_ftype_nulstr_in(nulcopy));
    ASSERT_EQ(IB_OK, rc);
    ASSERT_TRUE(f);
    ASSERT_EQ(11UL, f->nlen);
    ASSERT_EQ(0, memcmp("test_nulstr", f->name, 11));

    rc = ib_field_value(f, ib_ftype_nulstr_out(&nulout));
    ASSERT_EQ(IB_OK, rc);
    ASSERT_STREQ(nulstrval, nulout);

    rc = ib_field_create(&f, MM(), IB_S2SL("test_num"),
                         IB_FTYPE_NUM, ib_ftype_num_in(&numval));
    ASSERT_EQ(IB_OK, rc);
    ASSERT_TRUE(f);
    ASSERT_EQ(8UL, f->nlen);
    ASSERT_EQ(0, memcmp("test_num", f->name, 8));

    rc = ib_bytestr_dup_mem(&bytestrval, MM(),
                            (uint8_t *)nulstrval, strlen(nulstrval));
    ASSERT_EQ(IB_OK, rc);
    ASSERT_TRUE(f);

    rc = ib_field_create(&f, MM(), IB_S2SL("test_bytestr"),
                         IB_FTYPE_BYTESTR, ib_ftype_bytestr_in(bytestrval));
    ASSERT_EQ(IB_OK, rc);
    ASSERT_TRUE(f);
    ASSERT_EQ(12UL, f->nlen);
    ASSERT_EQ(0, memcmp("test_bytestr", f->name, 12));

    rc = ib_field_create(&f, MM(), IB_S2SL("test_nulstr_ex"),
                         IB_FTYPE_NULSTR, ib_ftype_nulstr_in(nulstrval));
    ASSERT_EQ(IB_OK, rc);
    ASSERT_TRUE(f);

    rc = ib_field_create(&f, MM(), IB_S2SL("test_num_ex"),
                         IB_FTYPE_NUM, ib_ftype_num_in(&numval));
    ASSERT_EQ(IB_OK, rc);
    ASSERT_TRUE(f);

    rc = ib_field_create(&f, MM(), IB_S2SL("test_bytestr_ex"),
                         IB_FTYPE_BYTESTR, ib_ftype_bytestr_in(bytestrval));
    ASSERT_EQ(IB_OK, rc);
    ASSERT_TRUE(f);
}
Ejemplo n.º 4
0
Archivo: pcre.c Proyecto: niubl/ironbee
/**
 * Set the matches from a multi-match dfa as a list in the CAPTURE
 * collection (all with "0" key).
 *
 * @param[in] tx Current transaction.
 * @param[in] capture Collection to capture to.
 * @param[in] ovector The vector of integer pairs of matches from PCRE.
 * @param[in] matches The number of matches.
 * @param[in] subject The matched-against string data.
 *
 * @returns IB_OK or IB_EALLOC.
 */
static
ib_status_t pcre_dfa_set_match(
    ib_tx_t    *tx,
    ib_field_t *capture,
    int        *ovector,
    int         matches,
    const char *subject
)
{
    assert(tx != NULL);
    assert(tx->ib != NULL);
    assert(capture != NULL);
    assert(ovector != NULL);

    int i;

    /* We have a match! Now populate TX:0-9 in tx->data. */
    ib_log_debug2_tx(tx, "DFA populating %d matches", matches);
    for (i = 0; i < matches; ++i)
    {
        size_t match_len;
        const char *match_start;
        const char *name;
        ib_bytestr_t *bs;
        ib_field_t *field;
        ib_status_t rc;

        /* Readability. Mark the start and length of the string. */
        match_start = subject+ovector[i * 2];
        match_len = ovector[i * 2 + 1] - ovector[i * 2];

        /* Create a byte-string representation */
        rc = ib_bytestr_dup_mem(&bs,
                                tx->mp,
                                (const uint8_t*)match_start,
                                match_len);
        if (rc != IB_OK) {
            return rc;
        }

        /* Create a field to hold the byte-string */
        name = ib_capture_name(0);
        rc = ib_field_create(&field, tx->mp, name, strlen(name),
                             IB_FTYPE_BYTESTR, ib_ftype_bytestr_in(bs));
        if (rc != IB_OK) {
            return rc;
        }

        /* Add it to the capture collection */
        rc = ib_capture_add_item(capture, field);
        if (rc != IB_OK) {
            return rc;
        }
    }

    return IB_OK;
}
Ejemplo n.º 5
0
/**
 * Eudoxus first match callback function.  Called when a match occurs.
 *
 * Always returns IA_EUDOXUS_CMD_STOP to stop matching (unless an
 * error occurs). If capture is enabled the matched text will be stored in the
 * capture variable.
 *
 * @param[in] engine Eudoxus engine.
 * @param[in] output Output defined by automata.
 * @param[in] output_length Length of output.
 * @param[in] input Current location in the input (first character
 *                  after the match).
 * @param[in,out] cbdata Pointer to the ee_callback_data_t instance we are
 *                       handling. This is needed for handling capture
 *                       of the match.
 * @return IA_EUDOXUS_CMD_ERROR on error, IA_EUDOXUS_CMD_STOP otherwise.
 */
static
ia_eudoxus_command_t ee_first_match_callback(ia_eudoxus_t* engine,
                                             const char *output,
                                             size_t output_length,
                                             const uint8_t *input,
                                             void *cbdata)
{
    assert(cbdata != NULL);
    assert(output != NULL);

    ib_status_t rc;
    uint32_t match_len;
    const ee_callback_data_t *ee_cbdata = cbdata;
    ib_tx_t *tx = ee_cbdata->tx;
    ib_field_t *capture = ee_cbdata->capture;
    ib_bytestr_t *bs;
    ib_field_t *field;
    const char *name;

    assert(tx != NULL);

    if (capture != NULL) {
        if (output_length != sizeof(uint32_t)) {
            return IA_EUDOXUS_CMD_ERROR;
        }
        match_len = *(uint32_t *)(output);
        rc = ib_capture_clear(capture);
        if (rc != IB_OK) {
            ib_log_error_tx(tx, "Error clearing captures: %s",
                            ib_status_to_string(rc));
            return IA_EUDOXUS_CMD_ERROR;
        }
        /* Create a byte-string representation */
        rc = ib_bytestr_dup_mem(&bs,
                                tx->mp,
                                (input - match_len),
                                match_len);
        if (rc != IB_OK) {
            return IA_EUDOXUS_CMD_ERROR;
        }
        name = ib_capture_name(0);
        rc = ib_field_create(&field, tx->mp, name, strlen(name),
                             IB_FTYPE_BYTESTR, ib_ftype_bytestr_in(bs));
        if (rc != IB_OK) {
            return IA_EUDOXUS_CMD_ERROR;
        }
        rc = ib_capture_set_item(capture, 0, tx->mp, field);
        if (rc != IB_OK) {
            return IA_EUDOXUS_CMD_ERROR;
        }
    }

    return IA_EUDOXUS_CMD_STOP;
}
Ejemplo n.º 6
0
ib_status_t ib_bytestr_dup_nulstr(
    ib_bytestr_t **pdst,
    ib_mm_t        mm,
    const char    *data
) {
    assert(pdst != NULL);
    assert(data != NULL);

    ib_status_t rc = ib_bytestr_dup_mem(
        pdst,
        mm,
        (uint8_t *)data,
        strlen(data)
    );

    return rc;
}
Ejemplo n.º 7
0
ib_status_t ib_bytestr_dup(
    ib_bytestr_t       **pdst,
    ib_mm_t              mm,
    const ib_bytestr_t  *src
) {
    assert(pdst != NULL);

    ib_status_t rc;
    rc = ib_bytestr_dup_mem(
        pdst,
        mm,
        ib_bytestr_const_ptr(src),
        ib_bytestr_length(src)
    );

    return rc;
}
Ejemplo n.º 8
0
ib_status_t ib_bytestr_dup_nulstr(
    ib_bytestr_t **pdst,
    ib_mpool_t *pool,
    const char *data
) {
    IB_FTRACE_INIT();

    assert(pdst != NULL);
    assert(pool != NULL);
    assert(data != NULL);

    ib_status_t rc = ib_bytestr_dup_mem(
        pdst,
        pool,
        (uint8_t *)data,
        strlen(data)
    );

    IB_FTRACE_RET_STATUS(rc);
}
Ejemplo n.º 9
0
ib_status_t ib_bytestr_dup(
    ib_bytestr_t       **pdst,
    ib_mpool_t          *pool,
    const ib_bytestr_t  *src
) {
    IB_FTRACE_INIT();

    assert(pdst != NULL);
    assert(pool != NULL);

    ib_status_t rc;
    rc = ib_bytestr_dup_mem(
        pdst,
        pool,
        ib_bytestr_const_ptr(src),
        ib_bytestr_length(src)
    );

    IB_FTRACE_RET_STATUS(rc);
}
Ejemplo n.º 10
0
/**
 * Set the matches into the given field name as .0, .1, .2 ... .9.
 *
 * @param[in] ib The IronBee engine to log to.
 * @param[in] tx The transaction to store the values into (tx->dpi).
 * @param[in] field_name The field to populate with Regex matches.
 * @param[in] ovector The vector of integer pairs of matches from PCRE.
 * @param[in] matches The number of matches.
 * @param[in] subject The matched-against string data.
 *
 * @returns IB_OK or IB_EALLOC.
 */
static ib_status_t pcre_set_matches(ib_engine_t *ib,
                                    ib_tx_t *tx,
                                    const char* field_name,
                                    int *ovector,
                                    int matches,
                                    const char *subject)
{
    IB_FTRACE_INIT();

    /* IronBee status. */
    ib_status_t rc;

    /* Iterator. */
    int i;

    /* Length of field_name. */
    const int field_name_sz = strlen(field_name);

    /* The length of the match. */
    size_t match_len;

    /* The first character in the match. */
    const char* match_start;

    /* +3 = '.', [digit], and \0. */
    char *full_field_name = malloc(field_name_sz+3);

    /* Holder to build an optional debug message in. */
    char *debug_msg;

    /* Holder for a copy of the field value when creating a new field. */
    ib_bytestr_t *field_value;

    /* Field holder. */
    ib_field_t *ib_field;

    /* Ensure the above allocations happened. */
    if (full_field_name==NULL) {
        IB_FTRACE_RET_STATUS(IB_EALLOC);
    }

    rc = ensure_field_exists(ib, tx, field_name);
    if (rc != IB_OK) {
        ib_log_alert_tx(tx, "Could not ensure that field %s was a list.",
            field_name);
        free(full_field_name);
        IB_FTRACE_RET_STATUS(IB_EINVAL);
    }

    /* We have a match! Now populate TX.0-9 in tx->dpi. */
    for (i=0; i<matches; i++)
    {
        /* Build the field name. Typically TX.0, TX.1 ... TX.9 */
        sprintf(full_field_name, "%s.%d", field_name, i);

        /* Readability. Mark the start and length of the string. */
        match_start = subject+ovector[i*2];
        match_len = ovector[i*2+1] - ovector[i*2];

        /* If debugging this, copy the string value out and print it to the
         * log. This could be dangerous as there could be non-character
         * values in the match. */
        if (ib_log_get_level(ib) >= 7) {
            debug_msg = malloc(match_len+1);

            /* Notice: Don't provoke a crash if malloc fails. */
            if (debug_msg != NULL) {
                memcpy(debug_msg, match_start, match_len);
                debug_msg[match_len] = '\0';

                ib_log_debug2_tx(tx, "REGEX Setting %s=%s",
                            full_field_name,
                            debug_msg);

                free(debug_msg);
            }
        }

        ib_data_get(tx->dpi, full_field_name, &ib_field);

        if (ib_field == NULL) {
            ib_data_add_bytestr(tx->dpi,
                                full_field_name,
                                (uint8_t*)subject+ovector[i*2],
                                match_len,
                                NULL);
        }
        else {
            ib_bytestr_dup_mem(&field_value,
                               tx->mp,
                               (const uint8_t*)match_start,
                               match_len);
            ib_field_setv_no_copy(
                ib_field,
                ib_ftype_bytestr_mutable_in(field_value)
            );
        }
    }

    IB_FTRACE_RET_STATUS(IB_OK);
}
Ejemplo n.º 11
0
ib_status_t ib_parsed_req_line_create(
    ib_parsed_req_line_t **line,
    ib_mm_t                mm,
    const char            *raw,
    size_t                 raw_len,
    const char            *method,
    size_t                 method_len,
    const char            *uri,
    size_t                 uri_len,
    const char            *protocol,
    size_t                 protocol_len
)
{
    ib_status_t rc = IB_OK;

    ib_parsed_req_line_t *line_tmp =
        ib_mm_alloc(mm, sizeof(*line_tmp));

    if (line_tmp == NULL) {
        return IB_EALLOC;
    }

    /* Record the components if available. If the components are
     * not available, but the raw line is, then it will be possible
     * to parse the components out later on.  Otherwise, if there
     * is no component and no raw line, then set default values.
     */
    if (method != NULL) {
        rc = ib_bytestr_dup_mem(
            &line_tmp->method,
            mm,
            (const uint8_t *)method, method_len
        );
        if (rc != IB_OK) {
            return rc;
        }
    }
    else {
        rc = ib_bytestr_dup_mem(
            &line_tmp->method,
            mm,
            (const uint8_t *)"", 0
        );
        if (rc != IB_OK) {
            return rc;
        }
    }

    if (uri != NULL) {
        rc = ib_bytestr_dup_mem(
            &line_tmp->uri,
            mm,
            (const uint8_t *)uri, uri_len
        );
        if (rc != IB_OK) {
            return rc;
        }
    }
    else {
        rc = ib_bytestr_dup_mem(
            &line_tmp->uri,
            mm,
            (const uint8_t *)"", 0
        );
        if (rc != IB_OK) {
            return rc;
        }
    }

    if (protocol != NULL) {
        rc = ib_bytestr_dup_mem(
            &line_tmp->protocol,
            mm,
            (const uint8_t *)protocol, protocol_len
        );
        if (rc != IB_OK) {
            return rc;
        }
    }
    else {
        rc = ib_bytestr_dup_mem(
            &line_tmp->protocol,
            mm,
            (const uint8_t *)"", 0
        );
        if (rc != IB_OK) {
            return rc;
        }
    }

    /* If no raw line is available, then create one. */
    if (raw == NULL) {
        if (method_len + uri_len + protocol_len == 0) {
            rc = ib_bytestr_dup_mem(
                &line_tmp->raw,
                mm,
                (const uint8_t *)"", 0
            );
            if (rc != IB_OK) {
                return rc;
            }
        }
        else {
            size_t raw_line_len;

            assert(method != NULL);
            assert(uri    != NULL);

            /* Create a correctly sized bytestr and manually copy
             * the data into it.
             */
            raw_line_len = method_len + 1 + uri_len +
                           (protocol == NULL ? 0 : 1 + protocol_len);
            rc = ib_bytestr_create(&line_tmp->raw, mm, raw_line_len);
            if (rc != IB_OK) {
                return rc;
            }

            ib_bytestr_append_mem(
                line_tmp->raw,
                (const uint8_t *)method, method_len
            );
            ib_bytestr_append_mem(
                line_tmp->raw,
                (const uint8_t *)" ", 1
            );
            ib_bytestr_append_mem(
                line_tmp->raw,
                (const uint8_t *)uri, uri_len
            );
            if (protocol != NULL) {
                ib_bytestr_append_mem(
                    line_tmp->raw,
                    (const uint8_t *)" ", 1
                );
                ib_bytestr_append_mem(
                    line_tmp->raw,
                    (const uint8_t *)protocol, protocol_len
                );
            }
        }
    }
    else {
        rc = ib_bytestr_dup_mem(
            &line_tmp->raw,
            mm,
            (const uint8_t *)raw, raw_len
        );
        if (rc != IB_OK) {
            return rc;
        }
    }

    /* Commit back successfully created line. */
    *line = line_tmp;

    return IB_OK;
}
Ejemplo n.º 12
0
Archivo: pcre.c Proyecto: niubl/ironbee
/**
 * Set the matches into the given field name as .0, .1, .2 ... .9.
 *
 * @param[in] tx Current transaction.
 * @param[in] capture Collection to capture to.
 * @param[in] ovector The vector of integer pairs of matches from PCRE.
 * @param[in] matches The number of matches.
 * @param[in] subject The matched-against string data.
 *
 * @returns IB_OK or IB_EALLOC.
 */
static
ib_status_t pcre_set_matches(
    const ib_tx_t *tx,
    ib_field_t    *capture,
    int           *ovector,
    int            matches,
    const char    *subject
)
{
    assert(tx != NULL);
    assert(tx->ib != NULL);
    assert(capture != NULL);
    assert(ovector != NULL);

    ib_status_t rc;
    int i;

    rc = ib_capture_clear(capture);
    if (rc != IB_OK) {
        ib_log_error_tx(tx, "Error clearing captures: %s",
                        ib_status_to_string(rc));
    }

    /* We have a match! Now populate TX:0-9 in tx->data. */
    ib_log_debug2_tx(tx, "REGEX populating %d matches", matches);
    for (i = 0; i < matches; ++i)
    {
        /* The length of the match. */
        size_t match_len;

        /* The first character in the match. */
        const char *match_start;

        /* Field name */
        const char *name;

        /* Holder for a copy of the field value when creating a new field. */
        ib_bytestr_t *bs;

        /* Field holder. */
        ib_field_t *field;

        /* Readability. Mark the start and length of the string. */
        match_start = subject+ovector[i*2];
        match_len = ovector[i*2+1] - ovector[i*2];

        /* Create a byte-string representation */
        rc = ib_bytestr_dup_mem(&bs,
                                tx->mp,
                                (const uint8_t*)match_start,
                                match_len);
        if (rc != IB_OK) {
            return rc;
        }

        /* Create a field to hold the byte-string */
        name = ib_capture_name(i);
        rc = ib_field_create(&field, tx->mp, name, strlen(name),
                             IB_FTYPE_BYTESTR, ib_ftype_bytestr_in(bs));
        if (rc != IB_OK) {
            return rc;
        }

        /* Add it to the capture collection */
        rc = ib_capture_set_item(capture, i, tx->mp, field);
        if (rc != IB_OK) {
            return rc;
        }
    }

    return IB_OK;
}
Ejemplo n.º 13
0
/// @test Test util field library - ib_field_format() with bytestr
TEST_F(TestIBUtilField, test_field_format_bytestr)
{
    ib_field_t *f;
    ib_status_t rc;
    char fmtbuf[32];
    const uint8_t in1[] = "a\0b";
    const uint8_t in2[] = "\fabcd\0efghijk\t";
    size_t size;
    ib_bytestr_t *bs;
    const char *tname;
    const char *buf;

    size = sizeof(in1) - 1;
    rc = ib_bytestr_dup_mem(&bs, MemPool(), in1, size);
    ASSERT_EQ(IB_OK, rc);

    rc = ib_field_create(&f, MemPool(), IB_FIELD_NAME("test_bytestr"),
                         IB_FTYPE_BYTESTR, ib_ftype_bytestr_in(bs));
    ASSERT_EQ(IB_OK, rc);
    ASSERT_TRUE(f != NULL);

    buf = ib_field_format(f, false, false, &tname, fmtbuf, sizeof(fmtbuf));
    ASSERT_STREQ((const char *)in1, fmtbuf);
    ASSERT_STREQ("BYTESTR", tname);
    ASSERT_EQ(buf, fmtbuf);

    buf = ib_field_format(f, false, true, &tname, fmtbuf, sizeof(fmtbuf));
    ASSERT_STREQ("a\\u0000b", fmtbuf);
    ASSERT_STREQ("BYTESTR", tname);
    ASSERT_EQ(buf, fmtbuf);

    buf = ib_field_format(f, true, true, &tname, fmtbuf, sizeof(fmtbuf));
    ASSERT_STREQ("\"a\\u0000b\"", fmtbuf);
    ASSERT_STREQ("BYTESTR", tname);
    ASSERT_EQ(buf, fmtbuf);


    size = sizeof(in2) - 1;
    rc = ib_bytestr_dup_mem(&bs, MemPool(), in2, size);
    ASSERT_EQ(IB_OK, rc);
    ASSERT_TRUE(f != NULL);

    rc = ib_field_create(&f, MemPool(), IB_FIELD_NAME("test_bytestr"),
                         IB_FTYPE_BYTESTR, ib_ftype_bytestr_in(bs));
    ASSERT_EQ(IB_OK, rc);
    ASSERT_TRUE(f);

    buf = ib_field_format(f, false, false, NULL, fmtbuf, sizeof(fmtbuf));
    ASSERT_STREQ((const char *)in2, fmtbuf);
    ASSERT_EQ(buf, fmtbuf);

    buf = ib_field_format(f, true, false, NULL, fmtbuf, sizeof(fmtbuf));
    ASSERT_STREQ("\"\fabcd\"", fmtbuf);
    ASSERT_EQ(buf, fmtbuf);

    buf = ib_field_format(f, false, true, NULL, fmtbuf, sizeof(fmtbuf));
    ASSERT_STREQ("\\fabcd\\u0000efghijk\\t", fmtbuf);
    ASSERT_EQ(buf, fmtbuf);

    buf = ib_field_format(f, true, true, NULL, fmtbuf, sizeof(fmtbuf));
    ASSERT_STREQ("\"\\fabcd\\u0000efghijk\\t\"", fmtbuf);
    ASSERT_EQ(buf, fmtbuf);
}
Ejemplo n.º 14
0
static ib_status_t field_from_string_internal(
    ib_mpool_t *mp,
    const char *name,
    size_t nlen,
    const char *vstr,
    size_t vlen,
    bool vstr_is_nulstr,
    ib_field_t **pfield)
{
    assert(mp != NULL);
    assert(name != NULL);
    assert(vstr != NULL);
    assert(pfield != NULL);

    ib_status_t conv;
    ib_status_t rc = IB_OK;
    ib_field_t *field;

    *pfield = NULL;

    /* Try to convert to an integer */
    if (*pfield == NULL) {
        ib_num_t num_val;
        if (vstr_is_nulstr) {
            conv = ib_string_to_num(vstr, 0, &num_val);
        }
        else {
            conv = ib_string_to_num_ex(vstr, vlen, 0, &num_val);
        }
        if (conv == IB_OK) {
            rc = ib_field_create(&field, mp,
                                 name, nlen,
                                 IB_FTYPE_NUM,
                                 ib_ftype_num_in(&num_val));
            *pfield = field;
        }
    }

    /* Try to convert to a float */
    if (*pfield == NULL) {
        ib_float_t float_val;
        if (vstr_is_nulstr) {
            conv = ib_string_to_float(vstr, &float_val);
        }
        else {
            conv = ib_string_to_float_ex(vstr, vlen, &float_val);
        }
        if (conv == IB_OK) {
            rc = ib_field_create(&field, mp,
                                 name, nlen,
                                 IB_FTYPE_FLOAT,
                                 ib_ftype_float_in(&float_val));
            *pfield = field;
        }
    }

    /* Finally, assume that it's a string */
    if (*pfield == NULL) {
        if (vstr_is_nulstr) {
            rc = ib_field_create(&field, mp,
                                 name, nlen,
                                 IB_FTYPE_NULSTR,
                                 ib_ftype_nulstr_in(vstr));
        }
        else {
            ib_bytestr_t *bs;
            rc = ib_bytestr_dup_mem(&bs, mp, (const uint8_t *)vstr, vlen);
            if (rc != IB_OK) {
                return rc;
            }
            rc = ib_field_create(&field, mp,
                                 name, nlen,
                                 IB_FTYPE_BYTESTR,
                                 ib_ftype_bytestr_in(bs));
        }
        *pfield = field;
    }

    return rc;
}
Ejemplo n.º 15
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;
}
Ejemplo n.º 16
0
ib_status_t ib_parsed_resp_line_create(
    ib_parsed_resp_line_t **line,
    ib_mm_t                 mm,
    const char             *raw,
    size_t                  raw_len,
    const char             *protocol,
    size_t                  protocol_len,
    const char             *status,
    size_t                  status_len,
    const char             *msg,
    size_t                  msg_len
)
{
    ib_status_t rc = IB_OK;

    ib_parsed_resp_line_t *line_tmp =
        ib_mm_alloc(mm, sizeof(*line_tmp));

    if (line_tmp == NULL) {
        return IB_EALLOC;
    }

    if (protocol != NULL) {
        rc = ib_bytestr_dup_mem(
            &line_tmp->protocol,
            mm,
            (const uint8_t *)protocol, protocol_len
        );
        if (rc != IB_OK) {
            return rc;
        }
    }
    else {
        rc = ib_bytestr_dup_mem(
            &line_tmp->protocol,
            mm,
            (const uint8_t *)"", 0
        );
        if (rc != IB_OK) {
            return rc;
        }
    }


    if (status != NULL) {
        rc = ib_bytestr_dup_mem(
            &line_tmp->status,
            mm,
            (const uint8_t *)status, status_len
        );
        if (rc != IB_OK) {
            return rc;
        }
    }
    else {
        rc = ib_bytestr_dup_mem(
            &line_tmp->status,
            mm,
            (const uint8_t *)"", 0
        );
        if (rc != IB_OK) {
            return rc;
        }
    }

    if (msg != NULL) {
        rc = ib_bytestr_dup_mem(
            &line_tmp->msg,
            mm,
            (const uint8_t *)msg, msg_len
        );
        if (rc != IB_OK) {
            return rc;
        }
    }
    else {
        rc = ib_bytestr_dup_mem(
            &line_tmp->msg,
            mm,
            (const uint8_t *)"", 0
        );
        if (rc != IB_OK) {
            return rc;
        }
    }

    /* If no raw line is available, then create one. */
    if (raw == NULL) {
        assert(protocol != NULL);
        assert(status   != NULL);

        if (protocol_len + status_len + msg_len == 0) {
            rc = ib_bytestr_dup_mem(
                &line_tmp->raw,
                mm,
                (const uint8_t *)"", 0
            );
            if (rc != IB_OK) {
                return rc;
            }
        }
        else {
            /* Create a correctly sized bytestr and manually copy
             * the data into it.
             */
            rc = ib_bytestr_create(
                &line_tmp->raw,
                mm,
                protocol_len + 1 + status_len +
                    (msg == NULL ? 0 : 1 + msg_len)
            );
            if (rc != IB_OK) {
                return rc;
            }

            ib_bytestr_append_mem(
                line_tmp->raw,
                (const uint8_t *)protocol, protocol_len
            );
            ib_bytestr_append_mem(
                line_tmp->raw,
                (const uint8_t *)" ", 1
            );
            ib_bytestr_append_mem(
                line_tmp->raw,
                (const uint8_t *)status, status_len
            );
            if (msg != NULL) {
                ib_bytestr_append_mem(
                    line_tmp->raw,
                    (const uint8_t *)" ", 1
                );
                ib_bytestr_append_mem(
                    line_tmp->raw,
                    (const uint8_t *)msg, msg_len
                );
            }
        }
    }
    else {
        rc = ib_bytestr_dup_mem(
            &line_tmp->raw,
            mm,
            (const uint8_t *)raw, raw_len
        );
        if (rc != IB_OK) {
            return rc;
        }
    }

    /* Commit back successfully created line. */
    *line = line_tmp;

    return IB_OK;
}
Ejemplo n.º 17
0
ib_status_t ib_parsed_resp_line_create(ib_tx_t *tx,
                                       ib_parsed_resp_line_t **line,
                                       const char *raw,
                                       size_t raw_len,
                                       const char *protocol,
                                       size_t protocol_len,
                                       const char *status,
                                       size_t status_len,
                                       const char *msg,
                                       size_t msg_len)
{
    ib_status_t rc = IB_OK;

    assert(tx != NULL);
    assert(tx->ib != NULL);
    assert(tx->mp != NULL);

    ib_parsed_resp_line_t *line_tmp = ib_mpool_alloc(tx->mp,
                                                     sizeof(*line_tmp));

    if (line_tmp == NULL) {
        *line = NULL;
        return IB_EALLOC;
    }

    if (protocol != NULL) {
        rc = ib_bytestr_dup_mem(&line_tmp->protocol,
                                tx->mp,
                                (const uint8_t *)protocol,
                                protocol_len);
        if (rc != IB_OK) {
            return rc;
        }
    }
    else {
        rc = ib_bytestr_dup_mem(&line_tmp->protocol,
                                tx->mp,
                                (const uint8_t *)"",
                                0);
        if (rc != IB_OK) {
            return rc;
        }
    }


    if (status != NULL) {
        rc = ib_bytestr_dup_mem(&line_tmp->status,
                                tx->mp,
                                (const uint8_t *)status,
                                status_len);
        if (rc != IB_OK) {
            return rc;
        }
    }
    else {
        rc = ib_bytestr_dup_mem(&line_tmp->status,
                                tx->mp,
                                (const uint8_t *)"",
                                0);
        if (rc != IB_OK) {
            return rc;
        }
    }

    if (msg != NULL) {
        rc = ib_bytestr_dup_mem(&line_tmp->msg,
                                tx->mp,
                                (const uint8_t *)msg,
                                msg_len);
        if (rc != IB_OK) {
            return rc;
        }
    }
    else {
        rc = ib_bytestr_dup_mem(&line_tmp->msg,
                                tx->mp,
                                (const uint8_t *)"",
                                0);
        if (rc != IB_OK) {
            return rc;
        }
    }

    /* If no raw line is available, then create one. */
    if (raw == NULL) {
        assert(protocol != NULL);
        assert(status != NULL);

        if (protocol_len + status_len + msg_len == 0) {
            rc = ib_bytestr_dup_mem(&line_tmp->raw,
                                    tx->mp,
                                    (const uint8_t *)"",
                                    0);
            if (rc != IB_OK) {
                return rc;
            }
        }
        else {
            /* Create a correctly sized bytestr and manually copy
             * the data into it.
             */
            rc = ib_bytestr_create(&line_tmp->raw,
                                   tx->mp,
                                   protocol_len + 1 + status_len +
                                   (msg == NULL ? 0 : 1 + msg_len));
            if (rc != IB_OK) {
                return rc;
            }

            ib_bytestr_append_mem(line_tmp->raw,
                                  (const uint8_t *)protocol,
                                  protocol_len);
            ib_bytestr_append_mem(line_tmp->raw,
                                  (const uint8_t *)" ",
                                  1);
            ib_bytestr_append_mem(line_tmp->raw,
                                  (const uint8_t *)status,
                                  status_len);
            if (msg != NULL) {
                ib_bytestr_append_mem(line_tmp->raw,
                                      (const uint8_t *)" ",
                                      1);
                ib_bytestr_append_mem(line_tmp->raw,
                                      (const uint8_t *)msg,
                                      msg_len);
            }
        }
    }
    else {
        rc = ib_bytestr_dup_mem(&line_tmp->raw,
                                tx->mp,
                                (const uint8_t *)raw,
                                raw_len);
        if (rc != IB_OK) {
            return rc;
        }

        /* Now, if all components are missing, then parse them out
         * from the raw line.  If only some are missing, then
         * do not assume anything is parsable.
         *
         * NOTE: This is a strict HTTP parser and assumes single
         *       space (0x20) component separators. Better is to
         *       have the server parse the components properly.
         */
        if ((protocol == NULL) && (status == NULL) && (msg == NULL)) {
            uint8_t *raw_end = (uint8_t *)(raw + raw_len) - 1;
            uint8_t *ptr = (uint8_t *)raw;
            const uint8_t *parsed_field = ptr;

            ib_log_debug_tx(tx, "Parsing raw response line into components.");

            /* Parse the protocol. */
            while (ptr <= raw_end) {
                if (*ptr == ' ') {
                    break;
                }
                ++ptr;
            }
            rc = ib_bytestr_dup_mem(&line_tmp->protocol,
                                    tx->mp,
                                    parsed_field,
                                    (ptr - parsed_field));
            if (rc != IB_OK) {
                return rc;
            }

            /* Parse the status. */
            parsed_field = ++ptr;
            while (ptr <= raw_end) {
                if (*ptr == ' ') {
                    break;
                }
                ++ptr;
            }
            rc = ib_bytestr_dup_mem(&line_tmp->status,
                                    tx->mp,
                                    parsed_field,
                                    (ptr - parsed_field));
            if (rc != IB_OK) {
                return rc;
            }

            /* Parse the message. */
            parsed_field = ++ptr;
            if (parsed_field <= raw_end) {
                rc = ib_bytestr_dup_mem(&line_tmp->msg,
                                        tx->mp,
                                        parsed_field,
                                        (raw_end - parsed_field) + 1);
                if (rc != IB_OK) {
                    return rc;
                }
            }
            else {
                rc = ib_bytestr_dup_mem(&line_tmp->msg,
                                        tx->mp,
                                        (const uint8_t *)"",
                                        0);
                if (rc != IB_OK) {
                    return rc;
                }
            }
        }
    }

    /* Commit back successfully created line. */
    *line = line_tmp;

    return IB_OK;
}
Ejemplo n.º 18
0
/**
 * Set the matches into the given field name as .0, .1, .2 ... .9.
 *
 * @param[in] ib The IronBee engine to log to.
 * @param[in] tx The transaction to store the values into (tx->dpi).
 * @param[in] field_name The field to populate with Regex matches.
 * @param[in] ovector The vector of integer pairs of matches from PCRE.
 * @param[in] matches The number of matches.
 * @param[in] subject The matched-against string data.
 *
 * @returns IB_OK or IB_EALLOC.
 */
static ib_status_t pcre_set_matches(ib_engine_t *ib,
                                    ib_tx_t *tx,
                                    int *ovector,
                                    int matches,
                                    const char *subject)
{
    IB_FTRACE_INIT();

    /* IronBee status. */
    ib_status_t rc;

    /* Iterator. */
    int i;

    rc = ib_data_capture_clear(tx);
    if (rc != IB_OK) {
        ib_log_error_tx(tx, "Error clearing captures: %s",
                        ib_status_to_string(rc));
    }

    /* We have a match! Now populate TX:0-9 in tx->dpi. */
    ib_log_debug2_tx(tx, "REGEX populating %d matches", matches);
    for (i=0; i<matches; i++)
    {
        /* The length of the match. */
        size_t match_len;

        /* The first character in the match. */
        const char *match_start;

        /* Field name */
        const char *name;

        /* Holder for a copy of the field value when creating a new field. */
        ib_bytestr_t *bs;

        /* Field holder. */
        ib_field_t *field;

        /* Readability. Mark the start and length of the string. */
        match_start = subject+ovector[i*2];
        match_len = ovector[i*2+1] - ovector[i*2];

        /* If debugging this, copy the string value out and print it to the
         * log. This could be dangerous as there could be non-character
         * values in the match. */
        ib_log_debug2_tx(tx, "REGEX Setting #%d=%.*s",
                         i, (int)match_len, match_start);

        /* Create a byte-string representation */
        rc = ib_bytestr_dup_mem(&bs,
                                tx->mp,
                                (const uint8_t*)match_start,
                                match_len);
        if (rc != IB_OK) {
            IB_FTRACE_RET_STATUS(rc);
        }

        /* Create a field to hold the byte-string */
        name = ib_data_capture_name(i);
        rc = ib_field_create(&field, tx->mp, name, strlen(name),
                             IB_FTYPE_BYTESTR, ib_ftype_bytestr_in(bs));
        if (rc != IB_OK) {
            IB_FTRACE_RET_STATUS(rc);
        }

        /* Add it to the capture collection */
        rc = ib_data_capture_set_item(tx, i, field);
        if (rc != IB_OK) {
            IB_FTRACE_RET_STATUS(rc);
        }
    }

    IB_FTRACE_RET_STATUS(IB_OK);
}
Ejemplo n.º 19
0
ib_status_t ib_parsed_req_line_create(ib_tx_t *tx,
                                      ib_parsed_req_line_t **line,
                                      const char *raw,
                                      size_t raw_len,
                                      const char *method,
                                      size_t method_len,
                                      const char *uri,
                                      size_t uri_len,
                                      const char *protocol,
                                      size_t protocol_len)
{
    ib_status_t rc = IB_OK;

    assert(tx != NULL);
    assert(tx->ib != NULL);
    assert(tx->mp != NULL);

    ib_parsed_req_line_t *line_tmp = ib_mpool_alloc(tx->mp,
                                                    sizeof(*line_tmp));

    if ( line_tmp == NULL ) {
        *line = NULL;
        return IB_EALLOC;
    }

    /* Record the components if available. If the components are
     * not available, but the raw line is, then it will be possible
     * to parse the components out later on.  Otherwise, if there
     * is no component and no raw line, then set default values.
     */
    if (method != NULL) {
        rc = ib_bytestr_dup_mem(&line_tmp->method,
                                tx->mp,
                                (const uint8_t *)method,
                                method_len);
        if (rc != IB_OK) {
            return rc;
        }
    }
    else {
        rc = ib_bytestr_dup_mem(&line_tmp->method,
                                tx->mp,
                                (const uint8_t *)"",
                                0);
        if (rc != IB_OK) {
            return rc;
        }
    }

    if (uri != NULL) {
        rc = ib_bytestr_dup_mem(&line_tmp->uri,
                                tx->mp,
                                (const uint8_t *)uri,
                                uri_len);
        if (rc != IB_OK) {
            return rc;
        }
    }
    else {
        rc = ib_bytestr_dup_mem(&line_tmp->uri,
                                tx->mp,
                                (const uint8_t *)"",
                                0);
        if (rc != IB_OK) {
            return rc;
        }
    }

    if (protocol != NULL) {
        rc = ib_bytestr_dup_mem(&line_tmp->protocol,
                                tx->mp,
                                (const uint8_t *)protocol,
                                protocol_len);
        if (rc != IB_OK) {
            return rc;
        }
    }
    else {
        rc = ib_bytestr_dup_mem(&line_tmp->protocol,
                                tx->mp,
                                (const uint8_t *)"",
                                0);
        if (rc != IB_OK) {
            return rc;
        }
    }

    /* If no raw line is available, then create one. */
    if (raw == NULL) {
        if (method_len + uri_len + protocol_len == 0) {
            ib_log_notice_tx(tx,
                "Unable to generate raw request line without line "
                "components - using zero length request line."
            );

            rc = ib_bytestr_dup_mem(&line_tmp->raw,
                                    tx->mp,
                                    (const uint8_t *)"",
                                    0);
            if (rc != IB_OK) {
                return rc;
            }
        }
        else {
            size_t raw_line_len;

            assert(method != NULL);
            assert(uri != NULL);

            /* Create a correctly sized bytestr and manually copy
             * the data into it.
             */
            raw_line_len = method_len + 1 + uri_len +
                           (protocol == NULL ? 0 : 1 + protocol_len);
            rc = ib_bytestr_create(&line_tmp->raw, tx->mp, raw_line_len);
            if (rc != IB_OK) {
                return rc;
            }

            ib_log_debug_tx(tx,
                            "Generating raw request line from components "
                            "(length %zd).", raw_line_len);

            ib_bytestr_append_mem(line_tmp->raw,
                                  (const uint8_t *)method,
                                  method_len);
            ib_bytestr_append_mem(line_tmp->raw,
                                  (const uint8_t *)" ",
                                  1);
            ib_bytestr_append_mem(line_tmp->raw,
                                  (const uint8_t *)uri,
                                  uri_len);
            if (protocol != NULL) {
                ib_bytestr_append_mem(line_tmp->raw,
                                      (const uint8_t *)" ",
                                      1);
                ib_bytestr_append_mem(line_tmp->raw,
                                      (const uint8_t *)protocol,
                                      protocol_len);
            }
        }
    }
    else {
        rc = ib_bytestr_dup_mem(&line_tmp->raw,
                                tx->mp,
                                (const uint8_t *)raw,
                                raw_len);
        if (rc != IB_OK) {
            return rc;
        }

        /* Now, if all components are missing, then parse them out
         * from the raw line.  If only some are missing, then
         * do not assume anything is parsable.
         *
         * NOTE: This is a strict HTTP parser and assumes single
         *       space (0x20) component separators. Better is to
         *       have the server parse the components properly.
         */
        if ((method == NULL) && (uri == NULL) && (protocol == NULL)) {
            uint8_t *raw_end = (uint8_t *)(raw + raw_len) - 1;
            uint8_t *ptr = (uint8_t *)raw;
            const uint8_t *parsed_field = ptr;

            ib_log_debug_tx(tx, "Parsing raw request line into components.");

            /* Parse the method. */
            while (ptr <= raw_end) {
                if (*ptr == ' ') {
                    break;
                }
                ++ptr;
            }
            rc = ib_bytestr_dup_mem(&line_tmp->method,
                                    tx->mp,
                                    parsed_field,
                                    (ptr - parsed_field));
            if (rc != IB_OK) {
                return rc;
            }

            /* Parse the uri. */
            parsed_field = ++ptr;
            while (ptr <= raw_end) {
                if (*ptr == ' ') {
                    break;
                }
                ++ptr;
            }
            rc = ib_bytestr_dup_mem(&line_tmp->uri,
                                    tx->mp,
                                    parsed_field,
                                    (ptr - parsed_field));
            if (rc != IB_OK) {
                return rc;
            }

            /* Parse the protocol. */
            parsed_field = ++ptr;
            if (parsed_field <= raw_end) {
                rc = ib_bytestr_dup_mem(&line_tmp->protocol,
                                        tx->mp,
                                        parsed_field,
                                        (raw_end - parsed_field) + 1);
                if (rc != IB_OK) {
                    return rc;
                }
            }
            else {
                rc = ib_bytestr_dup_mem(&line_tmp->protocol,
                                        tx->mp,
                                        (const uint8_t *)"",
                                        0);
                if (rc != IB_OK) {
                    return rc;
                }
            }
        }
    }

    /* Commit back successfully created line. */
    *line = line_tmp;

    return IB_OK;
}