/**
 * \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 *JsonAlertLogInitCtxSub(ConfNode *conf, OutputCtx *parent_ctx)
{
    AlertJsonThread *ajt = parent_ctx->data;

    OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx));
    if (unlikely(output_ctx == NULL))
        return NULL;

    if (conf) {
        const char *payload = ConfNodeLookupChildValue(conf, "payload");
        const char *packet  = ConfNodeLookupChildValue(conf, "packet");
        const char *payload_printable = ConfNodeLookupChildValue(conf, "payload-printable");

        if (payload_printable != NULL) {
            if (ConfValIsTrue(payload_printable)) {
                ajt->file_ctx->flags |= LOG_JSON_PAYLOAD;
            }
        }
        if (payload != NULL) {
            if (ConfValIsTrue(payload)) {
                ajt->file_ctx->flags |= LOG_JSON_PAYLOAD_BASE64;
            }
        }
        if (packet != NULL) {
            if (ConfValIsTrue(packet)) {
                ajt->file_ctx->flags |= LOG_JSON_PACKET;
            }
        }
    }

    output_ctx->data = ajt->file_ctx;
    output_ctx->DeInit = JsonAlertLogDeInitCtxSub;

    return output_ctx;
}
Exemple #2
0
/** \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;
}
Exemple #3
0
/** \brief Create a new http log LogFilestoreCtx.
 *  \param conf Pointer to ConfNode containing this loggers configuration.
 *  \return NULL if failure, LogFilestoreCtx* to the file_ctx if succesful
 * */
static OutputCtx *LogFilestoreLogInitCtx(ConfNode *conf)
{
    LogFileCtx *logfile_ctx = LogFileNewCtx();
    if (logfile_ctx == NULL) {
        SCLogDebug("Could not create new LogFilestoreCtx");
        return NULL;
    }

    OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx));
    if (unlikely(output_ctx == NULL))
        return NULL;

    output_ctx->data = NULL;
    output_ctx->DeInit = LogFilestoreLogDeInitCtx;

    char *s_default_log_dir = NULL;
    s_default_log_dir = ConfigGetLogDirectory();

    const char *s_base_dir = NULL;
    s_base_dir = ConfNodeLookupChildValue(conf, "log-dir");
    if (s_base_dir == NULL || strlen(s_base_dir) == 0) {
        strlcpy(g_logfile_base_dir,
                s_default_log_dir, sizeof(g_logfile_base_dir));
    } else {
        if (PathIsAbsolute(s_base_dir)) {
            strlcpy(g_logfile_base_dir,
                    s_base_dir, sizeof(g_logfile_base_dir));
        } else {
            snprintf(g_logfile_base_dir, sizeof(g_logfile_base_dir),
                    "%s/%s", s_default_log_dir, s_base_dir);
        }
    }

    const char *force_magic = ConfNodeLookupChildValue(conf, "force-magic");
    if (force_magic != NULL && ConfValIsTrue(force_magic)) {
        FileForceMagicEnable();
        SCLogInfo("forcing magic lookup for stored 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 stored files");
#else
        SCLogInfo("md5 calculation requires linking against libnss");
#endif
    }
    SCLogInfo("storing files in %s", g_logfile_base_dir);

    SCReturnPtr(output_ctx, "OutputCtx");
}
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 *OutputStatsLogInitSub(ConfNode *conf, OutputCtx *parent_ctx)
{
    AlertJsonThread *ajt = parent_ctx->data;

    OutputStatsCtx *stats_ctx = SCMalloc(sizeof(OutputStatsCtx));
    if (unlikely(stats_ctx == NULL))
        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)) &&
                (threads != NULL && ConfValIsFalse(threads))) {
            SCFree(stats_ctx);
            SCLogError(SC_ERR_JSON_STATS_LOG_NEGATED,
                    "Cannot disable both totals and threads in stats logging");
            return NULL;
        }

        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)) {
        SCFree(stats_ctx);
        return NULL;
    }

    stats_ctx->file_ctx = ajt->file_ctx;

    output_ctx->data = stats_ctx;
    output_ctx->DeInit = OutputStatsLogDeinitSub;

    return output_ctx;
}
void SCProfilingKeywordsGlobalInit(void) {
    ConfNode *conf;

    conf = ConfGetNode("profiling.keywords");
    if (conf != NULL) {
        if (ConfNodeChildValueIsTrue(conf, "enabled")) {
            profiling_keyword_enabled = 1;
            const char *filename = ConfNodeLookupChildValue(conf, "filename");
            if (filename != NULL) {

                char *log_dir;
                log_dir = ConfigGetLogDirectory();

                profiling_file_name = SCMalloc(PATH_MAX);
                if (unlikely(profiling_file_name == NULL)) {
                    SCLogError(SC_ERR_MEM_ALLOC, "can't duplicate file name");
                    exit(EXIT_FAILURE);
                }
                snprintf(profiling_file_name, PATH_MAX, "%s/%s", log_dir, filename);

                const char *v = ConfNodeLookupChildValue(conf, "append");
                if (v == NULL || ConfValIsTrue(v)) {
                    profiling_file_mode = "a";
                } else {
                    profiling_file_mode = "w";
                }

                profiling_keywords_output_to_file = 1;
            }
        }
    }
}
static OutputCtx *JsonDropLogInitCtxSub(ConfNode *conf, OutputCtx *parent_ctx)
{
    if (OutputDropLoggerEnable() != 0) {
        SCLogError(SC_ERR_CONF_YAML_ERROR, "only one 'drop' logger "
            "can be enabled");
        return NULL;
    }

    AlertJsonThread *ajt = parent_ctx->data;

    JsonDropOutputCtx *drop_ctx = SCCalloc(1, sizeof(*drop_ctx));
    if (drop_ctx == NULL)
        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;
            }
        }
    }

    drop_ctx->file_ctx = ajt->file_ctx;

    output_ctx->data = drop_ctx;
    output_ctx->DeInit = JsonDropLogDeInitCtxSub;
    return output_ctx;
}
OutputCtx *OutputTlsLogInitSub(ConfNode *conf, OutputCtx *parent_ctx)
{
    OutputJsonCtx *ojc = parent_ctx->data;

    OutputTlsCtx *tls_ctx = SCMalloc(sizeof(OutputTlsCtx));
    if (unlikely(tls_ctx == NULL))
        return NULL;

    OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx));
    if (unlikely(output_ctx == NULL)) {
        SCFree(tls_ctx);
        return NULL;
    }

    tls_ctx->file_ctx = ojc->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 = OutputTlsLogDeinitSub;

    AppLayerParserRegisterLogger(IPPROTO_TCP, ALPROTO_TLS);

    return output_ctx;
}
Exemple #9
0
OutputCtx *OutputHttpLogInitSub(ConfNode *conf, OutputCtx *parent_ctx)
{
    AlertJsonThread *ajt = parent_ctx->data;

    LogHttpFileCtx *http_ctx = SCMalloc(sizeof(LogHttpFileCtx));
    if (unlikely(http_ctx == NULL))
        return NULL;

    OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx));
    if (unlikely(output_ctx == NULL)) {
        SCFree(http_ctx);
        return NULL;
    }

    http_ctx->file_ctx = ajt->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;
}
Exemple #10
0
int AppLayerParserConfParserEnabled(const char *ipproto,
                                    const char *alproto_name)
{
    SCEnter();

    int enabled = 1;
    char param[100];
    ConfNode *node;
    int r;

    if (RunmodeIsUnittests())
        goto enabled;

    r = snprintf(param, sizeof(param), "%s%s%s", "app-layer.protocols.",
                 alproto_name, ".enabled");
    if (r < 0) {
        SCLogError(SC_ERR_FATAL, "snprintf failure.");
        exit(EXIT_FAILURE);
    } else if (r > (int)sizeof(param)) {
        SCLogError(SC_ERR_FATAL, "buffer not big enough to write param.");
        exit(EXIT_FAILURE);
    }

    node = ConfGetNode(param);
    if (node == NULL) {
        SCLogDebug("Entry for %s not found.", param);
        r = snprintf(param, sizeof(param), "%s%s%s%s%s", "app-layer.protocols.",
                     alproto_name, ".", ipproto, ".enabled");
        if (r < 0) {
            SCLogError(SC_ERR_FATAL, "snprintf failure.");
            exit(EXIT_FAILURE);
        } else if (r > (int)sizeof(param)) {
            SCLogError(SC_ERR_FATAL, "buffer not big enough to write param.");
            exit(EXIT_FAILURE);
        }

        node = ConfGetNode(param);
        if (node == NULL) {
            SCLogDebug("Entry for %s not found.", param);
            goto enabled;
        }
    }

    if (ConfValIsTrue(node->val)) {
        goto enabled;
    } else if (ConfValIsFalse(node->val)) {
        goto disabled;
    } else if (strcasecmp(node->val, "detection-only") == 0) {
        goto disabled;
    } else {
        SCLogError(SC_ERR_FATAL, "Invalid value found for %s.", param);
        exit(EXIT_FAILURE);
    }

 disabled:
    enabled = 0;
 enabled:
    SCReturnInt(enabled);
}
Exemple #11
0
/** \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 *OutputFileLogInitSub(ConfNode *conf, OutputCtx *parent_ctx)
{
    OutputJsonCtx *ojc = parent_ctx->data;

    OutputFileCtx *output_file_ctx = SCMalloc(sizeof(OutputFileCtx));
    if (unlikely(output_file_ctx == NULL))
        return NULL;

    OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx));
    if (unlikely(output_ctx == NULL)) {
        SCFree(output_file_ctx);
        return NULL;
    }

    output_file_ctx->file_ctx = ojc->file_ctx;

    if (conf) {
        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
        }
    }

    output_ctx->data = output_file_ctx;
    output_ctx->DeInit = OutputFileLogDeinitSub;

    FileForceTrackingEnable();
    return output_ctx;
}
Exemple #12
0
/** \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");
}
Exemple #13
0
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 Sets up the rule analyzer according to the config
 * \retval 1 if rule analyzer successfully enabled
 * \retval 0 if not enabled
 */
int SetupRuleAnalyzer(void)
{
    ConfNode *conf = ConfGetNode("engine-analysis");
    int enabled = 0;
    if (conf != NULL) {
        const char *value = ConfNodeLookupChildValue(conf, "rules");
        if (value && ConfValIsTrue(value)) {
            enabled = 1;
        } else if (value && strcasecmp(value, "warnings-only") == 0) {
            enabled = 1;
            rule_warnings_only = 1;
        }
        if (enabled) {
            char *log_dir;
            log_dir = ConfigGetLogDirectory();
            snprintf(log_path, sizeof(log_path), "%s/%s", log_dir, "rules_analysis.txt");
            rule_engine_analysis_FD = fopen(log_path, "w");
            if (rule_engine_analysis_FD == NULL) {
                SCLogError(SC_ERR_FOPEN, "failed to open %s: %s", log_path, strerror(errno));
                return 0;
            }

            SCLogInfo("Engine-Analysis for rules printed to file - %s",
                      log_path);

            struct timeval tval;
            struct tm *tms;
            gettimeofday(&tval, NULL);
            struct tm local_tm;
            tms = SCLocalTime(tval.tv_sec, &local_tm);
            fprintf(rule_engine_analysis_FD, "----------------------------------------------"
                    "---------------------\n");
            fprintf(rule_engine_analysis_FD, "Date: %" PRId32 "/%" PRId32 "/%04d -- "
                    "%02d:%02d:%02d\n",
                    tms->tm_mday, tms->tm_mon + 1, tms->tm_year + 1900, tms->tm_hour,
                    tms->tm_min, tms->tm_sec);
            fprintf(rule_engine_analysis_FD, "----------------------------------------------"
                    "---------------------\n");

            /*compile regex's for rule analysis*/
            if (PerCentEncodingSetup()== 0) {
                fprintf(rule_engine_analysis_FD, "Error compiling regex; can't check for percent encoding in normalized http content.\n");
            }
        }
    }
    else {
        SCLogInfo("Conf parameter \"engine-analysis.rules\" not found. "
                                      "Defaulting to not printing the rules analysis report.");
    }
    if (!enabled) {
        SCLogInfo("Engine-Analysis for rules disabled in conf file.");
        return 0;
    }
    return 1;
}
Exemple #15
0
/** \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;
}
Exemple #16
0
/** \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 *OutputFileLogInitSub(ConfNode *conf, OutputCtx *parent_ctx)
{
    OutputJsonCtx *ojc = parent_ctx->data;

    OutputFileCtx *output_file_ctx = SCMalloc(sizeof(OutputFileCtx));
    if (unlikely(output_file_ctx == NULL))
        return NULL;

    OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx));
    if (unlikely(output_ctx == NULL)) {
        SCFree(output_file_ctx);
        return NULL;
    }

    output_file_ctx->file_ctx = ojc->file_ctx;

    if (conf) {
        const char *force_filestore = ConfNodeLookupChildValue(conf, "force-filestore");
        if (force_filestore != NULL && ConfValIsTrue(force_filestore)) {
            FileForceFilestoreEnable();
            SCLogConfig("forcing filestore of all files");
        }

        const char *force_magic = ConfNodeLookupChildValue(conf, "force-magic");
        if (force_magic != NULL && ConfValIsTrue(force_magic)) {
            FileForceMagicEnable();
            SCLogConfig("forcing magic lookup for logged files");
        }

        FileForceHashParseCfg(conf);
    }

    output_ctx->data = output_file_ctx;
    output_ctx->DeInit = OutputFileLogDeinitSub;

    FileForceTrackingEnable();
    return output_ctx;
}
Exemple #17
0
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;
}
Exemple #18
0
/** \brief open the indicated file, logging any errors
 *  \param path filesystem path to open
 *  \param append_setting open file with O_APPEND: "yes" or "no"
 *  \retval FILE* on success
 *  \retval NULL on error
 */
static FILE *
SCLogOpenFileFp(const char *path, const char *append_setting)
{
    FILE *ret = NULL;

    if (ConfValIsTrue(append_setting)) {
        ret = fopen(path, "a");
    } else {
        ret = fopen(path, "w");
    }

    if (ret == NULL)
        SCLogError(SC_ERR_FOPEN, "Error opening file: \"%s\": %s",
                   path, strerror(errno));
    return ret;
}
Exemple #19
0
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;
}
Exemple #20
0
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;
}
Exemple #22
0
/** \brief open the indicated file, logging any errors
 *  \param path filesystem path to open
 *  \param append_setting open file with O_APPEND: "yes" or "no"
 *  \param mode permissions to set on file
 *  \retval FILE* on success
 *  \retval NULL on error
 */
static FILE *
SCLogOpenFileFp(const char *path, const char *append_setting, uint32_t mode)
{
    FILE *ret = NULL;

    char *filename = SCLogFilenameFromPattern(path);
    if (filename == NULL) {
        return NULL;
    }

    int rc = SCLogCreateDirectoryTree(filename);
    if (rc < 0) {
        SCFree(filename);
        return NULL;
    }

    if (ConfValIsTrue(append_setting)) {
        ret = fopen(filename, "a");
    } else {
        ret = fopen(filename, "w");
    }

    if (ret == NULL) {
        SCLogError(SC_ERR_FOPEN, "Error opening file: \"%s\": %s",
                   filename, strerror(errno));
    } else {
        if (mode != 0) {
            int r = chmod(filename, mode);
            if (r < 0) {
                SCLogWarning(SC_WARN_CHMOD, "Could not chmod %s to %u: %s",
                             filename, mode, strerror(errno));
            }
        }
    }

    SCFree(filename);
    return ret;
}
Exemple #23
0
OutputCtx *OutputTlsLogInitSub(ConfNode *conf, OutputCtx *parent_ctx)
{
    AlertJsonThread *ajt = parent_ctx->data;

    if (OutputTlsLoggerEnable() != 0) {
        SCLogError(SC_ERR_CONF_YAML_ERROR, "only one 'tls' logger "
            "can be enabled");
        return NULL;
    }

    OutputTlsCtx *tls_ctx = SCMalloc(sizeof(OutputTlsCtx));
    if (unlikely(tls_ctx == NULL))
        return NULL;

    OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx));
    if (unlikely(output_ctx == NULL)) {
        SCFree(tls_ctx);
        return NULL;
    }

    tls_ctx->file_ctx = ajt->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 = OutputTlsLogDeinitSub;

    return output_ctx;
}
Exemple #24
0
/** \brief Read the config set the file pointer, open the file
 *  \param file_ctx pointer to a created LogFileCtx using LogFileNewCtx()
 *  \param filename name of log file
 *  \param mode append mode (bool)
 *  \return -1 if failure, 0 if succesful
 * */
static int AlertPcapInfoOpenFileCtx(LogFileCtx *file_ctx, const char *filename,
                                    const char *mode)
{
    char log_path[PATH_MAX];
    char *log_dir;

    log_dir = ConfigGetLogDirectory();

    snprintf(log_path, PATH_MAX, "%s/%s", log_dir, filename);

    if (ConfValIsTrue(mode)) {
        file_ctx->fp = fopen(log_path, "a");
    } else {
        file_ctx->fp = fopen(log_path, "w");
    }

    if (file_ctx->fp == NULL) {
        SCLogError(SC_ERR_FOPEN, "failed to open %s: %s", log_path,
                strerror(errno));
        return -1;
    }

    return 0;
}
Exemple #25
0
/** \brief initialize the configuration
 *  \warning Not thread safe */
void DefragInitConfig(char quiet)
{
    SCLogDebug("initializing defrag engine...");

    memset(&defrag_config,  0, sizeof(defrag_config));
    //SC_ATOMIC_INIT(flow_flags);
    SC_ATOMIC_INIT(defragtracker_counter);
    SC_ATOMIC_INIT(defrag_memuse);
    SC_ATOMIC_INIT(defragtracker_prune_idx);
    DefragTrackerQueueInit(&defragtracker_spare_q);

    /* set defaults */
    defrag_config.hash_rand   = (uint32_t)RandomGet();
    defrag_config.hash_size   = DEFRAG_DEFAULT_HASHSIZE;
    defrag_config.memcap      = DEFRAG_DEFAULT_MEMCAP;
    defrag_config.prealloc    = DEFRAG_DEFAULT_PREALLOC;

    /* Check if we have memcap and hash_size defined at config */
    const char *conf_val;
    uint32_t configval = 0;

    /** set config values for memcap, prealloc and hash_size */
    if ((ConfGet("defrag.memcap", &conf_val)) == 1)
    {
        if (ParseSizeStringU64(conf_val, &defrag_config.memcap) < 0) {
            SCLogError(SC_ERR_SIZE_PARSE, "Error parsing defrag.memcap "
                       "from conf file - %s.  Killing engine",
                       conf_val);
            exit(EXIT_FAILURE);
        }
    }
    if ((ConfGet("defrag.hash-size", &conf_val)) == 1)
    {
        if (ByteExtractStringUint32(&configval, 10, strlen(conf_val),
                                    conf_val) > 0) {
            defrag_config.hash_size = configval;
        } else {
            WarnInvalidConfEntry("defrag.hash-size", "%"PRIu32, defrag_config.hash_size);
        }
    }


    if ((ConfGet("defrag.trackers", &conf_val)) == 1)
    {
        if (ByteExtractStringUint32(&configval, 10, strlen(conf_val),
                                    conf_val) > 0) {
            defrag_config.prealloc = configval;
        } else {
            WarnInvalidConfEntry("defrag.trackers", "%"PRIu32, defrag_config.prealloc);
        }
    }
    SCLogDebug("DefragTracker config from suricata.yaml: memcap: %"PRIu64", hash-size: "
               "%"PRIu32", prealloc: %"PRIu32, defrag_config.memcap,
               defrag_config.hash_size, defrag_config.prealloc);

    /* alloc hash memory */
    uint64_t hash_size = defrag_config.hash_size * sizeof(DefragTrackerHashRow);
    if (!(DEFRAG_CHECK_MEMCAP(hash_size))) {
        SCLogError(SC_ERR_DEFRAG_INIT, "allocating defrag hash failed: "
                "max defrag memcap is smaller than projected hash size. "
                "Memcap: %"PRIu64", Hash table size %"PRIu64". Calculate "
                "total hash size by multiplying \"defrag.hash-size\" with %"PRIuMAX", "
                "which is the hash bucket size.", defrag_config.memcap, hash_size,
                (uintmax_t)sizeof(DefragTrackerHashRow));
        exit(EXIT_FAILURE);
    }
    defragtracker_hash = SCCalloc(defrag_config.hash_size, sizeof(DefragTrackerHashRow));
    if (unlikely(defragtracker_hash == NULL)) {
        SCLogError(SC_ERR_FATAL, "Fatal error encountered in DefragTrackerInitConfig. Exiting...");
        exit(EXIT_FAILURE);
    }
    memset(defragtracker_hash, 0, defrag_config.hash_size * sizeof(DefragTrackerHashRow));

    uint32_t i = 0;
    for (i = 0; i < defrag_config.hash_size; i++) {
        DRLOCK_INIT(&defragtracker_hash[i]);
    }
    (void) SC_ATOMIC_ADD(defrag_memuse, (defrag_config.hash_size * sizeof(DefragTrackerHashRow)));

    if (quiet == FALSE) {
        SCLogConfig("allocated %"PRIu64" bytes of memory for the defrag hash... "
                  "%" PRIu32 " buckets of size %" PRIuMAX "",
                  SC_ATOMIC_GET(defrag_memuse), defrag_config.hash_size,
                  (uintmax_t)sizeof(DefragTrackerHashRow));
    }

    if ((ConfGet("defrag.prealloc", &conf_val)) == 1)
    {
        if (ConfValIsTrue(conf_val)) {
            /* pre allocate defrag trackers */
            for (i = 0; i < defrag_config.prealloc; i++) {
                if (!(DEFRAG_CHECK_MEMCAP(sizeof(DefragTracker)))) {
                    SCLogError(SC_ERR_DEFRAG_INIT, "preallocating defrag trackers failed: "
                            "max defrag memcap reached. Memcap %"PRIu64", "
                            "Memuse %"PRIu64".", defrag_config.memcap,
                            ((uint64_t)SC_ATOMIC_GET(defrag_memuse) + (uint64_t)sizeof(DefragTracker)));
                    exit(EXIT_FAILURE);
                }

                DefragTracker *h = DefragTrackerAlloc();
                if (h == NULL) {
                    SCLogError(SC_ERR_DEFRAG_INIT, "preallocating defrag failed: %s", strerror(errno));
                    exit(EXIT_FAILURE);
                }
                DefragTrackerEnqueue(&defragtracker_spare_q,h);
            }
            if (quiet == FALSE) {
                SCLogConfig("preallocated %" PRIu32 " defrag trackers of size %" PRIuMAX "",
                        defragtracker_spare_q.len, (uintmax_t)sizeof(DefragTracker));
            }
        }
    }

    if (quiet == FALSE) {
        SCLogConfig("defrag memory usage: %"PRIu64" bytes, maximum: %"PRIu64,
                SC_ATOMIC_GET(defrag_memuse), defrag_config.memcap);
    }

    return;
}
Exemple #26
0
/**
 * \brief Initialize profiling.
 */
void
SCProfilingInit(void)
{
    ConfNode *conf;

    SC_ATOMIC_INIT(samples);

    intmax_t rate_v = 0;
    (void)ConfGetInt("profiling.sample-rate", &rate_v);
    if (rate_v > 0 && rate_v < INT_MAX) {
        rate = (int)rate_v;
        if (rate != 1)
            SCLogInfo("profiling runs for every %dth packet", rate);
        else
            SCLogInfo("profiling runs for every packet");
    }

    conf = ConfGetNode("profiling.packets");
    if (conf != NULL) {
        if (ConfNodeChildValueIsTrue(conf, "enabled")) {
            profiling_packets_enabled = 1;

            if (pthread_mutex_init(&packet_profile_lock, NULL) != 0) {
                SCLogError(SC_ERR_MUTEX,
                        "Failed to initialize packet profiling mutex.");
                exit(EXIT_FAILURE);
            }
            memset(&packet_profile_data4, 0, sizeof(packet_profile_data4));
            memset(&packet_profile_data6, 0, sizeof(packet_profile_data6));
            memset(&packet_profile_tmm_data4, 0, sizeof(packet_profile_tmm_data4));
            memset(&packet_profile_tmm_data6, 0, sizeof(packet_profile_tmm_data6));
            memset(&packet_profile_app_data4, 0, sizeof(packet_profile_app_data4));
            memset(&packet_profile_app_data6, 0, sizeof(packet_profile_app_data6));
            memset(&packet_profile_app_pd_data4, 0, sizeof(packet_profile_app_pd_data4));
            memset(&packet_profile_app_pd_data6, 0, sizeof(packet_profile_app_pd_data6));
            memset(&packet_profile_detect_data4, 0, sizeof(packet_profile_detect_data4));
            memset(&packet_profile_detect_data6, 0, sizeof(packet_profile_detect_data6));
            memset(&packet_profile_log_data4, 0, sizeof(packet_profile_log_data4));
            memset(&packet_profile_log_data6, 0, sizeof(packet_profile_log_data6));
            memset(&packet_profile_flowworker_data, 0, sizeof(packet_profile_flowworker_data));

            const char *filename = ConfNodeLookupChildValue(conf, "filename");
            if (filename != NULL) {

                char *log_dir;
                log_dir = ConfigGetLogDirectory();

                profiling_packets_file_name = SCMalloc(PATH_MAX);
                if (unlikely(profiling_packets_file_name == NULL)) {
                    SCLogError(SC_ERR_MEM_ALLOC, "can't duplicate file name");
                    exit(EXIT_FAILURE);
                }

                snprintf(profiling_packets_file_name, PATH_MAX, "%s/%s", log_dir, filename);

                const char *v = ConfNodeLookupChildValue(conf, "append");
                if (v == NULL || ConfValIsTrue(v)) {
                    profiling_packets_file_mode = "a";
                } else {
                    profiling_packets_file_mode = "w";
                }

                profiling_packets_output_to_file = 1;
            }
        }

        conf = ConfGetNode("profiling.packets.csv");
        if (conf != NULL) {
            if (ConfNodeChildValueIsTrue(conf, "enabled")) {

                const char *filename = ConfNodeLookupChildValue(conf, "filename");
                if (filename == NULL) {
                    filename = "packet_profile.csv";
                }

                char *log_dir;
                log_dir = ConfigGetLogDirectory();

                profiling_csv_file_name = SCMalloc(PATH_MAX);
                if (unlikely(profiling_csv_file_name == NULL)) {
                    SCLogError(SC_ERR_MEM_ALLOC, "out of memory");
                    exit(EXIT_FAILURE);
                }
                snprintf(profiling_csv_file_name, PATH_MAX, "%s/%s", log_dir, filename);

                packet_profile_csv_fp = fopen(profiling_csv_file_name, "w");
                if (packet_profile_csv_fp == NULL) {
                    return;
                }
                fprintf(packet_profile_csv_fp, "pcap_cnt,ipver,ipproto,total,");
                int i;
                for (i = 0; i < TMM_SIZE; i++) {
                    fprintf(packet_profile_csv_fp, "%s,", TmModuleTmmIdToString(i));
                }
                fprintf(packet_profile_csv_fp, "threading,");
                for (i = 0; i < ALPROTO_MAX; i++) {
                    fprintf(packet_profile_csv_fp, "%s,", AppProtoToString(i));
                }
                fprintf(packet_profile_csv_fp, "proto detect,");
                for (i = 0; i < PROF_DETECT_SIZE; i++) {
                    fprintf(packet_profile_csv_fp, "%s,", PacketProfileDetectIdToString(i));
                }
                fprintf(packet_profile_csv_fp, "\n");

                profiling_packets_csv_enabled = 1;
            }
        }
    }

    conf = ConfGetNode("profiling.locks");
    if (conf != NULL) {
        if (ConfNodeChildValueIsTrue(conf, "enabled")) {
#ifndef PROFILE_LOCKING
            SCLogWarning(SC_WARN_PROFILE, "lock profiling not compiled in. Add --enable-profiling-locks to configure.");
#else
            profiling_locks_enabled = 1;

            LockRecordInitHash();

            const char *filename = ConfNodeLookupChildValue(conf, "filename");
            if (filename != NULL) {
                char *log_dir;
                log_dir = ConfigGetLogDirectory();

                profiling_locks_file_name = SCMalloc(PATH_MAX);
                if (unlikely(profiling_locks_file_name == NULL)) {
                    SCLogError(SC_ERR_MEM_ALLOC, "can't duplicate file name");
                    exit(EXIT_FAILURE);
                }

                snprintf(profiling_locks_file_name, PATH_MAX, "%s/%s", log_dir, filename);

                const char *v = ConfNodeLookupChildValue(conf, "append");
                if (v == NULL || ConfValIsTrue(v)) {
                    profiling_locks_file_mode = "a";
                } else {
                    profiling_locks_file_mode = "w";
                }

                profiling_locks_output_to_file = 1;
            }
#endif
        }
    }

}
/**
* \brief extract information from config file
*
* The returned structure will be freed by the thread init function.
* This is thus necessary to or copy the structure before giving it
* to thread or to reparse the file for each thread (and thus have
* new structure.
*
* \return a NetmapIfaceConfig corresponding to the interface name
*/
static void *ParseNetmapConfig(const char *iface_name)
{
    char *threadsstr = NULL;
    ConfNode *if_root;
    ConfNode *if_default = NULL;
    ConfNode *netmap_node;
    NetmapIfaceConfig *aconf = SCMalloc(sizeof(*aconf));
    char *tmpctype;
    char *copymodestr;
    int boolval;
    char *bpf_filter = NULL;
    char *out_iface = NULL;

    if (unlikely(aconf == NULL)) {
        return NULL;
    }

    if (iface_name == NULL) {
        SCFree(aconf);
        return NULL;
    }

    memset(aconf, 0, sizeof(*aconf));
    aconf->DerefFunc = NetmapDerefConfig;
    aconf->threads = 1;
    aconf->promisc = 1;
    aconf->checksum_mode = CHECKSUM_VALIDATION_AUTO;
    aconf->copy_mode = NETMAP_COPY_MODE_NONE;
    strlcpy(aconf->iface_name, iface_name, sizeof(aconf->iface_name));
    SC_ATOMIC_INIT(aconf->ref);
    (void) SC_ATOMIC_ADD(aconf->ref, 1);

    strlcpy(aconf->iface, aconf->iface_name, sizeof(aconf->iface));
    if (aconf->iface[0]) {
        size_t len = strlen(aconf->iface);
        if (aconf->iface[len-1] == '+') {
            aconf->iface[len-1] = '\0';
            aconf->iface_sw = 1;
        }
    }

    if (ConfGet("bpf-filter", &bpf_filter) == 1) {
        if (strlen(bpf_filter) > 0) {
            aconf->bpf_filter = bpf_filter;
            SCLogInfo("Going to use command-line provided bpf filter '%s'",
                    aconf->bpf_filter);
        }
    }

    /* Find initial node */
    netmap_node = ConfGetNode("netmap");
    if (netmap_node == NULL) {
        SCLogInfo("Unable to find netmap config using default value");
        return aconf;
    }

    if_root = ConfFindDeviceConfig(netmap_node, aconf->iface_name);

    if_default = ConfFindDeviceConfig(netmap_node, "default");

    if (if_root == NULL && if_default == NULL) {
        SCLogInfo("Unable to find netmap config for "
                "interface \"%s\" or \"default\", using default value",
                aconf->iface_name);
        return aconf;
    }

    /* If there is no setting for current interface use default one as main iface */
    if (if_root == NULL) {
        if_root = if_default;
        if_default = NULL;
    }

    if (ConfGetChildValueWithDefault(if_root, if_default, "threads", &threadsstr) != 1) {
        aconf->threads = 1;
    } else {
        if (strcmp(threadsstr, "auto") == 0) {
            aconf->threads = GetIfaceRSSQueuesNum(aconf->iface);
        } else {
            aconf->threads = (uint8_t)atoi(threadsstr);
        }
    }

    if (aconf->threads <= 0) {
        aconf->threads = 1;
    }
    if (aconf->threads) {
        SCLogInfo("Using %d threads for interface %s", aconf->threads,
                  aconf->iface_name);
    }

    if (ConfGetChildValueWithDefault(if_root, if_default, "copy-iface", &out_iface) == 1) {
        if (strlen(out_iface) > 0) {
            aconf->out_iface_name = out_iface;
        }
    }

    if (ConfGetChildValueWithDefault(if_root, if_default, "copy-mode", &copymodestr) == 1) {
        if (aconf->out_iface_name == NULL) {
            SCLogInfo("Copy mode activated but no destination"
                    " iface. Disabling feature");
        } else if (strlen(copymodestr) <= 0) {
            aconf->out_iface_name = NULL;
        } else if (strcmp(copymodestr, "ips") == 0) {
            SCLogInfo("Netmap IPS mode activated %s->%s",
                    aconf->iface_name,
                    aconf->out_iface_name);
            aconf->copy_mode = NETMAP_COPY_MODE_IPS;
        } else if (strcmp(copymodestr, "tap") == 0) {
            SCLogInfo("Netmap TAP mode activated %s->%s",
                    aconf->iface_name,
                    aconf->out_iface_name);
            aconf->copy_mode = NETMAP_COPY_MODE_TAP;
        } else {
            SCLogInfo("Invalid mode (not in tap, ips)");
        }
    }

    if (aconf->out_iface_name && aconf->out_iface_name[0]) {
        strlcpy(aconf->out_iface, aconf->out_iface_name,
                sizeof(aconf->out_iface));
        size_t len = strlen(aconf->out_iface);
        if (aconf->out_iface[len-1] == '+') {
            aconf->out_iface[len-1] = '\0';
            aconf->out_iface_sw = 1;
        }
    }

    SC_ATOMIC_RESET(aconf->ref);
    (void) SC_ATOMIC_ADD(aconf->ref, aconf->threads);

    /* load netmap bpf filter */
    /* command line value has precedence */
    if (ConfGet("bpf-filter", &bpf_filter) != 1) {
        if (ConfGetChildValueWithDefault(if_root, if_default, "bpf-filter", &bpf_filter) == 1) {
            if (strlen(bpf_filter) > 0) {
                aconf->bpf_filter = bpf_filter;
                SCLogInfo("Going to use bpf filter %s", aconf->bpf_filter);
            }
        }
    }

    (void)ConfGetChildValueBoolWithDefault(if_root, if_default, "disable-promisc", (int *)&boolval);
    if (boolval) {
        SCLogInfo("Disabling promiscuous mode on iface %s", aconf->iface);
        aconf->promisc = 0;
    }

    if (ConfGetChildValueWithDefault(if_root, if_default, "checksum-checks", &tmpctype) == 1) {
        if (strcmp(tmpctype, "auto") == 0) {
            aconf->checksum_mode = CHECKSUM_VALIDATION_AUTO;
        } else if (ConfValIsTrue(tmpctype)) {
            aconf->checksum_mode = CHECKSUM_VALIDATION_ENABLE;
        } else if (ConfValIsFalse(tmpctype)) {
            aconf->checksum_mode = CHECKSUM_VALIDATION_DISABLE;
        } else {
            SCLogError(SC_ERR_INVALID_ARGUMENT, "Invalid value for checksum-checks for %s", aconf->iface_name);
        }
    }

    return aconf;
}
Exemple #28
0
/**
 * \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 *JsonAlertLogInitCtxSub(ConfNode *conf, OutputCtx *parent_ctx)
{
    AlertJsonThread *ajt = parent_ctx->data;
    AlertJsonOutputCtx *json_output_ctx = NULL;
    HttpXFFCfg *xff_cfg = NULL;

    OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx));
    if (unlikely(output_ctx == NULL))
        return NULL;

    json_output_ctx = SCMalloc(sizeof(AlertJsonOutputCtx));
    if (unlikely(json_output_ctx == NULL)) {
        goto error;
    }
    memset(json_output_ctx, 0, sizeof(AlertJsonOutputCtx));

    xff_cfg = SCMalloc(sizeof(HttpXFFCfg));
    if (unlikely(xff_cfg == NULL)) {
        goto error;
    }
    memset(xff_cfg, 0, sizeof(HttpXFFCfg));

    json_output_ctx->file_ctx = ajt->file_ctx;
    json_output_ctx->xff_cfg = xff_cfg;

    if (conf != NULL) {
        const char *payload = ConfNodeLookupChildValue(conf, "payload");
        const char *packet  = ConfNodeLookupChildValue(conf, "packet");
        const char *payload_printable = ConfNodeLookupChildValue(conf, "payload-printable");
        const char *http = ConfNodeLookupChildValue(conf, "http");
        const char *tls = ConfNodeLookupChildValue(conf, "tls");
        const char *ssh = ConfNodeLookupChildValue(conf, "ssh");

        if (ssh != NULL) {
            if (ConfValIsTrue(ssh)) {
                json_output_ctx->flags |= LOG_JSON_SSH;
            }
        }
        if (tls != NULL) {
            if (ConfValIsTrue(tls)) {
                json_output_ctx->flags |= LOG_JSON_TLS;
            }
        }
        if (http != NULL) {
            if (ConfValIsTrue(http)) {
                json_output_ctx->flags |= LOG_JSON_HTTP;
            }
        }
        if (payload_printable != NULL) {
            if (ConfValIsTrue(payload_printable)) {
                json_output_ctx->flags |= LOG_JSON_PAYLOAD;
            }
        }
        if (payload != NULL) {
            if (ConfValIsTrue(payload)) {
                json_output_ctx->flags |= LOG_JSON_PAYLOAD_BASE64;
            }
        }
        if (packet != NULL) {
            if (ConfValIsTrue(packet)) {
                json_output_ctx->flags |= LOG_JSON_PACKET;
            }
        }

        HttpXFFGetCfg(conf, xff_cfg);
    }

    output_ctx->data = json_output_ctx;
    output_ctx->DeInit = JsonAlertLogDeInitCtxSub;

    return output_ctx;

error:
    if (json_output_ctx != NULL) {
        SCFree(json_output_ctx);
    }
    if (output_ctx != NULL) {
        SCFree(output_ctx);
    }

    return NULL;
}
Exemple #29
0
static void XffSetup(AlertJsonOutputCtx *json_output_ctx, ConfNode *conf)
{
    HttpXFFCfg *xff_cfg = NULL;

    xff_cfg = SCMalloc(sizeof(HttpXFFCfg));
    if (unlikely(xff_cfg == NULL)) {
        return;
    }
    memset(xff_cfg, 0, sizeof(HttpXFFCfg));

    json_output_ctx->xff_cfg = xff_cfg;

    uint32_t payload_buffer_size = JSON_STREAM_BUFFER_SIZE;

    if (conf != NULL) {
        const char *payload = ConfNodeLookupChildValue(conf, "payload");
        const char *payload_buffer_value = ConfNodeLookupChildValue(conf, "payload-buffer-size");
        const char *packet  = ConfNodeLookupChildValue(conf, "packet");
        const char *payload_printable = ConfNodeLookupChildValue(conf, "payload-printable");
        const char *http = ConfNodeLookupChildValue(conf, "http");
        const char *tls = ConfNodeLookupChildValue(conf, "tls");
        const char *ssh = ConfNodeLookupChildValue(conf, "ssh");
        const char *smtp = ConfNodeLookupChildValue(conf, "smtp");
        const char *tagged_packets = ConfNodeLookupChildValue(conf, "tagged-packets");

        if (ssh != NULL) {
            if (ConfValIsTrue(ssh)) {
                json_output_ctx->flags |= LOG_JSON_SSH;
            }
        }
        if (tls != NULL) {
            if (ConfValIsTrue(tls)) {
                json_output_ctx->flags |= LOG_JSON_TLS;
            }
        }
        if (http != NULL) {
            if (ConfValIsTrue(http)) {
                json_output_ctx->flags |= LOG_JSON_HTTP;
            }
        }
        if (smtp != NULL) {
            if (ConfValIsTrue(smtp)) {
                json_output_ctx->flags |= LOG_JSON_SMTP;
            }
        }
        if (payload_printable != NULL) {
            if (ConfValIsTrue(payload_printable)) {
                json_output_ctx->flags |= LOG_JSON_PAYLOAD;
            }
        }
        if (payload != NULL) {
            if (ConfValIsTrue(payload)) {
                json_output_ctx->flags |= LOG_JSON_PAYLOAD_BASE64;
            }
        }
        if (payload_buffer_value != NULL) {
            uint32_t value;
            if (ParseSizeStringU32(payload_buffer_value, &value) < 0) {
                SCLogError(SC_ERR_ALERT_PAYLOAD_BUFFER, "Error parsing "
                           "payload-buffer-size - %s. Killing engine",
                           payload_buffer_value);
                exit(EXIT_FAILURE);
            } else {
                payload_buffer_size = value;
            }
        }
        if (packet != NULL) {
            if (ConfValIsTrue(packet)) {
                json_output_ctx->flags |= LOG_JSON_PACKET;
            }
        }
        if (tagged_packets != NULL) {
            if (ConfValIsTrue(tagged_packets)) {
                json_output_ctx->flags |= LOG_JSON_TAGGED_PACKETS;
            }
        }

	json_output_ctx->payload_buffer_size = payload_buffer_size;
        HttpXFFGetCfg(conf, xff_cfg);
    }
}
Exemple #30
0
/** \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;
}