op.c 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916
  1. /**
  2. * op.c
  3. * Onion Proxy
  4. *
  5. * Matej Pfajfar <mp292@cam.ac.uk>
  6. */
  7. /*
  8. * Changes :
  9. * $Log$
  10. * Revision 1.1 2002/06/26 22:45:50 arma
  11. * Initial revision
  12. *
  13. * Revision 1.37 2002/06/14 20:45:56 mp292
  14. * *** empty log message ***
  15. *
  16. * Revision 1.36 2002/04/02 14:28:01 badbytes
  17. * Final finishes.
  18. *
  19. * Revision 1.35 2002/04/02 10:21:07 badbytes
  20. * *** empty log message ***
  21. *
  22. * Revision 1.34 2002/03/29 08:35:12 badbytes
  23. * Link encryption is now done on the entire cell header for simplicity.
  24. *
  25. * Revision 1.33 2002/03/28 17:57:59 badbytes
  26. * Bug fix.
  27. *
  28. * Revision 1.32 2002/03/28 11:01:43 badbytes
  29. * Now does link-encryption and link-padding.
  30. *
  31. * Revision 1.31 2002/03/12 23:40:32 mp292
  32. * Started on op<->router connection padding.
  33. *
  34. * Revision 1.30 2002/01/29 02:22:58 mp292
  35. * Put a timeout on all network I/O.
  36. *
  37. * Revision 1.29 2002/01/26 23:01:55 mp292
  38. * Reviewed according to Secure-Programs-HOWTO.
  39. *
  40. * Revision 1.28 2002/01/18 20:42:06 mp292
  41. * Reflects changes to common/onion.c:new_route()
  42. *
  43. * Revision 1.27 2002/01/17 23:49:15 mp292
  44. * Added size of public key to one of the debugging messages.
  45. *
  46. * Revision 1.26 2002/01/16 23:01:58 mp292
  47. * First phase of system testing completed (main functionality).
  48. *
  49. * Revision 1.25 2002/01/16 17:01:56 mp292
  50. * There was a bug in checking whether the incoming connection is local or not.
  51. *
  52. * Revision 1.24 2002/01/16 16:09:32 mp292
  53. * A pointer cast was missing. Fixed.
  54. *
  55. * Revision 1.23 2002/01/14 13:05:39 badbytes
  56. * System testing in progress.
  57. *
  58. * Revision 1.22 2002/01/11 15:47:25 badbytes
  59. * *** empty log message ***
  60. *
  61. * Revision 1.21 2002/01/09 09:18:35 badbytes
  62. * Now handles EINTR error from accept().
  63. *
  64. * Revision 1.20 2002/01/09 07:57:18 badbytes
  65. * Ciphers got out of sync, hopefully fixed.
  66. *
  67. * Revision 1.19 2001/12/19 11:15:41 badbytes
  68. * Corrected AF_INET to PF_INET in socket() calls.
  69. *
  70. * Revision 1.18 2001/12/19 08:38:38 badbytes
  71. * Zombie problems hopefully fixed.
  72. *
  73. * Revision 1.17 2001/12/19 08:29:29 badbytes
  74. * Tested. Still some problems with zombies in both op and smtpap.
  75. *
  76. * Revision 1.16 2001/12/18 15:51:58 badbytes
  77. * Connection with onion router established. Will continue testing tomorrow.
  78. *
  79. * Revision 1.15 2001/12/18 14:12:05 badbytes
  80. * Tested up to connect() to onion router.
  81. *
  82. * Revision 1.14 2001/12/18 12:21:11 badbytes
  83. * Forgot to convert port to network order :-)
  84. *
  85. * Revision 1.13 2001/12/18 11:52:27 badbytes
  86. * Coding completed. Proceeding to test.
  87. *
  88. * Revision 1.12 2001/12/17 13:36:15 badbytes
  89. * Writing handle_connection()
  90. *
  91. * Revision 1.11 2001/12/17 08:42:44 badbytes
  92. * getrouters() now returns an array of routers and also writes the length of the array to an int*.
  93. *
  94. * Revision 1.10 2001/12/14 14:45:13 badbytes
  95. * Added range checking for CoinWeight.
  96. *
  97. * Revision 1.9 2001/12/14 14:08:50 badbytes
  98. * getrouters() now returns an array of pointers rather than a linked list
  99. *
  100. * Revision 1.8 2001/12/14 13:31:20 badbytes
  101. * *** empty log message ***
  102. *
  103. * Revision 1.7 2001/12/14 13:17:12 badbytes
  104. * Corrected references to types.h
  105. *
  106. * Revision 1.6 2001/12/14 13:00:30 badbytes
  107. * Changed my mind, routers.c and routers.h stay where they are :-)
  108. *
  109. * Revision 1.5 2001/12/14 12:56:55 badbytes
  110. * Moved routers* to common/
  111. *
  112. * Revision 1.4 2001/12/14 12:42:50 badbytes
  113. * References to onion.h and onion.o now point to the common/ directory.
  114. *
  115. * Revision 1.3 2001/12/14 12:40:26 badbytes
  116. * Was being stupid - op doesn't need a private key!! Have removed ...
  117. *
  118. * Revision 1.2 2001/12/14 11:27:16 badbytes
  119. * Configuration and server setup completed.
  120. *
  121. * Revision 1.1 2001/12/13 15:15:11 badbytes
  122. * Started coding the onion proxy.
  123. *
  124. */
  125. #include <sys/types.h>
  126. #include <sys/socket.h>
  127. #include <sys/time.h>
  128. #include <sys/resource.h>
  129. #include <netinet/in.h>
  130. #include <netdb.h>
  131. #include <arpa/inet.h>
  132. #include <errno.h>
  133. #include <ctype.h>
  134. #include <stdio.h>
  135. #include <unistd.h>
  136. #include <signal.h>
  137. #include <wait.h>
  138. #include <openssl/err.h>
  139. #include <openssl/rsa.h>
  140. #include <openssl/pem.h>
  141. #include <openssl/evp.h>
  142. #include <openssl/rand.h>
  143. #include "../common/log.h"
  144. #include "../common/version.h"
  145. #include "../common/onion.h"
  146. #include "../common/utils.h"
  147. #include "../common/cell.h"
  148. #include "../common/scheduler.h"
  149. #include "config.h"
  150. #include "routers.h"
  151. #include "args.h"
  152. #include "auth.h"
  153. #include "op.h"
  154. #include "ss.h"
  155. #include "crypto.h"
  156. #include "buffers.h"
  157. /* global variables */
  158. /* default logging threshold */
  159. int loglevel = LOG_ERR;
  160. struct timeval conn_tout;
  161. struct timeval *conn_toutp = &conn_tout;
  162. /* valid command-line options */
  163. static char *args = "hf:p:l:";
  164. /* valid config file options */
  165. static config_opt_t options[] =
  166. {
  167. {"RouterFile", CONFIG_TYPE_STRING, {0}, 0},
  168. {"CoinWeight", CONFIG_TYPE_DOUBLE, {0}, 0},
  169. {"MaxConn", CONFIG_TYPE_INT, {0}, 0},
  170. {"ConnTimeout", CONFIG_TYPE_INT, {0}, 0},
  171. {"Bandwidth", CONFIG_TYPE_INT, {0}, 0},
  172. {0}
  173. };
  174. enum opts {
  175. RouterFile=0, CoinWeight, MaxConn, ConnTimeout, Bandwidth
  176. };
  177. int connections = 0; /* number of active connections */
  178. /* local host info */
  179. struct hostent *local_host;
  180. char local_hostname[512];
  181. struct sockaddr_in local, remote; /* local and remote address info */
  182. struct sockaddr_in or_addr; /* onion router address */
  183. int request_sock; /* where we listen for connections */
  184. int new_sock; /* for accepted connections */
  185. int or_sock; /* for connecting to the first onion router */
  186. /* router array */
  187. routent_t **routerarray = NULL;
  188. int rarray_len = 0;
  189. /* end of global variables */
  190. void send_to_router(int s,unsigned char **outbuf, size_t *outbuflen, size_t *outbuf_dataoffset, size_t *outbuf_datalen, struct timeval *lastsend, struct timeval *interval, sched_t *scheduler, EVP_CIPHER_CTX *ctx)
  191. {
  192. int retval;
  193. int cells;
  194. int datacells;
  195. int paddingcells;
  196. int i;
  197. int x;
  198. char *px;
  199. struct timeval now;
  200. cell_t cipher;
  201. cell_t *padding;
  202. int cipherlen;
  203. unsigned long elapsed;
  204. /* calculate the number of cells that need to be sent */
  205. retval = gettimeofday(&now,NULL);
  206. if (retval == -1)
  207. {
  208. log(LOG_ERR,"Could not get current time!");
  209. return;
  210. }
  211. elapsed = 1000000*(now.tv_sec-lastsend->tv_sec) + now.tv_usec-lastsend->tv_usec;
  212. if (elapsed < 1000000)
  213. {
  214. cells = ((options[Bandwidth].r.i) * 512) / /* number of bytes per second, divided by two */
  215. (1000000/elapsed); /* fractions of second since last send */
  216. }
  217. else
  218. {
  219. cells = ((options[Bandwidth].r.i) * 512) * /* number of bytes per second, divided by two */
  220. (elapsed/1000000); /* 1/fractions of second since last send */
  221. }
  222. cells /= sizeof(cell_t);
  223. datacells = (*outbuf_datalen)/sizeof(cell_t); /* number of data cells available */
  224. if (datacells > cells)
  225. datacells = cells;
  226. paddingcells = cells - datacells;
  227. /* send the data cells first */
  228. for (i=0; i<datacells; i++)
  229. {
  230. /* link-encrypt the cell header */
  231. printf("Cell header plaintext: ");
  232. for(x=0;x<8;x++) {
  233. printf("%u ",*(char *)(*outbuf+*outbuf_dataoffset+x));
  234. }
  235. printf("\n");
  236. retval = EVP_EncryptUpdate(ctx, (unsigned char *)&cipher, &cipherlen, *outbuf+*outbuf_dataoffset, 8);
  237. if (!retval)
  238. {
  239. log(LOG_ERR,"Link encryption failed. Exiting.");
  240. exit(-1);
  241. }
  242. printf("Cell header crypttext: ");
  243. px = (char *)&cipher;
  244. for(x=0;x<8;x++) {
  245. printf("%u ",px[x]);
  246. }
  247. printf("\n");
  248. /* copy the payload */
  249. memcpy((void *)cipher.payload, (void *)(*outbuf+*outbuf_dataoffset+8), CELL_PAYLOAD_SIZE);
  250. /* send the cell */
  251. log(LOG_DEBUG,"send_to_router(): Trying to send a data/create cell to router.");
  252. retval = write_tout(s,(unsigned char *)&cipher, sizeof(cell_t), conn_toutp);
  253. if (retval < sizeof(cell_t))
  254. {
  255. log(LOG_ERR,"Connection to the router seems to be lost. Exiting.");
  256. exit(-1);
  257. }
  258. *outbuf_dataoffset += sizeof(cell_t);
  259. *outbuf_datalen -= sizeof(cell_t);
  260. }
  261. /* send padding */
  262. for (i=0; i<cells-datacells; i++)
  263. {
  264. padding = new_padding_cell();
  265. if (!padding)
  266. {
  267. log(LOG_ERR,"Memory allocation error. Exiting.");
  268. exit(-1);
  269. }
  270. /* link encrypt the cell header */
  271. retval = EVP_EncryptUpdate(ctx, (unsigned char *)&cipher, &cipherlen, (unsigned char *)padding, 8);
  272. if (!retval)
  273. {
  274. log(LOG_ERR,"Link encryption failed. Exiting.");
  275. exit(-1);
  276. }
  277. /* copy the payload */
  278. memcpy((void *)cipher.payload, (void *)((unsigned char *)padding+8), CELL_PAYLOAD_SIZE);
  279. /* send the cell */
  280. log(LOG_DEBUG,"send_to_router(): Trying to send a padding cell to router.");
  281. retval = write_tout(s, (unsigned char *)&cipher, sizeof(cell_t), conn_toutp);
  282. if (retval < sizeof(cell_t))
  283. {
  284. log(LOG_ERR,"Connection to the router seems to be lost. Exiting.");
  285. exit(-1);
  286. }
  287. free((void *)padding);
  288. }
  289. /* update scheduler state, if we've sent anything to the router */
  290. if (cells)
  291. {
  292. retval = update_sched_entry(scheduler, *lastsend, *interval, now, *interval);
  293. if (retval == -1)
  294. {
  295. log(LOG_ERR,"Scheduler error. Exiting.");
  296. exit(-1);
  297. }
  298. memcpy((void *)lastsend,(void *)&now, sizeof(struct timeval));
  299. }
  300. }
  301. /* deal with a client */
  302. int handle_connection()
  303. {
  304. int retval = 0;
  305. int routelen = 0; /* length of the route */
  306. unsigned int *route = NULL; /* hops in the route as an array of indexes into rarray */
  307. routent_t *firsthop = NULL;
  308. uint32_t aci; /* ACI for this connection */
  309. unsigned char *onion = NULL; /* holds the onion */
  310. int onionlen = 0; /* onion length in host order */
  311. crypt_path_t **cpath = NULL; /* defines the crypt operations that need to be performed on incoming/outgoing data */
  312. char *dest_addr = NULL; /* destination address in ASCII format */
  313. int dest_addrlen = 0;
  314. char *dest_port = NULL; /* destination port in ASCII format */
  315. int dest_portlen = 0;
  316. ss_t *ss; /* standard structure */
  317. uint32_t router_addr_net; /* address of the first onion router in network order */
  318. unsigned char inbuf[1024]; /* buffer for forwarding data between ap and or */
  319. unsigned char *outbuf = NULL; /* buffer for cells which are to be transmitted to the first core onion router in the route */
  320. size_t outbuflen = 0;
  321. size_t outbuf_dataoffset = 0; /* offset to the beginning of the data */
  322. size_t outbuf_datalen = 0; /* length of the data stored in the buffer */
  323. cell_t cellbuf;
  324. int cellbuflen = 0;
  325. struct timeval lastsend; /* time of last transmission to the onion router */
  326. struct timeval interval; /* transmission interval */
  327. /* link encryption */
  328. unsigned char f_session_key[8];
  329. unsigned char f_session_iv[8] = {0,0,0,0,0,0,0,0};
  330. unsigned char b_session_key[8];
  331. unsigned char b_session_iv[8] = {0,0,0,0,0,0,0,0};
  332. EVP_CIPHER_CTX f_ctx;
  333. EVP_CIPHER_CTX b_ctx;
  334. /* scheduler */
  335. sched_t *scheduler;
  336. /* for use with select() */
  337. fd_set rmask, mask;
  338. int maxfd;
  339. struct timeval *timeout;
  340. /* get the standard structure */
  341. retval = process_ss(new_sock, conn_toutp, &ss,&dest_addr, &dest_addrlen, &dest_port, &dest_portlen);
  342. if (retval == -1)
  343. {
  344. log(LOG_ERR,"Error processing the standard structure.");
  345. return -1;
  346. }
  347. log(LOG_DEBUG,"handle_connection() : Destination = %s:%s",dest_addr,dest_port);
  348. /* choose a route */
  349. route = (unsigned int *)new_route(options[CoinWeight].r.d, routerarray,rarray_len, &routelen);
  350. if (!route)
  351. {
  352. log(LOG_ERR,"Error choosing a route through the OR network.");
  353. return -1;
  354. }
  355. log(LOG_DEBUG,"handle_connection() : Chosen a route of length %u : ",routelen);
  356. for (retval=routelen-1;retval>=0;retval--)
  357. {
  358. log(LOG_DEBUG,"handle_connection() : %u : %s:%u, %u",routelen-retval,(routerarray[route[retval]])->address,ntohs((routerarray[route[retval]])->port),RSA_size((routerarray[route[retval]])->pkey));
  359. }
  360. /* allocate memory for the crypt path */
  361. cpath = malloc(routelen * sizeof(crypt_path_t *));
  362. if (!cpath)
  363. {
  364. log(LOG_ERR,"Error allocating memory.");
  365. free(route);
  366. return -1;
  367. }
  368. /* create an onion and calculate crypto keys */
  369. onion = create_onion(routerarray,rarray_len,route,routelen,&onionlen,cpath);
  370. if (!onion)
  371. {
  372. log(LOG_ERR,"Error creating an onion.");
  373. free(route);
  374. return -1;
  375. }
  376. log(LOG_DEBUG,"handle_connection() : Created an onion of size %u bytes.",onionlen);
  377. log(LOG_DEBUG,"handle_connection() : Crypt path :");
  378. for (retval=0;retval<routelen;retval++)
  379. {
  380. log(LOG_DEBUG,"handle_connection() : %u/%u",(cpath[retval])->forwf, (cpath[retval])->backf);
  381. }
  382. /* connect to first onion router */
  383. or_sock = socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
  384. if (or_sock < 0)
  385. {
  386. free(route);
  387. free(onion);
  388. free(cpath);
  389. close(new_sock);
  390. log(LOG_ERR,"Error creating socket.");
  391. return -1;
  392. }
  393. log(LOG_DEBUG,"handle_connection() : Socket created.");
  394. firsthop = routerarray[route[routelen-1]];
  395. memset((void *)&or_addr,0,sizeof(or_addr));
  396. or_addr.sin_family=AF_INET;
  397. or_addr.sin_port=firsthop->entry_port;
  398. router_addr_net = firsthop->addr;
  399. memcpy(&or_addr.sin_addr,&router_addr_net,sizeof(struct sockaddr_in));
  400. log(LOG_DEBUG,"handle_connection() : Trying to connect to %s:%u",inet_ntoa(or_addr.sin_addr), ntohs(or_addr.sin_port));
  401. retval = connect(or_sock,(struct sockaddr *)&or_addr, sizeof(or_addr));
  402. if (retval == -1)
  403. {
  404. log(LOG_ERR,"Could not connect to onion router.");
  405. free(route);
  406. free(onion);
  407. free(cpath);
  408. close(or_sock);
  409. close(new_sock);
  410. return -1;
  411. }
  412. log(LOG_DEBUG,"handle_connection() : Connected to first onion router.");
  413. /* send session key and bandwidth info */
  414. retval = send_auth(or_sock, options[Bandwidth].r.i, firsthop->pkey, f_session_key, b_session_key);
  415. if (retval == -1)
  416. {
  417. close(or_sock);
  418. close(new_sock);
  419. log(LOG_ERR,"Lost connection to an onion router. Exiting.");
  420. return -1;
  421. }
  422. /* initialize crypto engines */
  423. EVP_CIPHER_CTX_init(&f_ctx);
  424. EVP_CIPHER_CTX_init(&b_ctx);
  425. EVP_EncryptInit(&f_ctx, EVP_des_ofb(), f_session_key, f_session_iv);
  426. EVP_DecryptInit(&b_ctx, EVP_des_ofb(), b_session_key, b_session_iv);
  427. /* chose an ACI */
  428. do
  429. {
  430. retval = RAND_pseudo_bytes((unsigned char *)&aci, 2);
  431. if (retval==-1)
  432. {
  433. log(LOG_ERR,"Random data generator doesn't seem to work. Exiting.");
  434. return -1;
  435. }
  436. } while(!aci); /* don't allow zero ACIs */
  437. log(LOG_DEBUG,"handle_connection() : ACI %u chosen.",aci);
  438. /* initialize last time of transmission to now */
  439. retval = gettimeofday(&lastsend, NULL);
  440. if (retval == -1)
  441. {
  442. log(LOG_ERR,"Could not get current time.");
  443. return -1;
  444. }
  445. /* calculate the transmission interval */
  446. interval.tv_sec = 0;
  447. interval.tv_usec = 250000/options[Bandwidth].r.i;
  448. /* initialize the scheduler */
  449. scheduler = new_sched();
  450. if (!scheduler)
  451. {
  452. log(LOG_ERR,"Could not initialize scheduler.");
  453. return -1;
  454. }
  455. retval = add_sched_entry(scheduler, lastsend, interval);
  456. if (retval == -1)
  457. {
  458. log(LOG_ERR,"Could not initialize scheduler.");
  459. return -1;
  460. }
  461. timeout = NULL;
  462. /* write the onion into the output buffer */
  463. retval = buffer_create(aci, (unsigned char *)onion, onionlen, &outbuf, &outbuflen, &outbuf_dataoffset, &outbuf_datalen, cpath, routelen);
  464. if (retval == -1)
  465. {
  466. log(LOG_DEBUG,"handle_connection() : Could not buffer the onion.");
  467. close(or_sock);
  468. return -1;
  469. }
  470. log(LOG_DEBUG,"handle_connection() : Onion buffered for output.");
  471. /* send standard structure */
  472. log(LOG_DEBUG,"handle_connection() : Calling send_crypt ... routelen=%u, sizeof(SS) = %u",routelen,sizeof(ss_t));
  473. retval = buffer_data(aci, (unsigned char *)ss, sizeof(ss_t), &outbuf, &outbuflen, &outbuf_dataoffset, &outbuf_datalen, cpath, routelen);
  474. if (retval == -1)
  475. {
  476. log(LOG_DEBUG,"handle_connection() : Could not buffer the standard structure for output.");
  477. close(or_sock);
  478. return -1;
  479. }
  480. log(LOG_DEBUG,"handle_connection() : Buffered the standard structure header.");
  481. retval = buffer_data(aci, dest_addr,dest_addrlen, &outbuf, &outbuflen, &outbuf_dataoffset, &outbuf_datalen, cpath, routelen);
  482. if (retval == -1)
  483. {
  484. log(LOG_DEBUG,"handle_connection() : Could not buffer the standard structure (dest. address) for output.");
  485. close(or_sock);
  486. return -1;
  487. }
  488. log(LOG_DEBUG,"handle_connection() : Buffered the destination address.");
  489. retval = buffer_data(aci, dest_port, dest_portlen, &outbuf, &outbuflen, &outbuf_dataoffset, &outbuf_datalen, cpath, routelen);
  490. if (retval == -1)
  491. {
  492. log(LOG_DEBUG,"handle_connection() : Could not buffer the standard structure (dest. port) for output.");
  493. close(or_sock);
  494. return -1;
  495. }
  496. log(LOG_DEBUG,"handle_connection() : Buffered the destination port.");
  497. /* forward data in both directions, crypt as necessary */
  498. /* use select() */
  499. FD_ZERO(&mask);
  500. FD_SET(new_sock, &mask);
  501. FD_SET(or_sock, &mask);
  502. if (new_sock > or_sock)
  503. maxfd = new_sock;
  504. else
  505. maxfd = or_sock;
  506. while(1)
  507. {
  508. rmask = mask;
  509. /* delete old timeout */
  510. if (timeout)
  511. free((void *)timeout);
  512. /* get the new one */
  513. retval = sched_trigger(scheduler, &timeout);
  514. if (retval == -1)
  515. {
  516. log(LOG_DEBUG,"Scheduler error.");
  517. break;
  518. }
  519. retval = select(maxfd+1,&rmask,NULL,NULL,timeout);
  520. if (retval < 0)
  521. {
  522. log(LOG_DEBUG,"handle_connection() : select() returned negative integer");
  523. break;
  524. }
  525. if (FD_ISSET(new_sock,&rmask))
  526. {
  527. log(LOG_DEBUG,"handle_connection() : FD_ISSET(new_sock)");
  528. retval = read_tout(new_sock, inbuf, 1024, 0, conn_toutp);
  529. if (retval <= 0)
  530. {
  531. log(LOG_DEBUG,"handle_connection() : Received EOF on new_sock.");
  532. break;
  533. }
  534. log(LOG_DEBUG,"handle_connection() : Received %u bytes from client.",retval);
  535. retval = buffer_data(aci, inbuf, retval, &outbuf, &outbuflen, &outbuf_dataoffset, &outbuf_datalen, cpath, routelen);
  536. if (retval < 0)
  537. {
  538. log(LOG_DEBUG,"handle_connection() : Could not buffer data for output to OR.");
  539. break;
  540. }
  541. log(LOG_DEBUG,"handle_connection() : Buffered %u bytes for output to the OR.",retval);
  542. }
  543. if (FD_ISSET(or_sock, &rmask))
  544. {
  545. log(LOG_DEBUG,"handle_connection() : FD_ISSET(or_sock)");
  546. /* read the remainder of the cell (or whatever we can get) */
  547. retval = read_tout(or_sock, ((unsigned char *)&cellbuf)+cellbuflen, sizeof(cell_t) - cellbuflen, 0, conn_toutp);
  548. if (retval <= 0)
  549. {
  550. log(LOG_DEBUG,"handle_connection() : Received EOF on or_sock.");
  551. break;
  552. }
  553. log(LOG_DEBUG,"handle_connection() : Received %u bytes from router.",retval);
  554. cellbuflen += retval;
  555. if (cellbuflen == sizeof(cell_t)) /* received an entire cell */
  556. {
  557. /* link decrypt the cell header */
  558. retval = EVP_DecryptUpdate(&b_ctx, (unsigned char *)inbuf, &cellbuflen, (unsigned char *)&cellbuf, 8);
  559. if (!retval)
  560. {
  561. log(LOG_ERR,"Decryption error. Closing the connection and exiting.");
  562. break;
  563. }
  564. if (((cell_t *)inbuf)->command == CELL_PADDING) /* padding, discard */
  565. {
  566. log(LOG_DEBUG,"Received a PADDING cell. Discarding.");
  567. ; /* discard */
  568. }
  569. else if (((cell_t *)inbuf)->command == CELL_DATA) /* only process DATA cells , discard otherwise */
  570. {
  571. /* decrypt the payload length */
  572. retval = crypt_b((unsigned char *)&((cell_t *)inbuf)->length, 1, cpath, routelen);
  573. if (retval == -1)
  574. {
  575. log(LOG_ERR,"Decryption error. Closing the connection and exiting.");
  576. break;
  577. }
  578. /* decrypt the payload */
  579. retval = crypt_b((unsigned char *)cellbuf.payload, CELL_PAYLOAD_SIZE, cpath, routelen);
  580. if (retval == -1)
  581. {
  582. log(LOG_ERR,"Decryption error. Closing the connection and exiting.");
  583. break;
  584. }
  585. /* send the payload to the application proxy */
  586. retval = write_tout(new_sock, (unsigned char *)cellbuf.payload, ((cell_t *)inbuf)->length, conn_toutp);
  587. if (retval < ((cell_t *)inbuf)->length)
  588. {
  589. log(LOG_ERR,"Connection to the application proxy seems to be lost.");
  590. break;
  591. }
  592. log(LOG_DEBUG,"handle_connection() : Sent %u bytes to client.",retval);
  593. }
  594. else
  595. log(LOG_DEBUG,"handle_connection() : Recived cell has incorrect command or ACI. Discarding.");
  596. cellbuflen = 0; /* get ready for the next cell */
  597. }
  598. }
  599. /* send cells to the router */
  600. send_to_router(or_sock,&outbuf, &outbuflen, &outbuf_dataoffset, &outbuf_datalen, &lastsend, &interval, scheduler, &f_ctx);
  601. }
  602. /* clean up */
  603. log(LOG_DEBUG,"handle_connection() : handle_connection() exiting.");
  604. close(or_sock);
  605. return 0;
  606. }
  607. /* used for reaping zombie processes */
  608. void sigchld_handler(int s)
  609. {
  610. while (wait(NULL) > 0);
  611. connections--;
  612. }
  613. int main(int argc, char *argv[])
  614. {
  615. int one = 1;
  616. int retval = 0;
  617. char *cp; /* temporary storage */
  618. int i=0; /* iteration counter */
  619. char *conf_filename = NULL; /* configuration file */
  620. size_t sin_size; /* for accept() calls */
  621. u_short p; /* onion proxy port */
  622. /* used for reaping zombie processes */
  623. struct sigaction sa;
  624. int islocal = 0; /* is the incoming connection local? */
  625. struct rlimit cd_limit; /* resource limit to prevent core dumps */
  626. /* prevent core dump */
  627. retval = getrlimit(RLIMIT_CORE, &cd_limit);
  628. if (retval == -1)
  629. {
  630. log(LOG_ERR,"Could not tell the OS to prevent core dumps for the process.");
  631. return -1;
  632. }
  633. cd_limit.rlim_cur = 0;
  634. retval = setrlimit(RLIMIT_CORE, &cd_limit);
  635. if (retval == -1)
  636. {
  637. log(LOG_ERR,"Could not tell the OS to prevent core dumps for the process.");
  638. return -1;
  639. }
  640. /* get command-line arguments */
  641. retval = getargs(argc,argv,args,&p,&conf_filename,&loglevel);
  642. if (retval == -1)
  643. {
  644. log(LOG_ERR,"Error processing command-line arguments.");
  645. exit(1);
  646. }
  647. /* load config file */
  648. retval = getconfig(conf_filename,options);
  649. if (retval == -1)
  650. {
  651. log(LOG_ERR,"Error loading configuration file.");
  652. exit(1);
  653. }
  654. if (options[RouterFile].err != 1)
  655. {
  656. log(LOG_ERR,"RouterFile option required, but not found.");
  657. exit(1);
  658. }
  659. if (options[CoinWeight].err == -1)
  660. {
  661. log(LOG_ERR,"Error reading the CoinWeight option.");
  662. exit(1);
  663. }
  664. if (options[CoinWeight].err == 0)
  665. {
  666. /* this is optional, so if not found, set default value */
  667. options[CoinWeight].r.d = OP_DEFAULT_COIN_WEIGHT;
  668. }
  669. else if ((options[CoinWeight].r.d < 0) || (options[CoinWeight].r.d >= 1))
  670. {
  671. /* must be a value in [0,1) */
  672. log(LOG_ERR,"CoinWeight option must be >= 0 and < 1.");
  673. exit(1);
  674. }
  675. if (options[Bandwidth].err == 0)
  676. {
  677. /* optional, set to default */
  678. options[Bandwidth].r.i = OP_DEFAULT_BANDWIDTH;
  679. }
  680. else if (options[Bandwidth].r.i <= 0)
  681. {
  682. log(LOG_ERR,"The Bandwidth option must be an integer greater than zero.");
  683. exit(1);
  684. }
  685. if (options[ConnTimeout].err != 1)
  686. {
  687. conn_tout.tv_sec = OP_DEFAULT_CONN_TIMEOUT;
  688. conn_tout.tv_usec = 0;
  689. }
  690. else
  691. {
  692. if (!options[ConnTimeout].r.i)
  693. conn_toutp = NULL;
  694. else
  695. conn_tout.tv_sec = options[ConnTimeout].r.i;
  696. conn_tout.tv_usec = 0;
  697. }
  698. /* load the routers file */
  699. routerarray = getrouters(options[RouterFile].r.str,&rarray_len);
  700. if (!routerarray)
  701. {
  702. log(LOG_ERR,"Error loading router list.");
  703. exit(1);
  704. }
  705. /* get local address so that we know where to allow connections from*/
  706. retval = gethostname(local_hostname, (size_t)512);
  707. if (retval < 0)
  708. {
  709. log(LOG_ERR,"Error getting local hostname.");
  710. return -1;
  711. }
  712. local_host = gethostbyname(local_hostname);
  713. if (!local_host)
  714. {
  715. log(LOG_ERR,"Error getting local address.");
  716. return -1;
  717. }
  718. log(LOG_DEBUG,"main() : Got local address : %s.",local_hostname);
  719. /* get the server up and running */
  720. request_sock = socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
  721. if (request_sock < 0)
  722. {
  723. log(LOG_ERR,"Error opening socket.");
  724. return -1;
  725. }
  726. setsockopt(request_sock, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
  727. log(LOG_DEBUG,"main() : Socket opened.");
  728. memset((void *)&local,0,sizeof(local)); /* clear the structure first */
  729. /* set up the sockaddr_in structure */
  730. local.sin_family=AF_INET;
  731. local.sin_addr.s_addr = INADDR_ANY;
  732. local.sin_port=htons(p);
  733. /* bind it to the socket */
  734. retval = bind(request_sock,(struct sockaddr *)&local, sizeof(local));
  735. if (retval < 0)
  736. {
  737. log(LOG_ERR,"Error binding socket to local port %d.",p);
  738. return retval;
  739. }
  740. log(LOG_DEBUG,"main() : Socket bound to port %d.",p);
  741. /* listen for connections */
  742. retval = listen(request_sock,SOMAXCONN);
  743. if (retval < 0)
  744. {
  745. log(LOG_ERR,"Could not listen for connections.");
  746. return retval;
  747. }
  748. log(LOG_DEBUG,"main() : Listening for connections.");
  749. /* server should now be up and running */
  750. /* install the signal handler for making sure zombie processes are killed */
  751. sa.sa_handler = sigchld_handler;
  752. sigemptyset(&sa.sa_mask);
  753. sa.sa_flags = SA_RESTART;
  754. retval = sigaction(SIGCHLD,&sa,NULL);
  755. if (retval < 0)
  756. {
  757. log(LOG_ERR,"Could not install a signal handler.");
  758. return -1;
  759. }
  760. /* main server loop */
  761. /* I use a forking server technique - this isn't the most efficient way to do it,
  762. * but it is simpler. */
  763. while(1)
  764. {
  765. sin_size = sizeof(struct sockaddr_in);
  766. new_sock = accept(request_sock,(struct sockaddr *)&remote,&sin_size);
  767. if (new_sock == -1)
  768. {
  769. if (errno != EINTR)
  770. log(LOG_ERR,"Could not accept socket connection.");
  771. else
  772. log(LOG_DEBUG,"main() : Interrupt received.");
  773. continue;
  774. }
  775. if (connections == options[MaxConn].r.i)
  776. {
  777. close(new_sock);
  778. log(LOG_NOTICE,"Maximum connection limit exceeded. Rejecting incoming request.");
  779. }
  780. connections++;
  781. log(LOG_DEBUG,"main() : Accepted a connection from %s.",inet_ntoa(remote.sin_addr));
  782. /* see if the connection is local, otherwise reject */
  783. /* first check that the connection is from the local host, otherwise reject */
  784. if (*(uint32_t *)&remote.sin_addr == inet_addr("127.0.0.1"))
  785. islocal=1;
  786. for (i=0; (local_host->h_addr_list[i] != NULL) && (!islocal); i++)
  787. {
  788. cp = local_host->h_addr_list[i];
  789. if (!memcmp(&remote.sin_addr, cp,sizeof(struct in_addr)))
  790. islocal = 1;
  791. }
  792. if (!islocal)
  793. {
  794. log(LOG_DEBUG,"main() : Incoming connection is not local. Will reject.");
  795. close(new_sock);
  796. }
  797. else
  798. {
  799. log(LOG_DEBUG,"main() : Incoming connection seems to be local. Will accept.");
  800. /* fork a process to deal with the customer */
  801. if (!fork()) /* this is the child process */
  802. {
  803. close(request_sock); /* the child doesn't need the request socket anymore */
  804. /* Main logic of op. */
  805. retval = handle_connection();
  806. log(LOG_DEBUG,"main() : Handle connection returned %d.",retval);
  807. /* End main logic */
  808. exit(retval); /* done, exit */
  809. }
  810. close(new_sock); /* don't need this anymore */
  811. }
  812. }
  813. return retval;
  814. }