diff options
Diffstat (limited to 'src/test/fuzz/fuzz_http.c')
-rw-r--r-- | src/test/fuzz/fuzz_http.c | 133 |
1 files changed, 133 insertions, 0 deletions
diff --git a/src/test/fuzz/fuzz_http.c b/src/test/fuzz/fuzz_http.c new file mode 100644 index 0000000000..2ffeb60244 --- /dev/null +++ b/src/test/fuzz/fuzz_http.c @@ -0,0 +1,133 @@ +/* Copyright (c) 2016-2017, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +#include "orconfig.h" + +#define BUFFERS_PRIVATE +#define DIRECTORY_PRIVATE + +#include "or.h" +#include "backtrace.h" +#include "buffers.h" +#include "config.h" +#include "connection.h" +#include "directory.h" +#include "torlog.h" + +#include "fuzzing.h" + +static void +mock_connection_write_to_buf_impl_(const char *string, size_t len, + connection_t *conn, int compressed) +{ + log_debug(LD_GENERAL, "%sResponse:\n%u\nConnection: %p\n%s\n", + compressed ? "Compressed " : "", (unsigned)len, conn, string); +} + +static int +mock_directory_handle_command_get(dir_connection_t *conn, + const char *headers, + const char *body, + size_t body_len) +{ + (void)conn; + + log_debug(LD_GENERAL, "Method:\nGET\n"); + + if (headers) { + log_debug(LD_GENERAL, "Header-Length:\n%u\n", (unsigned)strlen(headers)); + log_debug(LD_GENERAL, "Headers:\n%s\n", headers); + } + + log_debug(LD_GENERAL, "Body-Length:\n%u\n", (unsigned)body_len); + if (body) { + log_debug(LD_GENERAL, "Body:\n%s\n", body); + } + + /* Always tell the caller we succeeded */ + return 0; +} + +static int +mock_directory_handle_command_post(dir_connection_t *conn, + const char *headers, + const char *body, + size_t body_len) +{ + (void)conn; + + log_debug(LD_GENERAL, "Method:\nPOST\n"); + + if (headers) { + log_debug(LD_GENERAL, "Header-Length:\n%u\n", (unsigned)strlen(headers)); + log_debug(LD_GENERAL, "Headers:\n%s\n", headers); + } + + log_debug(LD_GENERAL, "Body-Length:\n%u\n", (unsigned)body_len); + if (body) { + log_debug(LD_GENERAL, "Body:\n%s\n", body); + } + + /* Always tell the caller we succeeded */ + return 0; +} + +int +fuzz_init(void) +{ + /* Set up fake response handler */ + MOCK(connection_write_to_buf_impl_, mock_connection_write_to_buf_impl_); + /* Set up the fake handler functions */ + MOCK(directory_handle_command_get, mock_directory_handle_command_get); + MOCK(directory_handle_command_post, mock_directory_handle_command_post); + + return 0; +} + +int +fuzz_cleanup(void) +{ + UNMOCK(connection_write_to_buf_impl_); + UNMOCK(directory_handle_command_get); + UNMOCK(directory_handle_command_post); + return 0; +} + +int +fuzz_main(const uint8_t *stdin_buf, size_t data_size) +{ + dir_connection_t dir_conn; + + /* Set up the fake connection */ + memset(&dir_conn, 0, sizeof(dir_connection_t)); + dir_conn.base_.type = CONN_TYPE_DIR; + /* Apparently tor sets this before directory_handle_command() is called. */ + dir_conn.base_.address = tor_strdup("replace-this-address.example.com"); + + dir_conn.base_.inbuf = buf_new_with_data((char*)stdin_buf, data_size); + if (!dir_conn.base_.inbuf) { + log_debug(LD_GENERAL, "Zero-Length-Input\n"); + goto done; + } + + /* Parse the headers */ + int rv = directory_handle_command(&dir_conn); + + /* TODO: check the output is correctly parsed based on the input */ + + /* Report the parsed origin address */ + if (dir_conn.base_.address) { + log_debug(LD_GENERAL, "Address:\n%s\n", dir_conn.base_.address); + } + + log_debug(LD_GENERAL, "Result:\n%d\n", rv); + + done: + /* Reset. */ + tor_free(dir_conn.base_.address); + buf_free(dir_conn.base_.inbuf); + dir_conn.base_.inbuf = NULL; + + return 0; +} + |