suricata
app-layer-ssh.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  * \author Victor Julien <victor@inliniac.net>
23  *
24  * App-layer parser for SSH protocol
25  *
26  */
27 
28 #include "suricata-common.h"
29 #include "decode.h"
30 #include "threads.h"
31 
32 #include "util-print.h"
33 #include "util-pool.h"
34 
35 #include "stream-tcp-private.h"
36 #include "stream-tcp-reassemble.h"
37 #include "stream-tcp.h"
38 #include "stream.h"
39 
40 #include "app-layer-detect-proto.h"
41 #include "app-layer-protos.h"
42 #include "app-layer-parser.h"
43 #include "app-layer-ssh.h"
44 #include "rust.h"
45 
46 #include "conf.h"
47 
48 #include "util-spm.h"
49 #include "util-unittest.h"
50 #include "util-debug.h"
51 #include "flow-private.h"
52 
53 #include "util-byte.h"
54 #include "util-memcmp.h"
55 
56 /* HASSH fingerprints are disabled by default */
57 #define SSH_CONFIG_DEFAULT_HASSH false
58 
59 static int SSHRegisterPatternsForProtocolDetection(void)
60 {
62  "SSH-", 4, 0, STREAM_TOSERVER) < 0)
63  {
64  return -1;
65  }
67  "SSH-", 4, 0, STREAM_TOCLIENT) < 0)
68  {
69  return -1;
70  }
71  return 0;
72 }
73 
74 bool SSHTxLogCondition(ThreadVars *tv, const Packet *p, void *state, void *tx, uint64_t tx_id)
75 {
76  return SCSshTxGetLogCondition(tx);
77 }
78 
79 /** \brief Function to register the SSH protocol parsers and other functions
80  */
82 {
83  const char *proto_name = "ssh";
84 
85  if (AppLayerProtoDetectConfProtoDetectionEnabled("tcp", proto_name)) {
87  if (SSHRegisterPatternsForProtocolDetection() < 0)
88  return;
89 
90  /* Check if we should generate Hassh fingerprints */
91  int enable_hassh = SSH_CONFIG_DEFAULT_HASSH;
92  const char *strval = NULL;
93  if (ConfGet("app-layer.protocols.ssh.hassh", &strval) != 1) {
94  enable_hassh = SSH_CONFIG_DEFAULT_HASSH;
95  } else if (strcmp(strval, "auto") == 0) {
96  enable_hassh = SSH_CONFIG_DEFAULT_HASSH;
97  } else if (ConfValIsFalse(strval)) {
98  enable_hassh = SSH_CONFIG_DEFAULT_HASSH;
99  } else if (ConfValIsTrue(strval)) {
100  enable_hassh = true;
101  }
102 
103  if (RunmodeIsUnittests() || enable_hassh) {
104  SCSshEnableHassh();
105  }
106  }
107 
108  SCLogDebug("Registering Rust SSH parser.");
109  SCRegisterSshParser();
110 
111 #ifdef UNITTESTS
113 #endif
114 }
115 
116 /* UNITTESTS */
117 #ifdef UNITTESTS
118 #include "flow-util.h"
119 #include "stream-tcp-util.h"
120 #include "util-unittest-helper.h"
121 
122 static int SSHParserTestUtilCheck(const char *protoexp, const char *softexp, void *tx, uint8_t flags) {
123  const uint8_t *protocol = NULL;
124  uint32_t p_len = 0;
125  const uint8_t *software = NULL;
126  uint32_t s_len = 0;
127 
128  if (SCSshTxGetProtocol(tx, &protocol, &p_len, flags) != 1) {
129  printf("Version string not parsed correctly return: ");
130  return 1;
131  }
132  if (protocol == NULL) {
133  printf("Version string not parsed correctly NULL: ");
134  return 1;
135  }
136 
137  if (p_len != strlen(protoexp)) {
138  printf("Version string not parsed correctly length: ");
139  return 1;
140  }
141  if (memcmp(protocol, protoexp, strlen(protoexp)) != 0) {
142  printf("Version string not parsed correctly: ");
143  return 1;
144  }
145 
146  if (softexp != NULL) {
147  if (SCSshTxGetSoftware(tx, &software, &s_len, flags) != 1)
148  return 1;
149  if (software == NULL)
150  return 1;
151  if (s_len != strlen(softexp)) {
152  printf("Software string not parsed correctly length: ");
153  return 1;
154  }
155  if (memcmp(software, softexp, strlen(softexp)) != 0) {
156  printf("Software string not parsed correctly: ");
157  return 1;
158  }
159  }
160  return 0;
161 }
162 
163 /** \test Send a version string in one chunk (client version str). */
164 static int SSHParserTest01(void)
165 {
166  int result = 0;
167  Flow f;
168  uint8_t sshbuf[] = "SSH-2.0-MySSHClient-0.5.1\n";
169  uint32_t sshlen = sizeof(sshbuf) - 1;
170  TcpSession ssn;
172 
173  memset(&f, 0, sizeof(f));
174  memset(&ssn, 0, sizeof(ssn));
175  FLOW_INITIALIZE(&f);
176  f.protoctx = (void *)&ssn;
177  f.alproto = ALPROTO_SSH;
178 
179  StreamTcpInitConfig(true);
180 
181  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_SSH,
182  STREAM_TOSERVER | STREAM_EOF, sshbuf, sshlen);
183  if (r != 0) {
184  printf("toclient chunk 1 returned %" PRId32 ", expected 0: ", r);
185  goto end;
186  }
187 
188  void *ssh_state = f.alstate;
189  if (ssh_state == NULL) {
190  printf("no ssh state: ");
191  goto end;
192  }
193 
194  void *tx = SCSshStateGetTx(ssh_state, 0);
195  if (SCSshTxGetAlStateProgress(tx, STREAM_TOSERVER) != SshStateBannerDone) {
196  printf("Client version string not parsed: ");
197  goto end;
198  }
199 
200  if (SSHParserTestUtilCheck("2.0", "MySSHClient-0.5.1", tx, STREAM_TOSERVER))
201  goto end;
202 
203  result = 1;
204 end:
205  if (alp_tctx != NULL)
207  StreamTcpFreeConfig(true);
208  FLOW_DESTROY(&f);
209  return result;
210 }
211 
212 /** \test Send a version string in one chunk but multiple lines and comments.
213  * (client version str)
214  */
215 static int SSHParserTest02(void)
216 {
217  int result = 0;
218  Flow f;
219  uint8_t sshbuf[] = "SSH-2.0-MySSHClient-0.5.1 some comments...\n";
220  uint32_t sshlen = sizeof(sshbuf) - 1;
221  TcpSession ssn;
223 
224  memset(&f, 0, sizeof(f));
225  memset(&ssn, 0, sizeof(ssn));
226  FLOW_INITIALIZE(&f);
227  f.protoctx = (void *)&ssn;
228  f.alproto = ALPROTO_SSH;
229 
230  StreamTcpInitConfig(true);
231 
232  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_SSH,
233  STREAM_TOSERVER | STREAM_EOF, sshbuf, sshlen);
234  if (r != 0) {
235  printf("toclient chunk 1 returned %" PRId32 ", expected 0: ", r);
236  goto end;
237  }
238 
239  void *ssh_state = f.alstate;
240  if (ssh_state == NULL) {
241  printf("no ssh state: ");
242  goto end;
243  }
244  void *tx = SCSshStateGetTx(ssh_state, 0);
245 
246  if (SCSshTxGetAlStateProgress(tx, STREAM_TOSERVER) != SshStateBannerDone) {
247  printf("Client version string not parsed: ");
248  goto end;
249  }
250  if (SSHParserTestUtilCheck("2.0", "MySSHClient-0.5.1", tx, STREAM_TOSERVER))
251  goto end;
252 
253  result = 1;
254 end:
255  if (alp_tctx != NULL)
257  StreamTcpFreeConfig(true);
258  FLOW_DESTROY(&f);
259  return result;
260 }
261 
262 /** \test Send a invalid version string in one chunk but multiple lines and comments.
263  * (client version str)
264  */
265 static int SSHParserTest03(void)
266 {
267  int result = 0;
268  Flow f;
269  uint8_t sshbuf[] = "SSH-2.0 some comments...\n";
270  uint32_t sshlen = sizeof(sshbuf) - 1;
271  TcpSession ssn;
273 
274  memset(&f, 0, sizeof(f));
275  memset(&ssn, 0, sizeof(ssn));
276  FLOW_INITIALIZE(&f);
277  f.protoctx = (void *)&ssn;
278  f.alproto = ALPROTO_SSH;
279 
280  StreamTcpInitConfig(true);
281 
282  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_SSH,
283  STREAM_TOSERVER | STREAM_EOF, sshbuf, sshlen);
284  if (r == 0) {
285  printf("toclient chunk 1 returned %" PRId32 ", expected != 0: ", r);
286  goto end;
287  }
288 
289  void *ssh_state = f.alstate;
290  if (ssh_state == NULL) {
291  printf("no ssh state: ");
292  goto end;
293  }
294  void *tx = SCSshStateGetTx(ssh_state, 0);
295 
296  if (SCSshTxGetAlStateProgress(tx, STREAM_TOSERVER) == SshStateBannerDone) {
297  printf("Client version string parsed? It's not a valid string: ");
298  goto end;
299  }
300  const uint8_t *dummy = NULL;
301  uint32_t dummy_len = 0;
302  if (SCSshTxGetProtocol(tx, &dummy, &dummy_len, STREAM_TOSERVER) != 0)
303  goto end;
304  if (SCSshTxGetSoftware(tx, &dummy, &dummy_len, STREAM_TOSERVER) != 0)
305  goto end;
306 
307  result = 1;
308 end:
309  if (alp_tctx != NULL)
311  StreamTcpFreeConfig(true);
312  FLOW_DESTROY(&f);
313  return result;
314 }
315 
316 /** \test Send a version string in one chunk (server version str). */
317 static int SSHParserTest04(void)
318 {
319  int result = 0;
320  Flow f;
321  uint8_t sshbuf[] = "SSH-2.0-MySSHClient-0.5.1\n";
322  uint32_t sshlen = sizeof(sshbuf) - 1;
323  TcpSession ssn;
325 
326  memset(&f, 0, sizeof(f));
327  memset(&ssn, 0, sizeof(ssn));
328  FLOW_INITIALIZE(&f);
329  f.protoctx = (void *)&ssn;
330  f.alproto = ALPROTO_SSH;
331 
332  StreamTcpInitConfig(true);
333 
334  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_SSH,
335  STREAM_TOCLIENT | STREAM_EOF, sshbuf, sshlen);
336  if (r != 0) {
337  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
338  goto end;
339  }
340 
341  void *ssh_state = f.alstate;
342  if (ssh_state == NULL) {
343  printf("no ssh state: ");
344  goto end;
345  }
346  void *tx = SCSshStateGetTx(ssh_state, 0);
347 
348  if (SCSshTxGetAlStateProgress(tx, STREAM_TOCLIENT) != SshStateBannerDone) {
349  printf("Client version string not parsed: ");
350  goto end;
351  }
352  if (SSHParserTestUtilCheck("2.0", "MySSHClient-0.5.1", tx, STREAM_TOCLIENT))
353  goto end;
354 
355  result = 1;
356 
357 end:
358  if (alp_tctx != NULL)
360  StreamTcpFreeConfig(true);
361  FLOW_DESTROY(&f);
362  return result;
363 }
364 
365 /** \test Send a version string in one chunk (server version str)
366  */
367 static int SSHParserTest05(void)
368 {
369  int result = 0;
370  Flow f;
371  uint8_t sshbuf[] = "SSH-2.0-MySSHClient-0.5.1 some comments...\n";
372  uint32_t sshlen = sizeof(sshbuf) - 1;
373  TcpSession ssn;
375 
376  memset(&f, 0, sizeof(f));
377  memset(&ssn, 0, sizeof(ssn));
378  FLOW_INITIALIZE(&f);
379  f.protoctx = (void *)&ssn;
380  f.alproto = ALPROTO_SSH;
381 
382  StreamTcpInitConfig(true);
383 
384  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_SSH,
385  STREAM_TOCLIENT | STREAM_EOF, sshbuf, sshlen);
386  if (r != 0) {
387  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
388  goto end;
389  }
390 
391  void *ssh_state = f.alstate;
392  if (ssh_state == NULL) {
393  printf("no ssh state: ");
394  goto end;
395  }
396  void *tx = SCSshStateGetTx(ssh_state, 0);
397 
398  if (SCSshTxGetAlStateProgress(tx, STREAM_TOCLIENT) != SshStateBannerDone) {
399  printf("Client version string not parsed: ");
400  goto end;
401  }
402  if (SSHParserTestUtilCheck("2.0", "MySSHClient-0.5.1", tx, STREAM_TOCLIENT))
403  goto end;
404 
405  result = 1;
406 end:
407  if (alp_tctx != NULL)
409  StreamTcpFreeConfig(true);
410  FLOW_DESTROY(&f);
411  return result;
412 }
413 
414 /** \test Send a invalid version string in one chunk (server version str)
415  */
416 static int SSHParserTest06(void)
417 {
418  int result = 0;
419  Flow f;
420  uint8_t sshbuf[] = "SSH-2.0 some comments...\n";
421  uint32_t sshlen = sizeof(sshbuf) - 1;
422  TcpSession ssn;
424 
425  memset(&f, 0, sizeof(f));
426  memset(&ssn, 0, sizeof(ssn));
427  FLOW_INITIALIZE(&f);
428  f.protoctx = (void *)&ssn;
429  f.alproto = ALPROTO_SSH;
430 
431  StreamTcpInitConfig(true);
432 
433  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_SSH,
434  STREAM_TOCLIENT | STREAM_EOF, sshbuf, sshlen);
435  if (r == 0) {
436  printf("toserver chunk 1 returned %" PRId32 ", expected != 0: ", r);
437  goto end;
438  }
439  /* Ok, it returned an error. Let's make sure we didn't parse the string at all */
440 
441  void *ssh_state = f.alstate;
442  if (ssh_state == NULL) {
443  printf("no ssh state: ");
444  goto end;
445  }
446  void *tx = SCSshStateGetTx(ssh_state, 0);
447 
448  if (SCSshTxGetAlStateProgress(tx, STREAM_TOCLIENT) == SshStateBannerDone) {
449  printf("Client version string parsed? It's not a valid string: ");
450  goto end;
451  }
452  const uint8_t *dummy = NULL;
453  uint32_t dummy_len = 0;
454  if (SCSshTxGetProtocol(tx, &dummy, &dummy_len, STREAM_TOCLIENT) != 0)
455  goto end;
456  if (SCSshTxGetSoftware(tx, &dummy, &dummy_len, STREAM_TOCLIENT) != 0)
457  goto end;
458 
459 
460  result = 1;
461 end:
462  if (alp_tctx != NULL)
464  StreamTcpFreeConfig(true);
465  FLOW_DESTROY(&f);
466  return result;
467 }
468 
469 #define MAX_SSH_TEST_SIZE 512
470 
471 static int SSHParserTest07(void)
472 {
473  TcpReassemblyThreadCtx *ra_ctx = NULL;
474  ThreadVars tv;
475  TcpSession ssn;
476  Flow *f = NULL;
477  Packet *p = NULL;
478 
479  char sshbufs[2][MAX_SSH_TEST_SIZE] = {"SSH-2.", "0-MySSHClient-0.5.1\r\n"};
480 
481  memset(&tv, 0x00, sizeof(tv));
482 
483  StreamTcpUTInit(&ra_ctx);
488 
489  f = UTHBuildFlow(AF_INET, "1.1.1.1", "2.2.2.2", 1234, 2222);
490  FAIL_IF_NULL(f);
491  f->protoctx = &ssn;
492  f->proto = IPPROTO_TCP;
493  f->alproto = ALPROTO_SSH;
494 
495  p = PacketGetFromAlloc();
496  FAIL_IF(unlikely(p == NULL));
497  p->proto = IPPROTO_TCP;
498  p->flow = f;
499 
500  uint32_t seq = 2;
501  for (int i=0; i<2; i++) {
502  FAIL_IF(StreamTcpUTAddSegmentWithPayload(&tv, ra_ctx, &ssn.client, seq, (uint8_t *) sshbufs[i], strlen(sshbufs[i])) == -1);
503  seq += strlen(sshbufs[i]);
504  FAIL_IF(StreamTcpReassembleAppLayer(&tv, ra_ctx, &ssn, &ssn.client, p, UPDATE_DIR_PACKET) < 0);
505  }
506 
507  void *ssh_state = f->alstate;
508  FAIL_IF_NULL(ssh_state);
509  void *tx = SCSshStateGetTx(ssh_state, 0);
510  FAIL_IF(SCSshTxGetAlStateProgress(tx, STREAM_TOSERVER) != SshStateBannerDone);
511 
512  FAIL_IF(SSHParserTestUtilCheck("2.0", "MySSHClient-0.5.1", tx, STREAM_TOSERVER));
513 
514  UTHFreePacket(p);
516  StreamTcpUTDeinit(ra_ctx);
517  UTHFreeFlow(f);
518  PASS;
519 }
520 
521 /** \test Send a version banner in three chunks. */
522 static int SSHParserTest08(void)
523 {
524  TcpReassemblyThreadCtx *ra_ctx = NULL;
525  ThreadVars tv;
526  TcpSession ssn;
527  Flow *f = NULL;
528  Packet *p = NULL;
529 
530  char sshbufs[3][MAX_SSH_TEST_SIZE] = {"SSH-", "2.", "0-MySSHClient-0.5.1\r\n"};
531 
532  memset(&tv, 0x00, sizeof(tv));
533 
534  StreamTcpUTInit(&ra_ctx);
539 
540  f = UTHBuildFlow(AF_INET, "1.1.1.1", "2.2.2.2", 1234, 2222);
541  FAIL_IF_NULL(f);
542  f->protoctx = &ssn;
543  f->proto = IPPROTO_TCP;
544  f->alproto = ALPROTO_SSH;
545 
546  p = PacketGetFromAlloc();
547  FAIL_IF(unlikely(p == NULL));
548  p->proto = IPPROTO_TCP;
549  p->flow = f;
550 
551  uint32_t seq = 2;
552  for (int i=0; i<3; i++) {
553  FAIL_IF(StreamTcpUTAddSegmentWithPayload(&tv, ra_ctx, &ssn.client, seq, (uint8_t *) sshbufs[i], strlen(sshbufs[i])) == -1);
554  seq += strlen(sshbufs[i]);
555  FAIL_IF(StreamTcpReassembleAppLayer(&tv, ra_ctx, &ssn, &ssn.client, p, UPDATE_DIR_PACKET) < 0);
556  }
557 
558  void *ssh_state = f->alstate;
559  FAIL_IF_NULL(ssh_state);
560  void *tx = SCSshStateGetTx(ssh_state, 0);
561  FAIL_IF(SCSshTxGetAlStateProgress(tx, STREAM_TOSERVER) != SshStateBannerDone);
562 
563  FAIL_IF(SSHParserTestUtilCheck("2.0", "MySSHClient-0.5.1", tx, STREAM_TOSERVER));
564 
565  UTHFreePacket(p);
567  StreamTcpUTDeinit(ra_ctx);
568  UTHFreeFlow(f);
569  PASS;
570 }
571 
572 static int SSHParserTest09(void)
573 {
574  TcpReassemblyThreadCtx *ra_ctx = NULL;
575  ThreadVars tv;
576  TcpSession ssn;
577  Flow *f = NULL;
578  Packet *p = NULL;
579 
580  char sshbufs[2][MAX_SSH_TEST_SIZE] = {"SSH-2.", "0-MySSHClient-0.5.1\r\n"};
581 
582  memset(&tv, 0x00, sizeof(tv));
583 
584  StreamTcpUTInit(&ra_ctx);
589 
590  f = UTHBuildFlow(AF_INET, "1.1.1.1", "2.2.2.2", 1234, 2222);
591  FAIL_IF_NULL(f);
592  f->protoctx = &ssn;
593  f->proto = IPPROTO_TCP;
594  f->alproto = ALPROTO_SSH;
595 
596  p = PacketGetFromAlloc();
597  FAIL_IF(unlikely(p == NULL));
598  p->proto = IPPROTO_TCP;
599  p->flow = f;
600 
601  uint32_t seq = 2;
602  for (int i=0; i<2; i++) {
603  FAIL_IF(StreamTcpUTAddSegmentWithPayload(&tv, ra_ctx, &ssn.server, seq, (uint8_t *) sshbufs[i], strlen(sshbufs[i])) == -1);
604  seq += strlen(sshbufs[i]);
605  FAIL_IF(StreamTcpReassembleAppLayer(&tv, ra_ctx, &ssn, &ssn.server, p, UPDATE_DIR_PACKET) < 0);
606  }
607 
608  void *ssh_state = f->alstate;
609  FAIL_IF_NULL(ssh_state);
610  void *tx = SCSshStateGetTx(ssh_state, 0);
611  FAIL_IF(SCSshTxGetAlStateProgress(tx, STREAM_TOCLIENT) != SshStateBannerDone);
612 
613  FAIL_IF(SSHParserTestUtilCheck("2.0", "MySSHClient-0.5.1", tx, STREAM_TOCLIENT));
614 
615  UTHFreePacket(p);
617  StreamTcpUTDeinit(ra_ctx);
618  UTHFreeFlow(f);
619  PASS;
620 }
621 
622 /** \test Send a version banner in three chunks. */
623 static int SSHParserTest10(void)
624 {
625  TcpReassemblyThreadCtx *ra_ctx = NULL;
626  ThreadVars tv;
627  TcpSession ssn;
628  Flow *f = NULL;
629  Packet *p = NULL;
630 
631  char sshbufs[3][MAX_SSH_TEST_SIZE] = {"SSH-", "2.", "0-MySSHClient-0.5.1\r\n"};
632 
633  memset(&tv, 0x00, sizeof(tv));
634 
635  StreamTcpUTInit(&ra_ctx);
640 
641  f = UTHBuildFlow(AF_INET, "1.1.1.1", "2.2.2.2", 1234, 2222);
642  FAIL_IF_NULL(f);
643  f->protoctx = &ssn;
644  f->proto = IPPROTO_TCP;
645  f->alproto = ALPROTO_SSH;
646 
647  p = PacketGetFromAlloc();
648  FAIL_IF(unlikely(p == NULL));
649  p->proto = IPPROTO_TCP;
650  p->flow = f;
651 
652  uint32_t seq = 2;
653  for (int i=0; i<3; i++) {
654  FAIL_IF(StreamTcpUTAddSegmentWithPayload(&tv, ra_ctx, &ssn.server, seq, (uint8_t *) sshbufs[i], strlen(sshbufs[i])) == -1);
655  seq += strlen(sshbufs[i]);
656  FAIL_IF(StreamTcpReassembleAppLayer(&tv, ra_ctx, &ssn, &ssn.server, p, UPDATE_DIR_PACKET) < 0);
657  }
658 
659  void *ssh_state = f->alstate;
660  FAIL_IF_NULL(ssh_state);
661  void *tx = SCSshStateGetTx(ssh_state, 0);
662  FAIL_IF(SCSshTxGetAlStateProgress(tx, STREAM_TOCLIENT) != SshStateBannerDone);
663 
664  FAIL_IF(SSHParserTestUtilCheck("2.0", "MySSHClient-0.5.1", tx, STREAM_TOCLIENT));
665 
666  UTHFreePacket(p);
668  StreamTcpUTDeinit(ra_ctx);
669  UTHFreeFlow(f);
670  PASS;
671 }
672 
673 /** \test Send a banner and record in three chunks. */
674 static int SSHParserTest11(void)
675 {
676  int result = 0;
677  Flow f;
678  uint8_t sshbuf1[] = "SSH-2.0-MySSHClient-0.5.1\r\n";
679  uint32_t sshlen1 = sizeof(sshbuf1) - 1;
680  uint8_t sshbuf2[] = { 0x00, 0x00, 0x00, 0x03, 0x01, 21, 0x00};
681  uint32_t sshlen2 = sizeof(sshbuf2);
682  TcpSession ssn;
684 
685  memset(&f, 0, sizeof(f));
686  memset(&ssn, 0, sizeof(ssn));
687  FLOW_INITIALIZE(&f);
688  f.protoctx = (void *)&ssn;
689  f.alproto = ALPROTO_SSH;
690 
691  StreamTcpInitConfig(true);
692 
693  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_SSH,
694  STREAM_TOSERVER, sshbuf1, sshlen1);
695  if (r != 0) {
696  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
697  goto end;
698  }
699  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER,
700  sshbuf2, sshlen2);
701  if (r != 0) {
702  printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r);
703  goto end;
704  }
705 
706  void *ssh_state = f.alstate;
707  if (ssh_state == NULL) {
708  printf("no ssh state: ");
709  goto end;
710  }
711  void *tx = SCSshStateGetTx(ssh_state, 0);
712  if (SCSshTxGetFlags(tx, STREAM_TOSERVER) != SshStateFinished) {
713  printf("Didn't detect the msg code of new keys (ciphered data starts): ");
714  goto end;
715  }
716  if (SSHParserTestUtilCheck("2.0", "MySSHClient-0.5.1", tx, STREAM_TOSERVER))
717  goto end;
718 
719  result = 1;
720 end:
721  if (alp_tctx != NULL)
723  StreamTcpFreeConfig(true);
724  FLOW_DESTROY(&f);
725  return result;
726 }
727 
728 /** \test Send a banner and 2 records record in four chunks. */
729 static int SSHParserTest12(void)
730 {
731  int result = 0;
732  Flow f;
733  uint8_t sshbuf1[] = "SSH-2.0-MySSHClient-0.5.1\r\n";
734  uint32_t sshlen1 = sizeof(sshbuf1) - 1;
735  uint8_t sshbuf2[] = { 0x00, 0x00, 0x00, 0x03,0x01, 17, 0x00};
736  uint32_t sshlen2 = sizeof(sshbuf2);
737  uint8_t sshbuf3[] = { 0x00, 0x00, 0x00, 0x03,0x01, 21, 0x00};
738  uint32_t sshlen3 = sizeof(sshbuf3);
739  TcpSession ssn;
741 
742  memset(&f, 0, sizeof(f));
743  memset(&ssn, 0, sizeof(ssn));
744  FLOW_INITIALIZE(&f);
745  f.protoctx = (void *)&ssn;
746  f.alproto = ALPROTO_SSH;
747 
748  StreamTcpInitConfig(true);
749 
750  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_SSH,
751  STREAM_TOSERVER, sshbuf1, sshlen1);
752  if (r != 0) {
753  printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
754  goto end;
755  }
756  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER,
757  sshbuf2, sshlen2);
758  if (r != 0) {
759  printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r);
760  goto end;
761  }
762  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER,
763  sshbuf3, sshlen3);
764  if (r != 0) {
765  printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r);
766  goto end;
767  }
768 
769  void *ssh_state = f.alstate;
770  if (ssh_state == NULL) {
771  printf("no ssh state: ");
772  goto end;
773  }
774  void *tx = SCSshStateGetTx(ssh_state, 0);
775  if (SCSshTxGetFlags(tx, STREAM_TOSERVER) != SshStateFinished) {
776  printf("Didn't detect the msg code of new keys (ciphered data starts): ");
777  goto end;
778  }
779  if (SSHParserTestUtilCheck("2.0", "MySSHClient-0.5.1", tx, STREAM_TOSERVER))
780  goto end;
781 
782  result = 1;
783 end:
784  if (alp_tctx != NULL)
786  StreamTcpFreeConfig(true);
787  FLOW_DESTROY(&f);
788  return result;
789 }
790 
791 /** \test Send a banner and 2 records record in four chunks. */
792 static int SSHParserTest13(void)
793 {
794  TcpReassemblyThreadCtx *ra_ctx = NULL;
795  ThreadVars tv;
796  TcpSession ssn;
797  Flow *f = NULL;
798  Packet *p = NULL;
799 
800  uint8_t sshbuf1[] = "SSH-2.0-MySSHClient-0.5.1\r\n";
801  uint8_t sshbuf2[] = { 0x00, 0x00, 0x00, 0x02, 0x01, 17};
802  uint8_t sshbuf3[] = { 0x00, 0x00, 0x00, 0x02, 0x01, 21};
803 
804  uint8_t* sshbufs[3] = {sshbuf1, sshbuf2, sshbuf3};
805  uint32_t sshlens[3] = {sizeof(sshbuf1) - 1, sizeof(sshbuf2), sizeof(sshbuf3)};
806 
807  memset(&tv, 0x00, sizeof(tv));
808 
809  StreamTcpUTInit(&ra_ctx);
814 
815  f = UTHBuildFlow(AF_INET, "1.1.1.1", "2.2.2.2", 1234, 2222);
816  FAIL_IF_NULL(f);
817  f->protoctx = &ssn;
818  f->proto = IPPROTO_TCP;
819  f->alproto = ALPROTO_SSH;
820 
821  p = PacketGetFromAlloc();
822  FAIL_IF(unlikely(p == NULL));
823  p->proto = IPPROTO_TCP;
824  p->flow = f;
825 
826  uint32_t seq = 2;
827  for (int i=0; i<3; i++) {
828  FAIL_IF(StreamTcpUTAddSegmentWithPayload(&tv, ra_ctx, &ssn.client, seq, sshbufs[i], sshlens[i]) == -1);
829  seq += sshlens[i];
830  FAIL_IF(StreamTcpReassembleAppLayer(&tv, ra_ctx, &ssn, &ssn.client, p, UPDATE_DIR_PACKET) < 0);
831  }
832 
833  void *ssh_state = f->alstate;
834  FAIL_IF_NULL(ssh_state);
835  void *tx = SCSshStateGetTx(ssh_state, 0);
836  FAIL_IF(SCSshTxGetFlags(tx, STREAM_TOSERVER) != SshStateFinished);
837 
838  FAIL_IF(SSHParserTestUtilCheck("2.0", "MySSHClient-0.5.1", tx, STREAM_TOSERVER));
839 
840  UTHFreePacket(p);
842  StreamTcpUTDeinit(ra_ctx);
843  UTHFreeFlow(f);
844  PASS;
845 }
846 
847 /** \test Send a banner and 2 records record in four chunks. */
848 static int SSHParserTest14(void)
849 {
850  TcpReassemblyThreadCtx *ra_ctx = NULL;
851  ThreadVars tv;
852  TcpSession ssn;
853  Flow *f = NULL;
854  Packet *p = NULL;
855 
856  uint8_t sshbuf1[] = "SSH-2.0-MySSHClient-0.5.1\r\n";
857  uint8_t sshbuf2[] = { 0x00, 0x00, 0x00, 0x10, 0x01, 17, 0x00};
858  uint8_t sshbuf3[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
859  uint8_t sshbuf4[] = { 0x09, 0x10, 0x11, 0x12, 0x13, 0x00};
860  /* first byte of this record in sshbuf4 */
861  uint8_t sshbuf5[] = { 0x00, 0x00, 0x02, 0x01, 21};
862 
863  uint8_t* sshbufs[5] = {sshbuf1, sshbuf2, sshbuf3, sshbuf4, sshbuf5};
864  uint32_t sshlens[5] = {sizeof(sshbuf1) - 1, sizeof(sshbuf2), sizeof(sshbuf3), sizeof(sshbuf4), sizeof(sshbuf5)};
865 
866  memset(&tv, 0x00, sizeof(tv));
867 
868  StreamTcpUTInit(&ra_ctx);
873 
874  f = UTHBuildFlow(AF_INET, "1.1.1.1", "2.2.2.2", 1234, 2222);
875  FAIL_IF_NULL(f);
876  f->protoctx = &ssn;
877  f->proto = IPPROTO_TCP;
878  f->alproto = ALPROTO_SSH;
879 
880  p = PacketGetFromAlloc();
881  FAIL_IF(unlikely(p == NULL));
882  p->proto = IPPROTO_TCP;
883  p->flow = f;
884 
885  uint32_t seq = 2;
886  for (int i=0; i<5; i++) {
887  FAIL_IF(StreamTcpUTAddSegmentWithPayload(&tv, ra_ctx, &ssn.client, seq, sshbufs[i], sshlens[i]) == -1);
888  seq += sshlens[i];
889  FAIL_IF(StreamTcpReassembleAppLayer(&tv, ra_ctx, &ssn, &ssn.client, p, UPDATE_DIR_PACKET) < 0);
890  }
891 
892  void *ssh_state = f->alstate;
893  FAIL_IF_NULL(ssh_state);
894  void *tx = SCSshStateGetTx(ssh_state, 0);
895  FAIL_IF(SCSshTxGetFlags(tx, STREAM_TOSERVER) != SshStateFinished);
896 
897  FAIL_IF(SSHParserTestUtilCheck("2.0", "MySSHClient-0.5.1", tx, STREAM_TOSERVER));
898 
899  UTHFreePacket(p);
901  StreamTcpUTDeinit(ra_ctx);
902  UTHFreeFlow(f);
903  PASS;
904 }
905 
906 /** \test Send a banner and 2 records record in four chunks. */
907 static int SSHParserTest15(void)
908 {
909  TcpReassemblyThreadCtx *ra_ctx = NULL;
910  ThreadVars tv;
911  TcpSession ssn;
912  Flow *f = NULL;
913  Packet *p = NULL;
914 
915  uint8_t sshbuf1[] = "SSH-2.0-MySSHClient-0.5.1\r\n";
916  uint8_t sshbuf2[] = { 0x00, 0x00, 0x00, 0x10, 0x01, 17, 0x00};
917  uint8_t sshbuf3[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
918  uint8_t sshbuf4[] = { 0x09, 0x10, 0x11, 0x12, 0x13, 0x00};
919  uint8_t sshbuf5[] = { 0x00, 0x00, 0x02, 0x01, 20, 0x00, 0x00, 0x00, 0x02, 0x01, 21};
920 
921  uint8_t* sshbufs[5] = {sshbuf1, sshbuf2, sshbuf3, sshbuf4, sshbuf5};
922  uint32_t sshlens[5] = {sizeof(sshbuf1) - 1, sizeof(sshbuf2), sizeof(sshbuf3), sizeof(sshbuf4), sizeof(sshbuf5)};
923 
924  memset(&tv, 0x00, sizeof(tv));
925 
926  StreamTcpUTInit(&ra_ctx);
931 
932  f = UTHBuildFlow(AF_INET, "1.1.1.1", "2.2.2.2", 1234, 2222);
933  FAIL_IF_NULL(f);
934  f->protoctx = &ssn;
935  f->proto = IPPROTO_TCP;
936  f->alproto = ALPROTO_SSH;
937 
938  p = PacketGetFromAlloc();
939  FAIL_IF(unlikely(p == NULL));
940  p->proto = IPPROTO_TCP;
941  p->flow = f;
942 
943  uint32_t seq = 2;
944  for (int i=0; i<5; i++) {
945  FAIL_IF(StreamTcpUTAddSegmentWithPayload(&tv, ra_ctx, &ssn.client, seq, sshbufs[i], sshlens[i]) == -1);
946  seq += sshlens[i];
947  FAIL_IF(StreamTcpReassembleAppLayer(&tv, ra_ctx, &ssn, &ssn.client, p, UPDATE_DIR_PACKET) < 0);
948  }
949 
950  void *ssh_state = f->alstate;
951  FAIL_IF_NULL(ssh_state);
952  void *tx = SCSshStateGetTx(ssh_state, 0);
953  FAIL_IF(SCSshTxGetFlags(tx, STREAM_TOSERVER) != SshStateFinished);
954 
955  FAIL_IF(SSHParserTestUtilCheck("2.0", "MySSHClient-0.5.1", tx, STREAM_TOSERVER));
956 
957  UTHFreePacket(p);
959  StreamTcpUTDeinit(ra_ctx);
960  UTHFreeFlow(f);
961  PASS;
962 }
963 
964 /** \test Send toserver a banner and record in three chunks. */
965 static int SSHParserTest16(void)
966 {
967  TcpReassemblyThreadCtx *ra_ctx = NULL;
968  ThreadVars tv;
969  TcpSession ssn;
970  Flow *f = NULL;
971  Packet *p = NULL;
972 
973  uint8_t sshbuf1[] = "SSH-";
974  uint8_t sshbuf2[] = "2.0-MySSHClient-0.5.1\r\n";
975  uint8_t sshbuf3[] = { 0x00, 0x00, 0x00, 0x03,0x01, 21, 0x00};
976 
977  uint8_t* sshbufs[3] = {sshbuf1, sshbuf2, sshbuf3};
978  uint32_t sshlens[3] = {sizeof(sshbuf1) - 1, sizeof(sshbuf2) - 1, sizeof(sshbuf3)};
979 
980  memset(&tv, 0x00, sizeof(tv));
981 
982  StreamTcpUTInit(&ra_ctx);
987 
988  f = UTHBuildFlow(AF_INET, "1.1.1.1", "2.2.2.2", 1234, 2222);
989  FAIL_IF_NULL(f);
990  f->protoctx = &ssn;
991  f->proto = IPPROTO_TCP;
992  f->alproto = ALPROTO_SSH;
993 
994  p = PacketGetFromAlloc();
995  FAIL_IF(unlikely(p == NULL));
996  p->proto = IPPROTO_TCP;
997  p->flow = f;
998 
999  uint32_t seq = 2;
1000  for (int i=0; i<3; i++) {
1001  FAIL_IF(StreamTcpUTAddSegmentWithPayload(&tv, ra_ctx, &ssn.server, seq, sshbufs[i], sshlens[i]) == -1);
1002  seq += sshlens[i];
1003  FAIL_IF(StreamTcpReassembleAppLayer(&tv, ra_ctx, &ssn, &ssn.server, p, UPDATE_DIR_PACKET) < 0);
1004  }
1005 
1006  void *ssh_state = f->alstate;
1007  FAIL_IF_NULL(ssh_state);
1008  void *tx = SCSshStateGetTx(ssh_state, 0);
1009  FAIL_IF(SCSshTxGetFlags(tx, STREAM_TOCLIENT) != SshStateFinished);
1010 
1011  FAIL_IF(SSHParserTestUtilCheck("2.0", "MySSHClient-0.5.1", tx, STREAM_TOCLIENT));
1012 
1013  UTHFreePacket(p);
1015  StreamTcpUTDeinit(ra_ctx);
1016  UTHFreeFlow(f);
1017  PASS;
1018 }
1019 
1020 /** \test Send toserver a banner and 2 records record in four chunks. */
1021 static int SSHParserTest17(void)
1022 {
1023  TcpReassemblyThreadCtx *ra_ctx = NULL;
1024  ThreadVars tv;
1025  TcpSession ssn;
1026  Flow *f = NULL;
1027  Packet *p = NULL;
1028 
1029  uint8_t sshbuf1[] = "SSH-";
1030  uint8_t sshbuf2[] = "2.0-MySSHClient-0.5.1\r\n";
1031  uint8_t sshbuf3[] = { 0x00, 0x00, 0x00, 0x03, 0x01, 17, 0x00};
1032  uint8_t sshbuf4[] = { 0x00, 0x00, 0x00, 0x03, 0x01, 21, 0x00};
1033 
1034  uint8_t* sshbufs[4] = {sshbuf1, sshbuf2, sshbuf3, sshbuf4};
1035  uint32_t sshlens[4] = {sizeof(sshbuf1) - 1, sizeof(sshbuf2) - 1, sizeof(sshbuf3), sizeof(sshbuf4)};
1036 
1037  memset(&tv, 0x00, sizeof(tv));
1038 
1039  StreamTcpUTInit(&ra_ctx);
1042  StreamTcpUTSetupStream(&ssn.server, 1);
1043  StreamTcpUTSetupStream(&ssn.client, 1);
1044 
1045  f = UTHBuildFlow(AF_INET, "1.1.1.1", "2.2.2.2", 1234, 2222);
1046  FAIL_IF_NULL(f);
1047  f->protoctx = &ssn;
1048  f->proto = IPPROTO_TCP;
1049  f->alproto = ALPROTO_SSH;
1050 
1051  p = PacketGetFromAlloc();
1052  FAIL_IF(unlikely(p == NULL));
1053  p->proto = IPPROTO_TCP;
1054  p->flow = f;
1055 
1056  uint32_t seq = 2;
1057  for (int i=0; i<4; i++) {
1058  FAIL_IF(StreamTcpUTAddSegmentWithPayload(&tv, ra_ctx, &ssn.server, seq, sshbufs[i], sshlens[i]) == -1);
1059  seq += sshlens[i];
1060  FAIL_IF(StreamTcpReassembleAppLayer(&tv, ra_ctx, &ssn, &ssn.server, p, UPDATE_DIR_PACKET) < 0);
1061  }
1062 
1063  void *ssh_state = f->alstate;
1064  FAIL_IF_NULL(ssh_state);
1065  void *tx = SCSshStateGetTx(ssh_state, 0);
1066  FAIL_IF(SCSshTxGetFlags(tx, STREAM_TOCLIENT) != SshStateFinished);
1067 
1068  FAIL_IF(SSHParserTestUtilCheck("2.0", "MySSHClient-0.5.1", tx, STREAM_TOCLIENT));
1069 
1070  UTHFreePacket(p);
1072  StreamTcpUTDeinit(ra_ctx);
1073  UTHFreeFlow(f);
1074  PASS;
1075 }
1076 
1077 /** \test 2 directional test */
1078 static int SSHParserTest18(void)
1079 {
1080  TcpReassemblyThreadCtx *ra_ctx = NULL;
1081  ThreadVars tv;
1082  TcpSession ssn;
1083  Flow *f = NULL;
1084  Packet *p = NULL;
1085 
1086  uint8_t server1[] = "SSH-2.0-OpenSSH_4.7p1 Debian-8ubuntu3\r\n";
1087  uint8_t sshbuf1[] = "SSH-";
1088  uint8_t sshbuf2[] = "2.0-MySSHClient-0.5.1\r\n";
1089  uint8_t server2[] = { 0x00, 0x00, 0x00, 0x03, 0x01, 21, 0x00 };
1090  uint8_t sshbuf3[] = { 0x00, 0x00, 0x00, 0x03, 0x01, 21, 0x00 };
1091 
1092 
1093  memset(&tv, 0x00, sizeof(tv));
1094 
1095  StreamTcpUTInit(&ra_ctx);
1098  StreamTcpUTSetupStream(&ssn.server, 1);
1099  StreamTcpUTSetupStream(&ssn.client, 1);
1100 
1101  uint8_t* sshbufs[5] = {server1, sshbuf1, sshbuf2, server2, sshbuf3};
1102  uint32_t sshlens[5] = {sizeof(server1) - 1, sizeof(sshbuf1) - 1, sizeof(sshbuf2) -1, sizeof(server2) - 1, sizeof(sshbuf3)};
1103  bool sshdirs[5] = {true, false, false, true, false};
1104 
1105  f = UTHBuildFlow(AF_INET, "1.1.1.1", "2.2.2.2", 1234, 2222);
1106  FAIL_IF_NULL(f);
1107  f->protoctx = &ssn;
1108  f->proto = IPPROTO_TCP;
1109  f->alproto = ALPROTO_SSH;
1110 
1111  p = PacketGetFromAlloc();
1112  FAIL_IF(unlikely(p == NULL));
1113  p->proto = IPPROTO_TCP;
1114  p->flow = f;
1115 
1116  uint32_t seqcli = 2;
1117  uint32_t seqsrv = 2;
1118  for (int i=0; i<5; i++) {
1119  if (sshdirs[i]) {
1120  FAIL_IF(StreamTcpUTAddSegmentWithPayload(&tv, ra_ctx, &ssn.server, seqsrv, sshbufs[i], sshlens[i]) == -1);
1121  seqsrv += sshlens[i];
1122  FAIL_IF(StreamTcpReassembleAppLayer(&tv, ra_ctx, &ssn, &ssn.server, p, UPDATE_DIR_PACKET) < 0);
1123  } else {
1124  FAIL_IF(StreamTcpUTAddSegmentWithPayload(&tv, ra_ctx, &ssn.client, seqcli, sshbufs[i], sshlens[i]) == -1);
1125  seqcli += sshlens[i];
1126  FAIL_IF(StreamTcpReassembleAppLayer(&tv, ra_ctx, &ssn, &ssn.client, p, UPDATE_DIR_PACKET) < 0);
1127  }
1128  }
1129 
1130  void *ssh_state = f->alstate;
1131  FAIL_IF_NULL(ssh_state);
1132  void *tx = SCSshStateGetTx(ssh_state, 0);
1133  FAIL_IF(SCSshTxGetFlags(tx, STREAM_TOCLIENT) != SshStateFinished);
1134 
1136 
1137  UTHFreePacket(p);
1139  StreamTcpUTDeinit(ra_ctx);
1140  UTHFreeFlow(f);
1141  PASS;
1142 }
1143 
1144 /** \test Really long banner handling: bannel exactly 255 */
1145 static int SSHParserTest19(void)
1146 {
1147  TcpReassemblyThreadCtx *ra_ctx = NULL;
1148  ThreadVars tv;
1149  TcpSession ssn;
1150  Flow *f = NULL;
1151  Packet *p = NULL;
1152 
1153  uint8_t sshbuf1[] = "SSH-";
1154  uint8_t sshbuf2[] = "2.0-";
1155  uint8_t sshbuf3[] = "abcdefghijklmnopqrstuvwxyz"
1156  "abcdefghijklmnopqrstuvwxyz"//60
1157  "abcdefghijklmnopqrstuvwxyz"
1158  "abcdefghijklmnopqrstuvwxyz"//112
1159  "abcdefghijklmnopqrstuvwxyz"
1160  "abcdefghijklmnopqrstuvwxyz"//164
1161  "abcdefghijklmnopqrstuvwxyz"
1162  "abcdefghijklmnopqrstuvwxyz"//216
1163  "abcdefghijklmnopqrstuvwxyz"//242
1164  "abcdefghijkl\r";//255
1165  uint8_t sshbuf4[] = { 0x00, 0x00, 0x00, 0x03, 0x01, 21, 0x00};
1166 
1167  uint8_t* sshbufs[4] = {sshbuf1, sshbuf2, sshbuf3, sshbuf4};
1168  uint32_t sshlens[4] = {sizeof(sshbuf1) - 1, sizeof(sshbuf2) - 1, sizeof(sshbuf3) - 1, sizeof(sshbuf4)};
1169 
1170  memset(&tv, 0x00, sizeof(tv));
1171 
1172  StreamTcpUTInit(&ra_ctx);
1175  StreamTcpUTSetupStream(&ssn.server, 1);
1176  StreamTcpUTSetupStream(&ssn.client, 1);
1177 
1178  f = UTHBuildFlow(AF_INET, "1.1.1.1", "2.2.2.2", 1234, 2222);
1179  FAIL_IF_NULL(f);
1180  f->protoctx = &ssn;
1181  f->proto = IPPROTO_TCP;
1182  f->alproto = ALPROTO_SSH;
1183 
1184  p = PacketGetFromAlloc();
1185  FAIL_IF(unlikely(p == NULL));
1186  p->proto = IPPROTO_TCP;
1187  p->flow = f;
1188 
1189  uint32_t seq = 2;
1190  for (int i=0; i<4; i++) {
1191  FAIL_IF(StreamTcpUTAddSegmentWithPayload(&tv, ra_ctx, &ssn.server, seq, sshbufs[i], sshlens[i]) == -1);
1192  seq += sshlens[i];
1193  FAIL_IF(StreamTcpReassembleAppLayer(&tv, ra_ctx, &ssn, &ssn.server, p, UPDATE_DIR_PACKET) < 0);
1194  }
1195 
1196  void *ssh_state = f->alstate;
1197  FAIL_IF_NULL(ssh_state);
1198  void *tx = SCSshStateGetTx(ssh_state, 0);
1199  FAIL_IF(SCSshTxGetFlags(tx, STREAM_TOCLIENT) != SshStateFinished);
1200 
1201  sshbuf3[sizeof(sshbuf3) - 2] = 0;
1202  FAIL_IF(SSHParserTestUtilCheck("2.0", (char *)sshbuf3, tx, STREAM_TOCLIENT));
1203 
1204  UTHFreePacket(p);
1206  StreamTcpUTDeinit(ra_ctx);
1207  UTHFreeFlow(f);
1208  PASS;
1209 }
1210 
1211 /** \test Really long banner handling: banner exactly 255,
1212  * followed by malformed record */
1213 static int SSHParserTest20(void)
1214 {
1215  TcpReassemblyThreadCtx *ra_ctx = NULL;
1216  ThreadVars tv;
1217  TcpSession ssn;
1218  Flow *f = NULL;
1219  Packet *p = NULL;
1220 
1221  uint8_t sshbuf1[] = "SSH-";
1222  uint8_t sshbuf2[] = "2.0-";
1223  uint8_t sshbuf3[] = "abcdefghijklmnopqrstuvwxyz"
1224  "abcdefghijklmnopqrstuvwxyz"//60
1225  "abcdefghijklmnopqrstuvwxyz"
1226  "abcdefghijklmnopqrstuvwxyz"//112
1227  "abcdefghijklmnopqrstuvwxyz"
1228  "abcdefghijklmnopqrstuvwxyz"//164
1229  "abcdefghijklmnopqrstuvwxyz"
1230  "abcdefghijklmnopqrstuvwxyz"//216
1231  "abcdefghijklmnopqrstuvwxyz"//242
1232  "abcdefghijklm\r";//256
1233  uint8_t sshbuf4[] = {'a','b','c','d','e','f', '\r',
1234  0x00, 0x00, 0x00, 0x06, 0x01, 21, 0x00, 0x00, 0x00};
1235 
1236  uint8_t* sshbufs[4] = {sshbuf1, sshbuf2, sshbuf3, sshbuf4};
1237  uint32_t sshlens[4] = {sizeof(sshbuf1) - 1, sizeof(sshbuf2) - 1, sizeof(sshbuf3) - 1, sizeof(sshbuf4) - 1};
1238 
1239  memset(&tv, 0x00, sizeof(tv));
1240 
1241  StreamTcpUTInit(&ra_ctx);
1244  StreamTcpUTSetupStream(&ssn.server, 1);
1245  StreamTcpUTSetupStream(&ssn.client, 1);
1246 
1247  f = UTHBuildFlow(AF_INET, "1.1.1.1", "2.2.2.2", 1234, 2222);
1248  FAIL_IF_NULL(f);
1249  f->protoctx = &ssn;
1250  f->proto = IPPROTO_TCP;
1251  f->alproto = ALPROTO_SSH;
1252 
1253  p = PacketGetFromAlloc();
1254  FAIL_IF(unlikely(p == NULL));
1255  p->proto = IPPROTO_TCP;
1256  p->flow = f;
1257 
1258  uint32_t seq = 2;
1259  for (int i=0; i<4; i++) {
1260  FAIL_IF(StreamTcpUTAddSegmentWithPayload(&tv, ra_ctx, &ssn.server, seq, sshbufs[i], sshlens[i]) == -1);
1261  seq += sshlens[i];
1262  FAIL_IF(StreamTcpReassembleAppLayer(&tv, ra_ctx, &ssn, &ssn.server, p, UPDATE_DIR_PACKET) < 0);
1263  }
1264 
1265  void *ssh_state = f->alstate;
1266  FAIL_IF_NULL(ssh_state);
1267  void *tx = SCSshStateGetTx(ssh_state, 0);
1268  FAIL_IF(SCSshTxGetFlags(tx, STREAM_TOCLIENT) != SshStateFinished);
1269 
1270  FAIL_IF(SSHParserTestUtilCheck("2.0", NULL, tx, STREAM_TOCLIENT));
1271 
1272  UTHFreePacket(p);
1274  StreamTcpUTDeinit(ra_ctx);
1275  UTHFreeFlow(f);
1276  PASS;
1277 }
1278 
1279 /** \test Fragmented banner handling: chunk has final part of bannel plus
1280  * a record. */
1281 static int SSHParserTest21(void)
1282 {
1283  TcpReassemblyThreadCtx *ra_ctx = NULL;
1284  ThreadVars tv;
1285  TcpSession ssn;
1286  Flow *f = NULL;
1287  Packet *p = NULL;
1288 
1289  uint8_t sshbuf1[] = "SSH-";
1290  uint8_t sshbuf2[] = "2.0-";
1291  uint8_t sshbuf3[] = "abcdefghijklmnopqrstuvwxyz"
1292  "abcdefghijklmnopqrstuvwxyz"//60
1293  "abcdefghijklmnopqrstuvwxyz"
1294  "abcdefghijklmnopqrstuvwxyz"//112
1295  "abcdefghijklmnopqrstuvwxyz"
1296  "abcdefghijklmnopqrstuvwxyz"//164
1297  "abcdefghijklmnopqrstuvwxyz"
1298  "abcdefghijklmnopqrstuvwxyz"//216
1299  "abcdefghijklmnopqrstuvwxy";//241
1300  uint8_t sshbuf4[] = {'l','i','b','s','s','h', '\r',
1301  0x00, 0x00, 0x00, 0x06, 0x01, 21, 0x00, 0x00, 0x00};
1302 
1303  uint8_t* sshbufs[4] = {sshbuf1, sshbuf2, sshbuf3, sshbuf4};
1304  uint32_t sshlens[4] = {sizeof(sshbuf1) - 1, sizeof(sshbuf2) - 1, sizeof(sshbuf3) - 1, sizeof(sshbuf4)};
1305 
1306  memset(&tv, 0x00, sizeof(tv));
1307 
1308  StreamTcpUTInit(&ra_ctx);
1311  StreamTcpUTSetupStream(&ssn.server, 1);
1312  StreamTcpUTSetupStream(&ssn.client, 1);
1313 
1314  f = UTHBuildFlow(AF_INET, "1.1.1.1", "2.2.2.2", 1234, 2222);
1315  FAIL_IF_NULL(f);
1316  f->protoctx = &ssn;
1317  f->proto = IPPROTO_TCP;
1318  f->alproto = ALPROTO_SSH;
1319 
1320  p = PacketGetFromAlloc();
1321  FAIL_IF(unlikely(p == NULL));
1322  p->proto = IPPROTO_TCP;
1323  p->flow = f;
1324 
1325  uint32_t seq = 2;
1326  for (int i=0; i<4; i++) {
1327  FAIL_IF(StreamTcpUTAddSegmentWithPayload(&tv, ra_ctx, &ssn.server, seq, sshbufs[i], sshlens[i]) == -1);
1328  seq += sshlens[i];
1329  FAIL_IF(StreamTcpReassembleAppLayer(&tv, ra_ctx, &ssn, &ssn.server, p, UPDATE_DIR_PACKET) < 0);
1330  }
1331 
1332  void *ssh_state = f->alstate;
1333  FAIL_IF_NULL(ssh_state);
1334  void *tx = SCSshStateGetTx(ssh_state, 0);
1335  FAIL_IF(SCSshTxGetFlags(tx, STREAM_TOCLIENT) != SshStateFinished);
1336 
1337  FAIL_IF(SSHParserTestUtilCheck("2.0", NULL, tx, STREAM_TOCLIENT));
1338 
1339  UTHFreePacket(p);
1341  StreamTcpUTDeinit(ra_ctx);
1342  UTHFreeFlow(f);
1343  PASS;
1344 }
1345 
1346 /** \test Fragmented banner handling: chunk has final part of bannel plus
1347  * a record. */
1348 static int SSHParserTest22(void)
1349 {
1350  TcpReassemblyThreadCtx *ra_ctx = NULL;
1351  ThreadVars tv;
1352  TcpSession ssn;
1353  Flow *f = NULL;
1354  Packet *p = NULL;
1355 
1356  uint8_t sshbuf1[] = "SSH-";
1357  uint8_t sshbuf2[] = "2.0-";
1358  uint8_t sshbuf3[] = {
1359  'l', 'i', 'b', 's', 's', 'h', '\r', //7
1360 
1361  0x00, 0x00, 0x00, 0x06, 0x01, 17, 0x00, 0x00, 0x00, 0x00,
1362  0x00, 0x00, 0x00, 0x06, 0x01, 17, 0x00, 0x00, 0x00, 0x00,
1363  0x00, 0x00, 0x00, 0x06, 0x01, 17, 0x00, 0x00, 0x00, 0x00,
1364  0x00, 0x00, 0x00, 0x06, 0x01, 17, 0x00, 0x00, 0x00, 0x00,
1365  0x00, 0x00, 0x00, 0x06, 0x01, 17, 0x00, 0x00, 0x00, 0x00, //50
1366 
1367  0x00, 0x00, 0x00, 0x06, 0x01, 17, 0x00, 0x00, 0x00, 0x00,
1368  0x00, 0x00, 0x00, 0x06, 0x01, 17, 0x00, 0x00, 0x00, 0x00,
1369  0x00, 0x00, 0x00, 0x06, 0x01, 17, 0x00, 0x00, 0x00, 0x00,
1370  0x00, 0x00, 0x00, 0x06, 0x01, 17, 0x00, 0x00, 0x00, 0x00,
1371  0x00, 0x00, 0x00, 0x06, 0x01, 17, 0x00, 0x00, 0x00, 0x00, //100
1372 
1373  0x00, 0x00, 0x00, 0x06, 0x01, 17, 0x00, 0x00, 0x00, 0x00,
1374  0x00, 0x00, 0x00, 0x06, 0x01, 17, 0x00, 0x00, 0x00, 0x00,
1375  0x00, 0x00, 0x00, 0x06, 0x01, 17, 0x00, 0x00, 0x00, 0x00,
1376  0x00, 0x00, 0x00, 0x06, 0x01, 17, 0x00, 0x00, 0x00, 0x00,
1377  0x00, 0x00, 0x00, 0x06, 0x01, 17, 0x00, 0x00, 0x00, 0x00, //150
1378 
1379  0x00, 0x00, 0x00, 0x06, 0x01, 17, 0x00, 0x00, 0x00, 0x00,
1380  0x00, 0x00, 0x00, 0x06, 0x01, 17, 0x00, 0x00, 0x00, 0x00,
1381  0x00, 0x00, 0x00, 0x06, 0x01, 17, 0x00, 0x00, 0x00, 0x00,
1382  0x00, 0x00, 0x00, 0x06, 0x01, 17, 0x00, 0x00, 0x00, 0x00,
1383  0x00, 0x00, 0x00, 0x06, 0x01, 17, 0x00, 0x00, 0x00, 0x00, //200
1384 
1385  0x00, 0x00, 0x00, 0x06, 0x01, 17, 0x00, 0x00, 0x00, 0x00,
1386  0x00, 0x00, 0x00, 0x06, 0x01, 17, 0x00, 0x00, 0x00, 0x00,
1387  0x00, 0x00, 0x00, 0x06, 0x01, 17, 0x00, 0x00, 0x00, 0x00,
1388  0x00, 0x00, 0x00, 0x06, 0x01, 17, 0x00, 0x00, 0x00, 0x00,
1389  0x00, 0x00, 0x00, 0x06, 0x01, 17, 0x00, 0x00, 0x00, 0x00, //250
1390 
1391  0x00, 0x00, 0x00, 0x06, 0x01, 17, 0x00, 0x00, 0x00, 0x00,
1392  0x00, 0x00, 0x00, 0x06, 0x01, 17, 0x00, 0x00, 0x00, 0x00,
1393  0x00, 0x00, 0x00, 0x06, 0x01, 17, 0x00, 0x00, 0x00, 0x00,
1394  0x00, 0x00, 0x00, 0x06, 0x01, 17, 0x00, 0x00, 0x00, 0x00,
1395  0x00, 0x00, 0x00, 0x06, 0x01, 21, 0x00, 0x00, 0x00, 0x00, //300
1396  };
1397 
1398 
1399  uint8_t* sshbufs[3] = {sshbuf1, sshbuf2, sshbuf3};
1400  uint32_t sshlens[3] = {sizeof(sshbuf1) - 1, sizeof(sshbuf2) - 1, sizeof(sshbuf3) - 1};
1401 
1402  memset(&tv, 0x00, sizeof(tv));
1403 
1404  StreamTcpUTInit(&ra_ctx);
1407  StreamTcpUTSetupStream(&ssn.server, 1);
1408  StreamTcpUTSetupStream(&ssn.client, 1);
1409 
1410  f = UTHBuildFlow(AF_INET, "1.1.1.1", "2.2.2.2", 1234, 2222);
1411  FAIL_IF_NULL(f);
1412  f->protoctx = &ssn;
1413  f->proto = IPPROTO_TCP;
1414  f->alproto = ALPROTO_SSH;
1415 
1416  p = PacketGetFromAlloc();
1417  FAIL_IF(unlikely(p == NULL));
1418  p->proto = IPPROTO_TCP;
1419  p->flow = f;
1420 
1421  uint32_t seq = 2;
1422  for (int i=0; i<3; i++) {
1423  FAIL_IF(StreamTcpUTAddSegmentWithPayload(&tv, ra_ctx, &ssn.server, seq, sshbufs[i], sshlens[i]) == -1);
1424  seq += sshlens[i];
1425  FAIL_IF(StreamTcpReassembleAppLayer(&tv, ra_ctx, &ssn, &ssn.server, p, UPDATE_DIR_PACKET) < 0);
1426  }
1427 
1428  void *ssh_state = f->alstate;
1429  FAIL_IF_NULL(ssh_state);
1430  void *tx = SCSshStateGetTx(ssh_state, 0);
1431  FAIL_IF(SCSshTxGetFlags(tx, STREAM_TOCLIENT) != SshStateFinished);
1432 
1433  FAIL_IF(SSHParserTestUtilCheck("2.0", "libssh", tx, STREAM_TOCLIENT));
1434 
1435  UTHFreePacket(p);
1437  StreamTcpUTDeinit(ra_ctx);
1438  UTHFreeFlow(f);
1439  PASS;
1440 }
1441 
1442 /** \test Send a version string in one chunk (client version str). */
1443 static int SSHParserTest23(void)
1444 {
1445  int result = 0;
1446  Flow f;
1447  uint8_t sshbuf[] = "SSH-2.0\r-MySSHClient-0.5.1\n";
1448  uint32_t sshlen = sizeof(sshbuf) - 1;
1449  TcpSession ssn;
1451 
1452  memset(&f, 0, sizeof(f));
1453  memset(&ssn, 0, sizeof(ssn));
1454  FLOW_INITIALIZE(&f);
1455  f.protoctx = (void *)&ssn;
1456  f.alproto = ALPROTO_SSH;
1457 
1458  StreamTcpInitConfig(true);
1459 
1460  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_SSH,
1461  STREAM_TOSERVER | STREAM_EOF, sshbuf, sshlen);
1462  if (r == 0) {
1463  printf("toclient chunk 1 returned 0 expected non null: ");
1464  goto end;
1465  }
1466 
1467  result = 1;
1468 end:
1469  if (alp_tctx != NULL)
1471  StreamTcpFreeConfig(true);
1472  FLOW_DESTROY(&f);
1473  return result;
1474 }
1475 
1476 /** \test Send a version string in one chunk (client version str). */
1477 static int SSHParserTest24(void)
1478 {
1479  int result = 0;
1480  Flow f;
1481  uint8_t sshbuf[] = "SSH-2.0-\rMySSHClient-0.5.1\n";
1482  uint32_t sshlen = sizeof(sshbuf) - 1;
1483  TcpSession ssn;
1485 
1486  memset(&f, 0, sizeof(f));
1487  memset(&ssn, 0, sizeof(ssn));
1488  FLOW_INITIALIZE(&f);
1489  f.protoctx = (void *)&ssn;
1490  f.alproto = ALPROTO_SSH;
1491 
1492  StreamTcpInitConfig(true);
1493 
1494  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_SSH,
1495  STREAM_TOSERVER | STREAM_EOF, sshbuf, sshlen);
1496  if (r != 0) {
1497  printf("toclient chunk 1 returned %" PRId32 ", expected 0: ", r);
1498  goto end;
1499  }
1500 
1501  void *ssh_state = f.alstate;
1502  if (ssh_state == NULL) {
1503  printf("no ssh state: ");
1504  goto end;
1505  }
1506  void *tx = SCSshStateGetTx(ssh_state, 0);
1507  if (SCSshTxGetFlags(tx, STREAM_TOSERVER) != SshStateBannerDone) {
1508  printf("Didn't detect the msg code of new keys (ciphered data starts): ");
1509  goto end;
1510  }
1511  if (SSHParserTestUtilCheck("2.0", NULL, tx, STREAM_TOSERVER))
1512  goto end;
1513 
1514  result = 1;
1515 end:
1516  if (alp_tctx != NULL)
1518  StreamTcpFreeConfig(true);
1519  FLOW_DESTROY(&f);
1520  return result;
1521 }
1522 
1523 /** \test Send a malformed banner */
1524 static int SSHParserTest25(void)
1525 {
1526  Flow f;
1527  uint8_t sshbuf[] = "\n";
1528  uint32_t sshlen = sizeof(sshbuf) - 1;
1529  TcpSession ssn;
1532 
1533  memset(&f, 0, sizeof(f));
1534  memset(&ssn, 0, sizeof(ssn));
1535  FLOW_INITIALIZE(&f);
1536  f.protoctx = (void *)&ssn;
1537  f.alproto = ALPROTO_SSH;
1538 
1539  StreamTcpInitConfig(true);
1540 
1541  int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_SSH,
1542  STREAM_TOSERVER | STREAM_EOF, sshbuf, sshlen);
1543  FAIL_IF(r != -1);
1544 
1545  void *ssh_state = f.alstate;
1546  FAIL_IF_NULL(ssh_state);
1547  void *tx = SCSshStateGetTx(ssh_state, 0);
1548  FAIL_IF(SCSshTxGetFlags(tx, STREAM_TOSERVER) == SshStateBannerDone);
1549  const uint8_t *dummy = NULL;
1550  uint32_t dummy_len = 0;
1551  FAIL_IF(SCSshTxGetSoftware(tx, &dummy, &dummy_len, STREAM_TOCLIENT) != 0);
1552 
1554  StreamTcpFreeConfig(true);
1555  FLOW_DESTROY(&f);
1556  PASS;
1557 }
1558 
1559 #endif /* UNITTESTS */
1560 
1562 {
1563 #ifdef UNITTESTS
1564  UtRegisterTest("SSHParserTest01 - ToServer", SSHParserTest01);
1565  UtRegisterTest("SSHParserTest02 - ToServer", SSHParserTest02);
1566  UtRegisterTest("SSHParserTest03 - ToServer", SSHParserTest03);
1567  UtRegisterTest("SSHParserTest04 - ToClient", SSHParserTest04);
1568  UtRegisterTest("SSHParserTest05 - ToClient", SSHParserTest05);
1569  UtRegisterTest("SSHParserTest06 - ToClient", SSHParserTest06);
1570  UtRegisterTest("SSHParserTest07 - ToServer 2 chunks", SSHParserTest07);
1571  UtRegisterTest("SSHParserTest08 - ToServer 3 chunks", SSHParserTest08);
1572  UtRegisterTest("SSHParserTest09 - ToClient 2 chunks", SSHParserTest09);
1573  UtRegisterTest("SSHParserTest10 - ToClient 3 chunks", SSHParserTest10);
1574  UtRegisterTest("SSHParserTest11 - ToClient 4 chunks", SSHParserTest11);
1575  UtRegisterTest("SSHParserTest12 - ToClient 4 chunks", SSHParserTest12);
1576  UtRegisterTest("SSHParserTest13 - ToClient 4 chunks", SSHParserTest13);
1577  UtRegisterTest("SSHParserTest14 - ToClient 4 chunks", SSHParserTest14);
1578  UtRegisterTest("SSHParserTest15", SSHParserTest15);
1579  UtRegisterTest("SSHParserTest16", SSHParserTest16);
1580  UtRegisterTest("SSHParserTest17", SSHParserTest17);
1581  UtRegisterTest("SSHParserTest18", SSHParserTest18);
1582  UtRegisterTest("SSHParserTest19", SSHParserTest19);
1583  UtRegisterTest("SSHParserTest20", SSHParserTest20);
1584  UtRegisterTest("SSHParserTest21", SSHParserTest21);
1585  UtRegisterTest("SSHParserTest22", SSHParserTest22);
1586  UtRegisterTest("SSHParserTest23", SSHParserTest23);
1587  UtRegisterTest("SSHParserTest24", SSHParserTest24);
1588  UtRegisterTest("SSHParserTest25", SSHParserTest25);
1589 #endif /* UNITTESTS */
1590 }
1591 
UPDATE_DIR_PACKET
@ UPDATE_DIR_PACKET
Definition: stream-tcp-reassemble.h:56
util-byte.h
Packet_::proto
uint8_t proto
Definition: decode.h:498
StreamTcpUTDeinit
void StreamTcpUTDeinit(TcpReassemblyThreadCtx *ra_ctx)
Definition: stream-tcp-util.c:51
FAIL_IF_NULL
#define FAIL_IF_NULL(expr)
Fail a test if expression evaluates to NULL.
Definition: util-unittest.h:89
AppLayerProtoDetectPMRegisterPatternCI
int AppLayerProtoDetectPMRegisterPatternCI(uint8_t ipproto, AppProto alproto, const char *pattern, uint16_t depth, uint16_t offset, uint8_t direction)
Registers a case-insensitive pattern for protocol detection.
Definition: app-layer-detect-proto.c:1676
app-layer-ssh.h
flow-util.h
stream-tcp.h
unlikely
#define unlikely(expr)
Definition: util-optimize.h:35
UtRegisterTest
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
Definition: util-unittest.c:103
RegisterSSHParsers
void RegisterSSHParsers(void)
Function to register the SSH protocol parsers and other functions.
Definition: app-layer-ssh.c:81
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:269
seq
uint32_t seq
Definition: stream-tcp-private.h:2
Flow_::proto
uint8_t proto
Definition: flow.h:376
threads.h
flow-private.h
Flow_
Flow data structure.
Definition: flow.h:354
StreamTcpReassembleAppLayer
int StreamTcpReassembleAppLayer(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx, TcpSession *ssn, TcpStream *stream, Packet *p, enum StreamUpdateDir app_update_dir)
Update the stream reassembly upon receiving a packet.
Definition: stream-tcp-reassemble.c:1398
SSHTxLogCondition
bool SSHTxLogCondition(ThreadVars *tv, const Packet *p, void *state, void *tx, uint64_t tx_id)
Definition: app-layer-ssh.c:74
AppLayerParserThreadCtxFree
void AppLayerParserThreadCtxFree(AppLayerParserThreadCtx *tctx)
Destroys the app layer parser thread context obtained using AppLayerParserThreadCtxAlloc().
Definition: app-layer-parser.c:312
rust.h
stream-tcp-reassemble.h
ALPROTO_SSH
@ ALPROTO_SSH
Definition: app-layer-protos.h:40
Flow_::protoctx
void * protoctx
Definition: flow.h:439
StreamTcpUTInitInline
void StreamTcpUTInitInline(void)
Definition: stream-tcp-util.c:58
util-unittest.h
ConfValIsTrue
int ConfValIsTrue(const char *val)
Check if a value is true.
Definition: conf.c:536
util-unittest-helper.h
util-memcmp.h
ConfGet
int ConfGet(const char *name, const char **vptr)
Retrieve the value of a configuration node.
Definition: conf.c:335
Flow_::alparser
AppLayerParserState * alparser
Definition: flow.h:473
StreamTcpUTInit
void StreamTcpUTInit(TcpReassemblyThreadCtx **ra_ctx)
Definition: stream-tcp-util.c:44
app-layer-detect-proto.h
StreamTcpInitConfig
void StreamTcpInitConfig(bool)
To initialize the stream global configuration data.
Definition: stream-tcp.c:488
UTHBuildFlow
Flow * UTHBuildFlow(int family, const char *src, const char *dst, Port sp, Port dp)
Definition: util-unittest-helper.c:482
FLOW_INITIALIZE
#define FLOW_INITIALIZE(f)
Definition: flow-util.h:38
protocol
uint16_t protocol
Definition: decode-ppp.h:2
decode.h
util-debug.h
PASS
#define PASS
Pass the test.
Definition: util-unittest.h:105
alp_tctx
AppLayerParserThreadCtx * alp_tctx
Definition: fuzz_applayerparserparse.c:22
util-print.h
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:58
StreamTcpUTSetupStream
void StreamTcpUTSetupStream(TcpStream *s, uint32_t isn)
Definition: stream-tcp-util.c:79
app-layer-parser.h
stream.h
AppLayerParserRegisterProtocolUnittests
void AppLayerParserRegisterProtocolUnittests(uint8_t ipproto, AppProto alproto, void(*RegisterUnittests)(void))
Definition: app-layer-parser.c:1804
Packet_
Definition: decode.h:476
stream-tcp-private.h
conf.h
AppLayerProtoDetectRegisterProtocol
void AppLayerProtoDetectRegisterProtocol(AppProto alproto, const char *alproto_name)
Registers a protocol for protocol detection phase.
Definition: app-layer-detect-proto.c:1767
RunmodeIsUnittests
int RunmodeIsUnittests(void)
Definition: suricata.c:255
APP_LAYER_PARSER_NO_INSPECTION
#define APP_LAYER_PARSER_NO_INSPECTION
Definition: app-layer-parser.h:35
UTHFreeFlow
void UTHFreeFlow(Flow *flow)
Definition: util-unittest-helper.c:487
AppLayerParserThreadCtxAlloc
AppLayerParserThreadCtx * AppLayerParserThreadCtxAlloc(void)
Gets a new app layer protocol's parser thread context.
Definition: app-layer-parser.c:285
StreamTcpUTClearSession
void StreamTcpUTClearSession(TcpSession *ssn)
Definition: stream-tcp-util.c:71
Packet_::flow
struct Flow_ * flow
Definition: decode.h:515
FAIL_IF
#define FAIL_IF(expr)
Fail a test if expression evaluates to true.
Definition: util-unittest.h:71
StreamTcpFreeConfig
void StreamTcpFreeConfig(bool quiet)
Definition: stream-tcp.c:859
flags
uint8_t flags
Definition: decode-gre.h:0
AppLayerParserParse
int AppLayerParserParse(ThreadVars *tv, AppLayerParserThreadCtx *alp_tctx, Flow *f, AppProto alproto, uint8_t flags, const uint8_t *input, uint32_t input_len)
Definition: app-layer-parser.c:1274
suricata-common.h
util-spm.h
TcpSession_::client
TcpStream client
Definition: stream-tcp-private.h:297
tv
ThreadVars * tv
Definition: fuzz_decodepcapfile.c:32
StreamTcpUTAddSegmentWithPayload
int StreamTcpUTAddSegmentWithPayload(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx, TcpStream *stream, uint32_t seq, uint8_t *payload, uint16_t len)
Definition: stream-tcp-util.c:113
PacketGetFromAlloc
Packet * PacketGetFromAlloc(void)
Get a malloced packet.
Definition: decode.c:232
StreamTcpUTSetupSession
void StreamTcpUTSetupSession(TcpSession *ssn)
Definition: stream-tcp-util.c:62
TcpSession_::server
TcpStream server
Definition: stream-tcp-private.h:296
UTHFreePacket
void UTHFreePacket(Packet *p)
UTHFreePacket: function to release the allocated data from UTHBuildPacket and the packet itself.
Definition: util-unittest-helper.c:467
Flow_::alstate
void * alstate
Definition: flow.h:474
ConfValIsFalse
int ConfValIsFalse(const char *val)
Check if a value is false.
Definition: conf.c:561
MAX_SSH_TEST_SIZE
#define MAX_SSH_TEST_SIZE
Definition: app-layer-ssh.c:469
stream-tcp-util.h
TcpReassemblyThreadCtx_
Definition: stream-tcp-reassemble.h:61
app-layer-protos.h
SSHParserRegisterTests
void SSHParserRegisterTests(void)
Definition: app-layer-ssh.c:1561
AppLayerParserThreadCtx_
Definition: app-layer-parser.c:58
TcpSession_
Definition: stream-tcp-private.h:283
AppLayerParserStateIssetFlag
uint16_t AppLayerParserStateIssetFlag(AppLayerParserState *pstate, uint16_t flag)
Definition: app-layer-parser.c:1793
Flow_::alproto
AppProto alproto
application level protocol
Definition: flow.h:448
util-pool.h
AppLayerProtoDetectConfProtoDetectionEnabled
int AppLayerProtoDetectConfProtoDetectionEnabled(const char *ipproto, const char *alproto)
Given a protocol name, checks if proto detection is enabled in the conf file.
Definition: app-layer-detect-proto.c:1959
FLOW_DESTROY
#define FLOW_DESTROY(f)
Definition: flow-util.h:119
SSH_CONFIG_DEFAULT_HASSH
#define SSH_CONFIG_DEFAULT_HASSH
Definition: app-layer-ssh.c:57