dirserv.c 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958
  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_NOTICE, "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_NOTICE, "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_NOTICE,
  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_NOTICE, "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_NOTICE, "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_NOTICE, "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 verified;
  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 verified;
  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. /** Generate a new directory and write it into a newly allocated string.
  516. * Point *<b>dir_out</b> to the allocated string. Sign 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 **dir_out,
  522. crypto_pk_env_t *private_key)
  523. {
  524. char *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. char *buf = NULL;
  533. size_t buf_len;
  534. int i;
  535. tor_assert(dir_out);
  536. *dir_out = NULL;
  537. if (!descriptor_list)
  538. descriptor_list = smartlist_create();
  539. if (list_server_status(&running_routers, &router_status))
  540. return -1;
  541. /* ASN.1-encode the public key. This is a temporary measure; once
  542. * everyone is running 0.0.9pre3 or later, we can shift to using a
  543. * PEM-encoded key instead.
  544. */
  545. #if 1
  546. if (crypto_pk_DER64_encode_public_key(private_key, &identity_pkey)<0) {
  547. log_fn(LOG_WARN,"write identity_pkey to string failed!");
  548. return -1;
  549. }
  550. #else
  551. {
  552. int l;
  553. if (crypto_pk_write_public_key_to_string(private_key,&identity_pkey,&l)<0) {
  554. log_fn(LOG_WARN,"write identity_pkey to string failed!");
  555. return -1;
  556. }
  557. }
  558. #endif
  559. {
  560. smartlist_t *versions;
  561. struct config_line_t *ln;
  562. versions = smartlist_create();
  563. for (ln = get_options()->RecommendedVersions; ln; ln = ln->next) {
  564. smartlist_split_string(versions, ln->value, ",",
  565. SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
  566. }
  567. recommended_versions = smartlist_join_strings(versions,",",0,NULL);
  568. SMARTLIST_FOREACH(versions,char *,s,tor_free(s));
  569. smartlist_free(versions);
  570. }
  571. dirserv_remove_old_servers(ROUTER_MAX_AGE);
  572. published_on = time(NULL);
  573. format_iso_time(published, published_on);
  574. buf_len = 2048+strlen(recommended_versions)+strlen(running_routers)+
  575. strlen(router_status);
  576. SMARTLIST_FOREACH(descriptor_list, descriptor_entry_t *, d,
  577. buf_len += strlen(d->descriptor));
  578. buf = tor_malloc(buf_len);
  579. /* We'll be comparing against buf_len throughout the rest of the
  580. function, though strictly speaking we shouldn't be able to exceed
  581. it. This is C, after all, so we may as well check for buffer
  582. overruns.*/
  583. tor_snprintf(buf, buf_len,
  584. "signed-directory\n"
  585. "published %s\n"
  586. "recommended-software %s\n"
  587. "running-routers %s\n"
  588. "opt router-status %s\n"
  589. "opt dir-signing-key %s\n\n",
  590. published, recommended_versions, running_routers, router_status,
  591. identity_pkey);
  592. tor_free(running_routers);
  593. tor_free(router_status);
  594. tor_free(identity_pkey);
  595. i = strlen(buf);
  596. cp = buf+i;
  597. SMARTLIST_FOREACH(descriptor_list, descriptor_entry_t *, d,
  598. if (strlcat(buf, d->descriptor, buf_len) >= buf_len)
  599. goto truncated);
  600. /* These multiple strlcat calls are inefficient, but dwarfed by the RSA
  601. signature.
  602. */
  603. if (strlcat(buf, "directory-signature ", buf_len) >= buf_len)
  604. goto truncated;
  605. if (strlcat(buf, get_options()->Nickname, buf_len) >= buf_len)
  606. goto truncated;
  607. if (strlcat(buf, "\n", buf_len) >= buf_len)
  608. goto truncated;
  609. if (router_get_dir_hash(buf,digest)) {
  610. log_fn(LOG_WARN,"couldn't compute digest");
  611. tor_free(buf);
  612. return -1;
  613. }
  614. if (crypto_pk_private_sign(private_key, signature, digest, 20) < 0) {
  615. log_fn(LOG_WARN,"couldn't sign digest");
  616. tor_free(buf);
  617. return -1;
  618. }
  619. log(LOG_DEBUG,"generated directory digest begins with %s",hex_str(digest,4));
  620. if (strlcat(cp, "-----BEGIN SIGNATURE-----\n", buf_len) >= buf_len)
  621. goto truncated;
  622. i = strlen(buf);
  623. cp = buf+i;
  624. if (base64_encode(cp, buf_len-i, signature, 128) < 0) {
  625. log_fn(LOG_WARN,"couldn't base64-encode signature");
  626. tor_free(buf);
  627. return -1;
  628. }
  629. if (strlcat(buf, "-----END SIGNATURE-----\n", buf_len) >= buf_len)
  630. goto truncated;
  631. *dir_out = buf;
  632. return 0;
  633. truncated:
  634. log_fn(LOG_WARN,"tried to exceed string length.");
  635. tor_free(buf);
  636. return -1;
  637. }
  638. /** Most recently generated encoded signed directory. */
  639. static char *the_directory = NULL;
  640. static size_t the_directory_len = 0;
  641. static char *the_directory_z = NULL;
  642. static size_t the_directory_z_len = 0;
  643. typedef struct cached_dir_t {
  644. char *dir;
  645. char *dir_z;
  646. size_t dir_len;
  647. size_t dir_z_len;
  648. time_t published;
  649. } cached_dir_t;
  650. /* used only by non-auth dirservers */
  651. static cached_dir_t cached_directory = { NULL, NULL, 0, 0, 0 };
  652. static cached_dir_t cached_runningrouters = { NULL, NULL, 0, 0, 0 };
  653. /** If we have no cached directory, or it is older than <b>when</b>, then
  654. * replace it with <b>directory</b>, published at <b>when</b>.
  655. */
  656. void dirserv_set_cached_directory(const char *directory, time_t when,
  657. int is_running_routers)
  658. {
  659. time_t now;
  660. cached_dir_t *d;
  661. now = time(NULL);
  662. d = is_running_routers ? &cached_runningrouters : &cached_directory;
  663. if (when<=d->published) {
  664. log_fn(LOG_INFO, "Ignoring old directory; not caching.");
  665. } else if (when>=now+ROUTER_ALLOW_SKEW) {
  666. log_fn(LOG_INFO, "Ignoring future directory; not caching.");
  667. } else if (when>d->published &&
  668. when<now+ROUTER_ALLOW_SKEW) {
  669. log_fn(LOG_DEBUG, "Caching directory.");
  670. tor_free(d->dir);
  671. d->dir = tor_strdup(directory);
  672. d->dir_len = strlen(directory);
  673. tor_free(d->dir_z);
  674. if (tor_gzip_compress(&(d->dir_z), &(d->dir_z_len), d->dir, d->dir_len,
  675. ZLIB_METHOD)) {
  676. log_fn(LOG_WARN,"Error compressing cached directory");
  677. }
  678. d->published = when;
  679. if (!is_running_routers) {
  680. char filename[512];
  681. tor_snprintf(filename,sizeof(filename),"%s/cached-directory", get_options()->DataDirectory);
  682. if (write_str_to_file(filename,cached_directory.dir,0) < 0) {
  683. log_fn(LOG_NOTICE, "Couldn't write cached directory to disk. Ignoring.");
  684. }
  685. }
  686. }
  687. }
  688. /** Set *<b>directory</b> to the most recently generated encoded signed
  689. * directory, generating a new one as necessary. If not an authoritative
  690. * directory may return 0 if no directory is yet cached.*/
  691. size_t dirserv_get_directory(const char **directory, int compress)
  692. {
  693. if (!get_options()->AuthoritativeDir) {
  694. cached_dir_t *d = &cached_directory;
  695. *directory = compress ? d->dir_z : d->dir;
  696. if (*directory) {
  697. return compress ? d->dir_z_len : d->dir_len;
  698. } else {
  699. /* no directory yet retrieved */
  700. return 0;
  701. }
  702. }
  703. if (the_directory_is_dirty &&
  704. the_directory_is_dirty + DIR_REGEN_SLACK_TIME < time(NULL)) {
  705. if (dirserv_regenerate_directory())
  706. return 0;
  707. } else {
  708. log(LOG_INFO,"Directory still clean, reusing.");
  709. }
  710. *directory = compress ? the_directory_z : the_directory;
  711. return compress ? the_directory_z_len : the_directory_len;
  712. }
  713. /**
  714. * Generate a fresh directory (authdirservers only.)
  715. */
  716. static int dirserv_regenerate_directory(void)
  717. {
  718. char *new_directory=NULL;
  719. if (dirserv_dump_directory_to_string(&new_directory,
  720. get_identity_key())) {
  721. log(LOG_WARN, "Error creating directory.");
  722. tor_free(new_directory);
  723. return -1;
  724. }
  725. tor_free(the_directory);
  726. the_directory = new_directory;
  727. the_directory_len = strlen(the_directory);
  728. log_fn(LOG_INFO,"New directory (size %d):\n%s",(int)the_directory_len,
  729. the_directory);
  730. tor_free(the_directory_z);
  731. if (tor_gzip_compress(&the_directory_z, &the_directory_z_len,
  732. the_directory, the_directory_len,
  733. ZLIB_METHOD)) {
  734. log_fn(LOG_WARN, "Error gzipping directory.");
  735. return -1;
  736. }
  737. /* Now read the directory we just made in order to update our own
  738. * router lists. This does more signature checking than is strictly
  739. * necessary, but safe is better than sorry. */
  740. new_directory = tor_strdup(the_directory);
  741. /* use a new copy of the dir, since get_dir_from_string scribbles on it */
  742. if (router_load_routerlist_from_directory(new_directory, get_identity_key(), 1)) {
  743. log_fn(LOG_ERR, "We just generated a directory we can't parse. Dying.");
  744. tor_cleanup();
  745. exit(0);
  746. }
  747. tor_free(new_directory);
  748. the_directory_is_dirty = 0;
  749. /* Save the directory to disk so we re-load it quickly on startup.
  750. */
  751. dirserv_set_cached_directory(the_directory, time(NULL), 0);
  752. return 0;
  753. }
  754. static char *the_runningrouters=NULL;
  755. static size_t the_runningrouters_len=0;
  756. static char *the_runningrouters_z=NULL;
  757. static size_t the_runningrouters_z_len=0;
  758. /** Replace the current running-routers list with a newly generated one. */
  759. static int generate_runningrouters(crypto_pk_env_t *private_key)
  760. {
  761. char *s=NULL, *cp;
  762. char *router_status=NULL;
  763. char digest[DIGEST_LEN];
  764. char signature[PK_BYTES];
  765. int i;
  766. char published[33];
  767. size_t len;
  768. time_t published_on;
  769. char *identity_pkey; /* Identity key, DER64-encoded. */
  770. if (list_server_status(NULL, &router_status)) {
  771. goto err;
  772. }
  773. /* ASN.1-encode the public key. This is a temporary measure; once
  774. * everyone is running 0.0.9pre3 or later, we can shift to using a
  775. * PEM-encoded key instead.
  776. */
  777. #if 1
  778. if (crypto_pk_DER64_encode_public_key(private_key, &identity_pkey)<0) {
  779. log_fn(LOG_WARN,"write identity_pkey to string failed!");
  780. goto err;
  781. }
  782. #else
  783. {
  784. int l;
  785. if (crypto_pk_write_public_key_to_string(private_key,&identity_pkey,&l)<0) {
  786. log_fn(LOG_WARN,"write identity_pkey to string failed!");
  787. goto err;
  788. }
  789. }
  790. #endif
  791. published_on = time(NULL);
  792. format_iso_time(published, published_on);
  793. len = 2048+strlen(router_status);
  794. s = tor_malloc_zero(len);
  795. tor_snprintf(s, len, "network-status\n"
  796. "published %s\n"
  797. "router-status %s\n"
  798. "opt dir-signing-key %s\n"
  799. "directory-signature %s\n"
  800. "-----BEGIN SIGNATURE-----\n",
  801. published, router_status, identity_pkey, get_options()->Nickname);
  802. tor_free(router_status);
  803. tor_free(identity_pkey);
  804. if (router_get_runningrouters_hash(s,digest)) {
  805. log_fn(LOG_WARN,"couldn't compute digest");
  806. goto err;
  807. }
  808. if (crypto_pk_private_sign(private_key, signature, digest, 20) < 0) {
  809. log_fn(LOG_WARN,"couldn't sign digest");
  810. goto err;
  811. }
  812. i = strlen(s);
  813. cp = s+i;
  814. if (base64_encode(cp, len-i, signature, 128) < 0) {
  815. log_fn(LOG_WARN,"couldn't base64-encode signature");
  816. goto err;
  817. }
  818. if (strlcat(s, "-----END SIGNATURE-----\n", len) >= len) {
  819. goto err;
  820. }
  821. tor_free(the_runningrouters);
  822. the_runningrouters = s;
  823. the_runningrouters_len = strlen(s);
  824. tor_free(the_runningrouters_z);
  825. if (tor_gzip_compress(&the_runningrouters_z, &the_runningrouters_z_len,
  826. the_runningrouters, the_runningrouters_len,
  827. ZLIB_METHOD)) {
  828. log_fn(LOG_WARN, "Error gzipping runningrouters");
  829. return -1;
  830. }
  831. runningrouters_is_dirty = 0;
  832. /* We don't cache running-routers to disk, so there's no point in
  833. * authdirservers caching it. */
  834. /* dirserv_set_cached_directory(the_runningrouters, time(NULL), 1); */
  835. return 0;
  836. err:
  837. tor_free(s);
  838. tor_free(router_status);
  839. return -1;
  840. }
  841. /** Set *<b>rr</b> to the most recently generated encoded signed
  842. * running-routers list, generating a new one as necessary. Return the
  843. * size of the directory on success, and 0 on failure. */
  844. size_t dirserv_get_runningrouters(const char **rr, int compress)
  845. {
  846. if (!get_options()->AuthoritativeDir) {
  847. cached_dir_t *d = &cached_runningrouters;
  848. *rr = compress ? d->dir_z : d->dir;
  849. if (*rr) {
  850. return compress ? d->dir_z_len : d->dir_len;
  851. } else {
  852. /* no directory yet retrieved */
  853. return 0;
  854. }
  855. }
  856. if (runningrouters_is_dirty &&
  857. runningrouters_is_dirty + DIR_REGEN_SLACK_TIME < time(NULL)) {
  858. if (generate_runningrouters(get_identity_key())) {
  859. log_fn(LOG_ERR, "Couldn't generate running-routers list?");
  860. return 0;
  861. }
  862. }
  863. *rr = compress ? the_runningrouters_z : the_runningrouters;
  864. return compress ? the_runningrouters_z_len : the_runningrouters_len;
  865. }