test_controller.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462
  1. /* Copyright (c) 2015-2016, The Tor Project, Inc. */
  2. /* See LICENSE for licensing information */
  3. #define CONTROL_PRIVATE
  4. #include "or.h"
  5. #include "control.h"
  6. #include "networkstatus.h"
  7. #include "rendservice.h"
  8. #include "test.h"
  9. static void
  10. test_add_onion_helper_keyarg(void *arg)
  11. {
  12. crypto_pk_t *pk = NULL;
  13. crypto_pk_t *pk2 = NULL;
  14. const char *key_new_alg = NULL;
  15. char *key_new_blob = NULL;
  16. char *err_msg = NULL;
  17. char *encoded = NULL;
  18. char *arg_str = NULL;
  19. (void) arg;
  20. /* Test explicit RSA1024 key generation. */
  21. pk = add_onion_helper_keyarg("NEW:RSA1024", 0, &key_new_alg, &key_new_blob,
  22. &err_msg);
  23. tt_assert(pk);
  24. tt_str_op(key_new_alg, OP_EQ, "RSA1024");
  25. tt_assert(key_new_blob);
  26. tt_assert(!err_msg);
  27. /* Test "BEST" key generation (Assumes BEST = RSA1024). */
  28. crypto_pk_free(pk);
  29. tor_free(key_new_blob);
  30. pk = add_onion_helper_keyarg("NEW:BEST", 0, &key_new_alg, &key_new_blob,
  31. &err_msg);
  32. tt_assert(pk);
  33. tt_str_op(key_new_alg, OP_EQ, "RSA1024");
  34. tt_assert(key_new_blob);
  35. tt_assert(!err_msg);
  36. /* Test discarding the private key. */
  37. crypto_pk_free(pk);
  38. tor_free(key_new_blob);
  39. pk = add_onion_helper_keyarg("NEW:BEST", 1, &key_new_alg, &key_new_blob,
  40. &err_msg);
  41. tt_assert(pk);
  42. tt_assert(!key_new_alg);
  43. tt_assert(!key_new_blob);
  44. tt_assert(!err_msg);
  45. /* Test generating a invalid key type. */
  46. crypto_pk_free(pk);
  47. pk = add_onion_helper_keyarg("NEW:RSA512", 0, &key_new_alg, &key_new_blob,
  48. &err_msg);
  49. tt_assert(!pk);
  50. tt_assert(!key_new_alg);
  51. tt_assert(!key_new_blob);
  52. tt_assert(err_msg);
  53. /* Test loading a RSA1024 key. */
  54. tor_free(err_msg);
  55. pk = pk_generate(0);
  56. tt_int_op(0, OP_EQ, crypto_pk_base64_encode(pk, &encoded));
  57. tor_asprintf(&arg_str, "RSA1024:%s", encoded);
  58. pk2 = add_onion_helper_keyarg(arg_str, 0, &key_new_alg, &key_new_blob,
  59. &err_msg);
  60. tt_assert(pk2);
  61. tt_assert(!key_new_alg);
  62. tt_assert(!key_new_blob);
  63. tt_assert(!err_msg);
  64. tt_assert(crypto_pk_cmp_keys(pk, pk2) == 0);
  65. /* Test loading a invalid key type. */
  66. tor_free(arg_str);
  67. crypto_pk_free(pk); pk = NULL;
  68. tor_asprintf(&arg_str, "RSA512:%s", encoded);
  69. pk = add_onion_helper_keyarg(arg_str, 0, &key_new_alg, &key_new_blob,
  70. &err_msg);
  71. tt_assert(!pk);
  72. tt_assert(!key_new_alg);
  73. tt_assert(!key_new_blob);
  74. tt_assert(err_msg);
  75. /* Test loading a invalid key. */
  76. tor_free(arg_str);
  77. crypto_pk_free(pk); pk = NULL;
  78. tor_free(err_msg);
  79. encoded[strlen(encoded)/2] = '\0';
  80. tor_asprintf(&arg_str, "RSA1024:%s", encoded);
  81. pk = add_onion_helper_keyarg(arg_str, 0, &key_new_alg, &key_new_blob,
  82. &err_msg);
  83. tt_assert(!pk);
  84. tt_assert(!key_new_alg);
  85. tt_assert(!key_new_blob);
  86. tt_assert(err_msg);
  87. done:
  88. crypto_pk_free(pk);
  89. crypto_pk_free(pk2);
  90. tor_free(key_new_blob);
  91. tor_free(err_msg);
  92. tor_free(encoded);
  93. tor_free(arg_str);
  94. }
  95. static void
  96. test_rend_service_parse_port_config(void *arg)
  97. {
  98. const char *sep = ",";
  99. rend_service_port_config_t *cfg = NULL;
  100. char *err_msg = NULL;
  101. (void)arg;
  102. /* Test "VIRTPORT" only. */
  103. cfg = rend_service_parse_port_config("80", sep, &err_msg);
  104. tt_assert(cfg);
  105. tt_assert(!err_msg);
  106. /* Test "VIRTPORT,TARGET" (Target is port). */
  107. rend_service_port_config_free(cfg);
  108. cfg = rend_service_parse_port_config("80,8080", sep, &err_msg);
  109. tt_assert(cfg);
  110. tt_assert(!err_msg);
  111. /* Test "VIRTPORT,TARGET" (Target is IPv4:port). */
  112. rend_service_port_config_free(cfg);
  113. cfg = rend_service_parse_port_config("80,192.0.2.1:8080", sep, &err_msg);
  114. tt_assert(cfg);
  115. tt_assert(!err_msg);
  116. /* Test "VIRTPORT,TARGET" (Target is IPv6:port). */
  117. rend_service_port_config_free(cfg);
  118. cfg = rend_service_parse_port_config("80,[2001:db8::1]:8080", sep, &err_msg);
  119. tt_assert(cfg);
  120. tt_assert(!err_msg);
  121. /* XXX: Someone should add tests for AF_UNIX targets if supported. */
  122. /* Test empty config. */
  123. rend_service_port_config_free(cfg);
  124. cfg = rend_service_parse_port_config("", sep, &err_msg);
  125. tt_assert(!cfg);
  126. tt_assert(err_msg);
  127. /* Test invalid port. */
  128. tor_free(err_msg);
  129. cfg = rend_service_parse_port_config("90001", sep, &err_msg);
  130. tt_assert(!cfg);
  131. tt_assert(err_msg);
  132. done:
  133. rend_service_port_config_free(cfg);
  134. tor_free(err_msg);
  135. }
  136. static void
  137. test_add_onion_helper_clientauth(void *arg)
  138. {
  139. rend_authorized_client_t *client = NULL;
  140. char *err_msg = NULL;
  141. int created = 0;
  142. (void)arg;
  143. /* Test "ClientName" only. */
  144. client = add_onion_helper_clientauth("alice", &created, &err_msg);
  145. tt_assert(client);
  146. tt_assert(created);
  147. tt_assert(!err_msg);
  148. rend_authorized_client_free(client);
  149. /* Test "ClientName:Blob" */
  150. client = add_onion_helper_clientauth("alice:475hGBHPlq7Mc0cRZitK/B",
  151. &created, &err_msg);
  152. tt_assert(client);
  153. tt_assert(!created);
  154. tt_assert(!err_msg);
  155. rend_authorized_client_free(client);
  156. /* Test invalid client names */
  157. client = add_onion_helper_clientauth("no*asterisks*allowed", &created,
  158. &err_msg);
  159. tt_assert(!client);
  160. tt_assert(err_msg);
  161. tor_free(err_msg);
  162. /* Test invalid auth cookie */
  163. client = add_onion_helper_clientauth("alice:12345", &created, &err_msg);
  164. tt_assert(!client);
  165. tt_assert(err_msg);
  166. tor_free(err_msg);
  167. /* Test invalid syntax */
  168. client = add_onion_helper_clientauth(":475hGBHPlq7Mc0cRZitK/B", &created,
  169. &err_msg);
  170. tt_assert(!client);
  171. tt_assert(err_msg);
  172. tor_free(err_msg);
  173. done:
  174. rend_authorized_client_free(client);
  175. tor_free(err_msg);
  176. }
  177. /* Mocks and data/variables used for GETINFO download status tests */
  178. static const download_status_t dl_status_default =
  179. { 0, 0, 0, DL_SCHED_CONSENSUS, DL_WANT_ANY_DIRSERVER,
  180. DL_SCHED_INCREMENT_FAILURE, DL_SCHED_RANDOM_EXPONENTIAL, 0, 0 };
  181. static download_status_t ns_dl_status[N_CONSENSUS_FLAVORS];
  182. static download_status_t ns_dl_status_bootstrap[N_CONSENSUS_FLAVORS];
  183. static download_status_t ns_dl_status_running[N_CONSENSUS_FLAVORS];
  184. /*
  185. * These should explore all the possible cases of download_status_to_string()
  186. * in control.c
  187. */
  188. static const download_status_t dls_sample_1 =
  189. { 1467163900, 0, 0, DL_SCHED_GENERIC, DL_WANT_ANY_DIRSERVER,
  190. DL_SCHED_INCREMENT_FAILURE, DL_SCHED_DETERMINISTIC, 0, 0 };
  191. static const char * dls_sample_1_str =
  192. "next-attempt-at 2016-06-29 01:31:40\n"
  193. "n-download-failures 0\n"
  194. "n-download-attempts 0\n"
  195. "schedule DL_SCHED_GENERIC\n"
  196. "want-authority DL_WANT_ANY_DIRSERVER\n"
  197. "increment-on DL_SCHED_INCREMENT_FAILURE\n"
  198. "backoff DL_SCHED_DETERMINISTIC\n";
  199. static const download_status_t dls_sample_2 =
  200. { 1467164400, 1, 2, DL_SCHED_CONSENSUS, DL_WANT_AUTHORITY,
  201. DL_SCHED_INCREMENT_FAILURE, DL_SCHED_DETERMINISTIC, 0, 0 };
  202. static const char * dls_sample_2_str =
  203. "next-attempt-at 2016-06-29 01:40:00\n"
  204. "n-download-failures 1\n"
  205. "n-download-attempts 2\n"
  206. "schedule DL_SCHED_CONSENSUS\n"
  207. "want-authority DL_WANT_AUTHORITY\n"
  208. "increment-on DL_SCHED_INCREMENT_FAILURE\n"
  209. "backoff DL_SCHED_DETERMINISTIC\n";
  210. static const download_status_t dls_sample_3 =
  211. { 1467154400, 12, 25, DL_SCHED_BRIDGE, DL_WANT_ANY_DIRSERVER,
  212. DL_SCHED_INCREMENT_ATTEMPT, DL_SCHED_DETERMINISTIC, 0, 0 };
  213. static const char * dls_sample_3_str =
  214. "next-attempt-at 2016-06-28 22:53:20\n"
  215. "n-download-failures 12\n"
  216. "n-download-attempts 25\n"
  217. "schedule DL_SCHED_BRIDGE\n"
  218. "want-authority DL_WANT_ANY_DIRSERVER\n"
  219. "increment-on DL_SCHED_INCREMENT_ATTEMPT\n"
  220. "backoff DL_SCHED_DETERMINISTIC\n";
  221. static const download_status_t dls_sample_4 =
  222. { 1467166600, 3, 0, DL_SCHED_GENERIC, DL_WANT_ANY_DIRSERVER,
  223. DL_SCHED_INCREMENT_FAILURE, DL_SCHED_RANDOM_EXPONENTIAL, 0, 0 };
  224. static const char * dls_sample_4_str =
  225. "next-attempt-at 2016-06-29 02:16:40\n"
  226. "n-download-failures 3\n"
  227. "n-download-attempts 0\n"
  228. "schedule DL_SCHED_GENERIC\n"
  229. "want-authority DL_WANT_ANY_DIRSERVER\n"
  230. "increment-on DL_SCHED_INCREMENT_FAILURE\n"
  231. "backoff DL_SCHED_RANDOM_EXPONENTIAL\n"
  232. "last-backoff-position 0\n"
  233. "last-delay-used 0\n";
  234. static const download_status_t dls_sample_5 =
  235. { 1467164600, 3, 7, DL_SCHED_CONSENSUS, DL_WANT_ANY_DIRSERVER,
  236. DL_SCHED_INCREMENT_FAILURE, DL_SCHED_RANDOM_EXPONENTIAL, 1, 2112, };
  237. static const char * dls_sample_5_str =
  238. "next-attempt-at 2016-06-29 01:43:20\n"
  239. "n-download-failures 3\n"
  240. "n-download-attempts 7\n"
  241. "schedule DL_SCHED_CONSENSUS\n"
  242. "want-authority DL_WANT_ANY_DIRSERVER\n"
  243. "increment-on DL_SCHED_INCREMENT_FAILURE\n"
  244. "backoff DL_SCHED_RANDOM_EXPONENTIAL\n"
  245. "last-backoff-position 1\n"
  246. "last-delay-used 2112\n";
  247. static const download_status_t dls_sample_6 =
  248. { 1467164200, 4, 9, DL_SCHED_CONSENSUS, DL_WANT_AUTHORITY,
  249. DL_SCHED_INCREMENT_ATTEMPT, DL_SCHED_RANDOM_EXPONENTIAL, 3, 432 };
  250. static const char * dls_sample_6_str =
  251. "next-attempt-at 2016-06-29 01:36:40\n"
  252. "n-download-failures 4\n"
  253. "n-download-attempts 9\n"
  254. "schedule DL_SCHED_CONSENSUS\n"
  255. "want-authority DL_WANT_AUTHORITY\n"
  256. "increment-on DL_SCHED_INCREMENT_ATTEMPT\n"
  257. "backoff DL_SCHED_RANDOM_EXPONENTIAL\n"
  258. "last-backoff-position 3\n"
  259. "last-delay-used 432\n";
  260. static void
  261. reset_mocked_dl_statuses(void)
  262. {
  263. int i;
  264. for (i = 0; i < N_CONSENSUS_FLAVORS; ++i) {
  265. memcpy(&(ns_dl_status[i]), &dl_status_default,
  266. sizeof(download_status_t));
  267. memcpy(&(ns_dl_status_bootstrap[i]), &dl_status_default,
  268. sizeof(download_status_t));
  269. memcpy(&(ns_dl_status_running[i]), &dl_status_default,
  270. sizeof(download_status_t));
  271. }
  272. }
  273. static download_status_t *
  274. ns_dl_status_mock(consensus_flavor_t flavor)
  275. {
  276. return &(ns_dl_status[flavor]);
  277. }
  278. static download_status_t *
  279. ns_dl_status_bootstrap_mock(consensus_flavor_t flavor)
  280. {
  281. return &(ns_dl_status_bootstrap[flavor]);
  282. }
  283. static download_status_t *
  284. ns_dl_status_running_mock(consensus_flavor_t flavor)
  285. {
  286. return &(ns_dl_status_running[flavor]);
  287. }
  288. static void
  289. setup_ns_mocks(void)
  290. {
  291. MOCK(networkstatus_get_dl_status_by_flavor, ns_dl_status_mock);
  292. MOCK(networkstatus_get_dl_status_by_flavor_bootstrap,
  293. ns_dl_status_bootstrap_mock);
  294. MOCK(networkstatus_get_dl_status_by_flavor_running,
  295. ns_dl_status_running_mock);
  296. reset_mocked_dl_statuses();
  297. }
  298. static void
  299. clear_ns_mocks(void)
  300. {
  301. UNMOCK(networkstatus_get_dl_status_by_flavor);
  302. UNMOCK(networkstatus_get_dl_status_by_flavor_bootstrap);
  303. UNMOCK(networkstatus_get_dl_status_by_flavor_running);
  304. }
  305. static void
  306. test_download_status_consensus(void *arg)
  307. {
  308. /* We just need one of these to pass, it doesn't matter what's in it */
  309. control_connection_t dummy;
  310. /* Get results out */
  311. char *answer = NULL;
  312. const char *errmsg = NULL;
  313. (void)arg;
  314. /* Check that the unknown prefix case works; no mocks needed yet */
  315. getinfo_helper_downloads(&dummy, "downloads/foo", &answer, &errmsg);
  316. tt_assert(answer == NULL);
  317. tt_str_op(errmsg, OP_EQ, "Unknown download status query");
  318. setup_ns_mocks();
  319. /*
  320. * Check returning serialized dlstatuses, and implicitly also test
  321. * download_status_to_string().
  322. */
  323. /* Case 1 default/FLAV_NS*/
  324. memcpy(&(ns_dl_status[FLAV_NS]), &dls_sample_1,
  325. sizeof(download_status_t));
  326. getinfo_helper_downloads(&dummy, "downloads/networkstatus/ns",
  327. &answer, &errmsg);
  328. tt_assert(answer != NULL);
  329. tt_assert(errmsg == NULL);
  330. tt_str_op(answer, OP_EQ, dls_sample_1_str);
  331. tor_free(answer);
  332. errmsg = NULL;
  333. /* Case 2 default/FLAV_MICRODESC */
  334. memcpy(&(ns_dl_status[FLAV_MICRODESC]), &dls_sample_2,
  335. sizeof(download_status_t));
  336. getinfo_helper_downloads(&dummy, "downloads/networkstatus/microdesc",
  337. &answer, &errmsg);
  338. tt_assert(answer != NULL);
  339. tt_assert(errmsg == NULL);
  340. tt_str_op(answer, OP_EQ, dls_sample_2_str);
  341. tor_free(answer);
  342. errmsg = NULL;
  343. /* Case 3 bootstrap/FLAV_NS */
  344. memcpy(&(ns_dl_status_bootstrap[FLAV_NS]), &dls_sample_3,
  345. sizeof(download_status_t));
  346. getinfo_helper_downloads(&dummy, "downloads/networkstatus/ns/bootstrap",
  347. &answer, &errmsg);
  348. tt_assert(answer != NULL);
  349. tt_assert(errmsg == NULL);
  350. tt_str_op(answer, OP_EQ, dls_sample_3_str);
  351. tor_free(answer);
  352. errmsg = NULL;
  353. /* Case 4 bootstrap/FLAV_MICRODESC */
  354. memcpy(&(ns_dl_status_bootstrap[FLAV_MICRODESC]), &dls_sample_4,
  355. sizeof(download_status_t));
  356. getinfo_helper_downloads(&dummy,
  357. "downloads/networkstatus/microdesc/bootstrap",
  358. &answer, &errmsg);
  359. tt_assert(answer != NULL);
  360. tt_assert(errmsg == NULL);
  361. tt_str_op(answer, OP_EQ, dls_sample_4_str);
  362. tor_free(answer);
  363. errmsg = NULL;
  364. /* Case 5 running/FLAV_NS */
  365. memcpy(&(ns_dl_status_running[FLAV_NS]), &dls_sample_5,
  366. sizeof(download_status_t));
  367. getinfo_helper_downloads(&dummy,
  368. "downloads/networkstatus/ns/running",
  369. &answer, &errmsg);
  370. tt_assert(answer != NULL);
  371. tt_assert(errmsg == NULL);
  372. tt_str_op(answer, OP_EQ, dls_sample_5_str);
  373. tor_free(answer);
  374. errmsg = NULL;
  375. /* Case 6 running/FLAV_MICRODESC */
  376. memcpy(&(ns_dl_status_running[FLAV_MICRODESC]), &dls_sample_6,
  377. sizeof(download_status_t));
  378. getinfo_helper_downloads(&dummy,
  379. "downloads/networkstatus/microdesc/running",
  380. &answer, &errmsg);
  381. tt_assert(answer != NULL);
  382. tt_assert(errmsg == NULL);
  383. tt_str_op(answer, OP_EQ, dls_sample_6_str);
  384. tor_free(answer);
  385. errmsg = NULL;
  386. /* Now check the error case */
  387. getinfo_helper_downloads(&dummy, "downloads/networkstatus/foo",
  388. &answer, &errmsg);
  389. tt_assert(answer == NULL);
  390. tt_assert(errmsg != NULL);
  391. tt_str_op(errmsg, OP_EQ, "Unknown flavor");
  392. errmsg = NULL;
  393. done:
  394. clear_ns_mocks();
  395. tor_free(answer);
  396. return;
  397. }
  398. struct testcase_t controller_tests[] = {
  399. { "add_onion_helper_keyarg", test_add_onion_helper_keyarg, 0, NULL, NULL },
  400. { "rend_service_parse_port_config", test_rend_service_parse_port_config, 0,
  401. NULL, NULL },
  402. { "add_onion_helper_clientauth", test_add_onion_helper_clientauth, 0, NULL,
  403. NULL },
  404. { "download_status_consensus", test_download_status_consensus, 0, NULL,
  405. NULL },
  406. END_OF_TESTCASES
  407. };