fuzz_http.c (3587B)
1 /* Copyright (c) 2016-2021, The Tor Project, Inc. */ 2 /* See LICENSE for licensing information */ 3 4 #include "orconfig.h" 5 6 #define BUFFERS_PRIVATE 7 #define DIRCACHE_PRIVATE 8 9 #include "core/or/or.h" 10 #include "lib/err/backtrace.h" 11 #include "lib/buf/buffers.h" 12 #include "app/config/config.h" 13 #include "core/mainloop/connection.h" 14 #include "feature/dircache/dircache.h" 15 #include "lib/log/log.h" 16 17 #include "feature/dircommon/dir_connection_st.h" 18 19 #include "test/fuzz/fuzzing.h" 20 21 static void 22 mock_connection_write_to_buf_impl_(const char *string, size_t len, 23 connection_t *conn, int compressed) 24 { 25 log_debug(LD_GENERAL, "%sResponse:\n%u\nConnection: %p\n%s\n", 26 compressed ? "Compressed " : "", (unsigned)len, conn, string); 27 } 28 29 static int 30 mock_directory_handle_command_get(dir_connection_t *conn, 31 const char *headers, 32 const char *body, 33 size_t body_len) 34 { 35 (void)conn; 36 37 log_debug(LD_GENERAL, "Method:\nGET\n"); 38 39 if (headers) { 40 log_debug(LD_GENERAL, "Header-Length:\n%u\n", (unsigned)strlen(headers)); 41 log_debug(LD_GENERAL, "Headers:\n%s\n", headers); 42 } 43 44 log_debug(LD_GENERAL, "Body-Length:\n%u\n", (unsigned)body_len); 45 if (body) { 46 log_debug(LD_GENERAL, "Body:\n%s\n", body); 47 } 48 49 /* Always tell the caller we succeeded */ 50 return 0; 51 } 52 53 static int 54 mock_directory_handle_command_post(dir_connection_t *conn, 55 const char *headers, 56 const char *body, 57 size_t body_len) 58 { 59 (void)conn; 60 61 log_debug(LD_GENERAL, "Method:\nPOST\n"); 62 63 if (headers) { 64 log_debug(LD_GENERAL, "Header-Length:\n%u\n", (unsigned)strlen(headers)); 65 log_debug(LD_GENERAL, "Headers:\n%s\n", headers); 66 } 67 68 log_debug(LD_GENERAL, "Body-Length:\n%u\n", (unsigned)body_len); 69 if (body) { 70 log_debug(LD_GENERAL, "Body:\n%s\n", body); 71 } 72 73 /* Always tell the caller we succeeded */ 74 return 0; 75 } 76 77 int 78 fuzz_init(void) 79 { 80 /* Set up fake response handler */ 81 MOCK(connection_write_to_buf_impl_, mock_connection_write_to_buf_impl_); 82 /* Set up the fake handler functions */ 83 MOCK(directory_handle_command_get, mock_directory_handle_command_get); 84 MOCK(directory_handle_command_post, mock_directory_handle_command_post); 85 86 return 0; 87 } 88 89 int 90 fuzz_cleanup(void) 91 { 92 UNMOCK(connection_write_to_buf_impl_); 93 UNMOCK(directory_handle_command_get); 94 UNMOCK(directory_handle_command_post); 95 return 0; 96 } 97 98 int 99 fuzz_main(const uint8_t *stdin_buf, size_t data_size) 100 { 101 dir_connection_t dir_conn; 102 103 /* Set up the fake connection */ 104 memset(&dir_conn, 0, sizeof(dir_connection_t)); 105 dir_conn.base_.type = CONN_TYPE_DIR; 106 /* Apparently tor sets this before directory_handle_command() is called. */ 107 dir_conn.base_.address = tor_strdup("replace-this-address.example.com"); 108 109 dir_conn.base_.inbuf = buf_new_with_data((char*)stdin_buf, data_size); 110 if (!dir_conn.base_.inbuf) { 111 log_debug(LD_GENERAL, "Zero-Length-Input\n"); 112 goto done; 113 } 114 115 /* Parse the headers */ 116 int rv = directory_handle_command(&dir_conn); 117 118 /* TODO: check the output is correctly parsed based on the input */ 119 120 /* Report the parsed origin address */ 121 if (dir_conn.base_.address) { 122 log_debug(LD_GENERAL, "Address:\n%s\n", dir_conn.base_.address); 123 } 124 125 log_debug(LD_GENERAL, "Result:\n%d\n", rv); 126 127 done: 128 /* Reset. */ 129 tor_free(dir_conn.base_.address); 130 buf_free(dir_conn.base_.inbuf); 131 dir_conn.base_.inbuf = NULL; 132 133 return 0; 134 }