Exemplo n.º 1
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;
}
Exemplo n.º 2
0
Arquivo: pcre.c Projeto: 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;
}
Exemplo n.º 3
0
Arquivo: pcre.c Projeto: niubl/ironbee
/**
 * @brief Execute the dfa operator
 *
 * @param[in] tx Current transaction.
 * @param[in] instance_data Instance data needed for execution.
 * @param[in] field The field to operate on.
 * @param[in] capture If non-NULL, the collection to capture to.
 * @param[out] result The result of the operator 1=true 0=false.
 * @param[in] cbdata Callback data.
 *
 * @returns IB_OK most times. IB_EALLOC when a memory allocation error handles.
 */
static
ib_status_t dfa_operator_execute(
    ib_tx_t *tx,
    void *instance_data,
    const ib_field_t *field,
    ib_field_t *capture,
    ib_num_t *result,
    void *cbdata
)
{
    assert(instance_data != NULL);
    assert(tx            != NULL);

    int matches;
    ib_status_t ib_rc;
    const int ovecsize = 3 * MATCH_MAX;
    modpcre_operator_data_t *operator_data =
        (modpcre_operator_data_t *)instance_data;
    int *ovector;
    const char *subject;
    size_t subject_len;
    const ib_bytestr_t *bytestr;
    dfa_workspace_t *dfa_workspace;
    const char *id = operator_data->id;
    int options; /* dfa exec options. */
    int start_offset;
    int match_count;
    const ib_module_t *m = (const ib_module_t *)cbdata;

    assert(m != NULL);
    assert(operator_data->cpdata->is_dfa == true);

    ovector = (int *)malloc(ovecsize*sizeof(*ovector));
    if (ovector==NULL) {
        return IB_EALLOC;
    }

    if (field->type == IB_FTYPE_NULSTR) {
        ib_rc = ib_field_value(field, ib_ftype_nulstr_out(&subject));
        if (ib_rc != IB_OK) {
            free(ovector);
            return ib_rc;
        }

        subject_len = strlen(subject);
    }
    else if (field->type == IB_FTYPE_BYTESTR) {
        ib_rc = ib_field_value(field, ib_ftype_bytestr_out(&bytestr));
        if (ib_rc != IB_OK) {
            free(ovector);
            return ib_rc;
        }

        subject_len = ib_bytestr_length(bytestr);
        subject = (const char *) ib_bytestr_const_ptr(bytestr);
    }
    else {
        free(ovector);
        return IB_EINVAL;
    }

    /* Get the per-tx workspace data for this rule data id. */
    ib_rc = get_dfa_tx_data(m, tx, id, &dfa_workspace);
    if (ib_rc == IB_ENOENT) {
        /* First time we are called, clear the captures. */
        if (capture) {
            ib_rc = ib_capture_clear(capture);
            if (ib_rc != IB_OK) {
                ib_log_error_tx(tx, "Error clearing captures: %s",
                                ib_status_to_string(ib_rc));
            }
        }

        options = PCRE_PARTIAL_SOFT;

        ib_rc = alloc_dfa_tx_data(m, tx, operator_data->cpdata, id, &dfa_workspace);
        if (ib_rc != IB_OK) {
            free(ovector);
            return ib_rc;
        }
    }
    else if (ib_rc == IB_OK) {
        options = PCRE_PARTIAL_SOFT | PCRE_DFA_RESTART;
    }
    else {
        free(ovector);
        return ib_rc;
    }

    /* Perform the match.
     * If capturing is specified, then find all matches.
     */
    start_offset = 0;
    match_count = 0;
    do {
        matches = pcre_dfa_exec(operator_data->cpdata->cpatt,
                                operator_data->cpdata->edata,
                                subject,
                                subject_len,
                                start_offset, /* Starting offset. */
                                options,
                                ovector,
                                ovecsize,
                                dfa_workspace->workspace,
                                dfa_workspace->wscount);

        if (matches > 0) {
            ++match_count;

            /* Use the longest match - the first in ovector -
             * to set the offset in the subject for the next
             * match.
             */
            start_offset = ovector[1] + 1;
            if (capture) {
                pcre_dfa_set_match(tx, capture, ovector, 1, subject);
            }
        }
    } while (capture && (matches > 0));

    if (match_count > 0) {
        ib_rc = IB_OK;
        *result = 1;
    }
    else if ((matches == 0) || (matches == PCRE_ERROR_NOMATCH)) {
        ib_rc = IB_OK;
        *result = 0;
    }
    else if (matches == PCRE_ERROR_PARTIAL) {
        ib_rc = IB_OK;
        *result = 0;
    }
    else {
        /* Some other error occurred. Set the status to false and
         * return the error. */
        ib_rc = IB_EUNKNOWN;
        *result = 0;
    }

    free(ovector);
    return ib_rc;
}
Exemplo n.º 4
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;
}