CHECK(status == ERR_PAGE_TRANSLATION);
}
-// Header value has maximum supported length + 1
-TEST(payload_injector_translate_test, val_len_too_big)
+// Verify field value length is translated correctly
+TEST(payload_injector_translate_test, val_len1)
{
const uint32_t size = strlen("Location: ") + 128 + strlen("\r\n\r\nbody");
uint8_t http_page[size];
control.http_page_len = size;
status = PayloadInjectorModule::get_http2_payload(control, http2_payload, payload_len);
- CHECK(status == ERR_HTTP2_HDR_FIELD_VAL_LEN);
+ CHECK(status == INJECTION_SUCCESS);
+
+ uint8_t out[] =
+ {
+ 0x0, 0x0, 0x84, 0x1, 0x4, 0x0, 0x0, 0x0, 0x1, 0xf, 0x1f, 0x7f, 0x1, 0x61,
+ 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
+ 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
+ 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
+ 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
+ 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
+ 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
+ 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
+ 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
+ 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
+ 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x0, 0x0, 0x4,
+ 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x62, 0x6f, 0x64, 0x79
+ };
+ CHECK(payload_len == sizeof(out));
+ CHECK(memcmp(http2_payload, out, payload_len) == 0);
+
+ snort_free(http2_payload);
}
-// Header value has maximum supported length 127
-TEST(payload_injector_translate_test, max_val)
+TEST(payload_injector_translate_test, val_len2)
{
const uint32_t size = strlen("Location: ") + 127 + strlen("\r\n\r\nbody");
uint8_t http_page[size];
status = PayloadInjectorModule::get_http2_payload(control, http2_payload, payload_len);
CHECK(status == INJECTION_SUCCESS);
+ uint8_t out[] =
+ {
+ 0x0, 0x0, 0x83, 0x1, 0x4, 0x0, 0x0, 0x0, 0x1, 0xf, 0x1f, 0x7f, 0x0, 0x61,
+ 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
+ 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
+ 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
+ 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
+ 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
+ 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
+ 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
+ 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
+ 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
+ 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x0, 0x0, 0x4, 0x0,
+ 0x1, 0x0, 0x0, 0x0, 0x1, 0x62, 0x6f, 0x64, 0x79
+ };
+ CHECK(payload_len == sizeof(out));
+ CHECK(memcmp(http2_payload, out, payload_len) == 0);
+ snort_free(http2_payload);
+}
+
+TEST(payload_injector_translate_test, val_len3)
+{
+ const uint32_t size = strlen("Location: ") + 500 + strlen("\r\n\r\nbody");
+ uint8_t http_page[size];
+ memset(http_page, 'a', size);
+ memcpy(http_page, "Location: ", strlen("Location: "));
+ memcpy(http_page+500+strlen("Location: "), "\r\n\r\nbody", strlen("\r\n\r\nbody"));
+
+ InjectionControl control;
+ control.stream_id = 1;
+ control.http_page = http_page;
+ control.http_page_len = size;
+ status = PayloadInjectorModule::get_http2_payload(control, http2_payload, payload_len);
+
+ CHECK(status == INJECTION_SUCCESS);
+
+ uint8_t out[] =
+ {
+ 0x0, 0x1, 0xf9, 0x1, 0x4, 0x0, 0x0, 0x0, 0x1, 0xf, 0x1f, 0x7f, 0xf5, 0x2,
+ 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
+ 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
+ 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
+ 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
+ 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
+ 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
+ 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
+ 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
+ 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
+ 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
+ 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
+ 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
+ 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
+ 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
+ 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
+ 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
+ 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
+ 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
+ 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
+ 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
+ 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
+ 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
+ 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
+ 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
+ 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
+ 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
+ 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
+ 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
+ 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
+ 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
+ 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
+ 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
+ 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
+ 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
+ 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
+ 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
+ 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
+ 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
+ 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x0, 0x0, 0x4, 0x0, 0x1, 0x0, 0x0, 0x0,
+ 0x1, 0x62, 0x6f, 0x64, 0x79
+ };
+ CHECK(payload_len == sizeof(out));
+ CHECK(memcmp(http2_payload, out, payload_len) == 0);
snort_free(http2_payload);
}
CHECK(status == ERR_TRANSLATED_HDRS_SIZE);
}
+// Translated header > 2000. Fails while trying to write Location field value length - failure when
+// writing first byte of 2.
+TEST(payload_injector_translate_test, http2_hdr_too_big3)
+{
+ const uint32_t size = strlen("Connection: close\r\n") * 111 + strlen("Location: ") +
+ strlen("\r\n\r\nbody") + 130;
+ uint8_t http_page[size];
+
+ memset(http_page, 'a', size);
+ uint8_t* cur_pos = http_page;
+ for (int i=0; i < 111; i++)
+ {
+ memcpy(cur_pos, "Connection: close\r\n", strlen("Connection: close\r\n"));
+ cur_pos += strlen("Connection: close\r\n");
+ }
+ memcpy(cur_pos, "Location: ", strlen("Location: "));
+ memcpy(http_page+size-strlen("\r\n\r\nbody"), "\r\n\r\nbody", strlen("\r\n\r\nbody"));
+
+ InjectionControl control;
+ control.stream_id = 1;
+ control.http_page = http_page;
+ control.http_page_len = size;
+ status = PayloadInjectorModule::get_http2_payload(control, http2_payload, payload_len);
+
+ CHECK(status == ERR_TRANSLATED_HDRS_SIZE);
+}
+
+// Translated header > 2000. Fails while trying to write Location field value length - failure when
+// writing second byte of 3.
+TEST(payload_injector_translate_test, http2_hdr_too_big4)
+{
+ const uint32_t size = strlen("Connection: close\r\n") * 110 + strlen("Location: ")*2 +
+ strlen("\r\n\r\nbody") + 300 + 14;
+ uint8_t http_page[size];
+
+ memset(http_page, 'a', size);
+ uint8_t* cur_pos = http_page;
+ for (int i=0; i < 110; i++)
+ {
+ memcpy(cur_pos, "Connection: close\r\n", strlen("Connection: close\r\n"));
+ cur_pos += strlen("Connection: close\r\n");
+ }
+ memcpy(cur_pos, "Location: ", strlen("Location: "));
+ memcpy(cur_pos+strlen("Location: ")+14, "\r\nLocation: ", strlen("\r\nLocation: "));
+ memcpy(http_page+size-strlen("\r\n\r\nbody"), "\r\n\r\nbody", strlen("\r\n\r\nbody"));
+
+ InjectionControl control;
+ control.stream_id = 1;
+ control.http_page = http_page;
+ control.http_page_len = size;
+ status = PayloadInjectorModule::get_http2_payload(control, http2_payload, payload_len);
+
+ CHECK(status == ERR_TRANSLATED_HDRS_SIZE);
+}
+
+// Translated header > 2000. Fails while trying to write translation of second "Location: "
+TEST(payload_injector_translate_test, http2_hdr_too_big5)
+{
+ const uint32_t size = strlen("Connection: close\r\n") * 110 + strlen("Location: ")*2 +
+ strlen("\r\n\r\nbody") + 300 + 16;
+ uint8_t http_page[size];
+
+ memset(http_page, 'a', size);
+ uint8_t* cur_pos = http_page;
+ for (int i=0; i < 110; i++)
+ {
+ memcpy(cur_pos, "Connection: close\r\n", strlen("Connection: close\r\n"));
+ cur_pos += strlen("Connection: close\r\n");
+ }
+ memcpy(cur_pos, "Location: ", strlen("Location: "));
+ memcpy(cur_pos+strlen("Location: ")+16, "\r\nLocation: ", strlen("\r\nLocation: "));
+ memcpy(http_page+size-strlen("\r\n\r\nbody"), "\r\n\r\nbody", strlen("\r\n\r\nbody"));
+
+ InjectionControl control;
+ control.stream_id = 1;
+ control.http_page = http_page;
+ control.http_page_len = size;
+ status = PayloadInjectorModule::get_http2_payload(control, http2_payload, payload_len);
+
+ CHECK(status == ERR_TRANSLATED_HDRS_SIZE);
+}
+
TEST(payload_injector_translate_test, payload_body_larger_than_max)
{
static const uint32_t size = (1<<14) + 1 + strlen("HTTP/1.1 403 Forbidden\r\n\r\n");
CHECK(status == ERR_PAGE_TRANSLATION);
}
+TEST(payload_injector_translate_test, 7_bit_int_min_max)
+{
+ uint8_t out[6];
+ uint32_t out_free_space = sizeof(out);
+
+ // Translate 0
+ uint8_t* cur = out;
+ InjectionReturnStatus status = write_7_bit_prefix_int(0, cur, out_free_space);
+ uint8_t expected_out[] = {0};
+ CHECK(status == INJECTION_SUCCESS);
+ CHECK(out_free_space == 5);
+ CHECK(memcmp(out, expected_out, 1) == 0);
+
+ // Translate max uint_32
+ cur = out;
+ out_free_space = sizeof(out);
+ status = write_7_bit_prefix_int(UINT32_MAX, cur, out_free_space);
+ uint8_t expected_out2[] = {0x7f, 0x80, 0xff, 0xff, 0xff, 0xf};
+ CHECK(status == INJECTION_SUCCESS);
+ CHECK(out_free_space == 0);
+ CHECK(memcmp(out, expected_out2, 6) == 0);
+}
+
+
int main(int argc, char** argv)
{
return CommandLineTestRunner::RunAllTests(argc, argv);