routers.c 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107
  1. /* Copyright 2001,2002 Roger Dingledine, Matej Pfajfar. */
  2. /* See LICENSE for licensing information */
  3. /* $Id$ */
  4. #define OR_PUBLICKEY_BEGIN_TAG "-----BEGIN RSA PUBLIC KEY-----\n"
  5. #define OR_PUBLICKEY_END_TAG "-----END RSA PUBLIC KEY-----\n"
  6. #define OR_SIGNATURE_BEGIN_TAG "-----BEGIN SIGNATURE-----\n"
  7. #define OR_SIGNATURE_END_TAG "-----END SIGNATURE-----\n"
  8. #define _GNU_SOURCE
  9. /* XXX this is required on rh7 to make strptime not complain. how bad
  10. * is this for portability?
  11. */
  12. #include "or.h"
  13. /****************************************************************************/
  14. /* router array */
  15. static directory_t *directory = NULL;
  16. extern or_options_t options; /* command-line and config-file options */
  17. extern routerinfo_t *my_routerinfo; /* from main.c */
  18. /****************************************************************************/
  19. struct directory_token;
  20. typedef struct directory_token directory_token_t;
  21. /* static function prototypes */
  22. void routerlist_free(routerinfo_t *list);
  23. static char *eat_whitespace(char *s);
  24. static char *eat_whitespace_no_nl(char *s);
  25. static char *find_whitespace(char *s);
  26. static void router_free_exit_policy(routerinfo_t *router);
  27. static int router_add_exit_policy(routerinfo_t *router,
  28. directory_token_t *tok);
  29. static int
  30. router_resolve_directory(directory_t *dir);
  31. /****************************************************************************/
  32. int learn_my_address(struct sockaddr_in *me) {
  33. /* local host information */
  34. char localhostname[256];
  35. struct hostent *localhost;
  36. static struct sockaddr_in answer;
  37. static int already_learned=0;
  38. if(!already_learned) {
  39. /* obtain local host information */
  40. if(gethostname(localhostname,sizeof(localhostname)) < 0) {
  41. log_fn(LOG_WARNING,"Error obtaining local hostname");
  42. return -1;
  43. }
  44. log_fn(LOG_DEBUG,"localhostname is '%s'.",localhostname);
  45. localhost = gethostbyname(localhostname);
  46. if (!localhost) {
  47. log_fn(LOG_WARNING,"Error obtaining local host info.");
  48. /* XXX maybe this is worse than warning? bad things happen when we don't know ourselves */
  49. return -1;
  50. }
  51. memset(&answer,0,sizeof(struct sockaddr_in));
  52. answer.sin_family = AF_INET;
  53. memcpy((void *)&answer.sin_addr,(void *)localhost->h_addr,sizeof(struct in_addr));
  54. answer.sin_port = htons((uint16_t) options.ORPort);
  55. log_fn(LOG_DEBUG,"chose address as '%s'.",inet_ntoa(answer.sin_addr));
  56. if (!strncmp("127.",inet_ntoa(answer.sin_addr), 4) &&
  57. strcasecmp(localhostname, "localhost")) {
  58. /* We're a loopback IP but we're not called localhost. Uh oh! */
  59. log_fn(LOG_WARNING, "Got a loopback address: /etc/hosts may be wrong");
  60. }
  61. already_learned = 1;
  62. }
  63. memcpy(me,&answer,sizeof(struct sockaddr_in));
  64. return 0;
  65. }
  66. void router_retry_connections(void) {
  67. int i;
  68. routerinfo_t *router;
  69. for (i=0;i<directory->n_routers;i++) {
  70. router = directory->routers[i];
  71. if(!connection_exact_get_by_addr_port(router->addr,router->or_port)) { /* not in the list */
  72. log_fn(LOG_DEBUG,"connecting to OR %s:%u.",router->address,router->or_port);
  73. connection_or_connect(router);
  74. }
  75. }
  76. }
  77. routerinfo_t *router_pick_directory_server(void) {
  78. /* currently, pick the first router with a positive dir_port */
  79. int i;
  80. routerinfo_t *router;
  81. if(!directory)
  82. return NULL;
  83. for(i=0;i<directory->n_routers;i++) {
  84. router = directory->routers[i];
  85. if(router->dir_port > 0)
  86. return router;
  87. }
  88. return NULL;
  89. }
  90. void router_upload_desc_to_dirservers(void) {
  91. int i;
  92. routerinfo_t *router;
  93. if(!directory)
  94. return;
  95. for(i=0;i<directory->n_routers;i++) {
  96. router = directory->routers[i];
  97. if(router->dir_port > 0)
  98. directory_initiate_command(router, DIR_CONN_STATE_CONNECTING_UPLOAD);
  99. }
  100. }
  101. routerinfo_t *router_get_by_addr_port(uint32_t addr, uint16_t port) {
  102. int i;
  103. routerinfo_t *router;
  104. assert(directory);
  105. for(i=0;i<directory->n_routers;i++) {
  106. router = directory->routers[i];
  107. if ((router->addr == addr) && (router->or_port == port))
  108. return router;
  109. }
  110. return NULL;
  111. }
  112. routerinfo_t *router_get_by_link_pk(crypto_pk_env_t *pk)
  113. {
  114. int i;
  115. routerinfo_t *router;
  116. assert(directory);
  117. for(i=0;i<directory->n_routers;i++) {
  118. router = directory->routers[i];
  119. if (0 == crypto_pk_cmp_keys(router->link_pkey, pk))
  120. return router;
  121. }
  122. return NULL;
  123. }
  124. #if 0
  125. routerinfo_t *router_get_by_identity_pk(crypto_pk_env_t *pk)
  126. {
  127. int i;
  128. routerinfo_t *router;
  129. assert(directory);
  130. for(i=0;i<directory->n_routers;i++) {
  131. router = directory->routers[i];
  132. /* XXX Should this really be a separate link key? */
  133. if (0 == crypto_pk_cmp_keys(router->identity_pkey, pk))
  134. return router;
  135. }
  136. return NULL;
  137. }
  138. #endif
  139. void router_get_directory(directory_t **pdirectory) {
  140. *pdirectory = directory;
  141. }
  142. /* return 1 if addr and port corresponds to my addr and my or_listenport. else 0,
  143. * or -1 for failure.
  144. */
  145. int router_is_me(uint32_t addr, uint16_t port)
  146. {
  147. /* XXXX Should this check the key too? */
  148. struct sockaddr_in me; /* my router identity */
  149. if(!options.OnionRouter) {
  150. /* we're not an OR. This obviously isn't us. */
  151. return 0;
  152. }
  153. if(learn_my_address(&me) < 0)
  154. return -1;
  155. /* XXX people call this function like a boolean. that's bad news: -1 is true. */
  156. if(ntohl(me.sin_addr.s_addr) == addr && ntohs(me.sin_port) == port)
  157. return 1;
  158. return 0;
  159. }
  160. /* delete a list of routers from memory */
  161. void routerinfo_free(routerinfo_t *router)
  162. {
  163. struct exit_policy_t *e = NULL, *etmp = NULL;
  164. if (!router)
  165. return;
  166. if (router->address)
  167. free(router->address);
  168. if (router->onion_pkey)
  169. crypto_free_pk_env(router->onion_pkey);
  170. if (router->link_pkey)
  171. crypto_free_pk_env(router->link_pkey);
  172. if (router->identity_pkey)
  173. crypto_free_pk_env(router->identity_pkey);
  174. e = router->exit_policy;
  175. while (e) {
  176. etmp = e->next;
  177. if (e->string) free(e->string);
  178. if (e->address) free(e->address);
  179. if (e->port) free(e->port);
  180. free(e);
  181. e = etmp;
  182. }
  183. free(router);
  184. }
  185. void directory_free(directory_t *directory)
  186. {
  187. int i;
  188. for (i = 0; i < directory->n_routers; ++i)
  189. routerinfo_free(directory->routers[i]);
  190. if (directory->routers)
  191. free(directory->routers);
  192. if(directory->software_versions)
  193. free(directory->software_versions);
  194. free(directory);
  195. }
  196. void router_forget_router(uint32_t addr, uint16_t port) {
  197. int i;
  198. routerinfo_t *router;
  199. router = router_get_by_addr_port(addr,port);
  200. if(!router) /* we don't seem to know about him in the first place */
  201. return;
  202. /* now walk down router_array until we get to router */
  203. for(i=0;i<directory->n_routers;i++)
  204. if(directory->routers[i] == router)
  205. break;
  206. assert(i != directory->n_routers); /* if so then router_get_by_addr_port should have returned null */
  207. // free(router); /* don't actually free; we'll free it when we free the whole thing */
  208. // log(LOG_DEBUG,"router_forget_router(): Forgot about router %d:%d",addr,port);
  209. for(; i<directory->n_routers-1;i++)
  210. directory->routers[i] = directory->routers[i+1];
  211. /* XXX bug, we're not decrementing n_routers here? needs more attention. -RD */
  212. }
  213. /* load the router list */
  214. int router_get_list_from_file(char *routerfile)
  215. {
  216. char *string;
  217. string = read_file_to_str(routerfile);
  218. if(!string) {
  219. log_fn(LOG_WARNING,"Failed to load routerfile %s.",routerfile);
  220. return -1;
  221. }
  222. if(router_get_list_from_string(string) < 0) {
  223. log_fn(LOG_WARNING,"The routerfile itself was corrupt.");
  224. free(string);
  225. return -1;
  226. }
  227. free(string);
  228. return 0;
  229. }
  230. typedef enum {
  231. K_ACCEPT,
  232. K_DIRECTORY_SIGNATURE,
  233. K_RECOMMENDED_SOFTWARE,
  234. K_REJECT,
  235. K_ROUTER,
  236. K_SIGNED_DIRECTORY,
  237. K_SIGNING_KEY,
  238. K_ONION_KEY,
  239. K_LINK_KEY,
  240. K_ROUTER_SIGNATURE,
  241. K_PUBLISHED,
  242. K_RUNNING_ROUTERS,
  243. _SIGNATURE,
  244. _PUBLIC_KEY,
  245. _ERR,
  246. _EOF
  247. } directory_keyword;
  248. struct token_table_ent { char *t; int v; };
  249. static struct token_table_ent token_table[] = {
  250. { "accept", K_ACCEPT },
  251. { "directory-signature", K_DIRECTORY_SIGNATURE },
  252. { "reject", K_REJECT },
  253. { "router", K_ROUTER },
  254. { "recommended-software", K_RECOMMENDED_SOFTWARE },
  255. { "signed-directory", K_SIGNED_DIRECTORY },
  256. { "signing-key", K_SIGNING_KEY },
  257. { "onion-key", K_ONION_KEY },
  258. { "link-key", K_LINK_KEY },
  259. { "router-signature", K_ROUTER_SIGNATURE },
  260. { "published", K_PUBLISHED },
  261. { "running-routers", K_RUNNING_ROUTERS },
  262. { NULL, -1 }
  263. };
  264. #define MAX_ARGS 1024
  265. struct directory_token {
  266. directory_keyword tp;
  267. union {
  268. struct {
  269. char *args[MAX_ARGS+1];
  270. int n_args;
  271. } cmd;
  272. char *signature;
  273. char *error;
  274. crypto_pk_env_t *public_key;
  275. } val;
  276. };
  277. /* Free any malloced resources allocated for a token. Don't call this if
  278. you inherit the reference to those resources.
  279. */
  280. static void
  281. router_release_token(directory_token_t *tok)
  282. {
  283. switch (tok->tp)
  284. {
  285. case _SIGNATURE:
  286. free(tok->val.signature);
  287. break;
  288. case _PUBLIC_KEY:
  289. crypto_free_pk_env(tok->val.public_key);
  290. break;
  291. default:
  292. break;
  293. }
  294. }
  295. static int
  296. _router_get_next_token(char **s, directory_token_t *tok) {
  297. char *next;
  298. crypto_pk_env_t *pkey = NULL;
  299. char *signature = NULL;
  300. int i, done;
  301. tok->tp = _ERR;
  302. tok->val.error = "";
  303. *s = eat_whitespace(*s);
  304. if (!**s) {
  305. tok->tp = _EOF;
  306. return 0;
  307. } else if (**s == '-') {
  308. next = strchr(*s, '\n');
  309. if (! next) { tok->val.error = "No newline at EOF"; return -1; }
  310. ++next;
  311. if (! strncmp(*s, OR_PUBLICKEY_BEGIN_TAG, next-*s)) {
  312. next = strstr(*s, OR_PUBLICKEY_END_TAG);
  313. if (!next) { tok->val.error = "No public key end tag found"; return -1; }
  314. next = strchr(next, '\n'); /* Part of OR_PUBLICKEY_END_TAG; can't fail.*/
  315. ++next;
  316. if (!(pkey = crypto_new_pk_env(CRYPTO_PK_RSA)))
  317. return -1;
  318. if (crypto_pk_read_public_key_from_string(pkey, *s, next-*s)) {
  319. crypto_free_pk_env(pkey);
  320. tok->val.error = "Couldn't parse public key.";
  321. return -1;
  322. }
  323. tok->tp = _PUBLIC_KEY;
  324. tok->val.public_key = pkey;
  325. *s = next;
  326. return 0;
  327. } else if (! strncmp(*s, OR_SIGNATURE_BEGIN_TAG, next-*s)) {
  328. /* Advance past newline; can't fail. */
  329. *s = strchr(*s, '\n');
  330. ++*s;
  331. /* Find end of base64'd data */
  332. next = strstr(*s, OR_SIGNATURE_END_TAG);
  333. if (!next) { tok->val.error = "No signature end tag found"; return -1; }
  334. signature = tor_malloc(256);
  335. i = base64_decode(signature, 256, *s, next-*s);
  336. if (i<0) {
  337. free(signature);
  338. tok->val.error = "Error decoding signature."; return -1;
  339. } else if (i != 128) {
  340. free(signature);
  341. tok->val.error = "Bad length on decoded signature."; return -1;
  342. }
  343. tok->tp = _SIGNATURE;
  344. tok->val.signature = signature;
  345. next = strchr(next, '\n'); /* Part of OR_SIGNATURE_END_TAG; can't fail.*/
  346. *s = next+1;
  347. return 0;
  348. } else {
  349. tok->val.error = "Unrecognized begin line"; return -1;
  350. }
  351. } else {
  352. next = find_whitespace(*s);
  353. if (!next) {
  354. tok->val.error = "Unexpected EOF"; return -1;
  355. }
  356. for (i = 0 ; token_table[i].t ; ++i) {
  357. if (!strncmp(token_table[i].t, *s, next-*s)) {
  358. tok->tp = token_table[i].v;
  359. i = 0;
  360. done = (*next == '\n');
  361. *s = eat_whitespace_no_nl(next);
  362. while (**s != '\n' && i <= MAX_ARGS && !done) {
  363. next = find_whitespace(*s);
  364. if (*next == '\n')
  365. done = 1;
  366. *next = 0;
  367. tok->val.cmd.args[i++] = *s;
  368. *s = eat_whitespace_no_nl(next+1);
  369. };
  370. tok->val.cmd.n_args = i;
  371. if (i > MAX_ARGS) {
  372. tok->tp = _ERR;
  373. tok->val.error = "Too many arguments"; return -1;
  374. }
  375. return 0;
  376. }
  377. }
  378. tok->val.error = "Unrecognized command"; return -1;
  379. }
  380. }
  381. #ifdef DEBUG_ROUTER_TOKENS
  382. static void
  383. router_dump_token(directory_token_t *tok) {
  384. int i;
  385. switch(tok->tp)
  386. {
  387. case _SIGNATURE:
  388. puts("(signature)");
  389. return;
  390. case _PUBLIC_KEY:
  391. puts("(public key)");
  392. return;
  393. case _ERR:
  394. printf("(Error: %s\n)", tok->val.error);
  395. return;
  396. case _EOF:
  397. puts("EOF");
  398. return;
  399. case K_ACCEPT: printf("Accept"); break;
  400. case K_DIRECTORY_SIGNATURE: printf("Directory-Signature"); break;
  401. case K_REJECT: printf("Reject"); break;
  402. case K_RECOMMENDED_SOFTWARE: printf("Server-Software"); break;
  403. case K_ROUTER: printf("Router"); break;
  404. case K_SIGNED_DIRECTORY: printf("Signed-Directory"); break;
  405. case K_SIGNING_KEY: printf("Signing-Key"); break;
  406. case K_ONION_KEY: printf("Onion-key"); break;
  407. case K_LINK_KEY: printf("Link-key"); break;
  408. case K_ROUTER_SIGNATURE: printf("Router-signature"); break;
  409. case K_PUBLISHED: printf("Published"); break;
  410. case K_RUNNING_ROUTERS: printf("Running-routers"); break;
  411. default:
  412. printf("?????? %d\n", tok->tp); return;
  413. }
  414. for (i = 0; i < tok->val.cmd.n_args; ++i) {
  415. printf(" \"%s\"", tok->val.cmd.args[i]);
  416. }
  417. printf("\n");
  418. return;
  419. }
  420. static int
  421. router_get_next_token(char **s, directory_token_t *tok) {
  422. int i;
  423. i = _router_get_next_token(s, tok);
  424. router_dump_token(tok);
  425. return i;
  426. }
  427. #else
  428. #define router_get_next_token _router_get_next_token
  429. #endif
  430. /* return the first char of s that is not whitespace and not a comment */
  431. static char *eat_whitespace(char *s) {
  432. assert(s);
  433. while(isspace(*s) || *s == '#') {
  434. while(isspace(*s))
  435. s++;
  436. if(*s == '#') { /* read to a \n or \0 */
  437. while(*s && *s != '\n')
  438. s++;
  439. if(!*s)
  440. return s;
  441. }
  442. }
  443. return s;
  444. }
  445. static char *eat_whitespace_no_nl(char *s) {
  446. while(*s == ' ' || *s == '\t')
  447. ++s;
  448. return s;
  449. }
  450. /* return the first char of s that is whitespace or '#' or '\0 */
  451. static char *find_whitespace(char *s) {
  452. assert(s);
  453. while(*s && !isspace(*s) && *s != '#')
  454. s++;
  455. return s;
  456. }
  457. int router_get_list_from_string(char *s)
  458. {
  459. if (router_get_list_from_string_impl(&s, &directory, -1, NULL)) {
  460. log(LOG_WARNING, "Error parsing router file");
  461. return -1;
  462. }
  463. if (router_resolve_directory(directory)) {
  464. log(LOG_WARNING, "Error resolving directory");
  465. return -1;
  466. }
  467. return 0;
  468. }
  469. static int router_get_hash_impl(char *s, char *digest, const char *start_str,
  470. const char *end_str)
  471. {
  472. char *start, *end;
  473. start = strstr(s, start_str);
  474. if (!start) {
  475. log_fn(LOG_WARNING,"couldn't find \"%s\"",start_str);
  476. return -1;
  477. }
  478. end = strstr(start+strlen(start_str), end_str);
  479. if (!end) {
  480. log_fn(LOG_WARNING,"couldn't find \"%s\"",end_str);
  481. return -1;
  482. }
  483. end = strchr(end, '\n');
  484. if (!end) {
  485. log_fn(LOG_WARNING,"couldn't find EOL");
  486. return -1;
  487. }
  488. ++end;
  489. if (crypto_SHA_digest(start, end-start, digest)) {
  490. log_fn(LOG_WARNING,"couldn't compute digest");
  491. return -1;
  492. }
  493. return 0;
  494. }
  495. int router_get_dir_hash(char *s, char *digest)
  496. {
  497. return router_get_hash_impl(s,digest,
  498. "signed-directory","directory-signature");
  499. }
  500. int router_get_router_hash(char *s, char *digest)
  501. {
  502. return router_get_hash_impl(s,digest,
  503. "router ","router-signature");
  504. }
  505. /* return 0 if myversion is in start. Else return -1. */
  506. int compare_recommended_versions(char *myversion, char *start) {
  507. int len_myversion = strlen(myversion);
  508. char *comma;
  509. char *end = start + strlen(start);
  510. log_fn(LOG_DEBUG,"checking '%s' in '%s'.", myversion, start);
  511. for(;;) {
  512. comma = strchr(start, ',');
  513. if( ((comma ? comma : end) - start == len_myversion) &&
  514. !strncmp(start, myversion, len_myversion)) /* only do strncmp if the length matches */
  515. return 0; /* success, it's there */
  516. if(!comma)
  517. return -1; /* nope */
  518. start = comma+1;
  519. }
  520. }
  521. int router_get_dir_from_string(char *s, crypto_pk_env_t *pkey)
  522. {
  523. if (router_get_dir_from_string_impl(s, &directory, pkey)) {
  524. log_fn(LOG_WARNING, "Couldn't parse directory.");
  525. return -1;
  526. }
  527. if (router_resolve_directory(directory)) {
  528. log_fn(LOG_WARNING, "Error resolving directory");
  529. return -1;
  530. }
  531. if (compare_recommended_versions(VERSION, directory->software_versions) < 0) {
  532. log(LOG_WARNING, "You are running tor version %s, which is no longer supported.\nPlease upgrade to one of %s.", VERSION, RECOMMENDED_SOFTWARE_VERSIONS);
  533. if(options.IgnoreVersion) {
  534. log(LOG_WARNING, "IgnoreVersion is set. If it breaks, we told you so.");
  535. } else {
  536. log(LOG_ERR,"Set IgnoreVersion config variable if you want to proceed.");
  537. fflush(0);
  538. exit(0);
  539. }
  540. }
  541. return 0;
  542. }
  543. int router_get_dir_from_string_impl(char *s, directory_t **dest,
  544. crypto_pk_env_t *pkey)
  545. {
  546. directory_token_t tok;
  547. char digest[20];
  548. char signed_digest[128];
  549. directory_t *new_dir = NULL;
  550. char *versions;
  551. struct tm published;
  552. time_t published_on;
  553. const char *good_nickname_lst[1024];
  554. int n_good_nicknames;
  555. #define NEXT_TOK() \
  556. do { \
  557. if (router_get_next_token(&s, &tok)) { \
  558. log_fn(LOG_WARNING, "Error reading directory: %s", tok.val.error);\
  559. return -1; \
  560. } } while (0)
  561. #define TOK_IS(type,name) \
  562. do { \
  563. if (tok.tp != type) { \
  564. router_release_token(&tok); \
  565. log_fn(LOG_WARNING, "Error reading directory: expected %s", name);\
  566. return -1; \
  567. } } while(0)
  568. if (router_get_dir_hash(s, digest)) {
  569. log_fn(LOG_WARNING, "Unable to compute digest of directory");
  570. goto err;
  571. }
  572. log(LOG_DEBUG,"Received directory hashes to %02x:%02x:%02x:%02x",
  573. ((int)digest[0])&0xff,((int)digest[1])&0xff,
  574. ((int)digest[2])&0xff,((int)digest[3])&0xff);
  575. NEXT_TOK();
  576. TOK_IS(K_SIGNED_DIRECTORY, "signed-directory");
  577. NEXT_TOK();
  578. TOK_IS(K_PUBLISHED, "published");
  579. if (tok.val.cmd.n_args != 2) {
  580. log_fn(LOG_WARNING, "Invalid published line");
  581. goto err;
  582. }
  583. tok.val.cmd.args[1][-1] = ' ';
  584. if (!strptime(tok.val.cmd.args[0], "%Y-%m-%d %H:%M:%S", &published)) {
  585. log_fn(LOG_WARNING, "Published time was unparseable"); goto err;
  586. }
  587. published_on = timegm(&published);
  588. NEXT_TOK();
  589. TOK_IS(K_RECOMMENDED_SOFTWARE, "recommended-software");
  590. if (tok.val.cmd.n_args != 1) {
  591. log_fn(LOG_WARNING, "Invalid recommended-software line");
  592. goto err;
  593. }
  594. versions = strdup(tok.val.cmd.args[0]);
  595. NEXT_TOK();
  596. TOK_IS(K_RUNNING_ROUTERS, "running-routers");
  597. n_good_nicknames = tok.val.cmd.n_args;
  598. memcpy(good_nickname_lst, tok.val.cmd.args, n_good_nicknames*sizeof(char *));
  599. if (router_get_list_from_string_impl(&s, &new_dir,
  600. n_good_nicknames, good_nickname_lst)) {
  601. log_fn(LOG_WARNING, "Error reading routers from directory");
  602. goto err;
  603. }
  604. new_dir->software_versions = versions;
  605. new_dir->published_on = published_on;
  606. NEXT_TOK();
  607. TOK_IS(K_DIRECTORY_SIGNATURE, "directory-signature");
  608. NEXT_TOK();
  609. TOK_IS(_SIGNATURE, "signature");
  610. if (pkey) {
  611. if (crypto_pk_public_checksig(pkey, tok.val.signature, 128, signed_digest)
  612. != 20) {
  613. log_fn(LOG_WARNING, "Error reading directory: invalid signature.");
  614. free(tok.val.signature);
  615. goto err;
  616. }
  617. log(LOG_DEBUG,"Signed directory hash starts %02x:%02x:%02x:%02x",
  618. ((int)signed_digest[0])&0xff,((int)signed_digest[1])&0xff,
  619. ((int)signed_digest[2])&0xff,((int)signed_digest[3])&0xff);
  620. if (memcmp(digest, signed_digest, 20)) {
  621. log_fn(LOG_WARNING, "Error reading directory: signature does not match.");
  622. free(tok.val.signature);
  623. goto err;
  624. }
  625. }
  626. free(tok.val.signature);
  627. NEXT_TOK();
  628. TOK_IS(_EOF, "end of directory");
  629. if (*dest)
  630. directory_free(*dest);
  631. *dest = new_dir;
  632. return 0;
  633. err:
  634. if (new_dir)
  635. directory_free(new_dir);
  636. return -1;
  637. #undef NEXT_TOK
  638. #undef TOK_IS
  639. }
  640. int router_get_list_from_string_impl(char **s, directory_t **dest,
  641. int n_good_nicknames,
  642. const char **good_nickname_lst)
  643. {
  644. routerinfo_t *router;
  645. routerinfo_t **rarray;
  646. int rarray_len = 0;
  647. int i;
  648. assert(s && *s);
  649. rarray = (routerinfo_t **)tor_malloc((sizeof(routerinfo_t *))*MAX_ROUTERS_IN_DIR);
  650. while (1) {
  651. *s = eat_whitespace(*s);
  652. if (strncmp(*s, "router ", 7)!=0)
  653. break;
  654. router = router_get_entry_from_string(s);
  655. if (!router) {
  656. log_fn(LOG_WARNING, "Error reading router");
  657. return -1;
  658. }
  659. if (rarray_len >= MAX_ROUTERS_IN_DIR) {
  660. log_fn(LOG_WARNING, "too many routers");
  661. routerinfo_free(router);
  662. continue;
  663. }
  664. if (n_good_nicknames>=0) {
  665. router->is_running = 0;
  666. for (i = 0; i < n_good_nicknames; ++i) {
  667. if (0==strcasecmp(good_nickname_lst[i], router->nickname)) {
  668. router->is_running = 1;
  669. break;
  670. }
  671. }
  672. }
  673. rarray[rarray_len++] = router;
  674. log_fn(LOG_DEBUG,"just added router #%d.",rarray_len);
  675. }
  676. if (*dest)
  677. directory_free(*dest);
  678. *dest = (directory_t *)tor_malloc(sizeof(directory_t));
  679. (*dest)->routers = rarray;
  680. (*dest)->n_routers = rarray_len;
  681. (*dest)->software_versions = NULL;
  682. return 0;
  683. }
  684. static int
  685. router_resolve(routerinfo_t *router)
  686. {
  687. struct hostent *rent;
  688. rent = (struct hostent *)gethostbyname(router->address);
  689. if (!rent) {
  690. log_fn(LOG_WARNING,"Could not get address for router %s.",router->address);
  691. return -1;
  692. }
  693. assert(rent->h_length == 4);
  694. memcpy(&router->addr, rent->h_addr,rent->h_length);
  695. router->addr = ntohl(router->addr); /* get it back into host order */
  696. return 0;
  697. }
  698. static int
  699. router_resolve_directory(directory_t *dir)
  700. {
  701. int i, max, remove;
  702. if (!dir)
  703. dir = directory;
  704. max = dir->n_routers;
  705. for (i = 0; i < max; ++i) {
  706. remove = 0;
  707. if (router_resolve(dir->routers[i])) {
  708. log_fn(LOG_WARNING, "Couldn't resolve router %s; removing",
  709. dir->routers[i]->address);
  710. remove = 1;
  711. routerinfo_free(dir->routers[i]);
  712. } else if (router_is_me(dir->routers[i]->addr, dir->routers[i]->or_port)) {
  713. my_routerinfo = dir->routers[i];
  714. remove = 1;
  715. }
  716. if (remove) {
  717. dir->routers[i] = dir->routers[--max];
  718. --dir->n_routers;
  719. --i;
  720. }
  721. }
  722. return 0;
  723. }
  724. /* reads a single router entry from s.
  725. * updates s so it points to after the router it just read.
  726. * mallocs a new router, returns it if all goes well, else returns NULL.
  727. */
  728. routerinfo_t *router_get_entry_from_string(char**s) {
  729. routerinfo_t *router = NULL;
  730. char signed_digest[128];
  731. char digest[128];
  732. directory_token_t _tok;
  733. directory_token_t *tok = &_tok;
  734. struct tm published;
  735. #define NEXT_TOKEN() \
  736. do { if (router_get_next_token(s, tok)) { \
  737. log_fn(LOG_WARNING, "Error reading directory: %s", tok->val.error);\
  738. goto err; \
  739. } } while(0)
  740. #define ARGS tok->val.cmd.args
  741. if (router_get_router_hash(*s, digest) < 0)
  742. return NULL;
  743. NEXT_TOKEN();
  744. if (tok->tp != K_ROUTER) {
  745. router_release_token(tok);
  746. log_fn(LOG_WARNING,"Entry does not start with \"router\"");
  747. return NULL;
  748. }
  749. router = tor_malloc(sizeof(routerinfo_t));
  750. memset(router,0,sizeof(routerinfo_t)); /* zero it out first */
  751. /* C doesn't guarantee that NULL is represented by 0 bytes. You'll
  752. thank me for this someday. */
  753. router->onion_pkey = router->identity_pkey = router->link_pkey = NULL;
  754. if (tok->val.cmd.n_args != 6) {
  755. log_fn(LOG_WARNING,"Wrong # of arguments to \"router\"");
  756. goto err;
  757. }
  758. if (!(router->nickname = strdup(ARGS[0])))
  759. goto err;
  760. if (strlen(router->nickname) > MAX_NICKNAME_LEN)
  761. goto err;
  762. if (strspn(router->nickname, LEGAL_NICKNAME_CHARACTERS) !=
  763. strlen(router->nickname))
  764. goto err;
  765. /* read router.address */
  766. if (!(router->address = strdup(ARGS[1])))
  767. goto err;
  768. router->addr = 0;
  769. /* Read router->or_port */
  770. router->or_port = atoi(ARGS[2]);
  771. if(!router->or_port) {
  772. log_fn(LOG_WARNING,"or_port unreadable or 0. Failing.");
  773. goto err;
  774. }
  775. /* Router->ap_port */
  776. router->ap_port = atoi(ARGS[3]);
  777. /* Router->dir_port */
  778. router->dir_port = atoi(ARGS[4]);
  779. /* Router->bandwidth */
  780. router->bandwidth = atoi(ARGS[5]);
  781. if (!router->bandwidth) {
  782. log_fn(LOG_WARNING,"bandwidth unreadable or 0. Failing.");
  783. }
  784. log_fn(LOG_DEBUG,"or_port %d, ap_port %d, dir_port %d, bandwidth %d.",
  785. router->or_port, router->ap_port, router->dir_port, router->bandwidth);
  786. NEXT_TOKEN();
  787. if (tok->tp != K_PUBLISHED) {
  788. log_fn(LOG_WARNING, "Missing published time"); goto err;
  789. }
  790. if (tok->val.cmd.n_args != 2) {
  791. log_fn(LOG_WARNING, "Wrong number of arguments to published"); goto err;
  792. }
  793. ARGS[1][-1] = ' '; /* Re-insert space. */
  794. if (!strptime(ARGS[0], "%Y-%m-%d %H:%M:%S", &published)) {
  795. log_fn(LOG_WARNING, "Published time was unparseable"); goto err;
  796. }
  797. router->published_on = timegm(&published);
  798. NEXT_TOKEN();
  799. if (tok->tp != K_ONION_KEY) {
  800. log_fn(LOG_WARNING, "Missing onion-key"); goto err;
  801. }
  802. NEXT_TOKEN();
  803. if (tok->tp != _PUBLIC_KEY) {
  804. log_fn(LOG_WARNING, "Missing onion key"); goto err;
  805. } /* XXX Check key length */
  806. router->onion_pkey = tok->val.public_key;
  807. NEXT_TOKEN();
  808. if (tok->tp != K_LINK_KEY) {
  809. log_fn(LOG_WARNING, "Missing link-key"); goto err;
  810. }
  811. NEXT_TOKEN();
  812. if (tok->tp != _PUBLIC_KEY) {
  813. log_fn(LOG_WARNING, "Missing link key"); goto err;
  814. } /* XXX Check key length */
  815. router->link_pkey = tok->val.public_key;
  816. NEXT_TOKEN();
  817. if (tok->tp != K_SIGNING_KEY) {
  818. log_fn(LOG_WARNING, "Missing signing-key"); goto err;
  819. }
  820. NEXT_TOKEN();
  821. if (tok->tp != _PUBLIC_KEY) {
  822. log_fn(LOG_WARNING, "Missing signing key"); goto err;
  823. }
  824. router->identity_pkey = tok->val.public_key;
  825. NEXT_TOKEN();
  826. while (tok->tp == K_ACCEPT || tok->tp == K_REJECT) {
  827. router_add_exit_policy(router, tok);
  828. NEXT_TOKEN();
  829. }
  830. if (tok->tp != K_ROUTER_SIGNATURE) {
  831. log_fn(LOG_WARNING,"Missing router signature");
  832. goto err;
  833. }
  834. NEXT_TOKEN();
  835. if (tok->tp != _SIGNATURE) {
  836. log_fn(LOG_WARNING,"Missing router signature");
  837. goto err;
  838. }
  839. assert (router->identity_pkey);
  840. if (crypto_pk_public_checksig(router->identity_pkey, tok->val.signature,
  841. 128, signed_digest) != 20) {
  842. log_fn(LOG_WARNING, "Invalid signature");
  843. goto err;
  844. }
  845. if (memcmp(digest, signed_digest, 20)) {
  846. log_fn(LOG_WARNING, "Mismatched signature");
  847. goto err;
  848. }
  849. return router;
  850. err:
  851. router_release_token(tok);
  852. if(router->address)
  853. free(router->address);
  854. if(router->link_pkey)
  855. crypto_free_pk_env(router->link_pkey);
  856. if(router->onion_pkey)
  857. crypto_free_pk_env(router->onion_pkey);
  858. if(router->identity_pkey)
  859. crypto_free_pk_env(router->identity_pkey);
  860. router_free_exit_policy(router);
  861. free(router);
  862. return NULL;
  863. #undef ARGS
  864. #undef NEXT_TOKEN
  865. }
  866. static void router_free_exit_policy(routerinfo_t *router) {
  867. struct exit_policy_t *tmpe;
  868. while(router->exit_policy) {
  869. tmpe = router->exit_policy;
  870. router->exit_policy = tmpe->next;
  871. free(tmpe->string);
  872. free(tmpe->address);
  873. free(tmpe->port);
  874. free(tmpe);
  875. }
  876. }
  877. static int router_add_exit_policy(routerinfo_t *router,
  878. directory_token_t *tok) {
  879. struct exit_policy_t *tmpe, *newe;
  880. char *arg, *colon;
  881. if (tok->val.cmd.n_args != 1)
  882. return -1;
  883. arg = tok->val.cmd.args[0];
  884. newe = tor_malloc(sizeof(struct exit_policy_t));
  885. memset(newe,0,sizeof(struct exit_policy_t));
  886. newe->string = tor_malloc(8+strlen(arg));
  887. if (tok->tp == K_REJECT) {
  888. strcpy(newe->string, "reject ");
  889. newe->policy_type = EXIT_POLICY_REJECT;
  890. } else {
  891. assert(tok->tp == K_ACCEPT);
  892. strcpy(newe->string, "accept ");
  893. newe->policy_type = EXIT_POLICY_ACCEPT;
  894. }
  895. strcat(newe->string, arg);
  896. colon = strchr(arg,':');
  897. if(!colon)
  898. goto policy_read_failed;
  899. *colon = 0;
  900. newe->address = strdup(arg);
  901. newe->port = strdup(colon+1);
  902. log_fn(LOG_DEBUG,"%s %s:%s",
  903. newe->policy_type == EXIT_POLICY_REJECT ? "reject" : "accept",
  904. newe->address, newe->port);
  905. /* now link newe onto the end of exit_policy */
  906. if(!router->exit_policy) {
  907. router->exit_policy = newe;
  908. return 0;
  909. }
  910. for(tmpe=router->exit_policy; tmpe->next; tmpe=tmpe->next) ;
  911. tmpe->next = newe;
  912. return 0;
  913. policy_read_failed:
  914. assert(newe->string);
  915. log_fn(LOG_WARNING,"Couldn't parse line '%s'. Dropping", newe->string);
  916. if(newe->string)
  917. free(newe->string);
  918. if(newe->address)
  919. free(newe->address);
  920. if(newe->port)
  921. free(newe->port);
  922. free(newe);
  923. return -1;
  924. }
  925. /* Return 0 if my exit policy says to allow connection to conn.
  926. * Else return -1.
  927. */
  928. int router_compare_to_exit_policy(connection_t *conn) {
  929. struct exit_policy_t *tmpe;
  930. if(!my_routerinfo) {
  931. log_fn(LOG_WARNING, "my_routerinfo undefined! Rejected.");
  932. return -1;
  933. }
  934. for(tmpe=my_routerinfo->exit_policy; tmpe; tmpe=tmpe->next) {
  935. assert(tmpe->address);
  936. assert(tmpe->port);
  937. /* Totally ignore the address field of the exit policy, for now. */
  938. if(!strcmp(tmpe->port,"*") || atoi(tmpe->port) == conn->port) {
  939. log_fn(LOG_INFO,"Port '%s' matches '%d'. %s.",
  940. tmpe->port, conn->port,
  941. tmpe->policy_type == EXIT_POLICY_ACCEPT ? "Accepting" : "Rejecting");
  942. if(tmpe->policy_type == EXIT_POLICY_ACCEPT)
  943. return 0;
  944. else
  945. return -1;
  946. }
  947. }
  948. return 0; /* accept all by default. */
  949. }
  950. /*
  951. Local Variables:
  952. mode:c
  953. indent-tabs-mode:nil
  954. c-basic-offset:2
  955. End:
  956. */