namespace NHttpEnums {
-static const uint32_t MAXOCTETS = 63780;
+static const int MAXOCTETS = 63780;
+static const int DATABLOCKSIZE = 16384;
static const uint32_t NHTTP_GID = 119;
int num_matches = 0;
int32_t buffer_length = 0;
- int curr_match;
+ int curr_match = -1; // FIXIT-P initialization that serves no functional purpose to prevent compiler warning
for (int k=0; k < num_headers; k++) {
if (header_name_id[k] == head_id) {
if (++num_matches == 1) curr_match = k; // remembering location of the first matching header
#include "snort.h"
#include "stream/stream_api.h"
#include "nhttp_enum.h"
-#include "nhttp_stream_splitter.h"
-#include "nhttp_api.h"
+#include "nhttp_msg_request.h"
+#include "nhttp_msg_status.h"
+#include "nhttp_msg_header.h"
+#include "nhttp_msg_body.h"
+#include "nhttp_msg_chunk.h"
+#include "nhttp_msg_trailer.h"
+#include "nhttp_test_manager.h"
#include "nhttp_inspect.h"
using namespace NHttpEnums;
}
}
-bool NHttpInspect::enabled ()
-{
- return true;
-}
-
-bool NHttpInspect::configure (SnortConfig *)
-{
- return true;
-}
-
bool NHttpInspect::get_buf(InspectionBuffer::Type ibt, Packet* p, InspectionBuffer& b)
{
switch ( ibt )
{
const HttpBuffer* h = GetHttpBuffer((HTTP_BUFFER)id);
- if ( !h )
+ if (!h) {
return false;
+ }
b.data = h->buf;
b.len = h->length;
return true;
}
-int NHttpInspect::verify(SnortConfig*)
-{
- return 0;
-}
-
-void NHttpInspect::show(SnortConfig*)
-{
- LogMessage("NHttpInspect\n");
-}
-
ProcessResult NHttpInspect::process(const uint8_t* data, const uint16_t dsize, Flow* const flow, SourceId source_id, bool buf_owner)
{
NHttpFlowData* session_data = (NHttpFlowData*)flow->get_application_data(NHttpFlowData::nhttp_flow_id);
//-------------------------------------------------------------------------
#include "framework/inspector.h"
-#include "nhttp_msg_request.h"
-#include "nhttp_msg_status.h"
-#include "nhttp_msg_header.h"
-#include "nhttp_msg_body.h"
-#include "nhttp_msg_chunk.h"
-#include "nhttp_msg_trailer.h"
-#include "nhttp_test_manager.h"
#include "nhttp_stream_splitter.h"
-#include "nhttp_test_input.h"
class NHttpApi;
class NHttpInspect : public Inspector {
public:
- NHttpInspect(bool test_input_, bool _test_output_);
+ NHttpInspect(bool test_input, bool test_output);
bool get_buf(InspectionBuffer::Type, Packet*, InspectionBuffer&);
bool get_buf(unsigned, Packet*, InspectionBuffer&);
- bool configure(SnortConfig*);
- int verify(SnortConfig*);
- void show(SnortConfig*);
+ bool configure(SnortConfig*) { return true; };
+ int verify(SnortConfig*) { return 0; };
+ void show(SnortConfig*) { LogMessage("NHttpInspect\n"); };
void eval(Packet*) { return; };
- bool enabled();
+ bool enabled() { return true; };
void tinit() {};
void tterm() {};
NHttpStreamSplitter* get_splitter(bool is_client_to_server) { return new
// size does exceed paf_max.
if ((session_data->type_expected[source_id] == SEC_BODY) &&
(session_data->data_length[source_id] <= session_data->unused_octets_visible[source_id]) &&
- (session_data->data_length[source_id] <= 16384) &&
- (session_data->section_buffer_length[source_id] + msg_text.length + session_data->data_length[source_id] <= 63780))
+ (session_data->data_length[source_id] <= DATABLOCKSIZE) &&
+ (session_data->section_buffer_length[source_id] + msg_text.length + session_data->data_length[source_id] <= MAXOCTETS))
{
return RES_AGGREGATE;
}
#include "snort.h"
#include "nhttp_enum.h"
-#include "nhttp_normalizers.h"
#include "nhttp_msg_request.h"
#include "nhttp_msg_header.h"
}
void NHttpMsgRequest::parse_start_line() {
+ // FIXIT-M this needs to be redesigned to parse a truncated request line and extract the method and URI.
+ // The current implementation just gives up if the " HTTP/X.Y" isn't in its proper place at the end of the line.
+
// There should be exactly two spaces. One following the method and one before "HTTP/".
- // Additional spaces located within the URI are not allowed but we will tolerate it
+ // Additional spaces located within the URI are not allowed by RFC but we will tolerate it
// <method><SP><URI><SP>HTTP/X.Y
if (start_line.start[start_line.length-9] != ' ') {
// space before "HTTP" missing or in wrong place
else if ((version.start[5] == '2') && (version.start[7] == '0')) {
version_id = VERS_2_0;
}
- else if ((version.start[5] >= '0') && (version.start[5] <= '9') && (version.start[7] >= '0') && (version.start[7] <= '9')) {
+ else if ((version.start[5] >= '0') && (version.start[5] <= '9') &&
+ (version.start[7] >= '0') && (version.start[7] <= '9')) {
version_id = VERS__OTHER;
infractions |= INF_UNKNOWNVERSION;
}
}
void NHttpMsgStatus::parse_start_line() {
+ // FIXIT-M need to be able to parse a truncated status line and extract version and status code.
+
// Eventually we may need to cater to certain format errors, but for now exact match or treat as error.
// HTTP/X.Y<SP>###<SP><text>
if ((start_line.length < 13) || (start_line.start[8] != ' ') || (start_line.start[12] != ' ')) {
session_data->infractions[source_id] = infractions;
switch (section_type) {
case SEC_BODY:
- paf_max = 16384;
+ paf_max = DATABLOCKSIZE;
break;
case SEC_CHUNK:
- paf_max = 16384 - session_data->chunk_buffer_length[source_id];
+ paf_max = DATABLOCKSIZE - session_data->chunk_buffer_length[source_id];
if (num_excess == 1) {
// zero-length chunk
session_data->type_expected[source_id] = SEC_TRAILER;
}
break;
default:
- paf_max = 63780;
+ paf_max = MAXOCTETS;
break;
}
if (tcp_close) {
StreamSplitter::Status NHttpStreamSplitter::scan (Flow* flow, const uint8_t* data, uint32_t length, uint32_t,
uint32_t* flush_offset) {
- assert(length <= 63780);
+ assert(length <= MAXOCTETS);
// When the system begins providing TCP connection close information this won't always be false. FIXIT-H
bool tcp_close = false;
default: assert(0); break;
}
- const uint32_t max_length = 63780 - splitter->get_octets_seen();
+ const uint32_t max_length = MAXOCTETS - splitter->get_octets_seen();
const ScanResult split_result = splitter->split(data, (length <= max_length) ? length : max_length);
switch (split_result) {
case SCAN_NOTFOUND:
- if (splitter->get_octets_seen() == 63780) {
+ if (splitter->get_octets_seen() == MAXOCTETS) {
// FIXIT-H need to process this data (except chunk header) not just discard it.
prepare_flush(session_data, flush_offset, source_id, SEC_DISCARD, tcp_close, 0, length, length, 0);
session_data->type_expected[source_id] = SEC_ABORT;
int32_t& buffer_length = !is_chunk ? session_data->section_buffer_length[source_id] : chunk_buffer_length;
if (buffer == nullptr) {
- buffer = new uint8_t[63780];
+ buffer = new uint8_t[MAXOCTETS];
}
uint32_t num_excess = session_data->num_excess[source_id];
// all the chunks in the buffer go to the inspector together. Zero-length chunk (len == 1, num_excess == 1)
// flushes accumulated chunks.
int32_t total_chunk_len = chunk_buffer_length + offset + len - num_excess;
- if ((total_chunk_len < 16384) && (num_excess == 0) && !tcp_close) {
+ if ((total_chunk_len < DATABLOCKSIZE) && (num_excess == 0) && !tcp_close) {
chunk_buffer_length = total_chunk_len;
return nullptr;
}
chunk_buffer_length = 0;
return nullptr;
}
- paf_max = 16384;
+ paf_max = DATABLOCKSIZE;
send_to_detection = my_inspector->process(chunk_buffer, total_chunk_len, flow, source_id, true);
}
const StreamBuffer* reassemble(Flow* flow, unsigned /* total*/, unsigned offset, const uint8_t* data, unsigned len,
uint32_t flags, unsigned& copied);
bool is_paf() { return true; };
- unsigned max() { return NHttpTestManager::use_test_input() ? 16384 : paf_max; };
+ unsigned max() { return NHttpTestManager::use_test_input() ? NHttpEnums::DATABLOCKSIZE : paf_max; };
private:
void prepare_flush(NHttpFlowData* session_data, uint32_t* flush_offset, NHttpEnums::SourceId source_id,
NHttpEnums::SectionType section_type, bool tcp_close, uint64_t infractions, uint32_t num_octets, uint32_t length,
uint32_t num_excess);
void create_event(NHttpEnums::EventSid sid);
NHttpInspect* const my_inspector;
- unsigned paf_max = 63780;
+ unsigned paf_max = NHttpEnums::MAXOCTETS;
};
#endif
int new_char;
typedef enum { WAITING, COMMENT, COMMAND, SECTION, ESCAPE, HEXVAL } State;
State state = WAITING;
- bool ending;
- int command_length;
+ bool ending = false;
+ int command_length = 0;
const int max_command = 100;
char command_value[max_command];
- uint8_t hex_val;
- int num_digits;
+ uint8_t hex_val = 0;
+ int num_digits = 0;
while ((new_char = getc(test_data_file)) != EOF) {
switch (state) {