DETECT_AL_HTTP_HEADER_REFERER,
DETECT_AL_HTTP_RAW_HEADER,
DETECT_AL_HTTP_URI,
+ DETECT_HTTP_URI,
DETECT_AL_HTTP_RAW_URI,
DETECT_AL_HTTP_STAT_MSG,
DETECT_AL_HTTP_STAT_CODE,
#include "app-layer-protos.h"
#include "util-validate.h"
-/** \brief HTTP URI Mpm prefilter callback
- *
- * \param det_ctx detection engine thread ctx
- * \param p packet to inspect
- * \param f flow to inspect
- * \param txv tx to inspect
- * \param pectx inspection context
- */
-static void PrefilterTxUri(DetectEngineThreadCtx *det_ctx, const void *pectx,
- Packet *p, Flow *f, void *txv,
- const uint64_t idx, const uint8_t flags)
-{
- SCEnter();
-
- const MpmCtx *mpm_ctx = (MpmCtx *)pectx;
- htp_tx_t *tx = (htp_tx_t *)txv;
- HtpTxUserData *tx_ud = htp_tx_get_user_data(tx);
-
- if (tx_ud == NULL || tx_ud->request_uri_normalized == NULL)
- return;
-
- const uint32_t uri_len = bstr_len(tx_ud->request_uri_normalized);
- const uint8_t *uri = bstr_ptr(tx_ud->request_uri_normalized);
-
- if (uri_len >= mpm_ctx->minlen) {
- (void)mpm_table[mpm_ctx->mpm_type].Search(mpm_ctx,
- &det_ctx->mtcu, &det_ctx->pmq, uri, uri_len);
- }
-}
-
-int PrefilterTxUriRegister(DetectEngineCtx *de_ctx,
- SigGroupHead *sgh, MpmCtx *mpm_ctx)
-{
- SCEnter();
-
- return PrefilterAppendTxEngine(de_ctx, sgh, PrefilterTxUri,
- ALPROTO_HTTP, HTP_REQUEST_LINE,
- mpm_ctx, NULL, "http_uri");
-}
-
-/**
- * \brief Do the content inspection & validation for a signature
- *
- * \param de_ctx Detection engine context
- * \param det_ctx Detection engine thread context
- * \param s Signature to inspect
- * \param sm SigMatch to inspect
- * \param f Flow
- * \param flags app layer flags
- * \param state App layer state
- *
- * \retval 0 no match.
- * \retval 1 match.
- * \retval 2 Sig can't match.
- */
-int DetectEngineInspectHttpUri(ThreadVars *tv,
- DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx,
- const Signature *s, const SigMatchData *smd,
- Flow *f, uint8_t flags, void *alstate, void *txv, uint64_t tx_id)
-{
- HtpTxUserData *tx_ud = htp_tx_get_user_data(txv);
-
- if (tx_ud == NULL || tx_ud->request_uri_normalized == NULL) {
- if (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, txv, flags) > HTP_REQUEST_LINE)
- return DETECT_ENGINE_INSPECT_SIG_CANT_MATCH;
- else
- return DETECT_ENGINE_INSPECT_SIG_NO_MATCH;
- }
-
- det_ctx->discontinue_matching = 0;
- det_ctx->buffer_offset = 0;
- det_ctx->inspection_recursion_counter = 0;
-
-#if 0
- PrintRawDataFp(stdout, (uint8_t *)bstr_ptr(tx_ud->request_uri_normalized),
- bstr_len(tx_ud->request_uri_normalized));
-#endif
-
- /* Inspect all the uricontents fetched on each
- * transaction at the app layer */
- int r = DetectEngineContentInspection(de_ctx, det_ctx, s, smd,
- f,
- bstr_ptr(tx_ud->request_uri_normalized),
- bstr_len(tx_ud->request_uri_normalized),
- 0, DETECT_CI_FLAGS_SINGLE,
- DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE, NULL);
- if (r == 1) {
- return DETECT_ENGINE_INSPECT_SIG_MATCH;
- } else {
- return DETECT_ENGINE_INSPECT_SIG_CANT_MATCH;
- }
-}
-
/***********************************Unittests**********************************/
#ifdef UNITTESTS
#include "detect-parse.h"
#include "detect-engine.h"
#include "detect-engine-mpm.h"
+#include "detect-engine-prefilter.h"
#include "detect-content.h"
#include "detect-pcre.h"
#include "detect-urilen.h"
static void DetectHttpUriSetupCallback(const DetectEngineCtx *de_ctx,
Signature *s);
static bool DetectHttpUriValidateCallback(const Signature *s, const char **sigerror);
-
+static InspectionBuffer *GetData(DetectEngineThreadCtx *det_ctx,
+ const DetectEngineTransforms *transforms,
+ Flow *_f, const uint8_t _flow_flags,
+ void *txv, const int list_id);
+static int DetectHttpUriSetupSticky(DetectEngineCtx *de_ctx, Signature *s, const char *str);
static int g_http_uri_buffer_id = 0;
/**
- * \brief Registration function for keyword: http_uri
+ * \brief Registration function for keywords: http_uri and http.uri
*/
void DetectHttpUriRegister (void)
{
+ /* http_uri content modifier */
sigmatch_table[DETECT_AL_HTTP_URI].name = "http_uri";
sigmatch_table[DETECT_AL_HTTP_URI].desc = "content modifier to match specifically and only on the HTTP uri-buffer";
sigmatch_table[DETECT_AL_HTTP_URI].url = DOC_URL DOC_VERSION "/rules/http-keywords.html#http-uri-and-http-raw-uri";
- sigmatch_table[DETECT_AL_HTTP_URI].Match = NULL;
sigmatch_table[DETECT_AL_HTTP_URI].Setup = DetectHttpUriSetup;
- sigmatch_table[DETECT_AL_HTTP_URI].Free = NULL;
sigmatch_table[DETECT_AL_HTTP_URI].RegisterTests = DetectHttpUriRegisterTests;
-
sigmatch_table[DETECT_AL_HTTP_URI].flags |= SIGMATCH_NOOPT;
- DetectAppLayerMpmRegister("http_uri", SIG_FLAG_TOSERVER, 2,
- PrefilterTxUriRegister);
+ /* http.uri sticky buffer */
+ sigmatch_table[DETECT_HTTP_URI].name = "http.uri";
+ sigmatch_table[DETECT_HTTP_URI].alias = "http.uri.normalized";
+ sigmatch_table[DETECT_HTTP_URI].desc = "sticky buffer to match specifically and only on the normalized HTTP URI buffer";
+ sigmatch_table[DETECT_HTTP_URI].url = DOC_URL DOC_VERSION "/rules/tls-keywords.html#http-uri";
+ sigmatch_table[DETECT_HTTP_URI].Setup = DetectHttpUriSetupSticky;
+ sigmatch_table[DETECT_HTTP_URI].flags |= SIGMATCH_NOOPT;
+
+ DetectAppLayerInspectEngineRegister2("http_uri", ALPROTO_HTTP,
+ SIG_FLAG_TOSERVER, HTP_REQUEST_LINE,
+ DetectEngineInspectBufferGeneric, GetData);
- DetectAppLayerInspectEngineRegister("http_uri",
- ALPROTO_HTTP, SIG_FLAG_TOSERVER, HTP_REQUEST_LINE,
- DetectEngineInspectHttpUri);
+ DetectAppLayerMpmRegister2("http_uri", SIG_FLAG_TOSERVER, 2,
+ PrefilterGenericMpmRegister, GetData, ALPROTO_HTTP,
+ HTP_REQUEST_LINE);
DetectBufferTypeSetDescriptionByName("http_uri",
"http request uri");
g_http_uri_buffer_id = DetectBufferTypeGetByName("http_uri");
}
-
/**
* \brief this function setups the http_uri modifier keyword used in the rule
*
DetectUrilenApplyToContent(s, g_http_uri_buffer_id);
}
+/**
+ * \brief this function setup the http.uri keyword used in the rule
+ *
+ * \param de_ctx Pointer to the Detection Engine Context
+ * \param s Pointer to the Signature to which the current keyword belongs
+ * \param str Should hold an empty string always
+ *
+ * \retval 0 On success
+ */
+static int DetectHttpUriSetupSticky(DetectEngineCtx *de_ctx, Signature *s, const char *str)
+{
+ DetectBufferSetActiveList(s, g_http_uri_buffer_id);
+ s->alproto = ALPROTO_HTTP;
+ return 0;
+}
+
+static InspectionBuffer *GetData(DetectEngineThreadCtx *det_ctx,
+ const DetectEngineTransforms *transforms, Flow *_f,
+ const uint8_t _flow_flags, void *txv, const int list_id)
+{
+ SCEnter();
+
+ InspectionBuffer *buffer = InspectionBufferGet(det_ctx, list_id);
+ if (buffer->inspect == NULL) {
+ htp_tx_t *tx = (htp_tx_t *)txv;
+ HtpTxUserData *tx_ud = htp_tx_get_user_data(tx);
+
+ if (tx_ud == NULL || tx_ud->request_uri_normalized == NULL) {
+ SCLogDebug("no tx_id or uri");
+ return NULL;
+ }
+
+ const uint32_t data_len = bstr_len(tx_ud->request_uri_normalized);
+ const uint8_t *data = bstr_ptr(tx_ud->request_uri_normalized);
+
+ InspectionBufferSetup(buffer, data, data_len);
+ InspectionBufferApplyTransforms(buffer, transforms);
+ }
+
+ return buffer;
+}
+
/******************************** UNITESTS **********************************/
#ifdef UNITTESTS
DetectEngineThreadCtx *det_ctx = NULL;
Flow f;
TcpSession ssn;
- int result = 0;
AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
+ FAIL_IF_NULL(alp_tctx);
memset(&th_v, 0, sizeof(th_v));
memset(&f, 0, sizeof(f));
memset(&ssn, 0, sizeof(ssn));
p = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP);
+ FAIL_IF_NULL(p);
FLOW_INITIALIZE(&f);
f.protoctx = (void *)&ssn;
StreamTcpInitConfig(TRUE);
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
- if (de_ctx == NULL) {
- goto end;
- }
-
+ FAIL_IF_NULL(de_ctx);
de_ctx->flags |= DE_QUIET;
- de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"HTTP URI cap\"; content:\"GET \"; depth:4; pcre:\"/GET (?P<pkt_http_uri>.*) HTTP\\/\\d\\.\\d\\r\\n/G\"; sid:1;)");
- if (de_ctx->sig_list == NULL) {
- result = 0;
- goto end;
- }
+ Signature *s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (msg:\"HTTP URI cap\"; content:\"GET \"; depth:4; pcre:\"/GET (?P<pkt_http_uri>.*) HTTP\\/\\d\\.\\d\\r\\n/G\"; sid:1;)");
+ FAIL_IF_NULL(s);
- de_ctx->sig_list->next = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"HTTP URI test\"; uricontent:\"two\"; sid:2;)");
- if (de_ctx->sig_list->next == NULL) {
- result = 0;
- goto end;
- }
+ s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (msg:\"HTTP URI test\"; uricontent:\"two\"; sid:2;)");
+ FAIL_IF_NULL(s);
SigGroupBuild(de_ctx);
DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
+ FAIL_IF_NULL(det_ctx);
- FLOWLOCK_WRLOCK(&f);
int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
STREAM_TOSERVER, buf, buflen);
- if (r != 0) {
- printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
- result = 0;
- FLOWLOCK_UNLOCK(&f);
- goto end;
- }
- FLOWLOCK_UNLOCK(&f);
+ FAIL_IF(r != 0);
SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
- if (PacketAlertCheck(p, 1) && PacketAlertCheck(p, 2))
- result = 1;
- else
- printf("sid:1 %s, sid:2 %s: ",
- PacketAlertCheck(p, 1) ? "OK" : "FAIL",
- PacketAlertCheck(p, 2) ? "OK" : "FAIL");
-
- SigGroupCleanup(de_ctx);
- SigCleanSignatures(de_ctx);
+ FAIL_IF_NOT(PacketAlertCheck(p, 1));
+ FAIL_IF_NOT(PacketAlertCheck(p, 2));
DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
DetectEngineCtxFree(de_ctx);
-end:
- if (alp_tctx != NULL)
- AppLayerParserThreadCtxFree(alp_tctx);
+ AppLayerParserThreadCtxFree(alp_tctx);
UTHFreePackets(&p, 1);
StreamTcpFreeConfig(TRUE);
FLOW_DESTROY(&f);
- return result;
+ PASS;
}
static int SigTest07 (void)