mirror of
https://github.com/zeek/zeek.git
synced 2025-10-06 16:48:19 +00:00
HTTP: Recognize and skip upgrade/websocket connections.
This adds a slight patch to the HTTP analyzer, which recognizez when a connection is upgraded to a different protocol (using a 101 reply with a few specific headers being set). In this case, the analyzer stops further processing of the connection (which will result in DPD errors) and raises a new event: event http_connection_upgrade(c: connection, protocol: string); Protocol contains the name of the protocol that is being upgraded to, as specified in one of the header values.
This commit is contained in:
parent
dbac2b1abb
commit
eab80c8834
8 changed files with 122 additions and 42 deletions
|
@ -822,6 +822,9 @@ HTTP_Analyzer::HTTP_Analyzer(Connection* conn)
|
|||
|
||||
connect_request = false;
|
||||
pia = 0;
|
||||
upgraded = false;
|
||||
upgrade_connection = false;
|
||||
upgrade_protocol.clear();
|
||||
|
||||
content_line_orig = new tcp::ContentLine_Analyzer(conn, true);
|
||||
AddSupportAnalyzer(content_line_orig);
|
||||
|
@ -879,6 +882,9 @@ void HTTP_Analyzer::DeliverStream(int len, const u_char* data, bool is_orig)
|
|||
if ( TCP() && TCP()->IsPartial() )
|
||||
return;
|
||||
|
||||
if ( upgraded )
|
||||
return;
|
||||
|
||||
if ( pia )
|
||||
{
|
||||
// There will be a PIA instance if this connection has been identified
|
||||
|
@ -1468,15 +1474,35 @@ void HTTP_Analyzer::ReplyMade(const int interrupted, const char* msg)
|
|||
unanswered_requests.pop();
|
||||
}
|
||||
|
||||
reply_code = 0;
|
||||
|
||||
if ( reply_reason_phrase )
|
||||
{
|
||||
Unref(reply_reason_phrase);
|
||||
reply_reason_phrase = 0;
|
||||
}
|
||||
|
||||
if ( interrupted )
|
||||
// unanswered requests = 1 because there is no pop after 101.
|
||||
if ( reply_code == 101 && unanswered_requests.size() == 1 && upgrade_connection &&
|
||||
upgrade_protocol.size() )
|
||||
{
|
||||
// Upgraded connection that switches immediately - e.g. websocket.
|
||||
upgraded = true;
|
||||
RemoveSupportAnalyzer(content_line_orig);
|
||||
RemoveSupportAnalyzer(content_line_resp);
|
||||
|
||||
if ( http_connection_upgrade )
|
||||
{
|
||||
val_list* vl = new val_list();
|
||||
vl->append(BuildConnVal());
|
||||
vl->append(new StringVal(upgrade_protocol));
|
||||
ConnectionEvent(http_connection_upgrade, vl);
|
||||
}
|
||||
}
|
||||
|
||||
reply_code = 0;
|
||||
upgrade_connection = false;
|
||||
upgrade_protocol.clear();
|
||||
|
||||
if ( interrupted || upgraded )
|
||||
reply_state = EXPECT_REPLY_NOTHING;
|
||||
else
|
||||
reply_state = EXPECT_REPLY_LINE;
|
||||
|
@ -1611,11 +1637,17 @@ void HTTP_Analyzer::HTTP_Header(int is_orig, mime::MIME_Header* h)
|
|||
|
||||
if ( ! is_orig &&
|
||||
mime::strcasecmp_n(h->get_name(), "connection") == 0 )
|
||||
{
|
||||
{
|
||||
if ( mime::strcasecmp_n(h->get_value_token(), "close") == 0 )
|
||||
connection_close = 1;
|
||||
connection_close = 1;
|
||||
else if ( mime::strcasecmp_n(h->get_value_token(), "upgrade") == 0 )
|
||||
upgrade_connection = true;
|
||||
}
|
||||
|
||||
if ( ! is_orig &&
|
||||
mime::strcasecmp_n(h->get_name(), "upgrade") == 0 )
|
||||
upgrade_protocol.assign(h->get_value_token().data, h->get_value_token().length);
|
||||
|
||||
if ( http_header )
|
||||
{
|
||||
Rule::PatternType rule =
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue