aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES5
-rw-r--r--RELEASE-NOTES2
-rw-r--r--lib/gtls.c32
3 files changed, 32 insertions, 7 deletions
diff --git a/CHANGES b/CHANGES
index d1c070fd6..4130e21eb 100644
--- a/CHANGES
+++ b/CHANGES
@@ -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");