https://bugzilla.redhat.com/show_bug.cgi?id=951637
Newer gnutls uses nettle, rather than gcrypt, which is a lot nicer
regarding initialization. Yet we were unconditionally initializing
gcrypt even when gnutls wouldn't be using it, and having two crypto
libraries linked into libvirt.so is pointless.
Assume that the switch to gnutls 3.0 is a reliable witness, when
pkg-config is present; otherwise be pessimistic and use gcrypt.
* configure.ac (WITH_GNUTLS): Probe whether to add -lgcrypt, and
define a witness WITH_GNUTLS_GCRYPT.
* src/libvirt.c (virTLSMutexInit, virTLSMutexDestroy)
(virTLSMutexLock, virTLSMutexUnlock, virTLSThreadImpl)
(virGlobalInit): Honor the witness.
* libvirt.spec.in (BuildRequires): Make gcrypt usage conditional,
no longer needed in Fedora 19.
Signed-off-by: Eric Blake <eblake(a)redhat.com>
---
v2: use second pkg-config invocation rather than ldd to determine
whether gnutls uses gcrypt
configure.ac | 27 +++++++++++++++++++--------
libvirt.spec.in | 2 ++
src/libvirt.c | 10 ++++++----
3 files changed, 27 insertions(+), 12 deletions(-)
diff --git a/configure.ac b/configure.ac
index cc9942a..eb56b63 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1076,12 +1076,19 @@ if test "x$with_gnutls" != "xno"; then
LIBS="$LIBS $GNUTLS_LIBS"
GNUTLS_FOUND=no
+ GNUTLS_GCRYPT=no
if test -x "$PKG_CONFIG" ; then
+ dnl double probe, since we know that gnutls 3.0 switched to nettle instead of
+ dnl gcrypt
PKG_CHECK_MODULES(GNUTLS, gnutls >= $GNUTLS_REQUIRED,
- [GNUTLS_FOUND=yes], [GNUTLS_FOUND=no])
+ [GNUTLS_FOUND=yes
+ PKG_CHECK_MODULES([GNUTLS], [gnutls >= 3.0], [], [GNUTLS_GCRYPT=yes])],
+ [GNUTLS_FOUND=no])
fi
if test "$GNUTLS_FOUND" = "no"; then
+ dnl pkg-config couldn't help us, assume gcrypt is necessary
fail=0
+ GNUTLS_GCRYPT=yes
AC_CHECK_HEADER([gnutls/gnutls.h], [], [fail=1])
AC_CHECK_LIB([gnutls], [gnutls_handshake],[], [fail=1], [-lgcrypt])
@@ -1098,13 +1105,17 @@ if test "x$with_gnutls" != "xno"; then
AC_MSG_ERROR([You must install the GnuTLS library in order to compile and run
libvirt])
fi
else
- dnl Not all versions of gnutls include -lgcrypt, and so we add
- dnl it explicitly for the calls to gcry_control/check_version
- GNUTLS_LIBS="$GNUTLS_LIBS -lgcrypt"
-
- dnl We're not using gcrypt deprecated features so define
- dnl GCRYPT_NO_DEPRECATED to avoid deprecated warnings
- GNUTLS_CFLAGS="$GNUTLS_CFLAGS -DGCRYPT_NO_DEPRECATED"
+ dnl If gnutls linked against -lgcrypt, then we must initialize gcrypt
+ dnl prior to using gnutls. Newer versions of gnutls use -lnettle, in
+ dnl which case we don't want to drag in gcrypt ourselves.
+ if test "$GNUTLS_GCRYPT" = yes; then
+ GNUTLS_LIBS="$GNUTLS_LIBS -lgcrypt"
+ dnl We're not using gcrypt deprecated features so define
+ dnl GCRYPT_NO_DEPRECATED to avoid deprecated warnings
+ GNUTLS_CFLAGS="$GNUTLS_CFLAGS -DGCRYPT_NO_DEPRECATED"
+ AC_DEFINE_UNQUOTED([WITH_GNUTLS_GCRYPT], 1,
+ [set to 1 if it is known or assumed that GNUTLS uses gcrypt])
+ fi
dnl gnutls 3.x moved some declarations to a new header
AC_CHECK_HEADERS([gnutls/crypto.h], [], [], [[
diff --git a/libvirt.spec.in b/libvirt.spec.in
index e0e0004..4320281 100644
--- a/libvirt.spec.in
+++ b/libvirt.spec.in
@@ -422,7 +422,9 @@ BuildRequires: readline-devel
BuildRequires: ncurses-devel
BuildRequires: gettext
BuildRequires: libtasn1-devel
+%if (0%{?rhel} && 0%{?rhel} < 7) || (0%{?fedora} && 0%{?fedora} <
19)
BuildRequires: libgcrypt-devel
+%endif
BuildRequires: gnutls-devel
BuildRequires: libattr-devel
%if %{with_libvirtd}
diff --git a/src/libvirt.c b/src/libvirt.c
index 8157488..66e8248 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -55,7 +55,9 @@
#include "intprops.h"
#include "virconf.h"
#if WITH_GNUTLS
-# include <gcrypt.h>
+# if WITH_GNUTLS_GCRYPT
+# include <gcrypt.h>
+# endif
# include "rpc/virnettlscontext.h"
#endif
#include "vircommand.h"
@@ -270,7 +272,7 @@ winsock_init(void)
#endif
-#ifdef WITH_GNUTLS
+#ifdef WITH_GNUTLS_GCRYPT
static int virTLSMutexInit(void **priv)
{
virMutexPtr lock = NULL;
@@ -323,7 +325,7 @@ static struct gcry_thread_cbs virTLSThreadImpl = {
virTLSMutexUnlock,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};
-#endif
+#endif /* WITH_GNUTLS_GCRYPT */
/* Helper macros to implement VIR_DOMAIN_DEBUG using just C99. This
* assumes you pass fewer than 15 arguments to VIR_DOMAIN_DEBUG, but
@@ -407,7 +409,7 @@ virGlobalInit(void)
virErrorInitialize() < 0)
goto error;
-#ifdef WITH_GNUTLS
+#ifdef WITH_GNUTLS_GCRYPT
/*
* This sequence of API calls it copied exactly from
* gnutls 2.12.23 source lib/gcrypt/init.c, with
--
1.8.3.1
--
libvir-list mailing list
libvir-list(a)redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
Hate to throw a monkey wrench in the plan, but GnuTLS 3.0 isn't the
nettle cut over. On my stable Gentoo box with GnuTLS 2.12.23, its
using nettle as seen by ldd.
ldd /usr/lib64/libgnutls.so.26
linux-vdso.so.1 (0x00007fffad3ff000)
libnettle.so.4 => /usr/lib64/libnettle.so.4 (0x00007f60fa4f4000)
libgmp.so.10 => /usr/lib64/libgmp.so.10 (0x00007f60fa284000)
libhogweed.so.2 => /usr/lib64/libhogweed.so.2 (0x00007f60fa054000)
libz.so.1 => /lib64/libz.so.1 (0x00007f60f9e3e000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f60f9c21000)
libtasn1.so.3 => /usr/lib64/libtasn1.so.3 (0x00007f60f9a0f000)
libc.so.6 => /lib64/libc.so.6 (0x00007f60f9661000)
/lib64/ld-linux-x86-64.so.2 (0x00007f60fa9ec000)
It appears it was an optional cutover and I guess Gentoo made the
plunge. Another idea, that you might hate would be to use pkg-config
directly and pass --static so we can get the private libraries. I'm
not running Fedora 19 yet so the best I can do is give you Fedora 18
as a comp, but that works out great since its using 2.12.23 as well.
stable Gentoo:
Name: GnuTLS
Description: Transport Security Layer implementation for the GNU system
URL:
Version: 2.12.23
Libs: -L${libdir} -lgnutls
Libs.private: -L/usr/lib64 -lnettle -lgmp -lhogweed
Requires.private: libtasn1 , zlib
Cflags: -I${includedir}
$ pkg-config --libs --static gnutls
-lgnutls -ltasn1 -lz -lnettle -lgmp -lhogweed
Fedora 18:
Name: GnuTLS
Description: Transport Security Layer implementation for the GNU system
URL:
Version: 2.12.23
Libs: -L${libdir} -lgnutls
Libs.private: -L/usr/lib64 -lgcrypt -L/usr/lib64 -lgpg-error
Requires.private: libtasn1 , zlib, p11-kit-1
Cflags: -I${includedir}
$ pkg-config --libs --static gnutls
-lgnutls -lgcrypt -lgpg-error -ltasn1 -lz -lp11-kit
With GnuTLS 3.2 I get the following:
pkg-config --libs --static gnutls
-lgnutls -lhogweed -lnettle -lz -lgmp
Maybe that helps?
--
Doug Goldstein