tor

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

test_dir_handle_get.c (85780B)


      1 /* Copyright (c) 2001-2004, Roger Dingledine.
      2 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
      3 * Copyright (c) 2007-2021, The Tor Project, Inc. */
      4 /* See LICENSE for licensing information */
      5 
      6 #define RENDCOMMON_PRIVATE
      7 #define GEOIP_PRIVATE
      8 #define CONNECTION_PRIVATE
      9 #define CONFIG_PRIVATE
     10 #define RENDCACHE_PRIVATE
     11 #define DIRCACHE_PRIVATE
     12 
     13 #include "core/or/or.h"
     14 #include "app/config/config.h"
     15 #include "core/mainloop/connection.h"
     16 #include "feature/dircache/consdiffmgr.h"
     17 #include "feature/dircommon/directory.h"
     18 #include "feature/dircache/dircache.h"
     19 #include "test/test.h"
     20 #include "lib/compress/compress.h"
     21 #include "feature/relay/relay_config.h"
     22 #include "feature/relay/router.h"
     23 #include "feature/nodelist/authcert.h"
     24 #include "feature/nodelist/dirlist.h"
     25 #include "feature/nodelist/routerlist.h"
     26 #include "feature/nodelist/microdesc.h"
     27 #include "test/test_helpers.h"
     28 #include "feature/nodelist/nodelist.h"
     29 #include "feature/client/entrynodes.h"
     30 #include "feature/dirparse/authcert_parse.h"
     31 #include "feature/dirparse/sigcommon.h"
     32 #include "feature/nodelist/networkstatus.h"
     33 #include "core/proto/proto_http.h"
     34 #include "lib/geoip/geoip.h"
     35 #include "feature/stats/geoip_stats.h"
     36 #include "feature/dircache/dirserv.h"
     37 #include "feature/dirauth/dirvote.h"
     38 #include "test/log_test_helpers.h"
     39 #include "feature/dirauth/voting_schedule.h"
     40 
     41 #include "feature/dircommon/dir_connection_st.h"
     42 #include "feature/dirclient/dir_server_st.h"
     43 #include "feature/nodelist/networkstatus_st.h"
     44 #include "feature/nodelist/routerinfo_st.h"
     45 #include "feature/nodelist/routerlist_st.h"
     46 
     47 #ifdef _WIN32
     48 /* For mkdir() */
     49 #include <direct.h>
     50 #else
     51 #include <dirent.h>
     52 #endif /* defined(_WIN32) */
     53 
     54 #ifdef HAVE_CFLAG_WOVERLENGTH_STRINGS
     55 DISABLE_GCC_WARNING("-Woverlength-strings")
     56 /* We allow huge string constants in the unit tests, but not in the code
     57 * at large. */
     58 #endif
     59 #include "vote_descriptors.inc"
     60 #ifdef HAVE_CFLAG_WOVERLENGTH_STRINGS
     61 ENABLE_GCC_WARNING("-Woverlength-strings")
     62 #endif
     63 
     64 #define NOT_FOUND "HTTP/1.0 404 Not found\r\n\r\n"
     65 #define BAD_REQUEST "HTTP/1.0 400 Bad request\r\n\r\n"
     66 #define SERVER_BUSY "HTTP/1.0 503 Directory busy, try again later\r\n\r\n"
     67 #define TOO_OLD "HTTP/1.0 404 Consensus is too old\r\n\r\n"
     68 #define NOT_ENOUGH_CONSENSUS_SIGNATURES "HTTP/1.0 404 " \
     69  "Consensus not signed by sufficient number of requested authorities\r\n\r\n"
     70 
     71 #define consdiffmgr_add_consensus consdiffmgr_add_consensus_nulterm
     72 
     73 static int
     74 mock_ignore_signature_token(const char *digest,
     75                            ssize_t digest_len,
     76                            struct directory_token_t *tok,
     77                            crypto_pk_t *pkey,
     78                            int flags,
     79                            const char *doctype)
     80 {
     81  (void)digest;
     82  (void)digest_len;
     83  (void)tok;
     84  (void)pkey;
     85  (void)flags;
     86  (void)doctype;
     87  return 0;
     88 }
     89 
     90 static dir_connection_t *
     91 new_dir_conn(void)
     92 {
     93  dir_connection_t *conn = dir_connection_new(AF_INET);
     94  tor_addr_from_ipv4h(&conn->base_.addr, 0x7f000001);
     95  TO_CONN(conn)->address = tor_strdup("127.0.0.1");
     96  return conn;
     97 }
     98 
     99 static void
    100 test_dir_handle_get_bad_request(void *data)
    101 {
    102  dir_connection_t *conn = NULL;
    103  char *header = NULL;
    104  (void) data;
    105 
    106  MOCK(connection_write_to_buf_impl_, connection_write_to_buf_mock);
    107 
    108  conn = new_dir_conn();
    109  tt_int_op(directory_handle_command_get(conn, "", NULL, 0), OP_EQ, 0);
    110 
    111  fetch_from_buf_http(TO_CONN(conn)->outbuf, &header, MAX_HEADERS_SIZE,
    112                      NULL, NULL, 1, 0);
    113 
    114  tt_str_op(header, OP_EQ, BAD_REQUEST);
    115 
    116  done:
    117    UNMOCK(connection_write_to_buf_impl_);
    118    connection_free_minimal(TO_CONN(conn));
    119    tor_free(header);
    120 }
    121 
    122 static void
    123 test_dir_handle_get_v1_command_not_found(void *data)
    124 {
    125  dir_connection_t *conn = NULL;
    126  char *header = NULL;
    127  (void) data;
    128 
    129  MOCK(connection_write_to_buf_impl_, connection_write_to_buf_mock);
    130 
    131  conn = new_dir_conn();
    132 
    133  // no frontpage configured
    134  tt_ptr_op(relay_get_dirportfrontpage(), OP_EQ, NULL);
    135 
    136  /* V1 path */
    137  tt_int_op(directory_handle_command_get(conn, GET("/tor/"), NULL, 0),
    138            OP_EQ, 0);
    139 
    140  fetch_from_buf_http(TO_CONN(conn)->outbuf, &header, MAX_HEADERS_SIZE,
    141                      NULL, NULL, 1, 0);
    142 
    143  tt_str_op(NOT_FOUND, OP_EQ, header);
    144 
    145  done:
    146    UNMOCK(connection_write_to_buf_impl_);
    147    connection_free_minimal(TO_CONN(conn));
    148    tor_free(header);
    149 }
    150 
    151 static const char*
    152 mock_get_dirportfrontpage(void)
    153 {
    154  return "HELLO FROM FRONTPAGE";
    155 }
    156 
    157 static void
    158 test_dir_handle_get_v1_command(void *data)
    159 {
    160  dir_connection_t *conn = NULL;
    161  char *header = NULL;
    162  char *body = NULL;
    163  size_t body_used = 0, body_len = 0;
    164  const char *exp_body = NULL;
    165  (void) data;
    166 
    167  MOCK(connection_write_to_buf_impl_, connection_write_to_buf_mock);
    168  MOCK(relay_get_dirportfrontpage, mock_get_dirportfrontpage);
    169 
    170  exp_body = relay_get_dirportfrontpage();
    171  body_len = strlen(exp_body);
    172 
    173  conn = new_dir_conn();
    174  tt_int_op(directory_handle_command_get(conn, GET("/tor/"), NULL, 0),
    175            OP_EQ, 0);
    176 
    177  fetch_from_buf_http(TO_CONN(conn)->outbuf, &header, MAX_HEADERS_SIZE,
    178                      &body, &body_used, body_len+1, 0);
    179 
    180  tt_assert(header);
    181  tt_assert(body);
    182 
    183  tt_ptr_op(strstr(header, "HTTP/1.0 200 OK\r\n"), OP_EQ, header);
    184  tt_assert(strstr(header, "Content-Type: text/html\r\n"));
    185  tt_assert(strstr(header, "Content-Encoding: identity\r\n"));
    186  tt_assert(strstr(header, "Content-Length: 20\r\n"));
    187 
    188  tt_int_op(body_used, OP_EQ, strlen(body));
    189  tt_str_op(body, OP_EQ, exp_body);
    190 
    191  done:
    192    UNMOCK(connection_write_to_buf_impl_);
    193    UNMOCK(relay_get_dirportfrontpage);
    194    connection_free_minimal(TO_CONN(conn));
    195    tor_free(header);
    196    tor_free(body);
    197 }
    198 
    199 static void
    200 test_dir_handle_get_not_found(void *data)
    201 {
    202  dir_connection_t *conn = NULL;
    203  char *header = NULL;
    204  (void) data;
    205 
    206  MOCK(connection_write_to_buf_impl_, connection_write_to_buf_mock);
    207 
    208  conn = new_dir_conn();
    209 
    210  /* Unrecognized path */
    211  tt_int_op(directory_handle_command_get(conn, GET("/anything"), NULL, 0),
    212            OP_EQ, 0);
    213  fetch_from_buf_http(TO_CONN(conn)->outbuf, &header, MAX_HEADERS_SIZE,
    214                      NULL, NULL, 1, 0);
    215 
    216  tt_str_op(NOT_FOUND, OP_EQ, header);
    217 
    218  done:
    219    UNMOCK(connection_write_to_buf_impl_);
    220    connection_free_minimal(TO_CONN(conn));
    221    tor_free(header);
    222 }
    223 
    224 static void
    225 test_dir_handle_get_robots_txt(void *data)
    226 {
    227  dir_connection_t *conn = NULL;
    228  char *header = NULL;
    229  char *body = NULL;
    230  size_t body_used = 0;
    231  (void) data;
    232 
    233  MOCK(connection_write_to_buf_impl_, connection_write_to_buf_mock);
    234 
    235  conn = new_dir_conn();
    236 
    237  tt_int_op(directory_handle_command_get(conn, GET("/tor/robots.txt"),
    238                                         NULL, 0), OP_EQ, 0);
    239  fetch_from_buf_http(TO_CONN(conn)->outbuf, &header, MAX_HEADERS_SIZE,
    240                      &body, &body_used, 29, 0);
    241 
    242  tt_assert(header);
    243  tt_assert(body);
    244 
    245  tt_ptr_op(strstr(header, "HTTP/1.0 200 OK\r\n"), OP_EQ, header);
    246  tt_assert(strstr(header, "Content-Type: text/plain\r\n"));
    247  tt_assert(strstr(header, "Content-Encoding: identity\r\n"));
    248  tt_assert(strstr(header, "Content-Length: 28\r\n"));
    249 
    250  tt_int_op(body_used, OP_EQ, strlen(body));
    251  tt_str_op(body, OP_EQ, "User-agent: *\r\nDisallow: /\r\n");
    252 
    253  done:
    254    UNMOCK(connection_write_to_buf_impl_);
    255    connection_free_minimal(TO_CONN(conn));
    256    tor_free(header);
    257    tor_free(body);
    258 }
    259 
    260 static const routerinfo_t * dhg_tests_router_get_my_routerinfo(void);
    261 ATTR_UNUSED static int dhg_tests_router_get_my_routerinfo_called = 0;
    262 
    263 static routerinfo_t *mock_routerinfo;
    264 
    265 static const routerinfo_t *
    266 dhg_tests_router_get_my_routerinfo(void)
    267 {
    268  if (!mock_routerinfo) {
    269    mock_routerinfo = tor_malloc_zero(sizeof(routerinfo_t));
    270  }
    271 
    272  return mock_routerinfo;
    273 }
    274 
    275 #define MICRODESC_GET(digest) GET("/tor/micro/d/" digest)
    276 static void
    277 test_dir_handle_get_micro_d_not_found(void *data)
    278 {
    279  dir_connection_t *conn = NULL;
    280  char *header = NULL;
    281  (void) data;
    282 
    283  MOCK(connection_write_to_buf_impl_, connection_write_to_buf_mock);
    284 
    285  #define B64_256_1 "8/Pz8/u7vz8/Pz+7vz8/Pz+7u/Pz8/P7u/Pz8/P7u78"
    286  #define B64_256_2 "zMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMw"
    287  conn = new_dir_conn();
    288 
    289  const char *req = MICRODESC_GET(B64_256_1 "-" B64_256_2);
    290  tt_int_op(directory_handle_command_get(conn, req, NULL, 0), OP_EQ, 0);
    291 
    292  fetch_from_buf_http(TO_CONN(conn)->outbuf, &header, MAX_HEADERS_SIZE,
    293                      NULL, NULL, 1, 0);
    294 
    295  tt_str_op(NOT_FOUND, OP_EQ, header);
    296 
    297  done:
    298    UNMOCK(connection_write_to_buf_impl_);
    299 
    300    connection_free_minimal(TO_CONN(conn));
    301    tor_free(header);
    302 }
    303 
    304 static or_options_t *mock_options = NULL;
    305 static void
    306 init_mock_options(void)
    307 {
    308  mock_options = options_new();
    309  mock_options->TestingTorNetwork = 1;
    310  mock_options->DataDirectory = tor_strdup(get_fname_rnd("datadir_tmp"));
    311  mock_options->CacheDirectory = tor_strdup(mock_options->DataDirectory);
    312  check_private_dir(mock_options->DataDirectory, CPD_CREATE, NULL);
    313 }
    314 
    315 static const or_options_t *
    316 mock_get_options(void)
    317 {
    318  tor_assert(mock_options);
    319  return mock_options;
    320 }
    321 
    322 static const char microdesc[] =
    323  "onion-key\n"
    324  "-----BEGIN RSA PUBLIC KEY-----\n"
    325  "MIGJAoGBAMjlHH/daN43cSVRaHBwgUfnszzAhg98EvivJ9Qxfv51mvQUxPjQ07es\n"
    326  "gV/3n8fyh3Kqr/ehi9jxkdgSRfSnmF7giaHL1SLZ29kA7KtST+pBvmTpDtHa3ykX\n"
    327  "Xorc7hJvIyTZoc1HU+5XSynj3gsBE5IGK1ZRzrNS688LnuZMVp1tAgMBAAE=\n"
    328  "-----END RSA PUBLIC KEY-----\n"
    329  "ntor-onion-key QlrOXAa8j3LD31LESsPm/lIKFBwevk2oXdqJcd9SEUc=\n";
    330 
    331 static void
    332 test_dir_handle_get_micro_d(void *data)
    333 {
    334  dir_connection_t *conn = NULL;
    335  microdesc_cache_t *mc = NULL ;
    336  smartlist_t *list = NULL;
    337  char digest[DIGEST256_LEN];
    338  char digest_base64[128];
    339  char path[80];
    340  char *header = NULL;
    341  char *body = NULL;
    342  size_t body_used = 0;
    343  (void) data;
    344 
    345  MOCK(get_options, mock_get_options);
    346  MOCK(connection_write_to_buf_impl_, connection_write_to_buf_mock);
    347 
    348  /* SETUP */
    349  init_mock_options();
    350 
    351  /* Add microdesc to cache */
    352  crypto_digest256(digest, microdesc, strlen(microdesc), DIGEST_SHA256);
    353  base64_encode_nopad(digest_base64, sizeof(digest_base64),
    354                      (uint8_t *) digest, DIGEST256_LEN);
    355 
    356  mc = get_microdesc_cache();
    357  list = microdescs_add_to_cache(mc, microdesc, NULL, SAVED_NOWHERE, 0,
    358                                  time(NULL), NULL);
    359  tt_int_op(1, OP_EQ, smartlist_len(list));
    360 
    361  /* Make the request */
    362  conn = new_dir_conn();
    363 
    364  tor_snprintf(path, sizeof(path), MICRODESC_GET("%s"), digest_base64);
    365  tt_int_op(directory_handle_command_get(conn, path, NULL, 0), OP_EQ, 0);
    366 
    367  fetch_from_buf_http(TO_CONN(conn)->outbuf, &header, MAX_HEADERS_SIZE,
    368                      &body, &body_used, strlen(microdesc)+1, 0);
    369 
    370  tt_assert(header);
    371  tt_assert(body);
    372 
    373  tt_ptr_op(strstr(header, "HTTP/1.0 200 OK\r\n"), OP_EQ, header);
    374  tt_assert(strstr(header, "Content-Type: text/plain\r\n"));
    375  tt_assert(strstr(header, "Content-Encoding: identity\r\n"));
    376 
    377  tt_int_op(body_used, OP_EQ, strlen(body));
    378  tt_str_op(body, OP_EQ, microdesc);
    379 
    380  done:
    381    UNMOCK(get_options);
    382    UNMOCK(connection_write_to_buf_impl_);
    383 
    384    or_options_free(mock_options); mock_options = NULL;
    385    connection_free_minimal(TO_CONN(conn));
    386    tor_free(header);
    387    tor_free(body);
    388    smartlist_free(list);
    389    microdesc_free_all();
    390 }
    391 
    392 static void
    393 test_dir_handle_get_micro_d_server_busy(void *data)
    394 {
    395  dir_connection_t *conn = NULL;
    396  microdesc_cache_t *mc = NULL ;
    397  smartlist_t *list = NULL;
    398  char digest[DIGEST256_LEN];
    399  char digest_base64[128];
    400  char path[80];
    401  char *header = NULL;
    402  (void) data;
    403 
    404  MOCK(get_options, mock_get_options);
    405  MOCK(connection_write_to_buf_impl_, connection_write_to_buf_mock);
    406 
    407  /* SETUP */
    408  init_mock_options();
    409 
    410  /* Add microdesc to cache */
    411  crypto_digest256(digest, microdesc, strlen(microdesc), DIGEST_SHA256);
    412  base64_encode_nopad(digest_base64, sizeof(digest_base64),
    413                      (uint8_t *) digest, DIGEST256_LEN);
    414 
    415  mc = get_microdesc_cache();
    416  list = microdescs_add_to_cache(mc, microdesc, NULL, SAVED_NOWHERE, 0,
    417                                  time(NULL), NULL);
    418  tt_int_op(1, OP_EQ, smartlist_len(list));
    419 
    420  //Make it busy
    421  mock_options->CountPrivateBandwidth = 1;
    422 
    423  /* Make the request */
    424  conn = new_dir_conn();
    425 
    426  tor_snprintf(path, sizeof(path), MICRODESC_GET("%s"), digest_base64);
    427  tt_int_op(directory_handle_command_get(conn, path, NULL, 0), OP_EQ, 0);
    428 
    429  fetch_from_buf_http(TO_CONN(conn)->outbuf, &header, MAX_HEADERS_SIZE,
    430                      NULL, NULL, 1, 0);
    431 
    432  tt_str_op(SERVER_BUSY, OP_EQ, header);
    433 
    434  done:
    435    UNMOCK(get_options);
    436    UNMOCK(connection_write_to_buf_impl_);
    437 
    438    or_options_free(mock_options); mock_options = NULL;
    439    connection_free_minimal(TO_CONN(conn));
    440    tor_free(header);
    441    smartlist_free(list);
    442    microdesc_free_all();
    443 }
    444 
    445 #define BRIDGES_PATH "/tor/networkstatus-bridges"
    446 static void
    447 test_dir_handle_get_networkstatus_bridges_not_found_without_auth(void *data)
    448 {
    449  dir_connection_t *conn = NULL;
    450  char *header = NULL;
    451  (void) data;
    452 
    453  MOCK(get_options, mock_get_options);
    454  MOCK(connection_write_to_buf_impl_, connection_write_to_buf_mock);
    455 
    456  /* SETUP */
    457  init_mock_options();
    458  mock_options->BridgeAuthoritativeDir = 1;
    459  mock_options->BridgePassword_AuthDigest_ = tor_strdup("digest");
    460 
    461  conn = new_dir_conn();
    462  TO_CONN(conn)->linked = 1;
    463 
    464  const char *req = GET(BRIDGES_PATH);
    465  tt_int_op(directory_handle_command_get(conn, req, NULL, 0), OP_EQ, 0);
    466 
    467  fetch_from_buf_http(TO_CONN(conn)->outbuf, &header, MAX_HEADERS_SIZE,
    468                      NULL, NULL, 1, 0);
    469 
    470  tt_str_op(NOT_FOUND, OP_EQ, header);
    471 
    472  done:
    473    UNMOCK(get_options);
    474    UNMOCK(connection_write_to_buf_impl_);
    475    or_options_free(mock_options); mock_options = NULL;
    476    connection_free_minimal(TO_CONN(conn));
    477    tor_free(header);
    478 }
    479 
    480 static void
    481 test_dir_handle_get_networkstatus_bridges(void *data)
    482 {
    483  dir_connection_t *conn = NULL;
    484  char *header = NULL;
    485  (void) data;
    486 
    487  MOCK(get_options, mock_get_options);
    488  MOCK(connection_write_to_buf_impl_, connection_write_to_buf_mock);
    489 
    490  /* SETUP */
    491  init_mock_options();
    492  mock_options->BridgeAuthoritativeDir = 1;
    493  mock_options->BridgePassword_AuthDigest_ = tor_malloc(DIGEST256_LEN);
    494  crypto_digest256(mock_options->BridgePassword_AuthDigest_,
    495                     "abcdefghijklm12345", 18, DIGEST_SHA256);
    496 
    497  conn = new_dir_conn();
    498  TO_CONN(conn)->linked = 1;
    499 
    500  const char *req = "GET " BRIDGES_PATH " HTTP/1.0\r\n"
    501                    "Authorization: Basic abcdefghijklm12345\r\n\r\n";
    502  tt_int_op(directory_handle_command_get(conn, req, NULL, 0), OP_EQ, 0);
    503 
    504  fetch_from_buf_http(TO_CONN(conn)->outbuf, &header, MAX_HEADERS_SIZE,
    505                      NULL, NULL, 1, 0);
    506 
    507  tt_ptr_op(strstr(header, "HTTP/1.0 200 OK\r\n"), OP_EQ, header);
    508  tt_assert(strstr(header, "Content-Type: text/plain\r\n"));
    509  tt_assert(strstr(header, "Content-Encoding: identity\r\n"));
    510  tt_assert(strstr(header, "Content-Length: 0\r\n"));
    511 
    512  done:
    513    UNMOCK(get_options);
    514    UNMOCK(connection_write_to_buf_impl_);
    515    or_options_free(mock_options); mock_options = NULL;
    516    connection_free_minimal(TO_CONN(conn));
    517    tor_free(header);
    518 }
    519 
    520 static void
    521 test_dir_handle_get_networkstatus_bridges_not_found_wrong_auth(void *data)
    522 {
    523  dir_connection_t *conn = NULL;
    524  char *header = NULL;
    525  (void) data;
    526 
    527  MOCK(get_options, mock_get_options);
    528  MOCK(connection_write_to_buf_impl_, connection_write_to_buf_mock);
    529 
    530  /* SETUP */
    531  init_mock_options();
    532  mock_options->BridgeAuthoritativeDir = 1;
    533  mock_options->BridgePassword_AuthDigest_ = tor_malloc(DIGEST256_LEN);
    534  crypto_digest256(mock_options->BridgePassword_AuthDigest_,
    535                     "abcdefghijklm12345", 18, DIGEST_SHA256);
    536 
    537  conn = new_dir_conn();
    538  TO_CONN(conn)->linked = 1;
    539 
    540  const char *req = "GET " BRIDGES_PATH " HTTP/1.0\r\n"
    541                           "Authorization: Basic NOTSAMEDIGEST\r\n\r\n";
    542  tt_int_op(directory_handle_command_get(conn, req, NULL, 0), OP_EQ, 0);
    543 
    544  fetch_from_buf_http(TO_CONN(conn)->outbuf, &header, MAX_HEADERS_SIZE,
    545                      NULL, NULL, 1, 0);
    546 
    547  tt_str_op(NOT_FOUND, OP_EQ, header);
    548 
    549  done:
    550    UNMOCK(get_options);
    551    UNMOCK(connection_write_to_buf_impl_);
    552    or_options_free(mock_options); mock_options = NULL;
    553    connection_free_minimal(TO_CONN(conn));
    554    tor_free(header);
    555 }
    556 
    557 #define SERVER_DESC_GET(id) GET("/tor/server/" id)
    558 static void
    559 test_dir_handle_get_server_descriptors_not_found(void* data)
    560 {
    561  dir_connection_t *conn = NULL;
    562  char *header = NULL;
    563  (void) data;
    564 
    565  MOCK(connection_write_to_buf_impl_, connection_write_to_buf_mock);
    566 
    567  conn = new_dir_conn();
    568 
    569  const char *req = SERVER_DESC_GET("invalid");
    570  tt_int_op(directory_handle_command_get(conn, req, NULL, 0), OP_EQ, 0);
    571 
    572  fetch_from_buf_http(TO_CONN(conn)->outbuf, &header, MAX_HEADERS_SIZE,
    573                      NULL, NULL, 1, 0);
    574 
    575  tt_str_op(NOT_FOUND, OP_EQ, header);
    576  tt_ptr_op(conn->spool, OP_EQ, NULL);
    577 
    578  done:
    579    UNMOCK(connection_write_to_buf_impl_);
    580    or_options_free(mock_options); mock_options = NULL;
    581    connection_free_minimal(TO_CONN(conn));
    582    tor_free(header);
    583 }
    584 
    585 static void
    586 test_dir_handle_get_server_descriptors_all(void* data)
    587 {
    588  dir_connection_t *conn = NULL;
    589  char *header = NULL;
    590  char *body = NULL;
    591  size_t body_used = 0;
    592  (void) data;
    593 
    594  /* Setup fake routerlist. */
    595  helper_setup_fake_routerlist();
    596 
    597  //TODO: change to router_get_my_extrainfo when testing "extra" path
    598  MOCK(router_get_my_routerinfo,
    599       dhg_tests_router_get_my_routerinfo);
    600  MOCK(connection_write_to_buf_impl_, connection_write_to_buf_mock);
    601 
    602  // We are one of the routers
    603  routerlist_t *our_routerlist = router_get_routerlist();
    604  tt_int_op(smartlist_len(our_routerlist->routers), OP_GE, 1);
    605  mock_routerinfo = smartlist_get(our_routerlist->routers, 0);
    606  set_server_identity_key(mock_routerinfo->identity_pkey);
    607  mock_routerinfo->cache_info.published_on = time(NULL);
    608 
    609  /* Treat "all" requests as if they were unencrypted */
    610  mock_routerinfo->cache_info.send_unencrypted = 1;
    611 
    612  conn = new_dir_conn();
    613 
    614  const char *req = SERVER_DESC_GET("all");
    615  tt_int_op(directory_handle_command_get(conn, req, NULL, 0), OP_EQ, 0);
    616 
    617  //TODO: Is this a BUG?
    618  //It requires strlen(signed_descriptor_len)+1 as body_len but returns a body
    619  //which is smaller than that by annotation_len bytes
    620  fetch_from_buf_http(TO_CONN(conn)->outbuf, &header, MAX_HEADERS_SIZE,
    621                      &body, &body_used,
    622                      1024*1024, 0);
    623 
    624  tt_assert(header);
    625  tt_assert(body);
    626 
    627  tt_ptr_op(strstr(header, "HTTP/1.0 200 OK\r\n"), OP_EQ, header);
    628  tt_assert(strstr(header, "Content-Type: text/plain\r\n"));
    629  tt_assert(strstr(header, "Content-Encoding: identity\r\n"));
    630 
    631  //TODO: Is this a BUG?
    632  //This is what should be expected: tt_int_op(body_used, OP_EQ, strlen(body));
    633  tt_int_op(body_used, OP_EQ,
    634            mock_routerinfo->cache_info.signed_descriptor_len);
    635 
    636  tt_str_op(body, OP_EQ, mock_routerinfo->cache_info.signed_descriptor_body +
    637                         mock_routerinfo->cache_info.annotations_len);
    638  tt_ptr_op(conn->spool, OP_EQ, NULL);
    639 
    640  done:
    641    UNMOCK(router_get_my_routerinfo);
    642    UNMOCK(connection_write_to_buf_impl_);
    643    connection_free_minimal(TO_CONN(conn));
    644    tor_free(header);
    645    tor_free(body);
    646 
    647    routerlist_free_all();
    648    nodelist_free_all();
    649    entry_guards_free_all();
    650 }
    651 
    652 static char
    653 TEST_DESCRIPTOR[] =
    654 "@uploaded-at 2014-06-08 19:20:11\n"
    655 "@source \"127.0.0.1\"\n"
    656 "router test000a 127.0.0.1 5000 0 7000\n"
    657 "platform Tor 0.2.5.3-alpha-dev on Linux\n"
    658 "protocols Link 1 2 Circuit 1\n"
    659 "published 2014-06-08 19:20:11\n"
    660 "fingerprint C7E7 CCB8 179F 8CC3 7F5C 8A04 2B3A 180B 934B 14BA\n"
    661 "uptime 0\n"
    662 "bandwidth 1073741824 1073741824 0\n"
    663 "extra-info-digest 67A152A4C7686FB07664F872620635F194D76D95\n"
    664 "caches-extra-info\n"
    665 "onion-key\n"
    666 "-----BEGIN RSA PUBLIC KEY-----\n"
    667 "MIGJAoGBAOuBUIEBARMkkka/TGyaQNgUEDLP0KG7sy6KNQTNOlZHUresPr/vlVjo\n"
    668 "HPpLMfu9M2z18c51YX/muWwY9x4MyQooD56wI4+AqXQcJRwQfQlPn3Ay82uZViA9\n"
    669 "DpBajRieLlKKkl145KjArpD7F5BVsqccvjErgFYXvhhjSrx7BVLnAgMBAAE=\n"
    670 "-----END RSA PUBLIC KEY-----\n"
    671 "signing-key\n"
    672 "-----BEGIN RSA PUBLIC KEY-----\n"
    673 "MIGJAoGBAN6NLnSxWQnFXxqZi5D3b0BMgV6y9NJLGjYQVP+eWtPZWgqyv4zeYsqv\n"
    674 "O9y6c5lvxyUxmNHfoAbe/s8f2Vf3/YaC17asAVSln4ktrr3e9iY74a9RMWHv1Gzk\n"
    675 "3042nMcqj3PEhRN0PoLkcOZNjjmNbaqki6qy9bWWZDNTdo+uI44dAgMBAAE=\n"
    676 "-----END RSA PUBLIC KEY-----\n"
    677 "hidden-service-dir\n"
    678 "contact auth0@test.test\n"
    679 "ntor-onion-key pK4bs08ERYN591jj7ca17Rn9Q02TIEfhnjR6hSq+fhU=\n"
    680 "reject *:*\n"
    681 "router-signature\n"
    682 "-----BEGIN SIGNATURE-----\n"
    683 "rx88DuM3Y7tODlHNDDEVzKpwh3csaG1or+T4l2Xs1oq3iHHyPEtB6QTLYrC60trG\n"
    684 "aAPsj3DEowGfjga1b248g2dtic8Ab+0exfjMm1RHXfDam5TXXZU3A0wMyoHjqHuf\n"
    685 "eChGPgFNUvEc+5YtD27qEDcUjcinYztTs7/dzxBT4PE=\n"
    686 "-----END SIGNATURE-----\n";
    687 
    688 static void
    689 test_dir_handle_get_server_descriptors_authority(void* data)
    690 {
    691  dir_connection_t *conn = NULL;
    692  char *header = NULL;
    693  char *body = NULL;
    694  size_t body_used = 0;
    695  crypto_pk_t *identity_pkey = pk_generate(0);
    696  (void) data;
    697 
    698  MOCK(router_get_my_routerinfo,
    699       dhg_tests_router_get_my_routerinfo);
    700  MOCK(connection_write_to_buf_impl_, connection_write_to_buf_mock);
    701 
    702  /* init mock */
    703  router_get_my_routerinfo();
    704  crypto_pk_get_digest(identity_pkey,
    705                       mock_routerinfo->cache_info.identity_digest);
    706 
    707  // the digest is mine (the channel is unnecrypted, so we must allow sending)
    708  set_server_identity_key(identity_pkey);
    709  mock_routerinfo->cache_info.send_unencrypted = 1;
    710 
    711  /* Setup descriptor */
    712  long annotation_len = strstr(TEST_DESCRIPTOR, "router ") - TEST_DESCRIPTOR;
    713  mock_routerinfo->cache_info.signed_descriptor_body =
    714    tor_strdup(TEST_DESCRIPTOR);
    715  mock_routerinfo->cache_info.signed_descriptor_len =
    716    strlen(TEST_DESCRIPTOR) - annotation_len;
    717  mock_routerinfo->cache_info.annotations_len = annotation_len;
    718  mock_routerinfo->cache_info.published_on = time(NULL);
    719 
    720  conn = new_dir_conn();
    721 
    722  const char *req = SERVER_DESC_GET("authority");
    723  tt_int_op(directory_handle_command_get(conn, req, NULL, 0), OP_EQ, 0);
    724 
    725  //TODO: Is this a BUG?
    726  //It requires strlen(TEST_DESCRIPTOR)+1 as body_len but returns a body which
    727  //is smaller than that by annotation_len bytes
    728  fetch_from_buf_http(TO_CONN(conn)->outbuf, &header, MAX_HEADERS_SIZE,
    729                      &body, &body_used, strlen(TEST_DESCRIPTOR)+1, 0);
    730 
    731  tt_assert(header);
    732  tt_assert(body);
    733 
    734  tt_ptr_op(strstr(header, "HTTP/1.0 200 OK\r\n"), OP_EQ, header);
    735  tt_assert(strstr(header, "Content-Type: text/plain\r\n"));
    736  tt_assert(strstr(header, "Content-Encoding: identity\r\n"));
    737 
    738  tt_int_op(body_used, OP_EQ, strlen(body));
    739 
    740  tt_str_op(body, OP_EQ, TEST_DESCRIPTOR + annotation_len);
    741  tt_ptr_op(conn->spool, OP_EQ, NULL);
    742 
    743  done:
    744    UNMOCK(router_get_my_routerinfo);
    745    UNMOCK(connection_write_to_buf_impl_);
    746    tor_free(mock_routerinfo->cache_info.signed_descriptor_body);
    747    tor_free(mock_routerinfo);
    748    connection_free_minimal(TO_CONN(conn));
    749    tor_free(header);
    750    tor_free(body);
    751    crypto_pk_free(identity_pkey);
    752 }
    753 
    754 static void
    755 test_dir_handle_get_server_descriptors_fp(void* data)
    756 {
    757  dir_connection_t *conn = NULL;
    758  char *header = NULL;
    759  char *body = NULL;
    760  size_t body_used = 0;
    761  crypto_pk_t *identity_pkey = pk_generate(0);
    762  (void) data;
    763 
    764  MOCK(router_get_my_routerinfo,
    765       dhg_tests_router_get_my_routerinfo);
    766  MOCK(connection_write_to_buf_impl_, connection_write_to_buf_mock);
    767 
    768  /* init mock */
    769  router_get_my_routerinfo();
    770  crypto_pk_get_digest(identity_pkey,
    771                       mock_routerinfo->cache_info.identity_digest);
    772 
    773  // the digest is mine (the channel is unnecrypted, so we must allow sending)
    774  set_server_identity_key(identity_pkey);
    775  mock_routerinfo->cache_info.send_unencrypted = 1;
    776 
    777  /* Setup descriptor */
    778  long annotation_len = strstr(TEST_DESCRIPTOR, "router ") - TEST_DESCRIPTOR;
    779  mock_routerinfo->cache_info.signed_descriptor_body =
    780    tor_strdup(TEST_DESCRIPTOR);
    781  mock_routerinfo->cache_info.signed_descriptor_len =
    782    strlen(TEST_DESCRIPTOR) - annotation_len;
    783  mock_routerinfo->cache_info.annotations_len = annotation_len;
    784  mock_routerinfo->cache_info.published_on = time(NULL);
    785 
    786  conn = new_dir_conn();
    787 
    788  #define HEX1 "Fe0daff89127389bc67558691231234551193EEE"
    789  #define HEX2 "Deadbeef99999991111119999911111111f00ba4"
    790  const char *hex_digest = hex_str(mock_routerinfo->cache_info.identity_digest,
    791                                   DIGEST_LEN);
    792 
    793  char req[155];
    794  tor_snprintf(req, sizeof(req), SERVER_DESC_GET("fp/%s+" HEX1 "+" HEX2),
    795               hex_digest);
    796  tt_int_op(directory_handle_command_get(conn, req, NULL, 0), OP_EQ, 0);
    797 
    798  //TODO: Is this a BUG?
    799  //It requires strlen(TEST_DESCRIPTOR)+1 as body_len but returns a body which
    800  //is smaller than that by annotation_len bytes
    801  fetch_from_buf_http(TO_CONN(conn)->outbuf, &header, MAX_HEADERS_SIZE,
    802                      &body, &body_used, strlen(TEST_DESCRIPTOR)+1, 0);
    803 
    804  tt_assert(header);
    805  tt_assert(body);
    806 
    807  tt_ptr_op(strstr(header, "HTTP/1.0 200 OK\r\n"), OP_EQ, header);
    808  tt_assert(strstr(header, "Content-Type: text/plain\r\n"));
    809  tt_assert(strstr(header, "Content-Encoding: identity\r\n"));
    810 
    811  tt_int_op(body_used, OP_EQ, strlen(body));
    812 
    813  tt_str_op(body, OP_EQ, TEST_DESCRIPTOR + annotation_len);
    814  tt_ptr_op(conn->spool, OP_EQ, NULL);
    815 
    816  done:
    817    UNMOCK(router_get_my_routerinfo);
    818    UNMOCK(connection_write_to_buf_impl_);
    819    tor_free(mock_routerinfo->cache_info.signed_descriptor_body);
    820    tor_free(mock_routerinfo);
    821    connection_free_minimal(TO_CONN(conn));
    822    tor_free(header);
    823    tor_free(body);
    824    crypto_pk_free(identity_pkey);
    825 }
    826 
    827 #define HEX1 "Fe0daff89127389bc67558691231234551193EEE"
    828 #define HEX2 "Deadbeef99999991111119999911111111f00ba4"
    829 
    830 static void
    831 test_dir_handle_get_server_descriptors_d(void* data)
    832 {
    833  dir_connection_t *conn = NULL;
    834  char *header = NULL;
    835  char *body = NULL;
    836  size_t body_used = 0;
    837  crypto_pk_t *identity_pkey = pk_generate(0);
    838  (void) data;
    839 
    840  /* Setup fake routerlist. */
    841  helper_setup_fake_routerlist();
    842 
    843  MOCK(connection_write_to_buf_impl_, connection_write_to_buf_mock);
    844 
    845  /* Get one router's signed_descriptor_digest */
    846  routerlist_t *our_routerlist = router_get_routerlist();
    847  tt_int_op(smartlist_len(our_routerlist->routers), OP_GE, 1);
    848  routerinfo_t *router = smartlist_get(our_routerlist->routers, 0);
    849  const char *hex_digest = hex_str(router->cache_info.signed_descriptor_digest,
    850                                   DIGEST_LEN);
    851 
    852  conn = new_dir_conn();
    853 
    854  char req_header[155]; /* XXX Why 155? What kind of number is that?? */
    855  tor_snprintf(req_header, sizeof(req_header),
    856               SERVER_DESC_GET("d/%s+" HEX1 "+" HEX2), hex_digest);
    857  tt_int_op(directory_handle_command_get(conn, req_header, NULL, 0), OP_EQ, 0);
    858 
    859  //TODO: Is this a BUG?
    860  //It requires strlen(signed_descriptor_len)+1 as body_len but returns a body
    861  //which is smaller than that by annotation_len bytes
    862  fetch_from_buf_http(TO_CONN(conn)->outbuf, &header, MAX_HEADERS_SIZE,
    863                      &body, &body_used,
    864                      router->cache_info.signed_descriptor_len+1, 0);
    865 
    866  tt_assert(header);
    867  tt_assert(body);
    868 
    869  tt_ptr_op(strstr(header, "HTTP/1.0 200 OK\r\n"), OP_EQ, header);
    870  tt_assert(strstr(header, "Content-Type: text/plain\r\n"));
    871  tt_assert(strstr(header, "Content-Encoding: identity\r\n"));
    872 
    873  //TODO: Is this a BUG?
    874  //This is what should be expected:
    875  //tt_int_op(body_used, OP_EQ, strlen(body));
    876  tt_int_op(body_used, OP_EQ, router->cache_info.signed_descriptor_len);
    877 
    878  tt_str_op(body, OP_EQ, router->cache_info.signed_descriptor_body +
    879                         router->cache_info.annotations_len);
    880  tt_ptr_op(conn->spool, OP_EQ, NULL);
    881 
    882  done:
    883    UNMOCK(connection_write_to_buf_impl_);
    884    tor_free(mock_routerinfo);
    885    connection_free_minimal(TO_CONN(conn));
    886    tor_free(header);
    887    tor_free(body);
    888    crypto_pk_free(identity_pkey);
    889 
    890    routerlist_free_all();
    891    nodelist_free_all();
    892    entry_guards_free_all();
    893 }
    894 
    895 static void
    896 test_dir_handle_get_server_descriptors_busy(void* data)
    897 {
    898  dir_connection_t *conn = NULL;
    899  char *header = NULL;
    900  crypto_pk_t *identity_pkey = pk_generate(0);
    901  (void) data;
    902 
    903  /* Setup fake routerlist. */
    904  helper_setup_fake_routerlist();
    905 
    906  MOCK(connection_write_to_buf_impl_, connection_write_to_buf_mock);
    907 
    908  //Make it busy
    909  MOCK(get_options, mock_get_options);
    910  init_mock_options();
    911  mock_options->CountPrivateBandwidth = 1;
    912 
    913  /* Get one router's signed_descriptor_digest */
    914  routerlist_t *our_routerlist = router_get_routerlist();
    915  tt_int_op(smartlist_len(our_routerlist->routers), OP_GE, 1);
    916  routerinfo_t *router = smartlist_get(our_routerlist->routers, 0);
    917  const char *hex_digest = hex_str(router->cache_info.signed_descriptor_digest,
    918                                   DIGEST_LEN);
    919 
    920  conn = new_dir_conn();
    921 
    922  #define HEX1 "Fe0daff89127389bc67558691231234551193EEE"
    923  #define HEX2 "Deadbeef99999991111119999911111111f00ba4"
    924  char req_header[155]; /* XXX 155? Why 155? */
    925  tor_snprintf(req_header, sizeof(req_header),
    926               SERVER_DESC_GET("d/%s+" HEX1 "+" HEX2), hex_digest);
    927  tt_int_op(directory_handle_command_get(conn, req_header, NULL, 0), OP_EQ, 0);
    928 
    929  fetch_from_buf_http(TO_CONN(conn)->outbuf, &header, MAX_HEADERS_SIZE,
    930                      NULL, NULL, 1, 0);
    931 
    932  tt_assert(header);
    933  tt_str_op(SERVER_BUSY, OP_EQ, header);
    934 
    935  tt_ptr_op(conn->spool, OP_EQ, NULL);
    936 
    937  done:
    938    UNMOCK(get_options);
    939    UNMOCK(connection_write_to_buf_impl_);
    940    tor_free(mock_routerinfo);
    941    connection_free_minimal(TO_CONN(conn));
    942    tor_free(header);
    943    crypto_pk_free(identity_pkey);
    944 
    945    routerlist_free_all();
    946    nodelist_free_all();
    947    entry_guards_free_all();
    948 }
    949 
    950 static void
    951 test_dir_handle_get_server_keys_bad_req(void* data)
    952 {
    953  dir_connection_t *conn = NULL;
    954  char *header = NULL;
    955  (void) data;
    956 
    957  MOCK(connection_write_to_buf_impl_, connection_write_to_buf_mock);
    958 
    959  conn = new_dir_conn();
    960 
    961  const char *req = GET("/tor/keys/");
    962  tt_int_op(directory_handle_command_get(conn, req, NULL, 0), OP_EQ, 0);
    963 
    964  fetch_from_buf_http(TO_CONN(conn)->outbuf, &header, MAX_HEADERS_SIZE,
    965                      NULL, NULL, 1, 0);
    966 
    967  tt_assert(header);
    968  tt_str_op(BAD_REQUEST, OP_EQ, header);
    969 
    970  done:
    971    UNMOCK(connection_write_to_buf_impl_);
    972    connection_free_minimal(TO_CONN(conn));
    973    tor_free(header);
    974 }
    975 
    976 static void
    977 test_dir_handle_get_server_keys_all_not_found(void* data)
    978 {
    979  dir_connection_t *conn = NULL;
    980  char *header = NULL;
    981  (void) data;
    982 
    983  MOCK(connection_write_to_buf_impl_, connection_write_to_buf_mock);
    984 
    985  conn = new_dir_conn();
    986 
    987  const char *req = GET("/tor/keys/all");
    988  tt_int_op(directory_handle_command_get(conn, req, NULL, 0), OP_EQ, 0);
    989 
    990  fetch_from_buf_http(TO_CONN(conn)->outbuf, &header, MAX_HEADERS_SIZE,
    991                      NULL, NULL, 1, 0);
    992 
    993  tt_assert(header);
    994  tt_str_op(NOT_FOUND, OP_EQ, header);
    995 
    996  done:
    997    UNMOCK(connection_write_to_buf_impl_);
    998    connection_free_minimal(TO_CONN(conn));
    999    tor_free(header);
   1000 }
   1001 
   1002 #define TEST_CERTIFICATE AUTHORITY_CERT_3
   1003 #define TEST_SIGNING_KEY AUTHORITY_SIGNKEY_A_DIGEST
   1004 
   1005 static const char TEST_CERT_IDENT_KEY[] =
   1006  "D867ACF56A9D229B35C25F0090BC9867E906BE69";
   1007 
   1008 static void
   1009 test_dir_handle_get_server_keys_all(void* data)
   1010 {
   1011  dir_connection_t *conn = NULL;
   1012  char *header = NULL;
   1013  char *body = NULL;
   1014  size_t body_used = 0;
   1015  const char digest[DIGEST_LEN] = "";
   1016 
   1017  dir_server_t *ds = NULL;
   1018  (void) data;
   1019 
   1020  MOCK(connection_write_to_buf_impl_, connection_write_to_buf_mock);
   1021 
   1022  clear_dir_servers();
   1023  routerlist_free_all();
   1024 
   1025  /* create a trusted ds */
   1026  ds = trusted_dir_server_new("ds", "127.0.0.1", 9059, 9060, NULL, digest,
   1027                              NULL, V3_DIRINFO, 1.0);
   1028  tt_assert(ds);
   1029  dir_server_add(ds);
   1030 
   1031  /* ds v3_identity_digest is the certificate's identity_key */
   1032  base16_decode(ds->v3_identity_digest, DIGEST_LEN,
   1033                TEST_CERT_IDENT_KEY, HEX_DIGEST_LEN);
   1034  tt_int_op(0, OP_EQ, trusted_dirs_load_certs_from_string(TEST_CERTIFICATE,
   1035    TRUSTED_DIRS_CERTS_SRC_DL_BY_ID_DIGEST, 1, NULL));
   1036 
   1037  conn = new_dir_conn();
   1038 
   1039  const char *req = GET("/tor/keys/all");
   1040  tt_int_op(directory_handle_command_get(conn, req, NULL, 0), OP_EQ, 0);
   1041 
   1042  fetch_from_buf_http(TO_CONN(conn)->outbuf, &header, MAX_HEADERS_SIZE,
   1043                      &body, &body_used, strlen(TEST_CERTIFICATE)+1, 0);
   1044 
   1045  tt_assert(header);
   1046  tt_assert(body);
   1047 
   1048  tt_ptr_op(strstr(header, "HTTP/1.0 200 OK\r\n"), OP_EQ, header);
   1049  tt_assert(strstr(header, "Content-Type: text/plain\r\n"));
   1050  tt_assert(strstr(header, "Content-Encoding: identity\r\n"));
   1051  tt_assert(strstr(header, "Content-Length: 1883\r\n"));
   1052 
   1053  tt_str_op(TEST_CERTIFICATE, OP_EQ, body);
   1054 
   1055  done:
   1056    UNMOCK(connection_write_to_buf_impl_);
   1057    connection_free_minimal(TO_CONN(conn));
   1058    tor_free(header);
   1059    tor_free(body);
   1060 
   1061    clear_dir_servers();
   1062    routerlist_free_all();
   1063 }
   1064 
   1065 static void
   1066 test_dir_handle_get_server_keys_authority_not_found(void* data)
   1067 {
   1068  dir_connection_t *conn = NULL;
   1069  char *header = NULL;
   1070  (void) data;
   1071 
   1072  MOCK(connection_write_to_buf_impl_, connection_write_to_buf_mock);
   1073 
   1074  conn = new_dir_conn();
   1075 
   1076  const char *req = GET("/tor/keys/authority");
   1077  tt_int_op(directory_handle_command_get(conn, req, NULL, 0), OP_EQ, 0);
   1078 
   1079  fetch_from_buf_http(TO_CONN(conn)->outbuf, &header, MAX_HEADERS_SIZE,
   1080                      NULL, NULL, 1, 0);
   1081 
   1082  tt_assert(header);
   1083  tt_str_op(NOT_FOUND, OP_EQ, header);
   1084 
   1085  done:
   1086    UNMOCK(connection_write_to_buf_impl_);
   1087    connection_free_minimal(TO_CONN(conn));
   1088    tor_free(header);
   1089 }
   1090 
   1091 static authority_cert_t * mock_cert = NULL;
   1092 
   1093 static authority_cert_t *
   1094 get_my_v3_authority_cert_m(void)
   1095 {
   1096  tor_assert(mock_cert);
   1097  return mock_cert;
   1098 }
   1099 
   1100 static void
   1101 test_dir_handle_get_server_keys_authority(void* data)
   1102 {
   1103  dir_connection_t *conn = NULL;
   1104  char *header = NULL;
   1105  char *body = NULL;
   1106  size_t body_used = 0;
   1107  (void) data;
   1108 
   1109  mock_cert = authority_cert_parse_from_string(TEST_CERTIFICATE,
   1110                                               strlen(TEST_CERTIFICATE),
   1111                                               NULL);
   1112 
   1113  MOCK(get_my_v3_authority_cert, get_my_v3_authority_cert_m);
   1114  MOCK(connection_write_to_buf_impl_, connection_write_to_buf_mock);
   1115 
   1116  conn = new_dir_conn();
   1117 
   1118  const char *req = GET("/tor/keys/authority");
   1119  tt_int_op(directory_handle_command_get(conn, req, NULL, 0), OP_EQ, 0);
   1120 
   1121  fetch_from_buf_http(TO_CONN(conn)->outbuf, &header, MAX_HEADERS_SIZE,
   1122                      &body, &body_used, strlen(TEST_CERTIFICATE)+1, 0);
   1123 
   1124  tt_assert(header);
   1125  tt_assert(body);
   1126 
   1127  tt_ptr_op(strstr(header, "HTTP/1.0 200 OK\r\n"), OP_EQ, header);
   1128  tt_assert(strstr(header, "Content-Type: text/plain\r\n"));
   1129  tt_assert(strstr(header, "Content-Encoding: identity\r\n"));
   1130  tt_assert(strstr(header, "Content-Length: 1883\r\n"));
   1131 
   1132  tt_str_op(TEST_CERTIFICATE, OP_EQ, body);
   1133 
   1134  done:
   1135    UNMOCK(get_my_v3_authority_cert);
   1136    UNMOCK(connection_write_to_buf_impl_);
   1137    connection_free_minimal(TO_CONN(conn));
   1138    tor_free(header);
   1139    tor_free(body);
   1140    authority_cert_free(mock_cert); mock_cert = NULL;
   1141 }
   1142 
   1143 static void
   1144 test_dir_handle_get_server_keys_fp_not_found(void* data)
   1145 {
   1146  dir_connection_t *conn = NULL;
   1147  char *header = NULL;
   1148  (void) data;
   1149 
   1150  MOCK(connection_write_to_buf_impl_, connection_write_to_buf_mock);
   1151 
   1152  conn = new_dir_conn();
   1153 
   1154  const char *req = GET("/tor/keys/fp/somehex");
   1155  tt_int_op(directory_handle_command_get(conn, req, NULL, 0), OP_EQ, 0);
   1156 
   1157  fetch_from_buf_http(TO_CONN(conn)->outbuf, &header, MAX_HEADERS_SIZE,
   1158                      NULL, NULL, 1, 0);
   1159 
   1160  tt_assert(header);
   1161  tt_str_op(NOT_FOUND, OP_EQ, header);
   1162 
   1163  done:
   1164    UNMOCK(connection_write_to_buf_impl_);
   1165    connection_free_minimal(TO_CONN(conn));
   1166    tor_free(header);
   1167 }
   1168 
   1169 static void
   1170 test_dir_handle_get_server_keys_fp(void* data)
   1171 {
   1172  dir_connection_t *conn = NULL;
   1173  char *header = NULL;
   1174  char *body = NULL;
   1175  size_t body_used = 0;
   1176  dir_server_t *ds = NULL;
   1177  const char digest[DIGEST_LEN] = "";
   1178  (void) data;
   1179 
   1180  MOCK(connection_write_to_buf_impl_, connection_write_to_buf_mock);
   1181 
   1182  clear_dir_servers();
   1183  routerlist_free_all();
   1184 
   1185  /* create a trusted ds */
   1186  ds = trusted_dir_server_new("ds", "127.0.0.1", 9059, 9060, NULL, digest,
   1187                              NULL, V3_DIRINFO, 1.0);
   1188  tt_assert(ds);
   1189  dir_server_add(ds);
   1190 
   1191  /* ds v3_identity_digest is the certificate's identity_key */
   1192  base16_decode(ds->v3_identity_digest, DIGEST_LEN,
   1193                TEST_CERT_IDENT_KEY, HEX_DIGEST_LEN);
   1194 
   1195  tt_int_op(0, OP_EQ, trusted_dirs_load_certs_from_string(TEST_CERTIFICATE,
   1196    TRUSTED_DIRS_CERTS_SRC_DL_BY_ID_DIGEST, 1, NULL));
   1197 
   1198  conn = new_dir_conn();
   1199  char req[71];
   1200  tor_snprintf(req, sizeof(req),
   1201                     GET("/tor/keys/fp/%s"), TEST_CERT_IDENT_KEY);
   1202  tt_int_op(directory_handle_command_get(conn, req, NULL, 0), OP_EQ, 0);
   1203 
   1204  fetch_from_buf_http(TO_CONN(conn)->outbuf, &header, MAX_HEADERS_SIZE,
   1205                      &body, &body_used, strlen(TEST_CERTIFICATE)+1, 0);
   1206 
   1207  tt_assert(header);
   1208  tt_assert(body);
   1209 
   1210  tt_ptr_op(strstr(header, "HTTP/1.0 200 OK\r\n"), OP_EQ, header);
   1211  tt_assert(strstr(header, "Content-Type: text/plain\r\n"));
   1212  tt_assert(strstr(header, "Content-Encoding: identity\r\n"));
   1213  tt_assert(strstr(header, "Content-Length: 1883\r\n"));
   1214 
   1215  tt_str_op(TEST_CERTIFICATE, OP_EQ, body);
   1216 
   1217  done:
   1218    UNMOCK(connection_write_to_buf_impl_);
   1219    connection_free_minimal(TO_CONN(conn));
   1220    tor_free(header);
   1221    tor_free(body);
   1222    clear_dir_servers();
   1223    routerlist_free_all();
   1224 }
   1225 
   1226 static void
   1227 test_dir_handle_get_server_keys_sk_not_found(void* data)
   1228 {
   1229  dir_connection_t *conn = NULL;
   1230  char *header = NULL;
   1231  (void) data;
   1232 
   1233  MOCK(connection_write_to_buf_impl_, connection_write_to_buf_mock);
   1234 
   1235  conn = new_dir_conn();
   1236 
   1237  const char *req = GET("/tor/keys/sk/somehex");
   1238  tt_int_op(directory_handle_command_get(conn, req, NULL, 0), OP_EQ, 0);
   1239 
   1240  fetch_from_buf_http(TO_CONN(conn)->outbuf, &header, MAX_HEADERS_SIZE,
   1241                      NULL, NULL, 1, 0);
   1242 
   1243  tt_assert(header);
   1244  tt_str_op(NOT_FOUND, OP_EQ, header);
   1245 
   1246  done:
   1247    UNMOCK(connection_write_to_buf_impl_);
   1248    connection_free_minimal(TO_CONN(conn));
   1249    tor_free(header);
   1250 }
   1251 
   1252 static void
   1253 test_dir_handle_get_server_keys_sk(void* data)
   1254 {
   1255  dir_connection_t *conn = NULL;
   1256  char *header = NULL;
   1257  char *body = NULL;
   1258  size_t body_used = 0;
   1259  (void) data;
   1260 
   1261  mock_cert = authority_cert_parse_from_string(TEST_CERTIFICATE,
   1262                                               strlen(TEST_CERTIFICATE),
   1263                                               NULL);
   1264  MOCK(get_my_v3_authority_cert, get_my_v3_authority_cert_m);
   1265  MOCK(connection_write_to_buf_impl_, connection_write_to_buf_mock);
   1266 
   1267  clear_dir_servers();
   1268  routerlist_free_all();
   1269 
   1270  tt_int_op(0, OP_EQ, trusted_dirs_load_certs_from_string(TEST_CERTIFICATE,
   1271    TRUSTED_DIRS_CERTS_SRC_DL_BY_ID_DIGEST, 1, NULL));
   1272 
   1273  conn = new_dir_conn();
   1274  char req[71];
   1275  tor_snprintf(req, sizeof(req),
   1276               GET("/tor/keys/sk/%s"), TEST_SIGNING_KEY);
   1277  tt_int_op(directory_handle_command_get(conn, req, NULL, 0), OP_EQ, 0);
   1278 
   1279  fetch_from_buf_http(TO_CONN(conn)->outbuf, &header, MAX_HEADERS_SIZE,
   1280                      &body, &body_used, strlen(TEST_CERTIFICATE)+1, 0);
   1281 
   1282  tt_assert(header);
   1283  tt_assert(body);
   1284 
   1285  tt_ptr_op(strstr(header, "HTTP/1.0 200 OK\r\n"), OP_EQ, header);
   1286  tt_assert(strstr(header, "Content-Type: text/plain\r\n"));
   1287  tt_assert(strstr(header, "Content-Encoding: identity\r\n"));
   1288  tt_assert(strstr(header, "Content-Length: 1883\r\n"));
   1289 
   1290  tt_str_op(TEST_CERTIFICATE, OP_EQ, body);
   1291 
   1292  done:
   1293    UNMOCK(get_my_v3_authority_cert);
   1294    UNMOCK(connection_write_to_buf_impl_);
   1295    connection_free_minimal(TO_CONN(conn));
   1296    authority_cert_free(mock_cert); mock_cert = NULL;
   1297    tor_free(header);
   1298    tor_free(body);
   1299 }
   1300 
   1301 static void
   1302 test_dir_handle_get_server_keys_fpsk_not_found(void* data)
   1303 {
   1304  dir_connection_t *conn = NULL;
   1305  char *header = NULL;
   1306  (void) data;
   1307 
   1308  MOCK(connection_write_to_buf_impl_, connection_write_to_buf_mock);
   1309 
   1310  conn = new_dir_conn();
   1311 
   1312  const char *req = GET("/tor/keys/fp-sk/somehex");
   1313  tt_int_op(directory_handle_command_get(conn, req, NULL, 0), OP_EQ, 0);
   1314 
   1315  fetch_from_buf_http(TO_CONN(conn)->outbuf, &header, MAX_HEADERS_SIZE,
   1316                      NULL, NULL, 1, 0);
   1317 
   1318  tt_assert(header);
   1319  tt_str_op(NOT_FOUND, OP_EQ, header);
   1320 
   1321  done:
   1322    UNMOCK(connection_write_to_buf_impl_);
   1323    connection_free_minimal(TO_CONN(conn));
   1324    tor_free(header);
   1325 }
   1326 
   1327 static void
   1328 test_dir_handle_get_server_keys_fpsk(void* data)
   1329 {
   1330  dir_connection_t *conn = NULL;
   1331  char *header = NULL;
   1332  char *body = NULL;
   1333  size_t body_used = 0;
   1334  dir_server_t *ds = NULL;
   1335  const char digest[DIGEST_LEN] = "";
   1336  (void) data;
   1337 
   1338  MOCK(connection_write_to_buf_impl_, connection_write_to_buf_mock);
   1339 
   1340  clear_dir_servers();
   1341  routerlist_free_all();
   1342 
   1343  /* create a trusted ds */
   1344  ds = trusted_dir_server_new("ds", "127.0.0.1", 9059, 9060, NULL, digest,
   1345                              NULL, V3_DIRINFO, 1.0);
   1346  tt_assert(ds);
   1347 
   1348  /* ds v3_identity_digest is the certificate's identity_key */
   1349  base16_decode(ds->v3_identity_digest, DIGEST_LEN,
   1350                TEST_CERT_IDENT_KEY, HEX_DIGEST_LEN);
   1351  dir_server_add(ds);
   1352 
   1353  tt_int_op(0, OP_EQ, trusted_dirs_load_certs_from_string(TEST_CERTIFICATE,
   1354    TRUSTED_DIRS_CERTS_SRC_DL_BY_ID_DIGEST, 1, NULL));
   1355 
   1356  conn = new_dir_conn();
   1357 
   1358  char req[115];
   1359  tor_snprintf(req, sizeof(req),
   1360               GET("/tor/keys/fp-sk/%s-%s"),
   1361               TEST_CERT_IDENT_KEY, TEST_SIGNING_KEY);
   1362 
   1363  tt_int_op(directory_handle_command_get(conn, req, NULL, 0), OP_EQ, 0);
   1364 
   1365  fetch_from_buf_http(TO_CONN(conn)->outbuf, &header, MAX_HEADERS_SIZE,
   1366                      &body, &body_used, strlen(TEST_CERTIFICATE)+1, 0);
   1367 
   1368  tt_assert(header);
   1369  tt_assert(body);
   1370 
   1371  tt_ptr_op(strstr(header, "HTTP/1.0 200 OK\r\n"), OP_EQ, header);
   1372  tt_assert(strstr(header, "Content-Type: text/plain\r\n"));
   1373  tt_assert(strstr(header, "Content-Encoding: identity\r\n"));
   1374  tt_assert(strstr(header, "Content-Length: 1883\r\n"));
   1375 
   1376  tt_str_op(TEST_CERTIFICATE, OP_EQ, body);
   1377 
   1378  done:
   1379    UNMOCK(connection_write_to_buf_impl_);
   1380    connection_free_minimal(TO_CONN(conn));
   1381    tor_free(header);
   1382    tor_free(body);
   1383 
   1384    clear_dir_servers();
   1385    routerlist_free_all();
   1386 }
   1387 
   1388 static void
   1389 test_dir_handle_get_server_keys_busy(void* data)
   1390 {
   1391  dir_connection_t *conn = NULL;
   1392  char *header = NULL;
   1393  dir_server_t *ds = NULL;
   1394  const char digest[DIGEST_LEN] = "";
   1395  (void) data;
   1396 
   1397  clear_dir_servers();
   1398  routerlist_free_all();
   1399 
   1400  /* create a trusted ds */
   1401  ds = trusted_dir_server_new("ds", "127.0.0.1", 9059, 9060, NULL, digest,
   1402                              NULL, V3_DIRINFO, 1.0);
   1403  tt_assert(ds);
   1404 
   1405  /* ds v3_identity_digest is the certificate's identity_key */
   1406  base16_decode(ds->v3_identity_digest, DIGEST_LEN,
   1407                TEST_CERT_IDENT_KEY, HEX_DIGEST_LEN);
   1408  dir_server_add(ds);
   1409 
   1410  tt_int_op(0, OP_EQ, trusted_dirs_load_certs_from_string(TEST_CERTIFICATE,
   1411    TRUSTED_DIRS_CERTS_SRC_DL_BY_ID_DIGEST, 1, NULL));
   1412 
   1413  MOCK(get_options, mock_get_options);
   1414  MOCK(connection_write_to_buf_impl_, connection_write_to_buf_mock);
   1415 
   1416  /* setup busy server */
   1417  init_mock_options();
   1418  mock_options->CountPrivateBandwidth = 1;
   1419 
   1420  conn = new_dir_conn();
   1421  char req[71];
   1422  tor_snprintf(req, sizeof(req), GET("/tor/keys/fp/%s"), TEST_CERT_IDENT_KEY);
   1423  tt_int_op(directory_handle_command_get(conn, req, NULL, 0), OP_EQ, 0);
   1424 
   1425  fetch_from_buf_http(TO_CONN(conn)->outbuf, &header, MAX_HEADERS_SIZE,
   1426                      NULL, NULL, 1, 0);
   1427 
   1428  tt_assert(header);
   1429  tt_str_op(SERVER_BUSY, OP_EQ, header);
   1430 
   1431  done:
   1432    UNMOCK(get_options);
   1433    UNMOCK(connection_write_to_buf_impl_);
   1434    connection_free_minimal(TO_CONN(conn));
   1435    tor_free(header);
   1436    or_options_free(mock_options); mock_options = NULL;
   1437 
   1438    clear_dir_servers();
   1439    routerlist_free_all();
   1440 }
   1441 
   1442 static networkstatus_t *mock_ns_val = NULL;
   1443 static networkstatus_t *
   1444 mock_ns_get_by_flavor(consensus_flavor_t f)
   1445 {
   1446  (void)f;
   1447  return mock_ns_val;
   1448 }
   1449 
   1450 static void
   1451 test_dir_handle_get_status_vote_current_consensus_ns_not_enough_sigs(void* d)
   1452 {
   1453  dir_connection_t *conn = NULL;
   1454  char *header = NULL;
   1455  char *stats = NULL;
   1456  (void) d;
   1457 
   1458  /* init mock */
   1459  mock_ns_val = tor_malloc_zero(sizeof(networkstatus_t));
   1460  mock_ns_val->flavor = FLAV_NS;
   1461  mock_ns_val->type = NS_TYPE_CONSENSUS;
   1462  mock_ns_val->voters = smartlist_new();
   1463  mock_ns_val->valid_after = time(NULL) - 1800;
   1464  mock_ns_val->valid_until = time(NULL) - 60;
   1465 
   1466  #define NETWORK_STATUS "some network status string"
   1467  consdiffmgr_add_consensus(NETWORK_STATUS, mock_ns_val);
   1468 
   1469  /* init mock */
   1470  init_mock_options();
   1471 
   1472  MOCK(get_options, mock_get_options);
   1473  MOCK(connection_write_to_buf_impl_, connection_write_to_buf_mock);
   1474  MOCK(networkstatus_get_latest_consensus_by_flavor, mock_ns_get_by_flavor);
   1475 
   1476  /* start gathering stats */
   1477  mock_options->DirReqStatistics = 1;
   1478  geoip_dirreq_stats_init(time(NULL));
   1479 
   1480  conn = new_dir_conn();
   1481 
   1482  tt_int_op(0, OP_EQ, directory_handle_command_get(conn,
   1483    GET("/tor/status-vote/current/consensus-ns/" HEX1 "+" HEX2), NULL, 0));
   1484 
   1485  fetch_from_buf_http(TO_CONN(conn)->outbuf, &header, MAX_HEADERS_SIZE,
   1486                      NULL, NULL, 1, 0);
   1487 
   1488  tt_assert(header);
   1489  tt_str_op(NOT_ENOUGH_CONSENSUS_SIGNATURES, OP_EQ, header);
   1490 
   1491  stats = geoip_format_dirreq_stats(time(NULL));
   1492  tt_assert(stats);
   1493  tt_assert(strstr(stats, "not-enough-sigs=8"));
   1494 
   1495  done:
   1496    UNMOCK(networkstatus_get_latest_consensus_by_flavor);
   1497    UNMOCK(connection_write_to_buf_impl_);
   1498    UNMOCK(get_options);
   1499 
   1500    connection_free_minimal(TO_CONN(conn));
   1501    tor_free(header);
   1502    tor_free(stats);
   1503    smartlist_free(mock_ns_val->voters);
   1504    tor_free(mock_ns_val);
   1505    or_options_free(mock_options); mock_options = NULL;
   1506 }
   1507 
   1508 static void
   1509 test_dir_handle_get_status_vote_current_consensus_ns_not_found(void* data)
   1510 {
   1511  dir_connection_t *conn = NULL;
   1512  char *header = NULL;
   1513  char *stats = NULL;
   1514  (void) data;
   1515 
   1516  init_mock_options();
   1517 
   1518  MOCK(get_options, mock_get_options);
   1519  MOCK(connection_write_to_buf_impl_, connection_write_to_buf_mock);
   1520 
   1521  /* start gathering stats */
   1522  mock_options->DirReqStatistics = 1;
   1523  geoip_dirreq_stats_init(time(NULL));
   1524 
   1525  conn = new_dir_conn();
   1526  tt_int_op(0, OP_EQ, directory_handle_command_get(conn,
   1527    GET("/tor/status-vote/current/consensus-ns"), NULL, 0));
   1528 
   1529  fetch_from_buf_http(TO_CONN(conn)->outbuf, &header, MAX_HEADERS_SIZE,
   1530                      NULL, NULL, 1, 0);
   1531  tt_assert(header);
   1532  tt_str_op(NOT_FOUND, OP_EQ, header);
   1533 
   1534  stats = geoip_format_dirreq_stats(time(NULL));
   1535  tt_assert(stats);
   1536  tt_assert(strstr(stats, "not-found=8"));
   1537 
   1538  done:
   1539    UNMOCK(connection_write_to_buf_impl_);
   1540    UNMOCK(get_options);
   1541    connection_free_minimal(TO_CONN(conn));
   1542    tor_free(header);
   1543    tor_free(stats);
   1544    or_options_free(mock_options); mock_options = NULL;
   1545 }
   1546 
   1547 static void
   1548 test_dir_handle_get_status_vote_current_consensus_too_old(void *data)
   1549 {
   1550  dir_connection_t *conn = NULL;
   1551  char *header = NULL;
   1552  (void)data;
   1553 
   1554  mock_ns_val = tor_malloc_zero(sizeof(networkstatus_t));
   1555  mock_ns_val->type = NS_TYPE_CONSENSUS;
   1556  mock_ns_val->flavor = FLAV_MICRODESC;
   1557  mock_ns_val->valid_after = time(NULL) - (24 * 60 * 60 + 1800);
   1558  mock_ns_val->fresh_until = time(NULL) - (24 * 60 * 60 + 900);
   1559  mock_ns_val->valid_until = time(NULL) - (24 * 60 * 60 + 20);
   1560 
   1561  #define NETWORK_STATUS "some network status string"
   1562  consdiffmgr_add_consensus(NETWORK_STATUS, mock_ns_val);
   1563 
   1564  init_mock_options();
   1565 
   1566  MOCK(get_options, mock_get_options);
   1567  MOCK(connection_write_to_buf_impl_, connection_write_to_buf_mock);
   1568  MOCK(networkstatus_get_latest_consensus_by_flavor, mock_ns_get_by_flavor);
   1569 
   1570  conn = new_dir_conn();
   1571 
   1572  setup_capture_of_logs(LOG_WARN);
   1573 
   1574  tt_int_op(0, OP_EQ, directory_handle_command_get(conn,
   1575    GET("/tor/status-vote/current/consensus-microdesc"), NULL, 0));
   1576 
   1577  fetch_from_buf_http(TO_CONN(conn)->outbuf, &header, MAX_HEADERS_SIZE,
   1578                      NULL, NULL, 1, 0);
   1579  tt_assert(header);
   1580  tt_str_op(TOO_OLD, OP_EQ, header);
   1581 
   1582  expect_log_msg_containing("too old");
   1583 
   1584  tor_free(header);
   1585  teardown_capture_of_logs();
   1586  tor_free(mock_ns_val);
   1587 
   1588  mock_ns_val = tor_malloc_zero(sizeof(networkstatus_t));
   1589  mock_ns_val->type = NS_TYPE_CONSENSUS;
   1590  mock_ns_val->flavor = FLAV_NS;
   1591  mock_ns_val->valid_after = time(NULL) - (24 * 60 * 60 + 1800);
   1592  mock_ns_val->fresh_until = time(NULL) - (24 * 60 * 60 + 900);
   1593  mock_ns_val->valid_until = time(NULL) - (24 * 60 * 60 + 20);
   1594 
   1595  #define NETWORK_STATUS "some network status string"
   1596  consdiffmgr_add_consensus(NETWORK_STATUS, mock_ns_val);
   1597 
   1598  setup_capture_of_logs(LOG_WARN);
   1599 
   1600  tt_int_op(0, OP_EQ, directory_handle_command_get(conn,
   1601    GET("/tor/status-vote/current/consensus"), NULL, 0));
   1602 
   1603  fetch_from_buf_http(TO_CONN(conn)->outbuf, &header, MAX_HEADERS_SIZE,
   1604                      NULL, NULL, 1, 0);
   1605  tt_assert(header);
   1606  tt_str_op(TOO_OLD, OP_EQ, header);
   1607 
   1608  expect_no_log_entry();
   1609 
   1610  done:
   1611    teardown_capture_of_logs();
   1612    UNMOCK(networkstatus_get_latest_consensus_by_flavor);
   1613    UNMOCK(connection_write_to_buf_impl_);
   1614    UNMOCK(get_options);
   1615    connection_free_minimal(TO_CONN(conn));
   1616    tor_free(header);
   1617    tor_free(mock_ns_val);
   1618    or_options_free(mock_options); mock_options = NULL;
   1619 }
   1620 
   1621 static int dhg_tests_geoip_get_country_by_addr(const tor_addr_t *addr);
   1622 ATTR_UNUSED static int dhg_tests_geoip_get_country_by_addr_called = 0;
   1623 
   1624 int
   1625 dhg_tests_geoip_get_country_by_addr(const tor_addr_t *addr)
   1626 {
   1627  (void)addr;
   1628  dhg_tests_geoip_get_country_by_addr_called++;
   1629  return 1;
   1630 }
   1631 
   1632 static void
   1633 status_vote_current_consensus_ns_test(char **header, char **body,
   1634                                      size_t *body_len)
   1635 {
   1636  dir_connection_t *conn = NULL;
   1637 
   1638  #define NETWORK_STATUS "some network status string"
   1639 #if 0
   1640  common_digests_t digests;
   1641  uint8_t sha3[DIGEST256_LEN];
   1642  memset(&digests, 0x60, sizeof(digests));
   1643  memset(sha3, 0x06, sizeof(sha3));
   1644  dirserv_set_cached_consensus_networkstatus(NETWORK_STATUS, "ns", &digests,
   1645                                             sha3,
   1646                                             time(NULL));
   1647 #endif /* 0 */
   1648  networkstatus_t *ns = tor_malloc_zero(sizeof(networkstatus_t));
   1649  ns->type = NS_TYPE_CONSENSUS;
   1650  ns->flavor = FLAV_NS;
   1651  ns->valid_after = time(NULL) - 1800;
   1652  ns->fresh_until = time(NULL) - 900;
   1653  ns->valid_until = time(NULL) - 60;
   1654  consdiffmgr_add_consensus(NETWORK_STATUS, ns);
   1655  networkstatus_vote_free(ns);
   1656 
   1657  MOCK(connection_write_to_buf_impl_, connection_write_to_buf_mock);
   1658 
   1659  tt_assert(mock_options);
   1660  mock_options->DirReqStatistics = 1;
   1661  geoip_dirreq_stats_init(time(NULL));
   1662 
   1663  /* init geoip database */
   1664  geoip_parse_entry("10,50,AB", AF_INET);
   1665  tt_str_op("ab", OP_EQ, geoip_get_country_name(1));
   1666 
   1667  conn = new_dir_conn();
   1668 
   1669  tt_int_op(0, OP_EQ, directory_handle_command_get(conn,
   1670    GET("/tor/status-vote/current/consensus-ns"), NULL, 0));
   1671 
   1672  fetch_from_buf_http(TO_CONN(conn)->outbuf, header, MAX_HEADERS_SIZE,
   1673                      body, body_len, strlen(NETWORK_STATUS)+7, 0);
   1674 
   1675  done:
   1676    UNMOCK(connection_write_to_buf_impl_);
   1677    connection_free_minimal(TO_CONN(conn));
   1678 }
   1679 
   1680 static void
   1681 test_dir_handle_get_status_vote_current_consensus_ns(void* data)
   1682 {
   1683  char *header = NULL;
   1684  char *body = NULL, *comp_body = NULL;
   1685  size_t body_used = 0, comp_body_used = 0;
   1686  char *stats = NULL, *hist = NULL;
   1687  (void) data;
   1688 
   1689  dirserv_free_all();
   1690  clear_geoip_db();
   1691 
   1692  MOCK(geoip_get_country_by_addr,
   1693       dhg_tests_geoip_get_country_by_addr);
   1694  MOCK(get_options, mock_get_options);
   1695 
   1696  init_mock_options();
   1697 
   1698  status_vote_current_consensus_ns_test(&header, &comp_body, &comp_body_used);
   1699  tt_assert(header);
   1700 
   1701  tt_ptr_op(strstr(header, "HTTP/1.0 200 OK\r\n"), OP_EQ, header);
   1702  tt_assert(strstr(header, "Content-Type: text/plain\r\n"));
   1703  tt_assert(strstr(header, "Content-Encoding: identity\r\n"));
   1704  tt_assert(strstr(header, "Pragma: no-cache\r\n"));
   1705 
   1706  compress_method_t compression = detect_compression_method(comp_body,
   1707                                                            comp_body_used);
   1708  tt_int_op(ZLIB_METHOD, OP_EQ, compression);
   1709 
   1710  tor_uncompress(&body, &body_used, comp_body, comp_body_used,
   1711                 compression, 0, LOG_PROTOCOL_WARN);
   1712 
   1713  tt_str_op(NETWORK_STATUS, OP_EQ, body);
   1714  tt_int_op(strlen(NETWORK_STATUS), OP_EQ, body_used);
   1715 
   1716  stats = geoip_format_dirreq_stats(time(NULL));
   1717  tt_assert(stats);
   1718 
   1719  tt_assert(strstr(stats, "ok=8"));
   1720  tt_assert(strstr(stats, "dirreq-v3-ips ab=8"));
   1721  tt_assert(strstr(stats, "dirreq-v3-reqs ab=8"));
   1722  tt_assert(strstr(stats, "dirreq-v3-direct-dl"
   1723                          " complete=0,timeout=0,running=4"));
   1724 
   1725  hist = geoip_get_request_history();
   1726  tt_assert(hist);
   1727  tt_str_op("ab=8", OP_EQ, hist);
   1728 
   1729  done:
   1730    UNMOCK(geoip_get_country_by_addr);
   1731    UNMOCK(get_options);
   1732    tor_free(header);
   1733    tor_free(comp_body);
   1734    tor_free(body);
   1735    tor_free(stats);
   1736    tor_free(hist);
   1737    or_options_free(mock_options); mock_options = NULL;
   1738 
   1739    dirserv_free_all();
   1740    clear_geoip_db();
   1741 }
   1742 
   1743 static void
   1744 test_dir_handle_get_status_vote_current_consensus_ns_busy(void* data)
   1745 {
   1746  char *header = NULL;
   1747  char *body = NULL;
   1748  size_t body_used = 0;
   1749  char *stats = NULL;
   1750  (void) data;
   1751 
   1752  dirserv_free_all();
   1753  clear_geoip_db();
   1754 
   1755  MOCK(get_options, mock_get_options);
   1756 
   1757  // Make it busy
   1758  init_mock_options();
   1759  mock_options->CountPrivateBandwidth = 1;
   1760 
   1761  status_vote_current_consensus_ns_test(&header, &body, &body_used);
   1762  tt_assert(header);
   1763 
   1764  tt_str_op(SERVER_BUSY, OP_EQ, header);
   1765 
   1766  stats = geoip_format_dirreq_stats(time(NULL));
   1767  tt_assert(stats);
   1768  tt_assert(strstr(stats, "busy=8"));
   1769 
   1770  done:
   1771    UNMOCK(get_options);
   1772    tor_free(header);
   1773    tor_free(body);
   1774    or_options_free(mock_options); mock_options = NULL;
   1775 
   1776    tor_free(stats);
   1777    dirserv_free_all();
   1778    clear_geoip_db();
   1779 }
   1780 
   1781 static void
   1782 test_dir_handle_get_status_vote_current_not_found(void* data)
   1783 {
   1784  dir_connection_t *conn = NULL;
   1785  char *header = NULL;
   1786  (void) data;
   1787 
   1788  MOCK(connection_write_to_buf_impl_, connection_write_to_buf_mock);
   1789 
   1790  conn = new_dir_conn();
   1791  tt_int_op(0, OP_EQ, directory_handle_command_get(conn,
   1792    GET("/tor/status-vote/current/" HEX1), NULL, 0));
   1793 
   1794  fetch_from_buf_http(TO_CONN(conn)->outbuf, &header, MAX_HEADERS_SIZE,
   1795                      NULL, NULL, 1, 0);
   1796  tt_assert(header);
   1797  tt_str_op(NOT_FOUND, OP_EQ, header);
   1798 
   1799  done:
   1800    UNMOCK(connection_write_to_buf_impl_);
   1801    connection_free_minimal(TO_CONN(conn));
   1802    tor_free(header);
   1803 }
   1804 
   1805 /* What vote do we ask for, to get the vote in vote_descriptors.inc ? */
   1806 #define VOTE_DIGEST "78400095d8e834d87135cfc46235c909f0e99911"
   1807 
   1808 static void
   1809 status_vote_current_d_test(char **header, char **body, size_t *body_l)
   1810 {
   1811  dir_connection_t *conn = NULL;
   1812 
   1813  MOCK(connection_write_to_buf_impl_, connection_write_to_buf_mock);
   1814 
   1815  conn = new_dir_conn();
   1816  tt_int_op(0, OP_EQ, directory_handle_command_get(conn,
   1817    GET("/tor/status-vote/current/d/" VOTE_DIGEST), NULL, 0));
   1818 
   1819  fetch_from_buf_http(TO_CONN(conn)->outbuf, header, MAX_HEADERS_SIZE,
   1820                      body, body_l, strlen(VOTE_BODY_V3)+1, 0);
   1821  tt_assert(header);
   1822 
   1823  done:
   1824    UNMOCK(connection_write_to_buf_impl_);
   1825    connection_free_minimal(TO_CONN(conn));
   1826 }
   1827 
   1828 static void
   1829 status_vote_next_d_test(char **header, char **body, size_t *body_l)
   1830 {
   1831  dir_connection_t *conn = NULL;
   1832 
   1833  MOCK(connection_write_to_buf_impl_, connection_write_to_buf_mock);
   1834 
   1835  conn = new_dir_conn();
   1836  tt_int_op(0, OP_EQ, directory_handle_command_get(conn,
   1837    GET("/tor/status-vote/next/d/" VOTE_DIGEST), NULL, 0));
   1838 
   1839  fetch_from_buf_http(TO_CONN(conn)->outbuf, header, MAX_HEADERS_SIZE,
   1840                      body, body_l, strlen(VOTE_BODY_V3)+1, 0);
   1841  tt_assert(header);
   1842 
   1843  done:
   1844    UNMOCK(connection_write_to_buf_impl_);
   1845    connection_free_minimal(TO_CONN(conn));
   1846 }
   1847 
   1848 static void
   1849 test_dir_handle_get_status_vote_current_d_not_found(void* data)
   1850 {
   1851  char *header = NULL;
   1852  (void) data;
   1853 
   1854  status_vote_current_d_test(&header, NULL, NULL);
   1855 
   1856  tt_assert(header);
   1857  tt_str_op(NOT_FOUND, OP_EQ, header);
   1858 
   1859  done:
   1860    tor_free(header);
   1861 }
   1862 
   1863 static void
   1864 test_dir_handle_get_status_vote_next_d_not_found(void* data)
   1865 {
   1866  char *header = NULL;
   1867  (void) data;
   1868 
   1869  status_vote_next_d_test(&header, NULL, NULL);
   1870 
   1871  tt_assert(header);
   1872  tt_str_op(NOT_FOUND, OP_EQ, header);
   1873 
   1874  done:
   1875    UNMOCK(connection_write_to_buf_impl_);
   1876    tor_free(header);
   1877 }
   1878 
   1879 static void
   1880 test_dir_handle_get_status_vote_d(void* data)
   1881 {
   1882  char *header = NULL, *body = NULL;
   1883  size_t body_used = 0;
   1884  dir_server_t *ds = NULL;
   1885  const char digest[DIGEST_LEN] = "";
   1886  (void) data;
   1887 
   1888  MOCK(check_signature_token, mock_ignore_signature_token);
   1889  clear_dir_servers();
   1890  dirvote_free_all();
   1891 
   1892  /* create a trusted ds */
   1893  ds = trusted_dir_server_new("ds", "127.0.0.1", 9059, 9060, NULL, digest,
   1894                              NULL, V3_DIRINFO, 1.0);
   1895  tt_assert(ds);
   1896  dir_server_add(ds);
   1897 
   1898  /* ds v3_identity_digest is the certificate's identity_key */
   1899  base16_decode(ds->v3_identity_digest, DIGEST_LEN,
   1900                TEST_CERT_IDENT_KEY, HEX_DIGEST_LEN);
   1901 
   1902  init_mock_options();
   1903  mock_options->AuthoritativeDir = 1;
   1904  mock_options->V3AuthoritativeDir = 1;
   1905  mock_options->TestingV3AuthVotingStartOffset = 0;
   1906  mock_options->TestingV3AuthInitialVotingInterval = 1;
   1907  mock_options->TestingV3AuthInitialVoteDelay = 1;
   1908  mock_options->TestingV3AuthInitialDistDelay = 1;
   1909 
   1910  time_t now = 1441223455 -1;
   1911  dirauth_sched_recalculate_timing(mock_options, now);
   1912 
   1913  const char *msg_out = NULL;
   1914  int status_out = 0;
   1915  struct pending_vote_t *pv = dirvote_add_vote(VOTE_BODY_V3, 0, "foo",
   1916                                               &msg_out, &status_out);
   1917  tt_assert(pv);
   1918 
   1919  status_vote_current_d_test(&header, &body, &body_used);
   1920 
   1921  tt_assert(header);
   1922  tt_ptr_op(strstr(header, "HTTP/1.0 200 OK\r\n"), OP_EQ, header);
   1923  tt_assert(strstr(header, "Content-Type: text/plain\r\n"));
   1924  tt_assert(strstr(header, "Content-Encoding: identity\r\n"));
   1925  tt_assert(strstr(header, "Content-Length: 4403\r\n"));
   1926 
   1927  tt_str_op(VOTE_BODY_V3, OP_EQ, body);
   1928 
   1929  tor_free(header);
   1930  tor_free(body);
   1931 
   1932  status_vote_next_d_test(&header, &body, &body_used);
   1933 
   1934  tt_assert(header);
   1935  tt_ptr_op(strstr(header, "HTTP/1.0 200 OK\r\n"), OP_EQ, header);
   1936  tt_assert(strstr(header, "Content-Type: text/plain\r\n"));
   1937  tt_assert(strstr(header, "Content-Encoding: identity\r\n"));
   1938  tt_assert(strstr(header, "Content-Length: 4403\r\n"));
   1939 
   1940  tt_str_op(VOTE_BODY_V3, OP_EQ, body);
   1941 
   1942  done:
   1943    UNMOCK(check_signature_token);
   1944    tor_free(header);
   1945    tor_free(body);
   1946    or_options_free(mock_options); mock_options = NULL;
   1947 
   1948    clear_dir_servers();
   1949    dirvote_free_all();
   1950    routerlist_free_all();
   1951 }
   1952 
   1953 static void
   1954 test_dir_handle_get_status_vote_next_not_found(void* data)
   1955 {
   1956  dir_connection_t *conn = NULL;
   1957  char *header = NULL;
   1958  (void) data;
   1959 
   1960  MOCK(connection_write_to_buf_impl_, connection_write_to_buf_mock);
   1961 
   1962  conn = new_dir_conn();
   1963  tt_int_op(0, OP_EQ, directory_handle_command_get(conn,
   1964    GET("/tor/status-vote/next/" HEX1), NULL, 0));
   1965 
   1966  fetch_from_buf_http(TO_CONN(conn)->outbuf, &header, MAX_HEADERS_SIZE,
   1967                      NULL, NULL, 1, 0);
   1968  tt_assert(header);
   1969  tt_str_op(NOT_FOUND, OP_EQ, header);
   1970 
   1971  done:
   1972    UNMOCK(connection_write_to_buf_impl_);
   1973    connection_free_minimal(TO_CONN(conn));
   1974    tor_free(header);
   1975 }
   1976 
   1977 static void
   1978 status_vote_next_consensus_test(char **header, char **body, size_t *body_used)
   1979 {
   1980  dir_connection_t *conn = NULL;
   1981 
   1982  MOCK(connection_write_to_buf_impl_, connection_write_to_buf_mock);
   1983 
   1984  conn = new_dir_conn();
   1985  tt_int_op(0, OP_EQ, directory_handle_command_get(conn,
   1986    GET("/tor/status-vote/next/consensus"), NULL, 0));
   1987 
   1988  fetch_from_buf_http(TO_CONN(conn)->outbuf, header, MAX_HEADERS_SIZE,
   1989                      body, body_used, 18, 0);
   1990  done:
   1991    UNMOCK(connection_write_to_buf_impl_);
   1992    connection_free_minimal(TO_CONN(conn));
   1993 }
   1994 
   1995 static void
   1996 test_dir_handle_get_status_vote_next_consensus_not_found(void* data)
   1997 {
   1998  char *header = NULL, *body = NULL;
   1999  size_t body_used;
   2000  (void) data;
   2001 
   2002  status_vote_next_consensus_test(&header, &body, &body_used);
   2003 
   2004  tt_assert(header);
   2005  tt_str_op(NOT_FOUND, OP_EQ, header);
   2006 
   2007  done:
   2008    tor_free(header);
   2009    tor_free(body);
   2010 }
   2011 
   2012 static void
   2013 test_dir_handle_get_status_vote_current_authority_not_found(void* data)
   2014 {
   2015  dir_connection_t *conn = NULL;
   2016  char *header = NULL;
   2017  (void) data;
   2018 
   2019  MOCK(connection_write_to_buf_impl_, connection_write_to_buf_mock);
   2020  MOCK(check_signature_token, mock_ignore_signature_token);
   2021 
   2022  conn = new_dir_conn();
   2023  tt_int_op(0, OP_EQ, directory_handle_command_get(conn,
   2024    GET("/tor/status-vote/current/authority"), NULL, 0));
   2025 
   2026  fetch_from_buf_http(TO_CONN(conn)->outbuf, &header, MAX_HEADERS_SIZE,
   2027                      NULL, NULL, 1, 0);
   2028  tt_assert(header);
   2029  tt_str_op(NOT_FOUND, OP_EQ, header);
   2030 
   2031  done:
   2032    UNMOCK(check_signature_token);
   2033    UNMOCK(connection_write_to_buf_impl_);
   2034    connection_free_minimal(TO_CONN(conn));
   2035    tor_free(header);
   2036 }
   2037 
   2038 static void
   2039 test_dir_handle_get_status_vote_next_authority_not_found(void* data)
   2040 {
   2041  dir_connection_t *conn = NULL;
   2042  char *header = NULL;
   2043  (void) data;
   2044 
   2045  MOCK(connection_write_to_buf_impl_, connection_write_to_buf_mock);
   2046  MOCK(check_signature_token, mock_ignore_signature_token);
   2047 
   2048  conn = new_dir_conn();
   2049  tt_int_op(0, OP_EQ, directory_handle_command_get(conn,
   2050    GET("/tor/status-vote/next/authority"), NULL, 0));
   2051 
   2052  fetch_from_buf_http(TO_CONN(conn)->outbuf, &header, MAX_HEADERS_SIZE,
   2053                      NULL, NULL, 1, 0);
   2054  tt_assert(header);
   2055  tt_str_op(NOT_FOUND, OP_EQ, header);
   2056 
   2057  done:
   2058    UNMOCK(check_signature_token);
   2059    UNMOCK(connection_write_to_buf_impl_);
   2060    connection_free_minimal(TO_CONN(conn));
   2061    tor_free(header);
   2062 }
   2063 
   2064 static void
   2065 test_dir_handle_get_status_vote_next_bandwidth_not_found(void* data)
   2066 {
   2067  dir_connection_t *conn = NULL;
   2068  char *header = NULL;
   2069  (void) data;
   2070 
   2071  MOCK(connection_write_to_buf_impl_, connection_write_to_buf_mock);
   2072  MOCK(check_signature_token, mock_ignore_signature_token);
   2073  conn = new_dir_conn();
   2074 
   2075  tt_int_op(0, OP_EQ, directory_handle_command_get(conn,
   2076    GET("/tor/status-vote/next/bandwidth"), NULL, 0));
   2077 
   2078  fetch_from_buf_http(TO_CONN(conn)->outbuf, &header, MAX_HEADERS_SIZE,
   2079                      NULL, NULL, 1, 0);
   2080  tt_assert(header);
   2081  tt_str_op(NOT_FOUND, OP_EQ, header);
   2082 
   2083  done:
   2084    UNMOCK(check_signature_token);
   2085    UNMOCK(connection_write_to_buf_impl_);
   2086    connection_free_minimal(TO_CONN(conn));
   2087    tor_free(header);
   2088 }
   2089 
   2090 static const char* dhg_tests_dirvote_get_pending_consensus(
   2091                                           consensus_flavor_t flav);
   2092 
   2093 const char*
   2094 dhg_tests_dirvote_get_pending_consensus(consensus_flavor_t flav)
   2095 {
   2096  (void)flav;
   2097  return "pending consensus";
   2098 }
   2099 
   2100 static void
   2101 test_dir_handle_get_status_vote_next_consensus(void* data)
   2102 {
   2103  char *header = NULL, *body = NULL;
   2104  size_t body_used = 0;
   2105  (void) data;
   2106 
   2107  MOCK(dirvote_get_pending_consensus,
   2108       dhg_tests_dirvote_get_pending_consensus);
   2109 
   2110  status_vote_next_consensus_test(&header, &body, &body_used);
   2111  tt_assert(header);
   2112 
   2113  tt_ptr_op(strstr(header, "HTTP/1.0 200 OK\r\n"), OP_EQ, header);
   2114  tt_assert(strstr(header, "Content-Type: text/plain\r\n"));
   2115  tt_assert(strstr(header, "Content-Encoding: identity\r\n"));
   2116  tt_assert(strstr(header, "Content-Length: 17\r\n"));
   2117 
   2118  tt_str_op("pending consensus", OP_EQ, body);
   2119 
   2120  done:
   2121    UNMOCK(dirvote_get_pending_consensus);
   2122    tor_free(header);
   2123    tor_free(body);
   2124 }
   2125 
   2126 static void
   2127 test_dir_handle_get_status_vote_next_consensus_busy(void* data)
   2128 {
   2129  char *header = NULL, *body = NULL;
   2130  size_t body_used = 0;
   2131  (void) data;
   2132 
   2133  MOCK(get_options, mock_get_options);
   2134  MOCK(dirvote_get_pending_consensus,
   2135       dhg_tests_dirvote_get_pending_consensus);
   2136 
   2137  //Make it busy
   2138  init_mock_options();
   2139  mock_options->CountPrivateBandwidth = 1;
   2140 
   2141  status_vote_next_consensus_test(&header, &body, &body_used);
   2142 
   2143  tt_assert(header);
   2144  tt_str_op(SERVER_BUSY, OP_EQ, header);
   2145 
   2146  done:
   2147    UNMOCK(dirvote_get_pending_consensus);
   2148    UNMOCK(get_options);
   2149    tor_free(header);
   2150    tor_free(body);
   2151    or_options_free(mock_options); mock_options = NULL;
   2152 }
   2153 
   2154 static void
   2155 status_vote_next_consensus_signatures_test(char **header, char **body,
   2156                                           size_t *body_used)
   2157 {
   2158  dir_connection_t *conn = NULL;
   2159 
   2160  MOCK(connection_write_to_buf_impl_, connection_write_to_buf_mock);
   2161 
   2162  conn = new_dir_conn();
   2163  tt_int_op(0, OP_EQ, directory_handle_command_get(conn,
   2164    GET("/tor/status-vote/next/consensus-signatures"), NULL, 0));
   2165 
   2166  fetch_from_buf_http(TO_CONN(conn)->outbuf, header, MAX_HEADERS_SIZE,
   2167                      body, body_used, 22, 0);
   2168 
   2169  done:
   2170    connection_free_minimal(TO_CONN(conn));
   2171    UNMOCK(connection_write_to_buf_impl_);
   2172 }
   2173 
   2174 static void
   2175 test_dir_handle_get_status_vote_next_consensus_signatures_not_found(void* data)
   2176 {
   2177  char *header = NULL, *body = NULL;
   2178  size_t body_used;
   2179  (void) data;
   2180 
   2181  status_vote_next_consensus_signatures_test(&header, &body, &body_used);
   2182 
   2183  tt_assert(header);
   2184  tt_str_op(NOT_FOUND, OP_EQ, header);
   2185 
   2186  done:
   2187    tor_free(header);
   2188    tor_free(body);
   2189 }
   2190 
   2191 static const char* dhg_tests_dirvote_get_pending_detached_signatures(void);
   2192 
   2193 const char*
   2194 dhg_tests_dirvote_get_pending_detached_signatures(void)
   2195 {
   2196  return "pending detached sigs";
   2197 }
   2198 
   2199 static void
   2200 test_dir_handle_get_status_vote_next_consensus_signatures(void* data)
   2201 {
   2202  char *header = NULL, *body = NULL;
   2203  size_t body_used = 0;
   2204  (void) data;
   2205 
   2206  MOCK(dirvote_get_pending_detached_signatures,
   2207       dhg_tests_dirvote_get_pending_detached_signatures);
   2208 
   2209  status_vote_next_consensus_signatures_test(&header, &body, &body_used);
   2210  tt_assert(header);
   2211 
   2212  tt_ptr_op(strstr(header, "HTTP/1.0 200 OK\r\n"), OP_EQ, header);
   2213  tt_assert(strstr(header, "Content-Type: text/plain\r\n"));
   2214  tt_assert(strstr(header, "Content-Encoding: identity\r\n"));
   2215  tt_assert(strstr(header, "Content-Length: 21\r\n"));
   2216 
   2217  tt_str_op("pending detached sigs", OP_EQ, body);
   2218 
   2219  done:
   2220    UNMOCK(dirvote_get_pending_detached_signatures);
   2221    tor_free(header);
   2222    tor_free(body);
   2223 }
   2224 
   2225 static void
   2226 test_dir_handle_get_status_vote_next_consensus_signatures_busy(void* data)
   2227 {
   2228  char *header = NULL, *body = NULL;
   2229  size_t body_used;
   2230  (void) data;
   2231 
   2232  MOCK(dirvote_get_pending_detached_signatures,
   2233       dhg_tests_dirvote_get_pending_detached_signatures);
   2234  MOCK(get_options, mock_get_options);
   2235 
   2236  //Make it busy
   2237  init_mock_options();
   2238  mock_options->CountPrivateBandwidth = 1;
   2239 
   2240  status_vote_next_consensus_signatures_test(&header, &body, &body_used);
   2241 
   2242  tt_assert(header);
   2243  tt_str_op(SERVER_BUSY, OP_EQ, header);
   2244 
   2245  done:
   2246    UNMOCK(get_options);
   2247    UNMOCK(dirvote_get_pending_detached_signatures);
   2248    tor_free(header);
   2249    tor_free(body);
   2250    or_options_free(mock_options); mock_options = NULL;
   2251 }
   2252 
   2253 static void
   2254 test_dir_handle_get_status_vote_next_authority(void* data)
   2255 {
   2256  dir_connection_t *conn = NULL;
   2257  char *header = NULL, *body = NULL;
   2258  const char *msg_out = NULL;
   2259  int status_out = 0;
   2260  size_t body_used = 0;
   2261  dir_server_t *ds = NULL;
   2262  const char digest[DIGEST_LEN] = "";
   2263  (void) data;
   2264 
   2265  MOCK(check_signature_token, mock_ignore_signature_token);
   2266  clear_dir_servers();
   2267  routerlist_free_all();
   2268  dirvote_free_all();
   2269 
   2270  mock_cert = authority_cert_parse_from_string(TEST_CERTIFICATE,
   2271                                               strlen(TEST_CERTIFICATE),
   2272                                               NULL);
   2273 
   2274  /* create a trusted ds */
   2275  ds = trusted_dir_server_new("ds", "127.0.0.1", 9059, 9060, NULL, digest,
   2276                              NULL, V3_DIRINFO, 1.0);
   2277  tt_assert(ds);
   2278  dir_server_add(ds);
   2279 
   2280  /* ds v3_identity_digest is the certificate's identity_key */
   2281  base16_decode(ds->v3_identity_digest, DIGEST_LEN,
   2282                TEST_CERT_IDENT_KEY, HEX_DIGEST_LEN);
   2283  tt_int_op(0, OP_EQ, trusted_dirs_load_certs_from_string(TEST_CERTIFICATE,
   2284    TRUSTED_DIRS_CERTS_SRC_DL_BY_ID_DIGEST, 1, NULL));
   2285 
   2286  init_mock_options();
   2287  mock_options->AuthoritativeDir = 1;
   2288  mock_options->V3AuthoritativeDir = 1;
   2289  mock_options->TestingV3AuthVotingStartOffset = 0;
   2290  mock_options->TestingV3AuthInitialVotingInterval = 1;
   2291  mock_options->TestingV3AuthInitialVoteDelay = 1;
   2292  mock_options->TestingV3AuthInitialDistDelay = 1;
   2293 
   2294  time_t now = 1441223455 -1;
   2295  dirauth_sched_recalculate_timing(mock_options, now);
   2296 
   2297  struct pending_vote_t *vote = dirvote_add_vote(VOTE_BODY_V3, 0, "foo",
   2298                                                 &msg_out, &status_out);
   2299  tt_assert(vote);
   2300 
   2301  MOCK(get_my_v3_authority_cert, get_my_v3_authority_cert_m);
   2302  MOCK(connection_write_to_buf_impl_, connection_write_to_buf_mock);
   2303 
   2304  conn = new_dir_conn();
   2305  tt_int_op(0, OP_EQ, directory_handle_command_get(conn,
   2306    GET("/tor/status-vote/next/authority"), NULL, 0));
   2307 
   2308  fetch_from_buf_http(TO_CONN(conn)->outbuf, &header, MAX_HEADERS_SIZE,
   2309                      &body, &body_used, strlen(VOTE_BODY_V3)+1, 0);
   2310 
   2311  tt_assert(header);
   2312  tt_ptr_op(strstr(header, "HTTP/1.0 200 OK\r\n"), OP_EQ, header);
   2313  tt_assert(strstr(header, "Content-Type: text/plain\r\n"));
   2314  tt_assert(strstr(header, "Content-Encoding: identity\r\n"));
   2315  tt_assert(strstr(header, "Content-Length: 4403\r\n"));
   2316 
   2317  tt_str_op(VOTE_BODY_V3, OP_EQ, body);
   2318 
   2319  done:
   2320    UNMOCK(check_signature_token);
   2321    UNMOCK(connection_write_to_buf_impl_);
   2322    UNMOCK(get_my_v3_authority_cert);
   2323    connection_free_minimal(TO_CONN(conn));
   2324    tor_free(header);
   2325    tor_free(body);
   2326    authority_cert_free(mock_cert); mock_cert = NULL;
   2327    or_options_free(mock_options); mock_options = NULL;
   2328 
   2329    clear_dir_servers();
   2330    routerlist_free_all();
   2331    dirvote_free_all();
   2332 }
   2333 
   2334 static void
   2335 test_dir_handle_get_status_vote_next_bandwidth(void* data)
   2336 {
   2337  dir_connection_t *conn = NULL;
   2338  char *header = NULL, *body = NULL;
   2339  size_t body_used = 0;
   2340  (void) data;
   2341 
   2342  const char *content =
   2343    "1541171221\n"
   2344    "node_id=$68A483E05A2ABDCA6DA5A3EF8DB5177638A27F80 "
   2345    "master_key_ed25519=YaqV4vbvPYKucElk297eVdNArDz9HtIwUoIeo0+cVIpQ "
   2346    "bw=760 nick=Test time=2018-05-08T16:13:26\n";
   2347 
   2348  init_mock_options();
   2349  MOCK(get_options, mock_get_options);
   2350  mock_options->V3BandwidthsFile = tor_strdup(
   2351    get_fname_rnd("V3BandwidthsFile")
   2352  );
   2353 
   2354  write_str_to_file(mock_options->V3BandwidthsFile, content, 0);
   2355 
   2356  MOCK(connection_write_to_buf_impl_, connection_write_to_buf_mock);
   2357 
   2358  conn = new_dir_conn();
   2359  tt_int_op(0, OP_EQ, directory_handle_command_get(conn,
   2360    GET("/tor/status-vote/next/bandwidth"), NULL, 0));
   2361 
   2362  fetch_from_buf_http(TO_CONN(conn)->outbuf, &header, MAX_HEADERS_SIZE,
   2363                      &body, &body_used, strlen(content)+1, 0);
   2364 
   2365  tt_assert(header);
   2366  tt_ptr_op(strstr(header, "HTTP/1.0 200 OK\r\n"), OP_EQ, header);
   2367  tt_assert(strstr(header, "Content-Type: text/plain\r\n"));
   2368  tt_assert(strstr(header, "Content-Encoding: identity\r\n"));
   2369  tt_assert(strstr(header, "Content-Length: 167\r\n"));
   2370 
   2371  /* Check cache lifetime */
   2372  char expbuf[RFC1123_TIME_LEN+1];
   2373  time_t now = approx_time();
   2374  /* BANDWIDTH_CACHE_LIFETIME is defined in dircache.c. */
   2375  format_rfc1123_time(expbuf, (time_t)(now + 30*60));
   2376  char *expires = NULL;
   2377  /* Change to 'Cache-control: max-age=%d' if using http/1.1. */
   2378  tor_asprintf(&expires, "Expires: %s\r\n", expbuf);
   2379  tt_assert(strstr(header, expires));
   2380 
   2381  tt_int_op(body_used, OP_EQ, strlen(body));
   2382  tt_str_op(content, OP_EQ, body);
   2383 
   2384  tor_free(header);
   2385  tor_free(body);
   2386 
   2387  /* Request the file using compression, the result should be the same. */
   2388  tt_int_op(0, OP_EQ, directory_handle_command_get(conn,
   2389    GET("/tor/status-vote/next/bandwidth.z"), NULL, 0));
   2390 
   2391  fetch_from_buf_http(TO_CONN(conn)->outbuf, &header, MAX_HEADERS_SIZE,
   2392                      &body, &body_used, strlen(content)+1, 0);
   2393 
   2394  tt_assert(header);
   2395  tt_ptr_op(strstr(header, "HTTP/1.0 200 OK\r\n"), OP_EQ, header);
   2396  tt_assert(strstr(header, "Content-Encoding: deflate\r\n"));
   2397 
   2398  /* Since using connection_write_to_buf_mock instead of mocking
   2399   * connection_buf_add_compress, the content is not actually compressed.
   2400   * If it would, the size and content would be different than the original.
   2401  */
   2402 
   2403 done:
   2404  UNMOCK(get_options);
   2405  UNMOCK(connection_write_to_buf_impl_);
   2406  connection_free_minimal(TO_CONN(conn));
   2407  tor_free(header);
   2408  tor_free(body);
   2409  tor_free(expires);
   2410  or_options_free(mock_options);
   2411 }
   2412 
   2413 static void
   2414 test_dir_handle_get_status_vote_current_authority(void* data)
   2415 {
   2416  dir_connection_t *conn = NULL;
   2417  char *header = NULL, *body = NULL;
   2418  const char *msg_out = NULL;
   2419  int status_out = 0;
   2420  size_t body_used = 0;
   2421  const char digest[DIGEST_LEN] = "";
   2422 
   2423  dir_server_t *ds = NULL;
   2424  (void) data;
   2425 
   2426  MOCK(check_signature_token, mock_ignore_signature_token);
   2427  clear_dir_servers();
   2428  routerlist_free_all();
   2429  dirvote_free_all();
   2430 
   2431  mock_cert = authority_cert_parse_from_string(TEST_CERTIFICATE,
   2432                                               strlen(TEST_CERTIFICATE),
   2433                                               NULL);
   2434 
   2435  /* create a trusted ds */
   2436  ds = trusted_dir_server_new("ds", "127.0.0.1", 9059, 9060, NULL, digest,
   2437                              NULL, V3_DIRINFO, 1.0);
   2438  tt_assert(ds);
   2439  dir_server_add(ds);
   2440 
   2441  /* ds v3_identity_digest is the certificate's identity_key */
   2442  base16_decode(ds->v3_identity_digest, DIGEST_LEN,
   2443                TEST_CERT_IDENT_KEY, HEX_DIGEST_LEN);
   2444 
   2445  tt_int_op(0, OP_EQ, trusted_dirs_load_certs_from_string(TEST_CERTIFICATE,
   2446    TRUSTED_DIRS_CERTS_SRC_DL_BY_ID_DIGEST, 1, NULL));
   2447 
   2448  init_mock_options();
   2449  mock_options->AuthoritativeDir = 1;
   2450  mock_options->V3AuthoritativeDir = 1;
   2451  mock_options->TestingV3AuthVotingStartOffset = 0;
   2452  mock_options->TestingV3AuthInitialVotingInterval = 1;
   2453  mock_options->TestingV3AuthInitialVoteDelay = 1;
   2454  mock_options->TestingV3AuthInitialDistDelay = 1;
   2455 
   2456  time_t now = 1441223455;
   2457  dirauth_sched_recalculate_timing(mock_options, now-1);
   2458 
   2459  struct pending_vote_t *vote = dirvote_add_vote(VOTE_BODY_V3, 0, "foo",
   2460                                                 &msg_out, &status_out);
   2461  tt_assert(vote);
   2462 
   2463  // move the pending vote to previous vote
   2464  dirvote_act(mock_options, now+1);
   2465 
   2466  MOCK(get_my_v3_authority_cert, get_my_v3_authority_cert_m);
   2467  MOCK(connection_write_to_buf_impl_, connection_write_to_buf_mock);
   2468 
   2469  conn = new_dir_conn();
   2470  tt_int_op(0, OP_EQ, directory_handle_command_get(conn,
   2471    GET("/tor/status-vote/current/authority"), NULL, 0));
   2472 
   2473  fetch_from_buf_http(TO_CONN(conn)->outbuf, &header, MAX_HEADERS_SIZE,
   2474                      &body, &body_used, strlen(VOTE_BODY_V3)+1, 0);
   2475 
   2476  tt_assert(header);
   2477  tt_ptr_op(strstr(header, "HTTP/1.0 200 OK\r\n"), OP_EQ, header);
   2478  tt_assert(strstr(header, "Content-Type: text/plain\r\n"));
   2479  tt_assert(strstr(header, "Content-Encoding: identity\r\n"));
   2480  tt_assert(strstr(header, "Content-Length: 4403\r\n"));
   2481 
   2482  tt_str_op(VOTE_BODY_V3, OP_EQ, body);
   2483 
   2484  done:
   2485    UNMOCK(check_signature_token);
   2486    UNMOCK(connection_write_to_buf_impl_);
   2487    UNMOCK(get_my_v3_authority_cert);
   2488    connection_free_minimal(TO_CONN(conn));
   2489    tor_free(header);
   2490    tor_free(body);
   2491    authority_cert_free(mock_cert); mock_cert = NULL;
   2492    or_options_free(mock_options); mock_options = NULL;
   2493 
   2494    clear_dir_servers();
   2495    routerlist_free_all();
   2496    dirvote_free_all();
   2497 }
   2498 
   2499 /* Test that a late vote is rejected, but an on-time vote is accepted. */
   2500 static void
   2501 test_dir_handle_get_status_vote_too_late(void* data)
   2502 {
   2503  dir_connection_t *conn = NULL;
   2504  char *header = NULL, *body = NULL;
   2505  const char *msg_out = NULL;
   2506  int status_out = 0;
   2507  size_t body_used = 0;
   2508  const char digest[DIGEST_LEN] = "";
   2509 
   2510  dir_server_t *ds = NULL;
   2511  const char* mode = (const char *)data;
   2512 
   2513  MOCK(check_signature_token, mock_ignore_signature_token);
   2514  clear_dir_servers();
   2515  routerlist_free_all();
   2516  dirvote_free_all();
   2517 
   2518  mock_cert = authority_cert_parse_from_string(TEST_CERTIFICATE,
   2519                                               strlen(TEST_CERTIFICATE),
   2520                                               NULL);
   2521 
   2522  /* create a trusted ds */
   2523  ds = trusted_dir_server_new("ds", "127.0.0.1", 9059, 9060, NULL, digest,
   2524                              NULL, V3_DIRINFO, 1.0);
   2525  tt_assert(ds);
   2526  dir_server_add(ds);
   2527 
   2528  /* ds v3_identity_digest is the certificate's identity_key */
   2529  base16_decode(ds->v3_identity_digest, DIGEST_LEN,
   2530                TEST_CERT_IDENT_KEY, HEX_DIGEST_LEN);
   2531 
   2532  tt_int_op(0, OP_EQ, trusted_dirs_load_certs_from_string(TEST_CERTIFICATE,
   2533    TRUSTED_DIRS_CERTS_SRC_DL_BY_ID_DIGEST, 1, NULL));
   2534 
   2535  init_mock_options();
   2536  mock_options->AuthoritativeDir = 1;
   2537  mock_options->V3AuthoritativeDir = 1;
   2538 
   2539  int base_delay = 0;
   2540  int vote_interval = 0;
   2541  int start_offset = 0;
   2542 
   2543  tt_assert(mode);
   2544  /* Set the required timings, see below for details */
   2545  if (strcmp(mode, "min") == 0) {
   2546    /* The minimum valid test network timing */
   2547    base_delay = 2;
   2548    vote_interval = 10;
   2549    start_offset = vote_interval - 5;
   2550  } else if (strcmp(mode, "chutney") == 0) {
   2551    /* The test network timing used by chutney */
   2552    base_delay = 4;
   2553    vote_interval = 20;
   2554    start_offset = vote_interval - 5;
   2555  } else if (strcmp(mode, "half-public") == 0) {
   2556    /* The short consensus failure timing used in the public network */
   2557    base_delay = 5*60;
   2558    vote_interval = 30*60;
   2559    start_offset = vote_interval - 9*60 - 5;
   2560  } else if (strcmp(mode, "public") == 0) {
   2561    /* The standard timing used in the public network */
   2562    base_delay = 5*60;
   2563    vote_interval = 60*60;
   2564    start_offset = vote_interval - 9*60 - 5;
   2565  }
   2566 
   2567  tt_assert(base_delay > 0);
   2568  tt_assert(vote_interval > 0);
   2569  tt_assert(start_offset > 0);
   2570 
   2571  /* Skew the time to fit the fixed time in the vote */
   2572  mock_options->TestingV3AuthVotingStartOffset = start_offset;
   2573  /* Calculate the rest of the timings */
   2574  mock_options->TestingV3AuthInitialVotingInterval = vote_interval;
   2575  mock_options->TestingV3AuthInitialVoteDelay = base_delay;
   2576  mock_options->TestingV3AuthInitialDistDelay = base_delay;
   2577 
   2578  time_t now = 1441223455;
   2579  dirauth_sched_recalculate_timing(mock_options, now-1);
   2580  const time_t voting_starts = voting_schedule.voting_starts;
   2581  const time_t fetch_missing = voting_schedule.fetch_missing_votes;
   2582 
   2583  struct pending_vote_t *vote = NULL;
   2584 
   2585  /* Next voting interval */
   2586  vote = dirvote_add_vote(VOTE_BODY_V3,
   2587                          fetch_missing + vote_interval, "foo",
   2588                          &msg_out, &status_out);
   2589  tt_assert(!vote);
   2590  tt_int_op(status_out, OP_EQ, 400);
   2591  tt_str_op(msg_out, OP_EQ,
   2592            "Posted vote received too late, would be dangerous to count it");
   2593 
   2594  /* Just after fetch missing */
   2595  vote = dirvote_add_vote(VOTE_BODY_V3,
   2596                          fetch_missing + 1, "foo",
   2597                          &msg_out, &status_out);
   2598  tt_assert(!vote);
   2599  tt_int_op(status_out, OP_EQ, 400);
   2600  tt_str_op(msg_out, OP_EQ,
   2601            "Posted vote received too late, would be dangerous to count it");
   2602 
   2603  /* On fetch missing */
   2604  vote = dirvote_add_vote(VOTE_BODY_V3,
   2605                          fetch_missing, "foo",
   2606                          &msg_out, &status_out);
   2607  tt_assert(vote);
   2608 
   2609  /* Move the pending vote to previous vote */
   2610  dirvote_act(mock_options, now+1);
   2611  /* And reset the timing */
   2612  dirauth_sched_recalculate_timing(mock_options, now-1);
   2613 
   2614  /* Between voting starts and fetch missing */
   2615  vote = dirvote_add_vote(VOTE_BODY_V3,
   2616                          voting_starts + 1, "foo",
   2617                          &msg_out, &status_out);
   2618  tt_assert(vote);
   2619 
   2620  /* Move the pending vote to previous vote */
   2621  dirvote_act(mock_options, now+1);
   2622  /* And reset the timing */
   2623  dirauth_sched_recalculate_timing(mock_options, now-1);
   2624 
   2625  /* On voting starts */
   2626  vote = dirvote_add_vote(VOTE_BODY_V3,
   2627                          voting_starts, "foo",
   2628                          &msg_out, &status_out);
   2629  tt_assert(vote);
   2630 
   2631  /* Move the pending vote to previous vote */
   2632  dirvote_act(mock_options, now+1);
   2633  /* And reset the timing */
   2634  dirauth_sched_recalculate_timing(mock_options, now-1);
   2635 
   2636  /* Just before voting starts */
   2637  vote = dirvote_add_vote(VOTE_BODY_V3,
   2638                          voting_starts - 1, "foo",
   2639                          &msg_out, &status_out);
   2640  tt_assert(vote);
   2641 
   2642  /* Move the pending vote to previous vote */
   2643  dirvote_act(mock_options, now+1);
   2644 
   2645  MOCK(get_my_v3_authority_cert, get_my_v3_authority_cert_m);
   2646  MOCK(connection_write_to_buf_impl_, connection_write_to_buf_mock);
   2647 
   2648  conn = new_dir_conn();
   2649  tt_int_op(0, OP_EQ, directory_handle_command_get(conn,
   2650    GET("/tor/status-vote/current/authority"), NULL, 0));
   2651 
   2652  fetch_from_buf_http(TO_CONN(conn)->outbuf, &header, MAX_HEADERS_SIZE,
   2653                      &body, &body_used, strlen(VOTE_BODY_V3)+1, 0);
   2654 
   2655  tt_assert(header);
   2656  tt_ptr_op(strstr(header, "HTTP/1.0 200 OK\r\n"), OP_EQ, header);
   2657  tt_assert(strstr(header, "Content-Type: text/plain\r\n"));
   2658  tt_assert(strstr(header, "Content-Encoding: identity\r\n"));
   2659  tt_assert(strstr(header, "Content-Length: 4403\r\n"));
   2660 
   2661  tt_str_op(VOTE_BODY_V3, OP_EQ, body);
   2662 
   2663  done:
   2664    UNMOCK(check_signature_token);
   2665    UNMOCK(connection_write_to_buf_impl_);
   2666    UNMOCK(get_my_v3_authority_cert);
   2667    connection_free_minimal(TO_CONN(conn));
   2668    tor_free(header);
   2669    tor_free(body);
   2670    authority_cert_free(mock_cert); mock_cert = NULL;
   2671    or_options_free(mock_options); mock_options = NULL;
   2672 
   2673    clear_dir_servers();
   2674    routerlist_free_all();
   2675    dirvote_free_all();
   2676 }
   2677 
   2678 static void
   2679 test_dir_handle_get_parse_accept_encoding(void *arg)
   2680 {
   2681  (void)arg;
   2682  const unsigned B_NONE = 1u << NO_METHOD;
   2683  const unsigned B_ZLIB = 1u << ZLIB_METHOD;
   2684  const unsigned B_GZIP = 1u << GZIP_METHOD;
   2685  const unsigned B_LZMA = 1u << LZMA_METHOD;
   2686  const unsigned B_ZSTD = 1u << ZSTD_METHOD;
   2687 
   2688  unsigned encodings;
   2689 
   2690  encodings = parse_accept_encoding_header("");
   2691  tt_uint_op(B_NONE, OP_EQ, encodings);
   2692 
   2693  encodings = parse_accept_encoding_header("  ");
   2694  tt_uint_op(B_NONE, OP_EQ, encodings);
   2695 
   2696  encodings = parse_accept_encoding_header("dewey, cheatham, and howe ");
   2697  tt_uint_op(B_NONE, OP_EQ, encodings);
   2698 
   2699  encodings = parse_accept_encoding_header("dewey, cheatham, and gzip");
   2700  tt_uint_op(B_NONE, OP_EQ, encodings);
   2701 
   2702  encodings = parse_accept_encoding_header("dewey, cheatham, and, gzip");
   2703  tt_uint_op(B_NONE|B_GZIP, OP_EQ, encodings);
   2704 
   2705  encodings = parse_accept_encoding_header(" gzip");
   2706  tt_uint_op(B_NONE|B_GZIP, OP_EQ, encodings);
   2707 
   2708  encodings = parse_accept_encoding_header("gzip");
   2709  tt_uint_op(B_NONE|B_GZIP, OP_EQ, encodings);
   2710 
   2711  encodings = parse_accept_encoding_header("x-zstd, deflate, x-tor-lzma");
   2712  tt_uint_op(B_NONE|B_ZLIB|B_ZSTD|B_LZMA, OP_EQ, encodings);
   2713 
   2714  encodings = parse_accept_encoding_header(
   2715                                        "x-zstd, deflate, x-tor-lzma, gzip");
   2716  tt_uint_op(B_NONE|B_ZLIB|B_ZSTD|B_LZMA|B_GZIP, OP_EQ, encodings);
   2717 
   2718  encodings = parse_accept_encoding_header("x-zstd,deflate,x-tor-lzma,gzip");
   2719  tt_uint_op(B_NONE|B_ZLIB|B_ZSTD|B_LZMA|B_GZIP, OP_EQ, encodings);
   2720 
   2721 done:
   2722  ;
   2723 }
   2724 
   2725 #define DIR_HANDLE_CMD(name,flags) \
   2726  { #name, test_dir_handle_get_##name, (flags), NULL, NULL }
   2727 
   2728 #ifdef COCCI
   2729 /* Coccinelle doesn't like the stringification in this macro */
   2730 #define DIR_HANDLE_CMD_ARG(name,flags,arg) \
   2731  DIR_HANDLE_CMD(name,flags)
   2732 #else
   2733 #define DIR_HANDLE_CMD_ARG(name,flags,arg) \
   2734  { #name "/" arg, test_dir_handle_get_##name, (flags), \
   2735    &passthrough_setup, (void *)(arg) }
   2736 #endif /* defined(COCCI) */
   2737 
   2738 struct testcase_t dir_handle_get_tests[] = {
   2739  DIR_HANDLE_CMD(not_found, 0),
   2740  DIR_HANDLE_CMD(bad_request, 0),
   2741  DIR_HANDLE_CMD(v1_command_not_found, 0),
   2742  DIR_HANDLE_CMD(v1_command, 0),
   2743  DIR_HANDLE_CMD(robots_txt, 0),
   2744  DIR_HANDLE_CMD(micro_d_not_found, 0),
   2745  DIR_HANDLE_CMD(micro_d_server_busy, 0),
   2746  DIR_HANDLE_CMD(micro_d, 0),
   2747  DIR_HANDLE_CMD(networkstatus_bridges_not_found_without_auth, 0),
   2748  DIR_HANDLE_CMD(networkstatus_bridges_not_found_wrong_auth, 0),
   2749  DIR_HANDLE_CMD(networkstatus_bridges, 0),
   2750  DIR_HANDLE_CMD(server_descriptors_not_found, 0),
   2751  DIR_HANDLE_CMD(server_descriptors_busy, TT_FORK),
   2752  DIR_HANDLE_CMD(server_descriptors_all, TT_FORK),
   2753  DIR_HANDLE_CMD(server_descriptors_authority, TT_FORK),
   2754  DIR_HANDLE_CMD(server_descriptors_fp, TT_FORK),
   2755  DIR_HANDLE_CMD(server_descriptors_d, TT_FORK),
   2756  DIR_HANDLE_CMD(server_keys_bad_req, 0),
   2757  DIR_HANDLE_CMD(server_keys_busy, 0),
   2758  DIR_HANDLE_CMD(server_keys_all_not_found, 0),
   2759  DIR_HANDLE_CMD(server_keys_all, 0),
   2760  DIR_HANDLE_CMD(server_keys_authority_not_found, 0),
   2761  DIR_HANDLE_CMD(server_keys_authority, 0),
   2762  DIR_HANDLE_CMD(server_keys_fp_not_found, 0),
   2763  DIR_HANDLE_CMD(server_keys_fp, 0),
   2764  DIR_HANDLE_CMD(server_keys_sk_not_found, 0),
   2765  DIR_HANDLE_CMD(server_keys_sk, 0),
   2766  DIR_HANDLE_CMD(server_keys_fpsk_not_found, 0),
   2767  DIR_HANDLE_CMD(server_keys_fpsk, 0),
   2768  DIR_HANDLE_CMD(status_vote_current_not_found, 0),
   2769  DIR_HANDLE_CMD(status_vote_next_not_found, 0),
   2770  DIR_HANDLE_CMD(status_vote_current_authority_not_found, 0),
   2771  DIR_HANDLE_CMD(status_vote_current_authority, 0),
   2772  DIR_HANDLE_CMD_ARG(status_vote_too_late, 0, "min"),
   2773  DIR_HANDLE_CMD_ARG(status_vote_too_late, 0, "chutney"),
   2774  DIR_HANDLE_CMD_ARG(status_vote_too_late, 0, "half-public"),
   2775  DIR_HANDLE_CMD_ARG(status_vote_too_late, 0, "public"),
   2776  DIR_HANDLE_CMD(status_vote_next_authority_not_found, 0),
   2777  DIR_HANDLE_CMD(status_vote_next_authority, 0),
   2778  DIR_HANDLE_CMD(status_vote_next_bandwidth_not_found, 0),
   2779  DIR_HANDLE_CMD(status_vote_next_bandwidth, 0),
   2780  DIR_HANDLE_CMD(status_vote_current_consensus_ns_not_enough_sigs, TT_FORK),
   2781  DIR_HANDLE_CMD(status_vote_current_consensus_ns_not_found, TT_FORK),
   2782  DIR_HANDLE_CMD(status_vote_current_consensus_too_old, TT_FORK),
   2783  DIR_HANDLE_CMD(status_vote_current_consensus_ns_busy, TT_FORK),
   2784  DIR_HANDLE_CMD(status_vote_current_consensus_ns, TT_FORK),
   2785  DIR_HANDLE_CMD(status_vote_current_d_not_found, 0),
   2786  DIR_HANDLE_CMD(status_vote_next_d_not_found, 0),
   2787  DIR_HANDLE_CMD(status_vote_d, 0),
   2788  DIR_HANDLE_CMD(status_vote_next_consensus_not_found, 0),
   2789  DIR_HANDLE_CMD(status_vote_next_consensus_busy, 0),
   2790  DIR_HANDLE_CMD(status_vote_next_consensus, 0),
   2791  DIR_HANDLE_CMD(status_vote_next_consensus_signatures_not_found, 0),
   2792  DIR_HANDLE_CMD(status_vote_next_consensus_signatures_busy, 0),
   2793  DIR_HANDLE_CMD(status_vote_next_consensus_signatures, 0),
   2794  DIR_HANDLE_CMD(parse_accept_encoding, 0),
   2795  END_OF_TESTCASES
   2796 };