X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=demos%2Ftunala%2Ftunala.c;h=ec49d3e943e3c2e276d624cdbd6b8ac97b41ce22;hp=dbf155c67a04d822b6b53520c485ae0d38f07a07;hb=3b28bc9910e12a8c34fb4643788e94b5c3bd184d;hpb=282d8b1c385aad08969a307950350574c66a3ec2 diff --git a/demos/tunala/tunala.c b/demos/tunala/tunala.c index dbf155c67a..ec49d3e943 100644 --- a/demos/tunala/tunala.c +++ b/demos/tunala/tunala.c @@ -69,8 +69,8 @@ typedef struct _tunala_world_t { static SSL_CTX *initialise_ssl_ctx(int server_mode, const char *engine_id, const char *CAfile, const char *cert, const char *key, const char *dcert, const char *dkey, const char *cipher_list, - const char *dh_file, const char *dh_special, int ctx_options, - int out_state, int out_verify, int verify_mode, + const char *dh_file, const char *dh_special, int tmp_rsa, + int ctx_options, int out_state, int out_verify, int verify_mode, unsigned int verify_depth); static void selector_init(tunala_selector_t *selector); static void selector_add_listener(tunala_selector_t *selector, int fd); @@ -80,7 +80,7 @@ static int selector_select(tunala_selector_t *selector); * which case *newfd is populated. */ static int selector_get_listener(tunala_selector_t *selector, int fd, int *newfd); static int tunala_world_new_item(tunala_world_t *world, int fd, - const unsigned char *ip, unsigned short port, int flipped); + const char *ip, unsigned short port, int flipped); static void tunala_world_del_item(tunala_world_t *world, unsigned int idx); static int tunala_item_io(tunala_selector_t *selector, tunala_item_t *item); @@ -102,12 +102,14 @@ static int def_flipped = 0; static const char *def_cipher_list = NULL; static const char *def_dh_file = NULL; static const char *def_dh_special = NULL; +static int def_tmp_rsa = 1; static int def_ctx_options = 0; static int def_verify_mode = 0; static unsigned int def_verify_depth = 10; static int def_out_state = 0; static unsigned int def_out_verify = 0; static int def_out_totals = 0; +static int def_out_conns = 0; static const char *helpstring = "\n'Tunala' (A tunneler with a New Zealand accent)\n" @@ -126,6 +128,7 @@ static const char *helpstring = " -cipher (specifies cipher list to use)\n" " -dh_file (a PEM file containing DH parameters to use)\n" " -dh_special (see below: def=NULL)\n" +" -no_tmp_rsa (don't generate temporary RSA keys)\n" " -no_ssl2 (disable SSLv2)\n" " -no_ssl3 (disable SSLv3)\n" " -no_tls1 (disable TLSv1)\n" @@ -133,6 +136,7 @@ static const char *helpstring = " -v_strict (do not continue if peer doesn't authenticate)\n" " -v_once (no verification in renegotiates)\n" " -v_depth (limit certificate chain depth, default = 10)\n" +" -out_conns (prints client connections and disconnections)\n" " -out_state (prints SSL handshake states)\n" " -out_verify <0|1|2|3> (prints certificate verification states: def=1)\n" " -out_totals (prints out byte-totals when a tunnel closes)\n" @@ -219,9 +223,7 @@ static int err_str1(const char *fmt, const char *str1) static int parse_max_tunnels(const char *s, unsigned int *maxtunnels) { unsigned long l; - char *temp; - l = strtoul(s, &temp, 10); - if((temp == s) || (*temp != '\0') || (l < 1) || (l > 1024)) { + if(!int_strtoul(s, &l) || (l < 1) || (l > 1024)) { fprintf(stderr, "Error, '%s' is an invalid value for " "maxtunnels\n", s); return 0; @@ -233,9 +235,7 @@ static int parse_max_tunnels(const char *s, unsigned int *maxtunnels) static int parse_server_mode(const char *s, int *servermode) { unsigned long l; - char *temp; - l = strtoul(s, &temp, 10); - if((temp == s) || (*temp != '\0') || (l > 1)) { + if(!int_strtoul(s, &l) || (l > 1)) { fprintf(stderr, "Error, '%s' is an invalid value for the " "server mode\n", s); return 0; @@ -258,9 +258,7 @@ static int parse_dh_special(const char *s, const char **dh_special) static int parse_verify_level(const char *s, unsigned int *verify_level) { unsigned long l; - char *temp; - l = strtoul(s, &temp, 10); - if((temp == s) || (*temp != '\0') || (l > 3)) { + if(!int_strtoul(s, &l) || (l > 3)) { fprintf(stderr, "Error, '%s' is an invalid value for " "out_verify\n", s); return 0; @@ -272,9 +270,7 @@ static int parse_verify_level(const char *s, unsigned int *verify_level) static int parse_verify_depth(const char *s, unsigned int *verify_depth) { unsigned long l; - char *temp; - l = strtoul(s, &temp, 10); - if((temp == s) || (*temp != '\0') || (l < 1) || (l > 50)) { + if(!int_strtoul(s, &l) || (l < 1) || (l > 50)) { fprintf(stderr, "Error, '%s' is an invalid value for " "verify_depth\n", s); return 0; @@ -284,14 +280,10 @@ static int parse_verify_depth(const char *s, unsigned int *verify_depth) } /* Some fprintf format strings used when tunnels close */ -static const char *io_stats_client_dirty = -" SSL (network) traffic to/from server; %8lu bytes in, %8lu bytes out\n"; -static const char *io_stats_client_clean = -" tunnelled data to/from server; %8lu bytes in, %8lu bytes out\n"; -static const char *io_stats_server_dirty = -" SSL (network) traffic to/from client; %8lu bytes in, %8lu bytes out\n"; -static const char *io_stats_server_clean = -" tunnelled data to/from client; %8lu bytes in, %8lu bytes out\n"; +static const char *io_stats_dirty = +" SSL traffic; %8lu bytes in, %8lu bytes out\n"; +static const char *io_stats_clean = +" clear traffic; %8lu bytes in, %8lu bytes out\n"; int main(int argc, char *argv[]) { @@ -299,7 +291,7 @@ int main(int argc, char *argv[]) int newfd; tunala_world_t world; tunala_item_t *t_item; - unsigned char *proxy_ip; + const char *proxy_ip; unsigned short proxy_port; /* Overridables */ const char *proxyhost = def_proxyhost; @@ -316,12 +308,14 @@ int main(int argc, char *argv[]) const char *cipher_list = def_cipher_list; const char *dh_file = def_dh_file; const char *dh_special = def_dh_special; + int tmp_rsa = def_tmp_rsa; int ctx_options = def_ctx_options; int verify_mode = def_verify_mode; unsigned int verify_depth = def_verify_depth; int out_state = def_out_state; unsigned int out_verify = def_out_verify; int out_totals = def_out_totals; + int out_conns = def_out_conns; /* Parse command-line arguments */ next_arg: @@ -436,6 +430,9 @@ next_arg: if(!parse_dh_special(*argv, &dh_special)) return 1; goto next_arg; + } else if(strcmp(*argv, "-no_tmp_rsa") == 0) { + tmp_rsa = 0; + goto next_arg; } else if(strcmp(*argv, "-no_ssl2") == 0) { ctx_options |= SSL_OP_NO_SSLv2; goto next_arg; @@ -474,6 +471,9 @@ next_arg: } else if(strcmp(*argv, "-out_totals") == 0) { out_totals = 1; goto next_arg; + } else if(strcmp(*argv, "-out_conns") == 0) { + out_conns = 1; + goto next_arg; } else if((strcmp(*argv, "-h") == 0) || (strcmp(*argv, "-help") == 0) || (strcmp(*argv, "-?") == 0)) { @@ -482,32 +482,34 @@ next_arg: } else return usage(*argv, 1); } + /* Run any sanity checks we want here */ + if(!cert && !dcert && server_mode) + fprintf(stderr, "WARNING: you are running an SSL server without " + "a certificate - this may not work!\n"); /* Initialise network stuff */ if(!ip_initialise()) return err_str0("ip_initialise failed"); - err_str0("ip_initialise succeeded"); /* Create the SSL_CTX */ if((world.ssl_ctx = initialise_ssl_ctx(server_mode, engine_id, cacert, cert, key, dcert, dkey, cipher_list, dh_file, - dh_special, ctx_options, out_state, out_verify, + dh_special, tmp_rsa, ctx_options, out_state, out_verify, verify_mode, verify_depth)) == NULL) return err_str1("initialise_ssl_ctx(engine_id=%s) failed", (engine_id == NULL) ? "NULL" : engine_id); - err_str1("initialise_ssl_ctx(engine_id=%s) succeeded", - (engine_id == NULL) ? "NULL" : engine_id); + if(engine_id) + fprintf(stderr, "Info, engine '%s' initialised\n", engine_id); /* Create the listener */ if((world.listen_fd = ip_create_listener(listenhost)) == -1) return err_str1("ip_create_listener(%s) failed", listenhost); - err_str1("ip_create_listener(%s) succeeded", listenhost); + fprintf(stderr, "Info, listening on '%s'\n", listenhost); if(!ip_parse_address(proxyhost, &proxy_ip, &proxy_port, 0)) return err_str1("ip_parse_address(%s) failed", proxyhost); - err_str1("ip_parse_address(%s) succeeded", proxyhost); - fprintf(stderr, "Info - proxying to %d.%d.%d.%d:%d\n", + fprintf(stderr, "Info, proxying to '%s' (%d.%d.%d.%d:%d)\n", proxyhost, (int)proxy_ip[0], (int)proxy_ip[1], (int)proxy_ip[2], (int)proxy_ip[3], (int)proxy_port); - fprintf(stderr, "Info - set maxtunnels to %d\n", (int)max_tunnels); - fprintf(stderr, "Info - set to operate as an SSL %s\n", + fprintf(stderr, "Info, set maxtunnels to %d\n", (int)max_tunnels); + fprintf(stderr, "Info, set to operate as an SSL %s\n", (server_mode ? "server" : "client")); /* Initialise the rest of the stuff */ world.tunnels_used = world.tunnels_size = 0; @@ -526,10 +528,15 @@ main_loop: /* Now do the select */ switch(selector_select(&world.selector)) { case -1: - fprintf(stderr, "selector_select returned a badness error.\n"); - abort(); + if(errno != EINTR) { + fprintf(stderr, "selector_select returned a " + "badness error.\n"); + goto shouldnt_happen; + } + fprintf(stderr, "Warn, selector interrupted by a signal\n"); + goto main_loop; case 0: - fprintf(stderr, "Warn, selector_select returned 0 - signal??\n"); + fprintf(stderr, "Warn, selector_select returned 0 - signal?""?\n"); goto main_loop; default: break; @@ -542,7 +549,7 @@ main_loop: if(!tunala_world_new_item(&world, newfd, proxy_ip, proxy_port, flipped)) fprintf(stderr, "tunala_world_new_item failed\n"); - else + else if(out_conns) fprintf(stderr, "Info, new tunnel opened, now up to " "%d\n", world.tunnels_used); } @@ -560,8 +567,7 @@ main_loop: goto skip_totals; fprintf(stderr, "Tunnel closing, traffic stats follow\n"); /* Display the encrypted (over the network) stats */ - fprintf(stderr, (server_mode ? io_stats_server_dirty : - io_stats_client_dirty), + fprintf(stderr, io_stats_dirty, buffer_total_in(state_machine_get_buffer( &t_item->sm,SM_DIRTY_IN)), buffer_total_out(state_machine_get_buffer( @@ -570,15 +576,15 @@ main_loop: * *receive* is data sent *out* of the state_machine on * its 'clean' side. Hence the apparent back-to-front * OUT/IN mixup here :-) */ - fprintf(stderr, (server_mode ? io_stats_server_clean : - io_stats_client_clean), + fprintf(stderr, io_stats_clean, buffer_total_out(state_machine_get_buffer( &t_item->sm,SM_CLEAN_OUT)), buffer_total_in(state_machine_get_buffer( &t_item->sm,SM_CLEAN_IN))); skip_totals: tunala_world_del_item(&world, loop); - fprintf(stderr, "Info, tunnel closed, down to %d\n", + if(out_conns) + fprintf(stderr, "Info, tunnel closed, down to %d\n", world.tunnels_used); } else { @@ -589,6 +595,7 @@ skip_totals: } goto main_loop; /* Should never get here */ +shouldnt_happen: abort(); return 1; } @@ -690,9 +697,11 @@ static int ctx_set_dh(SSL_CTX *ctx, const char *dh_file, const char *dh_special) abort(); fprintf(stderr, "Info, generating DH parameters ... "); fflush(stderr); - if((dh = DH_generate_parameters(512, DH_GENERATOR_5, - NULL, NULL)) == NULL) { + if(!(dh = DH_new()) || !DH_generate_parameters_ex(dh, 512, + DH_GENERATOR_5, NULL)) { fprintf(stderr, "error!\n"); + if(dh) + DH_free(dh); return 0; } fprintf(stderr, "complete\n"); @@ -721,12 +730,12 @@ do_it: static SSL_CTX *initialise_ssl_ctx(int server_mode, const char *engine_id, const char *CAfile, const char *cert, const char *key, const char *dcert, const char *dkey, const char *cipher_list, - const char *dh_file, const char *dh_special, int ctx_options, - int out_state, int out_verify, int verify_mode, + const char *dh_file, const char *dh_special, int tmp_rsa, + int ctx_options, int out_state, int out_verify, int verify_mode, unsigned int verify_depth) { - SSL_CTX *ctx, *ret = NULL; - SSL_METHOD *meth; + SSL_CTX *ctx = NULL, *ret = NULL; + const SSL_METHOD *meth; ENGINE *e = NULL; OpenSSL_add_ssl_algorithms(); @@ -736,6 +745,7 @@ static SSL_CTX *initialise_ssl_ctx(int server_mode, const char *engine_id, if(meth == NULL) goto err; if(engine_id) { + ENGINE_load_builtin_engines(); if((e = ENGINE_by_id(engine_id)) == NULL) { fprintf(stderr, "Error obtaining '%s' engine, openssl " "errors follow\n", engine_id); @@ -773,6 +783,9 @@ static SSL_CTX *initialise_ssl_ctx(int server_mode, const char *engine_id, /* dcert and dkey */ if((dcert || dkey) && !ctx_set_cert(ctx, dcert, dkey)) goto err; + /* temporary RSA key generation */ + if(tmp_rsa) + SSL_CTX_set_tmp_rsa_callback(ctx, cb_generate_tmp_rsa); /* cipher_list */ if(cipher_list) { @@ -935,7 +948,7 @@ static int tunala_world_make_room(tunala_world_t *world) } static int tunala_world_new_item(tunala_world_t *world, int fd, - const unsigned char *ip, unsigned short port, int flipped) + const char *ip, unsigned short port, int flipped) { tunala_item_t *item; int newfd;