#include "util-debug.h"
#include "util-print.h"
+#include "util-var.h"
/* prototypes */
void DetectAddressPrint(DetectAddress *);
*/
static int DetectAddressParse2(const DetectEngineCtx *de_ctx,
DetectAddressHead *gh, DetectAddressHead *ghn,
- char *s, int negate)
+ char *s, int negate, ResolvedVariablesList *var_list)
{
size_t x = 0;
size_t u = 0;
char *rule_var_address = NULL;
char *temp_rule_var_address = NULL;
+ if (AddVariableToResolveList(var_list, s) == -1) {
+ SCLogError(SC_ERR_INVALID_YAML_CONF_ENTRY, "Found a loop in a address "
+ "groups declaration. This is likely a misconfiguration.");
+ goto error;
+ }
+
SCLogDebug("s %s negate %s", s, negate ? "true" : "false");
for (u = 0, x = 0; u < size && x < sizeof(address); u++) {
/* normal block */
SCLogDebug("normal block");
- if (DetectAddressParse2(de_ctx, gh, ghn, address, (negate + n_set) % 2) < 0)
+ if (DetectAddressParse2(de_ctx, gh, ghn, address, (negate + n_set) % 2, var_list) < 0)
goto error;
} else {
/* negated block
DetectAddressHead tmp_gh = { NULL, NULL, NULL };
DetectAddressHead tmp_ghn = { NULL, NULL, NULL };
- if (DetectAddressParse2(de_ctx, &tmp_gh, &tmp_ghn, address, 0) < 0)
+ if (DetectAddressParse2(de_ctx, &tmp_gh, &tmp_ghn, address, 0, var_list) < 0)
goto error;
DetectAddress *tmp_ad;
SC_RULE_VARS_ADDRESS_GROUPS);
if (rule_var_address == NULL)
goto error;
+
if (strlen(rule_var_address) == 0) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "variable %s resolved "
"to nothing. This is likely a misconfiguration. "
"\"!$HOME_NET\" instead of !$HOME_NET. See issue #295.", s);
goto error;
}
+
SCLogDebug("rule_var_address %s", rule_var_address);
temp_rule_var_address = rule_var_address;
if ((negate + n_set) % 2) {
snprintf(temp_rule_var_address, strlen(rule_var_address) + 3,
"[%s]", rule_var_address);
}
- DetectAddressParse2(de_ctx, gh, ghn, temp_rule_var_address,
- (negate + n_set) % 2);
+
+
+ if (DetectAddressParse2(de_ctx, gh, ghn, temp_rule_var_address,
+ (negate + n_set) % 2, var_list) < 0)
+ goto error;
+
d_set = 0;
n_set = 0;
if (temp_rule_var_address != rule_var_address)
SC_RULE_VARS_ADDRESS_GROUPS);
if (rule_var_address == NULL)
goto error;
+
if (strlen(rule_var_address) == 0) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "variable %s resolved "
"to nothing. This is likely a misconfiguration. "
"\"!$HOME_NET\" instead of !$HOME_NET. See issue #295.", s);
goto error;
}
+
SCLogDebug("rule_var_address %s", rule_var_address);
temp_rule_var_address = rule_var_address;
if ((negate + n_set) % 2) {
snprintf(temp_rule_var_address, strlen(rule_var_address) + 3,
"[%s]", rule_var_address);
}
+
if (DetectAddressParse2(de_ctx, gh, ghn, temp_rule_var_address,
- (negate + n_set) % 2) < 0) {
+ (negate + n_set) % 2, var_list) < 0) {
SCLogDebug("DetectAddressParse2 hates us");
goto error;
}
return 0;
error:
+
return -1;
}
{
SCLogDebug("Testing address conf vars for any misconfigured values");
+ ResolvedVariablesList var_list = TAILQ_HEAD_INITIALIZER(var_list);
+
ConfNode *address_vars_node = ConfGetNode("vars.address-groups");
if (address_vars_node == NULL) {
return 0;
goto error;
}
- int r = DetectAddressParse2(NULL, gh, ghn, seq_node->val, /* start with negate no */0);
+ int r = DetectAddressParse2(NULL, gh, ghn, seq_node->val, /* start with negate no */0, &var_list);
+
+ CleanVariableResolveList(&var_list);
+
if (r < 0) {
SCLogError(SC_ERR_INVALID_YAML_CONF_ENTRY,
"failed to parse address var \"%s\" with value \"%s\". "
goto error;
}
+ CleanVariableResolveList(&var_list);
+
if (DetectAddressIsCompleteIPSpace(ghn)) {
SCLogError(SC_ERR_INVALID_YAML_CONF_ENTRY,
"address var - \"%s\" has the complete IP space negated "
goto error;
}
- r = DetectAddressParse2(de_ctx, gh, ghn, str, /* start with negate no */0);
+ r = DetectAddressParse2(de_ctx, gh, ghn, str, /* start with negate no */0, NULL);
if (r < 0) {
SCLogDebug("DetectAddressParse2 returned %d", r);
goto error;
#include "pkt-var.h"
#include "host.h"
#include "util-profiling.h"
+#include "util-var.h"
static int DetectPortCutNot(DetectPort *, DetectPort **);
static int DetectPortCut(DetectEngineCtx *, DetectPort *, DetectPort *,
*/
static int DetectPortParseDo(const DetectEngineCtx *de_ctx,
DetectPort **head, DetectPort **nhead,
- char *s, int negate)
+ char *s, int negate, ResolvedVariablesList *var_list)
{
size_t u = 0;
size_t x = 0;
char *rule_var_port = NULL;
int r = 0;
+ if (AddVariableToResolveList(var_list, s) == -1) {
+ SCLogError(SC_ERR_INVALID_YAML_CONF_ENTRY, "Found a loop in a port "
+ "groups declaration. This is likely a misconfiguration.");
+ goto error;
+ }
+
SCLogDebug("head %p, *head %p, negate %d", head, *head, negate);
for (u = 0, x = 0; u < size && x < sizeof(address); u++) {
SCLogDebug("Parsed port from DetectPortParseDo - %s", address);
x = 0;
- r = DetectPortParseDo(de_ctx, head, nhead, address, negate? negate: n_set);
+ r = DetectPortParseDo(de_ctx, head, nhead, address, negate? negate: n_set, var_list);
if (r == -1)
goto error;
temp_rule_var_port = alloc_rule_var_port;
}
r = DetectPortParseDo(de_ctx, head, nhead, temp_rule_var_port,
- (negate + n_set) % 2);//negate? negate: n_set);
+ (negate + n_set) % 2, var_list);//negate? negate: n_set);
if (r == -1)
goto error;
temp_rule_var_port = alloc_rule_var_port;
}
r = DetectPortParseDo(de_ctx, head, nhead, temp_rule_var_port,
- (negate + n_set) % 2);
+ (negate + n_set) % 2, var_list);
if (r == -1)
goto error;
{
SCLogDebug("Testing port conf vars for any misconfigured values");
+ ResolvedVariablesList var_list = TAILQ_HEAD_INITIALIZER(var_list);
+
ConfNode *port_vars_node = ConfGetNode("vars.port-groups");
if (port_vars_node == NULL) {
return 0;
goto error;
}
- int r = DetectPortParseDo(NULL, &gh, &ghn, seq_node->val, /* start with negate no */0);
+ int r = DetectPortParseDo(NULL, &gh, &ghn, seq_node->val, /* start with negate no */0, &var_list);
+
+ CleanVariableResolveList(&var_list);
+
if (r < 0) {
DetectPortCleanupList(gh);
+ SCLogError(SC_ERR_INVALID_YAML_CONF_ENTRY,
+ "failed to parse port var \"%s\" with value \"%s\". "
+ "Please check it's syntax", seq_node->name, seq_node->val);
goto error;
}
/* negate port list */
DetectPort *nhead = NULL;
- r = DetectPortParseDo(de_ctx, head, &nhead, str,/* start with negate no */0);
+ r = DetectPortParseDo(de_ctx, head, &nhead, str,/* start with negate no */0, NULL);
if (r < 0)
goto error;
int result = 0;
DetectPort *head = NULL, *nhead = NULL;
- if (DetectPortParseDo(NULL, &head, &nhead, "![!80]", 0) == -1)
+ if (DetectPortParseDo(NULL, &head, &nhead, "![!80]", 0, NULL) == -1)
return result;
result = (head != NULL);
listgv = listgv->next;
}
}
+
+// Checks if a variable is already in a resolve list and if it's not, adds it.
+int AddVariableToResolveList(ResolvedVariablesList *list, char *var)
+{
+ ResolvedVariable *p_item;
+
+ if (list == NULL || var == NULL)
+ return 0;
+
+ TAILQ_FOREACH(p_item, list, next) {
+ if (!strcmp(p_item->var_name, var)) {
+ return -1;
+ }
+ }
+
+ p_item = SCMalloc(sizeof(ResolvedVariable));
+
+ if (unlikely(p_item == NULL)) {
+ return -1;
+ }
+
+ strlcpy(p_item->var_name, var, sizeof(p_item->var_name) - 1);
+ TAILQ_INSERT_TAIL(list, p_item, next);
+
+ return 0;
+}
+
+void CleanVariableResolveList(ResolvedVariablesList *var_list)
+{
+ if (var_list == NULL) {
+ return;
+ }
+
+ ResolvedVariable *p_item;
+
+ while ((p_item = TAILQ_FIRST(var_list))) {
+ TAILQ_REMOVE(var_list, p_item, next);
+ SCFree(p_item);
+ }
+}
uint32_t expire;
} XBit;
+// A list of variables we try to resolve while parsing configuration file.
+// Helps to detect recursive declarations.
+typedef struct ResolvedVariable_ {
+ char var_name[256];
+ TAILQ_ENTRY(ResolvedVariable_) next;
+} ResolvedVariable;
+
+typedef TAILQ_HEAD(, ResolvedVariable_) ResolvedVariablesList;
+
void GenericVarFree(GenericVar *);
void GenericVarAppend(GenericVar **, GenericVar *);
void GenericVarRemove(GenericVar **, GenericVar *);
+int AddVariableToResolveList(ResolvedVariablesList *list, char *var);
+void CleanVariableResolveList(ResolvedVariablesList *var_list);
+
#endif /* __UTIL_VAR_H__ */