suricata
detect-template-rust-buffer.c
Go to the documentation of this file.
1 /* Copyright (C) 2015-2017 Open Information Security Foundation
2  *
3  * You can copy, redistribute or modify this Program under the terms of
4  * the GNU General Public License version 2 as published by the Free
5  * Software Foundation.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * version 2 along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15  * 02110-1301, USA.
16  */
17 
18 /*
19  * TODO: Update the \author in this file and detect-template.h.
20  * TODO: Update description in the \file section below.
21  * TODO: Remove SCLogNotice statements or convert to debug.
22  */
23 
24 /**
25  * \file
26  *
27  * \author FirstName LastName <yourname@domain>
28  *
29  * Set up of the "template_rust" keyword to allow content
30  * inspections on the decoded template application layer buffers.
31  */
32 
33 #include "suricata-common.h"
34 #include "conf.h"
35 #include "detect.h"
36 #include "detect-parse.h"
37 #include "detect-engine.h"
40 #include "app-layer-parser.h"
41 
42 #ifndef HAVE_RUST
43 
45 {
46 }
47 
48 #else
49 
50 #include "rust-applayertemplate-template-gen.h"
51 
52 static int DetectTemplateRustBufferSetup(DetectEngineCtx *, Signature *,
53  const char *);
54 static int DetectEngineInspectTemplateRustBuffer(ThreadVars *tv,
55  DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx,
56  const Signature *s, const SigMatchData *smd,
57  Flow *f, uint8_t flags, void *alstate, void *txv, uint64_t tx_id);
58 static void DetectTemplateRustBufferRegisterTests(void);
59 static int g_template_rust_id = 0;
60 
62 {
63  /* TEMPLATE_START_REMOVE */
64  if (ConfGetNode("app-layer.protocols.template-rust") == NULL) {
65  return;
66  }
67  /* TEMPLATE_END_REMOVE */
69  "template_rust_buffer";
71  "Template content modififier to match on the template buffers";
73  DetectTemplateRustBufferSetup;
75  DetectTemplateRustBufferRegisterTests;
76 
78 
79  /* register inspect engines */
80  DetectAppLayerInspectEngineRegister("template_rust_buffer",
82  DetectEngineInspectTemplateRustBuffer);
83  DetectAppLayerInspectEngineRegister("template_rust_buffer",
85  DetectEngineInspectTemplateRustBuffer);
86 
87  g_template_rust_id = DetectBufferTypeGetByName("template_rust_buffer");
88 
89  SCLogNotice("Template application layer detect registered.");
90 }
91 
92 static int DetectTemplateRustBufferSetup(DetectEngineCtx *de_ctx, Signature *s,
93  const char *str)
94 {
95  s->init_data->list = g_template_rust_id;
96 
98  return -1;
99 
100  return 0;
101 }
102 
103 static int DetectEngineInspectTemplateRustBuffer(ThreadVars *tv,
104  DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx,
105  const Signature *s, const SigMatchData *smd,
106  Flow *f, uint8_t flags, void *alstate, void *txv, uint64_t tx_id)
107 {
108  int ret = 0;
109  const uint8_t *data = NULL;
110  uint32_t data_len = 0;
111 
112  if (flags & STREAM_TOSERVER) {
113  rs_template_get_request_buffer(txv, (uint8_t **)&data, &data_len);
114  } else if (flags & STREAM_TOCLIENT) {
115  rs_template_get_response_buffer(txv, (uint8_t **)&data, &data_len);
116  }
117 
118  if (data != NULL) {
119  ret = DetectEngineContentInspection(de_ctx, det_ctx, s, smd,
120  f, (uint8_t *)data, data_len, 0, DETECT_CI_FLAGS_SINGLE,
122  }
123 
124  SCLogNotice("Returning %d.", ret);
125  return ret;
126 }
127 
128 #ifdef UNITTESTS
129 
130 #include "util-unittest.h"
131 #include "util-unittest-helper.h"
132 #include "app-layer-parser.h"
133 #include "detect-engine.h"
134 #include "detect-parse.h"
135 #include "flow-util.h"
136 #include "stream-tcp.h"
137 
138 static int DetectTemplateRustBufferTest(void)
139 {
141  DetectEngineThreadCtx *det_ctx = NULL;
142  DetectEngineCtx *de_ctx = NULL;
143  Flow f;
144  Packet *p;
145  TcpSession tcp;
146  ThreadVars tv;
147  Signature *s;
148 
149  uint8_t request[] = "12:Hello World!";
150 
151  /* Setup flow. */
152  memset(&f, 0, sizeof(Flow));
153  memset(&tcp, 0, sizeof(TcpSession));
154  memset(&tv, 0, sizeof(ThreadVars));
155  p = UTHBuildPacket(request, sizeof(request), IPPROTO_TCP);
156  FLOW_INITIALIZE(&f);
158  f.protoctx = (void *)&tcp;
159  f.proto = IPPROTO_TCP;
160  f.flags |= FLOW_IPV4;
161  p->flow = &f;
165 
166  de_ctx = DetectEngineCtxInit();
167  FAIL_IF_NULL(de_ctx);
168 
169  /* This rule should match. */
170  s = DetectEngineAppendSig(de_ctx,
171  "alert tcp any any -> any any ("
172  "msg:\"TEMPLATE Test Rule\"; "
173  "template_rust_buffer; content:\"World!\"; "
174  "sid:1; rev:1;)");
175  FAIL_IF_NULL(s);
176 
177  /* This rule should not match. */
178  s = DetectEngineAppendSig(de_ctx,
179  "alert tcp any any -> any any ("
180  "msg:\"TEMPLATE Test Rule\"; "
181  "template_rust_buffer; content:\"W0rld!\"; "
182  "sid:2; rev:1;)");
183  FAIL_IF_NULL(s);
184 
185  SigGroupBuild(de_ctx);
186  DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
187 
188  FLOWLOCK_WRLOCK(&f);
189  AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_TEMPLATE_RUST,
190  STREAM_TOSERVER, request, sizeof(request));
191  FLOWLOCK_UNLOCK(&f);
192 
193  /* Check that we have app-layer state. */
195 
196  SigMatchSignatures(&tv, de_ctx, det_ctx, p);
197  FAIL_IF(!PacketAlertCheck(p, 1));
198  FAIL_IF(PacketAlertCheck(p, 2));
199 
200  /* Cleanup. */
201  if (alp_tctx != NULL)
202  AppLayerParserThreadCtxFree(alp_tctx);
203  if (det_ctx != NULL)
204  DetectEngineThreadCtxDeinit(&tv, det_ctx);
205  if (de_ctx != NULL)
206  SigGroupCleanup(de_ctx);
207  if (de_ctx != NULL)
208  DetectEngineCtxFree(de_ctx);
210  FLOW_DESTROY(&f);
211  UTHFreePacket(p);
212 
213  PASS;
214 }
215 
216 #endif
217 
218 static void DetectTemplateRustBufferRegisterTests(void)
219 {
220 #ifdef UNITTESTS
221  UtRegisterTest("DetectTemplateRustBufferTest",
222  DetectTemplateRustBufferTest);
223 #endif /* UNITTESTS */
224 }
225 
226 #endif
Signature * DetectEngineAppendSig(DetectEngineCtx *de_ctx, const char *sigstr)
Parse and append a Signature into the Detection Engine Context signature list.
SigTableElmt sigmatch_table[DETECT_TBLSIZE]
Definition: detect.h:1403
SignatureInitData * init_data
Definition: detect.h:560
uint16_t flags
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition: detect.h:1146
int DetectSignatureSetAppProto(Signature *s, AppProto alproto)
struct Flow_ * flow
Definition: decode.h:444
int PacketAlertCheck(Packet *p, uint32_t sid)
Check if a certain sid alerted, this is used in the test functions.
uint8_t proto
Definition: flow.h:346
#define FLOWLOCK_UNLOCK(fb)
Definition: flow.h:235
#define PASS
Pass the test.
void DetectTemplateRustBufferRegister(void)
#define FAIL_IF(expr)
Fail a test if expression evaluates to false.
Definition: util-unittest.h:71
void AppLayerParserThreadCtxFree(AppLayerParserThreadCtx *tctx)
Destroys the app layer parser thread context obtained using AppLayerParserThreadCtxAlloc().
#define FLOW_PKT_ESTABLISHED
Definition: flow.h:195
Data needed for Match()
Definition: detect.h:333
void StreamTcpFreeConfig(char quiet)
Definition: stream-tcp.c:669
#define FLOWLOCK_WRLOCK(fb)
Definition: flow.h:232
TmEcode DetectEngineThreadCtxInit(ThreadVars *, void *, void **)
initialize thread specific detection engine context
const char * name
Definition: detect.h:1160
Signature container.
Definition: detect.h:492
#define TRUE
void * protoctx
Definition: flow.h:398
main detection engine ctx
Definition: detect.h:720
TmEcode DetectEngineThreadCtxDeinit(ThreadVars *, void *)
void * alstate
Definition: flow.h:436
int DetectBufferTypeGetByName(const char *name)
#define str(s)
#define SIG_FLAG_TOCLIENT
Definition: detect.h:244
#define FLOW_DESTROY(f)
Definition: flow-util.h:115
int SigGroupBuild(DetectEngineCtx *de_ctx)
Convert the signature list into the runtime match structure.
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
void SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Packet *p)
wrapper for old tests
Definition: detect.c:1752
#define SIG_FLAG_TOSERVER
Definition: detect.h:243
void StreamTcpInitConfig(char)
To initialize the stream global configuration data.
Definition: stream-tcp.c:365
uint8_t flowflags
Definition: decode.h:438
Packet * UTHBuildPacket(uint8_t *payload, uint16_t payload_len, uint8_t ipproto)
UTHBuildPacket is a wrapper that build packets with default ip and port fields.
#define STREAM_TOCLIENT
Definition: stream.h:32
#define FLOW_PKT_TOSERVER
Definition: flow.h:193
AppLayerParserThreadCtx * AppLayerParserThreadCtxAlloc(void)
Gets a new app layer protocol&#39;s parser thread context.
int SigGroupCleanup(DetectEngineCtx *de_ctx)
const char * desc
Definition: detect.h:1162
#define SCLogNotice(...)
Macro used to log NOTICE messages.
Definition: util-debug.h:269
uint16_t tx_id
#define SIGMATCH_NOOPT
Definition: detect.h:1328
int DetectEngineContentInspection(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, const Signature *s, const SigMatchData *smd, Flow *f, uint8_t *buffer, uint32_t buffer_len, uint32_t stream_start_offset, uint8_t flags, uint8_t inspection_mode, void *data)
Run the actual payload match functions.
#define FLOW_INITIALIZE(f)
Definition: flow-util.h:39
#define STREAM_TOSERVER
Definition: stream.h:31
void UTHFreePacket(Packet *p)
UTHFreePacket: function to release the allocated data from UTHBuildPacket and the packet itself...
ConfNode * ConfGetNode(const char *name)
Get a ConfNode by name.
Definition: conf.c:176
#define PKT_HAS_FLOW
Definition: decode.h:1101
#define DETECT_CI_FLAGS_SINGLE
#define FAIL_IF_NULL(expr)
Fail a test if expression evaluates to NULL.
Definition: util-unittest.h:89
Per thread variable structure.
Definition: threadvars.h:57
AppProto alproto
application level protocol
Definition: flow.h:407
uint32_t flags
Definition: decode.h:442
uint16_t flags
Definition: detect.h:1154
void DetectEngineCtxFree(DetectEngineCtx *)
Free a DetectEngineCtx::
Flow data structure.
Definition: flow.h:327
#define FLOW_IPV4
Definition: flow.h:93
uint32_t flags
Definition: flow.h:377
#define PKT_STREAM_EST
Definition: decode.h:1099
void DetectAppLayerInspectEngineRegister(const char *name, AppProto alproto, uint32_t dir, int progress, InspectEngineFuncPtr Callback)
register inspect engine at start up time
void(* RegisterTests)(void)
Definition: detect.h:1152
int AppLayerParserParse(ThreadVars *tv, AppLayerParserThreadCtx *alp_tctx, Flow *f, AppProto alproto, uint8_t flags, uint8_t *input, uint32_t input_len)
DetectEngineCtx * DetectEngineCtxInit(void)