X-Git-Url: https://ruderich.org/simon/gitweb/?a=blobdiff_plain;f=src%2Ftlsproxy.c;h=4bfc88d4f786ce68f21502e727bfbe6afcc00445;hb=33933ff752898dca2d5e5a7b995d129313716d5c;hp=5fed55427ae95468c88bed20b615472ba2bf8625;hpb=3c4d48bc9f6d8228b4eb61ef7920bdc64fc2eec1;p=tlsproxy%2Ftlsproxy.git diff --git a/src/tlsproxy.c b/src/tlsproxy.c index 5fed554..4bfc88d 100644 --- a/src/tlsproxy.c +++ b/src/tlsproxy.c @@ -3,7 +3,7 @@ * ensures the server certificate doesn't change. Normally this isn't detected * if a trusted CA for the new server certificate is installed. * - * Copyright (C) 2011 Simon Ruderich + * Copyright (C) 2011-2013 Simon Ruderich * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -59,7 +59,7 @@ GCRY_THREAD_OPTION_PTHREAD_IMPL; /* Server should shut down. Set by SIGINT handler. */ -static volatile int done; +static volatile int done = 0; /* Number of threads. */ static size_t thread_count; @@ -89,7 +89,11 @@ static void worker_thread(void); int main(int argc, char **argv) { int port; int client_socket, server_socket; +#ifdef USE_IPV4_ONLY + struct sockaddr_in server_in; +#else struct sockaddr_in6 server_in; +#endif size_t i; pthread_t *threads; @@ -101,15 +105,15 @@ int main(int argc, char **argv) { port = atoi(argv[argc - 1]); if (0 >= port || 0xffff < port) { print_usage(argv[0]); - fprintf(stderr, "\ninvalid port\n"); + fprintf(stderr, "\ninvalid port: '%s'\n", argv[argc - 1]); return EXIT_FAILURE; } - /* Setup our SIGINT signal handler which allows a "normal" termination of - * the server in DEBUG mode. */ sigemptyset(&action.sa_mask); action.sa_flags = 0; #ifdef DEBUG + /* Setup our SIGINT signal handler which allows a "normal" termination of + * the server in DEBUG mode. */ action.sa_handler = sigint_handler; sigaction(SIGINT, &action, NULL); #endif @@ -133,7 +137,7 @@ int main(int argc, char **argv) { initialize_gnutls(); /* Spawn worker threads to handle requests. */ - threads = (pthread_t *)malloc(thread_count * sizeof(pthread_t)); + threads = malloc(thread_count * sizeof(*threads)); if (NULL == threads) { perror("thread malloc failed"); return EXIT_FAILURE; @@ -154,26 +158,34 @@ int main(int argc, char **argv) { threads[i] = thread; } +#ifdef USE_IPV4_ONLY + server_socket = socket(PF_INET, SOCK_STREAM, 0); +#else server_socket = socket(PF_INET6, SOCK_STREAM, 0); +#endif if (-1 == server_socket) { perror("socket()"); return EXIT_FAILURE; } -#ifdef DEBUG /* Fast rebinding for debug mode, could cause invalid packets. */ - { + if (LOG_DEBUG_LEVEL <= global_log_level) { int socket_option = 1; setsockopt(server_socket, SOL_SOCKET, SO_REUSEADDR, &socket_option, sizeof(socket_option)); } -#endif /* Bind to the listen socket. */ memset(&server_in, 0, sizeof(server_in)); +#ifdef USE_IPV4_ONLY + server_in.sin_family = AF_INET; /* IPv4 only */ + server_in.sin_addr.s_addr = htonl(INADDR_ANY); /* bind to any address */ + server_in.sin_port = htons((uint16_t)port); /* port to bind to */ +#else server_in.sin6_family = AF_INET6; /* IPv6 (and IPv4) */ server_in.sin6_addr = in6addr_any; /* bind to any address */ server_in.sin6_port = htons((uint16_t)port); /* port to bind to */ +#endif if (-1 == bind(server_socket, (struct sockaddr *)&server_in, sizeof(server_in))) { perror("bind()"); @@ -185,7 +197,8 @@ int main(int argc, char **argv) { return EXIT_FAILURE; } - if (LOG_DEBUG <= global_log_level) { + if (LOG_DEBUG_LEVEL <= global_log_level) { + printf("tlsproxy %s\n", VERSION); printf("Listening for connections on port %d.\n", port); if (NULL != global_proxy_host && NULL != global_proxy_port) { @@ -202,7 +215,7 @@ int main(int argc, char **argv) { break; } - /* No lock, we only have one producer! */ + /* No lock necessary, we only have one producer! */ P(ringbuffer_free); ringbuffer[ringbuffer_write] = client_socket; ringbuffer_write = (ringbuffer_write + 1) % RINGBUFFER_SIZE; @@ -222,7 +235,6 @@ int main(int argc, char **argv) { errno = pthread_join(threads[i], NULL); if (0 != errno) { perror("pthread_join()"); - continue; } } @@ -254,17 +266,19 @@ static void parse_arguments(int argc, char **argv) { /* Default values. */ thread_count = 10; #ifdef DEBUG - global_log_level = LOG_DEBUG; + global_log_level = LOG_DEBUG_LEVEL; #else - global_log_level = LOG_WARNING; + global_log_level = LOG_WARNING_LEVEL; #endif + global_passthrough_unknown = 0; - while (-1 != (option = getopt(argc, argv, "d:p:t:h?"))) { + while (-1 != (option = getopt(argc, argv, "d:p:t:uh?"))) { switch (option) { case 'd': { if (0 > atoi(optarg)) { print_usage(argv[0]); - fprintf(stderr, "\n-d positive number required\n"); + fprintf(stderr, "\n-d positive number required: '%s'\n", + optarg); exit(EXIT_FAILURE); } global_log_level = atoi(optarg); @@ -280,7 +294,8 @@ static void parse_arguments(int argc, char **argv) { || 0 >= atoi(position + 1) || 0xffff < atoi(position + 1)) { print_usage(argv[0]); - fprintf(stderr, "\ninvalid -p, format host:port\n"); + fprintf(stderr, "\ninvalid -p: '%s', format host:port\n", + optarg); exit(EXIT_FAILURE); } @@ -304,12 +319,17 @@ static void parse_arguments(int argc, char **argv) { case 't': { if (0 >= atoi(optarg)) { print_usage(argv[0]); - fprintf(stderr, "\n-t positive number required\n"); + fprintf(stderr, "\n-t positive number required: '%s'\n", + optarg); exit(EXIT_FAILURE); } thread_count = (size_t)atoi(optarg); break; } + case 'u': { + global_passthrough_unknown = 1; + break; + } case 'h': default: /* '?' */ print_usage(argv[0]); @@ -324,12 +344,17 @@ static void parse_arguments(int argc, char **argv) { } } static void print_usage(const char *argv) { - fprintf(stderr, "Usage: %s [-d level] [-p host:port] [-t count] port\n", + fprintf(stderr, "tlsproxy %s, a certificate checking TLS proxy\n", + VERSION); + fprintf(stderr, "Usage: %s [-d level] [-p host:port] [-t count] [-u] port\n", argv); fprintf(stderr, "\n"); fprintf(stderr, "-d debug level: 0=errors only, 2=debug [default: 1]\n"); fprintf(stderr, "-p proxy hostname and port\n"); fprintf(stderr, "-t number of threads [default: 10]\n"); + fprintf(stderr, "-u passthrough connection if no certificate is stored \ +[default: error]\n"); + fprintf(stderr, " WARNING: might be a security problem!\n"); } static void initialize_gnutls(void) { @@ -356,18 +381,18 @@ static void initialize_gnutls(void) { GNUTLS_ERROR_EXIT(result, "gnutls_global_init()"); /* Setup GnuTLS cipher suites. */ - result = gnutls_priority_init(&tls_priority_cache, "NORMAL", NULL); + result = gnutls_priority_init(&global_tls_priority_cache, "NORMAL", NULL); GNUTLS_ERROR_EXIT(result, "gnutls_priority_init()"); /* Generate Diffie-Hellman parameters. */ - result = gnutls_dh_params_init(&tls_dh_params); + result = gnutls_dh_params_init(&global_tls_dh_params); GNUTLS_ERROR_EXIT(result, "gnutls_dh_params_init()"); - result = gnutls_dh_params_generate2(tls_dh_params, DH_SIZE); + result = gnutls_dh_params_generate2(global_tls_dh_params, DH_SIZE); GNUTLS_ERROR_EXIT(result, "gnutls_dh_params_generate2()"); } static void deinitialize_gnutls(void) { - gnutls_dh_params_deinit(tls_dh_params); - gnutls_priority_deinit(tls_priority_cache); + gnutls_dh_params_deinit(global_tls_dh_params); + gnutls_priority_deinit(global_tls_priority_cache); gnutls_global_deinit(); }