X-Git-Url: https://ruderich.org/simon/gitweb/?p=tlsproxy%2Ftlsproxy.git;a=blobdiff_plain;f=src%2Ftlsproxy.c;h=6d49253681ea05ff92b27c8e3a3e71de3d7ee5fa;hp=cfd240f3569a1460f7f11badb0690c9f0294bb00;hb=071dd5923aa311dc6830904a4e31db227ea08995;hpb=62c92fd81b76ba0cd2e45f0a01166d1a002d9f3c diff --git a/src/tlsproxy.c b/src/tlsproxy.c index cfd240f..6d49253 100644 --- a/src/tlsproxy.c +++ b/src/tlsproxy.c @@ -24,6 +24,7 @@ #include "connection.h" #include +#include #include #include #include @@ -31,6 +32,7 @@ #include #include #include +#include #if GNUTLS_VERSION_NUMBER <= 0x020b00 /* Necessary for GnuTLS when used with threads. */ @@ -42,9 +44,6 @@ GCRY_THREAD_OPTION_PTHREAD_IMPL; /* Size of ringbuffer. */ #define RINGBUFFER_SIZE 10 -/* Bit size of Diffie-Hellman key exchange parameters. */ -#define DH_SIZE 1024 - /* For gnutls_*() functions. */ #define GNUTLS_ERROR_EXIT(error, message) \ @@ -75,7 +74,7 @@ static void sigint_handler(int signal); static void parse_arguments(int argc, char **argv); static void print_usage(const char *argv); -static char *slurp_file(const char *path); +static char *slurp_text_file(const char *path); static void initialize_gnutls(void); static void deinitialize_gnutls(void); @@ -192,6 +191,7 @@ int main(int argc, char **argv) { if (global_log_level >= LOG_DEBUG1_LEVEL) { printf("tlsproxy %s\n", VERSION); printf("Listening for connections on port %d.\n", port); + printf("Priority string: %s.\n", PROXY_TLS_PRIORITIES); if (global_proxy_host != NULL && global_proxy_port != NULL) { printf("Using proxy: %s:%s.\n", global_proxy_host, @@ -240,6 +240,7 @@ int main(int argc, char **argv) { free(global_proxy_host); free(global_proxy_port); + free(global_http_digest_authorization); return EXIT_FAILURE; } @@ -258,7 +259,7 @@ static void parse_arguments(int argc, char **argv) { /* Default values. */ thread_count = 10; #ifdef DEBUG - global_log_level = LOG_DEBUG1_LEVEL; + global_log_level = LOG_DEBUG2_LEVEL; #else global_log_level = LOG_WARNING_LEVEL; #endif @@ -267,20 +268,20 @@ static void parse_arguments(int argc, char **argv) { while ((option = getopt(argc, argv, "a:d:p:t:uh?")) != -1) { switch (option) { case 'a': { - http_digest_authorization = slurp_file(optarg); - if (http_digest_authorization == NULL) { + global_http_digest_authorization = slurp_text_file(optarg); + if (global_http_digest_authorization == NULL) { fprintf(stderr, "failed to open authorization file '%s': ", optarg); perror(""); exit(EXIT_FAILURE); - } else if (strlen(http_digest_authorization) == 0) { + } else if (strlen(global_http_digest_authorization) == 0) { fprintf(stderr, "empty authorization file '%s'\n", optarg); exit(EXIT_FAILURE); } /* Just in case the file has a trailing newline. */ - strtok(http_digest_authorization, "\r\n"); + strtok(global_http_digest_authorization, "\r\n"); break; } @@ -356,7 +357,7 @@ static void print_usage(const char *argv) { argv); fprintf(stderr, "\n"); fprintf(stderr, "-a digest authentication file [default: none]\n"); - fprintf(stderr, "-d debug level: 0=errors only, 2=debug [default: 1]\n"); + fprintf(stderr, "-d debug level: 0=errors only, 2=debug, 3=more 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 \ @@ -364,10 +365,20 @@ static void print_usage(const char *argv) { fprintf(stderr, " WARNING: might be a security problem!\n"); } +#if 0 +static void log_function_gnutls(int level, const char *string) { + (void)level; + fprintf(stderr, " => %s", string); +} +#endif + static void initialize_gnutls(void) { int result; + char *dh_parameters; + gnutls_datum_t dh_parameters_datum; + /* Recent versions of GnuTLS automatically initialize the cryptography layer - * in gnutls_global_init(). */ + * in gnutls_global_init(), including a thread-safe setup. */ #if GNUTLS_VERSION_NUMBER <= 0x020b00 gcry_error_t error; @@ -387,19 +398,45 @@ static void initialize_gnutls(void) { } #endif + if (gnutls_check_version(GNUTLS_VERSION) == NULL) { + fprintf(stderr, "gnutls_check_version(): version mismatch, " + "expected at least '" GNUTLS_VERSION "'\n"); + exit(EXIT_FAILURE); + } + /* Initialize GnuTLS. */ result = gnutls_global_init(); GNUTLS_ERROR_EXIT(result, "gnutls_global_init()"); +#if 0 + gnutls_global_set_log_level(10); + gnutls_global_set_log_function(log_function_gnutls); +#endif + /* Setup GnuTLS cipher suites. */ - result = gnutls_priority_init(&global_tls_priority_cache, "NORMAL", NULL); + result = gnutls_priority_init(&global_tls_priority_cache, + PROXY_TLS_PRIORITIES, NULL); GNUTLS_ERROR_EXIT(result, "gnutls_priority_init()"); - /* Generate Diffie-Hellman parameters. */ + /* Read Diffie-Hellman parameters. */ + dh_parameters = slurp_text_file(PROXY_DH_PATH); + if (dh_parameters == NULL) { + fprintf(stderr, PROXY_DH_PATH " missing, " + "use `tlsproxy-setup` to create it\n"); + exit(EXIT_FAILURE); + } + dh_parameters_datum.data = (unsigned char *)dh_parameters; + assert(strlen(dh_parameters) <= UINT_MAX); + dh_parameters_datum.size = (unsigned int)(strlen(dh_parameters)); + result = gnutls_dh_params_init(&global_tls_dh_params); GNUTLS_ERROR_EXIT(result, "gnutls_dh_params_init()"); - result = gnutls_dh_params_generate2(global_tls_dh_params, DH_SIZE); - GNUTLS_ERROR_EXIT(result, "gnutls_dh_params_generate2()"); + result = gnutls_dh_params_import_pkcs3(global_tls_dh_params, + &dh_parameters_datum, + GNUTLS_X509_FMT_PEM); + GNUTLS_ERROR_EXIT(result, "gnutls_dh_params_import_pkcs3()"); + + free(dh_parameters); } static void deinitialize_gnutls(void) { gnutls_dh_params_deinit(global_tls_dh_params); @@ -433,7 +470,7 @@ static void *worker_thread(void *unused) { return NULL; } -static char *slurp_file(const char *path) { +static char *slurp_text_file(const char *path) { struct stat stat; size_t size_read; char *content = NULL;