83 static void SigMatchTransferSigMatchAcrossLists(
SigMatch *sm,
114 #define CASE_CODE_STRING(E, S) case E: return S; break
125 #undef CASE_CODE_STRING
129 #define CASE_CODE(E) case E: return #E
147 Signature *s,
const char *arg,
int sm_type,
int sm_list,
153 if (arg != NULL && strcmp(arg,
"") != 0) {
162 "with a sticky buffer still set. Reset sticky buffer "
163 "with pkt_data before using the modifier.",
177 "found inside the rule without a content context. "
178 "Please use a \"content\" keyword before using the "
186 "be used with the rawbytes rule keyword",
192 "be used with the replace rule keyword",
231 bool reuse_buffer =
false;
244 SCLogError(
"failed to expand rule buffer array");
253 SCLogDebug(
"idx %u list %d set up curbuf %p s->init_data->buffer_index %u",
294 if (sm->
ctx != NULL) {
305 ptrdiff_t
offset = e - table;
319 if (st->
name != NULL) {
351 if (strcmp(
str,
"all") == 0) {
363 char *xsaveptr = NULL;
364 char *key = strtok_r(copy,
",", &xsaveptr);
365 while (key != NULL) {
371 "argument '%s' not found",
374 key = strtok_r(NULL,
",", &xsaveptr);
401 SCLogDebug(
"s:%p new:%p list:%d: %s, s->init_data->list_set %s s->init_data->list %d", s,
new,
435 SCLogDebug(
"reusing buffer %u as it isn't multi-capable", x);
445 SCLogError(
"failed to expand rule buffer array");
475 SCLogDebug(
"appended %s to list %d, rule pos %u (s->init_data->list %d)",
494 if (sm->
prev != NULL)
496 if (sm->
next != NULL)
538 if (sm_last == NULL || sm_new->
idx > sm_last->
idx)
550 if (sm_last == NULL || sm_new->
idx > sm_last->
idx)
572 SCLogDebug(
"skip x %u s->init_data->list %d (int)s->init_data->buffers[x].id %d", x,
581 for (sm_type = va_arg(ap,
int); sm_type != -1; sm_type = va_arg(ap,
int)) {
585 if (sm_last == NULL || sm_new->
idx > sm_last->
idx)
602 for (sm_type = va_arg(ap,
int); sm_type != -1; sm_type = va_arg(ap,
int))
607 if (sm_last == NULL || sm_new->
idx > sm_last->
idx)
632 va_start(ap, sm_list);
634 for (sm_type = va_arg(ap,
int); sm_type != -1; sm_type = va_arg(ap,
int))
636 sm_new = SigMatchGetLastSMByType(sm_list, sm_type);
639 if (sm_last == NULL || sm_new->
idx > sm_last->
idx)
670 va_start(ap, list_id);
672 for (sm_type = va_arg(ap,
int); sm_type != -1; sm_type = va_arg(ap,
int)) {
676 if (sm_last == NULL || sm_new->
idx > sm_last->
idx)
688 va_start(ap, list_id);
690 for (sm_type = va_arg(ap,
int); sm_type != -1; sm_type = va_arg(ap,
int)) {
691 sm_new = SigMatchGetLastSMByType(sm_list, sm_type);
694 if (sm_last == NULL || sm_new->
idx > sm_last->
idx)
717 if (sm_last == NULL || sm_new->
idx > sm_last->
idx)
725 if (sm_last == NULL || sm_new->
idx > sm_last->
idx)
732 static void SigMatchTransferSigMatchAcrossLists(
SigMatch *sm,
738 if (sm->
prev != NULL)
740 if (sm->
next != NULL)
743 if (sm == *src_sm_list)
744 *src_sm_list = sm->
next;
745 if (sm == *src_sm_list_tail)
746 *src_sm_list_tail = sm->
prev;
748 if (*dst_sm_list == NULL) {
750 *dst_sm_list_tail = sm;
758 *dst_sm_list_tail = sm;
785 SCLogError(
"Unable to find the sm in any of the "
799 static int DetectSetupDirection(
Signature *s,
char **
str,
bool only_dir)
802 if (strncmp(*
str,
"to_client", strlen(
"to_client")) == 0) {
803 *
str += strlen(
"to_client");
805 while (**
str && isblank(**
str)) {
811 SCLogError(
"unknown option: only accepts to_server or to_client");
821 while (**
str && isblank(**
str)) {
833 }
else if (strncmp(*
str,
"to_server", strlen(
"to_server")) == 0) {
834 *
str += strlen(
"to_server");
836 while (**
str && isblank(**
str)) {
842 SCLogError(
"unknown option: only accepts to_server or to_client");
852 while (**
str && isblank(**
str)) {
864 }
else if (only_dir) {
865 SCLogError(
"unknown option: only accepts to_server or to_client");
872 size_t output_size,
bool requires)
875 char *optname = NULL;
876 char *optvalue = NULL;
879 while (isblank(*optstr)) {
884 char *optend = optstr;
886 optend = strchr(optend,
';');
887 if (optend == NULL) {
891 else if (optend > optstr && *(optend -1 ) ==
'\\') {
900 char *optvalptr = strchr(optstr,
':');
902 *(optvalptr++) =
'\0';
905 for (
size_t i = strlen(optvalptr); i > 0; i--) {
906 if (isblank(optvalptr[i - 1])) {
907 optvalptr[i - 1] =
'\0';
913 optvalue = optvalptr;
917 for (
size_t i = strlen(optstr); i > 0; i--) {
918 if (isblank(optstr[i - 1])) {
919 optstr[i - 1] =
'\0';
928 bool requires_only = strcasecmp(optname,
"requires") == 0 || strcasecmp(optname,
"sid") == 0;
929 if ((requires && !requires_only) || (!requires && requires_only)) {
934 st = SigTableGet(optname);
935 if (st == NULL || st->
Setup == NULL) {
936 SCLogError(
"unknown rule keyword '%s'.", optname);
941 if (optvalue == NULL || strlen(optvalue) == 0) {
943 "invalid formatting or malformed option to %s keyword: '%s'", optname, optstr);
947 if (optvalue && strlen(optvalue)) {
948 SCLogError(
"unexpected option to %s keyword: '%s'", optname, optstr);
958 #define URL "https://suricata.io/our-story/deprecation-policy/"
961 "and will be removed soon. See %s",
965 "and will be removed soon. Use '%s' instead. "
972 SCLogError(
"keyword \'%s\' is not allowed with firewall rules", optname);
977 SCLogError(
"keyword \'%s\' is not allowed in firewall mode", optname);
984 if (optvalue != NULL && strlen(optvalue) > 0) {
985 size_t ovlen = strlen(optvalue);
986 char *ptr = optvalue;
996 SCLogError(
"invalid formatting or malformed option to %s keyword: \'%s\'", optname,
1002 SCLogWarning(
"keyword \'%s\' has not been tested for firewall rules", optname);
1019 SCLogError(
"invalid formatting or malformed option to %s keyword: \'%s\'", optname,
1025 SCLogError(
"invalid formatting to %s keyword: "
1026 "value must be double quoted \'%s\'",
1032 && ovlen && *ptr ==
'"')
1034 for (; ovlen > 0; ovlen--) {
1035 if (isblank(ptr[ovlen - 1])) {
1036 ptr[ovlen - 1] =
'\0';
1041 if (ovlen && ptr[ovlen - 1] !=
'"') {
1042 SCLogError(
"bad option value formatting (possible missing semicolon) "
1043 "for keyword %s: \'%s\'",
1051 ptr[ovlen - 1] =
'\0';
1056 "for keyword %s: \'%s\'",
1063 "quotes on %s keyword that doesn't support them: \'%s\'", optname, optstr);
1081 if (setup_ret < 0) {
1085 if (setup_ret == -2) {
1097 if (strlen(optend) > 0) {
1098 strlcpy(output, optend, output_size);
1113 Signature *s,
const char *addrstr,
char flag)
1115 SCLogDebug(
"Address Group \"%s\" to be parsed now", addrstr);
1119 if (strcasecmp(addrstr,
"any") == 0)
1127 if (strcasecmp(addrstr,
"any") == 0)
1142 static bool IsBuiltIn(
const char *n)
1144 return strcmp(n,
"request_started") == 0 || strcmp(n,
"response_started") == 0 ||
1145 strcmp(n,
"request_complete") == 0 || strcmp(n,
"response_complete") == 0;
1160 SCLogDebug(
"alproto %u/%s", a, alproto_name);
1164 SCLogDebug(
"%s: max sub state for %u is %u", alproto_name, a, max_sub_state);
1165 for (uint8_t s = 1; s <= max_sub_state; s++) {
1169 if (sub_state_name == NULL)
1172 char ts_tx_started[64];
1173 snprintf(ts_tx_started,
sizeof(ts_tx_started),
"%s:%s:request_started:generic",
1174 alproto_name, sub_state_name);
1178 char tc_tx_started[64];
1179 snprintf(tc_tx_started,
sizeof(tc_tx_started),
"%s:%s:response_started:generic",
1180 alproto_name, sub_state_name);
1184 char ts_tx_complete[64];
1185 snprintf(ts_tx_complete,
sizeof(ts_tx_complete),
"%s:%s:request_complete:generic",
1186 alproto_name, sub_state_name);
1190 char tc_tx_complete[64];
1191 snprintf(tc_tx_complete,
sizeof(tc_tx_complete),
"%s:%s:response_complete:generic",
1192 alproto_name, sub_state_name);
1197 for (uint8_t state = 0; state <= max_state; state++) {
1198 const char *state_name =
1200 BUG_ON(state_name == NULL);
1202 if (state_name != NULL && !IsBuiltIn(state_name)) {
1204 snprintf(list_name,
sizeof(list_name),
"%s:%s:%s:generic", alproto_name,
1205 sub_state_name, state_name);
1211 for (uint8_t state = 0; state <= max_state; state++) {
1212 const char *state_name =
1214 BUG_ON(state_name == NULL);
1215 if (state_name != NULL && !IsBuiltIn(state_name)) {
1217 snprintf(list_name,
sizeof(list_name),
"%s:%s:%s:generic", alproto_name,
1218 sub_state_name, state_name);
1225 const uint8_t max_progress_ts =
1227 const uint8_t max_progress_tc =
1230 char ts_tx_started[64];
1231 snprintf(ts_tx_started,
sizeof(ts_tx_started),
"%s:request_started:generic",
1235 SCLogDebug(
"- hook %s:%s list %s (%u)", alproto_name,
"request_name", ts_tx_started,
1236 (uint32_t)strlen(ts_tx_started));
1238 char tc_tx_started[64];
1239 snprintf(tc_tx_started,
sizeof(tc_tx_started),
"%s:response_started:generic",
1243 SCLogDebug(
"- hook %s:%s list %s (%u)", alproto_name,
"response_name", tc_tx_started,
1244 (uint32_t)strlen(tc_tx_started));
1246 char ts_tx_complete[64];
1247 snprintf(ts_tx_complete,
sizeof(ts_tx_complete),
"%s:request_complete:generic",
1251 SCLogDebug(
"- hook %s:%s list %s (%u)", alproto_name,
"request_name", ts_tx_complete,
1252 (uint32_t)strlen(ts_tx_complete));
1254 char tc_tx_complete[64];
1255 snprintf(tc_tx_complete,
sizeof(tc_tx_complete),
"%s:response_complete:generic",
1259 SCLogDebug(
"- hook %s:%s list %s (%u)", alproto_name,
"response_name", tc_tx_complete,
1260 (uint32_t)strlen(tc_tx_complete));
1262 for (uint8_t
p = 0;
p <= max_progress_ts;
p++) {
1264 IPPROTO_TCP , a,
p, STREAM_TOSERVER);
1265 if (
name != NULL && !IsBuiltIn(
name)) {
1267 snprintf(list_name,
sizeof(list_name),
"%s:%s:generic", alproto_name,
name);
1268 SCLogDebug(
"- hook %s:%s list %s (%u)", alproto_name,
name, list_name,
1269 (uint32_t)strlen(list_name));
1275 for (uint8_t
p = 0;
p <= max_progress_tc;
p++) {
1277 IPPROTO_TCP , a,
p, STREAM_TOCLIENT);
1278 if (
name != NULL && !IsBuiltIn(
name)) {
1280 snprintf(list_name,
sizeof(list_name),
"%s:%s:generic", alproto_name,
name);
1281 SCLogDebug(
"- hook %s:%s list %s (%u)", alproto_name,
name, list_name,
1282 (uint32_t)strlen(list_name));
1309 if (strcmp(
str,
"flow_start") == 0) {
1311 }
else if (strcmp(
str,
"pre_flow") == 0) {
1313 }
else if (strcmp(
str,
"pre_stream") == 0) {
1315 }
else if (strcmp(
str,
"all") == 0) {
1328 return "flow_start";
1332 return "pre_stream";
1344 .t.pkt.ph = HookPktFromString(hook_str),
1352 static int SigParseProtoHookPkt(
Signature *s,
const char *proto_hook,
const char *
p,
const char *h)
1365 SCLogDebug(
"protocol:%s hook:%s: type:%s parsed hook:%s",
p, h,
1375 .t.app.alproto = alproto,
1376 .t.app.sub_state = sub_state,
1377 .t.app.app_progress = progress,
1385 static int SigParseProtoHookApp(
1386 Signature *s,
const char *proto_hook,
const char *
p,
const char *in_h)
1389 char generic_hook_name[256];
1390 strlcpy(hook, in_h,
sizeof(hook));
1391 const char *h = hook;
1392 const char *t = NULL;
1393 uint8_t sub_state = 0;
1395 bool has_type = strchr(hook,
':') != NULL;
1398 t = strtok_r(hook,
":", &rem);
1402 if (h == NULL || strlen(h) == 0) {
1403 SCLogError(
"invalid hook specification '%s'", hook);
1408 if (strlen(t) == 0) {
1409 SCLogError(
"invalid tx type specification '%s'", hook);
1412 if (strcmp(
p,
"http2") == 0 || strcmp(
p,
"doh2") == 0) {
1413 if (strcmp(t,
"stream") == 0) {
1414 sub_state = HTTP2TxTypeStream;
1415 }
else if (strcmp(t,
"global") == 0) {
1416 sub_state = HTTP2TxTypeGlobal;
1418 SCLogError(
"unknown %s tx type specification '%s': valid values are 'stream' "
1424 SCLogError(
"sub states currently only supported for http2 and doh2");
1435 if (strcmp(h,
"request_started") == 0) {
1439 }
else if (strcmp(h,
"response_started") == 0) {
1443 }
else if (strcmp(h,
"request_complete") == 0) {
1446 }
else if (strcmp(h,
"response_complete") == 0) {
1450 const int8_t progress_ts =
1452 if (progress_ts >= 0) {
1457 s->
alproto, sub_state, h, STREAM_TOCLIENT);
1458 if (progress_tc < 0) {
1465 snprintf(generic_hook_name,
sizeof(generic_hook_name),
"%s:%s:%s:generic",
p, t, h);
1469 "protocol %s requires a substate specification: %s:<sub_state>:%s",
p,
p, hook);
1480 if (strcmp(h,
"request_started") == 0) {
1484 }
else if (strcmp(h,
"response_started") == 0) {
1488 }
else if (strcmp(h,
"request_complete") == 0) {
1492 }
else if (strcmp(h,
"response_complete") == 0) {
1498 IPPROTO_TCP , s->
alproto, h, STREAM_TOSERVER);
1499 if (progress_ts >= 0) {
1507 IPPROTO_TCP , s->
alproto, h, STREAM_TOCLIENT);
1515 snprintf(generic_hook_name,
sizeof(generic_hook_name),
"%s:%s:generic",
p, h);
1517 SCLogDebug(
"generic_hook_name %s", generic_hook_name);
1521 SCLogError(
"no list registered as %s for hook %s", generic_hook_name, proto_hook);
1526 SCLogDebug(
"protocol:%s hook:%s: type:%s alproto:%u hook:%d",
p, h,
1536 printf(
"=========Supported Rule Protocols=========\n");
1553 static int SigParseProto(
Signature *s,
const char *protostr)
1556 if (strlen(protostr) >= 64)
1562 const char *h = NULL;
1564 bool has_hook = strchr(
proto,
':') != NULL;
1567 p = strtok_r(
proto,
":", &rem);
1571 if (
p == NULL || strlen(
p) == 0) {
1586 if (strlen(h) == 0) {
1590 if (SigParseProtoHookApp(s, protostr,
p, h) < 0) {
1591 SCLogError(
"protocol \"%s\" does not support hook \"%s\"",
p, h);
1598 "in a signature. Either detection for this protocol "
1599 "is not yet supported OR detection has been disabled for "
1600 "protocol through the yaml option "
1601 "app-layer.protocols.%s.detection-enabled",
1605 }
else if (h != NULL) {
1606 SCLogDebug(
"non-app-layer rule with %s:%s",
p, h);
1608 if (SigParseProtoHookPkt(s, protostr,
p, h) < 0) {
1609 SCLogError(
"protocol \"%s\" does not support hook \"%s\"",
p, h);
1638 Signature *s,
const char *portstr,
char flag)
1644 SCLogDebug(
"Port group \"%s\" to be parsed", portstr);
1647 if (strcasecmp(portstr,
"any") == 0)
1651 }
else if (flag == 1) {
1652 if (strcasecmp(portstr,
"any") == 0)
1667 static int SigParseActionRejectValidate(
const char *action)
1669 #ifdef HAVE_LIBNET11
1670 #if defined HAVE_LIBCAP_NG && !defined HAVE_LIBNET_CAPABILITIES
1673 "incompatible with POSIX based capabilities with privs dropping. "
1674 "For rejects to work, run as root/super user.");
1680 "required for action \"%s\" but is not compiled into Suricata",
1690 static uint8_t ActionStringToFlags(
const char *action)
1692 if (strcasecmp(action,
"alert") == 0) {
1694 }
else if (strcasecmp(action,
"drop") == 0) {
1696 }
else if (strcasecmp(action,
"pass") == 0) {
1698 }
else if (strcasecmp(action,
"reject") == 0 ||
1699 strcasecmp(action,
"rejectsrc") == 0)
1701 if (!(SigParseActionRejectValidate(action)))
1704 }
else if (strcasecmp(action,
"rejectdst") == 0) {
1705 if (!(SigParseActionRejectValidate(action)))
1708 }
else if (strcasecmp(action,
"rejectboth") == 0) {
1709 if (!(SigParseActionRejectValidate(action)))
1712 }
else if (strcasecmp(action,
"config") == 0) {
1714 }
else if (strcasecmp(action,
"accept") == 0) {
1717 SCLogError(
"An invalid action \"%s\" was given", action);
1733 static int SigParseActionDo(
const char *action_in,
const int idx,
const bool fw_rule,
1734 uint8_t *action_out, uint8_t *scope_out)
1737 strlcpy(action, action_in,
sizeof(action));
1738 const char *a = action;
1739 const char *o = NULL;
1741 bool has_scope = strchr(action,
':') != NULL;
1743 char *xsaveptr = NULL;
1744 a = strtok_r(action,
":", &xsaveptr);
1745 o = strtok_r(NULL,
":", &xsaveptr);
1749 SCLogError(
"invalid protocol specification '%s'", action_in);
1753 uint8_t
flags = ActionStringToFlags(a);
1766 SCLogError(
"only accept, config, drop and reject actions allowed as primary action "
1773 SCLogError(
"accept, config, drop and reject actions not allowed as secondary action "
1782 uint8_t scope_flags = 0;
1784 if (strcmp(o,
"packet") == 0) {
1786 }
else if (strcmp(o,
"flow") == 0) {
1789 SCLogError(
"invalid action scope '%s' in action '%s': only 'packet' and 'flow' "
1795 if (strcmp(o,
"packet") == 0) {
1797 }
else if (strcmp(o,
"hook") == 0) {
1799 }
else if (strcmp(o,
"tx") == 0) {
1801 }
else if (strcmp(o,
"flow") == 0) {
1805 "invalid action scope '%s' in action '%s': only 'packet', 'flow', 'tx' and "
1811 if (strcmp(o,
"packet") == 0) {
1814 SCLogError(
"invalid action scope '%s' in action '%s': only 'packet' allowed", o,
1819 SCLogError(
"invalid action scope '%s' in action '%s': scope only supported for actions "
1820 "'drop', 'pass' and 'reject'",
1824 if (*scope_out != 0 && *scope_out != scope_flags) {
1825 SCLogError(
"multi-action rules cannot use different action scopes");
1828 *scope_out = scope_flags;
1832 if (fw_rule && *scope_out == 0) {
1833 SCLogError(
"firewall rules require setting an explicit action scope");
1838 SCLogError(
"'accept' action only supported for firewall rules");
1841 *action_out |=
flags;
1845 static int SigParseAction(
Signature *s,
const char *action_in)
1854 FatalError(
"could not duplicate opt string");
1857 char *xsaveptr = NULL;
1858 char *a = strtok_r(copy,
",", &xsaveptr);
1864 a = strtok_r(NULL,
",", &xsaveptr);
1885 static inline int SigParseToken(
char **input,
char *output,
1886 const size_t output_size)
1888 size_t len = *input == NULL ? 0 : strlen(*input);
1894 while (
len && isblank(**input)) {
1899 char *endptr = strpbrk(*input,
" \t\n\r");
1900 if (endptr != NULL) {
1903 strlcpy(output, *input, output_size);
1920 static inline int SigParseList(
char **input,
char *output,
1921 const size_t output_size)
1924 size_t len = *input != NULL ? strlen(*input) : 0;
1930 while (
len && isblank(**input)) {
1936 for (i = 0; i <
len; i++) {
1937 char c = (*input)[i];
1940 }
else if (c ==
']') {
1942 }
else if (c ==
' ') {
1953 strlcpy(output, *input, output_size);
1954 *input = *input + i + 1;
1974 SigParseToken(&index, parser->
action,
sizeof(parser->
action));
1980 SigParseList(&index, parser->
src,
sizeof(parser->
src));
1983 SigParseList(&index, parser->
sp,
sizeof(parser->
sp));
1989 SigParseList(&index, parser->
dst,
sizeof(parser->
dst));
1992 SigParseList(&index, parser->
dp,
sizeof(parser->
dp));
1995 if (index == NULL) {
1999 while (isspace(*index) || *index ==
'(') {
2002 for (
size_t i = strlen(index); i > 0; i--) {
2003 if (isspace(index[i - 1]) || index[i - 1] ==
')') {
2004 index[i - 1] =
'\0';
2016 if (SigParseAction(s, parser->
action) < 0)
2019 if (SigParseProto(s, parser->
protocol) < 0)
2022 if (strcmp(parser->
direction,
"<>") == 0) {
2024 }
else if (strcmp(parser->
direction,
"=>") == 0) {
2026 SCLogError(
"transactional bidirectional rules not supported for firewall rules");
2031 }
else if (strcmp(parser->
direction,
"->") != 0) {
2032 SCLogError(
"\"%s\" is not a valid direction modifier, "
2033 "\"->\" and \"<>\" are supported.",
2060 static inline bool CheckAscii(
const char *
str)
2062 for (
size_t i = 0; i < strlen(
str); i++) {
2063 if (
str[i] < 0x20) {
2065 if (
str[i] == 0x0a ||
str[i] == 0x0d ||
str[i] == 0x09) {
2069 }
else if (
str[i] == 0x7f) {
2093 if (!SCCheckUtf8(sigstr)) {
2098 if (!CheckAscii(sigstr)) {
2099 SCLogError(
"rule contains invalid (control) characters");
2103 int ret = SigParseBasics(
de_ctx, s, sigstr, parser, addrs_direction, requires);
2110 if (strlen(parser->
opts) > 0) {
2111 size_t buffer_size = strlen(parser->
opts) + 1;
2113 char input[buffer_size];
2114 char output[buffer_size];
2115 memset(input, 0x00, buffer_size);
2116 memcpy(input, parser->
opts, strlen(parser->
opts) + 1);
2122 memset(output, 0x00, buffer_size);
2123 ret = SigParseOptions(
de_ctx, s, input, output, buffer_size, requires);
2125 memcpy(input, output, buffer_size);
2157 memset(b, 0,
sizeof(*b));
2205 static void SigMetadataFree(
Signature *s)
2212 if (s == NULL || s->
metadata == NULL) {
2219 next_mdata = mdata->
next;
2250 next_ref = ref->
next;
2304 while (sm != NULL) {
2313 while (sm != NULL) {
2334 if (s->
sp != NULL) {
2337 if (s->
dp != NULL) {
2386 if (s->
alproto == *alprotos) {
2429 }
else if (i == 1) {
2461 if (!AppProtoIsValid(alproto)) {
2485 alproto = AppProtoCommon(s->
alproto, alproto);
2487 SCLogError(
"can't set rule app proto to %s: already set to %s",
2514 if (addr_match4 == NULL) {
2520 addr_match4[idx].
ip =
SCNtohl(da->ip.addr_data32[0]);
2521 addr_match4[idx].
ip2 =
SCNtohl(da->ip2.addr_data32[0]);
2540 if (addr_match6 == NULL) {
2546 addr_match6[idx].
ip[0] =
SCNtohl(da->ip.addr_data32[0]);
2547 addr_match6[idx].
ip[1] =
SCNtohl(da->ip.addr_data32[1]);
2548 addr_match6[idx].
ip[2] =
SCNtohl(da->ip.addr_data32[2]);
2549 addr_match6[idx].
ip[3] =
SCNtohl(da->ip.addr_data32[3]);
2550 addr_match6[idx].
ip2[0] =
SCNtohl(da->ip2.addr_data32[0]);
2551 addr_match6[idx].
ip2[1] =
SCNtohl(da->ip2.addr_data32[1]);
2552 addr_match6[idx].
ip2[2] =
SCNtohl(da->ip2.addr_data32[2]);
2553 addr_match6[idx].
ip2[3] =
SCNtohl(da->ip2.addr_data32[3]);
2566 static void SigBuildAddressMatchArray(
Signature *s)
2583 static int SigMatchListLen(
SigMatch *sm)
2586 for (; sm != NULL; sm = sm->
next)
2597 int len = SigMatchListLen(
head);
2603 FatalError(
"initializing the detection engine failed");
2609 for (; sm != NULL; sm = sm->
next, smd++) {
2627 SCLogDebug(
"no prefilter for SIG_FLAG_FW_HOOK_LTE sig");
2654 SCLogDebug(
"s %u: no mpm; prefilter? de_ctx->prefilter_setting %u "
2655 "s->init_data->has_possible_prefilter %s",
2669 prefilter_list =
MIN(prefilter_list, sm->
type);
2679 if (sm->
type == prefilter_list) {
2696 static bool DetectRuleValidateTable(
const Signature *s)
2705 if (kw_tables_supported != 0 && (kw_tables_supported & table_as_flag) == 0) {
2706 SCLogError(
"rule %u uses hook \"%s\", but keyword \"%s\" doesn't support this hook",
2717 SCLogError(
"rule %u is loaded as a firewall rule, but does not specify an "
2727 SCLogError(
"rule %u uses action scope \"packet\" for an non-UDP app hook",
2745 SCLogError(
"rule %u: auto-accept notation (<hook) can only be used with accept:flow, "
2746 "accept:tx and accept:hook",
2755 static void DetectRuleSetTable(
Signature *s)
2788 if (!DetectFirewallRuleValidate(
de_ctx, s))
2794 static int SigValidateCheckBuffers(
2797 bool has_frame =
false;
2798 bool has_app =
false;
2799 bool has_pkt =
false;
2800 bool has_pmatch =
false;
2806 nlists += (nlists > 0);
2810 SCLogError(
"rule %u setup buffer %s but didn't add matches to it", s->
id,
2824 struct BufferVsDir {
2827 } bufdir[nlists + 1];
2828 memset(&bufdir, 0, (nlists + 1) *
sizeof(
struct BufferVsDir));
2842 if (b->
head == NULL) {
2847 has_frame |= bt->
frame;
2853 "specific matches (like dsize, flags, ttl) with stream / "
2854 "state matching by matching on app layer proto (like using "
2855 "http_* keywords).");
2859 uint32_t app_buffers_evaluated = 0;
2860 bool buffer_consumed =
false;
2861 uint32_t buffer_skip_alproto = 0;
2862 uint32_t buffer_skip_substate = 0;
2864 for (; app != NULL; app = app->
next) {
2867 app_buffers_evaluated++;
2875 SCLogDebug(
"%u:%s: for buffer %s skip engine %s alproto %s", s->
id,
2879 buffer_skip_alproto++;
2884 buffer_skip_substate++;
2890 SCLogDebug(
"%u:%s: for buffer %s skip engine %s alproto %s", s->
id,
2894 buffer_skip_alproto++;
2911 bufdir[b->
id].ts += (app->
dir == 0);
2912 bufdir[b->
id].tc += (app->
dir == 1);
2924 SCLogError(
"engine progress value doesn't match hook");
2929 buffer_consumed =
true;
2931 if (app_buffers_evaluated && !buffer_consumed) {
2932 SCLogError(
"incompatible rule conditions, skipped buffer %s, reasons: app proto %u sub "
2934 bt->
name, buffer_skip_alproto, buffer_skip_substate);
2949 if (has_pmatch && has_frame) {
2950 SCLogError(
"can't mix pure content and frame inspection");
2953 if (has_app && has_frame) {
2954 SCLogError(
"can't mix app-layer buffer and frame inspection");
2957 if (has_pkt && has_frame) {
2958 SCLogError(
"can't mix pkt buffer and frame inspection");
2962 for (
int x = 0; x < nlists; x++) {
2963 if (bufdir[x].
ts == 0 && bufdir[x].tc == 0)
2965 (*ts_excl) += (bufdir[x].ts > 0 && bufdir[x].tc == 0);
2966 (*tc_excl) += (bufdir[x].ts == 0 && bufdir[x].tc > 0);
2967 (*dir_amb) += (bufdir[x].ts > 0 && bufdir[x].tc > 0);
2976 static int SigValidatePacketStream(
const Signature *s)
2980 "tcp-stream or flow:only_stream. Invalidating signature.");
2986 static int SigConsolidateDirection(
2987 Signature *s,
const int ts_excl,
const int tc_excl,
const int dir_amb)
2990 if (!ts_excl || !tc_excl) {
2991 SCLogError(
"rule %u should use both directions, but does not", s->
id);
2995 SCLogError(
"rule %u means to use both directions, cannot have keywords ambiguous about "
3000 }
else if (ts_excl && tc_excl) {
3002 "rule %u mixes keywords with conflicting directions, a transactional rule with => "
3006 }
else if (ts_excl) {
3007 SCLogDebug(
"%u: implied rule direction is toserver", s->
id);
3009 SCLogError(
"rule %u mixes keywords with conflicting directions", s->
id);
3012 }
else if (tc_excl) {
3013 SCLogDebug(
"%u: implied rule direction is toclient", s->
id);
3015 SCLogError(
"rule %u mixes keywords with conflicting directions", s->
id);
3018 }
else if (dir_amb) {
3019 SCLogDebug(
"%u: rule direction cannot be deduced from keywords", s->
id);
3024 static void SigConsolidateTcpBuffer(
Signature *s)
3056 static bool SigInspectsFiles(
const Signature *s)
3067 static int SigValidateFileHandling(
const Signature *s)
3069 if (!SigInspectsFiles(s)) {
3076 "support file matching",
3093 SCLogError(
"No protocol support file matching");
3098 SCLogError(
"protocol HTTP2 doesn't support file name matching");
3104 static bool SigValidateEthernet(
const Signature *s)
3109 SCLogError(
"can't use ports with ether or arp rule");
3117 static bool SigValidateProtoPkthdr(
const Signature *s)
3120 SCLogError(
"protocol 'pkthdr' is for decoder-events only");
3149 static int SigValidateConsolidate(
3154 if (SigValidateFirewall(
de_ctx, s) == 0)
3157 if (SigValidatePacketStream(s) == 0) {
3161 if (!SigValidateEthernet(s)) {
3169 if (SigValidateCheckBuffers(
de_ctx, s, &ts_excl, &tc_excl, &dir_amb) == 0) {
3173 if (SigConsolidateDirection(s, ts_excl, tc_excl, dir_amb) == 0) {
3177 SigConsolidateTcpBuffer(s);
3180 DetectRuleSetTable(s);
3182 if (!SigValidateProtoPkthdr(s)) {
3186 if (!SigValidateFlowbitUse(
de_ctx, s)) {
3193 int r = SigValidateFileHandling(s);
3197 if (SigInspectsFiles(s)) {
3202 if (DetectRuleValidateTable(s) ==
false) {
3225 memset(&parser, 0x00,
sizeof(parser));
3230 if (firewall_rule) {
3247 int ret = SigParse(
de_ctx, sig, sigstr, dir, &parser,
true);
3254 }
else if (ret < 0) {
3260 SCLogError(
"Signature missing required value \"sid\".");
3265 ret = SigParse(
de_ctx, sig, sigstr, dir, &parser,
false);
3271 }
else if (ret == -2) {
3274 }
else if (ret < 0) {
3279 if (sig->
prio == -1)
3286 int override_needed = 0;
3290 override_needed = 1;
3292 override_needed = 1;
3296 override_needed = 0;
3305 if (override_needed)
3315 for ( ; sm != NULL; sm = sm->
next) {
3339 SCLogDebug(
"sig %"PRIu32
" SIG_FLAG_APPLAYER: %s, SIG_FLAG_PACKET: %s",
3343 SigBuildAddressMatchArray(sig);
3354 SigSetupPrefilter(
de_ctx, sig);
3357 if (SigValidateConsolidate(
de_ctx, sig, &parser, dir) == 0) {
3376 static bool SigHasSameSourceAndDestination(
const Signature *s)
3418 if (SigHasSameSourceAndDestination(sig)) {
3419 SCLogInfo(
"Rule with ID %u is bidirectional, but source and destination are the same, "
3420 "treating the rule as unidirectional", sig->
id);
3425 if (sig->
next == NULL) {
3455 return SigInitDo(
de_ctx, sigstr,
false);
3460 return SigInitDo(
de_ctx, sigstr,
true);
3469 static void DetectParseDupSigFreeFunc(
void *data)
3485 static uint32_t DetectParseDupSigHashFunc(
HashListTable *ht,
void *data, uint16_t datalen)
3504 static char DetectParseDupSigCompareFunc(
void *data1, uint16_t len1,
void *data2,
3510 if (sw1 == NULL || sw2 == NULL ||
3511 sw1->
s == NULL || sw2->
s == NULL)
3515 if (sw1->
s->
id == sw2->
s->
id && sw1->
s->
gid == sw2->
s->
gid)
return 1;
3531 DetectParseDupSigHashFunc,
3532 DetectParseDupSigCompareFunc,
3533 DetectParseDupSigFreeFunc);
3594 if (sw_dup == NULL) {
3607 (
void *)&sw_tmp, 0);
3621 if (sw->
s->
rev <= sw_dup->
s->
rev) {
3630 if (sw_dup->
s_prev == NULL) {
3638 sw_temp.
s = sw_dup->
s->
next;
3642 if (sw_temp.
s != NULL) {
3644 (
void *)&sw_temp, 0);
3665 sw_temp.
s = sw_dup->
s->
next;
3673 if (sw_temp.
s != NULL) {
3675 (
void *)&sw_temp, 0);
3691 (
void *)&sw_tmp, 0);
3693 if (sw_old->
s != sw_dup->
s) {
3736 int dup_sig = DetectEngineSignatureIsDuplicate(
de_ctx, sig);
3740 SCLogError(
"Duplicate signature \"%s\"", sigstr);
3742 }
else if (dup_sig == 2) {
3744 " so the older sig replaced by this new signature \"%s\"",
3749 if (sig->
next != NULL) {
3766 return (dup_sig == 0 || dup_sig == 2) ? sig : NULL;
3770 if (sig != NULL && sig->
next != NULL) {
3808 int dup_sig = DetectEngineSignatureIsDuplicate(
de_ctx, sig);
3812 SCLogError(
"Duplicate signature \"%s\"", sigstr);
3814 }
else if (dup_sig == 2) {
3816 " so the older sig replaced by this new signature \"%s\"",
3821 if (sig->
next != NULL) {
3838 return (dup_sig == 0 || dup_sig == 2) ? sig : NULL;
3842 if (sig != NULL && sig->
next != NULL) {
3855 int start_offset,
int options)
3857 *match = pcre2_match_data_create_from_pattern(parse_regex->
regex, NULL);
3859 return pcre2_match(parse_regex->
regex, (PCRE2_SPTR8)
str, strlen(
str), options, start_offset,
3860 *match, parse_regex->
context);
3867 pcre2_code_free(r->
regex);
3870 pcre2_match_context_free(r->
context);
3885 g_detect_parse_regex_list = NULL;
3894 FatalError(
"failed to alloc memory for pcre free list");
3897 r->
next = g_detect_parse_regex_list;
3898 g_detect_parse_regex_list = r;
3906 detect_parse->
regex =
3907 pcre2_compile((PCRE2_SPTR8)parse_str, PCRE2_ZERO_TERMINATED, opts, &en, &eo, NULL);
3908 if (detect_parse->
regex == NULL) {
3909 PCRE2_UCHAR errbuffer[256];
3910 pcre2_get_error_message(en, errbuffer,
sizeof(errbuffer));
3911 SCLogError(
"pcre compile of \"%s\" failed at "
3913 parse_str, en, errbuffer);
3916 detect_parse->
context = pcre2_match_context_create(NULL);
3917 if (detect_parse->
context == NULL) {
3918 SCLogError(
"pcre2 could not create match context");
3919 pcre2_code_free(detect_parse->
regex);
3920 detect_parse->
regex = NULL;
3935 if (detect_parse == NULL) {
3939 detect_parse->
regex =
3940 pcre2_compile((PCRE2_SPTR8)parse_str, PCRE2_ZERO_TERMINATED, opts, &en, &eo, NULL);
3941 if (detect_parse->
regex == NULL) {
3942 PCRE2_UCHAR errbuffer[256];
3943 pcre2_get_error_message(en, errbuffer,
sizeof(errbuffer));
3944 SCLogError(
"pcre2 compile of \"%s\" failed at "
3946 parse_str, (
int)eo, errbuffer);
3951 detect_parse->
next = g_detect_parse_regex_list;
3952 g_detect_parse_regex_list = detect_parse;
3953 return detect_parse;
3957 pcre2_match_data *match_data, uint32_t number, PCRE2_UCHAR *buffer, PCRE2_SIZE *bufflen)
3959 int r = pcre2_substring_copy_bynumber(match_data, number, buffer, bufflen);
3960 if (r == PCRE2_ERROR_UNSET) {
3969 pcre2_match_data *match_data, uint32_t number, PCRE2_UCHAR **bufferptr, PCRE2_SIZE *bufflen)
3971 int r = pcre2_substring_get_bynumber(match_data, number, bufferptr, bufflen);
3972 if (r == PCRE2_ERROR_UNSET) {
3987 static uint32_t AppPolicyHashFunc(
HashTable *ht,
void *data, uint16_t datalen)
3991 uint32_t hash =
p->alproto * 65537 +
p->sub_state * 257 +
p->progress * 5 +
3992 (
p->direction == STREAM_TOSERVER);
3993 hash ^= (hash >> 10) ^ (hash >> 20);
3997 static char AppPolicyCompareFunc(
void *data1, uint16_t datalen1,
void *data2, uint16_t datalen2)
4002 if (p1 == NULL || p2 == NULL)
4009 static void AppPolicyHashFree(
void *data)
4046 snprintf(out, out_size,
"rejectdst:%s", as);
4048 snprintf(out, out_size,
"rejectboth:%s", as);
4050 snprintf(out, out_size,
"rejectsrc:%s", as);
4053 snprintf(out, out_size,
"drop:%s", as);
4055 snprintf(out, out_size,
"accept:%s", as);
4061 strlcat(out,
",pass:flow", out_size);
4067 strlcat(out,
",alert", out_size);
4089 snprintf(msg,
sizeof(msg),
"SURICATA FW default packet policy");
4091 if (s->
msg == NULL) {
4115 snprintf(msg,
sizeof(msg),
"SURICATA FW default app policy");
4117 if (s->
msg == NULL) {
4142 if (policy_actions == NULL) {
4143 SCLogDebug(
"fw: no policy at %s", policy_name);
4148 uint8_t action_scope = 0;
4153 if (SigParseActionDo(paction->
val, idx,
true, &action, &action_scope) < 0)
4162 static int DoParseAppSubStatePolicy(
const char *prefix,
const AppProto app_proto,
4163 const uint8_t
sub_state,
const char *sub_state_name,
const uint8_t state,
4164 const char *hookname,
const uint8_t complete_state,
const int direction,
4167 char policy_name[256];
4168 BUG_ON(sub_state_name == NULL);
4169 BUG_ON(hookname == NULL);
4174 for (
int i = 0; nname[i] !=
'\0'; i++) {
4175 if (nname[i] ==
'_')
4180 int r = snprintf(policy_name,
sizeof(policy_name),
"%s.app.%s.%s.%s", prefix, app_name,
4181 sub_state_name, nname);
4184 if (r < 0 || (
size_t)r >=
sizeof(policy_name)) {
4185 FatalError(
"internal error: failed to assemble firewall policy config string");
4189 if (app_pol == NULL)
4201 r = DoParsePolicy(policy_name, &app_pol->
policy);
4208 FatalError(
"internal error: insert policy into hash table");
4213 return AddAppPolicySignature(app_pol);
4219 static int DoParseAppPolicy(
const char *prefix,
const AppProto app_proto,
const char *hookname,
4220 const uint8_t state,
const uint8_t complete_state,
const int direction,
4223 char policy_name[256];
4224 const char *in_name = hookname;
4225 if (hookname == NULL) {
4228 hookname =
"request-started";
4230 hookname =
"response-started";
4231 }
else if (state == complete_state) {
4233 hookname =
"request-complete";
4235 hookname =
"response-complete";
4237 if (hookname == NULL)
4243 for (
int i = 0; nname[i] !=
'\0'; i++) {
4244 if (nname[i] ==
'_')
4249 int r = snprintf(policy_name,
sizeof(policy_name),
"%s.app.%s.%s", prefix, app_name, nname);
4251 if (r < 0 || (
size_t)r >=
sizeof(policy_name)) {
4252 FatalError(
"internal error: failed to assemble firewall policy config string");
4256 if (app_pol == NULL)
4268 r = DoParsePolicy(policy_name, &app_pol->
policy);
4269 if (r == 0 && in_name != NULL) {
4272 hookname =
"request-started";
4274 hookname =
"response-started";
4275 }
else if (state == complete_state) {
4277 hookname =
"request-complete";
4279 hookname =
"response-complete";
4281 if (hookname == NULL)
4283 r = snprintf(policy_name,
sizeof(policy_name),
"%s.app.%s.%s", prefix, app_name, hookname);
4284 if (r < 0 || (
size_t)r >=
sizeof(policy_name)) {
4285 FatalError(
"internal error: failed to assemble firewall policy config string");
4288 r = DoParsePolicy(policy_name, &app_pol->
policy);
4296 FatalError(
"internal error: insert policy into hash table");
4302 return AddAppPolicySignature(app_pol);
4312 if (fw_policies == NULL)
4315 HashTableInit(512, AppPolicyHashFunc, AppPolicyCompareFunc, AppPolicyHashFree);
4337 char policy_name[256];
4338 char prefix[96] =
"firewall.policies";
4344 if (fw_policies == NULL)
4347 r = snprintf(policy_name,
sizeof(policy_name),
"%s.packet.filter", prefix);
4348 if (r < 0 || (
size_t)r >=
sizeof(policy_name)) {
4349 FatalError(
"internal error: failed to assemble firewall policy config string");
4355 if (AddPktPolicySignature(fw_policies,
4360 r = snprintf(policy_name,
sizeof(policy_name),
"%s.packet.pre-flow", prefix);
4361 if (r < 0 || (
size_t)r >=
sizeof(policy_name)) {
4362 FatalError(
"internal error: failed to assemble firewall policy config string");
4372 r = snprintf(policy_name,
sizeof(policy_name),
"%s.packet.pre-stream", prefix);
4373 if (r < 0 || (
size_t)r >=
sizeof(policy_name)) {
4374 FatalError(
"internal error: failed to assemble firewall policy config string");
4385 if (!AppProtoIsValid(a))
4391 for (uint8_t s = 1; s <= max_sub_state; s++) {
4395 if (sub_state_name == NULL)
4402 for (uint8_t state = 0; state <= max_state; state++) {
4404 sub_state_name, state);
4405 const char *state_name =
4407 BUG_ON(state_name == NULL);
4409 sub_state_name, state_name);
4410 if (DoParseAppSubStatePolicy(prefix, a, s, sub_state_name, state, state_name,
4411 max_state, STREAM_TOSERVER, fw_policies) < 0)
4415 for (uint8_t state = 0; state <= max_state; state++) {
4417 sub_state_name, state);
4418 const char *state_name =
4420 BUG_ON(state_name == NULL);
4422 sub_state_name, state_name);
4423 if (DoParseAppSubStatePolicy(prefix, a, s, sub_state_name, state, state_name,
4424 max_state, STREAM_TOCLIENT, fw_policies) < 0)
4429 const uint8_t complete_state_ts =
4431 a, STREAM_TOSERVER);
4432 for (uint8_t state = 0; state <= complete_state_ts; state++) {
4435 if (DoParseAppPolicy(prefix, a,
name, state, complete_state_ts, STREAM_TOSERVER,
4439 const uint8_t complete_state_tc =
4441 a, STREAM_TOCLIENT);
4442 for (uint8_t state = 0; state <= complete_state_tc; state++) {
4445 if (DoParseAppPolicy(prefix, a,
name, state, complete_state_tc, STREAM_TOCLIENT,
4462 static int SigParseTest01 (
void)
4471 sig =
SigInit(
de_ctx,
"alert tcp 1.2.3.4 any -> !1.2.3.4 any (msg:\"SigParseTest01\"; sid:1;)");
4481 static int SigParseTest02 (
void)
4496 sig =
SigInit(
de_ctx,
"alert tcp any !21:902 -> any any (msg:\"ET MALWARE Suspicious 220 Banner on Local Port\"; content:\"220\"; offset:0; depth:4; pcre:\"/220[- ]/\"; sid:2003055; rev:4;)");
4524 static int SigParseTest03 (
void)
4533 sig =
SigInit(
de_ctx,
"alert tcp 1.2.3.4 any <- !1.2.3.4 any (msg:\"SigParseTest03\"; sid:1;)");
4536 printf(
"expected NULL got sig ptr %p: ",sig);
4545 static int SigParseTest04 (
void)
4554 sig =
SigInit(
de_ctx,
"alert tcp 1.2.3.4 1024: -> !1.2.3.4 1024: (msg:\"SigParseTest04\"; sid:1;)");
4565 static int SigParseTest05 (
void)
4574 sig =
SigInit(
de_ctx,
"alert tcp 1.2.3.4 1024:65536 -> !1.2.3.4 any (msg:\"SigParseTest05\"; sid:1;)");
4578 printf(
"signature didn't fail to parse as we expected: ");
4588 static int SigParseTest06 (
void)
4597 sig =
SigInit(
de_ctx,
"alert tcp any any -> any any (flow:to_server; content:\"GET\"; nocase; http_method; uricontent:\"/uri/\"; nocase; content:\"Host|3A| abc\"; nocase; sid:1; rev:1;)");
4601 printf(
"signature failed to parse: ");
4615 static int SigParseTest07(
void)
4637 static int SigParseTest08(
void)
4660 static int SigParseTest09(
void)
4711 static int SigParseTest10(
void)
4743 static int SigParseTest11(
void)
4754 "drop tcp any any -> any 80 (msg:\"Snort_Inline is blocking the http link\"; sid:1;) ");
4756 printf(
"sig 1 didn't parse: ");
4761 "the http link\"; sid:2;) ");
4763 printf(
"sig 2 didn't parse: ");
4777 static int SigParseTest12(
void)
4789 printf(
"sig 1 should have given an error: ");
4803 static int SigParseTest13(
void)
4815 printf(
"sig 1 invalidated: failure");
4820 printf(
"sig doesn't have stream flag set\n");
4825 printf(
"sig has packet flag set\n");
4840 static int SigParseTest14(
void)
4852 printf(
"sig 1 invalidated: failure");
4857 printf(
"sig doesn't have packet flag set\n");
4862 printf(
"sig has stream flag set\n");
4877 static int SigParseTest15(
void)
4889 printf(
"sig 1 invalidated: failure");
4894 printf(
"sig doesn't have packet flag set\n");
4899 printf(
"sig doesn't have stream flag set\n");
4914 static int SigParseTest16(
void)
4926 printf(
"sig 1 invalidated: failure");
4931 printf(
"sig doesn't have packet flag set\n");
4936 printf(
"sig doesn't have stream flag set\n");
4951 static int SigParseTest17(
void)
4963 printf(
"sig 1 invalidated: failure");
4968 printf(
"sig doesn't have packet flag set\n");
4973 printf(
"sig doesn't have stream flag set\n");
4986 static int SigParseTest18 (
void)
4994 if (
DetectEngineAppendSig(
de_ctx,
"alert tcp 1.2.3.4 any -> !1.2.3.4 any (msg:\"SigParseTest01\"; sid:99999999999999999999;)") != NULL)
5005 static int SigParseTest19 (
void)
5013 if (
DetectEngineAppendSig(
de_ctx,
"alert tcp 1.2.3.4 any -> !1.2.3.4 any (msg:\"SigParseTest01\"; sid:1; gid:99999999999999999999;)") != NULL)
5024 static int SigParseTest20 (
void)
5032 if (
DetectEngineAppendSig(
de_ctx,
"alert tcp 1.2.3.4 any -> !1.2.3.4 any (msg:\"SigParseTest01\"; sid:1; rev:99999999999999999999;)") != NULL)
5043 static int SigParseTest21 (
void)
5062 static int SigParseTest22 (
void)
5070 if (
DetectEngineAppendSig(
de_ctx,
"alert tcp [10.10.10.0/24, !10.10.10.247] any -> [10.10.10.0/24, !10.10.10.247] any (sid:1;)") == NULL)
5083 static int SigParseTest23(
void)
5098 static int SigParseBidirecTest06 (
void)
5118 static int SigParseBidirecTest07 (
void)
5138 static int SigParseBidirecTest08 (
void)
5158 static int SigParseBidirecTest09 (
void)
5178 static int SigParseBidirecTest10 (
void)
5198 static int SigParseBidirecTest11 (
void)
5218 static int SigParseBidirecTest12 (
void)
5238 static int SigParseBidirecTest13 (
void)
5257 static int SigParseBidirecTest14 (
void)
5278 static int SigTestBidirec01 (
void)
5290 if (sig->
next != NULL)
5309 static int SigTestBidirec02 (
void)
5328 if (sig->
next == NULL)
5333 if (copy->
next != NULL)
5354 static int SigTestBidirec03 (
void)
5366 const char *sigs[3];
5367 sigs[0] =
"alert tcp any any -> 192.168.1.1 any (msg:\"SigTestBidirec03 sid 1\"; sid:1;)";
5368 sigs[1] =
"alert tcp any any <> 192.168.1.1 any (msg:\"SigTestBidirec03 sid 2 bidirectional\"; sid:2;)";
5369 sigs[2] =
"alert tcp any any -> 192.168.1.1 any (msg:\"SigTestBidirec03 sid 3\"; sid:3;)";
5376 if (sig->
next == NULL)
5387 uint8_t rawpkt1_ether[] = {
5388 0x00,0x50,0x56,0xea,0x00,0xbd,0x00,0x0c,
5389 0x29,0x40,0xc8,0xb5,0x08,0x00,0x45,0x00,
5390 0x01,0xa8,0xb9,0xbb,0x40,0x00,0x40,0x06,
5391 0xe0,0xbf,0xc0,0xa8,0x1c,0x83,0xc0,0xa8,
5392 0x01,0x01,0xb9,0x0a,0x00,0x50,0x6f,0xa2,
5393 0x92,0xed,0x7b,0xc1,0xd3,0x4d,0x50,0x18,
5394 0x16,0xd0,0xa0,0x6f,0x00,0x00,0x47,0x45,
5395 0x54,0x20,0x2f,0x20,0x48,0x54,0x54,0x50,
5396 0x2f,0x31,0x2e,0x31,0x0d,0x0a,0x48,0x6f,
5397 0x73,0x74,0x3a,0x20,0x31,0x39,0x32,0x2e,
5398 0x31,0x36,0x38,0x2e,0x31,0x2e,0x31,0x0d,
5399 0x0a,0x55,0x73,0x65,0x72,0x2d,0x41,0x67,
5400 0x65,0x6e,0x74,0x3a,0x20,0x4d,0x6f,0x7a,
5401 0x69,0x6c,0x6c,0x61,0x2f,0x35,0x2e,0x30,
5402 0x20,0x28,0x58,0x31,0x31,0x3b,0x20,0x55,
5403 0x3b,0x20,0x4c,0x69,0x6e,0x75,0x78,0x20,
5404 0x78,0x38,0x36,0x5f,0x36,0x34,0x3b,0x20,
5405 0x65,0x6e,0x2d,0x55,0x53,0x3b,0x20,0x72,
5406 0x76,0x3a,0x31,0x2e,0x39,0x2e,0x30,0x2e,
5407 0x31,0x34,0x29,0x20,0x47,0x65,0x63,0x6b,
5408 0x6f,0x2f,0x32,0x30,0x30,0x39,0x30,0x39,
5409 0x30,0x32,0x31,0x37,0x20,0x55,0x62,0x75,
5410 0x6e,0x74,0x75,0x2f,0x39,0x2e,0x30,0x34,
5411 0x20,0x28,0x6a,0x61,0x75,0x6e,0x74,0x79,
5412 0x29,0x20,0x46,0x69,0x72,0x65,0x66,0x6f,
5413 0x78,0x2f,0x33,0x2e,0x30,0x2e,0x31,0x34,
5414 0x0d,0x0a,0x41,0x63,0x63,0x65,0x70,0x74,
5415 0x3a,0x20,0x74,0x65,0x78,0x74,0x2f,0x68,
5416 0x74,0x6d,0x6c,0x2c,0x61,0x70,0x70,0x6c,
5417 0x69,0x63,0x61,0x74,0x69,0x6f,0x6e,0x2f,
5418 0x78,0x68,0x74,0x6d,0x6c,0x2b,0x78,0x6d,
5419 0x6c,0x2c,0x61,0x70,0x70,0x6c,0x69,0x63,
5420 0x61,0x74,0x69,0x6f,0x6e,0x2f,0x78,0x6d,
5421 0x6c,0x3b,0x71,0x3d,0x30,0x2e,0x39,0x2c,
5422 0x2a,0x2f,0x2a,0x3b,0x71,0x3d,0x30,0x2e,
5423 0x38,0x0d,0x0a,0x41,0x63,0x63,0x65,0x70,
5424 0x74,0x2d,0x4c,0x61,0x6e,0x67,0x75,0x61,
5425 0x67,0x65,0x3a,0x20,0x65,0x6e,0x2d,0x75,
5426 0x73,0x2c,0x65,0x6e,0x3b,0x71,0x3d,0x30,
5427 0x2e,0x35,0x0d,0x0a,0x41,0x63,0x63,0x65,
5428 0x70,0x74,0x2d,0x45,0x6e,0x63,0x6f,0x64,
5429 0x69,0x6e,0x67,0x3a,0x20,0x67,0x7a,0x69,
5430 0x70,0x2c,0x64,0x65,0x66,0x6c,0x61,0x74,
5431 0x65,0x0d,0x0a,0x41,0x63,0x63,0x65,0x70,
5432 0x74,0x2d,0x43,0x68,0x61,0x72,0x73,0x65,
5433 0x74,0x3a,0x20,0x49,0x53,0x4f,0x2d,0x38,
5434 0x38,0x35,0x39,0x2d,0x31,0x2c,0x75,0x74,
5435 0x66,0x2d,0x38,0x3b,0x71,0x3d,0x30,0x2e,
5436 0x37,0x2c,0x2a,0x3b,0x71,0x3d,0x30,0x2e,
5437 0x37,0x0d,0x0a,0x4b,0x65,0x65,0x70,0x2d,
5438 0x41,0x6c,0x69,0x76,0x65,0x3a,0x20,0x33,
5439 0x30,0x30,0x0d,0x0a,0x43,0x6f,0x6e,0x6e,
5440 0x65,0x63,0x74,0x69,0x6f,0x6e,0x3a,0x20,
5441 0x6b,0x65,0x65,0x70,0x2d,0x61,0x6c,0x69,
5442 0x76,0x65,0x0d,0x0a,0x0d,0x0a };
5452 uint32_t sids[3] = {1, 2, 3};
5453 uint32_t results[3] = {1, 1, 1};
5469 static int SigTestBidirec04 (
void)
5484 sig =
DetectEngineAppendSig(
de_ctx,
"alert tcp 192.168.1.1 any <> any any (msg:\"SigTestBidirec03 sid 2 bidirectional\"; sid:2;)");
5489 if (sig->
next == NULL)
5501 if (sig->
next == NULL)
5512 uint8_t rawpkt1_ether[] = {
5513 0x00,0x50,0x56,0xea,0x00,0xbd,0x00,0x0c,
5514 0x29,0x40,0xc8,0xb5,0x08,0x00,0x45,0x00,
5515 0x01,0xa8,0xb9,0xbb,0x40,0x00,0x40,0x06,
5516 0xe0,0xbf,0xc0,0xa8,0x1c,0x83,0xc0,0xa8,
5517 0x01,0x01,0xb9,0x0a,0x00,0x50,0x6f,0xa2,
5518 0x92,0xed,0x7b,0xc1,0xd3,0x4d,0x50,0x18,
5519 0x16,0xd0,0xa0,0x6f,0x00,0x00,0x47,0x45,
5520 0x54,0x20,0x2f,0x20,0x48,0x54,0x54,0x50,
5521 0x2f,0x31,0x2e,0x31,0x0d,0x0a,0x48,0x6f,
5522 0x73,0x74,0x3a,0x20,0x31,0x39,0x32,0x2e,
5523 0x31,0x36,0x38,0x2e,0x31,0x2e,0x31,0x0d,
5524 0x0a,0x55,0x73,0x65,0x72,0x2d,0x41,0x67,
5525 0x65,0x6e,0x74,0x3a,0x20,0x4d,0x6f,0x7a,
5526 0x69,0x6c,0x6c,0x61,0x2f,0x35,0x2e,0x30,
5527 0x20,0x28,0x58,0x31,0x31,0x3b,0x20,0x55,
5528 0x3b,0x20,0x4c,0x69,0x6e,0x75,0x78,0x20,
5529 0x78,0x38,0x36,0x5f,0x36,0x34,0x3b,0x20,
5530 0x65,0x6e,0x2d,0x55,0x53,0x3b,0x20,0x72,
5531 0x76,0x3a,0x31,0x2e,0x39,0x2e,0x30,0x2e,
5532 0x31,0x34,0x29,0x20,0x47,0x65,0x63,0x6b,
5533 0x6f,0x2f,0x32,0x30,0x30,0x39,0x30,0x39,
5534 0x30,0x32,0x31,0x37,0x20,0x55,0x62,0x75,
5535 0x6e,0x74,0x75,0x2f,0x39,0x2e,0x30,0x34,
5536 0x20,0x28,0x6a,0x61,0x75,0x6e,0x74,0x79,
5537 0x29,0x20,0x46,0x69,0x72,0x65,0x66,0x6f,
5538 0x78,0x2f,0x33,0x2e,0x30,0x2e,0x31,0x34,
5539 0x0d,0x0a,0x41,0x63,0x63,0x65,0x70,0x74,
5540 0x3a,0x20,0x74,0x65,0x78,0x74,0x2f,0x68,
5541 0x74,0x6d,0x6c,0x2c,0x61,0x70,0x70,0x6c,
5542 0x69,0x63,0x61,0x74,0x69,0x6f,0x6e,0x2f,
5543 0x78,0x68,0x74,0x6d,0x6c,0x2b,0x78,0x6d,
5544 0x6c,0x2c,0x61,0x70,0x70,0x6c,0x69,0x63,
5545 0x61,0x74,0x69,0x6f,0x6e,0x2f,0x78,0x6d,
5546 0x6c,0x3b,0x71,0x3d,0x30,0x2e,0x39,0x2c,
5547 0x2a,0x2f,0x2a,0x3b,0x71,0x3d,0x30,0x2e,
5548 0x38,0x0d,0x0a,0x41,0x63,0x63,0x65,0x70,
5549 0x74,0x2d,0x4c,0x61,0x6e,0x67,0x75,0x61,
5550 0x67,0x65,0x3a,0x20,0x65,0x6e,0x2d,0x75,
5551 0x73,0x2c,0x65,0x6e,0x3b,0x71,0x3d,0x30,
5552 0x2e,0x35,0x0d,0x0a,0x41,0x63,0x63,0x65,
5553 0x70,0x74,0x2d,0x45,0x6e,0x63,0x6f,0x64,
5554 0x69,0x6e,0x67,0x3a,0x20,0x67,0x7a,0x69,
5555 0x70,0x2c,0x64,0x65,0x66,0x6c,0x61,0x74,
5556 0x65,0x0d,0x0a,0x41,0x63,0x63,0x65,0x70,
5557 0x74,0x2d,0x43,0x68,0x61,0x72,0x73,0x65,
5558 0x74,0x3a,0x20,0x49,0x53,0x4f,0x2d,0x38,
5559 0x38,0x35,0x39,0x2d,0x31,0x2c,0x75,0x74,
5560 0x66,0x2d,0x38,0x3b,0x71,0x3d,0x30,0x2e,
5561 0x37,0x2c,0x2a,0x3b,0x71,0x3d,0x30,0x2e,
5562 0x37,0x0d,0x0a,0x4b,0x65,0x65,0x70,0x2d,
5563 0x41,0x6c,0x69,0x76,0x65,0x3a,0x20,0x33,
5564 0x30,0x30,0x0d,0x0a,0x43,0x6f,0x6e,0x6e,
5565 0x65,0x63,0x74,0x69,0x6f,0x6e,0x3a,0x20,
5566 0x6b,0x65,0x65,0x70,0x2d,0x61,0x6c,0x69,
5567 0x76,0x65,0x0d,0x0a,0x0d,0x0a };
5616 static int SigParseTestNegation01 (
void)
5630 static int SigParseTestNegation02 (
void)
5636 "alert tcp any !any -> any any (msg:\"SigTest41-02 src ip is !any \"; "
5637 "classtype:misc-activity; sid:410002; rev:1;)");
5645 static int SigParseTestNegation03 (
void)
5651 "alert tcp any any -> any [80:!80] (msg:\"SigTest41-03 dst port [80:!80] \"; "
5652 "classtype:misc-activity; sid:410003; rev:1;)");
5660 static int SigParseTestNegation04 (
void)
5671 s =
SigInit(
de_ctx,
"alert tcp any any -> any [80,!80] (msg:\"SigTest41-03 dst port [80:!80] \"; classtype:misc-activity; sid:410003; rev:1;)");
5686 static int SigParseTestNegation05 (
void)
5697 s =
SigInit(
de_ctx,
"alert tcp any any -> [192.168.0.2,!192.168.0.2] any (msg:\"SigTest41-04 dst ip [192.168.0.2,!192.168.0.2] \"; classtype:misc-activity; sid:410004; rev:1;)");
5712 static int SigParseTestNegation06 (
void)
5723 s =
SigInit(
de_ctx,
"alert tcp any any -> any [100:1000,!1:20000] (msg:\"SigTest41-05 dst port [100:1000,!1:20000] \"; classtype:misc-activity; sid:410005; rev:1;)");
5739 static int SigParseTestNegation07 (
void)
5745 de_ctx,
"alert tcp any any -> [192.168.0.2,!192.168.0.0/24] any (sid:410006;)");
5754 static int SigParseTestNegation08 (
void)
5766 "alert tcp any any -> [192.168.0.0/16,!192.168.0.0/24] any (sid:410006; rev:1;)");
5781 static int SigParseTestMpm01 (
void)
5790 sig =
SigInit(
de_ctx,
"alert tcp any any -> any any (msg:\"mpm test\"; content:\"abcd\"; sid:1;)");
5792 printf(
"sig failed to init: ");
5797 printf(
"sig doesn't have content list: ");
5812 static int SigParseTestMpm02 (
void)
5821 sig =
SigInit(
de_ctx,
"alert tcp any any -> any any (msg:\"mpm test\"; content:\"abcd\"; content:\"abcdef\"; sid:1;)");
5823 printf(
"sig failed to init: ");
5828 printf(
"sig doesn't have content list: ");
5843 static int SigParseTestAppLayerTLS01(
void)
5854 s =
SigInit(
de_ctx,
"alert tls any any -> any any (msg:\"SigParseTestAppLayerTLS01 \"; sid:410006; rev:1;)");
5856 printf(
"parsing sig failed: ");
5861 printf(
"alproto not set: ");
5878 static int SigParseTestAppLayerTLS02(
void)
5889 s =
SigInit(
de_ctx,
"alert tls any any -> any any (msg:\"SigParseTestAppLayerTLS02 \"; tls.version:1.0; sid:410006; rev:1;)");
5891 printf(
"parsing sig failed: ");
5896 printf(
"alproto not set: ");
5912 static int SigParseTestAppLayerTLS03(
void)
5919 "alert tls any any -> any any (msg:\"SigParseTestAppLayerTLS03 \"; "
5920 "tls.version:2.5; sid:410006; rev:1;)");
5926 static int SigParseTestUnbalancedQuotes01(
void)
5932 "alert http any any -> any any (msg:\"SigParseTestUnbalancedQuotes01\"; "
5933 "pcre:\"/\\/[a-z]+\\.php\\?[a-z]+?=\\d{7}&[a-z]+?=\\d{7,8}$/U\" "
5934 "flowbits:set,et.exploitkitlanding; classtype:trojan-activity; sid:2017078; rev:5;)");
5940 static int SigParseTestContentGtDsize01(
void)
5947 "dsize:21; content:\"0123456789001234567890|00 00|\"; "
5954 static int SigParseTestContentGtDsize02(
void)
5961 "dsize:21; content:\"0123456789|00 00|\"; offset:10; "
5978 static int SigParseBidirWithSameSrcAndDest01(
void)
5995 "alert tcp [1.2.3.4, 5.6.7.8] [80, 81] <> [5.6.7.8, 1.2.3.4] [81, 80] (sid:3;)");
6004 static int SigParseBidirWithSameSrcAndDest02(
void)
6012 de_ctx,
"alert tcp 1.2.3.4 any <> [1.2.3.4, 5.6.7.8, ::1] any (sid:1;)");
6019 de_ctx,
"alert tcp [1.2.3.4, ::1] [80, 81, 82] <> [1.2.3.4, ::1] [80, 81] (sid:2;)");
6026 "alert tcp [1.2.3.4, ::1, ABCD:AAAA::1] [80] <> [1.2.3.4, ::1] [80, 81] (sid:3;)");
6033 de_ctx,
"alert tcp [!1.2.3.4, 1.2.3.0/24] any <> [1.2.3.0/24, !1.2.3.4] any (sid:4;)");
6040 de_ctx,
"alert tcp [1.2.3.4, 1.2.3.0/24] any <> [1.2.3.0/24, !1.2.3.4] any (sid:5;)");
6049 static int SigParseTestActionReject(
void)
6055 de_ctx,
"reject tcp 1.2.3.4 any -> !1.2.3.4 any (msg:\"SigParseTest01\"; sid:1;)");
6056 #ifdef HAVE_LIBNET11
6067 static int SigParseTestActionDrop(
void)
6073 de_ctx,
"drop tcp 1.2.3.4 any -> !1.2.3.4 any (msg:\"SigParseTest01\"; sid:1;)");
6081 static int SigSetMultiAppProto(
void)
6156 static int DetectSetupDirection01(
void)
6161 char *
str = (
char *)
"to_client";
6162 FAIL_IF(DetectSetupDirection(s, &
str,
true) < 0);
6167 static int DetectSetupDirection02(
void)
6171 char *
str = (
char *)
"to_server";
6172 FAIL_IF(DetectSetupDirection(s, &
str,
true) < 0);
6174 str = (
char *)
"to_client";
6175 FAIL_IF(DetectSetupDirection(s, &
str,
true) >= 0);
6181 static int DetectSetupDirection03(
void)
6185 char *
str = (
char *)
"to_client , something";
6186 FAIL_IF(DetectSetupDirection(s, &
str,
false) < 0);
6188 str = (
char *)
"to_client,something";
6189 FAIL_IF(DetectSetupDirection(s, &
str,
false) < 0);
6195 static int DetectSetupDirection04(
void)
6200 char *
str = (
char *)
"to_client_toto";
6201 FAIL_IF(DetectSetupDirection(s, &
str,
true) >= 0);
6203 str = (
char *)
"to_client_toto";
6204 FAIL_IF(DetectSetupDirection(s, &
str,
false) < 0);
6206 str = (
char *)
"to_client,something";
6208 FAIL_IF(DetectSetupDirection(s, &
str,
true) >= 0);
6245 UtRegisterTest(
"SigParseTest21 -- address with space", SigParseTest21);
6246 UtRegisterTest(
"SigParseTest22 -- address with space", SigParseTest22);
6247 UtRegisterTest(
"SigParseTest23 -- carriage return", SigParseTest23);
6262 UtRegisterTest(
"SigParseTestNegation01", SigParseTestNegation01);
6263 UtRegisterTest(
"SigParseTestNegation02", SigParseTestNegation02);
6264 UtRegisterTest(
"SigParseTestNegation03", SigParseTestNegation03);
6265 UtRegisterTest(
"SigParseTestNegation04", SigParseTestNegation04);
6266 UtRegisterTest(
"SigParseTestNegation05", SigParseTestNegation05);
6267 UtRegisterTest(
"SigParseTestNegation06", SigParseTestNegation06);
6268 UtRegisterTest(
"SigParseTestNegation07", SigParseTestNegation07);
6269 UtRegisterTest(
"SigParseTestNegation08", SigParseTestNegation08);
6272 UtRegisterTest(
"SigParseTestAppLayerTLS01", SigParseTestAppLayerTLS01);
6273 UtRegisterTest(
"SigParseTestAppLayerTLS02", SigParseTestAppLayerTLS02);
6274 UtRegisterTest(
"SigParseTestAppLayerTLS03", SigParseTestAppLayerTLS03);
6275 UtRegisterTest(
"SigParseTestUnbalancedQuotes01", SigParseTestUnbalancedQuotes01);
6278 SigParseTestContentGtDsize01);
6280 SigParseTestContentGtDsize02);
6283 SigParseBidirWithSameSrcAndDest01);
6285 SigParseBidirWithSameSrcAndDest02);
6286 UtRegisterTest(
"SigParseTestActionReject", SigParseTestActionReject);
6287 UtRegisterTest(
"SigParseTestActionDrop", SigParseTestActionDrop);
6291 UtRegisterTest(
"DetectSetupDirection01", DetectSetupDirection01);
6292 UtRegisterTest(
"DetectSetupDirection02", DetectSetupDirection02);
6293 UtRegisterTest(
"DetectSetupDirection03", DetectSetupDirection03);
6294 UtRegisterTest(
"DetectSetupDirection04", DetectSetupDirection04);