hs_common.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363
  1. /* Copyright (c) 2016-2017, The Tor Project, Inc. */
  2. /* See LICENSE for licensing information */
  3. /**
  4. * \file hs_common.c
  5. * \brief Contains code shared between different HS protocol version as well
  6. * as useful data structures and accessors used by other subsystems.
  7. * The rendcommon.c should only contains code relating to the v2
  8. * protocol.
  9. **/
  10. #define HS_COMMON_PRIVATE
  11. #include "or.h"
  12. #include "config.h"
  13. #include "networkstatus.h"
  14. #include "hs_common.h"
  15. #include "rendcommon.h"
  16. /* Make sure that the directory for <b>service</b> is private, using the config
  17. * <b>username</b>.
  18. * If <b>create</b> is true:
  19. * - if the directory exists, change permissions if needed,
  20. * - if the directory does not exist, create it with the correct permissions.
  21. * If <b>create</b> is false:
  22. * - if the directory exists, check permissions,
  23. * - if the directory does not exist, check if we think we can create it.
  24. * Return 0 on success, -1 on failure. */
  25. int
  26. hs_check_service_private_dir(const char *username, const char *path,
  27. unsigned int dir_group_readable,
  28. unsigned int create)
  29. {
  30. cpd_check_t check_opts = CPD_NONE;
  31. tor_assert(path);
  32. if (create) {
  33. check_opts |= CPD_CREATE;
  34. } else {
  35. check_opts |= CPD_CHECK_MODE_ONLY;
  36. check_opts |= CPD_CHECK;
  37. }
  38. if (dir_group_readable) {
  39. check_opts |= CPD_GROUP_READ;
  40. }
  41. /* Check/create directory */
  42. if (check_private_dir(path, check_opts, username) < 0) {
  43. return -1;
  44. }
  45. return 0;
  46. }
  47. /** Get the default HS time period length in minutes from the consensus. */
  48. STATIC uint64_t
  49. get_time_period_length(void)
  50. {
  51. int32_t time_period_length = networkstatus_get_param(NULL, "hsdir_interval",
  52. HS_TIME_PERIOD_LENGTH_DEFAULT,
  53. HS_TIME_PERIOD_LENGTH_MIN,
  54. HS_TIME_PERIOD_LENGTH_MAX);
  55. /* Make sure it's a positive value. */
  56. tor_assert(time_period_length >= 0);
  57. /* uint64_t will always be able to contain a int32_t */
  58. return (uint64_t) time_period_length;
  59. }
  60. /** Get the HS time period number at time <b>now</b> */
  61. STATIC uint64_t
  62. get_time_period_num(time_t now)
  63. {
  64. uint64_t time_period_num;
  65. uint64_t time_period_length = get_time_period_length();
  66. uint64_t minutes_since_epoch = now / 60;
  67. /* Now subtract half a day to fit the prop224 time period schedule (see
  68. * section [TIME-PERIODS]). */
  69. tor_assert(minutes_since_epoch > HS_TIME_PERIOD_ROTATION_OFFSET);
  70. minutes_since_epoch -= HS_TIME_PERIOD_ROTATION_OFFSET;
  71. /* Calculate the time period */
  72. time_period_num = minutes_since_epoch / time_period_length;
  73. return time_period_num;
  74. }
  75. /** Get the number of the _upcoming_ HS time period, given that the current
  76. * time is <b>now</b>. */
  77. uint64_t
  78. hs_get_next_time_period_num(time_t now)
  79. {
  80. return get_time_period_num(now) + 1;
  81. }
  82. /* Create a new rend_data_t for a specific given <b>version</b>.
  83. * Return a pointer to the newly allocated data structure. */
  84. static rend_data_t *
  85. rend_data_alloc(uint32_t version)
  86. {
  87. rend_data_t *rend_data = NULL;
  88. switch (version) {
  89. case HS_VERSION_TWO:
  90. {
  91. rend_data_v2_t *v2 = tor_malloc_zero(sizeof(*v2));
  92. v2->base_.version = HS_VERSION_TWO;
  93. v2->base_.hsdirs_fp = smartlist_new();
  94. rend_data = &v2->base_;
  95. break;
  96. }
  97. default:
  98. tor_assert(0);
  99. break;
  100. }
  101. return rend_data;
  102. }
  103. /** Free all storage associated with <b>data</b> */
  104. void
  105. rend_data_free(rend_data_t *data)
  106. {
  107. if (!data) {
  108. return;
  109. }
  110. /* By using our allocation function, this should always be set. */
  111. tor_assert(data->hsdirs_fp);
  112. /* Cleanup the HSDir identity digest. */
  113. SMARTLIST_FOREACH(data->hsdirs_fp, char *, d, tor_free(d));
  114. smartlist_free(data->hsdirs_fp);
  115. /* Depending on the version, cleanup. */
  116. switch (data->version) {
  117. case HS_VERSION_TWO:
  118. {
  119. rend_data_v2_t *v2_data = TO_REND_DATA_V2(data);
  120. tor_free(v2_data);
  121. break;
  122. }
  123. default:
  124. tor_assert(0);
  125. }
  126. }
  127. /* Allocate and return a deep copy of <b>data</b>. */
  128. rend_data_t *
  129. rend_data_dup(const rend_data_t *data)
  130. {
  131. rend_data_t *data_dup = NULL;
  132. smartlist_t *hsdirs_fp = smartlist_new();
  133. tor_assert(data);
  134. tor_assert(data->hsdirs_fp);
  135. SMARTLIST_FOREACH(data->hsdirs_fp, char *, fp,
  136. smartlist_add(hsdirs_fp, tor_memdup(fp, DIGEST_LEN)));
  137. switch (data->version) {
  138. case HS_VERSION_TWO:
  139. {
  140. rend_data_v2_t *v2_data = tor_memdup(TO_REND_DATA_V2(data),
  141. sizeof(*v2_data));
  142. data_dup = &v2_data->base_;
  143. data_dup->hsdirs_fp = hsdirs_fp;
  144. break;
  145. }
  146. default:
  147. tor_assert(0);
  148. break;
  149. }
  150. return data_dup;
  151. }
  152. /* Compute the descriptor ID for each HS descriptor replica and save them. A
  153. * valid onion address must be present in the <b>rend_data</b>.
  154. *
  155. * Return 0 on success else -1. */
  156. static int
  157. compute_desc_id(rend_data_t *rend_data)
  158. {
  159. int ret = 0;
  160. unsigned replica;
  161. time_t now = time(NULL);
  162. tor_assert(rend_data);
  163. switch (rend_data->version) {
  164. case HS_VERSION_TWO:
  165. {
  166. rend_data_v2_t *v2_data = TO_REND_DATA_V2(rend_data);
  167. /* Compute descriptor ID for each replicas. */
  168. for (replica = 0; replica < ARRAY_LENGTH(v2_data->descriptor_id);
  169. replica++) {
  170. ret = rend_compute_v2_desc_id(v2_data->descriptor_id[replica],
  171. v2_data->onion_address,
  172. v2_data->descriptor_cookie,
  173. now, replica);
  174. if (ret < 0) {
  175. goto end;
  176. }
  177. }
  178. break;
  179. }
  180. default:
  181. tor_assert(0);
  182. }
  183. end:
  184. return ret;
  185. }
  186. /* Allocate and initialize a rend_data_t object for a service using the
  187. * provided arguments. All arguments are optional (can be NULL), except from
  188. * <b>onion_address</b> which MUST be set. The <b>pk_digest</b> is the hash of
  189. * the service private key. The <b>cookie</b> is the rendezvous cookie and
  190. * <b>auth_type</b> is which authentiation this service is configured with.
  191. *
  192. * Return a valid rend_data_t pointer. This only returns a version 2 object of
  193. * rend_data_t. */
  194. rend_data_t *
  195. rend_data_service_create(const char *onion_address, const char *pk_digest,
  196. const uint8_t *cookie, rend_auth_type_t auth_type)
  197. {
  198. /* Create a rend_data_t object for version 2. */
  199. rend_data_t *rend_data = rend_data_alloc(HS_VERSION_TWO);
  200. rend_data_v2_t *v2= TO_REND_DATA_V2(rend_data);
  201. /* We need at least one else the call is wrong. */
  202. tor_assert(onion_address != NULL);
  203. if (pk_digest) {
  204. memcpy(v2->rend_pk_digest, pk_digest, sizeof(v2->rend_pk_digest));
  205. }
  206. if (cookie) {
  207. memcpy(rend_data->rend_cookie, cookie, sizeof(rend_data->rend_cookie));
  208. }
  209. strlcpy(v2->onion_address, onion_address, sizeof(v2->onion_address));
  210. v2->auth_type = auth_type;
  211. return rend_data;
  212. }
  213. /* Allocate and initialize a rend_data_t object for a client request using the
  214. * given arguments. Either an onion address or a descriptor ID is needed. Both
  215. * can be given but in this case only the onion address will be used to make
  216. * the descriptor fetch. The <b>cookie</b> is the rendezvous cookie and
  217. * <b>auth_type</b> is which authentiation the service is configured with.
  218. *
  219. * Return a valid rend_data_t pointer or NULL on error meaning the
  220. * descriptor IDs couldn't be computed from the given data. */
  221. rend_data_t *
  222. rend_data_client_create(const char *onion_address, const char *desc_id,
  223. const char *cookie, rend_auth_type_t auth_type)
  224. {
  225. /* Create a rend_data_t object for version 2. */
  226. rend_data_t *rend_data = rend_data_alloc(HS_VERSION_TWO);
  227. rend_data_v2_t *v2= TO_REND_DATA_V2(rend_data);
  228. /* We need at least one else the call is wrong. */
  229. tor_assert(onion_address != NULL || desc_id != NULL);
  230. if (cookie) {
  231. memcpy(v2->descriptor_cookie, cookie, sizeof(v2->descriptor_cookie));
  232. }
  233. if (desc_id) {
  234. memcpy(v2->desc_id_fetch, desc_id, sizeof(v2->desc_id_fetch));
  235. }
  236. if (onion_address) {
  237. strlcpy(v2->onion_address, onion_address, sizeof(v2->onion_address));
  238. if (compute_desc_id(rend_data) < 0) {
  239. goto error;
  240. }
  241. }
  242. v2->auth_type = auth_type;
  243. return rend_data;
  244. error:
  245. rend_data_free(rend_data);
  246. return NULL;
  247. }
  248. /* Return the onion address from the rend data. Depending on the version,
  249. * the size of the address can vary but it's always NUL terminated. */
  250. const char *
  251. rend_data_get_address(const rend_data_t *rend_data)
  252. {
  253. tor_assert(rend_data);
  254. switch (rend_data->version) {
  255. case HS_VERSION_TWO:
  256. return TO_REND_DATA_V2(rend_data)->onion_address;
  257. default:
  258. /* We should always have a supported version. */
  259. tor_assert(0);
  260. }
  261. }
  262. /* Return the descriptor ID for a specific replica number from the rend
  263. * data. The returned data is a binary digest and depending on the version its
  264. * size can vary. The size of the descriptor ID is put in <b>len_out</b> if
  265. * non NULL. */
  266. const char *
  267. rend_data_get_desc_id(const rend_data_t *rend_data, uint8_t replica,
  268. size_t *len_out)
  269. {
  270. tor_assert(rend_data);
  271. switch (rend_data->version) {
  272. case HS_VERSION_TWO:
  273. tor_assert(replica < REND_NUMBER_OF_NON_CONSECUTIVE_REPLICAS);
  274. if (len_out) {
  275. *len_out = DIGEST_LEN;
  276. }
  277. return TO_REND_DATA_V2(rend_data)->descriptor_id[replica];
  278. default:
  279. /* We should always have a supported version. */
  280. tor_assert(0);
  281. }
  282. }
  283. /* Return the public key digest using the given <b>rend_data</b>. The size of
  284. * the digest is put in <b>len_out</b> (if set) which can differ depending on
  285. * the version. */
  286. const uint8_t *
  287. rend_data_get_pk_digest(const rend_data_t *rend_data, size_t *len_out)
  288. {
  289. tor_assert(rend_data);
  290. switch (rend_data->version) {
  291. case HS_VERSION_TWO:
  292. {
  293. const rend_data_v2_t *v2_data = TO_REND_DATA_V2(rend_data);
  294. if (len_out) {
  295. *len_out = sizeof(v2_data->rend_pk_digest);
  296. }
  297. return (const uint8_t *) v2_data->rend_pk_digest;
  298. }
  299. default:
  300. /* We should always have a supported version. */
  301. tor_assert(0);
  302. }
  303. }
  304. /* Default, minimum and maximum values for the maximum rendezvous failures
  305. * consensus parameter. */
  306. #define MAX_REND_FAILURES_DEFAULT 2
  307. #define MAX_REND_FAILURES_MIN 1
  308. #define MAX_REND_FAILURES_MAX 10
  309. /** How many times will a hidden service operator attempt to connect to
  310. * a requested rendezvous point before giving up? */
  311. int
  312. hs_get_service_max_rend_failures(void)
  313. {
  314. return networkstatus_get_param(NULL, "hs_service_max_rdv_failures",
  315. MAX_REND_FAILURES_DEFAULT,
  316. MAX_REND_FAILURES_MIN,
  317. MAX_REND_FAILURES_MAX);
  318. }