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 };