protocol-change: sets event in case of failure

Protocol change can fail if one protocol change is already
occuring.

Ticket: #5509
pull/7767/head
Philippe Antoine 3 years ago committed by Victor Julien
parent e94920b49f
commit 11f849c3ee

@ -87,4 +87,6 @@ alert http any any -> any any (msg:"SURICATA HTTP invalid Range header value"; f
alert http any any -> any any (msg:"SURICATA HTTP file name too long"; flow:established; app-layer-event:http.file_name_too_long; flowint:http.anomaly.count,+,1; classtype:protocol-command-decode; sid:2221052; rev:1;)
# next sid 2221053
alert http any any -> any any (msg:"SURICATA HTTP failed protocol change"; flow:established; app-layer-event:http.failed_protocol_change; flowint:http.anomaly.count,+,1; classtype:protocol-command-decode; sid:2221053; rev:1;)
# next sid 2221054

@ -30,4 +30,5 @@ alert smtp any any -> any any (msg:"SURICATA SMTP Mime boundary length exceeded"
alert smtp any any -> any any (msg:"SURICATA SMTP duplicate fields"; flow:established,to_server; app-layer-event:smtp.duplicate_fields; flowint:smtp.anomaly.count,+,1; classtype:protocol-command-decode; sid:2220018; rev:1;)
alert smtp any any -> any any (msg:"SURICATA SMTP unparsable content"; flow:established,to_server; app-layer-event:smtp.unparsable_content; flowint:smtp.anomaly.count,+,1; classtype:protocol-command-decode; sid:2220019; rev:1;)
alert smtp any any -> any any (msg:"SURICATA SMTP filename truncated"; flow:established,to_server; app-layer-event:smtp.mime_long_filename; flowint:smtp.anomaly.count,+,1; classtype:protocol-command-decode; sid:2220020; rev:1;)
# next sid 2220021
alert smtp any any -> any any (msg:"SURICATA SMTP failed protocol change"; flow:established; app-layer-event:smtp.failed_protocol_change; flowint:smtp.anomaly.count,+,1; classtype:protocol-command-decode; sid:2220021; rev:1;)
# next sid 2220022

@ -388,7 +388,7 @@ extern {
pp_min_depth: u16, pp_max_depth: u16) -> c_int;
pub fn AppLayerProtoDetectConfProtoDetectionEnabled(ipproto: *const c_char, proto: *const c_char) -> c_int;
pub fn AppLayerProtoDetectConfProtoDetectionEnabledDefault(ipproto: *const c_char, proto: *const c_char, default: bool) -> c_int;
pub fn AppLayerRequestProtocolTLSUpgrade(flow: *const Flow);
pub fn AppLayerRequestProtocolTLSUpgrade(flow: *const Flow) -> bool;
}
// Defined in app-layer-parser.h

@ -1958,13 +1958,13 @@ void AppLayerProtoDetectRegisterAlias(const char *proto_name, const char *proto_
* \param expect_proto expected protocol. AppLayer event will be set if
* detected protocol differs from this.
*/
void AppLayerRequestProtocolChange(Flow *f, uint16_t dp, AppProto expect_proto)
bool AppLayerRequestProtocolChange(Flow *f, uint16_t dp, AppProto expect_proto)
{
if (FlowChangeProto(f)) {
// If we are already changing protocols, from SMTP to TLS for instance,
// and that we do not get TLS but HTTP1, which is requesting whange to HTTP2,
// we do not proceed the new protocol change
return;
return false;
}
FlowSetChangeProtoFlag(f);
f->protodetect_dp = dp;
@ -1978,6 +1978,7 @@ void AppLayerRequestProtocolChange(Flow *f, uint16_t dp, AppProto expect_proto)
if (f->alproto_tc == ALPROTO_UNKNOWN) {
f->alproto_tc = f->alproto;
}
return true;
}
/** \brief request applayer to wrap up this protocol and rerun protocol
@ -1988,9 +1989,9 @@ void AppLayerRequestProtocolChange(Flow *f, uint16_t dp, AppProto expect_proto)
*
* \param f flow to act on
*/
void AppLayerRequestProtocolTLSUpgrade(Flow *f)
bool AppLayerRequestProtocolTLSUpgrade(Flow *f)
{
AppLayerRequestProtocolChange(f, 443, ALPROTO_TLS);
return AppLayerRequestProtocolChange(f, 443, ALPROTO_TLS);
}
void AppLayerProtoDetectReset(Flow *f)

@ -115,8 +115,8 @@ int AppLayerProtoDetectSetup(void);
*/
void AppLayerProtoDetectReset(Flow *);
void AppLayerRequestProtocolChange(Flow *f, uint16_t dp, AppProto expect_proto);
void AppLayerRequestProtocolTLSUpgrade(Flow *f);
bool AppLayerRequestProtocolChange(Flow *f, uint16_t dp, AppProto expect_proto);
bool AppLayerRequestProtocolTLSUpgrade(Flow *f);
/**
* \brief Cleans up the app layer protocol detection phase.

@ -172,6 +172,7 @@ SCEnumCharMap http_decoder_event_table[] = {
{ "MULTIPART_INVALID_HEADER", HTTP_DECODER_EVENT_MULTIPART_INVALID_HEADER },
{ "TOO_MANY_WARNINGS", HTTP_DECODER_EVENT_TOO_MANY_WARNINGS },
{ "FAILED_PROTOCOL_CHANGE", HTTP_DECODER_EVENT_FAILED_PROTOCOL_CHANGE },
{ NULL, -1 },
};
@ -968,7 +969,10 @@ static AppLayerResult HTPHandleResponseData(Flow *f, void *htp_state, AppLayerPa
}
consumed = htp_connp_res_data_consumed(hstate->connp);
hstate->slice = NULL;
AppLayerRequestProtocolChange(hstate->f, dp, ALPROTO_HTTP2);
if (!AppLayerRequestProtocolChange(hstate->f, dp, ALPROTO_HTTP2)) {
HTPSetEvent(hstate, NULL, STREAM_TOCLIENT,
HTTP_DECODER_EVENT_FAILED_PROTOCOL_CHANGE);
}
// During HTTP2 upgrade, we may consume the HTTP1 part of the data
// and we need to parser the remaining part with HTTP2
if (consumed > 0 && consumed < input_len) {
@ -2282,7 +2286,10 @@ static int HTPCallbackResponseComplete(htp_tx_t *tx)
dp = (uint16_t)tx->request_port_number;
}
// both ALPROTO_HTTP1 and ALPROTO_TLS are normal options
AppLayerRequestProtocolChange(hstate->f, dp, ALPROTO_UNKNOWN);
if (!AppLayerRequestProtocolChange(hstate->f, dp, ALPROTO_UNKNOWN)) {
HTPSetEvent(
hstate, htud, STREAM_TOCLIENT, HTTP_DECODER_EVENT_FAILED_PROTOCOL_CHANGE);
}
tx->request_progress = HTP_REQUEST_COMPLETE;
tx->response_progress = HTP_RESPONSE_COMPLETE;
}

@ -139,6 +139,8 @@ enum {
HTTP_DECODER_EVENT_MULTIPART_INVALID_HEADER,
HTTP_DECODER_EVENT_TOO_MANY_WARNINGS,
HTTP_DECODER_EVENT_FAILED_PROTOCOL_CHANGE,
};
typedef enum HtpSwfCompressType_ {

@ -145,6 +145,7 @@ SCEnumCharMap smtp_decoder_event_table[] = {
{ "NO_SERVER_WELCOME_MESSAGE", SMTP_DECODER_EVENT_NO_SERVER_WELCOME_MESSAGE },
{ "TLS_REJECTED", SMTP_DECODER_EVENT_TLS_REJECTED },
{ "DATA_COMMAND_REJECTED", SMTP_DECODER_EVENT_DATA_COMMAND_REJECTED },
{ "FAILED_PROTOCOL_CHANGE", SMTP_DECODER_EVENT_FAILED_PROTOCOL_CHANGE },
/* MIME Events */
{ "MIME_PARSE_FAILED", SMTP_DECODER_EVENT_MIME_PARSE_FAILED },
@ -944,7 +945,9 @@ static int SMTPProcessReply(SMTPState *state, Flow *f, AppLayerParserState *psta
if (reply_code == SMTP_REPLY_220) {
/* we are entering STARRTTLS data mode */
state->parser_state |= SMTP_PARSER_STATE_COMMAND_DATA_MODE;
AppLayerRequestProtocolTLSUpgrade(f);
if (!AppLayerRequestProtocolTLSUpgrade(f)) {
SMTPSetEvent(state, SMTP_DECODER_EVENT_FAILED_PROTOCOL_CHANGE);
}
if (state->curr_tx) {
SMTPTransactionComplete(state);
}

@ -38,6 +38,7 @@ enum {
SMTP_DECODER_EVENT_NO_SERVER_WELCOME_MESSAGE,
SMTP_DECODER_EVENT_TLS_REJECTED,
SMTP_DECODER_EVENT_DATA_COMMAND_REJECTED,
SMTP_DECODER_EVENT_FAILED_PROTOCOL_CHANGE,
/* MIME Events */
SMTP_DECODER_EVENT_MIME_PARSE_FAILED,

Loading…
Cancel
Save