From 5fe1dc1d2449109e34d1f3ef1dddb26ec3faefa9 Mon Sep 17 00:00:00 2001 From: Gurvinder Singh Date: Mon, 24 May 2010 19:59:21 +0200 Subject: [PATCH] support for sslv2/sslv3 their unit tests and better stream no reassembly flag handling --- src/Makefile.am | 1 + src/app-layer-detect-proto.c | 50 ++- src/app-layer-detect-proto.h | 1 + src/app-layer-ssl.c | 700 +++++++++++++++++++++++++++++++++++ src/app-layer-ssl.h | 83 +++++ src/app-layer-tls.c | 190 +++++++++- src/app-layer-tls.h | 11 +- src/detect-engine-mpm.c | 2 +- src/detect-tls-version.c | 2 +- src/detect-tls-version.h | 2 +- src/stream-tcp-reassemble.c | 9 +- src/stream-tcp.c | 122 ++---- src/suricata.c | 3 + 13 files changed, 1072 insertions(+), 104 deletions(-) create mode 100644 src/app-layer-ssl.c create mode 100644 src/app-layer-ssl.h diff --git a/src/Makefile.am b/src/Makefile.am index 77b7ce994e..6acbd398ef 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -193,6 +193,7 @@ app-layer-smb.c app-layer-smb.h \ app-layer-smb2.c app-layer-smb2.h \ app-layer-dcerpc.c app-layer-dcerpc.h \ app-layer-ftp.c app-layer-ftp.h \ +app-layer-ssl.c app-layer-ssl.h \ defrag.c defrag.h \ output.c output.h \ win32-misc.c win32-misc.h \ diff --git a/src/app-layer-detect-proto.c b/src/app-layer-detect-proto.c index 635e322bcd..c4febb5e86 100644 --- a/src/app-layer-detect-proto.c +++ b/src/app-layer-detect-proto.c @@ -147,17 +147,28 @@ static void AlpProtoFreeSignature(AlpProtoSignature *s) { * * \retval proto the detected proto or ALPROTO_UNKNOWN if no match */ -static uint16_t AlpProtoMatchSignature(AlpProtoSignature *s, uint8_t *buf, uint16_t buflen) { +static uint16_t AlpProtoMatchSignature(AlpProtoSignature *s, uint8_t *buf, + uint16_t buflen) +{ + SCEnter(); uint16_t proto = ALPROTO_UNKNOWN; - if (s->co->offset > buflen) + if (s->co->offset > buflen) { + SCLogDebug("s->co->offset (%"PRIu16") > buflen (%"PRIu16")", + s->co->offset, buflen); goto end; + } - if (s->co->depth > buflen) + if (s->co->depth > buflen) { + SCLogDebug("s->co->depth (%"PRIu16") > buflen (%"PRIu16")", + s->co->depth, buflen); goto end; + } uint8_t *sbuf = buf + s->co->offset; uint16_t sbuflen = s->co->depth - s->co->offset; + SCLogDebug("s->co->offset (%"PRIu16") s->co->depth (%"PRIu16")", + s->co->offset, s->co->depth); uint8_t *found = SpmSearch(sbuf, sbuflen, s->co->content, s->co->content_len); if (found != NULL) { @@ -165,7 +176,7 @@ static uint16_t AlpProtoMatchSignature(AlpProtoSignature *s, uint8_t *buf, uint1 } end: - return proto; + SCReturnInt(proto); } /** @@ -190,6 +201,8 @@ void AlpProtoAdd(AlpProtoDetectCtx *ctx, uint16_t ip_proto, uint16_t al_proto, c cd->id = DetectContentGetId(ctx->mpm_pattern_id_store, cd); //PrintRawDataFp(stdout,cd->content,cd->content_len); + SCLogDebug("cd->depth %"PRIu16" and cd->offset %"PRIu16" cd->id %"PRIu32"", + cd->depth, cd->offset, cd->id); AlpProtoDetectDirection *dir; if (flags & STREAM_TOCLIENT) { @@ -199,7 +212,7 @@ void AlpProtoAdd(AlpProtoDetectCtx *ctx, uint16_t ip_proto, uint16_t al_proto, c } mpm_table[dir->mpm_ctx.mpm_type].AddPattern(&dir->mpm_ctx, cd->content, cd->content_len, - cd->offset, cd->depth, dir->id, dir->id, 0); + cd->offset, cd->depth, cd->id, cd->id, 0); dir->map[dir->id] = al_proto; dir->id++; @@ -298,10 +311,18 @@ void AlpProtoFinalizeGlobal(AlpProtoDetectCtx *ctx) { memset(ctx->map, 0x00, ctx->sigs * sizeof(AlpProtoSignature *)); AlpProtoSignature *s = ctx->head; + AlpProtoSignature *temp = NULL; for ( ; s != NULL; s = s->next) { BUG_ON(s->co == NULL); - ctx->map[s->co->id] = s; + if (ctx->map[s->co->id] == NULL) { + ctx->map[s->co->id] = s; + } else { + temp = ctx->map[s->co->id]; + while (temp->map_next != NULL) + temp = temp->map_next; + temp->map_next = s; + } } } @@ -332,8 +353,8 @@ void AppLayerDetectProtoThreadInit(void) { AlpProtoAdd(&alp_proto_ctx, IPPROTO_TCP, ALPROTO_SSH, "SSH-", 4, 0, STREAM_TOSERVER); /** SSLv2 */ - AlpProtoAdd(&alp_proto_ctx, IPPROTO_TCP, ALPROTO_SSL, "|01 03 00|", 5, 2, STREAM_TOSERVER); - AlpProtoAdd(&alp_proto_ctx, IPPROTO_TCP, ALPROTO_SSL, "|16 03 00|", 5, 2, STREAM_TOSERVER); + AlpProtoAdd(&alp_proto_ctx, IPPROTO_TCP, ALPROTO_SSL, "|01 00 02|", 5, 2, STREAM_TOSERVER); + AlpProtoAdd(&alp_proto_ctx, IPPROTO_TCP, ALPROTO_SSL, "|00 02|", 7, 5, STREAM_TOCLIENT); /** SSLv3 */ AlpProtoAdd(&alp_proto_ctx, IPPROTO_TCP, ALPROTO_TLS, "|01 03 00|", 3, 0, STREAM_TOSERVER); @@ -467,13 +488,24 @@ uint16_t AppLayerDetectGetProto(AlpProtoDetectCtx *ctx, AlpProtoDetectThreadCtx /* We just work with the first match */ uint16_t patid = tdir->pmq.pattern_id_array[0]; + SCLogDebug("array count is %"PRIu32" patid %"PRIu16"", + tdir->pmq.pattern_id_array_cnt, patid); AlpProtoSignature *s = ctx->map[patid]; if (s == NULL) { goto end; } + uint8_t s_cnt = 1; - proto = AlpProtoMatchSignature(s, buf, buflen); + while (proto == ALPROTO_UNKNOWN && s != NULL) { + proto = AlpProtoMatchSignature(s, buf, buflen); + s = s->map_next; + if (s == NULL && s_cnt < tdir->pmq.pattern_id_array_cnt) { + patid = tdir->pmq.pattern_id_array[s_cnt]; + s = ctx->map[patid]; + s_cnt++; + } + } end: PmqReset(&tdir->pmq); diff --git a/src/app-layer-detect-proto.h b/src/app-layer-detect-proto.h index 35d60400ca..88e70077d3 100644 --- a/src/app-layer-detect-proto.h +++ b/src/app-layer-detect-proto.h @@ -44,6 +44,7 @@ typedef struct AlpProtoSignature_ { uint16_t proto; /**< protocol */ DetectContentData *co; /**< content match that needs to match */ struct AlpProtoSignature_ *next; /**< next signature */ + struct AlpProtoSignature_ *map_next; /**< next signature with same id */ } AlpProtoSignature; #define ALP_DETECT_MAX 256 diff --git a/src/app-layer-ssl.c b/src/app-layer-ssl.c new file mode 100644 index 0000000000..0f77458f64 --- /dev/null +++ b/src/app-layer-ssl.c @@ -0,0 +1,700 @@ +/* Copyright (C) 2007-2010 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 Gurvinder Singh + * + * App-layer detection of SSL2 protocol + * + */ + +#include + +#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-ssl.h" + +#include "util-spm.h" +#include "util-unittest.h" +#include "util-debug.h" +#include "flow-private.h" + +#include "util-byte.h" + +/** + * \brief Function to parse the SSL field in packet received from the client + * + * \param ssl_state Pointer the state in which the value to be stored + * \param pstate Application layer tarser state for this session + * \param input Pointer the received input data + * \param input_len Length in bytes of the received data + * \param output Pointer to the list of parsed output elements + */ +static int SSLParseClientRecord(Flow *f, void *ssl_state, AppLayerParserState *pstate, + uint8_t *input, uint32_t input_len, + AppLayerParserResult *output) +{ + SCEnter(); + SslClient *client = (SslClient *)input; + SslState *ssl_st = (SslState *)ssl_state; + + /* SSL client message should be larger than 5 bytes as we need to know, to + what is the SSL version and message type */ + if (input_len < 5) { + SCLogDebug("Input message lentgh (%"PRIu32") is not equal to minimum " + "valid ssl record message length, thus returning!!", input_len); + SCReturnInt(1); + } + + switch (client->msg_type) { + case SSL_CLIENT_HELLO: + if (client->major_ver != 0x02) { + SCLogError(SC_ERR_ALPARSER, "SSL version is not equal to 2, " + "incorrect message!!"); + SCReturnInt(-1); + } + + ssl_st->flags |= SSL_FLAG_CLIENT_HS; + ssl_st->client_content_type = client->msg_type; + ssl_st->client_version = client->minor_ver|client->major_ver; + if (client->session_id_len == 0) { + ssl_st->flags |= SSL_FLAG_NO_SESSION_ID; + } + SCLogDebug("SSLv2 CLIENT_HELLO message has been received"); + + break; + case SSL_CLIENT_MASTER_KEY: + if ( ! (ssl_st->flags & SSL_FLAG_CLIENT_HS)) { + SCLogDebug("client hello is not seen before master key " + "message!!"); + break; + } + ssl_st->flags |= SSL_FLAG_CLIENT_MASTER_KEY; + ssl_st->client_content_type = client->msg_type; + SCLogDebug("SSLv2 CLIENT_MASTER_KEY message has been received"); + + break; + case SSL_CLIENT_CERTIFICATE: + case SSL_CLIENT_FINISHED: + case SSL_REQUEST_CERTIFICATE: + if ((ssl_st->flags & SSL_FLAG_CLIENT_HS) && + (ssl_st->flags & SSL_FLAG_SERVER_HS)) + { + if (ssl_st->flags & SSL_FLAG_NO_SESSION_ID) { + ssl_st->flags |= SSL_FLAG_CLIENT_SSN_ENCRYPTED; + SCLogDebug("SSLv2 Client side has started the encryption"); + } else if (ssl_st->flags & SSL_FLAG_CLIENT_MASTER_KEY) { + ssl_st->flags |= SSL_FLAG_CLIENT_SSN_ENCRYPTED; + SCLogDebug("SSLv2 Client side has started the encryption"); + } + + if ((ssl_st->flags & SSL_FLAG_CLIENT_SSN_ENCRYPTED) && + (ssl_st->flags & SSL_FLAG_SERVER_SSN_ENCRYPTED)) + { + pstate->flags |= APP_LAYER_PARSER_DONE; + pstate->flags |= APP_LAYER_PARSER_NO_INSPECTION; + pstate->flags |= APP_LAYER_PARSER_NO_REASSEMBLY; + SCLogDebug("SSLv2 No reassembly & inspection has been set"); + } + } + ssl_st->client_content_type = client->msg_type; + + break; + case SSL_ERROR: + SCLogError(SC_ERR_ALPARSER, "Error encountered in establishing the " + "sslv2 session"); + SCReturnInt(-1); + default: + SCLogError(SC_ERR_ALPARSER, "Incorrect message type (%"PRIu8") " + "while establishing the sslv2 session", client->msg_type); + break; + } + SCReturnInt(1); +} + +/** + * \brief Function to parse the SSL field in packet received from the server + * + * \param ssl_state Pointer the state in which the value to be stored + * \param pstate Application layer tarser state for this session + * \param input Pointer the received input data + * \param input_len Length in bytes of the received data + * \param output Pointer to the list of parsed output elements + */ +static int SSLParseServerRecord(Flow *f, void *ssl_state, AppLayerParserState *pstate, + uint8_t *input, uint32_t input_len, + AppLayerParserResult *output) +{ + SCEnter(); + SCEnter(); + SslServer *server = (SslServer *)input; + SslState *ssl_st = (SslState *)ssl_state; + + if (input_len < 7) { + SCLogDebug("Input message lentgh (%"PRIu32") is not equal to minimum " + "valid ssl record message length, thus returning!!", input_len); + SCReturnInt(1); + } + + switch (server->msg_type) { + case SSL_SERVER_HELLO: + if (server->major_ver != 0x02) { + SCLogError(SC_ERR_ALPARSER, "SSL version is not equal to 2, " + "incorrect message!!"); + SCReturnInt(-1); + } + SCLogDebug("SSLv2 SERVER_HELLO message has been received"); + + ssl_st->flags |= SSL_FLAG_SERVER_HS; + ssl_st->server_content_type = server->msg_type; + ssl_st->server_version = server->minor_ver|server->major_ver; + break; + case SSL_SERVER_VERIFY: + case SSL_SERVER_FINISHED: + case SSL_REQUEST_CERTIFICATE: + if ((ssl_st->flags & SSL_FLAG_SERVER_HS) && + (ssl_st->flags & SSL_FLAG_CLIENT_HS)) + { + ssl_st->flags |= SSL_FLAG_SERVER_SSN_ENCRYPTED; + SCLogDebug("SSLv2 Server side has started the encryption"); + + if ((ssl_st->flags & SSL_FLAG_CLIENT_SSN_ENCRYPTED) && + (ssl_st->flags & SSL_FLAG_SERVER_SSN_ENCRYPTED)) + { + pstate->flags |= APP_LAYER_PARSER_DONE; + pstate->flags |= APP_LAYER_PARSER_NO_INSPECTION; + pstate->flags |= APP_LAYER_PARSER_NO_REASSEMBLY; + SCLogDebug("SSLv2 No reassembly & inspection has been set"); + } + } + ssl_st->server_content_type = server->msg_type; + + break; + case SSL_ERROR: + SCLogError(SC_ERR_ALPARSER, "Error encountered in establishing the " + "sslv2 session"); + SCReturnInt(-1); + default: + SCLogError(SC_ERR_ALPARSER, "Incorrect message type (%"PRIu8") " + "while establishing the sslv2 session", server->msg_type); + break; + } + SCReturnInt(1); +} + +/** \brief Function to allocates the TLS state memory + */ +static void *SSLStateAlloc(void) +{ + SCEnter(); + void *s = SCMalloc(sizeof(SslState)); + if (s == NULL) + return NULL; + + memset(s, 0, sizeof(SslState)); + SCReturnPtr(s, "SslState"); +} + +/** \brief Function to free the TLS state memory + */ +static void SSLStateFree(void *s) +{ + SCEnter(); + SCFree(s); + SCReturn; +} + +/** \brief Function to register the SSL protocol parsers and other functions + */ +void RegisterSSLParsers(void) +{ + AppLayerRegisterProto("ssl", ALPROTO_SSL, STREAM_TOSERVER, + SSLParseClientRecord); + + AppLayerRegisterProto("ssl", ALPROTO_SSL, STREAM_TOCLIENT, + SSLParseServerRecord); + + AppLayerRegisterStateFuncs(ALPROTO_SSL, SSLStateAlloc, SSLStateFree); + +} + +//#ifdef UNITTESTS +#include "util-unittest-helper.h" +#include "stream-tcp-reassemble.h" +#include "decode-tcp.h" + +extern uint16_t AppLayerParserGetStorageId (void); + +static int SSLParserTest01(void) { + int result = 1; + Flow f; + uint8_t sslbuf[] = {0x80, 0x31, 0x01, 0x00, 0x02 }; + uint32_t ssllen = sizeof(sslbuf); + TcpSession ssn; + + memset(&f, 0, sizeof(f)); + memset(&ssn, 0, sizeof(ssn)); + f.protoctx = (void *)&ssn; + + StreamTcpInitConfig(TRUE); + StreamL7DataPtrInit(&ssn); + + int r = AppLayerParse(&f, ALPROTO_SSL, STREAM_TOSERVER|STREAM_EOF, sslbuf, ssllen); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); + result = 0; + goto end; + } + + SslState *ssl_state = ssn.aldata[AlpGetStateIdx(ALPROTO_SSL)]; + if (ssl_state == NULL) { + printf("no ssl state: "); + result = 0; + goto end; + } + + if (ssl_state->client_content_type != 0x1) { + printf("expected content_type %" PRIu8 ", got %" PRIu8 ": ", 0x1, + ssl_state->client_content_type); + result = 0; + goto end; + } + + if (ssl_state->client_version != SSL_CLIENT_VERSION) { + printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ", + SSL_CLIENT_VERSION, ssl_state->client_version); + result = 0; + goto end; + } +end: + StreamL7DataPtrFree(&ssn); + StreamTcpFreeConfig(TRUE); + return result; +} + +static int SSLParserTest02(void) { + int result = 1; + Flow f; + uint8_t sslbuf[] = {0x80, 0x31, 0x04, 0x00, 0x01, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x10, 0x07, 0x00, 0xc0, + 0x05, 0x00, 0x80, 0x03, 0x00, 0x80, 0x01, 0x00, + 0x80, 0x08, 0x00, 0x80, 0x06, 0x00, 0x40, 0x04, + 0x00, 0x80, 0x02, 0x00, 0x80, 0x76, 0x64, 0x75, + 0x2d, 0xa7, 0x98, 0xfe, 0xc9, 0x12, 0x92, 0xc1, + 0x2f, 0x34, 0x84, 0x20, 0xc5}; + uint32_t ssllen = sizeof(sslbuf); + TcpSession ssn; + + memset(&f, 0, sizeof(f)); + memset(&ssn, 0, sizeof(ssn)); + f.protoctx = (void *)&ssn; + + StreamTcpInitConfig(TRUE); + StreamL7DataPtrInit(&ssn); + + int r = AppLayerParse(&f, ALPROTO_SSL, STREAM_TOCLIENT|STREAM_EOF, sslbuf, ssllen); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); + result = 0; + goto end; + } + + SslState *ssl_state = ssn.aldata[AlpGetStateIdx(ALPROTO_SSL)]; + if (ssl_state == NULL) { + printf("no ssl state: "); + result = 0; + goto end; + } + + if (ssl_state->server_content_type != SSL_SERVER_HELLO) { + printf("expected content_type %" PRIu8 ", got %" PRIu8 ": ", + SSL_SERVER_HELLO, ssl_state->client_content_type); + result = 0; + goto end; + } + + if (ssl_state->server_version != SSL_SERVER_VERSION) { + printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ", + SSL_SERVER_VERSION, ssl_state->client_version); + result = 0; + goto end; + } +end: + StreamL7DataPtrFree(&ssn); + StreamTcpFreeConfig(TRUE); + return result; +} + +static int SSLParserTest03(void) { + int result = 1; + Flow f; + uint8_t payload1[] = { 0x80, 0x31, 0x01, 0x00, 0x02, 0x00, + 0x18, 0x00, 0x00, 0x00, 0x10, 0x07, 0x00, 0xc0, + 0x05, 0x00, 0x80, 0x03, 0x00, 0x80, 0x01, 0x00, + 0x80, 0x08, 0x00, 0x80, 0x06, 0x00, 0x40, 0x04, + 0x00, 0x80, 0x02, 0x00, 0x80, 0x76, 0x64, 0x75, + 0x2d, 0xa7, 0x98, 0xfe, 0xc9, 0x12, 0x92, 0xc1, + 0x2f, 0x34, 0x84, 0x20, 0xc5 }; + uint32_t payload_len1 = sizeof(payload1); + uint8_t payload2[] = { 0x83, 0xbb, 0x04, 0x00, 0x01, 0x00, + 0x02, 0x03, 0x8b, 0x00, 0x15, 0x00, 0x10, 0x30, + 0x82, 0x03, 0x87, 0x30, 0x82, 0x02, 0xf0, 0xa0, + 0x03, 0x02, 0x01, 0x02, 0x02, 0x01, 0x01, 0x30, + 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x01, 0x04, 0x05, 0x00, 0x30, 0x78, + 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, + 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, + 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, + 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, + 0x69, 0x61, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, + 0x55, 0x04, 0x07, 0x13, 0x09, 0x53, 0x75, 0x6e, + 0x6e, 0x79, 0x76, 0x61, 0x6c, 0x65, 0x31, 0x19, + 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, + 0x10, 0x4d, 0x75, 0x53, 0x65, 0x63, 0x75, 0x72, + 0x69, 0x74, 0x79, 0x2c, 0x20, 0x49, 0x6e, 0x63, + 0x2e, 0x31, 0x25, 0x30, 0x23, 0x06, 0x09, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, + 0x16, 0x16, 0x61, 0x74, 0x75, 0x72, 0x6e, 0x65, + 0x72, 0x40, 0x6d, 0x75, 0x73, 0x65, 0x63, 0x75, + 0x72, 0x69, 0x74, 0x79, 0x2e, 0x63, 0x6f, 0x6d, + 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x35, 0x30, 0x36, + 0x30, 0x36, 0x32, 0x33, 0x32, 0x38, 0x35, 0x38, + 0x5a, 0x17, 0x0d, 0x31, 0x33, 0x31, 0x30, 0x32, + 0x37, 0x32, 0x33, 0x32, 0x38, 0x35, 0x38, 0x5a, + 0x30, 0x81, 0x96, 0x31, 0x0b, 0x30, 0x09, 0x06, + 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, + 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x0a, 0x43, 0x61, 0x6c, 0x69, 0x66, + 0x6f, 0x72, 0x6e, 0x69, 0x61, 0x31, 0x12, 0x30, + 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x09, + 0x53, 0x75, 0x6e, 0x6e, 0x79, 0x76, 0x61, 0x6c, + 0x65, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, + 0x04, 0x0a, 0x13, 0x10, 0x4d, 0x75, 0x53, 0x65, + 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x2c, 0x20, + 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x1c, 0x30, 0x1a, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x13, 0x73, + 0x74, 0x61, 0x6e, 0x2e, 0x6d, 0x75, 0x73, 0x65, + 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x2e, 0x63, + 0x6f, 0x6d, 0x31, 0x25, 0x30, 0x23, 0x06, 0x09, + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, + 0x01, 0x16, 0x16, 0x61, 0x74, 0x75, 0x72, 0x6e, + 0x65, 0x72, 0x40, 0x6d, 0x75, 0x73, 0x65, 0x63, + 0x75, 0x72, 0x69, 0x74, 0x79, 0x2e, 0x63, 0x6f, + 0x6d, 0x30, 0x81, 0x9f, 0x30, 0x0d, 0x06, 0x09, + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, + 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, 0x30, + 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xb4, 0xe7, + 0x9b, 0x0a, 0xe8, 0xbb, 0xec, 0x4b, 0x1e, 0x5a, + 0x37, 0x95, 0xa5, 0x18, 0x7d, 0xad, 0xa5, 0xbd, + 0xa3, 0x6b, 0x5c, 0xd1, 0x51, 0xce, 0x38, 0xf3, + 0x81, 0xb3, 0x85, 0x0e, 0xfe, 0x17, 0xef, 0x87, + 0xcb, 0x7f, 0xc7, 0x92, 0xeb, 0xa0, 0x89, 0x76, + 0x8b, 0xa3, 0x25, 0xb8, 0x20, 0xeb, 0xd8, 0x4a, + 0xa9, 0xb0, 0x3b, 0x08, 0x81, 0xc1, 0x8e, 0x3c, + 0x8f, 0x63, 0x8a, 0x47, 0xb5, 0x7f, 0x27, 0x4c, + 0x21, 0x2f, 0x86, 0xd3, 0x66, 0x0a, 0x97, 0x2a, + 0xe5, 0x9c, 0xd7, 0xa2, 0x5d, 0xb4, 0xce, 0xbc, + 0x4e, 0x28, 0xdc, 0x25, 0x6b, 0x2e, 0x39, 0xf5, + 0xbc, 0x98, 0x1b, 0x4c, 0x7c, 0x77, 0xa1, 0x61, + 0x52, 0xfd, 0x95, 0x49, 0x70, 0xf8, 0x94, 0xfb, + 0xa4, 0x11, 0x8a, 0x81, 0xa8, 0xd3, 0x26, 0x51, + 0x40, 0x01, 0xb0, 0x70, 0x45, 0xd5, 0xe4, 0xc5, + 0x49, 0x33, 0xb3, 0xed, 0xd8, 0xe7, 0x02, 0x03, + 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x00, 0x30, + 0x81, 0xfd, 0x30, 0x09, 0x06, 0x03, 0x55, 0x1d, + 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x2c, 0x06, + 0x09, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, + 0x01, 0x0d, 0x04, 0x1f, 0x16, 0x1d, 0x4f, 0x70, + 0x65, 0x6e, 0x53, 0x53, 0x4c, 0x20, 0x47, 0x65, + 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x20, + 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, + 0x61, 0x74, 0x65, 0x30, 0x1d, 0x06, 0x03, 0x55, + 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xbe, 0x59, + 0x54, 0xcf, 0x22, 0xe1, 0x74, 0xec, 0xe1, 0x8e, + 0x5c, 0x06, 0x2b, 0xf7, 0x1a, 0x7a, 0x6a, 0x50, + 0x67, 0x68, 0x30, 0x81, 0xa2, 0x06, 0x03, 0x55, + 0x1d, 0x23, 0x04, 0x81, 0x9a, 0x30, 0x81, 0x97, + 0x80, 0x14, 0x7d, 0x02, 0x2d, 0x18, 0xe0, 0xe3, + 0x76, 0x45, 0x4b, 0x2e, 0x08, 0x0a, 0xd3, 0xe5, + 0xd4, 0x92, 0x22, 0x71, 0xa4, 0xde, 0xa1, 0x7c, + 0xa4, 0x7a, 0x30, 0x78, 0x31, 0x0b, 0x30, 0x09, + 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, + 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, + 0x04, 0x08, 0x13, 0x0a, 0x43, 0x61, 0x6c, 0x69, + 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61, 0x31, 0x12, + 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, + 0x09, 0x53, 0x75, 0x6e, 0x6e, 0x79, 0x76, 0x61, + 0x6c, 0x65, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, + 0x55, 0x04, 0x0a, 0x13, 0x10, 0x4d, 0x75, 0x53, + 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x2c, + 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x25, 0x30, + 0x23, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x09, 0x01, 0x16, 0x16, 0x61, 0x74, + 0x75, 0x72, 0x6e, 0x65, 0x72, 0x40, 0x6d, 0x75, + 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, + 0x2e, 0x63, 0x6f, 0x6d, 0x82, 0x01, 0x00, 0x30, + 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x01, 0x04, 0x05, 0x00, 0x03, 0x81, + 0x81, 0x00, 0x4a, 0x5a, 0xd9, 0xd4, 0xe1, 0xe9, + 0xdd, 0xd5, 0x5c, 0xd3, 0x27, 0x2b, 0x01, 0x95, + 0x1b, 0x8c, 0xa9, 0x9c, 0x93, 0x8e, 0x01, 0x72, + 0xbf, 0xbc, 0x74, 0xbb, 0x30, 0x61, 0xa0, 0x52, + 0xfb, 0xe0, 0xa8, 0x8e, 0x2b, 0x34, 0xe8, 0xf3, + 0x4a, 0xfc, 0xc0, 0xb4, 0x63, 0x83, 0xa8, 0xb4, + 0x5e, 0xb9, 0xe4, 0x21, 0x2f, 0x6b, 0x04, 0x84, + 0x14, 0x98, 0xf0, 0xde, 0x18, 0xd0, 0xa7, 0x9a, + 0x0d, 0x6a, 0xd5, 0xa9, 0x44, 0x57, 0xf9, 0xb4, + 0xdb, 0x59, 0x56, 0x3e, 0x26, 0x49, 0x98, 0xf3, + 0x39, 0x8b, 0x8a, 0x66, 0xd2, 0xcb, 0xa9, 0x48, + 0xda, 0x71, 0xc7, 0x53, 0x28, 0x15, 0xc4, 0xc3, + 0x4c, 0xbb, 0xab, 0xc1, 0x69, 0xfb, 0x37, 0xfa, + 0x99, 0x2b, 0x2b, 0xfa, 0x9d, 0x33, 0xaa, 0x17, + 0xb2, 0xb1, 0x78, 0x9e, 0xa5, 0x50, 0x0a, 0x7c, + 0x4f, 0x8f, 0x4a, 0x93, 0xc2, 0x36, 0x55, 0x2e, + 0x17, 0x98, 0x07, 0x00, 0xc0, 0x03, 0x00, 0x80, + 0x01, 0x00, 0x80, 0x08, 0x00, 0x80, 0x06, 0x00, + 0x40, 0x04, 0x00, 0x80, 0x02, 0x00, 0x80, 0x57, + 0xbe, 0x5d, 0x5d, 0x97, 0xad, 0x58, 0x25, 0xf1, + 0x78, 0xeb, 0x27, 0xba, 0x45, 0xe8, 0x44 }; + uint32_t payload_len2 = sizeof(payload2); + uint8_t payload3[] = { 0x80, 0x92, 0x02, 0x07, 0x00, 0xc0, + 0x00, 0x00, 0x00, 0x80, 0x00, 0x08, 0x98, 0xb7, + 0xaf, 0x94, 0x0a, 0x00, 0x0c, 0x02, 0xb1, 0x4d, + 0x50, 0x50, 0x17, 0x78, 0x16, 0xba, 0x22, 0x7b, + 0x25, 0xab, 0x09, 0x9f, 0x30, 0xd6, 0xce, 0xa8, + 0xf6, 0x04, 0x41, 0xb3, 0xa4, 0x16, 0x33, 0x18, + 0x7b, 0x24, 0xa6, 0x30, 0x75, 0x67, 0x7a, 0xa7, + 0xac, 0xd2, 0xc2, 0xe3, 0x00, 0x13, 0xb0, 0x39, + 0xb0, 0x50, 0x2b, 0x55, 0x93, 0xd7, 0x65, 0x1f, + 0x00, 0x4f, 0xde, 0x15, 0xee, 0xa8, 0x9c, 0xbd, + 0x86, 0xaf, 0x99, 0x7a, 0x27, 0x53, 0xb3, 0x5a, + 0x4b, 0x90, 0xbd, 0xac, 0xc9, 0xd3, 0xc5, 0x31, + 0x06, 0x19, 0xd8, 0x2f, 0x6b, 0x3a, 0x31, 0xb4, + 0x34, 0xb8, 0x31, 0xec, 0x18, 0x6c, 0xad, 0x9e, + 0xa8, 0xf5, 0x3a, 0x9d, 0xd3, 0x74, 0x78, 0x33, + 0x06, 0x8b, 0x75, 0xc9, 0x39, 0xe8, 0x59, 0x98, + 0xc9, 0x96, 0xca, 0xc0, 0x2f, 0x1c, 0x53, 0xda, + 0x76, 0xab, 0xf1, 0x42, 0x6c, 0x71, 0xaf, 0xc9, + 0x52, 0xbe, 0xb0, 0x7a, 0x7d, 0xe1 }; + uint32_t payload_len3 = sizeof(payload3); + uint8_t payload4[] = { 0x00, 0x28, 0x07, 0xb8, 0xbb, 0x2c, + 0xce, 0xbe, 0x72, 0xa9, 0x61, 0xef, 0xbf, 0xfa, + 0x50, 0x92, 0x6d, 0x62, 0x77, 0xa3, 0x7b, 0x75, + 0xd6, 0x6e, 0x82, 0x12, 0x27, 0x87, 0x23, 0xce, + 0x9d, 0x44, 0xfe, 0x1f, 0xd0, 0x0e, 0x62, 0xff, + 0xd0, 0x24, 0xea, 0xc0, 0x18 }; + uint32_t payload_len4 = sizeof(payload4); + uint8_t payload5[] = { 0x00, 0x28, 0x07, 0x9a, 0x1d, 0xe2, + 0x5f, 0x79, 0xcc, 0x14, 0x5b, 0xb5, 0xad, 0x4f, + 0x15, 0x86, 0xe6, 0x03, 0x13, 0xe0, 0x96, 0x96, + 0x85, 0x46, 0x79, 0x0e, 0x3a, 0xe2, 0x84, 0x8d, + 0x8d, 0x88, 0xba, 0x7c, 0x6d, 0xa4, 0xb9, 0x9a, + 0xb1, 0x9f, 0x78, 0xe4, 0x83 }; + uint32_t payload_len5 = sizeof(payload5); + TcpSession ssn; + TCPHdr tcph; + Packet *p1 = UTHBuildPacket(payload1, payload_len1, IPPROTO_TCP); + Packet *p2 = UTHBuildPacket(payload2, payload_len2, IPPROTO_TCP); + Packet *p3 = UTHBuildPacket(payload3, payload_len3, IPPROTO_TCP); + Packet *p4 = UTHBuildPacket(payload4, payload_len4, IPPROTO_TCP); + Packet *p5 = UTHBuildPacket(payload5, payload_len5, IPPROTO_TCP); + + memset(&f, 0, sizeof(f)); + memset(&ssn, 0, sizeof(ssn)); + memset(&tcph, 0, sizeof(tcph)); + + StreamTcpInitConfig(TRUE); + TcpReassemblyThreadCtx *ra_ctx = StreamTcpReassembleInitThreadCtx(); + AppLayerDetectProtoThreadInit(); + + ssn.server.ra_base_seq = 390131220UL; + ssn.server.isn = 390131220UL; + ssn.server.last_ack = 427643676UL; + ssn.client.ra_base_seq = 4276431676UL; + ssn.client.isn = 4276431676UL; + ssn.client.last_ack = 390133221UL; + ssn.alproto = ALPROTO_UNKNOWN; + + f.protoctx = (void *)&ssn; + + tcph.th_win = htons(5480); + tcph.th_seq = htonl(4276431677UL); + tcph.th_ack = htonl(390131221UL); + tcph.th_flags = TH_ACK|TH_PUSH; + p1->tcph = &tcph; + p1->flowflags = FLOW_PKT_TOSERVER; + ssn.state = TCP_ESTABLISHED; + + TcpStream *s = NULL; + s = &ssn.client; + + if (StreamTcpReassembleHandleSegment(ra_ctx, &ssn, s, p1) == -1) { + printf("failed in segments reassembly, while processing toserver packet\n"); + goto end; + } + + p2->flowflags = FLOW_PKT_TOCLIENT; + tcph.th_seq = htonl(390131221UL); + tcph.th_ack = htonl(4276431728UL); + p2->tcph = &tcph; + p2->flow = &f; + s = &ssn.server; + + if (StreamTcpReassembleHandleSegment(ra_ctx, &ssn, s, p2) == -1) { + printf("failed in segments reassembly, while processing toserver packet\n"); + goto end; + } + + if (StreamTcpReassembleProcessAppLayer(ra_ctx) < 0) { + printf("failed in processing stream smsgs\n"); + goto end; + } + + p3->flowflags = FLOW_PKT_TOSERVER; + tcph.th_seq = htonl(4276431728UL); + tcph.th_ack = htonl(390132178UL); + p3->tcph = &tcph; + p3->flow = &f; + s = &ssn.client; + + if (StreamTcpReassembleHandleSegment(ra_ctx, &ssn, s, p3) == -1) { + printf("failed in segments reassembly, while processing toserver packet\n"); + goto end; + } + + if (StreamTcpReassembleProcessAppLayer(ra_ctx) < 0) { + printf("failed in processing stream smsgs\n"); + goto end; + } + + p4->flowflags = FLOW_PKT_TOCLIENT; + tcph.th_seq = htonl(390132178UL); + tcph.th_ack = htonl(4276431876UL); + p4->tcph = &tcph; + p4->flow = &f; + s = &ssn.server; + + if (StreamTcpReassembleHandleSegment(ra_ctx, &ssn, s, p4) == -1) { + printf("failed in segments reassembly, while processing toserver packet\n"); + goto end; + } + + if (StreamTcpReassembleProcessAppLayer(ra_ctx) < 0) { + printf("failed in processing stream smsgs\n"); + goto end; + } + + p5->flowflags = FLOW_PKT_TOSERVER; + tcph.th_seq = htonl(4276431876UL); + tcph.th_ack = htonl(390132221UL); + p5->tcph = &tcph; + p5->flow = &f; + s = &ssn.client; + + if (StreamTcpReassembleHandleSegment(ra_ctx, &ssn, s, p5) == -1) { + printf("failed in segments reassembly, while processing toserver packet\n"); + goto end; + } + + if (StreamTcpReassembleProcessAppLayer(ra_ctx) < 0) { + printf("failed in processing stream smsgs\n"); + goto end; + } + + tcph.th_seq = htonl(390132221UL); + tcph.th_ack = htonl(4276431919UL); + s = &ssn.server; + + if (StreamTcpReassembleHandleSegment(ra_ctx, &ssn, s, p4) == -1) { + printf("failed in segments reassembly, while processing toserver packet\n"); + goto end; + } + + if (StreamTcpReassembleProcessAppLayer(ra_ctx) < 0) { + printf("failed in processing stream smsgs\n"); + goto end; + } + + SslState *ssl_state = ssn.aldata[AlpGetStateIdx(ALPROTO_SSL)]; + if (ssl_state == NULL) { + printf("no ssl state: "); + result = 0; + goto end; + } + + if (ssl_state->client_content_type != 0x7) { + printf("expected content_type %" PRIu8 ", got %" PRIu8 ": ", 0x7, + ssl_state->client_content_type); + result = 0; + goto end; + } + + if (ssl_state->client_version != SSL_CLIENT_VERSION) { + printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ", + SSL_CLIENT_VERSION, ssl_state->client_version); + result = 0; + goto end; + } + + uint16_t app_layer_sid = AppLayerParserGetStorageId(); + AppLayerParserStateStore *parser_state_store = (AppLayerParserStateStore *) + ssn.aldata[app_layer_sid]; + AppLayerParserState *parser_state = &parser_state_store->to_server; + + if (!(parser_state->flags & APP_LAYER_PARSER_NO_INSPECTION) && + !(ssn.flags & STREAMTCP_FLAG_NOCLIENT_REASSEMBLY) && + !(ssn.flags & STREAMTCP_FLAG_NOSERVER_REASSEMBLY)) { + printf("The flags should be set\n"); + result = 0; + goto end; + } + + if (!(f.flags & FLOW_NOPAYLOAD_INSPECTION)) { + printf("The flags should be set\n"); + result = 0; + goto end; + } +end: + StreamL7DataPtrFree(&ssn); + StreamTcpFreeConfig(TRUE); + return result; +} +//#endif /* UNITTESTS */ + +void SSLParserRegisterTests(void) { +#ifdef UNITTESTS + UtRegisterTest("SSLParserTest01", SSLParserTest01, 1); + UtRegisterTest("SSLParserTest02", SSLParserTest02, 1); + UtRegisterTest("SSLParserTest03", SSLParserTest03, 1); +#endif /* UNITTESTS */ +} diff --git a/src/app-layer-ssl.h b/src/app-layer-ssl.h new file mode 100644 index 0000000000..b9dcaf1c7c --- /dev/null +++ b/src/app-layer-ssl.h @@ -0,0 +1,83 @@ +/* Copyright (C) 2007-2010 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 Gurvinder Singh + */ + +#ifndef _APP_LAYER_SSL_H +#define _APP_LAYER_SSL_H + +#define SSL_CLIENT_VERSION 0x0002 +#define SSL_SERVER_VERSION 0x0002 + +/* SSL state flags */ +#define SSL_FLAG_CLIENT_HS 0x01 +#define SSL_FLAG_SERVER_HS 0x02 +#define SSL_FLAG_CLIENT_MASTER_KEY 0x04 +#define SSL_FLAG_CLIENT_SSN_ENCRYPTED 0x08 +#define SSL_FLAG_SERVER_SSN_ENCRYPTED 0x10 +#define SSL_FLAG_NO_SESSION_ID 0x20 + +/* SSL message types */ +#define SSL_ERROR 0 +#define SSL_CLIENT_HELLO 1 +#define SSL_CLIENT_MASTER_KEY 2 +#define SSL_CLIENT_FINISHED 3 +#define SSL_SERVER_HELLO 4 +#define SSL_SERVER_VERIFY 5 +#define SSL_SERVER_FINISHED 6 +#define SSL_REQUEST_CERTIFICATE 7 +#define SSL_CLIENT_CERTIFICATE 8 + +/* structure to store the SSL state values */ +typedef struct SslState_ { + uint8_t client_content_type; /**< Client content type storage field */ + uint16_t client_version; /**< Client SSL version storage field */ + + uint8_t server_content_type; /**< Server content type storage field */ + uint16_t server_version; /**< Server SSL version storage field */ + + uint8_t flags; /**< Flags to indicate the current SSL + sessoin state */ +} SslState; + +typedef struct SslClient_ { + uint16_t length; /**< Length of the received message */ + uint8_t msg_type; + uint8_t minor_ver; + uint8_t major_ver; + uint16_t cipher_spec_len; + uint16_t session_id_len; +} SslClient; + +typedef struct SslServer_ { + uint16_t lentgth; + uint8_t msg_type; + uint8_t session_id; + uint8_t cert; + uint8_t minor_ver; + uint8_t major_ver; +} SslServer; + +void RegisterSSLParsers(void); +void SSLParserRegisterTests(void); + +#endif /* _APP_LAYER_SSL_H */ + diff --git a/src/app-layer-tls.c b/src/app-layer-tls.c index 21fa9c12de..8731734820 100644 --- a/src/app-layer-tls.c +++ b/src/app-layer-tls.c @@ -45,8 +45,6 @@ #include "conf.h" -#include "app-layer-tls.h" - #include "util-spm.h" #include "util-unittest.h" #include "util-debug.h" @@ -145,6 +143,9 @@ static int TLSParseClientVersion(Flow *f, void *tls_state, AppLayerParserState * u16conv = (struct u16conv_ *)input; switch (ntohs(u16conv->u)) { + case 0x0300: + state->client_version = SSL_VERSION_3; + break; case 0x0301: state->client_version = TLS_VERSION_10; break; @@ -434,7 +435,20 @@ static int TLSParseServerVersion(Flow *f, void *tls_state, AppLayerParserState * } *u16conv; u16conv = (struct u16conv_ *)input; - state->server_version = ntohs(u16conv->u); + switch (ntohs(u16conv->u)) { + case 0x0300: + state->server_version = SSL_VERSION_3; + break; + case 0x0301: + state->server_version = TLS_VERSION_10; + break; + case 0x0302: + state->server_version = TLS_VERSION_11; + break; + case 0x0303: + state->server_version = TLS_VERSION_12; + break; + } SCLogDebug("version %04"PRIx16"", state->server_version); SCReturnInt(0); @@ -1174,6 +1188,174 @@ end: return result; } +/** + * \test Test the detection of SSLv3 protocol from the given packet + */ +static int TLSParserTest07(void) { + int result = 1; + Flow f; + uint8_t tlsbuf[] = { 0x16, 0x03, 0x00, 0x00, 0x6f, 0x01, + 0x00, 0x00, 0x6b, 0x03, 0x00, 0x4b, 0x2f, 0xdc, + 0x4e, 0xe6, 0x95, 0xf1, 0xa0, 0xc7, 0xcf, 0x8e, + 0xf6, 0xeb, 0x22, 0x6d, 0xce, 0x9c, 0x44, 0xfb, + 0xc8, 0xa0, 0x44, 0x31, 0x15, 0x4c, 0xe9, 0x97, + 0xa7, 0xa1, 0xfe, 0xea, 0xcc, 0x20, 0x4b, 0x5d, + 0xfb, 0xa5, 0x63, 0x7a, 0x73, 0x95, 0xf7, 0xff, + 0x42, 0xac, 0x8f, 0x46, 0xed, 0xe4, 0xb1, 0x35, + 0x35, 0x78, 0x1a, 0x9d, 0xaf, 0x10, 0xc5, 0x52, + 0xf3, 0x7b, 0xfb, 0xb5, 0xe9, 0xa8, 0x00, 0x24, + 0x00, 0x88, 0x00, 0x87, 0x00, 0x39, 0x00, 0x38, + 0x00, 0x84, 0x00, 0x35, 0x00, 0x45, 0x00, 0x44, + 0x00, 0x33, 0x00, 0x32, 0x00, 0x96, 0x00, 0x41, + 0x00, 0x2f, 0x00, 0x16, 0x00, 0x13, 0xfe, 0xff, + 0x00, 0x0a, 0x00, 0x02, 0x01, 0x00 }; + uint32_t tlslen = sizeof(tlsbuf); + TcpSession ssn; + + memset(&f, 0, sizeof(f)); + memset(&ssn, 0, sizeof(ssn)); + f.protoctx = (void *)&ssn; + + StreamTcpInitConfig(TRUE); + StreamL7DataPtrInit(&ssn); + + int r = AppLayerParse(&f, ALPROTO_TLS, STREAM_TOSERVER, tlsbuf, tlslen); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); + result = 0; + goto end; + } + + TlsState *tls_state = ssn.aldata[AlpGetStateIdx(ALPROTO_TLS)]; + if (tls_state == NULL) { + printf("no tls state: "); + result = 0; + goto end; + } + + if (tls_state->client_content_type != 0x16) { + printf("expected content_type %" PRIu8 ", got %" PRIu8 ": ", 0x17, + tls_state->client_content_type); + result = 0; + goto end; + } + + if (tls_state->client_version != SSL_VERSION_3) { + printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ", + SSL_VERSION_3, tls_state->client_version); + result = 0; + goto end; + } + +end: + StreamL7DataPtrFree(&ssn); + StreamTcpFreeConfig(TRUE); + return result; +} + +/** \test Test the setting up of no reassembly and no payload inspection flag + * after detection of the SSLv3 handshake completion */ +static int TLSParserTest08(void) { + int result = 1; + Flow f; + uint8_t tlsbuf[] = { 0x16, 0x03, 0x00, 0x00, 0x01 }; + uint32_t tlslen = sizeof(tlsbuf); + TcpSession ssn; + + memset(&f, 0, sizeof(f)); + memset(&ssn, 0, sizeof(ssn)); + f.protoctx = (void *)&ssn; + + StreamTcpInitConfig(TRUE); + StreamL7DataPtrInit(&ssn); + + int r = AppLayerParse(&f, ALPROTO_TLS, STREAM_TOSERVER, tlsbuf, tlslen); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); + result = 0; + goto end; + } + + r = AppLayerParse(&f, ALPROTO_TLS, STREAM_TOCLIENT, tlsbuf, tlslen); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); + result = 0; + goto end; + } + + tlsbuf[0] = 0x14; + + r = AppLayerParse(&f, ALPROTO_TLS, STREAM_TOSERVER, tlsbuf, tlslen); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); + result = 0; + goto end; + } + + tlsbuf[0] = 0x14; + + r = AppLayerParse(&f, ALPROTO_TLS, STREAM_TOCLIENT, tlsbuf, tlslen); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); + result = 0; + goto end; + } + + tlsbuf[0] = 0x17; + + r = AppLayerParse(&f, ALPROTO_TLS, STREAM_TOSERVER, tlsbuf, tlslen); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); + result = 0; + goto end; + } + + TlsState *tls_state = ssn.aldata[AlpGetStateIdx(ALPROTO_TLS)]; + if (tls_state == NULL) { + printf("no tls state: "); + result = 0; + goto end; + } + + if (tls_state->client_content_type != 0x17) { + printf("expected content_type %" PRIu8 ", got %" PRIu8 ": ", 0x17, + tls_state->client_content_type); + result = 0; + goto end; + } + + if (tls_state->client_version != SSL_VERSION_3) { + printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ", + SSL_VERSION_3, tls_state->client_version); + result = 0; + goto end; + } + + uint16_t app_layer_sid = AppLayerParserGetStorageId(); + AppLayerParserStateStore *parser_state_store = (AppLayerParserStateStore *) + ssn.aldata[app_layer_sid]; + AppLayerParserState *parser_state = &parser_state_store->to_server; + + if (!(parser_state->flags & APP_LAYER_PARSER_NO_INSPECTION) && + !(ssn.flags & STREAMTCP_FLAG_NOCLIENT_REASSEMBLY) && + !(ssn.flags & STREAMTCP_FLAG_NOSERVER_REASSEMBLY)) { + printf("The flags should be set\n"); + result = 0; + goto end; + } + + if (!(f.flags & FLOW_NOPAYLOAD_INSPECTION)) { + printf("The flags should be set\n"); + result = 0; + goto end; + } + +end: + StreamL7DataPtrFree(&ssn); + StreamTcpFreeConfig(TRUE); + return result; +} + #endif /* UNITTESTS */ void TLSParserRegisterTests(void) { @@ -1184,6 +1366,8 @@ void TLSParserRegisterTests(void) { UtRegisterTest("TLSParserTest04", TLSParserTest04, 1); UtRegisterTest("TLSParserTest05", TLSParserTest05, 1); UtRegisterTest("TLSParserTest06", TLSParserTest06, 1); + UtRegisterTest("TLSParserTest07", TLSParserTest07, 1); + UtRegisterTest("TLSParserTest08", TLSParserTest08, 1); UtRegisterTest("TLSParserMultimsgTest01", TLSParserMultimsgTest01, 1); UtRegisterTest("TLSParserMultimsgTest02", TLSParserMultimsgTest02, 1); diff --git a/src/app-layer-tls.h b/src/app-layer-tls.h index 3c45c4f633..4948e426dc 100644 --- a/src/app-layer-tls.h +++ b/src/app-layer-tls.h @@ -58,11 +58,12 @@ typedef struct TlsState_ { } TlsState; enum { - TLS_VERSION_INVALID = 0, - TLS_VERSION_VALID, - TLS_VERSION_10, - TLS_VERSION_11, - TLS_VERSION_12, + TLS_VERSION_INVALID = 0x0000, + TLS_VERSION_VALID = 0x0001, + SSL_VERSION_3 = 0x0300, + TLS_VERSION_10 = 0x0301, + TLS_VERSION_11 = 0x0302, + TLS_VERSION_12 = 0x0303, }; void RegisterTLSParsers(void); diff --git a/src/detect-engine-mpm.c b/src/detect-engine-mpm.c index 5bf5337519..a6a71376b7 100644 --- a/src/detect-engine-mpm.c +++ b/src/detect-engine-mpm.c @@ -287,7 +287,7 @@ uint32_t ContentHashFunc(HashTable *ht, void *data, uint16_t datalen) { hash += co->content[i]; } hash = hash % ht->array_size; -//printf("hash %" PRIu32 "\n", hash); + SCLogDebug("hash %" PRIu32 "", hash); return hash; } diff --git a/src/detect-tls-version.c b/src/detect-tls-version.c index 60aa3bc53c..bb154a8715 100644 --- a/src/detect-tls-version.c +++ b/src/detect-tls-version.c @@ -146,7 +146,7 @@ int DetectTlsVersionMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Flow * */ DetectTlsVersionData *DetectTlsVersionParse (char *str) { - uint8_t temp; + uint16_t temp; DetectTlsVersionData *tls = NULL; #define MAX_SUBSTRINGS 30 int ret = 0, res = 0; diff --git a/src/detect-tls-version.h b/src/detect-tls-version.h index 53989fa3e3..c4dd16925e 100644 --- a/src/detect-tls-version.h +++ b/src/detect-tls-version.h @@ -25,7 +25,7 @@ #define __DETECT_TLS_VERSION_H__ typedef struct DetectTlsVersionData_ { - uint8_t ver; /** tls version to match */ + uint16_t ver; /** tls version to match */ } DetectTlsVersionData; /* prototypes */ diff --git a/src/stream-tcp-reassemble.c b/src/stream-tcp-reassemble.c index 6261d12adb..a9e73f9ed9 100644 --- a/src/stream-tcp-reassemble.c +++ b/src/stream-tcp-reassemble.c @@ -1490,6 +1490,8 @@ int StreamTcpReassembleHandleSegmentUpdateACK (TcpReassemblyThreadCtx *ra_ctx, uint16_t payload_len = 0; TcpSegment *seg = stream->seg_list; uint32_t next_seq = ra_base_seq + 1; + if (SEQ_GEQ(seg->seq, stream->last_ack)) + SCLogDebug("seg is %"PRIu32" and st %"PRIu32"",seg->seq, stream->last_ack); /* loop through the segments and fill one or more msgs */ for (; seg != NULL && SEQ_LT(seg->seq, stream->last_ack);) { @@ -1940,7 +1942,12 @@ int StreamTcpReassembleHandleSegment(TcpReassemblyThreadCtx *ra_ctx, SCReturnInt(-1); } - if (p->payload_len > 0) { + /* If no stream reassembly/application layer protocol inspection, then + simple return */ + if (p->payload_len > 0 && + (((stream == &ssn->client) && !(ssn->flags & STREAMTCP_FLAG_NOCLIENT_REASSEMBLY)) || + ((stream == &ssn->server) && !(ssn->flags & STREAMTCP_FLAG_NOSERVER_REASSEMBLY)))) + { if (StreamTcpReassembleHandleSegmentHandleData(ssn, stream, p) != 0) { SCLogDebug("StreamTcpReassembleHandleSegmentHandleData error"); SCReturnInt(-1); diff --git a/src/stream-tcp.c b/src/stream-tcp.c index ac049b1d68..3f37e7492a 100644 --- a/src/stream-tcp.c +++ b/src/stream-tcp.c @@ -693,11 +693,7 @@ static int StreamTcpPacketStateNone(ThreadVars *tv, Packet *p, ssn->client.last_ts = 0; } - /* If no stream reassembly/application layer protocol inspection, - * then simple return */ - if (! (ssn->flags & STREAMTCP_FLAG_NOCLIENT_REASSEMBLY)) - StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, &ssn->client, - p); + StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, &ssn->client, p); break; case TH_RST: @@ -1104,10 +1100,7 @@ static int StreamTcpPacketStateSynRecv(ThreadVars *tv, Packet *p, ssn->client.next_win = ssn->client.last_ack + ssn->client.window; - /* If no stream reassembly/application layer protocol - * inspection, then simple return*/ - if (!(ssn->flags & STREAMTCP_FLAG_NOSERVER_REASSEMBLY)) - StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, + StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, &ssn->server, p); } else { SCLogDebug("ssn %p: 4WHS wrong seq nr on packet", ssn); @@ -1167,10 +1160,7 @@ static int StreamTcpPacketStateSynRecv(ThreadVars *tv, Packet *p, ssn->client.wscale = TCP_WSCALE_MAX; } - /* If no stream reassembly/application layer protocol inspection - * then simple return*/ - if (!(ssn->flags & STREAMTCP_FLAG_NOCLIENT_REASSEMBLY)) - StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, + StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, &ssn->client, p); /* If asynchronous stream handling is allowed then set the session, @@ -1203,10 +1193,7 @@ static int StreamTcpPacketStateSynRecv(ThreadVars *tv, Packet *p, , ssn, TCP_GET_SEQ(p), p->payload_len, TCP_GET_SEQ(p) + p->payload_len, ssn->server.next_seq); - /* If no stream reassembly/application layer protocol inspection - * then simple return*/ - if (!(ssn->flags & STREAMTCP_FLAG_NOSERVER_REASSEMBLY)) - StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, + StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, &ssn->server, p); } else { @@ -1373,10 +1360,7 @@ static int HandleEstablishedPacketToServer(TcpSession *ssn, Packet *p, ssn->server.next_win, ssn->server.window); } - /*If no stream reassembly/application layer protocol inspection, - * then simple return*/ - if (!(ssn->flags & STREAMTCP_FLAG_NOCLIENT_REASSEMBLY)) - StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, &ssn->client, p); + StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, &ssn->client, p); } else { SCLogDebug("ssn %p: toserver => SEQ out of window, packet SEQ " "%" PRIu32 ", payload size %" PRIu32 " (%" PRIu32 ")," @@ -1469,10 +1453,7 @@ static int HandleEstablishedPacketToClient(TcpSession *ssn, Packet *p, TCP_GET_SEQ(p),ssn->client.next_win, ssn->client.window); } - /*If no stream reassembly/application layer protocol inspection, then - * simple return*/ - if (!(ssn->flags & STREAMTCP_FLAG_NOSERVER_REASSEMBLY)) - StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, &ssn->server, p); + StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, &ssn->server, p); } else { SCLogDebug("ssn %p: client => SEQ out of window, packet SEQ" "%" PRIu32 ", payload size %" PRIu32 " (%" PRIu32 ")," @@ -1587,8 +1568,7 @@ static int StreamTcpPacketStateEstablished(ThreadVars *tv, Packet *p, if (SEQ_GT(TCP_GET_ACK(p),ssn->server.last_ack)) ssn->server.last_ack = TCP_GET_ACK(p); - if (! (ssn->flags & STREAMTCP_FLAG_NOCLIENT_REASSEMBLY)) - StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, + StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, &ssn->client, p); SCLogDebug("ssn %p: =+ next SEQ %" PRIu32 ", last ACK " "%" PRIu32 "", ssn, ssn->client.next_seq, @@ -1609,8 +1589,7 @@ static int StreamTcpPacketStateEstablished(ThreadVars *tv, Packet *p, if (SEQ_GT(TCP_GET_ACK(p),ssn->client.last_ack)) ssn->client.last_ack = TCP_GET_ACK(p); - if (!(ssn->flags & STREAMTCP_FLAG_NOSERVER_REASSEMBLY)) - StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, + StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, &ssn->server, p); SCLogDebug("ssn %p: =+ next SEQ %" PRIu32 ", last ACK " "%" PRIu32 "", ssn, ssn->server.next_seq, @@ -1667,8 +1646,7 @@ static int StreamTcpHandleFin(StreamTcpThread *stt, TcpSession *ssn, Packet *p) if (SEQ_GT(TCP_GET_ACK(p),ssn->server.last_ack)) ssn->server.last_ack = TCP_GET_ACK(p); - if (! (ssn->flags & STREAMTCP_FLAG_NOCLIENT_REASSEMBLY)) - StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, &ssn->client, p); + StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, &ssn->client, p); SCLogDebug("ssn %p: =+ next SEQ %" PRIu32 ", last ACK %" PRIu32 "", ssn, ssn->client.next_seq, ssn->server.last_ack); @@ -1699,8 +1677,7 @@ static int StreamTcpHandleFin(StreamTcpThread *stt, TcpSession *ssn, Packet *p) if (SEQ_GT(TCP_GET_ACK(p),ssn->client.last_ack)) ssn->client.last_ack = TCP_GET_ACK(p); - if (!(ssn->flags & STREAMTCP_FLAG_NOSERVER_REASSEMBLY)) - StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, &ssn->server, p); + StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, &ssn->server, p); SCLogDebug("ssn %p: =+ next SEQ %" PRIu32 ", last ACK %" PRIu32 "", ssn, ssn->server.next_seq, ssn->client.last_ack); @@ -1752,8 +1729,7 @@ static int StreamTcpPacketStateFinWait1(ThreadVars *tv, Packet *p, if (SEQ_GT(TCP_GET_ACK(p),ssn->server.last_ack)) ssn->server.last_ack = TCP_GET_ACK(p); - if (! (ssn->flags & STREAMTCP_FLAG_NOCLIENT_REASSEMBLY)) - StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, + StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, &ssn->client, p); if (SEQ_EQ(ssn->client.next_seq, TCP_GET_SEQ(p))) { @@ -1783,8 +1759,7 @@ static int StreamTcpPacketStateFinWait1(ThreadVars *tv, Packet *p, if (SEQ_GT(TCP_GET_ACK(p),ssn->client.last_ack)) ssn->client.last_ack = TCP_GET_ACK(p); - if (!(ssn->flags & STREAMTCP_FLAG_NOSERVER_REASSEMBLY)) - StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, + StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, &ssn->server, p); if (SEQ_EQ(ssn->server.next_seq, TCP_GET_SEQ(p))) { @@ -1832,8 +1807,7 @@ static int StreamTcpPacketStateFinWait1(ThreadVars *tv, Packet *p, if (SEQ_GT(TCP_GET_ACK(p),ssn->server.last_ack)) ssn->server.last_ack = TCP_GET_ACK(p); - if (! (ssn->flags & STREAMTCP_FLAG_NOCLIENT_REASSEMBLY)) - StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, + StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, &ssn->client, p); if (SEQ_EQ(ssn->client.next_seq, TCP_GET_SEQ(p))) { @@ -1868,8 +1842,7 @@ static int StreamTcpPacketStateFinWait1(ThreadVars *tv, Packet *p, if (SEQ_GT(TCP_GET_ACK(p),ssn->client.last_ack)) ssn->client.last_ack = TCP_GET_ACK(p); - if (!(ssn->flags & STREAMTCP_FLAG_NOSERVER_REASSEMBLY)) - StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, + StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, &ssn->server, p); if (SEQ_EQ(ssn->server.next_seq, TCP_GET_SEQ(p))) { @@ -1949,8 +1922,7 @@ static int StreamTcpPacketStateFinWait2(ThreadVars *tv, Packet *p, if (SEQ_GT(TCP_GET_ACK(p),ssn->server.last_ack)) ssn->server.last_ack = TCP_GET_ACK(p); - if (! (ssn->flags & STREAMTCP_FLAG_NOCLIENT_REASSEMBLY)) - StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, + StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, &ssn->client, p); if (SEQ_EQ(ssn->client.next_seq, TCP_GET_SEQ(p))) { @@ -1981,8 +1953,7 @@ static int StreamTcpPacketStateFinWait2(ThreadVars *tv, Packet *p, if (SEQ_GT(TCP_GET_ACK(p),ssn->client.last_ack)) ssn->client.last_ack = TCP_GET_ACK(p); - if (!(ssn->flags & STREAMTCP_FLAG_NOSERVER_REASSEMBLY)) - StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, + StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, &ssn->server, p); if (SEQ_EQ(ssn->server.next_seq, TCP_GET_SEQ(p))) { @@ -2039,8 +2010,7 @@ static int StreamTcpPacketStateFinWait2(ThreadVars *tv, Packet *p, if (SEQ_GT(TCP_GET_ACK(p),ssn->server.last_ack)) ssn->server.last_ack = TCP_GET_ACK(p); - if (! (ssn->flags & STREAMTCP_FLAG_NOCLIENT_REASSEMBLY)) - StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, + StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, &ssn->client, p); SCLogDebug("ssn %p: =+ next SEQ %" PRIu32 ", last ACK " @@ -2068,8 +2038,7 @@ static int StreamTcpPacketStateFinWait2(ThreadVars *tv, Packet *p, if (SEQ_GT(TCP_GET_ACK(p),ssn->client.last_ack)) ssn->client.last_ack = TCP_GET_ACK(p); - if (!(ssn->flags & STREAMTCP_FLAG_NOSERVER_REASSEMBLY)) - StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, + StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, &ssn->server, p); SCLogDebug("ssn %p: =+ next SEQ %" PRIu32 ", last ACK " "%" PRIu32 "", ssn, ssn->server.next_seq, @@ -2129,8 +2098,7 @@ static int StreamTcpPacketStateClosing(ThreadVars *tv, Packet *p, if (SEQ_GT(TCP_GET_ACK(p),ssn->server.last_ack)) ssn->server.last_ack = TCP_GET_ACK(p); - if (! (ssn->flags & STREAMTCP_FLAG_NOCLIENT_REASSEMBLY)) - StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, + StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, &ssn->client, p); SCLogDebug("ssn %p: =+ next SEQ %" PRIu32 ", last ACK " "%" PRIu32 "", ssn, ssn->client.next_seq, @@ -2154,8 +2122,7 @@ static int StreamTcpPacketStateClosing(ThreadVars *tv, Packet *p, if (SEQ_GT(TCP_GET_ACK(p),ssn->client.last_ack)) ssn->client.last_ack = TCP_GET_ACK(p); - if (!(ssn->flags & STREAMTCP_FLAG_NOSERVER_REASSEMBLY)) - StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, + StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, &ssn->server, p); SCLogDebug("StreamTcpPacketStateClosing (%p): =+ next SEQ " "%" PRIu32 ", last ACK %" PRIu32 "", ssn, @@ -2227,8 +2194,7 @@ static int StreamTcpPacketStateCloseWait(ThreadVars *tv, Packet *p, if (SEQ_GT(TCP_GET_ACK(p),ssn->client.last_ack)) ssn->client.last_ack = TCP_GET_ACK(p); - if (!(ssn->flags & STREAMTCP_FLAG_NOSERVER_REASSEMBLY)) - StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, + StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, &ssn->server, p); SCLogDebug("ssn %p: =+ next SEQ %" PRIu32 ", last ACK " "%" PRIu32 "", ssn, ssn->server.next_seq, @@ -2255,8 +2221,7 @@ static int StreamTcpPacketStateCloseWait(ThreadVars *tv, Packet *p, if (SEQ_GT(TCP_GET_ACK(p),ssn->server.last_ack)) ssn->server.last_ack = TCP_GET_ACK(p); - if (!(ssn->flags & STREAMTCP_FLAG_NOSERVER_REASSEMBLY)) - StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, + StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, &ssn->client, p); SCLogDebug("ssn %p: =+ next SEQ %" PRIu32 ", last ACK " "%" PRIu32 "", ssn, ssn->client.next_seq, @@ -2289,8 +2254,7 @@ static int StreamTcpPacketStateCloseWait(ThreadVars *tv, Packet *p, if (SEQ_GT(TCP_GET_ACK(p),ssn->client.last_ack)) ssn->client.last_ack = TCP_GET_ACK(p); - if (!(ssn->flags & STREAMTCP_FLAG_NOSERVER_REASSEMBLY)) - StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, + StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, &ssn->server, p); SCLogDebug("ssn %p: =+ next SEQ %" PRIu32 ", last ACK " "%" PRIu32 "", ssn, ssn->server.next_seq, @@ -2314,8 +2278,7 @@ static int StreamTcpPacketStateCloseWait(ThreadVars *tv, Packet *p, if (SEQ_GT(TCP_GET_ACK(p),ssn->server.last_ack)) ssn->server.last_ack = TCP_GET_ACK(p); - if (!(ssn->flags & STREAMTCP_FLAG_NOSERVER_REASSEMBLY)) - StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, + StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, &ssn->client, p); SCLogDebug("ssn %p: =+ next SEQ %" PRIu32 ", last ACK " "%" PRIu32 "", ssn, ssn->client.next_seq, @@ -2374,8 +2337,7 @@ static int StreamTcpPakcetStateLastAck(ThreadVars *tv, Packet *p, if (SEQ_GT(TCP_GET_ACK(p),ssn->server.last_ack)) ssn->server.last_ack = TCP_GET_ACK(p); - if (! (ssn->flags & STREAMTCP_FLAG_NOCLIENT_REASSEMBLY)) - StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, + StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, &ssn->client, p); SCLogDebug("ssn %p: =+ next SEQ %" PRIu32 ", last ACK " "%" PRIu32 "", ssn, ssn->client.next_seq, @@ -2436,8 +2398,7 @@ static int StreamTcpPacketStateTimeWait(ThreadVars *tv, Packet *p, if (SEQ_GT(TCP_GET_ACK(p),ssn->server.last_ack)) ssn->server.last_ack = TCP_GET_ACK(p); - if (! (ssn->flags & STREAMTCP_FLAG_NOCLIENT_REASSEMBLY)) - StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, + StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, &ssn->client, p); SCLogDebug("ssn %p: =+ next SEQ %" PRIu32 ", last ACK " "%" PRIu32 "", ssn, ssn->client.next_seq, @@ -2463,8 +2424,7 @@ static int StreamTcpPacketStateTimeWait(ThreadVars *tv, Packet *p, if (SEQ_GT(TCP_GET_ACK(p),ssn->client.last_ack)) ssn->client.last_ack = TCP_GET_ACK(p); - if (!(ssn->flags & STREAMTCP_FLAG_NOSERVER_REASSEMBLY)) - StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, + StreamTcpReassembleHandleSegment(stt->ra_ctx, ssn, &ssn->server, p); SCLogDebug("ssn %p: =+ next SEQ %" PRIu32 ", last ACK " "%" PRIu32 "", ssn, ssn->server.next_seq, @@ -5221,9 +5181,6 @@ static int StreamTcpTest23(void) Flow f; TCPHdr tcph; TcpReassemblyThreadCtx *ra_ctx = StreamTcpReassembleInitThreadCtx(); - TcpStream stream; - memset(&stream, 0, sizeof (TcpStream)); - stream.os_policy = OS_POLICY_BSD; uint8_t packet[1460] = ""; int result = 1; @@ -5239,6 +5196,7 @@ static int StreamTcpTest23(void) memset(&p, 0, sizeof (Packet)); memset(&f, 0, sizeof (Flow)); memset(&tcph, 0, sizeof (TCPHdr)); + ssn.client.os_policy = OS_POLICY_BSD; f.protoctx = &ssn; p.src.family = AF_INET; p.dst.family = AF_INET; @@ -5254,7 +5212,7 @@ static int StreamTcpTest23(void) p.tcph->th_ack = htonl(3373419609UL); p.payload_len = 2; - if (StreamTcpReassembleHandleSegment(ra_ctx,&ssn, &stream, &p) == -1) { + if (StreamTcpReassembleHandleSegment(ra_ctx,&ssn, &ssn.client, &p) == -1) { printf("failed in segment reassmebling\n"); result &= 0; goto end; @@ -5264,7 +5222,7 @@ static int StreamTcpTest23(void) p.tcph->th_ack = htonl(3373419621UL); p.payload_len = 2; - if (StreamTcpReassembleHandleSegment(ra_ctx,&ssn, &stream, &p) == -1) { + if (StreamTcpReassembleHandleSegment(ra_ctx,&ssn, &ssn.client, &p) == -1) { printf("failed in segment reassmebling\n"); result &= 0; goto end; @@ -5274,19 +5232,19 @@ static int StreamTcpTest23(void) p.tcph->th_ack = htonl(3373419621UL); p.payload_len = 6; - if (StreamTcpReassembleHandleSegment(ra_ctx,&ssn, &stream, &p) == -1) { + if (StreamTcpReassembleHandleSegment(ra_ctx,&ssn, &ssn.client, &p) == -1) { printf("failed in segment reassmebling\n"); result &= 0; goto end; } - if(stream.seg_list_tail->payload_len != 4) { + if(ssn.client.seg_list_tail->payload_len != 4) { printf("failed in segment reassmebling\n"); result &= 0; } end: - StreamTcpReturnStreamSegments(&stream); + StreamTcpReturnStreamSegments(&ssn.client); StreamTcpFreeConfig(TRUE); if (stream_memuse == 0) { result &= 1; @@ -5304,9 +5262,6 @@ static int StreamTcpTest24(void) Flow f; TCPHdr tcph; TcpReassemblyThreadCtx *ra_ctx = StreamTcpReassembleInitThreadCtx(); - TcpStream stream; - memset(&stream, 0, sizeof (TcpStream)); - stream.os_policy = OS_POLICY_BSD; uint8_t packet[1460] = ""; int result = 1; @@ -5322,6 +5277,7 @@ static int StreamTcpTest24(void) memset(&p, 0, sizeof (Packet)); memset(&f, 0, sizeof (Flow)); memset(&tcph, 0, sizeof (TCPHdr)); + ssn.client.os_policy = OS_POLICY_BSD; f.protoctx = &ssn; p.src.family = AF_INET; p.dst.family = AF_INET; @@ -5337,7 +5293,7 @@ static int StreamTcpTest24(void) p.tcph->th_ack = htonl(3373419621UL); p.payload_len = 4; - if (StreamTcpReassembleHandleSegment(ra_ctx,&ssn, &stream, &p) == -1) { + if (StreamTcpReassembleHandleSegment(ra_ctx,&ssn, &ssn.client, &p) == -1) { printf("failed in segment reassmebling\n"); result &= 0; goto end; @@ -5347,7 +5303,7 @@ static int StreamTcpTest24(void) p.tcph->th_ack = htonl(3373419633UL); p.payload_len = 2; - if (StreamTcpReassembleHandleSegment(ra_ctx,&ssn, &stream, &p) == -1) { + if (StreamTcpReassembleHandleSegment(ra_ctx,&ssn, &ssn.client, &p) == -1) { printf("failed in segment reassmebling\n"); result &= 0; goto end; @@ -5357,19 +5313,19 @@ static int StreamTcpTest24(void) p.tcph->th_ack = htonl(3373419657UL); p.payload_len = 4; - if (StreamTcpReassembleHandleSegment(ra_ctx,&ssn, &stream, &p) == -1) { + if (StreamTcpReassembleHandleSegment(ra_ctx,&ssn, &ssn.client, &p) == -1) { printf("failed in segment reassmebling\n"); result &= 0; goto end; } - if(stream.seg_list_tail->payload_len != 2) { + if(ssn.client.seg_list_tail->payload_len != 2) { printf("failed in segment reassmebling\n"); result &= 0; } end: - StreamTcpReturnStreamSegments(&stream); + StreamTcpReturnStreamSegments(&ssn.client); StreamTcpFreeConfig(TRUE); if (stream_memuse == 0) { result &= 1; diff --git a/src/suricata.c b/src/suricata.c index 9cb23e8bf1..b82df17266 100644 --- a/src/suricata.c +++ b/src/suricata.c @@ -98,6 +98,7 @@ #include "app-layer-dcerpc.h" #include "app-layer-htp.h" #include "app-layer-ftp.h" +#include "app-layer-ssl.h" #include "util-radix-tree.h" #include "util-host-os-info.h" @@ -695,6 +696,7 @@ int main(int argc, char **argv) RegisterSMBParsers(); RegisterDCERPCParsers(); RegisterFTPParsers(); + RegisterSSLParsers(); AppLayerParsersInitPostProcess(); #ifdef UNITTESTS @@ -761,6 +763,7 @@ int main(int argc, char **argv) UtilActionRegisterTests(); SCClassConfRegisterTests(); SCThresholdConfRegisterTests(); + SSLParserRegisterTests(); #ifdef __SC_CUDA_SUPPORT__ SCCudaRegisterTests(); #endif