diff options
-rw-r--r-- | CHANGES | 5 | ||||
-rw-r--r-- | RELEASE-NOTES | 2 | ||||
-rw-r--r-- | lib/gtls.c | 32 |
3 files changed, 32 insertions, 7 deletions
@@ -7,6 +7,11 @@ Changelog Daniel S (28 April 2007) +- Peter O'Gorman fixed libcurl to not init GnuTLS as early as we did before, + since it then inits libgcrypt and libgcrypt is being evil and EXITS the + application if it fails to get a fine random seed. That's really not a nice + thing to do by a library. + - Frank Hempel fixed a curl_easy_duphandle() crash on a handle that had been removed from a multi handle, and then fixed another flaw that prevented curl_easy_duphandle() to work even after the first fix - the handle was diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 09d56b7c7..f4084218c 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -31,6 +31,8 @@ This release includes the following bugfixes: o compilation on VMS 64-bit mode o SCP/SFTP downloads could hang on the last bytes of a transfer o curl_easy_duphandle() crash + o curl -V / curl_verion*() works even when GnuTLS is used on a system without + a good random source This release includes the following known bugs: diff --git a/lib/gtls.c b/lib/gtls.c index 73461b9cc..0e100c621 100644 --- a/lib/gtls.c +++ b/lib/gtls.c @@ -63,7 +63,7 @@ static void tls_log_func(int level, const char *str) fprintf(stderr, "|<%d>| %s", level, str); } #endif - +static bool gtls_inited = FALSE; /* * Custom push and pull callback functions used by GNU TLS to read and write * to the socket. These functions are simple wrappers to send() and recv() @@ -85,17 +85,33 @@ static ssize_t Curl_gtls_pull(void *s, void *buf, size_t len) /* Global GnuTLS init, called from Curl_ssl_init() */ int Curl_gtls_init(void) { - gnutls_global_init(); +/* Unfortunately we can not init here, things like curl --version will + * fail to work if there is no egd socket available because libgcrypt + * will EXIT the application!! + * By doing the actual init later (before actually trying to use GnuTLS), + * we can at least provide basic info etc. + */ + return 1; +} + +static int _Curl_gtls_init(void) +{ + int ret = 1; + if (!gtls_inited) { + ret = gnutls_global_init()?0:1; #ifdef GTLSDEBUG - gnutls_global_set_log_function(tls_log_func); - gnutls_global_set_log_level(2); + gnutls_global_set_log_function(tls_log_func); + gnutls_global_set_log_level(2); #endif - return 1; + gtls_inited = TRUE; + } + return ret; } int Curl_gtls_cleanup(void) { - gnutls_global_deinit(); + if (gtls_inited) + gnutls_global_deinit(); return 1; } @@ -132,7 +148,8 @@ static CURLcode handshake(struct connectdata *conn, { struct SessionHandle *data = conn->data; int rc; - + if (!gtls_inited) + _Curl_gtls_init(); do { rc = gnutls_handshake(session); @@ -227,6 +244,7 @@ Curl_gtls_connect(struct connectdata *conn, void *ssl_sessionid; size_t ssl_idsize; + if (!gtls_inited) _Curl_gtls_init(); /* GnuTLS only supports TLSv1 (and SSLv3?) */ if(data->set.ssl.version == CURL_SSLVERSION_SSLv2) { failf(data, "GnuTLS does not support SSLv2"); |