Пример #1
0
/**
 * Configuration function to select ident provider
 * Implements IdentType directive
 *
 * @param cp IronBee configuration parser
 * @param name Unused
 * @param p1 Select ident provider
 * @param p2 Optional.  If set to "any", ident will be checked by all
 *           available providers if the configured provider doesn't
 *           identify.  Expected to be used in "Log" mode.
 * @param dummy Unused
 * @return status
 */
static ib_status_t ident_type(ib_cfgparser_t *cp, const char *name,
                              const char *p1, const char *p2, void *dummy)
{
    ident_cfg_t *cfg;
    ib_status_t rc;
    ib_module_t *m;
    char *p;

    rc = ib_engine_module_get(cp->ib, MODULE_NAME_STR, &m);
    assert((rc == IB_OK) && (m != NULL));
    rc = ib_context_module_config(ib_context_main(cp->ib), m, &cfg);
    assert((rc == IB_OK) && (cfg != NULL));

    cfg->type = p = ib_mm_strdup(cp->mm, p1);
    assert(p != NULL);
    do {
        if (isupper(*p)) {
            *p = tolower(*p);
        }
    } while (*++p);
    if (p2 && !strcasecmp(p2, "any")) {
        cfg->accept_any = 1;
    }
    else {
        cfg->accept_any = 0;
    }
    return rc;
}
Пример #2
0
/**
 * Configuration function to select what ident regime to operate
 * Implements IdentMode directive
 *
 * @param cp IronBee configuration parser
 * @param name Unused
 * @param p1 Select whether ident is "Off" (do nothing),
 *           "Log" (Log user id or unidentified) or
 *           "Require" (Log id and issue challenge if unidentified)
 * @param dummy Unused
 * @return OK, or EINVAL if p1 is unrecognized
 */
static ib_status_t ident_mode(ib_cfgparser_t *cp, const char *name,
                              const char *p1, void *dummy)
{
    ident_cfg_t *cfg;
    ib_status_t rc;
    ib_module_t *m;

    rc = ib_engine_module_get(cp->ib, MODULE_NAME_STR, &m);
    assert((rc == IB_OK) && (m != NULL));
    rc = ib_context_module_config(ib_context_main(cp->ib), m, &cfg);
    assert((rc == IB_OK) && (cfg != NULL));

    if (!strcasecmp(p1, "Off")) {
        cfg->mode = ident_off;
    }
    else if (!strcasecmp(p1, "Log")) {
        cfg->mode = ident_log;
    }
    else if (!strcasecmp(p1, "Require")) {
        cfg->mode = ident_require;
    }
    else {
        rc = IB_EINVAL;
    }
    return rc;
}
Пример #3
0
void DLL_PUBLIC ib_vlog_ex(ib_engine_t *ib, int level,
                           const ib_tx_t *tx,
                           const char *prefix, const char *file, int line,
                           const char *fmt, va_list ap)
{
    IB_FTRACE_INIT();

    IB_PROVIDER_API_TYPE(logger) *api;
    ib_core_cfg_t *corecfg;
    ib_provider_inst_t *pi = NULL;
    ib_status_t rc;
    ib_context_t *ctx;

    ctx = ib_context_main(ib);

    if (ctx != NULL) {
        rc = ib_context_module_config(ctx, ib_core_module(),
                                      (void *)&corecfg);
        if (rc == IB_OK) {
            pi = corecfg->pi.logger;
        }

        if (pi != NULL) {
            api = (IB_PROVIDER_API_TYPE(logger) *)pi->pr->api;

            api->vlogmsg(pi, ctx, level, tx, prefix, file, line, fmt, ap);

            IB_FTRACE_RET_VOID();
        }
Пример #4
0
/**
 * Access configuration data.
 *
 * @param[in] ib IronBee engine.
 * @return
 * - configuration on success.
 * - NULL on failure.
 */
static
ee_config_t *ee_get_config(
    ib_engine_t *ib
)
{
    assert(ib != NULL);

    ib_module_t  *module;
    ib_context_t *context;
    ib_status_t   rc;
    ee_config_t  *config;

    rc = ib_engine_module_get(ib, MODULE_NAME_STR, &module);
    if (rc != IB_OK) {
        return NULL;
    }

    context = ib_context_main(ib);
    if (context == NULL) {
        return NULL;
    }

    rc = ib_context_module_config(context, module, &config);
    if (rc != IB_OK) {
        return NULL;
    }

    return config;
}
Пример #5
0
ib_status_t ib_cfgparser_create(ib_cfgparser_t **pcp,
                                ib_engine_t *ib)
{
    IB_FTRACE_INIT(ib_cfgparser_create);
    ib_mpool_t *pool;
    ib_status_t rc;

    /* Create parser memory pool */
    rc = ib_mpool_create(&pool, ib->mp);
    if (rc != IB_OK) {
        rc = IB_EALLOC;
        goto failed;
    }

    /* Create the main structure in the memory pool */
    *pcp = (ib_cfgparser_t *)ib_mpool_calloc(pool, 1, sizeof(**pcp));
    if (*pcp == NULL) {
        rc = IB_EALLOC;
        goto failed;
    }
    (*pcp)->ib = ib;
    (*pcp)->mp = pool;

    /* Create the stack */
    rc = ib_list_create(&((*pcp)->stack), pool);
    if (rc != IB_OK) {
        goto failed;
    }
    (*pcp)->cur_ctx = ib_context_main(ib);
    ib_list_push((*pcp)->stack, (*pcp)->cur_ctx);

    /* Create the block tracking list */
    rc = ib_list_create(&((*pcp)->block), pool);
    if (rc != IB_OK) {
        goto failed;
    }

    /* Other fields are NULLed via calloc */

    ib_log_debug(ib, 9, "Stack: ctx=%p site=%p(%s) loc=%p(%s)",
                 (*pcp)->cur_ctx,
                 (*pcp)->cur_site, (*pcp)->cur_site?(*pcp)->cur_site->name:"NONE",
                 (*pcp)->cur_loc, (*pcp)->cur_loc?(*pcp)->cur_loc->path:"/");

    IB_FTRACE_RET_STATUS(rc);

failed:
    /* Make sure everything is cleaned up on failure */
    if (pool != NULL) {
        ib_mpool_destroy(pool);
    }
    *pcp = NULL;

    IB_FTRACE_RET_STATUS(rc);
}
Пример #6
0
TEST_F(TestIronBeeModuleRulesLua, operator_test)
{
    const ib_operator_t *op;
    void *instance_data;
    ib_num_t result;

    ib_field_t* field1;

    const char* op_name = "test_module_rules_lua.lua";
    const char* rule_name = "luarule001";

    char* str1 = (char *)ib_mpool_strdup(ib_engine->mp, "string 1");
    ASSERT_TRUE(str1);

    // Create field 1.
    ASSERT_EQ(IB_OK,
        ib_field_create(
            &field1,
            ib_engine->mp,
            IB_FIELD_NAME("field1"),
            IB_FTYPE_NULSTR,
            ib_ftype_nulstr_in(str1)
        )
    );

    /* Configure the operator. */
    configureIronBee();

    // Ensure that the operator exists.
    ASSERT_EQ(IB_OK,
        ib_operator_lookup(ib_engine, op_name, &op)
    );

    ASSERT_EQ(IB_OK, ib_operator_inst_create(op,
                                             ib_context_main(ib_engine),
                                             IB_OP_CAPABILITY_NON_STREAM,
                                             rule_name,
                                             &instance_data));
    performTx();

    // Attempt to match.
    ASSERT_EQ(IB_OK, ib_operator_inst_execute(op,
                                          instance_data,
                                          ib_tx,
                                          field1,
                                          NULL,
                                          &result));

    // This time we should succeed.
    ASSERT_TRUE(result);
}
Пример #7
0
/**
 * Handle on/off directives.
 *
 * @param[in] cp Config parser
 * @param[in] name Directive name
 * @param[in] onoff on/off flag
 * @param[in] cbdata Callback data (ignored)
 *
 * @returns Status code
 */
static ib_status_t handle_directive_onoff(ib_cfgparser_t *cp,
                                          const char *name,
                                          int onoff,
                                          void *cbdata)
{
    assert(cp != NULL);
    assert(name != NULL);
    assert(cp->ib != NULL);

    ib_engine_t *ib = cp->ib;
    ib_status_t rc;
    ib_module_t *module = NULL;
    modpcre_cfg_t *config = NULL;
    ib_context_t *ctx = cp->cur_ctx ? cp->cur_ctx : ib_context_main(ib);
    const char *pname;

    /* Get my module object */
    rc = ib_engine_module_get(cp->ib, MODULE_NAME_STR, &module);
    if (rc != IB_OK) {
        ib_cfg_log_error(cp, "Failed to get %s module object: %s",
                         MODULE_NAME_STR, ib_status_to_string(rc));
        return rc;
    }

    /* Get my module configuration */
    rc = ib_context_module_config(ctx, module, (void *)&config);
    if (rc != IB_OK) {
        ib_cfg_log_error(cp, "Failed to get %s module configuration: %s",
                         MODULE_NAME_STR, ib_status_to_string(rc));
        return rc;
    }

    if (strcasecmp("PcreStudy", name) == 0) {
        pname = MODULE_NAME_STR ".study";
    }
    else if (strcasecmp("PcreUseJit", name) == 0) {
        pname = MODULE_NAME_STR ".use_jit";
    }
    else {
        ib_cfg_log_error(cp, "Unhandled directive \"%s\"", name);
        return IB_EINVAL;
    }
    rc = ib_context_set_num(ctx, pname, onoff);
    if (rc != IB_OK) {
        ib_cfg_log_error(cp, "Failed to set \"%s\" to %s for \"%s\": %s",
                         pname, onoff ? "true" : "false", name,
                         ib_status_to_string(rc));
    }
    return IB_OK;
}
Пример #8
0
/**
 * Function exported to enable a module to register an ident provider
 *
 * @param engine Engine to register with
 * @param name Provider name (referenced in IdentType directive)
 * @param provider The identity provider
 * @return status
 */
ib_status_t ib_ident_provider_register(ib_engine_t *engine,
                                       const char *name,
                                       ib_ident_provider_t *provider)
{
    ident_cfg_t *cfg;
    ib_status_t rc;
    ib_module_t *m;

    rc = ib_engine_module_get(engine, MODULE_NAME_STR, &m);
    assert((rc == IB_OK) && (m != NULL));
    rc = ib_context_module_config(ib_context_main(engine), m, &cfg);
    assert((rc == IB_OK) && (cfg != NULL));

    if (cfg->providers == NULL) {
        rc = ib_hash_create(&cfg->providers, ib_engine_mm_main_get(engine));
        assert((rc == IB_OK) && (cfg->providers != NULL));
    }

    return ib_hash_set(cfg->providers, name, provider);
}
Пример #9
0
TEST_F(CoreOperatorsTest, ContainsTest)
{
    ib_status_t status;
    ib_num_t call_result;
    const ib_operator_t *op;
    void *instance_data;

    status = ib_operator_lookup(ib_engine, "contains", &op);

    ASSERT_EQ(IB_OK, status);


    status = ib_operator_inst_create(op,
                                     ib_context_main(ib_engine),
                                     IB_OP_CAPABILITY_NON_STREAM,
                                     "needle",
                                     &instance_data);
    ASSERT_EQ(IB_OK, status);

    // call contains
    ib_field_t *field;
    const char *matching = "data with needle in it";
    const char *nonmatching = "non matching string";
    ib_field_create(
        &field,
        ib_engine_pool_main_get(ib_engine),
        IB_FIELD_NAME("testfield"),
        IB_FTYPE_NULSTR,
        NULL
    );

    ib_field_setv(field, ib_ftype_nulstr_in(matching));
    status = ib_operator_inst_execute(op, instance_data, ib_tx, field, NULL, &call_result);
    ASSERT_EQ(IB_OK, status);
    EXPECT_EQ(1, call_result);

    ib_field_setv(field, ib_ftype_nulstr_in(nonmatching));
    status = ib_operator_inst_execute(op, instance_data, ib_tx, field, NULL, &call_result);
    ASSERT_EQ(IB_OK, status);
    EXPECT_EQ(0, call_result);
}
Пример #10
0
TEST_F(CoreOperatorsTest, NeTest)
{
    ib_status_t status;
    ib_num_t call_result;
    const ib_operator_t *op;
    void *instance_data;

    status = ib_operator_lookup(ib_engine, "ne", &op);

    ASSERT_EQ(IB_OK, status);

    status = ib_operator_inst_create(op,
                                     ib_context_main(ib_engine),
                                     IB_OP_CAPABILITY_NON_STREAM,
                                     "1",
                                     &instance_data);
    ASSERT_EQ(IB_OK, status);

    // call contains
    ib_field_t *field;
    const ib_num_t matching = 2;
    const ib_num_t nonmatching = 1;
    ib_field_create(
        &field,
        ib_engine_pool_main_get(ib_engine),
        IB_FIELD_NAME("testfield"),
        IB_FTYPE_NUM,
        ib_ftype_num_in(&matching)
    );

    ib_field_setv(field, ib_ftype_num_in(&matching));
    status = ib_operator_inst_execute(op, instance_data, ib_tx, field, NULL, &call_result);
    ASSERT_EQ(IB_OK, status);
    EXPECT_EQ(1, call_result);

    ib_field_setv(field, ib_ftype_num_in(&nonmatching));
    status = ib_operator_inst_execute(op, instance_data, ib_tx, field, NULL, &call_result);
    ASSERT_EQ(IB_OK, status);
    EXPECT_EQ(0, call_result);
}
Пример #11
0
/**
 * @internal
 * Handle a PocSigTrace directive.
 *
 * @param cp Config parser
 * @param name Directive name
 * @param p1 First parameter
 * @param cbdata Callback data (from directive registration)
 *
 * @returns Status code
 */
static ib_status_t pocsig_dir_trace(ib_cfgparser_t *cp,
                                    const char *name,
                                    const char *p1,
                                    void *cbdata)
{
    IB_FTRACE_INIT(pocsig_dir_trace);
    ib_engine_t *ib = cp->ib;
    ib_context_t *ctx = cp->cur_ctx ? cp->cur_ctx : ib_context_main(ib);
    ib_status_t rc;

    ib_log_debug(ib, 7, "%s: \"%s\" ctx=%p", name, p1, ctx);
    if (strcasecmp("On", p1) == 0) {
        rc = ib_context_set_num(ctx, MODULE_NAME_STR ".trace", 1);
        IB_FTRACE_RET_STATUS(rc);
    }
    else if (strcasecmp("Off", p1) == 0) {
        rc = ib_context_set_num(ctx, MODULE_NAME_STR ".trace", 0);
        IB_FTRACE_RET_STATUS(rc);
    }

    ib_log_error(ib, 1, "Failed to parse directive: %s \"%s\"", name, p1);
    IB_FTRACE_RET_STATUS(IB_EINVAL);
}
Пример #12
0
Context ConstEngine::main_context() const
{
  return Context(ib_context_main(ib()));
}
Пример #13
0
/**
 * Determine buffering policy from config settings
 *
 * @param[in] ibd - the filter descriptor
 * @param[in] tx - the transaction
 */
static void buffer_init(ibd_ctx *ibd, ib_tx_t *tx)
{
    ib_core_cfg_t *corecfg = NULL;
    ib_status_t rc;

    tsib_filter_ctx *fctx = ibd->data;
    ib_server_direction_t dir = ibd->ibd->dir;

    if (tx == NULL) {
        fctx->buffering = IOBUF_NOBUF;
        return;
    }
    rc = ib_core_context_config(ib_context_main(tx->ib), &corecfg);
    if (rc != IB_OK) {
        ib_log_error_tx(tx, "Error determining buffering configuration.");
    }
    else {
        if (dir == IBD_REQ) {
            fctx->buffering = (corecfg->buffer_req == 0)
                ? IOBUF_NOBUF :
                (corecfg->limits.request_body_buffer_limit < 0)
                    ? IOBUF_BUFFER_ALL :
                    (corecfg->limits.request_body_buffer_limit_action == IB_BUFFER_LIMIT_ACTION_FLUSH_ALL)
                        ? IOBUF_BUFFER_FLUSHALL
                        : IOBUF_BUFFER_FLUSHPART;
            fctx->buf_limit = (size_t) corecfg->limits.request_body_buffer_limit;
        }
        else {
            fctx->buffering = (corecfg->buffer_res == 0)
                ? IOBUF_NOBUF :
                (corecfg->limits.response_body_buffer_limit < 0)
                    ? IOBUF_BUFFER_ALL :
                    (corecfg->limits.response_body_buffer_limit_action == IB_BUFFER_LIMIT_ACTION_FLUSH_ALL)
                        ? IOBUF_BUFFER_FLUSHALL
                        : IOBUF_BUFFER_FLUSHPART;
            fctx->buf_limit = (size_t) corecfg->limits.response_body_buffer_limit;
        }
    }

    /* Override buffering based on flags */
    if (fctx->buffering != IOBUF_NOBUF) {
        if (dir == IBD_REQ) {
            if (ib_flags_any(tx->flags, IB_TX_FALLOW_ALL | IB_TX_FALLOW_REQUEST) ||
                (!ib_flags_all(tx->flags, IB_TX_FINSPECT_REQBODY) 
&&
                 !ib_flags_all(tx->flags, IB_TX_FINSPECT_REQHDR)) 
)
            {
                fctx->buffering = IOBUF_NOBUF;
                ib_log_debug2_tx(tx, "\tDisable request buffering");
            }
        } else if (dir == IBD_RESP) {
            if (ib_flags_any(tx->flags, IB_TX_FALLOW_ALL) ||
                (!ib_flags_all(tx->flags, IB_TX_FINSPECT_RESBODY) &&
                 !ib_flags_all(tx->flags, IB_TX_FINSPECT_RESHDR)) )
            {
                fctx->buffering = IOBUF_NOBUF;
                ib_log_debug2_tx(tx, "\tDisable response buffering");
            }
        }
    }
}
Пример #14
0
TEST_F(PcreModuleTest, test_pcre_operator)
{
    ib_field_t *outfield;
    ib_num_t result;
    ib_field_t *capture;
    const ib_operator_t *op;
    ib_operator_inst_t *opinst;
    ASSERT_EQ(IB_OK, ib_operator_lookup(ib_engine, IB_S2SL("pcre"), &op));

    // Create the operator instance.
    ASSERT_EQ(
        IB_OK,
        ib_operator_inst_create(
            &opinst,
            ib_engine_mm_main_get(ib_engine),
            ib_context_main(ib_engine),
            op,
            IB_OP_CAPABILITY_NONE,
            "string\\s2"
        )
    );

    // Attempt to match.
    ASSERT_EQ(
        IB_OK,
        ib_operator_inst_execute(
            opinst,
            rule_exec1.tx,
            field1,
            NULL,
            &result
        )
    );

    // We should fail.
    ASSERT_FALSE(result);

    // Attempt to match again.
    ASSERT_EQ(
        IB_OK,
        ib_operator_inst_execute(
            opinst,
            rule_exec1.tx,
            field2,
            NULL,
            &result
        )
    );

    // This time we should succeed.
    ASSERT_TRUE(result);

    // Should be no capture set */
    outfield = getTarget1(IB_TX_CAPTURE":0");
    ASSERT_FALSE(outfield);

    // Create the operator instance.
    ASSERT_EQ(
        IB_OK,
        ib_operator_inst_create(
            &opinst,
            ib_engine_mm_main_get(ib_engine),
            ib_context_main(ib_engine),
            op,
            IB_OP_CAPABILITY_NONE,
            "(string 2)"
        )
    );

    // Attempt to match.
    ASSERT_EQ(
        IB_OK,
        ib_operator_inst_execute(
            opinst,
            rule_exec1.tx,
            field1,
            NULL,
            &result
        )
    );

    // We should fail.
    ASSERT_FALSE(result);

    // Attempt to match again.
    ASSERT_EQ(
        IB_OK,
        ib_operator_inst_execute(
            opinst,
            rule_exec1.tx,
            field2,
            NULL,
            &result
        )
    );

    // This time we should succeed.
    ASSERT_TRUE(result);

    // Should be no capture (CAPTURE flag not set for rule 1)
    outfield = getTarget1(IB_TX_CAPTURE":0");
    ASSERT_FALSE(outfield);

    // Create the operator instance.
    ASSERT_EQ(
        IB_OK,
        ib_operator_inst_create(
            &opinst,
            ib_engine_mm_main_get(ib_engine),
            ib_context_main(ib_engine),
            op,
            IB_OP_CAPABILITY_NONE,
            "(string 2)"
        )
    );

    ASSERT_EQ(IB_OK,
              ib_capture_acquire(
                  rule_exec2.tx,
                  NULL,
                  &capture));

    // Attempt to match again.
    ASSERT_EQ(
        IB_OK,
        ib_operator_inst_execute(
            opinst,
            rule_exec1.tx,
            field2,
            capture,
            &result
        )
    );

    // This time we should succeed.
    ASSERT_TRUE(result);

    // Should be a capture (CAPTURE flag is set for rule 2)
    outfield = getTarget1(IB_TX_CAPTURE":0");
    ASSERT_TRUE(outfield);
}
Пример #15
0
/**
 * Handle single parameter directives.
 *
 * @param cp Config parser
 * @param name Directive name
 * @param p1 First parameter
 * @param cbdata Callback data (from directive registration)
 *
 * @returns Status code
 */
static ib_status_t handle_directive_param(ib_cfgparser_t *cp,
                                          const char *name,
                                          const char *p1,
                                          void *cbdata)
{
    assert(cp != NULL);
    assert(name != NULL);
    assert(p1 != NULL);
    assert(cp->ib != NULL);

    ib_engine_t *ib = cp->ib;
    ib_status_t rc;
    ib_module_t *module = NULL;
    modpcre_cfg_t *config = NULL;
    ib_context_t *ctx = cp->cur_ctx ? cp->cur_ctx : ib_context_main(ib);
    const char *pname;
    ib_num_t value;

    /* Get my module object */
    rc = ib_engine_module_get(cp->ib, MODULE_NAME_STR, &module);
    if (rc != IB_OK) {
        ib_cfg_log_error(cp, "Failed to get %s module object: %s",
                         MODULE_NAME_STR, ib_status_to_string(rc));
        return rc;
    }

    /* Get my module configuration */
    rc = ib_context_module_config(ctx, module, (void *)&config);
    if (rc != IB_OK) {
        ib_cfg_log_error(cp, "Failed to get %s module configuration: %s",
                         MODULE_NAME_STR, ib_status_to_string(rc));
        return rc;
    }

    /* p1 should be a number */
    rc = ib_string_to_num(p1, 0, &value);
    if (rc != IB_OK) {
        ib_cfg_log_error(cp,
                         "Failed to convert \"%s\" to a number for \"%s\": %s",
                         p1, name, ib_status_to_string(rc));
        return rc;
    }

    if (strcasecmp("PcreMatchLimit", name) == 0) {
        pname = "pcre.match_limit";
    }
    else if (strcasecmp("PcreMatchLimitRecursion", name) == 0) {
        pname = "pcre.match_limit_recursion";
    }
    else if (strcasecmp("PcreJitStackStart", name) == 0) {
        pname = "pcre.jit_stack_start";
    }
    else if (strcasecmp("PcreJitStackMax", name) == 0) {
        pname = "pcre.jit_stack_max";
    }
    else if (strcasecmp("PcreDfaWorkspaceSize", name) == 0) {
        pname = "pcre.dfa_workspace_size";
    }
    else {
        ib_cfg_log_error(cp, "Unhandled directive \"%s\"", name);
        return IB_EINVAL;
    }
    rc = ib_context_set_num(ctx, pname, value);
    if (rc != IB_OK) {
        ib_cfg_log_error(cp, "Failed to set \"%s\" to %ld for \"%s\": %s",
                         pname, (long int)value, name, ib_status_to_string(rc));
    }
    return IB_OK;
}
Пример #16
0
/**
 * @internal
 * Handle a PocSig directive.
 *
 * @param cp Config parser
 * @param name Directive name
 * @param args List of directive arguments
 * @param cbdata Callback data (from directive registration)
 *
 * @returns Status code
 */
static ib_status_t pocsig_dir_signature(ib_cfgparser_t *cp,
                                        const char *name,
                                        ib_list_t *args,
                                        void *cbdata)
{
    IB_FTRACE_INIT(pocsig_dir_signature);
    ib_engine_t *ib = cp->ib;
    ib_context_t *ctx = cp->cur_ctx ? cp->cur_ctx : ib_context_main(ib);
    ib_list_t *list;
    const char *target;
    const char *op;
    const char *action;
    pocsig_cfg_t *cfg;
    pocsig_phase_t phase;
    pocsig_sig_t *sig;
    const char *errptr;
    int erroff;
    ib_status_t rc;

    /* Get the pocsig configuration for this context. */
    rc = ib_context_module_config(ctx, IB_MODULE_STRUCT_PTR, (void *)&cfg);
    if (rc != IB_OK) {
        ib_log_error(ib, 1, "Failed to fetch %s config: %d",
                     MODULE_NAME_STR, rc);
    }

    /* Setup the PCRE matcher. */
    if (cfg->pcre == NULL) {
        rc = ib_matcher_create(ib, ib_engine_pool_config_get(ib),
                               "pcre", &cfg->pcre);
        if (rc != IB_OK) {
            ib_log_error(ib, 2, "Could not create a PCRE matcher: %d", rc);
            IB_FTRACE_RET_STATUS(rc);
        }
    }

    /* Determine phase and initialize the phase list if required. */
    if (strcasecmp("PocSigPreTx", name) == 0) {
        phase = POCSIG_PRE;
        if (cfg->phase[phase] == NULL) {
            rc = ib_list_create(cfg->phase + POCSIG_PRE,
                                ib_engine_pool_config_get(ib));
            if (rc != IB_OK) {
                IB_FTRACE_RET_STATUS(rc);
            }
        }
    }
    else if (strcasecmp("PocSigReqHead", name) == 0) {
        phase = POCSIG_REQHEAD;
        if (cfg->phase[phase] == NULL) {
            ib_log_debug(ib, 4, "Creating list for phase=%d", phase);
            rc = ib_list_create(&list,
                                ib_engine_pool_config_get(ib));
            if (rc != IB_OK) {
                IB_FTRACE_RET_STATUS(rc);
            }
            ib_log_debug(ib, 4, "List for phase=%d list=%p", phase, list);
            cfg->phase[phase] = list;
        }
    }
    else if (strcasecmp("PocSigReq", name) == 0) {
        phase = POCSIG_REQ;
        if (cfg->phase[phase] == NULL) {
            rc = ib_list_create(&cfg->phase[phase],
                                ib_engine_pool_config_get(ib));
            if (rc != IB_OK) {
                IB_FTRACE_RET_STATUS(rc);
            }
        }
    }
    else if (strcasecmp("PocSigResHead", name) == 0) {
        phase = POCSIG_RESHEAD;
        if (cfg->phase[phase] == NULL) {
            rc = ib_list_create(&cfg->phase[phase],
                                ib_engine_pool_config_get(ib));
            if (rc != IB_OK) {
                IB_FTRACE_RET_STATUS(rc);
            }
        }
    }
    else if (strcasecmp("PocSigRes", name) == 0) {
        phase = POCSIG_RES;
        if (cfg->phase[POCSIG_RES] == NULL) {
            rc = ib_list_create(&cfg->phase[POCSIG_RES],
                                ib_engine_pool_config_get(ib));
            if (rc != IB_OK) {
                IB_FTRACE_RET_STATUS(rc);
            }
        }
    }
    else if (strcasecmp("PocSigPostTx", name) == 0) {
        phase = POCSIG_POST;
        if (cfg->phase[phase] == NULL) {
            rc = ib_list_create(&cfg->phase[phase],
                                ib_engine_pool_config_get(ib));
            if (rc != IB_OK) {
                IB_FTRACE_RET_STATUS(rc);
            }
        }
    }
    else {
        ib_log_error(ib, 2, "Invalid signature: %s", name);
        IB_FTRACE_RET_STATUS(IB_EINVAL);
    }

    /* Target */
    rc = ib_list_shift(args, &target);
    if (rc != IB_OK) {
        ib_log_error(ib, 1, "No PocSig target");
        IB_FTRACE_RET_STATUS(IB_EINVAL);
    }

    /* Operator */
    rc = ib_list_shift(args, &op);
    if (rc != IB_OK) {
        ib_log_error(ib, 1, "No PocSig operator");
        IB_FTRACE_RET_STATUS(IB_EINVAL);
    }

    /* Action */
    rc = ib_list_shift(args, &action);
    if (rc != IB_OK) {
        ib_log_debug(ib, 4, "No PocSig action");
        action = "";
    }

    /* Signature */
    sig = (pocsig_sig_t *)ib_mpool_alloc(ib_engine_pool_config_get(ib),
                                         sizeof(*sig));
    if (sig == NULL) {
        IB_FTRACE_RET_STATUS(IB_EALLOC);
    }

    sig->target = ib_mpool_strdup(ib_engine_pool_config_get(ib), target);
    sig->patt = ib_mpool_strdup(ib_engine_pool_config_get(ib), op);
    sig->emsg = ib_mpool_strdup(ib_engine_pool_config_get(ib), action);

    /* Compile the PCRE patt. */
    if (cfg->pcre == NULL) {
        ib_log_error(ib, 2, "No PCRE matcher available (load the pcre module?)");
        IB_FTRACE_RET_STATUS(IB_EINVAL);
    }
    sig->cpatt = ib_matcher_compile(cfg->pcre, sig->patt, &errptr, &erroff);
    if (sig->cpatt == NULL) {
        ib_log_error(ib, 2, "Error at offset=%d of PCRE patt=\"%s\": %s",
                     erroff, sig->patt, errptr);
        IB_FTRACE_RET_STATUS(IB_EINVAL);
    }

    ib_log_debug(ib, 4, "POCSIG: \"%s\" \"%s\" \"%s\" phase=%d ctx=%p",
                 target, op, action, phase, ctx);

    /* Add the signature to the phase list. */
    rc = ib_list_push(cfg->phase[phase], sig);
    if (rc != IB_OK) {
        ib_log_error(ib, 1, "Failed to add signature");
        IB_FTRACE_RET_STATUS(rc);
    }

    IB_FTRACE_RET_STATUS(IB_OK);
}
Пример #17
0
/**
 * @internal
 * Initialize a context for the perf_stats module.
 *
 * This is a hack.
 * Hook callbacks set here to get end times for hooks.
 * Currently no other modules register hook call backs.
 * Because of this it should
 * ensure that we are the last thing called per event.
 *
 * @param[in] ib IronBee object
 * @param[in] m Module object
 * @param[in] ctx Context object
 * @param[in] cbdata Callback data (unused)
 */
static ib_status_t perf_stats_context_close(ib_engine_t  *ib,
                                            ib_module_t  *m,
                                            ib_context_t *ctx,
                                            void         *cbdata)
{
    IB_FTRACE_INIT();
    ib_status_t rc;
    int event;

    /* Check that we are in the main ctx otherwise return */
    if (ctx != ib_context_main(ib)) {
        IB_FTRACE_RET_STATUS(IB_OK);
    }

    for (event = 0; event < IB_STATE_EVENT_NUM; ++event) {
        event_info_t *eventp = &event_info[event];

        if ((eventp->cbdata_type == IB_CBDATA_NONE) ||
            (eventp->cbdata_type == IB_CBDATA_CONN_DATA_T))
        {
            rc = IB_EINVAL;
            ib_log_error(ib, "Cannot register handler "
                         "for:%d name:%s cbdata_type: %d",
                         eventp->number, eventp->name, eventp->cbdata_type);
        }
        else {
            switch( ib_state_hook_type( (ib_state_event_type_t)event ) ) {
                case IB_STATE_HOOK_CONN:
                    rc = ib_hook_conn_register(
                        ib,
                        (ib_state_event_type_t)event,
                        mod_perf_stats_event_stop_conn_callback,
                        (void *)eventp
                                               );
                    break;
                case IB_STATE_HOOK_CONNDATA:
                    rc = ib_hook_conndata_register(
                        ib,
                        (ib_state_event_type_t)event,
                        mod_perf_stats_event_stop_conndata_callback,
                        (void *)eventp
                                                   );
                    break;
                case IB_STATE_HOOK_TX:
                    rc = ib_hook_tx_register(
                        ib,
                        (ib_state_event_type_t)event,
                        mod_perf_stats_event_stop_tx_callback,
                        (void *)eventp
                                             );
                    break;
                case IB_STATE_HOOK_TXDATA:
                    rc = ib_hook_txdata_register(
                        ib,
                        (ib_state_event_type_t)event,
                        mod_perf_stats_event_stop_txdata_callback,
                        (void *)eventp
                                                 );
                    break;
                default:
                    rc = IB_EINVAL;
                    ib_log_error(ib, "Event with unknown hook type: %d/%s",
                                 eventp->number, eventp->name);

            }
        }

        if (rc != IB_OK) {
            ib_log_error(ib, "Hook register for "
                         "event:%d name:%s cbdata_type: %d returned %s",
                         eventp->number, eventp->name,
                         eventp->cbdata_type, ib_status_to_string(rc));
        }
    }

    IB_FTRACE_RET_STATUS(IB_OK);
}
Пример #18
0
/**
 * Handle request_header events for remote IP extraction.
 *
 * Extract the "request_headers" field (a list) from the transactions's
 * data provider instance, then loop through the list, looking for the
 * "X-Forwarded-For"  field.  If found, the first value in the (comma
 * separated) list replaces the local ip address string in the connection
 * object.
 *
 * @param[in] ib IronBee object
 * @param[in,out] tx Transaction object
 * @param[in] event Event type
 * @param[in] cbdata Callback data (module)
 *
 * @returns Status code
 */
static ib_status_t modua_remoteip(ib_engine_t *ib,
                                  ib_tx_t *tx,
                                  ib_state_event_type_t event,
                                  void *cbdata)
{
    assert(ib != NULL);
    assert(tx != NULL);
    assert(tx->var_store != NULL);
    assert(event == request_header_finished_event);

    const ib_module_t    *m = (const ib_module_t *)cbdata;
    ib_field_t           *field = NULL;
    ib_status_t           rc = IB_OK;
    const ib_bytestr_t   *bs;
    const uint8_t        *data;
    size_t                len;
    char                 *buf;
    uint8_t              *comma;
    const ib_list_t      *list;
    const ib_list_node_t *node;
    const ib_field_t     *forwarded;
    uint8_t              *stripped;
    size_t                num;
    ib_flags_t            flags;
    const modua_config_t *cfg;

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

    ib_log_debug3_tx(tx, "Checking for alternate remote address");

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

    num = ib_list_elements(list);
    if (num == 0) {
        ib_log_debug_tx(tx, "No X-Forwarded-For header found");
        return rc;
    }
    else if (num != 1) {
        ib_log_debug_tx(tx, "%zd X-Forwarded-For headers found: ignoring", num);
        return rc;
    }
    node = ib_list_last_const(list);
    if ( (node == NULL) || (node->data == NULL) ) {
        ib_log_notice_tx(tx, "Invalid X-Forwarded-For header found");
        return rc;
    }
    forwarded = (const ib_field_t *)node->data;

    /* Found it: copy the data into a newly allocated string buffer */
    rc = ib_field_value_type(forwarded,
                             ib_ftype_bytestr_out(&bs),
                             IB_FTYPE_BYTESTR);
    if (rc != IB_OK) {
        ib_log_notice_tx(tx, "Invalid X-Forwarded-For header value");
        return rc;
    }

    if (bs == NULL) {
        ib_log_notice_tx(tx, "X-Forwarded-For header not a bytestr");
        return IB_EINVAL;
    }
    len = ib_bytestr_length(bs);
    data = ib_bytestr_const_ptr(bs);

    /* Search for a comma in the buffer */
    comma = memchr(data, ',', len);
    if (comma != NULL) {
        len = comma - data;
    }

    /* Trim whitespace */
    stripped = (uint8_t *)data;
    rc = ib_strtrim_lr_ex(IB_STROP_INPLACE, tx->mp,
                          stripped, len,
                          &stripped, &len, &flags);
    if (rc != IB_OK) {
        return rc;
    }

    /* Verify that it looks like a valid IP v4/6 address */
    rc = ib_ip_validate_ex((const char *)stripped, len);
    if (rc != IB_OK) {
        ib_log_error_tx(tx,
            "X-Forwarded-For \"%.*s\" is not a valid IP address",
            (int)len, stripped
        );
        return IB_OK;
    }

    /* Allocate memory for copy of stripped string */
    buf = (char *)ib_mpool_alloc(tx->mp, len+1);
    if (buf == NULL) {
        ib_log_error_tx(tx,
                        "Failed to allocate %zd bytes for remote address",
                        len+1);
        return IB_EALLOC;
    }

    /* Copy the string out */
    memcpy(buf, stripped, len);
    buf[len] = '\0';

    ib_log_debug_tx(tx, "Remote address changed to \"%s\"", buf);

    /* This will lose the pointer to the original address
     * buffer, but it should be cleaned up with the rest
     * of the memory pool. */
    tx->er_ipstr = buf;

    /* Update the remote address field in the tx collection */
    rc = ib_field_create_bytestr_alias(
        &field,
        tx->mp,
        "", 0,
        (uint8_t *)buf, len
    );
    if (rc != IB_OK) {
        ib_log_error_tx(tx, "Failed to create field for remote_addr: %s",
                        ib_status_to_string(rc));
        return rc;
    }
    rc = ib_var_source_set(cfg->remote_addr, tx->var_store, field);
    if (rc != IB_OK) {
        ib_log_error_tx(tx,
                        "Failed to set remote address var: %s",
                        ib_status_to_string(rc));
        return rc;
    }

    return IB_OK;
}
Пример #19
0
/**
 * Ironbee initialisation function.  Sets up engine and logging,
 * and reads Ironbee config.
 *
 * @param[in]  cf     Configuration rec
 * @return     NGX_OK or error
 */
static ngx_int_t ironbee_init(ngx_conf_t *cf)
{
    ngx_log_t *prev_log;
    ib_context_t *ctx;
    ib_cfgparser_t *cp;
    ironbee_proc_t *proc;
    ib_status_t rc, rc1;

    prev_log = ngxib_log(cf->log);
    ngx_regex_malloc_init(cf->pool);

    ngx_log_error(NGX_LOG_NOTICE, cf->log, 0, "ironbee_init %d", getpid());

    proc = ngx_http_conf_get_module_main_conf(cf, ngx_ironbee_module);
    if (proc->loglevel == NGX_CONF_UNSET_UINT)
        proc->loglevel = 4; /* default */

    rc = ib_initialize();
    if (rc != IB_OK)
        cleanup_return(prev_log) IB2NG(rc);

    ib_util_log_level(proc->loglevel);

    rc = ib_engine_create(&ironbee, ngxib_server());
    if (rc != IB_OK)
        cleanup_return(prev_log) IB2NG(rc);

    if (proc->use_ngxib_logger)
        ib_log_set_logger_fn(ironbee, ngxib_logger, NULL);
    /* Using default log level function. */

    rc = ib_engine_init(ironbee);
    if (rc != IB_OK)
        cleanup_return(prev_log) IB2NG(rc);

    /* TODO: TS creates logfile at this point */

    ib_hook_conn_register(ironbee, conn_opened_event, ngxib_conn_init, NULL);

    rc = ib_cfgparser_create(&cp, ironbee);
    assert((cp != NULL) || (rc != IB_OK));
    if (rc != IB_OK)
        cleanup_return(prev_log) IB2NG(rc);

    rc = ib_engine_config_started(ironbee, cp);
    if (rc != IB_OK)
        cleanup_return(prev_log) IB2NG(rc);

    /* Get the main context, set some defaults */
    ctx = ib_context_main(ironbee);
    ib_context_set_num(ctx, "logger.log_level", proc->loglevel);

    /* FIXME - use the temp pool operation for this */
    char *buf = strndup((char*)proc->config_file.data, proc->config_file.len);
    rc = ib_cfgparser_parse(cp, buf);
    free(buf);
    rc1 = ib_engine_config_finished(ironbee);
    ib_cfgparser_destroy(cp);

    cleanup_return(prev_log) rc == IB_OK ? rc1 == IB_OK ? NGX_OK : IB2NG(rc1) : IB2NG(rc);
}
Пример #20
0
static
ib_status_t sqli_dir_fingerprint_set(
    ib_cfgparser_t *cp,
    const char     *directive_name,
    const char     *set_name,
    const char     *set_path,
    void           *cbdata
)
{
    assert(cp             != NULL);
    assert(directive_name != NULL);
    assert(set_name       != NULL);
    assert(set_path       != NULL);

    ib_status_t             rc;
    ib_context_t           *ctx = NULL;
    ib_module_t            *m   = NULL;
    sqli_module_config_t   *cfg = NULL;
    sqli_fingerprint_set_t *ps  = NULL;
    ib_mm_t                 mm;
    char                   *abs_set_path = NULL;

    rc = ib_cfgparser_context_current(cp, &ctx);
    assert(rc  == IB_OK);
    assert(ctx != NULL);

    if (ctx != ib_context_main(cp->ib)) {
        ib_cfg_log_error(cp,
            "%s: Only valid at main context.", directive_name
        );
        return IB_EINVAL;
    }

    if (strcmp("default", set_name) == 0) {
        ib_cfg_log_error(cp,
            "%s: default is a reserved set name.", directive_name
        );
        return IB_EINVAL;
    }

    mm = ib_engine_mm_main_get(cp->ib);

    rc = ib_engine_module_get(
        ib_context_get_engine(ctx),
        MODULE_NAME_STR,
        &m
    );
    assert(rc == IB_OK);

    rc = ib_context_module_config(ctx, m, &cfg);
    assert(rc == IB_OK);

    if (cfg->fingerprint_sets == NULL) {
        rc = ib_hash_create(&cfg->fingerprint_sets, mm);
        assert(rc == IB_OK);
    }
    assert(cfg->fingerprint_sets != NULL);

    rc = ib_hash_get(cfg->fingerprint_sets, NULL, set_name);
    if (rc == IB_OK) {
        ib_cfg_log_error(cp,
            "%s: Duplicate fingerprint set definition: %s",
            directive_name, set_name
        );
        return IB_EINVAL;
    }
    assert(rc == IB_ENOENT);

    abs_set_path = ib_util_relative_file(
        ib_engine_mm_config_get(cp->ib),
        ib_cfgparser_curr_file(cp),
        set_path
    );
    if (abs_set_path == NULL) {
        return IB_EALLOC;
    }

    rc = sqli_create_fingerprint_set_from_file(&ps, abs_set_path, mm);
    if (rc != IB_OK) {
        ib_cfg_log_error(cp,
            "%s: Failure to load fingerprint set from file: %s",
            directive_name, abs_set_path
        );
        return IB_EINVAL;
    }
    assert(ps != NULL);

    rc = ib_hash_set(cfg->fingerprint_sets, ib_mm_strdup(mm, set_name), ps);
    assert(rc == IB_OK);

    return IB_OK;
}
Пример #21
0
/**
 * Main identity handler.  Called both on request_header_finished and
 * request_finished: the configured provider decides which state to
 * run on, and skips (returns immediately) on the other state.
 *
 * If configured mode is "Off", just returns.  Otherwise calls provider's
 * check_id function to check and log user ID. Optionally cycles through
 * other providers.  Finally, if client is not identified and mode is
 * "Require", calls provider's challenge function to ask client to
 * identify (e.g. HTTP 401).
 *
 * @param ib The engine
 * @param tx The transaction
 * @param state State that triggered the call
 * @param cbdata Unused
 */
static ib_status_t ident_handler(ib_engine_t *ib, ib_tx_t *tx,
                                 ib_state_t state,
                                 void *cbdata)
{
    ident_cfg_t *cfg;
    const char *userid = NULL;
    ib_ident_provider_t *provider;
    ib_status_t rc;
    ib_module_t *m;

    assert(state == request_header_finished_state || state == request_finished_state);

    rc = ib_engine_module_get(ib, MODULE_NAME_STR, &m);
    assert((rc == IB_OK) && (m != NULL));
    rc = ib_context_module_config(ib_context_main(ib), m, &cfg);
    assert((rc == IB_OK) && (cfg != NULL));

    if (cfg->mode == ident_off) {
        return IB_OK;
    }
    if (cfg->type != NULL && cfg->providers != NULL) {
        rc = ib_hash_get(cfg->providers, &provider, cfg->type);
        if (rc != IB_OK || provider == NULL) {
            ib_log_error_tx(tx, "Identifier '%s' configured but not available", cfg->type);
            provider = &ident_dummy_provider;
        }
    }
    else {
        ib_log_error_tx(tx, "Ident module loaded but not configured!");
        provider = &ident_dummy_provider;
    }

    if (provider->state != state) {
        /* This provider doesn't check now */
        return IB_OK;
    }

    /* OK, ident is on.  Verify if there is a user ID */
    userid = provider->check_id(tx);

    if (userid == NULL && cfg->accept_any && cfg->providers != NULL) {
        ib_hash_iterator_t *iterator = ib_hash_iterator_create(tx->mm);
        ib_ident_provider_t *p;
        for (ib_hash_iterator_first(iterator, cfg->providers);
             !userid && !ib_hash_iterator_at_end(iterator);
             ib_hash_iterator_next(iterator)) {
            ib_hash_iterator_fetch(NULL, NULL, &p, iterator);
            /* configured provider already checked - so skip it now */
            if (p->check_id != provider->check_id) {
                userid = p->check_id(tx);
            }
        }
    }

    if (userid != NULL) {
        ib_log_info(ib, "User identified as %s", userid);
        return IB_OK;
    }

    /* If we haven't configured an ident type, don't enforce */
    if (cfg->type == NULL) {
        return IB_OK;
    }

    /* If we're enforcing ident, send a challenge */
    return provider->challenge(tx);
}
Пример #22
0
static int ironbee_init(const char *configfile, const char *logfile)
{
  /* grab from httpd module's post-config */
  ib_status_t rc;
//  ib_provider_t *lpr;
  ib_cfgparser_t *cp;
  ib_context_t *ctx;
  int rv;

  rc = ib_initialize();
  if (rc != IB_OK) {
    return rc;
  }

  ib_util_log_level(9);

  ib_trace_init(TRACEFILE);

  rc = ib_engine_create(&ironbee, &ibplugin);
  if (rc != IB_OK) {
    return rc;
  }

  rc = ib_provider_register(ironbee, IB_PROVIDER_TYPE_LOGGER, "ironbee-ts",
                            NULL, &ironbee_logger_iface, NULL);
  if (rc != IB_OK) {
    return rc;
  }

  ib_context_set_string(ib_context_engine(ironbee),
                        IB_PROVIDER_TYPE_LOGGER, "ironbee-ts");
  ib_context_set_num(ib_context_engine(ironbee),
                     IB_PROVIDER_TYPE_LOGGER ".log_level", 4);

  rc = ib_engine_init(ironbee);
  if (rc != IB_OK) {
    return rc;
  }

  /* success is documented as TS_LOG_ERROR_NO_ERROR but that's undefined.
   * It's actually a TS_SUCCESS (proxy/InkAPI.cc line 6641).
   */
  rv = TSTextLogObjectCreate(logfile, TS_LOG_MODE_ADD_TIMESTAMP, &ironbee_log);
  if (rv != TS_SUCCESS) {
    return IB_OK + rv;
  }
   
  rc = atexit(ibexit);
  if (rc != 0) {
    return IB_OK + rv;
  }

  ib_hook_register(ironbee, conn_opened_event,
                   (ib_void_fn_t)ironbee_conn_init, NULL);


  ib_state_notify_cfg_started(ironbee);
  ctx = ib_context_main(ironbee);

  ib_context_set_string(ctx, IB_PROVIDER_TYPE_LOGGER, "ironbee-ts");
  ib_context_set_num(ctx, "logger.log_level", 4);

  rc = ib_cfgparser_create(&cp, ironbee);
  if (rc != IB_OK) {
    return rc;
  }
  if (cp != NULL) {  // huh?
    ib_cfgparser_parse(cp, configfile);
    ib_cfgparser_destroy(cp);
  }
  ib_state_notify_cfg_finished(ironbee);


  return IB_OK;
}
Пример #23
0
TEST_F(OperatorTest, OperatorCallTest)
{
    ib_status_t status;
    ib_num_t call_result;
    void *instance_data;
    ib_operator_t *op;
    const ib_operator_t *cop;

    status = ib_operator_create_and_register(
        &op,
        ib_engine,
        "test_op",
        IB_OP_CAPABILITY_NON_STREAM,
        test_create_fn, NULL,
        NULL, NULL,
        test_execute_fn, NULL
    );
    ASSERT_EQ(IB_OK, status);

    status = ib_operator_lookup(ib_engine, "test_op", &cop);

    ASSERT_EQ(IB_OK, status);

    status = ib_operator_inst_create(op,
                                     ib_context_main(ib_engine),
                                     IB_OP_CAPABILITY_NON_STREAM,
                                     "INVALID",
                                     &instance_data);
    ASSERT_EQ(IB_EINVAL, status);

    status = ib_operator_inst_create(op,
                                     ib_context_main(ib_engine),
                                     IB_OP_CAPABILITY_NON_STREAM,
                                     "data",
                                     &instance_data);
    ASSERT_EQ(IB_OK, status);


    ib_field_t *field;
    const char *matching = "data matching string";
    const char *nonmatching = "non matching string";
    ib_field_create(
        &field,
        ib_engine_pool_main_get(ib_engine),
        IB_FIELD_NAME("testfield"),
        IB_FTYPE_NULSTR,
        NULL
    );

    ib_field_setv(field, ib_ftype_nulstr_in(matching));
    status = ib_operator_inst_execute(op, instance_data, ib_tx, field, NULL, &call_result);
    ASSERT_EQ(IB_OK, status);
    EXPECT_EQ(1, call_result);

    ib_field_setv(field, ib_ftype_nulstr_in(nonmatching));
    status = ib_operator_inst_execute(op, instance_data, ib_tx, field, NULL, &call_result);
    ASSERT_EQ(IB_OK, status);
    EXPECT_EQ(0, call_result);

    status = ib_operator_inst_destroy(op, instance_data);
    ASSERT_EQ(IB_OK, status);
}
Пример #24
0
/**
 * Initializes and configures the ironbee engine.
 */
static int ironbee_post_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptmp,
                             server_rec *s)
{
    ironbee_config_t *modcfg =
        (ironbee_config_t *)ap_get_module_config(s->module_config,
                                                 &ironbee_module);
    ib_cfgparser_t *cp;
    ib_provider_t *lpr;
    void *init = NULL;
    ib_status_t rc;


    /* Init IB library. */
    rc = ib_initialize();
    if (rc != IB_OK) {
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
                     IB_PRODUCT_NAME ": Error initializing ib library");
        return OK;
    }

    ib_util_log_level(4);

    /* Detect first (validation) run vs real config run. */
    apr_pool_userdata_get(&init, "ironbee-init", s->process->pool);
    if (init == NULL) {
        ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,
                     MODULE_NAME_FULL " loading.");

        apr_pool_userdata_set((const void *)1, "ironbee-init",
                              apr_pool_cleanup_null, s->process->pool);

        return OK;
    }

    /// @todo Tracefile needs removed
    //ib_trace_init("/tmp/ironbee.trace");
    ib_trace_init(NULL);

    /* Create the engine handle. */
    rc = ib_engine_create(&ironbee, &ibplugin);
    if (rc != IB_OK) {
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
                     IB_PRODUCT_NAME ": Error creating engine: %d", rc);
        return OK;
    }

    /* Register the logger. */
    rc = ib_provider_register(ironbee, IB_PROVIDER_TYPE_LOGGER,
                              MODULE_NAME_STR, &lpr,
                              &ironbee_logger_iface,
                              NULL);
    if (rc != IB_OK) {
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
                     IB_PRODUCT_NAME ": Error registering log provider: %d", rc);
        return OK;
    }
    ib_provider_data_set(lpr, (void *)s);

    /* Default logger */
    /// @todo Need to add a post set hook in core for this to work correctly
    ib_context_set_string(ib_context_engine(ironbee),
                          IB_PROVIDER_TYPE_LOGGER,
                          MODULE_NAME_STR);
    ib_context_set_num(ib_context_engine(ironbee),
                       IB_PROVIDER_TYPE_LOGGER ".log_level",
                       4);


    rc = ib_engine_init(ironbee);
    if (rc != IB_OK) {
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
                     IB_PRODUCT_NAME ": Error initializing engine: %d", rc);
        return OK;
    }

    /* Register module cleanup. */
    apr_pool_cleanup_register(p, (void *)s, ironbee_module_cleanup,
                              apr_pool_cleanup_null);

    /* Register conn/tx init hooks. */
    ib_hook_register(ironbee, conn_opened_event,
                     (ib_void_fn_t)ironbee_conn_init, s);

    /* Configure the engine. */
    if (modcfg->config != NULL) {
        ib_context_t *ctx;

        /* Notify the engine that the config process has started. This
         * will also create a main configuration context.
         */
        ib_state_notify_cfg_started(ironbee);

        /* Get the main configuration context. */
        ctx = ib_context_main(ironbee);

        /* Set some defaults */
        ib_context_set_string(ctx, IB_PROVIDER_TYPE_LOGGER, MODULE_NAME_STR);
        ib_context_set_num(ctx, "logger.log_level", 4);

        /* Parse the config file. */
        rc = ib_cfgparser_create(&cp, ironbee);
        if ((rc == IB_OK) && (cp != NULL)) {
            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
                         IB_PRODUCT_NAME ": Parsing config: %s",
                         modcfg->config);
            ib_cfgparser_parse(cp, modcfg->config);
            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
                         IB_PRODUCT_NAME ": Destroying config parser");
            ib_cfgparser_destroy(cp);
        }

        /* Notify the engine that the config process has finished. This
         * will also close out the main configuration context.
         */
        ib_state_notify_cfg_finished(ironbee);
    }
    else {
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
                     IB_PRODUCT_NAME ": No config specified with IronBeeConfig directive");
    }

    ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, s,
                 MODULE_NAME_FULL " configured.");

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

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

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

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

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

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

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

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