diff --git a/apache2/apache2_io.c b/apache2/apache2_io.c index 26f6b864..026f195d 100644 --- a/apache2/apache2_io.c +++ b/apache2/apache2_io.c @@ -84,7 +84,8 @@ apr_status_t input_filter(ap_filter_t *f, apr_bucket_brigade *bb_out, return APR_EGENERAL; } - if (chunk && !msr->txcfg->stream_inbody_inspection) { + //if (chunk && !msr->txcfg->stream_inbody_-nspection) { + if (chunk) { /* Copy the data we received in the chunk */ bucket = apr_bucket_heap_create(chunk->data, chunk->length, NULL, f->r->connection->bucket_alloc); @@ -112,7 +113,7 @@ apr_status_t input_filter(ap_filter_t *f, apr_bucket_brigade *bb_out, if (msr->txcfg->debuglog_level >= 4) { msr_log(msr, 4, "Input filter: Forwarded %" APR_SIZE_T_FMT " bytes.", chunk->length); } - } else if (msr->stream_input_data != NULL) { + } /*else if (msr->stream_input_data != NULL) { bucket = apr_bucket_heap_create(msr->stream_input_data, msr->stream_input_length, NULL, f->r->connection->bucket_alloc); @@ -125,7 +126,7 @@ apr_status_t input_filter(ap_filter_t *f, apr_bucket_brigade *bb_out, } } - +*/ if (rc == 0) { modsecurity_request_body_retrieve_end(msr); @@ -262,6 +263,11 @@ apr_status_t read_request_body(modsec_rec *msr, char **error_msg) { } } + if (msr->txcfg->stream_inbody_inspection == 1) { + msr->stream_input_length+=buflen; + modsecurity_request_body_to_stream(msr, buf, buflen, error_msg); + } + if (buflen != 0) { int rcbs = modsecurity_request_body_store(msr, buf, buflen, error_msg); if (rcbs < 0) { diff --git a/apache2/modsecurity.h b/apache2/modsecurity.h index 25472aaf..d7e8122f 100644 --- a/apache2/modsecurity.h +++ b/apache2/modsecurity.h @@ -580,6 +580,8 @@ apr_status_t DSOLOCAL modsecurity_request_body_store(modsec_rec *msr, apr_status_t DSOLOCAL modsecurity_request_body_end(modsec_rec *msr, char **error_msg); +apr_status_t DSOLOCAL modsecurity_request_body_to_stream(modsec_rec *msr, const char *buffer, int buflen, char **error_msg); + apr_status_t DSOLOCAL modsecurity_request_body_retrieve_start(modsec_rec *msr, char **error_msg); apr_status_t DSOLOCAL modsecurity_request_body_retrieve_end(modsec_rec *msr); diff --git a/apache2/msc_reqbody.c b/apache2/msc_reqbody.c index 88739c21..395a2ea2 100644 --- a/apache2/msc_reqbody.c +++ b/apache2/msc_reqbody.c @@ -82,6 +82,7 @@ static apr_status_t modsecurity_request_body_start_init(modsec_rec *msr, char ** apr_status_t modsecurity_request_body_start(modsec_rec *msr, char **error_msg) { *error_msg = NULL; msr->msc_reqbody_length = 0; + msr->stream_input_length = 0; /* Create a separate memory pool that will be used * to allocate structures from (not data, which is allocated @@ -95,7 +96,6 @@ apr_status_t modsecurity_request_body_start(modsec_rec *msr, char **error_msg) { char *my_error_msg = NULL; msre_reqbody_processor_metadata *metadata = (msre_reqbody_processor_metadata *)apr_table_get(msr->modsecurity->msre->reqbody_processors, msr->msc_reqbody_processor); - if (metadata != NULL) { if ( (metadata->init != NULL) @@ -379,27 +379,25 @@ apr_status_t modsecurity_request_body_store(modsec_rec *msr, return -1; } -static apr_status_t modsecurity_request_body_to_stream(modsec_rec *msr, char **error_msg) { - msc_data_chunk **chunks; - char *d; - int i, sofar; +apr_status_t modsecurity_request_body_to_stream(modsec_rec *msr, const char *buffer, int buflen, char **error_msg) { char *stream_input_body = NULL; + char *data = NULL; + int first_pkt = 0; - *error_msg = NULL; - - /* Allocate a buffer large enough to hold the request body. */ - - if (msr->msc_reqbody_length + 1 == 0) { - *error_msg = apr_psprintf(msr->mp, "Internal error, request body length will overflow the stream buffer: %u", - msr->msc_reqbody_length); - return -1; + if(msr->stream_input_data == NULL) { + msr->stream_input_data = (char *)calloc(sizeof(char), msr->stream_input_length + 1); + first_pkt = 1; } - - msr->stream_input_length = msr->msc_reqbody_length; - - if(msr->stream_input_data == NULL) - msr->stream_input_data = (char *)calloc(sizeof(char), msr->stream_input_length + 1); else { + + data = (char *)malloc(msr->stream_input_length + 1 - buflen); + + if(data == NULL) + return -1; + + memset(data, 0, msr->stream_input_length + 1 - buflen); + memcpy(data, msr->stream_input_data, msr->stream_input_length - buflen); + stream_input_body = (char *)realloc(msr->stream_input_data, msr->stream_input_length + 1); if(stream_input_body == NULL) { @@ -411,32 +409,29 @@ static apr_status_t modsecurity_request_body_to_stream(modsec_rec *msr, char **e } if (msr->stream_input_data== NULL) { + if(data) { + free(data); + data = NULL; + } *error_msg = apr_psprintf(msr->mp, "Unable to allocate memory to hold request body on stream. Asked for %" APR_SIZE_T_FMT " bytes.", - msr->stream_input_length + 1); + msr->stream_input_length + 1); return -1; } - msr->stream_input_data[msr->stream_input_length] = '\0'; + if(first_pkt) { + memcpy(msr->stream_input_data, buffer, msr->stream_input_length); + } else { + memcpy(msr->stream_input_data, data, msr->stream_input_length - buflen); + memcpy(msr->stream_input_data+(msr->stream_input_length - buflen), buffer, buflen); + } - /* Copy the data we keep in chunks into the new buffer. */ - - sofar = 0; - d = msr->stream_input_data; - chunks = (msc_data_chunk **)msr->msc_reqbody_chunks->elts; - for(i = 0; i < msr->msc_reqbody_chunks->nelts; i++) { - if (sofar + chunks[i]->length <= msr->stream_input_length) { - memcpy(d, chunks[i]->data, chunks[i]->length); - d += chunks[i]->length; - sofar += chunks[i]->length; - } else { - *error_msg = apr_psprintf(msr->mp, "Internal error, request body buffer overflow."); - return -1; - } + if(data) { + free(data); + data = NULL; } return 1; } - /** * Replace a bunch of chunks holding a request body with a single large chunk. */ @@ -552,9 +547,6 @@ apr_status_t modsecurity_request_body_end(modsec_rec *msr, char **error_msg) { /* Note that we've read the body. */ msr->msc_reqbody_read = 1; - if (msr->txcfg->stream_inbody_inspection) - modsecurity_request_body_to_stream(msr, error_msg); - /* Finalise body processing. */ if ((msr->msc_reqbody_processor != NULL) && (msr->msc_reqbody_error == 0)) { char *my_error_msg = NULL;