routers.c 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365
  1. /**
  2. * routers.c
  3. * Routines for loading the list of routers and their public RSA keys.
  4. *
  5. * Matej Pfajfar <mp292@cam.ac.uk>
  6. */
  7. #define OR_ROUTERLIST_SEPCHARS " \t\n"
  8. #define OR_PUBLICKEY_BEGIN_TAG "-----BEGIN RSA PUBLIC KEY-----\n"
  9. #include "or.h"
  10. /* delete a list of routers from memory */
  11. void delete_routerlist(routerinfo_t *list)
  12. {
  13. routerinfo_t *tmp = NULL;
  14. if (!list)
  15. return;
  16. do
  17. {
  18. tmp=list->next;
  19. free((void *)list->address);
  20. RSA_free(list->pkey);
  21. free((void *)list);
  22. list = tmp;
  23. }
  24. while (list != NULL);
  25. return;
  26. }
  27. /* create an NULL-terminated array of pointers pointing to elements of a router list */
  28. /* this is done in two passes through the list - inefficient but irrelevant as this is
  29. * only done once when op/or start up */
  30. routerinfo_t **make_rarray(routerinfo_t* list, size_t *len)
  31. {
  32. routerinfo_t *tmp=NULL;
  33. int listlen = 0;
  34. routerinfo_t **array=NULL;
  35. routerinfo_t **p=NULL;
  36. if ((!list) || (!len))
  37. return NULL;
  38. /* get the length of the list */
  39. tmp = list;
  40. do
  41. {
  42. listlen++;
  43. tmp = tmp->next;
  44. }
  45. while (tmp != NULL);
  46. array = malloc((listlen+1)*sizeof(routerinfo_t *));
  47. if (!array)
  48. {
  49. log(LOG_ERR,"Error allocating memory.");
  50. return NULL;
  51. }
  52. tmp=list;
  53. p = array;
  54. do
  55. {
  56. *p = tmp;
  57. p++;
  58. tmp = tmp->next;
  59. }
  60. while(tmp != NULL);
  61. *p=NULL;
  62. *len = listlen;
  63. return array;
  64. }
  65. /* load the router list */
  66. routerinfo_t **getrouters(char *routerfile, size_t *lenp)
  67. {
  68. int retval = 0;
  69. char *retp = NULL;
  70. routerinfo_t *router=NULL, *routerlist=NULL, *lastrouter=NULL;
  71. FILE *rf; /* router file */
  72. fpos_t fpos;
  73. char line[512];
  74. char *token;
  75. char *errtest; /* detecting errors in strtoul() calls */
  76. struct hostent *rent;
  77. if ((!routerfile) || (!lenp))
  78. return NULL;
  79. if (strcspn(routerfile,CONFIG_LEGAL_FILENAME_CHARACTERS) != 0)
  80. {
  81. log(LOG_ERR,"Filename %s contains illegal characters.",routerfile);
  82. return NULL;
  83. }
  84. /* open the router list */
  85. rf = fopen(routerfile,"r");
  86. if (!rf)
  87. {
  88. log(LOG_ERR,"Could not open %s.",routerfile);
  89. return NULL;
  90. }
  91. retp= fgets(line,512,rf);
  92. while (retp)
  93. {
  94. log(LOG_DEBUG,"getrouters():Line :%s",line);
  95. token = (char *)strtok(line,OR_ROUTERLIST_SEPCHARS);
  96. if (token)
  97. {
  98. log(LOG_DEBUG,"getrouters():Token : %s",token);
  99. if (token[0] != '#') /* ignore comment lines */
  100. {
  101. router = malloc(sizeof(routerinfo_t));
  102. if (!router)
  103. {
  104. log(LOG_ERR,"Could not allocate memory.");
  105. fclose(rf);
  106. delete_routerlist(routerlist);
  107. return NULL;
  108. }
  109. #if 0
  110. router->conn_bufs = NULL; /* no output buffers */
  111. router->last_conn_buf = NULL;
  112. router->next_to_service = 0;
  113. router->s = -1; /* to signify this router is as yet unconnected */
  114. router->celllen = 0; /* cell buffer is empty */
  115. #endif
  116. /* read the address */
  117. router->address = malloc(strlen(token)+1);
  118. if (!router->address)
  119. {
  120. log(LOG_ERR,"Could not allocate memory.");
  121. fclose(rf);
  122. free((void *)router);
  123. delete_routerlist(routerlist);
  124. return NULL;
  125. }
  126. strcpy(router->address,token);
  127. rent = (struct hostent *)gethostbyname(router->address);
  128. if (!rent)
  129. {
  130. log(LOG_ERR,"Could not get address for router %s.",router->address);
  131. fclose(rf);
  132. free((void *)router->address);
  133. free((void *)router);
  134. delete_routerlist(routerlist);
  135. return NULL;
  136. }
  137. memcpy(&router->addr, rent->h_addr,rent->h_length);
  138. /* read the port */
  139. token = (char *)strtok(NULL,OR_ROUTERLIST_SEPCHARS);
  140. if (token)
  141. {
  142. log(LOG_DEBUG,"getrouters():Token :%s",token);
  143. router->port = (uint16_t)strtoul(token,&errtest,0);
  144. if ((*token != '\0') && (*errtest == '\0')) /* conversion was successful */
  145. {
  146. /* convert port to network format */
  147. router->port = htons(router->port);
  148. /* read min bandwidth */
  149. token = (char *)strtok(NULL,OR_ROUTERLIST_SEPCHARS);
  150. if (token) /* min bandwidth */
  151. {
  152. router->min = (uint32_t)strtoul(token,&errtest,0);
  153. if ((*token != '\0') && (*errtest == '\0')) /* conversion was successful */
  154. {
  155. if (router->min) /* must not be zero */
  156. {
  157. /* read max bandwidth */
  158. token = (char *)strtok(NULL,OR_ROUTERLIST_SEPCHARS);
  159. if (token) /* max bandwidth */
  160. {
  161. router->max = (uint32_t)strtoul(token,&errtest,0);
  162. if ((*token != '\0') && (*errtest == '\0')) /* conversion was successful */
  163. {
  164. if (router->max) /* must not be zero */
  165. {
  166. /* check that there is a public key entry for that router */
  167. retval = fgetpos(rf, &fpos); /* save the current file position
  168. * we wil return to it later if we find a public key */
  169. if (retval == -1)
  170. {
  171. log(LOG_ERR,"Could not save position in %s.",routerfile);
  172. free((void *)router->address);
  173. free((void *)router);
  174. fclose(rf);
  175. delete_routerlist(routerlist);
  176. return NULL;
  177. }
  178. do /* read through to the next non-empty line */
  179. {
  180. retp=fgets(line,512,rf);
  181. if (!retp)
  182. {
  183. log(LOG_ERR,"Could not find a public key entry for router %s:%u.",router->address,router->port);
  184. free((void *)router->address);
  185. free((void *)router);
  186. fclose(rf);
  187. delete_routerlist(routerlist);
  188. return NULL;
  189. }
  190. log(LOG_DEBUG,"getrouters():Line:%s",line);
  191. if ((*line != '#') && ( strspn(line,OR_ROUTERLIST_SEPCHARS) != strlen(line) ))
  192. {
  193. break;
  194. }
  195. } while (1);
  196. if (!strcmp(line,OR_PUBLICKEY_BEGIN_TAG)) /* we've got the public key */
  197. {
  198. retval = fsetpos(rf,&fpos); /* get us back to where we were otherwise crypto lib won't find the key */
  199. if (retval == -1)
  200. {
  201. log(LOG_ERR,"Could not set position in %s.",routerfile);
  202. free((void *)router->address);
  203. free((void *)router);
  204. fclose(rf);
  205. delete_routerlist(routerlist);
  206. return NULL;
  207. }
  208. }
  209. else /* we found something else; this isn't right */
  210. {
  211. log(LOG_ERR,"Could not find a public key entry for router %s:%u.",router->address,router->port);
  212. free((void *)router->address);
  213. free((void *)router);
  214. fclose(rf);
  215. delete_routerlist(routerlist);
  216. return NULL;
  217. }
  218. log(LOG_DEBUG,"getrouters():Reading the key ...");
  219. /* read the public key into router->pkey */
  220. router->pkey=NULL;
  221. router->pkey = PEM_read_RSAPublicKey(rf,&router->pkey,NULL,NULL);
  222. if (!router->pkey) /* something went wrong */
  223. {
  224. log(LOG_ERR,"Could not read public key for router %s:%u.",router->address,router->port);
  225. free((void *)router->address);
  226. free((void *)router);
  227. fclose(rf);
  228. delete_routerlist(routerlist);
  229. return NULL;
  230. }
  231. else /* read the key */
  232. {
  233. log(LOG_DEBUG,"getrouters():Public key size = %u.", RSA_size(router->pkey));
  234. if (RSA_size(router->pkey) != 128) /* keys MUST be 1024 bits in size */
  235. {
  236. log(LOG_ERR,"Key for router %s:%u is not 1024 bits. All keys must be exactly 1024 bits long.",router->address,router->port);
  237. free((void *)router->address);
  238. RSA_free(router->pkey);
  239. free((void *)router);
  240. fclose(rf);
  241. delete_routerlist(routerlist);
  242. return NULL;
  243. }
  244. router->next = NULL;
  245. /* save the entry into the routerlist linked list */
  246. if (!routerlist) /* this is the first entry */
  247. routerlist = router;
  248. else
  249. lastrouter->next = (void *)router;
  250. lastrouter = router;
  251. }
  252. }
  253. else /* maximum link utilisation is zero */
  254. {
  255. log(LOG_ERR,"Entry for router %s doesn't contain a valid maximum bandwidth entry (must be > 0).",router->address);
  256. free((void *)router->address);
  257. free((void *)router);
  258. fclose(rf);
  259. delete_routerlist(routerlist);
  260. return NULL;
  261. }
  262. }
  263. else
  264. {
  265. log(LOG_ERR,"Entry for router %s doesn't seem to contain a valid maximum bandwidth entry.",router->address);
  266. free((void *)router->address);
  267. free((void *)router);
  268. fclose(rf);
  269. delete_routerlist(routerlist);
  270. return NULL;
  271. }
  272. }
  273. else
  274. {
  275. log(LOG_ERR,"Entry for router %s doesn't seem to contain a maximum bandwidth entry.",router->address);
  276. free((void *)router->address);
  277. free((void *)router);
  278. fclose(rf);
  279. delete_routerlist(routerlist);
  280. return NULL;
  281. }
  282. }
  283. else
  284. {
  285. log(LOG_ERR,"Entry for router %s doesn't contain a valid minimum bandwidth entry (must be > 0).",router->address);
  286. free((void *)router->address);
  287. free((void *)router);
  288. fclose(rf);
  289. delete_routerlist(routerlist);
  290. return NULL;
  291. }
  292. }
  293. else
  294. {
  295. log(LOG_ERR,"Entry for router %s doesn't seem to contain a valid minimum bandwidth entry.",router->address);
  296. free((void *)router->address);
  297. free((void *)router);
  298. fclose(rf);
  299. delete_routerlist(routerlist);
  300. return NULL;
  301. }
  302. }
  303. else
  304. {
  305. log(LOG_ERR,"Entry for router %s doesn't seem to contain a minimum bandwidth entry.",router->address);
  306. free((void *)router->address);
  307. free((void *)router);
  308. fclose(rf);
  309. delete_routerlist(routerlist);
  310. return NULL;
  311. }
  312. }
  313. else
  314. {
  315. log(LOG_ERR,"Entry for router %s doesn't seem to contain a valid port number.",router->address);
  316. free((void *)router->address);
  317. free((void *)router);
  318. fclose(rf);
  319. delete_routerlist(routerlist);
  320. return NULL;
  321. }
  322. }
  323. else
  324. {
  325. log(LOG_ERR,"Entry for router %s doesn't seem to contain a port number.",router->address);
  326. free((void *)router->address);
  327. free((void *)router);
  328. fclose(rf);
  329. delete_routerlist(routerlist);
  330. return NULL;
  331. }
  332. }
  333. }
  334. retp=fgets(line,512,rf);
  335. }
  336. fclose(rf);
  337. return make_rarray(routerlist, lenp);
  338. }