routers.c 28 KB

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