From 19d701ddf07d855128ded0cf2b573ce468e3bdd6 Mon Sep 17 00:00:00 2001 From: Ashlee Young Date: Wed, 20 Jan 2016 01:10:01 +0000 Subject: Removing Suricata and Audit from source repo, and updated build.sh to avoid building suricata. Will re-address this in C release via tar balls. Change-Id: I3710076f8b7f3313cb3cb5260c4eb0a6834d4f6e Signed-off-by: Ashlee Young --- framework/src/suricata/src/app-layer-ssh.c | 2607 ---------------------------- 1 file changed, 2607 deletions(-) delete mode 100644 framework/src/suricata/src/app-layer-ssh.c (limited to 'framework/src/suricata/src/app-layer-ssh.c') diff --git a/framework/src/suricata/src/app-layer-ssh.c b/framework/src/suricata/src/app-layer-ssh.c deleted file mode 100644 index 879c7746..00000000 --- a/framework/src/suricata/src/app-layer-ssh.c +++ /dev/null @@ -1,2607 +0,0 @@ -/* Copyright (C) 2007-2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Pablo Rincon - * \author Victor Julien - * - * App-layer parser for SSH protocol - * - */ - -#include "suricata-common.h" -#include "debug.h" -#include "decode.h" -#include "threads.h" - -#include "util-print.h" -#include "util-pool.h" - -#include "stream-tcp-private.h" -#include "stream-tcp-reassemble.h" -#include "stream-tcp.h" -#include "stream.h" - -#include "app-layer-protos.h" -#include "app-layer-parser.h" -#include "app-layer-ssh.h" - -#include "conf.h" - -#include "util-spm.h" -#include "util-unittest.h" -#include "util-debug.h" -#include "flow-private.h" - -#include "util-byte.h" -#include "util-memcmp.h" - -/** \internal - * \brief Function to parse the SSH version string of the client - * - * The input to this function is a byte buffer starting with SSH- - * - * \param ssh_state Pointer the state in which the value to be stored - * \param input Pointer the received input data - * \param input_len Length in bytes of the received data - * - * \retval len remaining length in input - */ -static int SSHParseBanner(SshState *state, SshHeader *header, const uint8_t *input, uint32_t input_len) -{ - const uint8_t *line_ptr = input; - uint32_t line_len = input_len; - - /* is it the version line? */ - if (SCMemcmp("SSH-", line_ptr, 4) != 0) { - SCReturnInt(-1); - } - - const uint8_t *banner_end = BasicSearch(line_ptr, line_len, (uint8_t*)"\r", 1); - if (banner_end == NULL) { - banner_end = BasicSearch(line_ptr, line_len, (uint8_t*)"\n", 1); - if (banner_end == NULL) { - SCLogDebug("No EOL at the end of banner buffer"); - SCReturnInt(-1); - } - } - - if ((banner_end - line_ptr) > 255) { - SCLogDebug("Invalid version string, it should be less than 255 " - "characters including , input value is %"PRIuMAX, - (banner_end - line_ptr)); - SCReturnInt(-1); - } - - /* don't search things behind the end of banner */ - line_len = banner_end - line_ptr; - - /* ok, we have found the version line/string, skip it and parse proto version */ - line_ptr += 4; - line_len -= 4; - - uint8_t *proto_end = BasicSearch(line_ptr, line_len, (uint8_t*)"-", 1); - if (proto_end == NULL) { - /* Strings starting with SSH- are not allowed - * if they are not the real version string */ - SCLogDebug("Info Version String for SSH (invalid usage of SSH- prefix)"); - SCReturnInt(-1); - } - uint64_t proto_ver_len = (uint64_t)(proto_end - line_ptr); - header->proto_version = SCMalloc(proto_ver_len + 1); - if (header->proto_version == NULL) { - SCReturnInt(-1); - } - memcpy(header->proto_version, line_ptr, proto_ver_len); - header->proto_version[proto_ver_len] = '\0'; - - /* Now lets parse the software & version */ - line_ptr += proto_ver_len + 1; - line_len -= proto_ver_len + 1; - if (line_len < 1) { - SCLogDebug("No software version specified (weird)"); - header->flags |= SSH_FLAG_VERSION_PARSED; - /* Return the remaining length */ - SCReturnInt(0); - } - - uint64_t sw_ver_len = (uint64_t)(banner_end - line_ptr); - /* sanity check on this arithmetic */ - if ((sw_ver_len <= 1) || (sw_ver_len >= input_len)) { - SCLogDebug("Should not have sw version length '%" PRIu64 "'", sw_ver_len); - SCReturnInt(-1); - } - - header->software_version = SCMalloc(sw_ver_len + 1); - if (header->software_version == NULL) { - SCReturnInt(-1); - } - memcpy(header->software_version, line_ptr, sw_ver_len); - header->software_version[sw_ver_len] = '\0'; - if (header->software_version[sw_ver_len - 1] == 0x0d) - header->software_version[sw_ver_len - 1] = '\0'; - - header->flags |= SSH_FLAG_VERSION_PARSED; - - /* Return the remaining length */ - int len = input_len - (banner_end - input); - SCReturnInt(len); -} - -static int SSHParseRecordHeader(SshState *state, SshHeader *header, - const uint8_t *input, uint32_t input_len) -{ -#ifdef DEBUG - BUG_ON(input_len != 6); -#else - if (input_len < 6) - SCReturnInt(-1); -#endif - /* input and input_len now point past initial line */ - uint32_t pkt_len = 0; - int r = ByteExtractUint32(&pkt_len, BYTE_BIG_ENDIAN, - 4, input); - if (r != 4) { - SCLogDebug("xtract 4 bytes failed %d", r); - SCReturnInt(-1); - } - if (pkt_len < 2) { - SCReturnInt(-1); - } - - header->pkt_len = pkt_len; - SCLogDebug("pkt len: %"PRIu32, pkt_len); - - input += 4; - //input_len -= 4; - - header->padding_len = *input; - - input += 1; - //input_len -= 1; - - SCLogDebug("padding: %u", header->padding_len); - - header->msg_code = *input; - - SCLogDebug("msg code: %u", header->msg_code); - - if (header->msg_code == SSH_MSG_NEWKEYS) { - /* done */ - SCLogDebug("done"); - header->flags |= SSH_FLAG_PARSER_DONE; - } else { - /* not yet done */ - SCLogDebug("not done"); - } - SCReturnInt(0); -} - -/** \internal - * \brief Function to parse the SSH field in packet received from the client - * - * Input to this function is a byte buffer starting with SSH- up to at least - * a \r or \n character. - * - * \param ssh_state Pointer the state in which the value to be stored - * \param input Pointer the received input data - * \param input_len Length in bytes of the received data - */ -static int SSHParseRecord(SshState *state, SshHeader *header, uint8_t *input, uint32_t input_len) -{ - SCEnter(); - int ret = 0; - - if (header->flags & SSH_FLAG_PARSER_DONE) { - SCReturnInt(0); - } - - SCLogDebug("state %p, input %p,input_len %" PRIu32, - state, input, input_len); - //PrintRawDataFp(stdout, input, input_len); - - if (!(header->flags & SSH_FLAG_VERSION_PARSED)) { - ret = SSHParseBanner(state, header, input, input_len); - if (ret < 0) { - SCLogDebug("Invalid version string"); - SCReturnInt(-1); - } else if (header->flags & SSH_FLAG_VERSION_PARSED) { - SCLogDebug("Version string parsed, remaining length %d", ret); - input += input_len - ret; - input_len -= (input_len - ret); - - uint32_t u = 0; - while (u < input_len && (input[u] == '\r' || input[u] == '\n')) { - u++; - } - SCLogDebug("skipping %u EOL bytes", u); - input += u; - input_len -= u; - - if (input_len == 0) - SCReturnInt(0); - - } else { - BUG_ON(1);// we only call this when we have enough data - SCLogDebug("Version string not parsed yet"); - //pstate->parse_field = 0; - SCReturnInt(0); - } - } else { - SCLogDebug("Version string already parsed"); - } - - /* skip bytes from the current record if we have to */ - if (header->record_left > 0) { - SCLogDebug("skipping bytes part of the current record"); - if (header->record_left > input_len) { - header->record_left -= input_len; - SCLogDebug("all input skipped, %u left in record", header->record_left); - SCReturnInt(0); - } else { - input_len -= header->record_left; - input += header->record_left; - header->record_left = 0; - - if (input_len == 0) { - SCLogDebug("all input skipped"); - SCReturnInt(0); - } - } - } - -again: - /* input is too small, even when combined with stored bytes */ - if (header->buf_offset + input_len < 6) { - memcpy(header->buf + header->buf_offset, input, input_len); - header->buf_offset += input_len; - SCReturnInt(0); - - /* we have enough bytes to parse 6 bytes, lets see if we have - * previously stored some */ - } else if (header->buf_offset > 0) { - uint8_t needed = 6 - header->buf_offset; - - SCLogDebug("parse stored"); - memcpy(header->buf + header->buf_offset, input, needed); - header->buf_offset = 6; - - // parse the 6 - if (SSHParseRecordHeader(state, header, header->buf, 6) < 0) - SCReturnInt(-1); - header->buf_offset = 0; - - uint32_t record_left = header->pkt_len - 2; - input_len -= needed; - input += needed; - - if (record_left > input_len) { - header->record_left = record_left - input_len; - } else { - input_len -= record_left; - if (input_len == 0) - SCReturnInt(0); - - input += record_left; - - SCLogDebug("we have %u left to parse", input_len); - goto again; - - } - - /* nothing stored, lets parse this directly */ - } else { - SCLogDebug("parse direct"); - //PrintRawDataFp(stdout, input, input_len); - if (SSHParseRecordHeader(state, header, input, 6) < 0) - SCReturnInt(-1); - - uint32_t record_left = header->pkt_len - 2; - SCLogDebug("record left %u", record_left); - input_len -= 6; - input += 6; - - if (record_left > input_len) { - header->record_left = record_left - input_len; - } else { - input_len -= record_left; - if (input_len == 0) - SCReturnInt(0); - input += record_left; - //PrintRawDataFp(stdout, input, input_len); - - SCLogDebug("we have %u left to parse", input_len); - goto again; - } - } - - SCReturnInt(0); -} - -static int EnoughData(uint8_t *input, uint32_t input_len) -{ - uint32_t u; - for (u = 0; u < input_len; u++) { - if (input[u] == '\r' || input[u] == '\n') - return TRUE; - } - return FALSE; -} - -#define MAX_BANNER_LEN 256 - -static int SSHParseData(SshState *state, SshHeader *header, - uint8_t *input, uint32_t input_len) -{ - /* we're looking for the banner */ - if (!(header->flags & SSH_FLAG_VERSION_PARSED)) - { - int banner_eol = EnoughData(input, input_len); - - /* fast track normal case: no buffering */ - if (header->banner_buffer == NULL && banner_eol) - { - SCLogDebug("enough data, parse now"); - // parse now - int r = SSHParseRecord(state, header, input, input_len); - SCReturnInt(r); - - /* banner EOL with existing buffer present. Time for magic. */ - } else if (banner_eol) { - SCLogDebug("banner EOL with existing buffer"); - - uint32_t tocopy = MAX_BANNER_LEN - header->banner_len; - if (tocopy > input_len) - tocopy = input_len; - - SCLogDebug("tocopy %u input_len %u", tocopy, input_len); - memcpy(header->banner_buffer + header->banner_len, input, tocopy); - header->banner_len += tocopy; - - SCLogDebug("header->banner_len %u", header->banner_len); - int r = SSHParseRecord(state, header, - header->banner_buffer, header->banner_len); - if (r == 0) { - input += tocopy; - input_len -= tocopy; - if (input_len > 0) { - SCLogDebug("handling remaining data %u", input_len); - r = SSHParseRecord(state, header, input, input_len); - } - } - SCReturnInt(r); - - /* no banner EOL, so we need to buffer */ - } else if (!banner_eol) { - if (header->banner_buffer == NULL) { - header->banner_buffer = SCMalloc(MAX_BANNER_LEN); - if (header->banner_buffer == NULL) - SCReturnInt(-1); - } - - uint32_t tocopy = MAX_BANNER_LEN - header->banner_len; - if (tocopy > input_len) - tocopy = input_len; - SCLogDebug("tocopy %u", tocopy); - - memcpy(header->banner_buffer + header->banner_len, input, tocopy); - header->banner_len += tocopy; - SCLogDebug("header->banner_len %u", header->banner_len); - } - - /* we have a banner, the rest is just records */ - } else { - int r = SSHParseRecord(state, header, input, input_len); - SCReturnInt(r); - } - - //PrintRawDataFp(stdout, input, input_len); - return 0; -} - -static int SSHParseRequest(Flow *f, void *state, AppLayerParserState *pstate, - uint8_t *input, uint32_t input_len, - void *local_data) -{ - SshState *ssh_state = (SshState *)state; - SshHeader *ssh_header = &ssh_state->cli_hdr; - - if (input == NULL && AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF)) { - SCReturnInt(1); - } else if (input == NULL || input_len == 0) { - SCReturnInt(-1); - } - - int r = SSHParseData(ssh_state, ssh_header, input, input_len); - - if (ssh_state->cli_hdr.flags & SSH_FLAG_PARSER_DONE && - ssh_state->srv_hdr.flags & SSH_FLAG_PARSER_DONE) { - AppLayerParserStateSetFlag(pstate, APP_LAYER_PARSER_NO_INSPECTION); - AppLayerParserStateSetFlag(pstate, APP_LAYER_PARSER_NO_REASSEMBLY); - } - - SCReturnInt(r); -} - -static int SSHParseResponse(Flow *f, void *state, AppLayerParserState *pstate, - uint8_t *input, uint32_t input_len, - void *local_data) -{ - SshState *ssh_state = (SshState *)state; - SshHeader *ssh_header = &ssh_state->srv_hdr; - - if (input == NULL && AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF)) { - SCReturnInt(1); - } else if (input == NULL || input_len == 0) { - SCReturnInt(-1); - } - - int r = SSHParseData(ssh_state, ssh_header, input, input_len); - - if (ssh_state->cli_hdr.flags & SSH_FLAG_PARSER_DONE && - ssh_state->srv_hdr.flags & SSH_FLAG_PARSER_DONE) { - AppLayerParserStateSetFlag(pstate, APP_LAYER_PARSER_NO_INSPECTION); - AppLayerParserStateSetFlag(pstate, APP_LAYER_PARSER_NO_REASSEMBLY); - } - - SCReturnInt(r); -} - -/** \brief Function to allocates the SSH state memory - */ -static void *SSHStateAlloc(void) -{ - void *s = SCMalloc(sizeof(SshState)); - if (unlikely(s == NULL)) - return NULL; - - memset(s, 0, sizeof(SshState)); - return s; -} - -/** \brief Function to free the SSH state memory - */ -static void SSHStateFree(void *state) -{ - SshState *s = (SshState *)state; - if (s->cli_hdr.proto_version != NULL) - SCFree(s->cli_hdr.proto_version); - if (s->cli_hdr.software_version != NULL) - SCFree(s->cli_hdr.software_version); - if (s->cli_hdr.banner_buffer != NULL) - SCFree(s->cli_hdr.banner_buffer); - - if (s->srv_hdr.proto_version != NULL) - SCFree(s->srv_hdr.proto_version); - if (s->srv_hdr.software_version != NULL) - SCFree(s->srv_hdr.software_version); - if (s->srv_hdr.banner_buffer != NULL) - SCFree(s->srv_hdr.banner_buffer); - - SCFree(s); -} - -static int SSHRegisterPatternsForProtocolDetection(void) -{ - if (AppLayerProtoDetectPMRegisterPatternCI(IPPROTO_TCP, ALPROTO_SSH, - "SSH-", 4, 0, STREAM_TOSERVER) < 0) - { - return -1; - } - if (AppLayerProtoDetectPMRegisterPatternCI(IPPROTO_TCP, ALPROTO_SSH, - "SSH-", 4, 0, STREAM_TOCLIENT) < 0) - { - return -1; - } - return 0; -} - -/** \brief Function to register the SSH protocol parsers and other functions - */ -void RegisterSSHParsers(void) -{ - char *proto_name = "ssh"; - - if (AppLayerProtoDetectConfProtoDetectionEnabled("tcp", proto_name)) { - AppLayerProtoDetectRegisterProtocol(ALPROTO_SSH, proto_name); - if (SSHRegisterPatternsForProtocolDetection() < 0) - return; - } - - if (AppLayerParserConfParserEnabled("tcp", proto_name)) { - AppLayerParserRegisterParser(IPPROTO_TCP, ALPROTO_SSH, STREAM_TOSERVER, - SSHParseRequest); - AppLayerParserRegisterParser(IPPROTO_TCP, ALPROTO_SSH, STREAM_TOCLIENT, - SSHParseResponse); - AppLayerParserRegisterStateFuncs(IPPROTO_TCP, ALPROTO_SSH, SSHStateAlloc, SSHStateFree); - AppLayerParserRegisterParserAcceptableDataDirection(IPPROTO_TCP, - ALPROTO_SSH, STREAM_TOSERVER|STREAM_TOCLIENT); - } else { -// SCLogInfo("Parsed disabled for %s protocol. Protocol detection" -// "still on.", proto_name); - } - -#ifdef UNITTESTS - AppLayerParserRegisterProtocolUnittests(IPPROTO_TCP, ALPROTO_SSH, SSHParserRegisterTests); -#endif -} - -/* UNITTESTS */ -#ifdef UNITTESTS - -/** \test Send a version string in one chunk (client version str). */ -static int SSHParserTest01(void) -{ - int result = 0; - Flow f; - uint8_t sshbuf[] = "SSH-2.0-MySSHClient-0.5.1\n"; - uint32_t sshlen = sizeof(sshbuf) - 1; - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - f.protoctx = (void *)&ssn; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER|STREAM_EOF, sshbuf, sshlen); - if (r != 0) { - printf("toclient chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SshState *ssh_state = f.alstate; - if (ssh_state == NULL) { - printf("no ssh state: "); - goto end; - } - - if ( !(ssh_state->cli_hdr.flags & SSH_FLAG_VERSION_PARSED)) { - printf("Client version string not parsed: "); - goto end; - } - - if (ssh_state->cli_hdr.software_version == NULL) { - printf("Client version string not parsed: "); - goto end; - } - - if (ssh_state->cli_hdr.proto_version == NULL) { - printf("Client version string not parsed: "); - goto end; - } - - if (strncmp((char*)ssh_state->cli_hdr.software_version, "MySSHClient-0.5.1", strlen("MySSHClient-0.5.1")) != 0) { - printf("Client version string not parsed correctly: "); - goto end; - } - - if (strncmp((char*)ssh_state->cli_hdr.proto_version, "2.0", strlen("2.0")) != 0) { - printf("Client version string not parsed correctly: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - return result; -} - -/** \test Send a version string in one chunk but multiple lines and comments. - * (client version str) - */ -static int SSHParserTest02(void) -{ - int result = 0; - Flow f; - uint8_t sshbuf[] = "SSH-2.0-MySSHClient-0.5.1 some comments...\n"; - uint32_t sshlen = sizeof(sshbuf) - 1; - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - f.protoctx = (void *)&ssn; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER|STREAM_EOF, sshbuf, sshlen); - if (r != 0) { - printf("toclient chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SshState *ssh_state = f.alstate; - if (ssh_state == NULL) { - printf("no ssh state: "); - goto end; - } - - if ( !(ssh_state->cli_hdr.flags & SSH_FLAG_VERSION_PARSED)) { - printf("Client version string not parsed: "); - goto end; - } - - if (ssh_state->cli_hdr.software_version == NULL) { - printf("Client version string not parsed: "); - goto end; - } - - if (ssh_state->cli_hdr.proto_version == NULL) { - printf("Client version string not parsed: "); - goto end; - } - - if (strncmp((char*)ssh_state->cli_hdr.software_version, "MySSHClient-0.5.1", strlen("MySSHClient-0.5.1")) != 0) { - printf("Client version string not parsed correctly: "); - goto end; - } - - if (strncmp((char*)ssh_state->cli_hdr.proto_version, "2.0", strlen("2.0")) != 0) { - printf("Client version string not parsed correctly: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - return result; -} - -/** \test Send a invalid version string in one chunk but multiple lines and comments. - * (client version str) - */ -static int SSHParserTest03(void) -{ - int result = 0; - Flow f; - uint8_t sshbuf[] = "SSH-2.0 some comments...\n"; - uint32_t sshlen = sizeof(sshbuf) - 1; - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - f.protoctx = (void *)&ssn; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER|STREAM_EOF, sshbuf, sshlen); - if (r == 0) { - printf("toclient chunk 1 returned %" PRId32 ", expected != 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SshState *ssh_state = f.alstate; - if (ssh_state == NULL) { - printf("no ssh state: "); - goto end; - } - - if (ssh_state->cli_hdr.flags & SSH_FLAG_VERSION_PARSED) { - printf("Client version string parsed? It's not a valid string: "); - goto end; - } - - if (ssh_state->cli_hdr.proto_version != NULL) { - goto end; - } - - if (ssh_state->cli_hdr.software_version != NULL) { - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - return result; -} - -/** \test Send a version string in one chunk (server version str). */ -static int SSHParserTest04(void) -{ - int result = 0; - Flow f; - uint8_t sshbuf[] = "SSH-2.0-MySSHClient-0.5.1\n"; - uint32_t sshlen = sizeof(sshbuf) - 1; - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - f.protoctx = (void *)&ssn; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOCLIENT|STREAM_EOF, sshbuf, sshlen); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SshState *ssh_state = f.alstate; - if (ssh_state == NULL) { - printf("no ssh state: "); - goto end; - } - - if (!(ssh_state->srv_hdr.flags & SSH_FLAG_VERSION_PARSED)) { - printf("Client version string not parsed: "); - goto end; - } - - if (ssh_state->srv_hdr.software_version == NULL) { - printf("Client version string not parsed: "); - goto end; - } - - if (ssh_state->srv_hdr.proto_version == NULL) { - printf("Client version string not parsed: "); - goto end; - } - - if (strncmp((char*)ssh_state->srv_hdr.software_version, "MySSHClient-0.5.1", strlen("MySSHClient-0.5.1")) != 0) { - printf("Client version string not parsed correctly: "); - goto end; - } - - if (strncmp((char*)ssh_state->srv_hdr.proto_version, "2.0", strlen("2.0")) != 0) { - printf("Client version string not parsed correctly: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - return result; -} - -/** \test Send a version string in one chunk (server version str) - */ -static int SSHParserTest05(void) -{ - int result = 0; - Flow f; - uint8_t sshbuf[] = "SSH-2.0-MySSHClient-0.5.1 some comments...\n"; - uint32_t sshlen = sizeof(sshbuf) - 1; - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - f.protoctx = (void *)&ssn; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOCLIENT|STREAM_EOF, sshbuf, sshlen); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SshState *ssh_state = f.alstate; - if (ssh_state == NULL) { - printf("no ssh state: "); - goto end; - } - - if (!(ssh_state->srv_hdr.flags & SSH_FLAG_VERSION_PARSED)) { - printf("Client version string not parsed: "); - goto end; - } - - if (ssh_state->srv_hdr.software_version == NULL) { - printf("Client version string not parsed: "); - goto end; - } - - if (ssh_state->srv_hdr.proto_version == NULL) { - printf("Client version string not parsed: "); - goto end; - } - - if (strncmp((char*)ssh_state->srv_hdr.software_version, "MySSHClient-0.5.1", strlen("MySSHClient-0.5.1")) != 0) { - printf("Client version string not parsed correctly: "); - goto end; - } - - if (strncmp((char*)ssh_state->srv_hdr.proto_version, "2.0", strlen("2.0")) != 0) { - printf("Client version string not parsed correctly: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - return result; -} - -/** \test Send a invalid version string in one chunk (server version str) - */ -static int SSHParserTest06(void) -{ - int result = 0; - Flow f; - uint8_t sshbuf[] = "SSH-2.0 some comments...\n"; - uint32_t sshlen = sizeof(sshbuf) - 1; - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - f.protoctx = (void *)&ssn; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOCLIENT|STREAM_EOF, sshbuf, sshlen); - if (r == 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected != 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - /* Ok, it returned an error. Let's make sure we didn't parse the string at all */ - - SshState *ssh_state = f.alstate; - if (ssh_state == NULL) { - printf("no ssh state: "); - goto end; - } - - if (ssh_state->srv_hdr.flags & SSH_FLAG_VERSION_PARSED) { - printf("Client version string parsed? It's not a valid string: "); - goto end; - } - - if (ssh_state->srv_hdr.proto_version != NULL) { - goto end; - } - - if (ssh_state->srv_hdr.software_version != NULL) { - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - return result; -} - -static int SSHParserTest07(void) -{ - int result = 0; - Flow f; - uint8_t sshbuf1[] = "SSH-2."; - uint32_t sshlen1 = sizeof(sshbuf1) - 1; - uint8_t sshbuf2[] = { "0-MySSHClient-0.5.1\r\n"}; - uint32_t sshlen2 = sizeof(sshbuf2) - 1; - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - f.protoctx = (void *)&ssn; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER, sshbuf1, sshlen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER, sshbuf2, sshlen2); - if (r != 0) { - printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SshState *ssh_state = f.alstate; - if (ssh_state == NULL) { - printf("no ssh state: "); - goto end; - } - - if ( !(ssh_state->cli_hdr.flags & SSH_FLAG_VERSION_PARSED)) { - printf("Client version string not parsed: "); - goto end; - } - - if (ssh_state->cli_hdr.software_version == NULL) { - printf("Client version string not parsed: "); - goto end; - } - - if (ssh_state->cli_hdr.proto_version == NULL) { - printf("Client version string not parsed: "); - goto end; - } - - if (strncmp((char*)ssh_state->cli_hdr.software_version, "MySSHClient-0.5.1", strlen("MySSHClient-0.5.1")) != 0) { - printf("Client version string not parsed correctly: "); - goto end; - } - - if (strncmp((char*)ssh_state->cli_hdr.proto_version, "2.0", strlen("2.0")) != 0) { - printf("Client version string not parsed correctly: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - return result; -} - -/** \test Send a version banner in three chunks. */ -static int SSHParserTest08(void) -{ - int result = 0; - Flow f; - uint8_t sshbuf1[] = "SSH-"; - uint32_t sshlen1 = sizeof(sshbuf1) - 1; - uint8_t sshbuf2[] = "2."; - uint32_t sshlen2 = sizeof(sshbuf2) - 1; - uint8_t sshbuf3[] = { "0-MySSHClient-0.5.1\r\n"}; - uint32_t sshlen3 = sizeof(sshbuf3) - 1; - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - f.protoctx = (void *)&ssn; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER, sshbuf1, sshlen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER, sshbuf2, sshlen2); - if (r != 0) { - printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER, sshbuf3, sshlen3); - if (r != 0) { - printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SshState *ssh_state = f.alstate; - if (ssh_state == NULL) { - printf("no ssh state: "); - goto end; - } - - if ( !(ssh_state->cli_hdr.flags & SSH_FLAG_VERSION_PARSED)) { - printf("Client version string not parsed: "); - goto end; - } - - if (ssh_state->cli_hdr.software_version == NULL) { - printf("Client version string not parsed: "); - goto end; - } - - if (ssh_state->cli_hdr.proto_version == NULL) { - printf("Client version string not parsed: "); - goto end; - } - - if (strncmp((char*)ssh_state->cli_hdr.software_version, "MySSHClient-0.5.1", strlen("MySSHClient-0.5.1")) != 0) { - printf("Client version string not parsed correctly: "); - goto end; - } - - if (strncmp((char*)ssh_state->cli_hdr.proto_version, "2.0", strlen("2.0")) != 0) { - printf("Client version string not parsed correctly: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - return result; -} - -static int SSHParserTest09(void) -{ - int result = 0; - Flow f; - uint8_t sshbuf1[] = "SSH-2."; - uint32_t sshlen1 = sizeof(sshbuf1) - 1; - uint8_t sshbuf2[] = { "0-MySSHClient-0.5.1\r\n"}; - uint32_t sshlen2 = sizeof(sshbuf2) - 1; - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - f.protoctx = (void *)&ssn; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOCLIENT, sshbuf1, sshlen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOCLIENT, sshbuf2, sshlen2); - if (r != 0) { - printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SshState *ssh_state = f.alstate; - if (ssh_state == NULL) { - printf("no ssh state: "); - goto end; - } - - if (!(ssh_state->srv_hdr.flags & SSH_FLAG_VERSION_PARSED)) { - printf("Client version string not parsed: "); - goto end; - } - - if (ssh_state->srv_hdr.software_version == NULL) { - printf("Client version string not parsed: "); - goto end; - } - - if (ssh_state->srv_hdr.proto_version == NULL) { - printf("Client version string not parsed: "); - goto end; - } - - if (strncmp((char*)ssh_state->srv_hdr.software_version, "MySSHClient-0.5.1", strlen("MySSHClient-0.5.1")) != 0) { - printf("Client version string not parsed correctly: "); - goto end; - } - - if (strncmp((char*)ssh_state->srv_hdr.proto_version, "2.0", strlen("2.0")) != 0) { - printf("Client version string not parsed correctly: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - return result; -} - -/** \test Send a version banner in three chunks. */ -static int SSHParserTest10(void) -{ - int result = 0; - Flow f; - uint8_t sshbuf1[] = "SSH-"; - uint32_t sshlen1 = sizeof(sshbuf1) - 1; - uint8_t sshbuf2[] = "2."; - uint32_t sshlen2 = sizeof(sshbuf2) - 1; - uint8_t sshbuf3[] = { "0-MySSHClient-0.5.1\r\n"}; - uint32_t sshlen3 = sizeof(sshbuf3) - 1; - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - f.protoctx = (void *)&ssn; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOCLIENT, sshbuf1, sshlen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOCLIENT, sshbuf2, sshlen2); - if (r != 0) { - printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOCLIENT, sshbuf3, sshlen3); - if (r != 0) { - printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SshState *ssh_state = f.alstate; - if (ssh_state == NULL) { - printf("no ssh state: "); - goto end; - } - - if (!(ssh_state->srv_hdr.flags & SSH_FLAG_VERSION_PARSED)) { - printf("Client version string not parsed: "); - goto end; - } - - if (ssh_state->srv_hdr.software_version == NULL) { - printf("Client version string not parsed: "); - goto end; - } - - if (ssh_state->srv_hdr.proto_version == NULL) { - printf("Client version string not parsed: "); - goto end; - } - - if (strncmp((char*)ssh_state->srv_hdr.software_version, "MySSHClient-0.5.1", strlen("MySSHClient-0.5.1")) != 0) { - printf("Client version string not parsed correctly: "); - goto end; - } - - if (strncmp((char*)ssh_state->srv_hdr.proto_version, "2.0", strlen("2.0")) != 0) { - printf("Client version string not parsed correctly: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - return result; -} - -/** \test Send a banner and record in three chunks. */ -static int SSHParserTest11(void) -{ - int result = 0; - Flow f; - uint8_t sshbuf1[] = "SSH-2.0-MySSHClient-0.5.1\r\n"; - uint32_t sshlen1 = sizeof(sshbuf1) - 1; - uint8_t sshbuf2[] = { 0x00, 0x00, 0x00, 0x03, 0x01, 21, 0x00}; - uint32_t sshlen2 = sizeof(sshbuf2); - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - f.protoctx = (void *)&ssn; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER, sshbuf1, sshlen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER, sshbuf2, sshlen2); - if (r != 0) { - printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SshState *ssh_state = f.alstate; - if (ssh_state == NULL) { - printf("no ssh state: "); - goto end; - } - - if ( !(ssh_state->cli_hdr.flags & SSH_FLAG_VERSION_PARSED)) { - printf("Client version string not parsed: "); - goto end; - } - - if (ssh_state->cli_hdr.software_version == NULL) { - printf("Client version string not parsed: "); - goto end; - } - - if (ssh_state->cli_hdr.proto_version == NULL) { - printf("Client version string not parsed: "); - goto end; - } - - if (strncmp((char*)ssh_state->cli_hdr.software_version, "MySSHClient-0.5.1", strlen("MySSHClient-0.5.1")) != 0) { - printf("Client version string not parsed correctly: "); - goto end; - } - - if (strncmp((char*)ssh_state->cli_hdr.proto_version, "2.0", strlen("2.0")) != 0) { - printf("Client version string not parsed correctly: "); - goto end; - } - - if ( !(ssh_state->cli_hdr.flags & SSH_FLAG_PARSER_DONE)) { - printf("Didn't detect the msg code of new keys (ciphered data starts): "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - return result; -} - -/** \test Send a banner and 2 records record in four chunks. */ -static int SSHParserTest12(void) -{ - int result = 0; - Flow f; - uint8_t sshbuf1[] = "SSH-2.0-MySSHClient-0.5.1\r\n"; - uint32_t sshlen1 = sizeof(sshbuf1) - 1; - uint8_t sshbuf2[] = { 0x00, 0x00, 0x00, 0x03,0x01, 17, 0x00}; - uint32_t sshlen2 = sizeof(sshbuf2); - uint8_t sshbuf3[] = { 0x00, 0x00, 0x00, 0x03,0x01, 21, 0x00}; - uint32_t sshlen3 = sizeof(sshbuf3); - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - f.protoctx = (void *)&ssn; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER, sshbuf1, sshlen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER, sshbuf2, sshlen2); - if (r != 0) { - printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER, sshbuf3, sshlen3); - if (r != 0) { - printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SshState *ssh_state = f.alstate; - if (ssh_state == NULL) { - printf("no ssh state: "); - goto end; - } - - if ( !(ssh_state->cli_hdr.flags & SSH_FLAG_VERSION_PARSED)) { - printf("Client version string not parsed: "); - goto end; - } - - if (ssh_state->cli_hdr.software_version == NULL) { - printf("Client version string not parsed: "); - goto end; - } - - if (ssh_state->cli_hdr.proto_version == NULL) { - printf("Client version string not parsed: "); - goto end; - } - - if (strncmp((char*)ssh_state->cli_hdr.software_version, "MySSHClient-0.5.1", strlen("MySSHClient-0.5.1")) != 0) { - printf("Client version string not parsed correctly: "); - goto end; - } - - if (strncmp((char*)ssh_state->cli_hdr.proto_version, "2.0", strlen("2.0")) != 0) { - printf("Client version string not parsed correctly: "); - goto end; - } - - if ( !(ssh_state->cli_hdr.flags & SSH_FLAG_PARSER_DONE)) { - printf("Didn't detect the msg code of new keys (ciphered data starts): "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - return result; -} - -/** \test Send a banner and 2 records record in four chunks. */ -static int SSHParserTest13(void) -{ - int result = 0; - Flow f; - uint8_t sshbuf1[] = "SSH-2.0-MySSHClient-0.5.1\r\n"; - uint32_t sshlen1 = sizeof(sshbuf1) - 1; - uint8_t sshbuf2[] = { 0x00, 0x00, 0x00, 0x02, 0x01, 17}; - uint32_t sshlen2 = sizeof(sshbuf2); - uint8_t sshbuf3[] = { 0x00, 0x00, 0x00, 0x02, 0x01, 21}; - uint32_t sshlen3 = sizeof(sshbuf3); - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - uint32_t u; - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - f.protoctx = (void *)&ssn; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER, sshbuf1, sshlen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - for (u = 0; u < sshlen2; u++) { - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER, &sshbuf2[u], 1); - if (r != 0) { - printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - } - for (u = 0; u < sshlen3; u++) { - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER, &sshbuf3[u], 1); - if (r != 0) { - printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - } - SshState *ssh_state = f.alstate; - if (ssh_state == NULL) { - printf("no ssh state: "); - goto end; - } - - if ( !(ssh_state->cli_hdr.flags & SSH_FLAG_VERSION_PARSED)) { - printf("Client version string not parsed: "); - goto end; - } - - if (ssh_state->cli_hdr.software_version == NULL) { - printf("Client version string not parsed: "); - goto end; - } - - if (ssh_state->cli_hdr.proto_version == NULL) { - printf("Client version string not parsed: "); - goto end; - } - - if (strncmp((char*)ssh_state->cli_hdr.software_version, "MySSHClient-0.5.1", strlen("MySSHClient-0.5.1")) != 0) { - printf("Client version string not parsed correctly: "); - goto end; - } - - if (strncmp((char*)ssh_state->cli_hdr.proto_version, "2.0", strlen("2.0")) != 0) { - printf("Client version string not parsed correctly: "); - goto end; - } - - if ( !(ssh_state->cli_hdr.flags & SSH_FLAG_PARSER_DONE)) { - printf("Didn't detect the msg code of new keys (ciphered data starts): "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - return result; -} - -/** \test Send a banner and 2 records record in four chunks. */ -static int SSHParserTest14(void) -{ - int result = 0; - Flow f; - uint8_t sshbuf1[] = "SSH-2.0-MySSHClient-0.5.1\r\n"; - uint32_t sshlen1 = sizeof(sshbuf1) - 1; - uint8_t sshbuf2[] = { 0x00, 0x00, 0x00, 0x10, 0x01, 17, 0x00}; - uint32_t sshlen2 = sizeof(sshbuf2); - - uint8_t sshbuf3[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}; - uint32_t sshlen3 = sizeof(sshbuf3); - uint8_t sshbuf4[] = { 0x09, 0x10, 0x11, 0x12, 0x13, 0x00}; - uint32_t sshlen4 = sizeof(sshbuf4); - - /* first byte of this record in sshbuf4 */ - uint8_t sshbuf5[] = { 0x00, 0x00, 0x02, 0x01, 21}; - uint32_t sshlen5 = sizeof(sshbuf5); - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - f.protoctx = (void *)&ssn; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER, sshbuf1, sshlen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER, sshbuf2, sshlen2); - if (r != 0) { - printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER, sshbuf3, sshlen3); - if (r != 0) { - printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER, sshbuf4, sshlen4); - if (r != 0) { - printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER, sshbuf5, sshlen5); - if (r != 0) { - printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SshState *ssh_state = f.alstate; - if (ssh_state == NULL) { - printf("no ssh state: "); - goto end; - } - - if ( !(ssh_state->cli_hdr.flags & SSH_FLAG_VERSION_PARSED)) { - printf("Client version string not parsed: "); - goto end; - } - - if (ssh_state->cli_hdr.software_version == NULL) { - printf("Client version string not parsed: "); - goto end; - } - - if (ssh_state->cli_hdr.proto_version == NULL) { - printf("Client version string not parsed: "); - goto end; - } - - if (strncmp((char*)ssh_state->cli_hdr.software_version, "MySSHClient-0.5.1", strlen("MySSHClient-0.5.1")) != 0) { - printf("Client version string not parsed correctly: "); - goto end; - } - - if (strncmp((char*)ssh_state->cli_hdr.proto_version, "2.0", strlen("2.0")) != 0) { - printf("Client version string not parsed correctly: "); - goto end; - } - - if ( !(ssh_state->cli_hdr.flags & SSH_FLAG_PARSER_DONE)) { - printf("Didn't detect the msg code of new keys (ciphered data starts): "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - return result; -} - -/** \test Send a banner and 2 records record in four chunks. */ -static int SSHParserTest15(void) -{ - int result = 0; - Flow f; - uint8_t sshbuf1[] = "SSH-2.0-MySSHClient-0.5.1\r\n"; - uint32_t sshlen1 = sizeof(sshbuf1) - 1; - uint8_t sshbuf2[] = { 0x00, 0x00, 0x00, 0x10, 0x01, 17, 0x00}; - uint32_t sshlen2 = sizeof(sshbuf2); - - uint8_t sshbuf3[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}; - uint32_t sshlen3 = sizeof(sshbuf3); - uint8_t sshbuf4[] = { 0x09, 0x10, 0x11, 0x12, 0x13, 0x00}; - uint32_t sshlen4 = sizeof(sshbuf4); - - /* first byte of this record in sshbuf4 */ - uint8_t sshbuf5[] = { 0x00, 0x00, 0x02, 0x01, 20, 0x00, 0x00, 0x00, 0x02, 0x01, 21}; - uint32_t sshlen5 = sizeof(sshbuf5); - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - f.protoctx = (void *)&ssn; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER, sshbuf1, sshlen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER, sshbuf2, sshlen2); - if (r != 0) { - printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER, sshbuf3, sshlen3); - if (r != 0) { - printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER, sshbuf4, sshlen4); - if (r != 0) { - printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER, sshbuf5, sshlen5); - if (r != 0) { - printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SshState *ssh_state = f.alstate; - if (ssh_state == NULL) { - printf("no ssh state: "); - goto end; - } - - if ( !(ssh_state->cli_hdr.flags & SSH_FLAG_VERSION_PARSED)) { - printf("Client version string not parsed: "); - goto end; - } - - if (ssh_state->cli_hdr.software_version == NULL) { - printf("Client version string not parsed: "); - goto end; - } - - if (ssh_state->cli_hdr.proto_version == NULL) { - printf("Client version string not parsed: "); - goto end; - } - - if (strncmp((char*)ssh_state->cli_hdr.software_version, "MySSHClient-0.5.1", strlen("MySSHClient-0.5.1")) != 0) { - printf("Client version string not parsed correctly: "); - goto end; - } - - if (strncmp((char*)ssh_state->cli_hdr.proto_version, "2.0", strlen("2.0")) != 0) { - printf("Client version string not parsed correctly: "); - goto end; - } - - if ( !(ssh_state->cli_hdr.flags & SSH_FLAG_PARSER_DONE)) { - printf("Didn't detect the msg code of new keys (ciphered data starts): "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - return result; -} - -/** \test Send toserver a banner and record in three chunks. */ -static int SSHParserTest16(void) -{ - int result = 0; - Flow f; - uint8_t sshbuf1[] = "SSH-"; - uint32_t sshlen1 = sizeof(sshbuf1) - 1; - uint8_t sshbuf2[] = "2.0-MySSHClient-0.5.1\r\n"; - uint32_t sshlen2 = sizeof(sshbuf2) - 1; - uint8_t sshbuf3[] = { 0x00, 0x00, 0x00, 0x03,0x01, 21, 0x00}; - uint32_t sshlen3 = sizeof(sshbuf3); - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - f.protoctx = (void *)&ssn; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOCLIENT, sshbuf1, sshlen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOCLIENT, sshbuf2, sshlen2); - if (r != 0) { - printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOCLIENT, sshbuf3, sshlen3); - if (r != 0) { - printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SshState *ssh_state = f.alstate; - if (ssh_state == NULL) { - printf("no ssh state: "); - goto end; - } - - if (!(ssh_state->srv_hdr.flags & SSH_FLAG_VERSION_PARSED)) { - printf("Client version string not parsed: "); - goto end; - } - - if (ssh_state->srv_hdr.software_version == NULL) { - printf("Client version string not parsed: "); - goto end; - } - - if (ssh_state->srv_hdr.proto_version == NULL) { - printf("Client version string not parsed: "); - goto end; - } - - if (strncmp((char*)ssh_state->srv_hdr.software_version, "MySSHClient-0.5.1", strlen("MySSHClient-0.5.1")) != 0) { - printf("Client version string not parsed correctly: "); - goto end; - } - - if (strncmp((char*)ssh_state->srv_hdr.proto_version, "2.0", strlen("2.0")) != 0) { - printf("Client version string not parsed correctly: "); - goto end; - } - - if ( !(ssh_state->srv_hdr.flags & SSH_FLAG_PARSER_DONE)) { - printf("Didn't detect the msg code of new keys (ciphered data starts): "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - return result; -} - -/** \test Send toserver a banner and 2 records record in four chunks. */ -static int SSHParserTest17(void) -{ - int result = 0; - Flow f; - uint8_t sshbuf1[] = "SSH-"; - uint32_t sshlen1 = sizeof(sshbuf1) - 1; - uint8_t sshbuf2[] = "2.0-MySSHClient-0.5.1\r\n"; - uint32_t sshlen2 = sizeof(sshbuf2) - 1; - uint8_t sshbuf3[] = { 0x00, 0x00, 0x00, 0x03, 0x01, 17, 0x00}; - uint32_t sshlen3 = sizeof(sshbuf3); - uint8_t sshbuf4[] = { 0x00, 0x00, 0x00, 0x03, 0x01, 21, 0x00}; - uint32_t sshlen4 = sizeof(sshbuf4); - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - f.protoctx = (void *)&ssn; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOCLIENT, sshbuf1, sshlen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOCLIENT, sshbuf2, sshlen2); - if (r != 0) { - printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOCLIENT, sshbuf3, sshlen3); - if (r != 0) { - printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOCLIENT, sshbuf4, sshlen4); - if (r != 0) { - printf("toserver chunk 4 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SshState *ssh_state = f.alstate; - if (ssh_state == NULL) { - printf("no ssh state: "); - goto end; - } - - if (!(ssh_state->srv_hdr.flags & SSH_FLAG_VERSION_PARSED)) { - printf("Client version string not parsed: "); - goto end; - } - - if (ssh_state->srv_hdr.software_version == NULL) { - printf("Client version string not parsed: "); - goto end; - } - - if (ssh_state->srv_hdr.proto_version == NULL) { - printf("Client version string not parsed: "); - goto end; - } - - if (strncmp((char*)ssh_state->srv_hdr.software_version, "MySSHClient-0.5.1", strlen("MySSHClient-0.5.1")) != 0) { - printf("Client version string not parsed correctly: "); - goto end; - } - - if (strncmp((char*)ssh_state->srv_hdr.proto_version, "2.0", strlen("2.0")) != 0) { - printf("Client version string not parsed correctly: "); - goto end; - } - - if ( !(ssh_state->srv_hdr.flags & SSH_FLAG_PARSER_DONE)) { - printf("Didn't detect the msg code of new keys (ciphered data starts): "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - return result; -} - -/** \test 2 directional test */ -static int SSHParserTest18(void) -{ - int result = 0; - Flow f; - - uint8_t server1[] = "SSH-2.0-OpenSSH_4.7p1 Debian-8ubuntu3\r\n"; - uint32_t serverlen1 = sizeof(server1) - 1; - - uint8_t sshbuf1[] = "SSH-"; - uint32_t sshlen1 = sizeof(sshbuf1) - 1; - uint8_t sshbuf2[] = "2.0-MySSHClient-0.5.1\r\n"; - uint32_t sshlen2 = sizeof(sshbuf2) - 1; - - uint8_t server2[] = { 0x00, 0x00, 0x00, 0x03, 0x01, 21, 0x00 }; - uint32_t serverlen2 = sizeof(server2) - 1; - - uint8_t sshbuf3[] = { 0x00, 0x00, 0x00, 0x03, 0x01, 21, 0x00 }; - uint32_t sshlen3 = sizeof(sshbuf3); - - - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - f.protoctx = (void *)&ssn; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOCLIENT, server1, serverlen1); - if (r != 0) { - printf("toclient chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER, sshbuf1, sshlen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER, sshbuf2, sshlen2); - if (r != 0) { - printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOCLIENT, server2, serverlen2); - if (r != 0) { - printf("toclient chunk 2 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER, sshbuf3, sshlen3); - if (r != 0) { - printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SshState *ssh_state = f.alstate; - if (ssh_state == NULL) { - printf("no ssh state: "); - goto end; - } - - if ( !(ssh_state->cli_hdr.flags & SSH_FLAG_PARSER_DONE)) { - printf("Didn't detect the msg code of new keys (ciphered data starts): "); - goto end; - } - - if ( !(ssh_state->srv_hdr.flags & SSH_FLAG_PARSER_DONE)) { - printf("Didn't detect the msg code of new keys (ciphered data starts): "); - goto end; - } - - if (!(AppLayerParserStateIssetFlag(f.alparser, APP_LAYER_PARSER_NO_INSPECTION))) { - printf("detection not disabled: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - return result; -} - -/** \test Really long banner handling: bannel exactly 255 */ -static int SSHParserTest19(void) -{ - int result = 0; - Flow f; - uint8_t sshbuf1[] = "SSH-"; - uint32_t sshlen1 = sizeof(sshbuf1) - 1; - uint8_t sshbuf2[] = "2.0-"; - uint32_t sshlen2 = sizeof(sshbuf2) - 1; // 8 - uint8_t sshbuf3[] = "abcdefghijklmnopqrstuvwxyz" - "abcdefghijklmnopqrstuvwxyz"//60 - "abcdefghijklmnopqrstuvwxyz" - "abcdefghijklmnopqrstuvwxyz"//112 - "abcdefghijklmnopqrstuvwxyz" - "abcdefghijklmnopqrstuvwxyz"//164 - "abcdefghijklmnopqrstuvwxyz" - "abcdefghijklmnopqrstuvwxyz"//216 - "abcdefghijklmnopqrstuvwxyz"//242 - "abcdefghijkl\r";//255 - uint32_t sshlen3 = sizeof(sshbuf3) - 1; - - uint8_t sshbuf4[] = { 0x00, 0x00, 0x00, 0x03, 0x01, 21, 0x00}; - uint32_t sshlen4 = sizeof(sshbuf4); - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - f.protoctx = (void *)&ssn; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOCLIENT, sshbuf1, sshlen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOCLIENT, sshbuf2, sshlen2); - if (r != 0) { - printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOCLIENT, sshbuf3, sshlen3); - if (r != 0) { - printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOCLIENT, sshbuf4, sshlen4); - if (r != 0) { - printf("toserver chunk 4 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SshState *ssh_state = f.alstate; - if (ssh_state == NULL) { - printf("no ssh state: "); - goto end; - } - - if (!(ssh_state->srv_hdr.flags & SSH_FLAG_VERSION_PARSED)) { - printf("Client version string not parsed: "); - goto end; - } - - if (ssh_state->srv_hdr.software_version == NULL) { - printf("Client version string not parsed: "); - goto end; - } - - if (ssh_state->srv_hdr.proto_version == NULL) { - printf("Client version string not parsed: "); - goto end; - } - - char *name = SCMalloc(256); - if (name == NULL) - goto end; - memset(name, 0x00, 256); - strlcpy(name, (char *)sshbuf3, strlen((char *)sshbuf3) - 1); - - if (strncmp((char*)ssh_state->srv_hdr.software_version, name, strlen(name)) != 0) { - printf("Client version string not parsed correctly: "); - goto end; - } - - if (strncmp((char*)ssh_state->srv_hdr.proto_version, "2.0", strlen("2.0")) != 0) { - printf("Client version string not parsed correctly: "); - goto end; - } - - if ( !(ssh_state->srv_hdr.flags & SSH_FLAG_PARSER_DONE)) { - printf("Didn't detect the msg code of new keys (ciphered data starts): "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - return result; -} - -/** \test Really long banner handling: banner exactly 255, - * followed by malformed record */ -static int SSHParserTest20(void) -{ - int result = 0; - Flow f; - uint8_t sshbuf1[] = "SSH-"; - uint32_t sshlen1 = sizeof(sshbuf1) - 1; - uint8_t sshbuf2[] = "2.0-"; - uint32_t sshlen2 = sizeof(sshbuf2) - 1; // 8 - uint8_t sshbuf3[] = "abcdefghijklmnopqrstuvwxyz" - "abcdefghijklmnopqrstuvwxyz"//60 - "abcdefghijklmnopqrstuvwxyz" - "abcdefghijklmnopqrstuvwxyz"//112 - "abcdefghijklmnopqrstuvwxyz" - "abcdefghijklmnopqrstuvwxyz"//164 - "abcdefghijklmnopqrstuvwxyz" - "abcdefghijklmnopqrstuvwxyz"//216 - "abcdefghijklmnopqrstuvwxyz"//242 - "abcdefghijklm\r";//256 - uint32_t sshlen3 = sizeof(sshbuf3) - 1; - uint8_t sshbuf4[] = {'a','b','c','d','e','f', '\r', - 0x00, 0x00, 0x00, 0x06, 0x01, 21, 0x00, 0x00, 0x00}; - uint32_t sshlen4 = sizeof(sshbuf4) - 1; - - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - f.protoctx = (void *)&ssn; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOCLIENT, sshbuf1, sshlen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOCLIENT, sshbuf2, sshlen2); - if (r != 0) { - printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOCLIENT, sshbuf3, sshlen3); - if (r != 0) { - printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SCLogDebug("chunk 4:"); - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOCLIENT, sshbuf4, sshlen4); - if (r != 0) { - printf("toserver chunk 4 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SshState *ssh_state = f.alstate; - if (ssh_state == NULL) { - printf("no ssh state: "); - goto end; - } - - if (!(ssh_state->srv_hdr.flags & SSH_FLAG_VERSION_PARSED)) { - printf("Client version string not parsed: "); - goto end; - } - - if (ssh_state->srv_hdr.software_version == NULL) { - printf("Client version string not parsed: "); - goto end; - } - - if (ssh_state->srv_hdr.proto_version == NULL) { - printf("Client version string not parsed: "); - goto end; - } - - if (strncmp((char*)ssh_state->srv_hdr.proto_version, "2.0", strlen("2.0")) != 0) { - printf("Client version string not parsed correctly: "); - goto end; - } - - if ((ssh_state->srv_hdr.flags & SSH_FLAG_PARSER_DONE)) { - printf("detected the msg code of new keys (ciphered data starts): "); - goto end; - } - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - return result; -} - -/** \test Fragmented banner handling: chunk has final part of bannel plus - * a record. */ -static int SSHParserTest21(void) -{ - int result = 0; - Flow f; - uint8_t sshbuf1[] = "SSH-"; - uint32_t sshlen1 = sizeof(sshbuf1) - 1; - uint8_t sshbuf2[] = "2.0-"; - uint32_t sshlen2 = sizeof(sshbuf2) - 1; // 8 - uint8_t sshbuf3[] = "abcdefghijklmnopqrstuvwxyz" - "abcdefghijklmnopqrstuvwxyz"//60 - "abcdefghijklmnopqrstuvwxyz" - "abcdefghijklmnopqrstuvwxyz"//112 - "abcdefghijklmnopqrstuvwxyz" - "abcdefghijklmnopqrstuvwxyz"//164 - "abcdefghijklmnopqrstuvwxyz" - "abcdefghijklmnopqrstuvwxyz"//216 - "abcdefghijklmnopqrstuvwxy";//241 - uint32_t sshlen3 = sizeof(sshbuf3) - 1; - uint8_t sshbuf4[] = {'l','i','b','s','s','h', '\r', - 0x00, 0x00, 0x00, 0x06, 0x01, 21, 0x00, 0x00, 0x00}; - uint32_t sshlen4 = sizeof(sshbuf4) - 1; - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - f.protoctx = (void *)&ssn; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOCLIENT, sshbuf1, sshlen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOCLIENT, sshbuf2, sshlen2); - if (r != 0) { - printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOCLIENT, sshbuf3, sshlen3); - if (r != 0) { - printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SCLogDebug("chunk 4:"); - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOCLIENT, sshbuf4, sshlen4); - if (r != 0) { - printf("toserver chunk 4 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SshState *ssh_state = f.alstate; - if (ssh_state == NULL) { - printf("no ssh state: "); - goto end; - } - - if (!(ssh_state->srv_hdr.flags & SSH_FLAG_VERSION_PARSED)) { - printf("Client version string not parsed: "); - goto end; - } - - if (ssh_state->srv_hdr.software_version == NULL) { - printf("Client version string not parsed: "); - goto end; - } - - if (ssh_state->srv_hdr.proto_version == NULL) { - printf("Client version string not parsed: "); - goto end; - } - - if (strncmp((char*)ssh_state->srv_hdr.proto_version, "2.0", strlen("2.0")) != 0) { - printf("Client version string not parsed correctly: "); - goto end; - } - - if ( !(ssh_state->srv_hdr.flags & SSH_FLAG_PARSER_DONE)) { - printf("Didn't detect the msg code of new keys (ciphered data starts): "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - return result; -} - -/** \test Fragmented banner handling: chunk has final part of bannel plus - * a record. */ -static int SSHParserTest22(void) -{ - int result = 0; - Flow f; - uint8_t sshbuf1[] = "SSH-"; - uint32_t sshlen1 = sizeof(sshbuf1) - 1; - uint8_t sshbuf2[] = "2.0-"; - uint32_t sshlen2 = sizeof(sshbuf2) - 1; // 8 - uint8_t sshbuf3[] = { - 'l', 'i', 'b', 's', 's', 'h', '\r', //7 - - 0x00, 0x00, 0x00, 0x06, 0x01, 17, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x06, 0x01, 17, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x06, 0x01, 17, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x06, 0x01, 17, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x06, 0x01, 17, 0x00, 0x00, 0x00, 0x00, //50 - - 0x00, 0x00, 0x00, 0x06, 0x01, 17, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x06, 0x01, 17, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x06, 0x01, 17, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x06, 0x01, 17, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x06, 0x01, 17, 0x00, 0x00, 0x00, 0x00, //100 - - 0x00, 0x00, 0x00, 0x06, 0x01, 17, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x06, 0x01, 17, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x06, 0x01, 17, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x06, 0x01, 17, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x06, 0x01, 17, 0x00, 0x00, 0x00, 0x00, //150 - - 0x00, 0x00, 0x00, 0x06, 0x01, 17, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x06, 0x01, 17, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x06, 0x01, 17, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x06, 0x01, 17, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x06, 0x01, 17, 0x00, 0x00, 0x00, 0x00, //200 - - 0x00, 0x00, 0x00, 0x06, 0x01, 17, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x06, 0x01, 17, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x06, 0x01, 17, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x06, 0x01, 17, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x06, 0x01, 17, 0x00, 0x00, 0x00, 0x00, //250 - - 0x00, 0x00, 0x00, 0x06, 0x01, 17, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x06, 0x01, 17, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x06, 0x01, 17, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x06, 0x01, 17, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x06, 0x01, 21, 0x00, 0x00, 0x00, 0x00, //300 - }; - uint32_t sshlen3 = sizeof(sshbuf3) - 1; - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - f.protoctx = (void *)&ssn; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOCLIENT, sshbuf1, sshlen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOCLIENT, sshbuf2, sshlen2); - if (r != 0) { - printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOCLIENT, sshbuf3, sshlen3); - if (r != 0) { - printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); -#if 0 - SCLogDebug("chunk 4:"); - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOCLIENT, sshbuf4, sshlen4); - if (r != 0) { - printf("toserver chunk 4 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); -#endif - SshState *ssh_state = f.alstate; - if (ssh_state == NULL) { - printf("no ssh state: "); - goto end; - } - - if (!(ssh_state->srv_hdr.flags & SSH_FLAG_VERSION_PARSED)) { - printf("Client version string not parsed: "); - goto end; - } - - if (ssh_state->srv_hdr.software_version == NULL) { - printf("Client version string not parsed: "); - goto end; - } - - if (ssh_state->srv_hdr.proto_version == NULL) { - printf("Client version string not parsed: "); - goto end; - } - - if (strncmp((char*)ssh_state->srv_hdr.proto_version, "2.0", strlen("2.0")) != 0) { - printf("Client version string not parsed correctly: "); - goto end; - } - - if ( !(ssh_state->srv_hdr.flags & SSH_FLAG_PARSER_DONE)) { - printf("Didn't detect the msg code of new keys (ciphered data starts): "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - return result; -} - -/** \test Send a version string in one chunk (client version str). */ -static int SSHParserTest23(void) -{ - int result = 0; - Flow f; - uint8_t sshbuf[] = "SSH-2.0\r-MySSHClient-0.5.1\n"; - uint32_t sshlen = sizeof(sshbuf) - 1; - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - f.protoctx = (void *)&ssn; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER|STREAM_EOF, sshbuf, sshlen); - if (r == 0) { - printf("toclient chunk 1 returned 0 expected non null: "); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - return result; -} - -/** \test Send a version string in one chunk (client version str). */ -static int SSHParserTest24(void) -{ - int result = 0; - Flow f; - uint8_t sshbuf[] = "SSH-2.0-\rMySSHClient-0.5.1\n"; - uint32_t sshlen = sizeof(sshbuf) - 1; - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - f.protoctx = (void *)&ssn; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER|STREAM_EOF, sshbuf, sshlen); - if (r != 0) { - printf("toclient chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SshState *ssh_state = f.alstate; - if (ssh_state == NULL) { - printf("no ssh state: "); - goto end; - } - - if ( !(ssh_state->cli_hdr.flags & SSH_FLAG_VERSION_PARSED)) { - printf("Client version string not parsed: "); - goto end; - } - - if (ssh_state->cli_hdr.software_version) { - printf("Client version string should not be parsed: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - return result; -} - - -#endif /* UNITTESTS */ - -void SSHParserRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("SSHParserTest01 - ToServer", SSHParserTest01, 1); - UtRegisterTest("SSHParserTest02 - ToServer", SSHParserTest02, 1); - UtRegisterTest("SSHParserTest03 - ToServer", SSHParserTest03, 1); - UtRegisterTest("SSHParserTest04 - ToClient", SSHParserTest04, 1); - UtRegisterTest("SSHParserTest05 - ToClient", SSHParserTest05, 1); - UtRegisterTest("SSHParserTest06 - ToClient", SSHParserTest06, 1); - UtRegisterTest("SSHParserTest07 - ToServer 2 chunks", SSHParserTest07, 1); - UtRegisterTest("SSHParserTest08 - ToServer 3 chunks", SSHParserTest08, 1); - UtRegisterTest("SSHParserTest09 - ToClient 2 chunks", SSHParserTest09, 1); - UtRegisterTest("SSHParserTest10 - ToClient 3 chunks", SSHParserTest10, 1); - UtRegisterTest("SSHParserTest11 - ToClient 4 chunks", SSHParserTest11, 1); - UtRegisterTest("SSHParserTest12 - ToClient 4 chunks", SSHParserTest12, 1); - UtRegisterTest("SSHParserTest13 - ToClient 4 chunks", SSHParserTest13, 1); - UtRegisterTest("SSHParserTest14 - ToClient 4 chunks", SSHParserTest14, 1); - UtRegisterTest("SSHParserTest15", SSHParserTest15, 1); - UtRegisterTest("SSHParserTest16", SSHParserTest16, 1); - UtRegisterTest("SSHParserTest17", SSHParserTest17, 1); - UtRegisterTest("SSHParserTest18", SSHParserTest18, 1); - UtRegisterTest("SSHParserTest19", SSHParserTest19, 1); - UtRegisterTest("SSHParserTest20", SSHParserTest20, 1); - UtRegisterTest("SSHParserTest21", SSHParserTest21, 1); - UtRegisterTest("SSHParserTest22", SSHParserTest22, 1); - UtRegisterTest("SSHParserTest23", SSHParserTest23, 1); - UtRegisterTest("SSHParserTest24", SSHParserTest24, 1); -#endif /* UNITTESTS */ -} - -- cgit 1.2.3-korg