suricata
detect-ssh-proto-version.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2014 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  * \file
20  *
21  * \author Pablo Rincon <pablo.rincon.crespo@gmail.com>
22  *
23  * Implements the ssh.protoversion keyword
24  * You can specify a concrete version like ssh.protoversion: 1.66
25  * or search for protoversion 2 compat (1.99 is considered as 2) like
26  * ssh.protoversion:2_compat
27  * or just the beginning of the string like ssh.protoversion:"1."
28  */
29 
30 #include "suricata-common.h"
31 #include "threads.h"
32 #include "debug.h"
33 #include "decode.h"
34 
35 #include "detect.h"
36 #include "detect-parse.h"
37 
38 #include "detect-engine.h"
39 #include "detect-engine-mpm.h"
40 #include "detect-engine-state.h"
41 
42 #include "flow.h"
43 #include "flow-var.h"
44 #include "flow-util.h"
45 
46 #include "util-debug.h"
47 #include "util-unittest.h"
48 #include "util-unittest-helper.h"
49 
50 #include "app-layer.h"
51 #include "app-layer-parser.h"
52 #include "app-layer-ssh.h"
54 
55 #include "stream-tcp.h"
56 
57 /**
58  * \brief Regex for parsing the protoversion string
59  */
60 #define PARSE_REGEX "^\\s*\"?\\s*([0-9]+([\\.\\-0-9]+)?|2_compat)\\s*\"?\\s*$"
61 
62 static pcre *parse_regex;
63 static pcre_extra *parse_regex_study;
64 
65 static int DetectSshVersionMatch (DetectEngineThreadCtx *,
66  Flow *, uint8_t, void *, void *,
67  const Signature *, const SigMatchCtx *);
68 static int DetectSshVersionSetup (DetectEngineCtx *, Signature *, const char *);
69 static void DetectSshVersionRegisterTests(void);
70 static void DetectSshVersionFree(void *);
71 static int g_ssh_banner_list_id = 0;
72 
73 /**
74  * \brief Registration function for keyword: ssh.protoversion
75  */
77 {
78  sigmatch_table[DETECT_AL_SSH_PROTOVERSION].name = "ssh.protoversion";
79  sigmatch_table[DETECT_AL_SSH_PROTOVERSION].desc = "match SSH protocol version";
80  sigmatch_table[DETECT_AL_SSH_PROTOVERSION].url = DOC_URL DOC_VERSION "/rules/ssh-keywords.html#ssh-protoversion";
82  sigmatch_table[DETECT_AL_SSH_PROTOVERSION].Setup = DetectSshVersionSetup;
83  sigmatch_table[DETECT_AL_SSH_PROTOVERSION].Free = DetectSshVersionFree;
84  sigmatch_table[DETECT_AL_SSH_PROTOVERSION].RegisterTests = DetectSshVersionRegisterTests;
87 
88  DetectSetupParseRegexes(PARSE_REGEX, &parse_regex, &parse_regex_study);
89 
90  g_ssh_banner_list_id = DetectBufferTypeRegister("ssh_banner");
91 }
92 
93 /**
94  * \brief match the specified version on a ssh session
95  *
96  * \param t pointer to thread vars
97  * \param det_ctx pointer to the pattern matcher thread
98  * \param p pointer to the current packet
99  * \param m pointer to the sigmatch that we will cast into DetectSshVersionData
100  *
101  * \retval 0 no match
102  * \retval 1 match
103  */
104 static int DetectSshVersionMatch (DetectEngineThreadCtx *det_ctx,
105  Flow *f, uint8_t flags, void *state, void *txv,
106  const Signature *s, const SigMatchCtx *m)
107 {
108  SCEnter();
109 
110  SCLogDebug("lets see");
111 
113  SshState *ssh_state = (SshState *)state;
114  if (ssh_state == NULL) {
115  SCLogDebug("no ssh state, no match");
116  SCReturnInt(0);
117  }
118 
119  int ret = 0;
120  if ((flags & STREAM_TOCLIENT) && (ssh_state->srv_hdr.flags & SSH_FLAG_VERSION_PARSED)) {
122  SCLogDebug("looking for ssh server protoversion 2 compat");
123  if (strncmp((char *) ssh_state->srv_hdr.proto_version, "2", 1) == 0 ||
124  strncmp((char *) ssh_state->srv_hdr.proto_version, "2.", 2) == 0 ||
125  strncmp((char *) ssh_state->srv_hdr.proto_version, "1.99", 4) == 0)
126  ret = 1;
127  } else {
128  SCLogDebug("looking for ssh server protoversion %s length %"PRIu16"", ssh->ver, ssh->len);
129  ret = (strncmp((char *) ssh_state->srv_hdr.proto_version, (char *) ssh->ver, ssh->len) == 0)? 1 : 0;
130  }
131  } else if ((flags & STREAM_TOSERVER) && (ssh_state->cli_hdr.flags & SSH_FLAG_VERSION_PARSED)) {
133  SCLogDebug("looking for client ssh client protoversion 2 compat");
134  if (strncmp((char *) ssh_state->cli_hdr.proto_version, "2", 1) == 0 ||
135  strncmp((char *) ssh_state->cli_hdr.proto_version, "2.", 2) == 0 ||
136  strncmp((char *) ssh_state->cli_hdr.proto_version, "1.99", 4) == 0)
137  ret = 1;
138  } else {
139  SCLogDebug("looking for ssh client protoversion %s length %"PRIu16"", ssh->ver, ssh->len);
140  ret = (strncmp((char *) ssh_state->cli_hdr.proto_version, (char *) ssh->ver, ssh->len) == 0)? 1 : 0;
141  }
142  }
143  SCReturnInt(ret);
144 }
145 
146 /**
147  * \brief This function is used to parse IPV4 ip_id passed via keyword: "id"
148  *
149  * \param idstr Pointer to the user provided id option
150  *
151  * \retval id_d pointer to DetectSshVersionData on success
152  * \retval NULL on failure
153  */
154 static DetectSshVersionData *DetectSshVersionParse (const char *str)
155 {
156  DetectSshVersionData *ssh = NULL;
157  #define MAX_SUBSTRINGS 30
158  int ret = 0, res = 0;
159  int ov[MAX_SUBSTRINGS];
160 
161  ret = pcre_exec(parse_regex, parse_regex_study, str, strlen(str), 0, 0,
162  ov, MAX_SUBSTRINGS);
163 
164  if (ret < 1 || ret > 3) {
165  SCLogError(SC_ERR_PCRE_MATCH, "invalid ssh.protoversion option");
166  goto error;
167  }
168 
169  if (ret > 1) {
170  const char *str_ptr;
171  res = pcre_get_substring((char *)str, ov, MAX_SUBSTRINGS, 1, &str_ptr);
172  if (res < 0) {
173  SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed");
174  goto error;
175  }
176 
177  /* We have a correct id option */
178  ssh = SCMalloc(sizeof(DetectSshVersionData));
179  if (unlikely(ssh == NULL)) {
180  pcre_free_substring(str_ptr);
181  goto error;
182  }
183  memset(ssh, 0x00, sizeof(DetectSshVersionData));
184 
185  /* If we expect a protocol version 2 or 1.99 (considered 2, we
186  * will compare it with both strings) */
187  if (strcmp("2_compat", str_ptr) == 0) {
189  SCLogDebug("will look for ssh protocol version 2 (2, 2.0, 1.99 that's considered as 2");
190  pcre_free_substring(str_ptr);
191  return ssh;
192  }
193 
194  ssh->ver = (uint8_t *)SCStrdup((char*)str_ptr);
195  if (ssh->ver == NULL) {
196  pcre_free_substring(str_ptr);
197  goto error;
198  }
199  ssh->len = strlen((char *) ssh->ver);
200  pcre_free_substring(str_ptr);
201 
202  SCLogDebug("will look for ssh %s", ssh->ver);
203  }
204 
205  return ssh;
206 
207 error:
208  if (ssh != NULL)
209  DetectSshVersionFree(ssh);
210  return NULL;
211 
212 }
213 
214 /**
215  * \brief this function is used to add the parsed "id" option
216  * \brief into the current signature
217  *
218  * \param de_ctx pointer to the Detection Engine Context
219  * \param s pointer to the Current Signature
220  * \param idstr pointer to the user provided "id" option
221  *
222  * \retval 0 on Success
223  * \retval -1 on Failure
224  */
225 static int DetectSshVersionSetup (DetectEngineCtx *de_ctx, Signature *s, const char *str)
226 {
227  DetectSshVersionData *ssh = NULL;
228  SigMatch *sm = NULL;
229 
231  return -1;
232 
233  ssh = DetectSshVersionParse(str);
234  if (ssh == NULL)
235  goto error;
236 
237  /* Okay so far so good, lets get this into a SigMatch
238  * and put it in the Signature. */
239  sm = SigMatchAlloc();
240  if (sm == NULL)
241  goto error;
242 
244  sm->ctx = (void *)ssh;
245 
246  SigMatchAppendSMToList(s, sm, g_ssh_banner_list_id);
247  return 0;
248 
249 error:
250  if (ssh != NULL)
251  DetectSshVersionFree(ssh);
252  if (sm != NULL)
253  SCFree(sm);
254  return -1;
255 
256 }
257 
258 /**
259  * \brief this function will free memory associated with DetectSshVersionData
260  *
261  * \param id_d pointer to DetectSshVersionData
262  */
263 void DetectSshVersionFree(void *ptr)
264 {
266  SCFree(sshd->ver);
267  SCFree(sshd);
268 }
269 
270 #ifdef UNITTESTS /* UNITTESTS */
271 
272 /**
273  * \test DetectSshVersionTestParse01 is a test to make sure that we parse
274  * a proto version correctly
275  */
276 static int DetectSshVersionTestParse01 (void)
277 {
278  DetectSshVersionData *ssh = NULL;
279  ssh = DetectSshVersionParse("1.0");
280  if (ssh != NULL && strncmp((char *) ssh->ver, "1.0", 3) == 0) {
281  DetectSshVersionFree(ssh);
282  return 1;
283  }
284 
285  return 0;
286 }
287 
288 /**
289  * \test DetectSshVersionTestParse02 is a test to make sure that we parse
290  * the proto version (compatible with proto version 2) correctly
291  */
292 static int DetectSshVersionTestParse02 (void)
293 {
294  DetectSshVersionData *ssh = NULL;
295  ssh = DetectSshVersionParse("2_compat");
297  DetectSshVersionFree(ssh);
298  return 1;
299  }
300 
301  return 0;
302 }
303 
304 /**
305  * \test DetectSshVersionTestParse03 is a test to make sure that we
306  * don't return a ssh_data with an invalid value specified
307  */
308 static int DetectSshVersionTestParse03 (void)
309 {
310  DetectSshVersionData *ssh = NULL;
311  ssh = DetectSshVersionParse("2_com");
312  if (ssh != NULL) {
313  DetectSshVersionFree(ssh);
314  return 0;
315  }
316  ssh = DetectSshVersionParse("");
317  if (ssh != NULL) {
318  DetectSshVersionFree(ssh);
319  return 0;
320  }
321  ssh = DetectSshVersionParse(".1");
322  if (ssh != NULL) {
323  DetectSshVersionFree(ssh);
324  return 0;
325  }
326  ssh = DetectSshVersionParse("lalala");
327  if (ssh != NULL) {
328  DetectSshVersionFree(ssh);
329  return 0;
330  }
331 
332  return 1;
333 }
334 
335 
336 #include "stream-tcp-reassemble.h"
337 
338 /** \test Send a get request in three chunks + more data. */
339 static int DetectSshVersionTestDetect01(void)
340 {
341  Flow f;
342  uint8_t sshbuf1[] = "SSH-1.";
343  uint32_t sshlen1 = sizeof(sshbuf1) - 1;
344  uint8_t sshbuf2[] = "10-PuTTY_2.123" ;
345  uint32_t sshlen2 = sizeof(sshbuf2) - 1;
346  uint8_t sshbuf3[] = "\n";
347  uint32_t sshlen3 = sizeof(sshbuf3) - 1;
348  uint8_t sshbuf4[] = "whatever...";
349  uint32_t sshlen4 = sizeof(sshbuf4) - 1;
350  TcpSession ssn;
351  Packet *p = NULL;
352  Signature *s = NULL;
353  ThreadVars th_v;
354  DetectEngineThreadCtx *det_ctx = NULL;
356 
357  memset(&th_v, 0, sizeof(th_v));
358  memset(&f, 0, sizeof(f));
359  memset(&ssn, 0, sizeof(ssn));
360 
361  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
362  FAIL_IF_NULL(p);
363 
364  FLOW_INITIALIZE(&f);
365  f.protoctx = (void *)&ssn;
366  p->flow = &f;
370  f.alproto = ALPROTO_SSH;
371  f.proto = IPPROTO_TCP;
372 
374 
376  FAIL_IF_NULL (de_ctx);
377  de_ctx->flags |= DE_QUIET;
378 
379  s = de_ctx->sig_list = SigInit(de_ctx,"alert ssh any any -> any any (msg:\"SSH\"; ssh.protoversion:1.10; sid:1;)");
380  FAIL_IF_NULL(s);
381 
382  SigGroupBuild(de_ctx);
383  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
384 
385  SCLogDebug("==> 1");
386  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_SSH,
387  STREAM_TOSERVER, sshbuf1, sshlen1);
388  FAIL_IF(r != 0);
389 
390  SCLogDebug("==> 2");
391  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER,
392  sshbuf2, sshlen2);
393  FAIL_IF(r != 0);
394 
395  SCLogDebug("==> 3");
396  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER,
397  sshbuf3, sshlen3);
398  FAIL_IF(r != 0);
399 
400  SCLogDebug("==> 4");
401  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER,
402  sshbuf4, sshlen4);
403  FAIL_IF(r != 0);
404 
405  SshState *ssh_state = f.alstate;
406  FAIL_IF_NULL(ssh_state);
407 
408  /* do detect */
409  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
410 
411  FAIL_IF(!(PacketAlertCheck(p, 1)));
412 
413  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
414  DetectEngineCtxFree(de_ctx);
415 
417  FLOW_DESTROY(&f);
418  UTHFreePackets(&p, 1);
419  AppLayerParserThreadCtxFree(alp_tctx);
420 
421  PASS;
422 }
423 
424 /** \test Send a get request in three chunks + more data. */
425 static int DetectSshVersionTestDetect02(void)
426 {
427  int result = 0;
428  Flow f;
429  uint8_t sshbuf1[] = "SSH-1.";
430  uint32_t sshlen1 = sizeof(sshbuf1) - 1;
431  uint8_t sshbuf2[] = "99-PuTTY_2.123" ;
432  uint32_t sshlen2 = sizeof(sshbuf2) - 1;
433  uint8_t sshbuf3[] = "\n";
434  uint32_t sshlen3 = sizeof(sshbuf3) - 1;
435  uint8_t sshbuf4[] = "whatever...";
436  uint32_t sshlen4 = sizeof(sshbuf4) - 1;
437  TcpSession ssn;
438  Packet *p = NULL;
439  Signature *s = NULL;
440  ThreadVars th_v;
441  DetectEngineThreadCtx *det_ctx = NULL;
443 
444  memset(&th_v, 0, sizeof(th_v));
445  memset(&f, 0, sizeof(f));
446  memset(&ssn, 0, sizeof(ssn));
447 
448  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
449 
450  FLOW_INITIALIZE(&f);
451  f.protoctx = (void *)&ssn;
452  p->flow = &f;
456  f.alproto = ALPROTO_SSH;
457  f.proto = IPPROTO_TCP;
458 
460 
462  if (de_ctx == NULL) {
463  goto end;
464  }
465 
466  de_ctx->flags |= DE_QUIET;
467 
468  s = de_ctx->sig_list = SigInit(de_ctx,"alert ssh any any -> any any (msg:\"SSH\"; ssh.protoversion:2_compat; sid:1;)");
469  if (s == NULL) {
470  goto end;
471  }
472 
473  SigGroupBuild(de_ctx);
474  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
475 
476  FLOWLOCK_WRLOCK(&f);
477  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_SSH,
478  STREAM_TOSERVER, sshbuf1, sshlen1);
479  if (r != 0) {
480  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
481  goto end;
482  }
483 
484  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER,
485  sshbuf2, sshlen2);
486  if (r != 0) {
487  printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r);
488  FLOWLOCK_UNLOCK(&f);
489  goto end;
490  }
491 
492  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER,
493  sshbuf3, sshlen3);
494  if (r != 0) {
495  printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r);
496  FLOWLOCK_UNLOCK(&f);
497  goto end;
498  }
499 
500  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER,
501  sshbuf4, sshlen4);
502  if (r != 0) {
503  printf("toserver chunk 4 returned %" PRId32 ", expected 0: ", r);
504  FLOWLOCK_UNLOCK(&f);
505  goto end;
506  }
507  FLOWLOCK_UNLOCK(&f);
508 
509  SshState *ssh_state = f.alstate;
510  if (ssh_state == NULL) {
511  printf("no ssh state: ");
512  goto end;
513  }
514 
515  /* do detect */
516  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
517 
518  if ( !(PacketAlertCheck(p, 1))) {
519  printf("Error, the sig should match: ");
520  goto end;
521  }
522 
523  result = 1;
524 end:
525  SigGroupCleanup(de_ctx);
526  SigCleanSignatures(de_ctx);
527 
528  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
529  DetectEngineCtxFree(de_ctx);
530 
532  FLOW_DESTROY(&f);
533 
534  UTHFreePackets(&p, 1);
535  if (alp_tctx != NULL)
536  AppLayerParserThreadCtxFree(alp_tctx);
537  return result;
538 }
539 
540 /** \test Send a get request in three chunks + more data. */
541 static int DetectSshVersionTestDetect03(void)
542 {
543  int result = 0;
544  Flow f;
545  uint8_t sshbuf1[] = "SSH-1.";
546  uint32_t sshlen1 = sizeof(sshbuf1) - 1;
547  uint8_t sshbuf2[] = "7-PuTTY_2.123" ;
548  uint32_t sshlen2 = sizeof(sshbuf2) - 1;
549  uint8_t sshbuf3[] = "\n";
550  uint32_t sshlen3 = sizeof(sshbuf3) - 1;
551  uint8_t sshbuf4[] = "whatever...";
552  uint32_t sshlen4 = sizeof(sshbuf4) - 1;
553  TcpSession ssn;
554  Packet *p = NULL;
555  Signature *s = NULL;
556  ThreadVars th_v;
557  DetectEngineThreadCtx *det_ctx = NULL;
559 
560  memset(&th_v, 0, sizeof(th_v));
561  memset(&f, 0, sizeof(f));
562  memset(&ssn, 0, sizeof(ssn));
563 
564  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
565 
566  FLOW_INITIALIZE(&f);
567  f.protoctx = (void *)&ssn;
568  p->flow = &f;
572  f.alproto = ALPROTO_SSH;
573  f.proto = IPPROTO_TCP;
574 
576 
578  if (de_ctx == NULL) {
579  goto end;
580  }
581 
582  de_ctx->flags |= DE_QUIET;
583 
584  s = de_ctx->sig_list = SigInit(de_ctx,"alert ssh any any -> any any (msg:\"SSH\"; ssh.protoversion:2_compat; sid:1;)");
585  if (s == NULL) {
586  goto end;
587  }
588 
589  SigGroupBuild(de_ctx);
590  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
591 
592  FLOWLOCK_WRLOCK(&f);
593  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_SSH,
594  STREAM_TOSERVER, sshbuf1, sshlen1);
595  if (r != 0) {
596  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
597  FLOWLOCK_UNLOCK(&f);
598  goto end;
599  }
600 
601  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER,
602  sshbuf2, sshlen2);
603  if (r != 0) {
604  printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r);
605  FLOWLOCK_UNLOCK(&f);
606  goto end;
607  }
608 
609  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER,
610  sshbuf3, sshlen3);
611  if (r != 0) {
612  printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r);
613  FLOWLOCK_UNLOCK(&f);
614  goto end;
615  }
616 
617  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER,
618  sshbuf4, sshlen4);
619  if (r != 0) {
620  printf("toserver chunk 4 returned %" PRId32 ", expected 0: ", r);
621  FLOWLOCK_UNLOCK(&f);
622  goto end;
623  }
624  FLOWLOCK_UNLOCK(&f);
625 
626  SshState *ssh_state = f.alstate;
627  if (ssh_state == NULL) {
628  printf("no ssh state: ");
629  goto end;
630  }
631 
632  /* do detect */
633  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
634 
635  if (PacketAlertCheck(p, 1)) {
636  printf("Error, 1.7 version is not 2 compat, so the sig should not match: ");
637  goto end;
638  }
639 
640  result = 1;
641 end:
642  SigGroupCleanup(de_ctx);
643  SigCleanSignatures(de_ctx);
644 
645  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
646  DetectEngineCtxFree(de_ctx);
647 
649  FLOW_DESTROY(&f);
650 
651  UTHFreePackets(&p, 1);
652  if (alp_tctx != NULL)
653  AppLayerParserThreadCtxFree(alp_tctx);
654  return result;
655 }
656 
657 #endif /* UNITTESTS */
658 
659 /**
660  * \brief this function registers unit tests for DetectSshVersion
661  */
662 void DetectSshVersionRegisterTests(void)
663 {
664 #ifdef UNITTESTS /* UNITTESTS */
665  UtRegisterTest("DetectSshVersionTestParse01", DetectSshVersionTestParse01);
666  UtRegisterTest("DetectSshVersionTestParse02", DetectSshVersionTestParse02);
667  UtRegisterTest("DetectSshVersionTestParse03", DetectSshVersionTestParse03);
668  UtRegisterTest("DetectSshVersionTestDetect01",
669  DetectSshVersionTestDetect01);
670  UtRegisterTest("DetectSshVersionTestDetect02",
671  DetectSshVersionTestDetect02);
672  UtRegisterTest("DetectSshVersionTestDetect03",
673  DetectSshVersionTestDetect03);
674 #endif /* UNITTESTS */
675 }
676 
SigTableElmt sigmatch_table[DETECT_TBLSIZE]
Definition: detect.h:1448
uint16_t flags
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition: detect.h:1186
#define SIGMATCH_INFO_DEPRECATED
Definition: detect.h:1395
SshHeader cli_hdr
Definition: app-layer-ssh.h:74
#define SCLogDebug(...)
Definition: util-debug.h:335
int DetectSignatureSetAppProto(Signature *s, AppProto alproto)
struct Flow_ * flow
Definition: decode.h:445
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:344
#define FLOWLOCK_UNLOCK(fb)
Definition: flow.h:243
#define PASS
Pass the test.
#define unlikely(expr)
Definition: util-optimize.h:35
#define PARSE_REGEX
Regex for parsing the protoversion string.
Signature * SigInit(DetectEngineCtx *, const char *)
Parses a signature and adds it to the Detection Engine Context.
uint8_t * proto_version
Definition: app-layer-ssh.h:60
Signature * sig_list
Definition: detect.h:767
#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:203
void SigCleanSignatures(DetectEngineCtx *de_ctx)
void StreamTcpFreeConfig(char quiet)
Definition: stream-tcp.c:669
#define FLOWLOCK_WRLOCK(fb)
Definition: flow.h:240
TmEcode DetectEngineThreadCtxInit(ThreadVars *, void *, void **)
initialize thread specific detection engine context
const char * name
Definition: detect.h:1200
Signature container.
Definition: detect.h:522
#define TRUE
Used to start a pointer to SigMatch context Should never be dereferenced without casting to something...
Definition: detect.h:313
void * protoctx
Definition: flow.h:400
main detection engine ctx
Definition: detect.h:761
TmEcode DetectEngineThreadCtxDeinit(ThreadVars *, void *)
void * alstate
Definition: flow.h:438
#define DE_QUIET
Definition: detect.h:292
#define str(s)
#define SSH_FLAG_VERSION_PARSED
Definition: app-layer-ssh.h:29
uint8_t flags
Definition: detect.h:762
SshHeader srv_hdr
Definition: app-layer-ssh.h:73
Data structures and function prototypes for keeping state for the detection engine.
void(* Free)(void *)
Definition: detect.h:1191
#define SCLogError(err_code,...)
Macro used to log ERROR messages.
Definition: util-debug.h:294
#define FLOW_DESTROY(f)
Definition: flow-util.h:121
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:1669
void DetectSetupParseRegexes(const char *parse_str, pcre **parse_regex, pcre_extra **parse_regex_study)
#define SIGMATCH_QUOTES_OPTIONAL
Definition: detect.h:1381
#define SCEnter(...)
Definition: util-debug.h:337
void StreamTcpInitConfig(char)
To initialize the stream global configuration data.
Definition: stream-tcp.c:365
uint8_t flowflags
Definition: decode.h:439
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.
uint16_t alternative
Definition: detect.h:1198
#define STREAM_TOCLIENT
Definition: stream.h:32
#define FLOW_PKT_TOSERVER
Definition: flow.h:201
AppLayerParserThreadCtx * AppLayerParserThreadCtxAlloc(void)
Gets a new app layer protocol&#39;s parser thread context.
int SigGroupCleanup(DetectEngineCtx *de_ctx)
uint8_t type
Definition: detect.h:319
#define SCReturnInt(x)
Definition: util-debug.h:341
void DetectSshVersionRegister(void)
Registration function for keyword: ssh.protoversion.
const char * desc
Definition: detect.h:1202
void SigMatchAppendSMToList(Signature *s, SigMatch *new, int list)
Append a SigMatch to the list type.
Definition: detect-parse.c:346
int DetectBufferTypeRegister(const char *name)
uint8_t flags
Definition: app-layer-ssh.h:58
SigMatchCtx * ctx
Definition: detect.h:321
#define SCMalloc(a)
Definition: util-mem.h:222
#define SCFree(a)
Definition: util-mem.h:322
PoolThreadReserved res
#define SSH_FLAG_PROTOVERSION_2_COMPAT
int AppLayerParserParse(ThreadVars *tv, AppLayerParserThreadCtx *alp_tctx, Flow *f, AppProto alproto, uint8_t flags, const uint8_t *input, uint32_t input_len)
const char * url
Definition: detect.h:1203
int(* AppLayerTxMatch)(DetectEngineThreadCtx *, Flow *, uint8_t flags, void *alstate, void *txv, const Signature *, const SigMatchCtx *)
Definition: detect.h:1173
#define FLOW_INITIALIZE(f)
Definition: flow-util.h:39
#define STREAM_TOSERVER
Definition: stream.h:31
SCMutex m
Definition: flow-hash.h:105
#define PKT_HAS_FLOW
Definition: decode.h:1093
#define SCStrdup(a)
Definition: util-mem.h:268
#define FAIL_IF_NULL(expr)
Fail a test if expression evaluates to NULL.
Definition: util-unittest.h:89
#define DOC_URL
Definition: suricata.h:86
SigMatch * SigMatchAlloc(void)
Definition: detect-parse.c:232
Per thread variable structure.
Definition: threadvars.h:57
AppProto alproto
application level protocol
Definition: flow.h:409
uint32_t flags
Definition: decode.h:443
#define DOC_VERSION
Definition: suricata.h:91
uint16_t flags
Definition: detect.h:1194
void DetectEngineCtxFree(DetectEngineCtx *)
Free a DetectEngineCtx::
void UTHFreePackets(Packet **p, int numpkts)
UTHFreePackets: function to release the allocated data from UTHBuildPacket and the packet itself...
Flow data structure.
Definition: flow.h:325
#define PKT_STREAM_EST
Definition: decode.h:1091
void(* RegisterTests)(void)
Definition: detect.h:1192
a single match condition for a signature
Definition: detect.h:318
DetectEngineCtx * DetectEngineCtxInit(void)
#define MAX_SUBSTRINGS