/** * \brief Create a new LogFileCtx for "drop" output style. * \param conf The configuration node for this output. * \return A LogFileCtx pointer on success, NULL on failure. */ static OutputCtx *LogDropLogInitCtx(ConfNode *conf) { if (OutputDropLoggerEnable() != 0) { SCLogError(SC_ERR_CONF_YAML_ERROR, "only one 'drop' logger " "can be enabled"); return NULL; } LogFileCtx *logfile_ctx = LogFileNewCtx(); if (logfile_ctx == NULL) { SCLogDebug("LogDropLogInitCtx: Could not create new LogFileCtx"); return NULL; } if (SCConfLogOpenGeneric(conf, logfile_ctx, DEFAULT_LOG_FILENAME, 1) < 0) { LogFileFreeCtx(logfile_ctx); return NULL; } OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx)); if (unlikely(output_ctx == NULL)) { LogFileFreeCtx(logfile_ctx); return NULL; } output_ctx->data = logfile_ctx; output_ctx->DeInit = LogDropLogDeInitCtx; return output_ctx; }
OutputCtx *OutputNetFlowLogInit(ConfNode *conf) { SCLogInfo("hi"); LogFileCtx *file_ctx = LogFileNewCtx(); if(file_ctx == NULL) { SCLogError(SC_ERR_NETFLOW_LOG_GENERIC, "couldn't create new file_ctx"); return NULL; } if (SCConfLogOpenGeneric(conf, file_ctx, DEFAULT_LOG_FILENAME, 1) < 0) { LogFileFreeCtx(file_ctx); return NULL; } LogJsonFileCtx *flow_ctx = SCMalloc(sizeof(LogJsonFileCtx)); if (unlikely(flow_ctx == NULL)) { LogFileFreeCtx(file_ctx); return NULL; } OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx)); if (unlikely(output_ctx == NULL)) { LogFileFreeCtx(file_ctx); SCFree(flow_ctx); return NULL; } flow_ctx->file_ctx = file_ctx; output_ctx->data = flow_ctx; output_ctx->DeInit = OutputNetFlowLogDeinit; return output_ctx; }
static OutputInitResult OutputFlowLogInit(ConfNode *conf) { OutputInitResult result = { NULL, false }; LogFileCtx *file_ctx = LogFileNewCtx(); if(file_ctx == NULL) { SCLogError(SC_ERR_FLOW_LOG_GENERIC, "couldn't create new file_ctx"); return result; } if (SCConfLogOpenGeneric(conf, file_ctx, DEFAULT_LOG_FILENAME, 1) < 0) { LogFileFreeCtx(file_ctx); return result; } LogJsonFileCtx *flow_ctx = SCMalloc(sizeof(LogJsonFileCtx)); if (unlikely(flow_ctx == NULL)) { LogFileFreeCtx(file_ctx); return result; } OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx)); if (unlikely(output_ctx == NULL)) { LogFileFreeCtx(file_ctx); SCFree(flow_ctx); return result; } flow_ctx->file_ctx = file_ctx; output_ctx->data = flow_ctx; output_ctx->DeInit = OutputFlowLogDeinit; result.ctx = output_ctx; result.ok = true; return result; }
/** * \brief Create a new LogFileCtx for alert debug logging. * * \param ConfNode containing configuration for this logger. * * \return output_ctx if succesful, NULL otherwise */ static OutputCtx *AlertDebugLogInitCtx(ConfNode *conf) { LogFileCtx *file_ctx = NULL; file_ctx = LogFileNewCtx(); if (file_ctx == NULL) { SCLogDebug("couldn't create new file_ctx"); goto error; } if (SCConfLogOpenGeneric(conf, file_ctx, DEFAULT_LOG_FILENAME, 1) < 0) { goto error; } OutputCtx *output_ctx = SCMalloc(sizeof(OutputCtx)); if (unlikely(output_ctx == NULL)) goto error; memset(output_ctx, 0x00, sizeof(OutputCtx)); output_ctx->data = file_ctx; output_ctx->DeInit = AlertDebugLogDeInitCtx; SCLogDebug("Alert debug log output initialized"); return output_ctx; error: if (file_ctx != NULL) { LogFileFreeCtx(file_ctx); } return NULL; }
static OutputCtx *InitCtx(ConfNode *conf, AppProto proto, const char *dft_name) { LogFileCtx *ctx = LogFileNewCtx(); if (ctx == NULL) { SCLogError(SC_ERR_JONS_LOG_GENERIC, "couldn't create new file_ctx"); return NULL; } if (SCConfLogOpenGeneric(conf, ctx, dft_name) < 0) { LogFileFreeCtx(ctx); return NULL; } DBJsonLogCtx *jctx = SCCalloc(sizeof(*jctx) , 1); if (unlikely(jctx == NULL)) { LogFileFreeCtx(ctx); return NULL; } jctx->ctx = ctx; OutputCtx *octx = SCCalloc(1, sizeof(*octx)); if (unlikely(octx == NULL)) { LogFileFreeCtx(ctx); SCFree(jctx); return NULL; } octx->data = jctx; octx->DeInit = DeinitCtx; SCLogDebug("log output initialized"); AppLayerParserRegisterLogger(IPPROTO_TCP, proto); return octx; }
static OutputCtx *JsonMSSqlLogInitCtx(ConfNode *cn) { static char default_11g_log_filename[] = "mssql.json"; LogFileCtx *file_ctx = LogFileNewCtx(); if (!file_ctx) { SCLogError(SC_ERR_MSSQL_LOG_GENERIC, "could not create new file_ctx"); return NULL; } if (SCConfLogOpenGeneric(cn, file_ctx, default_11g_log_filename)) { LogFileFreeCtx(file_ctx); return NULL; } LogMSSqlFileCtx *mssqllog_ctx = SCCalloc(sizeof(*mssqllog_ctx), 1); if (unlikely(!mssqllog_ctx )) { LogFileFreeCtx(file_ctx); return NULL; } mssqllog_ctx->file_ctx = file_ctx; OutputCtx *octx = SCCalloc(1, sizeof(*octx)); if (unlikely(!octx)) { LogFileFreeCtx(file_ctx); SCFree(mssqllog_ctx); return NULL; } octx->data = mssqllog_ctx; octx->DeInit = LogMSSqlLogDeinitCtx; SCLogDebug("mssql json log output initialized"); AppLayerParserRegisterLogger(IPPROTO_TCP, ALPROTO_MSSQL); return octx; }
static OutputInitResult JsonDropLogInitCtx(ConfNode *conf) { OutputInitResult result = { NULL, false }; if (OutputDropLoggerEnable() != 0) { SCLogError(SC_ERR_CONF_YAML_ERROR, "only one 'drop' logger " "can be enabled"); return result; } JsonDropOutputCtx *drop_ctx = SCCalloc(1, sizeof(*drop_ctx)); if (drop_ctx == NULL) return result; drop_ctx->file_ctx = LogFileNewCtx(); if (drop_ctx->file_ctx == NULL) { JsonDropOutputCtxFree(drop_ctx); return result; } if (SCConfLogOpenGeneric(conf, drop_ctx->file_ctx, DEFAULT_LOG_FILENAME, 1) < 0) { JsonDropOutputCtxFree(drop_ctx); return result; } OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx)); if (unlikely(output_ctx == NULL)) { JsonDropOutputCtxFree(drop_ctx); return result; } if (conf) { const char *extended = ConfNodeLookupChildValue(conf, "alerts"); if (extended != NULL) { if (ConfValIsTrue(extended)) { drop_ctx->flags = LOG_DROP_ALERTS; } } extended = ConfNodeLookupChildValue(conf, "flows"); if (extended != NULL) { if (strcasecmp(extended, "start") == 0) { g_droplog_flows_start = 1; } else if (strcasecmp(extended, "all") == 0) { g_droplog_flows_start = 0; } else { SCLogWarning(SC_ERR_CONF_YAML_ERROR, "valid options for " "'flow' are 'start' and 'all'"); } } } output_ctx->data = drop_ctx; output_ctx->DeInit = JsonDropLogDeInitCtx; result.ctx = output_ctx; result.ok = true; return result; }
/** \brief Create a new http log LogFileCtx. * \param conf Pointer to ConfNode containing this loggers configuration. * \return NULL if failure, LogFileCtx* to the file_ctx if succesful * */ OutputCtx *LogStatsLogInitCtx(ConfNode *conf) { LogFileCtx *file_ctx = LogFileNewCtx(); if (file_ctx == NULL) { SCLogError(SC_ERR_HTTP_LOG_GENERIC, "couldn't create new file_ctx"); return NULL; } if (SCConfLogOpenGeneric(conf, file_ctx, DEFAULT_LOG_FILENAME, 1) < 0) { LogFileFreeCtx(file_ctx); return NULL; } LogStatsFileCtx *statslog_ctx = SCMalloc(sizeof(LogStatsFileCtx)); if (unlikely(statslog_ctx == NULL)) { LogFileFreeCtx(file_ctx); return NULL; } memset(statslog_ctx, 0x00, sizeof(LogStatsFileCtx)); statslog_ctx->flags = LOG_STATS_TOTALS; if (conf != NULL) { const char *totals = ConfNodeLookupChildValue(conf, "totals"); const char *threads = ConfNodeLookupChildValue(conf, "threads"); const char *nulls = ConfNodeLookupChildValue(conf, "null-values"); SCLogDebug("totals %s threads %s", totals, threads); if (totals != NULL && ConfValIsFalse(totals)) { statslog_ctx->flags &= ~LOG_STATS_TOTALS; } if (threads != NULL && ConfValIsTrue(threads)) { statslog_ctx->flags |= LOG_STATS_THREADS; } if (nulls != NULL && ConfValIsTrue(nulls)) { statslog_ctx->flags |= LOG_STATS_NULLS; } SCLogDebug("statslog_ctx->flags %08x", statslog_ctx->flags); } statslog_ctx->file_ctx = file_ctx; OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx)); if (unlikely(output_ctx == NULL)) { LogFileFreeCtx(file_ctx); SCFree(statslog_ctx); return NULL; } output_ctx->data = statslog_ctx; output_ctx->DeInit = LogStatsLogDeInitCtx; SCLogDebug("STATS log output initialized"); return output_ctx; }
/** \brief Create a new tls log LogFileCtx. * \param conf Pointer to ConfNode containing this loggers configuration. * \return NULL if failure, LogFileCtx* to the file_ctx if succesful * */ static OutputCtx *LogTlsLogInitCtx(ConfNode *conf) { if (OutputTlsLoggerEnable() != 0) { SCLogError(SC_ERR_CONF_YAML_ERROR, "only one 'tls' logger " "can be enabled"); return NULL; } LogFileCtx* file_ctx = LogFileNewCtx(); if (file_ctx == NULL) { SCLogError(SC_ERR_TLS_LOG_GENERIC, "LogTlsLogInitCtx: Couldn't " "create new file_ctx"); return NULL; } if (SCConfLogOpenGeneric(conf, file_ctx, DEFAULT_LOG_FILENAME, 1) < 0) { goto filectx_error; } LogTlsFileCtx *tlslog_ctx = SCCalloc(1, sizeof(LogTlsFileCtx)); if (unlikely(tlslog_ctx == NULL)) goto filectx_error; tlslog_ctx->file_ctx = file_ctx; const char *extended = ConfNodeLookupChildValue(conf, "extended"); if (extended == NULL) { tlslog_ctx->flags |= LOG_TLS_DEFAULT; } else { if (ConfValIsTrue(extended)) { tlslog_ctx->flags |= LOG_TLS_EXTENDED; } } OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx)); if (unlikely(output_ctx == NULL)) goto tlslog_error; output_ctx->data = tlslog_ctx; output_ctx->DeInit = LogTlsLogDeInitCtx; SCLogDebug("TLS log output initialized"); /* enable the logger for the app layer */ AppLayerParserRegisterLogger(IPPROTO_TCP, ALPROTO_TLS); return output_ctx; tlslog_error: SCFree(tlslog_ctx); filectx_error: LogFileFreeCtx(file_ctx); return NULL; }
OutputCtx *OutputStatsLogInit(ConfNode *conf) { LogFileCtx *file_ctx = LogFileNewCtx(); if(file_ctx == NULL) { SCLogError(SC_ERR_STATS_LOG_GENERIC, "couldn't create new file_ctx"); return NULL; } if (SCConfLogOpenGeneric(conf, file_ctx, DEFAULT_LOG_FILENAME, 1) < 0) { LogFileFreeCtx(file_ctx); return NULL; } OutputStatsCtx *stats_ctx = SCMalloc(sizeof(OutputStatsCtx)); if (unlikely(stats_ctx == NULL)) { LogFileFreeCtx(file_ctx); return NULL; } stats_ctx->flags = JSON_STATS_TOTALS; if (conf != NULL) { const char *totals = ConfNodeLookupChildValue(conf, "totals"); const char *threads = ConfNodeLookupChildValue(conf, "threads"); const char *deltas = ConfNodeLookupChildValue(conf, "deltas"); SCLogDebug("totals %s threads %s deltas %s", totals, threads, deltas); if (totals != NULL && ConfValIsFalse(totals)) { stats_ctx->flags &= ~JSON_STATS_TOTALS; } if (threads != NULL && ConfValIsTrue(threads)) { stats_ctx->flags |= JSON_STATS_THREADS; } if (deltas != NULL && ConfValIsTrue(deltas)) { stats_ctx->flags |= JSON_STATS_DELTAS; } SCLogDebug("stats_ctx->flags %08x", stats_ctx->flags); } OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx)); if (unlikely(output_ctx == NULL)) { LogFileFreeCtx(file_ctx); SCFree(stats_ctx); return NULL; } stats_ctx->file_ctx = file_ctx; output_ctx->data = stats_ctx; output_ctx->DeInit = OutputStatsLogDeinit; return output_ctx; }
OutputCtx *OutputTlsLogInit(ConfNode *conf) { if (OutputTlsLoggerEnable() != 0) { SCLogError(SC_ERR_CONF_YAML_ERROR, "only one 'tls' logger " "can be enabled"); return NULL; } LogFileCtx *file_ctx = LogFileNewCtx(); if(file_ctx == NULL) { SCLogError(SC_ERR_HTTP_LOG_GENERIC, "couldn't create new file_ctx"); return NULL; } if (SCConfLogOpenGeneric(conf, file_ctx, DEFAULT_LOG_FILENAME) < 0) { LogFileFreeCtx(file_ctx); return NULL; } OutputTlsCtx *tls_ctx = SCMalloc(sizeof(OutputTlsCtx)); if (unlikely(tls_ctx == NULL)) { LogFileFreeCtx(file_ctx); return NULL; } OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx)); if (unlikely(output_ctx == NULL)) { LogFileFreeCtx(file_ctx); SCFree(tls_ctx); return NULL; } tls_ctx->file_ctx = file_ctx; tls_ctx->flags = LOG_TLS_DEFAULT; if (conf) { const char *extended = ConfNodeLookupChildValue(conf, "extended"); if (extended != NULL) { if (ConfValIsTrue(extended)) { tls_ctx->flags = LOG_TLS_EXTENDED; } } } output_ctx->data = tls_ctx; output_ctx->DeInit = OutputTlsLogDeinit; return output_ctx; }
OutputCtx *OutputHttpLogInit(ConfNode *conf) { LogFileCtx *file_ctx = LogFileNewCtx(); if(file_ctx == NULL) { SCLogError(SC_ERR_HTTP_LOG_GENERIC, "couldn't create new file_ctx"); return NULL; } if (SCConfLogOpenGeneric(conf, file_ctx, DEFAULT_LOG_FILENAME) < 0) { LogFileFreeCtx(file_ctx); return NULL; } LogHttpFileCtx *http_ctx = SCMalloc(sizeof(LogHttpFileCtx)); if (unlikely(http_ctx == NULL)) { LogFileFreeCtx(file_ctx); return NULL; } OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx)); if (unlikely(output_ctx == NULL)) { LogFileFreeCtx(file_ctx); SCFree(http_ctx); return NULL; } http_ctx->file_ctx = file_ctx; http_ctx->flags = LOG_HTTP_DEFAULT; if (conf) { const char *extended = ConfNodeLookupChildValue(conf, "extended"); if (extended != NULL) { if (ConfValIsTrue(extended)) { http_ctx->flags = LOG_HTTP_EXTENDED; } } } output_ctx->data = http_ctx; output_ctx->DeInit = NULL; /* enable the logger for the app layer */ AppLayerParserRegisterLogger(IPPROTO_TCP, ALPROTO_HTTP); return output_ctx; }
/** \brief Create a new http log LogFileCtx. * \param conf Pointer to ConfNode containing this loggers configuration. * \return NULL if failure, LogFileCtx* to the file_ctx if succesful * */ static OutputCtx *LogFileLogInitCtx(ConfNode *conf) { LogFileCtx *logfile_ctx = LogFileNewCtx(); if (logfile_ctx == NULL) { SCLogDebug("Could not create new LogFileCtx"); return NULL; } if (SCConfLogOpenGeneric(conf, logfile_ctx, DEFAULT_LOG_FILENAME, 1) < 0) { LogFileFreeCtx(logfile_ctx); return NULL; } OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx)); if (unlikely(output_ctx == NULL)) return NULL; output_ctx->data = logfile_ctx; output_ctx->DeInit = LogFileLogDeInitCtx; const char *force_filestore = ConfNodeLookupChildValue(conf, "force-filestore"); if (force_filestore != NULL && ConfValIsTrue(force_filestore)) { FileForceFilestoreEnable(); SCLogInfo("forcing filestore of all files"); } const char *force_magic = ConfNodeLookupChildValue(conf, "force-magic"); if (force_magic != NULL && ConfValIsTrue(force_magic)) { FileForceMagicEnable(); SCLogInfo("forcing magic lookup for logged files"); } const char *force_md5 = ConfNodeLookupChildValue(conf, "force-md5"); if (force_md5 != NULL && ConfValIsTrue(force_md5)) { #ifdef HAVE_NSS FileForceMd5Enable(); SCLogInfo("forcing md5 calculation for logged files"); #else SCLogInfo("md5 calculation requires linking against libnss"); #endif } FileForceTrackingEnable(); SCReturnPtr(output_ctx, "OutputCtx"); }
OutputCtx *OutputTlsLogInit(ConfNode *conf) { LogFileCtx *file_ctx = LogFileNewCtx(); if(file_ctx == NULL) { SCLogError(SC_ERR_TLS_LOG_GENERIC, "couldn't create new file_ctx"); return NULL; } if (SCConfLogOpenGeneric(conf, file_ctx, DEFAULT_LOG_FILENAME, 1) < 0) { LogFileFreeCtx(file_ctx); return NULL; } OutputTlsCtx *tls_ctx = SCMalloc(sizeof(OutputTlsCtx)); if (unlikely(tls_ctx == NULL)) { LogFileFreeCtx(file_ctx); return NULL; } OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx)); if (unlikely(output_ctx == NULL)) { LogFileFreeCtx(file_ctx); SCFree(tls_ctx); return NULL; } tls_ctx->file_ctx = file_ctx; tls_ctx->flags = LOG_TLS_DEFAULT; if (conf) { const char *extended = ConfNodeLookupChildValue(conf, "extended"); if (extended != NULL) { if (ConfValIsTrue(extended)) { tls_ctx->flags = LOG_TLS_EXTENDED; } } } output_ctx->data = tls_ctx; output_ctx->DeInit = OutputTlsLogDeinit; AppLayerParserRegisterLogger(IPPROTO_TCP, ALPROTO_TLS); return output_ctx; }
static OutputCtx *JsonDropLogInitCtx(ConfNode *conf) { if (OutputDropLoggerEnable() != 0) { SCLogError(SC_ERR_CONF_YAML_ERROR, "only one 'drop' logger " "can be enabled"); return NULL; } JsonDropOutputCtx *drop_ctx = SCCalloc(1, sizeof(*drop_ctx)); if (drop_ctx == NULL) return NULL; drop_ctx->file_ctx = LogFileNewCtx(); if (drop_ctx->file_ctx == NULL) { JsonDropOutputCtxFree(drop_ctx); return NULL; } if (SCConfLogOpenGeneric(conf, drop_ctx->file_ctx, DEFAULT_LOG_FILENAME, 1) < 0) { JsonDropOutputCtxFree(drop_ctx); return NULL; } OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx)); if (unlikely(output_ctx == NULL)) { JsonDropOutputCtxFree(drop_ctx); return NULL; } if (conf) { const char *extended = ConfNodeLookupChildValue(conf, "alerts"); if (extended != NULL) { if (ConfValIsTrue(extended)) { drop_ctx->flags = LOG_DROP_ALERTS; } } } output_ctx->data = drop_ctx; output_ctx->DeInit = JsonDropLogDeInitCtx; return output_ctx; }
/** * \brief Create a new LogFileCtx for "fast" output style. * \param conf The configuration node for this output. * \return A LogFileCtx pointer on success, NULL on failure. */ OutputCtx *AlertFastLogInitCtx(ConfNode *conf) { LogFileCtx *logfile_ctx = LogFileNewCtx(); if (logfile_ctx == NULL) { SCLogDebug("AlertFastLogInitCtx2: Could not create new LogFileCtx"); return NULL; } if (SCConfLogOpenGeneric(conf, logfile_ctx, DEFAULT_LOG_FILENAME) < 0) { LogFileFreeCtx(logfile_ctx); return NULL; } OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx)); if (unlikely(output_ctx == NULL)) return NULL; output_ctx->data = logfile_ctx; output_ctx->DeInit = AlertFastLogDeInitCtx; return output_ctx; }
OutputCtx *OutputSshLogInit(ConfNode *conf) { if (OutputSshLoggerEnable() != 0) { SCLogError(SC_ERR_CONF_YAML_ERROR, "only one 'ssh' logger " "can be enabled"); return NULL; } LogFileCtx *file_ctx = LogFileNewCtx(); if(file_ctx == NULL) { SCLogError(SC_ERR_HTTP_LOG_GENERIC, "couldn't create new file_ctx"); return NULL; } if (SCConfLogOpenGeneric(conf, file_ctx, DEFAULT_LOG_FILENAME) < 0) { LogFileFreeCtx(file_ctx); return NULL; } OutputSshCtx *ssh_ctx = SCMalloc(sizeof(OutputSshCtx)); if (unlikely(ssh_ctx == NULL)) { LogFileFreeCtx(file_ctx); return NULL; } OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx)); if (unlikely(output_ctx == NULL)) { LogFileFreeCtx(file_ctx); SCFree(ssh_ctx); return NULL; } ssh_ctx->file_ctx = file_ctx; output_ctx->data = ssh_ctx; output_ctx->DeInit = OutputSshLogDeinit; return output_ctx; }
/** * \brief Create a new LogFileCtx for "fast" output style. * \param conf The configuration node for this output. * \return A LogFileCtx pointer on success, NULL on failure. */ static OutputCtx *JsonAlertLogInitCtx(ConfNode *conf) { AlertJsonOutputCtx *json_output_ctx = NULL; LogFileCtx *logfile_ctx = LogFileNewCtx(); if (logfile_ctx == NULL) { SCLogDebug("AlertFastLogInitCtx2: Could not create new LogFileCtx"); return NULL; } if (SCConfLogOpenGeneric(conf, logfile_ctx, DEFAULT_LOG_FILENAME, 1) < 0) { LogFileFreeCtx(logfile_ctx); return NULL; } OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx)); if (unlikely(output_ctx == NULL)) { LogFileFreeCtx(logfile_ctx); return NULL; } json_output_ctx = SCMalloc(sizeof(AlertJsonOutputCtx)); if (unlikely(json_output_ctx == NULL)) { LogFileFreeCtx(logfile_ctx); SCFree(output_ctx); return NULL; } memset(json_output_ctx, 0, sizeof(AlertJsonOutputCtx)); json_output_ctx->file_ctx = logfile_ctx; XffSetup(json_output_ctx, conf); output_ctx->data = json_output_ctx; output_ctx->DeInit = JsonAlertLogDeInitCtx; return output_ctx; }
/** \brief Create a new http log LogFileCtx. * \param conf Pointer to ConfNode containing this loggers configuration. * \return NULL if failure, LogFileCtx* to the file_ctx if succesful * */ OutputCtx *LogStatsLogInitCtx(ConfNode *conf) { LogFileCtx *file_ctx = LogFileNewCtx(); if (file_ctx == NULL) { SCLogError(SC_ERR_HTTP_LOG_GENERIC, "couldn't create new file_ctx"); return NULL; } if (SCConfLogOpenGeneric(conf, file_ctx, DEFAULT_LOG_FILENAME) < 0) { LogFileFreeCtx(file_ctx); return NULL; } LogStatsFileCtx *statslog_ctx = SCMalloc(sizeof(LogStatsFileCtx)); if (unlikely(statslog_ctx == NULL)) { LogFileFreeCtx(file_ctx); return NULL; } memset(statslog_ctx, 0x00, sizeof(LogStatsFileCtx)); statslog_ctx->file_ctx = file_ctx; OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx)); if (unlikely(output_ctx == NULL)) { LogFileFreeCtx(file_ctx); SCFree(statslog_ctx); return NULL; } output_ctx->data = statslog_ctx; output_ctx->DeInit = LogStatsLogDeInitCtx; SCLogDebug("STATS log output initialized"); OutputRegisterFileRotationFlag(&file_ctx->rotation_flag); return output_ctx; }
/** * \brief Create a new LogFileCtx for "fast" output style. * \param conf The configuration node for this output. * \return A LogFileCtx pointer on success, NULL on failure. */ OutputInitResult OutputJsonInitCtx(ConfNode *conf) { OutputInitResult result = { NULL, false }; OutputJsonCtx *json_ctx = SCCalloc(1, sizeof(OutputJsonCtx)); if (unlikely(json_ctx == NULL)) { SCLogDebug("could not create new OutputJsonCtx"); return result; } /* First lookup a sensor-name value in this outputs configuration * node (deprecated). If that fails, lookup the global one. */ const char *sensor_name = ConfNodeLookupChildValue(conf, "sensor-name"); if (sensor_name != NULL) { SCLogWarning(SC_ERR_DEPRECATED_CONF, "Found deprecated eve-log setting \"sensor-name\". " "Please set sensor-name globally."); } else { (void)ConfGet("sensor-name", &sensor_name); } json_ctx->file_ctx = LogFileNewCtx(); if (unlikely(json_ctx->file_ctx == NULL)) { SCLogDebug("AlertJsonInitCtx: Could not create new LogFileCtx"); SCFree(json_ctx); return result; } if (sensor_name) { json_ctx->file_ctx->sensor_name = SCStrdup(sensor_name); if (json_ctx->file_ctx->sensor_name == NULL) { LogFileFreeCtx(json_ctx->file_ctx); SCFree(json_ctx); return result; } } else { json_ctx->file_ctx->sensor_name = NULL; } OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx)); if (unlikely(output_ctx == NULL)) { LogFileFreeCtx(json_ctx->file_ctx); SCFree(json_ctx); return result; } output_ctx->data = json_ctx; output_ctx->DeInit = OutputJsonDeInitCtx; if (conf) { const char *output_s = ConfNodeLookupChildValue(conf, "filetype"); // Backwards compatibility if (output_s == NULL) { output_s = ConfNodeLookupChildValue(conf, "type"); } if (output_s != NULL) { if (strcmp(output_s, "file") == 0 || strcmp(output_s, "regular") == 0) { json_ctx->json_out = LOGFILE_TYPE_FILE; } else if (strcmp(output_s, "syslog") == 0) { json_ctx->json_out = LOGFILE_TYPE_SYSLOG; } else if (strcmp(output_s, "unix_dgram") == 0) { json_ctx->json_out = LOGFILE_TYPE_UNIX_DGRAM; } else if (strcmp(output_s, "unix_stream") == 0) { json_ctx->json_out = LOGFILE_TYPE_UNIX_STREAM; } else if (strcmp(output_s, "redis") == 0) { #ifdef HAVE_LIBHIREDIS SCLogRedisInit(); json_ctx->json_out = LOGFILE_TYPE_REDIS; #else SCLogError(SC_ERR_INVALID_ARGUMENT, "redis JSON output option is not compiled"); exit(EXIT_FAILURE); #endif } else { SCLogError(SC_ERR_INVALID_ARGUMENT, "Invalid JSON output option: %s", output_s); exit(EXIT_FAILURE); } } const char *prefix = ConfNodeLookupChildValue(conf, "prefix"); if (prefix != NULL) { SCLogInfo("Using prefix '%s' for JSON messages", prefix); json_ctx->file_ctx->prefix = SCStrdup(prefix); if (json_ctx->file_ctx->prefix == NULL) { SCLogError(SC_ERR_MEM_ALLOC, "Failed to allocate memory for eve-log.prefix setting."); exit(EXIT_FAILURE); } json_ctx->file_ctx->prefix_len = strlen(prefix); } if (json_ctx->json_out == LOGFILE_TYPE_FILE || json_ctx->json_out == LOGFILE_TYPE_UNIX_DGRAM || json_ctx->json_out == LOGFILE_TYPE_UNIX_STREAM) { if (SCConfLogOpenGeneric(conf, json_ctx->file_ctx, DEFAULT_LOG_FILENAME, 1) < 0) { LogFileFreeCtx(json_ctx->file_ctx); SCFree(json_ctx); SCFree(output_ctx); return result; } OutputRegisterFileRotationFlag(&json_ctx->file_ctx->rotation_flag); } #ifndef OS_WIN32 else if (json_ctx->json_out == LOGFILE_TYPE_SYSLOG) { const char *facility_s = ConfNodeLookupChildValue(conf, "facility"); if (facility_s == NULL) { facility_s = DEFAULT_ALERT_SYSLOG_FACILITY_STR; } int facility = SCMapEnumNameToValue(facility_s, SCSyslogGetFacilityMap()); if (facility == -1) { SCLogWarning(SC_ERR_INVALID_ARGUMENT, "Invalid syslog facility: \"%s\"," " now using \"%s\" as syslog facility", facility_s, DEFAULT_ALERT_SYSLOG_FACILITY_STR); facility = DEFAULT_ALERT_SYSLOG_FACILITY; } const char *level_s = ConfNodeLookupChildValue(conf, "level"); if (level_s != NULL) { int level = SCMapEnumNameToValue(level_s, SCSyslogGetLogLevelMap()); if (level != -1) { json_ctx->file_ctx->syslog_setup.alert_syslog_level = level; } } const char *ident = ConfNodeLookupChildValue(conf, "identity"); /* if null we just pass that to openlog, which will then * figure it out by itself. */ openlog(ident, LOG_PID|LOG_NDELAY, facility); } #endif #ifdef HAVE_LIBHIREDIS else if (json_ctx->json_out == LOGFILE_TYPE_REDIS) { ConfNode *redis_node = ConfNodeLookupChild(conf, "redis"); if (!json_ctx->file_ctx->sensor_name) { char hostname[1024]; gethostname(hostname, 1023); json_ctx->file_ctx->sensor_name = SCStrdup(hostname); } if (json_ctx->file_ctx->sensor_name == NULL) { LogFileFreeCtx(json_ctx->file_ctx); SCFree(json_ctx); SCFree(output_ctx); return result; } if (SCConfLogOpenRedis(redis_node, json_ctx->file_ctx) < 0) { LogFileFreeCtx(json_ctx->file_ctx); SCFree(json_ctx); SCFree(output_ctx); return result; } } #endif const char *sensor_id_s = ConfNodeLookupChildValue(conf, "sensor-id"); if (sensor_id_s != NULL) { if (ByteExtractStringUint64((uint64_t *)&sensor_id, 10, 0, sensor_id_s) == -1) { SCLogError(SC_ERR_INVALID_ARGUMENT, "Failed to initialize JSON output, " "invalid sensor-id: %s", sensor_id_s); exit(EXIT_FAILURE); } } /* Check if top-level metadata should be logged. */ const ConfNode *metadata = ConfNodeLookupChild(conf, "metadata"); if (metadata && metadata->val && ConfValIsFalse(metadata->val)) { SCLogConfig("Disabling eve metadata logging."); json_ctx->cfg.include_metadata = false; } else { json_ctx->cfg.include_metadata = true; } /* See if we want to enable the community id */ const ConfNode *community_id = ConfNodeLookupChild(conf, "community-id"); if (community_id && community_id->val && ConfValIsTrue(community_id->val)) { SCLogConfig("Enabling eve community_id logging."); json_ctx->cfg.include_community_id = true; } else { json_ctx->cfg.include_community_id = false; } const char *cid_seed = ConfNodeLookupChildValue(conf, "community-id-seed"); if (cid_seed != NULL) { if (ByteExtractStringUint16(&json_ctx->cfg.community_id_seed, 10, 0, cid_seed) == -1) { SCLogError(SC_ERR_INVALID_ARGUMENT, "Failed to initialize JSON output, " "invalid community-id-seed: %s", cid_seed); exit(EXIT_FAILURE); } } /* Do we have a global eve xff configuration? */ const ConfNode *xff = ConfNodeLookupChild(conf, "xff"); if (xff != NULL) { json_ctx->xff_cfg = SCCalloc(1, sizeof(HttpXFFCfg)); if (likely(json_ctx->xff_cfg != NULL)) { HttpXFFGetCfg(conf, json_ctx->xff_cfg); } } const char *pcapfile_s = ConfNodeLookupChildValue(conf, "pcap-file"); if (pcapfile_s != NULL && ConfValIsTrue(pcapfile_s)) { json_ctx->file_ctx->is_pcap_offline = (RunmodeGetCurrent() == RUNMODE_PCAP_FILE); } json_ctx->file_ctx->type = json_ctx->json_out; } SCLogDebug("returning output_ctx %p", output_ctx); result.ctx = output_ctx; result.ok = true; return result; }
/** * \brief Create a new LogFileCtx for "fast" output style. * \param conf The configuration node for this output. * \return A LogFileCtx pointer on success, NULL on failure. */ OutputCtx *OutputJsonInitCtx(ConfNode *conf) { OutputJsonCtx *json_ctx = SCCalloc(1, sizeof(OutputJsonCtx));; if (unlikely(json_ctx == NULL)) { SCLogDebug("AlertJsonInitCtx: Could not create new LogFileCtx"); return NULL; } json_ctx->file_ctx = LogFileNewCtx(); if (unlikely(json_ctx->file_ctx == NULL)) { SCLogDebug("AlertJsonInitCtx: Could not create new LogFileCtx"); SCFree(json_ctx); return NULL; } OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx)); if (unlikely(output_ctx == NULL)) { LogFileFreeCtx(json_ctx->file_ctx); SCFree(json_ctx); return NULL; } output_ctx->data = json_ctx; output_ctx->DeInit = OutputJsonDeInitCtx; if (conf) { const char *output_s = ConfNodeLookupChildValue(conf, "type"); if (output_s != NULL) { if (strcmp(output_s, "file") == 0) { json_ctx->json_out = ALERT_FILE; } else if (strcmp(output_s, "syslog") == 0) { json_ctx->json_out = ALERT_SYSLOG; } else if (strcmp(output_s, "unix_dgram") == 0) { json_ctx->json_out = ALERT_UNIX_DGRAM; } else if (strcmp(output_s, "unix_stream") == 0) { json_ctx->json_out = ALERT_UNIX_STREAM; } else { SCLogError(SC_ERR_INVALID_ARGUMENT, "Invalid JSON output option: %s", output_s); exit(EXIT_FAILURE); } } if (json_ctx->json_out == ALERT_FILE) { if (SCConfLogOpenGeneric(conf, json_ctx->file_ctx, DEFAULT_LOG_FILENAME) < 0) { LogFileFreeCtx(json_ctx->file_ctx); SCFree(json_ctx); SCFree(output_ctx); return NULL; } const char *format_s = ConfNodeLookupChildValue(conf, "format"); if (format_s != NULL) { if (strcmp(format_s, "indent") == 0) { json_ctx->format = INDENT; } else if (strcmp(format_s, "compact") == 0) { json_ctx->format = COMPACT; } else { SCLogError(SC_ERR_INVALID_ARGUMENT, "Invalid JSON format option: %s", format_s); exit(EXIT_FAILURE); } } } else if (json_out == ALERT_SYSLOG) { const char *facility_s = ConfNodeLookupChildValue(conf, "facility"); if (facility_s == NULL) { facility_s = DEFAULT_ALERT_SYSLOG_FACILITY_STR; } int facility = SCMapEnumNameToValue(facility_s, SCSyslogGetFacilityMap()); if (facility == -1) { SCLogWarning(SC_ERR_INVALID_ARGUMENT, "Invalid syslog facility: \"%s\"," " now using \"%s\" as syslog facility", facility_s, DEFAULT_ALERT_SYSLOG_FACILITY_STR); facility = DEFAULT_ALERT_SYSLOG_FACILITY; } const char *level_s = ConfNodeLookupChildValue(conf, "level"); if (level_s != NULL) { int level = SCMapEnumNameToValue(level_s, SCSyslogGetLogLevelMap()); if (level != -1) { alert_syslog_level = level; } } const char *ident = ConfNodeLookupChildValue(conf, "identity"); /* if null we just pass that to openlog, which will then * figure it out by itself. */ openlog(ident, LOG_PID|LOG_NDELAY, facility); } const char *sensor_id_s = ConfNodeLookupChildValue(conf, "sensor-id"); if (sensor_id_s != NULL) { if (ByteExtractStringUint64((uint64_t *)&sensor_id, 10, 0, sensor_id_s) == -1) { SCLogError(SC_ERR_INVALID_ARGUMENT, "Failed to initialize JSON output, " "invalid sensor-is: %s", sensor_id_s); exit(EXIT_FAILURE); } } format = json_ctx->format; json_out = json_ctx->json_out; } return output_ctx; }
/** * \brief Create a new LogFileCtx for "fast" output style. * \param conf The configuration node for this output. * \return A LogFileCtx pointer on success, NULL on failure. */ OutputCtx *OutputJsonInitCtx(ConfNode *conf) { OutputJsonCtx *json_ctx = SCCalloc(1, sizeof(OutputJsonCtx));; const char *sensor_name = ConfNodeLookupChildValue(conf, "sensor-name"); if (unlikely(json_ctx == NULL)) { SCLogDebug("AlertJsonInitCtx: Could not create new LogFileCtx"); return NULL; } json_ctx->file_ctx = LogFileNewCtx(); if (unlikely(json_ctx->file_ctx == NULL)) { SCLogDebug("AlertJsonInitCtx: Could not create new LogFileCtx"); SCFree(json_ctx); return NULL; } if (sensor_name) { json_ctx->file_ctx->sensor_name = SCStrdup(sensor_name); if (json_ctx->file_ctx->sensor_name == NULL) { LogFileFreeCtx(json_ctx->file_ctx); SCFree(json_ctx); return NULL; } } else { json_ctx->file_ctx->sensor_name = NULL; } OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx)); if (unlikely(output_ctx == NULL)) { LogFileFreeCtx(json_ctx->file_ctx); SCFree(json_ctx); return NULL; } output_ctx->data = json_ctx; output_ctx->DeInit = OutputJsonDeInitCtx; if (conf) { const char *output_s = ConfNodeLookupChildValue(conf, "filetype"); // Backwards compatibility if (output_s == NULL) { output_s = ConfNodeLookupChildValue(conf, "type"); } if (output_s != NULL) { if (strcmp(output_s, "file") == 0 || strcmp(output_s, "regular") == 0) { json_ctx->json_out = LOGFILE_TYPE_FILE; } else if (strcmp(output_s, "syslog") == 0) { json_ctx->json_out = LOGFILE_TYPE_SYSLOG; } else if (strcmp(output_s, "unix_dgram") == 0) { json_ctx->json_out = LOGFILE_TYPE_UNIX_DGRAM; } else if (strcmp(output_s, "unix_stream") == 0) { json_ctx->json_out = LOGFILE_TYPE_UNIX_STREAM; } else if (strcmp(output_s, "redis") == 0) { #ifdef HAVE_LIBHIREDIS json_ctx->json_out = LOGFILE_TYPE_REDIS; #else SCLogError(SC_ERR_INVALID_ARGUMENT, "redis JSON output option is not compiled"); exit(EXIT_FAILURE); #endif } else { SCLogError(SC_ERR_INVALID_ARGUMENT, "Invalid JSON output option: %s", output_s); exit(EXIT_FAILURE); } } const char *prefix = ConfNodeLookupChildValue(conf, "prefix"); if (prefix != NULL) { SCLogInfo("Using prefix '%s' for JSON messages", prefix); json_ctx->file_ctx->prefix = SCStrdup(prefix); if (json_ctx->file_ctx->prefix == NULL) { SCLogError(SC_ERR_MEM_ALLOC, "Failed to allocate memory for eve-log.prefix setting."); exit(EXIT_FAILURE); } json_ctx->file_ctx->prefix_len = strlen(prefix); } if (json_ctx->json_out == LOGFILE_TYPE_FILE || json_ctx->json_out == LOGFILE_TYPE_UNIX_DGRAM || json_ctx->json_out == LOGFILE_TYPE_UNIX_STREAM) { if (SCConfLogOpenGeneric(conf, json_ctx->file_ctx, DEFAULT_LOG_FILENAME, 1) < 0) { LogFileFreeCtx(json_ctx->file_ctx); SCFree(json_ctx); SCFree(output_ctx); return NULL; } OutputRegisterFileRotationFlag(&json_ctx->file_ctx->rotation_flag); const char *format_s = ConfNodeLookupChildValue(conf, "format"); if (format_s != NULL) { if (strcmp(format_s, "indent") == 0) { json_ctx->format = INDENT; } else if (strcmp(format_s, "compact") == 0) { json_ctx->format = COMPACT; } else { SCLogError(SC_ERR_INVALID_ARGUMENT, "Invalid JSON format option: %s", format_s); exit(EXIT_FAILURE); } } } else if (json_ctx->json_out == LOGFILE_TYPE_SYSLOG) { const char *facility_s = ConfNodeLookupChildValue(conf, "facility"); if (facility_s == NULL) { facility_s = DEFAULT_ALERT_SYSLOG_FACILITY_STR; } int facility = SCMapEnumNameToValue(facility_s, SCSyslogGetFacilityMap()); if (facility == -1) { SCLogWarning(SC_ERR_INVALID_ARGUMENT, "Invalid syslog facility: \"%s\"," " now using \"%s\" as syslog facility", facility_s, DEFAULT_ALERT_SYSLOG_FACILITY_STR); facility = DEFAULT_ALERT_SYSLOG_FACILITY; } const char *level_s = ConfNodeLookupChildValue(conf, "level"); if (level_s != NULL) { int level = SCMapEnumNameToValue(level_s, SCSyslogGetLogLevelMap()); if (level != -1) { json_ctx->file_ctx->syslog_setup.alert_syslog_level = level; } } const char *ident = ConfNodeLookupChildValue(conf, "identity"); /* if null we just pass that to openlog, which will then * figure it out by itself. */ openlog(ident, LOG_PID|LOG_NDELAY, facility); } #ifdef HAVE_LIBHIREDIS else if (json_ctx->json_out == LOGFILE_TYPE_REDIS) { ConfNode *redis_node = ConfNodeLookupChild(conf, "redis"); if (!json_ctx->file_ctx->sensor_name) { char hostname[1024]; gethostname(hostname, 1023); json_ctx->file_ctx->sensor_name = SCStrdup(hostname); } if (json_ctx->file_ctx->sensor_name == NULL) { LogFileFreeCtx(json_ctx->file_ctx); SCFree(json_ctx); SCFree(output_ctx); return NULL; } if (SCConfLogOpenRedis(redis_node, json_ctx->file_ctx) < 0) { LogFileFreeCtx(json_ctx->file_ctx); SCFree(json_ctx); SCFree(output_ctx); return NULL; } } #endif const char *sensor_id_s = ConfNodeLookupChildValue(conf, "sensor-id"); if (sensor_id_s != NULL) { if (ByteExtractStringUint64((uint64_t *)&sensor_id, 10, 0, sensor_id_s) == -1) { SCLogError(SC_ERR_INVALID_ARGUMENT, "Failed to initialize JSON output, " "invalid sensor-is: %s", sensor_id_s); exit(EXIT_FAILURE); } } json_ctx->file_ctx->type = json_ctx->json_out; } SCLogDebug("returning output_ctx %p", output_ctx); return output_ctx; }
/** \brief Create a new http log LogFileCtx. * \param conf Pointer to ConfNode containing this loggers configuration. * \return NULL if failure, LogFileCtx* to the file_ctx if succesful * */ OutputCtx *LogTcpDataLogInitCtx(ConfNode *conf) { char filename[PATH_MAX] = ""; char dirname[32] = ""; strlcpy(filename, DEFAULT_LOG_FILENAME, sizeof(filename)); LogFileCtx *file_ctx = LogFileNewCtx(); if(file_ctx == NULL) { SCLogError(SC_ERR_TCPDATA_LOG_GENERIC, "couldn't create new file_ctx"); return NULL; } LogTcpDataFileCtx *tcpdatalog_ctx = SCMalloc(sizeof(LogTcpDataFileCtx)); if (unlikely(tcpdatalog_ctx == NULL)) { LogFileFreeCtx(file_ctx); return NULL; } memset(tcpdatalog_ctx, 0x00, sizeof(LogTcpDataFileCtx)); tcpdatalog_ctx->file_ctx = file_ctx; if (conf) { if (conf->name) { if (strcmp(conf->name, "tcp-data") == 0) { tcpdatalog_ctx->type = STREAMING_TCP_DATA; snprintf(filename, sizeof(filename), "%s.log", conf->name); strlcpy(dirname, "tcp", sizeof(dirname)); } else if (strcmp(conf->name, "http-body-data") == 0) { tcpdatalog_ctx->type = STREAMING_HTTP_BODIES; snprintf(filename, sizeof(filename), "%s.log", conf->name); strlcpy(dirname, "http", sizeof(dirname)); } } const char *logtype = ConfNodeLookupChildValue(conf, "type"); if (logtype == NULL) logtype = "file"; if (strcmp(logtype, "file") == 0) { tcpdatalog_ctx->file = 1; } else if (strcmp(logtype, "dir") == 0) { tcpdatalog_ctx->dir = 1; } else if (strcmp(logtype, "both") == 0) { tcpdatalog_ctx->file = 1; tcpdatalog_ctx->dir = 1; } } else { tcpdatalog_ctx->file = 1; tcpdatalog_ctx->dir = 0; } if (tcpdatalog_ctx->file == 1) { SCLogInfo("opening logfile"); if (SCConfLogOpenGeneric(conf, file_ctx, filename, 1) < 0) { LogFileFreeCtx(file_ctx); SCFree(tcpdatalog_ctx); return NULL; } } if (tcpdatalog_ctx->dir == 1) { tcpdatalog_ctx->log_dir = ConfigGetLogDirectory(); char dirfull[PATH_MAX]; /* create the filename to use */ snprintf(dirfull, PATH_MAX, "%s/%s", tcpdatalog_ctx->log_dir, dirname); SCLogInfo("using directory %s", dirfull); /* if mkdir fails file open will fail, so deal with errors there */ #ifndef OS_WIN32 (void)mkdir(dirfull, 0700); #else (void)mkdir(dirfull); #endif } OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx)); if (unlikely(output_ctx == NULL)) { goto parsererror; } output_ctx->data = tcpdatalog_ctx; output_ctx->DeInit = LogTcpDataLogDeInitCtx; SCLogDebug("Streaming log output initialized"); return output_ctx; parsererror: LogFileFreeCtx(file_ctx); SCFree(tcpdatalog_ctx); SCLogError(SC_ERR_INVALID_ARGUMENT,"Syntax error in custom http log format string."); return NULL; }
/** \brief Create a new http log LogFileCtx. * \param conf Pointer to ConfNode containing this loggers configuration. * \return NULL if failure, LogFileCtx* to the file_ctx if succesful * */ OutputCtx *LogHttpLogInitCtx(ConfNode *conf) { LogFileCtx* file_ctx = LogFileNewCtx(); const char *p, *np; uint32_t n; if(file_ctx == NULL) { SCLogError(SC_ERR_HTTP_LOG_GENERIC, "couldn't create new file_ctx"); return NULL; } if (SCConfLogOpenGeneric(conf, file_ctx, DEFAULT_LOG_FILENAME) < 0) { LogFileFreeCtx(file_ctx); return NULL; } LogHttpFileCtx *httplog_ctx = SCMalloc(sizeof(LogHttpFileCtx)); if (httplog_ctx == NULL) { LogFileFreeCtx(file_ctx); return NULL; } memset(httplog_ctx, 0x00, sizeof(LogHttpFileCtx)); httplog_ctx->file_ctx = file_ctx; httplog_ctx->cf_n=0; const char *extended = ConfNodeLookupChildValue(conf, "extended"); const char *custom = ConfNodeLookupChildValue(conf, "custom"); const char *customformat = ConfNodeLookupChildValue(conf, "customformat"); /* If custom logging format is selected, lets parse it */ if (custom != NULL && customformat != NULL && ConfValIsTrue(custom)) { p=customformat; httplog_ctx->flags |= LOG_HTTP_CUSTOM; for (httplog_ctx->cf_n = 0; httplog_ctx->cf_n < LOG_HTTP_MAXN_NODES-1 && p && *p != '\0'; httplog_ctx->cf_n++){ httplog_ctx->cf_nodes[httplog_ctx->cf_n] = SCMalloc(sizeof(LogHttpCustomFormatNode)); if (httplog_ctx->cf_nodes[httplog_ctx->cf_n] == NULL) { for (n = 0; n < httplog_ctx->cf_n; n++) { SCFree(httplog_ctx->cf_nodes[n]); } LogFileFreeCtx(file_ctx); SCFree(httplog_ctx); return NULL; } if (*p != '%'){ /* Literal found in format string */ httplog_ctx->cf_nodes[httplog_ctx->cf_n]->type = LOG_HTTP_CF_LITERAL; np = strchr(p, '%'); if (np == NULL){ n = LOG_HTTP_NODE_STRLEN-2; np = NULL; /* End */ }else{ n = np-p; } strlcpy(httplog_ctx->cf_nodes[httplog_ctx->cf_n]->data,p,n+1); p = np; } else { /* Non Literal found in format string */ p++; if (*p == '{') { /* Simple format char */ np = strchr(p, '}'); if (np != NULL && np-p > 1 && np-p < LOG_HTTP_NODE_STRLEN-2) { p++; n = np-p; strlcpy(httplog_ctx->cf_nodes[httplog_ctx->cf_n]->data, p, n+1); p = np; } p++; } else { httplog_ctx->cf_nodes[httplog_ctx->cf_n]->data[0] = '\0'; } httplog_ctx->cf_nodes[httplog_ctx->cf_n]->type = *p; if (*p == '%'){ httplog_ctx->cf_nodes[httplog_ctx->cf_n]->type = LOG_HTTP_CF_LITERAL; strlcpy(httplog_ctx->cf_nodes[httplog_ctx->cf_n]->data, "%", 2); } p++; } } } else { if (extended == NULL) { httplog_ctx->flags |= LOG_HTTP_DEFAULT; } else { if (ConfValIsTrue(extended)) { httplog_ctx->flags |= LOG_HTTP_EXTENDED; } } } OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx)); if (output_ctx == NULL) { for (n = 0; n < httplog_ctx->cf_n; n++) { SCFree(httplog_ctx->cf_nodes[n]); } LogFileFreeCtx(file_ctx); SCFree(httplog_ctx); return NULL; } output_ctx->data = httplog_ctx; output_ctx->DeInit = LogHttpLogDeInitCtx; SCLogDebug("HTTP log output initialized"); return output_ctx; }
/** \brief Create a new http log LogFileCtx. * \param conf Pointer to ConfNode containing this loggers configuration. * \return NULL if failure, LogFileCtx* to the file_ctx if succesful * */ OutputCtx *LogHttpLogInitCtx(ConfNode *conf) { LogFileCtx* file_ctx = LogFileNewCtx(); if(file_ctx == NULL) { SCLogError(SC_ERR_HTTP_LOG_GENERIC, "couldn't create new file_ctx"); return NULL; } if (SCConfLogOpenGeneric(conf, file_ctx, DEFAULT_LOG_FILENAME, 1) < 0) { LogFileFreeCtx(file_ctx); return NULL; } LogHttpFileCtx *httplog_ctx = SCMalloc(sizeof(LogHttpFileCtx)); if (unlikely(httplog_ctx == NULL)) { LogFileFreeCtx(file_ctx); return NULL; } memset(httplog_ctx, 0x00, sizeof(LogHttpFileCtx)); httplog_ctx->file_ctx = file_ctx; const char *extended = ConfNodeLookupChildValue(conf, "extended"); const char *custom = ConfNodeLookupChildValue(conf, "custom"); const char *customformat = ConfNodeLookupChildValue(conf, "customformat"); /* If custom logging format is selected, lets parse it */ if (custom != NULL && customformat != NULL && ConfValIsTrue(custom)) { httplog_ctx->cf = LogCustomFormatAlloc(); if (!httplog_ctx->cf) { goto errorfree; } httplog_ctx->flags |= LOG_HTTP_CUSTOM; /* Parsing */ if ( ! LogCustomFormatParse(httplog_ctx->cf, customformat)) { goto parsererror; } } else { if (extended == NULL) { httplog_ctx->flags |= LOG_HTTP_DEFAULT; } else { if (ConfValIsTrue(extended)) { httplog_ctx->flags |= LOG_HTTP_EXTENDED; } } } OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx)); if (unlikely(output_ctx == NULL)) { goto parsererror; } output_ctx->data = httplog_ctx; output_ctx->DeInit = LogHttpLogDeInitCtx; SCLogDebug("HTTP log output initialized"); /* enable the logger for the app layer */ AppLayerParserRegisterLogger(IPPROTO_TCP, ALPROTO_HTTP); return output_ctx; parsererror: SCLogError(SC_ERR_INVALID_ARGUMENT,"Syntax error in custom http log format string."); errorfree: LogCustomFormatFree(httplog_ctx->cf); LogFileFreeCtx(file_ctx); SCFree(httplog_ctx); return NULL; }
/** \brief Create a new http log LogFileCtx. * \param conf Pointer to ConfNode containing this loggers configuration. * \return NULL if failure, LogFileCtx* to the file_ctx if succesful * */ OutputCtx *LogHttpLogInitCtx(ConfNode *conf) { LogFileCtx* file_ctx = LogFileNewCtx(); const char *p, *np; uint32_t n; if(file_ctx == NULL) { SCLogError(SC_ERR_HTTP_LOG_GENERIC, "couldn't create new file_ctx"); return NULL; } if (SCConfLogOpenGeneric(conf, file_ctx, DEFAULT_LOG_FILENAME, 1) < 0) { LogFileFreeCtx(file_ctx); return NULL; } LogHttpFileCtx *httplog_ctx = SCMalloc(sizeof(LogHttpFileCtx)); if (unlikely(httplog_ctx == NULL)) { LogFileFreeCtx(file_ctx); return NULL; } memset(httplog_ctx, 0x00, sizeof(LogHttpFileCtx)); httplog_ctx->file_ctx = file_ctx; httplog_ctx->cf_n=0; const char *extended = ConfNodeLookupChildValue(conf, "extended"); const char *custom = ConfNodeLookupChildValue(conf, "custom"); const char *customformat = ConfNodeLookupChildValue(conf, "customformat"); /* If custom logging format is selected, lets parse it */ if (custom != NULL && customformat != NULL && ConfValIsTrue(custom)) { p=customformat; httplog_ctx->flags |= LOG_HTTP_CUSTOM; for (httplog_ctx->cf_n = 0; httplog_ctx->cf_n < LOG_HTTP_MAXN_NODES-1 && p && *p != '\0'; httplog_ctx->cf_n++){ httplog_ctx->cf_nodes[httplog_ctx->cf_n] = SCMalloc(sizeof(LogHttpCustomFormatNode)); if (httplog_ctx->cf_nodes[httplog_ctx->cf_n] == NULL) { for (n = 0; n < httplog_ctx->cf_n; n++) { SCFree(httplog_ctx->cf_nodes[n]); } LogFileFreeCtx(file_ctx); SCFree(httplog_ctx); return NULL; } httplog_ctx->cf_nodes[httplog_ctx->cf_n]->maxlen = 0; if (*p != '%'){ /* Literal found in format string */ httplog_ctx->cf_nodes[httplog_ctx->cf_n]->type = LOG_HTTP_CF_LITERAL; np = strchr(p, '%'); if (np == NULL){ n = LOG_HTTP_NODE_STRLEN-2; np = NULL; /* End */ }else{ n = np-p; } strlcpy(httplog_ctx->cf_nodes[httplog_ctx->cf_n]->data,p,n+1); p = np; } else { /* Non Literal found in format string */ p++; if (*p == '[') { /* Check if maxlength has been specified (ie: [25]) */ p++; np = strchr(p, ']'); if (np != NULL) { if (np-p > 0 && np-p < 10){ long maxlen = strtol(p,NULL,10); if (maxlen > 0 && maxlen < LOG_HTTP_NODE_MAXOUTPUTLEN) { httplog_ctx->cf_nodes[httplog_ctx->cf_n]->maxlen = (uint32_t) maxlen; } } else { goto parsererror; } p = np + 1; } else { goto parsererror; } } if (*p == '{') { /* Simple format char */ np = strchr(p, '}'); if (np != NULL && np-p > 1 && np-p < LOG_HTTP_NODE_STRLEN-2) { p++; n = np-p; strlcpy(httplog_ctx->cf_nodes[httplog_ctx->cf_n]->data, p, n+1); p = np; } else { goto parsererror; } p++; } else { httplog_ctx->cf_nodes[httplog_ctx->cf_n]->data[0] = '\0'; } httplog_ctx->cf_nodes[httplog_ctx->cf_n]->type = *p; if (*p == '%'){ httplog_ctx->cf_nodes[httplog_ctx->cf_n]->type = LOG_HTTP_CF_LITERAL; strlcpy(httplog_ctx->cf_nodes[httplog_ctx->cf_n]->data, "%", 2); } p++; } } } else { if (extended == NULL) { httplog_ctx->flags |= LOG_HTTP_DEFAULT; } else { if (ConfValIsTrue(extended)) { httplog_ctx->flags |= LOG_HTTP_EXTENDED; } } } OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx)); if (unlikely(output_ctx == NULL)) { goto parsererror; } output_ctx->data = httplog_ctx; output_ctx->DeInit = LogHttpLogDeInitCtx; SCLogDebug("HTTP log output initialized"); /* enable the logger for the app layer */ AppLayerParserRegisterLogger(IPPROTO_TCP, ALPROTO_HTTP); return output_ctx; parsererror: for (n = 0;n < httplog_ctx->cf_n;n++) { SCFree(httplog_ctx->cf_nodes[n]); } LogFileFreeCtx(file_ctx); SCFree(httplog_ctx); SCLogError(SC_ERR_INVALID_ARGUMENT,"Syntax error in custom http log format string."); return NULL; }