ib_status_t ib_ctxsel_registration_register( ib_engine_t *ib, const ib_ctxsel_registration_t *registration) { if ( (ib == NULL) || (registration == NULL) || (registration->module == NULL) || (registration->select_fn == NULL) ) { return IB_EINVAL; } if (registration->module == ib_core_module()) { if (ib->core_ctxsel.module != NULL) { return IB_DECLINED; } ctxsel_store(&ib->core_ctxsel, registration); } /* If it's not the core module, don't allow a second registrant */ else if (ib->act_ctxsel.module != ib_core_module()) { return IB_DECLINED; } ctxsel_store(&ib->act_ctxsel, registration); return IB_OK; }
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(); }
void ib_vclog_ex(ib_context_t *ctx, int level, const char *prefix, const char *file, int line, const char *fmt, va_list ap) { IB_FTRACE_INIT(ib_vclog_ex); IB_PROVIDER_API_TYPE(logger) *api; ib_core_cfg_t *corecfg; ib_provider_inst_t *pi = NULL; ib_status_t rc; char prefix_with_pid[1024]; if (prefix != NULL) { snprintf(prefix_with_pid, 1024, "[%d] %s", getpid(), prefix); } else { snprintf(prefix_with_pid, 1024, "[%d] ", getpid()); } 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, prefix_with_pid, file, line, fmt, ap); IB_FTRACE_RET_VOID(); }
ib_status_t ib_ctxsel_unregister( ib_engine_t *ib, const ib_module_t *module) { assert(ib != NULL); assert(ib->core_ctxsel.module == ib_core_module()); /* Don't allow core to unregister. */ if (module == ib_core_module()) { return IB_DECLINED; } /* Verify that this is the current module */ else if (module != ib->act_ctxsel.module) { return IB_DECLINED; } /* Revert to the the core's functions */ ctxsel_store(&ib->act_ctxsel, &ib->core_ctxsel); return IB_OK; }
ib_provider_inst_t *ib_log_provider_get_instance(ib_context_t *ctx) { IB_FTRACE_INIT(); ib_core_cfg_t *corecfg; ib_status_t rc; rc = ib_context_module_config(ctx, ib_core_module(), (void *)&corecfg); if (rc != IB_OK) { IB_FTRACE_RET_PTR(ib_provider_inst_t, NULL); } IB_FTRACE_RET_PTR(ib_provider_inst_t, corecfg->pi.logger); }
ib_status_t ib_parser_provider_set_instance(ib_context_t *ctx, ib_provider_inst_t *pi) { IB_FTRACE_INIT(); ib_core_cfg_t *corecfg; ib_status_t rc; rc = ib_context_module_config(ctx, ib_core_module(), (void *)&corecfg); if (rc != IB_OK) { IB_FTRACE_RET_STATUS(rc); } corecfg->pi.parser = pi; IB_FTRACE_RET_STATUS(rc); }
void ib_log_provider_set_instance(ib_context_t *ctx, ib_provider_inst_t *pi) { IB_FTRACE_INIT(); ib_core_cfg_t *corecfg; ib_status_t rc; rc = ib_context_module_config(ctx, ib_core_module(), (void *)&corecfg); if (rc != IB_OK) { /// @todo This func should return ib_status_t now IB_FTRACE_RET_VOID(); } corecfg->pi.logger = pi; IB_FTRACE_RET_VOID(); }
/** * @internal * * "Sniffs" the output (response) data from the connection stream. */ static int ironbee_output_filter (ap_filter_t *f, apr_bucket_brigade *bb) { apr_bucket *b; #if 0 conn_rec *c = f->c; ironbee_conn_context *ctx = f->ctx; ib_conn_t *iconn = ctx->iconn; ib_core_cfg_t *corecfg; int buffering = 0; /* Configure. */ ib_context_module_config(iconn->ctx, ib_core_module(), (void *)&corecfg); if (corecfg != NULL) { buffering = (int)corecfg->buffer_res; } #endif for (b = APR_BRIGADE_FIRST(bb); b != APR_BRIGADE_SENTINEL(bb); b = APR_BUCKET_NEXT(b)) { #if 0 /// @todo Should this be done? Maybe only for proxy? if (APR_BUCKET_IS_EOS(b)) { /// @todo Do we need to do this? Maybe only for proxy. apr_bucket *flush = apr_bucket_flush_create(f->c->bucket_alloc); APR_BUCKET_INSERT_BEFORE(b, flush); } if (buffering) { /// @todo setaside into our own pool to destroy later??? apr_bucket_setaside(b, c->pool); process_bucket(f, b); APR_BUCKET_REMOVE(b); } else { #endif process_bucket(f, b); #if 0 } #endif } return ap_pass_brigade(f->next, bb); }
/** * @internal * * "Sniffs" the input (request) data from the connection stream and tries * to determine who closed a connection and why. */ static int ironbee_input_filter(ap_filter_t *f, apr_bucket_brigade *bb, ap_input_mode_t mode, apr_read_type_e block, apr_off_t readbytes) { conn_rec *c = f->c; ironbee_conn_context *ctx = f->ctx; ib_conn_t *iconn = ctx->iconn; ib_core_cfg_t *corecfg; ib_stream_t *istream; apr_bucket *b; apr_status_t rc; int buffering = 0; /* Any mode not handled just gets passed through. */ if ((mode != AP_MODE_GETLINE) && (mode != AP_MODE_READBYTES)) { return ap_get_brigade(f->next, bb, mode, block, readbytes); } /* Configure. */ ib_context_module_config(iconn->ctx, ib_core_module(), (void *)&corecfg); if (corecfg != NULL) { buffering = (int)corecfg->buffer_req; } /* When buffering, data is removed from the brigade and handed * to IronBee. The filter must not return an empty brigade in this * case and keeps reading until there is processed data that comes * back from IronBee. */ do { ib_tx_t *itx = iconn->tx; /* If there is any processed data, then send it now. */ if (buffering && (itx != NULL)) { ib_sdata_t *sdata; /* Take any data from the drain (processed data) and * inject it back into the filter brigade. */ ib_fctl_drain(itx->fctl, &istream); if ((istream != NULL) && (istream->nelts > 0)) { int done = 0; while (!done) { apr_bucket *ibucket = NULL; /// @todo Handle multi-bucket lines if (mode == AP_MODE_GETLINE) { done = 1; } ib_stream_pull(istream, &sdata); if (sdata == NULL) { /* No more data left. */ break; } switch (sdata->type) { case IB_STREAM_DATA: #ifdef IB_DEBUG ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, IB_PRODUCT_NAME ": DATA[%d]: %.*s", (int)sdata->dlen, (int)sdata->dlen, (char *)sdata->data); #endif /// @todo Is this creating a copy? Just need a reference. ibucket = apr_bucket_heap_create(sdata->data, sdata->dlen, NULL, bb->bucket_alloc); break; case IB_STREAM_FLUSH: #ifdef IB_DEBUG ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, IB_PRODUCT_NAME ": FLUSH"); #endif ibucket = apr_bucket_flush_create(bb->bucket_alloc); break; case IB_STREAM_EOH: #ifdef IB_DEBUG ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, IB_PRODUCT_NAME ": EOH"); #endif /// @todo Do something here??? break; case IB_STREAM_EOB: #ifdef IB_DEBUG ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, IB_PRODUCT_NAME ": EOB"); #endif /// @todo Do something here??? break; case IB_STREAM_EOS: #ifdef IB_DEBUG ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, IB_PRODUCT_NAME ": EOS"); #endif ibucket = apr_bucket_eos_create(bb->bucket_alloc); break; default: ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, IB_PRODUCT_NAME ": UNKNOWN stream data type %d", sdata->type); } if (ibucket != NULL) { APR_BRIGADE_INSERT_TAIL(bb, ibucket); } } /* Need to send any processed data to avoid deadlock. */ if (!APR_BRIGADE_EMPTY(bb)) { return APR_SUCCESS; } } } /* Fetch data from the next filter. */ if (buffering) { ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "FETCH BRIGADE (buffering)"); /* Normally Apache will request the headers line-by-line, but * IronBee does not require this. So, here the request is * fetched with READBYTES and IronBee will then break * it back up into lines when it is injected back into * the brigade after the data is processed. */ rc = ap_get_brigade(f->next, bb, AP_MODE_READBYTES, block, HUGE_STRING_LEN); } else { ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "FETCH BRIGADE (non-buffering)"); rc = ap_get_brigade(f->next, bb, mode, block, readbytes); } /* Check for any timeouts/disconnects/errors. */ if (APR_STATUS_IS_TIMEUP(rc)) { ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, IB_PRODUCT_NAME ": %s server closed connection (%d)", f->frec->name, rc); ap_remove_input_filter(f); return rc; } else if (APR_STATUS_IS_EOF(rc) || apr_get_os_error() == ECONNRESET) { ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, IB_PRODUCT_NAME ": %s client closed connection (%d)", f->frec->name, rc); ap_remove_input_filter(f); return rc; } else if (rc != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, IB_PRODUCT_NAME ": %s returned %d (0x%08x) - %s", f->frec->name, rc, rc, strerror(apr_get_os_error())); return rc; } /* Process data. */ for (b = APR_BRIGADE_FIRST(bb); b != APR_BRIGADE_SENTINEL(bb); b = APR_BUCKET_NEXT(b)) { if (buffering) { /// @todo setaside into our own pool to destroy later??? apr_bucket_setaside(b, c->pool); process_bucket(f, b); APR_BUCKET_REMOVE(b); } else { process_bucket(f, b); } } } while (buffering); return APR_SUCCESS; }
ib_status_t core_audit_close(ib_provider_inst_t *lpi, ib_auditlog_t *log) { IB_FTRACE_INIT(); core_audit_cfg_t *cfg = (core_audit_cfg_t *)log->cfg_data; ib_core_cfg_t *corecfg; ib_status_t ib_rc; int sys_rc; char line[IB_LOGFORMAT_MAXLINELEN + 2]; int line_size = 0; /* Retrieve corecfg to get the AuditLogIndexFormat */ ib_rc = ib_context_module_config(log->ctx, ib_core_module(), &corecfg); if (ib_rc != IB_OK) { ib_log_alert(log->ib, "Failure accessing core module: %s", ib_status_to_string(ib_rc)); IB_FTRACE_RET_STATUS(ib_rc); } /* Close the audit log. */ if (cfg->fp != NULL) { fclose(cfg->fp); //rename temp to real sys_rc = rename(cfg->temp_path, cfg->full_path); if (sys_rc != 0) { sys_rc = errno; ib_log_error(log->ib, "Error renaming auditlog %s: %s (%d)", cfg->temp_path, strerror(sys_rc), sys_rc); IB_FTRACE_RET_STATUS(IB_EOTHER); } ib_log_info(log->ib, "AUDITLOG: %s", cfg->full_path); cfg->fp = NULL; } /* Write to the index file if using one. */ if ((cfg->index_fp != NULL) && (cfg->parts_written > 0)) { ib_lock_lock(&log->ctx->auditlog->index_fp_lock); ib_rc = core_audit_get_index_line(lpi, log, line, &line_size); if (ib_rc != IB_OK) { ib_lock_unlock(&log->ctx->auditlog->index_fp_lock); IB_FTRACE_RET_STATUS(ib_rc); } sys_rc = fwrite(line, line_size, 1, cfg->index_fp); if (sys_rc < 0) { sys_rc = errno; ib_log_error(log->ib, "Could not write to audit log index: %s (%d)", strerror(sys_rc), sys_rc); /// @todo Should retry (a piped logger may have died) fclose(cfg->index_fp); cfg->index_fp = NULL; log->ctx->auditlog->index_fp = cfg->index_fp; ib_lock_unlock(&log->ctx->auditlog->index_fp_lock); IB_FTRACE_RET_STATUS(IB_OK); } fflush(cfg->index_fp); ib_lock_unlock(&log->ctx->auditlog->index_fp_lock); } IB_FTRACE_RET_STATUS(IB_OK); }
ib_status_t core_audit_get_index_line(ib_provider_inst_t *lpi, ib_auditlog_t *log, char *line, int *line_size) { IB_FTRACE_INIT(); core_audit_cfg_t *cfg = (core_audit_cfg_t *)log->cfg_data; ib_core_cfg_t *corecfg; ib_tx_t *tx = log->tx; ib_conn_t *conn = tx->conn; ib_site_t *site = ib_context_site_get(log->ctx); const ib_logformat_t *lf; ib_status_t rc; char *ptr = line; char *tstamp = NULL; uint8_t which; int i = 0; int l = 0; int used = 0; const char *aux = NULL; /* Retrieve corecfg to get the AuditLogIndexFormat */ rc = ib_context_module_config(log->ctx, ib_core_module(), (void *)&corecfg); if (rc != IB_OK) { IB_FTRACE_RET_STATUS(rc); } lf = corecfg->auditlog_index_hp; which = lf->literal_starts ? 1 : 0; for (; (i < lf->field_cnt || l < lf->literal_cnt) && used < IB_LOGFORMAT_MAXLINELEN;) { if (which++ % 2 == 0) { int aux_i = 0; switch (lf->fields[i]) { case IB_LOG_FIELD_REMOTE_ADDR: aux = tx->er_ipstr; break; case IB_LOG_FIELD_LOCAL_ADDR: aux = conn->local_ipstr; break; case IB_LOG_FIELD_HOSTNAME: aux = tx->hostname; break; case IB_LOG_FIELD_SITE_ID: if (site == NULL) { aux = (char *)"-"; } else { aux = site->id_str; } break; case IB_LOG_FIELD_SENSOR_ID: aux = log->ib->sensor_id_str; break; case IB_LOG_FIELD_TRANSACTION_ID: aux = tx->id; break; case IB_LOG_FIELD_TIMESTAMP: /* Prepare timestamp (only if needed) */ tstamp = (char *)ib_mpool_alloc(log->mp, 30); if (tstamp == NULL) { IB_FTRACE_RET_STATUS(IB_EALLOC); } ib_clock_timestamp(tstamp, &tx->tv_created); aux = tstamp; break; case IB_LOG_FIELD_LOG_FILE: aux = cfg->fn; break; default: ptr[used++] = '\n'; /* Not understood */ IB_FTRACE_RET_STATUS(IB_EINVAL); break; } for (; aux != NULL && aux[aux_i] != '\0';) { if (used < IB_LOGFORMAT_MAXLINELEN) { ptr[used++] = aux[aux_i++]; } else { ptr[used++] = '\n'; IB_FTRACE_RET_STATUS(IB_ETRUNC); } } ++i; } else { /* Use literals */ if (used + lf->literals_len[l] < IB_LOGFORMAT_MAXLINELEN) { memcpy(&ptr[used], lf->literals[l], lf->literals_len[l]); used += lf->literals_len[l]; ++l; } else { /* Truncated.. */ ptr[used++] = '\n'; IB_FTRACE_RET_STATUS(IB_ETRUNC); } } } ptr[used++] = '\n'; *line_size = used; IB_FTRACE_RET_STATUS(IB_OK); }
ib_status_t core_audit_open(ib_provider_inst_t *lpi, ib_auditlog_t *log) { IB_FTRACE_INIT(); core_audit_cfg_t *cfg = (core_audit_cfg_t *)log->cfg_data; ib_core_cfg_t *corecfg; ib_status_t rc; /* Non const struct we will build and then assign to * corecfg->auditlog_index_hp. */ ib_logformat_t *auditlog_index_hp; assert(NULL != lpi); assert(NULL != log); assert(NULL != log->ctx); assert(NULL != log->ctx->auditlog); rc = ib_context_module_config(log->ctx, ib_core_module(), (void *)&corecfg); if (rc != IB_OK) { ib_log_error(log->ib, "Could not fetch core configuration: %s", ib_status_to_string(rc) ); IB_FTRACE_RET_STATUS(rc); } assert(NULL != corecfg); /* Copy the FILE* into the core_audit_cfg_t. */ if (log->ctx->auditlog->index_fp != NULL) { cfg->index_fp = log->ctx->auditlog->index_fp; } /* If we have a file name but no file pointer, assign cfg->index_fp. */ else if ((log->ctx->auditlog->index != NULL) && (cfg->index_fp == NULL)) { /** * Open the audit log index file. If the file name starts with * a | a pipe is opened to a subprocess, etc... */ rc = core_audit_open_auditindexfile(lpi, log, cfg, corecfg); if (rc != IB_OK) { ib_log_error(log->ib, "Could not open auditlog index."); IB_FTRACE_RET_STATUS(rc); } } /* Open audit file that contains the record identified by the line * written in index_fp. */ if (cfg->fp == NULL) { rc = core_audit_open_auditfile(lpi, log, cfg, corecfg); if (rc!=IB_OK) { ib_log_error(log->ib, "Failed to open audit log file."); IB_FTRACE_RET_STATUS(rc); } } /* Set the Audit Log index format */ if (corecfg->auditlog_index_hp == NULL) { rc = ib_logformat_create(log->ib->mp, &auditlog_index_hp); if (rc != IB_OK) { IB_FTRACE_RET_STATUS(rc); } if (corecfg->auditlog_index_fmt != NULL) { rc = ib_logformat_set(auditlog_index_hp, corecfg->auditlog_index_fmt); } else { rc = ib_logformat_set(auditlog_index_hp, IB_LOGFORMAT_DEFAULT); } if (rc != IB_OK) { IB_FTRACE_RET_STATUS(rc); } /* Commit built struct. */ corecfg->auditlog_index_hp = auditlog_index_hp; } IB_FTRACE_RET_STATUS(IB_OK); }