App layer protocol detection updated and improved. We now use

confirmation from both directions and set events if there's a mismatch
between the 2 directions.

FPs from corrupt flows have disappeared with this.
pull/567/head
Anoop Saldanha 12 years ago
parent 22c05da3cd
commit 0d7159b525

@ -722,6 +722,7 @@ void RegisterDCERPCUDPParsers(void) {
if (AppLayerProtoDetectionEnabled("dcerpc")) {
AlpProtoAdd(&alp_proto_ctx, proto_name, IPPROTO_UDP, ALPROTO_DCERPC_UDP, "|04 00|", 2, 0, STREAM_TOSERVER);
AppLayerRegisterParserAcceptableDataDirection(ALPROTO_DCERPC_UDP, STREAM_TOSERVER);
} else {
SCLogInfo("Protocol detection and parser disabled for %s protocol.",
"dcerpc");
@ -740,7 +741,7 @@ void RegisterDCERPCUDPParsers(void) {
"still on.", "dcerpc");
}
#ifdef UNITTESTS
AppLayerRegisterUnittests(ALPROTO_DCERPC_UDP, DCERPCUDPParserRegisterTests);
AppLayerParserRegisterUnittests(ALPROTO_DCERPC_UDP, DCERPCUDPParserRegisterTests);
#endif
return;

@ -1871,6 +1871,9 @@ void RegisterDCERPCParsers(void) {
if (AppLayerProtoDetectionEnabled(proto_name)) {
AlpProtoAdd(&alp_proto_ctx, proto_name, IPPROTO_TCP, ALPROTO_DCERPC, "|05 00|", 2, 0, STREAM_TOSERVER);
/* toclient direction */
AlpProtoAdd(&alp_proto_ctx, proto_name, IPPROTO_TCP, ALPROTO_DCERPC, "|05 00|", 2, 0, STREAM_TOCLIENT);
AppLayerRegisterParserAcceptableDataDirection(ALPROTO_DCERPC, STREAM_TOSERVER);
} else {
SCLogInfo("Protocol detection and parser disabled for %s protocol.",
proto_name);
@ -1889,7 +1892,7 @@ void RegisterDCERPCParsers(void) {
"still on.", proto_name);
}
#ifdef UNITTESTS
AppLayerRegisterUnittests(ALPROTO_DCERPC, DCERPCParserRegisterTests);
AppLayerParserRegisterUnittests(ALPROTO_DCERPC, DCERPCParserRegisterTests);
#endif
return;

@ -573,8 +573,17 @@ uint16_t AppLayerDetectGetProto(AlpProtoDetectCtx *ctx,
{
if (!FLOW_IS_PM_DONE(f, flags)) {
uint16_t pm_results[ALPROTO_MAX];
if (AppLayerDetectGetProtoPMParser(ctx, tctx, f, buf, buflen, flags, ipproto, pm_results) != 0) {
return pm_results[0];
uint16_t pm_matches = AppLayerDetectGetProtoPMParser(ctx, tctx, f, buf, buflen, flags, ipproto, pm_results);
uint8_t dir = (flags & STREAM_TOSERVER) ? 0 : 1;
for (uint16_t i = 0; i < pm_matches; i++) {
if (al_proto_table[pm_results[i]].pp_alproto_map[dir] != NULL) {
if (pm_results[i] != al_proto_table[pm_results[i]].pp_alproto_map[dir](buf, buflen, NULL)) {
/* \todo set event */
continue;
}
}
return pm_results[i];
}
}
if (!FLOW_IS_PP_DONE(f, flags))

@ -270,6 +270,7 @@ void RegisterFTPParsers(void) {
AlpProtoAdd(&alp_proto_ctx, proto_name, IPPROTO_TCP, ALPROTO_FTP, "USER ", 5, 0, STREAM_TOSERVER);
AlpProtoAdd(&alp_proto_ctx, proto_name, IPPROTO_TCP, ALPROTO_FTP, "PASS ", 5, 0, STREAM_TOSERVER);
AlpProtoAdd(&alp_proto_ctx, proto_name, IPPROTO_TCP, ALPROTO_FTP, "PORT ", 5, 0, STREAM_TOSERVER);
AppLayerRegisterParserAcceptableDataDirection(ALPROTO_FTP, STREAM_TOSERVER | STREAM_TOCLIENT);
}
if (AppLayerParserEnabled(proto_name)) {
@ -286,7 +287,7 @@ void RegisterFTPParsers(void) {
"still on.", proto_name);
}
#ifdef UNITTESTS
AppLayerRegisterUnittests(ALPROTO_FTP, FTPParserRegisterTests);
AppLayerParserRegisterUnittests(ALPROTO_FTP, FTPParserRegisterTests);
#endif
}

@ -2420,6 +2420,12 @@ void RegisterHTPParsers(void)
AlpProtoAdd(&alp_proto_ctx, proto_name, IPPROTO_TCP, ALPROTO_HTTP, "OPTIONS|09|", 8, 0, STREAM_TOSERVER);
AlpProtoAdd(&alp_proto_ctx, proto_name, IPPROTO_TCP, ALPROTO_HTTP, "CONNECT|20|", 8, 0, STREAM_TOSERVER);
AlpProtoAdd(&alp_proto_ctx, proto_name, IPPROTO_TCP, ALPROTO_HTTP, "CONNECT|09|", 8, 0, STREAM_TOSERVER);
/* toclient direction */
AlpProtoAdd(&alp_proto_ctx, proto_name, IPPROTO_TCP, ALPROTO_HTTP, "HTTP/0.9", 8, 0, STREAM_TOCLIENT);
AlpProtoAdd(&alp_proto_ctx, proto_name, IPPROTO_TCP, ALPROTO_HTTP, "HTTP/1.0", 8, 0, STREAM_TOCLIENT);
AlpProtoAdd(&alp_proto_ctx, proto_name, IPPROTO_TCP, ALPROTO_HTTP, "HTTP/1.1", 8, 0, STREAM_TOCLIENT);
AppLayerRegisterParserAcceptableDataDirection(ALPROTO_HTTP, STREAM_TOSERVER);
} else {
SCLogInfo("Protocol detection and parser disabled for %s protocol",
proto_name);
@ -2451,7 +2457,7 @@ void RegisterHTPParsers(void)
"still on.", proto_name);
}
#ifdef UNITTESTS
AppLayerRegisterUnittests(ALPROTO_HTTP, HTPParserRegisterTests);
AppLayerParserRegisterUnittests(ALPROTO_HTTP, HTPParserRegisterTests);
#endif
SCReturn;

@ -758,7 +758,7 @@ int AppLayerRegisterProto(char *name, uint8_t proto, uint8_t flags,
}
#ifdef UNITTESTS
void AppLayerRegisterUnittests(uint16_t proto, void (*RegisterUnittests)(void)) {
void AppLayerParserRegisterUnittests(uint16_t proto, void (*RegisterUnittests)(void)) {
al_proto_table[proto].RegisterUnittests = RegisterUnittests;
}
#endif
@ -2240,6 +2240,23 @@ static inline void AppLayerInsertNewProbingParser(AppLayerProbingParser **pp,
return;
}
void AppLayerRegisterParserAcceptableDataDirection(uint16_t al_proto,
uint8_t flags)
{
al_proto_table[al_proto].flags |= (flags & (STREAM_TOSERVER | STREAM_TOCLIENT));
return;
}
void AppLayerMapProbingParserAgainstAlproto(uint16_t al_proto,
uint8_t flags,
ProbingParserFPtr ProbingParser)
{
al_proto_table[al_proto].pp_alproto_map[(flags & STREAM_TOSERVER) ? 0 : 1] = ProbingParser;
return;
}
void AppLayerRegisterProbingParser(AlpProtoDetectCtx *ctx,
uint16_t ip_proto,
char *portstr,

@ -34,6 +34,9 @@ typedef struct AppLayerLocalMap_ {
uint16_t parser_id;
} AppLayerLocalMap;
typedef uint16_t (*ProbingParserFPtr)(uint8_t *input, uint32_t input_len,
uint32_t *offset);
/** \brief Mapping between ALPROTO_* and L7Parsers
*
* Map the proto to the parsers for the to_client and to_server directions.
@ -66,6 +69,10 @@ typedef struct AppLayerProto_ {
void *(*StateGetTx)(void *alstate, uint64_t tx_id);
int (*StateGetAlstateProgressCompletionStatus)(uint8_t direction);
ProbingParserFPtr pp_alproto_map[2];
/* The current values taken are STREAM_TOSERVER, STREAM_TOCLIENT */
uint8_t flags;
#ifdef UNITTESTS
void (*RegisterUnittests)(void);
#endif
@ -138,9 +145,6 @@ typedef struct AppLayerParserStateStore_ {
AppLayerDecoderEvents *decoder_events;
} AppLayerParserStateStore;
typedef uint16_t (*ProbingParserFPtr)(uint8_t *input, uint32_t input_len,
uint32_t *offset);
typedef struct AppLayerParserTableElement_ {
int (*AppLayerParser)(Flow *f, void *protocol_state, AppLayerParserState
*parser_state, uint8_t *input, uint32_t input_len,
@ -242,6 +246,11 @@ int AppLayerRegisterParser(char *name, uint16_t proto, uint16_t parser_id,
void *local_data,
AppLayerParserResult *output),
char *dependency);
void AppLayerRegisterParserAcceptableDataDirection(uint16_t al_proto,
uint8_t flags);
void AppLayerMapProbingParserAgainstAlproto(uint16_t al_proto,
uint8_t flags,
ProbingParserFPtr ProbingParser);
void AppLayerRegisterProbingParser(struct AlpProtoDetectCtx_ *,
uint16_t ip_proto,
char *portstr,
@ -250,7 +259,7 @@ void AppLayerRegisterProbingParser(struct AlpProtoDetectCtx_ *,
uint8_t flags,
ProbingParserFPtr ProbingParser);
#ifdef UNITTESTS
void AppLayerRegisterUnittests(uint16_t proto, void (*RegisterUnittests)(void));
void AppLayerParserRegisterUnittests(uint16_t proto, void (*RegisterUnittests)(void));
#endif
void AppLayerRegisterStateFuncs(uint16_t proto, void *(*StateAlloc)(void),
void (*StateFree)(void *));

@ -1420,6 +1420,8 @@ void RegisterSMBParsers(void) {
SMB_PROBING_PARSER_MIN_DEPTH, 0,
SMBProbingParser);
}
AppLayerRegisterParserAcceptableDataDirection(ALPROTO_SMB, STREAM_TOSERVER);
} else {
SCLogInfo("Protocol detection and parser disabled for %s protocol.",
proto_name);
@ -1436,7 +1438,7 @@ void RegisterSMBParsers(void) {
}
#ifdef UNITTESTS
AppLayerRegisterUnittests(ALPROTO_SMB, SMBParserRegisterTests);
AppLayerParserRegisterUnittests(ALPROTO_SMB, SMBParserRegisterTests);
#endif
return;
}

@ -531,7 +531,7 @@ void RegisterSMB2Parsers(void) {
}
#ifdef UNITTESTS
AppLayerRegisterUnittests(ALPROTO_SMB2, SMB2ParserRegisterTests);
AppLayerParserRegisterUnittests(ALPROTO_SMB2, SMB2ParserRegisterTests);
#endif
return;
}

@ -532,26 +532,16 @@ static int SMTPProcessReply(SMTPState *state, Flow *f,
reply_code = smtp_reply_map[pmq->pattern_id_array[0]].enum_value;
if (state->cmds_idx == state->cmds_cnt) {
/* decoder event - unable to match reply with request */
SCLogDebug("unable to match reply with request");
SCReturnInt(-1);
}
/* kinda hack needed for us. Our parser logs commands, to be
* matched against server replies. SMTP is normally accompanied by a
* toclient welcome message, which would have had no command to
* accompany it with. And also alproto detection sees to it that the
* toserver stream is the first one to be processed by the app layer.
* Hence check the first reply and if it is a welcome message(220),
* leave without matching it against any buffered command */
if (!(state->parser_state & SMTP_PARSER_STATE_FIRST_REPLY_SEEN)) {
state->parser_state |= SMTP_PARSER_STATE_FIRST_REPLY_SEEN;
if (reply_code == SMTP_REPLY_220) {
return 0;
if (!(state->parser_state & SMTP_PARSER_STATE_FIRST_REPLY_SEEN)) {
state->parser_state |= SMTP_PARSER_STATE_FIRST_REPLY_SEEN;
if (reply_code == SMTP_REPLY_220)
SCReturnInt(0);
else
AppLayerDecoderEventsSetEvent(f, SMTP_DECODER_EVENT_INVALID_REPLY);
} else {
/* set decoder event - first reply from server not a welcome message */
AppLayerDecoderEventsSetEvent(f,
SMTP_DECODER_EVENT_NO_SERVER_WELCOME_MESSAGE);
/* decoder event - unable to match reply with request */
SCLogDebug("unable to match reply with request");
SCReturnInt(-1);
}
}
@ -633,6 +623,10 @@ static int SMTPProcessRequest(SMTPState *state, Flow *f,
{
SCEnter();
if (!(state->parser_state & SMTP_PARSER_STATE_FIRST_REPLY_SEEN)) {
AppLayerDecoderEventsSetEvent(f, SMTP_DECODER_EVENT_NO_SERVER_WELCOME_MESSAGE);
}
/* there are 2 commands that can push it into this COMMAND_DATA mode -
* STARTTLS and DATA */
if (!(state->parser_state & SMTP_PARSER_STATE_COMMAND_DATA_MODE)) {
@ -852,6 +846,9 @@ void RegisterSMTPParsers(void)
STREAM_TOSERVER);
AlpProtoAdd(&alp_proto_ctx, proto_name, IPPROTO_TCP, ALPROTO_SMTP, "HELO", 4, 0,
STREAM_TOSERVER);
AlpProtoAdd(&alp_proto_ctx, proto_name, IPPROTO_TCP, ALPROTO_SMTP, "QUIT", 4, 0,
STREAM_TOSERVER);
AppLayerRegisterParserAcceptableDataDirection(ALPROTO_SMTP, STREAM_TOCLIENT);
} else {
SCLogInfo("Protocol detection and parser disabled for %s protocol.",
proto_name);
@ -877,7 +874,7 @@ void RegisterSMTPParsers(void)
SMTPSetMpmState();
#ifdef UNITTESTS
AppLayerRegisterUnittests(ALPROTO_SMTP, SMTPParserRegisterTests);
AppLayerParserRegisterUnittests(ALPROTO_SMTP, SMTPParserRegisterTests);
#endif
return;
}
@ -966,8 +963,8 @@ int SMTPParserTest01(void)
void *thread_local_data = SMTPLocalStorageAlloc();
SCMutexLock(&f.m);
r = AppLayerParse(thread_local_data, &f, ALPROTO_SMTP, STREAM_TOSERVER,
request1, request1_len);
r = AppLayerParse(thread_local_data, &f, ALPROTO_SMTP, STREAM_TOCLIENT,
welcome_reply, welcome_reply_len);
if (r != 0) {
printf("smtp check returned %" PRId32 ", expected 0: ", r);
SCMutexUnlock(&f.m);
@ -980,17 +977,16 @@ int SMTPParserTest01(void)
goto end;
}
if (smtp_state->input_len != 0 ||
smtp_state->cmds_cnt != 1 ||
smtp_state->cmds_cnt != 0 ||
smtp_state->cmds_idx != 0 ||
smtp_state->cmds[0] != SMTP_COMMAND_OTHER_CMD ||
smtp_state->parser_state != 0) {
smtp_state->parser_state != SMTP_PARSER_STATE_FIRST_REPLY_SEEN) {
printf("smtp parser in inconsistent state\n");
goto end;
}
SCMutexLock(&f.m);
r = AppLayerParse(thread_local_data, &f, ALPROTO_SMTP, STREAM_TOCLIENT,
welcome_reply, welcome_reply_len);
r = AppLayerParse(thread_local_data, &f, ALPROTO_SMTP, STREAM_TOSERVER,
request1, request1_len);
if (r != 0) {
printf("smtp check returned %" PRId32 ", expected 0: ", r);
SCMutexUnlock(&f.m);
@ -1323,8 +1319,8 @@ int SMTPParserTest02(void)
void *thread_local_data = SMTPLocalStorageAlloc();
SCMutexLock(&f.m);
r = AppLayerParse(thread_local_data, &f, ALPROTO_SMTP, STREAM_TOSERVER,
request1, request1_len);
r = AppLayerParse(thread_local_data, &f, ALPROTO_SMTP, STREAM_TOCLIENT,
welcome_reply, welcome_reply_len);
if (r != 0) {
printf("smtp check returned %" PRId32 ", expected 0: ", r);
SCMutexUnlock(&f.m);
@ -1337,17 +1333,16 @@ int SMTPParserTest02(void)
goto end;
}
if (smtp_state->input_len != 0 ||
smtp_state->cmds_cnt != 1 ||
smtp_state->cmds_cnt != 0 ||
smtp_state->cmds_idx != 0 ||
smtp_state->cmds[0] != SMTP_COMMAND_OTHER_CMD ||
smtp_state->parser_state != 0) {
smtp_state->parser_state != SMTP_PARSER_STATE_FIRST_REPLY_SEEN) {
printf("smtp parser in inconsistent state\n");
goto end;
}
SCMutexLock(&f.m);
r = AppLayerParse(thread_local_data, &f, ALPROTO_SMTP, STREAM_TOCLIENT,
welcome_reply, welcome_reply_len);
r = AppLayerParse(thread_local_data, &f, ALPROTO_SMTP, STREAM_TOSERVER,
request1, request1_len);
if (r != 0) {
printf("smtp check returned %" PRId32 ", expected 0: ", r);
SCMutexUnlock(&f.m);
@ -1956,8 +1951,8 @@ int SMTPParserTest03(void)
void *thread_local_data = SMTPLocalStorageAlloc();
SCMutexLock(&f.m);
r = AppLayerParse(thread_local_data, &f, ALPROTO_SMTP, STREAM_TOSERVER,
request1, request1_len);
r = AppLayerParse(thread_local_data, &f, ALPROTO_SMTP, STREAM_TOCLIENT,
welcome_reply, welcome_reply_len);
if (r != 0) {
printf("smtp check returned %" PRId32 ", expected 0: ", r);
SCMutexUnlock(&f.m);
@ -1970,17 +1965,16 @@ int SMTPParserTest03(void)
goto end;
}
if (smtp_state->input_len != 0 ||
smtp_state->cmds_cnt != 1 ||
smtp_state->cmds_cnt != 0 ||
smtp_state->cmds_idx != 0 ||
smtp_state->cmds[0] != SMTP_COMMAND_OTHER_CMD ||
smtp_state->parser_state != 0) {
smtp_state->parser_state != SMTP_PARSER_STATE_FIRST_REPLY_SEEN) {
printf("smtp parser in inconsistent state\n");
goto end;
}
SCMutexLock(&f.m);
r = AppLayerParse(thread_local_data, &f, ALPROTO_SMTP, STREAM_TOCLIENT,
welcome_reply, welcome_reply_len);
r = AppLayerParse(thread_local_data, &f, ALPROTO_SMTP, STREAM_TOSERVER,
request1, request1_len);
if (r != 0) {
printf("smtp check returned %" PRId32 ", expected 0: ", r);
SCMutexUnlock(&f.m);
@ -2102,8 +2096,8 @@ int SMTPParserTest04(void)
void *thread_local_data = SMTPLocalStorageAlloc();
SCMutexLock(&f.m);
r = AppLayerParse(thread_local_data, &f, ALPROTO_SMTP, STREAM_TOSERVER,
request1, request1_len);
r = AppLayerParse(thread_local_data, &f, ALPROTO_SMTP, STREAM_TOCLIENT,
welcome_reply, welcome_reply_len);
if (r != 0) {
printf("smtp check returned %" PRId32 ", expected 0: ", r);
SCMutexUnlock(&f.m);
@ -2116,17 +2110,16 @@ int SMTPParserTest04(void)
goto end;
}
if (smtp_state->input_len != 0 ||
smtp_state->cmds_cnt != 1 ||
smtp_state->cmds_cnt != 0 ||
smtp_state->cmds_idx != 0 ||
smtp_state->cmds[0] != SMTP_COMMAND_OTHER_CMD ||
smtp_state->parser_state != 0) {
smtp_state->parser_state != SMTP_PARSER_STATE_FIRST_REPLY_SEEN) {
printf("smtp parser in inconsistent state\n");
goto end;
}
SCMutexLock(&f.m);
r = AppLayerParse(thread_local_data, &f, ALPROTO_SMTP, STREAM_TOCLIENT,
welcome_reply, welcome_reply_len);
r = AppLayerParse(thread_local_data, &f, ALPROTO_SMTP, STREAM_TOSERVER,
request1, request1_len);
if (r != 0) {
printf("smtp check returned %" PRId32 ", expected 0: ", r);
SCMutexUnlock(&f.m);
@ -2248,8 +2241,8 @@ int SMTPParserTest05(void)
void *thread_local_data = SMTPLocalStorageAlloc();
SCMutexLock(&f.m);
r = AppLayerParse(thread_local_data, &f, ALPROTO_SMTP, STREAM_TOSERVER,
request1, request1_len);
r = AppLayerParse(thread_local_data, &f, ALPROTO_SMTP, STREAM_TOCLIENT,
welcome_reply, welcome_reply_len);
if (r != 0) {
printf("smtp check returned %" PRId32 ", expected 0: ", r);
SCMutexUnlock(&f.m);
@ -2262,17 +2255,16 @@ int SMTPParserTest05(void)
goto end;
}
if (smtp_state->input_len != 0 ||
smtp_state->cmds_cnt != 1 ||
smtp_state->cmds_cnt != 0 ||
smtp_state->cmds_idx != 0 ||
smtp_state->cmds[0] != SMTP_COMMAND_OTHER_CMD ||
smtp_state->parser_state != 0) {
smtp_state->parser_state != SMTP_PARSER_STATE_FIRST_REPLY_SEEN) {
printf("smtp parser in inconsistent state\n");
goto end;
}
SCMutexLock(&f.m);
r = AppLayerParse(thread_local_data, &f, ALPROTO_SMTP, STREAM_TOCLIENT,
welcome_reply, welcome_reply_len);
r = AppLayerParse(thread_local_data, &f, ALPROTO_SMTP, STREAM_TOSERVER,
request1, request1_len);
if (r != 0) {
printf("smtp check returned %" PRId32 ", expected 0: ", r);
SCMutexUnlock(&f.m);
@ -2543,8 +2535,8 @@ int SMTPParserTest06(void)
void *thread_local_data = SMTPLocalStorageAlloc();
SCMutexLock(&f.m);
r = AppLayerParse(thread_local_data, &f, ALPROTO_SMTP, STREAM_TOSERVER,
request1, request1_len);
r = AppLayerParse(thread_local_data, &f, ALPROTO_SMTP, STREAM_TOCLIENT,
welcome_reply, welcome_reply_len);
if (r != 0) {
printf("smtp check returned %" PRId32 ", expected 0: ", r);
SCMutexUnlock(&f.m);
@ -2557,17 +2549,16 @@ int SMTPParserTest06(void)
goto end;
}
if (smtp_state->input_len != 0 ||
smtp_state->cmds_cnt != 1 ||
smtp_state->cmds_cnt != 0 ||
smtp_state->cmds_idx != 0 ||
smtp_state->cmds[0] != SMTP_COMMAND_OTHER_CMD ||
smtp_state->parser_state != 0) {
smtp_state->parser_state != SMTP_PARSER_STATE_FIRST_REPLY_SEEN) {
printf("smtp parser in inconsistent state\n");
goto end;
}
SCMutexLock(&f.m);
r = AppLayerParse(thread_local_data, &f, ALPROTO_SMTP, STREAM_TOCLIENT,
welcome_reply, welcome_reply_len);
r = AppLayerParse(thread_local_data, &f, ALPROTO_SMTP, STREAM_TOSERVER,
request1, request1_len);
if (r != 0) {
printf("smtp check returned %" PRId32 ", expected 0: ", r);
SCMutexUnlock(&f.m);

@ -741,6 +741,7 @@ void RegisterSSHParsers(void)
/** SSH */
if (AppLayerProtoDetectionEnabled(proto_name)) {
AlpProtoAdd(&alp_proto_ctx, proto_name, IPPROTO_TCP, ALPROTO_SSH, "SSH-", 4, 0, STREAM_TOSERVER);
AppLayerRegisterParserAcceptableDataDirection(ALPROTO_SSH, STREAM_TOSERVER | STREAM_TOCLIENT);
} else {
SCLogInfo("Protocol detection and parser disabled for %s protocol.",
proto_name);
@ -759,7 +760,7 @@ void RegisterSSHParsers(void)
}
#ifdef UNITTESTS
AppLayerRegisterUnittests(ALPROTO_SSH, SSHParserRegisterTests);
AppLayerParserRegisterUnittests(ALPROTO_SSH, SSHParserRegisterTests);
#endif
}

@ -1016,6 +1016,15 @@ void RegisterSSLParsers(void)
AlpProtoAdd(&alp_proto_ctx, proto_name, IPPROTO_TCP, ALPROTO_TLS, "|01 03 03|", 3, 0, STREAM_TOSERVER);
AlpProtoAdd(&alp_proto_ctx, proto_name, IPPROTO_TCP, ALPROTO_TLS, "|16 03 03|", 3, 0, STREAM_TOSERVER); /* client hello */
/* toclient direction */
AlpProtoAdd(&alp_proto_ctx, proto_name, IPPROTO_TCP, ALPROTO_TLS, "|16 03 00|", 3, 0, STREAM_TOCLIENT); /* server hello */
/** TLSv1 */
AlpProtoAdd(&alp_proto_ctx, proto_name, IPPROTO_TCP, ALPROTO_TLS, "|16 03 01|", 3, 0, STREAM_TOCLIENT); /* server hello */
/** TLSv1.1 */
AlpProtoAdd(&alp_proto_ctx, proto_name, IPPROTO_TCP, ALPROTO_TLS, "|16 03 02|", 3, 0, STREAM_TOCLIENT); /* server hello */
/** TLSv1.2 */
AlpProtoAdd(&alp_proto_ctx, proto_name, IPPROTO_TCP, ALPROTO_TLS, "|16 03 03|", 3, 0, STREAM_TOCLIENT); /* server hello */
if (RunmodeIsUnittests()) {
AppLayerRegisterProbingParser(&alp_proto_ctx,
IPPROTO_TCP,
@ -1030,6 +1039,8 @@ void RegisterSSLParsers(void)
0, 3,
SSLProbingParser);
}
AppLayerRegisterParserAcceptableDataDirection(ALPROTO_TLS, STREAM_TOSERVER);
} else {
SCLogInfo("Protocol detection and parser disabled for %s protocol",
proto_name);
@ -1060,7 +1071,7 @@ void RegisterSSLParsers(void)
}
#ifdef UNITTESTS
AppLayerRegisterUnittests(ALPROTO_TLS, SSLParserRegisterTests);
AppLayerParserRegisterUnittests(ALPROTO_TLS, SSLParserRegisterTests);
#endif
/* Get the value of no reassembly option from the config file */

File diff suppressed because it is too large Load Diff

@ -38,10 +38,13 @@
uint16_t AppLayerGetProtoFromPacket(Packet *);
void *AppLayerGetProtoStateFromPacket(Packet *);
void *AppLayerGetProtoStateFromFlow(Flow *);
int AppLayerHandleTCPData(AlpProtoDetectThreadCtx *, Flow *, TcpSession *, TcpStream *, uint8_t *, uint32_t, uint8_t);
int AppLayerHandleTCPData(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx, Flow *f,
TcpSession *ssn, TcpStream *stream, uint8_t *data, uint32_t data_len, Packet *p, uint8_t flags);
int AppLayerHandleTCPMsg(AlpProtoDetectThreadCtx *, StreamMsg *);
//int AppLayerHandleMsg(AlpProtoDetectThreadCtx *, StreamMsg *);
int AppLayerHandleUdp(AlpProtoDetectThreadCtx *, Flow *, Packet *p);
void AppLayerRegisterUnittests(void);
#endif /* __APP_LAYER_H__ */

@ -50,6 +50,10 @@
FLOWLOCK_INIT((f)); \
(f)->protoctx = NULL; \
(f)->alproto = 0; \
(f)->alproto_ts = 0; \
(f)->alproto_tc = 0; \
(f)->data_al_so_far[0] = 0; \
(f)->data_al_so_far[1] = 0; \
(f)->de_ctx_id = 0; \
(f)->alparser = NULL; \
(f)->alstate = NULL; \
@ -85,6 +89,10 @@
(f)->alparser = NULL; \
(f)->alstate = NULL; \
(f)->alproto = 0; \
(f)->alproto_ts = 0; \
(f)->alproto_tc = 0; \
(f)->data_al_so_far[0] = 0; \
(f)->data_al_so_far[1] = 0; \
(f)->de_ctx_id = 0; \
if ((f)->de_state != NULL) { \
DetectEngineStateReset((f)->de_state, (STREAM_TOSERVER | STREAM_TOCLIENT)); \

@ -327,6 +327,10 @@ typedef struct Flow_
uint8_t pad0;
uint16_t alproto; /**< \brief application level protocol */
uint16_t alproto_ts;
uint16_t alproto_tc;
uint32_t data_al_so_far[2];
/** detection engine ctx id used to inspect this flow. Set at initial
* inspection. If it doesn't match the currently in use de_ctx, the

@ -63,6 +63,7 @@
#include "app-layer-detect-proto.h"
#include "app-layer-parser.h"
#include "app-layer.h"
#include "app-layer-smb.h"
#include "app-layer-dcerpc.h"
#include "app-layer-dcerpc-udp.h"
@ -257,6 +258,7 @@ int RunUnittests(int list_unittests, char *regex_arg)
#ifdef __SC_CUDA_SUPPORT__
CudaBufferRegisterUnittests();
#endif
AppLayerRegisterUnittests();
if (list_unittests) {
UtListTests(regex_arg);
} else {

@ -215,6 +215,8 @@ typedef struct TcpSession_ {
struct StreamMsg_ *toclient_smsg_head; /**< list of stream msgs (for detection inspection) */
struct StreamMsg_ *toclient_smsg_tail; /**< list of stream msgs (for detection inspection) */
int8_t data_first_seen_dir;
TcpStateQueue *queue; /**< list of SYN/ACK candidates */
} TcpSession;

File diff suppressed because it is too large Load Diff

@ -72,6 +72,9 @@ void StreamTcpReassembleFree(char);
void StreamTcpReassembleRegisterTests(void);
TcpReassemblyThreadCtx *StreamTcpReassembleInitThreadCtx(void);
void StreamTcpReassembleFreeThreadCtx(TcpReassemblyThreadCtx *);
int StreamTcpReassembleAppLayer (ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx,
TcpSession *ssn, TcpStream *stream,
Packet *p);
int StreamTcpReassembleProcessAppLayer(TcpReassemblyThreadCtx *);
void StreamTcpCreateTestPacket(uint8_t *, uint8_t, uint8_t, uint8_t);

@ -4139,8 +4139,8 @@ static int StreamTcpPacketIsWindowUpdate(TcpSession *ssn, Packet *p) {
}
/* flow is and stays locked */
static int StreamTcpPacket (ThreadVars *tv, Packet *p, StreamTcpThread *stt,
PacketQueue *pq)
int StreamTcpPacket (ThreadVars *tv, Packet *p, StreamTcpThread *stt,
PacketQueue *pq)
{
SCEnter();

@ -202,5 +202,11 @@ static inline int StreamHasUnprocessedSegments(TcpSession *ssn, int direction)
}
}
TmEcode StreamTcpThreadInit(ThreadVars *, void *, void **);
TmEcode StreamTcpThreadDeinit(ThreadVars *tv, void *data);
int StreamTcpPacket (ThreadVars *tv, Packet *p, StreamTcpThread *stt,
PacketQueue *pq);
void StreamTcpSessionClear(void *ssnptr);
#endif /* __STREAM_TCP_H__ */

Loading…
Cancel
Save