test_hs.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. /* Copyright (c) 2007-2015, The Tor Project, Inc. */
  2. /* See LICENSE for licensing information */
  3. /**
  4. * \file test_hs.c
  5. * \brief Unit tests for hidden service.
  6. **/
  7. #define CONTROL_PRIVATE
  8. #define CIRCUITBUILD_PRIVATE
  9. #include "or.h"
  10. #include "test.h"
  11. #include "control.h"
  12. #include "config.h"
  13. #include "routerset.h"
  14. #include "circuitbuild.h"
  15. #include "test_helpers.h"
  16. /* mock ID digest and longname for node that's in nodelist */
  17. #define HSDIR_EXIST_ID "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" \
  18. "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
  19. #define STR_HSDIR_EXIST_LONGNAME \
  20. "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=TestDir"
  21. /* mock ID digest and longname for node that's not in nodelist */
  22. #define HSDIR_NONE_EXIST_ID "\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB" \
  23. "\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB"
  24. #define STR_HSDIR_NONE_EXIST_LONGNAME \
  25. "$BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"
  26. /* DuckDuckGo descriptor as an example. */
  27. static const char *hs_desc_content = "\
  28. rendezvous-service-descriptor g5ojobzupf275beh5ra72uyhb3dkpxwg\r\n\
  29. version 2\r\n\
  30. permanent-key\r\n\
  31. -----BEGIN RSA PUBLIC KEY-----\r\n\
  32. MIGJAoGBAJ/SzzgrXPxTlFrKVhXh3buCWv2QfcNgncUpDpKouLn3AtPH5Ocys0jE\r\n\
  33. aZSKdvaiQ62md2gOwj4x61cFNdi05tdQjS+2thHKEm/KsB9BGLSLBNJYY356bupg\r\n\
  34. I5gQozM65ENelfxYlysBjJ52xSDBd8C4f/p9umdzaaaCmzXG/nhzAgMBAAE=\r\n\
  35. -----END RSA PUBLIC KEY-----\r\n\
  36. secret-id-part anmjoxxwiupreyajjt5yasimfmwcnxlf\r\n\
  37. publication-time 2015-03-11 19:00:00\r\n\
  38. protocol-versions 2,3\r\n\
  39. introduction-points\r\n\
  40. -----BEGIN MESSAGE-----\r\n\
  41. aW50cm9kdWN0aW9uLXBvaW50IDd1bnd4cmg2dG5kNGh6eWt1Z3EzaGZzdHduc2ll\r\n\
  42. cmhyCmlwLWFkZHJlc3MgMTg4LjEzOC4xMjEuMTE4Cm9uaW9uLXBvcnQgOTAwMQpv\r\n\
  43. bmlvbi1rZXkKLS0tLS1CRUdJTiBSU0EgUFVCTElDIEtFWS0tLS0tCk1JR0pBb0dC\r\n\
  44. QUxGRVVyeVpDbk9ROEhURmV5cDVjMTRObWVqL1BhekFLTTBxRENTNElKUWh0Y3g1\r\n\
  45. NXpRSFdOVWIKQ2hHZ0JqR1RjV3ZGRnA0N3FkdGF6WUZhVXE2c0lQKzVqeWZ5b0Q4\r\n\
  46. UmJ1bzBwQmFWclJjMmNhYUptWWM0RDh6Vgpuby9sZnhzOVVaQnZ1cWY4eHIrMDB2\r\n\
  47. S0JJNmFSMlA2OE1WeDhrMExqcUpUU2RKOE9idm9yQWdNQkFBRT0KLS0tLS1FTkQg\r\n\
  48. UlNBIFBVQkxJQyBLRVktLS0tLQpzZXJ2aWNlLWtleQotLS0tLUJFR0lOIFJTQSBQ\r\n\
  49. VUJMSUMgS0VZLS0tLS0KTUlHSkFvR0JBTnJHb0ozeTlHNXQzN2F2ekI1cTlwN1hG\r\n\
  50. VUplRUVYMUNOaExnWmJXWGJhVk5OcXpoZFhyL0xTUQppM1Z6dW5OaUs3cndUVnE2\r\n\
  51. K2QyZ1lRckhMMmIvMXBBY3ZKWjJiNSs0bTRRc0NibFpjRENXTktRbHJnRWN5WXRJ\r\n\
  52. CkdscXJTbFFEaXA0ZnNrUFMvNDVkWTI0QmJsQ3NGU1k3RzVLVkxJck4zZFpGbmJr\r\n\
  53. NEZIS1hBZ01CQUFFPQotLS0tLUVORCBSU0EgUFVCTElDIEtFWS0tLS0tCmludHJv\r\n\
  54. ZHVjdGlvbi1wb2ludCBiNGM3enlxNXNheGZzN2prNXFibG1wN3I1b3pwdHRvagpp\r\n\
  55. cC1hZGRyZXNzIDEwOS4xNjkuNDUuMjI2Cm9uaW9uLXBvcnQgOTAwMQpvbmlvbi1r\r\n\
  56. ZXkKLS0tLS1CRUdJTiBSU0EgUFVCTElDIEtFWS0tLS0tCk1JR0pBb0dCQU8xSXpw\r\n\
  57. WFFUTUY3RXZUb1NEUXpzVnZiRVFRQUQrcGZ6NzczMVRXZzVaUEJZY1EyUkRaeVp4\r\n\
  58. OEQKNUVQSU1FeUE1RE83cGd0ak5LaXJvYXJGMC8yempjMkRXTUlSaXZyU29YUWVZ\r\n\
  59. ZXlMM1pzKzFIajJhMDlCdkYxZAp6MEswblRFdVhoNVR5V3lyMHdsbGI1SFBnTlI0\r\n\
  60. MS9oYkprZzkwZitPVCtIeGhKL1duUml2QWdNQkFBRT0KLS0tLS1FTkQgUlNBIFBV\r\n\
  61. QkxJQyBLRVktLS0tLQpzZXJ2aWNlLWtleQotLS0tLUJFR0lOIFJTQSBQVUJMSUMg\r\n\
  62. S0VZLS0tLS0KTUlHSkFvR0JBSzNWZEJ2ajFtQllLL3JrcHNwcm9Ub0llNUtHVmth\r\n\
  63. QkxvMW1tK1I2YUVJek1VZFE1SjkwNGtyRwpCd3k5NC8rV0lGNFpGYXh5Z2phejl1\r\n\
  64. N2pKY1k3ZGJhd1pFeG1hYXFCRlRwL2h2ZG9rcHQ4a1ByRVk4OTJPRHJ1CmJORUox\r\n\
  65. N1FPSmVMTVZZZk5Kcjl4TWZCQ3JQai8zOGh2RUdrbWVRNmRVWElvbVFNaUJGOVRB\r\n\
  66. Z01CQUFFPQotLS0tLUVORCBSU0EgUFVCTElDIEtFWS0tLS0tCmludHJvZHVjdGlv\r\n\
  67. bi1wb2ludCBhdjVtcWl0Y2Q3cjJkandsYmN0c2Jlc2R3eGt0ZWtvegppcC1hZGRy\r\n\
  68. ZXNzIDE0NC43Ni44LjczCm9uaW9uLXBvcnQgNDQzCm9uaW9uLWtleQotLS0tLUJF\r\n\
  69. R0lOIFJTQSBQVUJMSUMgS0VZLS0tLS0KTUlHSkFvR0JBTzVweVZzQmpZQmNmMXBE\r\n\
  70. dklHUlpmWXUzQ05nNldka0ZLMGlvdTBXTGZtejZRVDN0NWhzd3cyVwpjejlHMXhx\r\n\
  71. MmN0Nkd6VWkrNnVkTDlITTRVOUdHTi9BbW8wRG9GV1hKWHpBQkFXd2YyMVdsd1lW\r\n\
  72. eFJQMHRydi9WCkN6UDkzcHc5OG5vSmdGUGRUZ05iMjdKYmVUZENLVFBrTEtscXFt\r\n\
  73. b3NveUN2RitRa25vUS9BZ01CQUFFPQotLS0tLUVORCBSU0EgUFVCTElDIEtFWS0t\r\n\
  74. LS0tCnNlcnZpY2Uta2V5Ci0tLS0tQkVHSU4gUlNBIFBVQkxJQyBLRVktLS0tLQpN\r\n\
  75. SUdKQW9HQkFMVjNKSmtWN3lTNU9jc1lHMHNFYzFQOTVRclFRR3ZzbGJ6Wi9zRGxl\r\n\
  76. RlpKYXFSOUYvYjRUVERNClNGcFMxcU1GbldkZDgxVmRGMEdYRmN2WVpLamRJdHU2\r\n\
  77. SndBaTRJeEhxeXZtdTRKdUxrcXNaTEFLaXRLVkx4eGsKeERlMjlDNzRWMmJrOTRJ\r\n\
  78. MEgybTNKS2tzTHVwc3VxWWRVUmhOVXN0SElKZmgyZmNIalF0bEFnTUJBQUU9Ci0t\r\n\
  79. LS0tRU5EIFJTQSBQVUJMSUMgS0VZLS0tLS0KCg==\r\n\
  80. -----END MESSAGE-----\r\n\
  81. signature\r\n\
  82. -----BEGIN SIGNATURE-----\r\n\
  83. d4OuCE5OLAOnRB6cQN6WyMEmg/BHem144Vec+eYgeWoKwx3MxXFplUjFxgnMlmwN\r\n\
  84. PcftsZf2ztN0sbNCtPgDL3d0PqvxY3iHTQAI8EbaGq/IAJUZ8U4y963dD5+Bn6JQ\r\n\
  85. myE3ctmh0vy5+QxSiRjmQBkuEpCyks7LvWvHYrhnmcg=\r\n\
  86. -----END SIGNATURE-----";
  87. /* Helper global variable for hidden service descriptor event test.
  88. * It's used as a pointer to dynamically created message buffer in
  89. * send_control_event_string_replacement function, which mocks
  90. * send_control_event_string function.
  91. *
  92. * Always free it after use! */
  93. static char *received_msg = NULL;
  94. /** Mock function for send_control_event_string
  95. */
  96. static void
  97. send_control_event_string_replacement(uint16_t event, event_format_t which,
  98. const char *msg)
  99. {
  100. (void) event;
  101. (void) which;
  102. tor_free(received_msg);
  103. received_msg = tor_strdup(msg);
  104. }
  105. /** Mock function for node_describe_longname_by_id, it returns either
  106. * STR_HSDIR_EXIST_LONGNAME or STR_HSDIR_NONE_EXIST_LONGNAME
  107. */
  108. static const char *
  109. node_describe_longname_by_id_replacement(const char *id_digest)
  110. {
  111. if (!strcmp(id_digest, HSDIR_EXIST_ID)) {
  112. return STR_HSDIR_EXIST_LONGNAME;
  113. } else {
  114. return STR_HSDIR_NONE_EXIST_LONGNAME;
  115. }
  116. }
  117. /** Make sure each hidden service descriptor async event generation
  118. *
  119. * function generates the message in expected format.
  120. */
  121. static void
  122. test_hs_desc_event(void *arg)
  123. {
  124. #define STR_HS_ADDR "ajhb7kljbiru65qo"
  125. #define STR_HS_ID "b3oeducbhjmbqmgw2i3jtz4fekkrinwj"
  126. #define STR_DESC_ID "g5ojobzupf275beh5ra72uyhb3dkpxwg"
  127. rend_data_t rend_query;
  128. const char *expected_msg;
  129. (void) arg;
  130. MOCK(send_control_event_string,
  131. send_control_event_string_replacement);
  132. MOCK(node_describe_longname_by_id,
  133. node_describe_longname_by_id_replacement);
  134. /* setup rend_query struct */
  135. strncpy(rend_query.onion_address, STR_HS_ADDR,
  136. REND_SERVICE_ID_LEN_BASE32+1);
  137. rend_query.auth_type = 0;
  138. /* test request event */
  139. control_event_hs_descriptor_requested(&rend_query, HSDIR_EXIST_ID,
  140. STR_HS_ID);
  141. expected_msg = "650 HS_DESC REQUESTED "STR_HS_ADDR" NO_AUTH "\
  142. STR_HSDIR_EXIST_LONGNAME" "STR_HS_ID"\r\n";
  143. tt_assert(received_msg);
  144. tt_str_op(received_msg,OP_EQ, expected_msg);
  145. tor_free(received_msg);
  146. /* test received event */
  147. rend_query.auth_type = 1;
  148. control_event_hs_descriptor_received(rend_query.onion_address,
  149. rend_query.auth_type, HSDIR_EXIST_ID);
  150. expected_msg = "650 HS_DESC RECEIVED "STR_HS_ADDR" BASIC_AUTH "\
  151. STR_HSDIR_EXIST_LONGNAME"\r\n";
  152. tt_assert(received_msg);
  153. tt_str_op(received_msg,OP_EQ, expected_msg);
  154. tor_free(received_msg);
  155. /* test failed event */
  156. rend_query.auth_type = 2;
  157. control_event_hs_descriptor_failed(rend_query.onion_address,
  158. rend_query.auth_type, HSDIR_NONE_EXIST_ID,
  159. "QUERY_REJECTED");
  160. expected_msg = "650 HS_DESC FAILED "STR_HS_ADDR" STEALTH_AUTH "\
  161. STR_HSDIR_NONE_EXIST_LONGNAME" REASON=QUERY_REJECTED\r\n";
  162. tt_assert(received_msg);
  163. tt_str_op(received_msg,OP_EQ, expected_msg);
  164. tor_free(received_msg);
  165. /* test invalid auth type */
  166. rend_query.auth_type = 999;
  167. control_event_hs_descriptor_failed(rend_query.onion_address,
  168. rend_query.auth_type, HSDIR_EXIST_ID,
  169. "QUERY_REJECTED");
  170. expected_msg = "650 HS_DESC FAILED "STR_HS_ADDR" UNKNOWN "\
  171. STR_HSDIR_EXIST_LONGNAME" REASON=QUERY_REJECTED\r\n";
  172. tt_assert(received_msg);
  173. tt_str_op(received_msg,OP_EQ, expected_msg);
  174. tor_free(received_msg);
  175. /* test valid content. */
  176. char *exp_msg;
  177. control_event_hs_descriptor_content(rend_query.onion_address, STR_DESC_ID,
  178. HSDIR_EXIST_ID, hs_desc_content);
  179. tor_asprintf(&exp_msg, "650+HS_DESC_CONTENT " STR_HS_ADDR " " STR_DESC_ID \
  180. " " STR_HSDIR_EXIST_LONGNAME "\r\n%s\r\n.\r\n650 OK\r\n",
  181. hs_desc_content);
  182. tt_assert(received_msg);
  183. tt_str_op(received_msg, OP_EQ, exp_msg);
  184. tor_free(received_msg);
  185. tor_free(exp_msg);
  186. done:
  187. UNMOCK(send_control_event_string);
  188. UNMOCK(node_describe_longname_by_id);
  189. tor_free(received_msg);
  190. }
  191. /* Make sure we always pick the right RP, given a well formatted
  192. * Tor2webRendezvousPoints value. */
  193. static void
  194. test_pick_tor2web_rendezvous_node(void *arg)
  195. {
  196. or_options_t *options = get_options_mutable();
  197. const node_t *chosen_rp = NULL;
  198. router_crn_flags_t flags = CRN_NEED_DESC;
  199. int retval, i;
  200. const char *tor2web_rendezvous_str = "test003r";
  201. (void) arg;
  202. /* Setup fake routerlist. */
  203. helper_setup_fake_routerlist();
  204. /* Parse Tor2webRendezvousPoints as a routerset. */
  205. options->Tor2webRendezvousPoints = routerset_new();
  206. retval = routerset_parse(options->Tor2webRendezvousPoints,
  207. tor2web_rendezvous_str,
  208. "test_tor2web_rp");
  209. tt_int_op(retval, >=, 0);
  210. /* Pick rendezvous point. Make sure the correct one is
  211. picked. Repeat many times to make sure it works properly. */
  212. for (i = 0; i < 50 ; i++) {
  213. chosen_rp = pick_tor2web_rendezvous_node(flags, options);
  214. tt_assert(chosen_rp);
  215. tt_str_op(chosen_rp->ri->nickname, ==, tor2web_rendezvous_str);
  216. }
  217. done:
  218. routerset_free(options->Tor2webRendezvousPoints);
  219. }
  220. /* Make sure we never pick an RP if Tor2webRendezvousPoints doesn't
  221. * correspond to an actual node. */
  222. static void
  223. test_pick_bad_tor2web_rendezvous_node(void *arg)
  224. {
  225. or_options_t *options = get_options_mutable();
  226. const node_t *chosen_rp = NULL;
  227. router_crn_flags_t flags = CRN_NEED_DESC;
  228. int retval, i;
  229. const char *tor2web_rendezvous_str = "dummy";
  230. (void) arg;
  231. /* Setup fake routerlist. */
  232. helper_setup_fake_routerlist();
  233. /* Parse Tor2webRendezvousPoints as a routerset. */
  234. options->Tor2webRendezvousPoints = routerset_new();
  235. retval = routerset_parse(options->Tor2webRendezvousPoints,
  236. tor2web_rendezvous_str,
  237. "test_tor2web_rp");
  238. tt_int_op(retval, >=, 0);
  239. /* Pick rendezvous point. Since Tor2webRendezvousPoints was set to a
  240. dummy value, we shouldn't find any eligible RPs. */
  241. for (i = 0; i < 50 ; i++) {
  242. chosen_rp = pick_tor2web_rendezvous_node(flags, options);
  243. tt_assert(!chosen_rp);
  244. }
  245. done:
  246. routerset_free(options->Tor2webRendezvousPoints);
  247. }
  248. struct testcase_t hs_tests[] = {
  249. { "hs_desc_event", test_hs_desc_event, TT_FORK,
  250. NULL, NULL },
  251. { "pick_tor2web_rendezvous_node", test_pick_tor2web_rendezvous_node, TT_FORK,
  252. NULL, NULL },
  253. { "pick_bad_tor2web_rendezvous_node",
  254. test_pick_bad_tor2web_rendezvous_node, TT_FORK,
  255. NULL, NULL },
  256. END_OF_TESTCASES
  257. };