- Autoconf goo for libyaml.

- Mock YAML configuration file.

- YAML loader for basic YAML files - not all YAML elements support yet..
  todo.

- Add --dump-config command line parameter to dump the state of the
  configuration db after loading the config file.
remotes/origin/master-1.0.x
Jason Ish 16 years ago committed by Victor Julien
parent 733c3bcb8c
commit c91a4baad5

@ -34,6 +34,9 @@
/* Define to 1 if you have the `pthread' library (-lpthread). */
#undef HAVE_LIBPTHREAD
/* Define to 1 if you have the `yaml' library (-lyaml). */
#undef HAVE_LIBYAML
/* Define to 1 if you have the <limits.h> header file. */
#undef HAVE_LIMITS_H

@ -85,6 +85,36 @@ AC_INIT(configure.in)
exit 1
fi
#libyaml
AC_ARG_WITH(libyaml_includes,
[ --with-libyaml-includes=DIR libyaml include directory],
[with_libyaml_includes="$withval"],[with_libyaml_includes=no])
AC_ARG_WITH(libyaml_libraries,
[ --with-libyaml-libraries=DIR libyaml library directory],
[with_libyaml_libraries="$withval"],[with_libyaml_libraries="no"])
if test "$with_libyaml_includes" != "no"; then
CPPFLAGS="${CPPFLAGS} -I${with_libyaml_includes}"
fi
AC_CHECK_HEADER(yaml.h,,LIBYAML="no")
if test "$with_libyaml_libraries" != "no"; then
LDFLAGS="${LDFLAGS} -L${with_libyaml_libraries}"
fi
LIBYAML=""
AC_CHECK_LIB(yaml,yaml_parser_initialize,,LIBYAML="no")
if test "$LIBYAML" = "no"; then
echo
echo " ERROR! libyaml library not found, go get it"
echo " from http://pyyaml.org/wiki/LibYAML."
echo " or check your package manager."
echo
exit 1
fi
#libpthread
AC_ARG_WITH(libpthread_includes,
[ --with-libpthread-includes=DIR libpthread include directory],

@ -0,0 +1,47 @@
# The default logging directory. Any log or output file will be
# placed here if its not specified with a full path name. This can be
# overridden with the -l command line parameter.
default-log-dir: /var/log/eidps
# Logging configuration. This is not about logging IDS alerts, but
# IDS output about what its doing, errors, etc.
logging:
# The default log level, can be overridden in an output section.
default-log-level: debug
# The default output format. Optional parameter, should default to
# something reasonable if not provided. Can be overriden in an
# output section.
default-format: "<%t> - <%l>"
# Default startup message. Optional parameter, should default to
# something reasonable if not provided. Can be overridden in an
# output section.
default-startup-message: Your IDS has started.
# A regex to filter output. Can be overridden in an output section.
# Defaults to empty (no filter).
default-output-filter:
# Configure the outputs. If no outputs are specified the engine
# will log to the console with an error log level.
output:
# Enable logging to the console. Be a little more verbose than
# default, log info and more critical.
- interface: console
log-level: info
# Log to a file as well. No log level specified so level will be
# set to the default-log-level.
- interface: file
filename: /var/log/eidps.log
# Log to syslog with facility local5. Again, no level specified so
# will level will be set to default-log-level. We also override the
# format as we don't want to log a timestamp, syslog will do that
# for us.
- interface: syslog
facility: local5
format: "%l"

@ -103,7 +103,8 @@ app-layer-parser.c app-layer-parser.h \
app-layer-http.c app-layer-http.h \
app-layer-tls.c app-layer-tls.h \
app-layer-protos.h \
conf.c conf.h
conf.c conf.h \
conf-yaml-loader.c conf-yaml-loader.h
# set the include path found by configure
INCLUDES= $(all_includes)

@ -0,0 +1,206 @@
/* Copyright (c) 2009 Open Information Security Foundation */
/**
* \file
*
* \author Endace Technology Limited - Jason Ish <jason.ish@endace.com>
*
* YAML configuration loader.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <yaml.h>
#include "conf.h"
#undef YAML_LOADER_DEBUG
#ifdef YAML_LOADER_DEBUG
#define DPRINTF(x) do { printf x ; } while (0)
#else
#define DPRINTF(x)
#endif /* YAML_LOADER_DEBUG */
/* Define to print the current YAML state. */
#undef PRINT_STATES
#ifdef PRINT_STATES
#define DPRINT_STATE(x) do { printf x ; } while (0)
#else
#define DPRINT_STATE(x)
#endif /* PRINT_STATES */
/* Defines the maximum number of levels YAML may nest. This is
* primarily used for construction of lookup-keys for configuration
* values. */
#define MAX_LEVELS 16
/* Configuration processing states. */
enum conf_state {
CONF_KEY = 0,
CONF_VAL,
};
/**
* \brief Return the name of the current configuration key value.
*
* This function returns the current value of the configuration key.
* This is all the key components joined together with a ".".
*
* NOTE: This function is not re-entrant safe, but we do not expect to
* be loading configuration files concurrently.
*/
static char *
GetKeyName(char **key, int level)
{
/* Statically allocate a string that should be large enough. */
static char print_key[1024];
int i;
print_key[0] = '\0';
for (i = 0; i <= level; i++) {
if (key[i] == NULL)
break;
if (strlen(key[i]) + strlen(print_key) + 2 > sizeof(print_key)) {
/* Overflow. */
return NULL;
}
else {
strncat(print_key, key[i], strlen(key[i]));
if (i < level)
strncat(print_key, ".", 1);
}
}
return print_key;
}
/**
* \brief Load a configuration file.
*
* Loads the IDS configuration file. On failure, the program will
* exist with an error message.
*
* \param filename Name of the filename to load.
*/
void
LoadYamlConf(const char *filename)
{
FILE *conf_file;
yaml_parser_t parser;
yaml_event_t event;
int done;
int level;
int state;
int inseq;
char *key[MAX_LEVELS];
memset(key, 0, sizeof(key));
if (yaml_parser_initialize(&parser) != 1) {
fprintf(stderr, "Failed to initialize yaml parser.\n");
exit(EXIT_FAILURE);
}
conf_file = fopen(filename, "r");
if (conf_file == NULL) {
fprintf(stderr, "Failed to open file: %s: %s\n", filename,
strerror(errno));
exit(EXIT_FAILURE);
}
yaml_parser_set_input_file(&parser, conf_file);
state = CONF_KEY;
done = 0;
level = -1;
inseq = 0;
while (!done) {
if (!yaml_parser_parse(&parser, &event)) {
fprintf(stderr, "Failed to parse configuration file: %s\n",
parser.problem);
exit(EXIT_FAILURE);
}
if (level > -1) {
DPRINTF(("Current key: %s\n", GetKeyName(key, level)));
}
switch (event.type) {
case YAML_STREAM_START_EVENT:
DPRINT_STATE(("YAML_STREAM_START_EVENT\n"));
break;
case YAML_STREAM_END_EVENT:
DPRINT_STATE(("YAML_STREAM_END_EVENT\n"));
done = 1;
break;
case YAML_DOCUMENT_START_EVENT:
DPRINT_STATE(("YAML_STREAM_END_EVENT\n"));
/* Ignored. */
break;
case YAML_DOCUMENT_END_EVENT:
DPRINT_STATE(("YAML_DOCUMENT_END_EVENT\n"));
/* Ignored. */
break;
case YAML_SEQUENCE_START_EVENT:
DPRINT_STATE(("YAML_SEQUENCE_START_EVENT\n"));
inseq = 1;
break;
case YAML_SEQUENCE_END_EVENT:
DPRINT_STATE(("YAML_SEQUENCE_END_EVENT\n"));
inseq = 0;
break;
case YAML_MAPPING_START_EVENT:
DPRINT_STATE(("YAML_MAPPING_START_EVENT\n"));
level++;
if (level == MAX_LEVELS) {
fprintf(stderr, "Reached maximum configuration nesting level.\n");
exit(EXIT_FAILURE);
}
/* Since we are entering a new mapping, state goes back to key. */
state = CONF_KEY;
break;
case YAML_MAPPING_END_EVENT:
DPRINT_STATE(("YAML_MAPPING_END_EVENT\n"));
if (level > -1) {
free(key[level]);
key[level] = NULL;
}
level--;
break;
case YAML_SCALAR_EVENT:
DPRINT_STATE(("YAML_SCALAR_EVENT\n"));
if (inseq) {
printf("Ignoring sequence value for %s\n",
GetKeyName(key, level));
break;
}
if (state == CONF_KEY) {
if (key[level] != NULL)
free(key[level]);
key[level] = strdup((char *)event.data.scalar.value);
/* Move state to expecting a value. */
state = CONF_VAL;
}
else if (state == CONF_VAL) {
ConfSet(GetKeyName(key, level), (char *)event.data.scalar.value,
1);
state = CONF_KEY;
}
break;
case YAML_ALIAS_EVENT:
DPRINT_STATE(("YAML_ALIAS_EVENT\n"));
break;
case YAML_NO_EVENT:
DPRINT_STATE(("YAML_NO_EVENT\n"));
break;
}
yaml_event_delete(&event);
}
yaml_parser_delete(&parser);
fclose(conf_file);
}

@ -0,0 +1,8 @@
/* Copyright (c) 2009 Open Information Security Foundation */
#ifndef __CONF_YAML_LOADER_H__
#define __CONF_YAML_LOADER_H__
void LoadYamlConf(const char *);
#endif /* !__CONF_YAML_LOADER_H__ */

@ -73,6 +73,7 @@
#include "util-time.h"
#include "conf.h"
#include "conf-yaml-loader.h"
/*
* we put this here, because we only use it here in main.
@ -1378,6 +1379,7 @@ int RunModeFilePcap2(DetectEngineCtx *de_ctx, char *file) {
void usage(const char *progname)
{
printf("USAGE: %s\n\n", progname);
printf("\t-c <path>: path to configuration file\n");
printf("\t-i <dev> : run in pcap live mode\n");
printf("\t-r <path>: run in pcap file/offline mode\n");
printf("\t-q <qid> : run in inline nfqueue mode\n");
@ -1397,6 +1399,8 @@ int main(int argc, char **argv)
char *pcap_dev = NULL;
char *sig_file = NULL;
int nfq_id = 0;
char *conf_filename = NULL;
int dump_config = 0;
/* registering signals we use */
SignalHandlerSetup(SIGINT, SignalHandlerSigint);
@ -1406,8 +1410,20 @@ int main(int argc, char **argv)
/* Initialize the configuration module. */
ConfInit();
while ((opt = getopt(argc, argv, "hi:l:q:r:us:")) != -1) {
struct option long_opts[] = {
{"dump-config", 0, &dump_config, 1},
{NULL, 0, NULL, 0}
};
char short_opts[] = "c:hi:l:q:r:us:";
while ((opt = getopt_long(argc, argv, short_opts, long_opts, NULL)) != -1) {
switch (opt) {
case 0:
/* Long opt handler. */
break;
case 'c':
conf_filename = optarg;
break;
case 'h':
usage(argv[0]);
exit(EXIT_SUCCESS);
@ -1447,6 +1463,16 @@ int main(int argc, char **argv)
}
}
/* Load yaml configuration file if provided. */
if (conf_filename != NULL) {
LoadYamlConf(conf_filename);
}
if (dump_config) {
ConfDump();
exit(EXIT_SUCCESS);
}
if (mode == MODE_UNKNOWN) {
usage(argv[0]);
exit(EXIT_FAILURE);

Loading…
Cancel
Save