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 "action \'config\' is not supported in threat detection rules with firewall mode");
1034 if (optvalue != NULL && strlen(optvalue) > 0) {
1035 size_t ovlen = strlen(optvalue);
1036 char *ptr = optvalue;
1046 SCLogError(
"invalid formatting or malformed option to %s keyword: \'%s\'", optname,
1052 SCLogWarning(
"keyword \'%s\' has not been tested for firewall rules", optname);
1069 SCLogError(
"invalid formatting or malformed option to %s keyword: \'%s\'", optname,
1075 SCLogError(
"invalid formatting to %s keyword: "
1076 "value must be double quoted \'%s\'",
1082 && ovlen && *ptr ==
'"')
1084 for (; ovlen > 0; ovlen--) {
1085 if (isblank(ptr[ovlen - 1])) {
1086 ptr[ovlen - 1] =
'\0';
1091 if (ovlen && ptr[ovlen - 1] !=
'"') {
1092 SCLogError(
"bad option value formatting (possible missing semicolon) "
1093 "for keyword %s: \'%s\'",
1101 ptr[ovlen - 1] =
'\0';
1106 "for keyword %s: \'%s\'",
1113 "quotes on %s keyword that doesn't support them: \'%s\'", optname, optstr);
1131 if (setup_ret < 0) {
1135 if (setup_ret == -2) {
1147 if (strlen(optend) > 0) {
1148 strlcpy(output, optend, output_size);
1163 Signature *s,
const char *addrstr,
char flag)
1165 SCLogDebug(
"Address Group \"%s\" to be parsed now", addrstr);
1169 if (strcasecmp(addrstr,
"any") == 0)
1177 if (strcasecmp(addrstr,
"any") == 0)
1192 static bool IsBuiltIn(
const char *n)
1194 return strcmp(n,
"request_started") == 0 || strcmp(n,
"response_started") == 0 ||
1195 strcmp(n,
"request_complete") == 0 || strcmp(n,
"response_complete") == 0;
1203 const uint8_t state,
const uint8_t complete_state,
const int direction)
1206 return (direction == STREAM_TOSERVER) ?
"request-started" :
"response-started";
1207 if (state == complete_state)
1208 return (direction == STREAM_TOSERVER) ?
"request-complete" :
"response-complete";
1224 SCLogDebug(
"alproto %u/%s", a, alproto_name);
1228 SCLogDebug(
"%s: max sub state for %u is %u", alproto_name, a, max_sub_state);
1229 for (uint8_t s = 1; s <= max_sub_state; s++) {
1233 if (sub_state_name == NULL)
1236 char ts_tx_started[64];
1237 snprintf(ts_tx_started,
sizeof(ts_tx_started),
"%s:%s:request_started:generic",
1238 alproto_name, sub_state_name);
1242 char tc_tx_started[64];
1243 snprintf(tc_tx_started,
sizeof(tc_tx_started),
"%s:%s:response_started:generic",
1244 alproto_name, sub_state_name);
1248 char ts_tx_complete[64];
1249 snprintf(ts_tx_complete,
sizeof(ts_tx_complete),
"%s:%s:request_complete:generic",
1250 alproto_name, sub_state_name);
1254 char tc_tx_complete[64];
1255 snprintf(tc_tx_complete,
sizeof(tc_tx_complete),
"%s:%s:response_complete:generic",
1256 alproto_name, sub_state_name);
1261 for (uint8_t state = 0; state <= max_state; state++) {
1262 const char *state_name =
1264 BUG_ON(state_name == NULL);
1266 if (state_name != NULL && !IsBuiltIn(state_name)) {
1268 snprintf(list_name,
sizeof(list_name),
"%s:%s:%s:generic", alproto_name,
1269 sub_state_name, state_name);
1275 for (uint8_t state = 0; state <= max_state; state++) {
1276 const char *state_name =
1278 BUG_ON(state_name == NULL);
1279 if (state_name != NULL && !IsBuiltIn(state_name)) {
1281 snprintf(list_name,
sizeof(list_name),
"%s:%s:%s:generic", alproto_name,
1282 sub_state_name, state_name);
1289 const uint8_t max_progress_ts =
1291 const uint8_t max_progress_tc =
1294 char ts_tx_started[64];
1295 snprintf(ts_tx_started,
sizeof(ts_tx_started),
"%s:request_started:generic",
1299 SCLogDebug(
"- hook %s:%s list %s (%u)", alproto_name,
"request_name", ts_tx_started,
1300 (uint32_t)strlen(ts_tx_started));
1302 char tc_tx_started[64];
1303 snprintf(tc_tx_started,
sizeof(tc_tx_started),
"%s:response_started:generic",
1307 SCLogDebug(
"- hook %s:%s list %s (%u)", alproto_name,
"response_name", tc_tx_started,
1308 (uint32_t)strlen(tc_tx_started));
1310 char ts_tx_complete[64];
1311 snprintf(ts_tx_complete,
sizeof(ts_tx_complete),
"%s:request_complete:generic",
1315 SCLogDebug(
"- hook %s:%s list %s (%u)", alproto_name,
"request_name", ts_tx_complete,
1316 (uint32_t)strlen(ts_tx_complete));
1318 char tc_tx_complete[64];
1319 snprintf(tc_tx_complete,
sizeof(tc_tx_complete),
"%s:response_complete:generic",
1323 SCLogDebug(
"- hook %s:%s list %s (%u)", alproto_name,
"response_name", tc_tx_complete,
1324 (uint32_t)strlen(tc_tx_complete));
1326 for (uint8_t
p = 0;
p <= max_progress_ts;
p++) {
1328 IPPROTO_TCP , a,
p, STREAM_TOSERVER);
1329 if (
name != NULL && !IsBuiltIn(
name)) {
1331 snprintf(list_name,
sizeof(list_name),
"%s:%s:generic", alproto_name,
name);
1332 SCLogDebug(
"- hook %s:%s list %s (%u)", alproto_name,
name, list_name,
1333 (uint32_t)strlen(list_name));
1339 for (uint8_t
p = 0;
p <= max_progress_tc;
p++) {
1341 IPPROTO_TCP , a,
p, STREAM_TOCLIENT);
1342 if (
name != NULL && !IsBuiltIn(
name)) {
1344 snprintf(list_name,
sizeof(list_name),
"%s:%s:generic", alproto_name,
name);
1345 SCLogDebug(
"- hook %s:%s list %s (%u)", alproto_name,
name, list_name,
1346 (uint32_t)strlen(list_name));
1373 if (strcmp(
str,
"flow_start") == 0) {
1375 }
else if (strcmp(
str,
"pre_flow") == 0) {
1377 }
else if (strcmp(
str,
"pre_stream") == 0) {
1379 }
else if (strcmp(
str,
"all") == 0) {
1392 return "flow_start";
1396 return "pre_stream";
1408 .t.pkt.ph = HookPktFromString(hook_str),
1416 static int SigParseProtoHookPkt(
Signature *s,
const char *proto_hook,
const char *
p,
const char *h)
1429 SCLogDebug(
"protocol:%s hook:%s: type:%s parsed hook:%s",
p, h,
1439 .t.app.alproto = alproto,
1440 .t.app.sub_state = sub_state,
1441 .t.app.app_progress = progress,
1449 static int SigParseProtoHookApp(
1450 Signature *s,
const char *proto_hook,
const char *
p,
const char *in_h)
1453 char generic_hook_name[256];
1454 strlcpy(hook, in_h,
sizeof(hook));
1455 const char *h = hook;
1456 const char *t = NULL;
1457 uint8_t sub_state = 0;
1459 bool has_type = strchr(hook,
':') != NULL;
1462 t = strtok_r(hook,
":", &rem);
1466 if (h == NULL || strlen(h) == 0) {
1467 SCLogError(
"invalid hook specification '%s'", hook);
1472 if (strlen(t) == 0) {
1473 SCLogError(
"invalid tx type specification '%s'", hook);
1476 if (strcmp(
p,
"http2") == 0 || strcmp(
p,
"doh2") == 0) {
1477 if (strcmp(t,
"stream") == 0) {
1478 sub_state = HTTP2TxTypeStream;
1479 }
else if (strcmp(t,
"global") == 0) {
1480 sub_state = HTTP2TxTypeGlobal;
1482 SCLogError(
"unknown %s tx type specification '%s': valid values are 'stream' "
1488 SCLogError(
"sub states currently only supported for http2 and doh2");
1494 SCLogError(
"hook '%s': the lower bound form '<' is only allowed for firewall "
1505 if (strcmp(h,
"request_started") == 0) {
1509 }
else if (strcmp(h,
"response_started") == 0) {
1513 }
else if (strcmp(h,
"request_complete") == 0) {
1516 }
else if (strcmp(h,
"response_complete") == 0) {
1520 const int8_t progress_ts =
1522 if (progress_ts >= 0) {
1527 s->
alproto, sub_state, h, STREAM_TOCLIENT);
1528 if (progress_tc < 0) {
1535 snprintf(generic_hook_name,
sizeof(generic_hook_name),
"%s:%s:%s:generic",
p, t, h);
1539 "protocol %s requires a substate specification: %s:<sub_state>:%s",
p,
p, hook);
1546 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) {
1568 }
else if (strcmp(h,
"response_complete") == 0) {
1574 IPPROTO_TCP , s->
alproto, h, STREAM_TOSERVER);
1575 if (progress_ts >= 0) {
1583 IPPROTO_TCP , s->
alproto, h, STREAM_TOCLIENT);
1591 snprintf(generic_hook_name,
sizeof(generic_hook_name),
"%s:%s:generic",
p, h);
1593 SCLogDebug(
"generic_hook_name %s", generic_hook_name);
1597 SCLogError(
"no list registered as %s for hook %s", generic_hook_name, proto_hook);
1602 SCLogDebug(
"protocol:%s hook:%s: type:%s alproto:%u hook:%d",
p, h,
1614 printf(
"=========Supported Rule Protocols=========\n");
1631 static int SigParseProto(
Signature *s,
const char *protostr)
1634 if (strlen(protostr) >= 64)
1640 const char *h = NULL;
1642 bool has_hook = strchr(
proto,
':') != NULL;
1645 p = strtok_r(
proto,
":", &rem);
1649 if (
p == NULL || strlen(
p) == 0) {
1664 if (strlen(h) == 0) {
1668 if (SigParseProtoHookApp(s, protostr,
p, h) < 0) {
1669 SCLogError(
"protocol \"%s\" does not support hook \"%s\"",
p, h);
1676 "in a signature. Either detection for this protocol "
1677 "is not yet supported OR detection has been disabled for "
1678 "protocol through the yaml option "
1679 "app-layer.protocols.%s.detection-enabled",
1683 }
else if (h != NULL) {
1684 SCLogDebug(
"non-app-layer rule with %s:%s",
p, h);
1686 if (SigParseProtoHookPkt(s, protostr,
p, h) < 0) {
1687 SCLogError(
"protocol \"%s\" does not support hook \"%s\"",
p, h);
1716 Signature *s,
const char *portstr,
char flag)
1722 SCLogDebug(
"Port group \"%s\" to be parsed", portstr);
1725 if (strcasecmp(portstr,
"any") == 0)
1729 }
else if (flag == 1) {
1730 if (strcasecmp(portstr,
"any") == 0)
1745 static int SigParseActionRejectValidate(
const char *action)
1747 #ifdef HAVE_LIBNET11
1748 #if defined HAVE_LIBCAP_NG && !defined HAVE_LIBNET_CAPABILITIES
1751 "incompatible with POSIX based capabilities with privs dropping. "
1752 "For rejects to work, run as root/super user.");
1758 "required for action \"%s\" but is not compiled into Suricata",
1768 static uint8_t ActionStringToFlags(
const char *action)
1770 if (strcasecmp(action,
"alert") == 0) {
1772 }
else if (strcasecmp(action,
"drop") == 0) {
1774 }
else if (strcasecmp(action,
"pass") == 0) {
1776 }
else if (strcasecmp(action,
"reject") == 0 ||
1777 strcasecmp(action,
"rejectsrc") == 0)
1779 if (!(SigParseActionRejectValidate(action)))
1782 }
else if (strcasecmp(action,
"rejectdst") == 0) {
1783 if (!(SigParseActionRejectValidate(action)))
1786 }
else if (strcasecmp(action,
"rejectboth") == 0) {
1787 if (!(SigParseActionRejectValidate(action)))
1790 }
else if (strcasecmp(action,
"config") == 0) {
1792 }
else if (strcasecmp(action,
"accept") == 0) {
1795 SCLogError(
"An invalid action \"%s\" was given", action);
1811 static int SigParseActionDo(
const char *action_in,
const int idx,
const bool fw_rule,
1812 uint8_t *action_out, uint8_t *scope_out)
1815 strlcpy(action, action_in,
sizeof(action));
1816 const char *a = action;
1817 const char *o = NULL;
1819 bool has_scope = strchr(action,
':') != NULL;
1821 char *xsaveptr = NULL;
1822 a = strtok_r(action,
":", &xsaveptr);
1823 o = strtok_r(NULL,
":", &xsaveptr);
1827 SCLogError(
"invalid protocol specification '%s'", action_in);
1831 uint8_t
flags = ActionStringToFlags(a);
1844 SCLogError(
"only accept, config, drop and reject actions allowed as primary action "
1851 SCLogError(
"accept, config, drop and reject actions not allowed as secondary action "
1857 SCLogError(
"'pass' is only supported as a secondary action for 'accept'");
1864 uint8_t scope_flags = 0;
1866 if (strcmp(o,
"packet") == 0) {
1868 }
else if (strcmp(o,
"flow") == 0) {
1871 SCLogError(
"invalid action scope '%s' in action '%s': only 'packet' and 'flow' "
1877 if (strcmp(o,
"packet") == 0) {
1879 }
else if (strcmp(o,
"hook") == 0) {
1881 }
else if (strcmp(o,
"tx") == 0) {
1883 }
else if (strcmp(o,
"flow") == 0) {
1887 "invalid action scope '%s' in action '%s': only 'packet', 'flow', 'tx' and "
1893 if (strcmp(o,
"packet") == 0) {
1896 SCLogError(
"invalid action scope '%s' in action '%s': only 'packet' allowed", o,
1901 SCLogError(
"invalid action scope '%s' in action '%s': scope only supported for actions "
1902 "'drop', 'pass' and 'reject'",
1906 if (*scope_out != 0 && *scope_out != scope_flags) {
1907 SCLogError(
"multi-action rules cannot use different action scopes");
1910 *scope_out = scope_flags;
1915 SCLogError(
"invalid action scope '%s' in action '%s': only 'packet' and 'flow' allowed",
1922 if (fw_rule && *scope_out == 0) {
1923 SCLogError(
"firewall rules require setting an explicit action scope");
1928 SCLogError(
"'accept' action only supported for firewall rules");
1931 *action_out |=
flags;
1935 static int SigParseAction(
Signature *s,
const char *action_in)
1944 FatalError(
"could not duplicate opt string");
1947 char *xsaveptr = NULL;
1948 char *a = strtok_r(copy,
",", &xsaveptr);
1954 a = strtok_r(NULL,
",", &xsaveptr);
1975 static inline int SigParseToken(
char **input,
char *output,
1976 const size_t output_size)
1978 size_t len = *input == NULL ? 0 : strlen(*input);
1984 while (
len && isblank(**input)) {
1989 char *endptr = strpbrk(*input,
" \t\n\r");
1990 if (endptr != NULL) {
1993 strlcpy(output, *input, output_size);
2010 static inline int SigParseList(
char **input,
char *output,
2011 const size_t output_size)
2014 size_t len = *input != NULL ? strlen(*input) : 0;
2020 while (
len && isblank(**input)) {
2026 for (i = 0; i <
len; i++) {
2027 char c = (*input)[i];
2030 }
else if (c ==
']') {
2032 }
else if (c ==
' ') {
2043 strlcpy(output, *input, output_size);
2044 *input = *input + i + 1;
2064 SigParseToken(&index, parser->
action,
sizeof(parser->
action));
2070 SigParseList(&index, parser->
src,
sizeof(parser->
src));
2073 SigParseList(&index, parser->
sp,
sizeof(parser->
sp));
2079 SigParseList(&index, parser->
dst,
sizeof(parser->
dst));
2082 SigParseList(&index, parser->
dp,
sizeof(parser->
dp));
2085 if (index == NULL) {
2089 while (isspace(*index) || *index ==
'(') {
2092 bool closing =
false;
2093 for (
size_t i = strlen(index); i > 0; i--) {
2094 if (index[i - 1] ==
')') {
2096 index[i - 1] =
'\0';
2097 }
else if (isspace(index[i - 1])) {
2098 index[i - 1] =
'\0';
2115 if (SigParseAction(s, parser->
action) < 0)
2118 if (SigParseProto(s, parser->
protocol) < 0)
2121 if (strcmp(parser->
direction,
"<>") == 0) {
2123 }
else if (strcmp(parser->
direction,
"=>") == 0) {
2125 SCLogError(
"transactional bidirectional rules not supported for firewall rules");
2130 }
else if (strcmp(parser->
direction,
"->") != 0) {
2131 SCLogError(
"\"%s\" is not a valid direction modifier, "
2132 "\"->\" and \"<>\" are supported.",
2159 static inline bool CheckAscii(
const char *
str)
2161 for (
size_t i = 0; i < strlen(
str); i++) {
2162 if (
str[i] < 0x20) {
2164 if (
str[i] == 0x0a ||
str[i] == 0x0d ||
str[i] == 0x09) {
2168 }
else if (
str[i] == 0x7f) {
2192 if (!SCCheckUtf8(sigstr)) {
2197 if (!CheckAscii(sigstr)) {
2198 SCLogError(
"rule contains invalid (control) characters");
2202 int ret = SigParseBasics(
de_ctx, s, sigstr, parser, addrs_direction, requires);
2209 if (strlen(parser->
opts) > 0) {
2210 size_t buffer_size = strlen(parser->
opts) + 1;
2212 char input[buffer_size];
2213 char output[buffer_size];
2214 memset(input, 0x00, buffer_size);
2215 memcpy(input, parser->
opts, strlen(parser->
opts) + 1);
2221 memset(output, 0x00, buffer_size);
2222 ret = SigParseOptions(
de_ctx, s, input, output, buffer_size, requires);
2224 memcpy(input, output, buffer_size);
2256 memset(b, 0,
sizeof(*b));
2304 static void SigMetadataFree(
Signature *s)
2311 if (s == NULL || s->
metadata == NULL) {
2318 next_mdata = mdata->
next;
2349 next_ref = ref->
next;
2403 while (sm != NULL) {
2412 while (sm != NULL) {
2433 if (s->
sp != NULL) {
2436 if (s->
dp != NULL) {
2472 const uint8_t *set = NULL;
2474 switch (pol_class) {
2476 set = fw_packet_hook_scopes;
2480 set = fw_packet_pre_flow_hook_scopes;
2481 n =
ARRAY_SIZE(fw_packet_pre_flow_hook_scopes);
2484 set = fw_app_hook_scopes;
2488 FatalError(
"Invalid firewall policy class %u", (
unsigned)pol_class);
2490 for (
size_t i = 0; i < n; i++) {
2491 if (set[i] == scope) {
2501 static void FirewallScopeHintForClass(
2504 const uint8_t *set = NULL;
2506 switch (pol_class) {
2508 set = fw_packet_hook_scopes;
2512 set = fw_packet_pre_flow_hook_scopes;
2513 n =
ARRAY_SIZE(fw_packet_pre_flow_hook_scopes);
2516 set = fw_app_hook_scopes;
2520 FatalError(
"Invalid firewall policy class %u", (
unsigned)pol_class);
2523 for (
size_t i = 0; i < n; i++) {
2524 if ((i > 0 &&
strlcat(out,
"/", out_size) >= out_size) ||
2526 FatalError(
"firewall policy scope hint too long");
2546 if (s->
alproto == *alprotos) {
2589 }
else if (i == 1) {
2621 if (!AppProtoIsValid(alproto)) {
2645 alproto = AppProtoCommon(s->
alproto, alproto);
2647 SCLogError(
"can't set rule app proto to %s: already set to %s",
2674 if (addr_match4 == NULL) {
2680 addr_match4[idx].
ip =
SCNtohl(da->ip.addr_data32[0]);
2681 addr_match4[idx].
ip2 =
SCNtohl(da->ip2.addr_data32[0]);
2700 if (addr_match6 == NULL) {
2706 addr_match6[idx].
ip[0] =
SCNtohl(da->ip.addr_data32[0]);
2707 addr_match6[idx].
ip[1] =
SCNtohl(da->ip.addr_data32[1]);
2708 addr_match6[idx].
ip[2] =
SCNtohl(da->ip.addr_data32[2]);
2709 addr_match6[idx].
ip[3] =
SCNtohl(da->ip.addr_data32[3]);
2710 addr_match6[idx].
ip2[0] =
SCNtohl(da->ip2.addr_data32[0]);
2711 addr_match6[idx].
ip2[1] =
SCNtohl(da->ip2.addr_data32[1]);
2712 addr_match6[idx].
ip2[2] =
SCNtohl(da->ip2.addr_data32[2]);
2713 addr_match6[idx].
ip2[3] =
SCNtohl(da->ip2.addr_data32[3]);
2726 static void SigBuildAddressMatchArray(
Signature *s)
2743 static int SigMatchListLen(
SigMatch *sm)
2746 for (; sm != NULL; sm = sm->
next)
2757 int len = SigMatchListLen(
head);
2763 FatalError(
"initializing the detection engine failed");
2769 for (; sm != NULL; sm = sm->
next, smd++) {
2787 SCLogDebug(
"no prefilter for SIG_FLAG_FW_HOOK_LTE sig");
2814 SCLogDebug(
"s %u: no mpm; prefilter? de_ctx->prefilter_setting %u "
2815 "s->init_data->has_possible_prefilter %s",
2829 prefilter_list =
MIN(prefilter_list, sm->
type);
2839 if (sm->
type == prefilter_list) {
2856 static bool DetectRuleValidateTable(
const Signature *s)
2865 if (kw_tables_supported != 0 && (kw_tables_supported & table_as_flag) == 0) {
2866 SCLogError(
"rule %u uses hook \"%s\", but keyword \"%s\" doesn't support this hook",
2877 SCLogError(
"rule %u is loaded as a firewall rule, but does not specify an "
2884 !FirewallScopeValidForClass(
2888 SCLogError(
"rule %u: action scope (\"%s\") is not valid for the \"pre_flow\" hook. Valid "
2898 SCLogError(
"rule %u uses action scope \"packet\" for an non-UDP app hook",
2916 SCLogError(
"rule %u: auto-accept notation (<hook) can only be used with accept:flow, "
2917 "accept:tx and accept:hook",
2926 static void DetectRuleSetTable(
Signature *s)
2959 if (!DetectFirewallRuleValidate(
de_ctx, s))
2965 static int SigValidateCheckBuffers(
2968 bool has_frame =
false;
2969 bool has_app =
false;
2970 bool has_pkt =
false;
2971 bool has_pmatch =
false;
2977 nlists += (nlists > 0);
2981 SCLogError(
"rule %u setup buffer %s but didn't add matches to it", s->
id,
2995 struct BufferVsDir {
2998 } bufdir[nlists + 1];
2999 memset(&bufdir, 0, (nlists + 1) *
sizeof(
struct BufferVsDir));
3013 if (b->
head == NULL) {
3018 has_frame |= bt->
frame;
3024 "specific matches (like dsize, flags, ttl) with stream / "
3025 "state matching by matching on app layer proto (like using "
3026 "http_* keywords).");
3030 uint32_t app_buffers_evaluated = 0;
3031 bool buffer_consumed =
false;
3032 uint32_t buffer_skip_alproto = 0;
3033 uint32_t buffer_skip_substate = 0;
3035 for (; app != NULL; app = app->
next) {
3038 app_buffers_evaluated++;
3046 SCLogDebug(
"%u:%s: for buffer %s skip engine %s alproto %s", s->
id,
3050 buffer_skip_alproto++;
3055 buffer_skip_substate++;
3061 SCLogDebug(
"%u:%s: for buffer %s skip engine %s alproto %s", s->
id,
3065 buffer_skip_alproto++;
3082 bufdir[b->
id].ts += (app->
dir == 0);
3083 bufdir[b->
id].tc += (app->
dir == 1);
3095 SCLogError(
"engine progress value doesn't match hook");
3100 buffer_consumed =
true;
3102 if (app_buffers_evaluated && !buffer_consumed) {
3103 SCLogError(
"incompatible rule conditions, skipped buffer %s, reasons: app proto %u sub "
3105 bt->
name, buffer_skip_alproto, buffer_skip_substate);
3120 if (has_pmatch && has_frame) {
3121 SCLogError(
"can't mix pure content and frame inspection");
3124 if (has_app && has_frame) {
3125 SCLogError(
"can't mix app-layer buffer and frame inspection");
3128 if (has_pkt && has_frame) {
3129 SCLogError(
"can't mix pkt buffer and frame inspection");
3133 for (
int x = 0; x < nlists; x++) {
3134 if (bufdir[x].
ts == 0 && bufdir[x].tc == 0)
3136 (*ts_excl) += (bufdir[x].ts > 0 && bufdir[x].tc == 0);
3137 (*tc_excl) += (bufdir[x].ts == 0 && bufdir[x].tc > 0);
3138 (*dir_amb) += (bufdir[x].ts > 0 && bufdir[x].tc > 0);
3147 static int SigValidatePacketStream(
const Signature *s)
3151 "tcp-stream or flow:only_stream. Invalidating signature.");
3157 static int SigConsolidateDirection(
3158 Signature *s,
const int ts_excl,
const int tc_excl,
const int dir_amb)
3161 if (!ts_excl || !tc_excl) {
3162 SCLogError(
"rule %u should use both directions, but does not", s->
id);
3166 SCLogError(
"rule %u means to use both directions, cannot have keywords ambiguous about "
3171 }
else if (ts_excl && tc_excl) {
3173 "rule %u mixes keywords with conflicting directions, a transactional rule with => "
3177 }
else if (ts_excl) {
3178 SCLogDebug(
"%u: implied rule direction is toserver", s->
id);
3180 SCLogError(
"rule %u mixes keywords with conflicting directions", s->
id);
3183 }
else if (tc_excl) {
3184 SCLogDebug(
"%u: implied rule direction is toclient", s->
id);
3186 SCLogError(
"rule %u mixes keywords with conflicting directions", s->
id);
3189 }
else if (dir_amb) {
3190 SCLogDebug(
"%u: rule direction cannot be deduced from keywords", s->
id);
3195 static void SigConsolidateTcpBuffer(
Signature *s)
3227 static bool SigInspectsFiles(
const Signature *s)
3238 static int SigValidateFileHandling(
const Signature *s)
3240 if (!SigInspectsFiles(s)) {
3247 "support file matching",
3264 SCLogError(
"No protocol support file matching");
3269 SCLogError(
"protocol HTTP2 doesn't support file name matching");
3275 static bool SigValidateEthernet(
const Signature *s)
3280 SCLogError(
"can't use ports with ether or arp rule");
3288 static bool SigValidateProtoPkthdr(
const Signature *s)
3291 SCLogError(
"protocol 'pkthdr' is for decoder-events only");
3320 static int SigValidateConsolidate(
3325 if (SigValidateFirewall(
de_ctx, s) == 0)
3328 if (SigValidatePacketStream(s) == 0) {
3332 if (!SigValidateEthernet(s)) {
3340 if (SigValidateCheckBuffers(
de_ctx, s, &ts_excl, &tc_excl, &dir_amb) == 0) {
3344 if (SigConsolidateDirection(s, ts_excl, tc_excl, dir_amb) == 0) {
3348 SigConsolidateTcpBuffer(s);
3351 DetectRuleSetTable(s);
3353 if (!SigValidateProtoPkthdr(s)) {
3357 if (!SigValidateFlowbitUse(
de_ctx, s)) {
3364 int r = SigValidateFileHandling(s);
3368 if (SigInspectsFiles(s)) {
3373 if (DetectRuleValidateTable(s) ==
false) {
3396 memset(&parser, 0x00,
sizeof(parser));
3401 if (firewall_rule) {
3418 int ret = SigParse(
de_ctx, sig, sigstr, dir, &parser,
true);
3425 }
else if (ret < 0) {
3431 SCLogError(
"Signature missing required value \"sid\".");
3436 ret = SigParse(
de_ctx, sig, sigstr, dir, &parser,
false);
3442 }
else if (ret == -2) {
3445 }
else if (ret < 0) {
3450 if (sig->
prio == -1)
3457 int override_needed = 0;
3461 override_needed = 1;
3463 override_needed = 1;
3467 override_needed = 0;
3476 if (override_needed)
3486 for ( ; sm != NULL; sm = sm->
next) {
3510 SCLogDebug(
"sig %"PRIu32
" SIG_FLAG_APPLAYER: %s, SIG_FLAG_PACKET: %s",
3514 SigBuildAddressMatchArray(sig);
3525 SigSetupPrefilter(
de_ctx, sig);
3528 if (SigValidateConsolidate(
de_ctx, sig, &parser, dir) == 0) {
3547 static bool SigHasSameSourceAndDestination(
const Signature *s)
3589 if (SigHasSameSourceAndDestination(sig)) {
3590 SCLogInfo(
"Rule with ID %u is bidirectional, but source and destination are the same, "
3591 "treating the rule as unidirectional", sig->
id);
3596 if (sig->
next == NULL) {
3626 return SigInitDo(
de_ctx, sigstr,
false);
3631 return SigInitDo(
de_ctx, sigstr,
true);
3640 static void DetectParseDupSigFreeFunc(
void *data)
3656 static uint32_t DetectParseDupSigHashFunc(
HashListTable *ht,
void *data, uint16_t datalen)
3675 static char DetectParseDupSigCompareFunc(
void *data1, uint16_t len1,
void *data2,
3681 if (sw1 == NULL || sw2 == NULL ||
3682 sw1->
s == NULL || sw2->
s == NULL)
3686 if (sw1->
s->
id == sw2->
s->
id && sw1->
s->
gid == sw2->
s->
gid)
return 1;
3702 DetectParseDupSigHashFunc,
3703 DetectParseDupSigCompareFunc,
3704 DetectParseDupSigFreeFunc);
3765 if (sw_dup == NULL) {
3778 (
void *)&sw_tmp, 0);
3792 if (sw->
s->
rev <= sw_dup->
s->
rev) {
3801 if (sw_dup->
s_prev == NULL) {
3809 sw_temp.
s = sw_dup->
s->
next;
3813 if (sw_temp.
s != NULL) {
3815 (
void *)&sw_temp, 0);
3836 sw_temp.
s = sw_dup->
s->
next;
3844 if (sw_temp.
s != NULL) {
3846 (
void *)&sw_temp, 0);
3862 (
void *)&sw_tmp, 0);
3864 if (sw_old->
s != sw_dup->
s) {
3907 int dup_sig = DetectEngineSignatureIsDuplicate(
de_ctx, sig);
3911 SCLogError(
"Duplicate signature \"%s\"", sigstr);
3913 }
else if (dup_sig == 2) {
3915 " so the older sig replaced by this new signature \"%s\"",
3920 if (sig->
next != NULL) {
3937 return (dup_sig == 0 || dup_sig == 2) ? sig : NULL;
3941 if (sig != NULL && sig->
next != NULL) {
3979 int dup_sig = DetectEngineSignatureIsDuplicate(
de_ctx, sig);
3983 SCLogError(
"Duplicate signature \"%s\"", sigstr);
3985 }
else if (dup_sig == 2) {
3987 " so the older sig replaced by this new signature \"%s\"",
3992 if (sig->
next != NULL) {
4009 return (dup_sig == 0 || dup_sig == 2) ? sig : NULL;
4013 if (sig != NULL && sig->
next != NULL) {
4026 int start_offset,
int options)
4028 *match = pcre2_match_data_create_from_pattern(parse_regex->
regex, NULL);
4030 return pcre2_match(parse_regex->
regex, (PCRE2_SPTR8)
str, strlen(
str), options, start_offset,
4031 *match, parse_regex->
context);
4038 pcre2_code_free(r->
regex);
4041 pcre2_match_context_free(r->
context);
4056 g_detect_parse_regex_list = NULL;
4065 FatalError(
"failed to alloc memory for pcre free list");
4068 r->
next = g_detect_parse_regex_list;
4069 g_detect_parse_regex_list = r;
4077 detect_parse->
regex =
4078 pcre2_compile((PCRE2_SPTR8)parse_str, PCRE2_ZERO_TERMINATED, opts, &en, &eo, NULL);
4079 if (detect_parse->
regex == NULL) {
4080 PCRE2_UCHAR errbuffer[256];
4081 pcre2_get_error_message(en, errbuffer,
sizeof(errbuffer));
4082 SCLogError(
"pcre compile of \"%s\" failed at "
4084 parse_str, en, errbuffer);
4087 detect_parse->
context = pcre2_match_context_create(NULL);
4088 if (detect_parse->
context == NULL) {
4089 SCLogError(
"pcre2 could not create match context");
4090 pcre2_code_free(detect_parse->
regex);
4091 detect_parse->
regex = NULL;
4106 if (detect_parse == NULL) {
4110 detect_parse->
regex =
4111 pcre2_compile((PCRE2_SPTR8)parse_str, PCRE2_ZERO_TERMINATED, opts, &en, &eo, NULL);
4112 if (detect_parse->
regex == NULL) {
4113 PCRE2_UCHAR errbuffer[256];
4114 pcre2_get_error_message(en, errbuffer,
sizeof(errbuffer));
4115 SCLogError(
"pcre2 compile of \"%s\" failed at "
4117 parse_str, (
int)eo, errbuffer);
4122 detect_parse->
next = g_detect_parse_regex_list;
4123 g_detect_parse_regex_list = detect_parse;
4124 return detect_parse;
4128 pcre2_match_data *match_data, uint32_t number, PCRE2_UCHAR *buffer, PCRE2_SIZE *bufflen)
4130 int r = pcre2_substring_copy_bynumber(match_data, number, buffer, bufflen);
4131 if (r == PCRE2_ERROR_UNSET) {
4140 pcre2_match_data *match_data, uint32_t number, PCRE2_UCHAR **bufferptr, PCRE2_SIZE *bufflen)
4142 int r = pcre2_substring_get_bynumber(match_data, number, bufferptr, bufflen);
4143 if (r == PCRE2_ERROR_UNSET) {
4158 static uint32_t AppPolicyHashFunc(
HashTable *ht,
void *data, uint16_t datalen)
4162 uint32_t hash =
p->alproto * 65537 +
p->sub_state * 257 +
p->progress * 5 +
4163 (
p->direction == STREAM_TOSERVER);
4164 hash ^= (hash >> 10) ^ (hash >> 20);
4168 static char AppPolicyCompareFunc(
void *data1, uint16_t datalen1,
void *data2, uint16_t datalen2)
4173 if (p1 == NULL || p2 == NULL)
4180 static void AppPolicyHashFree(
void *data)
4217 snprintf(out, out_size,
"rejectdst:%s", as);
4219 snprintf(out, out_size,
"rejectboth:%s", as);
4221 snprintf(out, out_size,
"rejectsrc:%s", as);
4224 snprintf(out, out_size,
"drop:%s", as);
4226 snprintf(out, out_size,
"accept:%s", as);
4232 strlcat(out,
",pass:flow", out_size);
4238 strlcat(out,
",alert", out_size);
4260 snprintf(msg,
sizeof(msg),
"SURICATA FW default packet policy");
4262 if (s->
msg == NULL) {
4286 snprintf(msg,
sizeof(msg),
"SURICATA FW default app policy");
4288 if (s->
msg == NULL) {
4314 if (policy_actions == NULL) {
4315 SCLogDebug(
"fw: no policy at %s", policy_name);
4320 uint8_t action_scope = 0;
4325 if (SigParseActionDo(paction->
val, idx,
true, &action, &action_scope) < 0)
4331 SCLogError(
"%s: 'config' is not a valid default policy action", policy_name);
4348 char *path = chain->path[chain->len];
4355 FatalError(
"%s: firewall YAML config path formatting failed", fmt);
4358 FatalError(
"%s: firewall YAML config path too long", path);
4361 for (uint8_t i = 0; i < chain->len; i++) {
4362 if (strcmp(chain->path[i], path) == 0)
4382 for (uint8_t i = 0; i < chain->
len; i++) {
4383 const char *path = chain->
path[i];
4385 int r = DoParsePolicy(path, &tmp);
4391 SCLogError(
"%s: policy is set but empty", path);
4394 if (!FirewallScopeValidForClass(tmp.
action_scope, pol_class)) {
4396 FirewallScopeHintForClass(pol_class, hint,
sizeof(hint));
4397 SCLogError(
"%s: action scope (\"%s\") is not valid. Valid scopes: %s", path,
4408 static void FirewallHookNameConvertUnderscoreToDash(
const char *in,
char *out,
size_t out_size)
4410 if (
strlcpy(out, in, out_size) >= out_size) {
4411 FatalError(
"%s: firewall policy config name too long", in);
4413 for (
size_t i = 0; out[i] !=
'\0'; i++) {
4425 static int DoParseAppPolicy(
const char *prefix,
const AppProto app_proto,
const uint8_t sub_state,
4426 const char *sub_state_name,
const char *hookname,
const uint8_t state,
4427 const uint8_t complete_state,
const int direction,
4431 if (app_proto_str == NULL) {
4432 SCLogError(
"Unknown app proto %u", (
unsigned)app_proto);
4438 if (hookname != NULL) {
4439 FirewallHookNameConvertUnderscoreToDash(hookname, hook,
sizeof(hook));
4444 if (sub_state_name != NULL) {
4446 FirewallHookNameConvertUnderscoreToDash(sub_state_name, sub + 1,
sizeof(sub) - 1);
4450 if (hookname != NULL) {
4452 FirewallPolicyChainAdd(&chain,
"%s.app.%s%s.%s", prefix, app_proto_str, sub, hook);
4454 if (generic_hook != NULL) {
4456 FirewallPolicyChainAdd(&chain,
"%s.app.%s%s.%s", prefix, app_proto_str, sub, generic_hook);
4459 FirewallPolicyChainAdd(&chain,
"%s.app.%s%s.default-policy", prefix, app_proto_str, sub);
4461 FirewallPolicyChainAdd(&chain,
"%s.app.%s.default-policy", prefix, app_proto_str);
4463 FirewallPolicyChainAdd(&chain,
"%s.app.default-policy", prefix);
4465 FirewallPolicyChainAdd(&chain,
"%s.default-policy", prefix);
4468 if (app_pol == NULL)
4487 FatalError(
"internal error: insert policy into hash table");
4493 return AddAppPolicySignature(app_pol);
4503 if (fw_policies == NULL)
4506 HashTableInit(512, AppPolicyHashFunc, AppPolicyCompareFunc, AppPolicyHashFree);
4534 FirewallPolicyChainAdd(&chain,
"%s.packet.%s", prefix, leaf);
4536 FirewallPolicyChainAdd(&chain,
"%s.packet.default-policy", prefix);
4538 FirewallPolicyChainAdd(&chain,
"%s.default-policy", prefix);
4544 int r = ResolveFirewallPolicy(pol, pol_class, &chain);
4549 return AddPktPolicySignature(fw_policies, pol,
id);
4557 static int DetectFirewallLoadPacketPolicies(
4560 if (DetectFirewallLoadPacketPolicy(
4563 if (DetectFirewallLoadPacketPolicy(
4566 if (DetectFirewallLoadPacketPolicy(
4589 {
ALPROTO_SSH,
"request-in-progress",
"request-banner" },
4590 {
ALPROTO_SSH,
"request-banner-wait-eol",
"request-banner" },
4591 {
ALPROTO_SSH,
"request-banner-done",
"request-kex" },
4592 {
ALPROTO_SSH,
"request-finished",
"request-session" },
4593 {
ALPROTO_SSH,
"response-in-progress",
"response-banner" },
4594 {
ALPROTO_SSH,
"response-banner-wait-eol",
"response-banner" },
4595 {
ALPROTO_SSH,
"response-banner-done",
"response-kex" },
4596 {
ALPROTO_SSH,
"response-finished",
"response-session" },
4597 {
ALPROTO_TLS,
"client-in-progress",
"client-started" },
4598 {
ALPROTO_TLS,
"client-hello-done",
"client-hello" },
4599 {
ALPROTO_TLS,
"client-cert-done",
"client-cert" },
4600 {
ALPROTO_TLS,
"client-handshake-done",
"client-data" },
4601 {
ALPROTO_TLS,
"server-in-progress",
"server-started" },
4602 {
ALPROTO_TLS,
"server-hello-done",
"server-data" },
4603 {
ALPROTO_TLS,
"server-cert-done",
"server-cert" },
4604 {
ALPROTO_TLS,
"server-handshake-done",
"server-data" },
4628 static bool FwPolicyKeyIsNonState(
const char *key)
4630 return strcmp(key,
"default-policy") == 0 || strcmp(key,
"request-started") == 0 ||
4631 strcmp(key,
"response-started") == 0 || strcmp(key,
"request-complete") == 0 ||
4632 strcmp(key,
"response-complete") == 0;
4635 static bool FwPolicyStateKeyIsKnown(
AppProto a,
const char *sub_state_name,
const char *key)
4638 if (FwPolicyKeyIsNonState(key)) {
4643 const uint8_t dirs[2] = { STREAM_TOSERVER, STREAM_TOCLIENT };
4645 if (sub_state_name == NULL) {
4646 for (
size_t d = 0; d < 2; d++) {
4648 for (uint8_t state = 0; state <= complete; state++) {
4657 FirewallHookNameConvertUnderscoreToDash(
name, dash,
sizeof(dash));
4658 if (strcmp(dash, key) == 0) {
4667 for (uint8_t s = 1; s <= max_sub_state; s++) {
4669 if (sub_name == NULL || strcmp(sub_name, sub_state_name) != 0) {
4673 for (
size_t d = 0; d < 2; d++) {
4674 for (uint8_t state = 0; state <= max_state; state++) {
4680 FirewallHookNameConvertUnderscoreToDash(
name, dash,
sizeof(dash));
4681 if (strcmp(dash, key) == 0) {
4710 static bool FirewallPolicyNodeIsMapping(
const SCConfNode *node)
4715 if (c->
name == NULL) {
4718 for (
const char *
p = c->
name; *
p;
p++) {
4719 if (*p < '0' || *p >
'9') {
4729 static bool FirewallPolicyNodeIsList(
const SCConfNode *node)
4737 if (c->
name == NULL) {
4740 for (
const char *
p = c->
name; *
p;
p++) {
4741 if (*p < '0' || *p >
'9') {
4749 static int WarnUnmatchedFirewallPolicyStateKeys(
4750 const char *prefix,
AppProto a,
const char *sub_state_name)
4753 if (
proto == NULL) {
4758 if (sub_state_name != NULL) {
4760 FirewallHookNameConvertUnderscoreToDash(sub_state_name, sub + 1,
sizeof(sub) - 1);
4764 const size_t path_len = strlen(prefix) + strlen(
proto) + strlen(sub) + 6;
4769 snprintf(path, path_len,
"%s.app.%s%s", prefix,
proto, sub);
4778 int known_wrong_keys = 0;
4780 if (c->
name == NULL) {
4784 if (sub_state_name == NULL) {
4790 bool is_sub_state_section =
false;
4791 if (c->head.tqh_first != NULL) {
4798 FirewallHookNameConvertUnderscoreToDash(sn, dash,
sizeof(dash));
4799 if (strcmp(dash, c->
name) == 0)
4800 is_sub_state_section =
true;
4803 if (is_sub_state_section)
4816 strcmp(c->
name,
"default-policy") == 0);
4817 if (consulted && FwPolicyStateKeyIsKnown(a, sub_state_name, c->
name)) {
4821 const char *hint = NULL;
4822 for (
size_t i = 0; i <
ARRAY_SIZE(g_fw_policy_state_rename_hints); i++) {
4823 if (g_fw_policy_state_rename_hints[i].
proto == a &&
4824 strcmp(c->
name, g_fw_policy_state_rename_hints[i].old_name) == 0) {
4825 hint = g_fw_policy_state_rename_hints[i].
new_name;
4832 SCLogError(
"firewall policy: key '%s' under %s matches no %s state: "
4833 "a state previously named '%s' was renamed to '%s' "
4834 "in this release - use the new name",
4838 SCLogWarning(
"firewall policy: key '%s' under %s matches no %s state "
4844 return known_wrong_keys;
4849 char prefix[96] =
"firewall.policies";
4855 if (fw_policies == NULL)
4858 if (DetectFirewallLoadPacketPolicies(fw_policies, prefix) < 0)
4861 int known_wrong_keys = 0;
4863 if (!AppProtoIsValid(a))
4869 for (uint8_t s = 1; s <= max_sub_state; s++) {
4873 if (sub_state_name == NULL)
4880 for (uint8_t state = 0; state <= max_state; state++) {
4882 sub_state_name, state);
4883 const char *state_name =
4885 BUG_ON(state_name == NULL);
4887 sub_state_name, state_name);
4888 if (DoParseAppPolicy(prefix, a, s, sub_state_name, state_name, state, max_state,
4889 STREAM_TOSERVER, fw_policies) < 0)
4893 for (uint8_t state = 0; state <= max_state; state++) {
4895 sub_state_name, state);
4896 const char *state_name =
4898 BUG_ON(state_name == NULL);
4900 sub_state_name, state_name);
4901 if (DoParseAppPolicy(prefix, a, s, sub_state_name, state_name, state, max_state,
4902 STREAM_TOCLIENT, fw_policies) < 0)
4906 known_wrong_keys += WarnUnmatchedFirewallPolicyStateKeys(prefix, a, sub_state_name);
4913 if (proto_name != NULL) {
4914 const size_t path_len = strlen(prefix) + 5 + strlen(proto_name) + 1;
4915 char *proto_path =
SCMalloc(path_len);
4916 if (proto_path != NULL) {
4917 snprintf(proto_path, path_len,
"%s.app.%s", prefix, proto_name);
4919 if (proto_node != NULL) {
4929 if (sc->
name == NULL || sc->head.tqh_first == NULL ||
4930 FirewallPolicyNodeIsList(sc) ||
4931 FwPolicyKeyIsNonState(sc->
name)) {
4934 bool known_section =
false;
4935 for (uint8_t s2 = 1; s2 <= max_sub_state; s2++) {
4941 FirewallHookNameConvertUnderscoreToDash(sn, dash,
sizeof(dash));
4942 if (strcmp(dash, sc->
name) == 0) {
4943 known_section =
true;
4947 if (!known_section) {
4948 SCLogWarning(
"firewall policy: sub-state section '%s' "
4949 "under %s matches no %s sub-state and is "
4951 sc->
name, proto_path, proto_name);
4961 known_wrong_keys += WarnUnmatchedFirewallPolicyStateKeys(prefix, a, NULL);
4963 const uint8_t complete_state_ts =
4965 a, STREAM_TOSERVER);
4966 for (uint8_t state = 0; state <= complete_state_ts; state++) {
4969 if (DoParseAppPolicy(prefix, a, 0, NULL,
name, state, complete_state_ts,
4970 STREAM_TOSERVER, fw_policies) < 0)
4973 const uint8_t complete_state_tc =
4975 a, STREAM_TOCLIENT);
4976 for (uint8_t state = 0; state <= complete_state_tc; state++) {
4979 if (DoParseAppPolicy(prefix, a, 0, NULL,
name, state, complete_state_tc,
4980 STREAM_TOCLIENT, fw_policies) < 0)
4984 known_wrong_keys += WarnUnmatchedFirewallPolicyStateKeys(prefix, a, NULL);
4987 if (known_wrong_keys) {
4991 "known to be renamed - fix the keys and retry",
5005 static int SigParseTest01 (
void)
5014 sig =
SigInit(
de_ctx,
"alert tcp 1.2.3.4 any -> !1.2.3.4 any (msg:\"SigParseTest01\"; sid:1;)");
5024 static int SigParseTest02 (
void)
5039 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;)");
5067 static int SigParseTest03 (
void)
5076 sig =
SigInit(
de_ctx,
"alert tcp 1.2.3.4 any <- !1.2.3.4 any (msg:\"SigParseTest03\"; sid:1;)");
5079 printf(
"expected NULL got sig ptr %p: ",sig);
5088 static int SigParseTest04 (
void)
5097 sig =
SigInit(
de_ctx,
"alert tcp 1.2.3.4 1024: -> !1.2.3.4 1024: (msg:\"SigParseTest04\"; sid:1;)");
5108 static int SigParseTest05 (
void)
5117 sig =
SigInit(
de_ctx,
"alert tcp 1.2.3.4 1024:65536 -> !1.2.3.4 any (msg:\"SigParseTest05\"; sid:1;)");
5121 printf(
"signature didn't fail to parse as we expected: ");
5131 static int SigParseTest06 (
void)
5140 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;)");
5144 printf(
"signature failed to parse: ");
5158 static int SigParseTest07(
void)
5180 static int SigParseTest08(
void)
5203 static int SigParseTest09(
void)
5254 static int SigParseTest10(
void)
5286 static int SigParseTest11(
void)
5297 "drop tcp any any -> any 80 (msg:\"Snort_Inline is blocking the http link\"; sid:1;) ");
5299 printf(
"sig 1 didn't parse: ");
5304 "the http link\"; sid:2;) ");
5306 printf(
"sig 2 didn't parse: ");
5320 static int SigParseTest12(
void)
5332 printf(
"sig 1 should have given an error: ");
5346 static int SigParseTest13(
void)
5358 printf(
"sig 1 invalidated: failure");
5363 printf(
"sig doesn't have stream flag set\n");
5368 printf(
"sig has packet flag set\n");
5383 static int SigParseTest14(
void)
5395 printf(
"sig 1 invalidated: failure");
5400 printf(
"sig doesn't have packet flag set\n");
5405 printf(
"sig has stream flag set\n");
5420 static int SigParseTest15(
void)
5432 printf(
"sig 1 invalidated: failure");
5437 printf(
"sig doesn't have packet flag set\n");
5442 printf(
"sig doesn't have stream flag set\n");
5457 static int SigParseTest16(
void)
5469 printf(
"sig 1 invalidated: failure");
5474 printf(
"sig doesn't have packet flag set\n");
5479 printf(
"sig doesn't have stream flag set\n");
5494 static int SigParseTest17(
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");
5529 static int SigParseTest18 (
void)
5537 if (
DetectEngineAppendSig(
de_ctx,
"alert tcp 1.2.3.4 any -> !1.2.3.4 any (msg:\"SigParseTest01\"; sid:99999999999999999999;)") != NULL)
5548 static int SigParseTest19 (
void)
5556 if (
DetectEngineAppendSig(
de_ctx,
"alert tcp 1.2.3.4 any -> !1.2.3.4 any (msg:\"SigParseTest01\"; sid:1; gid:99999999999999999999;)") != NULL)
5567 static int SigParseTest20 (
void)
5575 if (
DetectEngineAppendSig(
de_ctx,
"alert tcp 1.2.3.4 any -> !1.2.3.4 any (msg:\"SigParseTest01\"; sid:1; rev:99999999999999999999;)") != NULL)
5586 static int SigParseTest21 (
void)
5605 static int SigParseTest22 (
void)
5613 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)
5626 static int SigParseTest23(
void)
5641 static int SigParseBidirecTest06 (
void)
5661 static int SigParseBidirecTest07 (
void)
5681 static int SigParseBidirecTest08 (
void)
5701 static int SigParseBidirecTest09 (
void)
5721 static int SigParseBidirecTest10 (
void)
5741 static int SigParseBidirecTest11 (
void)
5761 static int SigParseBidirecTest12 (
void)
5781 static int SigParseBidirecTest13 (
void)
5800 static int SigParseBidirecTest14 (
void)
5821 static int SigTestBidirec01 (
void)
5833 if (sig->
next != NULL)
5852 static int SigTestBidirec02 (
void)
5871 if (sig->
next == NULL)
5876 if (copy->
next != NULL)
5897 static int SigTestBidirec03 (
void)
5909 const char *sigs[3];
5910 sigs[0] =
"alert tcp any any -> 192.168.1.1 any (msg:\"SigTestBidirec03 sid 1\"; sid:1;)";
5911 sigs[1] =
"alert tcp any any <> 192.168.1.1 any (msg:\"SigTestBidirec03 sid 2 bidirectional\"; sid:2;)";
5912 sigs[2] =
"alert tcp any any -> 192.168.1.1 any (msg:\"SigTestBidirec03 sid 3\"; sid:3;)";
5919 if (sig->
next == NULL)
5930 uint8_t rawpkt1_ether[] = {
5931 0x00,0x50,0x56,0xea,0x00,0xbd,0x00,0x0c,
5932 0x29,0x40,0xc8,0xb5,0x08,0x00,0x45,0x00,
5933 0x01,0xa8,0xb9,0xbb,0x40,0x00,0x40,0x06,
5934 0xe0,0xbf,0xc0,0xa8,0x1c,0x83,0xc0,0xa8,
5935 0x01,0x01,0xb9,0x0a,0x00,0x50,0x6f,0xa2,
5936 0x92,0xed,0x7b,0xc1,0xd3,0x4d,0x50,0x18,
5937 0x16,0xd0,0xa0,0x6f,0x00,0x00,0x47,0x45,
5938 0x54,0x20,0x2f,0x20,0x48,0x54,0x54,0x50,
5939 0x2f,0x31,0x2e,0x31,0x0d,0x0a,0x48,0x6f,
5940 0x73,0x74,0x3a,0x20,0x31,0x39,0x32,0x2e,
5941 0x31,0x36,0x38,0x2e,0x31,0x2e,0x31,0x0d,
5942 0x0a,0x55,0x73,0x65,0x72,0x2d,0x41,0x67,
5943 0x65,0x6e,0x74,0x3a,0x20,0x4d,0x6f,0x7a,
5944 0x69,0x6c,0x6c,0x61,0x2f,0x35,0x2e,0x30,
5945 0x20,0x28,0x58,0x31,0x31,0x3b,0x20,0x55,
5946 0x3b,0x20,0x4c,0x69,0x6e,0x75,0x78,0x20,
5947 0x78,0x38,0x36,0x5f,0x36,0x34,0x3b,0x20,
5948 0x65,0x6e,0x2d,0x55,0x53,0x3b,0x20,0x72,
5949 0x76,0x3a,0x31,0x2e,0x39,0x2e,0x30,0x2e,
5950 0x31,0x34,0x29,0x20,0x47,0x65,0x63,0x6b,
5951 0x6f,0x2f,0x32,0x30,0x30,0x39,0x30,0x39,
5952 0x30,0x32,0x31,0x37,0x20,0x55,0x62,0x75,
5953 0x6e,0x74,0x75,0x2f,0x39,0x2e,0x30,0x34,
5954 0x20,0x28,0x6a,0x61,0x75,0x6e,0x74,0x79,
5955 0x29,0x20,0x46,0x69,0x72,0x65,0x66,0x6f,
5956 0x78,0x2f,0x33,0x2e,0x30,0x2e,0x31,0x34,
5957 0x0d,0x0a,0x41,0x63,0x63,0x65,0x70,0x74,
5958 0x3a,0x20,0x74,0x65,0x78,0x74,0x2f,0x68,
5959 0x74,0x6d,0x6c,0x2c,0x61,0x70,0x70,0x6c,
5960 0x69,0x63,0x61,0x74,0x69,0x6f,0x6e,0x2f,
5961 0x78,0x68,0x74,0x6d,0x6c,0x2b,0x78,0x6d,
5962 0x6c,0x2c,0x61,0x70,0x70,0x6c,0x69,0x63,
5963 0x61,0x74,0x69,0x6f,0x6e,0x2f,0x78,0x6d,
5964 0x6c,0x3b,0x71,0x3d,0x30,0x2e,0x39,0x2c,
5965 0x2a,0x2f,0x2a,0x3b,0x71,0x3d,0x30,0x2e,
5966 0x38,0x0d,0x0a,0x41,0x63,0x63,0x65,0x70,
5967 0x74,0x2d,0x4c,0x61,0x6e,0x67,0x75,0x61,
5968 0x67,0x65,0x3a,0x20,0x65,0x6e,0x2d,0x75,
5969 0x73,0x2c,0x65,0x6e,0x3b,0x71,0x3d,0x30,
5970 0x2e,0x35,0x0d,0x0a,0x41,0x63,0x63,0x65,
5971 0x70,0x74,0x2d,0x45,0x6e,0x63,0x6f,0x64,
5972 0x69,0x6e,0x67,0x3a,0x20,0x67,0x7a,0x69,
5973 0x70,0x2c,0x64,0x65,0x66,0x6c,0x61,0x74,
5974 0x65,0x0d,0x0a,0x41,0x63,0x63,0x65,0x70,
5975 0x74,0x2d,0x43,0x68,0x61,0x72,0x73,0x65,
5976 0x74,0x3a,0x20,0x49,0x53,0x4f,0x2d,0x38,
5977 0x38,0x35,0x39,0x2d,0x31,0x2c,0x75,0x74,
5978 0x66,0x2d,0x38,0x3b,0x71,0x3d,0x30,0x2e,
5979 0x37,0x2c,0x2a,0x3b,0x71,0x3d,0x30,0x2e,
5980 0x37,0x0d,0x0a,0x4b,0x65,0x65,0x70,0x2d,
5981 0x41,0x6c,0x69,0x76,0x65,0x3a,0x20,0x33,
5982 0x30,0x30,0x0d,0x0a,0x43,0x6f,0x6e,0x6e,
5983 0x65,0x63,0x74,0x69,0x6f,0x6e,0x3a,0x20,
5984 0x6b,0x65,0x65,0x70,0x2d,0x61,0x6c,0x69,
5985 0x76,0x65,0x0d,0x0a,0x0d,0x0a };
5995 uint32_t sids[3] = {1, 2, 3};
5996 uint32_t results[3] = {1, 1, 1};
6012 static int SigTestBidirec04 (
void)
6027 sig =
DetectEngineAppendSig(
de_ctx,
"alert tcp 192.168.1.1 any <> any any (msg:\"SigTestBidirec03 sid 2 bidirectional\"; sid:2;)");
6032 if (sig->
next == NULL)
6044 if (sig->
next == NULL)
6055 uint8_t rawpkt1_ether[] = {
6056 0x00,0x50,0x56,0xea,0x00,0xbd,0x00,0x0c,
6057 0x29,0x40,0xc8,0xb5,0x08,0x00,0x45,0x00,
6058 0x01,0xa8,0xb9,0xbb,0x40,0x00,0x40,0x06,
6059 0xe0,0xbf,0xc0,0xa8,0x1c,0x83,0xc0,0xa8,
6060 0x01,0x01,0xb9,0x0a,0x00,0x50,0x6f,0xa2,
6061 0x92,0xed,0x7b,0xc1,0xd3,0x4d,0x50,0x18,
6062 0x16,0xd0,0xa0,0x6f,0x00,0x00,0x47,0x45,
6063 0x54,0x20,0x2f,0x20,0x48,0x54,0x54,0x50,
6064 0x2f,0x31,0x2e,0x31,0x0d,0x0a,0x48,0x6f,
6065 0x73,0x74,0x3a,0x20,0x31,0x39,0x32,0x2e,
6066 0x31,0x36,0x38,0x2e,0x31,0x2e,0x31,0x0d,
6067 0x0a,0x55,0x73,0x65,0x72,0x2d,0x41,0x67,
6068 0x65,0x6e,0x74,0x3a,0x20,0x4d,0x6f,0x7a,
6069 0x69,0x6c,0x6c,0x61,0x2f,0x35,0x2e,0x30,
6070 0x20,0x28,0x58,0x31,0x31,0x3b,0x20,0x55,
6071 0x3b,0x20,0x4c,0x69,0x6e,0x75,0x78,0x20,
6072 0x78,0x38,0x36,0x5f,0x36,0x34,0x3b,0x20,
6073 0x65,0x6e,0x2d,0x55,0x53,0x3b,0x20,0x72,
6074 0x76,0x3a,0x31,0x2e,0x39,0x2e,0x30,0x2e,
6075 0x31,0x34,0x29,0x20,0x47,0x65,0x63,0x6b,
6076 0x6f,0x2f,0x32,0x30,0x30,0x39,0x30,0x39,
6077 0x30,0x32,0x31,0x37,0x20,0x55,0x62,0x75,
6078 0x6e,0x74,0x75,0x2f,0x39,0x2e,0x30,0x34,
6079 0x20,0x28,0x6a,0x61,0x75,0x6e,0x74,0x79,
6080 0x29,0x20,0x46,0x69,0x72,0x65,0x66,0x6f,
6081 0x78,0x2f,0x33,0x2e,0x30,0x2e,0x31,0x34,
6082 0x0d,0x0a,0x41,0x63,0x63,0x65,0x70,0x74,
6083 0x3a,0x20,0x74,0x65,0x78,0x74,0x2f,0x68,
6084 0x74,0x6d,0x6c,0x2c,0x61,0x70,0x70,0x6c,
6085 0x69,0x63,0x61,0x74,0x69,0x6f,0x6e,0x2f,
6086 0x78,0x68,0x74,0x6d,0x6c,0x2b,0x78,0x6d,
6087 0x6c,0x2c,0x61,0x70,0x70,0x6c,0x69,0x63,
6088 0x61,0x74,0x69,0x6f,0x6e,0x2f,0x78,0x6d,
6089 0x6c,0x3b,0x71,0x3d,0x30,0x2e,0x39,0x2c,
6090 0x2a,0x2f,0x2a,0x3b,0x71,0x3d,0x30,0x2e,
6091 0x38,0x0d,0x0a,0x41,0x63,0x63,0x65,0x70,
6092 0x74,0x2d,0x4c,0x61,0x6e,0x67,0x75,0x61,
6093 0x67,0x65,0x3a,0x20,0x65,0x6e,0x2d,0x75,
6094 0x73,0x2c,0x65,0x6e,0x3b,0x71,0x3d,0x30,
6095 0x2e,0x35,0x0d,0x0a,0x41,0x63,0x63,0x65,
6096 0x70,0x74,0x2d,0x45,0x6e,0x63,0x6f,0x64,
6097 0x69,0x6e,0x67,0x3a,0x20,0x67,0x7a,0x69,
6098 0x70,0x2c,0x64,0x65,0x66,0x6c,0x61,0x74,
6099 0x65,0x0d,0x0a,0x41,0x63,0x63,0x65,0x70,
6100 0x74,0x2d,0x43,0x68,0x61,0x72,0x73,0x65,
6101 0x74,0x3a,0x20,0x49,0x53,0x4f,0x2d,0x38,
6102 0x38,0x35,0x39,0x2d,0x31,0x2c,0x75,0x74,
6103 0x66,0x2d,0x38,0x3b,0x71,0x3d,0x30,0x2e,
6104 0x37,0x2c,0x2a,0x3b,0x71,0x3d,0x30,0x2e,
6105 0x37,0x0d,0x0a,0x4b,0x65,0x65,0x70,0x2d,
6106 0x41,0x6c,0x69,0x76,0x65,0x3a,0x20,0x33,
6107 0x30,0x30,0x0d,0x0a,0x43,0x6f,0x6e,0x6e,
6108 0x65,0x63,0x74,0x69,0x6f,0x6e,0x3a,0x20,
6109 0x6b,0x65,0x65,0x70,0x2d,0x61,0x6c,0x69,
6110 0x76,0x65,0x0d,0x0a,0x0d,0x0a };
6159 static int SigParseTestNegation01 (
void)
6173 static int SigParseTestNegation02 (
void)
6179 "alert tcp any !any -> any any (msg:\"SigTest41-02 src ip is !any \"; "
6180 "classtype:misc-activity; sid:410002; rev:1;)");
6188 static int SigParseTestNegation03 (
void)
6194 "alert tcp any any -> any [80:!80] (msg:\"SigTest41-03 dst port [80:!80] \"; "
6195 "classtype:misc-activity; sid:410003; rev:1;)");
6203 static int SigParseTestNegation04 (
void)
6214 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;)");
6229 static int SigParseTestNegation05 (
void)
6240 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;)");
6255 static int SigParseTestNegation06 (
void)
6266 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;)");
6282 static int SigParseTestNegation07 (
void)
6288 de_ctx,
"alert tcp any any -> [192.168.0.2,!192.168.0.0/24] any (sid:410006;)");
6297 static int SigParseTestNegation08 (
void)
6309 "alert tcp any any -> [192.168.0.0/16,!192.168.0.0/24] any (sid:410006; rev:1;)");
6324 static int SigParseTestMpm01 (
void)
6333 sig =
SigInit(
de_ctx,
"alert tcp any any -> any any (msg:\"mpm test\"; content:\"abcd\"; sid:1;)");
6335 printf(
"sig failed to init: ");
6340 printf(
"sig doesn't have content list: ");
6355 static int SigParseTestMpm02 (
void)
6364 sig =
SigInit(
de_ctx,
"alert tcp any any -> any any (msg:\"mpm test\"; content:\"abcd\"; content:\"abcdef\"; sid:1;)");
6366 printf(
"sig failed to init: ");
6371 printf(
"sig doesn't have content list: ");
6386 static int SigParseTestAppLayerTLS01(
void)
6397 s =
SigInit(
de_ctx,
"alert tls any any -> any any (msg:\"SigParseTestAppLayerTLS01 \"; sid:410006; rev:1;)");
6399 printf(
"parsing sig failed: ");
6404 printf(
"alproto not set: ");
6421 static int SigParseTestAppLayerTLS02(
void)
6432 s =
SigInit(
de_ctx,
"alert tls any any -> any any (msg:\"SigParseTestAppLayerTLS02 \"; tls.version:1.0; sid:410006; rev:1;)");
6434 printf(
"parsing sig failed: ");
6439 printf(
"alproto not set: ");
6455 static int SigParseTestAppLayerTLS03(
void)
6462 "alert tls any any -> any any (msg:\"SigParseTestAppLayerTLS03 \"; "
6463 "tls.version:2.5; sid:410006; rev:1;)");
6469 static int SigParseTestUnbalancedQuotes01(
void)
6475 "alert http any any -> any any (msg:\"SigParseTestUnbalancedQuotes01\"; "
6476 "pcre:\"/\\/[a-z]+\\.php\\?[a-z]+?=\\d{7}&[a-z]+?=\\d{7,8}$/U\" "
6477 "flowbits:set,et.exploitkitlanding; classtype:trojan-activity; sid:2017078; rev:5;)");
6483 static int SigParseTestContentGtDsize01(
void)
6490 "dsize:21; content:\"0123456789001234567890|00 00|\"; "
6497 static int SigParseTestContentGtDsize02(
void)
6504 "dsize:21; content:\"0123456789|00 00|\"; offset:10; "
6521 static int SigParseBidirWithSameSrcAndDest01(
void)
6538 "alert tcp [1.2.3.4, 5.6.7.8] [80, 81] <> [5.6.7.8, 1.2.3.4] [81, 80] (sid:3;)");
6547 static int SigParseBidirWithSameSrcAndDest02(
void)
6555 de_ctx,
"alert tcp 1.2.3.4 any <> [1.2.3.4, 5.6.7.8, ::1] any (sid:1;)");
6562 de_ctx,
"alert tcp [1.2.3.4, ::1] [80, 81, 82] <> [1.2.3.4, ::1] [80, 81] (sid:2;)");
6569 "alert tcp [1.2.3.4, ::1, ABCD:AAAA::1] [80] <> [1.2.3.4, ::1] [80, 81] (sid:3;)");
6576 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;)");
6583 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;)");
6592 static int SigParseTestActionReject(
void)
6598 de_ctx,
"reject tcp 1.2.3.4 any -> !1.2.3.4 any (msg:\"SigParseTest01\"; sid:1;)");
6599 #ifdef HAVE_LIBNET11
6610 static int SigParseTestActionDrop(
void)
6616 de_ctx,
"drop tcp 1.2.3.4 any -> !1.2.3.4 any (msg:\"SigParseTest01\"; sid:1;)");
6624 static int SigSetMultiAppProto(
void)
6699 static int DetectSetupDirection01(
void)
6704 char *
str = (
char *)
"to_client";
6705 FAIL_IF(DetectSetupDirection(s, &
str,
true) < 0);
6710 static int DetectSetupDirection02(
void)
6714 char *
str = (
char *)
"to_server";
6715 FAIL_IF(DetectSetupDirection(s, &
str,
true) < 0);
6717 str = (
char *)
"to_client";
6718 FAIL_IF(DetectSetupDirection(s, &
str,
true) >= 0);
6724 static int DetectSetupDirection03(
void)
6728 char *
str = (
char *)
"to_client , something";
6729 FAIL_IF(DetectSetupDirection(s, &
str,
false) < 0);
6731 str = (
char *)
"to_client,something";
6732 FAIL_IF(DetectSetupDirection(s, &
str,
false) < 0);
6738 static int DetectSetupDirection04(
void)
6743 char *
str = (
char *)
"to_client_toto";
6744 FAIL_IF(DetectSetupDirection(s, &
str,
true) >= 0);
6746 str = (
char *)
"to_client_toto";
6747 FAIL_IF(DetectSetupDirection(s, &
str,
false) < 0);
6749 str = (
char *)
"to_client,something";
6751 FAIL_IF(DetectSetupDirection(s, &
str,
true) >= 0);
6788 UtRegisterTest(
"SigParseTest21 -- address with space", SigParseTest21);
6789 UtRegisterTest(
"SigParseTest22 -- address with space", SigParseTest22);
6790 UtRegisterTest(
"SigParseTest23 -- carriage return", SigParseTest23);
6805 UtRegisterTest(
"SigParseTestNegation01", SigParseTestNegation01);
6806 UtRegisterTest(
"SigParseTestNegation02", SigParseTestNegation02);
6807 UtRegisterTest(
"SigParseTestNegation03", SigParseTestNegation03);
6808 UtRegisterTest(
"SigParseTestNegation04", SigParseTestNegation04);
6809 UtRegisterTest(
"SigParseTestNegation05", SigParseTestNegation05);
6810 UtRegisterTest(
"SigParseTestNegation06", SigParseTestNegation06);
6811 UtRegisterTest(
"SigParseTestNegation07", SigParseTestNegation07);
6812 UtRegisterTest(
"SigParseTestNegation08", SigParseTestNegation08);
6815 UtRegisterTest(
"SigParseTestAppLayerTLS01", SigParseTestAppLayerTLS01);
6816 UtRegisterTest(
"SigParseTestAppLayerTLS02", SigParseTestAppLayerTLS02);
6817 UtRegisterTest(
"SigParseTestAppLayerTLS03", SigParseTestAppLayerTLS03);
6818 UtRegisterTest(
"SigParseTestUnbalancedQuotes01", SigParseTestUnbalancedQuotes01);
6821 SigParseTestContentGtDsize01);
6823 SigParseTestContentGtDsize02);
6826 SigParseBidirWithSameSrcAndDest01);
6828 SigParseBidirWithSameSrcAndDest02);
6829 UtRegisterTest(
"SigParseTestActionReject", SigParseTestActionReject);
6830 UtRegisterTest(
"SigParseTestActionDrop", SigParseTestActionDrop);
6834 UtRegisterTest(
"DetectSetupDirection01", DetectSetupDirection01);
6835 UtRegisterTest(
"DetectSetupDirection02", DetectSetupDirection02);
6836 UtRegisterTest(
"DetectSetupDirection03", DetectSetupDirection03);
6837 UtRegisterTest(
"DetectSetupDirection04", DetectSetupDirection04);