Let flow:only_stream and flow:no_stream set the require packet and require stream flags. Toss out sigs with conflicting settings. Rename flow:stream_only to flow:only_stream. Fixes #261.

remotes/origin/master-1.2.x
Victor Julien 15 years ago
parent c04f45ccb9
commit 298289f43f

@ -53,7 +53,6 @@ void DetectFlowFree(void *);
/** /**
* \brief Registration function for flow: keyword * \brief Registration function for flow: keyword
* \todo add support for no_stream and stream_only
*/ */
void DetectFlowRegister (void) { void DetectFlowRegister (void) {
sigmatch_table[DETECT_FLOW].name = "flow"; 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: * \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 t pointer to thread vars
* \param det_ctx pointer to the pattern matcher thread * \param det_ctx pointer to the pattern matcher thread
@ -238,21 +236,21 @@ DetectFlowData *DetectFlowParse (char *flowstr)
goto error; goto error;
} }
fd->flags |= FLOW_PKT_TOSERVER; fd->flags |= FLOW_PKT_TOSERVER;
} else if (strcasecmp(args[i], "stream_only") == 0) { } else if (strcasecmp(args[i], "only_stream") == 0) {
if (fd->flags & FLOW_PKT_STREAMONLY) { if (fd->flags & FLOW_PKT_ONLYSTREAM) {
SCLogError(SC_ERR_FLAGS_MODIFIER, "cannot set stream_only flag is already set"); SCLogError(SC_ERR_FLAGS_MODIFIER, "cannot set only_stream flag is already set");
goto error; goto error;
} else if (fd->flags & FLOW_PKT_NOSTREAM) { } 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; goto error;
} }
fd->flags |= FLOW_PKT_STREAMONLY; fd->flags |= FLOW_PKT_ONLYSTREAM;
} else if (strcasecmp(args[i], "no_stream") == 0) { } else if (strcasecmp(args[i], "no_stream") == 0) {
if (fd->flags & FLOW_PKT_NOSTREAM) { if (fd->flags & FLOW_PKT_NOSTREAM) {
SCLogError(SC_ERR_FLAGS_MODIFIER, "cannot set no_stream flag is already set"); SCLogError(SC_ERR_FLAGS_MODIFIER, "cannot set no_stream flag is already set");
goto error; goto error;
} else if (fd->flags & FLOW_PKT_STREAMONLY) { } else if (fd->flags & FLOW_PKT_ONLYSTREAM) {
SCLogError(SC_ERR_FLAGS_MODIFIER, "cannot set no_stream flag, FLOW_PKT_STREAMONLY already set"); SCLogError(SC_ERR_FLAGS_MODIFIER, "cannot set no_stream flag, FLOW_PKT_ONLYSTREAM already set");
goto error; goto error;
} }
fd->flags |= FLOW_PKT_NOSTREAM; fd->flags |= FLOW_PKT_NOSTREAM;
@ -302,7 +300,8 @@ int DetectFlowSetup (DetectEngineCtx *de_ctx, Signature *s, char *flowstr)
//printf("DetectFlowSetup: \'%s\'\n", flowstr); //printf("DetectFlowSetup: \'%s\'\n", flowstr);
fd = DetectFlowParse(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 /* Okay so far so good, lets get this into a SigMatch
* and put it in the Signature. */ * and put it in the Signature. */
@ -315,6 +314,13 @@ int DetectFlowSetup (DetectEngineCtx *de_ctx, Signature *s, char *flowstr)
SigMatchAppendPacket(s, sm); 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; s->init_flags |= SIG_FLAG_INIT_FLOW;
return 0; 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 DetectFlowTestParse18 (void) {
int result = 0; int result = 0;
DetectFlowData *fd = NULL; DetectFlowData *fd = NULL;
fd = DetectFlowParse("from_server,established,stream_only"); fd = DetectFlowParse("from_server,established,only_stream");
if (fd != NULL) { 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; result = 1;
} else { } 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); fd->flags, fd->match_cnt);
} }
DetectFlowFree(fd); 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 DetectFlowTestParseNocase18 (void) {
int result = 0; int result = 0;
DetectFlowData *fd = NULL; DetectFlowData *fd = NULL;
fd = DetectFlowParse("FROM_SERVER,ESTABLISHED,STREAM_ONLY"); fd = DetectFlowParse("FROM_SERVER,ESTABLISHED,ONLY_STREAM");
if (fd != NULL) { 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; result = 1;
} else { } 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); fd->flags, fd->match_cnt);
} }
DetectFlowFree(fd); DetectFlowFree(fd);
@ -893,7 +899,7 @@ int DetectFlowTestParseNocase18 (void) {
int DetectFlowTestParse19 (void) { int DetectFlowTestParse19 (void) {
int result = 1; int result = 1;
DetectFlowData *fd = NULL; DetectFlowData *fd = NULL;
fd = DetectFlowParse("from_server,established,stream_only,a"); fd = DetectFlowParse("from_server,established,only_stream,a");
if (fd != NULL) { if (fd != NULL) {
printf("expected: NULL got 0x%02X %" PRId32 ": ",fd->flags, fd->match_cnt); printf("expected: NULL got 0x%02X %" PRId32 ": ",fd->flags, fd->match_cnt);
result = 0; result = 0;

@ -819,6 +819,12 @@ int SigParseProto(Signature *s, const char *protostr) {
SCReturnInt(-1); 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); SCReturnInt(0);
} }
@ -1305,6 +1311,12 @@ static void SigBuildAddressMatchArray(Signature *s) {
static int SigValidate(Signature *s) { static int SigValidate(Signature *s) {
SCEnter(); 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 */ /* check for uricontent + from_server/to_client */
if (s->sm_lists[DETECT_SM_LIST_UMATCH] != NULL) { if (s->sm_lists[DETECT_SM_LIST_UMATCH] != NULL) {
SigMatch *sm; SigMatch *sm;

@ -233,18 +233,20 @@ typedef struct DetectPort_ {
#define SIG_FLAG_IPONLY (1<<8) /**< ip only signature */ #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_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_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 (1<<12)
#define SIG_FLAG_MPM_PACKET_NEG (1<<12) #define SIG_FLAG_MPM_PACKET_NEG (1<<13)
#define SIG_FLAG_MPM_STREAM (1<<13) #define SIG_FLAG_MPM_STREAM (1<<14)
#define SIG_FLAG_MPM_STREAM_NEG (1<<14) #define SIG_FLAG_MPM_STREAM_NEG (1<<15)
#define SIG_FLAG_MPM_HTTP (1<<15) #define SIG_FLAG_MPM_HTTP (1<<16)
#define SIG_FLAG_MPM_HTTP_NEG (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 */ /* signature init flags */
#define SIG_FLAG_INIT_DEONLY 1 /**< decode event only signature */ #define SIG_FLAG_INIT_DEONLY 1 /**< decode event only signature */

@ -168,8 +168,10 @@
#define FLOW_PKT_STATELESS 0x08 #define FLOW_PKT_STATELESS 0x08
#define FLOW_PKT_TOSERVER_IPONLY_SET 0x10 #define FLOW_PKT_TOSERVER_IPONLY_SET 0x10
#define FLOW_PKT_TOCLIENT_IPONLY_SET 0x20 #define FLOW_PKT_TOCLIENT_IPONLY_SET 0x20
/** \todo only used by flow keyword internally. */
#define FLOW_PKT_NOSTREAM 0x40 #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 */ /* global flow config */
typedef struct FlowCnf_ typedef struct FlowCnf_

Loading…
Cancel
Save