tor

The Tor anonymity network
git clone https://git.dasho.dev/tor.git
Log | Files | Refs | README | LICENSE

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 }