test_controller.c (65685B)
1 /* Copyright (c) 2015-2021, The Tor Project, Inc. */ 2 /* See LICENSE for licensing information */ 3 4 #define CONTROL_CMD_PRIVATE 5 #define CONTROL_GETINFO_PRIVATE 6 #include "core/or/or.h" 7 #include "app/config/config.h" 8 #include "lib/crypt_ops/crypto_ed25519.h" 9 #include "feature/client/bridges.h" 10 #include "feature/control/control.h" 11 #include "feature/control/control_cmd.h" 12 #include "feature/control/control_getinfo.h" 13 #include "feature/control/control_proto.h" 14 #include "feature/client/entrynodes.h" 15 #include "feature/dircache/cached_dir_st.h" 16 #include "feature/dircache/dirserv.h" 17 #include "feature/hs/hs_common.h" 18 #include "feature/nodelist/networkstatus.h" 19 #include "feature/nodelist/authcert.h" 20 #include "feature/nodelist/nodelist.h" 21 #include "feature/stats/rephist.h" 22 #include "test/test.h" 23 #include "test/test_helpers.h" 24 #include "lib/net/resolve.h" 25 #include "lib/encoding/confline.h" 26 #include "lib/encoding/kvline.h" 27 28 #include "feature/control/control_connection_st.h" 29 #include "feature/control/control_cmd_args_st.h" 30 #include "feature/dirclient/download_status_st.h" 31 #include "feature/nodelist/microdesc_st.h" 32 #include "feature/nodelist/node_st.h" 33 34 typedef struct { 35 const char *input; 36 const char *expected_parse; 37 const char *expected_error; 38 } parser_testcase_t; 39 40 typedef struct { 41 const control_cmd_syntax_t *syntax; 42 size_t n_testcases; 43 const parser_testcase_t *testcases; 44 } parse_test_params_t; 45 46 static char * 47 control_cmd_dump_args(const control_cmd_args_t *result) 48 { 49 buf_t *buf = buf_new(); 50 buf_add_string(buf, "{ args=["); 51 if (result->args) { 52 if (smartlist_len(result->args)) { 53 buf_add_string(buf, " "); 54 } 55 SMARTLIST_FOREACH_BEGIN(result->args, const char *, s) { 56 const bool last = (s_sl_idx == smartlist_len(result->args)-1); 57 buf_add_printf(buf, "%s%s ", 58 escaped(s), 59 last ? "" : ","); 60 } SMARTLIST_FOREACH_END(s); 61 } 62 buf_add_string(buf, "]"); 63 if (result->cmddata) { 64 buf_add_string(buf, ", obj="); 65 buf_add_string(buf, escaped(result->cmddata)); 66 } 67 if (result->kwargs) { 68 buf_add_string(buf, ", { "); 69 const config_line_t *line; 70 for (line = result->kwargs; line; line = line->next) { 71 const bool last = (line->next == NULL); 72 buf_add_printf(buf, "%s=%s%s ", line->key, escaped(line->value), 73 last ? "" : ","); 74 } 75 buf_add_string(buf, "}"); 76 } 77 buf_add_string(buf, " }"); 78 79 char *encoded = buf_extract(buf, NULL); 80 buf_free(buf); 81 return encoded; 82 } 83 84 static void 85 test_controller_parse_cmd(void *arg) 86 { 87 const parse_test_params_t *params = arg; 88 control_cmd_args_t *result = NULL; 89 char *error = NULL; 90 char *encoded = NULL; 91 92 for (size_t i = 0; i < params->n_testcases; ++i) { 93 const parser_testcase_t *t = ¶ms->testcases[i]; 94 result = control_cmd_parse_args("EXAMPLE", 95 params->syntax, 96 strlen(t->input), 97 t->input, 98 &error); 99 // A valid test should expect exactly one parse or error. 100 tt_int_op((t->expected_parse == NULL), OP_NE, 101 (t->expected_error == NULL)); 102 // We get a result or an error, not both. 103 tt_int_op((result == NULL), OP_EQ, (error != NULL)); 104 // We got the one we expected. 105 tt_int_op((result == NULL), OP_EQ, (t->expected_parse == NULL)); 106 107 if (result) { 108 encoded = control_cmd_dump_args(result); 109 tt_str_op(encoded, OP_EQ, t->expected_parse); 110 } else { 111 tt_str_op(error, OP_EQ, t->expected_error); 112 } 113 114 tor_free(error); 115 tor_free(encoded); 116 control_cmd_args_free(result); 117 } 118 119 done: 120 tor_free(error); 121 tor_free(encoded); 122 control_cmd_args_free(result); 123 } 124 125 #ifndef COCCI 126 #define OK(inp, out) \ 127 { inp "\r\n", out, NULL } 128 #define ERR(inp, err) \ 129 { inp "\r\n", NULL, err } 130 131 #define TESTPARAMS(syntax, array) \ 132 { &syntax, \ 133 ARRAY_LENGTH(array), \ 134 array } 135 #endif /* !defined(COCCI) */ 136 137 static const parser_testcase_t one_to_three_tests[] = { 138 ERR("", "Need at least 1 argument(s)"), 139 ERR(" \t", "Need at least 1 argument(s)"), 140 OK("hello", "{ args=[ \"hello\" ] }"), 141 OK("hello world", "{ args=[ \"hello\", \"world\" ] }"), 142 OK("hello world", "{ args=[ \"hello\", \"world\" ] }"), 143 OK(" hello world", "{ args=[ \"hello\", \"world\" ] }"), 144 OK(" hello world ", "{ args=[ \"hello\", \"world\" ] }"), 145 OK("hello there world", "{ args=[ \"hello\", \"there\", \"world\" ] }"), 146 ERR("why hello there world", "Cannot accept more than 3 argument(s)"), 147 ERR("hello\r\nworld.\r\n.", "Unexpected body"), 148 }; 149 150 static const control_cmd_syntax_t one_to_three_syntax = { 151 .min_args=1, .max_args=3 152 }; 153 154 static const parse_test_params_t parse_one_to_three_params = 155 TESTPARAMS( one_to_three_syntax, one_to_three_tests ); 156 157 // = 158 static const parser_testcase_t no_args_one_obj_tests[] = { 159 ERR("Hi there!\r\n.", "Cannot accept more than 0 argument(s)"), 160 ERR("", "Empty body"), 161 OK("\r\n", "{ args=[], obj=\"\\n\" }"), 162 OK("\r\nHello world\r\n", "{ args=[], obj=\"Hello world\\n\\n\" }"), 163 OK("\r\nHello\r\nworld\r\n", "{ args=[], obj=\"Hello\\nworld\\n\\n\" }"), 164 OK("\r\nHello\r\n..\r\nworld\r\n", 165 "{ args=[], obj=\"Hello\\n.\\nworld\\n\\n\" }"), 166 }; 167 static const control_cmd_syntax_t no_args_one_obj_syntax = { 168 .min_args=0, .max_args=0, 169 .want_cmddata=true, 170 }; 171 static const parse_test_params_t parse_no_args_one_obj_params = 172 TESTPARAMS( no_args_one_obj_syntax, no_args_one_obj_tests ); 173 174 static const parser_testcase_t no_args_kwargs_tests[] = { 175 OK("", "{ args=[] }"), 176 OK(" ", "{ args=[] }"), 177 OK("hello there=world", "{ args=[], { hello=\"\", there=\"world\" } }"), 178 OK("hello there=world today", 179 "{ args=[], { hello=\"\", there=\"world\", today=\"\" } }"), 180 ERR("=Foo", "Cannot parse keyword argument(s)"), 181 }; 182 static const control_cmd_syntax_t no_args_kwargs_syntax = { 183 .min_args=0, .max_args=0, 184 .accept_keywords=true, 185 .kvline_flags=KV_OMIT_VALS 186 }; 187 static const parse_test_params_t parse_no_args_kwargs_params = 188 TESTPARAMS( no_args_kwargs_syntax, no_args_kwargs_tests ); 189 190 static const char *one_arg_kwargs_allow_keywords[] = { 191 "Hello", "world", NULL 192 }; 193 static const parser_testcase_t one_arg_kwargs_tests[] = { 194 ERR("", "Need at least 1 argument(s)"), 195 OK("Hi", "{ args=[ \"Hi\" ] }"), 196 ERR("hello there=world", "Unrecognized keyword argument \"there\""), 197 OK("Hi HELLO=foo", "{ args=[ \"Hi\" ], { HELLO=\"foo\" } }"), 198 OK("Hi world=\"bar baz\" hello ", 199 "{ args=[ \"Hi\" ], { world=\"bar baz\", hello=\"\" } }"), 200 }; 201 static const control_cmd_syntax_t one_arg_kwargs_syntax = { 202 .min_args=1, .max_args=1, 203 .accept_keywords=true, 204 .allowed_keywords=one_arg_kwargs_allow_keywords, 205 .kvline_flags=KV_OMIT_VALS|KV_QUOTED, 206 }; 207 static const parse_test_params_t parse_one_arg_kwargs_params = 208 TESTPARAMS( one_arg_kwargs_syntax, one_arg_kwargs_tests ); 209 210 static char *reply_str = NULL; 211 /* Mock for control_write_reply that copies the string for inspection 212 * by tests */ 213 static void 214 mock_control_write_reply(control_connection_t *conn, int code, int c, 215 const char *s) 216 { 217 (void)conn; 218 (void)code; 219 (void)c; 220 tor_free(reply_str); 221 reply_str = tor_strdup(s); 222 } 223 224 static void 225 test_add_onion_helper_keyarg_v3(void *arg) 226 { 227 int ret, hs_version; 228 add_onion_secret_key_t pk; 229 char *key_new_blob = NULL; 230 const char *key_new_alg = NULL; 231 232 (void) arg; 233 MOCK(control_write_reply, mock_control_write_reply); 234 235 memset(&pk, 0, sizeof(pk)); 236 237 /* Test explicit ED25519-V3 key generation. */ 238 tor_free(reply_str); 239 ret = add_onion_helper_keyarg("NEW:ED25519-V3", 0, &key_new_alg, 240 &key_new_blob, &pk, &hs_version, 241 NULL); 242 tt_int_op(ret, OP_EQ, 0); 243 tt_int_op(hs_version, OP_EQ, HS_VERSION_THREE); 244 tt_assert(pk.v3); 245 tt_str_op(key_new_alg, OP_EQ, "ED25519-V3"); 246 tt_assert(key_new_blob); 247 tt_ptr_op(reply_str, OP_EQ, NULL); 248 tor_free(pk.v3); pk.v3 = NULL; 249 tor_free(key_new_blob); 250 251 /* Test "BEST" key generation (Assumes BEST = ED25519-V3). */ 252 tor_free(pk.v3); pk.v3 = NULL; 253 tor_free(key_new_blob); 254 ret = add_onion_helper_keyarg("NEW:BEST", 0, &key_new_alg, &key_new_blob, 255 &pk, &hs_version, NULL); 256 tt_int_op(ret, OP_EQ, 0); 257 tt_int_op(hs_version, OP_EQ, HS_VERSION_THREE); 258 tt_assert(pk.v3); 259 tt_str_op(key_new_alg, OP_EQ, "ED25519-V3"); 260 tt_assert(key_new_blob); 261 tt_ptr_op(reply_str, OP_EQ, NULL); 262 263 /* Test discarding the private key. */ 264 tor_free(reply_str); 265 tor_free(pk.v3); pk.v3 = NULL; 266 tor_free(key_new_blob); 267 ret = add_onion_helper_keyarg("NEW:ED25519-V3", 1, &key_new_alg, 268 &key_new_blob, &pk, &hs_version, 269 NULL); 270 tt_int_op(ret, OP_EQ, 0); 271 tt_int_op(hs_version, OP_EQ, HS_VERSION_THREE); 272 tt_assert(pk.v3); 273 tt_ptr_op(key_new_alg, OP_EQ, NULL); 274 tt_ptr_op(key_new_blob, OP_EQ, NULL); 275 tt_ptr_op(reply_str, OP_EQ, NULL); 276 tor_free(pk.v3); pk.v3 = NULL; 277 tor_free(key_new_blob); 278 279 /* Test passing a key blob. */ 280 { 281 /* The base64 key and hex key are the same. Hex key is 64 bytes long. The 282 * sk has been generated randomly using python3. */ 283 const char *base64_sk = 284 "a9bT19PqGC9Y+BmOo1IQvCGjjwxMiaaxEXZ+FKMxpEQW" 285 "6AmSV5roThUGMRCaqQSCnR2jI1vL2QxHORzI4RxMmw=="; 286 const char *hex_sk = 287 "\x6b\xd6\xd3\xd7\xd3\xea\x18\x2f\x58\xf8\x19\x8e\xa3\x52\x10\xbc" 288 "\x21\xa3\x8f\x0c\x4c\x89\xa6\xb1\x11\x76\x7e\x14\xa3\x31\xa4\x44" 289 "\x16\xe8\x09\x92\x57\x9a\xe8\x4e\x15\x06\x31\x10\x9a\xa9\x04\x82" 290 "\x9d\x1d\xa3\x23\x5b\xcb\xd9\x0c\x47\x39\x1c\xc8\xe1\x1c\x4c\x9b"; 291 char *key_blob = NULL; 292 293 tor_asprintf(&key_blob, "ED25519-V3:%s", base64_sk); 294 tt_assert(key_blob); 295 tor_free(reply_str); 296 ret = add_onion_helper_keyarg(key_blob, 1, &key_new_alg, 297 &key_new_blob, &pk, &hs_version, 298 NULL); 299 tor_free(key_blob); 300 tt_int_op(ret, OP_EQ, 0); 301 tt_int_op(hs_version, OP_EQ, HS_VERSION_THREE); 302 tt_assert(pk.v3); 303 tt_mem_op(pk.v3, OP_EQ, hex_sk, 64); 304 tt_ptr_op(key_new_alg, OP_EQ, NULL); 305 tt_ptr_op(key_new_blob, OP_EQ, NULL); 306 tt_ptr_op(reply_str, OP_EQ, NULL); 307 tor_free(pk.v3); pk.v3 = NULL; 308 tor_free(key_new_blob); 309 } 310 311 done: 312 tor_free(pk.v3); 313 tor_free(key_new_blob); 314 tor_free(reply_str); 315 UNMOCK(control_write_reply); 316 } 317 318 static void 319 test_getinfo_helper_onion(void *arg) 320 { 321 (void)arg; 322 control_connection_t dummy; 323 /* Get results out */ 324 char *answer = NULL; 325 const char *errmsg = NULL; 326 char *service_id = NULL; 327 int rt = 0; 328 329 dummy.ephemeral_onion_services = NULL; 330 331 /* successfully get an empty answer */ 332 rt = getinfo_helper_onions(&dummy, "onions/current", &answer, &errmsg); 333 tt_int_op(rt, OP_EQ, 0); 334 tt_str_op(answer, OP_EQ, ""); 335 tor_free(answer); 336 337 /* successfully get an empty answer */ 338 rt = getinfo_helper_onions(&dummy, "onions/detached", &answer, &errmsg); 339 tt_int_op(rt, OP_EQ, 0); 340 tt_str_op(answer, OP_EQ, ""); 341 tor_free(answer); 342 343 /* get an answer for one onion service */ 344 service_id = tor_strdup("dummy_onion_id"); 345 dummy.ephemeral_onion_services = smartlist_new(); 346 smartlist_add(dummy.ephemeral_onion_services, service_id); 347 rt = getinfo_helper_onions(&dummy, "onions/current", &answer, &errmsg); 348 tt_int_op(rt, OP_EQ, 0); 349 tt_str_op(answer, OP_EQ, "dummy_onion_id"); 350 351 done: 352 tor_free(answer); 353 tor_free(service_id); 354 smartlist_free(dummy.ephemeral_onion_services); 355 } 356 357 static void 358 test_hs_parse_port_config(void *arg) 359 { 360 const char *sep = ","; 361 hs_port_config_t *cfg = NULL; 362 char *err_msg = NULL; 363 364 (void)arg; 365 366 /* Test "VIRTPORT" only. */ 367 cfg = hs_parse_port_config("80", sep, &err_msg); 368 tt_assert(cfg); 369 tt_ptr_op(err_msg, OP_EQ, NULL); 370 371 /* Test "VIRTPORT,TARGET" (Target is port). */ 372 hs_port_config_free(cfg); 373 cfg = hs_parse_port_config("80,8080", sep, &err_msg); 374 tt_assert(cfg); 375 tt_ptr_op(err_msg, OP_EQ, NULL); 376 377 /* Test "VIRTPORT,TARGET" (Target is IPv4:port). */ 378 hs_port_config_free(cfg); 379 cfg = hs_parse_port_config("80,192.0.2.1:8080", sep, &err_msg); 380 tt_assert(cfg); 381 tt_ptr_op(err_msg, OP_EQ, NULL); 382 383 /* Test "VIRTPORT,TARGET" (Target is IPv6:port). */ 384 hs_port_config_free(cfg); 385 cfg = hs_parse_port_config("80,[2001:db8::1]:8080", sep, &err_msg); 386 tt_assert(cfg); 387 tt_ptr_op(err_msg, OP_EQ, NULL); 388 hs_port_config_free(cfg); 389 cfg = NULL; 390 391 /* XXX: Someone should add tests for AF_UNIX targets if supported. */ 392 393 /* Test empty config. */ 394 hs_port_config_free(cfg); 395 cfg = hs_parse_port_config("", sep, &err_msg); 396 tt_ptr_op(cfg, OP_EQ, NULL); 397 tt_assert(err_msg); 398 399 /* Test invalid port. */ 400 tor_free(err_msg); 401 cfg = hs_parse_port_config("90001", sep, &err_msg); 402 tt_ptr_op(cfg, OP_EQ, NULL); 403 tt_assert(err_msg); 404 tor_free(err_msg); 405 406 /* unix port */ 407 cfg = NULL; 408 409 /* quoted unix port */ 410 tor_free(err_msg); 411 cfg = hs_parse_port_config("100 unix:\"/tmp/foo bar\"", 412 " ", &err_msg); 413 tt_assert(cfg); 414 tt_ptr_op(err_msg, OP_EQ, NULL); 415 hs_port_config_free(cfg); 416 cfg = NULL; 417 418 /* quoted unix port */ 419 tor_free(err_msg); 420 cfg = hs_parse_port_config("100 unix:\"/tmp/foo bar\"", 421 " ", &err_msg); 422 tt_assert(cfg); 423 tt_ptr_op(err_msg, OP_EQ, NULL); 424 hs_port_config_free(cfg); 425 cfg = NULL; 426 427 /* quoted unix port, missing end quote */ 428 cfg = hs_parse_port_config("100 unix:\"/tmp/foo bar", 429 " ", &err_msg); 430 tt_ptr_op(cfg, OP_EQ, NULL); 431 tt_str_op(err_msg, OP_EQ, "Couldn't process address <unix:\"/tmp/foo bar> " 432 "from hidden service configuration"); 433 tor_free(err_msg); 434 435 /* bogus IP address */ 436 MOCK(tor_addr_lookup, mock_tor_addr_lookup__fail_on_bad_addrs); 437 cfg = hs_parse_port_config("100 foo!!.example.com:9000", 438 " ", &err_msg); 439 UNMOCK(tor_addr_lookup); 440 tt_ptr_op(cfg, OP_EQ, NULL); 441 tt_str_op(err_msg, OP_EQ, "Unparseable address in hidden service port " 442 "configuration."); 443 tor_free(err_msg); 444 445 /* bogus port port */ 446 cfg = hs_parse_port_config("100 99999", 447 " ", &err_msg); 448 tt_ptr_op(cfg, OP_EQ, NULL); 449 tt_str_op(err_msg, OP_EQ, "Unparseable or out-of-range port \"99999\" " 450 "in hidden service port configuration."); 451 tor_free(err_msg); 452 453 /* Wrong target address and port separation */ 454 cfg = hs_parse_port_config("80,127.0.0.1 1234", sep, 455 &err_msg); 456 tt_ptr_op(cfg, OP_EQ, NULL); 457 tt_assert(err_msg); 458 tor_free(err_msg); 459 460 done: 461 hs_port_config_free(cfg); 462 tor_free(err_msg); 463 } 464 465 /* Mocks and data/variables used for GETINFO download status tests */ 466 467 static const download_status_t dl_status_default = 468 { 0, 0, 0, DL_SCHED_CONSENSUS, DL_WANT_ANY_DIRSERVER, 469 DL_SCHED_INCREMENT_FAILURE, 0, 0 }; 470 static download_status_t ns_dl_status[N_CONSENSUS_FLAVORS]; 471 static download_status_t ns_dl_status_bootstrap[N_CONSENSUS_FLAVORS]; 472 static download_status_t ns_dl_status_running[N_CONSENSUS_FLAVORS]; 473 474 /* 475 * These should explore all the possible cases of download_status_to_string() 476 * in control.c 477 */ 478 static const download_status_t dls_sample_1 = 479 { 1467163900, 0, 0, DL_SCHED_GENERIC, DL_WANT_ANY_DIRSERVER, 480 DL_SCHED_INCREMENT_FAILURE, 0, 0 }; 481 static const char * dls_sample_1_str = 482 "next-attempt-at 2016-06-29 01:31:40\n" 483 "n-download-failures 0\n" 484 "n-download-attempts 0\n" 485 "schedule DL_SCHED_GENERIC\n" 486 "want-authority DL_WANT_ANY_DIRSERVER\n" 487 "increment-on DL_SCHED_INCREMENT_FAILURE\n" 488 "backoff DL_SCHED_RANDOM_EXPONENTIAL\n" 489 "last-backoff-position 0\n" 490 "last-delay-used 0\n"; 491 static const download_status_t dls_sample_2 = 492 { 1467164400, 1, 2, DL_SCHED_CONSENSUS, DL_WANT_AUTHORITY, 493 DL_SCHED_INCREMENT_FAILURE, 0, 0 }; 494 static const char * dls_sample_2_str = 495 "next-attempt-at 2016-06-29 01:40:00\n" 496 "n-download-failures 1\n" 497 "n-download-attempts 2\n" 498 "schedule DL_SCHED_CONSENSUS\n" 499 "want-authority DL_WANT_AUTHORITY\n" 500 "increment-on DL_SCHED_INCREMENT_FAILURE\n" 501 "backoff DL_SCHED_RANDOM_EXPONENTIAL\n" 502 "last-backoff-position 0\n" 503 "last-delay-used 0\n"; 504 static const download_status_t dls_sample_3 = 505 { 1467154400, 12, 25, DL_SCHED_BRIDGE, DL_WANT_ANY_DIRSERVER, 506 DL_SCHED_INCREMENT_ATTEMPT, 0, 0 }; 507 static const char * dls_sample_3_str = 508 "next-attempt-at 2016-06-28 22:53:20\n" 509 "n-download-failures 12\n" 510 "n-download-attempts 25\n" 511 "schedule DL_SCHED_BRIDGE\n" 512 "want-authority DL_WANT_ANY_DIRSERVER\n" 513 "increment-on DL_SCHED_INCREMENT_ATTEMPT\n" 514 "backoff DL_SCHED_RANDOM_EXPONENTIAL\n" 515 "last-backoff-position 0\n" 516 "last-delay-used 0\n"; 517 static const download_status_t dls_sample_4 = 518 { 1467166600, 3, 0, DL_SCHED_GENERIC, DL_WANT_ANY_DIRSERVER, 519 DL_SCHED_INCREMENT_FAILURE, 0, 0 }; 520 static const char * dls_sample_4_str = 521 "next-attempt-at 2016-06-29 02:16:40\n" 522 "n-download-failures 3\n" 523 "n-download-attempts 0\n" 524 "schedule DL_SCHED_GENERIC\n" 525 "want-authority DL_WANT_ANY_DIRSERVER\n" 526 "increment-on DL_SCHED_INCREMENT_FAILURE\n" 527 "backoff DL_SCHED_RANDOM_EXPONENTIAL\n" 528 "last-backoff-position 0\n" 529 "last-delay-used 0\n"; 530 static const download_status_t dls_sample_5 = 531 { 1467164600, 3, 7, DL_SCHED_CONSENSUS, DL_WANT_ANY_DIRSERVER, 532 DL_SCHED_INCREMENT_FAILURE, 1, 2112, }; 533 static const char * dls_sample_5_str = 534 "next-attempt-at 2016-06-29 01:43:20\n" 535 "n-download-failures 3\n" 536 "n-download-attempts 7\n" 537 "schedule DL_SCHED_CONSENSUS\n" 538 "want-authority DL_WANT_ANY_DIRSERVER\n" 539 "increment-on DL_SCHED_INCREMENT_FAILURE\n" 540 "backoff DL_SCHED_RANDOM_EXPONENTIAL\n" 541 "last-backoff-position 1\n" 542 "last-delay-used 2112\n"; 543 static const download_status_t dls_sample_6 = 544 { 1467164200, 4, 9, DL_SCHED_CONSENSUS, DL_WANT_AUTHORITY, 545 DL_SCHED_INCREMENT_ATTEMPT, 3, 432 }; 546 static const char * dls_sample_6_str = 547 "next-attempt-at 2016-06-29 01:36:40\n" 548 "n-download-failures 4\n" 549 "n-download-attempts 9\n" 550 "schedule DL_SCHED_CONSENSUS\n" 551 "want-authority DL_WANT_AUTHORITY\n" 552 "increment-on DL_SCHED_INCREMENT_ATTEMPT\n" 553 "backoff DL_SCHED_RANDOM_EXPONENTIAL\n" 554 "last-backoff-position 3\n" 555 "last-delay-used 432\n"; 556 557 /* Simulated auth certs */ 558 static const char *auth_id_digest_1_str = 559 "63CDD326DFEF0CA020BDD3FEB45A3286FE13A061"; 560 static download_status_t auth_def_cert_download_status_1; 561 static const char *auth_id_digest_2_str = 562 "2C209FCDD8D48DC049777B8DC2C0F94A0408BE99"; 563 static download_status_t auth_def_cert_download_status_2; 564 /* Expected form of digest list returned for GETINFO downloads/cert/fps */ 565 static const char *auth_id_digest_expected_list = 566 "63CDD326DFEF0CA020BDD3FEB45A3286FE13A061\n" 567 "2C209FCDD8D48DC049777B8DC2C0F94A0408BE99\n"; 568 569 /* Signing keys for simulated auth 1 */ 570 static const char *auth_1_sk_1_str = 571 "AA69566029B1F023BA09451B8F1B10952384EB58"; 572 static download_status_t auth_1_sk_1_dls; 573 static const char *auth_1_sk_2_str = 574 "710865C7F06B73C5292695A8C34F1C94F769FF72"; 575 static download_status_t auth_1_sk_2_dls; 576 /* 577 * Expected form of sk digest list for 578 * GETINFO downloads/cert/<auth_id_digest_1_str>/sks 579 */ 580 static const char *auth_1_sk_digest_expected_list = 581 "AA69566029B1F023BA09451B8F1B10952384EB58\n" 582 "710865C7F06B73C5292695A8C34F1C94F769FF72\n"; 583 584 /* Signing keys for simulated auth 2 */ 585 static const char *auth_2_sk_1_str = 586 "4299047E00D070AD6703FE00BE7AA756DB061E62"; 587 static download_status_t auth_2_sk_1_dls; 588 static const char *auth_2_sk_2_str = 589 "9451B8F1B10952384EB58B5F230C0BB701626C9B"; 590 static download_status_t auth_2_sk_2_dls; 591 /* 592 * Expected form of sk digest list for 593 * GETINFO downloads/cert/<auth_id_digest_2_str>/sks 594 */ 595 static const char *auth_2_sk_digest_expected_list = 596 "4299047E00D070AD6703FE00BE7AA756DB061E62\n" 597 "9451B8F1B10952384EB58B5F230C0BB701626C9B\n"; 598 599 /* Simulated router descriptor digests or bridge identity digests */ 600 static const char *descbr_digest_1_str = 601 "616408544C7345822696074A1A3DFA16AB381CBD"; 602 static download_status_t descbr_digest_1_dl; 603 static const char *descbr_digest_2_str = 604 "06E8067246967265DBCB6641631B530EFEC12DC3"; 605 static download_status_t descbr_digest_2_dl; 606 /* Expected form of digest list returned for GETINFO downloads/desc/descs */ 607 static const char *descbr_expected_list = 608 "616408544C7345822696074A1A3DFA16AB381CBD\n" 609 "06E8067246967265DBCB6641631B530EFEC12DC3\n"; 610 /* 611 * Flag to make all descbr queries fail, to simulate not being 612 * configured such that such queries make sense. 613 */ 614 static int disable_descbr = 0; 615 616 static void 617 reset_mocked_dl_statuses(void) 618 { 619 int i; 620 621 for (i = 0; i < N_CONSENSUS_FLAVORS; ++i) { 622 memcpy(&(ns_dl_status[i]), &dl_status_default, 623 sizeof(download_status_t)); 624 memcpy(&(ns_dl_status_bootstrap[i]), &dl_status_default, 625 sizeof(download_status_t)); 626 memcpy(&(ns_dl_status_running[i]), &dl_status_default, 627 sizeof(download_status_t)); 628 } 629 630 memcpy(&auth_def_cert_download_status_1, &dl_status_default, 631 sizeof(download_status_t)); 632 memcpy(&auth_def_cert_download_status_2, &dl_status_default, 633 sizeof(download_status_t)); 634 memcpy(&auth_1_sk_1_dls, &dl_status_default, 635 sizeof(download_status_t)); 636 memcpy(&auth_1_sk_2_dls, &dl_status_default, 637 sizeof(download_status_t)); 638 memcpy(&auth_2_sk_1_dls, &dl_status_default, 639 sizeof(download_status_t)); 640 memcpy(&auth_2_sk_2_dls, &dl_status_default, 641 sizeof(download_status_t)); 642 643 memcpy(&descbr_digest_1_dl, &dl_status_default, 644 sizeof(download_status_t)); 645 memcpy(&descbr_digest_2_dl, &dl_status_default, 646 sizeof(download_status_t)); 647 } 648 649 static download_status_t * 650 ns_dl_status_mock(consensus_flavor_t flavor) 651 { 652 return &(ns_dl_status[flavor]); 653 } 654 655 static download_status_t * 656 ns_dl_status_bootstrap_mock(consensus_flavor_t flavor) 657 { 658 return &(ns_dl_status_bootstrap[flavor]); 659 } 660 661 static download_status_t * 662 ns_dl_status_running_mock(consensus_flavor_t flavor) 663 { 664 return &(ns_dl_status_running[flavor]); 665 } 666 667 static void 668 setup_ns_mocks(void) 669 { 670 MOCK(networkstatus_get_dl_status_by_flavor, ns_dl_status_mock); 671 MOCK(networkstatus_get_dl_status_by_flavor_bootstrap, 672 ns_dl_status_bootstrap_mock); 673 MOCK(networkstatus_get_dl_status_by_flavor_running, 674 ns_dl_status_running_mock); 675 reset_mocked_dl_statuses(); 676 } 677 678 static void 679 clear_ns_mocks(void) 680 { 681 UNMOCK(networkstatus_get_dl_status_by_flavor); 682 UNMOCK(networkstatus_get_dl_status_by_flavor_bootstrap); 683 UNMOCK(networkstatus_get_dl_status_by_flavor_running); 684 } 685 686 static smartlist_t * 687 cert_dl_status_auth_ids_mock(void) 688 { 689 char digest[DIGEST_LEN], *tmp; 690 int len; 691 smartlist_t *list = NULL; 692 693 /* Just pretend we have only the two hard-coded digests listed above */ 694 list = smartlist_new(); 695 len = base16_decode(digest, DIGEST_LEN, 696 auth_id_digest_1_str, strlen(auth_id_digest_1_str)); 697 tt_int_op(len, OP_EQ, DIGEST_LEN); 698 tmp = tor_malloc(DIGEST_LEN); 699 memcpy(tmp, digest, DIGEST_LEN); 700 smartlist_add(list, tmp); 701 len = base16_decode(digest, DIGEST_LEN, 702 auth_id_digest_2_str, strlen(auth_id_digest_2_str)); 703 tt_int_op(len, OP_EQ, DIGEST_LEN); 704 tmp = tor_malloc(DIGEST_LEN); 705 memcpy(tmp, digest, DIGEST_LEN); 706 smartlist_add(list, tmp); 707 708 done: 709 return list; 710 } 711 712 static download_status_t * 713 cert_dl_status_def_for_auth_mock(const char *digest) 714 { 715 download_status_t *dl = NULL; 716 char digest_str[HEX_DIGEST_LEN+1]; 717 718 tt_ptr_op(digest, OP_NE, NULL); 719 base16_encode(digest_str, HEX_DIGEST_LEN + 1, 720 digest, DIGEST_LEN); 721 digest_str[HEX_DIGEST_LEN] = '\0'; 722 723 if (strcmp(digest_str, auth_id_digest_1_str) == 0) { 724 dl = &auth_def_cert_download_status_1; 725 } else if (strcmp(digest_str, auth_id_digest_2_str) == 0) { 726 dl = &auth_def_cert_download_status_2; 727 } 728 729 done: 730 return dl; 731 } 732 733 static smartlist_t * 734 cert_dl_status_sks_for_auth_id_mock(const char *digest) 735 { 736 smartlist_t *list = NULL; 737 char sk[DIGEST_LEN]; 738 char digest_str[HEX_DIGEST_LEN+1]; 739 char *tmp; 740 int len; 741 742 tt_ptr_op(digest, OP_NE, NULL); 743 base16_encode(digest_str, HEX_DIGEST_LEN + 1, 744 digest, DIGEST_LEN); 745 digest_str[HEX_DIGEST_LEN] = '\0'; 746 747 /* 748 * Build a list of two hard-coded digests, depending on what we 749 * were just passed. 750 */ 751 if (strcmp(digest_str, auth_id_digest_1_str) == 0) { 752 list = smartlist_new(); 753 len = base16_decode(sk, DIGEST_LEN, 754 auth_1_sk_1_str, strlen(auth_1_sk_1_str)); 755 tt_int_op(len, OP_EQ, DIGEST_LEN); 756 tmp = tor_malloc(DIGEST_LEN); 757 memcpy(tmp, sk, DIGEST_LEN); 758 smartlist_add(list, tmp); 759 len = base16_decode(sk, DIGEST_LEN, 760 auth_1_sk_2_str, strlen(auth_1_sk_2_str)); 761 tt_int_op(len, OP_EQ, DIGEST_LEN); 762 tmp = tor_malloc(DIGEST_LEN); 763 memcpy(tmp, sk, DIGEST_LEN); 764 smartlist_add(list, tmp); 765 } else if (strcmp(digest_str, auth_id_digest_2_str) == 0) { 766 list = smartlist_new(); 767 len = base16_decode(sk, DIGEST_LEN, 768 auth_2_sk_1_str, strlen(auth_2_sk_1_str)); 769 tt_int_op(len, OP_EQ, DIGEST_LEN); 770 tmp = tor_malloc(DIGEST_LEN); 771 memcpy(tmp, sk, DIGEST_LEN); 772 smartlist_add(list, tmp); 773 len = base16_decode(sk, DIGEST_LEN, 774 auth_2_sk_2_str, strlen(auth_2_sk_2_str)); 775 tt_int_op(len, OP_EQ, DIGEST_LEN); 776 tmp = tor_malloc(DIGEST_LEN); 777 memcpy(tmp, sk, DIGEST_LEN); 778 smartlist_add(list, tmp); 779 } 780 781 done: 782 return list; 783 } 784 785 static download_status_t * 786 cert_dl_status_fp_sk_mock(const char *fp_digest, const char *sk_digest) 787 { 788 download_status_t *dl = NULL; 789 char fp_digest_str[HEX_DIGEST_LEN+1], sk_digest_str[HEX_DIGEST_LEN+1]; 790 791 /* 792 * Unpack the digests so we can compare them and figure out which 793 * dl status we want. 794 */ 795 796 tt_ptr_op(fp_digest, OP_NE, NULL); 797 base16_encode(fp_digest_str, HEX_DIGEST_LEN + 1, 798 fp_digest, DIGEST_LEN); 799 fp_digest_str[HEX_DIGEST_LEN] = '\0'; 800 tt_ptr_op(sk_digest, OP_NE, NULL); 801 base16_encode(sk_digest_str, HEX_DIGEST_LEN + 1, 802 sk_digest, DIGEST_LEN); 803 sk_digest_str[HEX_DIGEST_LEN] = '\0'; 804 805 if (strcmp(fp_digest_str, auth_id_digest_1_str) == 0) { 806 if (strcmp(sk_digest_str, auth_1_sk_1_str) == 0) { 807 dl = &auth_1_sk_1_dls; 808 } else if (strcmp(sk_digest_str, auth_1_sk_2_str) == 0) { 809 dl = &auth_1_sk_2_dls; 810 } 811 } else if (strcmp(fp_digest_str, auth_id_digest_2_str) == 0) { 812 if (strcmp(sk_digest_str, auth_2_sk_1_str) == 0) { 813 dl = &auth_2_sk_1_dls; 814 } else if (strcmp(sk_digest_str, auth_2_sk_2_str) == 0) { 815 dl = &auth_2_sk_2_dls; 816 } 817 } 818 819 done: 820 return dl; 821 } 822 823 static void 824 setup_cert_mocks(void) 825 { 826 MOCK(list_authority_ids_with_downloads, cert_dl_status_auth_ids_mock); 827 MOCK(id_only_download_status_for_authority_id, 828 cert_dl_status_def_for_auth_mock); 829 MOCK(list_sk_digests_for_authority_id, 830 cert_dl_status_sks_for_auth_id_mock); 831 MOCK(download_status_for_authority_id_and_sk, 832 cert_dl_status_fp_sk_mock); 833 reset_mocked_dl_statuses(); 834 } 835 836 static void 837 clear_cert_mocks(void) 838 { 839 UNMOCK(list_authority_ids_with_downloads); 840 UNMOCK(id_only_download_status_for_authority_id); 841 UNMOCK(list_sk_digests_for_authority_id); 842 UNMOCK(download_status_for_authority_id_and_sk); 843 } 844 845 static smartlist_t * 846 descbr_get_digests_mock(void) 847 { 848 char digest[DIGEST_LEN], *tmp; 849 int len; 850 smartlist_t *list = NULL; 851 852 if (!disable_descbr) { 853 /* Just pretend we have only the two hard-coded digests listed above */ 854 list = smartlist_new(); 855 len = base16_decode(digest, DIGEST_LEN, 856 descbr_digest_1_str, strlen(descbr_digest_1_str)); 857 tt_int_op(len, OP_EQ, DIGEST_LEN); 858 tmp = tor_malloc(DIGEST_LEN); 859 memcpy(tmp, digest, DIGEST_LEN); 860 smartlist_add(list, tmp); 861 len = base16_decode(digest, DIGEST_LEN, 862 descbr_digest_2_str, strlen(descbr_digest_2_str)); 863 tt_int_op(len, OP_EQ, DIGEST_LEN); 864 tmp = tor_malloc(DIGEST_LEN); 865 memcpy(tmp, digest, DIGEST_LEN); 866 smartlist_add(list, tmp); 867 } 868 869 done: 870 return list; 871 } 872 873 static download_status_t * 874 descbr_get_dl_by_digest_mock(const char *digest) 875 { 876 download_status_t *dl = NULL; 877 char digest_str[HEX_DIGEST_LEN+1]; 878 879 if (!disable_descbr) { 880 tt_ptr_op(digest, OP_NE, NULL); 881 base16_encode(digest_str, HEX_DIGEST_LEN + 1, 882 digest, DIGEST_LEN); 883 digest_str[HEX_DIGEST_LEN] = '\0'; 884 885 if (strcmp(digest_str, descbr_digest_1_str) == 0) { 886 dl = &descbr_digest_1_dl; 887 } else if (strcmp(digest_str, descbr_digest_2_str) == 0) { 888 dl = &descbr_digest_2_dl; 889 } 890 } 891 892 done: 893 return dl; 894 } 895 896 static void 897 setup_desc_mocks(void) 898 { 899 MOCK(router_get_descriptor_digests, 900 descbr_get_digests_mock); 901 MOCK(router_get_dl_status_by_descriptor_digest, 902 descbr_get_dl_by_digest_mock); 903 reset_mocked_dl_statuses(); 904 } 905 906 static void 907 clear_desc_mocks(void) 908 { 909 UNMOCK(router_get_descriptor_digests); 910 UNMOCK(router_get_dl_status_by_descriptor_digest); 911 } 912 913 static void 914 setup_bridge_mocks(void) 915 { 916 disable_descbr = 0; 917 918 MOCK(list_bridge_identities, 919 descbr_get_digests_mock); 920 MOCK(get_bridge_dl_status_by_id, 921 descbr_get_dl_by_digest_mock); 922 reset_mocked_dl_statuses(); 923 } 924 925 static void 926 clear_bridge_mocks(void) 927 { 928 UNMOCK(list_bridge_identities); 929 UNMOCK(get_bridge_dl_status_by_id); 930 931 disable_descbr = 0; 932 } 933 934 static void 935 test_download_status_consensus(void *arg) 936 { 937 /* We just need one of these to pass, it doesn't matter what's in it */ 938 control_connection_t dummy; 939 /* Get results out */ 940 char *answer = NULL; 941 const char *errmsg = NULL; 942 943 (void)arg; 944 945 /* Check that the unknown prefix case works; no mocks needed yet */ 946 getinfo_helper_downloads(&dummy, "downloads/foo", &answer, &errmsg); 947 tt_ptr_op(answer, OP_EQ, NULL); 948 tt_str_op(errmsg, OP_EQ, "Unknown download status query"); 949 950 setup_ns_mocks(); 951 952 /* 953 * Check returning serialized dlstatuses, and implicitly also test 954 * download_status_to_string(). 955 */ 956 957 /* Case 1 default/FLAV_NS*/ 958 memcpy(&(ns_dl_status[FLAV_NS]), &dls_sample_1, 959 sizeof(download_status_t)); 960 getinfo_helper_downloads(&dummy, "downloads/networkstatus/ns", 961 &answer, &errmsg); 962 tt_ptr_op(answer, OP_NE, NULL); 963 tt_ptr_op(errmsg, OP_EQ, NULL); 964 tt_str_op(answer, OP_EQ, dls_sample_1_str); 965 tor_free(answer); 966 errmsg = NULL; 967 968 /* Case 2 default/FLAV_MICRODESC */ 969 memcpy(&(ns_dl_status[FLAV_MICRODESC]), &dls_sample_2, 970 sizeof(download_status_t)); 971 getinfo_helper_downloads(&dummy, "downloads/networkstatus/microdesc", 972 &answer, &errmsg); 973 tt_ptr_op(answer, OP_NE, NULL); 974 tt_ptr_op(errmsg, OP_EQ, NULL); 975 tt_str_op(answer, OP_EQ, dls_sample_2_str); 976 tor_free(answer); 977 errmsg = NULL; 978 979 /* Case 3 bootstrap/FLAV_NS */ 980 memcpy(&(ns_dl_status_bootstrap[FLAV_NS]), &dls_sample_3, 981 sizeof(download_status_t)); 982 getinfo_helper_downloads(&dummy, "downloads/networkstatus/ns/bootstrap", 983 &answer, &errmsg); 984 tt_ptr_op(answer, OP_NE, NULL); 985 tt_ptr_op(errmsg, OP_EQ, NULL); 986 tt_str_op(answer, OP_EQ, dls_sample_3_str); 987 tor_free(answer); 988 errmsg = NULL; 989 990 /* Case 4 bootstrap/FLAV_MICRODESC */ 991 memcpy(&(ns_dl_status_bootstrap[FLAV_MICRODESC]), &dls_sample_4, 992 sizeof(download_status_t)); 993 getinfo_helper_downloads(&dummy, 994 "downloads/networkstatus/microdesc/bootstrap", 995 &answer, &errmsg); 996 tt_ptr_op(answer, OP_NE, NULL); 997 tt_ptr_op(errmsg, OP_EQ, NULL); 998 tt_str_op(answer, OP_EQ, dls_sample_4_str); 999 tor_free(answer); 1000 errmsg = NULL; 1001 1002 /* Case 5 running/FLAV_NS */ 1003 memcpy(&(ns_dl_status_running[FLAV_NS]), &dls_sample_5, 1004 sizeof(download_status_t)); 1005 getinfo_helper_downloads(&dummy, 1006 "downloads/networkstatus/ns/running", 1007 &answer, &errmsg); 1008 tt_ptr_op(answer, OP_NE, NULL); 1009 tt_ptr_op(errmsg, OP_EQ, NULL); 1010 tt_str_op(answer, OP_EQ, dls_sample_5_str); 1011 tor_free(answer); 1012 errmsg = NULL; 1013 1014 /* Case 6 running/FLAV_MICRODESC */ 1015 memcpy(&(ns_dl_status_running[FLAV_MICRODESC]), &dls_sample_6, 1016 sizeof(download_status_t)); 1017 getinfo_helper_downloads(&dummy, 1018 "downloads/networkstatus/microdesc/running", 1019 &answer, &errmsg); 1020 tt_ptr_op(answer, OP_NE, NULL); 1021 tt_ptr_op(errmsg, OP_EQ, NULL); 1022 tt_str_op(answer, OP_EQ, dls_sample_6_str); 1023 tor_free(answer); 1024 errmsg = NULL; 1025 1026 /* Now check the error case */ 1027 getinfo_helper_downloads(&dummy, "downloads/networkstatus/foo", 1028 &answer, &errmsg); 1029 tt_ptr_op(answer, OP_EQ, NULL); 1030 tt_ptr_op(errmsg, OP_NE, NULL); 1031 tt_str_op(errmsg, OP_EQ, "Unknown flavor"); 1032 errmsg = NULL; 1033 1034 done: 1035 clear_ns_mocks(); 1036 tor_free(answer); 1037 1038 return; 1039 } 1040 1041 static void 1042 test_download_status_cert(void *arg) 1043 { 1044 /* We just need one of these to pass, it doesn't matter what's in it */ 1045 control_connection_t dummy; 1046 /* Get results out */ 1047 char *question = NULL; 1048 char *answer = NULL; 1049 const char *errmsg = NULL; 1050 1051 (void)arg; 1052 1053 setup_cert_mocks(); 1054 1055 /* 1056 * Check returning serialized dlstatuses and digest lists, and implicitly 1057 * also test download_status_to_string() and digest_list_to_string(). 1058 */ 1059 1060 /* Case 1 - list of authority identity fingerprints */ 1061 getinfo_helper_downloads(&dummy, 1062 "downloads/cert/fps", 1063 &answer, &errmsg); 1064 tt_ptr_op(answer, OP_NE, NULL); 1065 tt_ptr_op(errmsg, OP_EQ, NULL); 1066 tt_str_op(answer, OP_EQ, auth_id_digest_expected_list); 1067 tor_free(answer); 1068 errmsg = NULL; 1069 1070 /* Case 2 - download status for default cert for 1st auth id */ 1071 memcpy(&auth_def_cert_download_status_1, &dls_sample_1, 1072 sizeof(download_status_t)); 1073 tor_asprintf(&question, "downloads/cert/fp/%s", auth_id_digest_1_str); 1074 tt_ptr_op(question, OP_NE, NULL); 1075 getinfo_helper_downloads(&dummy, question, &answer, &errmsg); 1076 tt_ptr_op(answer, OP_NE, NULL); 1077 tt_ptr_op(errmsg, OP_EQ, NULL); 1078 tt_str_op(answer, OP_EQ, dls_sample_1_str); 1079 tor_free(question); 1080 tor_free(answer); 1081 errmsg = NULL; 1082 1083 /* Case 3 - download status for default cert for 2nd auth id */ 1084 memcpy(&auth_def_cert_download_status_2, &dls_sample_2, 1085 sizeof(download_status_t)); 1086 tor_asprintf(&question, "downloads/cert/fp/%s", auth_id_digest_2_str); 1087 tt_ptr_op(question, OP_NE, NULL); 1088 getinfo_helper_downloads(&dummy, question, &answer, &errmsg); 1089 tt_ptr_op(answer, OP_NE, NULL); 1090 tt_ptr_op(errmsg, OP_EQ, NULL); 1091 tt_str_op(answer, OP_EQ, dls_sample_2_str); 1092 tor_free(question); 1093 tor_free(answer); 1094 errmsg = NULL; 1095 1096 /* Case 4 - list of signing key digests for 1st auth id */ 1097 tor_asprintf(&question, "downloads/cert/fp/%s/sks", auth_id_digest_1_str); 1098 tt_ptr_op(question, OP_NE, NULL); 1099 getinfo_helper_downloads(&dummy, question, &answer, &errmsg); 1100 tt_ptr_op(answer, OP_NE, NULL); 1101 tt_ptr_op(errmsg, OP_EQ, NULL); 1102 tt_str_op(answer, OP_EQ, auth_1_sk_digest_expected_list); 1103 tor_free(question); 1104 tor_free(answer); 1105 errmsg = NULL; 1106 1107 /* Case 5 - list of signing key digests for 2nd auth id */ 1108 tor_asprintf(&question, "downloads/cert/fp/%s/sks", auth_id_digest_2_str); 1109 tt_ptr_op(question, OP_NE, NULL); 1110 getinfo_helper_downloads(&dummy, question, &answer, &errmsg); 1111 tt_ptr_op(answer, OP_NE, NULL); 1112 tt_ptr_op(errmsg, OP_EQ, NULL); 1113 tt_str_op(answer, OP_EQ, auth_2_sk_digest_expected_list); 1114 tor_free(question); 1115 tor_free(answer); 1116 errmsg = NULL; 1117 1118 /* Case 6 - download status for 1st auth id, 1st sk */ 1119 memcpy(&auth_1_sk_1_dls, &dls_sample_3, 1120 sizeof(download_status_t)); 1121 tor_asprintf(&question, "downloads/cert/fp/%s/%s", 1122 auth_id_digest_1_str, auth_1_sk_1_str); 1123 tt_ptr_op(question, OP_NE, NULL); 1124 getinfo_helper_downloads(&dummy, question, &answer, &errmsg); 1125 tt_ptr_op(answer, OP_NE, NULL); 1126 tt_ptr_op(errmsg, OP_EQ, NULL); 1127 tt_str_op(answer, OP_EQ, dls_sample_3_str); 1128 tor_free(question); 1129 tor_free(answer); 1130 errmsg = NULL; 1131 1132 /* Case 7 - download status for 1st auth id, 2nd sk */ 1133 memcpy(&auth_1_sk_2_dls, &dls_sample_4, 1134 sizeof(download_status_t)); 1135 tor_asprintf(&question, "downloads/cert/fp/%s/%s", 1136 auth_id_digest_1_str, auth_1_sk_2_str); 1137 tt_ptr_op(question, OP_NE, NULL); 1138 getinfo_helper_downloads(&dummy, question, &answer, &errmsg); 1139 tt_ptr_op(answer, OP_NE, NULL); 1140 tt_ptr_op(errmsg, OP_EQ, NULL); 1141 tt_str_op(answer, OP_EQ, dls_sample_4_str); 1142 tor_free(question); 1143 tor_free(answer); 1144 errmsg = NULL; 1145 1146 /* Case 8 - download status for 2nd auth id, 1st sk */ 1147 memcpy(&auth_2_sk_1_dls, &dls_sample_5, 1148 sizeof(download_status_t)); 1149 tor_asprintf(&question, "downloads/cert/fp/%s/%s", 1150 auth_id_digest_2_str, auth_2_sk_1_str); 1151 tt_ptr_op(question, OP_NE, NULL); 1152 getinfo_helper_downloads(&dummy, question, &answer, &errmsg); 1153 tt_ptr_op(answer, OP_NE, NULL); 1154 tt_ptr_op(errmsg, OP_EQ, NULL); 1155 tt_str_op(answer, OP_EQ, dls_sample_5_str); 1156 tor_free(question); 1157 tor_free(answer); 1158 errmsg = NULL; 1159 1160 /* Case 9 - download status for 2nd auth id, 2nd sk */ 1161 memcpy(&auth_2_sk_2_dls, &dls_sample_6, 1162 sizeof(download_status_t)); 1163 tor_asprintf(&question, "downloads/cert/fp/%s/%s", 1164 auth_id_digest_2_str, auth_2_sk_2_str); 1165 tt_ptr_op(question, OP_NE, NULL); 1166 getinfo_helper_downloads(&dummy, question, &answer, &errmsg); 1167 tt_ptr_op(answer, OP_NE, NULL); 1168 tt_ptr_op(errmsg, OP_EQ, NULL); 1169 tt_str_op(answer, OP_EQ, dls_sample_6_str); 1170 tor_free(question); 1171 tor_free(answer); 1172 errmsg = NULL; 1173 1174 /* Now check the error cases */ 1175 1176 /* Case 1 - query is garbage after downloads/cert/ part */ 1177 getinfo_helper_downloads(&dummy, "downloads/cert/blahdeblah", 1178 &answer, &errmsg); 1179 tt_ptr_op(answer, OP_EQ, NULL); 1180 tt_ptr_op(errmsg, OP_NE, NULL); 1181 tt_str_op(errmsg, OP_EQ, "Unknown certificate download status query"); 1182 errmsg = NULL; 1183 1184 /* 1185 * Case 2 - looks like downloads/cert/fp/<fp>, but <fp> isn't even 1186 * the right length for a digest. 1187 */ 1188 getinfo_helper_downloads(&dummy, "downloads/cert/fp/2B1D36D32B2942406", 1189 &answer, &errmsg); 1190 tt_ptr_op(answer, OP_EQ, NULL); 1191 tt_ptr_op(errmsg, OP_NE, NULL); 1192 tt_str_op(errmsg, OP_EQ, "That didn't look like a digest"); 1193 errmsg = NULL; 1194 1195 /* 1196 * Case 3 - looks like downloads/cert/fp/<fp>, and <fp> is digest-sized, 1197 * but not parseable as one. 1198 */ 1199 getinfo_helper_downloads(&dummy, 1200 "downloads/cert/fp/82F52AF55D250115FE44D3GC81D49643241D56A1", 1201 &answer, &errmsg); 1202 tt_ptr_op(answer, OP_EQ, NULL); 1203 tt_ptr_op(errmsg, OP_NE, NULL); 1204 tt_str_op(errmsg, OP_EQ, "That didn't look like a digest"); 1205 errmsg = NULL; 1206 1207 /* 1208 * Case 4 - downloads/cert/fp/<fp>, and <fp> is not a known authority 1209 * identity digest 1210 */ 1211 getinfo_helper_downloads(&dummy, 1212 "downloads/cert/fp/AC4F23B5745BDD2A77997B85B1FD85D05C2E0F61", 1213 &answer, &errmsg); 1214 tt_ptr_op(answer, OP_EQ, NULL); 1215 tt_ptr_op(errmsg, OP_NE, NULL); 1216 tt_str_op(errmsg, OP_EQ, 1217 "Failed to get download status for this authority identity digest"); 1218 errmsg = NULL; 1219 1220 /* 1221 * Case 5 - looks like downloads/cert/fp/<fp>/<anything>, but <fp> doesn't 1222 * parse as a sensible digest. 1223 */ 1224 getinfo_helper_downloads(&dummy, 1225 "downloads/cert/fp/82F52AF55D250115FE44D3GC81D49643241D56A1/blah", 1226 &answer, &errmsg); 1227 tt_ptr_op(answer, OP_EQ, NULL); 1228 tt_ptr_op(errmsg, OP_NE, NULL); 1229 tt_str_op(errmsg, OP_EQ, "That didn't look like an identity digest"); 1230 errmsg = NULL; 1231 1232 /* 1233 * Case 6 - looks like downloads/cert/fp/<fp>/<anything>, but <fp> doesn't 1234 * parse as a sensible digest. 1235 */ 1236 getinfo_helper_downloads(&dummy, 1237 "downloads/cert/fp/82F52AF55D25/blah", 1238 &answer, &errmsg); 1239 tt_ptr_op(answer, OP_EQ, NULL); 1240 tt_ptr_op(errmsg, OP_NE, NULL); 1241 tt_str_op(errmsg, OP_EQ, "That didn't look like an identity digest"); 1242 errmsg = NULL; 1243 1244 /* 1245 * Case 7 - downloads/cert/fp/<fp>/sks, and <fp> is not a known authority 1246 * digest. 1247 */ 1248 getinfo_helper_downloads(&dummy, 1249 "downloads/cert/fp/AC4F23B5745BDD2A77997B85B1FD85D05C2E0F61/sks", 1250 &answer, &errmsg); 1251 tt_ptr_op(answer, OP_EQ, NULL); 1252 tt_ptr_op(errmsg, OP_NE, NULL); 1253 tt_str_op(errmsg, OP_EQ, 1254 "Failed to get list of signing key digests for this authority " 1255 "identity digest"); 1256 errmsg = NULL; 1257 1258 /* 1259 * Case 8 - looks like downloads/cert/fp/<fp>/<sk>, but <sk> doesn't 1260 * parse as a signing key digest. 1261 */ 1262 getinfo_helper_downloads(&dummy, 1263 "downloads/cert/fp/AC4F23B5745BDD2A77997B85B1FD85D05C2E0F61/" 1264 "82F52AF55D250115FE44D3GC81D49643241D56A1", 1265 &answer, &errmsg); 1266 tt_ptr_op(answer, OP_EQ, NULL); 1267 tt_ptr_op(errmsg, OP_NE, NULL); 1268 tt_str_op(errmsg, OP_EQ, "That didn't look like a signing key digest"); 1269 errmsg = NULL; 1270 1271 /* 1272 * Case 9 - looks like downloads/cert/fp/<fp>/<sk>, but <sk> doesn't 1273 * parse as a signing key digest. 1274 */ 1275 getinfo_helper_downloads(&dummy, 1276 "downloads/cert/fp/AC4F23B5745BDD2A77997B85B1FD85D05C2E0F61/" 1277 "82F52AF55D250115FE44D", 1278 &answer, &errmsg); 1279 tt_ptr_op(answer, OP_EQ, NULL); 1280 tt_ptr_op(errmsg, OP_NE, NULL); 1281 tt_str_op(errmsg, OP_EQ, "That didn't look like a signing key digest"); 1282 errmsg = NULL; 1283 1284 /* 1285 * Case 10 - downloads/cert/fp/<fp>/<sk>, but <fp> isn't a known 1286 * authority identity digest. 1287 */ 1288 getinfo_helper_downloads(&dummy, 1289 "downloads/cert/fp/C6B05DF332F74DB9A13498EE3BBC7AA2F69FCB45/" 1290 "3A214FC21AE25B012C2ECCB5F4EC8A3602D0545D", 1291 &answer, &errmsg); 1292 tt_ptr_op(answer, OP_EQ, NULL); 1293 tt_ptr_op(errmsg, OP_NE, NULL); 1294 tt_str_op(errmsg, OP_EQ, 1295 "Failed to get download status for this identity/" 1296 "signing key digest pair"); 1297 errmsg = NULL; 1298 1299 /* 1300 * Case 11 - downloads/cert/fp/<fp>/<sk>, but <sk> isn't a known 1301 * signing key digest. 1302 */ 1303 getinfo_helper_downloads(&dummy, 1304 "downloads/cert/fp/63CDD326DFEF0CA020BDD3FEB45A3286FE13A061/" 1305 "3A214FC21AE25B012C2ECCB5F4EC8A3602D0545D", 1306 &answer, &errmsg); 1307 tt_ptr_op(answer, OP_EQ, NULL); 1308 tt_ptr_op(errmsg, OP_NE, NULL); 1309 tt_str_op(errmsg, OP_EQ, 1310 "Failed to get download status for this identity/" 1311 "signing key digest pair"); 1312 errmsg = NULL; 1313 1314 /* 1315 * Case 12 - downloads/cert/fp/<fp>/<sk>, but <sk> is on the list for 1316 * a different authority identity digest. 1317 */ 1318 getinfo_helper_downloads(&dummy, 1319 "downloads/cert/fp/63CDD326DFEF0CA020BDD3FEB45A3286FE13A061/" 1320 "9451B8F1B10952384EB58B5F230C0BB701626C9B", 1321 &answer, &errmsg); 1322 tt_ptr_op(answer, OP_EQ, NULL); 1323 tt_ptr_op(errmsg, OP_NE, NULL); 1324 tt_str_op(errmsg, OP_EQ, 1325 "Failed to get download status for this identity/" 1326 "signing key digest pair"); 1327 errmsg = NULL; 1328 1329 done: 1330 clear_cert_mocks(); 1331 tor_free(answer); 1332 1333 return; 1334 } 1335 1336 static void 1337 test_download_status_desc(void *arg) 1338 { 1339 /* We just need one of these to pass, it doesn't matter what's in it */ 1340 control_connection_t dummy; 1341 /* Get results out */ 1342 char *question = NULL; 1343 char *answer = NULL; 1344 const char *errmsg = NULL; 1345 1346 (void)arg; 1347 1348 setup_desc_mocks(); 1349 1350 /* 1351 * Check returning serialized dlstatuses and digest lists, and implicitly 1352 * also test download_status_to_string() and digest_list_to_string(). 1353 */ 1354 1355 /* Case 1 - list of router descriptor digests */ 1356 getinfo_helper_downloads(&dummy, 1357 "downloads/desc/descs", 1358 &answer, &errmsg); 1359 tt_ptr_op(answer, OP_NE, NULL); 1360 tt_ptr_op(errmsg, OP_EQ, NULL); 1361 tt_str_op(answer, OP_EQ, descbr_expected_list); 1362 tor_free(answer); 1363 errmsg = NULL; 1364 1365 /* Case 2 - get download status for router descriptor 1 */ 1366 memcpy(&descbr_digest_1_dl, &dls_sample_1, 1367 sizeof(download_status_t)); 1368 tor_asprintf(&question, "downloads/desc/%s", descbr_digest_1_str); 1369 tt_ptr_op(question, OP_NE, NULL); 1370 getinfo_helper_downloads(&dummy, question, &answer, &errmsg); 1371 tt_ptr_op(answer, OP_NE, NULL); 1372 tt_ptr_op(errmsg, OP_EQ, NULL); 1373 tt_str_op(answer, OP_EQ, dls_sample_1_str); 1374 tor_free(question); 1375 tor_free(answer); 1376 errmsg = NULL; 1377 1378 /* Case 3 - get download status for router descriptor 1 */ 1379 memcpy(&descbr_digest_2_dl, &dls_sample_2, 1380 sizeof(download_status_t)); 1381 tor_asprintf(&question, "downloads/desc/%s", descbr_digest_2_str); 1382 tt_ptr_op(question, OP_NE, NULL); 1383 getinfo_helper_downloads(&dummy, question, &answer, &errmsg); 1384 tt_ptr_op(answer, OP_NE, NULL); 1385 tt_ptr_op(errmsg, OP_EQ, NULL); 1386 tt_str_op(answer, OP_EQ, dls_sample_2_str); 1387 tor_free(question); 1388 tor_free(answer); 1389 errmsg = NULL; 1390 1391 /* Now check the error cases */ 1392 1393 /* Case 1 - non-digest-length garbage after downloads/desc */ 1394 getinfo_helper_downloads(&dummy, "downloads/desc/blahdeblah", 1395 &answer, &errmsg); 1396 tt_ptr_op(answer, OP_EQ, NULL); 1397 tt_ptr_op(errmsg, OP_NE, NULL); 1398 tt_str_op(errmsg, OP_EQ, "Unknown router descriptor download status query"); 1399 errmsg = NULL; 1400 1401 /* Case 2 - nonparseable digest-shaped thing */ 1402 getinfo_helper_downloads( 1403 &dummy, 1404 "downloads/desc/774EC52FD9A5B80A6FACZE536616E8022E3470AG", 1405 &answer, &errmsg); 1406 tt_ptr_op(answer, OP_EQ, NULL); 1407 tt_ptr_op(errmsg, OP_NE, NULL); 1408 tt_str_op(errmsg, OP_EQ, "That didn't look like a digest"); 1409 errmsg = NULL; 1410 1411 /* Case 3 - digest we have no descriptor for */ 1412 getinfo_helper_downloads( 1413 &dummy, 1414 "downloads/desc/B05B46135B0B2C04EBE1DD6A6AE4B12D7CD2226A", 1415 &answer, &errmsg); 1416 tt_ptr_op(answer, OP_EQ, NULL); 1417 tt_ptr_op(errmsg, OP_NE, NULL); 1418 tt_str_op(errmsg, OP_EQ, "No such descriptor digest found"); 1419 errmsg = NULL; 1420 1421 /* Case 4 - microdescs only */ 1422 disable_descbr = 1; 1423 getinfo_helper_downloads(&dummy, 1424 "downloads/desc/descs", 1425 &answer, &errmsg); 1426 tt_ptr_op(answer, OP_EQ, NULL); 1427 tt_ptr_op(errmsg, OP_NE, NULL); 1428 tt_str_op(errmsg, OP_EQ, 1429 "We don't seem to have a networkstatus-flavored consensus"); 1430 errmsg = NULL; 1431 disable_descbr = 0; 1432 1433 done: 1434 clear_desc_mocks(); 1435 tor_free(answer); 1436 1437 return; 1438 } 1439 1440 static void 1441 test_download_status_bridge(void *arg) 1442 { 1443 /* We just need one of these to pass, it doesn't matter what's in it */ 1444 control_connection_t dummy; 1445 /* Get results out */ 1446 char *question = NULL; 1447 char *answer = NULL; 1448 const char *errmsg = NULL; 1449 1450 (void)arg; 1451 1452 setup_bridge_mocks(); 1453 1454 /* 1455 * Check returning serialized dlstatuses and digest lists, and implicitly 1456 * also test download_status_to_string() and digest_list_to_string(). 1457 */ 1458 1459 /* Case 1 - list of bridge identity digests */ 1460 getinfo_helper_downloads(&dummy, 1461 "downloads/bridge/bridges", 1462 &answer, &errmsg); 1463 tt_ptr_op(answer, OP_NE, NULL); 1464 tt_ptr_op(errmsg, OP_EQ, NULL); 1465 tt_str_op(answer, OP_EQ, descbr_expected_list); 1466 tor_free(answer); 1467 errmsg = NULL; 1468 1469 /* Case 2 - get download status for bridge descriptor 1 */ 1470 memcpy(&descbr_digest_1_dl, &dls_sample_3, 1471 sizeof(download_status_t)); 1472 tor_asprintf(&question, "downloads/bridge/%s", descbr_digest_1_str); 1473 tt_ptr_op(question, OP_NE, NULL); 1474 getinfo_helper_downloads(&dummy, question, &answer, &errmsg); 1475 tt_ptr_op(answer, OP_NE, NULL); 1476 tt_ptr_op(errmsg, OP_EQ, NULL); 1477 tt_str_op(answer, OP_EQ, dls_sample_3_str); 1478 tor_free(question); 1479 tor_free(answer); 1480 errmsg = NULL; 1481 1482 /* Case 3 - get download status for router descriptor 1 */ 1483 memcpy(&descbr_digest_2_dl, &dls_sample_4, 1484 sizeof(download_status_t)); 1485 tor_asprintf(&question, "downloads/bridge/%s", descbr_digest_2_str); 1486 tt_ptr_op(question, OP_NE, NULL); 1487 getinfo_helper_downloads(&dummy, question, &answer, &errmsg); 1488 tt_ptr_op(answer, OP_NE, NULL); 1489 tt_ptr_op(errmsg, OP_EQ, NULL); 1490 tt_str_op(answer, OP_EQ, dls_sample_4_str); 1491 tor_free(question); 1492 tor_free(answer); 1493 errmsg = NULL; 1494 1495 /* Now check the error cases */ 1496 1497 /* Case 1 - non-digest-length garbage after downloads/bridge */ 1498 getinfo_helper_downloads(&dummy, "downloads/bridge/blahdeblah", 1499 &answer, &errmsg); 1500 tt_ptr_op(answer, OP_EQ, NULL); 1501 tt_ptr_op(errmsg, OP_NE, NULL); 1502 tt_str_op(errmsg, OP_EQ, "Unknown bridge descriptor download status query"); 1503 errmsg = NULL; 1504 1505 /* Case 2 - nonparseable digest-shaped thing */ 1506 getinfo_helper_downloads( 1507 &dummy, 1508 "downloads/bridge/774EC52FD9A5B80A6FACZE536616E8022E3470AG", 1509 &answer, &errmsg); 1510 tt_ptr_op(answer, OP_EQ, NULL); 1511 tt_ptr_op(errmsg, OP_NE, NULL); 1512 tt_str_op(errmsg, OP_EQ, "That didn't look like a digest"); 1513 errmsg = NULL; 1514 1515 /* Case 3 - digest we have no descriptor for */ 1516 getinfo_helper_downloads( 1517 &dummy, 1518 "downloads/bridge/B05B46135B0B2C04EBE1DD6A6AE4B12D7CD2226A", 1519 &answer, &errmsg); 1520 tt_ptr_op(answer, OP_EQ, NULL); 1521 tt_ptr_op(errmsg, OP_NE, NULL); 1522 tt_str_op(errmsg, OP_EQ, "No such bridge identity digest found"); 1523 errmsg = NULL; 1524 1525 /* Case 4 - bridges disabled */ 1526 disable_descbr = 1; 1527 getinfo_helper_downloads(&dummy, 1528 "downloads/bridge/bridges", 1529 &answer, &errmsg); 1530 tt_ptr_op(answer, OP_EQ, NULL); 1531 tt_ptr_op(errmsg, OP_NE, NULL); 1532 tt_str_op(errmsg, OP_EQ, "We don't seem to be using bridges"); 1533 errmsg = NULL; 1534 disable_descbr = 0; 1535 1536 done: 1537 clear_bridge_mocks(); 1538 tor_free(answer); 1539 1540 return; 1541 } 1542 1543 /** Mock cached consensus */ 1544 static cached_dir_t *mock_ns_consensus_cache; 1545 static cached_dir_t *mock_microdesc_consensus_cache; 1546 1547 /** Mock the function that retrieves consensus from cache. These use a 1548 * global variable so that they can be cleared from within the test. 1549 * The actual code retains the pointer to the consensus data, but 1550 * we are doing this here, to prevent memory leaks 1551 * from within the tests */ 1552 static cached_dir_t * 1553 mock_dirserv_get_consensus(const char *flavor_name) 1554 { 1555 if (!strcmp(flavor_name, "ns")) { 1556 mock_ns_consensus_cache = tor_malloc_zero(sizeof(cached_dir_t)); 1557 mock_ns_consensus_cache->dir = tor_strdup("mock_ns_consensus"); 1558 return mock_ns_consensus_cache; 1559 } else { 1560 mock_microdesc_consensus_cache = tor_malloc_zero(sizeof(cached_dir_t)); 1561 mock_microdesc_consensus_cache->dir = tor_strdup( 1562 "mock_microdesc_consensus"); 1563 return mock_microdesc_consensus_cache; 1564 } 1565 } 1566 1567 /** Mock the function that retrieves consensuses 1568 * from a files in the directory. */ 1569 static tor_mmap_t * 1570 mock_tor_mmap_file(const char* filename) 1571 { 1572 tor_mmap_t *res; 1573 res = tor_malloc_zero(sizeof(tor_mmap_t)); 1574 if (strstr(filename, "cached-consensus") != NULL) { 1575 res->data = "mock_ns_consensus"; 1576 } else if (strstr(filename, "cached-microdesc-consensus") != NULL) { 1577 res->data = "mock_microdesc_consensus"; 1578 } else { 1579 res->data = "."; 1580 } 1581 res->size = strlen(res->data); 1582 return res; 1583 } 1584 1585 /** Mock the function that clears file data 1586 * loaded into the memory */ 1587 static int 1588 mock_tor_munmap_file(tor_mmap_t *handle) 1589 { 1590 tor_free(handle); 1591 return 0; 1592 } 1593 1594 static void 1595 test_getinfo_helper_current_consensus_from_file(void *arg) 1596 { 1597 /* We just need one of these to pass, it doesn't matter what's in it */ 1598 control_connection_t dummy; 1599 /* Get results out */ 1600 char *answer = NULL; 1601 const char *errmsg = NULL; 1602 1603 (void)arg; 1604 1605 MOCK(tor_mmap_file, mock_tor_mmap_file); 1606 MOCK(tor_munmap_file, mock_tor_munmap_file); 1607 1608 getinfo_helper_dir(&dummy, 1609 "dir/status-vote/current/consensus", 1610 &answer, 1611 &errmsg); 1612 tt_str_op(answer, OP_EQ, "mock_ns_consensus"); 1613 tt_ptr_op(errmsg, OP_EQ, NULL); 1614 tor_free(answer); 1615 errmsg = NULL; 1616 1617 getinfo_helper_dir(&dummy, 1618 "dir/status-vote/current/consensus-microdesc", 1619 &answer, 1620 &errmsg); 1621 tt_str_op(answer, OP_EQ, "mock_microdesc_consensus"); 1622 tt_ptr_op(errmsg, OP_EQ, NULL); 1623 errmsg = NULL; 1624 1625 done: 1626 tor_free(answer); 1627 UNMOCK(tor_mmap_file); 1628 UNMOCK(tor_munmap_file); 1629 return; 1630 } 1631 1632 static void 1633 test_getinfo_helper_current_consensus_from_cache(void *arg) 1634 { 1635 /* We just need one of these to pass, it doesn't matter what's in it */ 1636 control_connection_t dummy; 1637 /* Get results out */ 1638 char *answer = NULL; 1639 const char *errmsg = NULL; 1640 1641 (void)arg; 1642 or_options_t *options = get_options_mutable(); 1643 options->FetchUselessDescriptors = 1; 1644 MOCK(dirserv_get_consensus, mock_dirserv_get_consensus); 1645 1646 getinfo_helper_dir(&dummy, 1647 "dir/status-vote/current/consensus", 1648 &answer, 1649 &errmsg); 1650 tt_str_op(answer, OP_EQ, "mock_ns_consensus"); 1651 tt_ptr_op(errmsg, OP_EQ, NULL); 1652 tor_free(answer); 1653 tor_free(mock_ns_consensus_cache->dir); 1654 tor_free(mock_ns_consensus_cache); 1655 errmsg = NULL; 1656 1657 getinfo_helper_dir(&dummy, 1658 "dir/status-vote/current/consensus-microdesc", 1659 &answer, 1660 &errmsg); 1661 tt_str_op(answer, OP_EQ, "mock_microdesc_consensus"); 1662 tt_ptr_op(errmsg, OP_EQ, NULL); 1663 tor_free(mock_microdesc_consensus_cache->dir); 1664 tor_free(answer); 1665 errmsg = NULL; 1666 1667 done: 1668 options->FetchUselessDescriptors = 0; 1669 tor_free(answer); 1670 tor_free(mock_microdesc_consensus_cache); 1671 UNMOCK(dirserv_get_consensus); 1672 return; 1673 } 1674 1675 /** Set timeval to a mock date and time. This is necessary 1676 * to make tor_gettimeofday() mockable. */ 1677 static void 1678 mock_tor_gettimeofday(struct timeval *timeval) 1679 { 1680 timeval->tv_sec = 1523405073; 1681 timeval->tv_usec = 271645; 1682 } 1683 1684 static void 1685 test_current_time(void *arg) 1686 { 1687 /* We just need one of these to pass, it doesn't matter what's in it */ 1688 control_connection_t dummy; 1689 /* Get results out */ 1690 char *answer = NULL; 1691 const char *errmsg = NULL; 1692 1693 (void)arg; 1694 1695 /* We need these for storing the (mock) time. */ 1696 MOCK(tor_gettimeofday, mock_tor_gettimeofday); 1697 struct timeval now; 1698 tor_gettimeofday(&now); 1699 char timebuf[ISO_TIME_LEN+1]; 1700 1701 /* Case 1 - local time */ 1702 format_local_iso_time_nospace(timebuf, (time_t)now.tv_sec); 1703 getinfo_helper_current_time(&dummy, 1704 "current-time/local", 1705 &answer, &errmsg); 1706 tt_ptr_op(answer, OP_NE, NULL); 1707 tt_ptr_op(errmsg, OP_EQ, NULL); 1708 tt_str_op(answer, OP_EQ, timebuf); 1709 tor_free(answer); 1710 errmsg = NULL; 1711 1712 /* Case 2 - UTC time */ 1713 format_iso_time_nospace(timebuf, (time_t)now.tv_sec); 1714 getinfo_helper_current_time(&dummy, 1715 "current-time/utc", 1716 &answer, &errmsg); 1717 tt_ptr_op(answer, OP_NE, NULL); 1718 tt_ptr_op(errmsg, OP_EQ, NULL); 1719 tt_str_op(answer, OP_EQ, timebuf); 1720 tor_free(answer); 1721 errmsg = NULL; 1722 1723 done: 1724 UNMOCK(tor_gettimeofday); 1725 tor_free(answer); 1726 1727 return; 1728 } 1729 1730 static size_t n_nodelist_get_list = 0; 1731 static smartlist_t *nodes = NULL; 1732 1733 static const smartlist_t * 1734 mock_nodelist_get_list(void) 1735 { 1736 n_nodelist_get_list++; 1737 tor_assert(nodes); 1738 1739 return nodes; 1740 } 1741 1742 static void 1743 test_getinfo_md_all(void *arg) 1744 { 1745 char *answer = NULL; 1746 const char *errmsg = NULL; 1747 int retval = 0; 1748 1749 (void)arg; 1750 1751 node_t *node1 = tor_malloc(sizeof(node_t)); 1752 memset(node1, 0, sizeof(node_t)); 1753 node1->md = tor_malloc(sizeof(microdesc_t)); 1754 memset(node1->md, 0, sizeof(microdesc_t)); 1755 node1->md->body = tor_strdup("md1\n"); 1756 node1->md->bodylen = 4; 1757 1758 node_t *node2 = tor_malloc(sizeof(node_t)); 1759 memset(node2, 0, sizeof(node_t)); 1760 node2->md = tor_malloc(sizeof(microdesc_t)); 1761 memset(node2->md, 0, sizeof(microdesc_t)); 1762 node2->md->body = tor_strdup("md2\n"); 1763 node2->md->bodylen = 4; 1764 1765 MOCK(nodelist_get_list, mock_nodelist_get_list); 1766 1767 nodes = smartlist_new(); 1768 1769 retval = getinfo_helper_dir(NULL, "md/all", &answer, &errmsg); 1770 1771 tt_int_op(n_nodelist_get_list, OP_EQ, 1); 1772 tt_int_op(retval, OP_EQ, 0); 1773 tt_assert(answer != NULL); 1774 tt_assert(errmsg == NULL); 1775 tt_str_op(answer, OP_EQ, ""); 1776 1777 tor_free(answer); 1778 1779 smartlist_add(nodes, node1); 1780 smartlist_add(nodes, node2); 1781 1782 retval = getinfo_helper_dir(NULL, "md/all", &answer, &errmsg); 1783 1784 tt_int_op(n_nodelist_get_list, OP_EQ, 2); 1785 tt_int_op(retval, OP_EQ, 0); 1786 tt_assert(answer != NULL); 1787 tt_assert(errmsg == NULL); 1788 1789 tt_str_op(answer, OP_EQ, "md1\nmd2\n"); 1790 1791 done: 1792 UNMOCK(nodelist_get_list); 1793 tor_free(node1->md->body); 1794 tor_free(node1->md); 1795 tor_free(node1); 1796 tor_free(node2->md->body); 1797 tor_free(node2->md); 1798 tor_free(node2); 1799 tor_free(answer); 1800 smartlist_free(nodes); 1801 return; 1802 } 1803 1804 static smartlist_t *reply_strs; 1805 1806 static void 1807 mock_control_write_reply_list(control_connection_t *conn, int code, int c, 1808 const char *s) 1809 { 1810 (void)conn; 1811 /* To make matching easier, don't append "\r\n" */ 1812 smartlist_add_asprintf(reply_strs, "%03d%c%s", code, c, s); 1813 } 1814 1815 static void 1816 test_control_reply(void *arg) 1817 { 1818 (void)arg; 1819 smartlist_t *lines = smartlist_new(); 1820 1821 MOCK(control_write_reply, mock_control_write_reply); 1822 1823 tor_free(reply_str); 1824 control_reply_clear(lines); 1825 control_reply_add_str(lines, 250, "FOO"); 1826 control_write_reply_lines(NULL, lines); 1827 tt_str_op(reply_str, OP_EQ, "FOO"); 1828 1829 tor_free(reply_str); 1830 control_reply_clear(lines); 1831 control_reply_add_done(lines); 1832 control_write_reply_lines(NULL, lines); 1833 tt_str_op(reply_str, OP_EQ, "OK"); 1834 1835 tor_free(reply_str); 1836 control_reply_clear(lines); 1837 UNMOCK(control_write_reply); 1838 MOCK(control_write_reply, mock_control_write_reply_list); 1839 reply_strs = smartlist_new(); 1840 control_reply_add_one_kv(lines, 250, 0, "A", "B"); 1841 control_reply_add_one_kv(lines, 250, 0, "C", "D"); 1842 control_write_reply_lines(NULL, lines); 1843 tt_int_op(smartlist_len(reply_strs), OP_EQ, 2); 1844 tt_str_op((char *)smartlist_get(reply_strs, 0), OP_EQ, "250-A=B"); 1845 tt_str_op((char *)smartlist_get(reply_strs, 1), OP_EQ, "250 C=D"); 1846 1847 control_reply_clear(lines); 1848 SMARTLIST_FOREACH(reply_strs, char *, p, tor_free(p)); 1849 smartlist_clear(reply_strs); 1850 control_reply_add_printf(lines, 250, "PROTOCOLINFO %d", 1); 1851 control_reply_add_one_kv(lines, 250, KV_OMIT_VALS|KV_RAW, "AUTH", ""); 1852 control_reply_append_kv(lines, "METHODS", "COOKIE"); 1853 control_reply_append_kv(lines, "COOKIEFILE", escaped("/tmp/cookie")); 1854 control_reply_add_done(lines); 1855 control_write_reply_lines(NULL, lines); 1856 tt_int_op(smartlist_len(reply_strs), OP_EQ, 3); 1857 tt_str_op((char *)smartlist_get(reply_strs, 0), 1858 OP_EQ, "250-PROTOCOLINFO 1"); 1859 tt_str_op((char *)smartlist_get(reply_strs, 1), 1860 OP_EQ, "250-AUTH METHODS=COOKIE COOKIEFILE=\"/tmp/cookie\""); 1861 tt_str_op((char *)smartlist_get(reply_strs, 2), 1862 OP_EQ, "250 OK"); 1863 1864 done: 1865 UNMOCK(control_write_reply); 1866 tor_free(reply_str); 1867 control_reply_free(lines); 1868 if (reply_strs) 1869 SMARTLIST_FOREACH(reply_strs, char *, p, tor_free(p)); 1870 smartlist_free(reply_strs); 1871 return; 1872 } 1873 1874 static void 1875 test_control_getconf(void *arg) 1876 { 1877 (void)arg; 1878 control_connection_t conn; 1879 char *args = NULL; 1880 int r = -1; 1881 1882 memset(&conn, 0, sizeof(conn)); 1883 conn.current_cmd = tor_strdup("GETCONF"); 1884 1885 MOCK(control_write_reply, mock_control_write_reply_list); 1886 reply_strs = smartlist_new(); 1887 1888 args = tor_strdup(""); 1889 r = handle_control_command(&conn, (uint32_t)strlen(args), args); 1890 tt_int_op(r, OP_EQ, 0); 1891 tt_int_op(smartlist_len(reply_strs), OP_EQ, 1); 1892 tt_str_op((char *)smartlist_get(reply_strs, 0), OP_EQ, "250 OK"); 1893 SMARTLIST_FOREACH(reply_strs, char *, p, tor_free(p)); 1894 smartlist_clear(reply_strs); 1895 tor_free(args); 1896 1897 args = tor_strdup("NoSuch"); 1898 r = handle_control_command(&conn, (uint32_t)strlen(args), args); 1899 tt_int_op(r, OP_EQ, 0); 1900 tt_int_op(smartlist_len(reply_strs), OP_EQ, 1); 1901 tt_str_op((char *)smartlist_get(reply_strs, 0), OP_EQ, 1902 "552 Unrecognized configuration key \"NoSuch\""); 1903 tor_free(args); 1904 SMARTLIST_FOREACH(reply_strs, char *, p, tor_free(p)); 1905 smartlist_clear(reply_strs); 1906 1907 args = tor_strdup("NoSuch1 NoSuch2"); 1908 r = handle_control_command(&conn, (uint32_t)strlen(args), args); 1909 tt_int_op(r, OP_EQ, 0); 1910 tt_int_op(smartlist_len(reply_strs), OP_EQ, 2); 1911 tt_str_op((char *)smartlist_get(reply_strs, 0), OP_EQ, 1912 "552-Unrecognized configuration key \"NoSuch1\""); 1913 tt_str_op((char *)smartlist_get(reply_strs, 1), OP_EQ, 1914 "552 Unrecognized configuration key \"NoSuch2\""); 1915 tor_free(args); 1916 SMARTLIST_FOREACH(reply_strs, char *, p, tor_free(p)); 1917 smartlist_clear(reply_strs); 1918 1919 args = tor_strdup("ControlPort NoSuch"); 1920 r = handle_control_command(&conn, (uint32_t)strlen(args), args); 1921 tt_int_op(r, OP_EQ, 0); 1922 /* Valid keys ignored if there are any invalid ones */ 1923 tt_int_op(smartlist_len(reply_strs), OP_EQ, 1); 1924 tt_str_op((char *)smartlist_get(reply_strs, 0), OP_EQ, 1925 "552 Unrecognized configuration key \"NoSuch\""); 1926 tor_free(args); 1927 SMARTLIST_FOREACH(reply_strs, char *, p, tor_free(p)); 1928 smartlist_clear(reply_strs); 1929 1930 args = tor_strdup("ClientOnly"); 1931 r = handle_control_command(&conn, (uint32_t)strlen(args), args); 1932 tt_int_op(r, OP_EQ, 0); 1933 tt_int_op(smartlist_len(reply_strs), OP_EQ, 1); 1934 /* According to config.c, this is an exception for the unit tests */ 1935 tt_str_op((char *)smartlist_get(reply_strs, 0), OP_EQ, "250 ClientOnly=0"); 1936 tor_free(args); 1937 SMARTLIST_FOREACH(reply_strs, char *, p, tor_free(p)); 1938 smartlist_clear(reply_strs); 1939 1940 args = tor_strdup("BridgeRelay ClientOnly"); 1941 r = handle_control_command(&conn, (uint32_t)strlen(args), args); 1942 tt_int_op(r, OP_EQ, 0); 1943 tt_int_op(smartlist_len(reply_strs), OP_EQ, 2); 1944 /* Change if config.c changes BridgeRelay default (unlikely) */ 1945 tt_str_op((char *)smartlist_get(reply_strs, 0), OP_EQ, "250-BridgeRelay=0"); 1946 tt_str_op((char *)smartlist_get(reply_strs, 1), OP_EQ, "250 ClientOnly=0"); 1947 tor_free(args); 1948 SMARTLIST_FOREACH(reply_strs, char *, p, tor_free(p)); 1949 smartlist_clear(reply_strs); 1950 1951 done: 1952 tor_free(conn.current_cmd); 1953 tor_free(args); 1954 UNMOCK(control_write_reply); 1955 SMARTLIST_FOREACH(reply_strs, char *, p, tor_free(p)); 1956 smartlist_free(reply_strs); 1957 } 1958 1959 static int 1960 mock_rep_hist_get_circuit_handshake(uint16_t type) 1961 { 1962 int ret; 1963 1964 switch (type) { 1965 case ONION_HANDSHAKE_TYPE_NTOR: 1966 ret = 80; 1967 break; 1968 case ONION_HANDSHAKE_TYPE_TAP: 1969 ret = 86; 1970 break; 1971 default: 1972 ret = 0; 1973 break; 1974 } 1975 1976 return ret; 1977 } 1978 1979 static void 1980 test_stats(void *arg) 1981 { 1982 /* We just need one of these to pass, it doesn't matter what's in it */ 1983 control_connection_t dummy; 1984 /* Get results out */ 1985 char *answer = NULL; 1986 const char *errmsg = NULL; 1987 1988 (void) arg; 1989 1990 /* We need these for returning the (mock) rephist. */ 1991 MOCK(rep_hist_get_circuit_handshake_requested, 1992 mock_rep_hist_get_circuit_handshake); 1993 MOCK(rep_hist_get_circuit_handshake_assigned, 1994 mock_rep_hist_get_circuit_handshake); 1995 1996 /* NTor tests */ 1997 getinfo_helper_rephist(&dummy, "stats/ntor/requested", 1998 &answer, &errmsg); 1999 tt_ptr_op(answer, OP_NE, NULL); 2000 tt_ptr_op(errmsg, OP_EQ, NULL); 2001 tt_str_op(answer, OP_EQ, "80"); 2002 tor_free(answer); 2003 errmsg = NULL; 2004 2005 getinfo_helper_rephist(&dummy, "stats/ntor/assigned", 2006 &answer, &errmsg); 2007 tt_ptr_op(answer, OP_NE, NULL); 2008 tt_ptr_op(errmsg, OP_EQ, NULL); 2009 tt_str_op(answer, OP_EQ, "80"); 2010 tor_free(answer); 2011 errmsg = NULL; 2012 2013 /* TAP tests */ 2014 getinfo_helper_rephist(&dummy, "stats/tap/requested", 2015 &answer, &errmsg); 2016 tt_ptr_op(answer, OP_NE, NULL); 2017 tt_ptr_op(errmsg, OP_EQ, NULL); 2018 tt_str_op(answer, OP_EQ, "86"); 2019 tor_free(answer); 2020 errmsg = NULL; 2021 2022 getinfo_helper_rephist(&dummy, "stats/tap/assigned", 2023 &answer, &errmsg); 2024 tt_ptr_op(answer, OP_NE, NULL); 2025 tt_ptr_op(errmsg, OP_EQ, NULL); 2026 tt_str_op(answer, OP_EQ, "86"); 2027 tor_free(answer); 2028 errmsg = NULL; 2029 2030 getinfo_helper_rephist(&dummy, "stats/tap/onion_circuits_ddosed", 2031 &answer, &errmsg); 2032 tt_ptr_op(answer, OP_EQ, NULL); 2033 tt_str_op(errmsg, OP_EQ, "Unrecognized handshake type"); 2034 errmsg = NULL; 2035 2036 done: 2037 UNMOCK(rep_hist_get_circuit_handshake_requested); 2038 UNMOCK(rep_hist_get_circuit_handshake_assigned); 2039 tor_free(answer); 2040 2041 return; 2042 } 2043 2044 #ifndef COCCI 2045 #define PARSER_TEST(type) \ 2046 { "parse/" #type, test_controller_parse_cmd, 0, &passthrough_setup, \ 2047 (void*)&parse_ ## type ## _params } 2048 #endif 2049 2050 struct testcase_t controller_tests[] = { 2051 PARSER_TEST(one_to_three), 2052 PARSER_TEST(no_args_one_obj), 2053 PARSER_TEST(no_args_kwargs), 2054 PARSER_TEST(one_arg_kwargs), 2055 { "add_onion_helper_keyarg_v3", test_add_onion_helper_keyarg_v3, 0, 2056 NULL, NULL }, 2057 { "getinfo_helper_onion", test_getinfo_helper_onion, 0, NULL, NULL }, 2058 { "hs_parse_port_config", test_hs_parse_port_config, 0, 2059 NULL, NULL }, 2060 { "download_status_consensus", test_download_status_consensus, 0, NULL, 2061 NULL }, 2062 {"getinfo_helper_current_consensus_from_cache", 2063 test_getinfo_helper_current_consensus_from_cache, 0, NULL, NULL }, 2064 {"getinfo_helper_current_consensus_from_file", 2065 test_getinfo_helper_current_consensus_from_file, 0, NULL, NULL }, 2066 { "download_status_cert", test_download_status_cert, 0, NULL, 2067 NULL }, 2068 { "download_status_desc", test_download_status_desc, 0, NULL, NULL }, 2069 { "download_status_bridge", test_download_status_bridge, 0, NULL, NULL }, 2070 { "current_time", test_current_time, 0, NULL, NULL }, 2071 { "getinfo_md_all", test_getinfo_md_all, 0, NULL, NULL }, 2072 { "control_reply", test_control_reply, 0, NULL, NULL }, 2073 { "control_getconf", test_control_getconf, 0, NULL, NULL }, 2074 { "stats", test_stats, 0, NULL, NULL }, 2075 END_OF_TESTCASES 2076 };