Hi.

Attached is the RFC version of patch (against old version of libvirt) which compiles out support for SSL encryption on libvirt connections.

It is meant only to provoke a discussion whether such option is deemed acceptable to libvirt, or it would be a complete waste of time to rebase this patch to current git and improve it by disabling other SSL-related functionality.

The motivation behind the change: making possible to configure libvirt to rely on absolute minimum of other libraries. Resulting configuration ought to connect to local libvirt daemon through Unix sockets.

--
Mikhail Gusarov
Software Engineer
CFEngine AS

Nydalsveien 33
0484 Oslo
>From 9f0ba4f3402023a44f716a0dc032c6bf55412b59 Mon Sep 17 00:00:00 2001
From: Mikhail Gusarov <mikhail.gusa...@cfengine.com>
Date: Thu, 21 Jul 2011 10:03:03 +0200
Subject: [PATCH 1/2] Disable GnuTLS in remote driver

---
 configure.ac               |   29 +++++++++++++++++----
 src/libvirt.c              |    6 ++++
 src/remote/remote_driver.c |   57 +++++++++++++++++++++++++++++++++++++-------
 3 files changed, 77 insertions(+), 15 deletions(-)

diff --git a/configure.ac b/configure.ac
index ecaf9cb..0dbe38b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -672,30 +672,47 @@ CFLAGS="$old_cflags"
 LIBS="$old_libs"
 
 dnl GnuTLS library
+AC_ARG_WITH([gnutls],
+  AC_HELP_STRING([--with-gnutls], [use GnuTLS for SSL-secured communication @<:@default=check@:>@]),
+  [],
+  [with_gnutls=check])
+
 GNUTLS_CFLAGS=
 GNUTLS_LIBS=
 GNUTLS_FOUND=no
-if test -x "$PKG_CONFIG" ; then
+if test "x$with_gnutls" = "xyes" || test "x$with_gnutls" = "xcheck"; then
+  if test -x "$PKG_CONFIG" ; then
   PKG_CHECK_MODULES(GNUTLS, gnutls >= $GNUTLS_REQUIRED,
      [GNUTLS_FOUND=yes], [GNUTLS_FOUND=no])
-fi
-if test "$GNUTLS_FOUND" = "no"; then
+  fi
+  if test "$GNUTLS_FOUND" = "no"; then
   fail=0
   old_libs="$LIBS"
   AC_CHECK_HEADER([gnutls/gnutls.h], [], [fail=1])
   AC_CHECK_LIB([gnutls], [gnutls_handshake],[], [fail=1], [-lgcrypt])
 
-  test $fail = 1 &&
+    if test $fail = 1; then
+      if test "x$with_gnutls" = "xcheck"; then
+        with_gnutls=no
+      else
     AC_MSG_ERROR([You must install the GnuTLS library in order to compile and run libvirt])
+      fi
+    fi
 
   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="$LIBS -lgcrypt"
   LIBS="$old_libs"
-else
+  else
   GNUTLS_LIBS="$GNUTLS_LIBS -lgcrypt"
-fi
+  fi
 
+  if test "x$with_gnutls" = "xyes"; then
+    AC_DEFINE_UNQUOTED([HAVE_GNUTLS], 1,
+      [whether GnuTLS is used to SSL-secure communications])
+  fi
+fi
+AM_CONDITIONAL([HAVE_GNUTLS], [test "x$with_gnutls" = "xyes"])
 AC_SUBST([GNUTLS_CFLAGS])
 AC_SUBST([GNUTLS_LIBS])
 
diff --git a/src/libvirt.c b/src/libvirt.c
index ca383ba..928898f 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -20,7 +20,9 @@
 #include <assert.h>
 #include <sys/wait.h>
 #include <time.h>
+#if HAVE_GNUTLS
 #include <gcrypt.h>
+#endif
 
 #include <libxml/parser.h>
 #include <libxml/xpath.h>
@@ -255,6 +257,7 @@ winsock_init (void)
 }
 #endif
 
+#if HAVE_GNUTLS
 static int virTLSMutexInit (void **priv)
 {                                                                             \
     virMutexPtr lock = NULL;
@@ -307,6 +310,7 @@ static struct gcry_thread_cbs virTLSThreadImpl = {
     virTLSMutexUnlock,
     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
 };
+#endif
 
 
 /**
@@ -331,8 +335,10 @@ virInitialize(void)
         virRandomInitialize(time(NULL) ^ getpid()))
         return -1;
 
+#if HAVE_GNUTLS
     gcry_control(GCRYCTL_SET_THREAD_CBS, &virTLSThreadImpl);
     gcry_check_version(NULL);
+#endif
 
     virLogSetFromEnv();
 
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index a945710..f446784 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -56,9 +56,11 @@
 
 #include <rpc/types.h>
 #include <rpc/xdr.h>
-#include <gnutls/gnutls.h>
-#include <gnutls/x509.h>
-#include "gnutls_1_0_compat.h"
+#if HAVE_GNUTLS
+#  include <gnutls/gnutls.h>
+#  include <gnutls/x509.h>
+#  include "gnutls_1_0_compat.h"
+#endif
 #if HAVE_SASL
 # include <sasl/sasl.h>
 #endif
@@ -152,9 +154,11 @@ struct private_data {
     int errfd;                /* File handle connected to remote stderr */
     int watch;                  /* File handle watch */
     pid_t pid;                  /* PID of tunnel process */
+#if HAVE_GNUTLS
     int uses_tls;               /* TLS enabled on socket? */
-    int is_secure;              /* Secure if TLS or SASL or UNIX sockets */
     gnutls_session_t session;   /* GnuTLS session (if uses_tls != 0). */
+#endif
+    int is_secure;              /* Secure if TLS or SASL or UNIX sockets */
     char *type;                 /* Cached return from remoteType. */
     int counter;                /* Generates serial numbers for RPC. */
     int localUses;              /* Ref count for private data */
@@ -263,9 +267,11 @@ void remoteDomainEventQueueFlush(int timer, void *opaque);
 /* Helper functions for remoteOpen. */
 static char *get_transport_from_scheme (char *scheme);
 
+#if HAVE_GNUTLS
 /* GnuTLS functions used by remoteOpen. */
 static int initialize_gnutls(void);
 static gnutls_session_t negotiate_gnutls_on_connection (virConnectPtr conn, struct private_data *priv, int no_verify);
+#endif
 
 #ifdef WITH_LIBVIRTD
 static int
@@ -373,7 +379,9 @@ doRemoteOpen (virConnectPtr conn,
     int wakeupFD[2] = { -1, -1 };
     char *transport_str = NULL;
     enum {
+#if HAVE_GNUTLS
         trans_tls,
+#endif
         trans_unix,
         trans_ssh,
         trans_ext,
@@ -391,14 +399,19 @@ doRemoteOpen (virConnectPtr conn,
             transport_str = get_transport_from_scheme (conn->uri->scheme);
 
             if (!transport_str) {
+#if HAVE_GNUTLS
                 if (conn->uri->server)
                     transport = trans_tls;
                 else
+#endif
                     transport = trans_unix;
             } else {
+#if HAVE_GNUTLS
                 if (STRCASEEQ (transport_str, "tls"))
                     transport = trans_tls;
-                else if (STRCASEEQ (transport_str, "unix"))
+                else
+#endif
+                    if (STRCASEEQ (transport_str, "unix"))
                     transport = trans_unix;
                 else if (STRCASEEQ (transport_str, "ssh"))
                     transport = trans_ssh;
@@ -409,7 +422,11 @@ doRemoteOpen (virConnectPtr conn,
                 else {
                     remoteError(VIR_ERR_INVALID_ARG, "%s",
                                 _("remote_open: transport in URL not recognised "
-                                  "(should be tls|unix|ssh|ext|tcp)"));
+                                  "(should be "
+#if HAVE_GNUTLS
+                                  "tls|"
+#endif
+                                  "unix|ssh|ext|tcp)"));
                     return VIR_DRV_OPEN_ERROR;
                 }
             }
@@ -433,9 +450,11 @@ doRemoteOpen (virConnectPtr conn,
     /* Remote server defaults to "localhost" if not specified. */
     if (conn->uri && conn->uri->port != 0) {
         if (virAsprintf(&port, "%d", conn->uri->port) == -1) goto out_of_memory;
+#if HAVE_GNUTLS
     } else if (transport == trans_tls) {
         port = strdup (LIBVIRTD_TLS_PORT);
         if (!port) goto out_of_memory;
+#endif
     } else if (transport == trans_tcp) {
         port = strdup (LIBVIRTD_TCP_PORT);
         if (!port) goto out_of_memory;
@@ -572,12 +591,14 @@ doRemoteOpen (virConnectPtr conn,
 
     /* Connect to the remote service. */
     switch (transport) {
+#if HAVE_GNUTLS
     case trans_tls:
         if (initialize_gnutls() == -1) goto failed;
         priv->uses_tls = 1;
         priv->is_secure = 1;
 
         /*FALLTHROUGH*/
+#endif
     case trans_tcp: {
         // http://people.redhat.com/drepper/userapi-ipv6.html
         struct addrinfo *res, *r;
@@ -625,6 +646,7 @@ doRemoteOpen (virConnectPtr conn,
                 continue;
             }
 
+#if HAVE_GNUTLS
             if (priv->uses_tls) {
                 priv->session =
                     negotiate_gnutls_on_connection
@@ -635,6 +657,7 @@ doRemoteOpen (virConnectPtr conn,
                     goto failed;
                 }
             }
+#endif
             goto tcp_connected;
         }
 
@@ -959,10 +982,12 @@ doRemoteOpen (virConnectPtr conn,
         close(priv->errfd);
 
     if (priv->sock >= 0) {
+#if HAVE_GNUTLS
         if (priv->uses_tls && priv->session) {
             gnutls_bye (priv->session, GNUTLS_SHUT_RDWR);
             gnutls_deinit (priv->session);
         }
+#endif
         close (priv->sock);
 #ifndef WIN32
         if (priv->pid > 0) {
@@ -1117,6 +1142,7 @@ get_transport_from_scheme (char *scheme)
     return p ? p+1 : 0;
 }
 
+#if HAVE_GNUTLS
 /* GnuTLS functions used by remoteOpen. */
 static gnutls_certificate_credentials_t x509_cred;
 
@@ -1139,6 +1165,7 @@ static void remote_debug_gnutls_log(int level, const char* str) {
     DEBUG("%d %s", level, str);
 }
 
+
 static int
 initialize_gnutls(void)
 {
@@ -1413,6 +1440,7 @@ verify_certificate (virConnectPtr conn ATTRIBUTE_UNUSED,
 
     return 0;
 }
+#endif
 
 /*----------------------------------------------------------------------*/
 
@@ -1434,10 +1462,12 @@ doRemoteClose (virConnectPtr conn, struct private_data *priv)
         return -1;
 
     /* Close socket. */
+#if HAVE_GNUTLS
     if (priv->uses_tls && priv->session) {
         gnutls_bye (priv->session, GNUTLS_SHUT_RDWR);
         gnutls_deinit (priv->session);
     }
+#endif
 #if HAVE_SASL
     if (priv->saslconn)
         sasl_dispose (&priv->saslconn);
@@ -1678,8 +1708,10 @@ static int remoteIsEncrypted(virConnectPtr conn)
               (xdrproc_t) xdr_remote_is_secure_ret, (char *) &ret) == -1)
         goto done;
 
+#if HAVE_GNUTLS
     if (priv->uses_tls)
         encrypted = 1;
+#endif
 #if HAVE_SASL
     else if (priv->saslconn)
         encrypted = 1;
@@ -6954,6 +6986,7 @@ remoteAuthSASL (virConnectPtr conn, struct private_data *priv, int in_open,
         goto cleanup;
     }
 
+#if HAVE_GNUTLS
     /* Initialize some connection props we care about */
     if (priv->uses_tls) {
         gnutls_cipher_algorithm_t cipher;
@@ -6975,6 +7008,7 @@ remoteAuthSASL (virConnectPtr conn, struct private_data *priv, int in_open,
             goto cleanup;
         }
     }
+#endif
 
     memset (&secprops, 0, sizeof secprops);
     /* If we've got TLS, we don't care about SSF */
@@ -8994,7 +9028,7 @@ remoteIOWriteBuffer(struct private_data *priv,
                     const char *bytes, int len)
 {
     int ret;
-
+#if HAVE_GNUTLS
     if (priv->uses_tls) {
     tls_resend:
         ret = gnutls_record_send (priv->session, bytes, len);
@@ -9007,7 +9041,9 @@ remoteIOWriteBuffer(struct private_data *priv,
             remoteError(VIR_ERR_GNUTLS_ERROR, "%s", gnutls_strerror (ret));
             return -1;
         }
-    } else {
+    } else
+#endif
+    {
     resend:
         ret = send (priv->sock, bytes, len, 0);
         if (ret == -1) {
@@ -9032,6 +9068,7 @@ remoteIOReadBuffer(struct private_data *priv,
 {
     int ret;
 
+#if HAVE_GNUTLS
     if (priv->uses_tls) {
     tls_resend:
         ret = gnutls_record_recv (priv->session, bytes, len);
@@ -9051,7 +9088,9 @@ remoteIOReadBuffer(struct private_data *priv,
                             _("server closed connection"));
             return -1;
         }
-    } else {
+    } else
+#endif
+    {
     resend:
         ret = recv (priv->sock, bytes, len, 0);
         if (ret <= 0) {
-- 
1.7.4.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Reply via email to