dirserv.c 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938
  1. /* Copyright 2001-2004 Roger Dingledine.
  2. * Copyright 2004 Roger Dingledine, Nick Mathewson. */
  3. /* See LICENSE for licensing information */
  4. /* $Id$ */
  5. const char dirserv_c_id[] = "$Id$";
  6. #include "or.h"
  7. /**
  8. * \file dirserv.c
  9. * \brief Directory server core implementation.
  10. **/
  11. /** How far in the future do we allow a router to get? (seconds) */
  12. #define ROUTER_ALLOW_SKEW (30*60)
  13. /** How many seconds do we wait before regenerating the directory? */
  14. #define DIR_REGEN_SLACK_TIME 10
  15. /** Do we need to regenerate the directory when someone asks for it? */
  16. static int the_directory_is_dirty = 1;
  17. static int runningrouters_is_dirty = 1;
  18. static int list_server_status(char **running_routers_out,
  19. char **router_status_out);
  20. static void directory_remove_unrecognized(void);
  21. static int dirserv_regenerate_directory(void);
  22. /* Should be static; exposed for testing */
  23. void add_fingerprint_to_dir(const char *nickname, const char *fp);
  24. /************** Fingerprint handling code ************/
  25. typedef struct fingerprint_entry_t {
  26. char *nickname;
  27. char *fingerprint; /**< Stored as HEX_DIGEST_LEN characters, followed by a NUL */
  28. } fingerprint_entry_t;
  29. /** List of nickname-\>identity fingerprint mappings for all the routers
  30. * that we recognize. Used to prevent Sybil attacks. */
  31. static smartlist_t *fingerprint_list = NULL;
  32. /** Add the fingerprint <b>fp</b> for the nickname <b>nickname</b> to
  33. * the global list of recognized identity key fingerprints.
  34. */
  35. void /* Should be static; exposed for testing */
  36. add_fingerprint_to_dir(const char *nickname, const char *fp)
  37. {
  38. int i;
  39. fingerprint_entry_t *ent;
  40. if (!fingerprint_list)
  41. fingerprint_list = smartlist_create();
  42. for (i = 0; i < smartlist_len(fingerprint_list); ++i) {
  43. ent = smartlist_get(fingerprint_list, i);
  44. if (!strcasecmp(ent->nickname,nickname)) {
  45. tor_free(ent->fingerprint);
  46. ent->fingerprint = tor_strdup(fp);
  47. return;
  48. }
  49. }
  50. ent = tor_malloc(sizeof(fingerprint_entry_t));
  51. ent->nickname = tor_strdup(nickname);
  52. ent->fingerprint = tor_strdup(fp);
  53. tor_strstrip(ent->fingerprint, " ");
  54. smartlist_add(fingerprint_list, ent);
  55. }
  56. /** Add the nickname and fingerprint for this OR to the recognized list.
  57. */
  58. int
  59. dirserv_add_own_fingerprint(const char *nickname, crypto_pk_env_t *pk)
  60. {
  61. char fp[FINGERPRINT_LEN+1];
  62. if (crypto_pk_get_fingerprint(pk, fp, 0)<0) {
  63. log_fn(LOG_ERR, "Error computing fingerprint");
  64. return -1;
  65. }
  66. add_fingerprint_to_dir(nickname, fp);
  67. return 0;
  68. }
  69. /** Parse the nickname-\>fingerprint mappings stored in the file named
  70. * <b>fname</b>. The file format is line-based, with each non-blank
  71. * holding one nickname, some space, and a fingerprint for that
  72. * nickname. On success, replace the current fingerprint list with
  73. * the contents of <b>fname</b> and return 0. On failure, leave the
  74. * current fingerprint list untouched, and return -1. */
  75. int
  76. dirserv_parse_fingerprint_file(const char *fname)
  77. {
  78. char *cf;
  79. char *nickname, *fingerprint;
  80. smartlist_t *fingerprint_list_new;
  81. int i, result;
  82. fingerprint_entry_t *ent;
  83. struct config_line_t *front=NULL, *list;
  84. cf = read_file_to_str(fname, 0);
  85. if (!cf) {
  86. log_fn(LOG_WARN, "Cannot open fingerprint file %s", fname);
  87. return -1;
  88. }
  89. result = config_get_lines(cf, &front);
  90. tor_free(cf);
  91. if (result < 0) {
  92. log_fn(LOG_WARN, "Error reading from fingerprint file");
  93. return -1;
  94. }
  95. fingerprint_list_new = smartlist_create();
  96. for (list=front; list; list=list->next) {
  97. nickname = list->key; fingerprint = list->value;
  98. if (strlen(nickname) > MAX_NICKNAME_LEN) {
  99. log(LOG_WARN, "Nickname '%s' too long in fingerprint file. Skipping.", nickname);
  100. continue;
  101. }
  102. if (strlen(fingerprint) != FINGERPRINT_LEN ||
  103. !crypto_pk_check_fingerprint_syntax(fingerprint)) {
  104. log_fn(LOG_WARN, "Invalid fingerprint (nickname '%s', fingerprint %s). Skipping.",
  105. nickname, fingerprint);
  106. continue;
  107. }
  108. if (0==strcasecmp(nickname, DEFAULT_CLIENT_NICKNAME)) {
  109. /* If you approved an OR called "client", then clients who use
  110. * the default nickname could all be rejected. That's no good. */
  111. log(LOG_WARN,
  112. "Authorizing a nickname '%s' would break many clients; skipping.",
  113. DEFAULT_CLIENT_NICKNAME);
  114. continue;
  115. }
  116. for (i = 0; i < smartlist_len(fingerprint_list_new); ++i) {
  117. ent = smartlist_get(fingerprint_list_new, i);
  118. if (0==strcasecmp(ent->nickname, nickname)) {
  119. log(LOG_WARN, "Duplicate nickname '%s'. Skipping.",nickname);
  120. break; /* out of the for. the 'if' below means skip to the next line. */
  121. }
  122. }
  123. if (i == smartlist_len(fingerprint_list_new)) { /* not a duplicate */
  124. ent = tor_malloc(sizeof(fingerprint_entry_t));
  125. ent->nickname = tor_strdup(nickname);
  126. ent->fingerprint = tor_strdup(fingerprint);
  127. tor_strstrip(ent->fingerprint, " ");
  128. smartlist_add(fingerprint_list_new, ent);
  129. }
  130. }
  131. config_free_lines(front);
  132. dirserv_free_fingerprint_list();
  133. fingerprint_list = fingerprint_list_new;
  134. /* Delete any routers whose fingerprints we no longer recognize */
  135. directory_remove_unrecognized();
  136. return 0;
  137. }
  138. /** Check whether <b>router</b> has a nickname/identity key combination that
  139. * we recognize from the fingerprint list. Return 1 if router's
  140. * identity and nickname match, -1 if we recognize the nickname but
  141. * the identity key is wrong, and 0 if the nickname is not known. */
  142. int
  143. dirserv_router_fingerprint_is_known(const routerinfo_t *router)
  144. {
  145. int i, found=0;
  146. fingerprint_entry_t *ent =NULL;
  147. char fp[FINGERPRINT_LEN+1];
  148. if (!fingerprint_list)
  149. fingerprint_list = smartlist_create();
  150. log_fn(LOG_DEBUG, "%d fingerprints known.", smartlist_len(fingerprint_list));
  151. for (i=0;i<smartlist_len(fingerprint_list);++i) {
  152. ent = smartlist_get(fingerprint_list, i);
  153. log_fn(LOG_DEBUG,"%s vs %s", router->nickname, ent->nickname);
  154. if (!strcasecmp(router->nickname,ent->nickname)) {
  155. found = 1;
  156. break;
  157. }
  158. }
  159. if (!found) { /* No such server known */
  160. log_fn(LOG_INFO,"no fingerprint found for '%s'",router->nickname);
  161. return 0;
  162. }
  163. if (crypto_pk_get_fingerprint(router->identity_pkey, fp, 0)) {
  164. log_fn(LOG_WARN,"error computing fingerprint");
  165. return -1;
  166. }
  167. if (0==strcasecmp(ent->fingerprint, fp)) {
  168. log_fn(LOG_DEBUG,"good fingerprint for '%s'",router->nickname);
  169. return 1; /* Right fingerprint. */
  170. } else {
  171. log_fn(LOG_WARN,"mismatched fingerprint for '%s'",router->nickname);
  172. return -1; /* Wrong fingerprint. */
  173. }
  174. }
  175. /** If we are an authoritative dirserver, and the list of approved
  176. * servers contains one whose identity key digest is <b>digest</b>,
  177. * return that router's nickname. Otherwise return NULL. */
  178. const char *dirserv_get_nickname_by_digest(const char *digest)
  179. {
  180. char hexdigest[HEX_DIGEST_LEN+1];
  181. if (!fingerprint_list)
  182. return NULL;
  183. tor_assert(digest);
  184. base16_encode(hexdigest, HEX_DIGEST_LEN+1, digest, DIGEST_LEN);
  185. SMARTLIST_FOREACH(fingerprint_list, fingerprint_entry_t*, ent,
  186. { if (!strcasecmp(hexdigest, ent->fingerprint))
  187. return ent->nickname; } );
  188. return NULL;
  189. }
  190. #if 0
  191. /** Return true iff any router named <b>nickname</b> with <b>digest</b>
  192. * is in the verified fingerprint list. */
  193. static int
  194. router_nickname_is_approved(const char *nickname, const char *digest)
  195. {
  196. const char *n;
  197. n = dirserv_get_nickname_by_digest(digest);
  198. if (n && !strcasecmp(n,nickname))
  199. return 1;
  200. else
  201. return 0;
  202. }
  203. #endif
  204. /** Clear the current fingerprint list. */
  205. void
  206. dirserv_free_fingerprint_list()
  207. {
  208. int i;
  209. fingerprint_entry_t *ent;
  210. if (!fingerprint_list)
  211. return;
  212. for (i = 0; i < smartlist_len(fingerprint_list); ++i) {
  213. ent = smartlist_get(fingerprint_list, i);
  214. tor_free(ent->nickname);
  215. tor_free(ent->fingerprint);
  216. tor_free(ent);
  217. }
  218. smartlist_free(fingerprint_list);
  219. fingerprint_list = NULL;
  220. }
  221. /*
  222. * Descriptor list
  223. */
  224. /** A directory server's view of a server descriptor. Contains both
  225. * parsed and unparsed versions. */
  226. typedef struct descriptor_entry_t {
  227. char *nickname;
  228. time_t published;
  229. size_t desc_len;
  230. char *descriptor;
  231. int verified;
  232. routerinfo_t *router;
  233. } descriptor_entry_t;
  234. /** List of all server descriptors that this dirserv is holding. */
  235. static smartlist_t *descriptor_list = NULL;
  236. /** Release the storage held by <b>desc</b> */
  237. static void free_descriptor_entry(descriptor_entry_t *desc)
  238. {
  239. tor_free(desc->descriptor);
  240. tor_free(desc->nickname);
  241. routerinfo_free(desc->router);
  242. tor_free(desc);
  243. }
  244. /** Release all storage that the dirserv is holding for server
  245. * descriptors. */
  246. void
  247. dirserv_free_descriptors()
  248. {
  249. if (!descriptor_list)
  250. return;
  251. SMARTLIST_FOREACH(descriptor_list, descriptor_entry_t *, d,
  252. free_descriptor_entry(d));
  253. smartlist_clear(descriptor_list);
  254. }
  255. /** Parse the server descriptor at *desc and maybe insert it into the
  256. * list of server descriptors, and (if the descriptor is well-formed)
  257. * advance *desc immediately past the descriptor's end.
  258. *
  259. * Return 1 if descriptor is well-formed and accepted;
  260. * 0 if well-formed and server is unapproved;
  261. * -1 if not well-formed or other error.
  262. */
  263. int
  264. dirserv_add_descriptor(const char **desc)
  265. {
  266. descriptor_entry_t *ent = NULL;
  267. routerinfo_t *ri = NULL;
  268. int i, r, found=-1;
  269. char *start, *end;
  270. char *desc_tmp = NULL;
  271. const char *cp;
  272. size_t desc_len;
  273. time_t now;
  274. int verified=1; /* whether we knew its fingerprint already */
  275. if (!descriptor_list)
  276. descriptor_list = smartlist_create();
  277. start = strstr(*desc, "router ");
  278. if (!start) {
  279. log_fn(LOG_WARN, "no 'router' line found. This is not a descriptor.");
  280. return -1;
  281. }
  282. if ((end = strstr(start+6, "\nrouter "))) {
  283. ++end; /* Include NL. */
  284. } else if ((end = strstr(start+6, "\ndirectory-signature"))) {
  285. ++end;
  286. } else {
  287. end = start+strlen(start);
  288. }
  289. desc_len = end-start;
  290. cp = desc_tmp = tor_strndup(start, desc_len);
  291. /* Check: is the descriptor syntactically valid? */
  292. ri = router_parse_entry_from_string(cp, NULL);
  293. tor_free(desc_tmp);
  294. if (!ri) {
  295. log(LOG_WARN, "Couldn't parse descriptor");
  296. return -1;
  297. }
  298. /* Okay. Now check whether the fingerprint is recognized. */
  299. r = dirserv_router_fingerprint_is_known(ri);
  300. if (r==-1) {
  301. log_fn(LOG_WARN, "Known nickname '%s', wrong fingerprint. Not adding.", ri->nickname);
  302. routerinfo_free(ri);
  303. *desc = end;
  304. return 0;
  305. }
  306. if (r==0) {
  307. char fp[FINGERPRINT_LEN+1];
  308. log_fn(LOG_INFO, "Unknown nickname '%s' (%s:%d). Adding.",
  309. ri->nickname, ri->address, ri->or_port);
  310. if (crypto_pk_get_fingerprint(ri->identity_pkey, fp, 1) < 0) {
  311. log_fn(LOG_WARN, "Error computing fingerprint for '%s'", ri->nickname);
  312. } else {
  313. log_fn(LOG_INFO, "Fingerprint line: %s %s", ri->nickname, fp);
  314. }
  315. verified = 0;
  316. }
  317. /* Is there too much clock skew? */
  318. now = time(NULL);
  319. if (ri->published_on > now+ROUTER_ALLOW_SKEW) {
  320. log_fn(LOG_WARN, "Publication time for nickname '%s' is too far in the future; possible clock skew. Not adding.", ri->nickname);
  321. routerinfo_free(ri);
  322. *desc = end;
  323. return 0;
  324. }
  325. if (ri->published_on < now-ROUTER_MAX_AGE) {
  326. log_fn(LOG_WARN, "Publication time for router with nickname '%s' is too far in the past. Not adding.", ri->nickname);
  327. routerinfo_free(ri);
  328. *desc = end;
  329. return 0;
  330. }
  331. /* Do we already have an entry for this router? */
  332. for (i = 0; i < smartlist_len(descriptor_list); ++i) {
  333. ent = smartlist_get(descriptor_list, i);
  334. if (!strcasecmp(ri->nickname, ent->nickname)) {
  335. found = i;
  336. break;
  337. }
  338. }
  339. if (found >= 0) {
  340. /* if so, decide whether to update it. */
  341. if (ent->published >= ri->published_on) {
  342. /* We already have a newer or equal-time descriptor */
  343. log_fn(LOG_INFO,"We already have a new enough desc for nickname '%s'. Not adding.",ri->nickname);
  344. /* This isn't really an error; return success. */
  345. routerinfo_free(ri);
  346. *desc = end;
  347. return 1;
  348. }
  349. /* We don't have a newer one; we'll update this one. */
  350. log_fn(LOG_INFO,"Dirserv updating desc for nickname '%s'",ri->nickname);
  351. free_descriptor_entry(ent);
  352. smartlist_del_keeporder(descriptor_list, found);
  353. } else {
  354. /* Add at the end. */
  355. log_fn(LOG_INFO,"Dirserv adding desc for nickname '%s'",ri->nickname);
  356. }
  357. ent = tor_malloc(sizeof(descriptor_entry_t));
  358. ent->nickname = tor_strdup(ri->nickname);
  359. ent->published = ri->published_on;
  360. ent->desc_len = desc_len;
  361. ent->descriptor = tor_strndup(start,desc_len);
  362. ent->router = ri;
  363. ent->verified = verified;
  364. smartlist_add(descriptor_list, ent);
  365. *desc = end;
  366. directory_set_dirty();
  367. return 1;
  368. }
  369. /** Remove all descriptors whose nicknames or fingerprints we don't
  370. * recognize. (Descriptors that used to be good can become
  371. * unrecognized when we reload the fingerprint list.)
  372. */
  373. static void
  374. directory_remove_unrecognized(void)
  375. {
  376. int i;
  377. descriptor_entry_t *ent;
  378. if (!descriptor_list)
  379. descriptor_list = smartlist_create();
  380. for (i = 0; i < smartlist_len(descriptor_list); ++i) {
  381. ent = smartlist_get(descriptor_list, i);
  382. if (dirserv_router_fingerprint_is_known(ent->router)<=0) {
  383. log(LOG_INFO, "Router '%s' is no longer recognized",
  384. ent->nickname);
  385. free_descriptor_entry(ent);
  386. smartlist_del(descriptor_list, i--);
  387. }
  388. }
  389. }
  390. /** Mark the directory as <b>dirty</b> -- when we're next asked for a
  391. * directory, we will rebuild it instead of reusing the most recently
  392. * generated one.
  393. */
  394. void
  395. directory_set_dirty()
  396. {
  397. time_t now = time(NULL);
  398. if (!the_directory_is_dirty)
  399. the_directory_is_dirty = now;
  400. if (!runningrouters_is_dirty)
  401. runningrouters_is_dirty = now;
  402. }
  403. /** Load all descriptors from a directory stored in the string
  404. * <b>dir</b>.
  405. */
  406. int
  407. dirserv_load_from_directory_string(const char *dir)
  408. {
  409. const char *cp = dir;
  410. while (1) {
  411. cp = strstr(cp, "\nrouter ");
  412. if (!cp) break;
  413. ++cp;
  414. if (dirserv_add_descriptor(&cp) < 0) {
  415. return -1;
  416. }
  417. --cp; /*Back up to newline.*/
  418. }
  419. return 0;
  420. }
  421. /**
  422. * Allocate and return a description of the status of the server <b>desc</b>,
  423. * for use in a running-routers line (if <b>rr_format</b> is true), or in a
  424. * router-status line (if <b>rr_format</b> is false. The server is listed
  425. * as running iff <b>is_live</b> is true.
  426. */
  427. static char *
  428. list_single_server_status(descriptor_entry_t *desc, int is_live,
  429. int rr_format)
  430. {
  431. char buf[MAX_NICKNAME_LEN+HEX_DIGEST_LEN+4]; /* !nickname=$hexdigest\0 */
  432. char *cp;
  433. tor_assert(desc);
  434. tor_assert(desc->router);
  435. cp = buf;
  436. if (!is_live) {
  437. *cp++ = '!';
  438. }
  439. if (desc->verified) {
  440. strlcpy(cp, desc->nickname, sizeof(buf)-(cp-buf));
  441. cp += strlen(cp);
  442. if (!rr_format)
  443. *cp++ = '=';
  444. }
  445. if (!desc->verified || !rr_format) {
  446. *cp++ = '$';
  447. base16_encode(cp, HEX_DIGEST_LEN+1, desc->router->identity_digest,
  448. DIGEST_LEN);
  449. }
  450. return tor_strdup(buf);
  451. }
  452. /** Allocate the contents of a running-routers line and a router-status line,
  453. * and store them in *<b>running_routers_out</b> and *<b>router_status_out</b>
  454. * respectively. Return 0 on success, -1 on failure.
  455. */
  456. static int
  457. list_server_status(char **running_routers_out, char **router_status_out)
  458. {
  459. /* List of entries in running-routers style: An optional !, then either
  460. * a nickname or a dollar-prefixed hexdigest. */
  461. smartlist_t *rr_entries;
  462. /* List of entries in a router-status style: An optional !, then an optional
  463. * equals-suffixed nickname, then a dollar-prefixed hexdigest. */
  464. smartlist_t *rs_entries;
  465. tor_assert(running_routers_out || router_status_out);
  466. rr_entries = smartlist_create();
  467. rs_entries = smartlist_create();
  468. SMARTLIST_FOREACH(descriptor_list, descriptor_entry_t *, d,
  469. {
  470. int is_live;
  471. connection_t *conn;
  472. tor_assert(d->router);
  473. conn = connection_get_by_identity_digest(
  474. d->router->identity_digest, CONN_TYPE_OR);
  475. /* Treat a router as alive if
  476. * - It's me, and I'm not hibernating.
  477. * or - we're connected to it. */
  478. is_live = (router_is_me(d->router) && !we_are_hibernating()) ||
  479. (conn && conn->state == OR_CONN_STATE_OPEN);
  480. smartlist_add(rr_entries, list_single_server_status(d, is_live, 1));
  481. smartlist_add(rs_entries, list_single_server_status(d, is_live, 0));
  482. });
  483. if (running_routers_out)
  484. *running_routers_out = smartlist_join_strings(rr_entries, " ", 0,NULL);
  485. if (router_status_out)
  486. *router_status_out = smartlist_join_strings(rs_entries, " ", 0,NULL);
  487. SMARTLIST_FOREACH(rr_entries, char *, cp, tor_free(cp));
  488. SMARTLIST_FOREACH(rs_entries, char *, cp, tor_free(cp));
  489. smartlist_free(rr_entries);
  490. smartlist_free(rs_entries);
  491. return 0;
  492. }
  493. /** Remove any descriptors from the directory that are more than <b>age</b>
  494. * seconds old.
  495. */
  496. void
  497. dirserv_remove_old_servers(int age)
  498. {
  499. int i;
  500. time_t cutoff;
  501. descriptor_entry_t *ent;
  502. if (!descriptor_list)
  503. descriptor_list = smartlist_create();
  504. cutoff = time(NULL) - age;
  505. for (i = 0; i < smartlist_len(descriptor_list); ++i) {
  506. ent = smartlist_get(descriptor_list, i);
  507. if (ent->published <= cutoff) {
  508. /* descriptor_list[i] is too old. Remove it. */
  509. free_descriptor_entry(ent);
  510. smartlist_del(descriptor_list, i--);
  511. directory_set_dirty();
  512. }
  513. }
  514. }
  515. /** Dump all routers currently in the directory into the string
  516. * <b>s</b>, using at most <b>maxlen</b> characters, and signing the
  517. * directory with <b>private_key</b>. Return 0 on success, -1 on
  518. * failure.
  519. */
  520. int
  521. dirserv_dump_directory_to_string(char *s, size_t maxlen,
  522. crypto_pk_env_t *private_key)
  523. {
  524. char *eos, *cp;
  525. char *running_routers, *router_status;
  526. char *identity_pkey; /* Identity key, DER64-encoded. */
  527. char *recommended_versions;
  528. char digest[20];
  529. char signature[128];
  530. char published[33];
  531. time_t published_on;
  532. int i;
  533. eos = s+maxlen;
  534. if (!descriptor_list)
  535. descriptor_list = smartlist_create();
  536. if (list_server_status(&running_routers, &router_status))
  537. return -1;
  538. /* ASN.1-encode the public key. This is a temporary measure; once
  539. * everyone is running 0.0.9pre3 or later, we can shift to using a
  540. * PEM-encoded key instead.
  541. */
  542. #if 1
  543. if (crypto_pk_DER64_encode_public_key(private_key, &identity_pkey)<0) {
  544. log_fn(LOG_WARN,"write identity_pkey to string failed!");
  545. return -1;
  546. }
  547. #else
  548. {
  549. int l;
  550. if (crypto_pk_write_public_key_to_string(private_key,&identity_pkey,&l)<0) {
  551. log_fn(LOG_WARN,"write identity_pkey to string failed!");
  552. return -1;
  553. }
  554. }
  555. #endif
  556. {
  557. smartlist_t *versions;
  558. struct config_line_t *ln;
  559. versions = smartlist_create();
  560. for (ln = get_options()->RecommendedVersions; ln; ln = ln->next) {
  561. smartlist_split_string(versions, ln->value, ",",
  562. SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
  563. }
  564. recommended_versions = smartlist_join_strings(versions,",",0,NULL);
  565. SMARTLIST_FOREACH(versions,char *,s,tor_free(s));
  566. smartlist_free(versions);
  567. }
  568. dirserv_remove_old_servers(ROUTER_MAX_AGE);
  569. published_on = time(NULL);
  570. format_iso_time(published, published_on);
  571. tor_snprintf(s, maxlen,
  572. "signed-directory\n"
  573. "published %s\n"
  574. "recommended-software %s\n"
  575. "running-routers %s\n"
  576. "opt router-status %s\n"
  577. "opt dir-signing-key %s\n\n",
  578. published, recommended_versions, running_routers, router_status,
  579. identity_pkey);
  580. tor_free(running_routers);
  581. tor_free(router_status);
  582. tor_free(identity_pkey);
  583. i = strlen(s);
  584. cp = s+i;
  585. SMARTLIST_FOREACH(descriptor_list, descriptor_entry_t *, d,
  586. if (strlcat(s, d->descriptor, maxlen) >= maxlen)
  587. goto truncated);
  588. /* These multiple strlcat calls are inefficient, but dwarfed by the RSA
  589. signature.
  590. */
  591. if (strlcat(s, "directory-signature ", maxlen) >= maxlen)
  592. goto truncated;
  593. if (strlcat(s, get_options()->Nickname, maxlen) >= maxlen)
  594. goto truncated;
  595. if (strlcat(s, "\n", maxlen) >= maxlen)
  596. goto truncated;
  597. if (router_get_dir_hash(s,digest)) {
  598. log_fn(LOG_WARN,"couldn't compute digest");
  599. return -1;
  600. }
  601. if (crypto_pk_private_sign(private_key, signature, digest, 20) < 0) {
  602. log_fn(LOG_WARN,"couldn't sign digest");
  603. return -1;
  604. }
  605. log(LOG_DEBUG,"generated directory digest begins with %s",hex_str(digest,4));
  606. if (strlcat(cp, "-----BEGIN SIGNATURE-----\n", maxlen) >= maxlen)
  607. goto truncated;
  608. i = strlen(s);
  609. cp = s+i;
  610. if (base64_encode(cp, maxlen-i, signature, 128) < 0) {
  611. log_fn(LOG_WARN,"couldn't base64-encode signature");
  612. return -1;
  613. }
  614. if (strlcat(s, "-----END SIGNATURE-----\n", maxlen) >= maxlen)
  615. goto truncated;
  616. return 0;
  617. truncated:
  618. log_fn(LOG_WARN,"tried to exceed string length.");
  619. return -1;
  620. }
  621. /** Most recently generated encoded signed directory. */
  622. static char *the_directory = NULL;
  623. static size_t the_directory_len = 0;
  624. static char *the_directory_z = NULL;
  625. static size_t the_directory_z_len = 0;
  626. typedef struct cached_dir_t {
  627. char *dir;
  628. char *dir_z;
  629. size_t dir_len;
  630. size_t dir_z_len;
  631. time_t published;
  632. } cached_dir_t;
  633. /* used only by non-auth dirservers */
  634. static cached_dir_t cached_directory = { NULL, NULL, 0, 0, 0 };
  635. static cached_dir_t cached_runningrouters = { NULL, NULL, 0, 0, 0 };
  636. /** If we have no cached directory, or it is older than <b>when</b>, then
  637. * replace it with <b>directory</b>, published at <b>when</b>.
  638. */
  639. void dirserv_set_cached_directory(const char *directory, time_t when,
  640. int is_running_routers)
  641. {
  642. time_t now;
  643. cached_dir_t *d;
  644. now = time(NULL);
  645. d = is_running_routers ? &cached_runningrouters : &cached_directory;
  646. if (when<=d->published) {
  647. log_fn(LOG_INFO, "Ignoring old directory; not caching.");
  648. } else if (when>=now+ROUTER_ALLOW_SKEW) {
  649. log_fn(LOG_INFO, "Ignoring future directory; not caching.");
  650. } else if (when>d->published &&
  651. when<now+ROUTER_ALLOW_SKEW) {
  652. log_fn(LOG_DEBUG, "Caching directory.");
  653. tor_free(d->dir);
  654. d->dir = tor_strdup(directory);
  655. d->dir_len = strlen(directory);
  656. tor_free(d->dir_z);
  657. if (tor_gzip_compress(&(d->dir_z), &(d->dir_z_len), d->dir, d->dir_len,
  658. ZLIB_METHOD)) {
  659. log_fn(LOG_WARN,"Error compressing cached directory");
  660. }
  661. d->published = when;
  662. if (!is_running_routers) {
  663. char filename[512];
  664. tor_snprintf(filename,sizeof(filename),"%s/cached-directory", get_options()->DataDirectory);
  665. if (write_str_to_file(filename,cached_directory.dir,0) < 0) {
  666. log_fn(LOG_WARN, "Couldn't write cached directory to disk. Ignoring.");
  667. }
  668. }
  669. }
  670. }
  671. /** Set *<b>directory</b> to the most recently generated encoded signed
  672. * directory, generating a new one as necessary. If not an authoritative
  673. * directory may return 0 if no directory is yet cached.*/
  674. size_t dirserv_get_directory(const char **directory, int compress)
  675. {
  676. if (!get_options()->AuthoritativeDir) {
  677. cached_dir_t *d = &cached_directory;
  678. *directory = compress ? d->dir_z : d->dir;
  679. if (*directory) {
  680. return compress ? d->dir_z_len : d->dir_len;
  681. } else {
  682. /* no directory yet retrieved */
  683. return 0;
  684. }
  685. }
  686. if (the_directory_is_dirty &&
  687. the_directory_is_dirty + DIR_REGEN_SLACK_TIME < time(NULL)) {
  688. if (dirserv_regenerate_directory())
  689. return 0;
  690. } else {
  691. log(LOG_INFO,"Directory still clean, reusing.");
  692. }
  693. *directory = compress ? the_directory_z : the_directory;
  694. return compress ? the_directory_z_len : the_directory_len;
  695. }
  696. /**
  697. * Generate a fresh directory (authdirservers only.)
  698. */
  699. static int dirserv_regenerate_directory(void)
  700. {
  701. char *new_directory;
  702. new_directory = tor_malloc(MAX_DIR_SIZE);
  703. if (dirserv_dump_directory_to_string(new_directory, MAX_DIR_SIZE,
  704. get_identity_key())) {
  705. log(LOG_WARN, "Error creating directory.");
  706. tor_free(new_directory);
  707. return -1;
  708. }
  709. tor_free(the_directory);
  710. the_directory = new_directory;
  711. the_directory_len = strlen(the_directory);
  712. log_fn(LOG_INFO,"New directory (size %d):\n%s",(int)the_directory_len,
  713. the_directory);
  714. tor_free(the_directory_z);
  715. if (tor_gzip_compress(&the_directory_z, &the_directory_z_len,
  716. the_directory, the_directory_len,
  717. ZLIB_METHOD)) {
  718. log_fn(LOG_WARN, "Error gzipping directory.");
  719. return -1;
  720. }
  721. /* Now read the directory we just made in order to update our own
  722. * router lists. This does more signature checking than is strictly
  723. * necessary, but safe is better than sorry. */
  724. new_directory = tor_strdup(the_directory);
  725. /* use a new copy of the dir, since get_dir_from_string scribbles on it */
  726. if (router_load_routerlist_from_directory(new_directory, get_identity_key(), 1)) {
  727. log_fn(LOG_ERR, "We just generated a directory we can't parse. Dying.");
  728. tor_cleanup();
  729. exit(0);
  730. }
  731. tor_free(new_directory);
  732. the_directory_is_dirty = 0;
  733. /* Save the directory to disk so we re-load it quickly on startup.
  734. */
  735. dirserv_set_cached_directory(the_directory, time(NULL), 0);
  736. return 0;
  737. }
  738. static char *the_runningrouters=NULL;
  739. static size_t the_runningrouters_len=0;
  740. static char *the_runningrouters_z=NULL;
  741. static size_t the_runningrouters_z_len=0;
  742. /** Replace the current running-routers list with a newly generated one. */
  743. static int generate_runningrouters(crypto_pk_env_t *private_key)
  744. {
  745. char *s=NULL, *cp;
  746. char *router_status=NULL;
  747. char digest[DIGEST_LEN];
  748. char signature[PK_BYTES];
  749. int i;
  750. char published[33];
  751. size_t len;
  752. time_t published_on;
  753. char *identity_pkey; /* Identity key, DER64-encoded. */
  754. len = 1024+(MAX_HEX_NICKNAME_LEN+2)*smartlist_len(descriptor_list);
  755. s = tor_malloc_zero(len);
  756. if (list_server_status(NULL, &router_status)) {
  757. goto err;
  758. }
  759. /* ASN.1-encode the public key. This is a temporary measure; once
  760. * everyone is running 0.0.9pre3 or later, we can shift to using a
  761. * PEM-encoded key instead.
  762. */
  763. #if 1
  764. if (crypto_pk_DER64_encode_public_key(private_key, &identity_pkey)<0) {
  765. log_fn(LOG_WARN,"write identity_pkey to string failed!");
  766. goto err;
  767. }
  768. #else
  769. {
  770. int l;
  771. if (crypto_pk_write_public_key_to_string(private_key,&identity_pkey,&l)<0) {
  772. log_fn(LOG_WARN,"write identity_pkey to string failed!");
  773. goto err;
  774. }
  775. }
  776. #endif
  777. published_on = time(NULL);
  778. format_iso_time(published, published_on);
  779. tor_snprintf(s, len, "network-status\n"
  780. "published %s\n"
  781. "router-status %s\n"
  782. "opt dir-signing-key %s\n"
  783. "directory-signature %s\n"
  784. "-----BEGIN SIGNATURE-----\n",
  785. published, router_status, identity_pkey, get_options()->Nickname);
  786. tor_free(router_status);
  787. tor_free(identity_pkey);
  788. if (router_get_runningrouters_hash(s,digest)) {
  789. log_fn(LOG_WARN,"couldn't compute digest");
  790. goto err;
  791. }
  792. if (crypto_pk_private_sign(private_key, signature, digest, 20) < 0) {
  793. log_fn(LOG_WARN,"couldn't sign digest");
  794. goto err;
  795. }
  796. i = strlen(s);
  797. cp = s+i;
  798. if (base64_encode(cp, len-i, signature, 128) < 0) {
  799. log_fn(LOG_WARN,"couldn't base64-encode signature");
  800. goto err;
  801. }
  802. if (strlcat(s, "-----END SIGNATURE-----\n", len) >= len) {
  803. goto err;
  804. }
  805. tor_free(the_runningrouters);
  806. the_runningrouters = s;
  807. the_runningrouters_len = strlen(s);
  808. tor_free(the_runningrouters_z);
  809. if (tor_gzip_compress(&the_runningrouters_z, &the_runningrouters_z_len,
  810. the_runningrouters, the_runningrouters_len,
  811. ZLIB_METHOD)) {
  812. log_fn(LOG_WARN, "Error gzipping runningrouters");
  813. return -1;
  814. }
  815. runningrouters_is_dirty = 0;
  816. /* We don't cache runnning-routers to disk, so there's no point in
  817. * authdirservers caching it. */
  818. /* dirserv_set_cached_directory(the_runningrouters, time(NULL), 1); */
  819. return 0;
  820. err:
  821. tor_free(s);
  822. tor_free(router_status);
  823. return -1;
  824. }
  825. /** Set *<b>rr</b> to the most recently generated encoded signed
  826. * running-routers list, generating a new one as necessary. Return the
  827. * size of the directory on success, and 0 on failure. */
  828. size_t dirserv_get_runningrouters(const char **rr, int compress)
  829. {
  830. if (!get_options()->AuthoritativeDir) {
  831. cached_dir_t *d = &cached_runningrouters;
  832. *rr = compress ? d->dir_z : d->dir;
  833. if (*rr) {
  834. return compress ? d->dir_z_len : d->dir_len;
  835. } else {
  836. /* no directory yet retrieved */
  837. return 0;
  838. }
  839. }
  840. if (runningrouters_is_dirty &&
  841. runningrouters_is_dirty + DIR_REGEN_SLACK_TIME < time(NULL)) {
  842. if (generate_runningrouters(get_identity_key())) {
  843. log_fn(LOG_ERR, "Couldn't generate running-routers list?");
  844. return 0;
  845. }
  846. }
  847. *rr = compress ? the_runningrouters_z : the_runningrouters;
  848. return compress ? the_runningrouters_z_len : the_runningrouters_len;
  849. }