83 static void SigMatchTransferSigMatchAcrossLists(
SigMatch *sm,
114 #define CASE_CODE_STRING(E, S) case E: return S; break
125 #undef CASE_CODE_STRING
129 #define CASE_CODE(E) case E: return #E
147 Signature *s,
const char *arg,
int sm_type,
int sm_list,
153 if (arg != NULL && strcmp(arg,
"") != 0) {
162 "with a sticky buffer still set. Reset sticky buffer "
163 "with pkt_data before using the modifier.",
177 "found inside the rule without a content context. "
178 "Please use a \"content\" keyword before using the "
186 "be used with the rawbytes rule keyword",
192 "be used with the replace rule keyword",
231 bool reuse_buffer =
false;
244 SCLogError(
"failed to expand rule buffer array");
253 SCLogDebug(
"idx %u list %d set up curbuf %p s->init_data->buffer_index %u",
294 if (sm->
ctx != NULL) {
305 ptrdiff_t
offset = e - table;
319 if (st->
name != NULL) {
351 if (strcmp(
str,
"all") == 0) {
363 char *xsaveptr = NULL;
364 char *key = strtok_r(copy,
",", &xsaveptr);
365 while (key != NULL) {
371 "argument '%s' not found",
374 key = strtok_r(NULL,
",", &xsaveptr);
401 SCLogDebug(
"s:%p new:%p list:%d: %s, s->init_data->list_set %s s->init_data->list %d", s,
new,
435 SCLogDebug(
"reusing buffer %u as it isn't multi-capable", x);
445 SCLogError(
"failed to expand rule buffer array");
475 SCLogDebug(
"appended %s to list %d, rule pos %u (s->init_data->list %d)",
494 if (sm->
prev != NULL)
496 if (sm->
next != NULL)
538 if (sm_last == NULL || sm_new->
idx > sm_last->
idx)
550 if (sm_last == NULL || sm_new->
idx > sm_last->
idx)
572 SCLogDebug(
"skip x %u s->init_data->list %d (int)s->init_data->buffers[x].id %d", x,
581 for (sm_type = va_arg(ap,
int); sm_type != -1; sm_type = va_arg(ap,
int)) {
585 if (sm_last == NULL || sm_new->
idx > sm_last->
idx)
602 for (sm_type = va_arg(ap,
int); sm_type != -1; sm_type = va_arg(ap,
int))
607 if (sm_last == NULL || sm_new->
idx > sm_last->
idx)
632 va_start(ap, sm_list);
634 for (sm_type = va_arg(ap,
int); sm_type != -1; sm_type = va_arg(ap,
int))
636 sm_new = SigMatchGetLastSMByType(sm_list, sm_type);
639 if (sm_last == NULL || sm_new->
idx > sm_last->
idx)
670 va_start(ap, list_id);
672 for (sm_type = va_arg(ap,
int); sm_type != -1; sm_type = va_arg(ap,
int)) {
676 if (sm_last == NULL || sm_new->
idx > sm_last->
idx)
688 va_start(ap, list_id);
690 for (sm_type = va_arg(ap,
int); sm_type != -1; sm_type = va_arg(ap,
int)) {
691 sm_new = SigMatchGetLastSMByType(sm_list, sm_type);
694 if (sm_last == NULL || sm_new->
idx > sm_last->
idx)
717 if (sm_last == NULL || sm_new->
idx > sm_last->
idx)
725 if (sm_last == NULL || sm_new->
idx > sm_last->
idx)
732 static void SigMatchTransferSigMatchAcrossLists(
SigMatch *sm,
738 if (sm->
prev != NULL)
740 if (sm->
next != NULL)
743 if (sm == *src_sm_list)
744 *src_sm_list = sm->
next;
745 if (sm == *src_sm_list_tail)
746 *src_sm_list_tail = sm->
prev;
748 if (*dst_sm_list == NULL) {
750 *dst_sm_list_tail = sm;
758 *dst_sm_list_tail = sm;
785 SCLogError(
"Unable to find the sm in any of the "
799 static int DetectSetupDirection(
Signature *s,
char **
str,
bool only_dir)
802 if (strncmp(*
str,
"to_client", strlen(
"to_client")) == 0) {
803 *
str += strlen(
"to_client");
805 while (**
str && isblank(**
str)) {
811 SCLogError(
"unknown option: only accepts to_server or to_client");
821 while (**
str && isblank(**
str)) {
833 }
else if (strncmp(*
str,
"to_server", strlen(
"to_server")) == 0) {
834 *
str += strlen(
"to_server");
836 while (**
str && isblank(**
str)) {
842 SCLogError(
"unknown option: only accepts to_server or to_client");
852 while (**
str && isblank(**
str)) {
864 }
else if (only_dir) {
865 SCLogError(
"unknown option: only accepts to_server or to_client");
872 size_t output_size,
bool requires)
875 char *optname = NULL;
876 char *optvalue = NULL;
879 while (isblank(*optstr)) {
884 char *optend = optstr;
886 optend = strchr(optend,
';');
887 if (optend == NULL) {
891 else if (optend > optstr && *(optend -1 ) ==
'\\') {
900 char *optvalptr = strchr(optstr,
':');
902 *(optvalptr++) =
'\0';
905 for (
size_t i = strlen(optvalptr); i > 0; i--) {
906 if (isblank(optvalptr[i - 1])) {
907 optvalptr[i - 1] =
'\0';
913 optvalue = optvalptr;
917 for (
size_t i = strlen(optstr); i > 0; i--) {
918 if (isblank(optstr[i - 1])) {
919 optstr[i - 1] =
'\0';
928 bool requires_only = strcasecmp(optname,
"requires") == 0 || strcasecmp(optname,
"sid") == 0;
929 if ((requires && !requires_only) || (!requires && requires_only)) {
934 st = SigTableGet(optname);
935 if (st == NULL || st->
Setup == NULL) {
936 SCLogError(
"unknown rule keyword '%s'.", optname);
941 if (optvalue == NULL || strlen(optvalue) == 0) {
943 "invalid formatting or malformed option to %s keyword: '%s'", optname, optstr);
947 if (optvalue && strlen(optvalue)) {
948 SCLogError(
"unexpected option to %s keyword: '%s'", optname, optstr);
958 #define URL "https://suricata.io/our-story/deprecation-policy/"
961 "and will be removed soon. See %s",
965 "and will be removed soon. Use '%s' instead. "
974 if (optvalue != NULL && strlen(optvalue) > 0) {
975 size_t ovlen = strlen(optvalue);
976 char *ptr = optvalue;
986 SCLogError(
"invalid formatting or malformed option to %s keyword: \'%s\'", optname,
992 SCLogWarning(
"keyword \'%s\' has not been tested for firewall rules", optname);
1009 SCLogError(
"invalid formatting or malformed option to %s keyword: \'%s\'", optname,
1015 SCLogError(
"invalid formatting to %s keyword: "
1016 "value must be double quoted \'%s\'",
1022 && ovlen && *ptr ==
'"')
1024 for (; ovlen > 0; ovlen--) {
1025 if (isblank(ptr[ovlen - 1])) {
1026 ptr[ovlen - 1] =
'\0';
1031 if (ovlen && ptr[ovlen - 1] !=
'"') {
1032 SCLogError(
"bad option value formatting (possible missing semicolon) "
1033 "for keyword %s: \'%s\'",
1041 ptr[ovlen - 1] =
'\0';
1046 "for keyword %s: \'%s\'",
1053 "quotes on %s keyword that doesn't support them: \'%s\'", optname, optstr);
1071 if (setup_ret < 0) {
1075 if (setup_ret == -2) {
1087 if (strlen(optend) > 0) {
1088 strlcpy(output, optend, output_size);
1103 Signature *s,
const char *addrstr,
char flag)
1105 SCLogDebug(
"Address Group \"%s\" to be parsed now", addrstr);
1109 if (strcasecmp(addrstr,
"any") == 0)
1117 if (strcasecmp(addrstr,
"any") == 0)
1132 static bool IsBuiltIn(
const char *n)
1134 return strcmp(n,
"request_started") == 0 || strcmp(n,
"response_started") == 0 ||
1135 strcmp(n,
"request_complete") == 0 || strcmp(n,
"response_complete") == 0;
1150 if (strcmp(alproto_name,
"http") == 0)
1151 alproto_name =
"http1";
1152 SCLogDebug(
"alproto %u/%s", a, alproto_name);
1154 const int max_progress_ts =
1156 const int max_progress_tc =
1159 char ts_tx_started[64];
1160 snprintf(ts_tx_started,
sizeof(ts_tx_started),
"%s:request_started:generic", alproto_name);
1163 SCLogDebug(
"- hook %s:%s list %s (%u)", alproto_name,
"request_name", ts_tx_started,
1164 (uint32_t)strlen(ts_tx_started));
1166 char tc_tx_started[64];
1167 snprintf(tc_tx_started,
sizeof(tc_tx_started),
"%s:response_started:generic", alproto_name);
1170 SCLogDebug(
"- hook %s:%s list %s (%u)", alproto_name,
"response_name", tc_tx_started,
1171 (uint32_t)strlen(tc_tx_started));
1173 char ts_tx_complete[64];
1174 snprintf(ts_tx_complete,
sizeof(ts_tx_complete),
"%s:request_complete:generic",
1178 SCLogDebug(
"- hook %s:%s list %s (%u)", alproto_name,
"request_name", ts_tx_complete,
1179 (uint32_t)strlen(ts_tx_complete));
1181 char tc_tx_complete[64];
1182 snprintf(tc_tx_complete,
sizeof(tc_tx_complete),
"%s:response_complete:generic",
1186 SCLogDebug(
"- hook %s:%s list %s (%u)", alproto_name,
"response_name", tc_tx_complete,
1187 (uint32_t)strlen(tc_tx_complete));
1189 for (
int p = 0; p <= max_progress_ts; p++) {
1191 IPPROTO_TCP , a, p, STREAM_TOSERVER);
1192 if (
name != NULL && !IsBuiltIn(
name)) {
1194 snprintf(list_name,
sizeof(list_name),
"%s:%s:generic", alproto_name,
name);
1195 SCLogDebug(
"- hook %s:%s list %s (%u)", alproto_name,
name, list_name,
1196 (uint32_t)strlen(list_name));
1202 for (
int p = 0; p <= max_progress_tc; p++) {
1204 IPPROTO_TCP , a, p, STREAM_TOCLIENT);
1205 if (
name != NULL && !IsBuiltIn(
name)) {
1207 snprintf(list_name,
sizeof(list_name),
"%s:%s:generic", alproto_name,
name);
1208 SCLogDebug(
"- hook %s:%s list %s (%u)", alproto_name,
name, list_name,
1209 (uint32_t)strlen(list_name));
1235 if (strcmp(
str,
"flow_start") == 0) {
1237 }
else if (strcmp(
str,
"pre_flow") == 0) {
1239 }
else if (strcmp(
str,
"pre_stream") == 0) {
1241 }
else if (strcmp(
str,
"all") == 0) {
1254 return "flow_start";
1258 return "pre_stream";
1270 .t.pkt.ph = HookPktFromString(hook_str),
1278 static int SigParseProtoHookPkt(
Signature *s,
const char *proto_hook,
const char *p,
const char *h)
1291 SCLogDebug(
"protocol:%s hook:%s: type:%s parsed hook:%s", p, h,
1301 .t.app.alproto = alproto,
1302 .t.app.app_progress = progress,
1310 static int SigParseProtoHookApp(
Signature *s,
const char *proto_hook,
const char *p,
const char *h)
1312 if (strcmp(h,
"request_started") == 0) {
1316 }
else if (strcmp(h,
"response_started") == 0) {
1320 }
else if (strcmp(h,
"request_complete") == 0) {
1324 }
else if (strcmp(h,
"response_complete") == 0) {
1330 IPPROTO_TCP , s->
alproto, h, STREAM_TOSERVER);
1331 if (progress_ts >= 0) {
1336 IPPROTO_TCP , s->
alproto, h, STREAM_TOCLIENT);
1337 if (progress_tc < 0) {
1345 char generic_hook_name[64];
1346 snprintf(generic_hook_name,
sizeof(generic_hook_name),
"%s:generic", proto_hook);
1349 SCLogError(
"no list registered as %s for hook %s", generic_hook_name, proto_hook);
1354 SCLogDebug(
"protocol:%s hook:%s: type:%s alproto:%u hook:%d", p, h,
1364 printf(
"=========Supported Rule Protocols=========\n");
1381 static int SigParseProto(
Signature *s,
const char *protostr)
1384 if (strlen(protostr) > 32)
1389 const char *p =
proto;
1390 const char *h = NULL;
1392 bool has_hook = strchr(
proto,
':') != NULL;
1394 char *xsaveptr = NULL;
1395 p = strtok_r(
proto,
":", &xsaveptr);
1396 h = strtok_r(NULL,
":", &xsaveptr);
1414 if (SigParseProtoHookApp(s, protostr, p, h) < 0) {
1415 SCLogError(
"protocol \"%s\" does not support hook \"%s\"", p, h);
1422 "in a signature. Either detection for this protocol "
1423 "is not yet supported OR detection has been disabled for "
1424 "protocol through the yaml option "
1425 "app-layer.protocols.%s.detection-enabled",
1429 }
else if (h != NULL) {
1430 SCLogDebug(
"non-app-layer rule with %s:%s", p, h);
1432 if (SigParseProtoHookPkt(s, protostr, p, h) < 0) {
1433 SCLogError(
"protocol \"%s\" does not support hook \"%s\"", p, h);
1462 Signature *s,
const char *portstr,
char flag)
1468 SCLogDebug(
"Port group \"%s\" to be parsed", portstr);
1471 if (strcasecmp(portstr,
"any") == 0)
1475 }
else if (flag == 1) {
1476 if (strcasecmp(portstr,
"any") == 0)
1491 static int SigParseActionRejectValidate(
const char *action)
1493 #ifdef HAVE_LIBNET11
1494 #if defined HAVE_LIBCAP_NG && !defined HAVE_LIBNET_CAPABILITIES
1497 "incompatible with POSIX based capabilities with privs dropping. "
1498 "For rejects to work, run as root/super user.");
1504 "required for action \"%s\" but is not compiled into Suricata",
1514 static uint8_t ActionStringToFlags(
const char *action)
1516 if (strcasecmp(action,
"alert") == 0) {
1518 }
else if (strcasecmp(action,
"drop") == 0) {
1520 }
else if (strcasecmp(action,
"pass") == 0) {
1522 }
else if (strcasecmp(action,
"reject") == 0 ||
1523 strcasecmp(action,
"rejectsrc") == 0)
1525 if (!(SigParseActionRejectValidate(action)))
1528 }
else if (strcasecmp(action,
"rejectdst") == 0) {
1529 if (!(SigParseActionRejectValidate(action)))
1532 }
else if (strcasecmp(action,
"rejectboth") == 0) {
1533 if (!(SigParseActionRejectValidate(action)))
1536 }
else if (strcasecmp(action,
"config") == 0) {
1538 }
else if (strcasecmp(action,
"accept") == 0) {
1541 SCLogError(
"An invalid action \"%s\" was given", action);
1557 static int SigParseActionDo(
const char *action_in,
const int idx,
const bool fw_rule,
1558 uint8_t *action_out, uint8_t *scope_out)
1561 strlcpy(action, action_in,
sizeof(action));
1562 const char *a = action;
1563 const char *o = NULL;
1565 bool has_scope = strchr(action,
':') != NULL;
1567 char *xsaveptr = NULL;
1568 a = strtok_r(action,
":", &xsaveptr);
1569 o = strtok_r(NULL,
":", &xsaveptr);
1573 SCLogError(
"invalid protocol specification '%s'", action_in);
1577 uint8_t
flags = ActionStringToFlags(a);
1584 SCLogError(
"only accept, config, drop and reject actions allowed as primary action "
1591 SCLogError(
"accept, config, drop and reject actions not allowed as secondary action "
1600 uint8_t scope_flags = 0;
1602 if (strcmp(o,
"packet") == 0) {
1604 }
else if (strcmp(o,
"flow") == 0) {
1607 SCLogError(
"invalid action scope '%s' in action '%s': only 'packet' and 'flow' "
1613 if (strcmp(o,
"packet") == 0) {
1615 }
else if (strcmp(o,
"hook") == 0) {
1617 }
else if (strcmp(o,
"tx") == 0) {
1619 }
else if (strcmp(o,
"flow") == 0) {
1623 "invalid action scope '%s' in action '%s': only 'packet', 'flow', 'tx' and "
1629 if (strcmp(o,
"packet") == 0) {
1632 SCLogError(
"invalid action scope '%s' in action '%s': only 'packet' allowed", o,
1637 SCLogError(
"invalid action scope '%s' in action '%s': scope only supported for actions "
1638 "'drop', 'pass' and 'reject'",
1642 if (*scope_out != 0 && *scope_out != scope_flags) {
1643 SCLogError(
"multi-action rules cannot use different action scopes");
1646 *scope_out = scope_flags;
1650 if (fw_rule && *scope_out == 0) {
1651 SCLogError(
"firewall rules require setting an explicit action scope");
1656 SCLogError(
"'accept' action only supported for firewall rules");
1659 *action_out |=
flags;
1663 static int SigParseAction(
Signature *s,
const char *action_in)
1672 FatalError(
"could not duplicate opt string");
1675 char *xsaveptr = NULL;
1676 char *a = strtok_r(copy,
",", &xsaveptr);
1682 a = strtok_r(NULL,
",", &xsaveptr);
1703 static inline int SigParseToken(
char **input,
char *output,
1704 const size_t output_size)
1706 size_t len = *input == NULL ? 0 : strlen(*input);
1712 while (
len && isblank(**input)) {
1717 char *endptr = strpbrk(*input,
" \t\n\r");
1718 if (endptr != NULL) {
1721 strlcpy(output, *input, output_size);
1738 static inline int SigParseList(
char **input,
char *output,
1739 const size_t output_size)
1742 size_t len = *input != NULL ? strlen(*input) : 0;
1748 while (
len && isblank(**input)) {
1754 for (i = 0; i <
len; i++) {
1755 char c = (*input)[i];
1758 }
else if (c ==
']') {
1760 }
else if (c ==
' ') {
1771 strlcpy(output, *input, output_size);
1772 *input = *input + i + 1;
1792 SigParseToken(&index, parser->
action,
sizeof(parser->
action));
1798 SigParseList(&index, parser->
src,
sizeof(parser->
src));
1801 SigParseList(&index, parser->
sp,
sizeof(parser->
sp));
1807 SigParseList(&index, parser->
dst,
sizeof(parser->
dst));
1810 SigParseList(&index, parser->
dp,
sizeof(parser->
dp));
1813 if (index == NULL) {
1817 while (isspace(*index) || *index ==
'(') {
1820 for (
size_t i = strlen(index); i > 0; i--) {
1821 if (isspace(index[i - 1]) || index[i - 1] ==
')') {
1822 index[i - 1] =
'\0';
1834 if (SigParseAction(s, parser->
action) < 0)
1837 if (SigParseProto(s, parser->
protocol) < 0)
1840 if (strcmp(parser->
direction,
"<>") == 0) {
1842 }
else if (strcmp(parser->
direction,
"=>") == 0) {
1844 SCLogError(
"transactional bidirectional rules not supported for firewall rules");
1849 }
else if (strcmp(parser->
direction,
"->") != 0) {
1850 SCLogError(
"\"%s\" is not a valid direction modifier, "
1851 "\"->\" and \"<>\" are supported.",
1878 static inline bool CheckAscii(
const char *
str)
1880 for (
size_t i = 0; i < strlen(
str); i++) {
1881 if (
str[i] < 0x20) {
1883 if (
str[i] == 0x0a ||
str[i] == 0x0d ||
str[i] == 0x09) {
1887 }
else if (
str[i] == 0x7f) {
1911 if (!SCCheckUtf8(sigstr)) {
1916 if (!CheckAscii(sigstr)) {
1917 SCLogError(
"rule contains invalid (control) characters");
1921 int ret = SigParseBasics(
de_ctx, s, sigstr, parser, addrs_direction, requires);
1928 if (strlen(parser->
opts) > 0) {
1929 size_t buffer_size = strlen(parser->
opts) + 1;
1931 char input[buffer_size];
1932 char output[buffer_size];
1933 memset(input, 0x00, buffer_size);
1934 memcpy(input, parser->
opts, strlen(parser->
opts) + 1);
1940 memset(output, 0x00, buffer_size);
1941 ret = SigParseOptions(
de_ctx, s, input, output, buffer_size, requires);
1943 memcpy(input, output, buffer_size);
1975 memset(b, 0,
sizeof(*b));
2023 static void SigMetadataFree(
Signature *s)
2030 if (s == NULL || s->
metadata == NULL) {
2037 next_mdata = mdata->
next;
2068 next_ref = ref->
next;
2122 while (sm != NULL) {
2131 while (sm != NULL) {
2152 if (s->
sp != NULL) {
2155 if (s->
dp != NULL) {
2204 if (s->
alproto == *alprotos) {
2247 }
else if (i == 1) {
2279 if (!AppProtoIsValid(alproto)) {
2303 alproto = AppProtoCommon(s->
alproto, alproto);
2305 SCLogError(
"can't set rule app proto to %s: already set to %s",
2332 if (addr_match4 == NULL) {
2338 addr_match4[idx].
ip =
SCNtohl(da->ip.addr_data32[0]);
2339 addr_match4[idx].
ip2 =
SCNtohl(da->ip2.addr_data32[0]);
2358 if (addr_match6 == NULL) {
2364 addr_match6[idx].
ip[0] =
SCNtohl(da->ip.addr_data32[0]);
2365 addr_match6[idx].
ip[1] =
SCNtohl(da->ip.addr_data32[1]);
2366 addr_match6[idx].
ip[2] =
SCNtohl(da->ip.addr_data32[2]);
2367 addr_match6[idx].
ip[3] =
SCNtohl(da->ip.addr_data32[3]);
2368 addr_match6[idx].
ip2[0] =
SCNtohl(da->ip2.addr_data32[0]);
2369 addr_match6[idx].
ip2[1] =
SCNtohl(da->ip2.addr_data32[1]);
2370 addr_match6[idx].
ip2[2] =
SCNtohl(da->ip2.addr_data32[2]);
2371 addr_match6[idx].
ip2[3] =
SCNtohl(da->ip2.addr_data32[3]);
2384 static void SigBuildAddressMatchArray(
Signature *s)
2401 static int SigMatchListLen(
SigMatch *sm)
2404 for (; sm != NULL; sm = sm->
next)
2415 int len = SigMatchListLen(
head);
2421 FatalError(
"initializing the detection engine failed");
2427 for (; sm != NULL; sm = sm->
next, smd++) {
2467 SCLogDebug(
"s %u: no mpm; prefilter? de_ctx->prefilter_setting %u "
2468 "s->init_data->has_possible_prefilter %s",
2482 prefilter_list =
MIN(prefilter_list, sm->
type);
2492 if (sm->
type == prefilter_list) {
2509 static bool DetectRuleValidateTable(
const Signature *s)
2518 if (kw_tables_supported != 0 && (kw_tables_supported & table_as_flag) == 0) {
2519 SCLogError(
"rule %u uses hook \"%s\", but keyword \"%s\" doesn't support this hook",
2530 SCLogError(
"rule %u is loaded as a firewall rule, but does not specify an "
2540 SCLogError(
"rule %u uses action scope \"packet\" for an non-UDP app hook",
2557 static void DetectRuleSetTable(
Signature *s)
2590 if (!DetectFirewallRuleValidate(
de_ctx, s))
2596 static int SigValidateCheckBuffers(
2599 bool has_frame =
false;
2600 bool has_app =
false;
2601 bool has_pkt =
false;
2602 bool has_pmatch =
false;
2608 nlists += (nlists > 0);
2612 SCLogError(
"rule %u setup buffer %s but didn't add matches to it", s->
id,
2626 struct BufferVsDir {
2629 } bufdir[nlists + 1];
2630 memset(&bufdir, 0, (nlists + 1) *
sizeof(
struct BufferVsDir));
2644 if (b->
head == NULL) {
2649 has_frame |= bt->
frame;
2655 "specific matches (like dsize, flags, ttl) with stream / "
2656 "state matching by matching on app layer proto (like using "
2657 "http_* keywords).");
2662 for (; app != NULL; app = app->
next) {
2677 bufdir[b->
id].ts += (app->
dir == 0);
2678 bufdir[b->
id].tc += (app->
dir == 1);
2692 SCLogError(
"engine progress value doesn't match hook");
2711 if (has_pmatch && has_frame) {
2712 SCLogError(
"can't mix pure content and frame inspection");
2715 if (has_app && has_frame) {
2716 SCLogError(
"can't mix app-layer buffer and frame inspection");
2719 if (has_pkt && has_frame) {
2720 SCLogError(
"can't mix pkt buffer and frame inspection");
2724 for (
int x = 0; x < nlists; x++) {
2725 if (bufdir[x].
ts == 0 && bufdir[x].tc == 0)
2727 (*ts_excl) += (bufdir[x].ts > 0 && bufdir[x].tc == 0);
2728 (*tc_excl) += (bufdir[x].ts == 0 && bufdir[x].tc > 0);
2729 (*dir_amb) += (bufdir[x].ts > 0 && bufdir[x].tc > 0);
2738 static int SigValidatePacketStream(
const Signature *s)
2742 "tcp-stream or flow:only_stream. Invalidating signature.");
2748 static int SigConsolidateDirection(
2749 Signature *s,
const int ts_excl,
const int tc_excl,
const int dir_amb)
2752 if (!ts_excl || !tc_excl) {
2753 SCLogError(
"rule %u should use both directions, but does not", s->
id);
2757 SCLogError(
"rule %u means to use both directions, cannot have keywords ambiguous about "
2762 }
else if (ts_excl && tc_excl) {
2764 "rule %u mixes keywords with conflicting directions, a transactional rule with => "
2768 }
else if (ts_excl) {
2769 SCLogDebug(
"%u: implied rule direction is toserver", s->
id);
2771 SCLogError(
"rule %u mixes keywords with conflicting directions", s->
id);
2774 }
else if (tc_excl) {
2775 SCLogDebug(
"%u: implied rule direction is toclient", s->
id);
2777 SCLogError(
"rule %u mixes keywords with conflicting directions", s->
id);
2780 }
else if (dir_amb) {
2781 SCLogDebug(
"%u: rule direction cannot be deduced from keywords", s->
id);
2786 static void SigConsolidateTcpBuffer(
Signature *s)
2818 static bool SigInspectsFiles(
const Signature *s)
2829 static int SigValidateFileHandling(
const Signature *s)
2831 if (!SigInspectsFiles(s)) {
2838 "support file matching",
2855 SCLogError(
"No protocol support file matching");
2860 SCLogError(
"protocol HTTP2 doesn't support file name matching");
2866 static bool SigValidateEthernet(
const Signature *s)
2871 SCLogError(
"can't use ports with ether or arp rule");
2879 static bool SigValidateProtoPkthdr(
const Signature *s)
2882 SCLogError(
"protocol 'pkthdr' is for decoder-events only");
2898 static int SigValidateConsolidate(
2903 if (SigValidateFirewall(
de_ctx, s) == 0)
2906 if (SigValidatePacketStream(s) == 0) {
2910 if (!SigValidateEthernet(s)) {
2918 if (SigValidateCheckBuffers(
de_ctx, s, &ts_excl, &tc_excl, &dir_amb) == 0) {
2922 if (SigConsolidateDirection(s, ts_excl, tc_excl, dir_amb) == 0) {
2926 SigConsolidateTcpBuffer(s);
2929 DetectRuleSetTable(s);
2931 if (!SigValidateProtoPkthdr(s)) {
2938 int r = SigValidateFileHandling(s);
2942 if (SigInspectsFiles(s)) {
2947 if (DetectRuleValidateTable(s) ==
false) {
2970 memset(&parser, 0x00,
sizeof(parser));
2975 if (firewall_rule) {
2992 int ret = SigParse(
de_ctx, sig, sigstr, dir, &parser,
true);
2999 }
else if (ret < 0) {
3005 SCLogError(
"Signature missing required value \"sid\".");
3010 ret = SigParse(
de_ctx, sig, sigstr, dir, &parser,
false);
3016 }
else if (ret == -2) {
3019 }
else if (ret < 0) {
3024 if (sig->
prio == -1)
3031 int override_needed = 0;
3035 override_needed = 1;
3037 override_needed = 1;
3041 override_needed = 0;
3050 if (override_needed)
3060 for ( ; sm != NULL; sm = sm->
next) {
3084 SCLogDebug(
"sig %"PRIu32
" SIG_FLAG_APPLAYER: %s, SIG_FLAG_PACKET: %s",
3088 SigBuildAddressMatchArray(sig);
3099 SigSetupPrefilter(
de_ctx, sig);
3102 if (SigValidateConsolidate(
de_ctx, sig, &parser, dir) == 0) {
3121 static bool SigHasSameSourceAndDestination(
const Signature *s)
3163 if (SigHasSameSourceAndDestination(sig)) {
3164 SCLogInfo(
"Rule with ID %u is bidirectional, but source and destination are the same, "
3165 "treating the rule as unidirectional", sig->
id);
3170 if (sig->
next == NULL) {
3200 return SigInitDo(
de_ctx, sigstr,
false);
3205 return SigInitDo(
de_ctx, sigstr,
true);
3214 static void DetectParseDupSigFreeFunc(
void *data)
3230 static uint32_t DetectParseDupSigHashFunc(
HashListTable *ht,
void *data, uint16_t datalen)
3249 static char DetectParseDupSigCompareFunc(
void *data1, uint16_t len1,
void *data2,
3255 if (sw1 == NULL || sw2 == NULL ||
3256 sw1->
s == NULL || sw2->
s == NULL)
3260 if (sw1->
s->
id == sw2->
s->
id && sw1->
s->
gid == sw2->
s->
gid)
return 1;
3276 DetectParseDupSigHashFunc,
3277 DetectParseDupSigCompareFunc,
3278 DetectParseDupSigFreeFunc);
3339 if (sw_dup == NULL) {
3352 (
void *)&sw_tmp, 0);
3364 if (sw->
s->
rev <= sw_dup->
s->
rev) {
3373 if (sw_dup->
s_prev == NULL) {
3381 sw_temp.
s = sw_dup->
s->
next;
3385 if (sw_temp.
s != NULL) {
3387 (
void *)&sw_temp, 0);
3407 sw_temp.
s = sw_dup->
s->
next;
3415 if (sw_temp.
s != NULL) {
3417 (
void *)&sw_temp, 0);
3432 (
void *)&sw_tmp, 0);
3433 if (sw_old->
s != sw_dup->
s) {
3476 int dup_sig = DetectEngineSignatureIsDuplicate(
de_ctx, sig);
3480 SCLogError(
"Duplicate signature \"%s\"", sigstr);
3482 }
else if (dup_sig == 2) {
3484 " so the older sig replaced by this new signature \"%s\"",
3489 if (sig->
next != NULL) {
3506 return (dup_sig == 0 || dup_sig == 2) ? sig : NULL;
3510 if (sig != NULL && sig->
next != NULL) {
3548 int dup_sig = DetectEngineSignatureIsDuplicate(
de_ctx, sig);
3552 SCLogError(
"Duplicate signature \"%s\"", sigstr);
3554 }
else if (dup_sig == 2) {
3556 " so the older sig replaced by this new signature \"%s\"",
3561 if (sig->
next != NULL) {
3578 return (dup_sig == 0 || dup_sig == 2) ? sig : NULL;
3582 if (sig != NULL && sig->
next != NULL) {
3595 int start_offset,
int options)
3597 *match = pcre2_match_data_create_from_pattern(parse_regex->
regex, NULL);
3599 return pcre2_match(parse_regex->
regex, (PCRE2_SPTR8)
str, strlen(
str), options, start_offset,
3600 *match, parse_regex->
context);
3607 pcre2_code_free(r->
regex);
3610 pcre2_match_context_free(r->
context);
3625 g_detect_parse_regex_list = NULL;
3634 FatalError(
"failed to alloc memory for pcre free list");
3637 r->
next = g_detect_parse_regex_list;
3638 g_detect_parse_regex_list = r;
3646 detect_parse->
regex =
3647 pcre2_compile((PCRE2_SPTR8)parse_str, PCRE2_ZERO_TERMINATED, opts, &en, &eo, NULL);
3648 if (detect_parse->
regex == NULL) {
3649 PCRE2_UCHAR errbuffer[256];
3650 pcre2_get_error_message(en, errbuffer,
sizeof(errbuffer));
3651 SCLogError(
"pcre compile of \"%s\" failed at "
3653 parse_str, en, errbuffer);
3656 detect_parse->
context = pcre2_match_context_create(NULL);
3657 if (detect_parse->
context == NULL) {
3658 SCLogError(
"pcre2 could not create match context");
3659 pcre2_code_free(detect_parse->
regex);
3660 detect_parse->
regex = NULL;
3675 if (detect_parse == NULL) {
3679 detect_parse->
regex =
3680 pcre2_compile((PCRE2_SPTR8)parse_str, PCRE2_ZERO_TERMINATED, opts, &en, &eo, NULL);
3681 if (detect_parse->
regex == NULL) {
3682 PCRE2_UCHAR errbuffer[256];
3683 pcre2_get_error_message(en, errbuffer,
sizeof(errbuffer));
3684 SCLogError(
"pcre2 compile of \"%s\" failed at "
3686 parse_str, (
int)eo, errbuffer);
3691 detect_parse->
next = g_detect_parse_regex_list;
3692 g_detect_parse_regex_list = detect_parse;
3693 return detect_parse;
3697 pcre2_match_data *match_data, uint32_t number, PCRE2_UCHAR *buffer, PCRE2_SIZE *bufflen)
3699 int r = pcre2_substring_copy_bynumber(match_data, number, buffer, bufflen);
3700 if (r == PCRE2_ERROR_UNSET) {
3709 pcre2_match_data *match_data, uint32_t number, PCRE2_UCHAR **bufferptr, PCRE2_SIZE *bufflen)
3711 int r = pcre2_substring_get_bynumber(match_data, number, bufferptr, bufflen);
3712 if (r == PCRE2_ERROR_UNSET) {
3730 if (policy_actions == NULL) {
3731 SCLogDebug(
"fw: no policy at %s", policy_name);
3736 uint8_t action_scope = 0;
3741 if (SigParseActionDo(paction->
val, idx,
true, &action, &action_scope) < 0)
3750 static int DoParseAppPolicy(
const char *prefix,
const AppProto app_proto,
const char *hookname,
3751 const uint8_t state,
const uint8_t complete_state,
const int direction,
3754 char policy_name[256];
3755 const char *in_name = hookname;
3756 if (hookname == NULL) {
3758 if (direction == STREAM_TOSERVER)
3759 hookname =
"request-started";
3761 hookname =
"response-started";
3762 }
else if (state == complete_state) {
3763 if (direction == STREAM_TOSERVER)
3764 hookname =
"request-complete";
3766 hookname =
"response-complete";
3768 if (hookname == NULL)
3774 for (
int i = 0; nname[i] !=
'\0'; i++) {
3775 if (nname[i] ==
'_')
3780 int r = snprintf(policy_name,
sizeof(policy_name),
"%s.%s.%s", prefix, app_name, nname);
3782 if (r < 0 || (
size_t)r >=
sizeof(policy_name)) {
3783 FatalError(
"internal error: failed to assemble firewall policy config string");
3786 if (direction == STREAM_TOSERVER)
3787 r = DoParsePolicy(policy_name, &app_fw_policies[app_proto].
ts[state]);
3789 r = DoParsePolicy(policy_name, &app_fw_policies[app_proto].tc[state]);
3790 if (r == 0 && in_name != NULL) {
3792 if (direction == STREAM_TOSERVER)
3793 hookname =
"request-started";
3795 hookname =
"response-started";
3796 }
else if (state == complete_state) {
3797 if (direction == STREAM_TOSERVER)
3798 hookname =
"request-complete";
3800 hookname =
"response-complete";
3802 if (hookname == NULL)
3804 r = snprintf(policy_name,
sizeof(policy_name),
"%s.%s.%s", prefix, app_name, hookname);
3805 if (r < 0 || (
size_t)r >=
sizeof(policy_name)) {
3806 FatalError(
"internal error: failed to assemble firewall policy config string");
3809 if (direction == STREAM_TOSERVER)
3810 return DoParsePolicy(policy_name, &app_fw_policies[app_proto].
ts[state]);
3812 return DoParsePolicy(policy_name, &app_fw_policies[app_proto].tc[state]);
3822 if (fw_policies == NULL)
3825 if (app_fw_policies == NULL)
3838 for (
int i = 0; i < 48; i++) {
3856 char policy_name[256];
3857 char prefix[96] =
"firewall.policies";
3863 if (fw_policies == NULL)
3866 if (app_fw_policies == NULL)
3869 r = snprintf(policy_name,
sizeof(policy_name),
"%s.packet-filter", prefix);
3870 if (r < 0 || (
size_t)r >=
sizeof(policy_name)) {
3871 FatalError(
"internal error: failed to assemble firewall policy config string");
3877 r = snprintf(policy_name,
sizeof(policy_name),
"%s.packet-pre-flow", prefix);
3878 if (r < 0 || (
size_t)r >=
sizeof(policy_name)) {
3879 FatalError(
"internal error: failed to assemble firewall policy config string");
3885 r = snprintf(policy_name,
sizeof(policy_name),
"%s.packet-pre-stream", prefix);
3886 if (r < 0 || (
size_t)r >=
sizeof(policy_name)) {
3887 FatalError(
"internal error: failed to assemble firewall policy config string");
3894 if (!AppProtoIsValid(a))
3897 const uint8_t complete_state_ts =
3899 for (uint8_t state = 0; state <= complete_state_ts; state++) {
3902 if (DoParseAppPolicy(prefix, a,
name, state, complete_state_ts, STREAM_TOSERVER,
3903 app_fw_policies) < 0)
3907 const uint8_t complete_state_tc =
3909 for (uint8_t state = 0; state <= complete_state_tc; state++) {
3912 if (DoParseAppPolicy(prefix, a,
name, state, complete_state_tc, STREAM_TOCLIENT,
3913 app_fw_policies) < 0)
3929 static int SigParseTest01 (
void)
3938 sig =
SigInit(
de_ctx,
"alert tcp 1.2.3.4 any -> !1.2.3.4 any (msg:\"SigParseTest01\"; sid:1;)");
3948 static int SigParseTest02 (
void)
3963 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;)");
3991 static int SigParseTest03 (
void)
4000 sig =
SigInit(
de_ctx,
"alert tcp 1.2.3.4 any <- !1.2.3.4 any (msg:\"SigParseTest03\"; sid:1;)");
4003 printf(
"expected NULL got sig ptr %p: ",sig);
4012 static int SigParseTest04 (
void)
4021 sig =
SigInit(
de_ctx,
"alert tcp 1.2.3.4 1024: -> !1.2.3.4 1024: (msg:\"SigParseTest04\"; sid:1;)");
4032 static int SigParseTest05 (
void)
4041 sig =
SigInit(
de_ctx,
"alert tcp 1.2.3.4 1024:65536 -> !1.2.3.4 any (msg:\"SigParseTest05\"; sid:1;)");
4045 printf(
"signature didn't fail to parse as we expected: ");
4055 static int SigParseTest06 (
void)
4064 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;)");
4068 printf(
"signature failed to parse: ");
4082 static int SigParseTest07(
void)
4104 static int SigParseTest08(
void)
4127 static int SigParseTest09(
void)
4178 static int SigParseTest10(
void)
4210 static int SigParseTest11(
void)
4221 "drop tcp any any -> any 80 (msg:\"Snort_Inline is blocking the http link\"; sid:1;) ");
4223 printf(
"sig 1 didn't parse: ");
4228 "the http link\"; sid:2;) ");
4230 printf(
"sig 2 didn't parse: ");
4244 static int SigParseTest12(
void)
4256 printf(
"sig 1 should have given an error: ");
4270 static int SigParseTest13(
void)
4282 printf(
"sig 1 invalidated: failure");
4287 printf(
"sig doesn't have stream flag set\n");
4292 printf(
"sig has packet flag set\n");
4307 static int SigParseTest14(
void)
4319 printf(
"sig 1 invalidated: failure");
4324 printf(
"sig doesn't have packet flag set\n");
4329 printf(
"sig has stream flag set\n");
4344 static int SigParseTest15(
void)
4356 printf(
"sig 1 invalidated: failure");
4361 printf(
"sig doesn't have packet flag set\n");
4366 printf(
"sig doesn't have stream flag set\n");
4381 static int SigParseTest16(
void)
4393 printf(
"sig 1 invalidated: failure");
4398 printf(
"sig doesn't have packet flag set\n");
4403 printf(
"sig doesn't have stream flag set\n");
4418 static int SigParseTest17(
void)
4430 printf(
"sig 1 invalidated: failure");
4435 printf(
"sig doesn't have packet flag set\n");
4440 printf(
"sig doesn't have stream flag set\n");
4453 static int SigParseTest18 (
void)
4461 if (
DetectEngineAppendSig(
de_ctx,
"alert tcp 1.2.3.4 any -> !1.2.3.4 any (msg:\"SigParseTest01\"; sid:99999999999999999999;)") != NULL)
4472 static int SigParseTest19 (
void)
4480 if (
DetectEngineAppendSig(
de_ctx,
"alert tcp 1.2.3.4 any -> !1.2.3.4 any (msg:\"SigParseTest01\"; sid:1; gid:99999999999999999999;)") != NULL)
4491 static int SigParseTest20 (
void)
4499 if (
DetectEngineAppendSig(
de_ctx,
"alert tcp 1.2.3.4 any -> !1.2.3.4 any (msg:\"SigParseTest01\"; sid:1; rev:99999999999999999999;)") != NULL)
4510 static int SigParseTest21 (
void)
4529 static int SigParseTest22 (
void)
4537 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)
4550 static int SigParseTest23(
void)
4565 static int SigParseBidirecTest06 (
void)
4585 static int SigParseBidirecTest07 (
void)
4605 static int SigParseBidirecTest08 (
void)
4625 static int SigParseBidirecTest09 (
void)
4645 static int SigParseBidirecTest10 (
void)
4665 static int SigParseBidirecTest11 (
void)
4685 static int SigParseBidirecTest12 (
void)
4705 static int SigParseBidirecTest13 (
void)
4724 static int SigParseBidirecTest14 (
void)
4745 static int SigTestBidirec01 (
void)
4757 if (sig->
next != NULL)
4776 static int SigTestBidirec02 (
void)
4795 if (sig->
next == NULL)
4800 if (copy->
next != NULL)
4821 static int SigTestBidirec03 (
void)
4833 const char *sigs[3];
4834 sigs[0] =
"alert tcp any any -> 192.168.1.1 any (msg:\"SigTestBidirec03 sid 1\"; sid:1;)";
4835 sigs[1] =
"alert tcp any any <> 192.168.1.1 any (msg:\"SigTestBidirec03 sid 2 bidirectional\"; sid:2;)";
4836 sigs[2] =
"alert tcp any any -> 192.168.1.1 any (msg:\"SigTestBidirec03 sid 3\"; sid:3;)";
4843 if (sig->
next == NULL)
4854 uint8_t rawpkt1_ether[] = {
4855 0x00,0x50,0x56,0xea,0x00,0xbd,0x00,0x0c,
4856 0x29,0x40,0xc8,0xb5,0x08,0x00,0x45,0x00,
4857 0x01,0xa8,0xb9,0xbb,0x40,0x00,0x40,0x06,
4858 0xe0,0xbf,0xc0,0xa8,0x1c,0x83,0xc0,0xa8,
4859 0x01,0x01,0xb9,0x0a,0x00,0x50,0x6f,0xa2,
4860 0x92,0xed,0x7b,0xc1,0xd3,0x4d,0x50,0x18,
4861 0x16,0xd0,0xa0,0x6f,0x00,0x00,0x47,0x45,
4862 0x54,0x20,0x2f,0x20,0x48,0x54,0x54,0x50,
4863 0x2f,0x31,0x2e,0x31,0x0d,0x0a,0x48,0x6f,
4864 0x73,0x74,0x3a,0x20,0x31,0x39,0x32,0x2e,
4865 0x31,0x36,0x38,0x2e,0x31,0x2e,0x31,0x0d,
4866 0x0a,0x55,0x73,0x65,0x72,0x2d,0x41,0x67,
4867 0x65,0x6e,0x74,0x3a,0x20,0x4d,0x6f,0x7a,
4868 0x69,0x6c,0x6c,0x61,0x2f,0x35,0x2e,0x30,
4869 0x20,0x28,0x58,0x31,0x31,0x3b,0x20,0x55,
4870 0x3b,0x20,0x4c,0x69,0x6e,0x75,0x78,0x20,
4871 0x78,0x38,0x36,0x5f,0x36,0x34,0x3b,0x20,
4872 0x65,0x6e,0x2d,0x55,0x53,0x3b,0x20,0x72,
4873 0x76,0x3a,0x31,0x2e,0x39,0x2e,0x30,0x2e,
4874 0x31,0x34,0x29,0x20,0x47,0x65,0x63,0x6b,
4875 0x6f,0x2f,0x32,0x30,0x30,0x39,0x30,0x39,
4876 0x30,0x32,0x31,0x37,0x20,0x55,0x62,0x75,
4877 0x6e,0x74,0x75,0x2f,0x39,0x2e,0x30,0x34,
4878 0x20,0x28,0x6a,0x61,0x75,0x6e,0x74,0x79,
4879 0x29,0x20,0x46,0x69,0x72,0x65,0x66,0x6f,
4880 0x78,0x2f,0x33,0x2e,0x30,0x2e,0x31,0x34,
4881 0x0d,0x0a,0x41,0x63,0x63,0x65,0x70,0x74,
4882 0x3a,0x20,0x74,0x65,0x78,0x74,0x2f,0x68,
4883 0x74,0x6d,0x6c,0x2c,0x61,0x70,0x70,0x6c,
4884 0x69,0x63,0x61,0x74,0x69,0x6f,0x6e,0x2f,
4885 0x78,0x68,0x74,0x6d,0x6c,0x2b,0x78,0x6d,
4886 0x6c,0x2c,0x61,0x70,0x70,0x6c,0x69,0x63,
4887 0x61,0x74,0x69,0x6f,0x6e,0x2f,0x78,0x6d,
4888 0x6c,0x3b,0x71,0x3d,0x30,0x2e,0x39,0x2c,
4889 0x2a,0x2f,0x2a,0x3b,0x71,0x3d,0x30,0x2e,
4890 0x38,0x0d,0x0a,0x41,0x63,0x63,0x65,0x70,
4891 0x74,0x2d,0x4c,0x61,0x6e,0x67,0x75,0x61,
4892 0x67,0x65,0x3a,0x20,0x65,0x6e,0x2d,0x75,
4893 0x73,0x2c,0x65,0x6e,0x3b,0x71,0x3d,0x30,
4894 0x2e,0x35,0x0d,0x0a,0x41,0x63,0x63,0x65,
4895 0x70,0x74,0x2d,0x45,0x6e,0x63,0x6f,0x64,
4896 0x69,0x6e,0x67,0x3a,0x20,0x67,0x7a,0x69,
4897 0x70,0x2c,0x64,0x65,0x66,0x6c,0x61,0x74,
4898 0x65,0x0d,0x0a,0x41,0x63,0x63,0x65,0x70,
4899 0x74,0x2d,0x43,0x68,0x61,0x72,0x73,0x65,
4900 0x74,0x3a,0x20,0x49,0x53,0x4f,0x2d,0x38,
4901 0x38,0x35,0x39,0x2d,0x31,0x2c,0x75,0x74,
4902 0x66,0x2d,0x38,0x3b,0x71,0x3d,0x30,0x2e,
4903 0x37,0x2c,0x2a,0x3b,0x71,0x3d,0x30,0x2e,
4904 0x37,0x0d,0x0a,0x4b,0x65,0x65,0x70,0x2d,
4905 0x41,0x6c,0x69,0x76,0x65,0x3a,0x20,0x33,
4906 0x30,0x30,0x0d,0x0a,0x43,0x6f,0x6e,0x6e,
4907 0x65,0x63,0x74,0x69,0x6f,0x6e,0x3a,0x20,
4908 0x6b,0x65,0x65,0x70,0x2d,0x61,0x6c,0x69,
4909 0x76,0x65,0x0d,0x0a,0x0d,0x0a };
4919 uint32_t sids[3] = {1, 2, 3};
4920 uint32_t results[3] = {1, 1, 1};
4936 static int SigTestBidirec04 (
void)
4951 sig =
DetectEngineAppendSig(
de_ctx,
"alert tcp 192.168.1.1 any <> any any (msg:\"SigTestBidirec03 sid 2 bidirectional\"; sid:2;)");
4956 if (sig->
next == NULL)
4968 if (sig->
next == NULL)
4979 uint8_t rawpkt1_ether[] = {
4980 0x00,0x50,0x56,0xea,0x00,0xbd,0x00,0x0c,
4981 0x29,0x40,0xc8,0xb5,0x08,0x00,0x45,0x00,
4982 0x01,0xa8,0xb9,0xbb,0x40,0x00,0x40,0x06,
4983 0xe0,0xbf,0xc0,0xa8,0x1c,0x83,0xc0,0xa8,
4984 0x01,0x01,0xb9,0x0a,0x00,0x50,0x6f,0xa2,
4985 0x92,0xed,0x7b,0xc1,0xd3,0x4d,0x50,0x18,
4986 0x16,0xd0,0xa0,0x6f,0x00,0x00,0x47,0x45,
4987 0x54,0x20,0x2f,0x20,0x48,0x54,0x54,0x50,
4988 0x2f,0x31,0x2e,0x31,0x0d,0x0a,0x48,0x6f,
4989 0x73,0x74,0x3a,0x20,0x31,0x39,0x32,0x2e,
4990 0x31,0x36,0x38,0x2e,0x31,0x2e,0x31,0x0d,
4991 0x0a,0x55,0x73,0x65,0x72,0x2d,0x41,0x67,
4992 0x65,0x6e,0x74,0x3a,0x20,0x4d,0x6f,0x7a,
4993 0x69,0x6c,0x6c,0x61,0x2f,0x35,0x2e,0x30,
4994 0x20,0x28,0x58,0x31,0x31,0x3b,0x20,0x55,
4995 0x3b,0x20,0x4c,0x69,0x6e,0x75,0x78,0x20,
4996 0x78,0x38,0x36,0x5f,0x36,0x34,0x3b,0x20,
4997 0x65,0x6e,0x2d,0x55,0x53,0x3b,0x20,0x72,
4998 0x76,0x3a,0x31,0x2e,0x39,0x2e,0x30,0x2e,
4999 0x31,0x34,0x29,0x20,0x47,0x65,0x63,0x6b,
5000 0x6f,0x2f,0x32,0x30,0x30,0x39,0x30,0x39,
5001 0x30,0x32,0x31,0x37,0x20,0x55,0x62,0x75,
5002 0x6e,0x74,0x75,0x2f,0x39,0x2e,0x30,0x34,
5003 0x20,0x28,0x6a,0x61,0x75,0x6e,0x74,0x79,
5004 0x29,0x20,0x46,0x69,0x72,0x65,0x66,0x6f,
5005 0x78,0x2f,0x33,0x2e,0x30,0x2e,0x31,0x34,
5006 0x0d,0x0a,0x41,0x63,0x63,0x65,0x70,0x74,
5007 0x3a,0x20,0x74,0x65,0x78,0x74,0x2f,0x68,
5008 0x74,0x6d,0x6c,0x2c,0x61,0x70,0x70,0x6c,
5009 0x69,0x63,0x61,0x74,0x69,0x6f,0x6e,0x2f,
5010 0x78,0x68,0x74,0x6d,0x6c,0x2b,0x78,0x6d,
5011 0x6c,0x2c,0x61,0x70,0x70,0x6c,0x69,0x63,
5012 0x61,0x74,0x69,0x6f,0x6e,0x2f,0x78,0x6d,
5013 0x6c,0x3b,0x71,0x3d,0x30,0x2e,0x39,0x2c,
5014 0x2a,0x2f,0x2a,0x3b,0x71,0x3d,0x30,0x2e,
5015 0x38,0x0d,0x0a,0x41,0x63,0x63,0x65,0x70,
5016 0x74,0x2d,0x4c,0x61,0x6e,0x67,0x75,0x61,
5017 0x67,0x65,0x3a,0x20,0x65,0x6e,0x2d,0x75,
5018 0x73,0x2c,0x65,0x6e,0x3b,0x71,0x3d,0x30,
5019 0x2e,0x35,0x0d,0x0a,0x41,0x63,0x63,0x65,
5020 0x70,0x74,0x2d,0x45,0x6e,0x63,0x6f,0x64,
5021 0x69,0x6e,0x67,0x3a,0x20,0x67,0x7a,0x69,
5022 0x70,0x2c,0x64,0x65,0x66,0x6c,0x61,0x74,
5023 0x65,0x0d,0x0a,0x41,0x63,0x63,0x65,0x70,
5024 0x74,0x2d,0x43,0x68,0x61,0x72,0x73,0x65,
5025 0x74,0x3a,0x20,0x49,0x53,0x4f,0x2d,0x38,
5026 0x38,0x35,0x39,0x2d,0x31,0x2c,0x75,0x74,
5027 0x66,0x2d,0x38,0x3b,0x71,0x3d,0x30,0x2e,
5028 0x37,0x2c,0x2a,0x3b,0x71,0x3d,0x30,0x2e,
5029 0x37,0x0d,0x0a,0x4b,0x65,0x65,0x70,0x2d,
5030 0x41,0x6c,0x69,0x76,0x65,0x3a,0x20,0x33,
5031 0x30,0x30,0x0d,0x0a,0x43,0x6f,0x6e,0x6e,
5032 0x65,0x63,0x74,0x69,0x6f,0x6e,0x3a,0x20,
5033 0x6b,0x65,0x65,0x70,0x2d,0x61,0x6c,0x69,
5034 0x76,0x65,0x0d,0x0a,0x0d,0x0a };
5043 memset(&th_v, 0,
sizeof(th_v));
5083 static int SigParseTestNegation01 (
void)
5097 static int SigParseTestNegation02 (
void)
5103 "alert tcp any !any -> any any (msg:\"SigTest41-02 src ip is !any \"; "
5104 "classtype:misc-activity; sid:410002; rev:1;)");
5112 static int SigParseTestNegation03 (
void)
5118 "alert tcp any any -> any [80:!80] (msg:\"SigTest41-03 dst port [80:!80] \"; "
5119 "classtype:misc-activity; sid:410003; rev:1;)");
5127 static int SigParseTestNegation04 (
void)
5138 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;)");
5153 static int SigParseTestNegation05 (
void)
5164 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;)");
5179 static int SigParseTestNegation06 (
void)
5190 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;)");
5206 static int SigParseTestNegation07 (
void)
5212 de_ctx,
"alert tcp any any -> [192.168.0.2,!192.168.0.0/24] any (sid:410006;)");
5221 static int SigParseTestNegation08 (
void)
5233 "alert tcp any any -> [192.168.0.0/16,!192.168.0.0/24] any (sid:410006; rev:1;)");
5248 static int SigParseTestMpm01 (
void)
5257 sig =
SigInit(
de_ctx,
"alert tcp any any -> any any (msg:\"mpm test\"; content:\"abcd\"; sid:1;)");
5259 printf(
"sig failed to init: ");
5264 printf(
"sig doesn't have content list: ");
5279 static int SigParseTestMpm02 (
void)
5288 sig =
SigInit(
de_ctx,
"alert tcp any any -> any any (msg:\"mpm test\"; content:\"abcd\"; content:\"abcdef\"; sid:1;)");
5290 printf(
"sig failed to init: ");
5295 printf(
"sig doesn't have content list: ");
5310 static int SigParseTestAppLayerTLS01(
void)
5321 s =
SigInit(
de_ctx,
"alert tls any any -> any any (msg:\"SigParseTestAppLayerTLS01 \"; sid:410006; rev:1;)");
5323 printf(
"parsing sig failed: ");
5328 printf(
"alproto not set: ");
5345 static int SigParseTestAppLayerTLS02(
void)
5356 s =
SigInit(
de_ctx,
"alert tls any any -> any any (msg:\"SigParseTestAppLayerTLS02 \"; tls.version:1.0; sid:410006; rev:1;)");
5358 printf(
"parsing sig failed: ");
5363 printf(
"alproto not set: ");
5379 static int SigParseTestAppLayerTLS03(
void)
5386 "alert tls any any -> any any (msg:\"SigParseTestAppLayerTLS03 \"; "
5387 "tls.version:2.5; sid:410006; rev:1;)");
5393 static int SigParseTestUnbalancedQuotes01(
void)
5399 "alert http any any -> any any (msg:\"SigParseTestUnbalancedQuotes01\"; "
5400 "pcre:\"/\\/[a-z]+\\.php\\?[a-z]+?=\\d{7}&[a-z]+?=\\d{7,8}$/U\" "
5401 "flowbits:set,et.exploitkitlanding; classtype:trojan-activity; sid:2017078; rev:5;)");
5407 static int SigParseTestContentGtDsize01(
void)
5414 "dsize:21; content:\"0123456789001234567890|00 00|\"; "
5421 static int SigParseTestContentGtDsize02(
void)
5428 "dsize:21; content:\"0123456789|00 00|\"; offset:10; "
5445 static int SigParseBidirWithSameSrcAndDest01(
void)
5462 "alert tcp [1.2.3.4, 5.6.7.8] [80, 81] <> [5.6.7.8, 1.2.3.4] [81, 80] (sid:3;)");
5471 static int SigParseBidirWithSameSrcAndDest02(
void)
5479 de_ctx,
"alert tcp 1.2.3.4 any <> [1.2.3.4, 5.6.7.8, ::1] any (sid:1;)");
5486 de_ctx,
"alert tcp [1.2.3.4, ::1] [80, 81, 82] <> [1.2.3.4, ::1] [80, 81] (sid:2;)");
5493 "alert tcp [1.2.3.4, ::1, ABCD:AAAA::1] [80] <> [1.2.3.4, ::1] [80, 81] (sid:3;)");
5500 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;)");
5507 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;)");
5516 static int SigParseTestActionReject(
void)
5522 de_ctx,
"reject tcp 1.2.3.4 any -> !1.2.3.4 any (msg:\"SigParseTest01\"; sid:1;)");
5523 #ifdef HAVE_LIBNET11
5534 static int SigParseTestActionDrop(
void)
5540 de_ctx,
"drop tcp 1.2.3.4 any -> !1.2.3.4 any (msg:\"SigParseTest01\"; sid:1;)");
5548 static int SigSetMultiAppProto(
void)
5623 static int DetectSetupDirection01(
void)
5628 char *
str = (
char *)
"to_client";
5629 FAIL_IF(DetectSetupDirection(s, &
str,
true) < 0);
5634 static int DetectSetupDirection02(
void)
5638 char *
str = (
char *)
"to_server";
5639 FAIL_IF(DetectSetupDirection(s, &
str,
true) < 0);
5641 str = (
char *)
"to_client";
5642 FAIL_IF(DetectSetupDirection(s, &
str,
true) >= 0);
5648 static int DetectSetupDirection03(
void)
5652 char *
str = (
char *)
"to_client , something";
5653 FAIL_IF(DetectSetupDirection(s, &
str,
false) < 0);
5655 str = (
char *)
"to_client,something";
5656 FAIL_IF(DetectSetupDirection(s, &
str,
false) < 0);
5662 static int DetectSetupDirection04(
void)
5667 char *
str = (
char *)
"to_client_toto";
5668 FAIL_IF(DetectSetupDirection(s, &
str,
true) >= 0);
5670 str = (
char *)
"to_client_toto";
5671 FAIL_IF(DetectSetupDirection(s, &
str,
false) < 0);
5673 str = (
char *)
"to_client,something";
5675 FAIL_IF(DetectSetupDirection(s, &
str,
true) >= 0);
5712 UtRegisterTest(
"SigParseTest21 -- address with space", SigParseTest21);
5713 UtRegisterTest(
"SigParseTest22 -- address with space", SigParseTest22);
5714 UtRegisterTest(
"SigParseTest23 -- carriage return", SigParseTest23);
5729 UtRegisterTest(
"SigParseTestNegation01", SigParseTestNegation01);
5730 UtRegisterTest(
"SigParseTestNegation02", SigParseTestNegation02);
5731 UtRegisterTest(
"SigParseTestNegation03", SigParseTestNegation03);
5732 UtRegisterTest(
"SigParseTestNegation04", SigParseTestNegation04);
5733 UtRegisterTest(
"SigParseTestNegation05", SigParseTestNegation05);
5734 UtRegisterTest(
"SigParseTestNegation06", SigParseTestNegation06);
5735 UtRegisterTest(
"SigParseTestNegation07", SigParseTestNegation07);
5736 UtRegisterTest(
"SigParseTestNegation08", SigParseTestNegation08);
5739 UtRegisterTest(
"SigParseTestAppLayerTLS01", SigParseTestAppLayerTLS01);
5740 UtRegisterTest(
"SigParseTestAppLayerTLS02", SigParseTestAppLayerTLS02);
5741 UtRegisterTest(
"SigParseTestAppLayerTLS03", SigParseTestAppLayerTLS03);
5742 UtRegisterTest(
"SigParseTestUnbalancedQuotes01", SigParseTestUnbalancedQuotes01);
5745 SigParseTestContentGtDsize01);
5747 SigParseTestContentGtDsize02);
5750 SigParseBidirWithSameSrcAndDest01);
5752 SigParseBidirWithSameSrcAndDest02);
5753 UtRegisterTest(
"SigParseTestActionReject", SigParseTestActionReject);
5754 UtRegisterTest(
"SigParseTestActionDrop", SigParseTestActionDrop);
5758 UtRegisterTest(
"DetectSetupDirection01", DetectSetupDirection01);
5759 UtRegisterTest(
"DetectSetupDirection02", DetectSetupDirection02);
5760 UtRegisterTest(
"DetectSetupDirection03", DetectSetupDirection03);
5761 UtRegisterTest(
"DetectSetupDirection04", DetectSetupDirection04);