[prelude-cvslog] r9950 - prelude-correlator/trunk/plugins/pcre
noreply at prelude-ids.org
noreply at prelude-ids.org
Wed Sep 26 13:26:52 CEST 2007
Author: yoann
Date: 2007-09-26 13:26:50 +0200 (Wed, 26 Sep 2007)
New Revision: 9950
Modified:
prelude-correlator/trunk/plugins/pcre/pcre-mod.c
Log:
The user can now provide infinite number of "elseif" command.
"elif" is now accepted as a shortcut for "elseif".
Both left and right if operand can now be context.
Modified: prelude-correlator/trunk/plugins/pcre/pcre-mod.c
===================================================================
--- prelude-correlator/trunk/plugins/pcre/pcre-mod.c 2007-09-26 11:26:41 UTC (rev 9949)
+++ prelude-correlator/trunk/plugins/pcre/pcre-mod.c 2007-09-26 11:26:50 UTC (rev 9950)
@@ -82,25 +82,23 @@
typedef enum {
- IF_OPERATOR_EQUAL = 0x01,
- IF_OPERATOR_LOWER = 0x02,
- IF_OPERATOR_GREATER = 0x04,
- IF_OPERATOR_NOT = 0x08,
+ IF_OPERATOR_EQUAL = 0x01, /* integer, string, idmef */
+ IF_OPERATOR_LOWER = 0x02, /* integer */
+ IF_OPERATOR_GREATER = 0x04, /* integer */
+ IF_OPERATOR_NOT = 0x08, /* any */
+ IF_OPERATOR_IN = 0x10 /* idmef */
} if_operator_type_t;
struct if_cb {
prelude_list_t list;
- value_container_t *if_vcont;
+ value_container_t *left;
if_operator_type_t if_op;
- float if_value;
+ value_container_t *right;
prelude_list_t if_operation_list;
- value_container_t *else_vcont;
- if_operator_type_t else_op;
- float else_value;
- prelude_list_t else_operation_list;
+ struct if_cb *next;
};
@@ -329,7 +327,9 @@
if ( ! ctx )
prelude_log(PRELUDE_LOG_ERR, "alert on non existant context '%s'.\n", prelude_string_get_string(str));
else {
- if ( ! pcre_context_get_value_idmef(ctx) )
+ if ( pcre_context_get_type(ctx) != PCRE_CONTEXT_TYPE_IDMEF )
+ prelude_log(PRELUDE_LOG_ERR, "'%s' context isn't an IDMEF container.\n", prelude_string_get_string(str));
+ else if ( ! pcre_context_get_value_idmef(ctx) )
prelude_log(PRELUDE_LOG_ERR, "'%s' context contain no idmef value.\n", prelude_string_get_string(str));
else {
prelude_log_debug(3, "[%s]: emit alert.\n", pcre_context_get_name(ctx));
@@ -381,89 +381,118 @@
-static int do_op_if(pcre_plugin_t *plugin, pcre_rule_t *rule, prelude_string_t *str,
- idmef_message_t *input, capture_string_t *capture,
- int op, float value, prelude_list_t *operation_list)
+static int cmp_float(prelude_string_t *lefts, prelude_string_t *rights, int op)
{
- float val;
prelude_bool_t ok = FALSE;
+ float left, right;
- if ( prelude_string_is_empty(str) )
- return -1;
+ left = (float) strtod(prelude_string_get_string(lefts), NULL);
+ right = (float) strtod(prelude_string_get_string(rights), NULL);
- if ( op != 0 ) {
- val = (float) strtod(prelude_string_get_string(str), NULL);
+ if ( op & IF_OPERATOR_EQUAL && left == right )
+ ok = TRUE;
- if ( op & IF_OPERATOR_EQUAL && val == value )
- ok = TRUE;
+ else if ( op & IF_OPERATOR_LOWER && left < right )
+ ok = TRUE;
- else if ( op & IF_OPERATOR_LOWER && val < value )
- ok = TRUE;
+ else if ( op & IF_OPERATOR_GREATER && left > right )
+ ok = TRUE;
- else if ( op & IF_OPERATOR_GREATER && val > value )
- ok = TRUE;
+ return (ok == TRUE) ? 0 : -1;
+}
- if ( ! ok && ! (op & IF_OPERATOR_NOT) )
- return -1;
- }
- pcre_operation_execute(plugin, rule, operation_list, input, capture);
- return 0;
+static int cmp_string(prelude_string_t *lefts, prelude_string_t *rights, int op)
+{
+ const char *ls, *lr;
+
+ ls = prelude_string_get_string(lefts);
+ lr = prelude_string_get_string(rights);
+
+ if ( op & IF_OPERATOR_EQUAL )
+ return (strcmp(ls, lr) == 0) ? 0 : -1;
+
+ else if ( op & IF_OPERATOR_IN )
+ return ( strstr(lr, ls) ) ? 0 : -1;
+
+ else
+ return -1;
}
-static int op_if(pcre_plugin_t *plugin, pcre_rule_t *rule,
- idmef_message_t *input, capture_string_t *capture, void *extra,
- prelude_list_t *context_result)
+
+static int cmp_idmef(idmef_message_t *left, idmef_message_t *right)
{
- int ret;
- prelude_string_t *str;
- struct if_cb *ifcb = extra;
- prelude_bool_t do_else = TRUE;
- prelude_list_t list, *tmp, *bkp;
+}
+
+static int do_op_if(pcre_plugin_t *plugin, pcre_rule_t *rule,
+ struct if_cb *ifcb,
+ idmef_message_t *input, capture_string_t *capture)
+{
+ int ret, rval = -1;
+ prelude_string_t *str, *str2;
+ prelude_list_t list, list2, *tmp, *tmp2, *bkp, *bkp2;
+
+ if ( ! ifcb->left && ! ifcb->right )
+ return 0; /* else */
+
prelude_list_init(&list);
+ prelude_list_init(&list2);
- if ( ifcb->if_vcont ) {
- ret = value_container_resolve_listed(&list, ifcb->if_vcont, plugin, rule, capture);
+ ret = value_container_resolve_listed(&list, ifcb->left, plugin, rule, capture);
+ if ( ret < 0 )
+ return 0;
+
+ if ( ifcb->right ) {
+ ret = value_container_resolve_listed(&list2, ifcb->right, plugin, rule, capture);
if ( ret < 0 )
return 0;
+ }
- prelude_list_for_each_safe(&list, tmp, bkp) {
- str = prelude_linked_object_get_object(tmp);
+ prelude_list_for_each_safe(&list, tmp, bkp) {
+ str = prelude_linked_object_get_object(tmp);
- ret = do_op_if(plugin, rule, str, input, capture, ifcb->if_op, ifcb->if_value, &ifcb->if_operation_list);
+ if ( ! ifcb->right )
+ rval = 0;
- prelude_string_destroy(str);
- if ( ret == 0 )
- do_else = FALSE;
+ prelude_list_for_each_safe(&list2, tmp2, bkp2) {
+ str2 = prelude_linked_object_get_object(tmp2);
+
+ if ( rval < 0 ) {
+ ret = cmp_float(str, str2, ifcb->if_op);
+ if ( (ret == 0 && ! (ifcb->if_op & IF_OPERATOR_NOT)) ||
+ (ret < 0 && (ifcb->if_op & IF_OPERATOR_NOT)) ) {
+ rval = 0;
+ }
+ }
+
+ prelude_string_destroy(str2);
}
- }
- else if ( ifcb->if_value ) {
- pcre_operation_execute(plugin, rule, &ifcb->if_operation_list, input, capture);
- do_else = FALSE;
+ prelude_string_destroy(str);
}
- if ( ! do_else )
- return 0;
+ return rval;
+}
- if ( ifcb->else_vcont ) {
- ret = value_container_resolve_listed(&list, ifcb->else_vcont, plugin, rule, capture);
- if ( ret < 0 )
- return 0;
+static int op_if(pcre_plugin_t *plugin, pcre_rule_t *rule,
+ idmef_message_t *input, capture_string_t *capture, void *extra,
+ prelude_list_t *context_result)
+{
+ int ret;
+ struct if_cb *ifcb = extra;
- prelude_list_for_each_safe(&list, tmp, bkp) {
- str = prelude_linked_object_get_object(tmp);
-
- do_op_if(plugin, rule, str, input, capture, ifcb->else_op, ifcb->else_value, &ifcb->else_operation_list);
- prelude_string_destroy(str);
+ do {
+ ret = do_op_if(plugin, rule, ifcb, input, capture);
+ if ( ret == 0 ) {
+ pcre_operation_execute(plugin, rule, &ifcb->if_operation_list, input, capture);
+ break;
}
- }
- else if ( ! prelude_list_is_empty(&ifcb->else_operation_list) )
- do_op_if(plugin, rule, NULL, input, capture, ifcb->else_op, ifcb->else_value, &ifcb->else_operation_list);
+ ifcb = ifcb->next;
+ } while ( ifcb );
return 0;
}
@@ -1426,12 +1455,12 @@
static void if_cb_destroy(struct if_cb *ifcb)
{
free_operation(&ifcb->if_operation_list);
- free_operation(&ifcb->else_operation_list);
- value_container_destroy(ifcb->if_vcont);
+ value_container_destroy(ifcb->left);
+ value_container_destroy(ifcb->right);
- if ( ifcb->else_vcont )
- value_container_destroy(ifcb->else_vcont);
+ if ( ifcb->next )
+ if_cb_destroy(ifcb->next);
free(ifcb);
}
@@ -1440,10 +1469,9 @@
static int do_parse_if(FILE *fd, const char *filename, unsigned int *line,
pcre_plugin_t *plugin, pcre_rule_t *rule, const char *variable, const char *value,
- prelude_list_t *operation_list, value_container_t **vcont, if_operator_type_t *if_op, float *if_value)
+ struct if_cb *ifcb)
{
int ret, i;
- char *eptr;
size_t len;
struct {
const char *operator;
@@ -1458,7 +1486,7 @@
};
if ( variable ) {
- ret = value_container_new(vcont, variable);
+ ret = value_container_new(&ifcb->left, variable);
if ( ret < 0 )
return -1;
@@ -1466,7 +1494,7 @@
len = strlen(optbl[i].operator);
if ( strncmp(value, optbl[i].operator, len) == 0 ) {
- *if_op = optbl[i].type;
+ ifcb->if_op = optbl[i].type;
value += len;
break;
}
@@ -1481,16 +1509,18 @@
* If there is no value, we just check whether the specified context exist.
*/
if ( *value != '{' ) {
+ char *end;
value += strspn(value, " ");
+ end = value + strcspn(value, "{ ");
+ *end = 0;
- *if_value = strtod(value, &eptr);
-
- if ( eptr == value || (*eptr != ' ' && *eptr != '{') )
+ ret = value_container_new(&ifcb->right, value);
+ if ( ret < 0 )
return prelude_error_verbose(PRELUDE_ERROR_GENERIC,
"Invalid value specified to 'if' command: '%s'", value);
}
- ret = parse_ruleset(&rule->rule_list, plugin, rule, operation_list, filename, line, fd);
+ ret = parse_ruleset(&rule->rule_list, plugin, rule, &ifcb->if_operation_list, filename, line, fd);
if ( ret < 0 )
return ret;
@@ -1512,10 +1542,8 @@
}
prelude_list_init(&ifcb->if_operation_list);
- prelude_list_init(&ifcb->else_operation_list);
- ret = do_parse_if(fd, filename, line, plugin, rule, variable, value,
- &ifcb->if_operation_list, &ifcb->if_vcont, &ifcb->if_op, &ifcb->if_value);
+ ret = do_parse_if(fd, filename, line, plugin, rule, variable, value, ifcb);
if ( ret < 0 ) {
if_cb_destroy(ifcb);
return ret;
@@ -1536,22 +1564,33 @@
prelude_list_t *operation_list, const char *variable, const char *value)
{
int ret;
- struct if_cb *ifcb;
+ struct if_cb *last, *ifcb;
pcre_operation_t *op;
op = get_last_operation(operation_list);
if ( ! op || op->op != op_if )
return -1;
- ifcb = op->extra;
+ last = op->extra;
+ while ( last->next )
+ last = last->next;
- ret = do_parse_if(fd, filename, line, plugin, rule, variable, value,
- &ifcb->else_operation_list, &ifcb->else_vcont, &ifcb->else_op, &ifcb->else_value);
+ ifcb = calloc(1, sizeof(*ifcb));
+ if ( ! ifcb ) {
+ prelude_log(PRELUDE_LOG_ERR, "memory exhausted.\n");
+ return -1;
+ }
+
+ prelude_list_init(&ifcb->if_operation_list);
+
+ ret = do_parse_if(fd, filename, line, plugin, rule, variable, value, ifcb);
if ( ret < 0 ) {
if_cb_destroy(ifcb);
return ret;
}
+ last->next = ifcb;
+
return 0;
}
@@ -1704,7 +1743,7 @@
if ( strcmp(operation, "if") == 0 )
return parse_if(fd, filename, line, plugin, rule, operation_list, variable, value);
- if ( strncmp(operation, "else", 4) == 0 )
+ if ( strncmp(operation, "else", 4) == 0 || strncmp(operation, "elif", 4) == 0 )
return parse_else(fd, filename, line, plugin, rule, operation_list, variable, value);
if ( strcmp(operation, "for") == 0 )
More information about the Prelude-cvslog
mailing list