app-layer: support to server and to client probing parsers

When registering a probing parser allow to_server and
to_client parsers to be registered. Previously the
probing parser may be called for both directions which
in some cases works OK, but in others can cause
the to_client side to be detected as failed.
pull/2484/head
Jason Ish 9 years ago
parent 586774203f
commit c35c18a797

@ -75,8 +75,12 @@ typedef struct AppLayerProtoDetectProbingParserElement_ {
uint32_t min_depth;
/* the max length of data after which this parser won't be invoked */
uint32_t max_depth;
/* the probing parser function */
ProbingParserFPtr ProbingParser;
/* the to_server probing parser function */
ProbingParserFPtr ProbingParserTs;
/* the to_client probing parser function */
ProbingParserFPtr ProbingParserTc;
struct AppLayerProtoDetectProbingParserElement_ *next;
} AppLayerProtoDetectProbingParserElement;
@ -395,14 +399,18 @@ static AppProto AppLayerProtoDetectPPGetProto(Flow *f,
continue;
}
alproto = pe->ProbingParser(buf, buflen, NULL);
if (alproto != ALPROTO_UNKNOWN && alproto != ALPROTO_FAILED)
goto end;
if (alproto == ALPROTO_FAILED ||
(pe->max_depth != 0 && buflen > pe->max_depth)) {
alproto_masks[0] |= pe->alproto_mask;
}
pe = pe->next;
if (direction & STREAM_TOSERVER && pe->ProbingParserTs != NULL) {
alproto = pe->ProbingParserTs(buf, buflen, NULL);
} else if (pe->ProbingParserTc != NULL) {
alproto = pe->ProbingParserTc(buf, buflen, NULL);
}
if (alproto != ALPROTO_UNKNOWN && alproto != ALPROTO_FAILED)
goto end;
if (alproto == ALPROTO_FAILED ||
(pe->max_depth != 0 && buflen > pe->max_depth)) {
alproto_masks[0] |= pe->alproto_mask;
}
pe = pe->next;
}
pe = pe2;
while (pe != NULL) {
@ -412,7 +420,7 @@ static AppProto AppLayerProtoDetectPPGetProto(Flow *f,
continue;
}
alproto = pe->ProbingParser(buf, buflen, NULL);
alproto = pe->ProbingParserTs(buf, buflen, NULL);
if (alproto != ALPROTO_UNKNOWN && alproto != ALPROTO_FAILED)
goto end;
if (alproto == ALPROTO_FAILED ||
@ -579,9 +587,7 @@ static AppLayerProtoDetectProbingParserElement *
AppLayerProtoDetectProbingParserElementCreate(AppProto alproto,
uint16_t port,
uint16_t min_depth,
uint16_t max_depth,
uint16_t (*AppLayerProtoDetectProbingParserFunc)
(uint8_t *input, uint32_t input_len, uint32_t *offset))
uint16_t max_depth)
{
AppLayerProtoDetectProbingParserElement *pe = AppLayerProtoDetectProbingParserElementAlloc();
@ -590,7 +596,6 @@ AppLayerProtoDetectProbingParserElementCreate(AppProto alproto,
pe->alproto_mask = AppLayerProtoDetectProbingParserGetMask(alproto);
pe->min_depth = min_depth;
pe->max_depth = max_depth;
pe->ProbingParser = AppLayerProtoDetectProbingParserFunc;
pe->next = NULL;
if (max_depth != 0 && min_depth >= max_depth) {
@ -603,11 +608,6 @@ AppLayerProtoDetectProbingParserElementCreate(AppProto alproto,
"the probing parser. Invalid alproto - %d", alproto);
goto error;
}
if (AppLayerProtoDetectProbingParserFunc == NULL) {
SCLogError(SC_ERR_ALPARSER, "Invalid arguments sent to "
"register the probing parser. Probing parser func NULL");
goto error;
}
SCReturnPtr(pe, "AppLayerProtoDetectProbingParserElement");
error:
@ -627,7 +627,8 @@ AppLayerProtoDetectProbingParserElementDuplicate(AppLayerProtoDetectProbingParse
new_pe->alproto_mask = pe->alproto_mask;
new_pe->min_depth = pe->min_depth;
new_pe->max_depth = pe->max_depth;
new_pe->ProbingParser = pe->ProbingParser;
new_pe->ProbingParserTs = pe->ProbingParserTs;
new_pe->ProbingParserTc = pe->ProbingParserTc;
new_pe->next = NULL;
SCReturnPtr(new_pe, "AppLayerProtoDetectProbingParserElement");
@ -860,7 +861,8 @@ static void AppLayerProtoDetectInsertNewProbingParser(AppLayerProtoDetectProbing
AppProto alproto,
uint16_t min_depth, uint16_t max_depth,
uint8_t direction,
ProbingParserFPtr ProbingParser)
ProbingParserFPtr ProbingParser1,
ProbingParserFPtr ProbingParser2)
{
SCEnter();
@ -964,13 +966,14 @@ static void AppLayerProtoDetectInsertNewProbingParser(AppLayerProtoDetectProbing
AppLayerProtoDetectProbingParserElement *new_pe =
AppLayerProtoDetectProbingParserElementCreate(alproto,
curr_port->port,
min_depth, max_depth,
ProbingParser);
min_depth, max_depth);
if (new_pe == NULL)
goto error;
curr_pe = new_pe;
AppLayerProtoDetectProbingParserElement **head_pe;
if (direction & STREAM_TOSERVER) {
curr_pe->ProbingParserTs = ProbingParser1;
curr_pe->ProbingParserTc = ProbingParser2;
if (curr_port->dp == NULL)
curr_port->dp_max_depth = new_pe->max_depth;
if (new_pe->max_depth == 0)
@ -982,6 +985,8 @@ static void AppLayerProtoDetectInsertNewProbingParser(AppLayerProtoDetectProbing
curr_port->alproto_mask |= new_pe->alproto_mask;
head_pe = &curr_port->dp;
} else {
curr_pe->ProbingParserTs = ProbingParser2;
curr_pe->ProbingParserTc = ProbingParser1;
if (curr_port->sp == NULL)
curr_port->sp_max_depth = new_pe->max_depth;
if (new_pe->max_depth == 0)
@ -1390,7 +1395,8 @@ void AppLayerProtoDetectPPRegister(uint8_t ipproto,
AppProto alproto,
uint16_t min_depth, uint16_t max_depth,
uint8_t direction,
ProbingParserFPtr ProbingParser)
ProbingParserFPtr ProbingParser1,
ProbingParserFPtr ProbingParser2)
{
SCEnter();
@ -1408,7 +1414,8 @@ void AppLayerProtoDetectPPRegister(uint8_t ipproto,
alproto,
min_depth, max_depth,
direction,
ProbingParser);
ProbingParser1,
ProbingParser2);
}
temp_dp = temp_dp->next;
}
@ -1422,7 +1429,8 @@ int AppLayerProtoDetectPPParseConfPorts(const char *ipproto_name,
const char *alproto_name,
AppProto alproto,
uint16_t min_depth, uint16_t max_depth,
ProbingParserFPtr ProbingParser)
ProbingParserFPtr ProbingParserTs,
ProbingParserFPtr ProbingParserTc)
{
SCEnter();
@ -1469,7 +1477,7 @@ int AppLayerProtoDetectPPParseConfPorts(const char *ipproto_name,
alproto,
min_depth, max_depth,
STREAM_TOSERVER, /* to indicate dp */
ProbingParser);
ProbingParserTs, ProbingParserTc);
}
/* detect by source port of flow */
@ -1483,7 +1491,7 @@ int AppLayerProtoDetectPPParseConfPorts(const char *ipproto_name,
alproto,
min_depth, max_depth,
STREAM_TOCLIENT, /* to indicate sp */
ProbingParser);
ProbingParserTc, ProbingParserTs);
}
@ -2980,57 +2988,57 @@ static int AppLayerProtoDetectTest15(void)
ALPROTO_HTTP,
5, 8,
STREAM_TOSERVER,
ProbingParserDummyForTesting);
ProbingParserDummyForTesting, NULL);
AppLayerProtoDetectPPRegister(IPPROTO_TCP,
"80",
ALPROTO_SMB,
5, 6,
STREAM_TOSERVER,
ProbingParserDummyForTesting);
ProbingParserDummyForTesting, NULL);
AppLayerProtoDetectPPRegister(IPPROTO_TCP,
"80",
ALPROTO_FTP,
7, 10,
STREAM_TOSERVER,
ProbingParserDummyForTesting);
ProbingParserDummyForTesting, NULL);
AppLayerProtoDetectPPRegister(IPPROTO_TCP,
"81",
ALPROTO_DCERPC,
9, 10,
STREAM_TOSERVER,
ProbingParserDummyForTesting);
ProbingParserDummyForTesting, NULL);
AppLayerProtoDetectPPRegister(IPPROTO_TCP,
"81",
ALPROTO_FTP,
7, 15,
STREAM_TOSERVER,
ProbingParserDummyForTesting);
ProbingParserDummyForTesting, NULL);
AppLayerProtoDetectPPRegister(IPPROTO_TCP,
"0",
ALPROTO_SMTP,
12, 0,
STREAM_TOSERVER,
ProbingParserDummyForTesting);
ProbingParserDummyForTesting, NULL);
AppLayerProtoDetectPPRegister(IPPROTO_TCP,
"0",
ALPROTO_TLS,
12, 18,
STREAM_TOSERVER,
ProbingParserDummyForTesting);
ProbingParserDummyForTesting, NULL);
AppLayerProtoDetectPPRegister(IPPROTO_TCP,
"85",
ALPROTO_DCERPC,
9, 10,
STREAM_TOSERVER,
ProbingParserDummyForTesting);
ProbingParserDummyForTesting, NULL);
AppLayerProtoDetectPPRegister(IPPROTO_TCP,
"85",
ALPROTO_FTP,
7, 15,
STREAM_TOSERVER,
ProbingParserDummyForTesting);
ProbingParserDummyForTesting, NULL);
result = 1;
AppLayerProtoDetectPPRegister(IPPROTO_UDP,
@ -3038,7 +3046,7 @@ static int AppLayerProtoDetectTest15(void)
ALPROTO_IMAP,
12, 23,
STREAM_TOSERVER,
ProbingParserDummyForTesting);
ProbingParserDummyForTesting, NULL);
/* toclient */
AppLayerProtoDetectPPRegister(IPPROTO_TCP,
@ -3046,74 +3054,74 @@ static int AppLayerProtoDetectTest15(void)
ALPROTO_JABBER,
12, 23,
STREAM_TOCLIENT,
ProbingParserDummyForTesting);
ProbingParserDummyForTesting, NULL);
AppLayerProtoDetectPPRegister(IPPROTO_TCP,
"0",
ALPROTO_IRC,
12, 14,
STREAM_TOCLIENT,
ProbingParserDummyForTesting);
ProbingParserDummyForTesting, NULL);
AppLayerProtoDetectPPRegister(IPPROTO_TCP,
"85",
ALPROTO_DCERPC,
9, 10,
STREAM_TOCLIENT,
ProbingParserDummyForTesting);
ProbingParserDummyForTesting, NULL);
AppLayerProtoDetectPPRegister(IPPROTO_TCP,
"81",
ALPROTO_FTP,
7, 15,
STREAM_TOCLIENT,
ProbingParserDummyForTesting);
ProbingParserDummyForTesting, NULL);
AppLayerProtoDetectPPRegister(IPPROTO_TCP,
"0",
ALPROTO_TLS,
12, 18,
STREAM_TOCLIENT,
ProbingParserDummyForTesting);
ProbingParserDummyForTesting, NULL);
AppLayerProtoDetectPPRegister(IPPROTO_TCP,
"80",
ALPROTO_HTTP,
5, 8,
STREAM_TOCLIENT,
ProbingParserDummyForTesting);
ProbingParserDummyForTesting, NULL);
AppLayerProtoDetectPPRegister(IPPROTO_TCP,
"81",
ALPROTO_DCERPC,
9, 10,
STREAM_TOCLIENT,
ProbingParserDummyForTesting);
ProbingParserDummyForTesting, NULL);
AppLayerProtoDetectPPRegister(IPPROTO_TCP,
"90",
ALPROTO_FTP,
7, 15,
STREAM_TOCLIENT,
ProbingParserDummyForTesting);
ProbingParserDummyForTesting, NULL);
AppLayerProtoDetectPPRegister(IPPROTO_TCP,
"80",
ALPROTO_SMB,
5, 6,
STREAM_TOCLIENT,
ProbingParserDummyForTesting);
ProbingParserDummyForTesting, NULL);
AppLayerProtoDetectPPRegister(IPPROTO_UDP,
"85",
ALPROTO_IMAP,
12, 23,
STREAM_TOCLIENT,
ProbingParserDummyForTesting);
ProbingParserDummyForTesting, NULL);
AppLayerProtoDetectPPRegister(IPPROTO_TCP,
"0",
ALPROTO_SMTP,
12, 17,
STREAM_TOCLIENT,
ProbingParserDummyForTesting);
ProbingParserDummyForTesting, NULL);
AppLayerProtoDetectPPRegister(IPPROTO_TCP,
"80",
ALPROTO_FTP,
7, 10,
STREAM_TOCLIENT,
ProbingParserDummyForTesting);
ProbingParserDummyForTesting, NULL);
AppLayerProtoDetectPPTestDataElement element_ts_80[] = {
{ "http", ALPROTO_HTTP, 80, 1 << ALPROTO_HTTP, 5, 8 },

@ -65,7 +65,8 @@ void AppLayerProtoDetectPPRegister(uint8_t ipproto,
AppProto alproto,
uint16_t min_depth, uint16_t max_depth,
uint8_t direction,
ProbingParserFPtr ProbingParser);
ProbingParserFPtr ProbingParser1,
ProbingParserFPtr ProbingParser2);
/**
* \retval bool 0 if no config was found, 1 if config was found
*/
@ -74,7 +75,8 @@ int AppLayerProtoDetectPPParseConfPorts(const char *ipproto_name,
const char *alproto_name,
AppProto alproto,
uint16_t min_depth, uint16_t max_depth,
ProbingParserFPtr ProbingParser);
ProbingParserFPtr ProbingParserTs,
ProbingParserFPtr ProbingParserTc);
/***** PM registration *****/

@ -1592,12 +1592,12 @@ void RegisterDNP3Parsers(void)
if (RunmodeIsUnittests()) {
AppLayerProtoDetectPPRegister(IPPROTO_TCP, DNP3_DEFAULT_PORT,
ALPROTO_DNP3, 0, sizeof(DNP3LinkHeader), STREAM_TOSERVER,
DNP3ProbingParser);
DNP3ProbingParser, NULL);
}
else {
if (!AppLayerProtoDetectPPParseConfPorts("tcp", IPPROTO_TCP,
proto_name, ALPROTO_DNP3, 0, sizeof(DNP3LinkHeader),
DNP3ProbingParser)) {
DNP3ProbingParser, NULL)) {
return;
}
}

@ -641,12 +641,12 @@ void RegisterDNSTCPParsers(void)
ALPROTO_DNS,
0, sizeof(DNSTcpHeader),
STREAM_TOSERVER,
DNSTcpProbingParser);
DNSTcpProbingParser, NULL);
} else {
int have_cfg = AppLayerProtoDetectPPParseConfPorts("tcp", IPPROTO_TCP,
proto_name, ALPROTO_DNS,
0, sizeof(DNSTcpHeader),
DNSTcpProbingParser);
DNSTcpProbingParser, NULL);
/* if we have no config, we enable the default port 53 */
if (!have_cfg) {
SCLogWarning(SC_ERR_DNS_CONFIG, "no DNS TCP config found, "
@ -654,7 +654,7 @@ void RegisterDNSTCPParsers(void)
"port 53.");
AppLayerProtoDetectPPRegister(IPPROTO_TCP, "53",
ALPROTO_DNS, 0, sizeof(DNSTcpHeader),
STREAM_TOSERVER, DNSTcpProbingParser);
STREAM_TOSERVER, DNSTcpProbingParser, NULL);
}
}
} else {

@ -395,12 +395,13 @@ void RegisterDNSUDPParsers(void)
ALPROTO_DNS,
0, sizeof(DNSHeader),
STREAM_TOSERVER,
DNSUdpProbingParser);
DNSUdpProbingParser,
NULL);
} else {
int have_cfg = AppLayerProtoDetectPPParseConfPorts("udp", IPPROTO_UDP,
proto_name, ALPROTO_DNS,
0, sizeof(DNSHeader),
DNSUdpProbingParser);
DNSUdpProbingParser, NULL);
/* if we have no config, we enable the default port 53 */
if (!have_cfg) {
SCLogWarning(SC_ERR_DNS_CONFIG, "no DNS UDP config found, "
@ -408,7 +409,7 @@ void RegisterDNSUDPParsers(void)
"port 53.");
AppLayerProtoDetectPPRegister(IPPROTO_UDP, "53",
ALPROTO_DNS, 0, sizeof(DNSHeader),
STREAM_TOSERVER, DNSUdpProbingParser);
STREAM_TOSERVER, DNSUdpProbingParser, NULL);
}
}
} else {

@ -383,27 +383,27 @@ void RegisterENIPUDPParsers(void)
if (RunmodeIsUnittests())
{
AppLayerProtoDetectPPRegister(IPPROTO_UDP, "44818", ALPROTO_ENIP,
0, sizeof(ENIPEncapHdr), STREAM_TOSERVER, ENIPProbingParser);
0, sizeof(ENIPEncapHdr), STREAM_TOSERVER, ENIPProbingParser, NULL);
AppLayerProtoDetectPPRegister(IPPROTO_UDP, "44818", ALPROTO_ENIP,
0, sizeof(ENIPEncapHdr), STREAM_TOCLIENT, ENIPProbingParser);
0, sizeof(ENIPEncapHdr), STREAM_TOCLIENT, ENIPProbingParser, NULL);
} else
{
if (!AppLayerProtoDetectPPParseConfPorts("udp", IPPROTO_UDP,
proto_name, ALPROTO_ENIP, 0, sizeof(ENIPEncapHdr),
ENIPProbingParser))
ENIPProbingParser, ENIPProbingParser))
{
SCLogDebug(
"no ENIP UDP config found enabling ENIP detection on port 44818.");
AppLayerProtoDetectPPRegister(IPPROTO_UDP, "44818",
ALPROTO_ENIP, 0, sizeof(ENIPEncapHdr), STREAM_TOSERVER,
ENIPProbingParser);
ENIPProbingParser, NULL);
AppLayerProtoDetectPPRegister(IPPROTO_UDP, "44818",
ALPROTO_ENIP, 0, sizeof(ENIPEncapHdr), STREAM_TOCLIENT,
ENIPProbingParser);
ENIPProbingParser, NULL);
}
}
@ -471,16 +471,16 @@ void RegisterENIPTCPParsers(void)
if (RunmodeIsUnittests())
{
AppLayerProtoDetectPPRegister(IPPROTO_TCP, "44818", ALPROTO_ENIP,
0, sizeof(ENIPEncapHdr), STREAM_TOSERVER, ENIPProbingParser);
0, sizeof(ENIPEncapHdr), STREAM_TOSERVER, ENIPProbingParser, NULL);
AppLayerProtoDetectPPRegister(IPPROTO_TCP, "44818", ALPROTO_ENIP,
0, sizeof(ENIPEncapHdr), STREAM_TOCLIENT, ENIPProbingParser);
0, sizeof(ENIPEncapHdr), STREAM_TOCLIENT, ENIPProbingParser, NULL);
} else
{
if (!AppLayerProtoDetectPPParseConfPorts("tcp", IPPROTO_TCP,
proto_name, ALPROTO_ENIP, 0, sizeof(ENIPEncapHdr),
ENIPProbingParser))
ENIPProbingParser, ENIPProbingParser))
{
return;
}

@ -1455,14 +1455,14 @@ void RegisterModbusParsers(void)
ALPROTO_MODBUS,
0, sizeof(ModbusHeader),
STREAM_TOSERVER,
ModbusProbingParser);
ModbusProbingParser, NULL);
} else {
/* If there is no app-layer section for Modbus, silently
* leave it disabled. */
if (!AppLayerProtoDetectPPParseConfPorts("tcp", IPPROTO_TCP,
proto_name, ALPROTO_MODBUS,
0, sizeof(ModbusHeader),
ModbusProbingParser)) {
ModbusProbingParser, NULL)) {
#ifndef AFLFUZZ_APPLAYER
return;
#endif

@ -1526,12 +1526,12 @@ void RegisterSMBParsers(void)
ALPROTO_SMB,
SMB_PROBING_PARSER_MIN_DEPTH, 0,
STREAM_TOSERVER,
SMBProbingParser);
SMBProbingParser, NULL);
} else {
AppLayerProtoDetectPPParseConfPorts("tcp", IPPROTO_TCP,
proto_name, ALPROTO_SMB,
SMB_PROBING_PARSER_MIN_DEPTH, 0,
SMBProbingParser);
SMBProbingParser, NULL);
}
AppLayerParserRegisterParserAcceptableDataDirection(IPPROTO_TCP, ALPROTO_SMB, STREAM_TOSERVER);
@ -2217,7 +2217,7 @@ int SMBParserTest05(void)
ALPROTO_SMB,
SMB_PROBING_PARSER_MIN_DEPTH, 0,
STREAM_TOSERVER,
SMBProbingParser);
SMBProbingParser, NULL);
AppLayerProtoDetectPrepareState();
alpd_tctx = AppLayerProtoDetectGetCtxThread();
@ -2301,7 +2301,7 @@ int SMBParserTest06(void)
ALPROTO_SMB,
SMB_PROBING_PARSER_MIN_DEPTH, 0,
STREAM_TOSERVER,
SMBProbingParser);
SMBProbingParser, NULL);
AppLayerProtoDetectPrepareState();
alpd_tctx = AppLayerProtoDetectGetCtxThread();

@ -1766,12 +1766,12 @@ void RegisterSSLParsers(void)
ALPROTO_TLS,
0, 3,
STREAM_TOSERVER,
SSLProbingParser);
SSLProbingParser, NULL);
} else {
AppLayerProtoDetectPPParseConfPorts("tcp", IPPROTO_TCP,
proto_name, ALPROTO_TLS,
0, 3,
SSLProbingParser);
SSLProbingParser, NULL);
}
} else {
SCLogInfo("Protocol detection and parser disabled for %s protocol",

@ -472,21 +472,21 @@ void RegisterTemplateParsers(void)
SCLogNotice("Unittest mode, registeringd default configuration.");
AppLayerProtoDetectPPRegister(IPPROTO_TCP, TEMPLATE_DEFAULT_PORT,
ALPROTO_TEMPLATE, 0, TEMPLATE_MIN_FRAME_LEN, STREAM_TOSERVER,
TemplateProbingParser);
TemplateProbingParser, NULL);
}
else {
if (!AppLayerProtoDetectPPParseConfPorts("tcp", IPPROTO_TCP,
proto_name, ALPROTO_TEMPLATE, 0, TEMPLATE_MIN_FRAME_LEN,
TemplateProbingParser)) {
TemplateProbingParser, NULL)) {
SCLogNotice("No echo app-layer configuration, enabling echo"
" detection TCP detection on port %s.",
TEMPLATE_DEFAULT_PORT);
AppLayerProtoDetectPPRegister(IPPROTO_TCP,
TEMPLATE_DEFAULT_PORT, ALPROTO_TEMPLATE, 0,
TEMPLATE_MIN_FRAME_LEN, STREAM_TOSERVER,
TemplateProbingParser);
TemplateProbingParser, NULL);
}
}

Loading…
Cancel
Save