diff --git a/src/detect-flow.c b/src/detect-flow.c index d89e60cb40..e632822689 100644 --- a/src/detect-flow.c +++ b/src/detect-flow.c @@ -53,7 +53,6 @@ void DetectFlowFree(void *); /** * \brief Registration function for flow: keyword - * \todo add support for no_stream and stream_only */ void DetectFlowRegister (void) { sigmatch_table[DETECT_FLOW].name = "flow"; @@ -94,7 +93,6 @@ error: /** * \brief This function is used to match flow flags set on a packet with those passed via flow: - * \todo We need to add support for no_stream and stream_only flag checking * * \param t pointer to thread vars * \param det_ctx pointer to the pattern matcher thread @@ -238,21 +236,21 @@ DetectFlowData *DetectFlowParse (char *flowstr) goto error; } fd->flags |= FLOW_PKT_TOSERVER; - } else if (strcasecmp(args[i], "stream_only") == 0) { - if (fd->flags & FLOW_PKT_STREAMONLY) { - SCLogError(SC_ERR_FLAGS_MODIFIER, "cannot set stream_only flag is already set"); + } else if (strcasecmp(args[i], "only_stream") == 0) { + if (fd->flags & FLOW_PKT_ONLYSTREAM) { + SCLogError(SC_ERR_FLAGS_MODIFIER, "cannot set only_stream flag is already set"); goto error; } else if (fd->flags & FLOW_PKT_NOSTREAM) { - SCLogError(SC_ERR_FLAGS_MODIFIER, "cannot set stream_only flag, FLOW_PKT_NOSTREAM already set"); + SCLogError(SC_ERR_FLAGS_MODIFIER, "cannot set only_stream flag, FLOW_PKT_NOSTREAM already set"); goto error; } - fd->flags |= FLOW_PKT_STREAMONLY; + fd->flags |= FLOW_PKT_ONLYSTREAM; } else if (strcasecmp(args[i], "no_stream") == 0) { if (fd->flags & FLOW_PKT_NOSTREAM) { SCLogError(SC_ERR_FLAGS_MODIFIER, "cannot set no_stream flag is already set"); goto error; - } else if (fd->flags & FLOW_PKT_STREAMONLY) { - SCLogError(SC_ERR_FLAGS_MODIFIER, "cannot set no_stream flag, FLOW_PKT_STREAMONLY already set"); + } else if (fd->flags & FLOW_PKT_ONLYSTREAM) { + SCLogError(SC_ERR_FLAGS_MODIFIER, "cannot set no_stream flag, FLOW_PKT_ONLYSTREAM already set"); goto error; } fd->flags |= FLOW_PKT_NOSTREAM; @@ -302,7 +300,8 @@ int DetectFlowSetup (DetectEngineCtx *de_ctx, Signature *s, char *flowstr) //printf("DetectFlowSetup: \'%s\'\n", flowstr); fd = DetectFlowParse(flowstr); - if (fd == NULL) goto error; + if (fd == NULL) + goto error; /* Okay so far so good, lets get this into a SigMatch * and put it in the Signature. */ @@ -315,6 +314,13 @@ int DetectFlowSetup (DetectEngineCtx *de_ctx, Signature *s, char *flowstr) SigMatchAppendPacket(s, sm); + if (fd->flags & FLOW_PKT_ONLYSTREAM) { + s->flags |= SIG_FLAG_REQUIRE_STREAM; + } + if (fd->flags & FLOW_PKT_NOSTREAM) { + s->flags |= SIG_FLAG_REQUIRE_PACKET; + } + s->init_flags |= SIG_FLAG_INIT_FLOW; return 0; @@ -847,17 +853,17 @@ int DetectFlowTestParse17 (void) { } /** - * \test DetectFlowTestParse18 is a test for setting the from_server,stateless,stream_only flow opts (order of state,dir reversed) + * \test DetectFlowTestParse18 is a test for setting the from_server,stateless,only_stream flow opts (order of state,dir reversed) */ int DetectFlowTestParse18 (void) { int result = 0; DetectFlowData *fd = NULL; - fd = DetectFlowParse("from_server,established,stream_only"); + fd = DetectFlowParse("from_server,established,only_stream"); if (fd != NULL) { - if (fd->flags & FLOW_PKT_ESTABLISHED && fd->flags & FLOW_PKT_TOCLIENT && fd->flags & FLOW_PKT_STREAMONLY && fd->match_cnt == 3) { + if (fd->flags & FLOW_PKT_ESTABLISHED && fd->flags & FLOW_PKT_TOCLIENT && fd->flags & FLOW_PKT_ONLYSTREAM && fd->match_cnt == 3) { result = 1; } else { - printf("expected 0x%02X cnt %" PRId32 " got 0x%02X cnt %" PRId32 ": ", FLOW_PKT_ESTABLISHED + FLOW_PKT_TOCLIENT + FLOW_PKT_STREAMONLY, 3, + printf("expected 0x%02X cnt %" PRId32 " got 0x%02X cnt %" PRId32 ": ", FLOW_PKT_ESTABLISHED + FLOW_PKT_TOCLIENT + FLOW_PKT_ONLYSTREAM, 3, fd->flags, fd->match_cnt); } DetectFlowFree(fd); @@ -867,17 +873,17 @@ int DetectFlowTestParse18 (void) { } /** - * \test DetectFlowTestParseNocase18 is a test for setting the from_server,stateless,stream_only flow opts (order of state,dir reversed) + * \test DetectFlowTestParseNocase18 is a test for setting the from_server,stateless,only_stream flow opts (order of state,dir reversed) */ int DetectFlowTestParseNocase18 (void) { int result = 0; DetectFlowData *fd = NULL; - fd = DetectFlowParse("FROM_SERVER,ESTABLISHED,STREAM_ONLY"); + fd = DetectFlowParse("FROM_SERVER,ESTABLISHED,ONLY_STREAM"); if (fd != NULL) { - if (fd->flags & FLOW_PKT_ESTABLISHED && fd->flags & FLOW_PKT_TOCLIENT && fd->flags & FLOW_PKT_STREAMONLY && fd->match_cnt == 3) { + if (fd->flags & FLOW_PKT_ESTABLISHED && fd->flags & FLOW_PKT_TOCLIENT && fd->flags & FLOW_PKT_ONLYSTREAM && fd->match_cnt == 3) { result = 1; } else { - printf("expected 0x%02X cnt %" PRId32 " got 0x%02X cnt %" PRId32 ": ", FLOW_PKT_ESTABLISHED + FLOW_PKT_TOCLIENT + FLOW_PKT_STREAMONLY, 3, + printf("expected 0x%02X cnt %" PRId32 " got 0x%02X cnt %" PRId32 ": ", FLOW_PKT_ESTABLISHED + FLOW_PKT_TOCLIENT + FLOW_PKT_ONLYSTREAM, 3, fd->flags, fd->match_cnt); } DetectFlowFree(fd); @@ -893,7 +899,7 @@ int DetectFlowTestParseNocase18 (void) { int DetectFlowTestParse19 (void) { int result = 1; DetectFlowData *fd = NULL; - fd = DetectFlowParse("from_server,established,stream_only,a"); + fd = DetectFlowParse("from_server,established,only_stream,a"); if (fd != NULL) { printf("expected: NULL got 0x%02X %" PRId32 ": ",fd->flags, fd->match_cnt); result = 0; diff --git a/src/detect-parse.c b/src/detect-parse.c index 50df0a71a8..fa6dd7216a 100644 --- a/src/detect-parse.c +++ b/src/detect-parse.c @@ -819,6 +819,12 @@ int SigParseProto(Signature *s, const char *protostr) { SCReturnInt(-1); } + if (s->proto.flags & DETECT_PROTO_ONLY_PKT) { + s->flags |= SIG_FLAG_REQUIRE_PACKET; + } else if (s->proto.flags & DETECT_PROTO_ONLY_STREAM) { + s->flags |= SIG_FLAG_REQUIRE_STREAM; + } + SCReturnInt(0); } @@ -1305,6 +1311,12 @@ static void SigBuildAddressMatchArray(Signature *s) { static int SigValidate(Signature *s) { SCEnter(); + if (s->flags & SIG_FLAG_REQUIRE_PACKET && + s->flags & SIG_FLAG_REQUIRE_STREAM) { + SCLogError(SC_ERR_INVALID_SIGNATURE, "can't mix packet keywords with tcp-stream or flow:only_stream."); + SCReturnInt(0); + } + /* check for uricontent + from_server/to_client */ if (s->sm_lists[DETECT_SM_LIST_UMATCH] != NULL) { SigMatch *sm; diff --git a/src/detect.h b/src/detect.h index 1068283446..ab7b0abb74 100644 --- a/src/detect.h +++ b/src/detect.h @@ -233,18 +233,20 @@ typedef struct DetectPort_ { #define SIG_FLAG_IPONLY (1<<8) /**< ip only signature */ #define SIG_FLAG_STATE_MATCH (1<<9) /**< signature has matches that require stateful inspection */ + #define SIG_FLAG_REQUIRE_PACKET (1<<10) /**< signature is requiring packet match */ +#define SIG_FLAG_REQUIRE_STREAM (1<<11) /**< signature is requiring stream match */ -#define SIG_FLAG_MPM_PACKET (1<<11) -#define SIG_FLAG_MPM_PACKET_NEG (1<<12) -#define SIG_FLAG_MPM_STREAM (1<<13) -#define SIG_FLAG_MPM_STREAM_NEG (1<<14) -#define SIG_FLAG_MPM_HTTP (1<<15) -#define SIG_FLAG_MPM_HTTP_NEG (1<<16) +#define SIG_FLAG_MPM_PACKET (1<<12) +#define SIG_FLAG_MPM_PACKET_NEG (1<<13) +#define SIG_FLAG_MPM_STREAM (1<<14) +#define SIG_FLAG_MPM_STREAM_NEG (1<<15) +#define SIG_FLAG_MPM_HTTP (1<<16) +#define SIG_FLAG_MPM_HTTP_NEG (1<<17) -#define SIG_FLAG_REQUIRE_FLOWVAR (1<<17) /**< signature can only match if a flowbit, flowvar or flowint is available. */ +#define SIG_FLAG_REQUIRE_FLOWVAR (1<<18) /**< signature can only match if a flowbit, flowvar or flowint is available. */ -#define SIG_FLAG_FILESTORE (1<<18) /**< signature has filestore keyword */ +#define SIG_FLAG_FILESTORE (1<<19) /**< signature has filestore keyword */ /* signature init flags */ #define SIG_FLAG_INIT_DEONLY 1 /**< decode event only signature */ diff --git a/src/flow.h b/src/flow.h index bcb0457fdd..c63c35d96c 100644 --- a/src/flow.h +++ b/src/flow.h @@ -168,8 +168,10 @@ #define FLOW_PKT_STATELESS 0x08 #define FLOW_PKT_TOSERVER_IPONLY_SET 0x10 #define FLOW_PKT_TOCLIENT_IPONLY_SET 0x20 +/** \todo only used by flow keyword internally. */ #define FLOW_PKT_NOSTREAM 0x40 -#define FLOW_PKT_STREAMONLY 0x80 +/** \todo only used by flow keyword internally. */ +#define FLOW_PKT_ONLYSTREAM 0x80 /* global flow config */ typedef struct FlowCnf_