rendservice.c 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994
  1. /* Copyright 2004 Roger Dingledine, Nick Mathewson. */
  2. /* See LICENSE for licensing information */
  3. /* $Id$ */
  4. /**
  5. * \file rendservice.c
  6. * \brief The hidden-service side of rendezvous functionality.
  7. **/
  8. #include "or.h"
  9. static circuit_t *find_intro_circuit(routerinfo_t *router, const char *pk_digest);
  10. /** Represents the mapping from a virtual port of a rendezvous service to
  11. * a real port on some IP.
  12. */
  13. typedef struct rend_service_port_config_t {
  14. uint16_t virtual_port;
  15. uint16_t real_port;
  16. uint32_t real_address;
  17. } rend_service_port_config_t;
  18. /** Try to maintain this many intro points per service if possible. */
  19. #define NUM_INTRO_POINTS 3
  20. /** If we can't build our intro circuits, don't retry for this long. */
  21. #define INTRO_CIRC_RETRY_PERIOD 60*5
  22. /** Don't try to build more than this many circuits before giving up
  23. * for a while.*/
  24. #define MAX_INTRO_CIRCS_PER_PERIOD 10
  25. /** How many times will a hidden service operator attempt to connect to
  26. * a requested rendezvous point before giving up? */
  27. #define MAX_REND_FAILURES 3
  28. /** Represents a single hidden service running at this OP. */
  29. typedef struct rend_service_t {
  30. /** Fields specified in config file */
  31. char *directory; /**< where in the filesystem it stores it */
  32. smartlist_t *ports; /**< List of rend_service_port_config_t */
  33. char *intro_prefer_nodes; /**< comma-separated list of nicknames */
  34. char *intro_exclude_nodes; /**< comma-separated list of nicknames */
  35. /* Other fields */
  36. crypto_pk_env_t *private_key;
  37. char service_id[REND_SERVICE_ID_LEN+1];
  38. char pk_digest[DIGEST_LEN];
  39. smartlist_t *intro_nodes; /**< list of hexdigests for intro points we have,
  40. * or are trying to establish. */
  41. time_t intro_period_started;
  42. int n_intro_circuits_launched; /**< count of intro circuits we have
  43. * established in this period. */
  44. rend_service_descriptor_t *desc;
  45. int desc_is_dirty;
  46. time_t next_upload_time;
  47. } rend_service_t;
  48. /** A list of rend_service_t's for services run on this OP.
  49. */
  50. static smartlist_t *rend_service_list = NULL;
  51. /** Release the storage held by <b>service</b>.
  52. */
  53. static void rend_service_free(rend_service_t *service)
  54. {
  55. if (!service) return;
  56. tor_free(service->directory);
  57. SMARTLIST_FOREACH(service->ports, void*, p, tor_free(p));
  58. smartlist_free(service->ports);
  59. if (service->private_key)
  60. crypto_free_pk_env(service->private_key);
  61. tor_free(service->intro_prefer_nodes);
  62. tor_free(service->intro_exclude_nodes);
  63. SMARTLIST_FOREACH(service->intro_nodes, void*, p, tor_free(p));
  64. smartlist_free(service->intro_nodes);
  65. if (service->desc)
  66. rend_service_descriptor_free(service->desc);
  67. tor_free(service);
  68. }
  69. /** Release all the storage held in rend_service_list, and allocate a new,
  70. * empty rend_service_list.
  71. */
  72. static void rend_service_free_all(void)
  73. {
  74. if (!rend_service_list) {
  75. rend_service_list = smartlist_create();
  76. return;
  77. }
  78. SMARTLIST_FOREACH(rend_service_list, rend_service_t*, ptr,
  79. rend_service_free(ptr));
  80. smartlist_free(rend_service_list);
  81. rend_service_list = smartlist_create();
  82. }
  83. /** Validate <b>service</b> and add it to rend_service_list if possible.
  84. */
  85. static void add_service(rend_service_t *service)
  86. {
  87. int i;
  88. rend_service_port_config_t *p;
  89. struct in_addr addr;
  90. if (!service->intro_prefer_nodes)
  91. service->intro_prefer_nodes = tor_strdup("");
  92. if (!service->intro_exclude_nodes)
  93. service->intro_exclude_nodes = tor_strdup("");
  94. if (!smartlist_len(service->ports)) {
  95. log_fn(LOG_WARN, "Hidden service with no ports configured; ignoring.");
  96. rend_service_free(service);
  97. } else {
  98. smartlist_set_capacity(service->ports, -1);
  99. smartlist_add(rend_service_list, service);
  100. log_fn(LOG_DEBUG,"Configuring service with directory %s",service->directory);
  101. for (i = 0; i < smartlist_len(service->ports); ++i) {
  102. p = smartlist_get(service->ports, i);
  103. addr.s_addr = htonl(p->real_address);
  104. log_fn(LOG_DEBUG,"Service maps port %d to %s:%d",
  105. p->virtual_port, inet_ntoa(addr), p->real_port);
  106. }
  107. }
  108. }
  109. /** Parses a real-port to virtual-port mapping and returns a new
  110. * rend_service_port_config_t.
  111. *
  112. * The format is: VirtualPort (IP|RealPort|IP:RealPort)?
  113. *
  114. * IP defaults to 127.0.0.1; RealPort defaults to VirtualPort.
  115. */
  116. static rend_service_port_config_t *parse_port_config(const char *string)
  117. {
  118. int virtport;
  119. int realport;
  120. uint16_t p;
  121. uint32_t addr;
  122. char *endptr;
  123. rend_service_port_config_t *result;
  124. virtport = (int) strtol(string, &endptr, 10);
  125. if (endptr == string) {
  126. log_fn(LOG_WARN, "Missing port in hidden service port configuration");
  127. return NULL;
  128. }
  129. if (virtport < 1 || virtport > 65535) {
  130. log_fn(LOG_WARN, "Port out of range in hidden service port configuration");
  131. return NULL;
  132. }
  133. string = endptr + strspn(endptr, " \t");
  134. if (!*string) {
  135. /* No addr:port part; use default. */
  136. realport = virtport;
  137. addr = 0x7F000001u; /* 127.0.0.1 */
  138. } else if (strchr(string, ':') || strchr(string, '.')) {
  139. if (parse_addr_port(string, NULL, &addr, &p)<0) {
  140. log_fn(LOG_WARN,"Unparseable address in hidden service port configuration");
  141. return NULL;
  142. }
  143. realport = p?p:virtport;
  144. } else {
  145. /* No addr:port, no addr -- must be port. */
  146. realport = strtol(string, &endptr, 10);
  147. if (*endptr) {
  148. log_fn(LOG_WARN, "Unparseable or missing port in hidden service port configuration.");
  149. return NULL;
  150. }
  151. if (realport < 1 || realport > 65535) {
  152. log_fn(LOG_WARN, "Port out of range");
  153. return NULL;
  154. }
  155. addr = 0x7F000001u; /* Default to 127.0.0.1 */
  156. }
  157. result = tor_malloc(sizeof(rend_service_port_config_t));
  158. result->virtual_port = virtport;
  159. result->real_port = realport;
  160. result->real_address = addr;
  161. return result;
  162. }
  163. /** Set up rend_service_list, based on the values of HiddenServiceDir and
  164. * HiddenServicePort in <b>options</b>. Return 0 on success and -1 on
  165. * failure. (If <b>validate_only</b> is set, parse, warn and return as
  166. * normal, but don't actually change the configured services.)
  167. */
  168. int rend_config_services(or_options_t *options, int validate_only)
  169. {
  170. struct config_line_t *line;
  171. rend_service_t *service = NULL;
  172. rend_service_port_config_t *portcfg;
  173. if (!validate_only)
  174. rend_service_free_all();
  175. for (line = options->RendConfigLines; line; line = line->next) {
  176. if (!strcasecmp(line->key, "HiddenServiceDir")) {
  177. if (service) {
  178. if (validate_only)
  179. rend_service_free(service);
  180. else
  181. add_service(service);
  182. }
  183. service = tor_malloc_zero(sizeof(rend_service_t));
  184. service->directory = tor_strdup(line->value);
  185. service->ports = smartlist_create();
  186. service->intro_nodes = smartlist_create();
  187. service->intro_period_started = time(NULL);
  188. continue;
  189. }
  190. if (!service) {
  191. log_fn(LOG_WARN, "HiddenServicePort with no preceeding HiddenServiceDir directive");
  192. rend_service_free(service);
  193. return -1;
  194. }
  195. if (!strcasecmp(line->key, "HiddenServicePort")) {
  196. portcfg = parse_port_config(line->value);
  197. if (!portcfg) {
  198. rend_service_free(service);
  199. return -1;
  200. }
  201. smartlist_add(service->ports, portcfg);
  202. } else if (!strcasecmp(line->key, "HiddenServiceNodes")) {
  203. if (service->intro_prefer_nodes) {
  204. log_fn(LOG_WARN, "Got multiple HiddenServiceNodes lines for a single service");
  205. return -1;
  206. }
  207. service->intro_prefer_nodes = tor_strdup(line->value);
  208. } else {
  209. tor_assert(!strcasecmp(line->key, "HiddenServiceExcludeNodes"));
  210. if (service->intro_exclude_nodes) {
  211. log_fn(LOG_WARN, "Got multiple HiddenServiceExcludedNodes lines for a single service");
  212. return -1;
  213. }
  214. service->intro_exclude_nodes = tor_strdup(line->value);
  215. }
  216. }
  217. if (service) {
  218. if (validate_only)
  219. rend_service_free(service);
  220. else
  221. add_service(service);
  222. }
  223. return 0;
  224. }
  225. /** Replace the old value of <b>service</b>-\>desc with one that reflects
  226. * the other fields in service.
  227. */
  228. static void rend_service_update_descriptor(rend_service_t *service)
  229. {
  230. rend_service_descriptor_t *d;
  231. circuit_t *circ;
  232. int i,n;
  233. routerinfo_t *router;
  234. if (service->desc) {
  235. rend_service_descriptor_free(service->desc);
  236. service->desc = NULL;
  237. }
  238. d = service->desc = tor_malloc(sizeof(rend_service_descriptor_t));
  239. d->pk = crypto_pk_dup_key(service->private_key);
  240. d->timestamp = time(NULL);
  241. n = smartlist_len(service->intro_nodes);
  242. d->n_intro_points = 0;
  243. d->intro_points = tor_malloc(sizeof(char*)*n);
  244. for (i=0; i < n; ++i) {
  245. router = router_get_by_nickname(smartlist_get(service->intro_nodes, i));
  246. if(!router) {
  247. log_fn(LOG_WARN,"Router '%s' not found. Skipping.",
  248. (char*)smartlist_get(service->intro_nodes, i));
  249. continue;
  250. }
  251. circ = find_intro_circuit(router, service->pk_digest);
  252. if (circ && circ->purpose == CIRCUIT_PURPOSE_S_INTRO) {
  253. /* We have an entirely established intro circuit. */
  254. d->intro_points[d->n_intro_points++] = tor_strdup(router->nickname);
  255. }
  256. }
  257. }
  258. /** Load and/or generate private keys for all hidden services. Return 0 on
  259. * success, -1 on failure.
  260. */
  261. int rend_service_load_keys(void)
  262. {
  263. int i;
  264. rend_service_t *s;
  265. char fname[512];
  266. char buf[128];
  267. for (i=0; i < smartlist_len(rend_service_list); ++i) {
  268. s = smartlist_get(rend_service_list,i);
  269. if (s->private_key)
  270. continue;
  271. log_fn(LOG_INFO, "Loading hidden-service keys from '%s'", s->directory);
  272. /* Check/create directory */
  273. if (check_private_dir(s->directory, CPD_CREATE) < 0)
  274. return -1;
  275. /* Load key */
  276. if (strlcpy(fname,s->directory,sizeof(fname)) >= sizeof(fname) ||
  277. strlcat(fname,"/private_key",sizeof(fname)) >= sizeof(fname)) {
  278. log_fn(LOG_WARN, "Directory name too long: '%s'", s->directory);
  279. return -1;
  280. }
  281. s->private_key = init_key_from_file(fname);
  282. if (!s->private_key)
  283. return -1;
  284. /* Create service file */
  285. if (rend_get_service_id(s->private_key, s->service_id)<0) {
  286. log_fn(LOG_WARN, "Couldn't encode service ID");
  287. return -1;
  288. }
  289. if (crypto_pk_get_digest(s->private_key, s->pk_digest)<0) {
  290. log_fn(LOG_WARN, "Couldn't compute hash of public key");
  291. return -1;
  292. }
  293. if (strlcpy(fname,s->directory,sizeof(fname)) >= sizeof(fname) ||
  294. strlcat(fname,"/hostname",sizeof(fname)) >= sizeof(fname)) {
  295. log_fn(LOG_WARN, "Directory name too long: '%s'", s->directory);
  296. return -1;
  297. }
  298. tor_snprintf(buf, sizeof(buf),"%s.onion\n", s->service_id);
  299. if (write_str_to_file(fname,buf,0)<0)
  300. return -1;
  301. }
  302. return 0;
  303. }
  304. /** Return the service whose public key has a digest of <b>digest</b>. Return
  305. * NULL if no such service exists.
  306. */
  307. static rend_service_t *
  308. rend_service_get_by_pk_digest(const char* digest)
  309. {
  310. SMARTLIST_FOREACH(rend_service_list, rend_service_t*, s,
  311. if (!memcmp(s->pk_digest,digest,DIGEST_LEN)) return s);
  312. return NULL;
  313. }
  314. /******
  315. * Handle cells
  316. ******/
  317. /** Respond to an INTRODUCE2 cell by launching a circuit to the chosen
  318. * rendezvous points.
  319. */
  320. int
  321. rend_service_introduce(circuit_t *circuit, const char *request, size_t request_len)
  322. {
  323. char *ptr, *rp_nickname, *r_cookie;
  324. char buf[RELAY_PAYLOAD_SIZE];
  325. char keys[DIGEST_LEN+CPATH_KEY_MATERIAL_LEN]; /* Holds KH, Df, Db, Kf, Kb */
  326. rend_service_t *service;
  327. int r, i;
  328. size_t len, keylen;
  329. crypto_dh_env_t *dh = NULL;
  330. circuit_t *launched = NULL;
  331. crypt_path_t *cpath = NULL;
  332. char serviceid[REND_SERVICE_ID_LEN+1];
  333. char hexcookie[9];
  334. int version;
  335. size_t nickname_field_len;
  336. base32_encode(serviceid, REND_SERVICE_ID_LEN+1,
  337. circuit->rend_pk_digest,10);
  338. log_fn(LOG_INFO, "Received INTRODUCE2 cell for service %s on circ %d",
  339. serviceid, circuit->n_circ_id);
  340. if (circuit->purpose != CIRCUIT_PURPOSE_S_INTRO) {
  341. log_fn(LOG_WARN, "Got an INTRODUCE2 over a non-introduction circuit %d",
  342. circuit->n_circ_id);
  343. return -1;
  344. }
  345. /* min key length plus digest length plus nickname length */
  346. if (request_len < DIGEST_LEN+REND_COOKIE_LEN+(MAX_NICKNAME_LEN+1)+
  347. DH_KEY_LEN+42) {
  348. log_fn(LOG_WARN, "Got a truncated INTRODUCE2 cell on circ %d",
  349. circuit->n_circ_id);
  350. return -1;
  351. }
  352. /* first DIGEST_LEN bytes of request is service pk digest */
  353. service = rend_service_get_by_pk_digest(request);
  354. if (!service) {
  355. log_fn(LOG_WARN, "Got an INTRODUCE2 cell for an unrecognized service %s",
  356. serviceid);
  357. return -1;
  358. }
  359. if (memcmp(circuit->rend_pk_digest, request, DIGEST_LEN)) {
  360. base32_encode(serviceid, REND_SERVICE_ID_LEN+1, request, 10);
  361. log_fn(LOG_WARN, "Got an INTRODUCE2 cell for the wrong service (%s)",
  362. serviceid);
  363. return -1;
  364. }
  365. keylen = crypto_pk_keysize(service->private_key);
  366. if (request_len < keylen+DIGEST_LEN) {
  367. log_fn(LOG_WARN, "PK-encrypted portion of INTRODUCE2 cell was truncated");
  368. return -1;
  369. }
  370. /* Next N bytes is encrypted with service key */
  371. r = crypto_pk_private_hybrid_decrypt(
  372. service->private_key,buf,request+DIGEST_LEN,request_len-DIGEST_LEN,
  373. PK_PKCS1_OAEP_PADDING,1);
  374. if (r<0) {
  375. log_fn(LOG_WARN, "Couldn't decrypt INTRODUCE2 cell");
  376. return -1;
  377. }
  378. len = r;
  379. if (*buf == 1) {
  380. rp_nickname = buf+1;
  381. nickname_field_len = MAX_HEX_NICKNAME_LEN+1;
  382. version = 1;
  383. } else {
  384. nickname_field_len = MAX_NICKNAME_LEN+1;
  385. rp_nickname = buf;
  386. version = 0;
  387. }
  388. /* XXX when 0.0.8.1 and 0.0.9pre3-4 are obsolete, change this to
  389. * reject version != 1. */
  390. ptr=memchr(rp_nickname,0,nickname_field_len);
  391. if (!ptr || ptr == rp_nickname) {
  392. log_fn(LOG_WARN, "Couldn't find a null-padded nickname in INTRODUCE2 cell");
  393. return -1;
  394. }
  395. if ((version == 0 && !is_legal_nickname(rp_nickname)) ||
  396. (version == 1 && !is_legal_nickname_or_hexdigest(rp_nickname))) {
  397. log_fn(LOG_WARN, "Bad nickname in INTRODUCE2 cell.");
  398. return -1;
  399. }
  400. /* Okay, now we know that a nickname is at the start of the buffer. */
  401. ptr = rp_nickname+nickname_field_len;
  402. len -= nickname_field_len;
  403. if (len != REND_COOKIE_LEN+DH_KEY_LEN) {
  404. log_fn(LOG_WARN, "Bad length %u for INTRODUCE2 cell.", (int)len);
  405. return -1;
  406. }
  407. r_cookie = ptr;
  408. base16_encode(hexcookie,9,r_cookie,4);
  409. /* Try DH handshake... */
  410. dh = crypto_dh_new();
  411. if (!dh || crypto_dh_generate_public(dh)<0) {
  412. log_fn(LOG_WARN, "Couldn't build DH state or generate public key");
  413. goto err;
  414. }
  415. if (crypto_dh_compute_secret(dh, ptr+REND_COOKIE_LEN, DH_KEY_LEN, keys,
  416. DIGEST_LEN+CPATH_KEY_MATERIAL_LEN)<0) {
  417. log_fn(LOG_WARN, "Couldn't complete DH handshake");
  418. goto err;
  419. }
  420. /* Launch a circuit to alice's chosen rendezvous point.
  421. */
  422. for(i=0;i<MAX_REND_FAILURES;i++) {
  423. launched = circuit_launch_by_nickname(CIRCUIT_PURPOSE_S_CONNECT_REND, rp_nickname);
  424. if (launched)
  425. break;
  426. }
  427. if(!launched) { /* give up */
  428. log_fn(LOG_WARN,"Giving up launching first hop of circuit to rendezvous point '%s' for service %s",
  429. rp_nickname, serviceid);
  430. goto err;
  431. }
  432. log_fn(LOG_INFO,
  433. "Accepted intro; launching circuit to '%s' (cookie %s) for service %s",
  434. rp_nickname, hexcookie, serviceid);
  435. tor_assert(launched->build_state);
  436. /* Fill in the circuit's state. */
  437. memcpy(launched->rend_pk_digest, circuit->rend_pk_digest,
  438. DIGEST_LEN);
  439. memcpy(launched->rend_cookie, r_cookie, REND_COOKIE_LEN);
  440. strlcpy(launched->rend_query, service->service_id,
  441. sizeof(launched->rend_query));
  442. launched->build_state->pending_final_cpath = cpath =
  443. tor_malloc_zero(sizeof(crypt_path_t));
  444. cpath->handshake_state = dh;
  445. dh = NULL;
  446. if (circuit_init_cpath_crypto(cpath,keys+DIGEST_LEN,1)<0)
  447. goto err;
  448. memcpy(cpath->handshake_digest, keys, DIGEST_LEN);
  449. return 0;
  450. err:
  451. if (dh) crypto_dh_free(dh);
  452. if (launched) circuit_mark_for_close(launched);
  453. return -1;
  454. }
  455. /** Called when we fail building a rendezvous circuit at some point other
  456. * than the last hop: launches a new circuit to the same rendezvous point.
  457. */
  458. void
  459. rend_service_relaunch_rendezvous(circuit_t *oldcirc)
  460. {
  461. circuit_t *newcirc;
  462. cpath_build_state_t *newstate, *oldstate;
  463. tor_assert(oldcirc->purpose == CIRCUIT_PURPOSE_S_CONNECT_REND);
  464. if (!oldcirc->build_state ||
  465. oldcirc->build_state->failure_count > MAX_REND_FAILURES) {
  466. log_fn(LOG_INFO,"Attempt to build circuit to %s for rendezvous has failed too many times; giving up.",
  467. oldcirc->build_state->chosen_exit_name);
  468. return;
  469. }
  470. oldstate = oldcirc->build_state;
  471. tor_assert(oldstate);
  472. if(oldstate->pending_final_cpath == NULL) {
  473. log_fn(LOG_INFO,"Skipping relaunch of circ that failed on its first hop. Initiator will retry.");
  474. return;
  475. }
  476. log_fn(LOG_INFO,"Reattempting rendezvous circuit to %s",
  477. oldstate->chosen_exit_name);
  478. newcirc = circuit_launch_by_nickname(CIRCUIT_PURPOSE_S_CONNECT_REND,
  479. oldstate->chosen_exit_name);
  480. if (!newcirc) {
  481. log_fn(LOG_WARN,"Couldn't relaunch rendezvous circuit to %s",
  482. oldstate->chosen_exit_name);
  483. return;
  484. }
  485. newstate = newcirc->build_state;
  486. tor_assert(newstate);
  487. newstate->failure_count = oldstate->failure_count+1;
  488. newstate->pending_final_cpath = oldstate->pending_final_cpath;
  489. oldstate->pending_final_cpath = NULL;
  490. memcpy(newcirc->rend_query, oldcirc->rend_query, REND_SERVICE_ID_LEN+1);
  491. memcpy(newcirc->rend_pk_digest, oldcirc->rend_pk_digest, DIGEST_LEN);
  492. memcpy(newcirc->rend_cookie, oldcirc->rend_cookie, REND_COOKIE_LEN);
  493. }
  494. /** Launch a circuit to serve as an introduction point for the service
  495. * <b>service</b> at the introduction point <b>nickname</b>
  496. */
  497. static int
  498. rend_service_launch_establish_intro(rend_service_t *service, const char *nickname)
  499. {
  500. circuit_t *launched;
  501. log_fn(LOG_INFO, "Launching circuit to introduction point %s for service %s",
  502. nickname, service->service_id);
  503. ++service->n_intro_circuits_launched;
  504. launched = circuit_launch_by_nickname(CIRCUIT_PURPOSE_S_ESTABLISH_INTRO, nickname);
  505. if (!launched) {
  506. log_fn(LOG_WARN, "Can't launch circuit to establish introduction at '%s'",
  507. nickname);
  508. return -1;
  509. }
  510. strlcpy(launched->rend_query, service->service_id,
  511. sizeof(launched->rend_query));
  512. memcpy(launched->rend_pk_digest, service->pk_digest, DIGEST_LEN);
  513. return 0;
  514. }
  515. /** Called when we're done building a circuit to an introduction point:
  516. * sends a RELAY_ESTABLISH_INTRO cell.
  517. */
  518. void
  519. rend_service_intro_has_opened(circuit_t *circuit)
  520. {
  521. rend_service_t *service;
  522. size_t len;
  523. int r;
  524. char buf[RELAY_PAYLOAD_SIZE];
  525. char auth[DIGEST_LEN + 9];
  526. char serviceid[REND_SERVICE_ID_LEN+1];
  527. tor_assert(circuit->purpose == CIRCUIT_PURPOSE_S_ESTABLISH_INTRO);
  528. tor_assert(CIRCUIT_IS_ORIGIN(circuit));
  529. tor_assert(circuit->cpath);
  530. base32_encode(serviceid, REND_SERVICE_ID_LEN+1,
  531. circuit->rend_pk_digest,10);
  532. service = rend_service_get_by_pk_digest(circuit->rend_pk_digest);
  533. if (!service) {
  534. log_fn(LOG_WARN, "Unrecognized service ID %s on introduction circuit %d",
  535. serviceid, circuit->n_circ_id);
  536. goto err;
  537. }
  538. log_fn(LOG_INFO,
  539. "Established circuit %d as introduction point for service %s",
  540. circuit->n_circ_id, serviceid);
  541. /* Build the payload for a RELAY_ESTABLISH_INTRO cell. */
  542. len = crypto_pk_asn1_encode(service->private_key, buf+2,
  543. RELAY_PAYLOAD_SIZE-2);
  544. set_uint16(buf, htons((uint16_t)len));
  545. len += 2;
  546. memcpy(auth, circuit->cpath->prev->handshake_digest, DIGEST_LEN);
  547. memcpy(auth+DIGEST_LEN, "INTRODUCE", 9);
  548. if (crypto_digest(buf+len, auth, DIGEST_LEN+9))
  549. goto err;
  550. len += 20;
  551. r = crypto_pk_private_sign_digest(service->private_key, buf+len, buf, len);
  552. if (r<0) {
  553. log_fn(LOG_WARN, "Couldn't sign introduction request");
  554. goto err;
  555. }
  556. len += r;
  557. if (connection_edge_send_command(NULL, circuit,RELAY_COMMAND_ESTABLISH_INTRO,
  558. buf, len, circuit->cpath->prev)<0) {
  559. log_fn(LOG_WARN,
  560. "Couldn't send introduction request for service %s on circuit %d",
  561. serviceid, circuit->n_circ_id);
  562. goto err;
  563. }
  564. return;
  565. err:
  566. circuit_mark_for_close(circuit);
  567. }
  568. /** Called when we get an INTRO_ESTABLISHED cell; mark the circuit as a
  569. * live introduction point, and note that the service descriptor is
  570. * now out-of-date.*/
  571. int
  572. rend_service_intro_established(circuit_t *circuit, const char *request, size_t request_len)
  573. {
  574. rend_service_t *service;
  575. if (circuit->purpose != CIRCUIT_PURPOSE_S_ESTABLISH_INTRO) {
  576. log_fn(LOG_WARN, "received INTRO_ESTABLISHED cell on non-intro circuit");
  577. goto err;
  578. }
  579. service = rend_service_get_by_pk_digest(circuit->rend_pk_digest);
  580. if (!service) {
  581. log_fn(LOG_WARN, "Unknown service on introduction circuit %d",
  582. circuit->n_circ_id);
  583. goto err;
  584. }
  585. service->desc_is_dirty = 1;
  586. circuit->purpose = CIRCUIT_PURPOSE_S_INTRO;
  587. return 0;
  588. err:
  589. circuit_mark_for_close(circuit);
  590. return -1;
  591. }
  592. /** Called once a circuit to a rendezvous point is established: sends a
  593. * RELAY_COMMAND_RENDEZVOUS1 cell.
  594. */
  595. void
  596. rend_service_rendezvous_has_opened(circuit_t *circuit)
  597. {
  598. rend_service_t *service;
  599. char buf[RELAY_PAYLOAD_SIZE];
  600. crypt_path_t *hop;
  601. char serviceid[REND_SERVICE_ID_LEN+1];
  602. char hexcookie[9];
  603. tor_assert(circuit->purpose == CIRCUIT_PURPOSE_S_CONNECT_REND);
  604. tor_assert(circuit->cpath);
  605. tor_assert(circuit->build_state);
  606. hop = circuit->build_state->pending_final_cpath;
  607. tor_assert(hop);
  608. base16_encode(hexcookie,9,circuit->rend_cookie,4);
  609. base32_encode(serviceid, REND_SERVICE_ID_LEN+1,
  610. circuit->rend_pk_digest,10);
  611. log_fn(LOG_INFO,
  612. "Done building circuit %d to rendezvous with cookie %s for service %s",
  613. circuit->n_circ_id, hexcookie, serviceid);
  614. service = rend_service_get_by_pk_digest(circuit->rend_pk_digest);
  615. if (!service) {
  616. log_fn(LOG_WARN, "Internal error: unrecognized service ID on introduction circuit");
  617. goto err;
  618. }
  619. /* All we need to do is send a RELAY_RENDEZVOUS1 cell... */
  620. memcpy(buf, circuit->rend_cookie, REND_COOKIE_LEN);
  621. if (crypto_dh_get_public(hop->handshake_state,
  622. buf+REND_COOKIE_LEN, DH_KEY_LEN)<0) {
  623. log_fn(LOG_WARN,"Couldn't get DH public key");
  624. goto err;
  625. }
  626. memcpy(buf+REND_COOKIE_LEN+DH_KEY_LEN, hop->handshake_digest,
  627. DIGEST_LEN);
  628. /* Send the cell */
  629. if (connection_edge_send_command(NULL, circuit, RELAY_COMMAND_RENDEZVOUS1,
  630. buf, REND_COOKIE_LEN+DH_KEY_LEN+DIGEST_LEN,
  631. circuit->cpath->prev)<0) {
  632. log_fn(LOG_WARN, "Couldn't send RENDEZVOUS1 cell");
  633. goto err;
  634. }
  635. crypto_dh_free(hop->handshake_state);
  636. hop->handshake_state = NULL;
  637. /* Append the cpath entry. */
  638. hop->state = CPATH_STATE_OPEN;
  639. /* set the windows to default. these are the windows
  640. * that bob thinks alice has.
  641. */
  642. hop->package_window = CIRCWINDOW_START;
  643. hop->deliver_window = CIRCWINDOW_START;
  644. onion_append_to_cpath(&circuit->cpath, hop);
  645. circuit->build_state->pending_final_cpath = NULL; /* prevent double-free */
  646. /* Change the circuit purpose. */
  647. circuit->purpose = CIRCUIT_PURPOSE_S_REND_JOINED;
  648. return;
  649. err:
  650. circuit_mark_for_close(circuit);
  651. }
  652. /*
  653. * Manage introduction points
  654. */
  655. /** Return the (possibly non-open) introduction circuit ending at
  656. * <b>router</b> for the service whose public key is <b>pk_digest</b>. Return
  657. * NULL if no such service is found.
  658. */
  659. static circuit_t *
  660. find_intro_circuit(routerinfo_t *router, const char *pk_digest)
  661. {
  662. circuit_t *circ = NULL;
  663. tor_assert(router);
  664. while ((circ = circuit_get_next_by_pk_and_purpose(circ,pk_digest,
  665. CIRCUIT_PURPOSE_S_INTRO))) {
  666. tor_assert(circ->cpath);
  667. if (circ->build_state->chosen_exit_name &&
  668. !strcasecmp(circ->build_state->chosen_exit_name, router->nickname)) {
  669. return circ;
  670. }
  671. }
  672. circ = NULL;
  673. while ((circ = circuit_get_next_by_pk_and_purpose(circ,pk_digest,
  674. CIRCUIT_PURPOSE_S_ESTABLISH_INTRO))) {
  675. tor_assert(circ->cpath);
  676. if (circ->build_state->chosen_exit_name &&
  677. !strcasecmp(circ->build_state->chosen_exit_name, router->nickname)) {
  678. return circ;
  679. }
  680. }
  681. return NULL;
  682. }
  683. /** Encode and sign an up-to-date service descriptor for <b>service</b>,
  684. * and upload it to all the dirservers.
  685. */
  686. static void
  687. upload_service_descriptor(rend_service_t *service)
  688. {
  689. char *desc;
  690. size_t desc_len;
  691. /* Update the descriptor. */
  692. rend_service_update_descriptor(service);
  693. if (rend_encode_service_descriptor(service->desc,
  694. service->private_key,
  695. &desc, &desc_len)<0) {
  696. log_fn(LOG_WARN, "Couldn't encode service descriptor; not uploading");
  697. return;
  698. }
  699. /* Post it to the dirservers */
  700. directory_post_to_dirservers(DIR_PURPOSE_UPLOAD_RENDDESC, desc, desc_len);
  701. tor_free(desc);
  702. service->desc_is_dirty = 0;
  703. }
  704. /* XXXX Make this longer once directories remember service descriptors across
  705. * restarts.*/
  706. #define MAX_SERVICE_PUBLICATION_INTERVAL (15*60)
  707. /** For every service, check how many intro points it currently has, and:
  708. * - Pick new intro points as necessary.
  709. * - Launch circuits to any new intro points.
  710. */
  711. void rend_services_introduce(void) {
  712. int i,j,r;
  713. routerinfo_t *router;
  714. rend_service_t *service;
  715. char *intro;
  716. int changed, prev_intro_nodes;
  717. smartlist_t *intro_routers, *exclude_routers;
  718. time_t now;
  719. intro_routers = smartlist_create();
  720. exclude_routers = smartlist_create();
  721. now = time(NULL);
  722. for (i=0; i< smartlist_len(rend_service_list); ++i) {
  723. smartlist_clear(intro_routers);
  724. service = smartlist_get(rend_service_list, i);
  725. tor_assert(service);
  726. changed = 0;
  727. if (now > service->intro_period_started+INTRO_CIRC_RETRY_PERIOD) {
  728. /* One period has elapsed; we can try building circuits again. */
  729. service->intro_period_started = now;
  730. service->n_intro_circuits_launched = 0;
  731. } else if (service->n_intro_circuits_launched >=
  732. MAX_INTRO_CIRCS_PER_PERIOD) {
  733. /* We have failed too many times in this period; wait for the next
  734. * one before we try again. */
  735. continue;
  736. }
  737. /* Find out which introduction points we have in progress for this service. */
  738. for (j=0;j< smartlist_len(service->intro_nodes); ++j) {
  739. intro = smartlist_get(service->intro_nodes, j);
  740. router = router_get_by_nickname(intro);
  741. if (!router || !find_intro_circuit(router,service->pk_digest)) {
  742. log_fn(LOG_INFO,"Giving up on %s as intro point for %s.",
  743. intro, service->service_id);
  744. smartlist_del(service->intro_nodes,j--);
  745. changed = service->desc_is_dirty = 1;
  746. }
  747. smartlist_add(intro_routers, router);
  748. }
  749. /* We have enough intro points, and the intro points we thought we had were
  750. * all connected.
  751. */
  752. if (!changed && smartlist_len(service->intro_nodes) >= NUM_INTRO_POINTS) {
  753. /* We have all our intro points! Start a fresh period and reset the
  754. * circuit count. */
  755. service->intro_period_started = now;
  756. service->n_intro_circuits_launched = 0;
  757. continue;
  758. }
  759. /* Remember how many introduction circuits we started with. */
  760. prev_intro_nodes = smartlist_len(service->intro_nodes);
  761. smartlist_add_all(exclude_routers, intro_routers);
  762. /* The directory is now here. Pick three ORs as intro points. */
  763. for (j=prev_intro_nodes; j < NUM_INTRO_POINTS; ++j) {
  764. router = router_choose_random_node(service->intro_prefer_nodes,
  765. service->intro_exclude_nodes, exclude_routers, 1, 0,
  766. get_options()->_AllowUnverified & ALLOW_UNVERIFIED_INTRODUCTION, 0);
  767. if (!router) {
  768. log_fn(LOG_WARN, "Could only establish %d introduction points for %s",
  769. smartlist_len(service->intro_nodes), service->service_id);
  770. break;
  771. }
  772. changed = 1;
  773. smartlist_add(intro_routers, router);
  774. smartlist_add(exclude_routers, router);
  775. /*XXX009 should strdup the hexdigest, not nickname */
  776. smartlist_add(service->intro_nodes, tor_strdup(router->nickname));
  777. log_fn(LOG_INFO,"Picked router %s as an intro point for %s.", router->nickname,
  778. service->service_id);
  779. }
  780. /* Reset exclude_routers, for the next time around the loop. */
  781. smartlist_clear(exclude_routers);
  782. /* If there's no need to launch new circuits, stop here. */
  783. if (!changed)
  784. continue;
  785. /* Establish new introduction points. */
  786. for (j=prev_intro_nodes; j < smartlist_len(service->intro_nodes); ++j) {
  787. intro = smartlist_get(service->intro_nodes, j);
  788. r = rend_service_launch_establish_intro(service, intro);
  789. if (r<0) {
  790. log_fn(LOG_WARN, "Error launching circuit to node %s for service %s",
  791. intro, service->service_id);
  792. }
  793. }
  794. }
  795. smartlist_free(intro_routers);
  796. smartlist_free(exclude_routers);
  797. }
  798. /** Regenerate and upload rendezvous service descriptors for all
  799. * services, if necessary. If the descriptor has been dirty enough
  800. * for long enough, definitely upload; else only upload when the
  801. * periodic timeout has expired.
  802. *
  803. * For the first upload, pick a random time between now and two periods
  804. * from now, and pick it independently for each service.
  805. */
  806. void
  807. rend_consider_services_upload(time_t now) {
  808. int i;
  809. rend_service_t *service;
  810. int rendpostperiod = get_options()->RendPostPeriod;
  811. for (i=0; i< smartlist_len(rend_service_list); ++i) {
  812. service = smartlist_get(rend_service_list, i);
  813. if (!service->next_upload_time) { /* never been uploaded yet */
  814. service->next_upload_time =
  815. now + crypto_pseudo_rand_int(2*rendpostperiod);
  816. }
  817. if (service->next_upload_time < now ||
  818. (service->desc_is_dirty &&
  819. service->next_upload_time < now-5)) {
  820. /* if it's time, or if the directory servers have a wrong service
  821. * descriptor and this has been the case for 5 seconds, upload a
  822. * new one. */
  823. upload_service_descriptor(service);
  824. service->next_upload_time = now + rendpostperiod;
  825. }
  826. }
  827. }
  828. /** Log the status of introduction points for all rendezvous services
  829. * at log severity <b>serverity</b>.
  830. */
  831. void
  832. rend_service_dump_stats(int severity)
  833. {
  834. int i,j;
  835. routerinfo_t *router;
  836. rend_service_t *service;
  837. char *nickname;
  838. circuit_t *circ;
  839. for (i=0; i < smartlist_len(rend_service_list); ++i) {
  840. service = smartlist_get(rend_service_list, i);
  841. log(severity, "Service configured in %s:", service->directory);
  842. for (j=0; j < smartlist_len(service->intro_nodes); ++j) {
  843. nickname = smartlist_get(service->intro_nodes, j);
  844. router = router_get_by_nickname(smartlist_get(service->intro_nodes,j));
  845. if (!router) {
  846. log(severity, " Intro point at %s: unrecognized router",nickname);
  847. continue;
  848. }
  849. circ = find_intro_circuit(router, service->pk_digest);
  850. if (!circ) {
  851. log(severity, " Intro point at %s: no circuit",nickname);
  852. continue;
  853. }
  854. log(severity, " Intro point at %s: circuit is %s",nickname,
  855. circuit_state_to_string[circ->state]);
  856. }
  857. }
  858. }
  859. /** Given <b>conn</b>, a rendezvous exit stream, look up the hidden service for
  860. * 'circ', and look up the port and address based on conn-\>port.
  861. * Assign the actual conn-\>addr and conn-\>port. Return -1 if failure,
  862. * or 0 for success.
  863. */
  864. int
  865. rend_service_set_connection_addr_port(connection_t *conn, circuit_t *circ)
  866. {
  867. rend_service_t *service;
  868. int i;
  869. rend_service_port_config_t *p;
  870. char serviceid[REND_SERVICE_ID_LEN+1];
  871. tor_assert(circ->purpose == CIRCUIT_PURPOSE_S_REND_JOINED);
  872. log_fn(LOG_DEBUG,"beginning to hunt for addr/port");
  873. base32_encode(serviceid, REND_SERVICE_ID_LEN+1,
  874. circ->rend_pk_digest,10);
  875. service = rend_service_get_by_pk_digest(circ->rend_pk_digest);
  876. if (!service) {
  877. log_fn(LOG_WARN, "Couldn't find any service associated with pk %s on rendezvous circuit %d; closing",
  878. serviceid, circ->n_circ_id);
  879. return -1;
  880. }
  881. for (i = 0; i < smartlist_len(service->ports); ++i) {
  882. p = smartlist_get(service->ports, i);
  883. if (conn->port == p->virtual_port) {
  884. conn->addr = p->real_address;
  885. conn->port = p->real_port;
  886. return 0;
  887. }
  888. }
  889. log_fn(LOG_INFO, "No virtual port mapping exists for port %d on service %s",
  890. conn->port,serviceid);
  891. return -1;
  892. }