diff --git a/src/app-layer-ssh.c b/src/app-layer-ssh.c index 8205c4709a..8f85a57c50 100644 --- a/src/app-layer-ssh.c +++ b/src/app-layer-ssh.c @@ -316,18 +316,6 @@ again: } } -#if 0 - if (state->cli_hdr.msg_code == SSH_MSG_NEWKEYS) { - /* We are not going to inspect any packet more - * as the data is now encrypted */ - SCLogDebug("SSH parser done (the rest of the communication is encrypted)"); - pstate->flags |= APP_LAYER_PARSER_DONE; - pstate->flags |= APP_LAYER_PARSER_NO_INSPECTION; - pstate->flags |= APP_LAYER_PARSER_NO_REASSEMBLY; - pstate->parse_field = 1; - SCReturnInt(1); - } -#endif SCReturnInt(0); } @@ -406,6 +394,13 @@ static int SSHParseRequest(Flow *f, void *state, AppLayerParserState *pstate, SshHeader *ssh_header = &ssh_state->cli_hdr; 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); } @@ -417,6 +412,13 @@ static int SSHParseResponse(Flow *f, void *state, AppLayerParserState *pstate, SshHeader *ssh_header = &ssh_state->srv_hdr; 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); } @@ -1856,6 +1858,109 @@ end: 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; +} + #endif /* UNITTESTS */ void SSHParserRegisterTests(void) { @@ -1877,6 +1982,7 @@ void SSHParserRegisterTests(void) { UtRegisterTest("SSHParserTest15", SSHParserTest15, 1); UtRegisterTest("SSHParserTest16", SSHParserTest16, 1); UtRegisterTest("SSHParserTest17", SSHParserTest17, 1); + UtRegisterTest("SSHParserTest18", SSHParserTest18, 1); #endif /* UNITTESTS */ }