+16/11/21 - build 219
+
+-- add dce auto detect to wizard
+-- add MIME file processing to new http_inspect
+-- add chapters on perf_monitor and file processing to user manual
+-- appid refactoring and cleanup
+-- many appid fixes for leaks, sanitizer, and analyzer issues
+-- fix appid pattern matching for http
+-- fix various race conditions reported by thread sanitizer
+-- fix out-of-order FIN handling
+-- fix cmake package name used in HS and HWLOC so that REQUIRED works
+-- fix out-of-tree doc builds
+-- fix image sizes to fit page; thanks to wyatuestc for reporting the issue
+-- fix fast pattern selection when multiple designated
+ thanks to j.mcdowell@titanicsystems.com for reporting the issue
+-- change -L to -K in README and manual; thanks to jncornett for reporting the issue
+-- support compiling catch tests in standalone source files
+-- create pid file after dropping privileges
+-- improve detection and use of CppUTest in non-standard locations
+
16/11/04 - build 218
-- fix shutdown stats
return false;
}
- const CiscoMetaDataOpt* cmd_options =
+ const CiscoMetaDataOpt* cmd_options =
reinterpret_cast<const CiscoMetaDataOpt*>(raw.data + sizeof(CiscoMetaDataHdr));
// validate options, lengths, and SGTs
cmdh_rem_len -= sizeof(CiscoMetaDataHdr) + sizeof(uint16_t); //2 octects for ethertype
for(int i = 0; cmdh_rem_len > 0; i++)
{
- // Top 3 bits (length) must be equal to 0 or 4
+ // Top 3 bits (length) must be equal to 0 or 4
// Bottom 13 bits (type) must be 1 to indicate SGT
const CiscoMetaDataOpt* opt = &cmd_options[i];
uint16_t len = ntohs(opt->opt_len_type) >> CISCO_META_OPT_LEN_SHIFT;
return handle;
}
-
+
void TcpConnector::process_receive()
{
TcpConnectorMsgHdr hdr;
run_thread = true;
receive_thread = new std::thread(&TcpConnector::receive_processing_thread, this);
}
-
+
void TcpConnector::stop_receive_thread()
{
if ( receive_thread != nullptr )
delete receive_thread;
}
}
-
+
TcpConnector::TcpConnector(TcpConnectorConfig* tcp_connector_config, int sfd)
{
DebugMessage(DEBUG_CONNECTORS,"TcpConnector::TcpConnector()\n");
sprintf(port_string, "%5d", (cfg->base_port + instance));
TcpConnector* tcp_connector;
-
+
if ( cfg->setup == TcpConnectorConfig::Setup::CALL )
tcp_connector = tcp_connector_tinit_call(cfg, port_string);
else if ( cfg->setup == TcpConnectorConfig::Setup::ANSWER )
(uint8_t)p->ptrs.icmph->type == icmp::Icmp6Types::ECHO_REPLY) )
{
uint16_t icmp_id = ntohs(p->ptrs.icmph->s_icmp_id);
- if ( config.eval( icmp_id ) )
+ if ( config.eval( icmp_id ) )
return DETECTION_OPTION_MATCH;
}
return DETECTION_OPTION_NO_MATCH;
bool operator==(const IpsOption&) const override;
int eval(Cursor&, Packet*) override;
-
+
private:
uint32_t get_int(const uint8_t *&);
bool check_rpc_call(const uint8_t *&);
const uint32_t RPC_MSG_VERSION = 2;
const uint32_t CALL = 0;
-
+
RpcCheckData config;
};
return DETECTION_OPTION_NO_MATCH;
}
-// check if there is a detection match
+// check if there is a detection match
bool RpcOption::is_match(Packet * p)
-{
- // get pointer to packet data
+{
+ // get pointer to packet data
const uint8_t* packet_data = p->data;
-
+
// read xid.. not being used currently
// so just move to the next int
- packet_data += 4;
+ packet_data += 4;
// read direction .. CALL or REPLY etc..
uint32_t message_type = get_int(packet_data);
{
return false;
}
-
+
// assumed to be valid packet
return true;
}
if ( !check_procedure(procedure) )
return false;
- // if nothing fails, return a match
+ // if nothing fails, return a match
return true;
-}
+}
-// only check program values
+// only check program values
bool RpcOption::check_program( uint32_t program )
{
return (config.program == program);
if(config.flags & RPC_CHECK_VERSION)
{
return (config.version == version);
- }
-
+ }
+
return true;
}
{
return (config.procedure == procedure);
}
-
+
return true;
-}
+}
//-------------------------------------------------------------------------
// module
// //
//-----------------------------------------------//
-#define BUILD "218"
+#define BUILD "219"
#endif
TEST_CASE("trace_log", "[trace]")
{
Trace TRACE_NAME(testing) = TRACE_SECTION_2 | TRACE_SECTION_3;
-
+
testing_dump[0] = '\0';
trace_log(testing, "my message");
CHECK( !strcmp(testing_dump, "testing: my message") );
TEST_CASE("trace_logf", "[trace]")
{
Trace TRACE_NAME(testing) = TRACE_SECTION_2 | TRACE_SECTION_3;
-
+
testing_dump[0] = '\0';
trace_logf(testing, "%s %s", "my", "message");
CHECK( !strcmp(testing_dump, "testing: my message") );
TEST_CASE("trace_debug", "[trace]")
{
Trace TRACE_NAME(testing) = TRACE_SECTION_2 | TRACE_SECTION_3;
-
+
testing_dump[0] = '\0';
trace_debug(testing, "my message"); CHECK( !strcmp(testing_dump, "testing: " __FILE__ ":" sx(__LINE__) ": my message") );
TEST_CASE("trace_debugf", "[trace]")
{
Trace TRACE_NAME(testing) = TRACE_SECTION_2 | TRACE_SECTION_3;
-
+
testing_dump[0] = '\0';
trace_debugf(testing, "%s %s", "my", "message"); CHECK( !strcmp(testing_dump, "testing: " __FILE__ ":" sx(__LINE__) ": my message") );
{
dump_field(s, pfx, m->params);
}
-
+
s = m->name;
if ( m->default_params )
assert(data);
if(*data)
snort_free(*data);
-
+
*data = (char*)snort_alloc(header_length + 1);
memcpy(*data, header_start, header_length);
*(*data + header_length) = '\0';
{ "bootp_flows", "count of bootp flows discovered by appid" },
{ "dcerpc_tcp_flows", "count of dce rpc flows over tcp discovered by appid" },
{ "dcerpc_udp_flows", "count of dce rpc flows over udp discovered by appid" },
- { "direct_connect_flows", "count of direct connect flows discovered by appid" },
+ { "direct_connect_flows", "count of direct connect flows discovered by appid" },
{ "dns_tcp_flows", "count of dns flows over tcp discovered by appid" },
{ "dns_udp_flows", "count of dns flows over udp discovered by appid" },
{ "ftp_flows", "count of ftp flows discovered by appid" },
int mlpProcessPatterns(void* root);
void* mlpMatchPatternLongest(void* root, tMlpPattern** inputPatternList);
void* mlpMatchPatternUrl(void* root, tMlpPattern** inputPatternList);
-void* mlpMatchPatternCustom(void* root, tMlpPattern** inputPatternList,
+void* mlpMatchPatternCustom(void* root, tMlpPattern** inputPatternList,
int (* callback)(void*, void*, int, void*, void*));
void mlpDestroy(void* root);
void mlpDump(void* root);
return 0;
}
-static inline uint8_t* continue_buffer_scan(const uint8_t* start, const uint8_t* end, MatchedPatterns* mp,
- DetectorHTTPPattern* match)
+static inline uint8_t* continue_buffer_scan(
+ const uint8_t* start, const uint8_t* end, MatchedPatterns* mp, DetectorHTTPPattern*)
{
uint8_t* bp = (uint8_t*) (start) + mp->index;
if( (bp >= end) || (*bp != ' ' && *bp != 0x09 && *bp != '/') )
case APP_ID_GOOGLE_DESKTOP:
buffPtr = (uint8_t*)start + tmp->index;
-
+
if(buffPtr >= end)
- break;
-
+ break;
+
if (*buffPtr != ')')
{
if (*buffPtr != ' ' && *buffPtr != 0x09 && *buffPtr != '/')
case APP_ID_WGET:
buffPtr = (uint8_t*)start + tmp->index;
if(buffPtr >= end)
- break;
+ break;
while (i < MAX_VERSION_SIZE - 1 && buffPtr < end)
{
temp_ver[i++] = *buffPtr++;
buffPtr = (uint8_t*)start + tmp->index;
if(buffPtr >= end)
- break;
+ break;
if (*buffPtr == (uint8_t)'/')
{
{
case APP_ID_SQUID:
data_ptr = (uint8_t*)data + mp->index;
-
+
if (data_ptr >= end)
break;
-
+
if (*data_ptr == '/')
{
data_ptr++;
void Debug::print(const char*, int, uint64_t, const char*, ...) { }
#endif
-struct AddAppData
+struct AddAppData
{
AppId client_id = 0;
std::string *version_str = nullptr;
app_data.version_str = new std::string(version);
}
-ClientAppApi fake_clientappapi =
+ClientAppApi fake_clientappapi =
{
nullptr,
nullptr,
ud->appid_config->tcp_port_only[port] = appId;
else if (protocol == 17)
ud->appid_config->udp_port_only[port] = appId;
-
+
AppInfoManager::get_instance().set_app_info_active(appId);
return 0;
{
TestData test_data;
test_data.scan_flags = 0;
-
+
run_event_handler(test_data);
}
TestData test_data;
test_data.scan_flags = SCAN_HTTP_HOST_URL_FLAG;
test_data.host = HOST;
-
+
run_event_handler(test_data);
}
TestData test_data;
test_data.scan_flags = 0;
test_data.cookie = COOKIE;
-
+
run_event_handler(test_data);
}
test_data.scan_flags = SCAN_HTTP_HOST_URL_FLAG;
test_data.host = HOST;
test_data.uri = URI;
-
+
run_event_handler(test_data);
}
TestData test_data;
test_data.scan_flags = SCAN_HTTP_USER_AGENT_FLAG;
test_data.useragent = USERAGENT;
-
+
run_event_handler(test_data);
}
TestData test_data;
test_data.scan_flags = 0;
test_data.x_working_with = X_WORKING_WITH;
-
+
run_event_handler(test_data);
}
TestData test_data;
test_data.scan_flags = 0;
test_data.referer = REFERER;
-
+
run_event_handler(test_data);
}
TestData test_data;
test_data.scan_flags = SCAN_HTTP_VIA_FLAG;
test_data.via = VIA;
-
+
run_event_handler(test_data);
}
test_data.scan_flags = 0;
test_data.http_flows = 0; // Flows are only counted on request header
test_data.content_type = CONTENT_TYPE;
-
+
run_event_handler(test_data);
}
test_data.scan_flags = 0;
test_data.http_flows = 0; // Flows are only counted on request header
test_data.location = LOCATION;
-
+
run_event_handler(test_data);
}
test_data.scan_flags = 0;
test_data.http_flows = 0; // Flows are only counted on request header
test_data.server = SERVER;
-
+
run_event_handler(test_data);
}
test_data.scan_flags = 0;
test_data.http_flows = 0; // Flows are only counted on request header
test_data.response_code = RESPONSE_CODE;
-
+
run_event_handler(test_data);
}
test_data.scan_flags = 0;
test_data.http_flows = 0; // Flows are only counted on request header
test_data.response_code = 1000;
-
+
TestData expect_data = test_data;
expect_data.response_code = 0;
test_data.referer = REFERER;
test_data.useragent = USERAGENT;
test_data.cookie = COOKIE;
-
+
run_event_handler(test_data, &expect_data);
}
test_data.response_code = RESPONSE_CODE;
test_data.content_type = CONTENT_TYPE;
test_data.location = LOCATION;
-
+
run_event_handler(test_data, &expect_data);
}
++bstats.verdicts[stuff.action];
return 0;
}
-
+
int Binder::exec(int operation, void* pv)
{
switch( operation )
const uint8_t* HttpEvent::get_content_type(int32_t& length)
{
- return get_header(HttpEnums::HTTP_BUFFER_HEADER,
+ return get_header(HttpEnums::HTTP_BUFFER_HEADER,
HttpEnums::HEAD_CONTENT_TYPE, length);
}
const uint8_t* HttpEvent::get_via(int32_t& length)
{
- return get_header(HttpEnums::HTTP_BUFFER_HEADER, HttpEnums::HEAD_VIA,
+ return get_header(HttpEnums::HTTP_BUFFER_HEADER, HttpEnums::HEAD_VIA,
length);
}
const uint8_t* HttpEvent::get_x_working_with(int32_t& length)
{
- return get_header(HttpEnums::HTTP_BUFFER_HEADER,
+ return get_header(HttpEnums::HTTP_BUFFER_HEADER,
HttpEnums::HEAD_X_WORKING_WITH, length);
}
{
if( !current_media_session )
return nullptr;
-
+
auto session = new SipEventMediaSession(current_media_session);
sessions.push_front(session);
{
if( !current_media_data )
return nullptr;
-
+
auto d = new SipEventMediaData(current_media_data);
data.push_front(d);
-
+
current_media_data = current_media_data->nextM;
-
- return d;
+
+ return d;
}
{
public:
SipEventMediaData(SIP_MediaData* data)
- { this->data = data; }
-
+ { this->data = data; }
+
const sfip_t* get_address() const;
uint16_t get_port() const;
{
}
-SO_PUBLIC void LogMessage(const char*, ...)
+SO_PUBLIC void LogMessage(const char*, ...)
{
}
dce2_smb_sess->sd.wire_pkt = p;
dce2_smb_sess->sd.config = (void*)config;
}
-
+
return dce2_smb_sess;
}
{
dce2_smb_sess = dce2_create_new_smb_session(p, config);
}
-
+
DebugFormat(DEBUG_DCE_SMB, "Session pointer: %p\n", (void*)dce2_smb_sess);
return dce2_smb_sess;
{
charset_code = (CharsetCode)substr_to_code(last_token.start, last_token.length, HttpMsgHeadShared::charset_code_opt_list);
- if( charset_code != CHARSET_UNKNOWN )
+ if ( charset_code != CHARSET_UNKNOWN )
return;
}
else if ( charset_code == CHARSET_UTF7 )
case SMTP_PAF_DATA_STATE:
if (pfdata->cmd_info.search_id == SMTP_PAF_AUTH_CMD)
{
- if ( max_auth_command_line_len &&
+ if ( max_auth_command_line_len &&
(((int)i + pfdata->data_info.boundary_len) > max_auth_command_line_len) &&
!alert_generated)
{
assert(msg);
// Is the message long enough to have our content?
- if ( ((unsigned)(msg->content_length()) - (unsigned)(msg->cursor - msg->content())) <
+ if ( ((unsigned)(msg->content_length()) - (unsigned)(msg->cursor - msg->content())) <
sizeof(SessionHAContent) )
return false;
}
void TcpSession::check_fin_transition_status(TcpSegmentDescriptor& tsd)
{
- if((tsd.get_seg_len() != 0) &&
+ if((tsd.get_seg_len() != 0) &&
SEQ_EQ(listener->get_fin_final_seq(), listener->r_nxt_ack))
{
listener->set_tcp_event(TcpStreamTracker::TCP_FIN_RECV_EVENT);
listener = trk.session->client;
trk.update_on_fin_sent(tsd);
- if( SEQ_EQ(tsd.get_end_seq(), (listener->r_nxt_ack + tsd.get_seg_len())) || listener->process_inorder_fin()
- || !listener->is_segment_seq_valid(tsd) )
+ if ( SEQ_EQ(tsd.get_end_seq(), (listener->r_nxt_ack + tsd.get_seg_len())) ||
+ listener->process_inorder_fin() || !listener->is_segment_seq_valid(tsd) )
{
trk.session->eof_handle(tsd.get_pkt());
trk.set_tcp_state(TcpStreamTracker::TCP_FIN_WAIT1);
else if (!keyword.compare("ascii"))
parse_deleted_option("ascii", data_stream);
-
+
else if (!keyword.compare("utf_8"))
{
table_api.add_diff_option_comment("utf_8", "utf8");
tmpval = parse_yn_bool_option("utf8", data_stream, false);
}
-
+
else if (!keyword.compare("u_encode"))
{
table_api.add_diff_option_comment("u_encode", "percent_u");