#include "payload_injector.h"
#include "detection/detection_engine.h"
+#include "flow/session.h"
#include "packet_io/active.h"
#include "protocols/packet.h"
#include "service_inspectors/http2_inspect/http2_flow_data.h"
{ ERR_TRANSLATED_HDRS_SIZE,
"HTTP/2 translated header size is bigger than expected. Update max size." },
{ ERR_HTTP2_EVEN_STREAM_ID, "HTTP/2 - injection to server initiated stream" },
- { ERR_PKT_FROM_SERVER, "Packet is from server" }
+ { ERR_PKT_FROM_SERVER, "Packet is from server" },
+ { ERR_CONFLICTING_S2C_TRAFFIC, "Conflicting S2C HTTP traffic in progress" }
};
InjectionReturnStatus PayloadInjector::inject_http2_payload(Packet* p,
// FIXIT-E mid-frame injection not supported
status = ERR_HTTP2_MID_FRAME;
}
+ else if (p->flow->session and
+ p->flow->session->are_client_segments_queued())
+ {
+ status = ERR_CONFLICTING_S2C_TRAFFIC;
+ }
else
{
uint8_t* http2_payload;
else if (!p->flow->gadget || strcmp(p->flow->gadget->get_name(),"http_inspect") ==
0)
{
- payload_injector_stats.http_injects++;
- p->active->send_data(p, df, control.http_page, control.http_page_len);
+ if (p->flow->session and
+ p->flow->session->are_client_segments_queued())
+ {
+ status = ERR_CONFLICTING_S2C_TRAFFIC;
+ p->active->send_data(p, df, nullptr, 0); // To send reset
+ }
+ else
+ {
+ payload_injector_stats.http_injects++;
+ p->active->send_data(p, df, control.http_page, control.http_page_len);
+ }
}
else if (strcmp(p->flow->gadget->get_name(),"http2_inspect") == 0)
status = inject_http2_payload(p, control, df);
"HTTP/2 translated header size is bigger than expected. Update max size.") == 0);
}
+TEST(payload_injector_translate_err_test, conflicting_s2c_traffic)
+{
+ Packet p(false);
+ set_configured();
+ p.packet_flags = PKT_STREAM_EST;
+ p.flow = &flow;
+ translation_status = ERR_CONFLICTING_S2C_TRAFFIC;
+ status = PayloadInjector::inject_http_payload(&p, control);
+ const char* err_string = PayloadInjector::get_err_string(status);
+ CHECK(strcmp(err_string,
+ "Conflicting S2C HTTP traffic in progress") == 0);
+}
int main(int argc, char** argv)
{
return CommandLineTestRunner::RunAllTests(argc, argv);
void disable_reassembly(snort::Flow*) override;
uint8_t get_reassembly_direction() override;
uint8_t missing_in_reassembled(uint8_t dir) override;
+ bool are_client_segments_queued() override;
bool add_alert(snort::Packet*, uint32_t gid, uint32_t sid) override;
bool check_alerted(snort::Packet*, uint32_t gid, uint32_t sid) override;