コード例 #1
0
ファイル: bytestr.c プロジェクト: moon2l/ironbee
ib_status_t ib_bytestr_alias(
    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;

    if ((src == NULL) || (src->data == NULL)) {
        IB_FTRACE_RET_STATUS(IB_EINVAL);
    }

    rc = ib_bytestr_alias_mem(
        pdst,
        pool,
        ib_bytestr_const_ptr(src),
        src->length
    );

    IB_FTRACE_RET_STATUS(rc);
}
コード例 #2
0
ファイル: core_vars.c プロジェクト: poona/ironbee
static void core_gen_tx_bytestr_alias2(
    ib_tx_t *tx,
    const char *name,
    const char *val, size_t val_length
)
{
    assert(tx != NULL);
    assert(name != NULL);
    assert(val != NULL);

    ib_status_t rc;
    ib_bytestr_t *bytestr;

    rc = ib_bytestr_alias_mem(
             &bytestr,
             tx->mp,
             (const uint8_t *)val,
             val_length
         );
    if (rc != IB_OK) {
        ib_log_warning_tx(tx, "Failed to create alias for \"%s\" var: %s",
                          name, ib_status_to_string(rc));
        return;
    }

    core_gen_tx_bytestr_alias(tx, name, bytestr);
}
コード例 #3
0
ファイル: bytestr.c プロジェクト: B0SB05/ironbee
ib_status_t ib_bytestr_alias_nulstr(
    ib_bytestr_t **pdst,
    ib_mm_t        mm,
    const char    *data
)
{
    assert(pdst != NULL);

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

    return rc;
}
コード例 #4
0
ファイル: bytestr.c プロジェクト: moon2l/ironbee
ib_status_t ib_bytestr_alias_nulstr(ib_bytestr_t **pdst,
                                    ib_mpool_t *pool,
                                    const char *data)
{
    IB_FTRACE_INIT();

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

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

    IB_FTRACE_RET_STATUS(rc);
}
コード例 #5
0
ファイル: bytestr.c プロジェクト: B0SB05/ironbee
ib_status_t ib_bytestr_alias(
    ib_bytestr_t       **pdst,
    ib_mm_t              mm,
    const ib_bytestr_t  *src
)
{
    assert(pdst != NULL);

    ib_status_t rc;

    if ((src == NULL) || (src->data == NULL)) {
        return IB_EINVAL;
    }

    rc = ib_bytestr_alias_mem(
        pdst,
        mm,
        ib_bytestr_const_ptr(src),
        src->length
    );

    return rc;
}
コード例 #6
0
ファイル: field.c プロジェクト: aburan28/ironbee
ib_status_t ib_field_create_bytestr_alias(
    ib_field_t **pf,
    ib_mpool_t  *mp,
    const char  *name,
    size_t       nlen,
    uint8_t     *val,
    size_t       vlen
)
{
    ib_status_t rc;
    ib_bytestr_t *bs;

    rc = ib_bytestr_alias_mem(&bs, mp, val, vlen);
    if (rc != IB_OK) {
        goto failed;
    }

    rc = ib_field_create_no_copy(
        pf, mp, name, nlen,
        IB_FTYPE_BYTESTR,
        ib_ftype_bytestr_mutable_in(bs)
    );
    if (rc != IB_OK) {
        goto failed;
    }

    ib_field_util_log_debug("FIELD_CREATE_BYTESTR_ALIAS", (*pf));

    return IB_OK;

failed:
    /* Make sure everything is cleaned up on failure. */
    *pf = NULL;

    return rc;
}
コード例 #7
0
ファイル: tfn.c プロジェクト: niq/ironbee
ib_status_t ib_tfn_transform_field(ib_tfn_t *tfn,
                                   ib_field_t *f,
                                   ib_flags_t *pflags)
{
    IB_FTRACE_INIT(ib_tfn_transform);
    ib_bytestr_t *bs;
    char *str;
    uint8_t *data_out;
    size_t dlen_out;
    ib_status_t rc;

    switch(f->type) {
        case IB_FTYPE_BYTESTR:
            bs = ib_field_value_bytestr(f);

            rc = tfn->transform(tfn->fndata,
                                f->mp,
                                ib_bytestr_ptr(bs),
                                ib_bytestr_length(bs),
                                &data_out,
                                &dlen_out,
                                pflags);

            /* If it is modified and not done inplace, then the
             * field value needs to be updated.
             */
            if (   IB_TFN_CHECK_FMODIFIED(*pflags)
                && !IB_TFN_CHECK_FINPLACE(*pflags))
            {
                ib_bytestr_t *bs_new;

                rc = ib_bytestr_alias_mem(&bs_new, f->mp, data_out, dlen_out);
                if (rc != IB_OK) {
                    IB_FTRACE_RET_STATUS(rc);
                }

                rc = ib_field_setv(f, bs_new);
            }

            IB_FTRACE_RET_STATUS(rc);

        case IB_FTYPE_NULSTR:
            str = ib_field_value_nulstr(f),

            rc = tfn->transform(tfn->fndata,
                                f->mp,
                                (uint8_t *)str,
                                strlen(str),
                                &data_out,
                                &dlen_out,
                                pflags);

            /* If it is modified and not done inplace, then the
             * field value needs to be updated.
             *
             * NOTE: Anytime a transformation modifies data it
             *       MUST NUL terminate the data and it is a bug
             *       if this is not done.
             */
            if (   IB_TFN_CHECK_FMODIFIED(*pflags)
                && !IB_TFN_CHECK_FINPLACE(*pflags))
            {
                rc = ib_field_setv(f, data_out);
            }

            IB_FTRACE_RET_STATUS(rc);
    }


    IB_FTRACE_RET_STATUS(IB_EINVAL);
}
コード例 #8
0
static
ib_status_t sqltfn_normalize_pg_tfn(ib_engine_t *ib,
                                    ib_mpool_t *mp,
                                    void *tfn_data,
                                    const ib_field_t *field_in,
                                    const ib_field_t **field_out,
                                    ib_flags_t *pflags)
{
    assert(ib != NULL);
    assert(mp != NULL);
    assert(field_in != NULL);
    assert(field_out != NULL);
    assert(pflags != NULL);

    ib_bytestr_t *bs_in;
    ib_bytestr_t *bs_out;
    const char *buf_in;
    const char *buf_in_start;
    size_t buf_in_len;
    char *buf_out;
    char *buf_out_end;
    size_t buf_out_len;
    size_t lead_len = 0;
    ib_status_t rc;
    int ret;
    ib_field_t *field_new;

    /* Currently only bytestring types are supported.
     * Other types will just get passed through. */
    if (field_in->type != IB_FTYPE_BYTESTR) {
        *field_out = field_in;
        return IB_OK;
    }

    /* Extract the underlying incoming value. */
    rc = ib_field_value(field_in, ib_ftype_bytestr_mutable_out(&bs_in));
    if (rc != IB_OK) {
        return rc;
    }

    /* Create a buffer for normalization. */
    buf_out = buf_out_end = (char *)ib_mpool_alloc(mp, ib_bytestr_length(bs_in));
    if (buf_out == NULL) {
        return IB_EALLOC;
    }

    /* As SQL can be injected into a string, the normalization
     * needs to start after the first quote character if one
     * exists.
     *
     * First try single quote, then double, then none.
     *
     * TODO: Handle returning multiple transformations:
     *       1) Straight normalization
     *       2) Normalization as if with single quotes (starting point
     *          should be based on straight normalization)
     *       3) Normalization as if with double quotes (starting point
     *          should be based on straight normalization)
     */
    buf_in = (const char *)ib_bytestr_const_ptr(bs_in);
    buf_in_start = memchr(buf_in, '\'', ib_bytestr_length(bs_in));
    if (buf_in_start == NULL) {
        buf_in_start = memchr(buf_in, '"', ib_bytestr_length(bs_in));
    }
    if (buf_in_start == NULL) {
        buf_in_start = buf_in;
        buf_in_len = ib_bytestr_length(bs_in);
    }
    else {
        ++buf_in_start; /* After the quote. */
        buf_in_len = ib_bytestr_length(bs_in) - (buf_in_start - buf_in);
    }

    /* Copy the leading string if one exists. */
    if (buf_in_start != buf_in) {
        lead_len = buf_in_start - buf_in;
        memcpy(buf_out, buf_in, lead_len);
        buf_out_end += lead_len;
    }

    /* Normalize. */
    ret = sqltfn_normalize_pg_ex(buf_in_start, buf_in_len,
                                 &buf_out_end, &buf_out_len);
    if (ret < 0) {
        return IB_EALLOC;
    }
    else if (ret > 0) {
        /* Mark as modified. */
        *pflags = IB_TFN_FMODIFIED;
    }


    /* Create the output field wrapping bs_out. */
    buf_out_len += lead_len;
    rc = ib_bytestr_alias_mem(&bs_out, mp, (uint8_t *)buf_out, buf_out_len);
    if (rc != IB_OK) {
        return rc;
    }
    rc =ib_field_create(&field_new, mp,
                        field_in->name, field_in->nlen,
                        IB_FTYPE_BYTESTR,
                        ib_ftype_bytestr_mutable_in(bs_out));
    if (rc == IB_OK) {
        *field_out = field_new;
    }
    return rc;
}
コード例 #9
0
ファイル: libinjection.c プロジェクト: niubl/ironbee
static
ib_status_t sqli_normalize_tfn(ib_mpool_t *mp,
                               const ib_field_t *field_in,
                               const ib_field_t **field_out,
                               void *tfn_data)
{
    assert(mp != NULL);
    assert(field_in != NULL);
    assert(field_out != NULL);

    const sqli_pattern_set_t *ps = (const sqli_pattern_set_t *)tfn_data;
    sfilter sf;
    ib_bytestr_t *bs_in;
    ib_bytestr_t *bs_out;
    const char *buf_in;
    char *buf_in_start;
    size_t buf_in_len;
    char *buf_out;
    char *buf_out_end;
    size_t buf_out_len;
    size_t lead_len = 0;
    char prev_token_type;
    ib_field_t *field_new;
    ib_status_t rc;
    size_t fingerprint_len;

    /* Currently only bytestring types are supported.
     * Other types will just get passed through. */
    if (field_in->type != IB_FTYPE_BYTESTR) {
        *field_out = field_in;
        return IB_OK;
    }

    /* Extract the underlying incoming value. */
    rc = ib_field_value(field_in, ib_ftype_bytestr_mutable_out(&bs_in));
    if (rc != IB_OK) {
        return rc;
    }

    /* Create a buffer big enough (double) to allow for normalization. */
    buf_in = (const char *)ib_bytestr_const_ptr(bs_in);
    buf_out = buf_out_end = (char *)ib_mpool_calloc(mp, 2, ib_bytestr_length(bs_in));
    if (buf_out == NULL) {
        return IB_EALLOC;
    }

/* TODO: With the latest libinjection, we will need to do something like the
 * following, but more robust, instead of just calling is_sqli. This seems
 * to be because folding is now called, which removes some tokens.
 */
#if 0
    /* As SQL can be injected into a string, the normalization
     * needs to start after the first quote character if one
     * exists.
     *
     * First try single quote, then double, then none.
     *
     * TODO: Handle returning multiple transformations:
     *       1) Straight normalization
     *       2) Normalization as if with single quotes (starting point
     *          should be based on straight normalization)
     *       3) Normalization as if with double quotes (starting point
     *          should be based on straight normalization)
     */
    buf_in_start = memchr(buf_in, CHAR_SINGLE, ib_bytestr_length(bs_in));
    if (buf_in_start == NULL) {
        buf_in_start = memchr(buf_in, CHAR_DOUBLE, ib_bytestr_length(bs_in));
    }
    if (buf_in_start == NULL) {
        buf_in_start = (char *)buf_in;
        buf_in_len = ib_bytestr_length(bs_in);
    }
    else {
        ++buf_in_start; /* After the quote. */
        buf_in_len = ib_bytestr_length(bs_in) - (buf_in_start - buf_in);
    }

    /* Copy the leading string if one exists. */
    if (buf_in_start != buf_in) {
        lead_len = buf_in_start - buf_in;
        memcpy(buf_out, buf_in, lead_len);
        buf_out_end += lead_len;
    }
#endif
    buf_in_start = (char *)buf_in;
    buf_in_len = ib_bytestr_length(bs_in);

    /* Copy the normalized tokens as a space separated list. Since
     * the tokenizer does not backtrack, and the normalized values
     * are always equal to or less than the original length, the
     * tokens are written back to the beginning of the original
     * buffer.
     */
    libinjection_sqli_init(&sf,buf_in_start, buf_in_len, FLAG_NONE);
    libinjection_sqli_callback(&sf, sqli_lookup_word, (void *)ps);

    /* NOTE: We do not care if it is sqli, but just want the tokens. */
    libinjection_is_sqli(&sf);

    if (strlen(sf.fingerprint) == 0) {
        *field_out = field_in;
        return IB_OK;
    }

    buf_out_len = 0;
    prev_token_type = 0;
    fingerprint_len = strlen(sf.fingerprint);
    for (size_t i = 0; i < fingerprint_len; ++i) {
        stoken_t current = sf.tokenvec[i];
        size_t token_len = strlen(current.val);

        /* Add in the space if required. */
        if ((buf_out_end != buf_out) &&
            (current.type != 'o') &&
            (prev_token_type != 'o') &&
            (current.type != ',') &&
            (*(buf_out_end - 1) != ','))
        {
            *buf_out_end = ' ';
            buf_out_end += 1;
            ++buf_out_len;
        }

        /* Copy the token value. */
        memcpy(buf_out_end, current.val, token_len);
        buf_out_end += token_len;
        buf_out_len += token_len;

        prev_token_type = current.type;
    }


    /* Create the output field wrapping bs_out. */
    buf_out_len += lead_len;
    rc = ib_bytestr_alias_mem(&bs_out, mp, (uint8_t *)buf_out, buf_out_len);
    if (rc != IB_OK) {
        return rc;
    }
    rc = ib_field_create(&field_new, mp,
                         field_in->name, field_in->nlen,
                         IB_FTYPE_BYTESTR,
                         ib_ftype_bytestr_mutable_in(bs_out));
    if (rc == IB_OK) {
        *field_out = field_new;
    }
    return rc;
}
コード例 #10
0
ファイル: core_fields.c プロジェクト: strategist922/ironbee
/**
 * 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;
}
コード例 #11
0
static
ib_status_t sqli_normalize_tfn(ib_engine_t *ib,
                               ib_mpool_t *mp,
                               void *tfn_data,
                               const ib_field_t *field_in,
                               const ib_field_t **field_out,
                               ib_flags_t *pflags)
{
    assert(ib != NULL);
    assert(mp != NULL);
    assert(field_in != NULL);
    assert(field_out != NULL);
    assert(pflags != NULL);

    sfilter sf;
    ib_bytestr_t *bs_in;
    ib_bytestr_t *bs_out;
    const char *buf_in;
    char *buf_in_start;
    size_t buf_in_len;
    char *buf_out;
    char *buf_out_end;
    size_t buf_out_len;
    size_t lead_len = 0;
    char prev_token_type;
    ib_field_t *field_new;
    ib_status_t rc;
    size_t pat_len;

    /* Currently only bytestring types are supported.
     * Other types will just get passed through. */
    if (field_in->type != IB_FTYPE_BYTESTR) {
        *field_out = field_in;
        return IB_OK;
    }

    /* Extract the underlying incoming value. */
    rc = ib_field_value(field_in, ib_ftype_bytestr_mutable_out(&bs_in));
    if (rc != IB_OK) {
        return rc;
    }

    /* Create a buffer big enough (double) to allow for normalization. */
    buf_in = (const char *)ib_bytestr_const_ptr(bs_in);
    buf_out = buf_out_end = (char *)ib_mpool_calloc(mp, 2, ib_bytestr_length(bs_in));
    if (buf_out == NULL) {
        return IB_EALLOC;
    }

    /* As SQL can be injected into a string, the normalization
     * needs to start after the first quote character if one
     * exists.
     *
     * First try single quote, then double, then none.
     *
     * TODO: Handle returning multiple transformations:
     *       1) Straight normalization
     *       2) Normalization as if with single quotes (starting point
     *          should be based on straight normalization)
     *       3) Normalization as if with double quotes (starting point
     *          should be based on straight normalization)
     */
    buf_in_start = memchr(buf_in, CHAR_SINGLE, ib_bytestr_length(bs_in));
    if (buf_in_start == NULL) {
        buf_in_start = memchr(buf_in, CHAR_DOUBLE, ib_bytestr_length(bs_in));
    }
    if (buf_in_start == NULL) {
        buf_in_start = (char *)buf_in;
        buf_in_len = ib_bytestr_length(bs_in);
    }
    else {
        ++buf_in_start; /* After the quote. */
        buf_in_len = ib_bytestr_length(bs_in) - (buf_in_start - buf_in);
    }

    /* Copy the leading string if one exists. */
    if (buf_in_start != buf_in) {
        lead_len = buf_in_start - buf_in;
        memcpy(buf_out, buf_in, lead_len);
        buf_out_end += lead_len;
    }

    /* Copy the normalized tokens as a space separated list. Since
     * the tokenizer does not backtrack, and the normalized values
     * are always equal to or less than the original length, the
     * tokens are written back to the beginning of the original
     * buffer.
     */
    libinjection_is_sqli(&sf, buf_in_start, buf_in_len, NULL, NULL);
    buf_out_len = 0;
    prev_token_type = 0;
    pat_len = strlen(sf.pat);
    for (size_t i = 0; i < pat_len; ++i) {
        stoken_t current = sf.tokenvec[i];
        size_t token_len = strlen(current.val);
        ib_log_debug2(ib, "SQLi TOKEN: %c \"%s\"", current.type, current.val);

        /* Add in the space if required. */
        if ((buf_out_end != buf_out) &&
            (current.type != 'o') &&
            (prev_token_type != 'o') &&
            (current.type != ',') &&
            (*(buf_out_end - 1) != ','))
        {
            *buf_out_end = ' ';
            buf_out_end += 1;
            ++buf_out_len;
        }

        /* Copy the token value. */
        memcpy(buf_out_end, current.val, token_len);
        buf_out_end += token_len;
        buf_out_len += token_len;

        prev_token_type = current.type;
    }

    /* Mark as modified. */
    *pflags = IB_TFN_FMODIFIED;

    /* Create the output field wrapping bs_out. */
    buf_out_len += lead_len;
    rc = ib_bytestr_alias_mem(&bs_out, mp, (uint8_t *)buf_out, buf_out_len);
    if (rc != IB_OK) {
        return rc;
    }
    rc = ib_field_create(&field_new, mp,
                         field_in->name, field_in->nlen,
                         IB_FTYPE_BYTESTR,
                         ib_ftype_bytestr_mutable_in(bs_out));
    if (rc == IB_OK) {
        *field_out = field_new;
    }
    return rc;
}