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)
754 if (sm_last == NULL || sm_new->
idx > sm_last->
idx)
762 if (sm_last == NULL || sm_new->
idx > sm_last->
idx)
769 static void SigMatchTransferSigMatchAcrossLists(
SigMatch *sm,
775 if (sm->
prev != NULL)
777 if (sm->
next != NULL)
780 if (sm == *src_sm_list)
781 *src_sm_list = sm->
next;
782 if (sm == *src_sm_list_tail)
783 *src_sm_list_tail = sm->
prev;
785 if (*dst_sm_list == NULL) {
787 *dst_sm_list_tail = sm;
795 *dst_sm_list_tail = sm;
822 SCLogError(
"Unable to find the sm in any of the "
836 static int DetectSetupDirection(
Signature *s,
char **
str,
bool only_dir)
839 if (strncmp(*
str,
"to_client", strlen(
"to_client")) == 0) {
840 *
str += strlen(
"to_client");
842 while (**
str && isblank(**
str)) {
848 SCLogError(
"unknown option: only accepts to_server or to_client");
858 while (**
str && isblank(**
str)) {
870 }
else if (strncmp(*
str,
"to_server", strlen(
"to_server")) == 0) {
871 *
str += strlen(
"to_server");
873 while (**
str && isblank(**
str)) {
879 SCLogError(
"unknown option: only accepts to_server or to_client");
889 while (**
str && isblank(**
str)) {
901 }
else if (only_dir) {
902 SCLogError(
"unknown option: only accepts to_server or to_client");
909 size_t output_size,
bool requires)
912 char *optname = NULL;
913 char *optvalue = NULL;
916 while (isblank(*optstr)) {
921 char *optend = optstr;
923 optend = strchr(optend,
';');
924 if (optend == NULL) {
928 else if (optend > optstr && *(optend -1 ) ==
'\\') {
937 char *optvalptr = strchr(optstr,
':');
939 *(optvalptr++) =
'\0';
942 for (
size_t i = strlen(optvalptr); i > 0; i--) {
943 if (isblank(optvalptr[i - 1])) {
944 optvalptr[i - 1] =
'\0';
950 optvalue = optvalptr;
954 for (
size_t i = strlen(optstr); i > 0; i--) {
955 if (isblank(optstr[i - 1])) {
956 optstr[i - 1] =
'\0';
965 bool requires_only = strcasecmp(optname,
"requires") == 0 || strcasecmp(optname,
"sid") == 0;
966 if ((requires && !requires_only) || (!requires && requires_only)) {
971 st = SigTableGet(optname);
972 if (st == NULL || st->
Setup == NULL) {
973 SCLogError(
"unknown rule keyword '%s'.", optname);
978 if (optvalue == NULL || strlen(optvalue) == 0) {
980 "invalid formatting or malformed option to %s keyword: '%s'", optname, optstr);
984 if (optvalue && strlen(optvalue)) {
985 SCLogError(
"unexpected option to %s keyword: '%s'", optname, optstr);
995 #define URL "https://suricata.io/our-story/deprecation-policy/"
998 "and will be removed soon. See %s",
1002 "and will be removed soon. Use '%s' instead. "
1009 SCLogError(
"keyword \'%s\' is not supported with firewall rules", optname);
1014 SCLogError(
"keyword \'%s\' is not supported in firewall mode", optname);
1021 SCLogError(
"keyword \'%s\' is not supported in threat detection rules with firewall mode",
1028 if (optvalue != NULL && strlen(optvalue) > 0) {
1029 size_t ovlen = strlen(optvalue);
1030 char *ptr = optvalue;
1040 SCLogError(
"invalid formatting or malformed option to %s keyword: \'%s\'", optname,
1046 SCLogWarning(
"keyword \'%s\' has not been tested for firewall rules", optname);
1063 SCLogError(
"invalid formatting or malformed option to %s keyword: \'%s\'", optname,
1069 SCLogError(
"invalid formatting to %s keyword: "
1070 "value must be double quoted \'%s\'",
1076 && ovlen && *ptr ==
'"')
1078 for (; ovlen > 0; ovlen--) {
1079 if (isblank(ptr[ovlen - 1])) {
1080 ptr[ovlen - 1] =
'\0';
1085 if (ovlen && ptr[ovlen - 1] !=
'"') {
1086 SCLogError(
"bad option value formatting (possible missing semicolon) "
1087 "for keyword %s: \'%s\'",
1095 ptr[ovlen - 1] =
'\0';
1100 "for keyword %s: \'%s\'",
1107 "quotes on %s keyword that doesn't support them: \'%s\'", optname, optstr);
1125 if (setup_ret < 0) {
1129 if (setup_ret == -2) {
1141 if (strlen(optend) > 0) {
1142 strlcpy(output, optend, output_size);
1157 Signature *s,
const char *addrstr,
char flag)
1159 SCLogDebug(
"Address Group \"%s\" to be parsed now", addrstr);
1163 if (strcasecmp(addrstr,
"any") == 0)
1171 if (strcasecmp(addrstr,
"any") == 0)
1186 static bool IsBuiltIn(
const char *n)
1188 return strcmp(n,
"request_started") == 0 || strcmp(n,
"response_started") == 0 ||
1189 strcmp(n,
"request_complete") == 0 || strcmp(n,
"response_complete") == 0;
1197 const uint8_t state,
const uint8_t complete_state,
const int direction)
1200 return (direction == STREAM_TOSERVER) ?
"request-started" :
"response-started";
1201 if (state == complete_state)
1202 return (direction == STREAM_TOSERVER) ?
"request-complete" :
"response-complete";
1218 SCLogDebug(
"alproto %u/%s", a, alproto_name);
1222 SCLogDebug(
"%s: max sub state for %u is %u", alproto_name, a, max_sub_state);
1223 for (uint8_t s = 1; s <= max_sub_state; s++) {
1227 if (sub_state_name == NULL)
1230 char ts_tx_started[64];
1231 snprintf(ts_tx_started,
sizeof(ts_tx_started),
"%s:%s:request_started:generic",
1232 alproto_name, sub_state_name);
1236 char tc_tx_started[64];
1237 snprintf(tc_tx_started,
sizeof(tc_tx_started),
"%s:%s:response_started:generic",
1238 alproto_name, sub_state_name);
1242 char ts_tx_complete[64];
1243 snprintf(ts_tx_complete,
sizeof(ts_tx_complete),
"%s:%s:request_complete:generic",
1244 alproto_name, sub_state_name);
1248 char tc_tx_complete[64];
1249 snprintf(tc_tx_complete,
sizeof(tc_tx_complete),
"%s:%s:response_complete:generic",
1250 alproto_name, sub_state_name);
1255 for (uint8_t state = 0; state <= max_state; state++) {
1256 const char *state_name =
1258 BUG_ON(state_name == NULL);
1260 if (state_name != NULL && !IsBuiltIn(state_name)) {
1262 snprintf(list_name,
sizeof(list_name),
"%s:%s:%s:generic", alproto_name,
1263 sub_state_name, state_name);
1269 for (uint8_t state = 0; state <= max_state; state++) {
1270 const char *state_name =
1272 BUG_ON(state_name == NULL);
1273 if (state_name != NULL && !IsBuiltIn(state_name)) {
1275 snprintf(list_name,
sizeof(list_name),
"%s:%s:%s:generic", alproto_name,
1276 sub_state_name, state_name);
1283 const uint8_t max_progress_ts =
1285 const uint8_t max_progress_tc =
1288 char ts_tx_started[64];
1289 snprintf(ts_tx_started,
sizeof(ts_tx_started),
"%s:request_started:generic",
1293 SCLogDebug(
"- hook %s:%s list %s (%u)", alproto_name,
"request_name", ts_tx_started,
1294 (uint32_t)strlen(ts_tx_started));
1296 char tc_tx_started[64];
1297 snprintf(tc_tx_started,
sizeof(tc_tx_started),
"%s:response_started:generic",
1301 SCLogDebug(
"- hook %s:%s list %s (%u)", alproto_name,
"response_name", tc_tx_started,
1302 (uint32_t)strlen(tc_tx_started));
1304 char ts_tx_complete[64];
1305 snprintf(ts_tx_complete,
sizeof(ts_tx_complete),
"%s:request_complete:generic",
1309 SCLogDebug(
"- hook %s:%s list %s (%u)", alproto_name,
"request_name", ts_tx_complete,
1310 (uint32_t)strlen(ts_tx_complete));
1312 char tc_tx_complete[64];
1313 snprintf(tc_tx_complete,
sizeof(tc_tx_complete),
"%s:response_complete:generic",
1317 SCLogDebug(
"- hook %s:%s list %s (%u)", alproto_name,
"response_name", tc_tx_complete,
1318 (uint32_t)strlen(tc_tx_complete));
1320 for (uint8_t
p = 0;
p <= max_progress_ts;
p++) {
1322 IPPROTO_TCP , a,
p, STREAM_TOSERVER);
1323 if (
name != NULL && !IsBuiltIn(
name)) {
1325 snprintf(list_name,
sizeof(list_name),
"%s:%s:generic", alproto_name,
name);
1326 SCLogDebug(
"- hook %s:%s list %s (%u)", alproto_name,
name, list_name,
1327 (uint32_t)strlen(list_name));
1333 for (uint8_t
p = 0;
p <= max_progress_tc;
p++) {
1335 IPPROTO_TCP , a,
p, STREAM_TOCLIENT);
1336 if (
name != NULL && !IsBuiltIn(
name)) {
1338 snprintf(list_name,
sizeof(list_name),
"%s:%s:generic", alproto_name,
name);
1339 SCLogDebug(
"- hook %s:%s list %s (%u)", alproto_name,
name, list_name,
1340 (uint32_t)strlen(list_name));
1367 if (strcmp(
str,
"flow_start") == 0) {
1369 }
else if (strcmp(
str,
"pre_flow") == 0) {
1371 }
else if (strcmp(
str,
"pre_stream") == 0) {
1373 }
else if (strcmp(
str,
"all") == 0) {
1386 return "flow_start";
1390 return "pre_stream";
1402 .t.pkt.ph = HookPktFromString(hook_str),
1410 static int SigParseProtoHookPkt(
Signature *s,
const char *proto_hook,
const char *
p,
const char *h)
1423 SCLogDebug(
"protocol:%s hook:%s: type:%s parsed hook:%s",
p, h,
1433 .t.app.alproto = alproto,
1434 .t.app.sub_state = sub_state,
1435 .t.app.app_progress = progress,
1443 static int SigParseProtoHookApp(
1444 Signature *s,
const char *proto_hook,
const char *
p,
const char *in_h)
1447 char generic_hook_name[256];
1448 strlcpy(hook, in_h,
sizeof(hook));
1449 const char *h = hook;
1450 const char *t = NULL;
1451 uint8_t sub_state = 0;
1453 bool has_type = strchr(hook,
':') != NULL;
1456 t = strtok_r(hook,
":", &rem);
1460 if (h == NULL || strlen(h) == 0) {
1461 SCLogError(
"invalid hook specification '%s'", hook);
1466 if (strlen(t) == 0) {
1467 SCLogError(
"invalid tx type specification '%s'", hook);
1470 if (strcmp(
p,
"http2") == 0 || strcmp(
p,
"doh2") == 0) {
1471 if (strcmp(t,
"stream") == 0) {
1472 sub_state = HTTP2TxTypeStream;
1473 }
else if (strcmp(t,
"global") == 0) {
1474 sub_state = HTTP2TxTypeGlobal;
1476 SCLogError(
"unknown %s tx type specification '%s': valid values are 'stream' "
1482 SCLogError(
"sub states currently only supported for http2 and doh2");
1488 SCLogError(
"hook '%s': the lower bound form '<' is only allowed for firewall "
1499 if (strcmp(h,
"request_started") == 0) {
1503 }
else if (strcmp(h,
"response_started") == 0) {
1507 }
else if (strcmp(h,
"request_complete") == 0) {
1510 }
else if (strcmp(h,
"response_complete") == 0) {
1514 const int8_t progress_ts =
1516 if (progress_ts >= 0) {
1521 s->
alproto, sub_state, h, STREAM_TOCLIENT);
1522 if (progress_tc < 0) {
1529 snprintf(generic_hook_name,
sizeof(generic_hook_name),
"%s:%s:%s:generic",
p, t, h);
1533 "protocol %s requires a substate specification: %s:<sub_state>:%s",
p,
p, hook);
1540 SCLogError(
"hook '%s': the lower bound form '<' is only allowed for firewall "
1550 if (strcmp(h,
"request_started") == 0) {
1554 }
else if (strcmp(h,
"response_started") == 0) {
1558 }
else if (strcmp(h,
"request_complete") == 0) {
1562 }
else if (strcmp(h,
"response_complete") == 0) {
1568 IPPROTO_TCP , s->
alproto, h, STREAM_TOSERVER);
1569 if (progress_ts >= 0) {
1577 IPPROTO_TCP , s->
alproto, h, STREAM_TOCLIENT);
1585 snprintf(generic_hook_name,
sizeof(generic_hook_name),
"%s:%s:generic",
p, h);
1587 SCLogDebug(
"generic_hook_name %s", generic_hook_name);
1591 SCLogError(
"no list registered as %s for hook %s", generic_hook_name, proto_hook);
1596 SCLogDebug(
"protocol:%s hook:%s: type:%s alproto:%u hook:%d",
p, h,
1608 printf(
"=========Supported Rule Protocols=========\n");
1625 static int SigParseProto(
Signature *s,
const char *protostr)
1628 if (strlen(protostr) >= 64)
1634 const char *h = NULL;
1636 bool has_hook = strchr(
proto,
':') != NULL;
1639 p = strtok_r(
proto,
":", &rem);
1643 if (
p == NULL || strlen(
p) == 0) {
1658 if (strlen(h) == 0) {
1662 if (SigParseProtoHookApp(s, protostr,
p, h) < 0) {
1663 SCLogError(
"protocol \"%s\" does not support hook \"%s\"",
p, h);
1670 "in a signature. Either detection for this protocol "
1671 "is not yet supported OR detection has been disabled for "
1672 "protocol through the yaml option "
1673 "app-layer.protocols.%s.detection-enabled",
1677 }
else if (h != NULL) {
1678 SCLogDebug(
"non-app-layer rule with %s:%s",
p, h);
1680 if (SigParseProtoHookPkt(s, protostr,
p, h) < 0) {
1681 SCLogError(
"protocol \"%s\" does not support hook \"%s\"",
p, h);
1710 Signature *s,
const char *portstr,
char flag)
1716 SCLogDebug(
"Port group \"%s\" to be parsed", portstr);
1719 if (strcasecmp(portstr,
"any") == 0)
1723 }
else if (flag == 1) {
1724 if (strcasecmp(portstr,
"any") == 0)
1739 static int SigParseActionRejectValidate(
const char *action)
1741 #ifdef HAVE_LIBNET11
1742 #if defined HAVE_LIBCAP_NG && !defined HAVE_LIBNET_CAPABILITIES
1745 "incompatible with POSIX based capabilities with privs dropping. "
1746 "For rejects to work, run as root/super user.");
1752 "required for action \"%s\" but is not compiled into Suricata",
1762 static uint8_t ActionStringToFlags(
const char *action)
1764 if (strcasecmp(action,
"alert") == 0) {
1766 }
else if (strcasecmp(action,
"drop") == 0) {
1768 }
else if (strcasecmp(action,
"pass") == 0) {
1770 }
else if (strcasecmp(action,
"reject") == 0 ||
1771 strcasecmp(action,
"rejectsrc") == 0)
1773 if (!(SigParseActionRejectValidate(action)))
1776 }
else if (strcasecmp(action,
"rejectdst") == 0) {
1777 if (!(SigParseActionRejectValidate(action)))
1780 }
else if (strcasecmp(action,
"rejectboth") == 0) {
1781 if (!(SigParseActionRejectValidate(action)))
1784 }
else if (strcasecmp(action,
"config") == 0) {
1786 }
else if (strcasecmp(action,
"accept") == 0) {
1789 SCLogError(
"An invalid action \"%s\" was given", action);
1805 static int SigParseActionDo(
const char *action_in,
const int idx,
const bool fw_rule,
1806 uint8_t *action_out, uint8_t *scope_out)
1809 strlcpy(action, action_in,
sizeof(action));
1810 const char *a = action;
1811 const char *o = NULL;
1813 bool has_scope = strchr(action,
':') != NULL;
1815 char *xsaveptr = NULL;
1816 a = strtok_r(action,
":", &xsaveptr);
1817 o = strtok_r(NULL,
":", &xsaveptr);
1821 SCLogError(
"invalid protocol specification '%s'", action_in);
1825 uint8_t
flags = ActionStringToFlags(a);
1838 SCLogError(
"only accept, config, drop and reject actions allowed as primary action "
1845 SCLogError(
"accept, config, drop and reject actions not allowed as secondary action "
1851 SCLogError(
"'pass' is only supported as a secondary action for 'accept'");
1858 uint8_t scope_flags = 0;
1860 if (strcmp(o,
"packet") == 0) {
1862 }
else if (strcmp(o,
"flow") == 0) {
1865 SCLogError(
"invalid action scope '%s' in action '%s': only 'packet' and 'flow' "
1871 if (strcmp(o,
"packet") == 0) {
1873 }
else if (strcmp(o,
"hook") == 0) {
1875 }
else if (strcmp(o,
"tx") == 0) {
1877 }
else if (strcmp(o,
"flow") == 0) {
1881 "invalid action scope '%s' in action '%s': only 'packet', 'flow', 'tx' and "
1887 if (strcmp(o,
"packet") == 0) {
1890 SCLogError(
"invalid action scope '%s' in action '%s': only 'packet' allowed", o,
1895 SCLogError(
"invalid action scope '%s' in action '%s': scope only supported for actions "
1896 "'drop', 'pass' and 'reject'",
1900 if (*scope_out != 0 && *scope_out != scope_flags) {
1901 SCLogError(
"multi-action rules cannot use different action scopes");
1904 *scope_out = scope_flags;
1909 SCLogError(
"invalid action scope '%s' in action '%s': only 'packet' and 'flow' allowed",
1916 if (fw_rule && *scope_out == 0) {
1917 SCLogError(
"firewall rules require setting an explicit action scope");
1922 SCLogError(
"'accept' action only supported for firewall rules");
1925 *action_out |=
flags;
1929 static int SigParseAction(
Signature *s,
const char *action_in)
1938 FatalError(
"could not duplicate opt string");
1941 char *xsaveptr = NULL;
1942 char *a = strtok_r(copy,
",", &xsaveptr);
1948 a = strtok_r(NULL,
",", &xsaveptr);
1969 static inline int SigParseToken(
char **input,
char *output,
1970 const size_t output_size)
1972 size_t len = *input == NULL ? 0 : strlen(*input);
1978 while (
len && isblank(**input)) {
1983 char *endptr = strpbrk(*input,
" \t\n\r");
1984 if (endptr != NULL) {
1987 strlcpy(output, *input, output_size);
2004 static inline int SigParseList(
char **input,
char *output,
2005 const size_t output_size)
2008 size_t len = *input != NULL ? strlen(*input) : 0;
2014 while (
len && isblank(**input)) {
2020 for (i = 0; i <
len; i++) {
2021 char c = (*input)[i];
2024 }
else if (c ==
']') {
2026 }
else if (c ==
' ') {
2037 strlcpy(output, *input, output_size);
2038 *input = *input + i + 1;
2058 SigParseToken(&index, parser->
action,
sizeof(parser->
action));
2064 SigParseList(&index, parser->
src,
sizeof(parser->
src));
2067 SigParseList(&index, parser->
sp,
sizeof(parser->
sp));
2073 SigParseList(&index, parser->
dst,
sizeof(parser->
dst));
2076 SigParseList(&index, parser->
dp,
sizeof(parser->
dp));
2079 if (index == NULL) {
2083 while (isspace(*index) || *index ==
'(') {
2086 bool closing =
false;
2087 for (
size_t i = strlen(index); i > 0; i--) {
2088 if (index[i - 1] ==
')') {
2090 index[i - 1] =
'\0';
2091 }
else if (isspace(index[i - 1])) {
2092 index[i - 1] =
'\0';
2109 if (SigParseAction(s, parser->
action) < 0)
2112 if (SigParseProto(s, parser->
protocol) < 0)
2115 if (strcmp(parser->
direction,
"<>") == 0) {
2117 }
else if (strcmp(parser->
direction,
"=>") == 0) {
2119 SCLogError(
"transactional bidirectional rules not supported for firewall rules");
2124 }
else if (strcmp(parser->
direction,
"->") != 0) {
2125 SCLogError(
"\"%s\" is not a valid direction modifier, "
2126 "\"->\" and \"<>\" are supported.",
2153 static inline bool CheckAscii(
const char *
str)
2155 for (
size_t i = 0; i < strlen(
str); i++) {
2156 if (
str[i] < 0x20) {
2158 if (
str[i] == 0x0a ||
str[i] == 0x0d ||
str[i] == 0x09) {
2162 }
else if (
str[i] == 0x7f) {
2186 if (!SCCheckUtf8(sigstr)) {
2191 if (!CheckAscii(sigstr)) {
2192 SCLogError(
"rule contains invalid (control) characters");
2196 int ret = SigParseBasics(
de_ctx, s, sigstr, parser, addrs_direction, requires);
2203 if (strlen(parser->
opts) > 0) {
2204 size_t buffer_size = strlen(parser->
opts) + 1;
2206 char input[buffer_size];
2207 char output[buffer_size];
2208 memset(input, 0x00, buffer_size);
2209 memcpy(input, parser->
opts, strlen(parser->
opts) + 1);
2215 memset(output, 0x00, buffer_size);
2216 ret = SigParseOptions(
de_ctx, s, input, output, buffer_size, requires);
2218 memcpy(input, output, buffer_size);
2250 memset(b, 0,
sizeof(*b));
2298 static void SigMetadataFree(
Signature *s)
2305 if (s == NULL || s->
metadata == NULL) {
2312 next_mdata = mdata->
next;
2343 next_ref = ref->
next;
2397 while (sm != NULL) {
2406 while (sm != NULL) {
2427 if (s->
sp != NULL) {
2430 if (s->
dp != NULL) {
2466 const uint8_t *set = NULL;
2468 switch (pol_class) {
2470 set = fw_packet_hook_scopes;
2474 set = fw_packet_pre_flow_hook_scopes;
2475 n =
ARRAY_SIZE(fw_packet_pre_flow_hook_scopes);
2478 set = fw_app_hook_scopes;
2482 FatalError(
"Invalid firewall policy class %u", (
unsigned)pol_class);
2484 for (
size_t i = 0; i < n; i++) {
2485 if (set[i] == scope) {
2495 static void FirewallScopeHintForClass(
2498 const uint8_t *set = NULL;
2500 switch (pol_class) {
2502 set = fw_packet_hook_scopes;
2506 set = fw_packet_pre_flow_hook_scopes;
2507 n =
ARRAY_SIZE(fw_packet_pre_flow_hook_scopes);
2510 set = fw_app_hook_scopes;
2514 FatalError(
"Invalid firewall policy class %u", (
unsigned)pol_class);
2517 for (
size_t i = 0; i < n; i++) {
2518 if ((i > 0 &&
strlcat(out,
"/", out_size) >= out_size) ||
2520 FatalError(
"firewall policy scope hint too long");
2540 if (s->
alproto == *alprotos) {
2583 }
else if (i == 1) {
2615 if (!AppProtoIsValid(alproto)) {
2639 alproto = AppProtoCommon(s->
alproto, alproto);
2641 SCLogError(
"can't set rule app proto to %s: already set to %s",
2668 if (addr_match4 == NULL) {
2674 addr_match4[idx].
ip =
SCNtohl(da->ip.addr_data32[0]);
2675 addr_match4[idx].
ip2 =
SCNtohl(da->ip2.addr_data32[0]);
2694 if (addr_match6 == NULL) {
2700 addr_match6[idx].
ip[0] =
SCNtohl(da->ip.addr_data32[0]);
2701 addr_match6[idx].
ip[1] =
SCNtohl(da->ip.addr_data32[1]);
2702 addr_match6[idx].
ip[2] =
SCNtohl(da->ip.addr_data32[2]);
2703 addr_match6[idx].
ip[3] =
SCNtohl(da->ip.addr_data32[3]);
2704 addr_match6[idx].
ip2[0] =
SCNtohl(da->ip2.addr_data32[0]);
2705 addr_match6[idx].
ip2[1] =
SCNtohl(da->ip2.addr_data32[1]);
2706 addr_match6[idx].
ip2[2] =
SCNtohl(da->ip2.addr_data32[2]);
2707 addr_match6[idx].
ip2[3] =
SCNtohl(da->ip2.addr_data32[3]);
2720 static void SigBuildAddressMatchArray(
Signature *s)
2737 static int SigMatchListLen(
SigMatch *sm)
2740 for (; sm != NULL; sm = sm->
next)
2751 int len = SigMatchListLen(
head);
2757 FatalError(
"initializing the detection engine failed");
2763 for (; sm != NULL; sm = sm->
next, smd++) {
2781 SCLogDebug(
"no prefilter for SIG_FLAG_FW_HOOK_LTE sig");
2808 SCLogDebug(
"s %u: no mpm; prefilter? de_ctx->prefilter_setting %u "
2809 "s->init_data->has_possible_prefilter %s",
2823 prefilter_list =
MIN(prefilter_list, sm->
type);
2833 if (sm->
type == prefilter_list) {
2850 static bool DetectRuleValidateTable(
const Signature *s)
2859 if (kw_tables_supported != 0 && (kw_tables_supported & table_as_flag) == 0) {
2860 SCLogError(
"rule %u uses hook \"%s\", but keyword \"%s\" doesn't support this hook",
2871 SCLogError(
"rule %u is loaded as a firewall rule, but does not specify an "
2878 !FirewallScopeValidForClass(
2882 SCLogError(
"rule %u: action scope (\"%s\") is not valid for the \"pre_flow\" hook. Valid "
2892 SCLogError(
"rule %u uses action scope \"packet\" for an non-UDP app hook",
2910 SCLogError(
"rule %u: auto-accept notation (<hook) can only be used with accept:flow, "
2911 "accept:tx and accept:hook",
2920 static void DetectRuleSetTable(
Signature *s)
2953 if (!DetectFirewallRuleValidate(
de_ctx, s))
2959 static int SigValidateCheckBuffers(
2962 bool has_frame =
false;
2963 bool has_app =
false;
2964 bool has_pkt =
false;
2965 bool has_pmatch =
false;
2971 nlists += (nlists > 0);
2975 SCLogError(
"rule %u setup buffer %s but didn't add matches to it", s->
id,
2989 struct BufferVsDir {
2992 } bufdir[nlists + 1];
2993 memset(&bufdir, 0, (nlists + 1) *
sizeof(
struct BufferVsDir));
3007 if (b->
head == NULL) {
3012 has_frame |= bt->
frame;
3018 "specific matches (like dsize, flags, ttl) with stream / "
3019 "state matching by matching on app layer proto (like using "
3020 "http_* keywords).");
3024 uint32_t app_buffers_evaluated = 0;
3025 bool buffer_consumed =
false;
3026 uint32_t buffer_skip_alproto = 0;
3027 uint32_t buffer_skip_substate = 0;
3029 for (; app != NULL; app = app->
next) {
3032 app_buffers_evaluated++;
3040 SCLogDebug(
"%u:%s: for buffer %s skip engine %s alproto %s", s->
id,
3044 buffer_skip_alproto++;
3049 buffer_skip_substate++;
3055 SCLogDebug(
"%u:%s: for buffer %s skip engine %s alproto %s", s->
id,
3059 buffer_skip_alproto++;
3076 bufdir[b->
id].ts += (app->
dir == 0);
3077 bufdir[b->
id].tc += (app->
dir == 1);
3089 SCLogError(
"engine progress value doesn't match hook");
3094 buffer_consumed =
true;
3096 if (app_buffers_evaluated && !buffer_consumed) {
3097 SCLogError(
"incompatible rule conditions, skipped buffer %s, reasons: app proto %u sub "
3099 bt->
name, buffer_skip_alproto, buffer_skip_substate);
3114 if (has_pmatch && has_frame) {
3115 SCLogError(
"can't mix pure content and frame inspection");
3118 if (has_app && has_frame) {
3119 SCLogError(
"can't mix app-layer buffer and frame inspection");
3122 if (has_pkt && has_frame) {
3123 SCLogError(
"can't mix pkt buffer and frame inspection");
3127 for (
int x = 0; x < nlists; x++) {
3128 if (bufdir[x].
ts == 0 && bufdir[x].tc == 0)
3130 (*ts_excl) += (bufdir[x].ts > 0 && bufdir[x].tc == 0);
3131 (*tc_excl) += (bufdir[x].ts == 0 && bufdir[x].tc > 0);
3132 (*dir_amb) += (bufdir[x].ts > 0 && bufdir[x].tc > 0);
3141 static int SigValidatePacketStream(
const Signature *s)
3145 "tcp-stream or flow:only_stream. Invalidating signature.");
3151 static int SigConsolidateDirection(
3152 Signature *s,
const int ts_excl,
const int tc_excl,
const int dir_amb)
3155 if (!ts_excl || !tc_excl) {
3156 SCLogError(
"rule %u should use both directions, but does not", s->
id);
3160 SCLogError(
"rule %u means to use both directions, cannot have keywords ambiguous about "
3165 }
else if (ts_excl && tc_excl) {
3167 "rule %u mixes keywords with conflicting directions, a transactional rule with => "
3171 }
else if (ts_excl) {
3172 SCLogDebug(
"%u: implied rule direction is toserver", s->
id);
3174 SCLogError(
"rule %u mixes keywords with conflicting directions", s->
id);
3177 }
else if (tc_excl) {
3178 SCLogDebug(
"%u: implied rule direction is toclient", s->
id);
3180 SCLogError(
"rule %u mixes keywords with conflicting directions", s->
id);
3183 }
else if (dir_amb) {
3184 SCLogDebug(
"%u: rule direction cannot be deduced from keywords", s->
id);
3189 static void SigConsolidateTcpBuffer(
Signature *s)
3221 static bool SigInspectsFiles(
const Signature *s)
3232 static int SigValidateFileHandling(
const Signature *s)
3234 if (!SigInspectsFiles(s)) {
3241 "support file matching",
3258 SCLogError(
"No protocol support file matching");
3263 SCLogError(
"protocol HTTP2 doesn't support file name matching");
3269 static bool SigValidateEthernet(
const Signature *s)
3274 SCLogError(
"can't use ports with ether or arp rule");
3282 static bool SigValidateProtoPkthdr(
const Signature *s)
3285 SCLogError(
"protocol 'pkthdr' is for decoder-events only");
3314 static int SigValidateConsolidate(
3319 if (SigValidateFirewall(
de_ctx, s) == 0)
3322 if (SigValidatePacketStream(s) == 0) {
3326 if (!SigValidateEthernet(s)) {
3334 if (SigValidateCheckBuffers(
de_ctx, s, &ts_excl, &tc_excl, &dir_amb) == 0) {
3338 if (SigConsolidateDirection(s, ts_excl, tc_excl, dir_amb) == 0) {
3342 SigConsolidateTcpBuffer(s);
3345 DetectRuleSetTable(s);
3347 if (!SigValidateProtoPkthdr(s)) {
3351 if (!SigValidateFlowbitUse(
de_ctx, s)) {
3358 int r = SigValidateFileHandling(s);
3362 if (SigInspectsFiles(s)) {
3367 if (DetectRuleValidateTable(s) ==
false) {
3390 memset(&parser, 0x00,
sizeof(parser));
3395 if (firewall_rule) {
3412 int ret = SigParse(
de_ctx, sig, sigstr, dir, &parser,
true);
3419 }
else if (ret < 0) {
3425 SCLogError(
"Signature missing required value \"sid\".");
3430 ret = SigParse(
de_ctx, sig, sigstr, dir, &parser,
false);
3436 }
else if (ret == -2) {
3439 }
else if (ret < 0) {
3444 if (sig->
prio == -1)
3451 int override_needed = 0;
3455 override_needed = 1;
3457 override_needed = 1;
3461 override_needed = 0;
3470 if (override_needed)
3480 for ( ; sm != NULL; sm = sm->
next) {
3504 SCLogDebug(
"sig %"PRIu32
" SIG_FLAG_APPLAYER: %s, SIG_FLAG_PACKET: %s",
3508 SigBuildAddressMatchArray(sig);
3519 SigSetupPrefilter(
de_ctx, sig);
3522 if (SigValidateConsolidate(
de_ctx, sig, &parser, dir) == 0) {
3541 static bool SigHasSameSourceAndDestination(
const Signature *s)
3583 if (SigHasSameSourceAndDestination(sig)) {
3584 SCLogInfo(
"Rule with ID %u is bidirectional, but source and destination are the same, "
3585 "treating the rule as unidirectional", sig->
id);
3590 if (sig->
next == NULL) {
3620 return SigInitDo(
de_ctx, sigstr,
false);
3625 return SigInitDo(
de_ctx, sigstr,
true);
3634 static void DetectParseDupSigFreeFunc(
void *data)
3650 static uint32_t DetectParseDupSigHashFunc(
HashListTable *ht,
void *data, uint16_t datalen)
3669 static char DetectParseDupSigCompareFunc(
void *data1, uint16_t len1,
void *data2,
3675 if (sw1 == NULL || sw2 == NULL ||
3676 sw1->
s == NULL || sw2->
s == NULL)
3680 if (sw1->
s->
id == sw2->
s->
id && sw1->
s->
gid == sw2->
s->
gid)
return 1;
3696 DetectParseDupSigHashFunc,
3697 DetectParseDupSigCompareFunc,
3698 DetectParseDupSigFreeFunc);
3759 if (sw_dup == NULL) {
3772 (
void *)&sw_tmp, 0);
3786 if (sw->
s->
rev <= sw_dup->
s->
rev) {
3795 if (sw_dup->
s_prev == NULL) {
3803 sw_temp.
s = sw_dup->
s->
next;
3807 if (sw_temp.
s != NULL) {
3809 (
void *)&sw_temp, 0);
3830 sw_temp.
s = sw_dup->
s->
next;
3838 if (sw_temp.
s != NULL) {
3840 (
void *)&sw_temp, 0);
3856 (
void *)&sw_tmp, 0);
3858 if (sw_old->
s != sw_dup->
s) {
3901 int dup_sig = DetectEngineSignatureIsDuplicate(
de_ctx, sig);
3905 SCLogError(
"Duplicate signature \"%s\"", sigstr);
3907 }
else if (dup_sig == 2) {
3909 " so the older sig replaced by this new signature \"%s\"",
3914 if (sig->
next != NULL) {
3931 return (dup_sig == 0 || dup_sig == 2) ? sig : NULL;
3935 if (sig != NULL && sig->
next != NULL) {
3973 int dup_sig = DetectEngineSignatureIsDuplicate(
de_ctx, sig);
3977 SCLogError(
"Duplicate signature \"%s\"", sigstr);
3979 }
else if (dup_sig == 2) {
3981 " so the older sig replaced by this new signature \"%s\"",
3986 if (sig->
next != NULL) {
4003 return (dup_sig == 0 || dup_sig == 2) ? sig : NULL;
4007 if (sig != NULL && sig->
next != NULL) {
4020 int start_offset,
int options)
4022 *match = pcre2_match_data_create_from_pattern(parse_regex->
regex, NULL);
4024 return pcre2_match(parse_regex->
regex, (PCRE2_SPTR8)
str, strlen(
str), options, start_offset,
4025 *match, parse_regex->
context);
4032 pcre2_code_free(r->
regex);
4035 pcre2_match_context_free(r->
context);
4050 g_detect_parse_regex_list = NULL;
4059 FatalError(
"failed to alloc memory for pcre free list");
4062 r->
next = g_detect_parse_regex_list;
4063 g_detect_parse_regex_list = r;
4071 detect_parse->
regex =
4072 pcre2_compile((PCRE2_SPTR8)parse_str, PCRE2_ZERO_TERMINATED, opts, &en, &eo, NULL);
4073 if (detect_parse->
regex == NULL) {
4074 PCRE2_UCHAR errbuffer[256];
4075 pcre2_get_error_message(en, errbuffer,
sizeof(errbuffer));
4076 SCLogError(
"pcre compile of \"%s\" failed at "
4078 parse_str, en, errbuffer);
4081 detect_parse->
context = pcre2_match_context_create(NULL);
4082 if (detect_parse->
context == NULL) {
4083 SCLogError(
"pcre2 could not create match context");
4084 pcre2_code_free(detect_parse->
regex);
4085 detect_parse->
regex = NULL;
4100 if (detect_parse == NULL) {
4104 detect_parse->
regex =
4105 pcre2_compile((PCRE2_SPTR8)parse_str, PCRE2_ZERO_TERMINATED, opts, &en, &eo, NULL);
4106 if (detect_parse->
regex == NULL) {
4107 PCRE2_UCHAR errbuffer[256];
4108 pcre2_get_error_message(en, errbuffer,
sizeof(errbuffer));
4109 SCLogError(
"pcre2 compile of \"%s\" failed at "
4111 parse_str, (
int)eo, errbuffer);
4116 detect_parse->
next = g_detect_parse_regex_list;
4117 g_detect_parse_regex_list = detect_parse;
4118 return detect_parse;
4122 pcre2_match_data *match_data, uint32_t number, PCRE2_UCHAR *buffer, PCRE2_SIZE *bufflen)
4124 int r = pcre2_substring_copy_bynumber(match_data, number, buffer, bufflen);
4125 if (r == PCRE2_ERROR_UNSET) {
4134 pcre2_match_data *match_data, uint32_t number, PCRE2_UCHAR **bufferptr, PCRE2_SIZE *bufflen)
4136 int r = pcre2_substring_get_bynumber(match_data, number, bufferptr, bufflen);
4137 if (r == PCRE2_ERROR_UNSET) {
4152 static uint32_t AppPolicyHashFunc(
HashTable *ht,
void *data, uint16_t datalen)
4156 uint32_t hash =
p->alproto * 65537 +
p->sub_state * 257 +
p->progress * 5 +
4157 (
p->direction == STREAM_TOSERVER);
4158 hash ^= (hash >> 10) ^ (hash >> 20);
4162 static char AppPolicyCompareFunc(
void *data1, uint16_t datalen1,
void *data2, uint16_t datalen2)
4167 if (p1 == NULL || p2 == NULL)
4174 static void AppPolicyHashFree(
void *data)
4211 snprintf(out, out_size,
"rejectdst:%s", as);
4213 snprintf(out, out_size,
"rejectboth:%s", as);
4215 snprintf(out, out_size,
"rejectsrc:%s", as);
4218 snprintf(out, out_size,
"drop:%s", as);
4220 snprintf(out, out_size,
"accept:%s", as);
4226 strlcat(out,
",pass:flow", out_size);
4232 strlcat(out,
",alert", out_size);
4254 snprintf(msg,
sizeof(msg),
"SURICATA FW default packet policy");
4256 if (s->
msg == NULL) {
4280 snprintf(msg,
sizeof(msg),
"SURICATA FW default app policy");
4282 if (s->
msg == NULL) {
4308 if (policy_actions == NULL) {
4309 SCLogDebug(
"fw: no policy at %s", policy_name);
4314 uint8_t action_scope = 0;
4319 if (SigParseActionDo(paction->
val, idx,
true, &action, &action_scope) < 0)
4325 SCLogError(
"%s: 'config' is not a valid default policy action", policy_name);
4342 char *path = chain->path[chain->len];
4349 FatalError(
"%s: firewall YAML config path formatting failed", fmt);
4352 FatalError(
"%s: firewall YAML config path too long", path);
4355 for (uint8_t i = 0; i < chain->len; i++) {
4356 if (strcmp(chain->path[i], path) == 0)
4376 for (uint8_t i = 0; i < chain->
len; i++) {
4377 const char *path = chain->
path[i];
4379 int r = DoParsePolicy(path, &tmp);
4385 SCLogError(
"%s: policy is set but empty", path);
4388 if (!FirewallScopeValidForClass(tmp.
action_scope, pol_class)) {
4390 FirewallScopeHintForClass(pol_class, hint,
sizeof(hint));
4391 SCLogError(
"%s: action scope (\"%s\") is not valid. Valid scopes: %s", path,
4402 static void FirewallHookNameConvertUnderscoreToDash(
const char *in,
char *out,
size_t out_size)
4404 if (
strlcpy(out, in, out_size) >= out_size) {
4405 FatalError(
"%s: firewall policy config name too long", in);
4407 for (
size_t i = 0; out[i] !=
'\0'; i++) {
4419 static int DoParseAppPolicy(
const char *prefix,
const AppProto app_proto,
const uint8_t sub_state,
4420 const char *sub_state_name,
const char *hookname,
const uint8_t state,
4421 const uint8_t complete_state,
const int direction,
4425 if (app_proto_str == NULL) {
4426 SCLogError(
"Unknown app proto %u", (
unsigned)app_proto);
4432 if (hookname != NULL) {
4433 FirewallHookNameConvertUnderscoreToDash(hookname, hook,
sizeof(hook));
4438 if (sub_state_name != NULL) {
4440 FirewallHookNameConvertUnderscoreToDash(sub_state_name, sub + 1,
sizeof(sub) - 1);
4444 if (hookname != NULL) {
4446 FirewallPolicyChainAdd(&chain,
"%s.app.%s%s.%s", prefix, app_proto_str, sub, hook);
4448 if (generic_hook != NULL) {
4450 FirewallPolicyChainAdd(&chain,
"%s.app.%s%s.%s", prefix, app_proto_str, sub, generic_hook);
4453 FirewallPolicyChainAdd(&chain,
"%s.app.%s%s.default-policy", prefix, app_proto_str, sub);
4455 FirewallPolicyChainAdd(&chain,
"%s.app.%s.default-policy", prefix, app_proto_str);
4457 FirewallPolicyChainAdd(&chain,
"%s.app.default-policy", prefix);
4459 FirewallPolicyChainAdd(&chain,
"%s.default-policy", prefix);
4462 if (app_pol == NULL)
4481 FatalError(
"internal error: insert policy into hash table");
4487 return AddAppPolicySignature(app_pol);
4497 if (fw_policies == NULL)
4500 HashTableInit(512, AppPolicyHashFunc, AppPolicyCompareFunc, AppPolicyHashFree);
4528 FirewallPolicyChainAdd(&chain,
"%s.packet.%s", prefix, leaf);
4530 FirewallPolicyChainAdd(&chain,
"%s.packet.default-policy", prefix);
4532 FirewallPolicyChainAdd(&chain,
"%s.default-policy", prefix);
4538 int r = ResolveFirewallPolicy(pol, pol_class, &chain);
4543 return AddPktPolicySignature(fw_policies, pol,
id);
4551 static int DetectFirewallLoadPacketPolicies(
4554 if (DetectFirewallLoadPacketPolicy(
4557 if (DetectFirewallLoadPacketPolicy(
4560 if (DetectFirewallLoadPacketPolicy(
4583 {
ALPROTO_SSH,
"request-in-progress",
"request-banner" },
4584 {
ALPROTO_SSH,
"request-banner-wait-eol",
"request-banner" },
4585 {
ALPROTO_SSH,
"request-banner-done",
"request-kex" },
4586 {
ALPROTO_SSH,
"request-finished",
"request-session" },
4587 {
ALPROTO_SSH,
"response-in-progress",
"response-banner" },
4588 {
ALPROTO_SSH,
"response-banner-wait-eol",
"response-banner" },
4589 {
ALPROTO_SSH,
"response-banner-done",
"response-kex" },
4590 {
ALPROTO_SSH,
"response-finished",
"response-session" },
4591 {
ALPROTO_TLS,
"client-in-progress",
"client-started" },
4592 {
ALPROTO_TLS,
"client-hello-done",
"client-hello" },
4593 {
ALPROTO_TLS,
"client-cert-done",
"client-cert" },
4594 {
ALPROTO_TLS,
"client-handshake-done",
"client-data" },
4595 {
ALPROTO_TLS,
"server-in-progress",
"server-started" },
4596 {
ALPROTO_TLS,
"server-hello-done",
"server-data" },
4597 {
ALPROTO_TLS,
"server-cert-done",
"server-cert" },
4598 {
ALPROTO_TLS,
"server-handshake-done",
"server-data" },
4622 static bool FwPolicyKeyIsNonState(
const char *key)
4624 return strcmp(key,
"default-policy") == 0 || strcmp(key,
"request-started") == 0 ||
4625 strcmp(key,
"response-started") == 0 || strcmp(key,
"request-complete") == 0 ||
4626 strcmp(key,
"response-complete") == 0;
4629 static bool FwPolicyStateKeyIsKnown(
AppProto a,
const char *sub_state_name,
const char *key)
4632 if (FwPolicyKeyIsNonState(key)) {
4637 const uint8_t dirs[2] = { STREAM_TOSERVER, STREAM_TOCLIENT };
4639 if (sub_state_name == NULL) {
4640 for (
size_t d = 0; d < 2; d++) {
4642 for (uint8_t state = 0; state <= complete; state++) {
4651 FirewallHookNameConvertUnderscoreToDash(
name, dash,
sizeof(dash));
4652 if (strcmp(dash, key) == 0) {
4661 for (uint8_t s = 1; s <= max_sub_state; s++) {
4663 if (sub_name == NULL || strcmp(sub_name, sub_state_name) != 0) {
4667 for (
size_t d = 0; d < 2; d++) {
4668 for (uint8_t state = 0; state <= max_state; state++) {
4674 FirewallHookNameConvertUnderscoreToDash(
name, dash,
sizeof(dash));
4675 if (strcmp(dash, key) == 0) {
4704 static bool FirewallPolicyNodeIsMapping(
const SCConfNode *node)
4709 if (c->
name == NULL) {
4712 for (
const char *
p = c->
name; *
p;
p++) {
4713 if (*p < '0' || *p >
'9') {
4723 static bool FirewallPolicyNodeIsList(
const SCConfNode *node)
4731 if (c->
name == NULL) {
4734 for (
const char *
p = c->
name; *
p;
p++) {
4735 if (*p < '0' || *p >
'9') {
4743 static int WarnUnmatchedFirewallPolicyStateKeys(
4744 const char *prefix,
AppProto a,
const char *sub_state_name)
4747 if (
proto == NULL) {
4752 if (sub_state_name != NULL) {
4754 FirewallHookNameConvertUnderscoreToDash(sub_state_name, sub + 1,
sizeof(sub) - 1);
4758 const size_t path_len = strlen(prefix) + strlen(
proto) + strlen(sub) + 6;
4763 snprintf(path, path_len,
"%s.app.%s%s", prefix,
proto, sub);
4772 int known_wrong_keys = 0;
4774 if (c->
name == NULL) {
4778 if (sub_state_name == NULL) {
4784 bool is_sub_state_section =
false;
4785 if (c->head.tqh_first != NULL) {
4792 FirewallHookNameConvertUnderscoreToDash(sn, dash,
sizeof(dash));
4793 if (strcmp(dash, c->
name) == 0)
4794 is_sub_state_section =
true;
4797 if (is_sub_state_section)
4810 strcmp(c->
name,
"default-policy") == 0);
4811 if (consulted && FwPolicyStateKeyIsKnown(a, sub_state_name, c->
name)) {
4815 const char *hint = NULL;
4816 for (
size_t i = 0; i <
ARRAY_SIZE(g_fw_policy_state_rename_hints); i++) {
4817 if (g_fw_policy_state_rename_hints[i].
proto == a &&
4818 strcmp(c->
name, g_fw_policy_state_rename_hints[i].old_name) == 0) {
4819 hint = g_fw_policy_state_rename_hints[i].
new_name;
4826 SCLogError(
"firewall policy: key '%s' under %s matches no %s state: "
4827 "a state previously named '%s' was renamed to '%s' "
4828 "in this release - use the new name",
4832 SCLogWarning(
"firewall policy: key '%s' under %s matches no %s state "
4838 return known_wrong_keys;
4843 char prefix[96] =
"firewall.policies";
4849 if (fw_policies == NULL)
4852 if (DetectFirewallLoadPacketPolicies(fw_policies, prefix) < 0)
4855 int known_wrong_keys = 0;
4857 if (!AppProtoIsValid(a))
4863 for (uint8_t s = 1; s <= max_sub_state; s++) {
4867 if (sub_state_name == NULL)
4874 for (uint8_t state = 0; state <= max_state; state++) {
4876 sub_state_name, state);
4877 const char *state_name =
4879 BUG_ON(state_name == NULL);
4881 sub_state_name, state_name);
4882 if (DoParseAppPolicy(prefix, a, s, sub_state_name, state_name, state, max_state,
4883 STREAM_TOSERVER, fw_policies) < 0)
4887 for (uint8_t state = 0; state <= max_state; state++) {
4889 sub_state_name, state);
4890 const char *state_name =
4892 BUG_ON(state_name == NULL);
4894 sub_state_name, state_name);
4895 if (DoParseAppPolicy(prefix, a, s, sub_state_name, state_name, state, max_state,
4896 STREAM_TOCLIENT, fw_policies) < 0)
4900 known_wrong_keys += WarnUnmatchedFirewallPolicyStateKeys(prefix, a, sub_state_name);
4907 if (proto_name != NULL) {
4908 const size_t path_len = strlen(prefix) + 5 + strlen(proto_name) + 1;
4909 char *proto_path =
SCMalloc(path_len);
4910 if (proto_path != NULL) {
4911 snprintf(proto_path, path_len,
"%s.app.%s", prefix, proto_name);
4913 if (proto_node != NULL) {
4923 if (sc->
name == NULL || sc->head.tqh_first == NULL ||
4924 FirewallPolicyNodeIsList(sc) ||
4925 FwPolicyKeyIsNonState(sc->
name)) {
4928 bool known_section =
false;
4929 for (uint8_t s2 = 1; s2 <= max_sub_state; s2++) {
4935 FirewallHookNameConvertUnderscoreToDash(sn, dash,
sizeof(dash));
4936 if (strcmp(dash, sc->
name) == 0) {
4937 known_section =
true;
4941 if (!known_section) {
4942 SCLogWarning(
"firewall policy: sub-state section '%s' "
4943 "under %s matches no %s sub-state and is "
4945 sc->
name, proto_path, proto_name);
4955 known_wrong_keys += WarnUnmatchedFirewallPolicyStateKeys(prefix, a, NULL);
4957 const uint8_t complete_state_ts =
4959 a, STREAM_TOSERVER);
4960 for (uint8_t state = 0; state <= complete_state_ts; state++) {
4963 if (DoParseAppPolicy(prefix, a, 0, NULL,
name, state, complete_state_ts,
4964 STREAM_TOSERVER, fw_policies) < 0)
4967 const uint8_t complete_state_tc =
4969 a, STREAM_TOCLIENT);
4970 for (uint8_t state = 0; state <= complete_state_tc; state++) {
4973 if (DoParseAppPolicy(prefix, a, 0, NULL,
name, state, complete_state_tc,
4974 STREAM_TOCLIENT, fw_policies) < 0)
4978 known_wrong_keys += WarnUnmatchedFirewallPolicyStateKeys(prefix, a, NULL);
4981 if (known_wrong_keys) {
4985 "known to be renamed - fix the keys and retry",
4999 static int SigParseTest01 (
void)
5008 sig =
SigInit(
de_ctx,
"alert tcp 1.2.3.4 any -> !1.2.3.4 any (msg:\"SigParseTest01\"; sid:1;)");
5018 static int SigParseTest02 (
void)
5033 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;)");
5061 static int SigParseTest03 (
void)
5070 sig =
SigInit(
de_ctx,
"alert tcp 1.2.3.4 any <- !1.2.3.4 any (msg:\"SigParseTest03\"; sid:1;)");
5073 printf(
"expected NULL got sig ptr %p: ",sig);
5082 static int SigParseTest04 (
void)
5091 sig =
SigInit(
de_ctx,
"alert tcp 1.2.3.4 1024: -> !1.2.3.4 1024: (msg:\"SigParseTest04\"; sid:1;)");
5102 static int SigParseTest05 (
void)
5111 sig =
SigInit(
de_ctx,
"alert tcp 1.2.3.4 1024:65536 -> !1.2.3.4 any (msg:\"SigParseTest05\"; sid:1;)");
5115 printf(
"signature didn't fail to parse as we expected: ");
5125 static int SigParseTest06 (
void)
5134 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;)");
5138 printf(
"signature failed to parse: ");
5152 static int SigParseTest07(
void)
5174 static int SigParseTest08(
void)
5197 static int SigParseTest09(
void)
5248 static int SigParseTest10(
void)
5280 static int SigParseTest11(
void)
5291 "drop tcp any any -> any 80 (msg:\"Snort_Inline is blocking the http link\"; sid:1;) ");
5293 printf(
"sig 1 didn't parse: ");
5298 "the http link\"; sid:2;) ");
5300 printf(
"sig 2 didn't parse: ");
5314 static int SigParseTest12(
void)
5326 printf(
"sig 1 should have given an error: ");
5340 static int SigParseTest13(
void)
5352 printf(
"sig 1 invalidated: failure");
5357 printf(
"sig doesn't have stream flag set\n");
5362 printf(
"sig has packet flag set\n");
5377 static int SigParseTest14(
void)
5389 printf(
"sig 1 invalidated: failure");
5394 printf(
"sig doesn't have packet flag set\n");
5399 printf(
"sig has stream flag set\n");
5414 static int SigParseTest15(
void)
5426 printf(
"sig 1 invalidated: failure");
5431 printf(
"sig doesn't have packet flag set\n");
5436 printf(
"sig doesn't have stream flag set\n");
5451 static int SigParseTest16(
void)
5463 printf(
"sig 1 invalidated: failure");
5468 printf(
"sig doesn't have packet flag set\n");
5473 printf(
"sig doesn't have stream flag set\n");
5488 static int SigParseTest17(
void)
5500 printf(
"sig 1 invalidated: failure");
5505 printf(
"sig doesn't have packet flag set\n");
5510 printf(
"sig doesn't have stream flag set\n");
5523 static int SigParseTest18 (
void)
5531 if (
DetectEngineAppendSig(
de_ctx,
"alert tcp 1.2.3.4 any -> !1.2.3.4 any (msg:\"SigParseTest01\"; sid:99999999999999999999;)") != NULL)
5542 static int SigParseTest19 (
void)
5550 if (
DetectEngineAppendSig(
de_ctx,
"alert tcp 1.2.3.4 any -> !1.2.3.4 any (msg:\"SigParseTest01\"; sid:1; gid:99999999999999999999;)") != NULL)
5561 static int SigParseTest20 (
void)
5569 if (
DetectEngineAppendSig(
de_ctx,
"alert tcp 1.2.3.4 any -> !1.2.3.4 any (msg:\"SigParseTest01\"; sid:1; rev:99999999999999999999;)") != NULL)
5580 static int SigParseTest21 (
void)
5599 static int SigParseTest22 (
void)
5607 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)
5620 static int SigParseTest23(
void)
5635 static int SigParseBidirecTest06 (
void)
5655 static int SigParseBidirecTest07 (
void)
5675 static int SigParseBidirecTest08 (
void)
5695 static int SigParseBidirecTest09 (
void)
5715 static int SigParseBidirecTest10 (
void)
5735 static int SigParseBidirecTest11 (
void)
5755 static int SigParseBidirecTest12 (
void)
5775 static int SigParseBidirecTest13 (
void)
5794 static int SigParseBidirecTest14 (
void)
5815 static int SigTestBidirec01 (
void)
5827 if (sig->
next != NULL)
5846 static int SigTestBidirec02 (
void)
5865 if (sig->
next == NULL)
5870 if (copy->
next != NULL)
5891 static int SigTestBidirec03 (
void)
5903 const char *sigs[3];
5904 sigs[0] =
"alert tcp any any -> 192.168.1.1 any (msg:\"SigTestBidirec03 sid 1\"; sid:1;)";
5905 sigs[1] =
"alert tcp any any <> 192.168.1.1 any (msg:\"SigTestBidirec03 sid 2 bidirectional\"; sid:2;)";
5906 sigs[2] =
"alert tcp any any -> 192.168.1.1 any (msg:\"SigTestBidirec03 sid 3\"; sid:3;)";
5913 if (sig->
next == NULL)
5924 uint8_t rawpkt1_ether[] = {
5925 0x00,0x50,0x56,0xea,0x00,0xbd,0x00,0x0c,
5926 0x29,0x40,0xc8,0xb5,0x08,0x00,0x45,0x00,
5927 0x01,0xa8,0xb9,0xbb,0x40,0x00,0x40,0x06,
5928 0xe0,0xbf,0xc0,0xa8,0x1c,0x83,0xc0,0xa8,
5929 0x01,0x01,0xb9,0x0a,0x00,0x50,0x6f,0xa2,
5930 0x92,0xed,0x7b,0xc1,0xd3,0x4d,0x50,0x18,
5931 0x16,0xd0,0xa0,0x6f,0x00,0x00,0x47,0x45,
5932 0x54,0x20,0x2f,0x20,0x48,0x54,0x54,0x50,
5933 0x2f,0x31,0x2e,0x31,0x0d,0x0a,0x48,0x6f,
5934 0x73,0x74,0x3a,0x20,0x31,0x39,0x32,0x2e,
5935 0x31,0x36,0x38,0x2e,0x31,0x2e,0x31,0x0d,
5936 0x0a,0x55,0x73,0x65,0x72,0x2d,0x41,0x67,
5937 0x65,0x6e,0x74,0x3a,0x20,0x4d,0x6f,0x7a,
5938 0x69,0x6c,0x6c,0x61,0x2f,0x35,0x2e,0x30,
5939 0x20,0x28,0x58,0x31,0x31,0x3b,0x20,0x55,
5940 0x3b,0x20,0x4c,0x69,0x6e,0x75,0x78,0x20,
5941 0x78,0x38,0x36,0x5f,0x36,0x34,0x3b,0x20,
5942 0x65,0x6e,0x2d,0x55,0x53,0x3b,0x20,0x72,
5943 0x76,0x3a,0x31,0x2e,0x39,0x2e,0x30,0x2e,
5944 0x31,0x34,0x29,0x20,0x47,0x65,0x63,0x6b,
5945 0x6f,0x2f,0x32,0x30,0x30,0x39,0x30,0x39,
5946 0x30,0x32,0x31,0x37,0x20,0x55,0x62,0x75,
5947 0x6e,0x74,0x75,0x2f,0x39,0x2e,0x30,0x34,
5948 0x20,0x28,0x6a,0x61,0x75,0x6e,0x74,0x79,
5949 0x29,0x20,0x46,0x69,0x72,0x65,0x66,0x6f,
5950 0x78,0x2f,0x33,0x2e,0x30,0x2e,0x31,0x34,
5951 0x0d,0x0a,0x41,0x63,0x63,0x65,0x70,0x74,
5952 0x3a,0x20,0x74,0x65,0x78,0x74,0x2f,0x68,
5953 0x74,0x6d,0x6c,0x2c,0x61,0x70,0x70,0x6c,
5954 0x69,0x63,0x61,0x74,0x69,0x6f,0x6e,0x2f,
5955 0x78,0x68,0x74,0x6d,0x6c,0x2b,0x78,0x6d,
5956 0x6c,0x2c,0x61,0x70,0x70,0x6c,0x69,0x63,
5957 0x61,0x74,0x69,0x6f,0x6e,0x2f,0x78,0x6d,
5958 0x6c,0x3b,0x71,0x3d,0x30,0x2e,0x39,0x2c,
5959 0x2a,0x2f,0x2a,0x3b,0x71,0x3d,0x30,0x2e,
5960 0x38,0x0d,0x0a,0x41,0x63,0x63,0x65,0x70,
5961 0x74,0x2d,0x4c,0x61,0x6e,0x67,0x75,0x61,
5962 0x67,0x65,0x3a,0x20,0x65,0x6e,0x2d,0x75,
5963 0x73,0x2c,0x65,0x6e,0x3b,0x71,0x3d,0x30,
5964 0x2e,0x35,0x0d,0x0a,0x41,0x63,0x63,0x65,
5965 0x70,0x74,0x2d,0x45,0x6e,0x63,0x6f,0x64,
5966 0x69,0x6e,0x67,0x3a,0x20,0x67,0x7a,0x69,
5967 0x70,0x2c,0x64,0x65,0x66,0x6c,0x61,0x74,
5968 0x65,0x0d,0x0a,0x41,0x63,0x63,0x65,0x70,
5969 0x74,0x2d,0x43,0x68,0x61,0x72,0x73,0x65,
5970 0x74,0x3a,0x20,0x49,0x53,0x4f,0x2d,0x38,
5971 0x38,0x35,0x39,0x2d,0x31,0x2c,0x75,0x74,
5972 0x66,0x2d,0x38,0x3b,0x71,0x3d,0x30,0x2e,
5973 0x37,0x2c,0x2a,0x3b,0x71,0x3d,0x30,0x2e,
5974 0x37,0x0d,0x0a,0x4b,0x65,0x65,0x70,0x2d,
5975 0x41,0x6c,0x69,0x76,0x65,0x3a,0x20,0x33,
5976 0x30,0x30,0x0d,0x0a,0x43,0x6f,0x6e,0x6e,
5977 0x65,0x63,0x74,0x69,0x6f,0x6e,0x3a,0x20,
5978 0x6b,0x65,0x65,0x70,0x2d,0x61,0x6c,0x69,
5979 0x76,0x65,0x0d,0x0a,0x0d,0x0a };
5989 uint32_t sids[3] = {1, 2, 3};
5990 uint32_t results[3] = {1, 1, 1};
6006 static int SigTestBidirec04 (
void)
6021 sig =
DetectEngineAppendSig(
de_ctx,
"alert tcp 192.168.1.1 any <> any any (msg:\"SigTestBidirec03 sid 2 bidirectional\"; sid:2;)");
6026 if (sig->
next == NULL)
6038 if (sig->
next == NULL)
6049 uint8_t rawpkt1_ether[] = {
6050 0x00,0x50,0x56,0xea,0x00,0xbd,0x00,0x0c,
6051 0x29,0x40,0xc8,0xb5,0x08,0x00,0x45,0x00,
6052 0x01,0xa8,0xb9,0xbb,0x40,0x00,0x40,0x06,
6053 0xe0,0xbf,0xc0,0xa8,0x1c,0x83,0xc0,0xa8,
6054 0x01,0x01,0xb9,0x0a,0x00,0x50,0x6f,0xa2,
6055 0x92,0xed,0x7b,0xc1,0xd3,0x4d,0x50,0x18,
6056 0x16,0xd0,0xa0,0x6f,0x00,0x00,0x47,0x45,
6057 0x54,0x20,0x2f,0x20,0x48,0x54,0x54,0x50,
6058 0x2f,0x31,0x2e,0x31,0x0d,0x0a,0x48,0x6f,
6059 0x73,0x74,0x3a,0x20,0x31,0x39,0x32,0x2e,
6060 0x31,0x36,0x38,0x2e,0x31,0x2e,0x31,0x0d,
6061 0x0a,0x55,0x73,0x65,0x72,0x2d,0x41,0x67,
6062 0x65,0x6e,0x74,0x3a,0x20,0x4d,0x6f,0x7a,
6063 0x69,0x6c,0x6c,0x61,0x2f,0x35,0x2e,0x30,
6064 0x20,0x28,0x58,0x31,0x31,0x3b,0x20,0x55,
6065 0x3b,0x20,0x4c,0x69,0x6e,0x75,0x78,0x20,
6066 0x78,0x38,0x36,0x5f,0x36,0x34,0x3b,0x20,
6067 0x65,0x6e,0x2d,0x55,0x53,0x3b,0x20,0x72,
6068 0x76,0x3a,0x31,0x2e,0x39,0x2e,0x30,0x2e,
6069 0x31,0x34,0x29,0x20,0x47,0x65,0x63,0x6b,
6070 0x6f,0x2f,0x32,0x30,0x30,0x39,0x30,0x39,
6071 0x30,0x32,0x31,0x37,0x20,0x55,0x62,0x75,
6072 0x6e,0x74,0x75,0x2f,0x39,0x2e,0x30,0x34,
6073 0x20,0x28,0x6a,0x61,0x75,0x6e,0x74,0x79,
6074 0x29,0x20,0x46,0x69,0x72,0x65,0x66,0x6f,
6075 0x78,0x2f,0x33,0x2e,0x30,0x2e,0x31,0x34,
6076 0x0d,0x0a,0x41,0x63,0x63,0x65,0x70,0x74,
6077 0x3a,0x20,0x74,0x65,0x78,0x74,0x2f,0x68,
6078 0x74,0x6d,0x6c,0x2c,0x61,0x70,0x70,0x6c,
6079 0x69,0x63,0x61,0x74,0x69,0x6f,0x6e,0x2f,
6080 0x78,0x68,0x74,0x6d,0x6c,0x2b,0x78,0x6d,
6081 0x6c,0x2c,0x61,0x70,0x70,0x6c,0x69,0x63,
6082 0x61,0x74,0x69,0x6f,0x6e,0x2f,0x78,0x6d,
6083 0x6c,0x3b,0x71,0x3d,0x30,0x2e,0x39,0x2c,
6084 0x2a,0x2f,0x2a,0x3b,0x71,0x3d,0x30,0x2e,
6085 0x38,0x0d,0x0a,0x41,0x63,0x63,0x65,0x70,
6086 0x74,0x2d,0x4c,0x61,0x6e,0x67,0x75,0x61,
6087 0x67,0x65,0x3a,0x20,0x65,0x6e,0x2d,0x75,
6088 0x73,0x2c,0x65,0x6e,0x3b,0x71,0x3d,0x30,
6089 0x2e,0x35,0x0d,0x0a,0x41,0x63,0x63,0x65,
6090 0x70,0x74,0x2d,0x45,0x6e,0x63,0x6f,0x64,
6091 0x69,0x6e,0x67,0x3a,0x20,0x67,0x7a,0x69,
6092 0x70,0x2c,0x64,0x65,0x66,0x6c,0x61,0x74,
6093 0x65,0x0d,0x0a,0x41,0x63,0x63,0x65,0x70,
6094 0x74,0x2d,0x43,0x68,0x61,0x72,0x73,0x65,
6095 0x74,0x3a,0x20,0x49,0x53,0x4f,0x2d,0x38,
6096 0x38,0x35,0x39,0x2d,0x31,0x2c,0x75,0x74,
6097 0x66,0x2d,0x38,0x3b,0x71,0x3d,0x30,0x2e,
6098 0x37,0x2c,0x2a,0x3b,0x71,0x3d,0x30,0x2e,
6099 0x37,0x0d,0x0a,0x4b,0x65,0x65,0x70,0x2d,
6100 0x41,0x6c,0x69,0x76,0x65,0x3a,0x20,0x33,
6101 0x30,0x30,0x0d,0x0a,0x43,0x6f,0x6e,0x6e,
6102 0x65,0x63,0x74,0x69,0x6f,0x6e,0x3a,0x20,
6103 0x6b,0x65,0x65,0x70,0x2d,0x61,0x6c,0x69,
6104 0x76,0x65,0x0d,0x0a,0x0d,0x0a };
6153 static int SigParseTestNegation01 (
void)
6167 static int SigParseTestNegation02 (
void)
6173 "alert tcp any !any -> any any (msg:\"SigTest41-02 src ip is !any \"; "
6174 "classtype:misc-activity; sid:410002; rev:1;)");
6182 static int SigParseTestNegation03 (
void)
6188 "alert tcp any any -> any [80:!80] (msg:\"SigTest41-03 dst port [80:!80] \"; "
6189 "classtype:misc-activity; sid:410003; rev:1;)");
6197 static int SigParseTestNegation04 (
void)
6208 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;)");
6223 static int SigParseTestNegation05 (
void)
6234 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;)");
6249 static int SigParseTestNegation06 (
void)
6260 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;)");
6276 static int SigParseTestNegation07 (
void)
6282 de_ctx,
"alert tcp any any -> [192.168.0.2,!192.168.0.0/24] any (sid:410006;)");
6291 static int SigParseTestNegation08 (
void)
6303 "alert tcp any any -> [192.168.0.0/16,!192.168.0.0/24] any (sid:410006; rev:1;)");
6318 static int SigParseTestMpm01 (
void)
6327 sig =
SigInit(
de_ctx,
"alert tcp any any -> any any (msg:\"mpm test\"; content:\"abcd\"; sid:1;)");
6329 printf(
"sig failed to init: ");
6334 printf(
"sig doesn't have content list: ");
6349 static int SigParseTestMpm02 (
void)
6358 sig =
SigInit(
de_ctx,
"alert tcp any any -> any any (msg:\"mpm test\"; content:\"abcd\"; content:\"abcdef\"; sid:1;)");
6360 printf(
"sig failed to init: ");
6365 printf(
"sig doesn't have content list: ");
6380 static int SigParseTestAppLayerTLS01(
void)
6391 s =
SigInit(
de_ctx,
"alert tls any any -> any any (msg:\"SigParseTestAppLayerTLS01 \"; sid:410006; rev:1;)");
6393 printf(
"parsing sig failed: ");
6398 printf(
"alproto not set: ");
6415 static int SigParseTestAppLayerTLS02(
void)
6426 s =
SigInit(
de_ctx,
"alert tls any any -> any any (msg:\"SigParseTestAppLayerTLS02 \"; tls.version:1.0; sid:410006; rev:1;)");
6428 printf(
"parsing sig failed: ");
6433 printf(
"alproto not set: ");
6449 static int SigParseTestAppLayerTLS03(
void)
6456 "alert tls any any -> any any (msg:\"SigParseTestAppLayerTLS03 \"; "
6457 "tls.version:2.5; sid:410006; rev:1;)");
6463 static int SigParseTestUnbalancedQuotes01(
void)
6469 "alert http any any -> any any (msg:\"SigParseTestUnbalancedQuotes01\"; "
6470 "pcre:\"/\\/[a-z]+\\.php\\?[a-z]+?=\\d{7}&[a-z]+?=\\d{7,8}$/U\" "
6471 "flowbits:set,et.exploitkitlanding; classtype:trojan-activity; sid:2017078; rev:5;)");
6477 static int SigParseTestContentGtDsize01(
void)
6484 "dsize:21; content:\"0123456789001234567890|00 00|\"; "
6491 static int SigParseTestContentGtDsize02(
void)
6498 "dsize:21; content:\"0123456789|00 00|\"; offset:10; "
6515 static int SigParseBidirWithSameSrcAndDest01(
void)
6532 "alert tcp [1.2.3.4, 5.6.7.8] [80, 81] <> [5.6.7.8, 1.2.3.4] [81, 80] (sid:3;)");
6541 static int SigParseBidirWithSameSrcAndDest02(
void)
6549 de_ctx,
"alert tcp 1.2.3.4 any <> [1.2.3.4, 5.6.7.8, ::1] any (sid:1;)");
6556 de_ctx,
"alert tcp [1.2.3.4, ::1] [80, 81, 82] <> [1.2.3.4, ::1] [80, 81] (sid:2;)");
6563 "alert tcp [1.2.3.4, ::1, ABCD:AAAA::1] [80] <> [1.2.3.4, ::1] [80, 81] (sid:3;)");
6570 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;)");
6577 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;)");
6586 static int SigParseTestActionReject(
void)
6592 de_ctx,
"reject tcp 1.2.3.4 any -> !1.2.3.4 any (msg:\"SigParseTest01\"; sid:1;)");
6593 #ifdef HAVE_LIBNET11
6604 static int SigParseTestActionDrop(
void)
6610 de_ctx,
"drop tcp 1.2.3.4 any -> !1.2.3.4 any (msg:\"SigParseTest01\"; sid:1;)");
6618 static int SigSetMultiAppProto(
void)
6693 static int DetectSetupDirection01(
void)
6698 char *
str = (
char *)
"to_client";
6699 FAIL_IF(DetectSetupDirection(s, &
str,
true) < 0);
6704 static int DetectSetupDirection02(
void)
6708 char *
str = (
char *)
"to_server";
6709 FAIL_IF(DetectSetupDirection(s, &
str,
true) < 0);
6711 str = (
char *)
"to_client";
6712 FAIL_IF(DetectSetupDirection(s, &
str,
true) >= 0);
6718 static int DetectSetupDirection03(
void)
6722 char *
str = (
char *)
"to_client , something";
6723 FAIL_IF(DetectSetupDirection(s, &
str,
false) < 0);
6725 str = (
char *)
"to_client,something";
6726 FAIL_IF(DetectSetupDirection(s, &
str,
false) < 0);
6732 static int DetectSetupDirection04(
void)
6737 char *
str = (
char *)
"to_client_toto";
6738 FAIL_IF(DetectSetupDirection(s, &
str,
true) >= 0);
6740 str = (
char *)
"to_client_toto";
6741 FAIL_IF(DetectSetupDirection(s, &
str,
false) < 0);
6743 str = (
char *)
"to_client,something";
6745 FAIL_IF(DetectSetupDirection(s, &
str,
true) >= 0);
6782 UtRegisterTest(
"SigParseTest21 -- address with space", SigParseTest21);
6783 UtRegisterTest(
"SigParseTest22 -- address with space", SigParseTest22);
6784 UtRegisterTest(
"SigParseTest23 -- carriage return", SigParseTest23);
6799 UtRegisterTest(
"SigParseTestNegation01", SigParseTestNegation01);
6800 UtRegisterTest(
"SigParseTestNegation02", SigParseTestNegation02);
6801 UtRegisterTest(
"SigParseTestNegation03", SigParseTestNegation03);
6802 UtRegisterTest(
"SigParseTestNegation04", SigParseTestNegation04);
6803 UtRegisterTest(
"SigParseTestNegation05", SigParseTestNegation05);
6804 UtRegisterTest(
"SigParseTestNegation06", SigParseTestNegation06);
6805 UtRegisterTest(
"SigParseTestNegation07", SigParseTestNegation07);
6806 UtRegisterTest(
"SigParseTestNegation08", SigParseTestNegation08);
6809 UtRegisterTest(
"SigParseTestAppLayerTLS01", SigParseTestAppLayerTLS01);
6810 UtRegisterTest(
"SigParseTestAppLayerTLS02", SigParseTestAppLayerTLS02);
6811 UtRegisterTest(
"SigParseTestAppLayerTLS03", SigParseTestAppLayerTLS03);
6812 UtRegisterTest(
"SigParseTestUnbalancedQuotes01", SigParseTestUnbalancedQuotes01);
6815 SigParseTestContentGtDsize01);
6817 SigParseTestContentGtDsize02);
6820 SigParseBidirWithSameSrcAndDest01);
6822 SigParseBidirWithSameSrcAndDest02);
6823 UtRegisterTest(
"SigParseTestActionReject", SigParseTestActionReject);
6824 UtRegisterTest(
"SigParseTestActionDrop", SigParseTestActionDrop);
6828 UtRegisterTest(
"DetectSetupDirection01", DetectSetupDirection01);
6829 UtRegisterTest(
"DetectSetupDirection02", DetectSetupDirection02);
6830 UtRegisterTest(
"DetectSetupDirection03", DetectSetupDirection03);
6831 UtRegisterTest(
"DetectSetupDirection04", DetectSetupDirection04);