rendservice.c 31 KB

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