From 43b39d333f2b006dc890b881e2e109e9773f20d0 Mon Sep 17 00:00:00 2001 From: Victor Julien Date: Tue, 1 Oct 2013 13:49:39 +0200 Subject: [PATCH] http: fix some decoder events Some events we retrieved from error messages are flag now, so check those. Not all can be converted though. These are no longer set: HTTP_DECODER_EVENT_INVALID_TRANSFER_ENCODING_VALUE_IN_RESPONSE HTTP_DECODER_EVENT_INVALID_AUTHORITY_PORT Part of Bug #982. --- src/app-layer-htp.c | 53 ++++++++++++++++++++++++++++++++++++++------- 1 file changed, 45 insertions(+), 8 deletions(-) diff --git a/src/app-layer-htp.c b/src/app-layer-htp.c index 7411c39dba..f1d728c1aa 100644 --- a/src/app-layer-htp.c +++ b/src/app-layer-htp.c @@ -399,23 +399,24 @@ void AppLayerHtpNeedFileInspection(void) SCReturn; } +/* below error messages updated up to libhtp 0.5.7 (git 379632278b38b9a792183694a4febb9e0dbd1e7a) */ struct { char *msg; int de; } htp_errors[] = { { "GZip decompressor: inflateInit2 failed", HTTP_DECODER_EVENT_GZIP_DECOMPRESSION_FAILED}, { "Request field invalid: colon missing", HTTP_DECODER_EVENT_REQUEST_FIELD_MISSING_COLON}, - { "Response field invalid: colon missing", HTTP_DECODER_EVENT_RESPONSE_FIELD_MISSING_COLON}, + { "Response field invalid: missing colon", HTTP_DECODER_EVENT_RESPONSE_FIELD_MISSING_COLON}, { "Request chunk encoding: Invalid chunk length", HTTP_DECODER_EVENT_INVALID_REQUEST_CHUNK_LEN}, { "Response chunk encoding: Invalid chunk length", HTTP_DECODER_EVENT_INVALID_RESPONSE_CHUNK_LEN}, - { "Invalid T-E value in request", HTTP_DECODER_EVENT_INVALID_TRANSFER_ENCODING_VALUE_IN_REQUEST}, - { "Invalid T-E value in response", HTTP_DECODER_EVENT_INVALID_TRANSFER_ENCODING_VALUE_IN_RESPONSE}, - { "Invalid C-L field in request", HTTP_DECODER_EVENT_INVALID_CONTENT_LENGTH_FIELD_IN_REQUEST}, +/* { "Invalid T-E value in request", HTTP_DECODER_EVENT_INVALID_TRANSFER_ENCODING_VALUE_IN_REQUEST}, <- tx flag HTP_REQUEST_INVALID_T_E + { "Invalid T-E value in response", HTTP_DECODER_EVENT_INVALID_TRANSFER_ENCODING_VALUE_IN_RESPONSE}, <- nothing to replace it */ +/* { "Invalid C-L field in request", HTTP_DECODER_EVENT_INVALID_CONTENT_LENGTH_FIELD_IN_REQUEST}, <- tx flag HTP_REQUEST_INVALID_C_L */ { "Invalid C-L field in response", HTTP_DECODER_EVENT_INVALID_CONTENT_LENGTH_FIELD_IN_RESPONSE}, { "Already seen 100-Continue", HTTP_DECODER_EVENT_100_CONTINUE_ALREADY_SEEN}, { "Unable to match response to request", HTTP_DECODER_EVENT_UNABLE_TO_MATCH_RESPONSE_TO_REQUEST}, { "Invalid server port information in request", HTTP_DECODER_EVENT_INVALID_SERVER_PORT_IN_REQUEST}, - { "Invalid authority port", HTTP_DECODER_EVENT_INVALID_AUTHORITY_PORT}, +/* { "Invalid authority port", HTTP_DECODER_EVENT_INVALID_AUTHORITY_PORT}, htp no longer returns this error */ { "Request buffer over", HTTP_DECODER_EVENT_REQUEST_FIELD_TOO_LONG}, { "Response buffer over", HTTP_DECODER_EVENT_RESPONSE_FIELD_TOO_LONG}, }; @@ -429,11 +430,14 @@ struct { { "Response field invalid", HTTP_DECODER_EVENT_RESPONSE_HEADER_INVALID}, { "Request header name is not a token", HTTP_DECODER_EVENT_REQUEST_HEADER_INVALID}, { "Response header name is not a token", HTTP_DECODER_EVENT_RESPONSE_HEADER_INVALID}, - { "Host information in request headers required by HTTP/1.1", HTTP_DECODER_EVENT_MISSING_HOST_HEADER}, - { "Host information ambiguous", HTTP_DECODER_EVENT_HOST_HEADER_AMBIGUOUS}, +/* { "Host information in request headers required by HTTP/1.1", HTTP_DECODER_EVENT_MISSING_HOST_HEADER}, <- tx flag HTP_HOST_MISSING + { "Host information ambiguous", HTTP_DECODER_EVENT_HOST_HEADER_AMBIGUOUS}, <- tx flag HTP_HOST_AMBIGUOUS */ { "Invalid request field folding", HTTP_DECODER_EVENT_INVALID_REQUEST_FIELD_FOLDING}, { "Invalid response field folding", HTTP_DECODER_EVENT_INVALID_RESPONSE_FIELD_FOLDING}, - { "Request server port number differs from the actual TCP port", HTTP_DECODER_EVENT_REQUEST_SERVER_PORT_TCP_PORT_MISMATCH}, + /* line is now: htp_log(connp, HTP_LOG_MARK, HTP_LOG_ERROR, 0, "Request server port=%d number differs from the actual TCP port=%d", port, connp->conn->server_port); + * luckily, "Request server port=" is unique */ +/* { "Request server port number differs from the actual TCP port", HTTP_DECODER_EVENT_REQUEST_SERVER_PORT_TCP_PORT_MISMATCH}, */ + { "Request server port=", HTTP_DECODER_EVENT_REQUEST_SERVER_PORT_TCP_PORT_MISMATCH}, }; #define HTP_ERROR_MAX (sizeof(htp_errors) / sizeof(htp_errors[0])) @@ -554,6 +558,29 @@ static void HTPHandleWarning(HtpState *s) { } } +static inline void HTPErrorCheckTxRequestFlags(HtpState *s, htp_tx_t *tx) +{ +#ifdef DEBUG + BUG_ON(s == NULL || tx == NULL); +#endif + if (tx->flags & ( HTP_REQUEST_INVALID_T_E|HTP_REQUEST_INVALID_C_L| + HTP_HOST_MISSING|HTP_HOST_AMBIGUOUS)) + { + if (tx->flags & HTP_REQUEST_INVALID_T_E) + AppLayerDecoderEventsSetEvent(s->f, + HTTP_DECODER_EVENT_INVALID_TRANSFER_ENCODING_VALUE_IN_REQUEST); + if (tx->flags & HTP_REQUEST_INVALID_C_L) + AppLayerDecoderEventsSetEvent(s->f, + HTTP_DECODER_EVENT_INVALID_CONTENT_LENGTH_FIELD_IN_REQUEST); + if (tx->flags & HTP_HOST_MISSING) + AppLayerDecoderEventsSetEvent(s->f, + HTTP_DECODER_EVENT_MISSING_HOST_HEADER); + if (tx->flags & HTP_HOST_AMBIGUOUS) + AppLayerDecoderEventsSetEvent(s->f, + HTTP_DECODER_EVENT_HOST_HEADER_AMBIGUOUS); + } +} + /** * \brief Function to handle the reassembled data from client and feed it to * the HTP library to process it. @@ -1890,6 +1917,8 @@ static int HTPCallbackRequest(htp_tx_t *tx) { SCLogDebug("HTTP request completed"); if (tx != NULL) { + HTPErrorCheckTxRequestFlags(hstate, tx); + HtpTxUserData *htud = (HtpTxUserData *)htp_tx_get_user_data(tx); if (htud != NULL) { if (htud->tsflags & HTP_FILENAME_SET) { @@ -1961,6 +1990,10 @@ static int HTPCallbackRequestLine(htp_tx_t *tx) tx_ud->request_uri_normalized = request_uri_normalized; htp_tx_set_user_data(tx, tx_ud); + if (tx && tx->flags) { + HtpState *hstate = htp_connp_get_user_data(tx->connp); + HTPErrorCheckTxRequestFlags(hstate, tx); + } return HTP_OK; } @@ -2011,6 +2044,10 @@ static int HTPCallbackRequestHeaderData(htp_tx_data_t *tx_data) tx_data->data, tx_data->len); tx_ud->request_headers_raw_len += tx_data->len; + if (tx_data->tx && tx_data->tx->flags) { + HtpState *hstate = htp_connp_get_user_data(tx_data->tx->connp); + HTPErrorCheckTxRequestFlags(hstate, tx_data->tx); + } return HTP_OK; }