]> xenbits.xensource.com Git - libvirt.git/commitdiff
build: avoid -lgcrypt with newer gnutls
authorEric Blake <eblake@redhat.com>
Thu, 25 Jul 2013 22:03:17 +0000 (16:03 -0600)
committerEric Blake <eblake@redhat.com>
Mon, 12 Aug 2013 15:58:48 +0000 (09:58 -0600)
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, but mostly harmless
(it doesn't crash, but does interfere with certification efforts).

There are three distinct version ranges to worry about when
determining which crypto lib gnutls uses, per these gnutls mails:
2.12: http://lists.gnu.org/archive/html/gnutls-devel/2011-03/msg00034.html
3.0: http://lists.gnu.org/archive/html/gnutls-devel/2011-07/msg00035.html

If pkg-config can prove version numbers and/or list the crypto
library used for static linking, we have our proof; if not, it
is safer (even if pointless) to continue to use gcrypt ourselves.

* 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@redhat.com>
configure.ac
libvirt.spec.in
src/libvirt.c

index d3219ceddd09f8147a109293dbe6c6b7a1fc3dc7..6cfb7e96c1ce6dfeed728b5fc2cbf808d0dc154a 100644 (file)
@@ -1086,12 +1086,26 @@ if test "x$with_gnutls" != "xno"; then
   LIBS="$LIBS $GNUTLS_LIBS"
 
   GNUTLS_FOUND=no
+  GNUTLS_GCRYPT=unknown
   if test -x "$PKG_CONFIG" ; then
+    dnl Triple probe: gnutls < 2.12 only used gcrypt, gnutls >= 3.0 uses
+    dnl only nettle, and versions in between had a configure option.
+    dnl Our goal is to avoid gcrypt if we can prove gnutls uses nettle,
+    dnl but it is a safe fallback to use gcrypt if we can't prove anything.
+    if $PKG_CONFIG --exists 'gnutls >= 3.0'; then
+      GNUTLS_GCRYPT=no
+    elif $PKG_CONFIG --exists 'gnutls >= 2.12'; then
+      GNUTLS_GCRYPT=probe
+    else
+      GNUTLS_GCRYPT=yes
+    fi
     PKG_CHECK_MODULES(GNUTLS, gnutls >= $GNUTLS_REQUIRED,
       [GNUTLS_FOUND=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])
 
@@ -1108,13 +1122,22 @@ 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 See comments above about when to use gcrypt.
+    if test "$GNUTLS_GCRYPT" = probe; then
+      case `$PKG_CONFIG --libs --static gnutls` in
+        *gcrypt*) GNUTLS_GCRYPT=yes     ;;
+        *nettle*) GNUTLS_GCRYPT=no      ;;
+        *)        GNUTLS_GCRYPT=unknown ;;
+      esac
+    fi
+    if test "$GNUTLS_GCRYPT" = yes || test "$GNUTLS_GCRYPT" = unknown; 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], [], [], [[
index 5346b8bc4c35fe03647c3c7404a4aea4f3fcf24a..054d9b89833c365c0fdd2e88669d5b2c2bc4ff82 100644 (file)
@@ -438,7 +438,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}
index 815748806a88012a644dab3f67edfd341a47db73..66e82485ae2d22f842cb0f5e967aec2a8561b886 100644 (file)
@@ -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