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