Exemple #1
0
ib_status_t ib_dso_open(
    ib_dso_t   **dso,
    const char  *file,
    ib_mpool_t  *pool
)
{
    void *handle;

    /// @todo Probably need to do this portably someday

    handle = dlopen(file, RTLD_LAZY);
    if (handle == NULL) {
        ib_util_log_error("%s", dlerror());
        return IB_EINVAL;
    }

    *dso = ib_mpool_alloc(pool, sizeof(**dso));
    if (*dso == NULL) {
        dlclose(handle);
        return IB_EALLOC;
    }

    (*dso)->mp = pool;
    (*dso)->handle = handle;

    return IB_OK;
}
Exemple #2
0
ib_status_t ib_dso_open(
    ib_dso_t   **dso,
    const char  *file,
    ib_mm_t      mm
)
{
    assert(dso != NULL);
    assert(file != NULL);

    void *handle;

    /// @todo Probably need to do this portably someday

    handle = dlopen(file, RTLD_GLOBAL|RTLD_LAZY);
    if (handle == NULL) {
        ib_util_log_error("%s", dlerror());
        return IB_EINVAL;
    }

    *dso = ib_mm_alloc(mm, sizeof(**dso));
    if (*dso == NULL) {
        dlclose(handle);
        return IB_EALLOC;
    }

    (*dso)->mm = mm;
    (*dso)->handle = handle;

    return IB_OK;
}
Exemple #3
0
ib_status_t ibpp_caught_boost_exception(
    ib_engine_t*            engine,
    const boost::exception& e
)
{
    std::string message;
    int level = 1;

    message = "Unknown boost::exception thrown: ";
    if (boost::get_error_info<boost::throw_function>(e)) {
        message += *boost::get_error_info<boost::throw_function>(e);
    }
    else {
        message += "No information provided.  Please report as bug.";
    }

    if (boost::get_error_info<errinfo_level>(e)) {
        level = *boost::get_error_info<errinfo_level>(e);
    }

    if (engine) {
        ib_log(engine, level, "%s", message.c_str());
        ib_log_debug(engine, "%s",
            diagnostic_information(e).c_str()
        );
    } else {
        ib_util_log_error("%s", message.c_str());
        ib_util_log_debug("%s", diagnostic_information(e).c_str()
        );
    }

    return IB_EUNKNOWN;
}
Exemple #4
0
ib_status_t ibpp_caught_ib_exception(
    ib_engine_t* engine,
    ib_status_t  status,
    const error& e
)
{
    std::string message;
    int level = 1;

    message = std::string(ib_status_to_string(status)) + ":";
    if (boost::get_error_info<errinfo_what>(e)) {
        message += *boost::get_error_info<errinfo_what>(e);
    }
    else {
        message += "IronBee++ Exception but no explanation provided.  "
                   "Please report as bug.";
    }

    if (boost::get_error_info<errinfo_level>(e)) {
        level = *boost::get_error_info<errinfo_level>(e);
    }

    if (engine) {
        ib_log(engine, level, "%s", message.c_str());
        ib_log_debug(engine, "%s", diagnostic_information(e).c_str() );
    } else {
        ib_util_log_error("%s", message.c_str());
        ib_util_log_debug("%s", diagnostic_information(e).c_str()
        );
    }
    return status;
}
Exemple #5
0
ib_status_t ibpp_caught_std_exception(
    ib_engine_t*          engine,
    ib_status_t           status,
    const std::exception& e
)
{
    if (status == IB_EALLOC) {
        return status;
    }

    std::string message;
    if (status == IB_EINVAL) {
        message = "Invalid argument: ";
    }
    else {
        message = "Unknown std::exception thrown: ";
    }
    message += e.what();

    if (engine) {
        ib_log_error(engine,  "%s", message.c_str());
    } else {
        ib_util_log_error("%s", message.c_str());
    }

    return status;
}
Exemple #6
0
ib_status_t ib_util_mkpath(const char *path, mode_t mode)
{
    char *ppath = NULL;
    char *cpath = NULL;
    ib_status_t rc;

    if (strcmp(path, ".") == 0 || strcmp(path, "/") == 0) {
        return IB_OK;
    }

    /* Attempt to create the dir.  If it returns ENOENT, then 
     * recursivly attempt to create the parent dir(s) until
     * they are all created.
     */
    if ((mkdir(path, mode) == -1) && (errno == ENOENT)) {
        int ec;

        /* Some implementations may modify the path argument,
         * so make a copy first. */
        if ((cpath = strdup(path)) == NULL) {
            return IB_EALLOC;
        }

        if ((ppath = dirname(cpath)) == NULL) {
            rc = IB_EINVAL;
            goto cleanup;
        }

        rc = ib_util_mkpath(ppath, mode);
        if (rc != IB_OK) {
            goto cleanup;
        }

        /* Parent path was created, so try again. */
        ec = mkdir(path, mode);
        if (ec == -1) {
            ec = errno;
            ib_util_log_error(3, "Failed to create path \"%s\": %s (%d)",
                              path, strerror(ec), ec);
            rc = IB_EINVAL;
            goto cleanup;
        }
    }

    rc = IB_OK;

cleanup:
    if (cpath != NULL) {
        free(cpath);
    }

    return rc;
}
Exemple #7
0
ib_status_t ibpp_caught_unknown_exception(
    ib_engine_t* engine
)
{
    if (engine) {
        ib_log_error(engine,  "%s",
            "Completely unknown exception thrown.  "
            "Please report as bug."
        );
    } else {
        ib_util_log_error("%s",
            "Completely unknown exception thrown.  "
            "Please report as bug."
        );
    }

    return IB_EUNKNOWN;
}
Exemple #8
0
ib_status_t DLL_PUBLIC ib_dso_sym_find(
    ib_dso_sym_t **psym,
    ib_dso_t      *dso,
    const char    *name
)
{
    char *err;

    if (dso == NULL || psym == NULL) {
        return IB_EINVAL;
    }

    dlerror(); /* Clear any errors */

    *psym = dlsym(dso->handle, name);
    err = dlerror();
    if (err != NULL) {
        ib_util_log_error("%s", err);
        return IB_ENOENT;
    }

    return IB_OK;
}
Exemple #9
0
/**
 * Internal compilation of the modpcre pattern.
 *
 * @param[in] ib IronBee engine for logging.
 * @param[in] pool The memory pool to allocate memory out of.
 * @param[out] pcre_cpatt Struct containing the compilation.
 * @param[in] patt The uncompiled pattern to match.
 * @param[out] errptr Pointer to an error message describing the failure.
 * @param[out] errorffset The location of the failure, if this fails.
 * @returns IronBee status. IB_EINVAL if the pattern is invalid,
 *          IB_EALLOC if memory allocation fails or IB_OK.
 */
static ib_status_t pcre_compile_internal(ib_engine_t *ib,
                                         ib_mpool_t *pool,
                                         modpcre_cpatt_t **pcre_cpatt,
                                         const char *patt,
                                         const char **errptr,
                                         int *erroffset)
{
    IB_FTRACE_INIT();

    /* Compiled pattern. */
    pcre *cpatt = NULL;

    /* Compiled pattern size. Used to copy cpatt. */
    size_t cpatt_sz;

    /* Extra data structure. This contains the study_data pointer. */
    pcre_extra *edata = NULL;

    /* Size of edata->study_data. */
    size_t study_data_sz;

    /* Is the compiled regex jit-compiled? This impacts how it is executed. */
    int is_jit;

    /* How cpatt is produced. */
    const int compile_flags = PCRE_DOTALL | PCRE_DOLLAR_ENDONLY;
#ifdef PCRE_HAVE_JIT
    /* Determine the success of a call. */
    int rc;

    /* Determines if the pcre compilation was successful with pcre_jit. */
    int pcre_jit_ret;

    /* How edata is produced if we are using JIT. */
    const int study_flags = PCRE_STUDY_JIT_COMPILE;
#else

    /* How edata is produced if we are not using JIT. */
    const int study_flags = 0;
#endif /* PCRE_HAVE_JIT */

    cpatt = pcre_compile(patt, compile_flags, errptr, erroffset, NULL);

    if (*errptr != NULL) {
        ib_util_log_error("PCRE compile error for \"%s\": %s at offset %d",
                          patt, *errptr, *erroffset);
        IB_FTRACE_RET_STATUS(IB_EINVAL);
    }

    edata = pcre_study(cpatt, study_flags, errptr);

#ifdef PCRE_HAVE_JIT
    if(*errptr != NULL)  {
        pcre_free(cpatt);
        ib_util_log_error("PCRE-JIT study failed: %s", *errptr);
        IB_FTRACE_RET_STATUS(IB_EINVAL);
    }

    /* The check to see if JIT compilation was a success changed in 8.20RC1
       now uses pcre_fullinfo see doc/pcrejit.3 */
    rc = pcre_fullinfo(cpatt, edata, PCRE_INFO_JIT, &pcre_jit_ret);
    if (rc != 0) {
        ib_log_error(ib, "PCRE-JIT failed to get pcre_fullinfo");
        is_jit = 0;
    }
    else if (pcre_jit_ret != 1) {
        ib_log_info(ib, "PCRE-JIT compiler does not support: %s", patt);
        ib_log_info(ib, "It will fallback to the normal PCRE");
        is_jit = 0;
    }
    else { /* Assume pcre_jit_ret == 1. */
        is_jit = 1;
    }
#else
    if(*errptr != NULL)  {
        pcre_free(cpatt);
        ib_log_info(ib, "PCRE study failed: %s", *errptr);
    }
    is_jit = 0;
#endif /*PCRE_HAVE_JIT*/

    /* Compute the size of the populated values of cpatt. */
    pcre_fullinfo(cpatt, edata, PCRE_INFO_SIZE, &cpatt_sz);

    if (edata != NULL) {
        pcre_fullinfo(cpatt, edata, PCRE_INFO_STUDYSIZE, &study_data_sz);
    }
    else {
        study_data_sz = 0;
    }

    /**
     * Below is only allocation and copy operations to pass the PCRE results
     * back to the output variable pcre_cpatt.
     */

    *pcre_cpatt = (modpcre_cpatt_t *)ib_mpool_alloc(pool, sizeof(**pcre_cpatt));
    if (*pcre_cpatt == NULL) {
        pcre_free(cpatt);
        pcre_free(edata);
        ib_log_error(ib,
                     "Failed to allocate pcre_cpatt of size: %zd",
                     sizeof(**pcre_cpatt));
        IB_FTRACE_RET_STATUS(IB_EALLOC);
    }

    (*pcre_cpatt)->is_jit = is_jit;
    (*pcre_cpatt)->cpatt_sz = cpatt_sz;
    (*pcre_cpatt)->study_data_sz = study_data_sz;

    /* Copy pattern. */
    (*pcre_cpatt)->patt  = ib_mpool_strdup(pool, patt);
    if ((*pcre_cpatt)->patt == NULL) {
        pcre_free(cpatt);
        pcre_free(edata);
        ib_log_error(ib, "Failed to duplicate pattern string: %s", patt);
        IB_FTRACE_RET_STATUS(IB_EALLOC);
    }

    /* Copy compiled pattern. */
    (*pcre_cpatt)->cpatt = ib_mpool_memdup(pool, cpatt, cpatt_sz);
    pcre_free(cpatt);
    if ((*pcre_cpatt)->cpatt == NULL) {
        pcre_free(edata);
        ib_log_error(ib, "Failed to duplicate pattern of size: %zd", cpatt_sz);
        IB_FTRACE_RET_STATUS(IB_EALLOC);
    }

    /* Copy extra data (study data). */
    if (edata != NULL) {

        /* Copy edata. */
        (*pcre_cpatt)->edata = ib_mpool_memdup(pool, edata, sizeof(*edata));

        if ((*pcre_cpatt)->edata == NULL) {
            pcre_free(edata);
            ib_log_error(ib, "Failed to duplicate edata.");
            IB_FTRACE_RET_STATUS(IB_EALLOC);
        }

        /* Copy edata->study_data. */
        (*pcre_cpatt)->edata->study_data = ib_mpool_memdup(pool,
                                                           edata->study_data,
                                                           study_data_sz);
        pcre_free(edata);
        if ((*pcre_cpatt)->edata->study_data == NULL) {
            ib_log_error(ib, "Failed to study data of size: %zd", study_data_sz);
            IB_FTRACE_RET_STATUS(IB_EALLOC);
        }
    }
    else {
        (*pcre_cpatt)->edata = NULL;
    }

    IB_FTRACE_RET_STATUS(IB_OK);
}
Exemple #10
0
/**
 * Internal compilation of the dfa pattern.
 *
 * The major difference in this compilation from that of a normal pcre pattern
 * is that it does not use PCRE_JIT because it is intended for use
 * on streaming data. Streaming data is delivered in chunks
 * and partial matches are found. Doing partial matches and resumes
 * disable JIT optimizations and some a few other normal optimizations.
 *
 * @param[in] pool The memory pool to allocate memory out of.
 * @param[out] pcre_cpatt Struct containing the compilation.
 * @param[in] patt The uncompiled pattern to match.
 * @param[out] errptr Pointer to an error message describing the failure.
 * @param[out] errorffset The location of the failure, if this fails.
 * @returns IronBee status. IB_EINVAL if the pattern is invalid,
 *          IB_EALLOC if memory allocation fails or IB_OK.
 */
static ib_status_t dfa_compile_internal(ib_mpool_t *pool,
                                        dfa_rule_data_t **dfa_cpatt,
                                        const char *patt,
                                        const char **errptr,
                                        int *erroffset)
{
    IB_FTRACE_INIT();

    /* Compiled pattern. */
    pcre *cpatt = NULL;

    /* Compiled pattern size. Used to copy cpatt. */
    size_t cpatt_sz;

    /* Extra data structure. This contains the study_data pointer. */
    pcre_extra *edata = NULL;

    /* Size of edata->study_data. */
    size_t study_data_sz;

    /* How cpatt is produced. */
    const int compile_flags = PCRE_DOTALL | PCRE_DOLLAR_ENDONLY;

    /* How edata is produced if we are not using JIT. */
    const int study_flags = 0;

    cpatt = pcre_compile(patt, compile_flags, errptr, erroffset, NULL);

    if (*errptr != NULL) {
        ib_util_log_error("PCRE compile error for \"%s\": %s at offset %d",
                          patt, *errptr, *erroffset);
        IB_FTRACE_RET_STATUS(IB_EINVAL);
    }

    edata = pcre_study(cpatt, study_flags, errptr);

    if(*errptr != NULL)  {
        pcre_free(cpatt);
        ib_util_log_error("PCRE study failed: %s", *errptr);
    }

    /* Compute the size of the populated values of cpatt. */
    pcre_fullinfo(cpatt, edata, PCRE_INFO_SIZE, &cpatt_sz);

    if (edata != NULL) {
        pcre_fullinfo(cpatt, edata, PCRE_INFO_STUDYSIZE, &study_data_sz);
    }
    else {
        study_data_sz = 0;
    }

    /**
     * Below is only allocation and copy operations to pass the PCRE results
     * back to the output variable dfa_cpatt.
     */

    *dfa_cpatt = (dfa_rule_data_t *)ib_mpool_alloc(pool, sizeof(**dfa_cpatt));
    if (*dfa_cpatt == NULL) {
        pcre_free(cpatt);
        pcre_free(edata);
        IB_FTRACE_RET_STATUS(IB_EALLOC);
    }

    (*dfa_cpatt)->cpatt_sz = cpatt_sz;
    (*dfa_cpatt)->study_data_sz = study_data_sz;

    /* Copy pattern. */
    (*dfa_cpatt)->patt  = ib_mpool_strdup(pool, patt);
    if ((*dfa_cpatt)->patt == NULL) {
        pcre_free(cpatt);
        pcre_free(edata);
        IB_FTRACE_RET_STATUS(IB_EALLOC);
    }

    /* Copy compiled pattern. */
    (*dfa_cpatt)->cpatt = ib_mpool_memdup(pool, cpatt, cpatt_sz);
    pcre_free(cpatt);
    if ((*dfa_cpatt)->cpatt == NULL) {
        pcre_free(edata);
        IB_FTRACE_RET_STATUS(IB_EALLOC);
    }

    /* Copy extra data (study data). */
    if (edata != NULL) {

        /* Copy edata. */
        (*dfa_cpatt)->edata = ib_mpool_memdup(pool, edata, sizeof(*edata));

        if ((*dfa_cpatt)->edata == NULL) {
            pcre_free(edata);
            IB_FTRACE_RET_STATUS(IB_EALLOC);
        }

        /* Copy edata->study_data. */
        (*dfa_cpatt)->edata->study_data = ib_mpool_memdup(pool,
                                                           edata->study_data,
                                                           study_data_sz);
        pcre_free(edata);
        if ((*dfa_cpatt)->edata->study_data == NULL) {
            IB_FTRACE_RET_STATUS(IB_EALLOC);
        }
    }
    else {
        (*dfa_cpatt)->edata = NULL;
    }

    IB_FTRACE_RET_STATUS(IB_OK);
}