|
|
|
@ -27,6 +27,11 @@
|
|
|
|
|
* values. */
|
|
|
|
|
#define MAX_LEVELS 16
|
|
|
|
|
|
|
|
|
|
/* Sometimes we'll have to create a node name on the fly (integer
|
|
|
|
|
* conversion, etc), so this is a default length to allocate that will
|
|
|
|
|
* work most of the time. */
|
|
|
|
|
#define DEFAULT_NAME_LEN 16
|
|
|
|
|
|
|
|
|
|
/* Configuration processing states. */
|
|
|
|
|
enum conf_state {
|
|
|
|
|
CONF_KEY = 0,
|
|
|
|
@ -77,15 +82,15 @@ GetKeyName(char **key, int level)
|
|
|
|
|
*
|
|
|
|
|
* \param parser A pointer to an active yaml_parser_t.
|
|
|
|
|
* \param parent The parent configuration node.
|
|
|
|
|
* \param init_state State to start off as.
|
|
|
|
|
*/
|
|
|
|
|
static void
|
|
|
|
|
ConfYamlParse2(yaml_parser_t *parser, ConfNode *parent, int init_state)
|
|
|
|
|
ConfYamlParse2(yaml_parser_t *parser, ConfNode *parent, int inseq)
|
|
|
|
|
{
|
|
|
|
|
ConfNode *node = parent;
|
|
|
|
|
yaml_event_t event;
|
|
|
|
|
int done = 0;
|
|
|
|
|
int state = init_state;
|
|
|
|
|
int state = 0;
|
|
|
|
|
int seq_idx = 0;
|
|
|
|
|
|
|
|
|
|
while (!done) {
|
|
|
|
|
if (!yaml_parser_parse(parser, &event)) {
|
|
|
|
@ -95,41 +100,44 @@ ConfYamlParse2(yaml_parser_t *parser, ConfNode *parent, int init_state)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (event.type == YAML_SCALAR_EVENT) {
|
|
|
|
|
if (state) {
|
|
|
|
|
ConfNode *new;
|
|
|
|
|
new = ConfNodeNew();
|
|
|
|
|
if (new == NULL) {
|
|
|
|
|
SCLogError(SC_ERR_MEM_ALLOC,
|
|
|
|
|
"Failed to allocate memory for new configuration node.");
|
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
|
}
|
|
|
|
|
new->val = strdup((char *)event.data.scalar.value);
|
|
|
|
|
TAILQ_INSERT_TAIL(&node->head, new, next);
|
|
|
|
|
char *value = (char *)event.data.scalar.value;
|
|
|
|
|
if (inseq) {
|
|
|
|
|
ConfNode *seq_node = ConfNodeNew();
|
|
|
|
|
seq_node->name = calloc(1, DEFAULT_NAME_LEN);
|
|
|
|
|
snprintf(seq_node->name, DEFAULT_NAME_LEN, "%d", seq_idx++);
|
|
|
|
|
seq_node->val = strdup(value);
|
|
|
|
|
TAILQ_INSERT_TAIL(&parent->head, seq_node, next);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
node = ConfNodeNew();
|
|
|
|
|
if (node == NULL) {
|
|
|
|
|
SCLogError(SC_ERR_MEM_ALLOC,
|
|
|
|
|
"Failed to allocate memory for new configuration node.");
|
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
|
if (state == CONF_KEY) {
|
|
|
|
|
node = ConfNodeNew();
|
|
|
|
|
node->name = strdup((char *)event.data.scalar.value);
|
|
|
|
|
TAILQ_INSERT_TAIL(&parent->head, node, next);
|
|
|
|
|
state = CONF_VAL;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
node->val = strdup((char *)event.data.scalar.value);
|
|
|
|
|
state = CONF_KEY;
|
|
|
|
|
}
|
|
|
|
|
node->val = strdup((char *)event.data.scalar.value);
|
|
|
|
|
TAILQ_INSERT_TAIL(&parent->head, node, next);
|
|
|
|
|
}
|
|
|
|
|
state ^= CONF_VAL;
|
|
|
|
|
}
|
|
|
|
|
else if (event.type == YAML_SEQUENCE_START_EVENT) {
|
|
|
|
|
state = CONF_SEQ;
|
|
|
|
|
}
|
|
|
|
|
else if (event.type == YAML_SEQUENCE_END_EVENT) {
|
|
|
|
|
state = CONF_KEY;
|
|
|
|
|
|
|
|
|
|
/* Only b/c we called from the old parser... */
|
|
|
|
|
if (init_state != CONF_KEY)
|
|
|
|
|
return;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
else if (event.type == YAML_MAPPING_START_EVENT) {
|
|
|
|
|
ConfYamlParse2(parser, node, 0);
|
|
|
|
|
if (inseq) {
|
|
|
|
|
ConfNode *seq_node = ConfNodeNew();
|
|
|
|
|
seq_node->name = calloc(1, DEFAULT_NAME_LEN);
|
|
|
|
|
snprintf(seq_node->name, DEFAULT_NAME_LEN, "%d", seq_idx++);
|
|
|
|
|
TAILQ_INSERT_TAIL(&node->head, seq_node, next);
|
|
|
|
|
ConfYamlParse2(parser, seq_node, 0);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
ConfYamlParse2(parser, node, inseq);
|
|
|
|
|
}
|
|
|
|
|
state ^= CONF_VAL;
|
|
|
|
|
}
|
|
|
|
|
else if (event.type == YAML_MAPPING_END_EVENT) {
|
|
|
|
@ -187,13 +195,8 @@ ConfYamlParse(yaml_parser_t *parser)
|
|
|
|
|
case YAML_SEQUENCE_START_EVENT: {
|
|
|
|
|
ConfNode *new;
|
|
|
|
|
new = ConfNodeNew();
|
|
|
|
|
if (new == NULL) {
|
|
|
|
|
SCLogError(SC_ERR_MEM_ALLOC,
|
|
|
|
|
"Failed to allocate new configuration node.");
|
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
|
}
|
|
|
|
|
new->name = strdup(GetKeyName(key, level));
|
|
|
|
|
ConfYamlParse2(parser, new, CONF_SEQ);
|
|
|
|
|
ConfYamlParse2(parser, new, 1);
|
|
|
|
|
ConfSetNode(new);
|
|
|
|
|
state = CONF_KEY;
|
|
|
|
|
break;
|
|
|
|
@ -292,9 +295,6 @@ static int
|
|
|
|
|
ConfYamlRuleFileTest(void)
|
|
|
|
|
{
|
|
|
|
|
char input[] = "\
|
|
|
|
|
some-other-list:\n\
|
|
|
|
|
- one\n\
|
|
|
|
|
- two\n\
|
|
|
|
|
rule-files:\n\
|
|
|
|
|
- netbios.rules\n\
|
|
|
|
|
- x11.rules\n\
|
|
|
|
@ -329,6 +329,73 @@ default-log-dir: /tmp\n\
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
ConfYamlLoggingOutputTest(void)
|
|
|
|
|
{
|
|
|
|
|
char input[] = "\
|
|
|
|
|
logging:\n\
|
|
|
|
|
output:\n\
|
|
|
|
|
- interface: console\n\
|
|
|
|
|
log-level: error\n\
|
|
|
|
|
- interface: syslog\n\
|
|
|
|
|
facility: local4\n\
|
|
|
|
|
log-level: info\n\
|
|
|
|
|
";
|
|
|
|
|
|
|
|
|
|
ConfYamlLoadString(input, strlen(input));
|
|
|
|
|
|
|
|
|
|
ConfNode *outputs;
|
|
|
|
|
outputs = ConfGetNode("logging.output");
|
|
|
|
|
if (outputs == NULL)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
ConfNode *output;
|
|
|
|
|
ConfNode *output_param;
|
|
|
|
|
|
|
|
|
|
output = TAILQ_FIRST(&outputs->head);
|
|
|
|
|
if (output == NULL)
|
|
|
|
|
return 0;
|
|
|
|
|
if (strcmp(output->name, "0") != 0)
|
|
|
|
|
return 0;
|
|
|
|
|
output_param = TAILQ_FIRST(&output->head);
|
|
|
|
|
if (output_param == NULL)
|
|
|
|
|
return 0;
|
|
|
|
|
if (strcmp(output_param->name, "interface") != 0)
|
|
|
|
|
return 0;
|
|
|
|
|
if (strcmp(output_param->val, "console") != 0)
|
|
|
|
|
return 0;
|
|
|
|
|
output_param = TAILQ_NEXT(output_param, next);
|
|
|
|
|
if (strcmp(output_param->name, "log-level") != 0)
|
|
|
|
|
return 0;
|
|
|
|
|
if (strcmp(output_param->val, "error") != 0)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
output = TAILQ_NEXT(output, next);
|
|
|
|
|
if (output == NULL)
|
|
|
|
|
return 0;
|
|
|
|
|
if (strcmp(output->name, "1") != 0)
|
|
|
|
|
return 0;
|
|
|
|
|
output_param = TAILQ_FIRST(&output->head);
|
|
|
|
|
if (output_param == NULL)
|
|
|
|
|
return 0;
|
|
|
|
|
if (strcmp(output_param->name, "interface") != 0)
|
|
|
|
|
return 0;
|
|
|
|
|
if (strcmp(output_param->val, "syslog") != 0)
|
|
|
|
|
return 0;
|
|
|
|
|
output_param = TAILQ_NEXT(output_param, next);
|
|
|
|
|
if (strcmp(output_param->name, "facility") != 0)
|
|
|
|
|
return 0;
|
|
|
|
|
if (strcmp(output_param->val, "local4") != 0)
|
|
|
|
|
return 0;
|
|
|
|
|
output_param = TAILQ_NEXT(output_param, next);
|
|
|
|
|
if (strcmp(output_param->name, "log-level") != 0)
|
|
|
|
|
return 0;
|
|
|
|
|
if (strcmp(output_param->val, "info") != 0)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endif /* UNITTESTS */
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
@ -336,5 +403,6 @@ ConfYamlRegisterTests(void)
|
|
|
|
|
{
|
|
|
|
|
#ifdef UNITTESTS
|
|
|
|
|
UtRegisterTest("ConfYamlRuleFileTest", ConfYamlRuleFileTest, 1);
|
|
|
|
|
UtRegisterTest("ConfYamlLoggingOutputTest", ConfYamlLoggingOutputTest, 1);
|
|
|
|
|
#endif /* UNITTESTS */
|
|
|
|
|
}
|
|
|
|
|