routers.c 28 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067
  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. _SIGNATURE,
  260. _PUBLIC_KEY,
  261. _ERR,
  262. _EOF
  263. } directory_keyword;
  264. struct token_table_ent { char *t; int v; };
  265. static struct token_table_ent token_table[] = {
  266. { "accept", K_ACCEPT },
  267. { "directory-signature", K_DIRECTORY_SIGNATURE },
  268. { "reject", K_REJECT },
  269. { "router", K_ROUTER },
  270. { "recommended-software", K_RECOMMENDED_SOFTWARE },
  271. { "signed-directory", K_SIGNED_DIRECTORY },
  272. { "signing-key", K_SIGNING_KEY },
  273. { "onion-key", K_ONION_KEY },
  274. { "link-key", K_LINK_KEY },
  275. { "router-signature", K_ROUTER_SIGNATURE },
  276. { NULL, -1 }
  277. };
  278. #define MAX_ARGS 8
  279. struct directory_token {
  280. directory_keyword tp;
  281. union {
  282. struct {
  283. char *args[MAX_ARGS+1];
  284. int n_args;
  285. } cmd;
  286. char *signature;
  287. char *error;
  288. crypto_pk_env_t *public_key;
  289. } val;
  290. };
  291. /* Free any malloced resources allocated for a token. Don't call this if
  292. you inherit the reference to those resources.
  293. */
  294. static void
  295. router_release_token(directory_token_t *tok)
  296. {
  297. switch (tok->tp)
  298. {
  299. case _SIGNATURE:
  300. free(tok->val.signature);
  301. break;
  302. case _PUBLIC_KEY:
  303. crypto_free_pk_env(tok->val.public_key);
  304. break;
  305. default:
  306. break;
  307. }
  308. }
  309. static int
  310. _router_get_next_token(char **s, directory_token_t *tok) {
  311. char *next;
  312. crypto_pk_env_t *pkey = NULL;
  313. char *signature = NULL;
  314. int i, done;
  315. tok->tp = _ERR;
  316. tok->val.error = "";
  317. *s = eat_whitespace(*s);
  318. if (!**s) {
  319. tok->tp = _EOF;
  320. return 0;
  321. } else if (**s == '-') {
  322. next = strchr(*s, '\n');
  323. if (! next) { tok->val.error = "No newline at EOF"; return -1; }
  324. ++next;
  325. if (! strncmp(*s, OR_PUBLICKEY_BEGIN_TAG, next-*s)) {
  326. next = strstr(*s, OR_PUBLICKEY_END_TAG);
  327. if (!next) { tok->val.error = "No public key end tag found"; return -1; }
  328. next = strchr(next, '\n'); /* Part of OR_PUBLICKEY_END_TAG; can't fail.*/
  329. ++next;
  330. if (!(pkey = crypto_new_pk_env(CRYPTO_PK_RSA)))
  331. return -1;
  332. if (crypto_pk_read_public_key_from_string(pkey, *s, next-*s)) {
  333. crypto_free_pk_env(pkey);
  334. tok->val.error = "Couldn't parse public key.";
  335. return -1;
  336. }
  337. tok->tp = _PUBLIC_KEY;
  338. tok->val.public_key = pkey;
  339. *s = next;
  340. return 0;
  341. } else if (! strncmp(*s, OR_SIGNATURE_BEGIN_TAG, next-*s)) {
  342. /* Advance past newline; can't fail. */
  343. *s = strchr(*s, '\n');
  344. ++*s;
  345. /* Find end of base64'd data */
  346. next = strstr(*s, OR_SIGNATURE_END_TAG);
  347. if (!next) { tok->val.error = "No signature end tag found"; return -1; }
  348. signature = tor_malloc(256);
  349. i = base64_decode(signature, 256, *s, next-*s);
  350. if (i<0) {
  351. free(signature);
  352. tok->val.error = "Error decoding signature."; return -1;
  353. } else if (i != 128) {
  354. free(signature);
  355. tok->val.error = "Bad length on decoded signature."; return -1;
  356. }
  357. tok->tp = _SIGNATURE;
  358. tok->val.signature = signature;
  359. next = strchr(next, '\n'); /* Part of OR_SIGNATURE_END_TAG; can't fail.*/
  360. *s = next+1;
  361. return 0;
  362. } else {
  363. tok->val.error = "Unrecognized begin line"; return -1;
  364. }
  365. } else {
  366. next = find_whitespace(*s);
  367. if (!next) {
  368. tok->val.error = "Unexpected EOF"; return -1;
  369. }
  370. for (i = 0 ; token_table[i].t ; ++i) {
  371. if (!strncmp(token_table[i].t, *s, next-*s)) {
  372. tok->tp = token_table[i].v;
  373. i = 0;
  374. done = (*next == '\n');
  375. *s = eat_whitespace_no_nl(next);
  376. while (**s != '\n' && i <= MAX_ARGS && !done) {
  377. next = find_whitespace(*s);
  378. if (*next == '\n')
  379. done = 1;
  380. *next = 0;
  381. tok->val.cmd.args[i++] = *s;
  382. *s = eat_whitespace_no_nl(next+1);
  383. };
  384. tok->val.cmd.n_args = i;
  385. if (i > MAX_ARGS) {
  386. tok->tp = _ERR;
  387. tok->val.error = "Too many arguments"; return -1;
  388. }
  389. return 0;
  390. }
  391. }
  392. tok->val.error = "Unrecognized command"; return -1;
  393. }
  394. }
  395. #ifdef DEBUG_ROUTER_TOKENS
  396. static void
  397. router_dump_token(directory_token_t *tok) {
  398. int i;
  399. switch(tok->tp)
  400. {
  401. case _SIGNATURE:
  402. puts("(signature)");
  403. return;
  404. case _PUBLIC_KEY:
  405. puts("(public key)");
  406. return;
  407. case _ERR:
  408. printf("(Error: %s\n)", tok->val.error);
  409. return;
  410. case _EOF:
  411. puts("EOF");
  412. return;
  413. case K_ACCEPT: printf("Accept"); break;
  414. case K_DIRECTORY_SIGNATURE: printf("Directory-Signature"); break;
  415. case K_REJECT: printf("Reject"); break;
  416. case K_RECOMMENDED_SOFTWARE: printf("Server-Software"); break;
  417. case K_ROUTER: printf("Router"); break;
  418. case K_SIGNED_DIRECTORY: printf("Signed-Directory"); break;
  419. case K_SIGNING_KEY: printf("Signing-Key"); break;
  420. case K_ONION_KEY: printf("Onion-key"); break;
  421. case K_LINK_KEY: printf("Link-key"); break;
  422. case K_ROUTER_SIGNATURE: printf("Router-signature"); break;
  423. default:
  424. printf("?????? %d\n", tok->tp); return;
  425. }
  426. for (i = 0; i < tok->val.cmd.n_args; ++i) {
  427. printf(" \"%s\"", tok->val.cmd.args[i]);
  428. }
  429. printf("\n");
  430. return;
  431. }
  432. static int
  433. router_get_next_token(char **s, directory_token_t *tok) {
  434. int i;
  435. i = _router_get_next_token(s, tok);
  436. router_dump_token(tok);
  437. return i;
  438. }
  439. #else
  440. #define router_get_next_token _router_get_next_token
  441. #endif
  442. /* return the first char of s that is not whitespace and not a comment */
  443. static char *eat_whitespace(char *s) {
  444. assert(s);
  445. while(isspace(*s) || *s == '#') {
  446. while(isspace(*s))
  447. s++;
  448. if(*s == '#') { /* read to a \n or \0 */
  449. while(*s && *s != '\n')
  450. s++;
  451. if(!*s)
  452. return s;
  453. }
  454. }
  455. return s;
  456. }
  457. static char *eat_whitespace_no_nl(char *s) {
  458. while(*s == ' ' || *s == '\t')
  459. ++s;
  460. return s;
  461. }
  462. /* return the first char of s that is whitespace or '#' or '\0 */
  463. static char *find_whitespace(char *s) {
  464. assert(s);
  465. while(*s && !isspace(*s) && *s != '#')
  466. s++;
  467. return s;
  468. }
  469. int router_get_list_from_string(char *s)
  470. {
  471. if (router_get_list_from_string_impl(&s, &directory)) {
  472. log(LOG_WARNING, "Error parsing router file");
  473. return -1;
  474. }
  475. if (router_resolve_directory(directory)) {
  476. log(LOG_WARNING, "Error resolving directory");
  477. return -1;
  478. }
  479. return 0;
  480. }
  481. static int router_get_hash_impl(char *s, char *digest, const char *start_str,
  482. const char *end_str)
  483. {
  484. char *start, *end;
  485. start = strstr(s, start_str);
  486. if (!start) {
  487. log_fn(LOG_WARNING,"couldn't find \"%s\"",start_str);
  488. return -1;
  489. }
  490. end = strstr(start+strlen(start_str), end_str);
  491. if (!end) {
  492. log_fn(LOG_WARNING,"couldn't find \"%s\"",end_str);
  493. return -1;
  494. }
  495. end = strchr(end, '\n');
  496. if (!end) {
  497. log_fn(LOG_WARNING,"couldn't find EOL");
  498. return -1;
  499. }
  500. ++end;
  501. if (crypto_SHA_digest(start, end-start, digest)) {
  502. log_fn(LOG_WARNING,"couldn't compute digest");
  503. return -1;
  504. }
  505. return 0;
  506. }
  507. static int router_get_dir_hash(char *s, char *digest)
  508. {
  509. return router_get_hash_impl(s,digest,
  510. "signed-directory","directory-signature");
  511. }
  512. int router_get_router_hash(char *s, char *digest)
  513. {
  514. return router_get_hash_impl(s,digest,
  515. "router ","router-signature");
  516. }
  517. /* return 0 if myversion is in start. Else return -1. */
  518. int compare_recommended_versions(char *myversion, char *start) {
  519. int len_myversion = strlen(myversion);
  520. char *comma;
  521. char *end = start + strlen(start);
  522. log_fn(LOG_DEBUG,"checking '%s' in '%s'.", myversion, start);
  523. for(;;) {
  524. comma = strchr(start, ',');
  525. if( ((comma ? comma : end) - start == len_myversion) &&
  526. !strncmp(start, myversion, len_myversion)) /* only do strncmp if the length matches */
  527. return 0; /* success, it's there */
  528. if(!comma)
  529. return -1; /* nope */
  530. start = comma+1;
  531. }
  532. }
  533. int router_get_dir_from_string(char *s, crypto_pk_env_t *pkey)
  534. {
  535. if (router_get_dir_from_string_impl(s, &directory, pkey)) {
  536. log_fn(LOG_WARNING, "Couldn't parse directory.");
  537. return -1;
  538. }
  539. if (router_resolve_directory(directory)) {
  540. log_fn(LOG_WARNING, "Error resolving directory");
  541. return -1;
  542. }
  543. if (compare_recommended_versions(VERSION, directory->software_versions) < 0) {
  544. log(LOG_WARNING, "You are running tor version %s, which is no longer supported.\nPlease upgrade to one of %s.", VERSION, RECOMMENDED_SOFTWARE_VERSIONS);
  545. if(options.IgnoreVersion) {
  546. log(LOG_WARNING, "IgnoreVersion is set. If it breaks, we told you so.");
  547. } else {
  548. log(LOG_ERR,"Set IgnoreVersion config variable if you want to proceed.");
  549. fflush(0);
  550. exit(0);
  551. }
  552. }
  553. return 0;
  554. }
  555. int router_get_dir_from_string_impl(char *s, directory_t **dest,
  556. crypto_pk_env_t *pkey)
  557. {
  558. directory_token_t tok;
  559. char digest[20];
  560. char signed_digest[128];
  561. directory_t *new_dir = NULL;
  562. char *versions;
  563. #define NEXT_TOK() \
  564. do { \
  565. if (router_get_next_token(&s, &tok)) { \
  566. log_fn(LOG_WARNING, "Error reading directory: %s", tok.val.error);\
  567. return -1; \
  568. } } while (0)
  569. #define TOK_IS(type,name) \
  570. do { \
  571. if (tok.tp != type) { \
  572. router_release_token(&tok); \
  573. log_fn(LOG_WARNING, "Error reading directory: expected %s", name);\
  574. return -1; \
  575. } } while(0)
  576. if (router_get_dir_hash(s, digest)) {
  577. log_fn(LOG_WARNING, "Unable to compute digest of directory");
  578. goto err;
  579. }
  580. NEXT_TOK();
  581. TOK_IS(K_SIGNED_DIRECTORY, "signed-directory");
  582. NEXT_TOK();
  583. TOK_IS(K_RECOMMENDED_SOFTWARE, "recommended-software");
  584. if (tok.val.cmd.n_args != 1) {
  585. log_fn(LOG_WARNING, "Invalid recommded-software line");
  586. goto err;
  587. }
  588. versions = strdup(tok.val.cmd.args[0]);
  589. if (router_get_list_from_string_impl(&s, &new_dir)) {
  590. log_fn(LOG_WARNING, "Error reading routers from directory");
  591. goto err;
  592. }
  593. new_dir->software_versions = versions;
  594. NEXT_TOK();
  595. TOK_IS(K_DIRECTORY_SIGNATURE, "directory-signature");
  596. NEXT_TOK();
  597. TOK_IS(_SIGNATURE, "signature");
  598. if (pkey) {
  599. if (crypto_pk_public_checksig(pkey, tok.val.signature, 128, signed_digest)
  600. != 20) {
  601. log_fn(LOG_WARNING, "Error reading directory: invalid signature.");
  602. free(tok.val.signature);
  603. goto err;
  604. }
  605. if (memcmp(digest, signed_digest, 20)) {
  606. log_fn(LOG_WARNING, "Error reading directory: signature does not match.");
  607. free(tok.val.signature);
  608. goto err;
  609. }
  610. }
  611. free(tok.val.signature);
  612. NEXT_TOK();
  613. TOK_IS(_EOF, "end of directory");
  614. if (*dest)
  615. directory_free(*dest);
  616. *dest = new_dir;
  617. return 0;
  618. err:
  619. if (new_dir)
  620. directory_free(new_dir);
  621. return -1;
  622. #undef NEXT_TOK
  623. #undef TOK_IS
  624. }
  625. int router_get_list_from_string_impl(char **s, directory_t **dest)
  626. {
  627. routerinfo_t *router;
  628. routerinfo_t **rarray;
  629. int rarray_len = 0;
  630. assert(s);
  631. rarray = (routerinfo_t **)tor_malloc((sizeof(routerinfo_t *))*MAX_ROUTERS_IN_DIR);
  632. while (1) {
  633. *s = eat_whitespace(*s);
  634. if (strncmp(*s, "router ", 7)!=0)
  635. break;
  636. router = router_get_entry_from_string(s);
  637. if (!router) {
  638. log_fn(LOG_WARNING, "Error reading router");
  639. return -1;
  640. }
  641. if (rarray_len >= MAX_ROUTERS_IN_DIR) {
  642. log_fn(LOG_WARNING, "too many routers");
  643. routerinfo_free(router);
  644. continue;
  645. }
  646. rarray[rarray_len++] = router;
  647. }
  648. if (*dest)
  649. directory_free(*dest);
  650. *dest = (directory_t *)tor_malloc(sizeof(directory_t));
  651. (*dest)->routers = rarray;
  652. (*dest)->n_routers = rarray_len;
  653. (*dest)->software_versions = NULL;
  654. return 0;
  655. }
  656. static int
  657. router_resolve(routerinfo_t *router)
  658. {
  659. struct hostent *rent;
  660. rent = (struct hostent *)gethostbyname(router->address);
  661. if (!rent) {
  662. log_fn(LOG_WARNING,"Could not get address for router %s.",router->address);
  663. return -1;
  664. }
  665. assert(rent->h_length == 4);
  666. memcpy(&router->addr, rent->h_addr,rent->h_length);
  667. router->addr = ntohl(router->addr); /* get it back into host order */
  668. return 0;
  669. }
  670. static int
  671. router_resolve_directory(directory_t *dir)
  672. {
  673. int i, max, remove;
  674. if (!dir)
  675. dir = directory;
  676. max = dir->n_routers;
  677. for (i = 0; i < max; ++i) {
  678. remove = 0;
  679. if (router_resolve(dir->routers[i])) {
  680. log_fn(LOG_WARNING, "Couldn't resolve router %s; removing",
  681. dir->routers[i]->address);
  682. remove = 1;
  683. routerinfo_free(dir->routers[i]);
  684. } else if (router_is_me(dir->routers[i]->addr, dir->routers[i]->or_port)) {
  685. my_routerinfo = dir->routers[i];
  686. remove = 1;
  687. }
  688. if (remove) {
  689. dir->routers[i] = dir->routers[--max];
  690. --dir->n_routers;
  691. --i;
  692. }
  693. }
  694. return 0;
  695. }
  696. /* reads a single router entry from s.
  697. * updates s so it points to after the router it just read.
  698. * mallocs a new router, returns it if all goes well, else returns NULL.
  699. */
  700. routerinfo_t *router_get_entry_from_string(char**s) {
  701. routerinfo_t *router = NULL;
  702. #if 0
  703. char signed_digest[128];
  704. #endif
  705. char digest[128];
  706. directory_token_t _tok;
  707. directory_token_t *tok = &_tok;
  708. #define NEXT_TOKEN() \
  709. do { if (router_get_next_token(s, tok)) { \
  710. log_fn(LOG_WARNING, "Error reading directory: %s", tok->val.error);\
  711. goto err; \
  712. } } while(0)
  713. #define ARGS tok->val.cmd.args
  714. if (router_get_router_hash(*s, digest) < 0)
  715. return NULL;
  716. NEXT_TOKEN();
  717. if (tok->tp != K_ROUTER) {
  718. router_release_token(tok);
  719. log_fn(LOG_WARNING,"Entry does not start with \"router\"");
  720. return NULL;
  721. }
  722. router = tor_malloc(sizeof(routerinfo_t));
  723. memset(router,0,sizeof(routerinfo_t)); /* zero it out first */
  724. /* C doesn't guarantee that NULL is represented by 0 bytes. You'll
  725. thank me for this someday. */
  726. router->onion_pkey = router->identity_pkey = router->link_pkey = NULL;
  727. if (tok->val.cmd.n_args != 5) {
  728. log_fn(LOG_WARNING,"Wrong # of arguments to \"router\"");
  729. goto err;
  730. }
  731. /* read router.address */
  732. if (!(router->address = strdup(ARGS[0])))
  733. goto err;
  734. router->addr = 0;
  735. /* Read router->or_port */
  736. router->or_port = atoi(ARGS[1]);
  737. if(!router->or_port) {
  738. log_fn(LOG_WARNING,"or_port unreadable or 0. Failing.");
  739. goto err;
  740. }
  741. /* Router->ap_port */
  742. router->ap_port = atoi(ARGS[2]);
  743. /* Router->dir_port */
  744. router->dir_port = atoi(ARGS[3]);
  745. /* Router->bandwidth */
  746. router->bandwidth = atoi(ARGS[4]);
  747. if (!router->bandwidth) {
  748. log_fn(LOG_WARNING,"bandwidth unreadable or 0. Failing.");
  749. }
  750. log_fn(LOG_DEBUG,"or_port %d, ap_port %d, dir_port %d, bandwidth %d.",
  751. router->or_port, router->ap_port, router->dir_port, router->bandwidth);
  752. NEXT_TOKEN();
  753. if (tok->tp != K_ONION_KEY) {
  754. log_fn(LOG_WARNING, "Missing onion-key"); goto err;
  755. }
  756. NEXT_TOKEN();
  757. if (tok->tp != _PUBLIC_KEY) {
  758. log_fn(LOG_WARNING, "Missing onion key"); goto err;
  759. } /* XXX Check key length */
  760. router->onion_pkey = tok->val.public_key;
  761. NEXT_TOKEN();
  762. if (tok->tp != K_LINK_KEY) {
  763. log_fn(LOG_WARNING, "Missing link-key"); goto err;
  764. }
  765. NEXT_TOKEN();
  766. if (tok->tp != _PUBLIC_KEY) {
  767. log_fn(LOG_WARNING, "Missing link key"); goto err;
  768. } /* XXX Check key length */
  769. router->link_pkey = tok->val.public_key;
  770. NEXT_TOKEN();
  771. if (tok->tp != K_SIGNING_KEY) {
  772. log_fn(LOG_WARNING, "Missing signing-key"); goto err;
  773. }
  774. NEXT_TOKEN();
  775. if (tok->tp != _PUBLIC_KEY) {
  776. log_fn(LOG_WARNING, "Missing signing key"); goto err;
  777. }
  778. router->identity_pkey = tok->val.public_key;
  779. NEXT_TOKEN();
  780. while (tok->tp == K_ACCEPT || tok->tp == K_REJECT) {
  781. router_add_exit_policy(router, tok);
  782. NEXT_TOKEN();
  783. }
  784. if (tok->tp != K_ROUTER_SIGNATURE) {
  785. log_fn(LOG_WARNING,"Missing router signature");
  786. goto err;
  787. }
  788. NEXT_TOKEN();
  789. if (tok->tp != _SIGNATURE) {
  790. log_fn(LOG_WARNING,"Missing router signature");
  791. goto err;
  792. }
  793. assert (router->identity_pkey);
  794. #if 0
  795. /* XXX This should get re-enabled, once directory servers properly
  796. * XXX relay signed router blocks. */
  797. if (crypto_pk_public_checksig(router->identity_pkey, tok->val.signature,
  798. 128, signed_digest) != 20) {
  799. log_fn(LOG_WARNING, "Invalid signature");
  800. goto err;
  801. }
  802. if (memcmp(digest, signed_digest, 20)) {
  803. log_fn(LOG_WARNING, "Mismatched signature");
  804. goto err;
  805. }
  806. #endif
  807. return router;
  808. err:
  809. router_release_token(tok);
  810. if(router->address)
  811. free(router->address);
  812. if(router->link_pkey)
  813. crypto_free_pk_env(router->link_pkey);
  814. if(router->onion_pkey)
  815. crypto_free_pk_env(router->onion_pkey);
  816. if(router->identity_pkey)
  817. crypto_free_pk_env(router->identity_pkey);
  818. router_free_exit_policy(router);
  819. free(router);
  820. return NULL;
  821. #undef ARGS
  822. #undef NEXT_TOKEN
  823. }
  824. static void router_free_exit_policy(routerinfo_t *router) {
  825. struct exit_policy_t *tmpe;
  826. while(router->exit_policy) {
  827. tmpe = router->exit_policy;
  828. router->exit_policy = tmpe->next;
  829. free(tmpe->string);
  830. free(tmpe->address);
  831. free(tmpe->port);
  832. free(tmpe);
  833. }
  834. }
  835. static int router_add_exit_policy(routerinfo_t *router,
  836. directory_token_t *tok) {
  837. struct exit_policy_t *tmpe, *newe;
  838. char *arg, *colon;
  839. if (tok->val.cmd.n_args != 1)
  840. return -1;
  841. arg = tok->val.cmd.args[0];
  842. newe = tor_malloc(sizeof(struct exit_policy_t));
  843. memset(newe,0,sizeof(struct exit_policy_t));
  844. newe->string = tor_malloc(8+strlen(arg));
  845. if (tok->tp == K_REJECT) {
  846. strcpy(newe->string, "reject ");
  847. newe->policy_type = EXIT_POLICY_REJECT;
  848. } else {
  849. assert(tok->tp == K_ACCEPT);
  850. strcpy(newe->string, "accept ");
  851. newe->policy_type = EXIT_POLICY_ACCEPT;
  852. }
  853. strcat(newe->string, arg);
  854. colon = strchr(arg,':');
  855. if(!colon)
  856. goto policy_read_failed;
  857. *colon = 0;
  858. newe->address = strdup(arg);
  859. newe->port = strdup(colon+1);
  860. log_fn(LOG_DEBUG,"%s %s:%s",
  861. newe->policy_type == EXIT_POLICY_REJECT ? "reject" : "accept",
  862. newe->address, newe->port);
  863. /* now link newe onto the end of exit_policy */
  864. if(!router->exit_policy) {
  865. router->exit_policy = newe;
  866. return 0;
  867. }
  868. for(tmpe=router->exit_policy; tmpe->next; tmpe=tmpe->next) ;
  869. tmpe->next = newe;
  870. return 0;
  871. policy_read_failed:
  872. assert(newe->string);
  873. log_fn(LOG_WARNING,"Couldn't parse line '%s'. Dropping", newe->string);
  874. if(newe->string)
  875. free(newe->string);
  876. if(newe->address)
  877. free(newe->address);
  878. if(newe->port)
  879. free(newe->port);
  880. free(newe);
  881. return -1;
  882. }
  883. /* Return 0 if my exit policy says to allow connection to conn.
  884. * Else return -1.
  885. */
  886. int router_compare_to_exit_policy(connection_t *conn) {
  887. struct exit_policy_t *tmpe;
  888. if(!my_routerinfo) {
  889. log_fn(LOG_WARNING, "my_routerinfo undefined! Rejected.");
  890. return -1;
  891. }
  892. for(tmpe=my_routerinfo->exit_policy; tmpe; tmpe=tmpe->next) {
  893. assert(tmpe->address);
  894. assert(tmpe->port);
  895. /* Totally ignore the address field of the exit policy, for now. */
  896. if(!strcmp(tmpe->port,"*") || atoi(tmpe->port) == conn->port) {
  897. log_fn(LOG_INFO,"Port '%s' matches '%d'. %s.",
  898. tmpe->port, conn->port,
  899. tmpe->policy_type == EXIT_POLICY_ACCEPT ? "Accepting" : "Rejecting");
  900. if(tmpe->policy_type == EXIT_POLICY_ACCEPT)
  901. return 0;
  902. else
  903. return -1;
  904. }
  905. }
  906. return 0; /* accept all by default. */
  907. }
  908. /*
  909. Local Variables:
  910. mode:c
  911. indent-tabs-mode:nil
  912. c-basic-offset:2
  913. End:
  914. */