http: introduces ALPROTO_HTTP_ANY

For any versions of HTTP, both ALPROTO_HTTP and ALPROTO_HTTP2
pull/5875/head
Philippe Antoine 6 years ago committed by Victor Julien
parent c8dbe24fb6
commit 93e6401ce0

@ -2094,9 +2094,15 @@ void AppLayerProtoDetectSupportedIpprotos(AppProto alproto, uint8_t *ipprotos)
{
SCEnter();
AppLayerProtoDetectPMGetIpprotos(alproto, ipprotos);
AppLayerProtoDetectPPGetIpprotos(alproto, ipprotos);
AppLayerProtoDetectPEGetIpprotos(alproto, ipprotos);
// Custom case for only signature-only protocol so far
if (alproto == ALPROTO_HTTP_ANY) {
AppLayerProtoDetectSupportedIpprotos(ALPROTO_HTTP, ipprotos);
AppLayerProtoDetectSupportedIpprotos(ALPROTO_HTTP2, ipprotos);
} else {
AppLayerProtoDetectPMGetIpprotos(alproto, ipprotos);
AppLayerProtoDetectPPGetIpprotos(alproto, ipprotos);
AppLayerProtoDetectPEGetIpprotos(alproto, ipprotos);
}
SCReturn;
}
@ -2109,6 +2115,7 @@ AppProto AppLayerProtoDetectGetProtoByName(const char *alproto_name)
AppProto b = StringToAppProto(alproto_name);
for (a = 0; a < ALPROTO_MAX; a++) {
if (alpd_ctx.alproto_names[a] != NULL && AppProtoEquals(b, a)) {
// That means return HTTP_ANY if HTTP1 or HTTP2 is enabled
SCReturnCT(b, "AppProto");
}
}

@ -1140,6 +1140,11 @@ uint64_t AppLayerParserGetTransactionActive(const Flow *f,
int AppLayerParserSupportsFiles(uint8_t ipproto, AppProto alproto)
{
// Custom case for only signature-only protocol so far
if (alproto == ALPROTO_HTTP_ANY) {
return AppLayerParserSupportsFiles(ipproto, ALPROTO_HTTP) ||
AppLayerParserSupportsFiles(ipproto, ALPROTO_HTTP2);
}
if (alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].StateGetFiles != NULL)
return TRUE;
return FALSE;

@ -120,6 +120,9 @@ const char *AppProtoToString(AppProto alproto)
case ALPROTO_HTTP2:
proto_name = "http2";
break;
case ALPROTO_HTTP_ANY:
proto_name = "http_any";
break;
case ALPROTO_FAILED:
proto_name = "failed";
break;
@ -138,7 +141,10 @@ AppProto StringToAppProto(const char *proto_name)
{
if (proto_name == NULL) return ALPROTO_UNKNOWN;
if (strcmp(proto_name,"http")==0) return ALPROTO_HTTP;
if (strcmp(proto_name, "http") == 0)
return ALPROTO_HTTP_ANY;
if (strcmp(proto_name, "http1") == 0)
return ALPROTO_HTTP;
if (strcmp(proto_name,"ftp")==0) return ALPROTO_FTP;
if (strcmp(proto_name, "ftp-data") == 0)
return ALPROTO_FTPDATA;

@ -58,6 +58,10 @@ enum AppProtoEnum {
ALPROTO_RDP,
ALPROTO_HTTP2,
// signature-only (ie not seen in flow)
// HTTP for any version (ALPROTO_HTTP (version 1) or ALPROTO_HTTP2)
ALPROTO_HTTP_ANY,
/* used by the probing parser when alproto detection fails
* permanently for that particular stream */
ALPROTO_FAILED,
@ -80,6 +84,11 @@ static inline bool AppProtoIsValid(AppProto a)
// wether a signature AppProto matches a flow (or signature) AppProto
static inline bool AppProtoEquals(AppProto sigproto, AppProto alproto)
{
switch (sigproto) {
case ALPROTO_HTTP_ANY:
return (alproto == ALPROTO_HTTP) || (alproto == ALPROTO_HTTP2) ||
(alproto == ALPROTO_HTTP_ANY);
}
return (sigproto == alproto);
}

@ -236,6 +236,16 @@ static int DetectAppLayerEventParseAppP2(DetectAppLayerEventData *data,
return 0;
}
static AppProto AppLayerEventGetProtoByName(char *alproto_name)
{
AppProto alproto = AppLayerGetProtoByName(alproto_name);
if (alproto == ALPROTO_HTTP_ANY) {
// app-layer events http refer to http1
alproto = ALPROTO_HTTP;
}
return alproto;
}
static DetectAppLayerEventData *DetectAppLayerEventParseAppP1(const char *arg)
{
/* period index */
@ -250,7 +260,7 @@ static DetectAppLayerEventData *DetectAppLayerEventParseAppP1(const char *arg)
/* + 1 for trailing \0 */
strlcpy(alproto_name, arg, p_idx - arg + 1);
const AppProto alproto = AppLayerGetProtoByName(alproto_name);
const AppProto alproto = AppLayerEventGetProtoByName(alproto_name);
if (alproto == ALPROTO_UNKNOWN) {
if (!strcmp(alproto_name, "file")) {
needs_detctx = true;

@ -290,7 +290,7 @@ static int DetectAppLayerProtocolTest01(void)
{
DetectAppLayerProtocolData *data = DetectAppLayerProtocolParse("http", false);
FAIL_IF_NULL(data);
FAIL_IF(data->alproto != ALPROTO_HTTP);
FAIL_IF(data->alproto != ALPROTO_HTTP_ANY);
FAIL_IF(data->negated != 0);
DetectAppLayerProtocolFree(NULL, data);
PASS;
@ -300,7 +300,7 @@ static int DetectAppLayerProtocolTest02(void)
{
DetectAppLayerProtocolData *data = DetectAppLayerProtocolParse("http", true);
FAIL_IF_NULL(data);
FAIL_IF(data->alproto != ALPROTO_HTTP);
FAIL_IF(data->alproto != ALPROTO_HTTP_ANY);
FAIL_IF(data->negated == 0);
DetectAppLayerProtocolFree(NULL, data);
PASS;
@ -324,7 +324,7 @@ static int DetectAppLayerProtocolTest03(void)
FAIL_IF_NULL(s->sm_lists[DETECT_SM_LIST_MATCH]->ctx);
data = (DetectAppLayerProtocolData *)s->sm_lists[DETECT_SM_LIST_MATCH]->ctx;
FAIL_IF(data->alproto != ALPROTO_HTTP);
FAIL_IF(data->alproto != ALPROTO_HTTP_ANY);
FAIL_IF(data->negated);
DetectEngineCtxFree(de_ctx);
PASS;
@ -349,7 +349,7 @@ static int DetectAppLayerProtocolTest04(void)
data = (DetectAppLayerProtocolData*)s->sm_lists[DETECT_SM_LIST_MATCH]->ctx;
FAIL_IF_NULL(data);
FAIL_IF(data->alproto != ALPROTO_HTTP);
FAIL_IF(data->alproto != ALPROTO_HTTP_ANY);
FAIL_IF(data->negated == 0);
DetectEngineCtxFree(de_ctx);
@ -375,7 +375,7 @@ static int DetectAppLayerProtocolTest05(void)
data = (DetectAppLayerProtocolData*)s->sm_lists[DETECT_SM_LIST_MATCH]->ctx;
FAIL_IF_NULL(data);
FAIL_IF(data->alproto != ALPROTO_HTTP);
FAIL_IF(data->alproto != ALPROTO_HTTP_ANY);
FAIL_IF(data->negated == 0);
data = (DetectAppLayerProtocolData*)s->sm_lists[DETECT_SM_LIST_MATCH]->next->ctx;
@ -515,7 +515,7 @@ static int DetectAppLayerProtocolTest14(void)
FAIL_IF_NULL(s1->sm_lists[DETECT_SM_LIST_MATCH]);
FAIL_IF_NULL(s1->sm_lists[DETECT_SM_LIST_MATCH]->ctx);
data = (DetectAppLayerProtocolData *)s1->sm_lists[DETECT_SM_LIST_MATCH]->ctx;
FAIL_IF(data->alproto != ALPROTO_HTTP);
FAIL_IF(data->alproto != ALPROTO_HTTP_ANY);
FAIL_IF(data->negated);
Signature *s2 = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any "
@ -525,7 +525,7 @@ static int DetectAppLayerProtocolTest14(void)
FAIL_IF_NULL(s2->sm_lists[DETECT_SM_LIST_MATCH]);
FAIL_IF_NULL(s2->sm_lists[DETECT_SM_LIST_MATCH]->ctx);
data = (DetectAppLayerProtocolData *)s2->sm_lists[DETECT_SM_LIST_MATCH]->ctx;
FAIL_IF(data->alproto != ALPROTO_HTTP);
FAIL_IF(data->alproto != ALPROTO_HTTP_ANY);
FAIL_IF(data->negated);
/* flow:established and other options not supported for PD-only */
@ -536,7 +536,7 @@ static int DetectAppLayerProtocolTest14(void)
FAIL_IF_NULL(s3->sm_lists[DETECT_SM_LIST_MATCH]);
FAIL_IF_NULL(s3->sm_lists[DETECT_SM_LIST_MATCH]->ctx);
data = (DetectAppLayerProtocolData *)s3->sm_lists[DETECT_SM_LIST_MATCH]->ctx;
FAIL_IF(data->alproto != ALPROTO_HTTP);
FAIL_IF(data->alproto != ALPROTO_HTTP_ANY);
FAIL_IF(data->negated);
SigGroupBuild(de_ctx);

@ -269,13 +269,14 @@ static int DetectFiledataSetup (DetectEngineCtx *de_ctx, Signature *s, const cha
(s->alproto != ALPROTO_UNKNOWN && s->alproto != ALPROTO_HTTP &&
s->alproto != ALPROTO_SMTP && s->alproto != ALPROTO_SMB &&
s->alproto != ALPROTO_HTTP2 && s->alproto != ALPROTO_FTP &&
s->alproto != ALPROTO_FTPDATA)) {
s->alproto != ALPROTO_FTPDATA && s->alproto != ALPROTO_HTTP_ANY)) {
SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "rule contains conflicting keywords.");
return -1;
}
if (s->alproto == ALPROTO_HTTP && (s->init_data->init_flags & SIG_FLAG_INIT_FLOW) &&
(s->flags & SIG_FLAG_TOSERVER) && !(s->flags & SIG_FLAG_TOCLIENT)) {
if ((s->alproto == ALPROTO_HTTP || s->alproto == ALPROTO_HTTP_ANY) &&
(s->init_data->init_flags & SIG_FLAG_INIT_FLOW) && (s->flags & SIG_FLAG_TOSERVER) &&
!(s->flags & SIG_FLAG_TOCLIENT)) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "Can't use file_data with "
"flow:to_server or flow:from_client with http.");
return -1;
@ -299,11 +300,11 @@ static int DetectFiledataSetup (DetectEngineCtx *de_ctx, Signature *s, const cha
static void DetectFiledataSetupCallback(const DetectEngineCtx *de_ctx,
Signature *s)
{
if (s->alproto == ALPROTO_HTTP || s->alproto == ALPROTO_UNKNOWN) {
if (s->alproto == ALPROTO_HTTP || s->alproto == ALPROTO_UNKNOWN ||
s->alproto == ALPROTO_HTTP_ANY) {
AppLayerHtpEnableResponseBodyCallback();
}
/* server body needs to be inspected in sync with stream if possible */
s->init_data->init_flags |= SIG_FLAG_INIT_NEED_FLUSH;

@ -455,7 +455,7 @@ static int DetectFilestoreSetup (DetectEngineCtx *de_ctx, Signature *s, const ch
sm->ctx = (SigMatchCtx*)NULL;
}
if (s->alproto == ALPROTO_HTTP) {
if (s->alproto == ALPROTO_HTTP || s->alproto == ALPROTO_HTTP_ANY) {
AppLayerHtpNeedFileInspection();
}

@ -1493,6 +1493,8 @@ int DetectSignatureSetAppProto(Signature *s, AppProto alproto)
if (s->alproto != ALPROTO_UNKNOWN && !AppProtoEquals(s->alproto, alproto)) {
if (AppProtoEquals(alproto, s->alproto)) {
// happens if alproto = HTTP_ANY and s->alproto = HTTP1
// in this case, we must keep the most restrictive HTTP1
alproto = s->alproto;
} else {
SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS,
@ -1874,7 +1876,7 @@ static int SigValidate(DetectEngineCtx *de_ctx, Signature *s)
SCReturnInt(0);
}
if (s->alproto == ALPROTO_HTTP) {
if (s->alproto == ALPROTO_HTTP || s->alproto == ALPROTO_HTTP_ANY) {
AppLayerHtpNeedFileInspection();
}
}

Loading…
Cancel
Save