routers.c 29 KB

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