connection_or.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580
  1. #include "or.h"
  2. /*
  3. *
  4. * these two functions are the main ways 'in' to connection_or
  5. *
  6. */
  7. int connection_or_process_inbuf(connection_t *conn) {
  8. assert(conn && conn->type == CONN_TYPE_OR);
  9. if(conn->inbuf_reached_eof) {
  10. /* eof reached, kill it. */
  11. log(LOG_DEBUG,"connection_or_process_inbuf(): conn reached eof. Closing.");
  12. return -1;
  13. }
  14. log(LOG_DEBUG,"connection_or_process_inbuf(): state %d.",conn->state);
  15. switch(conn->state) {
  16. case OR_CONN_STATE_CLIENT_AUTH_WAIT:
  17. return or_handshake_client_process_auth(conn);
  18. case OR_CONN_STATE_SERVER_AUTH_WAIT:
  19. return or_handshake_server_process_auth(conn);
  20. case OR_CONN_STATE_SERVER_NONCE_WAIT:
  21. return or_handshake_server_process_nonce(conn);
  22. case OR_CONN_STATE_OPEN:
  23. return connection_process_cell_from_inbuf(conn);
  24. default:
  25. log(LOG_DEBUG,"connection_or_process_inbuf() called in state where I'm writing. Ignoring buf for now.");
  26. }
  27. return 0;
  28. }
  29. int connection_or_finished_flushing(connection_t *conn) {
  30. int e, len=sizeof(e);
  31. assert(conn && conn->type == CONN_TYPE_OR);
  32. switch(conn->state) {
  33. case OR_CONN_STATE_CLIENT_CONNECTING:
  34. if (getsockopt(conn->s, SOL_SOCKET, SO_ERROR, &e, &len) < 0) { /* not yet */
  35. if(errno != EINPROGRESS){
  36. /* yuck. kill it. */
  37. log(LOG_DEBUG,"connection_or_finished_flushing(): in-progress connect failed. Removing.");
  38. return -1;
  39. } else {
  40. return 0; /* no change, see if next time is better */
  41. }
  42. }
  43. /* the connect has finished. */
  44. log(LOG_DEBUG,"connection_or_finished_flushing() : Connection to router %s:%u established.",
  45. conn->address,ntohs(conn->port));
  46. return or_handshake_client_send_auth(conn);
  47. case OR_CONN_STATE_CLIENT_SENDING_AUTH:
  48. log(LOG_DEBUG,"connection_or_finished_flushing(): client finished sending auth.");
  49. conn->state = OR_CONN_STATE_CLIENT_AUTH_WAIT;
  50. connection_watch_events(conn, POLLIN);
  51. return 0;
  52. case OR_CONN_STATE_CLIENT_SENDING_NONCE:
  53. log(LOG_DEBUG,"connection_or_finished_flushing(): client finished sending nonce.");
  54. conn_or_init_crypto(conn);
  55. conn->state = OR_CONN_STATE_OPEN;
  56. connection_watch_events(conn, POLLIN);
  57. return 0;
  58. case OR_CONN_STATE_SERVER_SENDING_AUTH:
  59. log(LOG_DEBUG,"connection_or_finished_flushing(): server finished sending auth.");
  60. conn->state = OR_CONN_STATE_SERVER_NONCE_WAIT;
  61. connection_watch_events(conn, POLLIN);
  62. return 0;
  63. case OR_CONN_STATE_OPEN:
  64. /* FIXME down the road, we'll clear out circuits that are pending to close */
  65. connection_watch_events(conn, POLLIN);
  66. return 0;
  67. default:
  68. log(LOG_DEBUG,"Bug: connection_or_finished_flushing() called in unexpected state.");
  69. return 0;
  70. }
  71. return 0;
  72. }
  73. /*********************/
  74. connection_t *connection_or_new(void) {
  75. return connection_new(CONN_TYPE_OR);
  76. }
  77. connection_t *connection_or_new_listener(void) {
  78. return connection_new(CONN_TYPE_OR_LISTENER);
  79. }
  80. void conn_or_init_crypto(connection_t *conn) {
  81. int x;
  82. assert(conn);
  83. printf("f_session_key: ");
  84. for(x=0;x<8;x++) {
  85. printf("%d ",conn->f_session_key[x]);
  86. }
  87. printf("\nb_session_key: ");
  88. for(x=0;x<8;x++) {
  89. printf("%d ",conn->b_session_key[x]);
  90. }
  91. printf("\n");
  92. memset(conn->f_session_iv,0,8);
  93. memset(conn->b_session_iv,0,8);
  94. EVP_CIPHER_CTX_init(&conn->f_ctx);
  95. EVP_CIPHER_CTX_init(&conn->b_ctx);
  96. EVP_EncryptInit(&conn->f_ctx, EVP_des_ofb(), conn->f_session_key, conn->f_session_iv);
  97. EVP_DecryptInit(&conn->b_ctx, EVP_des_ofb(), conn->b_session_key, conn->b_session_iv);
  98. /* always encrypt with f, always decrypt with b */
  99. }
  100. /*
  101. *
  102. * auth handshake, as performed by OR *initiating* the connection
  103. *
  104. */
  105. int connect_to_router(routerinfo_t *router, RSA *prkey, struct sockaddr_in *local) {
  106. connection_t *conn;
  107. struct sockaddr_in router_addr;
  108. int s;
  109. if ((!router) || (!prkey) || (!local))
  110. return -1;
  111. if(router->addr == local->sin_addr.s_addr && router->port == local->sin_port) {
  112. /* this is me! don't connect to me. */
  113. return 0;
  114. }
  115. conn = connection_or_new();
  116. /* set up conn so it's got all the data we need to remember */
  117. conn->addr = router->addr, conn->port = router->port;
  118. conn->prkey = prkey;
  119. conn->min = router->min, conn->max = router->max;
  120. conn->pkey = router->pkey;
  121. conn->address = strdup(router->address);
  122. memcpy(&conn->local,local,sizeof(struct sockaddr_in));
  123. s=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
  124. if (s < 0)
  125. {
  126. log(LOG_ERR,"Error creating network socket.");
  127. connection_free(conn);
  128. return -1;
  129. }
  130. fcntl(s, F_SETFL, O_NONBLOCK); /* set s to non-blocking */
  131. memset((void *)&router_addr,0,sizeof(router_addr));
  132. router_addr.sin_family = AF_INET;
  133. router_addr.sin_port = router->port;
  134. memcpy((void *)&router_addr.sin_addr, &router->addr, sizeof(uint32_t));
  135. log(LOG_DEBUG,"connect_to_router() : Trying to connect to %s:%u.",inet_ntoa(*(struct in_addr *)&router->addr),ntohs(router->port));
  136. if(connect(s,(struct sockaddr *)&router_addr,sizeof(router_addr)) < 0){
  137. if(errno != EINPROGRESS){
  138. /* yuck. kill it. */
  139. connection_free(conn);
  140. return -1;
  141. } else {
  142. /* it's in progress. set state appropriately and return. */
  143. conn->s = s;
  144. conn->state = OR_CONN_STATE_CLIENT_CONNECTING;
  145. if(connection_add(conn) < 0) { /* no space, forget it */
  146. connection_free(conn);
  147. return -1;
  148. }
  149. /* i think only pollout is needed, but i'm curious if pollin ever gets caught -RD */
  150. log(LOG_DEBUG,"connect_to_router() : connect in progress.");
  151. connection_watch_events(conn, POLLOUT | POLLIN);
  152. return 0;
  153. }
  154. }
  155. /* it succeeded. we're connected. */
  156. conn->s = s;
  157. if(connection_add(conn) < 0) { /* no space, forget it */
  158. connection_free(conn);
  159. return -1;
  160. }
  161. log(LOG_DEBUG,"connect_to_router() : Connection to router %s:%u established.",router->address,ntohs(router->port));
  162. /* move to the next step in the handshake */
  163. if(or_handshake_client_send_auth(conn) < 0) {
  164. connection_remove(conn);
  165. connection_free(conn);
  166. return -1;
  167. }
  168. return 0;
  169. }
  170. int or_handshake_client_send_auth(connection_t *conn) {
  171. int retval;
  172. char keys[16];
  173. char buf[44];
  174. char cipher[128];
  175. if (!conn)
  176. return -1;
  177. /* generate random keys */
  178. retval = RAND_bytes(keys,16);
  179. if (retval != 1) /* error */
  180. {
  181. log(LOG_ERR,"Cannot generate a secure DES key.");
  182. return -1;
  183. }
  184. log(LOG_DEBUG,"or_handshake_client_send_auth() : Generated DES keys.");
  185. /* save keys */
  186. memcpy(conn->f_session_key,keys,8);
  187. memcpy(conn->b_session_key,keys+8,8);
  188. /* generate first message */
  189. memcpy(buf,&conn->local.sin_addr,4); /* local address */
  190. memcpy(buf+4,(void *)&conn->local.sin_port,2); /* local port */
  191. memcpy(buf+6, (void *)&conn->addr, 4); /* remote address */
  192. memcpy(buf+10, (void *)&conn->port, 2); /* remote port */
  193. memcpy(buf+12,keys,16); /* keys */
  194. *((uint32_t *)(buf+28)) = htonl(conn->min); /* min link utilisation */
  195. *((uint32_t *)(buf+32)) = htonl(conn->max); /* maximum link utilisation */
  196. log(LOG_DEBUG,"or_handshake_client_send_auth() : Generated first authentication message.");
  197. /* encrypt message */
  198. retval = RSA_public_encrypt(36,buf,cipher,conn->pkey,RSA_PKCS1_PADDING);
  199. if (retval == -1) /* error */
  200. {
  201. log(LOG_ERR,"Public-key encryption failed during authentication to %s:%u.",conn->address,ntohs(conn->port));
  202. log(LOG_DEBUG,"or_handshake_client_send_auth() : Reason : %s.",ERR_reason_error_string(ERR_get_error()));
  203. return -1;
  204. }
  205. log(LOG_DEBUG,"or_handshake_client_send_auth() : Encrypted authentication message.");
  206. /* send message */
  207. if(connection_write_to_buf(cipher, 128, conn) < 0) {
  208. log(LOG_DEBUG,"or_handshake_client_send_auth(): my outbuf is full. Oops.");
  209. return -1;
  210. }
  211. retval = connection_flush_buf(conn);
  212. if(retval < 0) {
  213. log(LOG_DEBUG,"or_handshake_client_send_auth(): bad socket while flushing.");
  214. return -1;
  215. }
  216. if(retval > 0) {
  217. /* still stuff on the buffer. */
  218. conn->state = OR_CONN_STATE_CLIENT_SENDING_AUTH;
  219. connection_watch_events(conn, POLLOUT | POLLIN);
  220. return 0;
  221. }
  222. /* it finished sending */
  223. log(LOG_DEBUG,"or_handshake_client_send_auth(): Finished sending authentication message.");
  224. conn->state = OR_CONN_STATE_CLIENT_AUTH_WAIT;
  225. connection_watch_events(conn, POLLIN);
  226. return 0;
  227. }
  228. int or_handshake_client_process_auth(connection_t *conn) {
  229. char buf[128]; /* only 44 of this is expected to be used */
  230. char cipher[128];
  231. uint32_t min,max;
  232. int retval;
  233. assert(conn);
  234. if(conn->inbuf_datalen < 128) /* entire response available? */
  235. return 0; /* not yet */
  236. if(connection_fetch_from_buf(cipher,128,conn) < 0) {
  237. return -1;
  238. }
  239. log(LOG_DEBUG,"or_handshake_client_process_auth() : Received auth.");
  240. /* decrypt response */
  241. retval = RSA_private_decrypt(128,cipher,buf,conn->prkey,RSA_PKCS1_PADDING);
  242. if (retval == -1)
  243. {
  244. log(LOG_ERR,"Public-key decryption failed during authentication to %s:%u.",
  245. conn->address,ntohs(conn->port));
  246. log(LOG_DEBUG,"or_handshake_client_process_auth() : Reason : %s.",
  247. ERR_reason_error_string(ERR_get_error()));
  248. return -1;
  249. }
  250. else if (retval != 44)
  251. {
  252. log(LOG_ERR,"Received an incorrect response from router %s:%u during authentication.",
  253. conn->address,ntohs(conn->port));
  254. return -1;
  255. }
  256. log(LOG_DEBUG,"or_handshake_client_process_auth() : Decrypted response.");
  257. /* check validity */
  258. if ( (memcmp(&conn->local.sin_addr, buf, 4)) || /* local address */
  259. (memcmp(&conn->local.sin_port, buf+4, 2)) || /* local port */
  260. (memcmp(&conn->addr, buf+6, 4)) || /* remote address */
  261. (memcmp(&conn->port, buf+10, 2)) || /* remote port */
  262. (memcmp(&conn->f_session_key, buf+12, 8)) || /* keys */
  263. (memcmp(&conn->b_session_key, buf+20, 8)))
  264. { /* incorrect response */
  265. log(LOG_ERR,"Router %s:%u failed to authenticate. Either the key I have is obsolete or they're doing something they're not supposed to.",conn->address,ntohs(conn->port));
  266. return -1;
  267. }
  268. log(LOG_DEBUG,"or_handshake_client_process_auth() : Response valid.");
  269. /* update link info */
  270. min = *(uint32_t *)(buf+28);
  271. max = *(uint32_t *)(buf+32);
  272. min = ntohl(min);
  273. max = ntohl(max);
  274. if (conn->min > min)
  275. conn->min = min;
  276. if (conn->max > max)
  277. conn->max = max;
  278. /* reply is just local addr/port, remote addr/port, nonce */
  279. memcpy(buf+12, buf+36, 8);
  280. /* encrypt reply */
  281. retval = RSA_public_encrypt(20,buf,cipher,conn->pkey,RSA_PKCS1_PADDING);
  282. if (retval == -1) /* error */
  283. {
  284. log(LOG_ERR,"Public-key encryption failed during authentication to %s:%u.",conn->address,ntohs(conn->port));
  285. log(LOG_DEBUG,"or_handshake_client_process_auth() : Reason : %s.",ERR_reason_error_string(ERR_get_error()));
  286. return -1;
  287. }
  288. /* send the message */
  289. if(connection_write_to_buf(cipher, 128, conn) < 0) {
  290. log(LOG_DEBUG,"or_handshake_client_process_auth(): my outbuf is full. Oops.");
  291. return -1;
  292. }
  293. retval = connection_flush_buf(conn);
  294. if(retval < 0) {
  295. log(LOG_DEBUG,"or_handshake_client_process_auth(): bad socket while flushing.");
  296. return -1;
  297. }
  298. if(retval > 0) {
  299. /* still stuff on the buffer. */
  300. conn->state = OR_CONN_STATE_CLIENT_SENDING_NONCE;
  301. connection_watch_events(conn, POLLOUT | POLLIN);
  302. /* return(connection_process_inbuf(conn)); process the rest of the inbuf */
  303. return 0;
  304. }
  305. /* it finished sending */
  306. log(LOG_DEBUG,"or_handshake_client_process_auth(): Finished sending nonce.");
  307. conn_or_init_crypto(conn);
  308. conn->state = OR_CONN_STATE_OPEN;
  309. connection_watch_events(conn, POLLIN);
  310. return connection_process_inbuf(conn); /* process the rest of the inbuf */
  311. }
  312. /*
  313. *
  314. * auth handshake, as performed by OR *receiving* the connection
  315. *
  316. */
  317. int or_handshake_server_process_auth(connection_t *conn) {
  318. int retval;
  319. char buf[128]; /* only 42 of this is expected to be used */
  320. char cipher[128];
  321. uint32_t addr;
  322. uint16_t port;
  323. uint32_t min,max;
  324. routerinfo_t *router;
  325. assert(conn);
  326. log(LOG_DEBUG,"or_handshake_server_process_auth() entered.");
  327. if(conn->inbuf_datalen < 128) /* entire response available? */
  328. return 0; /* not yet */
  329. if(connection_fetch_from_buf(cipher,128,conn) < 0) {
  330. return -1;
  331. }
  332. log(LOG_DEBUG,"or_handshake_server_process_auth() : Received auth.");
  333. /* decrypt response */
  334. retval = RSA_private_decrypt(128,cipher,buf,conn->prkey,RSA_PKCS1_PADDING);
  335. if (retval == -1)
  336. {
  337. log(LOG_ERR,"Public-key decryption failed during authentication to %s:%u.",
  338. conn->address,ntohs(conn->port));
  339. log(LOG_DEBUG,"or_handshake_server_process_auth() : Reason : %s.",
  340. ERR_reason_error_string(ERR_get_error()));
  341. return -1;
  342. }
  343. else if (retval != 36)
  344. {
  345. log(LOG_ERR,"Received an incorrect authentication request.");
  346. return -1;
  347. }
  348. log(LOG_DEBUG,"or_handshake_server_process_auth() : Decrypted authentication message.");
  349. /* identify the router */
  350. memcpy(&addr,buf,4); /* save the IP address */
  351. memcpy(&port,buf+4,2); /* save the port */
  352. router = router_get_by_addr_port(addr,port);
  353. if (!router)
  354. {
  355. log(LOG_DEBUG,"or_handshake_server_process_auth() : Received a connection from an unknown router. Will drop.");
  356. return -1;
  357. }
  358. log(LOG_DEBUG,"or_handshake_server_process_auth() : Router identified as %s:%u.",
  359. router->address,ntohs(router->port));
  360. if(connection_get_by_addr_port(addr,port)) {
  361. log(LOG_DEBUG,"or_handshake_server_process_auth(): That router is already connected. Dropping.");
  362. return -1;
  363. }
  364. /* save keys */
  365. memcpy(conn->b_session_key,buf+12,8);
  366. memcpy(conn->f_session_key,buf+20,8);
  367. /* update link info */
  368. min = *(uint32_t *)(buf+28);
  369. max = *(uint32_t *)(buf+32);
  370. min = ntohl(min);
  371. max = ntohl(max);
  372. conn->min = router->min;
  373. conn->max = router->max;
  374. if (conn->min > min)
  375. conn->min = min;
  376. if (conn->max > max)
  377. conn->max = max;
  378. /* copy all relevant info to conn */
  379. conn->addr = router->addr, conn->port = router->port;
  380. conn->pkey = router->pkey;
  381. conn->address = strdup(router->address);
  382. /* generate a nonce */
  383. retval = RAND_pseudo_bytes(conn->nonce,8);
  384. if (retval == -1) /* error */
  385. {
  386. log(LOG_ERR,"Cannot generate a nonce.");
  387. return -1;
  388. }
  389. log(LOG_DEBUG,"or_handshake_server_process_auth() : Nonce generated.");
  390. /* generate message */
  391. memcpy(buf+36,conn->nonce,8); /* append the nonce to the end of the message */
  392. *(uint32_t *)(buf+28) = htonl(conn->min); /* send min link utilisation */
  393. *(uint32_t *)(buf+32) = htonl(conn->max); /* send max link utilisation */
  394. /* encrypt message */
  395. retval = RSA_public_encrypt(44,buf,cipher,conn->pkey,RSA_PKCS1_PADDING);
  396. if (retval == -1) /* error */
  397. {
  398. log(LOG_ERR,"Public-key encryption failed during authentication to %s:%u.",conn->address,ntohs(conn->port));
  399. log(LOG_DEBUG,"or_handshake_server_process_auth() : Reason : %s.",ERR_reason_error_string(ERR_get_error()));
  400. return -1;
  401. }
  402. log(LOG_DEBUG,"or_handshake_server_process_auth() : Reply encrypted.");
  403. /* send message */
  404. if(connection_write_to_buf(cipher, 128, conn) < 0) {
  405. log(LOG_DEBUG,"or_handshake_server_process_auth(): my outbuf is full. Oops.");
  406. return -1;
  407. }
  408. retval = connection_flush_buf(conn);
  409. if(retval < 0) {
  410. log(LOG_DEBUG,"or_handshake_server_process_auth(): bad socket while flushing.");
  411. return -1;
  412. }
  413. if(retval > 0) {
  414. /* still stuff on the buffer. */
  415. conn->state = OR_CONN_STATE_SERVER_SENDING_AUTH;
  416. connection_watch_events(conn, POLLOUT | POLLIN);
  417. return 0;
  418. }
  419. /* it finished sending */
  420. log(LOG_DEBUG,"or_handshake_server_process_auth(): Finished sending auth.");
  421. conn->state = OR_CONN_STATE_SERVER_NONCE_WAIT;
  422. connection_watch_events(conn, POLLIN);
  423. return 0;
  424. }
  425. int or_handshake_server_process_nonce(connection_t *conn) {
  426. char buf[128];
  427. char cipher[128];
  428. int retval;
  429. assert(conn);
  430. if(conn->inbuf_datalen < 128) /* entire response available? */
  431. return 0; /* not yet */
  432. if(connection_fetch_from_buf(cipher,128,conn) < 0) {
  433. return -1;
  434. }
  435. log(LOG_DEBUG,"or_handshake_server_process_nonce() : Received auth.");
  436. /* decrypt response */
  437. retval = RSA_private_decrypt(128,cipher,buf,conn->prkey,RSA_PKCS1_PADDING);
  438. if (retval == -1)
  439. {
  440. log(LOG_ERR,"Public-key decryption failed during authentication to %s:%u.",
  441. conn->address,ntohs(conn->port));
  442. log(LOG_DEBUG,"or_handshake_server_process_nonce() : Reason : %s.",
  443. ERR_reason_error_string(ERR_get_error()));
  444. return -1;
  445. }
  446. else if (retval != 20)
  447. {
  448. log(LOG_ERR,"Received an incorrect response from router %s:%u during authentication.",
  449. conn->address,ntohs(conn->port));
  450. return -1;
  451. }
  452. log(LOG_DEBUG,"or_handshake_server_process_nonce() : Response decrypted.");
  453. /* check validity */
  454. if ((memcmp(&conn->addr,buf, 4)) || /* remote address */
  455. (memcmp(&conn->port,buf+4,2)) || /* remote port */
  456. (memcmp(&conn->local.sin_addr,buf+6,4)) || /* local address */
  457. (memcmp(&conn->local.sin_port,buf+10,2)) || /* local port */
  458. (memcmp(conn->nonce,buf+12,8))) /* nonce */
  459. {
  460. log(LOG_ERR,"Router %s:%u failed to authenticate. Either the key I have is obsolete or they're doing something they're not supposed to.",conn->address,ntohs(conn->port));
  461. return -1;
  462. }
  463. log(LOG_DEBUG,"or_handshake_server_process_nonce() : Response valid. Authentication complete.");
  464. conn_or_init_crypto(conn);
  465. conn->state = OR_CONN_STATE_OPEN;
  466. connection_watch_events(conn, POLLIN);
  467. return connection_process_inbuf(conn); /* process the rest of the inbuf */
  468. }
  469. /* ********************************** */
  470. int connection_or_create_listener(RSA *prkey, struct sockaddr_in *local) {
  471. log(LOG_DEBUG,"connection_create_or_listener starting");
  472. return connection_create_listener(prkey, local, CONN_TYPE_OR_LISTENER);
  473. }
  474. int connection_or_handle_listener_read(connection_t *conn) {
  475. log(LOG_NOTICE,"OR: Received a connection request from a router. Attempting to authenticate.");
  476. return connection_handle_listener_read(conn, CONN_TYPE_OR, OR_CONN_STATE_SERVER_AUTH_WAIT);
  477. }