82 static void SigMatchTransferSigMatchAcrossLists(
SigMatch *sm,
118 static const uint8_t fw_packet_hook_scopes[] = {
123 static const uint8_t fw_packet_pre_flow_hook_scopes[] = {
127 static const uint8_t fw_app_hook_scopes[] = {
134 #define FW_POLICY_YAML_PATH_MAX 320
136 #define FW_POLICY_YAML_PATH_NAME_MAX 64
138 #define FW_POLICY_CHAIN_MAX 6
151 #define CASE_CODE_STRING(E, S) case E: return S; break
162 #undef CASE_CODE_STRING
166 #define CASE_CODE(E) case E: return #E
184 Signature *s,
const char *arg,
int sm_type,
int sm_list,
190 if (arg != NULL && strcmp(arg,
"") != 0) {
199 "with a sticky buffer still set. Reset sticky buffer "
200 "with pkt_data before using the modifier.",
214 "found inside the rule without a content context. "
215 "Please use a \"content\" keyword before using the "
223 "be used with the rawbytes rule keyword",
229 "be used with the replace rule keyword",
268 bool reuse_buffer =
false;
281 SCLogError(
"failed to expand rule buffer array");
290 SCLogDebug(
"idx %u list %d set up curbuf %p s->init_data->buffer_index %u",
331 if (sm->
ctx != NULL) {
342 ptrdiff_t
offset = e - table;
356 if (st->
name != NULL) {
388 if (strcmp(
str,
"all") == 0) {
400 char *xsaveptr = NULL;
401 char *key = strtok_r(copy,
",", &xsaveptr);
402 while (key != NULL) {
408 "argument '%s' not found",
411 key = strtok_r(NULL,
",", &xsaveptr);
438 SCLogDebug(
"s:%p new:%p list:%d: %s, s->init_data->list_set %s s->init_data->list %d", s,
new,
472 SCLogDebug(
"reusing buffer %u as it isn't multi-capable", x);
482 SCLogError(
"failed to expand rule buffer array");
512 SCLogDebug(
"appended %s to list %d, rule pos %u (s->init_data->list %d)",
531 if (sm->
prev != NULL)
533 if (sm->
next != NULL)
575 if (sm_last == NULL || sm_new->
idx > sm_last->
idx)
587 if (sm_last == NULL || sm_new->
idx > sm_last->
idx)
609 SCLogDebug(
"skip x %u s->init_data->list %d (int)s->init_data->buffers[x].id %d", x,
618 for (sm_type = va_arg(ap,
int); sm_type != -1; sm_type = va_arg(ap,
int)) {
622 if (sm_last == NULL || sm_new->
idx > sm_last->
idx)
639 for (sm_type = va_arg(ap,
int); sm_type != -1; sm_type = va_arg(ap,
int))
644 if (sm_last == NULL || sm_new->
idx > sm_last->
idx)
669 va_start(ap, sm_list);
671 for (sm_type = va_arg(ap,
int); sm_type != -1; sm_type = va_arg(ap,
int))
673 sm_new = SigMatchGetLastSMByType(sm_list, sm_type);
676 if (sm_last == NULL || sm_new->
idx > sm_last->
idx)
707 va_start(ap, list_id);
709 for (sm_type = va_arg(ap,
int); sm_type != -1; sm_type = va_arg(ap,
int)) {
713 if (sm_last == NULL || sm_new->
idx > sm_last->
idx)
725 va_start(ap, list_id);
727 for (sm_type = va_arg(ap,
int); sm_type != -1; sm_type = va_arg(ap,
int)) {
728 sm_new = SigMatchGetLastSMByType(sm_list, sm_type);
731 if (sm_last == NULL || sm_new->
idx > sm_last->
idx)
777 return SigMatchGetLastSMByType(sm->
prev,
type);
805 if (sm_last == NULL || sm_new->
idx > sm_last->
idx)
813 if (sm_last == NULL || sm_new->
idx > sm_last->
idx)
820 static void SigMatchTransferSigMatchAcrossLists(
SigMatch *sm,
826 if (sm->
prev != NULL)
828 if (sm->
next != NULL)
831 if (sm == *src_sm_list)
832 *src_sm_list = sm->
next;
833 if (sm == *src_sm_list_tail)
834 *src_sm_list_tail = sm->
prev;
836 if (*dst_sm_list == NULL) {
838 *dst_sm_list_tail = sm;
846 *dst_sm_list_tail = sm;
873 SCLogError(
"Unable to find the sm in any of the "
887 static int DetectSetupDirection(
Signature *s,
char **
str,
bool only_dir)
890 if (strncmp(*
str,
"to_client", strlen(
"to_client")) == 0) {
891 *
str += strlen(
"to_client");
893 while (**
str && isblank(**
str)) {
899 SCLogError(
"unknown option: only accepts to_server or to_client");
909 while (**
str && isblank(**
str)) {
921 }
else if (strncmp(*
str,
"to_server", strlen(
"to_server")) == 0) {
922 *
str += strlen(
"to_server");
924 while (**
str && isblank(**
str)) {
930 SCLogError(
"unknown option: only accepts to_server or to_client");
940 while (**
str && isblank(**
str)) {
952 }
else if (only_dir) {
953 SCLogError(
"unknown option: only accepts to_server or to_client");
960 size_t output_size,
bool requires)
963 char *optname = NULL;
964 char *optvalue = NULL;
967 while (isblank(*optstr)) {
972 char *optend = optstr;
974 optend = strchr(optend,
';');
975 if (optend == NULL) {
979 else if (optend > optstr && *(optend -1 ) ==
'\\') {
988 char *optvalptr = strchr(optstr,
':');
990 *(optvalptr++) =
'\0';
993 for (
size_t i = strlen(optvalptr); i > 0; i--) {
994 if (isblank(optvalptr[i - 1])) {
995 optvalptr[i - 1] =
'\0';
1001 optvalue = optvalptr;
1005 for (
size_t i = strlen(optstr); i > 0; i--) {
1006 if (isblank(optstr[i - 1])) {
1007 optstr[i - 1] =
'\0';
1016 bool requires_only = strcasecmp(optname,
"requires") == 0 || strcasecmp(optname,
"sid") == 0;
1017 if ((requires && !requires_only) || (!requires && requires_only)) {
1022 st = SigTableGet(optname);
1023 if (st == NULL || st->
Setup == NULL) {
1024 SCLogError(
"unknown rule keyword '%s'.", optname);
1029 if (optvalue == NULL || strlen(optvalue) == 0) {
1031 "invalid formatting or malformed option to %s keyword: '%s'", optname, optstr);
1035 if (optvalue && strlen(optvalue)) {
1036 SCLogError(
"unexpected option to %s keyword: '%s'", optname, optstr);
1046 #define URL "https://suricata.io/our-story/deprecation-policy/"
1049 "and will be removed soon. See %s",
1053 "and will be removed soon. Use '%s' instead. "
1060 SCLogError(
"keyword \'%s\' is not supported with firewall rules", optname);
1065 SCLogError(
"keyword \'%s\' is not supported in firewall mode", optname);
1072 SCLogError(
"keyword \'%s\' is not supported in threat detection rules with firewall mode",
1079 "action \'config\' is not supported in threat detection rules with firewall mode");
1085 if (optvalue != NULL && strlen(optvalue) > 0) {
1086 size_t ovlen = strlen(optvalue);
1087 char *ptr = optvalue;
1097 SCLogError(
"invalid formatting or malformed option to %s keyword: \'%s\'", optname,
1103 SCLogWarning(
"keyword \'%s\' has not been tested for firewall rules", optname);
1120 SCLogError(
"invalid formatting or malformed option to %s keyword: \'%s\'", optname,
1126 SCLogError(
"invalid formatting to %s keyword: "
1127 "value must be double quoted \'%s\'",
1133 && ovlen && *ptr ==
'"')
1135 for (; ovlen > 0; ovlen--) {
1136 if (isblank(ptr[ovlen - 1])) {
1137 ptr[ovlen - 1] =
'\0';
1142 if (ovlen && ptr[ovlen - 1] !=
'"') {
1143 SCLogError(
"bad option value formatting (possible missing semicolon) "
1144 "for keyword %s: \'%s\'",
1152 ptr[ovlen - 1] =
'\0';
1157 "for keyword %s: \'%s\'",
1164 "quotes on %s keyword that doesn't support them: \'%s\'", optname, optstr);
1182 if (setup_ret < 0) {
1186 if (setup_ret == -2) {
1198 if (strlen(optend) > 0) {
1199 strlcpy(output, optend, output_size);
1214 Signature *s,
const char *addrstr,
char flag)
1216 SCLogDebug(
"Address Group \"%s\" to be parsed now", addrstr);
1220 if (strcasecmp(addrstr,
"any") == 0)
1228 if (strcasecmp(addrstr,
"any") == 0)
1243 static bool IsBuiltIn(
const char *n)
1245 return strcmp(n,
"request_started") == 0 || strcmp(n,
"response_started") == 0 ||
1246 strcmp(n,
"request_complete") == 0 || strcmp(n,
"response_complete") == 0;
1254 const uint8_t state,
const uint8_t complete_state,
const int direction)
1257 return (direction == STREAM_TOSERVER) ?
"request-started" :
"response-started";
1258 if (state == complete_state)
1259 return (direction == STREAM_TOSERVER) ?
"request-complete" :
"response-complete";
1275 SCLogDebug(
"alproto %u/%s", a, alproto_name);
1279 SCLogDebug(
"%s: max sub state for %u is %u", alproto_name, a, max_sub_state);
1280 for (uint8_t s = 1; s <= max_sub_state; s++) {
1284 if (sub_state_name == NULL)
1287 char ts_tx_started[64];
1288 snprintf(ts_tx_started,
sizeof(ts_tx_started),
"%s:%s:request_started:generic",
1289 alproto_name, sub_state_name);
1293 char tc_tx_started[64];
1294 snprintf(tc_tx_started,
sizeof(tc_tx_started),
"%s:%s:response_started:generic",
1295 alproto_name, sub_state_name);
1299 char ts_tx_complete[64];
1300 snprintf(ts_tx_complete,
sizeof(ts_tx_complete),
"%s:%s:request_complete:generic",
1301 alproto_name, sub_state_name);
1305 char tc_tx_complete[64];
1306 snprintf(tc_tx_complete,
sizeof(tc_tx_complete),
"%s:%s:response_complete:generic",
1307 alproto_name, sub_state_name);
1312 for (uint8_t state = 0; state <= max_state; state++) {
1313 const char *state_name =
1315 BUG_ON(state_name == NULL);
1317 if (state_name != NULL && !IsBuiltIn(state_name)) {
1319 snprintf(list_name,
sizeof(list_name),
"%s:%s:%s:generic", alproto_name,
1320 sub_state_name, state_name);
1326 for (uint8_t state = 0; state <= max_state; state++) {
1327 const char *state_name =
1329 BUG_ON(state_name == NULL);
1330 if (state_name != NULL && !IsBuiltIn(state_name)) {
1332 snprintf(list_name,
sizeof(list_name),
"%s:%s:%s:generic", alproto_name,
1333 sub_state_name, state_name);
1340 const uint8_t max_progress_ts =
1342 const uint8_t max_progress_tc =
1345 char ts_tx_started[64];
1346 snprintf(ts_tx_started,
sizeof(ts_tx_started),
"%s:request_started:generic",
1350 SCLogDebug(
"- hook %s:%s list %s (%u)", alproto_name,
"request_name", ts_tx_started,
1351 (uint32_t)strlen(ts_tx_started));
1353 char tc_tx_started[64];
1354 snprintf(tc_tx_started,
sizeof(tc_tx_started),
"%s:response_started:generic",
1358 SCLogDebug(
"- hook %s:%s list %s (%u)", alproto_name,
"response_name", tc_tx_started,
1359 (uint32_t)strlen(tc_tx_started));
1361 char ts_tx_complete[64];
1362 snprintf(ts_tx_complete,
sizeof(ts_tx_complete),
"%s:request_complete:generic",
1366 SCLogDebug(
"- hook %s:%s list %s (%u)", alproto_name,
"request_name", ts_tx_complete,
1367 (uint32_t)strlen(ts_tx_complete));
1369 char tc_tx_complete[64];
1370 snprintf(tc_tx_complete,
sizeof(tc_tx_complete),
"%s:response_complete:generic",
1374 SCLogDebug(
"- hook %s:%s list %s (%u)", alproto_name,
"response_name", tc_tx_complete,
1375 (uint32_t)strlen(tc_tx_complete));
1377 for (uint8_t
p = 0;
p <= max_progress_ts;
p++) {
1379 IPPROTO_TCP , a,
p, STREAM_TOSERVER);
1380 if (
name != NULL && !IsBuiltIn(
name)) {
1382 snprintf(list_name,
sizeof(list_name),
"%s:%s:generic", alproto_name,
name);
1383 SCLogDebug(
"- hook %s:%s list %s (%u)", alproto_name,
name, list_name,
1384 (uint32_t)strlen(list_name));
1390 for (uint8_t
p = 0;
p <= max_progress_tc;
p++) {
1392 IPPROTO_TCP , a,
p, STREAM_TOCLIENT);
1393 if (
name != NULL && !IsBuiltIn(
name)) {
1395 snprintf(list_name,
sizeof(list_name),
"%s:%s:generic", alproto_name,
name);
1396 SCLogDebug(
"- hook %s:%s list %s (%u)", alproto_name,
name, list_name,
1397 (uint32_t)strlen(list_name));
1424 if (strcmp(
str,
"flow_start") == 0) {
1426 }
else if (strcmp(
str,
"pre_flow") == 0) {
1428 }
else if (strcmp(
str,
"pre_stream") == 0) {
1430 }
else if (strcmp(
str,
"all") == 0) {
1443 return "flow_start";
1447 return "pre_stream";
1459 .t.pkt.ph = HookPktFromString(hook_str),
1467 static int SigParseProtoHookPkt(
Signature *s,
const char *proto_hook,
const char *
p,
const char *h)
1480 SCLogDebug(
"protocol:%s hook:%s: type:%s parsed hook:%s",
p, h,
1490 .t.app.alproto = alproto,
1491 .t.app.sub_state = sub_state,
1492 .t.app.app_progress = progress,
1500 static int SigParseProtoHookApp(
1501 Signature *s,
const char *proto_hook,
const char *
p,
const char *in_h)
1504 char generic_hook_name[256];
1505 strlcpy(hook, in_h,
sizeof(hook));
1506 const char *h = hook;
1507 const char *t = NULL;
1508 uint8_t sub_state = 0;
1510 bool has_type = strchr(hook,
':') != NULL;
1513 t = strtok_r(hook,
":", &rem);
1517 if (h == NULL || strlen(h) == 0) {
1518 SCLogError(
"invalid hook specification '%s'", hook);
1523 if (strlen(t) == 0) {
1524 SCLogError(
"invalid tx type specification '%s'", hook);
1527 if (strcmp(
p,
"http2") == 0 || strcmp(
p,
"doh2") == 0) {
1528 if (strcmp(t,
"stream") == 0) {
1529 sub_state = HTTP2TxTypeStream;
1530 }
else if (strcmp(t,
"global") == 0) {
1531 sub_state = HTTP2TxTypeGlobal;
1533 SCLogError(
"unknown %s tx type specification '%s': valid values are 'stream' "
1539 SCLogError(
"sub states currently only supported for http2 and doh2");
1545 SCLogError(
"hook '%s': the lower bound form '<' is only allowed for firewall "
1556 if (strcmp(h,
"request_started") == 0) {
1560 }
else if (strcmp(h,
"response_started") == 0) {
1564 }
else if (strcmp(h,
"request_complete") == 0) {
1567 }
else if (strcmp(h,
"response_complete") == 0) {
1571 const int8_t progress_ts =
1573 if (progress_ts >= 0) {
1578 s->
alproto, sub_state, h, STREAM_TOCLIENT);
1579 if (progress_tc < 0) {
1586 snprintf(generic_hook_name,
sizeof(generic_hook_name),
"%s:%s:%s:generic",
p, t, h);
1590 "protocol %s requires a substate specification: %s:<sub_state>:%s",
p,
p, hook);
1597 SCLogError(
"hook '%s': the lower bound form '<' is only allowed for firewall "
1607 if (strcmp(h,
"request_started") == 0) {
1611 }
else if (strcmp(h,
"response_started") == 0) {
1615 }
else if (strcmp(h,
"request_complete") == 0) {
1619 }
else if (strcmp(h,
"response_complete") == 0) {
1625 IPPROTO_TCP , s->
alproto, h, STREAM_TOSERVER);
1626 if (progress_ts >= 0) {
1634 IPPROTO_TCP , s->
alproto, h, STREAM_TOCLIENT);
1642 snprintf(generic_hook_name,
sizeof(generic_hook_name),
"%s:%s:generic",
p, h);
1644 SCLogDebug(
"generic_hook_name %s", generic_hook_name);
1648 SCLogError(
"no list registered as %s for hook %s", generic_hook_name, proto_hook);
1653 SCLogDebug(
"protocol:%s hook:%s: type:%s alproto:%u hook:%d",
p, h,
1665 printf(
"=========Supported Rule Protocols=========\n");
1682 static int SigParseProto(
Signature *s,
const char *protostr)
1685 if (strlen(protostr) >= 64)
1691 const char *h = NULL;
1693 bool has_hook = strchr(
proto,
':') != NULL;
1696 p = strtok_r(
proto,
":", &rem);
1700 if (
p == NULL || strlen(
p) == 0) {
1715 if (strlen(h) == 0) {
1719 if (SigParseProtoHookApp(s, protostr,
p, h) < 0) {
1720 SCLogError(
"protocol \"%s\" does not support hook \"%s\"",
p, h);
1727 "in a signature. Either detection for this protocol "
1728 "is not yet supported OR detection has been disabled for "
1729 "protocol through the yaml option "
1730 "app-layer.protocols.%s.detection-enabled",
1734 }
else if (h != NULL) {
1735 SCLogDebug(
"non-app-layer rule with %s:%s",
p, h);
1737 if (SigParseProtoHookPkt(s, protostr,
p, h) < 0) {
1738 SCLogError(
"protocol \"%s\" does not support hook \"%s\"",
p, h);
1767 Signature *s,
const char *portstr,
char flag)
1773 SCLogDebug(
"Port group \"%s\" to be parsed", portstr);
1776 if (strcasecmp(portstr,
"any") == 0)
1780 }
else if (flag == 1) {
1781 if (strcasecmp(portstr,
"any") == 0)
1796 static int SigParseActionRejectValidate(
const char *action)
1798 #ifdef HAVE_LIBNET11
1799 #if defined HAVE_LIBCAP_NG && !defined HAVE_LIBNET_CAPABILITIES
1802 "incompatible with POSIX based capabilities with privs dropping. "
1803 "For rejects to work, run as root/super user.");
1809 "required for action \"%s\" but is not compiled into Suricata",
1819 static uint8_t ActionStringToFlags(
const char *action)
1821 if (strcasecmp(action,
"alert") == 0) {
1823 }
else if (strcasecmp(action,
"drop") == 0) {
1825 }
else if (strcasecmp(action,
"pass") == 0) {
1827 }
else if (strcasecmp(action,
"reject") == 0 ||
1828 strcasecmp(action,
"rejectsrc") == 0)
1830 if (!(SigParseActionRejectValidate(action)))
1833 }
else if (strcasecmp(action,
"rejectdst") == 0) {
1834 if (!(SigParseActionRejectValidate(action)))
1837 }
else if (strcasecmp(action,
"rejectboth") == 0) {
1838 if (!(SigParseActionRejectValidate(action)))
1841 }
else if (strcasecmp(action,
"config") == 0) {
1843 }
else if (strcasecmp(action,
"accept") == 0) {
1846 SCLogError(
"An invalid action \"%s\" was given", action);
1862 static int SigParseActionDo(
const char *action_in,
const int idx,
const bool fw_rule,
1863 uint8_t *action_out, uint8_t *scope_out)
1866 strlcpy(action, action_in,
sizeof(action));
1867 const char *a = action;
1868 const char *o = NULL;
1870 bool has_scope = strchr(action,
':') != NULL;
1872 char *xsaveptr = NULL;
1873 a = strtok_r(action,
":", &xsaveptr);
1874 o = strtok_r(NULL,
":", &xsaveptr);
1878 SCLogError(
"invalid protocol specification '%s'", action_in);
1882 uint8_t
flags = ActionStringToFlags(a);
1895 SCLogError(
"only accept, config, drop and reject actions allowed as primary action "
1902 SCLogError(
"accept, config, drop and reject actions not allowed as secondary action "
1908 SCLogError(
"'pass' is only supported as a secondary action for 'accept'");
1915 uint8_t scope_flags = 0;
1917 if (strcmp(o,
"packet") == 0) {
1919 }
else if (strcmp(o,
"flow") == 0) {
1922 SCLogError(
"invalid action scope '%s' in action '%s': only 'packet' and 'flow' "
1928 if (strcmp(o,
"packet") == 0) {
1930 }
else if (strcmp(o,
"hook") == 0) {
1932 }
else if (strcmp(o,
"tx") == 0) {
1934 }
else if (strcmp(o,
"flow") == 0) {
1938 "invalid action scope '%s' in action '%s': only 'packet', 'flow', 'tx' and "
1944 if (strcmp(o,
"packet") == 0) {
1947 SCLogError(
"invalid action scope '%s' in action '%s': only 'packet' allowed", o,
1952 SCLogError(
"invalid action scope '%s' in action '%s': scope only supported for actions "
1953 "'drop', 'pass' and 'reject'",
1957 if (*scope_out != 0 && *scope_out != scope_flags) {
1958 SCLogError(
"multi-action rules cannot use different action scopes");
1961 *scope_out = scope_flags;
1966 SCLogError(
"invalid action scope '%s' in action '%s': only 'packet' and 'flow' allowed",
1973 if (fw_rule && *scope_out == 0) {
1974 SCLogError(
"firewall rules require setting an explicit action scope");
1979 SCLogError(
"'accept' action only supported for firewall rules");
1982 *action_out |=
flags;
1986 static int SigParseAction(
Signature *s,
const char *action_in)
1995 FatalError(
"could not duplicate opt string");
1998 char *xsaveptr = NULL;
1999 char *a = strtok_r(copy,
",", &xsaveptr);
2005 a = strtok_r(NULL,
",", &xsaveptr);
2026 static inline int SigParseToken(
char **input,
char *output,
2027 const size_t output_size)
2029 size_t len = *input == NULL ? 0 : strlen(*input);
2035 while (
len && isblank(**input)) {
2040 char *endptr = strpbrk(*input,
" \t\n\r");
2041 if (endptr != NULL) {
2044 strlcpy(output, *input, output_size);
2061 static inline int SigParseList(
char **input,
char *output,
2062 const size_t output_size)
2065 size_t len = *input != NULL ? strlen(*input) : 0;
2071 while (
len && isblank(**input)) {
2077 for (i = 0; i <
len; i++) {
2078 char c = (*input)[i];
2081 }
else if (c ==
']') {
2083 }
else if (c ==
' ') {
2094 strlcpy(output, *input, output_size);
2095 *input = *input + i + 1;
2115 SigParseToken(&index, parser->
action,
sizeof(parser->
action));
2121 SigParseList(&index, parser->
src,
sizeof(parser->
src));
2124 SigParseList(&index, parser->
sp,
sizeof(parser->
sp));
2130 SigParseList(&index, parser->
dst,
sizeof(parser->
dst));
2133 SigParseList(&index, parser->
dp,
sizeof(parser->
dp));
2136 if (index == NULL) {
2140 while (isspace(*index) || *index ==
'(') {
2143 bool closing =
false;
2144 for (
size_t i = strlen(index); i > 0; i--) {
2145 if (index[i - 1] ==
')') {
2147 index[i - 1] =
'\0';
2148 }
else if (isspace(index[i - 1])) {
2149 index[i - 1] =
'\0';
2166 if (SigParseAction(s, parser->
action) < 0)
2169 if (SigParseProto(s, parser->
protocol) < 0)
2172 if (strcmp(parser->
direction,
"<>") == 0) {
2174 }
else if (strcmp(parser->
direction,
"=>") == 0) {
2176 SCLogError(
"transactional bidirectional rules not supported for firewall rules");
2181 }
else if (strcmp(parser->
direction,
"->") != 0) {
2182 SCLogError(
"\"%s\" is not a valid direction modifier, "
2183 "\"->\" and \"<>\" are supported.",
2210 static inline bool CheckAscii(
const char *
str)
2212 for (
size_t i = 0; i < strlen(
str); i++) {
2213 if (
str[i] < 0x20) {
2215 if (
str[i] == 0x0a ||
str[i] == 0x0d ||
str[i] == 0x09) {
2219 }
else if (
str[i] == 0x7f) {
2243 if (!SCCheckUtf8(sigstr)) {
2248 if (!CheckAscii(sigstr)) {
2249 SCLogError(
"rule contains invalid (control) characters");
2253 int ret = SigParseBasics(
de_ctx, s, sigstr, parser, addrs_direction, requires);
2260 if (strlen(parser->
opts) > 0) {
2261 size_t buffer_size = strlen(parser->
opts) + 1;
2263 char input[buffer_size];
2264 char output[buffer_size];
2265 memset(input, 0x00, buffer_size);
2266 memcpy(input, parser->
opts, strlen(parser->
opts) + 1);
2272 memset(output, 0x00, buffer_size);
2273 ret = SigParseOptions(
de_ctx, s, input, output, buffer_size, requires);
2275 memcpy(input, output, buffer_size);
2307 memset(b, 0,
sizeof(*b));
2355 static void SigMetadataFree(
Signature *s)
2362 if (s == NULL || s->
metadata == NULL) {
2369 next_mdata = mdata->
next;
2400 next_ref = ref->
next;
2454 while (sm != NULL) {
2463 while (sm != NULL) {
2484 if (s->
sp != NULL) {
2487 if (s->
dp != NULL) {
2523 const uint8_t *set = NULL;
2525 switch (pol_class) {
2527 set = fw_packet_hook_scopes;
2531 set = fw_packet_pre_flow_hook_scopes;
2532 n =
ARRAY_SIZE(fw_packet_pre_flow_hook_scopes);
2535 set = fw_app_hook_scopes;
2539 FatalError(
"Invalid firewall policy class %u", (
unsigned)pol_class);
2541 for (
size_t i = 0; i < n; i++) {
2542 if (set[i] == scope) {
2552 static void FirewallScopeHintForClass(
2555 const uint8_t *set = NULL;
2557 switch (pol_class) {
2559 set = fw_packet_hook_scopes;
2563 set = fw_packet_pre_flow_hook_scopes;
2564 n =
ARRAY_SIZE(fw_packet_pre_flow_hook_scopes);
2567 set = fw_app_hook_scopes;
2571 FatalError(
"Invalid firewall policy class %u", (
unsigned)pol_class);
2574 for (
size_t i = 0; i < n; i++) {
2575 if ((i > 0 &&
strlcat(out,
"/", out_size) >= out_size) ||
2577 FatalError(
"firewall policy scope hint too long");
2597 if (s->
alproto == *alprotos) {
2640 }
else if (i == 1) {
2695 if (!AppProtoIsValid(alproto)) {
2719 alproto = AppProtoCommon(s->
alproto, alproto);
2721 SCLogError(
"can't set rule app proto to %s: already set to %s",
2748 if (addr_match4 == NULL) {
2754 addr_match4[idx].
ip =
SCNtohl(da->ip.addr_data32[0]);
2755 addr_match4[idx].
ip2 =
SCNtohl(da->ip2.addr_data32[0]);
2774 if (addr_match6 == NULL) {
2780 addr_match6[idx].
ip[0] =
SCNtohl(da->ip.addr_data32[0]);
2781 addr_match6[idx].
ip[1] =
SCNtohl(da->ip.addr_data32[1]);
2782 addr_match6[idx].
ip[2] =
SCNtohl(da->ip.addr_data32[2]);
2783 addr_match6[idx].
ip[3] =
SCNtohl(da->ip.addr_data32[3]);
2784 addr_match6[idx].
ip2[0] =
SCNtohl(da->ip2.addr_data32[0]);
2785 addr_match6[idx].
ip2[1] =
SCNtohl(da->ip2.addr_data32[1]);
2786 addr_match6[idx].
ip2[2] =
SCNtohl(da->ip2.addr_data32[2]);
2787 addr_match6[idx].
ip2[3] =
SCNtohl(da->ip2.addr_data32[3]);
2800 static void SigBuildAddressMatchArray(
Signature *s)
2817 static int SigMatchListLen(
SigMatch *sm)
2820 for (; sm != NULL; sm = sm->
next)
2831 int len = SigMatchListLen(
head);
2837 FatalError(
"initializing the detection engine failed");
2843 for (; sm != NULL; sm = sm->
next, smd++) {
2861 SCLogDebug(
"no prefilter for SIG_FLAG_FW_HOOK_LTE sig");
2888 SCLogDebug(
"s %u: no mpm; prefilter? de_ctx->prefilter_setting %u "
2889 "s->init_data->has_possible_prefilter %s",
2903 prefilter_list =
MIN(prefilter_list, sm->
type);
2913 if (sm->
type == prefilter_list) {
2930 static bool DetectRuleValidateTable(
const Signature *s)
2939 if (kw_tables_supported != 0 && (kw_tables_supported & table_as_flag) == 0) {
2940 SCLogError(
"rule %u uses hook \"%s\", but keyword \"%s\" doesn't support this hook",
2951 SCLogError(
"rule %u is loaded as a firewall rule, but does not specify an "
2958 !FirewallScopeValidForClass(
2962 SCLogError(
"rule %u: action scope (\"%s\") is not valid for the \"pre_flow\" hook. Valid "
2972 SCLogError(
"rule %u uses action scope \"packet\" for an non-UDP app hook",
2990 SCLogError(
"rule %u: auto-accept notation (<hook) can only be used with accept:flow, "
2991 "accept:tx and accept:hook",
3000 static void DetectRuleSetTable(
Signature *s)
3033 if (!DetectFirewallRuleValidate(
de_ctx, s))
3039 static int SigValidateCheckBuffers(
3042 bool has_frame =
false;
3043 bool has_app =
false;
3044 bool has_pkt =
false;
3045 bool has_pmatch =
false;
3051 nlists += (nlists > 0);
3055 SCLogError(
"rule %u setup buffer %s but didn't add matches to it", s->
id,
3069 struct BufferVsDir {
3072 } bufdir[nlists + 1];
3073 memset(&bufdir, 0, (nlists + 1) *
sizeof(
struct BufferVsDir));
3087 if (b->
head == NULL) {
3092 has_frame |= bt->
frame;
3098 "specific matches (like dsize, flags, ttl) with stream / "
3099 "state matching by matching on app layer proto (like using "
3100 "http_* keywords).");
3104 uint32_t app_buffers_evaluated = 0;
3105 bool buffer_consumed =
false;
3106 uint32_t buffer_skip_alproto = 0;
3107 uint32_t buffer_skip_substate = 0;
3109 for (; app != NULL; app = app->
next) {
3112 app_buffers_evaluated++;
3120 SCLogDebug(
"%u:%s: for buffer %s skip engine %s alproto %s", s->
id,
3124 buffer_skip_alproto++;
3129 buffer_skip_substate++;
3135 SCLogDebug(
"%u:%s: for buffer %s skip engine %s alproto %s", s->
id,
3139 buffer_skip_alproto++;
3156 bufdir[b->
id].ts += (app->
dir == 0);
3157 bufdir[b->
id].tc += (app->
dir == 1);
3169 SCLogError(
"engine progress value doesn't match hook");
3174 buffer_consumed =
true;
3176 if (app_buffers_evaluated && !buffer_consumed) {
3177 SCLogError(
"incompatible rule conditions, skipped buffer %s, reasons: app proto %u sub "
3179 bt->
name, buffer_skip_alproto, buffer_skip_substate);
3194 if (has_pmatch && has_frame) {
3195 SCLogError(
"can't mix pure content and frame inspection");
3198 if (has_app && has_frame) {
3199 SCLogError(
"can't mix app-layer buffer and frame inspection");
3202 if (has_pkt && has_frame) {
3203 SCLogError(
"can't mix pkt buffer and frame inspection");
3207 for (
int x = 0; x < nlists; x++) {
3208 if (bufdir[x].
ts == 0 && bufdir[x].tc == 0)
3210 (*ts_excl) += (bufdir[x].ts > 0 && bufdir[x].tc == 0);
3211 (*tc_excl) += (bufdir[x].ts == 0 && bufdir[x].tc > 0);
3212 (*dir_amb) += (bufdir[x].ts > 0 && bufdir[x].tc > 0);
3221 static int SigValidatePacketStream(
const Signature *s)
3225 "tcp-stream or flow:only_stream. Invalidating signature.");
3231 static int SigConsolidateDirection(
3232 Signature *s,
const int ts_excl,
const int tc_excl,
const int dir_amb)
3235 if (!ts_excl || !tc_excl) {
3236 SCLogError(
"rule %u should use both directions, but does not", s->
id);
3240 SCLogError(
"rule %u means to use both directions, cannot have keywords ambiguous about "
3245 }
else if (ts_excl && tc_excl) {
3247 "rule %u mixes keywords with conflicting directions, a transactional rule with => "
3251 }
else if (ts_excl) {
3252 SCLogDebug(
"%u: implied rule direction is toserver", s->
id);
3254 SCLogError(
"rule %u mixes keywords with conflicting directions", s->
id);
3257 }
else if (tc_excl) {
3258 SCLogDebug(
"%u: implied rule direction is toclient", s->
id);
3260 SCLogError(
"rule %u mixes keywords with conflicting directions", s->
id);
3263 }
else if (dir_amb) {
3264 SCLogDebug(
"%u: rule direction cannot be deduced from keywords", s->
id);
3269 static void SigConsolidateTcpBuffer(
Signature *s)
3301 static bool SigInspectsFiles(
const Signature *s)
3312 static int SigValidateFileHandling(
const Signature *s)
3314 if (!SigInspectsFiles(s)) {
3321 "support file matching",
3338 SCLogError(
"No protocol support file matching");
3343 SCLogError(
"protocol HTTP2 doesn't support file name matching");
3349 static bool SigValidateEthernet(
const Signature *s)
3354 SCLogError(
"can't use ports with ether or arp rule");
3362 static bool SigValidateProtoPkthdr(
const Signature *s)
3365 SCLogError(
"protocol 'pkthdr' is for decoder-events only");
3394 static int SigValidateConsolidate(
3399 if (SigValidateFirewall(
de_ctx, s) == 0)
3402 if (SigValidatePacketStream(s) == 0) {
3406 if (!SigValidateEthernet(s)) {
3414 if (SigValidateCheckBuffers(
de_ctx, s, &ts_excl, &tc_excl, &dir_amb) == 0) {
3418 if (SigConsolidateDirection(s, ts_excl, tc_excl, dir_amb) == 0) {
3422 SigConsolidateTcpBuffer(s);
3425 DetectRuleSetTable(s);
3427 if (!SigValidateProtoPkthdr(s)) {
3431 if (!SigValidateFlowbitUse(
de_ctx, s)) {
3438 int r = SigValidateFileHandling(s);
3442 if (SigInspectsFiles(s)) {
3447 if (DetectRuleValidateTable(s) ==
false) {
3470 memset(&parser, 0x00,
sizeof(parser));
3475 if (firewall_rule) {
3492 int ret = SigParse(
de_ctx, sig, sigstr, dir, &parser,
true);
3499 }
else if (ret < 0) {
3505 SCLogError(
"Signature missing required value \"sid\".");
3510 ret = SigParse(
de_ctx, sig, sigstr, dir, &parser,
false);
3516 }
else if (ret == -2) {
3519 }
else if (ret < 0) {
3524 if (sig->
prio == -1)
3531 int override_needed = 0;
3535 override_needed = 1;
3537 override_needed = 1;
3541 override_needed = 0;
3550 if (override_needed)
3560 for ( ; sm != NULL; sm = sm->
next) {
3584 SCLogDebug(
"sig %"PRIu32
" SIG_FLAG_APPLAYER: %s, SIG_FLAG_PACKET: %s",
3588 SigBuildAddressMatchArray(sig);
3599 SigSetupPrefilter(
de_ctx, sig);
3602 if (SigValidateConsolidate(
de_ctx, sig, &parser, dir) == 0) {
3621 static bool SigHasSameSourceAndDestination(
const Signature *s)
3663 if (SigHasSameSourceAndDestination(sig)) {
3664 SCLogInfo(
"Rule with ID %u is bidirectional, but source and destination are the same, "
3665 "treating the rule as unidirectional", sig->
id);
3670 if (sig->
next == NULL) {
3700 return SigInitDo(
de_ctx, sigstr,
false);
3705 return SigInitDo(
de_ctx, sigstr,
true);
3714 static void DetectParseDupSigFreeFunc(
void *data)
3730 static uint32_t DetectParseDupSigHashFunc(
HashListTable *ht,
void *data, uint16_t datalen)
3749 static char DetectParseDupSigCompareFunc(
void *data1, uint16_t len1,
void *data2,
3755 if (sw1 == NULL || sw2 == NULL ||
3756 sw1->
s == NULL || sw2->
s == NULL)
3760 if (sw1->
s->
id == sw2->
s->
id && sw1->
s->
gid == sw2->
s->
gid)
return 1;
3776 DetectParseDupSigHashFunc,
3777 DetectParseDupSigCompareFunc,
3778 DetectParseDupSigFreeFunc);
3839 if (sw_dup == NULL) {
3852 (
void *)&sw_tmp, 0);
3866 if (sw->
s->
rev <= sw_dup->
s->
rev) {
3875 if (sw_dup->
s_prev == NULL) {
3883 sw_temp.
s = sw_dup->
s->
next;
3887 if (sw_temp.
s != NULL) {
3889 (
void *)&sw_temp, 0);
3910 sw_temp.
s = sw_dup->
s->
next;
3918 if (sw_temp.
s != NULL) {
3920 (
void *)&sw_temp, 0);
3936 (
void *)&sw_tmp, 0);
3938 if (sw_old->
s != sw_dup->
s) {
3981 int dup_sig = DetectEngineSignatureIsDuplicate(
de_ctx, sig);
3985 SCLogError(
"Duplicate signature \"%s\"", sigstr);
3987 }
else if (dup_sig == 2) {
3989 " so the older sig replaced by this new signature \"%s\"",
3994 if (sig->
next != NULL) {
4011 return (dup_sig == 0 || dup_sig == 2) ? sig : NULL;
4015 if (sig != NULL && sig->
next != NULL) {
4053 int dup_sig = DetectEngineSignatureIsDuplicate(
de_ctx, sig);
4057 SCLogError(
"Duplicate signature \"%s\"", sigstr);
4059 }
else if (dup_sig == 2) {
4061 " so the older sig replaced by this new signature \"%s\"",
4066 if (sig->
next != NULL) {
4083 return (dup_sig == 0 || dup_sig == 2) ? sig : NULL;
4087 if (sig != NULL && sig->
next != NULL) {
4100 int start_offset,
int options)
4102 *match = pcre2_match_data_create_from_pattern(parse_regex->
regex, NULL);
4104 return pcre2_match(parse_regex->
regex, (PCRE2_SPTR8)
str, strlen(
str), options, start_offset,
4105 *match, parse_regex->
context);
4112 pcre2_code_free(r->
regex);
4115 pcre2_match_context_free(r->
context);
4130 g_detect_parse_regex_list = NULL;
4139 FatalError(
"failed to alloc memory for pcre free list");
4142 r->
next = g_detect_parse_regex_list;
4143 g_detect_parse_regex_list = r;
4151 detect_parse->
regex =
4152 pcre2_compile((PCRE2_SPTR8)parse_str, PCRE2_ZERO_TERMINATED, opts, &en, &eo, NULL);
4153 if (detect_parse->
regex == NULL) {
4154 PCRE2_UCHAR errbuffer[256];
4155 pcre2_get_error_message(en, errbuffer,
sizeof(errbuffer));
4156 SCLogError(
"pcre compile of \"%s\" failed at "
4158 parse_str, en, errbuffer);
4161 detect_parse->
context = pcre2_match_context_create(NULL);
4162 if (detect_parse->
context == NULL) {
4163 SCLogError(
"pcre2 could not create match context");
4164 pcre2_code_free(detect_parse->
regex);
4165 detect_parse->
regex = NULL;
4180 if (detect_parse == NULL) {
4184 detect_parse->
regex =
4185 pcre2_compile((PCRE2_SPTR8)parse_str, PCRE2_ZERO_TERMINATED, opts, &en, &eo, NULL);
4186 if (detect_parse->
regex == NULL) {
4187 PCRE2_UCHAR errbuffer[256];
4188 pcre2_get_error_message(en, errbuffer,
sizeof(errbuffer));
4189 SCLogError(
"pcre2 compile of \"%s\" failed at "
4191 parse_str, (
int)eo, errbuffer);
4196 detect_parse->
next = g_detect_parse_regex_list;
4197 g_detect_parse_regex_list = detect_parse;
4198 return detect_parse;
4202 pcre2_match_data *match_data, uint32_t number, PCRE2_UCHAR *buffer, PCRE2_SIZE *bufflen)
4204 int r = pcre2_substring_copy_bynumber(match_data, number, buffer, bufflen);
4205 if (r == PCRE2_ERROR_UNSET) {
4214 pcre2_match_data *match_data, uint32_t number, PCRE2_UCHAR **bufferptr, PCRE2_SIZE *bufflen)
4216 int r = pcre2_substring_get_bynumber(match_data, number, bufferptr, bufflen);
4217 if (r == PCRE2_ERROR_UNSET) {
4232 static uint32_t AppPolicyHashFunc(
HashTable *ht,
void *data, uint16_t datalen)
4236 uint32_t hash =
p->alproto * 65537 +
p->sub_state * 257 +
p->progress * 5 +
4237 (
p->direction == STREAM_TOSERVER);
4238 hash ^= (hash >> 10) ^ (hash >> 20);
4242 static char AppPolicyCompareFunc(
void *data1, uint16_t datalen1,
void *data2, uint16_t datalen2)
4247 if (p1 == NULL || p2 == NULL)
4254 static void AppPolicyHashFree(
void *data)
4291 snprintf(out, out_size,
"rejectdst:%s", as);
4293 snprintf(out, out_size,
"rejectboth:%s", as);
4295 snprintf(out, out_size,
"rejectsrc:%s", as);
4298 snprintf(out, out_size,
"drop:%s", as);
4300 snprintf(out, out_size,
"accept:%s", as);
4306 strlcat(out,
",pass:flow", out_size);
4312 strlcat(out,
",alert", out_size);
4334 snprintf(msg,
sizeof(msg),
"SURICATA FW default packet policy");
4336 if (s->
msg == NULL) {
4360 snprintf(msg,
sizeof(msg),
"SURICATA FW default app policy");
4362 if (s->
msg == NULL) {
4388 if (policy_actions == NULL) {
4389 SCLogDebug(
"fw: no policy at %s", policy_name);
4394 uint8_t action_scope = 0;
4399 if (SigParseActionDo(paction->
val, idx,
true, &action, &action_scope) < 0)
4405 SCLogError(
"%s: 'config' is not a valid default policy action", policy_name);
4422 char *path = chain->path[chain->len];
4429 FatalError(
"%s: firewall YAML config path formatting failed", fmt);
4432 FatalError(
"%s: firewall YAML config path too long", path);
4435 for (uint8_t i = 0; i < chain->len; i++) {
4436 if (strcmp(chain->path[i], path) == 0)
4456 for (uint8_t i = 0; i < chain->
len; i++) {
4457 const char *path = chain->
path[i];
4459 int r = DoParsePolicy(path, &tmp);
4465 SCLogError(
"%s: policy is set but empty", path);
4468 if (!FirewallScopeValidForClass(tmp.
action_scope, pol_class)) {
4470 FirewallScopeHintForClass(pol_class, hint,
sizeof(hint));
4471 SCLogError(
"%s: action scope (\"%s\") is not valid. Valid scopes: %s", path,
4482 static void FirewallHookNameConvertUnderscoreToDash(
const char *in,
char *out,
size_t out_size)
4484 if (
strlcpy(out, in, out_size) >= out_size) {
4485 FatalError(
"%s: firewall policy config name too long", in);
4487 for (
size_t i = 0; out[i] !=
'\0'; i++) {
4499 static int DoParseAppPolicy(
const char *prefix,
const AppProto app_proto,
const uint8_t sub_state,
4500 const char *sub_state_name,
const char *hookname,
const uint8_t state,
4501 const uint8_t complete_state,
const int direction,
4505 if (app_proto_str == NULL) {
4506 SCLogError(
"Unknown app proto %u", (
unsigned)app_proto);
4512 if (hookname != NULL) {
4513 FirewallHookNameConvertUnderscoreToDash(hookname, hook,
sizeof(hook));
4518 if (sub_state_name != NULL) {
4520 FirewallHookNameConvertUnderscoreToDash(sub_state_name, sub + 1,
sizeof(sub) - 1);
4524 if (hookname != NULL) {
4526 FirewallPolicyChainAdd(&chain,
"%s.app.%s%s.%s", prefix, app_proto_str, sub, hook);
4528 if (generic_hook != NULL) {
4530 FirewallPolicyChainAdd(&chain,
"%s.app.%s%s.%s", prefix, app_proto_str, sub, generic_hook);
4533 FirewallPolicyChainAdd(&chain,
"%s.app.%s%s.default-policy", prefix, app_proto_str, sub);
4535 FirewallPolicyChainAdd(&chain,
"%s.app.%s.default-policy", prefix, app_proto_str);
4537 FirewallPolicyChainAdd(&chain,
"%s.app.default-policy", prefix);
4539 FirewallPolicyChainAdd(&chain,
"%s.default-policy", prefix);
4542 if (app_pol == NULL)
4561 FatalError(
"internal error: insert policy into hash table");
4567 return AddAppPolicySignature(app_pol);
4577 if (fw_policies == NULL)
4580 HashTableInit(512, AppPolicyHashFunc, AppPolicyCompareFunc, AppPolicyHashFree);
4608 FirewallPolicyChainAdd(&chain,
"%s.packet.%s", prefix, leaf);
4610 FirewallPolicyChainAdd(&chain,
"%s.packet.default-policy", prefix);
4612 FirewallPolicyChainAdd(&chain,
"%s.default-policy", prefix);
4618 int r = ResolveFirewallPolicy(pol, pol_class, &chain);
4623 return AddPktPolicySignature(fw_policies, pol,
id);
4631 static int DetectFirewallLoadPacketPolicies(
4634 if (DetectFirewallLoadPacketPolicy(
4637 if (DetectFirewallLoadPacketPolicy(
4640 if (DetectFirewallLoadPacketPolicy(
4663 {
ALPROTO_SSH,
"request-in-progress",
"request-banner" },
4664 {
ALPROTO_SSH,
"request-banner-wait-eol",
"request-banner" },
4665 {
ALPROTO_SSH,
"request-banner-done",
"request-kex" },
4666 {
ALPROTO_SSH,
"request-finished",
"request-session" },
4667 {
ALPROTO_SSH,
"response-in-progress",
"response-banner" },
4668 {
ALPROTO_SSH,
"response-banner-wait-eol",
"response-banner" },
4669 {
ALPROTO_SSH,
"response-banner-done",
"response-kex" },
4670 {
ALPROTO_SSH,
"response-finished",
"response-session" },
4671 {
ALPROTO_TLS,
"client-in-progress",
"client-started" },
4672 {
ALPROTO_TLS,
"client-hello-done",
"client-hello" },
4673 {
ALPROTO_TLS,
"client-cert-done",
"client-cert" },
4674 {
ALPROTO_TLS,
"client-handshake-done",
"client-data" },
4675 {
ALPROTO_TLS,
"server-in-progress",
"server-started" },
4676 {
ALPROTO_TLS,
"server-hello-done",
"server-data" },
4677 {
ALPROTO_TLS,
"server-cert-done",
"server-cert" },
4678 {
ALPROTO_TLS,
"server-handshake-done",
"server-data" },
4702 static bool FwPolicyKeyIsNonState(
const char *key)
4704 return strcmp(key,
"default-policy") == 0 || strcmp(key,
"request-started") == 0 ||
4705 strcmp(key,
"response-started") == 0 || strcmp(key,
"request-complete") == 0 ||
4706 strcmp(key,
"response-complete") == 0;
4709 static bool FwPolicyStateKeyIsKnown(
AppProto a,
const char *sub_state_name,
const char *key)
4712 if (FwPolicyKeyIsNonState(key)) {
4717 const uint8_t dirs[2] = { STREAM_TOSERVER, STREAM_TOCLIENT };
4719 if (sub_state_name == NULL) {
4720 for (
size_t d = 0; d < 2; d++) {
4722 for (uint8_t state = 0; state <= complete; state++) {
4731 FirewallHookNameConvertUnderscoreToDash(
name, dash,
sizeof(dash));
4732 if (strcmp(dash, key) == 0) {
4741 for (uint8_t s = 1; s <= max_sub_state; s++) {
4743 if (sub_name == NULL || strcmp(sub_name, sub_state_name) != 0) {
4747 for (
size_t d = 0; d < 2; d++) {
4748 for (uint8_t state = 0; state <= max_state; state++) {
4754 FirewallHookNameConvertUnderscoreToDash(
name, dash,
sizeof(dash));
4755 if (strcmp(dash, key) == 0) {
4784 static bool FirewallPolicyNodeIsMapping(
const SCConfNode *node)
4789 if (c->
name == NULL) {
4792 for (
const char *
p = c->
name; *
p;
p++) {
4793 if (*p < '0' || *p >
'9') {
4803 static bool FirewallPolicyNodeIsList(
const SCConfNode *node)
4811 if (c->
name == NULL) {
4814 for (
const char *
p = c->
name; *
p;
p++) {
4815 if (*p < '0' || *p >
'9') {
4823 static int WarnUnmatchedFirewallPolicyStateKeys(
4824 const char *prefix,
AppProto a,
const char *sub_state_name)
4827 if (
proto == NULL) {
4832 if (sub_state_name != NULL) {
4834 FirewallHookNameConvertUnderscoreToDash(sub_state_name, sub + 1,
sizeof(sub) - 1);
4838 const size_t path_len = strlen(prefix) + strlen(
proto) + strlen(sub) + 6;
4843 snprintf(path, path_len,
"%s.app.%s%s", prefix,
proto, sub);
4852 int known_wrong_keys = 0;
4854 if (c->
name == NULL) {
4858 if (sub_state_name == NULL) {
4864 bool is_sub_state_section =
false;
4865 if (c->head.tqh_first != NULL) {
4872 FirewallHookNameConvertUnderscoreToDash(sn, dash,
sizeof(dash));
4873 if (strcmp(dash, c->
name) == 0)
4874 is_sub_state_section =
true;
4877 if (is_sub_state_section)
4890 strcmp(c->
name,
"default-policy") == 0);
4891 if (consulted && FwPolicyStateKeyIsKnown(a, sub_state_name, c->
name)) {
4895 const char *hint = NULL;
4896 for (
size_t i = 0; i <
ARRAY_SIZE(g_fw_policy_state_rename_hints); i++) {
4897 if (g_fw_policy_state_rename_hints[i].
proto == a &&
4898 strcmp(c->
name, g_fw_policy_state_rename_hints[i].old_name) == 0) {
4899 hint = g_fw_policy_state_rename_hints[i].
new_name;
4906 SCLogError(
"firewall policy: key '%s' under %s matches no %s state: "
4907 "a state previously named '%s' was renamed to '%s' "
4908 "in this release - use the new name",
4912 SCLogWarning(
"firewall policy: key '%s' under %s matches no %s state "
4918 return known_wrong_keys;
4923 char prefix[96] =
"firewall.policies";
4929 if (fw_policies == NULL)
4932 if (DetectFirewallLoadPacketPolicies(fw_policies, prefix) < 0)
4935 int known_wrong_keys = 0;
4937 if (!AppProtoIsValid(a))
4943 for (uint8_t s = 1; s <= max_sub_state; s++) {
4947 if (sub_state_name == NULL)
4954 for (uint8_t state = 0; state <= max_state; state++) {
4956 sub_state_name, state);
4957 const char *state_name =
4959 BUG_ON(state_name == NULL);
4961 sub_state_name, state_name);
4962 if (DoParseAppPolicy(prefix, a, s, sub_state_name, state_name, state, max_state,
4963 STREAM_TOSERVER, fw_policies) < 0)
4967 for (uint8_t state = 0; state <= max_state; state++) {
4969 sub_state_name, state);
4970 const char *state_name =
4972 BUG_ON(state_name == NULL);
4974 sub_state_name, state_name);
4975 if (DoParseAppPolicy(prefix, a, s, sub_state_name, state_name, state, max_state,
4976 STREAM_TOCLIENT, fw_policies) < 0)
4980 known_wrong_keys += WarnUnmatchedFirewallPolicyStateKeys(prefix, a, sub_state_name);
4987 if (proto_name != NULL) {
4988 const size_t path_len = strlen(prefix) + 5 + strlen(proto_name) + 1;
4989 char *proto_path =
SCMalloc(path_len);
4990 if (proto_path != NULL) {
4991 snprintf(proto_path, path_len,
"%s.app.%s", prefix, proto_name);
4993 if (proto_node != NULL) {
5003 if (sc->
name == NULL || sc->head.tqh_first == NULL ||
5004 FirewallPolicyNodeIsList(sc) ||
5005 FwPolicyKeyIsNonState(sc->
name)) {
5008 bool known_section =
false;
5009 for (uint8_t s2 = 1; s2 <= max_sub_state; s2++) {
5015 FirewallHookNameConvertUnderscoreToDash(sn, dash,
sizeof(dash));
5016 if (strcmp(dash, sc->
name) == 0) {
5017 known_section =
true;
5021 if (!known_section) {
5022 SCLogWarning(
"firewall policy: sub-state section '%s' "
5023 "under %s matches no %s sub-state and is "
5025 sc->
name, proto_path, proto_name);
5035 known_wrong_keys += WarnUnmatchedFirewallPolicyStateKeys(prefix, a, NULL);
5037 const uint8_t complete_state_ts =
5039 a, STREAM_TOSERVER);
5040 for (uint8_t state = 0; state <= complete_state_ts; state++) {
5043 if (DoParseAppPolicy(prefix, a, 0, NULL,
name, state, complete_state_ts,
5044 STREAM_TOSERVER, fw_policies) < 0)
5047 const uint8_t complete_state_tc =
5049 a, STREAM_TOCLIENT);
5050 for (uint8_t state = 0; state <= complete_state_tc; state++) {
5053 if (DoParseAppPolicy(prefix, a, 0, NULL,
name, state, complete_state_tc,
5054 STREAM_TOCLIENT, fw_policies) < 0)
5058 known_wrong_keys += WarnUnmatchedFirewallPolicyStateKeys(prefix, a, NULL);
5061 if (known_wrong_keys) {
5065 "known to be renamed - fix the keys and retry",
5079 static int SigParseTest01 (
void)
5088 sig =
SigInit(
de_ctx,
"alert tcp 1.2.3.4 any -> !1.2.3.4 any (msg:\"SigParseTest01\"; sid:1;)");
5098 static int SigParseTest02 (
void)
5113 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;)");
5141 static int SigParseTest03 (
void)
5150 sig =
SigInit(
de_ctx,
"alert tcp 1.2.3.4 any <- !1.2.3.4 any (msg:\"SigParseTest03\"; sid:1;)");
5153 printf(
"expected NULL got sig ptr %p: ",sig);
5162 static int SigParseTest04 (
void)
5171 sig =
SigInit(
de_ctx,
"alert tcp 1.2.3.4 1024: -> !1.2.3.4 1024: (msg:\"SigParseTest04\"; sid:1;)");
5182 static int SigParseTest05 (
void)
5191 sig =
SigInit(
de_ctx,
"alert tcp 1.2.3.4 1024:65536 -> !1.2.3.4 any (msg:\"SigParseTest05\"; sid:1;)");
5195 printf(
"signature didn't fail to parse as we expected: ");
5205 static int SigParseTest06 (
void)
5214 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;)");
5218 printf(
"signature failed to parse: ");
5232 static int SigParseTest07(
void)
5254 static int SigParseTest08(
void)
5277 static int SigParseTest09(
void)
5328 static int SigParseTest10(
void)
5360 static int SigParseTest11(
void)
5371 "drop tcp any any -> any 80 (msg:\"Snort_Inline is blocking the http link\"; sid:1;) ");
5373 printf(
"sig 1 didn't parse: ");
5378 "the http link\"; sid:2;) ");
5380 printf(
"sig 2 didn't parse: ");
5394 static int SigParseTest12(
void)
5406 printf(
"sig 1 should have given an error: ");
5420 static int SigParseTest13(
void)
5432 printf(
"sig 1 invalidated: failure");
5437 printf(
"sig doesn't have stream flag set\n");
5442 printf(
"sig has packet flag set\n");
5457 static int SigParseTest14(
void)
5469 printf(
"sig 1 invalidated: failure");
5474 printf(
"sig doesn't have packet flag set\n");
5479 printf(
"sig has stream flag set\n");
5494 static int SigParseTest15(
void)
5506 printf(
"sig 1 invalidated: failure");
5511 printf(
"sig doesn't have packet flag set\n");
5516 printf(
"sig doesn't have stream flag set\n");
5531 static int SigParseTest16(
void)
5543 printf(
"sig 1 invalidated: failure");
5548 printf(
"sig doesn't have packet flag set\n");
5553 printf(
"sig doesn't have stream flag set\n");
5568 static int SigParseTest17(
void)
5580 printf(
"sig 1 invalidated: failure");
5585 printf(
"sig doesn't have packet flag set\n");
5590 printf(
"sig doesn't have stream flag set\n");
5603 static int SigParseTest18 (
void)
5611 if (
DetectEngineAppendSig(
de_ctx,
"alert tcp 1.2.3.4 any -> !1.2.3.4 any (msg:\"SigParseTest01\"; sid:99999999999999999999;)") != NULL)
5622 static int SigParseTest19 (
void)
5630 if (
DetectEngineAppendSig(
de_ctx,
"alert tcp 1.2.3.4 any -> !1.2.3.4 any (msg:\"SigParseTest01\"; sid:1; gid:99999999999999999999;)") != NULL)
5641 static int SigParseTest20 (
void)
5649 if (
DetectEngineAppendSig(
de_ctx,
"alert tcp 1.2.3.4 any -> !1.2.3.4 any (msg:\"SigParseTest01\"; sid:1; rev:99999999999999999999;)") != NULL)
5660 static int SigParseTest21 (
void)
5679 static int SigParseTest22 (
void)
5687 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)
5700 static int SigParseTest23(
void)
5715 static int SigParseBidirecTest06 (
void)
5735 static int SigParseBidirecTest07 (
void)
5755 static int SigParseBidirecTest08 (
void)
5775 static int SigParseBidirecTest09 (
void)
5795 static int SigParseBidirecTest10 (
void)
5815 static int SigParseBidirecTest11 (
void)
5835 static int SigParseBidirecTest12 (
void)
5855 static int SigParseBidirecTest13 (
void)
5874 static int SigParseBidirecTest14 (
void)
5895 static int SigTestBidirec01 (
void)
5907 if (sig->
next != NULL)
5926 static int SigTestBidirec02 (
void)
5945 if (sig->
next == NULL)
5950 if (copy->
next != NULL)
5971 static int SigTestBidirec03 (
void)
5983 const char *sigs[3];
5984 sigs[0] =
"alert tcp any any -> 192.168.1.1 any (msg:\"SigTestBidirec03 sid 1\"; sid:1;)";
5985 sigs[1] =
"alert tcp any any <> 192.168.1.1 any (msg:\"SigTestBidirec03 sid 2 bidirectional\"; sid:2;)";
5986 sigs[2] =
"alert tcp any any -> 192.168.1.1 any (msg:\"SigTestBidirec03 sid 3\"; sid:3;)";
5993 if (sig->
next == NULL)
6004 uint8_t rawpkt1_ether[] = {
6005 0x00,0x50,0x56,0xea,0x00,0xbd,0x00,0x0c,
6006 0x29,0x40,0xc8,0xb5,0x08,0x00,0x45,0x00,
6007 0x01,0xa8,0xb9,0xbb,0x40,0x00,0x40,0x06,
6008 0xe0,0xbf,0xc0,0xa8,0x1c,0x83,0xc0,0xa8,
6009 0x01,0x01,0xb9,0x0a,0x00,0x50,0x6f,0xa2,
6010 0x92,0xed,0x7b,0xc1,0xd3,0x4d,0x50,0x18,
6011 0x16,0xd0,0xa0,0x6f,0x00,0x00,0x47,0x45,
6012 0x54,0x20,0x2f,0x20,0x48,0x54,0x54,0x50,
6013 0x2f,0x31,0x2e,0x31,0x0d,0x0a,0x48,0x6f,
6014 0x73,0x74,0x3a,0x20,0x31,0x39,0x32,0x2e,
6015 0x31,0x36,0x38,0x2e,0x31,0x2e,0x31,0x0d,
6016 0x0a,0x55,0x73,0x65,0x72,0x2d,0x41,0x67,
6017 0x65,0x6e,0x74,0x3a,0x20,0x4d,0x6f,0x7a,
6018 0x69,0x6c,0x6c,0x61,0x2f,0x35,0x2e,0x30,
6019 0x20,0x28,0x58,0x31,0x31,0x3b,0x20,0x55,
6020 0x3b,0x20,0x4c,0x69,0x6e,0x75,0x78,0x20,
6021 0x78,0x38,0x36,0x5f,0x36,0x34,0x3b,0x20,
6022 0x65,0x6e,0x2d,0x55,0x53,0x3b,0x20,0x72,
6023 0x76,0x3a,0x31,0x2e,0x39,0x2e,0x30,0x2e,
6024 0x31,0x34,0x29,0x20,0x47,0x65,0x63,0x6b,
6025 0x6f,0x2f,0x32,0x30,0x30,0x39,0x30,0x39,
6026 0x30,0x32,0x31,0x37,0x20,0x55,0x62,0x75,
6027 0x6e,0x74,0x75,0x2f,0x39,0x2e,0x30,0x34,
6028 0x20,0x28,0x6a,0x61,0x75,0x6e,0x74,0x79,
6029 0x29,0x20,0x46,0x69,0x72,0x65,0x66,0x6f,
6030 0x78,0x2f,0x33,0x2e,0x30,0x2e,0x31,0x34,
6031 0x0d,0x0a,0x41,0x63,0x63,0x65,0x70,0x74,
6032 0x3a,0x20,0x74,0x65,0x78,0x74,0x2f,0x68,
6033 0x74,0x6d,0x6c,0x2c,0x61,0x70,0x70,0x6c,
6034 0x69,0x63,0x61,0x74,0x69,0x6f,0x6e,0x2f,
6035 0x78,0x68,0x74,0x6d,0x6c,0x2b,0x78,0x6d,
6036 0x6c,0x2c,0x61,0x70,0x70,0x6c,0x69,0x63,
6037 0x61,0x74,0x69,0x6f,0x6e,0x2f,0x78,0x6d,
6038 0x6c,0x3b,0x71,0x3d,0x30,0x2e,0x39,0x2c,
6039 0x2a,0x2f,0x2a,0x3b,0x71,0x3d,0x30,0x2e,
6040 0x38,0x0d,0x0a,0x41,0x63,0x63,0x65,0x70,
6041 0x74,0x2d,0x4c,0x61,0x6e,0x67,0x75,0x61,
6042 0x67,0x65,0x3a,0x20,0x65,0x6e,0x2d,0x75,
6043 0x73,0x2c,0x65,0x6e,0x3b,0x71,0x3d,0x30,
6044 0x2e,0x35,0x0d,0x0a,0x41,0x63,0x63,0x65,
6045 0x70,0x74,0x2d,0x45,0x6e,0x63,0x6f,0x64,
6046 0x69,0x6e,0x67,0x3a,0x20,0x67,0x7a,0x69,
6047 0x70,0x2c,0x64,0x65,0x66,0x6c,0x61,0x74,
6048 0x65,0x0d,0x0a,0x41,0x63,0x63,0x65,0x70,
6049 0x74,0x2d,0x43,0x68,0x61,0x72,0x73,0x65,
6050 0x74,0x3a,0x20,0x49,0x53,0x4f,0x2d,0x38,
6051 0x38,0x35,0x39,0x2d,0x31,0x2c,0x75,0x74,
6052 0x66,0x2d,0x38,0x3b,0x71,0x3d,0x30,0x2e,
6053 0x37,0x2c,0x2a,0x3b,0x71,0x3d,0x30,0x2e,
6054 0x37,0x0d,0x0a,0x4b,0x65,0x65,0x70,0x2d,
6055 0x41,0x6c,0x69,0x76,0x65,0x3a,0x20,0x33,
6056 0x30,0x30,0x0d,0x0a,0x43,0x6f,0x6e,0x6e,
6057 0x65,0x63,0x74,0x69,0x6f,0x6e,0x3a,0x20,
6058 0x6b,0x65,0x65,0x70,0x2d,0x61,0x6c,0x69,
6059 0x76,0x65,0x0d,0x0a,0x0d,0x0a };
6069 uint32_t sids[3] = {1, 2, 3};
6070 uint32_t results[3] = {1, 1, 1};
6086 static int SigTestBidirec04 (
void)
6101 sig =
DetectEngineAppendSig(
de_ctx,
"alert tcp 192.168.1.1 any <> any any (msg:\"SigTestBidirec03 sid 2 bidirectional\"; sid:2;)");
6106 if (sig->
next == NULL)
6118 if (sig->
next == NULL)
6129 uint8_t rawpkt1_ether[] = {
6130 0x00,0x50,0x56,0xea,0x00,0xbd,0x00,0x0c,
6131 0x29,0x40,0xc8,0xb5,0x08,0x00,0x45,0x00,
6132 0x01,0xa8,0xb9,0xbb,0x40,0x00,0x40,0x06,
6133 0xe0,0xbf,0xc0,0xa8,0x1c,0x83,0xc0,0xa8,
6134 0x01,0x01,0xb9,0x0a,0x00,0x50,0x6f,0xa2,
6135 0x92,0xed,0x7b,0xc1,0xd3,0x4d,0x50,0x18,
6136 0x16,0xd0,0xa0,0x6f,0x00,0x00,0x47,0x45,
6137 0x54,0x20,0x2f,0x20,0x48,0x54,0x54,0x50,
6138 0x2f,0x31,0x2e,0x31,0x0d,0x0a,0x48,0x6f,
6139 0x73,0x74,0x3a,0x20,0x31,0x39,0x32,0x2e,
6140 0x31,0x36,0x38,0x2e,0x31,0x2e,0x31,0x0d,
6141 0x0a,0x55,0x73,0x65,0x72,0x2d,0x41,0x67,
6142 0x65,0x6e,0x74,0x3a,0x20,0x4d,0x6f,0x7a,
6143 0x69,0x6c,0x6c,0x61,0x2f,0x35,0x2e,0x30,
6144 0x20,0x28,0x58,0x31,0x31,0x3b,0x20,0x55,
6145 0x3b,0x20,0x4c,0x69,0x6e,0x75,0x78,0x20,
6146 0x78,0x38,0x36,0x5f,0x36,0x34,0x3b,0x20,
6147 0x65,0x6e,0x2d,0x55,0x53,0x3b,0x20,0x72,
6148 0x76,0x3a,0x31,0x2e,0x39,0x2e,0x30,0x2e,
6149 0x31,0x34,0x29,0x20,0x47,0x65,0x63,0x6b,
6150 0x6f,0x2f,0x32,0x30,0x30,0x39,0x30,0x39,
6151 0x30,0x32,0x31,0x37,0x20,0x55,0x62,0x75,
6152 0x6e,0x74,0x75,0x2f,0x39,0x2e,0x30,0x34,
6153 0x20,0x28,0x6a,0x61,0x75,0x6e,0x74,0x79,
6154 0x29,0x20,0x46,0x69,0x72,0x65,0x66,0x6f,
6155 0x78,0x2f,0x33,0x2e,0x30,0x2e,0x31,0x34,
6156 0x0d,0x0a,0x41,0x63,0x63,0x65,0x70,0x74,
6157 0x3a,0x20,0x74,0x65,0x78,0x74,0x2f,0x68,
6158 0x74,0x6d,0x6c,0x2c,0x61,0x70,0x70,0x6c,
6159 0x69,0x63,0x61,0x74,0x69,0x6f,0x6e,0x2f,
6160 0x78,0x68,0x74,0x6d,0x6c,0x2b,0x78,0x6d,
6161 0x6c,0x2c,0x61,0x70,0x70,0x6c,0x69,0x63,
6162 0x61,0x74,0x69,0x6f,0x6e,0x2f,0x78,0x6d,
6163 0x6c,0x3b,0x71,0x3d,0x30,0x2e,0x39,0x2c,
6164 0x2a,0x2f,0x2a,0x3b,0x71,0x3d,0x30,0x2e,
6165 0x38,0x0d,0x0a,0x41,0x63,0x63,0x65,0x70,
6166 0x74,0x2d,0x4c,0x61,0x6e,0x67,0x75,0x61,
6167 0x67,0x65,0x3a,0x20,0x65,0x6e,0x2d,0x75,
6168 0x73,0x2c,0x65,0x6e,0x3b,0x71,0x3d,0x30,
6169 0x2e,0x35,0x0d,0x0a,0x41,0x63,0x63,0x65,
6170 0x70,0x74,0x2d,0x45,0x6e,0x63,0x6f,0x64,
6171 0x69,0x6e,0x67,0x3a,0x20,0x67,0x7a,0x69,
6172 0x70,0x2c,0x64,0x65,0x66,0x6c,0x61,0x74,
6173 0x65,0x0d,0x0a,0x41,0x63,0x63,0x65,0x70,
6174 0x74,0x2d,0x43,0x68,0x61,0x72,0x73,0x65,
6175 0x74,0x3a,0x20,0x49,0x53,0x4f,0x2d,0x38,
6176 0x38,0x35,0x39,0x2d,0x31,0x2c,0x75,0x74,
6177 0x66,0x2d,0x38,0x3b,0x71,0x3d,0x30,0x2e,
6178 0x37,0x2c,0x2a,0x3b,0x71,0x3d,0x30,0x2e,
6179 0x37,0x0d,0x0a,0x4b,0x65,0x65,0x70,0x2d,
6180 0x41,0x6c,0x69,0x76,0x65,0x3a,0x20,0x33,
6181 0x30,0x30,0x0d,0x0a,0x43,0x6f,0x6e,0x6e,
6182 0x65,0x63,0x74,0x69,0x6f,0x6e,0x3a,0x20,
6183 0x6b,0x65,0x65,0x70,0x2d,0x61,0x6c,0x69,
6184 0x76,0x65,0x0d,0x0a,0x0d,0x0a };
6233 static int SigParseTestNegation01 (
void)
6247 static int SigParseTestNegation02 (
void)
6253 "alert tcp any !any -> any any (msg:\"SigTest41-02 src ip is !any \"; "
6254 "classtype:misc-activity; sid:410002; rev:1;)");
6262 static int SigParseTestNegation03 (
void)
6268 "alert tcp any any -> any [80:!80] (msg:\"SigTest41-03 dst port [80:!80] \"; "
6269 "classtype:misc-activity; sid:410003; rev:1;)");
6277 static int SigParseTestNegation04 (
void)
6288 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;)");
6303 static int SigParseTestNegation05 (
void)
6314 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;)");
6329 static int SigParseTestNegation06 (
void)
6340 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;)");
6356 static int SigParseTestNegation07 (
void)
6362 de_ctx,
"alert tcp any any -> [192.168.0.2,!192.168.0.0/24] any (sid:410006;)");
6371 static int SigParseTestNegation08 (
void)
6383 "alert tcp any any -> [192.168.0.0/16,!192.168.0.0/24] any (sid:410006; rev:1;)");
6398 static int SigParseTestMpm01 (
void)
6407 sig =
SigInit(
de_ctx,
"alert tcp any any -> any any (msg:\"mpm test\"; content:\"abcd\"; sid:1;)");
6409 printf(
"sig failed to init: ");
6414 printf(
"sig doesn't have content list: ");
6429 static int SigParseTestMpm02 (
void)
6438 sig =
SigInit(
de_ctx,
"alert tcp any any -> any any (msg:\"mpm test\"; content:\"abcd\"; content:\"abcdef\"; sid:1;)");
6440 printf(
"sig failed to init: ");
6445 printf(
"sig doesn't have content list: ");
6460 static int SigParseTestAppLayerTLS01(
void)
6471 s =
SigInit(
de_ctx,
"alert tls any any -> any any (msg:\"SigParseTestAppLayerTLS01 \"; sid:410006; rev:1;)");
6473 printf(
"parsing sig failed: ");
6478 printf(
"alproto not set: ");
6495 static int SigParseTestAppLayerTLS02(
void)
6506 s =
SigInit(
de_ctx,
"alert tls any any -> any any (msg:\"SigParseTestAppLayerTLS02 \"; tls.version:1.0; sid:410006; rev:1;)");
6508 printf(
"parsing sig failed: ");
6513 printf(
"alproto not set: ");
6529 static int SigParseTestAppLayerTLS03(
void)
6536 "alert tls any any -> any any (msg:\"SigParseTestAppLayerTLS03 \"; "
6537 "tls.version:2.5; sid:410006; rev:1;)");
6543 static int SigParseTestUnbalancedQuotes01(
void)
6549 "alert http any any -> any any (msg:\"SigParseTestUnbalancedQuotes01\"; "
6550 "pcre:\"/\\/[a-z]+\\.php\\?[a-z]+?=\\d{7}&[a-z]+?=\\d{7,8}$/U\" "
6551 "flowbits:set,et.exploitkitlanding; classtype:trojan-activity; sid:2017078; rev:5;)");
6557 static int SigParseTestContentGtDsize01(
void)
6564 "dsize:21; content:\"0123456789001234567890|00 00|\"; "
6571 static int SigParseTestContentGtDsize02(
void)
6578 "dsize:21; content:\"0123456789|00 00|\"; offset:10; "
6595 static int SigParseBidirWithSameSrcAndDest01(
void)
6612 "alert tcp [1.2.3.4, 5.6.7.8] [80, 81] <> [5.6.7.8, 1.2.3.4] [81, 80] (sid:3;)");
6621 static int SigParseBidirWithSameSrcAndDest02(
void)
6629 de_ctx,
"alert tcp 1.2.3.4 any <> [1.2.3.4, 5.6.7.8, ::1] any (sid:1;)");
6636 de_ctx,
"alert tcp [1.2.3.4, ::1] [80, 81, 82] <> [1.2.3.4, ::1] [80, 81] (sid:2;)");
6643 "alert tcp [1.2.3.4, ::1, ABCD:AAAA::1] [80] <> [1.2.3.4, ::1] [80, 81] (sid:3;)");
6650 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;)");
6657 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;)");
6666 static int SigParseTestActionReject(
void)
6672 de_ctx,
"reject tcp 1.2.3.4 any -> !1.2.3.4 any (msg:\"SigParseTest01\"; sid:1;)");
6673 #ifdef HAVE_LIBNET11
6684 static int SigParseTestActionDrop(
void)
6690 de_ctx,
"drop tcp 1.2.3.4 any -> !1.2.3.4 any (msg:\"SigParseTest01\"; sid:1;)");
6698 static int SigSetMultiAppProto(
void)
6773 static int DetectSetupDirection01(
void)
6778 char *
str = (
char *)
"to_client";
6779 FAIL_IF(DetectSetupDirection(s, &
str,
true) < 0);
6784 static int DetectSetupDirection02(
void)
6788 char *
str = (
char *)
"to_server";
6789 FAIL_IF(DetectSetupDirection(s, &
str,
true) < 0);
6791 str = (
char *)
"to_client";
6792 FAIL_IF(DetectSetupDirection(s, &
str,
true) >= 0);
6798 static int DetectSetupDirection03(
void)
6802 char *
str = (
char *)
"to_client , something";
6803 FAIL_IF(DetectSetupDirection(s, &
str,
false) < 0);
6805 str = (
char *)
"to_client,something";
6806 FAIL_IF(DetectSetupDirection(s, &
str,
false) < 0);
6812 static int DetectSetupDirection04(
void)
6817 char *
str = (
char *)
"to_client_toto";
6818 FAIL_IF(DetectSetupDirection(s, &
str,
true) >= 0);
6820 str = (
char *)
"to_client_toto";
6821 FAIL_IF(DetectSetupDirection(s, &
str,
false) < 0);
6823 str = (
char *)
"to_client,something";
6825 FAIL_IF(DetectSetupDirection(s, &
str,
true) >= 0);
6862 UtRegisterTest(
"SigParseTest21 -- address with space", SigParseTest21);
6863 UtRegisterTest(
"SigParseTest22 -- address with space", SigParseTest22);
6864 UtRegisterTest(
"SigParseTest23 -- carriage return", SigParseTest23);
6879 UtRegisterTest(
"SigParseTestNegation01", SigParseTestNegation01);
6880 UtRegisterTest(
"SigParseTestNegation02", SigParseTestNegation02);
6881 UtRegisterTest(
"SigParseTestNegation03", SigParseTestNegation03);
6882 UtRegisterTest(
"SigParseTestNegation04", SigParseTestNegation04);
6883 UtRegisterTest(
"SigParseTestNegation05", SigParseTestNegation05);
6884 UtRegisterTest(
"SigParseTestNegation06", SigParseTestNegation06);
6885 UtRegisterTest(
"SigParseTestNegation07", SigParseTestNegation07);
6886 UtRegisterTest(
"SigParseTestNegation08", SigParseTestNegation08);
6889 UtRegisterTest(
"SigParseTestAppLayerTLS01", SigParseTestAppLayerTLS01);
6890 UtRegisterTest(
"SigParseTestAppLayerTLS02", SigParseTestAppLayerTLS02);
6891 UtRegisterTest(
"SigParseTestAppLayerTLS03", SigParseTestAppLayerTLS03);
6892 UtRegisterTest(
"SigParseTestUnbalancedQuotes01", SigParseTestUnbalancedQuotes01);
6895 SigParseTestContentGtDsize01);
6897 SigParseTestContentGtDsize02);
6900 SigParseBidirWithSameSrcAndDest01);
6902 SigParseBidirWithSameSrcAndDest02);
6903 UtRegisterTest(
"SigParseTestActionReject", SigParseTestActionReject);
6904 UtRegisterTest(
"SigParseTestActionDrop", SigParseTestActionDrop);
6908 UtRegisterTest(
"DetectSetupDirection01", DetectSetupDirection01);
6909 UtRegisterTest(
"DetectSetupDirection02", DetectSetupDirection02);
6910 UtRegisterTest(
"DetectSetupDirection03", DetectSetupDirection03);
6911 UtRegisterTest(
"DetectSetupDirection04", DetectSetupDirection04);