1#if defined(NO_BUFFER) || defined(NO_IP) || defined(NO_OPENSSL)
2#error "Badness, NO_BUFFER, NO_IP or NO_OPENSSL is defined, turn them *off*"
3#endif
4
5/* Include our bits'n'pieces */
6#include "tunala.h"
7
8
9/********************************************/
10/* Our local types that specify our "world" */
11/********************************************/
12
13/* These represent running "tunnels". Eg. if you wanted to do SSL in a
14 * "message-passing" scanario, the "int" file-descriptors might be replaced by
15 * thread or process IDs, and the "select" code might be replaced by message
16 * handling code. Whatever. */
17typedef struct _tunala_item_t {
18	/* The underlying SSL state machine. This is a data-only processing unit
19	 * and we communicate with it by talking to its four "buffers". */
20	state_machine_t sm;
21	/* The file-descriptors for the "dirty" (encrypted) side of the SSL
22	 * setup. In actuality, this is typically a socket and both values are
23	 * identical. */
24	int dirty_read, dirty_send;
25	/* The file-descriptors for the "clean" (unencrypted) side of the SSL
26	 * setup. These could be stdin/stdout, a socket (both values the same),
27	 * or whatever you like. */
28	int clean_read, clean_send;
29} tunala_item_t;
30
31/* This structure is used as the data for running the main loop. Namely, in a
32 * network format such as this, it is stuff for select() - but as pointed out,
33 * when moving the real-world to somewhere else, this might be replaced by
34 * something entirely different. It's basically the stuff that controls when
35 * it's time to do some "work". */
36typedef struct _select_sets_t {
37	int max; /* As required as the first argument to select() */
38	fd_set reads, sends, excepts; /* As passed to select() */
39} select_sets_t;
40typedef struct _tunala_selector_t {
41	select_sets_t last_selected; /* Results of the last select() */
42	select_sets_t next_select; /* What we'll next select on */
43} tunala_selector_t;
44
45/* This structure is *everything*. We do it to avoid the use of globals so that,
46 * for example, it would be easier to shift things around between async-IO,
47 * thread-based, or multi-fork()ed (or combinations thereof). */
48typedef struct _tunala_world_t {
49	/* The file-descriptor we "listen" on for new connections */
50	int listen_fd;
51	/* The array of tunnels */
52	tunala_item_t *tunnels;
53	/* the number of tunnels in use and allocated, respectively */
54	unsigned int tunnels_used, tunnels_size;
55	/* Our outside "loop" context stuff */
56	tunala_selector_t selector;
57	/* Our SSL_CTX, which is configured as the SSL client or server and has
58	 * the various cert-settings and callbacks configured. */
59	SSL_CTX *ssl_ctx;
60	/* Simple flag with complex logic :-) Indicates whether we're an SSL
61	 * server or an SSL client. */
62	int server_mode;
63} tunala_world_t;
64
65/*****************************/
66/* Internal static functions */
67/*****************************/
68
69static SSL_CTX *initialise_ssl_ctx(int server_mode, const char *engine_id,
70		const char *CAfile, const char *cert, const char *key,
71		const char *dcert, const char *dkey, const char *cipher_list,
72		const char *dh_file, const char *dh_special, int tmp_rsa,
73		int ctx_options, int out_state, int out_verify, int verify_mode,
74		unsigned int verify_depth);
75static void selector_init(tunala_selector_t *selector);
76static void selector_add_listener(tunala_selector_t *selector, int fd);
77static void selector_add_tunala(tunala_selector_t *selector, tunala_item_t *t);
78static int selector_select(tunala_selector_t *selector);
79/* This returns -1 for error, 0 for no new connections, or 1 for success, in
80 * which case *newfd is populated. */
81static int selector_get_listener(tunala_selector_t *selector, int fd, int *newfd);
82static int tunala_world_new_item(tunala_world_t *world, int fd,
83		const char *ip, unsigned short port, int flipped);
84static void tunala_world_del_item(tunala_world_t *world, unsigned int idx);
85static int tunala_item_io(tunala_selector_t *selector, tunala_item_t *item);
86
87/*********************************************/
88/* MAIN FUNCTION (and its utility functions) */
89/*********************************************/
90
91static const char *def_proxyhost = "127.0.0.1:443";
92static const char *def_listenhost = "127.0.0.1:8080";
93static int def_max_tunnels = 50;
94static const char *def_cacert = NULL;
95static const char *def_cert = NULL;
96static const char *def_key = NULL;
97static const char *def_dcert = NULL;
98static const char *def_dkey = NULL;
99static const char *def_engine_id = NULL;
100static int def_server_mode = 0;
101static int def_flipped = 0;
102static const char *def_cipher_list = NULL;
103static const char *def_dh_file = NULL;
104static const char *def_dh_special = NULL;
105static int def_tmp_rsa = 1;
106static int def_ctx_options = 0;
107static int def_verify_mode = 0;
108static unsigned int def_verify_depth = 10;
109static int def_out_state = 0;
110static unsigned int def_out_verify = 0;
111static int def_out_totals = 0;
112static int def_out_conns = 0;
113
114static const char *helpstring =
115"\n'Tunala' (A tunneler with a New Zealand accent)\n"
116"Usage: tunala [options], where options are from;\n"
117" -listen [host:]<port>  (default = 127.0.0.1:8080)\n"
118" -proxy <host>:<port>   (default = 127.0.0.1:443)\n"
119" -maxtunnels <num>      (default = 50)\n"
120" -cacert <path|NULL>    (default = NULL)\n"
121" -cert <path|NULL>      (default = NULL)\n"
122" -key <path|NULL>       (default = whatever '-cert' is)\n"
123" -dcert <path|NULL>     (usually for DSA, default = NULL)\n"
124" -dkey <path|NULL>      (usually for DSA, default = whatever '-dcert' is)\n"
125" -engine <id|NULL>      (default = NULL)\n"
126" -server <0|1>          (default = 0, ie. an SSL client)\n"
127" -flipped <0|1>         (makes SSL servers be network clients, and vice versa)\n"
128" -cipher <list>         (specifies cipher list to use)\n"
129" -dh_file <path>        (a PEM file containing DH parameters to use)\n"
130" -dh_special <NULL|generate|standard> (see below: def=NULL)\n"
131" -no_tmp_rsa            (don't generate temporary RSA keys)\n"
132" -no_ssl2               (disable SSLv2)\n"
133" -no_ssl3               (disable SSLv3)\n"
134" -no_tls1               (disable TLSv1)\n"
135" -v_peer                (verify the peer certificate)\n"
136" -v_strict              (do not continue if peer doesn't authenticate)\n"
137" -v_once                (no verification in renegotiates)\n"
138" -v_depth <num>         (limit certificate chain depth, default = 10)\n"
139" -out_conns             (prints client connections and disconnections)\n"
140" -out_state             (prints SSL handshake states)\n"
141" -out_verify <0|1|2|3>  (prints certificate verification states: def=1)\n"
142" -out_totals            (prints out byte-totals when a tunnel closes)\n"
143" -<h|help|?>            (displays this help screen)\n"
144"Notes:\n"
145"(1) It is recommended to specify a cert+key when operating as an SSL server.\n"
146"    If you only specify '-cert', the same file must contain a matching\n"
147"    private key.\n"
148"(2) Either dh_file or dh_special can be used to specify where DH parameters\n"
149"    will be obtained from (or '-dh_special NULL' for the default choice) but\n"
150"    you cannot specify both. For dh_special, 'generate' will create new DH\n"
151"    parameters on startup, and 'standard' will use embedded parameters\n"
152"    instead.\n"
153"(3) Normally an ssl client connects to an ssl server - so that an 'ssl client\n"
154"    tunala' listens for 'clean' client connections and proxies ssl, and an\n"
155"    'ssl server tunala' listens for ssl connections and proxies 'clean'. With\n"
156"    '-flipped 1', this behaviour is reversed so that an 'ssl server tunala'\n"
157"    listens for clean client connections and proxies ssl (but participating\n"
158"    as an ssl *server* in the SSL/TLS protocol), and an 'ssl client tunala'\n"
159"    listens for ssl connections (participating as an ssl *client* in the\n"
160"    SSL/TLS protocol) and proxies 'clean' to the end destination. This can\n"
161"    be useful for allowing network access to 'servers' where only the server\n"
162"    needs to authenticate the client (ie. the other way is not required).\n"
163"    Even with client and server authentication, this 'technique' mitigates\n"
164"    some DoS (denial-of-service) potential as it will be the network client\n"
165"    having to perform the first private key operation rather than the other\n"
166"    way round.\n"
167"(4) The 'technique' used by setting '-flipped 1' is probably compatible with\n"
168"    absolutely nothing except another complimentary instance of 'tunala'\n"
169"    running with '-flipped 1'. :-)\n";
170
171/* Default DH parameters for use with "-dh_special standard" ... stolen striaght
172 * from s_server. */
173static unsigned char dh512_p[]={
174	0xDA,0x58,0x3C,0x16,0xD9,0x85,0x22,0x89,0xD0,0xE4,0xAF,0x75,
175	0x6F,0x4C,0xCA,0x92,0xDD,0x4B,0xE5,0x33,0xB8,0x04,0xFB,0x0F,
176	0xED,0x94,0xEF,0x9C,0x8A,0x44,0x03,0xED,0x57,0x46,0x50,0xD3,
177	0x69,0x99,0xDB,0x29,0xD7,0x76,0x27,0x6B,0xA2,0xD3,0xD4,0x12,
178	0xE2,0x18,0xF4,0xDD,0x1E,0x08,0x4C,0xF6,0xD8,0x00,0x3E,0x7C,
179	0x47,0x74,0xE8,0x33,
180	};
181static unsigned char dh512_g[]={
182	0x02,
183	};
184
185/* And the function that parses the above "standard" parameters, again, straight
186 * out of s_server. */
187static DH *get_dh512(void)
188	{
189	DH *dh=NULL;
190
191	if ((dh=DH_new()) == NULL) return(NULL);
192	dh->p=BN_bin2bn(dh512_p,sizeof(dh512_p),NULL);
193	dh->g=BN_bin2bn(dh512_g,sizeof(dh512_g),NULL);
194	if ((dh->p == NULL) || (dh->g == NULL))
195		return(NULL);
196	return(dh);
197	}
198
199/* Various help/error messages used by main() */
200static int usage(const char *errstr, int isunknownarg)
201{
202	if(isunknownarg)
203		fprintf(stderr, "Error: unknown argument '%s'\n", errstr);
204	else
205		fprintf(stderr, "Error: %s\n", errstr);
206	fprintf(stderr, "%s\n", helpstring);
207	return 1;
208}
209
210static int err_str0(const char *str0)
211{
212	fprintf(stderr, "%s\n", str0);
213	return 1;
214}
215
216static int err_str1(const char *fmt, const char *str1)
217{
218	fprintf(stderr, fmt, str1);
219	fprintf(stderr, "\n");
220	return 1;
221}
222
223static int parse_max_tunnels(const char *s, unsigned int *maxtunnels)
224{
225	unsigned long l;
226	if(!int_strtoul(s, &l) || (l < 1) || (l > 1024)) {
227		fprintf(stderr, "Error, '%s' is an invalid value for "
228				"maxtunnels\n", s);
229		return 0;
230	}
231	*maxtunnels = (unsigned int)l;
232	return 1;
233}
234
235static int parse_server_mode(const char *s, int *servermode)
236{
237	unsigned long l;
238	if(!int_strtoul(s, &l) || (l > 1)) {
239		fprintf(stderr, "Error, '%s' is an invalid value for the "
240				"server mode\n", s);
241		return 0;
242	}
243	*servermode = (int)l;
244	return 1;
245}
246
247static int parse_dh_special(const char *s, const char **dh_special)
248{
249	if((strcmp(s, "NULL") == 0) || (strcmp(s, "generate") == 0) ||
250			(strcmp(s, "standard") == 0)) {
251		*dh_special = s;
252		return 1;
253	}
254	fprintf(stderr, "Error, '%s' is an invalid value for 'dh_special'\n", s);
255	return 0;
256}
257
258static int parse_verify_level(const char *s, unsigned int *verify_level)
259{
260	unsigned long l;
261	if(!int_strtoul(s, &l) || (l > 3)) {
262		fprintf(stderr, "Error, '%s' is an invalid value for "
263				"out_verify\n", s);
264		return 0;
265	}
266	*verify_level = (unsigned int)l;
267	return 1;
268}
269
270static int parse_verify_depth(const char *s, unsigned int *verify_depth)
271{
272	unsigned long l;
273	if(!int_strtoul(s, &l) || (l < 1) || (l > 50)) {
274		fprintf(stderr, "Error, '%s' is an invalid value for "
275				"verify_depth\n", s);
276		return 0;
277	}
278	*verify_depth = (unsigned int)l;
279	return 1;
280}
281
282/* Some fprintf format strings used when tunnels close */
283static const char *io_stats_dirty =
284"    SSL traffic;   %8lu bytes in, %8lu bytes out\n";
285static const char *io_stats_clean =
286"    clear traffic; %8lu bytes in, %8lu bytes out\n";
287
288int main(int argc, char *argv[])
289{
290	unsigned int loop;
291	int newfd;
292	tunala_world_t world;
293	tunala_item_t *t_item;
294	const char *proxy_ip;
295	unsigned short proxy_port;
296	/* Overridables */
297	const char *proxyhost = def_proxyhost;
298	const char *listenhost = def_listenhost;
299	unsigned int max_tunnels = def_max_tunnels;
300	const char *cacert = def_cacert;
301	const char *cert = def_cert;
302	const char *key = def_key;
303	const char *dcert = def_dcert;
304	const char *dkey = def_dkey;
305	const char *engine_id = def_engine_id;
306	int server_mode = def_server_mode;
307	int flipped = def_flipped;
308	const char *cipher_list = def_cipher_list;
309	const char *dh_file = def_dh_file;
310	const char *dh_special = def_dh_special;
311	int tmp_rsa = def_tmp_rsa;
312	int ctx_options = def_ctx_options;
313	int verify_mode = def_verify_mode;
314	unsigned int verify_depth = def_verify_depth;
315	int out_state = def_out_state;
316	unsigned int out_verify = def_out_verify;
317	int out_totals = def_out_totals;
318	int out_conns = def_out_conns;
319
320/* Parse command-line arguments */
321next_arg:
322	argc--; argv++;
323	if(argc > 0) {
324		if(strcmp(*argv, "-listen") == 0) {
325			if(argc < 2)
326				return usage("-listen requires an argument", 0);
327			argc--; argv++;
328			listenhost = *argv;
329			goto next_arg;
330		} else if(strcmp(*argv, "-proxy") == 0) {
331			if(argc < 2)
332				return usage("-proxy requires an argument", 0);
333			argc--; argv++;
334			proxyhost = *argv;
335			goto next_arg;
336		} else if(strcmp(*argv, "-maxtunnels") == 0) {
337			if(argc < 2)
338				return usage("-maxtunnels requires an argument", 0);
339			argc--; argv++;
340			if(!parse_max_tunnels(*argv, &max_tunnels))
341				return 1;
342			goto next_arg;
343		} else if(strcmp(*argv, "-cacert") == 0) {
344			if(argc < 2)
345				return usage("-cacert requires an argument", 0);
346			argc--; argv++;
347			if(strcmp(*argv, "NULL") == 0)
348				cacert = NULL;
349			else
350				cacert = *argv;
351			goto next_arg;
352		} else if(strcmp(*argv, "-cert") == 0) {
353			if(argc < 2)
354				return usage("-cert requires an argument", 0);
355			argc--; argv++;
356			if(strcmp(*argv, "NULL") == 0)
357				cert = NULL;
358			else
359				cert = *argv;
360			goto next_arg;
361		} else if(strcmp(*argv, "-key") == 0) {
362			if(argc < 2)
363				return usage("-key requires an argument", 0);
364			argc--; argv++;
365			if(strcmp(*argv, "NULL") == 0)
366				key = NULL;
367			else
368				key = *argv;
369			goto next_arg;
370		} else if(strcmp(*argv, "-dcert") == 0) {
371			if(argc < 2)
372				return usage("-dcert requires an argument", 0);
373			argc--; argv++;
374			if(strcmp(*argv, "NULL") == 0)
375				dcert = NULL;
376			else
377				dcert = *argv;
378			goto next_arg;
379		} else if(strcmp(*argv, "-dkey") == 0) {
380			if(argc < 2)
381				return usage("-dkey requires an argument", 0);
382			argc--; argv++;
383			if(strcmp(*argv, "NULL") == 0)
384				dkey = NULL;
385			else
386				dkey = *argv;
387			goto next_arg;
388		} else if(strcmp(*argv, "-engine") == 0) {
389			if(argc < 2)
390				return usage("-engine requires an argument", 0);
391			argc--; argv++;
392			engine_id = *argv;
393			goto next_arg;
394		} else if(strcmp(*argv, "-server") == 0) {
395			if(argc < 2)
396				return usage("-server requires an argument", 0);
397			argc--; argv++;
398			if(!parse_server_mode(*argv, &server_mode))
399				return 1;
400			goto next_arg;
401		} else if(strcmp(*argv, "-flipped") == 0) {
402			if(argc < 2)
403				return usage("-flipped requires an argument", 0);
404			argc--; argv++;
405			if(!parse_server_mode(*argv, &flipped))
406				return 1;
407			goto next_arg;
408		} else if(strcmp(*argv, "-cipher") == 0) {
409			if(argc < 2)
410				return usage("-cipher requires an argument", 0);
411			argc--; argv++;
412			cipher_list = *argv;
413			goto next_arg;
414		} else if(strcmp(*argv, "-dh_file") == 0) {
415			if(argc < 2)
416				return usage("-dh_file requires an argument", 0);
417			if(dh_special)
418				return usage("cannot mix -dh_file with "
419						"-dh_special", 0);
420			argc--; argv++;
421			dh_file = *argv;
422			goto next_arg;
423		} else if(strcmp(*argv, "-dh_special") == 0) {
424			if(argc < 2)
425				return usage("-dh_special requires an argument", 0);
426			if(dh_file)
427				return usage("cannot mix -dh_file with "
428						"-dh_special", 0);
429			argc--; argv++;
430			if(!parse_dh_special(*argv, &dh_special))
431				return 1;
432			goto next_arg;
433		} else if(strcmp(*argv, "-no_tmp_rsa") == 0) {
434			tmp_rsa = 0;
435			goto next_arg;
436		} else if(strcmp(*argv, "-no_ssl2") == 0) {
437			ctx_options |= SSL_OP_NO_SSLv2;
438			goto next_arg;
439		} else if(strcmp(*argv, "-no_ssl3") == 0) {
440			ctx_options |= SSL_OP_NO_SSLv3;
441			goto next_arg;
442		} else if(strcmp(*argv, "-no_tls1") == 0) {
443			ctx_options |= SSL_OP_NO_TLSv1;
444			goto next_arg;
445		} else if(strcmp(*argv, "-v_peer") == 0) {
446			verify_mode |= SSL_VERIFY_PEER;
447			goto next_arg;
448		} else if(strcmp(*argv, "-v_strict") == 0) {
449			verify_mode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
450			goto next_arg;
451		} else if(strcmp(*argv, "-v_once") == 0) {
452			verify_mode |= SSL_VERIFY_CLIENT_ONCE;
453			goto next_arg;
454		} else if(strcmp(*argv, "-v_depth") == 0) {
455			if(argc < 2)
456				return usage("-v_depth requires an argument", 0);
457			argc--; argv++;
458			if(!parse_verify_depth(*argv, &verify_depth))
459				return 1;
460			goto next_arg;
461		} else if(strcmp(*argv, "-out_state") == 0) {
462			out_state = 1;
463			goto next_arg;
464		} else if(strcmp(*argv, "-out_verify") == 0) {
465			if(argc < 2)
466				return usage("-out_verify requires an argument", 0);
467			argc--; argv++;
468			if(!parse_verify_level(*argv, &out_verify))
469				return 1;
470			goto next_arg;
471		} else if(strcmp(*argv, "-out_totals") == 0) {
472			out_totals = 1;
473			goto next_arg;
474		} else if(strcmp(*argv, "-out_conns") == 0) {
475			out_conns = 1;
476			goto next_arg;
477		} else if((strcmp(*argv, "-h") == 0) ||
478				(strcmp(*argv, "-help") == 0) ||
479				(strcmp(*argv, "-?") == 0)) {
480			fprintf(stderr, "%s\n", helpstring);
481			return 0;
482		} else
483			return usage(*argv, 1);
484	}
485	/* Run any sanity checks we want here */
486	if(!cert && !dcert && server_mode)
487		fprintf(stderr, "WARNING: you are running an SSL server without "
488				"a certificate - this may not work!\n");
489
490	/* Initialise network stuff */
491	if(!ip_initialise())
492		return err_str0("ip_initialise failed");
493	/* Create the SSL_CTX */
494	if((world.ssl_ctx = initialise_ssl_ctx(server_mode, engine_id,
495			cacert, cert, key, dcert, dkey, cipher_list, dh_file,
496			dh_special, tmp_rsa, ctx_options, out_state, out_verify,
497			verify_mode, verify_depth)) == NULL)
498		return err_str1("initialise_ssl_ctx(engine_id=%s) failed",
499			(engine_id == NULL) ? "NULL" : engine_id);
500	if(engine_id)
501		fprintf(stderr, "Info, engine '%s' initialised\n", engine_id);
502	/* Create the listener */
503	if((world.listen_fd = ip_create_listener(listenhost)) == -1)
504		return err_str1("ip_create_listener(%s) failed", listenhost);
505	fprintf(stderr, "Info, listening on '%s'\n", listenhost);
506	if(!ip_parse_address(proxyhost, &proxy_ip, &proxy_port, 0))
507		return err_str1("ip_parse_address(%s) failed", proxyhost);
508	fprintf(stderr, "Info, proxying to '%s' (%d.%d.%d.%d:%d)\n", proxyhost,
509			(int)proxy_ip[0], (int)proxy_ip[1],
510			(int)proxy_ip[2], (int)proxy_ip[3], (int)proxy_port);
511	fprintf(stderr, "Info, set maxtunnels to %d\n", (int)max_tunnels);
512	fprintf(stderr, "Info, set to operate as an SSL %s\n",
513			(server_mode ? "server" : "client"));
514	/* Initialise the rest of the stuff */
515	world.tunnels_used = world.tunnels_size = 0;
516	world.tunnels = NULL;
517	world.server_mode = server_mode;
518	selector_init(&world.selector);
519
520/* We're ready to loop */
521main_loop:
522	/* Should we listen for *new* tunnels? */
523	if(world.tunnels_used < max_tunnels)
524		selector_add_listener(&world.selector, world.listen_fd);
525	/* We should add in our existing tunnels */
526	for(loop = 0; loop < world.tunnels_used; loop++)
527		selector_add_tunala(&world.selector, world.tunnels + loop);
528	/* Now do the select */
529	switch(selector_select(&world.selector)) {
530	case -1:
531		if(errno != EINTR) {
532			fprintf(stderr, "selector_select returned a "
533					"badness error.\n");
534			goto shouldnt_happen;
535		}
536		fprintf(stderr, "Warn, selector interrupted by a signal\n");
537		goto main_loop;
538	case 0:
539		fprintf(stderr, "Warn, selector_select returned 0 - signal?""?\n");
540		goto main_loop;
541	default:
542		break;
543	}
544	/* Accept new connection if we should and can */
545	if((world.tunnels_used < max_tunnels) && (selector_get_listener(
546					&world.selector, world.listen_fd,
547					&newfd) == 1)) {
548		/* We have a new connection */
549		if(!tunala_world_new_item(&world, newfd, proxy_ip,
550						proxy_port, flipped))
551			fprintf(stderr, "tunala_world_new_item failed\n");
552		else if(out_conns)
553			fprintf(stderr, "Info, new tunnel opened, now up to "
554					"%d\n", world.tunnels_used);
555	}
556	/* Give each tunnel its moment, note the while loop is because it makes
557	 * the logic easier than with "for" to deal with an array that may shift
558	 * because of deletes. */
559	loop = 0;
560	t_item = world.tunnels;
561	while(loop < world.tunnels_used) {
562		if(!tunala_item_io(&world.selector, t_item)) {
563			/* We're closing whether for reasons of an error or a
564			 * natural close. Don't increment loop or t_item because
565			 * the next item is moving to us! */
566			if(!out_totals)
567				goto skip_totals;
568			fprintf(stderr, "Tunnel closing, traffic stats follow\n");
569			/* Display the encrypted (over the network) stats */
570			fprintf(stderr, io_stats_dirty,
571				buffer_total_in(state_machine_get_buffer(
572						&t_item->sm,SM_DIRTY_IN)),
573				buffer_total_out(state_machine_get_buffer(
574						&t_item->sm,SM_DIRTY_OUT)));
575			/* Display the local (tunnelled) stats. NB: Data we
576			 * *receive* is data sent *out* of the state_machine on
577			 * its 'clean' side. Hence the apparent back-to-front
578			 * OUT/IN mixup here :-) */
579			fprintf(stderr, io_stats_clean,
580				buffer_total_out(state_machine_get_buffer(
581						&t_item->sm,SM_CLEAN_OUT)),
582				buffer_total_in(state_machine_get_buffer(
583						&t_item->sm,SM_CLEAN_IN)));
584skip_totals:
585			tunala_world_del_item(&world, loop);
586			if(out_conns)
587				fprintf(stderr, "Info, tunnel closed, down to %d\n",
588					world.tunnels_used);
589		}
590		else {
591			/* Move to the next item */
592			loop++;
593			t_item++;
594		}
595	}
596	goto main_loop;
597	/* Should never get here */
598shouldnt_happen:
599	abort();
600	return 1;
601}
602
603/****************/
604/* OpenSSL bits */
605/****************/
606
607static int ctx_set_cert(SSL_CTX *ctx, const char *cert, const char *key)
608{
609	FILE *fp = NULL;
610	X509 *x509 = NULL;
611	EVP_PKEY *pkey = NULL;
612	int toret = 0; /* Assume an error */
613
614	/* cert */
615	if(cert) {
616		if((fp = fopen(cert, "r")) == NULL) {
617			fprintf(stderr, "Error opening cert file '%s'\n", cert);
618			goto err;
619		}
620		if(!PEM_read_X509(fp, &x509, NULL, NULL)) {
621			fprintf(stderr, "Error reading PEM cert from '%s'\n",
622					cert);
623			goto err;
624		}
625		if(!SSL_CTX_use_certificate(ctx, x509)) {
626			fprintf(stderr, "Error, cert in '%s' can not be used\n",
627					cert);
628			goto err;
629		}
630		/* Clear the FILE* for reuse in the "key" code */
631		fclose(fp);
632		fp = NULL;
633		fprintf(stderr, "Info, operating with cert in '%s'\n", cert);
634		/* If a cert was given without matching key, we assume the same
635		 * file contains the required key. */
636		if(!key)
637			key = cert;
638	} else {
639		if(key)
640			fprintf(stderr, "Error, can't specify a key without a "
641					"corresponding certificate\n");
642		else
643			fprintf(stderr, "Error, ctx_set_cert called with "
644					"NULLs!\n");
645		goto err;
646	}
647	/* key */
648	if(key) {
649		if((fp = fopen(key, "r")) == NULL) {
650			fprintf(stderr, "Error opening key file '%s'\n", key);
651			goto err;
652		}
653		if(!PEM_read_PrivateKey(fp, &pkey, NULL, NULL)) {
654			fprintf(stderr, "Error reading PEM key from '%s'\n",
655					key);
656			goto err;
657		}
658		if(!SSL_CTX_use_PrivateKey(ctx, pkey)) {
659			fprintf(stderr, "Error, key in '%s' can not be used\n",
660					key);
661			goto err;
662		}
663		fprintf(stderr, "Info, operating with key in '%s'\n", key);
664	} else
665		fprintf(stderr, "Info, operating without a cert or key\n");
666	/* Success */
667	toret = 1; err:
668	if(x509)
669		X509_free(x509);
670	if(pkey)
671		EVP_PKEY_free(pkey);
672	if(fp)
673		fclose(fp);
674	return toret;
675}
676
677static int ctx_set_dh(SSL_CTX *ctx, const char *dh_file, const char *dh_special)
678{
679	DH *dh = NULL;
680	FILE *fp = NULL;
681
682	if(dh_special) {
683		if(strcmp(dh_special, "NULL") == 0)
684			return 1;
685		if(strcmp(dh_special, "standard") == 0) {
686			if((dh = get_dh512()) == NULL) {
687				fprintf(stderr, "Error, can't parse 'standard'"
688						" DH parameters\n");
689				return 0;
690			}
691			fprintf(stderr, "Info, using 'standard' DH parameters\n");
692			goto do_it;
693		}
694		if(strcmp(dh_special, "generate") != 0)
695			/* This shouldn't happen - screening values is handled
696			 * in main(). */
697			abort();
698		fprintf(stderr, "Info, generating DH parameters ... ");
699		fflush(stderr);
700		if((dh = DH_generate_parameters(512, DH_GENERATOR_5,
701					NULL, NULL)) == NULL) {
702			fprintf(stderr, "error!\n");
703			return 0;
704		}
705		fprintf(stderr, "complete\n");
706		goto do_it;
707	}
708	/* So, we're loading dh_file */
709	if((fp = fopen(dh_file, "r")) == NULL) {
710		fprintf(stderr, "Error, couldn't open '%s' for DH parameters\n",
711				dh_file);
712		return 0;
713	}
714	dh = PEM_read_DHparams(fp, NULL, NULL, NULL);
715	fclose(fp);
716	if(dh == NULL) {
717		fprintf(stderr, "Error, could not parse DH parameters from '%s'\n",
718				dh_file);
719		return 0;
720	}
721	fprintf(stderr, "Info, using DH parameters from file '%s'\n", dh_file);
722do_it:
723	SSL_CTX_set_tmp_dh(ctx, dh);
724	DH_free(dh);
725	return 1;
726}
727
728static SSL_CTX *initialise_ssl_ctx(int server_mode, const char *engine_id,
729		const char *CAfile, const char *cert, const char *key,
730		const char *dcert, const char *dkey, const char *cipher_list,
731		const char *dh_file, const char *dh_special, int tmp_rsa,
732		int ctx_options, int out_state, int out_verify, int verify_mode,
733		unsigned int verify_depth)
734{
735	SSL_CTX *ctx = NULL, *ret = NULL;
736	SSL_METHOD *meth;
737	ENGINE *e = NULL;
738
739        OpenSSL_add_ssl_algorithms();
740        SSL_load_error_strings();
741
742	meth = (server_mode ? SSLv23_server_method() : SSLv23_client_method());
743	if(meth == NULL)
744		goto err;
745	if(engine_id) {
746		ENGINE_load_builtin_engines();
747		if((e = ENGINE_by_id(engine_id)) == NULL) {
748			fprintf(stderr, "Error obtaining '%s' engine, openssl "
749					"errors follow\n", engine_id);
750			goto err;
751		}
752		if(!ENGINE_set_default(e, ENGINE_METHOD_ALL)) {
753			fprintf(stderr, "Error assigning '%s' engine, openssl "
754					"errors follow\n", engine_id);
755			goto err;
756		}
757		ENGINE_free(e);
758	}
759	if((ctx = SSL_CTX_new(meth)) == NULL)
760		goto err;
761	/* cacert */
762	if(CAfile) {
763		if(!X509_STORE_load_locations(SSL_CTX_get_cert_store(ctx),
764					CAfile, NULL)) {
765			fprintf(stderr, "Error loading CA cert(s) in '%s'\n",
766					CAfile);
767			goto err;
768		}
769		fprintf(stderr, "Info, operating with CA cert(s) in '%s'\n",
770				CAfile);
771	} else
772		fprintf(stderr, "Info, operating without a CA cert(-list)\n");
773	if(!SSL_CTX_set_default_verify_paths(ctx)) {
774		fprintf(stderr, "Error setting default verify paths\n");
775		goto err;
776	}
777
778	/* cert and key */
779	if((cert || key) && !ctx_set_cert(ctx, cert, key))
780		goto err;
781	/* dcert and dkey */
782	if((dcert || dkey) && !ctx_set_cert(ctx, dcert, dkey))
783		goto err;
784	/* temporary RSA key generation */
785	if(tmp_rsa)
786		SSL_CTX_set_tmp_rsa_callback(ctx, cb_generate_tmp_rsa);
787
788	/* cipher_list */
789	if(cipher_list) {
790		if(!SSL_CTX_set_cipher_list(ctx, cipher_list)) {
791			fprintf(stderr, "Error setting cipher list '%s'\n",
792					cipher_list);
793			goto err;
794		}
795		fprintf(stderr, "Info, set cipher list '%s'\n", cipher_list);
796	} else
797		fprintf(stderr, "Info, operating with default cipher list\n");
798
799	/* dh_file & dh_special */
800	if((dh_file || dh_special) && !ctx_set_dh(ctx, dh_file, dh_special))
801		goto err;
802
803	/* ctx_options */
804	SSL_CTX_set_options(ctx, ctx_options);
805
806	/* out_state (output of SSL handshake states to screen). */
807	if(out_state)
808		cb_ssl_info_set_output(stderr);
809
810	/* out_verify */
811	if(out_verify > 0) {
812		cb_ssl_verify_set_output(stderr);
813		cb_ssl_verify_set_level(out_verify);
814	}
815
816	/* verify_depth */
817	cb_ssl_verify_set_depth(verify_depth);
818
819	/* Success! (includes setting verify_mode) */
820	SSL_CTX_set_info_callback(ctx, cb_ssl_info);
821	SSL_CTX_set_verify(ctx, verify_mode, cb_ssl_verify);
822	ret = ctx;
823err:
824	if(!ret) {
825		ERR_print_errors_fp(stderr);
826		if(ctx)
827			SSL_CTX_free(ctx);
828	}
829	return ret;
830}
831
832/*****************/
833/* Selector bits */
834/*****************/
835
836static void selector_sets_init(select_sets_t *s)
837{
838	s->max = 0;
839	FD_ZERO(&s->reads);
840	FD_ZERO(&s->sends);
841	FD_ZERO(&s->excepts);
842}
843static void selector_init(tunala_selector_t *selector)
844{
845	selector_sets_init(&selector->last_selected);
846	selector_sets_init(&selector->next_select);
847}
848
849#define SEL_EXCEPTS 0x00
850#define SEL_READS   0x01
851#define SEL_SENDS   0x02
852static void selector_add_raw_fd(tunala_selector_t *s, int fd, int flags)
853{
854	FD_SET(fd, &s->next_select.excepts);
855	if(flags & SEL_READS)
856		FD_SET(fd, &s->next_select.reads);
857	if(flags & SEL_SENDS)
858		FD_SET(fd, &s->next_select.sends);
859	/* Adjust "max" */
860	if(s->next_select.max < (fd + 1))
861		s->next_select.max = fd + 1;
862}
863
864static void selector_add_listener(tunala_selector_t *selector, int fd)
865{
866	selector_add_raw_fd(selector, fd, SEL_READS);
867}
868
869static void selector_add_tunala(tunala_selector_t *s, tunala_item_t *t)
870{
871	/* Set clean read if sm.clean_in is not full */
872	if(t->clean_read != -1) {
873		selector_add_raw_fd(s, t->clean_read,
874			(buffer_full(state_machine_get_buffer(&t->sm,
875				SM_CLEAN_IN)) ? SEL_EXCEPTS : SEL_READS));
876	}
877	/* Set clean send if sm.clean_out is not empty */
878	if(t->clean_send != -1) {
879		selector_add_raw_fd(s, t->clean_send,
880			(buffer_empty(state_machine_get_buffer(&t->sm,
881				SM_CLEAN_OUT)) ? SEL_EXCEPTS : SEL_SENDS));
882	}
883	/* Set dirty read if sm.dirty_in is not full */
884	if(t->dirty_read != -1) {
885		selector_add_raw_fd(s, t->dirty_read,
886			(buffer_full(state_machine_get_buffer(&t->sm,
887				SM_DIRTY_IN)) ? SEL_EXCEPTS : SEL_READS));
888	}
889	/* Set dirty send if sm.dirty_out is not empty */
890	if(t->dirty_send != -1) {
891		selector_add_raw_fd(s, t->dirty_send,
892			(buffer_empty(state_machine_get_buffer(&t->sm,
893				SM_DIRTY_OUT)) ? SEL_EXCEPTS : SEL_SENDS));
894	}
895}
896
897static int selector_select(tunala_selector_t *selector)
898{
899	memcpy(&selector->last_selected, &selector->next_select,
900			sizeof(select_sets_t));
901	selector_sets_init(&selector->next_select);
902	return select(selector->last_selected.max,
903			&selector->last_selected.reads,
904			&selector->last_selected.sends,
905			&selector->last_selected.excepts, NULL);
906}
907
908/* This returns -1 for error, 0 for no new connections, or 1 for success, in
909 * which case *newfd is populated. */
910static int selector_get_listener(tunala_selector_t *selector, int fd, int *newfd)
911{
912	if(FD_ISSET(fd, &selector->last_selected.excepts))
913		return -1;
914	if(!FD_ISSET(fd, &selector->last_selected.reads))
915		return 0;
916	if((*newfd = ip_accept_connection(fd)) == -1)
917		return -1;
918	return 1;
919}
920
921/************************/
922/* "Tunala" world stuff */
923/************************/
924
925static int tunala_world_make_room(tunala_world_t *world)
926{
927	unsigned int newsize;
928	tunala_item_t *newarray;
929
930	if(world->tunnels_used < world->tunnels_size)
931		return 1;
932	newsize = (world->tunnels_size == 0 ? 16 :
933			((world->tunnels_size * 3) / 2));
934	if((newarray = malloc(newsize * sizeof(tunala_item_t))) == NULL)
935		return 0;
936	memset(newarray, 0, newsize * sizeof(tunala_item_t));
937	if(world->tunnels_used > 0)
938		memcpy(newarray, world->tunnels,
939			world->tunnels_used * sizeof(tunala_item_t));
940	if(world->tunnels_size > 0)
941		free(world->tunnels);
942	/* migrate */
943	world->tunnels = newarray;
944	world->tunnels_size = newsize;
945	return 1;
946}
947
948static int tunala_world_new_item(tunala_world_t *world, int fd,
949		const char *ip, unsigned short port, int flipped)
950{
951	tunala_item_t *item;
952	int newfd;
953	SSL *new_ssl = NULL;
954
955	if(!tunala_world_make_room(world))
956		return 0;
957	if((new_ssl = SSL_new(world->ssl_ctx)) == NULL) {
958		fprintf(stderr, "Error creating new SSL\n");
959		ERR_print_errors_fp(stderr);
960		return 0;
961	}
962	item = world->tunnels + (world->tunnels_used++);
963	state_machine_init(&item->sm);
964	item->clean_read = item->clean_send =
965		item->dirty_read = item->dirty_send = -1;
966	if((newfd = ip_create_connection_split(ip, port)) == -1)
967		goto err;
968	/* Which way round? If we're a server, "fd" is the dirty side and the
969	 * connection we open is the clean one. For a client, it's the other way
970	 * around. Unless, of course, we're "flipped" in which case everything
971	 * gets reversed. :-) */
972	if((world->server_mode && !flipped) ||
973			(!world->server_mode && flipped)) {
974		item->dirty_read = item->dirty_send = fd;
975		item->clean_read = item->clean_send = newfd;
976	} else {
977		item->clean_read = item->clean_send = fd;
978		item->dirty_read = item->dirty_send = newfd;
979	}
980	/* We use the SSL's "app_data" to indicate a call-back induced "kill" */
981	SSL_set_app_data(new_ssl, NULL);
982	if(!state_machine_set_SSL(&item->sm, new_ssl, world->server_mode))
983		goto err;
984	return 1;
985err:
986	tunala_world_del_item(world, world->tunnels_used - 1);
987	return 0;
988
989}
990
991static void tunala_world_del_item(tunala_world_t *world, unsigned int idx)
992{
993	tunala_item_t *item = world->tunnels + idx;
994	if(item->clean_read != -1)
995		close(item->clean_read);
996	if(item->clean_send != item->clean_read)
997		close(item->clean_send);
998	item->clean_read = item->clean_send = -1;
999	if(item->dirty_read != -1)
1000		close(item->dirty_read);
1001	if(item->dirty_send != item->dirty_read)
1002		close(item->dirty_send);
1003	item->dirty_read = item->dirty_send = -1;
1004	state_machine_close(&item->sm);
1005	/* OK, now we fix the item array */
1006	if(idx + 1 < world->tunnels_used)
1007		/* We need to scroll entries to the left */
1008		memmove(world->tunnels + idx,
1009				world->tunnels + (idx + 1),
1010				(world->tunnels_used - (idx + 1)) *
1011					sizeof(tunala_item_t));
1012	world->tunnels_used--;
1013}
1014
1015static int tunala_item_io(tunala_selector_t *selector, tunala_item_t *item)
1016{
1017	int c_r, c_s, d_r, d_s; /* Four boolean flags */
1018
1019	/* Take ourselves out of the gene-pool if there was an except */
1020	if((item->clean_read != -1) && FD_ISSET(item->clean_read,
1021				&selector->last_selected.excepts))
1022		return 0;
1023	if((item->clean_send != -1) && FD_ISSET(item->clean_send,
1024				&selector->last_selected.excepts))
1025		return 0;
1026	if((item->dirty_read != -1) && FD_ISSET(item->dirty_read,
1027				&selector->last_selected.excepts))
1028		return 0;
1029	if((item->dirty_send != -1) && FD_ISSET(item->dirty_send,
1030				&selector->last_selected.excepts))
1031		return 0;
1032	/* Grab our 4 IO flags */
1033	c_r = c_s = d_r = d_s = 0;
1034	if(item->clean_read != -1)
1035		c_r = FD_ISSET(item->clean_read, &selector->last_selected.reads);
1036	if(item->clean_send != -1)
1037		c_s = FD_ISSET(item->clean_send, &selector->last_selected.sends);
1038	if(item->dirty_read != -1)
1039		d_r = FD_ISSET(item->dirty_read, &selector->last_selected.reads);
1040	if(item->dirty_send != -1)
1041		d_s = FD_ISSET(item->dirty_send, &selector->last_selected.sends);
1042	/* If no IO has happened for us, skip needless data looping */
1043	if(!c_r && !c_s && !d_r && !d_s)
1044		return 1;
1045	if(c_r)
1046		c_r = (buffer_from_fd(state_machine_get_buffer(&item->sm,
1047				SM_CLEAN_IN), item->clean_read) <= 0);
1048	if(c_s)
1049		c_s = (buffer_to_fd(state_machine_get_buffer(&item->sm,
1050				SM_CLEAN_OUT), item->clean_send) <= 0);
1051	if(d_r)
1052		d_r = (buffer_from_fd(state_machine_get_buffer(&item->sm,
1053				SM_DIRTY_IN), item->dirty_read) <= 0);
1054	if(d_s)
1055		d_s = (buffer_to_fd(state_machine_get_buffer(&item->sm,
1056				SM_DIRTY_OUT), item->dirty_send) <= 0);
1057	/* If any of the flags is non-zero, that means they need closing */
1058	if(c_r) {
1059		close(item->clean_read);
1060		if(item->clean_send == item->clean_read)
1061			item->clean_send = -1;
1062		item->clean_read = -1;
1063	}
1064	if(c_s && (item->clean_send != -1)) {
1065		close(item->clean_send);
1066		if(item->clean_send == item->clean_read)
1067			item->clean_read = -1;
1068		item->clean_send = -1;
1069	}
1070	if(d_r) {
1071		close(item->dirty_read);
1072		if(item->dirty_send == item->dirty_read)
1073			item->dirty_send = -1;
1074		item->dirty_read = -1;
1075	}
1076	if(d_s && (item->dirty_send != -1)) {
1077		close(item->dirty_send);
1078		if(item->dirty_send == item->dirty_read)
1079			item->dirty_read = -1;
1080		item->dirty_send = -1;
1081	}
1082	/* This function name is attributed to the term donated by David
1083	 * Schwartz on openssl-dev, message-ID:
1084	 * <NCBBLIEPOCNJOAEKBEAKEEDGLIAA.davids@webmaster.com>. :-) */
1085	if(!state_machine_churn(&item->sm))
1086		/* If the SSL closes, it will also zero-out the _in buffers
1087		 * and will in future process just outgoing data. As and
1088		 * when the outgoing data has gone, it will return zero
1089		 * here to tell us to bail out. */
1090		return 0;
1091	/* Otherwise, we return zero if both sides are dead. */
1092	if(((item->clean_read == -1) || (item->clean_send == -1)) &&
1093			((item->dirty_read == -1) || (item->dirty_send == -1)))
1094		return 0;
1095	/* If only one side closed, notify the SSL of this so it can take
1096	 * appropriate action. */
1097	if((item->clean_read == -1) || (item->clean_send == -1)) {
1098		if(!state_machine_close_clean(&item->sm))
1099			return 0;
1100	}
1101	if((item->dirty_read == -1) || (item->dirty_send == -1)) {
1102		if(!state_machine_close_dirty(&item->sm))
1103			return 0;
1104	}
1105	return 1;
1106}
1107
1108