|
|
|
@ -1743,197 +1743,6 @@ error:
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Parse a content string, ie "abc|DE|fgh"
|
|
|
|
|
*
|
|
|
|
|
* \param content_str null terminated string containing the content
|
|
|
|
|
* \param result result pointer to pass the fully parsed byte array
|
|
|
|
|
* \param result_len size of the resulted data
|
|
|
|
|
* \param flags flags to be set by this parsing function
|
|
|
|
|
*
|
|
|
|
|
* \retval -1 error
|
|
|
|
|
* \retval 0 ok
|
|
|
|
|
*
|
|
|
|
|
* \initonly
|
|
|
|
|
*/
|
|
|
|
|
int DetectParseContentString (char *contentstr, uint8_t **result, uint16_t *result_len, uint32_t *result_flags)
|
|
|
|
|
{
|
|
|
|
|
char *str = NULL;
|
|
|
|
|
char *temp = NULL;
|
|
|
|
|
uint16_t len;
|
|
|
|
|
uint16_t pos = 0;
|
|
|
|
|
uint16_t slen = 0;
|
|
|
|
|
uint8_t *content = NULL;
|
|
|
|
|
uint16_t content_len = 0;
|
|
|
|
|
uint32_t flags = 0;
|
|
|
|
|
|
|
|
|
|
if ((temp = SCStrdup(contentstr)) == NULL) {
|
|
|
|
|
SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory. Exiting...");
|
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (strlen(temp) == 0) {
|
|
|
|
|
SCFree(temp);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* skip the first spaces */
|
|
|
|
|
slen = strlen(temp);
|
|
|
|
|
while (pos < slen && isspace((unsigned char)temp[pos])) {
|
|
|
|
|
pos++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (temp[pos] == '!') {
|
|
|
|
|
SCFree(temp);
|
|
|
|
|
|
|
|
|
|
if ((temp = SCStrdup(contentstr + pos + 1)) == NULL) {
|
|
|
|
|
SCLogError(SC_ERR_MEM_ALLOC, "error allocating memory. exiting...");
|
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pos = 0;
|
|
|
|
|
flags |= DETECT_CONTENT_NEGATED;
|
|
|
|
|
SCLogDebug("negation in place");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (temp[pos] == '\"' && strlen(temp + pos) == 1)
|
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
|
|
if (temp[pos] == '\"' && temp[pos + strlen(temp + pos) - 1] == '\"') {
|
|
|
|
|
if ((str = SCStrdup(temp + pos + 1)) == NULL) {
|
|
|
|
|
SCLogError(SC_ERR_MEM_ALLOC, "error allocating memory. exiting...");
|
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
str[strlen(temp) - pos - 2] = '\0';
|
|
|
|
|
} else if (temp[pos] == '\"' || temp[pos + strlen(temp + pos) - 1] == '\"') {
|
|
|
|
|
goto error;
|
|
|
|
|
} else {
|
|
|
|
|
if ((str = SCStrdup(temp + pos)) == NULL) {
|
|
|
|
|
SCLogError(SC_ERR_MEM_ALLOC, "error allocating memory. exiting...");
|
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SCFree(temp);
|
|
|
|
|
temp = NULL;
|
|
|
|
|
|
|
|
|
|
len = strlen(str);
|
|
|
|
|
if (len == 0)
|
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
|
|
//SCLogDebug("DetectContentParse: \"%s\", len %" PRIu32 "", str, len);
|
|
|
|
|
char converted = 0;
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
uint16_t i, x;
|
|
|
|
|
uint8_t bin = 0;
|
|
|
|
|
uint8_t escape = 0;
|
|
|
|
|
uint8_t binstr[3] = "";
|
|
|
|
|
uint8_t binpos = 0;
|
|
|
|
|
uint16_t bin_count = 0;
|
|
|
|
|
|
|
|
|
|
for (i = 0, x = 0; i < len; i++) {
|
|
|
|
|
// SCLogDebug("str[%02u]: %c", i, str[i]);
|
|
|
|
|
if (str[i] == '|') {
|
|
|
|
|
bin_count++;
|
|
|
|
|
if (bin) {
|
|
|
|
|
bin = 0;
|
|
|
|
|
} else {
|
|
|
|
|
bin = 1;
|
|
|
|
|
}
|
|
|
|
|
} else if(!escape && str[i] == '\\') {
|
|
|
|
|
escape = 1;
|
|
|
|
|
} else {
|
|
|
|
|
if (bin) {
|
|
|
|
|
if (isdigit((unsigned char)str[i]) ||
|
|
|
|
|
str[i] == 'A' || str[i] == 'a' ||
|
|
|
|
|
str[i] == 'B' || str[i] == 'b' ||
|
|
|
|
|
str[i] == 'C' || str[i] == 'c' ||
|
|
|
|
|
str[i] == 'D' || str[i] == 'd' ||
|
|
|
|
|
str[i] == 'E' || str[i] == 'e' ||
|
|
|
|
|
str[i] == 'F' || str[i] == 'f')
|
|
|
|
|
{
|
|
|
|
|
// SCLogDebug("part of binary: %c", str[i]);
|
|
|
|
|
|
|
|
|
|
binstr[binpos] = (char)str[i];
|
|
|
|
|
binpos++;
|
|
|
|
|
|
|
|
|
|
if (binpos == 2) {
|
|
|
|
|
uint8_t c = strtol((char *)binstr, (char **) NULL, 16) & 0xFF;
|
|
|
|
|
binpos = 0;
|
|
|
|
|
str[x] = c;
|
|
|
|
|
x++;
|
|
|
|
|
converted = 1;
|
|
|
|
|
}
|
|
|
|
|
} else if (str[i] == ' ') {
|
|
|
|
|
// SCLogDebug("space as part of binary string");
|
|
|
|
|
}
|
|
|
|
|
} else if (escape) {
|
|
|
|
|
if (str[i] == ':' ||
|
|
|
|
|
str[i] == ';' ||
|
|
|
|
|
str[i] == '\\' ||
|
|
|
|
|
str[i] == '\"')
|
|
|
|
|
{
|
|
|
|
|
str[x] = str[i];
|
|
|
|
|
x++;
|
|
|
|
|
} else {
|
|
|
|
|
//SCLogDebug("Can't escape %c", str[i]);
|
|
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
escape = 0;
|
|
|
|
|
converted = 1;
|
|
|
|
|
} else {
|
|
|
|
|
str[x] = str[i];
|
|
|
|
|
x++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (bin_count % 2 != 0) {
|
|
|
|
|
SCLogError(SC_ERR_INVALID_SIGNATURE, "Invalid hex code assembly in "
|
|
|
|
|
"content - %s. Invalidating signature", str);
|
|
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#if 0//def DEBUG
|
|
|
|
|
if (SCLogDebugEnabled()) {
|
|
|
|
|
for (i = 0; i < x; i++) {
|
|
|
|
|
if (isprint(str[i])) SCLogDebug("%c", str[i]);
|
|
|
|
|
else SCLogDebug("\\x%02u", str[i]);
|
|
|
|
|
}
|
|
|
|
|
SCLogDebug("");
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
if (converted) {
|
|
|
|
|
len = x;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
content = SCMalloc(len);
|
|
|
|
|
if (unlikely(content == NULL)) {
|
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
memcpy(content, str, len);
|
|
|
|
|
content_len = len;
|
|
|
|
|
|
|
|
|
|
SCFree(str);
|
|
|
|
|
|
|
|
|
|
*result = content;
|
|
|
|
|
*result_len = content_len;
|
|
|
|
|
*result_flags = flags;
|
|
|
|
|
SCLogDebug("flags %02X, result_flags %02X", flags, *result_flags);
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
error:
|
|
|
|
|
SCFree(str);
|
|
|
|
|
SCFree(temp);
|
|
|
|
|
if (content != NULL)
|
|
|
|
|
SCFree(content);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
/*
|
|
|
|
|
* TESTS
|
|
|
|
|
*/
|
|
|
|
|