routers.c 30 KB

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