diff --git a/src/analyzer/protocol/http/HTTP.cc b/src/analyzer/protocol/http/HTTP.cc index b477f939ec..e5b1b63e4c 100644 --- a/src/analyzer/protocol/http/HTTP.cc +++ b/src/analyzer/protocol/http/HTTP.cc @@ -995,28 +995,9 @@ void HTTP_Analyzer::DeliverStream(int len, const u_char* data, bool is_orig) HTTP_Reply(); - if ( connect_request && reply_code == 200 ) - { - pia = new pia::PIA_TCP(Conn()); - - if ( AddChildAnalyzer(pia) ) - { - pia->FirstPacket(true, 0); - pia->FirstPacket(false, 0); - - // This connection has transitioned to no longer - // being http and the content line support analyzers - // need to be removed. - RemoveSupportAnalyzer(content_line_orig); - RemoveSupportAnalyzer(content_line_resp); - - return; - } - - else - // AddChildAnalyzer() will have deleted PIA. - pia = 0; - } + if ( connect_request && reply_code != 200 ) + // Request failed, do not set up tunnel. + connect_request = false; InitHTTPMessage(content_line, reply_message, is_orig, @@ -1036,6 +1017,30 @@ void HTTP_Analyzer::DeliverStream(int len, const u_char* data, bool is_orig) case EXPECT_REPLY_MESSAGE: reply_message->Deliver(len, line, 1); + + if ( connect_request && len == 0 ) + { + // End of message header reached, set up + // tunnel decapsulation. + pia = new pia::PIA_TCP(Conn()); + + if ( AddChildAnalyzer(pia) ) + { + pia->FirstPacket(true, 0); + pia->FirstPacket(false, 0); + + // This connection has transitioned to no longer + // being http and the content line support analyzers + // need to be removed. + RemoveSupportAnalyzer(content_line_orig); + RemoveSupportAnalyzer(content_line_resp); + } + + else + // AddChildAnalyzer() will have deleted PIA. + pia = 0; + } + break; case EXPECT_REPLY_TRAILER: diff --git a/testing/btest/Baseline/scripts.base.protocols.http.http-connect-with-header/conn.log b/testing/btest/Baseline/scripts.base.protocols.http.http-connect-with-header/conn.log new file mode 100644 index 0000000000..7adb1bd2e8 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.http.http-connect-with-header/conn.log @@ -0,0 +1,10 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path conn +#open 2015-10-23-20-09-31 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state local_orig local_resp missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes tunnel_parents +#types time string addr port addr port enum string interval count count string bool bool count string count count count count set[string] +1443732977.727740 CXWv6p3arKYeMETxOg ::1 52522 ::1 80 tcp ssl,http 0.691241 3644 55499 S1 - - 0 ShAaDd 29 5744 29 57599 (empty) +#close 2015-10-23-20-09-32 diff --git a/testing/btest/Baseline/scripts.base.protocols.http.http-connect-with-header/http.log b/testing/btest/Baseline/scripts.base.protocols.http.http-connect-with-header/http.log new file mode 100644 index 0000000000..e7d3078204 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.http.http-connect-with-header/http.log @@ -0,0 +1,10 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path http +#open 2015-10-23-20-09-31 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p trans_depth method host uri referrer user_agent request_body_len response_body_len status_code status_msg info_code info_msg filename tags username password proxied orig_fuids orig_mime_types resp_fuids resp_mime_types +#types time string addr port addr port count string string string string string count count count string count string string set[enum] string string set[string] vector[string] vector[string] vector[string] vector[string] +1443732977.728092 CXWv6p3arKYeMETxOg ::1 52522 ::1 80 1 CONNECT secure.newegg.com secure.newegg.com:443 - Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:41.0) Gecko/20100101 Firefox/41.0 0 0 200 Connection Established - - - (empty) - - PROXY-CONNECTION -> keep-alive - - - - +#close 2015-10-23-20-09-32 diff --git a/testing/btest/Baseline/scripts.base.protocols.http.http-connect-with-header/tunnel.log b/testing/btest/Baseline/scripts.base.protocols.http.http-connect-with-header/tunnel.log new file mode 100644 index 0000000000..95dfd233d2 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.http.http-connect-with-header/tunnel.log @@ -0,0 +1,10 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path tunnel +#open 2015-10-23-20-09-55 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p tunnel_type action +#types time string addr port addr port enum enum +1443732977.848660 - ::1 0 ::1 80 Tunnel::HTTP Tunnel::DISCOVER +#close 2015-10-23-20-09-55 diff --git a/testing/btest/Traces/http/connect-with-header.trace b/testing/btest/Traces/http/connect-with-header.trace new file mode 100644 index 0000000000..740b5ffce8 Binary files /dev/null and b/testing/btest/Traces/http/connect-with-header.trace differ diff --git a/testing/btest/scripts/base/protocols/http/http-connect-with-header.bro b/testing/btest/scripts/base/protocols/http/http-connect-with-header.bro new file mode 100644 index 0000000000..84172878f6 --- /dev/null +++ b/testing/btest/scripts/base/protocols/http/http-connect-with-header.bro @@ -0,0 +1,12 @@ +# This tests that the HTTP analyzer handles HTTP CONNECT proxying correctly +# when the server include a header line into its response. +# +# @TEST-EXEC: bro -C -r $TRACES/http/connect-with-header.trace %INPUT +# @TEST-EXEC: btest-diff conn.log +# @TEST-EXEC: btest-diff http.log +# @TEST-EXEC: btest-diff tunnel.log + +@load base/protocols/conn +@load base/protocols/http +@load base/protocols/tunnels +@load base/frameworks/dpd