mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 06:38:20 +00:00
HTTP: Implement FlipRoles()
When Zeek flips roles of a HTTP connection subsequent to the HTTP analyzer being attached, that analyzer would not update its own ContentLine analyzer state, resulting in the wrong ContentLine analyzer being switched into plain delivery mode. In debug builds, this would result in assertion failures, in production builds, the HTTP analyzer would receive HTTP bodies as individual header lines, or conversely, individual header lines would be delivered as a large chunk from the ContentLine analyzer. PCAPs were generated locally using tcprewrite to select well-known-http ports for both endpoints, then editcap to drop the first SYN packet. Kudos to @JordanBarnartt for keeping at it. Closes #3789
This commit is contained in:
parent
c6368fc3f0
commit
377fd711bd
12 changed files with 88 additions and 0 deletions
|
@ -1020,6 +1020,36 @@ void HTTP_Analyzer::Undelivered(uint64_t seq, int len, bool is_orig) {
|
|||
}
|
||||
}
|
||||
|
||||
void HTTP_Analyzer::FlipRoles() {
|
||||
analyzer::tcp::TCP_ApplicationAnalyzer::FlipRoles();
|
||||
|
||||
// If FlipRoles() is invoked after we've upgraded to something,
|
||||
// don't do anything. This shouldn't happen as flipping of TCP
|
||||
// connections currently happens before any data is transferred,
|
||||
// but better safe than sorry.
|
||||
if ( upgraded || pia ) {
|
||||
Weird("HTTP_late_flip_roles");
|
||||
return;
|
||||
}
|
||||
|
||||
// If we haven't upgraded but saw request or replies, just bail
|
||||
// for the rest of this connection. Again, this should never happen
|
||||
// right now, but raise a weird in case it starts to happen.
|
||||
if ( num_requests > 0 || num_replies > 0 ) {
|
||||
Weird("HTTP_late_flip_roles");
|
||||
SetSkip(true);
|
||||
return;
|
||||
}
|
||||
|
||||
// IsOrig() of the support analyzer has been updated, but we still need
|
||||
// to change the analyzer's local state and the partial skipping setting.
|
||||
bool skip_partial_orig = content_line_orig->SkipPartial();
|
||||
bool skip_partial_resp = content_line_resp->SkipPartial();
|
||||
std::swap(content_line_orig, content_line_resp);
|
||||
content_line_orig->SetSkipPartial(skip_partial_orig);
|
||||
content_line_resp->SetSkipPartial(skip_partial_resp);
|
||||
}
|
||||
|
||||
void HTTP_Analyzer::EndpointEOF(bool is_orig) {
|
||||
analyzer::tcp::TCP_ApplicationAnalyzer::EndpointEOF(is_orig);
|
||||
|
||||
|
|
|
@ -167,6 +167,7 @@ public:
|
|||
void Done() override;
|
||||
void DeliverStream(int len, const u_char* data, bool orig) override;
|
||||
void Undelivered(uint64_t seq, int len, bool orig) override;
|
||||
void FlipRoles() override;
|
||||
|
||||
// Overridden from analyzer::tcp::TCP_ApplicationAnalyzer
|
||||
void EndpointEOF(bool is_orig) override;
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
|
||||
id.orig_h id.orig_p id.resp_h id.resp_p history service
|
||||
127.0.0.1 1080 127.0.0.1 8000 ^hADadFf http
|
|
@ -0,0 +1,4 @@
|
|||
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
|
||||
id.orig_h id.orig_p id.resp_h id.resp_p analyzers mime_type sha1
|
||||
127.0.0.1 1080 127.0.0.1 8000 SHA1 image/png 1991cedee47909e324ac1b8bee2020d5690891e1
|
||||
127.0.0.1 1080 127.0.0.1 8000 SHA1 text/json eae909a9c2827d827ef30a6675a6388770ddc88d
|
|
@ -0,0 +1,3 @@
|
|||
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
|
||||
id.orig_h id.orig_p id.resp_h id.resp_p host method uri version user_agent status_code status_msg
|
||||
127.0.0.1 1080 127.0.0.1 8000 localhost:8000 POST / 1.1 curl/7.81.0 200 OK
|
|
@ -0,0 +1,3 @@
|
|||
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
|
||||
id.orig_h id.orig_p id.resp_h id.resp_p history service
|
||||
127.0.0.1 1080 127.0.0.1 80 ^hADadFf http
|
|
@ -0,0 +1,3 @@
|
|||
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
|
||||
id.orig_h id.orig_p id.resp_h id.resp_p analyzers mime_type sha1
|
||||
127.0.0.1 1080 127.0.0.1 80 SHA1 image/png 1991cedee47909e324ac1b8bee2020d5690891e1
|
|
@ -0,0 +1,3 @@
|
|||
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
|
||||
id.orig_h id.orig_p id.resp_h id.resp_p host method uri version user_agent status_code status_msg
|
||||
127.0.0.1 1080 127.0.0.1 80 localhost GET /zeek.png 1.1 curl/7.81.0 200 OK
|
BIN
testing/btest/Traces/http/zeek-image-1080-80-x.pcap
Normal file
BIN
testing/btest/Traces/http/zeek-image-1080-80-x.pcap
Normal file
Binary file not shown.
BIN
testing/btest/Traces/http/zeek-image-post-1080-8000-x.pcap
Normal file
BIN
testing/btest/Traces/http/zeek-image-post-1080-8000-x.pcap
Normal file
Binary file not shown.
|
@ -0,0 +1,19 @@
|
|||
# @TEST-DOC: Flipping roles of a HTTP connection didn't flip the content line analyzers, resulting in inconsistent deliveries. Regression test for #3789
|
||||
|
||||
# Pcap contains a POST of the Zeek logo, expecting SHA1 1991cedee47909e324ac1b8bee2020d5690891e1 in files.log
|
||||
# @TEST-EXEC: zeek -b -r $TRACES/http/zeek-image-post-1080-8000-x.pcap %INPUT
|
||||
# @TEST-EXEC: zeek-cut -m id.orig_h id.orig_p id.resp_h id.resp_p history service < conn.log > conn.log.cut
|
||||
# @TEST-EXEC: zeek-cut -m id.orig_h id.orig_p id.resp_h id.resp_p host method uri version user_agent status_code status_msg < http.log > http.log.cut
|
||||
# @TEST-EXEC: zeek-cut -m id.orig_h id.orig_p id.resp_h id.resp_p analyzers mime_type sha1 < files.log > files.log.cut
|
||||
# @TEST-EXEC: btest-diff conn.log.cut
|
||||
# @TEST-EXEC: btest-diff http.log.cut
|
||||
# @TEST-EXEC: btest-diff files.log.cut
|
||||
|
||||
@load base/protocols/conn
|
||||
@load base/protocols/http
|
||||
@load base/files/hash
|
||||
|
||||
event file_new(f: fa_file)
|
||||
{
|
||||
Files::add_analyzer(f, Files::ANALYZER_SHA1);
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
# @TEST-DOC: Flipping roles of a HTTP connection didn't flip the content line analyzers, resulting in inconsistent deliveries. Regression test for #3789
|
||||
|
||||
# Pcap contains a download of the Zeek logo, expecting SHA1 1991cedee47909e324ac1b8bee2020d5690891e1 in files.log
|
||||
# @TEST-EXEC: zeek -b -r $TRACES/http/zeek-image-1080-80-x.pcap %INPUT
|
||||
# @TEST-EXEC: zeek-cut -m id.orig_h id.orig_p id.resp_h id.resp_p history service < conn.log > conn.log.cut
|
||||
# @TEST-EXEC: zeek-cut -m id.orig_h id.orig_p id.resp_h id.resp_p host method uri version user_agent status_code status_msg < http.log > http.log.cut
|
||||
# @TEST-EXEC: zeek-cut -m id.orig_h id.orig_p id.resp_h id.resp_p analyzers mime_type sha1 < files.log > files.log.cut
|
||||
# @TEST-EXEC: btest-diff conn.log.cut
|
||||
# @TEST-EXEC: btest-diff http.log.cut
|
||||
# @TEST-EXEC: btest-diff files.log.cut
|
||||
|
||||
@load base/protocols/conn
|
||||
@load base/protocols/http
|
||||
@load base/files/hash
|
||||
|
||||
event file_new(f: fa_file)
|
||||
{
|
||||
Files::add_analyzer(f, Files::ANALYZER_SHA1);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue